Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Aug 2010 19:54:46 +0000 (12:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Aug 2010 19:54:46 +0000 (12:54 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [DNS RESOLVER] Minor typo correction
  DNS: Fixes for the DNS query module
  cifs: Include linux/err.h for IS_ERR and PTR_ERR
  DNS: Make AFS go to the DNS for AFSDB records for unknown cells
  DNS: Separate out CIFS DNS Resolver code
  cifs: account for new creduid=0x%x parameter in spnego upcall string
  cifs: reduce false positives with inode aliasing serverino autodisable
  CIFS: Make cifs_convert_address() take a const src pointer and a length
  cifs: show features compiled in as part of DebugData
  cifs: update README

Fix up trivial conflicts in fs/cifs/cifsfs.c due to workqueue changes

1904 files changed:
Documentation/ABI/testing/debugfs-kmemtrace [deleted file]
Documentation/ABI/testing/sysfs-bus-pci
Documentation/DocBook/device-drivers.tmpl
Documentation/DocBook/kgdb.tmpl
Documentation/DocBook/stylesheet.xsl
Documentation/coccinelle.txt [new file with mode: 0644]
Documentation/feature-removal-schedule.txt
Documentation/filesystems/caching/fscache.txt
Documentation/filesystems/sysfs-pci.txt
Documentation/filesystems/sysfs.txt
Documentation/firmware_class/hotplug-script
Documentation/hwmon/pkgtemp [new file with mode: 0644]
Documentation/kbuild/kbuild.txt
Documentation/kbuild/kconfig.txt
Documentation/kbuild/makefiles.txt
Documentation/kernel-parameters.txt
Documentation/pcmcia/driver-changes.txt
Documentation/slow-work.txt [deleted file]
Documentation/timers/timers-howto.txt [new file with mode: 0644]
Documentation/trace/ftrace-design.txt
Documentation/trace/kmemtrace.txt [deleted file]
Documentation/trace/kprobetrace.txt
Documentation/vm/page-types.c
Documentation/x86/zero-page.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/local64.h [new file with mode: 0644]
arch/arm/Kconfig
arch/arm/include/asm/kgdb.h
arch/arm/include/asm/local64.h [new file with mode: 0644]
arch/arm/kernel/kgdb.c
arch/arm/kernel/perf_event.c
arch/avr32/Kconfig
arch/avr32/Makefile
arch/avr32/include/asm/local64.h [new file with mode: 0644]
arch/blackfin/Kconfig
arch/blackfin/Makefile
arch/blackfin/include/asm/local64.h [new file with mode: 0644]
arch/cris/Kconfig
arch/cris/include/asm/local64.h [new file with mode: 0644]
arch/frv/Kconfig
arch/frv/Makefile
arch/frv/include/asm/local64.h [new file with mode: 0644]
arch/frv/kernel/local64.h [new file with mode: 0644]
arch/h8300/Kconfig
arch/h8300/include/asm/local64.h [new file with mode: 0644]
arch/ia64/Kconfig
arch/ia64/Makefile
arch/ia64/include/asm/local64.h [new file with mode: 0644]
arch/ia64/kernel/msi_ia64.c
arch/ia64/kernel/smpboot.c
arch/ia64/kernel/time.c
arch/ia64/sn/kernel/msi_sn.c
arch/m32r/Kconfig
arch/m32r/Makefile
arch/m32r/include/asm/local64.h [new file with mode: 0644]
arch/m68k/Kconfig
arch/m68k/Makefile
arch/m68k/include/asm/local64.h [new file with mode: 0644]
arch/m68knommu/Kconfig
arch/microblaze/Kconfig
arch/microblaze/include/asm/irq.h
arch/microblaze/include/asm/local64.h [new file with mode: 0644]
arch/microblaze/include/asm/of_device.h [deleted file]
arch/microblaze/include/asm/of_platform.h [deleted file]
arch/microblaze/include/asm/page.h
arch/microblaze/include/asm/pci-bridge.h
arch/microblaze/include/asm/prom.h
arch/microblaze/include/asm/topology.h
arch/microblaze/kernel/Makefile
arch/microblaze/kernel/irq.c
arch/microblaze/kernel/of_device.c [deleted file]
arch/microblaze/kernel/of_platform.c [deleted file]
arch/microblaze/kernel/prom_parse.c
arch/microblaze/kernel/reset.c
arch/microblaze/kernel/setup.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/include/asm/kgdb.h
arch/mips/include/asm/local64.h [new file with mode: 0644]
arch/mips/kernel/kgdb.c
arch/mn10300/Kconfig
arch/mn10300/include/asm/local64.h [new file with mode: 0644]
arch/parisc/Kconfig
arch/parisc/include/asm/local64.h [new file with mode: 0644]
arch/parisc/kernel/ftrace.c
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/irq.h
arch/powerpc/include/asm/local64.h [new file with mode: 0644]
arch/powerpc/include/asm/macio.h
arch/powerpc/include/asm/of_device.h [deleted file]
arch/powerpc/include/asm/of_platform.h [deleted file]
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/perf_event.h
arch/powerpc/include/asm/prom.h
arch/powerpc/include/asm/smu.h
arch/powerpc/include/asm/topology.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/dma-swiotlb.c
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/legacy_serial.c
arch/powerpc/kernel/misc.S
arch/powerpc/kernel/of_device.c [deleted file]
arch/powerpc/kernel/of_platform.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/perf_event.c
arch/powerpc/kernel/perf_event_fsl_emb.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/time.c
arch/powerpc/platforms/512x/clock.c
arch/powerpc/platforms/52xx/lite5200.c
arch/powerpc/platforms/52xx/mpc52xx_gpio.c
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
arch/powerpc/platforms/82xx/ep8248e.c
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
arch/powerpc/platforms/83xx/suspend.c
arch/powerpc/platforms/86xx/gef_gpio.c
arch/powerpc/platforms/amigaone/setup.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/beat_iommu.c
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/platforms/cell/qpace_setup.c
arch/powerpc/platforms/cell/setup.c
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/pasemi/gpio_mdio.c
arch/powerpc/platforms/powermac/feature.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/sysdev/axonram.c
arch/powerpc/sysdev/bestcomm/bestcomm.c
arch/powerpc/sysdev/bestcomm/sram.c
arch/powerpc/sysdev/cpm1.c
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/fsl_gtm.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_pmc.c
arch/powerpc/sysdev/fsl_rio.c
arch/powerpc/sysdev/mpc8xxx_gpio.c
arch/powerpc/sysdev/mv64x60_dev.c
arch/powerpc/sysdev/mv64x60_pci.c
arch/powerpc/sysdev/pmi.c
arch/powerpc/sysdev/ppc4xx_gpio.c
arch/powerpc/sysdev/qe_lib/gpio.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/powerpc/sysdev/simple_gpio.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/include/asm/local64.h [new file with mode: 0644]
arch/s390/kernel/time.c
arch/score/Kconfig
arch/score/Makefile
arch/score/include/asm/local64.h [new file with mode: 0644]
arch/sh/Kconfig
arch/sh/include/asm/local64.h [new file with mode: 0644]
arch/sh/kernel/perf_event.c
arch/sparc/Kconfig
arch/sparc/include/asm/device.h
arch/sparc/include/asm/floppy_64.h
arch/sparc/include/asm/local64.h [new file with mode: 0644]
arch/sparc/include/asm/of_device.h [deleted file]
arch/sparc/include/asm/of_platform.h [deleted file]
arch/sparc/include/asm/parport.h
arch/sparc/include/asm/perf_event.h
arch/sparc/include/asm/prom.h
arch/sparc/kernel/apc.c
arch/sparc/kernel/auxio_64.c
arch/sparc/kernel/central.c
arch/sparc/kernel/chmc.c
arch/sparc/kernel/helpers.S
arch/sparc/kernel/ioport.c
arch/sparc/kernel/of_device_32.c
arch/sparc/kernel/of_device_64.c
arch/sparc/kernel/of_device_common.c
arch/sparc/kernel/pci.c
arch/sparc/kernel/pci_fire.c
arch/sparc/kernel/pci_impl.h
arch/sparc/kernel/pci_psycho.c
arch/sparc/kernel/pci_sabre.c
arch/sparc/kernel/pci_schizo.c
arch/sparc/kernel/pci_sun4v.c
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/pmc.c
arch/sparc/kernel/power.c
arch/sparc/kernel/prom.h
arch/sparc/kernel/prom_64.c
arch/sparc/kernel/prom_common.c
arch/sparc/kernel/prom_irqtrans.c
arch/sparc/kernel/psycho_common.c
arch/sparc/kernel/psycho_common.h
arch/sparc/kernel/sbus.c
arch/sparc/kernel/time_32.c
arch/sparc/kernel/time_64.c
arch/sparc/mm/io-unit.c
arch/sparc/mm/iommu.c
arch/um/Kconfig.common
arch/um/include/asm/pgtable-3level.h
arch/um/kernel/time.c
arch/x86/Kconfig
arch/x86/boot/Makefile
arch/x86/boot/boot.h
arch/x86/boot/cmdline.c
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/cmdline.c [new file with mode: 0644]
arch/x86/boot/compressed/early_serial_console.c [new file with mode: 0644]
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/boot/compressed/misc.c
arch/x86/boot/compressed/misc.h [new file with mode: 0644]
arch/x86/boot/compressed/string.c [new file with mode: 0644]
arch/x86/boot/compressed/vmlinux.lds.S
arch/x86/boot/ctype.h [new file with mode: 0644]
arch/x86/boot/early_serial_console.c [new file with mode: 0644]
arch/x86/boot/main.c
arch/x86/boot/printf.c
arch/x86/boot/string.c
arch/x86/boot/tty.c
arch/x86/configs/i386_defconfig
arch/x86/configs/x86_64_defconfig
arch/x86/include/asm/acpi.h
arch/x86/include/asm/alternative.h
arch/x86/include/asm/apb_timer.h
arch/x86/include/asm/bootparam.h
arch/x86/include/asm/cmpxchg_32.h
arch/x86/include/asm/cmpxchg_64.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/hw_breakpoint.h
arch/x86/include/asm/hypervisor.h
arch/x86/include/asm/i387.h
arch/x86/include/asm/irq_vectors.h
arch/x86/include/asm/kgdb.h
arch/x86/include/asm/local64.h [new file with mode: 0644]
arch/x86/include/asm/mce.h
arch/x86/include/asm/mrst.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/msr.h
arch/x86/include/asm/nmi.h
arch/x86/include/asm/olpc_ofw.h [new file with mode: 0644]
arch/x86/include/asm/pci_x86.h
arch/x86/include/asm/perf_event.h
arch/x86/include/asm/perf_event_p4.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/required-features.h
arch/x86/include/asm/rwsem.h
arch/x86/include/asm/setup.h
arch/x86/include/asm/stacktrace.h
arch/x86/include/asm/xen/hypercall.h
arch/x86/include/asm/xsave.h
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/realmode/wakeup.S
arch/x86/kernel/alternative.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/apb_timer.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/apic/Makefile
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/hw_nmi.c [new file with mode: 0644]
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/nmi.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/hypervisor.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mcheck/mce_intel.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/mshyperv.c
arch/x86/kernel/cpu/mtrr/cleanup.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event_p4.c
arch/x86/kernel/cpu/scattered.c [new file with mode: 0644]
arch/x86/kernel/cpu/topology.c [moved from arch/x86/kernel/cpu/addon_cpuid_features.c with 66% similarity]
arch/x86/kernel/cpu/vmware.c
arch/x86/kernel/dumpstack.c
arch/x86/kernel/dumpstack.h [deleted file]
arch/x86/kernel/dumpstack_32.c
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_64.S
arch/x86/kernel/head_32.S
arch/x86/kernel/head_64.S
arch/x86/kernel/hpet.c
arch/x86/kernel/hw_breakpoint.c
arch/x86/kernel/i387.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/kprobes.c
arch/x86/kernel/mrst.c
arch/x86/kernel/olpc.c
arch/x86/kernel/olpc_ofw.c [new file with mode: 0644]
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/stacktrace.c
arch/x86/kernel/traps.c
arch/x86/kernel/tsc.c
arch/x86/kernel/verify_cpu_64.S
arch/x86/kernel/vsyscall_64.c
arch/x86/kernel/xsave.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/Makefile
arch/x86/lib/clear_page_64.S
arch/x86/lib/cmpxchg.c [moved from arch/x86/kernel/cpu/cmpxchg.c with 75% similarity]
arch/x86/lib/copy_page_64.S
arch/x86/lib/copy_user_64.S
arch/x86/lib/memcpy_64.S
arch/x86/lib/memset_64.S
arch/x86/mm/dump_pagetables.c
arch/x86/mm/ioremap.c
arch/x86/mm/kmmio.c
arch/x86/mm/pat.c
arch/x86/mm/pf_in.c
arch/x86/mm/testmmiotrace.c
arch/x86/mm/tlb.c
arch/x86/oprofile/nmi_int.c
arch/x86/pci/acpi.c
arch/x86/pci/common.c
arch/x86/pci/irq.c
arch/x86/pci/legacy.c
arch/x86/vdso/Makefile
arch/x86/vdso/checkundef.sh [new file with mode: 0755]
arch/x86/vdso/vdso32-setup.c
arch/x86/vdso/vma.c
arch/x86/xen/Kconfig
arch/x86/xen/Makefile
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/mmu.h
arch/x86/xen/platform-pci-unplug.c [new file with mode: 0644]
arch/x86/xen/setup.c
arch/x86/xen/smp.c
arch/x86/xen/suspend.c
arch/x86/xen/time.c
arch/x86/xen/xen-ops.h
arch/xtensa/Kconfig
arch/xtensa/include/asm/local64.h [new file with mode: 0644]
drivers/Makefile
drivers/acpi/acpi_pad.c
drivers/acpi/osl.c
drivers/acpi/pci_root.c
drivers/acpi/processor_idle.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/ahci_platform.c
drivers/ata/ata_generic.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/libata.h
drivers/ata/pata_pcmcia.c
drivers/ata/pata_samsung_cf.c [new file with mode: 0644]
drivers/ata/pata_scc.c
drivers/ata/sata_dwc_460ex.c [new file with mode: 0644]
drivers/ata/sata_fsl.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/atm/fore200e.c
drivers/base/bus.c
drivers/base/core.c
drivers/base/dd.c
drivers/base/dma-coherent.c
drivers/base/firmware_class.c
drivers/base/platform.c
drivers/block/virtio_blk.c
drivers/block/xen-blkfront.c
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/dtl1_cs.c
drivers/char/agp/efficeon-agp.c
drivers/char/agp/intel-agp.c
drivers/char/agp/intel-agp.h
drivers/char/agp/intel-gtt.c
drivers/char/bsr.c
drivers/char/hw_random/n2-drv.c
drivers/char/mem.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/pcmcia/ipwireless/main.c
drivers/char/pcmcia/ipwireless/main.h
drivers/char/pcmcia/ipwireless/tty.h
drivers/char/pcmcia/synclink_cs.c
drivers/char/tty_io.c
drivers/char/vt.c
drivers/clocksource/acpi_pm.c
drivers/crypto/n2_core.c
drivers/firmware/dcdbas.c
drivers/firmware/dmi-id.c
drivers/firmware/dmi_scan.c
drivers/gpio/gpiolib.c
drivers/gpio/xilinx_gpio.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/Makefile
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_encoder_slave.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_global.c [moved from drivers/gpu/drm/ttm/ttm_global.c with 79% similarity]
drivers/gpu/drm/drm_info.c
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_platform.c [new file with mode: 0644]
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_trace.h [new file with mode: 0644]
drivers/gpu/drm/drm_trace_points.c [new file with mode: 0644]
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/i2c/Makefile
drivers/gpu/drm/i2c/ch7006_drv.c
drivers/gpu/drm/i2c/ch7006_priv.h
drivers/gpu/drm/i2c/sil164_drv.c [new file with mode: 0644]
drivers/gpu/drm/i810/i810_dma.c
drivers/gpu/drm/i810/i810_drv.c
drivers/gpu/drm/i810/i810_drv.h
drivers/gpu/drm/i830/i830_dma.c
drivers/gpu/drm/i830/i830_drv.c
drivers/gpu/drm/i830/i830_drv.h
drivers/gpu/drm/i830/i830_irq.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/i915_trace.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/mga/mga_dma.c
drivers/gpu/drm/mga/mga_drv.c
drivers/gpu/drm/mga/mga_drv.h
drivers/gpu/drm/mga/mga_irq.c
drivers/gpu/drm/mga/mga_state.c
drivers/gpu/drm/mga/mga_warp.c
drivers/gpu/drm/nouveau/Kconfig
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bios.h
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_calc.c
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.h
drivers/gpu/drm/nouveau/nouveau_dma.c
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_encoder.h
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_grctx.c [deleted file]
drivers/gpu/drm/nouveau/nouveau_i2c.c
drivers/gpu/drm/nouveau/nouveau_i2c.h
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_notifier.c
drivers/gpu/drm/nouveau/nouveau_object.c
drivers/gpu/drm/nouveau/nouveau_reg.h
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nouveau_ttm.c
drivers/gpu/drm/nouveau/nv04_crtc.c
drivers/gpu/drm/nouveau/nv04_dac.c
drivers/gpu/drm/nouveau/nv04_dfp.c
drivers/gpu/drm/nouveau/nv04_display.c
drivers/gpu/drm/nouveau/nv04_fifo.c
drivers/gpu/drm/nouveau/nv04_graph.c
drivers/gpu/drm/nouveau/nv04_instmem.c
drivers/gpu/drm/nouveau/nv04_mc.c
drivers/gpu/drm/nouveau/nv04_tv.c
drivers/gpu/drm/nouveau/nv10_fifo.c
drivers/gpu/drm/nouveau/nv10_gpio.c [moved from drivers/gpu/drm/nouveau/nv17_gpio.c with 95% similarity]
drivers/gpu/drm/nouveau/nv17_tv.c
drivers/gpu/drm/nouveau/nv20_graph.c
drivers/gpu/drm/nouveau/nv30_fb.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nv40_fifo.c
drivers/gpu/drm/nouveau/nv40_graph.c
drivers/gpu/drm/nouveau/nv40_mc.c
drivers/gpu/drm/nouveau/nv50_crtc.c
drivers/gpu/drm/nouveau/nv50_dac.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_display.h
drivers/gpu/drm/nouveau/nv50_fifo.c
drivers/gpu/drm/nouveau/nv50_gpio.c
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_instmem.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/nouveau/nvreg.h
drivers/gpu/drm/r128/r128_cce.c
drivers/gpu/drm/r128/r128_drv.c
drivers/gpu/drm/r128/r128_drv.h
drivers/gpu/drm/r128/r128_irq.c
drivers/gpu/drm/r128/r128_state.c
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atom.h
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100d.h
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300d.h
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r500_reg.h
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_audio.c
drivers/gpu/drm/radeon/r600_blit_shaders.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_acpi.c [new file with mode: 0644]
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_legacy_tv.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/reg_srcs/r300
drivers/gpu/drm/radeon/reg_srcs/r420
drivers/gpu/drm/radeon/reg_srcs/rs600
drivers/gpu/drm/radeon/reg_srcs/rv515
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/rv770d.h
drivers/gpu/drm/savage/savage_bci.c
drivers/gpu/drm/sis/sis_drv.c
drivers/gpu/drm/sis/sis_mm.c
drivers/gpu/drm/ttm/Makefile
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_util.c
drivers/gpu/drm/ttm/ttm_module.c
drivers/gpu/drm/via/via_dma.c
drivers/gpu/drm/via/via_dmablit.c
drivers/gpu/drm/via/via_dmablit.h
drivers/gpu/drm/via/via_drv.h
drivers/gpu/drm/via/via_irq.c
drivers/gpu/drm/via/via_map.c
drivers/gpu/drm/via/via_mm.c
drivers/gpu/drm/via/via_verifier.c
drivers/gpu/drm/via/via_verifier.h
drivers/gpu/drm/via/via_video.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/pkgtemp.c [new file with mode: 0644]
drivers/hwmon/ultra45_env.c
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/i2c-core.c
drivers/ide/ide-cs.c
drivers/input/misc/ixp4xx-beeper.c
drivers/input/misc/sparcspkr.c
drivers/input/serio/i8042-sparcio.h
drivers/input/xen-kbdfront.c
drivers/isdn/hardware/avm/avm_cs.c
drivers/isdn/hisax/avma1_cs.c
drivers/isdn/hisax/elsa_cs.c
drivers/isdn/hisax/sedlbauer_cs.c
drivers/isdn/hisax/teles_cs.c
drivers/leds/leds-bd2802.c
drivers/macintosh/macio_sysfs.c
drivers/macintosh/via-pmu.c
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-driver.h
drivers/media/video/ivtv/ivtv-irq.c
drivers/media/video/ivtv/ivtv-irq.h
drivers/misc/Kconfig
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/sdricoh_cs.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/maps/sun_uflash.c
drivers/net/e1000e/netdev.c
drivers/net/fsl_pq_mdio.c
drivers/net/ibm_newemac/core.c
drivers/net/myri_sbus.c
drivers/net/niu.c
drivers/net/niu.h
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/com20020_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/ibmtr_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/r8169.c
drivers/net/sunbmac.c
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/sunqe.c
drivers/net/wireless/airo_cs.c
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/b43/pcmcia.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/net/wireless/orinoco/spectrum_cs.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/wl3501_cs.c
drivers/net/xilinx_emaclite.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/of/address.c [new file with mode: 0644]
drivers/of/base.c
drivers/of/device.c
drivers/of/fdt.c
drivers/of/gpio.c
drivers/of/irq.c [new file with mode: 0644]
drivers/of/of_i2c.c
drivers/of/of_mdio.c
drivers/of/of_spi.c
drivers/of/platform.c
drivers/oprofile/event_buffer.c
drivers/parport/parport_cs.c
drivers/parport/parport_sunbpp.c
drivers/pci/Makefile
drivers/pci/bus.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/pciehp_pci.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/hotplug/shpchp_pci.c
drivers/pci/intel-iommu.c
drivers/pci/intr_remapping.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-label.c [new file with mode: 0644]
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/Kconfig
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/pcie/aspm.c
drivers/pci/probe.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/pci/search.c
drivers/pci/setup-bus.c
drivers/pci/setup-irq.c
drivers/pcmcia/Makefile
drivers/pcmcia/au1000_generic.h
drivers/pcmcia/au1000_pb1x00.c
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs.c
drivers/pcmcia/cs_internal.h
drivers/pcmcia/db1xxx_ss.c
drivers/pcmcia/ds.c
drivers/pcmcia/i82092.c
drivers/pcmcia/i82365.c
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/pcmcia/pcmcia_cis.c
drivers/pcmcia/pcmcia_ioctl.c [deleted file]
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/rsrc_iodyn.c
drivers/pcmcia/rsrc_mgr.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/soc_common.h
drivers/pcmcia/socket_sysfs.c
drivers/pcmcia/tcic.c
drivers/pcmcia/xxs1500_ss.c
drivers/pcmcia/yenta_socket.c
drivers/regulator/core.c
drivers/sbus/char/bbc_i2c.c
drivers/sbus/char/display7seg.c
drivers/sbus/char/envctrl.c
drivers/sbus/char/flash.c
drivers/sbus/char/uctrl.c
drivers/scsi/arcmsr/arcmsr_attr.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/pcmcia/aha152x_stub.c
drivers/scsi/pcmcia/fdomain_stub.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/qlogic_stub.c
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/qlogicpti.c
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_sysfs.c
drivers/scsi/sun_esp.c
drivers/serial/kgdboc.c
drivers/serial/serial_cs.c
drivers/serial/sunhv.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/serial/uartlite.c
drivers/spi/mpc512x_psc_spi.c
drivers/spi/mpc52xx_psc_spi.c
drivers/spi/mpc52xx_spi.c
drivers/spi/spi.c
drivers/spi/spi_mpc8xxx.c
drivers/spi/spi_ppc4xx.c
drivers/spi/xilinx_spi.c
drivers/spi/xilinx_spi_of.c
drivers/ssb/main.c
drivers/ssb/pcmcia.c
drivers/ssb/scan.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/adis16255/adis16255.c
drivers/staging/batman-adv/CHANGELOG
drivers/staging/batman-adv/Kconfig
drivers/staging/batman-adv/Makefile
drivers/staging/batman-adv/README
drivers/staging/batman-adv/TODO
drivers/staging/batman-adv/aggregation.c
drivers/staging/batman-adv/aggregation.h
drivers/staging/batman-adv/bat_debugfs.c [new file with mode: 0644]
drivers/staging/batman-adv/bat_debugfs.h [new file with mode: 0644]
drivers/staging/batman-adv/bat_sysfs.c
drivers/staging/batman-adv/bat_sysfs.h
drivers/staging/batman-adv/bitarray.c
drivers/staging/batman-adv/bitarray.h
drivers/staging/batman-adv/device.c [deleted file]
drivers/staging/batman-adv/hard-interface.c
drivers/staging/batman-adv/hard-interface.h
drivers/staging/batman-adv/hash.c
drivers/staging/batman-adv/hash.h
drivers/staging/batman-adv/icmp_socket.c [new file with mode: 0644]
drivers/staging/batman-adv/icmp_socket.h [moved from drivers/staging/batman-adv/device.h with 54% similarity]
drivers/staging/batman-adv/main.c
drivers/staging/batman-adv/main.h
drivers/staging/batman-adv/originator.c
drivers/staging/batman-adv/originator.h
drivers/staging/batman-adv/packet.h
drivers/staging/batman-adv/ring_buffer.h
drivers/staging/batman-adv/routing.c
drivers/staging/batman-adv/routing.h
drivers/staging/batman-adv/send.c
drivers/staging/batman-adv/send.h
drivers/staging/batman-adv/soft-interface.c
drivers/staging/batman-adv/soft-interface.h
drivers/staging/batman-adv/sysfs-class-net-batman-adv [new file with mode: 0644]
drivers/staging/batman-adv/sysfs-class-net-mesh [new file with mode: 0644]
drivers/staging/batman-adv/translation-table.c
drivers/staging/batman-adv/translation-table.h
drivers/staging/batman-adv/types.h
drivers/staging/batman-adv/vis.c
drivers/staging/batman-adv/vis.h
drivers/staging/comedi/TODO
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/comedidev.h
drivers/staging/comedi/drivers/8255.c
drivers/staging/comedi/drivers/acl7225b.c
drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
drivers/staging/comedi/drivers/addi-data/addi_common.c
drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
drivers/staging/comedi/drivers/addi_apci_035.c
drivers/staging/comedi/drivers/addi_apci_1032.c
drivers/staging/comedi/drivers/addi_apci_1500.c
drivers/staging/comedi/drivers/addi_apci_1516.c
drivers/staging/comedi/drivers/addi_apci_1564.c
drivers/staging/comedi/drivers/addi_apci_16xx.c
drivers/staging/comedi/drivers/addi_apci_2016.c
drivers/staging/comedi/drivers/addi_apci_2032.c
drivers/staging/comedi/drivers/addi_apci_2200.c
drivers/staging/comedi/drivers/addi_apci_3001.c
drivers/staging/comedi/drivers/addi_apci_3120.c
drivers/staging/comedi/drivers/addi_apci_3501.c
drivers/staging/comedi/drivers/addi_apci_3xxx.c
drivers/staging/comedi/drivers/adl_pci6208.c
drivers/staging/comedi/drivers/adl_pci7230.c
drivers/staging/comedi/drivers/adl_pci7296.c
drivers/staging/comedi/drivers/adl_pci7432.c
drivers/staging/comedi/drivers/adl_pci8164.c
drivers/staging/comedi/drivers/adl_pci9111.c
drivers/staging/comedi/drivers/adl_pci9118.c
drivers/staging/comedi/drivers/adq12b.c
drivers/staging/comedi/drivers/adv_pci1710.c
drivers/staging/comedi/drivers/adv_pci1723.c
drivers/staging/comedi/drivers/adv_pci_dio.c
drivers/staging/comedi/drivers/aio_aio12_8.c
drivers/staging/comedi/drivers/aio_iiro_16.c
drivers/staging/comedi/drivers/am9513.h
drivers/staging/comedi/drivers/amplc_dio200.c
drivers/staging/comedi/drivers/amplc_pc236.c
drivers/staging/comedi/drivers/amplc_pc263.c
drivers/staging/comedi/drivers/amplc_pci224.c
drivers/staging/comedi/drivers/amplc_pci230.c
drivers/staging/comedi/drivers/c6xdigio.c
drivers/staging/comedi/drivers/cb_das16_cs.c
drivers/staging/comedi/drivers/cb_pcidas.c
drivers/staging/comedi/drivers/cb_pcidas64.c
drivers/staging/comedi/drivers/cb_pcidda.c
drivers/staging/comedi/drivers/cb_pcidio.c
drivers/staging/comedi/drivers/cb_pcimdas.c
drivers/staging/comedi/drivers/cb_pcimdda.c
drivers/staging/comedi/drivers/comedi_bond.c
drivers/staging/comedi/drivers/comedi_parport.c
drivers/staging/comedi/drivers/comedi_test.c
drivers/staging/comedi/drivers/contec_pci_dio.c
drivers/staging/comedi/drivers/daqboard2000.c
drivers/staging/comedi/drivers/das08.c
drivers/staging/comedi/drivers/das08_cs.c
drivers/staging/comedi/drivers/das16.c
drivers/staging/comedi/drivers/das16m1.c
drivers/staging/comedi/drivers/das1800.c
drivers/staging/comedi/drivers/das6402.c
drivers/staging/comedi/drivers/das800.c
drivers/staging/comedi/drivers/dmm32at.c
drivers/staging/comedi/drivers/dt2801.c
drivers/staging/comedi/drivers/dt2811.c
drivers/staging/comedi/drivers/dt2814.c
drivers/staging/comedi/drivers/dt2815.c
drivers/staging/comedi/drivers/dt2817.c
drivers/staging/comedi/drivers/dt282x.c
drivers/staging/comedi/drivers/dt3000.c
drivers/staging/comedi/drivers/dt9812.c
drivers/staging/comedi/drivers/fl512.c
drivers/staging/comedi/drivers/gsc_hpdi.c
drivers/staging/comedi/drivers/icp_multi.c
drivers/staging/comedi/drivers/icp_multi.h
drivers/staging/comedi/drivers/ii_pci20kc.c
drivers/staging/comedi/drivers/jr3_pci.c
drivers/staging/comedi/drivers/ke_counter.c
drivers/staging/comedi/drivers/me4000.c
drivers/staging/comedi/drivers/me_daq.c
drivers/staging/comedi/drivers/mite.c
drivers/staging/comedi/drivers/mpc624.c
drivers/staging/comedi/drivers/mpc8260cpm.c
drivers/staging/comedi/drivers/multiq3.c
drivers/staging/comedi/drivers/ni_6527.c
drivers/staging/comedi/drivers/ni_65xx.c
drivers/staging/comedi/drivers/ni_660x.c
drivers/staging/comedi/drivers/ni_670x.c
drivers/staging/comedi/drivers/ni_at_a2150.c
drivers/staging/comedi/drivers/ni_at_ao.c
drivers/staging/comedi/drivers/ni_atmio.c
drivers/staging/comedi/drivers/ni_atmio16d.c
drivers/staging/comedi/drivers/ni_daq_700.c
drivers/staging/comedi/drivers/ni_daq_dio24.c
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/comedi/drivers/ni_labpc_cs.c
drivers/staging/comedi/drivers/ni_mio_cs.c
drivers/staging/comedi/drivers/ni_pcidio.c
drivers/staging/comedi/drivers/ni_pcimio.c
drivers/staging/comedi/drivers/ni_tio.c
drivers/staging/comedi/drivers/pcl711.c
drivers/staging/comedi/drivers/pcl724.c
drivers/staging/comedi/drivers/pcl725.c
drivers/staging/comedi/drivers/pcl726.c
drivers/staging/comedi/drivers/pcl730.c
drivers/staging/comedi/drivers/pcl812.c
drivers/staging/comedi/drivers/pcl816.c
drivers/staging/comedi/drivers/pcl818.c
drivers/staging/comedi/drivers/pcm3724.c
drivers/staging/comedi/drivers/pcm3730.c
drivers/staging/comedi/drivers/pcm_common.c
drivers/staging/comedi/drivers/pcmad.c
drivers/staging/comedi/drivers/pcmda12.c
drivers/staging/comedi/drivers/pcmmio.c
drivers/staging/comedi/drivers/pcmuio.c
drivers/staging/comedi/drivers/poc.c
drivers/staging/comedi/drivers/quatech_daqp_cs.c
drivers/staging/comedi/drivers/rtd520.c
drivers/staging/comedi/drivers/rti800.c
drivers/staging/comedi/drivers/rti802.c
drivers/staging/comedi/drivers/s526.c
drivers/staging/comedi/drivers/s626.c
drivers/staging/comedi/drivers/s626.h
drivers/staging/comedi/drivers/serial2002.c
drivers/staging/comedi/drivers/skel.c
drivers/staging/comedi/drivers/ssv_dnp.c
drivers/staging/comedi/drivers/unioxx5.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxfast.c
drivers/staging/comedi/kcomedilib/kcomedilib_main.c
drivers/staging/crystalhd/crystalhd_lnx.c
drivers/staging/cx25821/cx25821-alsa.c
drivers/staging/cxt1e1/functions.c
drivers/staging/cxt1e1/hwprobe.c
drivers/staging/cxt1e1/linux.c
drivers/staging/cxt1e1/musycc.c
drivers/staging/cxt1e1/pmc93x6_eeprom.c
drivers/staging/cxt1e1/pmcc4.h
drivers/staging/cxt1e1/pmcc4_drv.c
drivers/staging/cxt1e1/sbecom_inline_linux.h
drivers/staging/dream/camera/msm_vfe8x.c
drivers/staging/dream/pmem.c
drivers/staging/dt3155/Kconfig [deleted file]
drivers/staging/dt3155/Makefile [deleted file]
drivers/staging/dt3155/TODO [deleted file]
drivers/staging/dt3155/allocator.README [deleted file]
drivers/staging/dt3155/allocator.c [deleted file]
drivers/staging/dt3155/allocator.h [deleted file]
drivers/staging/dt3155/dt3155.h [deleted file]
drivers/staging/dt3155/dt3155.sysvinit [deleted file]
drivers/staging/dt3155/dt3155_drv.c [deleted file]
drivers/staging/dt3155/dt3155_drv.h [deleted file]
drivers/staging/dt3155/dt3155_io.c [deleted file]
drivers/staging/dt3155/dt3155_io.h [deleted file]
drivers/staging/dt3155/dt3155_isr.c [deleted file]
drivers/staging/dt3155/dt3155_isr.h [deleted file]
drivers/staging/dt3155v4l/dt3155v4l.c
drivers/staging/easycap/Kconfig [new file with mode: 0644]
drivers/staging/easycap/Makefile [new file with mode: 0644]
drivers/staging/easycap/README [new file with mode: 0644]
drivers/staging/easycap/easycap.h [new file with mode: 0644]
drivers/staging/easycap/easycap_debug.h [new file with mode: 0644]
drivers/staging/easycap/easycap_ioctl.c [new file with mode: 0644]
drivers/staging/easycap/easycap_ioctl.h [new file with mode: 0644]
drivers/staging/easycap/easycap_low.c [new file with mode: 0644]
drivers/staging/easycap/easycap_main.c [new file with mode: 0644]
drivers/staging/easycap/easycap_settings.c [new file with mode: 0644]
drivers/staging/easycap/easycap_sound.c [new file with mode: 0644]
drivers/staging/easycap/easycap_sound.h [new file with mode: 0644]
drivers/staging/easycap/easycap_standard.h [new file with mode: 0644]
drivers/staging/easycap/easycap_testcard.c [new file with mode: 0644]
drivers/staging/et131x/et1310_phy.c
drivers/staging/hv/Kconfig
drivers/staging/hv/Makefile
drivers/staging/hv/blkvsc.c
drivers/staging/hv/blkvsc_drv.c
drivers/staging/hv/channel.c
drivers/staging/hv/channel_mgmt.c
drivers/staging/hv/channel_mgmt.h
drivers/staging/hv/connection.c
drivers/staging/hv/hv.c
drivers/staging/hv/hv_timesource.c [new file with mode: 0644]
drivers/staging/hv/hv_utils.c
drivers/staging/hv/logging.h
drivers/staging/hv/netvsc.c
drivers/staging/hv/netvsc_drv.c
drivers/staging/hv/ring_buffer.c
drivers/staging/hv/ring_buffer.h
drivers/staging/hv/rndis_filter.c
drivers/staging/hv/storvsc.c
drivers/staging/hv/storvsc_drv.c
drivers/staging/hv/vmbus.c
drivers/staging/hv/vmbus_drv.c
drivers/staging/iio/Documentation/overview.txt
drivers/staging/iio/Kconfig
drivers/staging/iio/Makefile
drivers/staging/iio/TODO
drivers/staging/iio/accel/Kconfig
drivers/staging/iio/accel/Makefile
drivers/staging/iio/accel/adis16209.h
drivers/staging/iio/accel/adis16209_core.c
drivers/staging/iio/accel/adis16209_ring.c
drivers/staging/iio/accel/adis16209_trigger.c
drivers/staging/iio/accel/adis16220.h
drivers/staging/iio/accel/adis16220_core.c
drivers/staging/iio/accel/adis16240.h
drivers/staging/iio/accel/adis16240_core.c
drivers/staging/iio/accel/adis16240_ring.c
drivers/staging/iio/accel/adis16240_trigger.c
drivers/staging/iio/accel/kxsd9.c
drivers/staging/iio/accel/lis3l02dq.h
drivers/staging/iio/accel/lis3l02dq_core.c
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/accel/sca3000.h
drivers/staging/iio/accel/sca3000_core.c
drivers/staging/iio/adc/Makefile
drivers/staging/iio/adc/adc.h
drivers/staging/iio/adc/max1363.h
drivers/staging/iio/adc/max1363_core.c
drivers/staging/iio/adc/max1363_ring.c
drivers/staging/iio/chrdev.h
drivers/staging/iio/gyro/Makefile
drivers/staging/iio/gyro/adis16260.h
drivers/staging/iio/gyro/adis16260_core.c
drivers/staging/iio/gyro/adis16260_ring.c
drivers/staging/iio/gyro/adis16260_trigger.c
drivers/staging/iio/iio.h
drivers/staging/iio/imu/Kconfig
drivers/staging/iio/imu/Makefile
drivers/staging/iio/imu/adis16300.h
drivers/staging/iio/imu/adis16300_core.c
drivers/staging/iio/imu/adis16300_ring.c
drivers/staging/iio/imu/adis16300_trigger.c
drivers/staging/iio/imu/adis16350.h
drivers/staging/iio/imu/adis16350_core.c
drivers/staging/iio/imu/adis16350_ring.c
drivers/staging/iio/imu/adis16350_trigger.c
drivers/staging/iio/imu/adis16400.h
drivers/staging/iio/imu/adis16400_core.c
drivers/staging/iio/imu/adis16400_ring.c
drivers/staging/iio/imu/adis16400_trigger.c
drivers/staging/iio/industrialio-core.c
drivers/staging/iio/industrialio-ring.c
drivers/staging/iio/industrialio-trigger.c
drivers/staging/iio/light/Kconfig
drivers/staging/iio/light/light.h
drivers/staging/iio/light/tsl2563.c
drivers/staging/iio/magnetometer/Kconfig [new file with mode: 0644]
drivers/staging/iio/magnetometer/Makefile [new file with mode: 0644]
drivers/staging/iio/magnetometer/hmc5843.c [new file with mode: 0644]
drivers/staging/iio/ring_generic.h
drivers/staging/iio/ring_sw.c
drivers/staging/iio/ring_sw.h
drivers/staging/iio/sysfs.h
drivers/staging/iio/trigger.h
drivers/staging/iio/trigger/Makefile
drivers/staging/iio/trigger/iio-trig-gpio.c
drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
drivers/staging/line6/Kconfig
drivers/staging/line6/driver.c
drivers/staging/memrar/TODO
drivers/staging/memrar/memrar-abi
drivers/staging/memrar/memrar_handler.c
drivers/staging/msm/Kconfig
drivers/staging/msm/Makefile
drivers/staging/msm/lcdc_grapefruit.c [deleted file]
drivers/staging/msm/lcdc_st1_wxga.c [deleted file]
drivers/staging/msm/lcdc_wxga.c [deleted file]
drivers/staging/msm/mddi_toshiba_wvga.c [deleted file]
drivers/staging/msm/mddihost.h
drivers/staging/msm/mdp4_debugfs.c
drivers/staging/msm/mdp4_overlay.c
drivers/staging/msm/msm_fb_def.h
drivers/staging/msm/staging-devices.c
drivers/staging/octeon/cvmx-cmd-queue.c
drivers/staging/octeon/cvmx-fau.h
drivers/staging/octeon/ethernet-spi.c
drivers/staging/otus/80211core/ctxrx.c
drivers/staging/otus/TODO
drivers/staging/otus/apdbg.c
drivers/staging/otus/hal/hpani.c
drivers/staging/otus/hal/hpmain.c
drivers/staging/otus/hal/hpreg.c
drivers/staging/otus/ioctl.c
drivers/staging/otus/wrap_sec.c
drivers/staging/otus/wrap_usb.c
drivers/staging/otus/wwrap.c
drivers/staging/otus/zdusb.c
drivers/staging/panel/panel.c
drivers/staging/pohmelfs/inode.c
drivers/staging/quatech_usb2/quatech_usb2.c
drivers/staging/quickstart/Kconfig [new file with mode: 0644]
drivers/staging/quickstart/Makefile [new file with mode: 0644]
drivers/staging/quickstart/quickstart.c [new file with mode: 0644]
drivers/staging/ramzswap/Kconfig [deleted file]
drivers/staging/ramzswap/Makefile [deleted file]
drivers/staging/ramzswap/ramzswap.txt [deleted file]
drivers/staging/ramzswap/ramzswap_drv.c [deleted file]
drivers/staging/rt2860/ap.h
drivers/staging/rt2860/chlist.h
drivers/staging/rt2860/common/cmm_wpa.c
drivers/staging/rt2860/common/rtmp_timer.c
drivers/staging/rt2860/mlme.h
drivers/staging/rt2860/rt_linux.c
drivers/staging/rt2860/rtmp.h
drivers/staging/rt2860/usb_main_dev.c
drivers/staging/rt3070/md4.h [deleted file]
drivers/staging/rtl8187se/Kconfig
drivers/staging/rtl8192e/Kconfig
drivers/staging/rtl8192e/ieee80211/dot11d.c
drivers/staging/rtl8192e/ieee80211/ieee80211.h
drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h
drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c
drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
drivers/staging/rtl8192e/r8190_rtl8256.c
drivers/staging/rtl8192e/r8192E.h
drivers/staging/rtl8192e/r8192E_core.c
drivers/staging/rtl8192e/r8192E_dm.c
drivers/staging/rtl8192e/r8192E_wx.c
drivers/staging/rtl8192e/r819xE_phy.c
drivers/staging/rtl8192su/Kconfig
drivers/staging/rtl8192su/TODO
drivers/staging/rtl8192su/ieee80211/dot11d.c
drivers/staging/rtl8192su/ieee80211/dot11d.h
drivers/staging/rtl8192su/ieee80211/ieee80211.h
drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h
drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c
drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h
drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192su/ieee80211/rtl819x_BA.h
drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h
drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h
drivers/staging/rtl8192su/ieee80211/rtl819x_TS.h
drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
drivers/staging/rtl8192su/r8192SU_HWImg.c
drivers/staging/rtl8192su/r8192SU_HWImg.h
drivers/staging/rtl8192su/r8192SU_led.c
drivers/staging/rtl8192su/r8192S_Efuse.c
drivers/staging/rtl8192su/r8192S_Efuse.h
drivers/staging/rtl8192su/r8192S_firmware.c
drivers/staging/rtl8192su/r8192S_firmware.h
drivers/staging/rtl8192su/r8192S_hw.h
drivers/staging/rtl8192su/r8192S_phy.c
drivers/staging/rtl8192su/r8192U.h
drivers/staging/rtl8192su/r8192U_core.c
drivers/staging/rtl8192su/r8192U_dm.c
drivers/staging/rtl8192su/r8192U_wx.c
drivers/staging/rtl8192su/r819xU_cmdpkt.c
drivers/staging/rtl8192su/r819xU_cmdpkt.h
drivers/staging/rtl8192u/Kconfig
drivers/staging/rtl8192u/dot11d.h
drivers/staging/rtl8192u/ieee80211.h [deleted file]
drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192u/r8192U.h
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rtl8192u/r8192U_wx.h
drivers/staging/rtl8192u/r819xU_firmware.c
drivers/staging/sep/sep_driver_api.h
drivers/staging/slicoss/slic.h
drivers/staging/slicoss/slicoss.c
drivers/staging/sm7xx/smtcfb.c
drivers/staging/solo6x10/Kconfig [new file with mode: 0644]
drivers/staging/solo6x10/Makefile [new file with mode: 0644]
drivers/staging/solo6x10/TODO [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-core.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-disp.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-enc.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-g723.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-gpio.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-i2c.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-jpeg.h [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-offsets.h [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-osd-font.h [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-p2m.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-registers.h [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-tw28.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-tw28.h [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-v4l2-enc.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010-v4l2.c [new file with mode: 0644]
drivers/staging/solo6x10/solo6010.h [new file with mode: 0644]
drivers/staging/spectra/Kconfig [new file with mode: 0644]
drivers/staging/spectra/Makefile [new file with mode: 0644]
drivers/staging/spectra/README [new file with mode: 0644]
drivers/staging/spectra/ffsdefs.h [new file with mode: 0644]
drivers/staging/spectra/ffsport.c [new file with mode: 0644]
drivers/staging/spectra/ffsport.h [new file with mode: 0644]
drivers/staging/spectra/flash.c [new file with mode: 0644]
drivers/staging/spectra/flash.h [new file with mode: 0644]
drivers/staging/spectra/lld.c [new file with mode: 0644]
drivers/staging/spectra/lld.h [new file with mode: 0644]
drivers/staging/spectra/lld_cdma.c [new file with mode: 0644]
drivers/staging/spectra/lld_cdma.h [new file with mode: 0644]
drivers/staging/spectra/lld_emu.c [new file with mode: 0644]
drivers/staging/spectra/lld_emu.h [new file with mode: 0644]
drivers/staging/spectra/lld_mtd.c [new file with mode: 0644]
drivers/staging/spectra/lld_mtd.h [new file with mode: 0644]
drivers/staging/spectra/lld_nand.c [new file with mode: 0644]
drivers/staging/spectra/lld_nand.h [new file with mode: 0644]
drivers/staging/spectra/nand_regs.h [new file with mode: 0644]
drivers/staging/spectra/spectraswconfig.h [new file with mode: 0644]
drivers/staging/ti-st/Kconfig
drivers/staging/ti-st/TODO
drivers/staging/ti-st/bt_drv.c
drivers/staging/ti-st/st.h
drivers/staging/ti-st/st_core.c
drivers/staging/ti-st/st_core.h
drivers/staging/ti-st/st_kim.c
drivers/staging/ti-st/st_kim.h
drivers/staging/ti-st/st_ll.c
drivers/staging/ti-st/st_ll.h
drivers/staging/ti-st/sysfs-uim
drivers/staging/tidspbridge/Documentation/CONTRIBUTORS [new file with mode: 0644]
drivers/staging/tidspbridge/Documentation/README [new file with mode: 0644]
drivers/staging/tidspbridge/Documentation/error-codes [new file with mode: 0644]
drivers/staging/tidspbridge/Kconfig [new file with mode: 0644]
drivers/staging/tidspbridge/Makefile [new file with mode: 0644]
drivers/staging/tidspbridge/TODO [new file with mode: 0644]
drivers/staging/tidspbridge/core/_cmm.h [new file with mode: 0644]
drivers/staging/tidspbridge/core/_deh.h [new file with mode: 0644]
drivers/staging/tidspbridge/core/_msg_sm.h [new file with mode: 0644]
drivers/staging/tidspbridge/core/_tiomap.h [new file with mode: 0644]
drivers/staging/tidspbridge/core/_tiomap_pwr.h [new file with mode: 0644]
drivers/staging/tidspbridge/core/chnl_sm.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/dsp-clock.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/io_sm.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/msg_sm.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/tiomap3430.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/tiomap3430_pwr.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/tiomap_io.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/tiomap_io.h [new file with mode: 0644]
drivers/staging/tidspbridge/core/ue_deh.c [new file with mode: 0644]
drivers/staging/tidspbridge/core/wdt.c [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/cload.c [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/dload_internal.h [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/doff.h [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/getsection.c [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/header.h [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/module_list.h [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/params.h [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/reloc.c [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/reloc_table.h [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/reloc_table_c6000.c [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/tramp.c [new file with mode: 0644]
drivers/staging/tidspbridge/dynload/tramp_table_c6000.c [new file with mode: 0644]
drivers/staging/tidspbridge/gen/gb.c [new file with mode: 0644]
drivers/staging/tidspbridge/gen/gh.c [new file with mode: 0644]
drivers/staging/tidspbridge/gen/gs.c [new file with mode: 0644]
drivers/staging/tidspbridge/gen/uuidutil.c [new file with mode: 0644]
drivers/staging/tidspbridge/hw/EasiGlobal.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/MMUAccInt.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/MMURegAcM.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/hw_defs.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/hw_mmu.c [new file with mode: 0644]
drivers/staging/tidspbridge/hw/hw_mmu.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/brddefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/cfg.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/chnl.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/chnldefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/clk.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/cmm.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/cod.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dbc.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dbdcd.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dbdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dbldefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dbll.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dblldefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dehdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dev.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/devdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/disp.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dispdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dmm.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/drv.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/drvdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspapi.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspchnl.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspdeh.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspdrv.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspio.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspioctl.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dspmsg.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/gb.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/getsection.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/gh.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/gs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/host_os.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/io.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/io_sm.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/iodefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/ldr.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/list.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/memdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/mgr.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/msg.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/msgdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/nldr.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/node.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/nodedefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/nodepriv.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/ntfy.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/proc.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/procpriv.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/pwr.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/rmm.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/rms_sh.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/rmstypes.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/services.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/strm.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/strmdefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/sync.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/utildefs.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/uuidutil.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/wdt.h [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/chnl.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/chnlobj.h [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/cmm.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/cod.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/dbll.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/dev.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/dmm.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/dspapi.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/io.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/ioobj.h [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/msg.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/msgobj.h [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/dbdcd.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/disp.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/drv.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/drv_interface.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/drv_interface.h [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/dspdrv.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/mgr.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/nldr.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/node.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/proc.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/pwr.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/rmm.c [new file with mode: 0644]
drivers/staging/tidspbridge/rmgr/strm.c [new file with mode: 0644]
drivers/staging/tidspbridge/services/cfg.c [new file with mode: 0644]
drivers/staging/tidspbridge/services/ntfy.c [new file with mode: 0644]
drivers/staging/tidspbridge/services/services.c [new file with mode: 0644]
drivers/staging/tidspbridge/services/sync.c [new file with mode: 0644]
drivers/staging/usbip/stub.h
drivers/staging/usbip/stub_dev.c
drivers/staging/usbip/stub_main.c
drivers/staging/usbip/stub_rx.c
drivers/staging/usbip/usbip_common.h
drivers/staging/vme/bridges/vme_ca91cx42.c
drivers/staging/vme/bridges/vme_tsi148.c
drivers/staging/vme/devices/vme_user.c
drivers/staging/vt6655/80211hdr.h
drivers/staging/vt6655/80211mgr.c
drivers/staging/vt6655/80211mgr.h
drivers/staging/vt6655/IEEE11h.c
drivers/staging/vt6655/IEEE11h.h
drivers/staging/vt6655/Makefile
drivers/staging/vt6655/TODO
drivers/staging/vt6655/aes_ccmp.c
drivers/staging/vt6655/aes_ccmp.h
drivers/staging/vt6655/baseband.c
drivers/staging/vt6655/baseband.h
drivers/staging/vt6655/bssdb.c
drivers/staging/vt6655/bssdb.h
drivers/staging/vt6655/card.c
drivers/staging/vt6655/card.h
drivers/staging/vt6655/channel.c [new file with mode: 0644]
drivers/staging/vt6655/channel.h [new file with mode: 0644]
drivers/staging/vt6655/country.h
drivers/staging/vt6655/datarate.c
drivers/staging/vt6655/datarate.h
drivers/staging/vt6655/desc.h
drivers/staging/vt6655/device.h
drivers/staging/vt6655/device_cfg.h
drivers/staging/vt6655/device_main.c
drivers/staging/vt6655/dpc.c
drivers/staging/vt6655/dpc.h
drivers/staging/vt6655/hostap.c
drivers/staging/vt6655/iocmd.h
drivers/staging/vt6655/ioctl.c
drivers/staging/vt6655/ioctl.h
drivers/staging/vt6655/iwctl.c
drivers/staging/vt6655/key.c
drivers/staging/vt6655/key.h
drivers/staging/vt6655/mac.c
drivers/staging/vt6655/mac.h
drivers/staging/vt6655/mib.c
drivers/staging/vt6655/mib.h
drivers/staging/vt6655/michael.c
drivers/staging/vt6655/michael.h
drivers/staging/vt6655/power.c
drivers/staging/vt6655/power.h
drivers/staging/vt6655/rc4.c
drivers/staging/vt6655/rc4.h
drivers/staging/vt6655/rf.c
drivers/staging/vt6655/rf.h
drivers/staging/vt6655/rxtx.c
drivers/staging/vt6655/rxtx.h
drivers/staging/vt6655/srom.c
drivers/staging/vt6655/srom.h
drivers/staging/vt6655/tcrc.c
drivers/staging/vt6655/tcrc.h
drivers/staging/vt6655/tether.c
drivers/staging/vt6655/tether.h
drivers/staging/vt6655/tkip.c
drivers/staging/vt6655/tkip.h
drivers/staging/vt6655/tmacro.h
drivers/staging/vt6655/ttype.h
drivers/staging/vt6655/upc.h
drivers/staging/vt6655/vntwifi.c
drivers/staging/vt6655/vntwifi.h
drivers/staging/vt6655/wcmd.c
drivers/staging/vt6655/wcmd.h
drivers/staging/vt6655/wctl.c
drivers/staging/vt6655/wctl.h
drivers/staging/vt6655/wmgr.c
drivers/staging/vt6655/wmgr.h
drivers/staging/vt6655/wpa.c
drivers/staging/vt6655/wpa.h
drivers/staging/vt6655/wpa2.c
drivers/staging/vt6655/wpa2.h
drivers/staging/vt6655/wpactl.c
drivers/staging/vt6655/wpactl.h
drivers/staging/vt6655/wroute.c
drivers/staging/vt6655/wroute.h
drivers/staging/vt6656/80211mgr.c
drivers/staging/vt6656/80211mgr.h
drivers/staging/vt6656/aes_ccmp.c
drivers/staging/vt6656/baseband.c
drivers/staging/vt6656/baseband.h
drivers/staging/vt6656/bssdb.c
drivers/staging/vt6656/bssdb.h
drivers/staging/vt6656/card.c
drivers/staging/vt6656/channel.c
drivers/staging/vt6656/channel.h
drivers/staging/vt6656/control.c
drivers/staging/vt6656/control.h
drivers/staging/vt6656/datarate.c
drivers/staging/vt6656/desc.h
drivers/staging/vt6656/device.h
drivers/staging/vt6656/device_cfg.h
drivers/staging/vt6656/dpc.c
drivers/staging/vt6656/firmware.c
drivers/staging/vt6656/int.c
drivers/staging/vt6656/int.h
drivers/staging/vt6656/iocmd.h
drivers/staging/vt6656/ioctl.c
drivers/staging/vt6656/iowpa.h
drivers/staging/vt6656/iwctl.c
drivers/staging/vt6656/iwctl.h
drivers/staging/vt6656/key.c
drivers/staging/vt6656/mac.c
drivers/staging/vt6656/mac.h
drivers/staging/vt6656/main_usb.c
drivers/staging/vt6656/mib.c
drivers/staging/vt6656/mib.h
drivers/staging/vt6656/michael.c
drivers/staging/vt6656/michael.h
drivers/staging/vt6656/power.c
drivers/staging/vt6656/power.h
drivers/staging/vt6656/rf.h
drivers/staging/vt6656/rndis.h
drivers/staging/vt6656/rxtx.c
drivers/staging/vt6656/rxtx.h
drivers/staging/vt6656/tether.h
drivers/staging/vt6656/tkip.c
drivers/staging/vt6656/ttype.h
drivers/staging/vt6656/usbpipe.c
drivers/staging/vt6656/usbpipe.h
drivers/staging/vt6656/wcmd.c
drivers/staging/vt6656/wcmd.h
drivers/staging/vt6656/wctl.c
drivers/staging/vt6656/wmgr.c
drivers/staging/vt6656/wmgr.h
drivers/staging/vt6656/wpa.c
drivers/staging/vt6656/wpa2.h
drivers/staging/vt6656/wpactl.c
drivers/staging/winbond/mac_structures.h
drivers/staging/winbond/phy_calibration.c
drivers/staging/winbond/reg.c
drivers/staging/winbond/wbusb.c
drivers/staging/wlags49_h2/hcf.c
drivers/staging/wlags49_h2/mdd.h
drivers/staging/wlags49_h2/wl_cs.c
drivers/staging/wlags49_h2/wl_cs.h
drivers/staging/wlags49_h2/wl_internal.h
drivers/staging/wlags49_h2/wl_netdev.c
drivers/staging/wlags49_h2/wl_pci.c
drivers/staging/wlags49_h2/wl_pci.h
drivers/staging/wlags49_h2/wl_profile.c
drivers/staging/wlags49_h2/wl_util.c
drivers/staging/wlags49_h2/wl_util.h
drivers/staging/wlan-ng/Kconfig
drivers/staging/wlan-ng/Makefile
drivers/staging/wlan-ng/cfg80211.c [new file with mode: 0644]
drivers/staging/wlan-ng/hfa384x.h
drivers/staging/wlan-ng/hfa384x_usb.c
drivers/staging/wlan-ng/p80211conv.c
drivers/staging/wlan-ng/p80211conv.h
drivers/staging/wlan-ng/p80211hdr.h
drivers/staging/wlan-ng/p80211ioctl.h
drivers/staging/wlan-ng/p80211meta.h
drivers/staging/wlan-ng/p80211metastruct.h
drivers/staging/wlan-ng/p80211mgmt.h
drivers/staging/wlan-ng/p80211msg.h
drivers/staging/wlan-ng/p80211netdev.c
drivers/staging/wlan-ng/p80211netdev.h
drivers/staging/wlan-ng/p80211req.c
drivers/staging/wlan-ng/p80211wext.c [deleted file]
drivers/staging/wlan-ng/prism2fw.c
drivers/staging/wlan-ng/prism2mgmt.c
drivers/staging/wlan-ng/prism2mib.c
drivers/staging/wlan-ng/prism2sta.c
drivers/staging/wlan-ng/prism2usb.c
drivers/staging/xgifb/XGI.h [deleted file]
drivers/staging/xgifb/XGI_accel.c
drivers/staging/xgifb/XGI_accel.h
drivers/staging/xgifb/XGI_main.h
drivers/staging/xgifb/XGI_main_26.c
drivers/staging/xgifb/XGIfb.h
drivers/staging/xgifb/osdef.h [deleted file]
drivers/staging/xgifb/vb_def.h
drivers/staging/xgifb/vb_ext.c
drivers/staging/xgifb/vb_ext.h
drivers/staging/xgifb/vb_init.c
drivers/staging/xgifb/vb_init.h
drivers/staging/xgifb/vb_setmode.c
drivers/staging/xgifb/vb_setmode.h
drivers/staging/xgifb/vb_struct.h
drivers/staging/xgifb/vb_table.h
drivers/staging/xgifb/vb_util.c
drivers/staging/xgifb/vb_util.h
drivers/staging/xgifb/vgatypes.h
drivers/staging/zram/Kconfig [new file with mode: 0644]
drivers/staging/zram/Makefile [new file with mode: 0644]
drivers/staging/zram/xvmalloc.c [moved from drivers/staging/ramzswap/xvmalloc.c with 100% similarity]
drivers/staging/zram/xvmalloc.h [moved from drivers/staging/ramzswap/xvmalloc.h with 100% similarity]
drivers/staging/zram/xvmalloc_int.h [moved from drivers/staging/ramzswap/xvmalloc_int.h with 100% similarity]
drivers/staging/zram/zram.txt [new file with mode: 0644]
drivers/staging/zram/zram_drv.c [new file with mode: 0644]
drivers/staging/zram/zram_drv.h [moved from drivers/staging/ramzswap/ramzswap_drv.h with 69% similarity]
drivers/staging/zram/zram_ioctl.h [moved from drivers/staging/ramzswap/ramzswap_ioctl.h with 68% similarity]
drivers/telephony/ixj_pcmcia.c
drivers/uio/uio_cif.c
drivers/uio/uio_pdrv_genirq.c
drivers/uio/uio_sercos3.c
drivers/usb/gadget/fsl_qe_udc.c
drivers/usb/host/sl811_cs.c
drivers/video/bw2.c
drivers/video/cg14.c
drivers/video/cg3.c
drivers/video/cg6.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/controlfb.c
drivers/video/ffb.c
drivers/video/leo.c
drivers/video/offb.c
drivers/video/p9100.c
drivers/video/sunxvr1000.c
drivers/video/tcx.c
drivers/video/xen-fbfront.c
drivers/watchdog/cpwd.c
drivers/watchdog/riowd.c
drivers/xen/Kconfig
drivers/xen/Makefile
drivers/xen/events.c
drivers/xen/grant-table.c
drivers/xen/manage.c
drivers/xen/platform-pci.c [new file with mode: 0644]
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_xs.c
drivers/xen/xenfs/super.c
drivers/xen/xenfs/xenbus.c
fs/aio.c
fs/cachefiles/namei.c
fs/cachefiles/rdwr.c
fs/char_dev.c
fs/cifs/Kconfig
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/misc.c
fs/exec.c
fs/file.c
fs/fscache/Kconfig
fs/fscache/internal.h
fs/fscache/main.c
fs/fscache/object-list.c
fs/fscache/object.c
fs/fscache/operation.c
fs/fscache/page.c
fs/gfs2/Kconfig
fs/gfs2/incore.h
fs/gfs2/main.c
fs/gfs2/ops_fstype.c
fs/gfs2/recovery.c
fs/gfs2/recovery.h
fs/gfs2/sys.c
fs/partitions/check.c
fs/sysfs/file.c
include/asm-generic/gpio.h
include/asm-generic/local64.h [new file with mode: 0644]
include/asm-generic/vmlinux.lds.h
include/drm/drm.h
include/drm/drmP.h
include/drm/drm_crtc.h
include/drm/drm_crtc_helper.h
include/drm/drm_fb_helper.h
include/drm/drm_global.h [new file with mode: 0644]
include/drm/drm_mm.h
include/drm/drm_mode.h
include/drm/drm_pciids.h
include/drm/i2c/sil164.h [new file with mode: 0644]
include/drm/radeon_drm.h
include/drm/ttm/ttm_bo_driver.h
include/drm/ttm/ttm_module.h
include/linux/ahci_platform.h
include/linux/clocksource.h
include/linux/compiler.h
include/linux/console.h
include/linux/cpu.h
include/linux/cpuset.h
include/linux/delay.h
include/linux/device.h
include/linux/dmi.h
include/linux/fb.h
include/linux/fdtable.h
include/linux/fscache-cache.h
include/linux/ftrace.h
include/linux/ftrace_event.h
include/linux/interrupt.h
include/linux/io-mapping.h
include/linux/io.h
include/linux/iommu.h
include/linux/kdb.h
include/linux/kernel.h
include/linux/kgdb.h
include/linux/kmemtrace.h [deleted file]
include/linux/kthread.h
include/linux/libata.h
include/linux/msi.h
include/linux/nmi.h
include/linux/of.h
include/linux/of_address.h [new file with mode: 0644]
include/linux/of_device.h
include/linux/of_gpio.h
include/linux/of_i2c.h
include/linux/of_irq.h [new file with mode: 0644]
include/linux/of_platform.h
include/linux/of_spi.h
include/linux/page-flags.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/perf_event.h
include/linux/platform_device.h
include/linux/rcupdate.h
include/linux/sched.h
include/linux/slab.h
include/linux/slab_def.h
include/linux/slow-work.h [deleted file]
include/linux/slub_def.h
include/linux/syscalls.h
include/linux/sysfs.h
include/linux/time.h
include/linux/topology.h
include/linux/tty.h
include/linux/vmalloc.h
include/linux/workqueue.h
include/pcmcia/cistpl.h
include/pcmcia/cs.h
include/pcmcia/cs_types.h [deleted file]
include/pcmcia/ds.h
include/pcmcia/ss.h
include/trace/boot.h [deleted file]
include/trace/events/sched.h
include/trace/events/timer.h
include/trace/events/workqueue.h [deleted file]
include/trace/ftrace.h
include/trace/syscall.h
include/xen/events.h
include/xen/grant_table.h
include/xen/hvm.h [new file with mode: 0644]
include/xen/interface/features.h
include/xen/interface/grant_table.h
include/xen/interface/hvm/hvm_op.h [new file with mode: 0644]
include/xen/interface/hvm/params.h [new file with mode: 0644]
include/xen/platform_pci.h [new file with mode: 0644]
include/xen/xen-ops.h
init/Kconfig
init/main.c
kernel/Makefile
kernel/async.c
kernel/cgroup.c
kernel/cpu.c
kernel/cpuset.c
kernel/debug/debug_core.c
kernel/debug/gdbstub.c
kernel/debug/kdb/kdb_main.c
kernel/debug/kdb/kdb_private.h
kernel/fork.c
kernel/hrtimer.c
kernel/hw_breakpoint.c
kernel/irq/manage.c
kernel/kthread.c
kernel/lockdep.c
kernel/module.c
kernel/perf_event.c
kernel/posix-cpu-timers.c
kernel/posix-timers.c
kernel/power/process.c
kernel/rcupdate.c
kernel/rcutiny.c
kernel/rcutorture.c
kernel/rcutree.c
kernel/sched.c
kernel/sched_clock.c
kernel/sched_cpupri.c
kernel/sched_cpupri.h
kernel/sched_debug.c
kernel/sched_fair.c
kernel/sched_rt.c
kernel/sched_stats.h
kernel/slow-work-debugfs.c [deleted file]
kernel/slow-work.c [deleted file]
kernel/slow-work.h [deleted file]
kernel/softlockup.c [deleted file]
kernel/sysctl.c
kernel/time.c
kernel/time/Kconfig
kernel/time/clocksource.c
kernel/time/tick-sched.c
kernel/time/timekeeping.c
kernel/timer.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/ftrace.c
kernel/trace/kmemtrace.c [deleted file]
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_boot.c [deleted file]
kernel/trace/trace_clock.c
kernel/trace/trace_entries.h
kernel/trace/trace_event_perf.c
kernel/trace/trace_events.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_export.c
kernel/trace/trace_functions.c
kernel/trace/trace_functions_graph.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_kdb.c [new file with mode: 0644]
kernel/trace/trace_kprobe.c
kernel/trace/trace_ksym.c [deleted file]
kernel/trace/trace_output.c
kernel/trace/trace_sched_wakeup.c
kernel/trace/trace_selftest.c
kernel/trace/trace_stack.c
kernel/trace/trace_syscalls.c
kernel/trace/trace_sysprof.c [deleted file]
kernel/watchdog.c [new file with mode: 0644]
kernel/workqueue.c
kernel/workqueue_sched.h [new file with mode: 0644]
lib/Kconfig.debug
lib/ioremap.c
mm/backing-dev.c
mm/highmem.c
mm/mmap.c
mm/slab.c
mm/slob.c
mm/slub.c
mm/vmalloc.c
scripts/Makefile.build
scripts/Makefile.help [new file with mode: 0644]
scripts/Makefile.modpost
scripts/checkkconfigsymbols.sh
scripts/coccicheck [new file with mode: 0755]
scripts/coccinelle/alloc/drop_kmalloc_cast.cocci [new file with mode: 0644]
scripts/coccinelle/alloc/kzalloc-simple.cocci [new file with mode: 0644]
scripts/coccinelle/deref_null.cocci [new file with mode: 0644]
scripts/coccinelle/err_cast.cocci [new file with mode: 0644]
scripts/coccinelle/resource_size.cocci [new file with mode: 0644]
scripts/decodecode
scripts/dtc/fstree.c
scripts/kconfig/.gitignore
scripts/kconfig/Makefile
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kconfig/expr.c
scripts/kconfig/expr.h
scripts/kconfig/gconf.c
scripts/kconfig/lkc.h
scripts/kconfig/lkc_proto.h
scripts/kconfig/lxdialog/checklist.c
scripts/kconfig/mconf.c
scripts/kconfig/menu.c
scripts/kconfig/qconf.cc
scripts/kconfig/qconf.h
scripts/kconfig/symbol.c
scripts/mod/file2alias.c
scripts/mod/modpost.c
scripts/mod/modpost.h
scripts/package/Makefile
scripts/package/builddeb
scripts/recordmcount.pl
security/apparmor/Kconfig
security/keys/request_key.c
sound/pcmcia/pdaudiocf/pdaudiocf.c
sound/pcmcia/pdaudiocf/pdaudiocf.h
sound/pcmcia/vx/vxpocket.c
sound/pcmcia/vx/vxpocket.h
sound/sparc/amd7930.c
sound/sparc/cs4231.c
sound/sparc/dbri.c
tools/perf/.gitignore
tools/perf/Documentation/perf-buildid-cache.txt
tools/perf/Documentation/perf-probe.txt
tools/perf/Documentation/perf-record.txt
tools/perf/Documentation/perf-stat.txt
tools/perf/Documentation/perf-top.txt
tools/perf/MANIFEST [new file with mode: 0644]
tools/perf/Makefile
tools/perf/arch/sh/Makefile [new file with mode: 0644]
tools/perf/arch/sh/util/dwarf-regs.c [new file with mode: 0644]
tools/perf/builtin-annotate.c
tools/perf/builtin-buildid-cache.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-diff.c
tools/perf/builtin-probe.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-stat.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/feature-tests.mak [new file with mode: 0644]
tools/perf/perf-archive.sh
tools/perf/perf.c
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py [new file with mode: 0644]
tools/perf/scripts/python/bin/sched-migration-record [new file with mode: 0644]
tools/perf/scripts/python/bin/sched-migration-report [new file with mode: 0644]
tools/perf/scripts/python/sched-migration.py [new file with mode: 0644]
tools/perf/util/build-id.c
tools/perf/util/cache.h
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/config.c
tools/perf/util/cpumap.c
tools/perf/util/cpumap.h
tools/perf/util/debug.c
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/header.c
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/newt.c
tools/perf/util/parse-events.c
tools/perf/util/probe-event.c
tools/perf/util/probe-event.h
tools/perf/util/probe-finder.c
tools/perf/util/probe-finder.h
tools/perf/util/session.c
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/symbol.c
tools/perf/util/symbol.h
tools/perf/util/thread.c
tools/perf/util/thread.h
tools/perf/util/util.h

diff --git a/Documentation/ABI/testing/debugfs-kmemtrace b/Documentation/ABI/testing/debugfs-kmemtrace
deleted file mode 100644 (file)
index 5e6a92a..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-What:          /sys/kernel/debug/kmemtrace/
-Date:          July 2008
-Contact:       Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
-Description:
-
-In kmemtrace-enabled kernels, the following files are created:
-
-/sys/kernel/debug/kmemtrace/
-       cpu<n>          (0400)  Per-CPU tracing data, see below. (binary)
-       total_overruns  (0400)  Total number of bytes which were dropped from
-                               cpu<n> files because of full buffer condition,
-                               non-binary. (text)
-       abi_version     (0400)  Kernel's kmemtrace ABI version. (text)
-
-Each per-CPU file should be read according to the relay interface. That is,
-the reader should set affinity to that specific CPU and, as currently done by
-the userspace application (though there are other methods), use poll() with
-an infinite timeout before every read(). Otherwise, erroneous data may be
-read. The binary data has the following _core_ format:
-
-       Event ID        (1 byte)        Unsigned integer, one of:
-               0 - represents an allocation (KMEMTRACE_EVENT_ALLOC)
-               1 - represents a freeing of previously allocated memory
-                   (KMEMTRACE_EVENT_FREE)
-       Type ID         (1 byte)        Unsigned integer, one of:
-               0 - this is a kmalloc() / kfree()
-               1 - this is a kmem_cache_alloc() / kmem_cache_free()
-               2 - this is a __get_free_pages() et al.
-       Event size      (2 bytes)       Unsigned integer representing the
-                                       size of this event. Used to extend
-                                       kmemtrace. Discard the bytes you
-                                       don't know about.
-       Sequence number (4 bytes)       Signed integer used to reorder data
-                                       logged on SMP machines. Wraparound
-                                       must be taken into account, although
-                                       it is unlikely.
-       Caller address  (8 bytes)       Return address to the caller.
-       Pointer to mem  (8 bytes)       Pointer to target memory area. Can be
-                                       NULL, but not all such calls might be
-                                       recorded.
-
-In case of KMEMTRACE_EVENT_ALLOC events, the next fields follow:
-
-       Requested bytes (8 bytes)       Total number of requested bytes,
-                                       unsigned, must not be zero.
-       Allocated bytes (8 bytes)       Total number of actually allocated
-                                       bytes, unsigned, must not be lower
-                                       than requested bytes.
-       Requested flags (4 bytes)       GFP flags supplied by the caller.
-       Target CPU      (4 bytes)       Signed integer, valid for event id 1.
-                                       If equal to -1, target CPU is the same
-                                       as origin CPU, but the reverse might
-                                       not be true.
-
-The data is made available in the same endianness the machine has.
-
-Other event ids and type ids may be defined and added. Other fields may be
-added by increasing event size, but see below for details.
-Every modification to the ABI, including new id definitions, are followed
-by bumping the ABI version by one.
-
-Adding new data to the packet (features) is done at the end of the mandatory
-data:
-       Feature size    (2 byte)
-       Feature ID      (1 byte)
-       Feature data    (Feature size - 3 bytes)
-
-
-Users:
-       kmemtrace-user - git://repo.or.cz/kmemtrace-user.git
-
index 25be3250f7d66f17c0a4d88974441ced8f4ca633..f979d825d112109e03db36cf44ad170a7743fd06 100644 (file)
@@ -139,3 +139,30 @@ Contact:   linux-pci@vger.kernel.org
 Description:
                This symbolic link points to the PCI hotplug controller driver
                module that manages the hotplug slot.
+
+What:          /sys/bus/pci/devices/.../label
+Date:          July 2010
+Contact:       Narendra K <narendra_k@dell.com>, linux-bugs@dell.com
+Description:
+               Reading this attribute will provide the firmware
+               given name(SMBIOS type 41 string) of the PCI device.
+               The attribute will be created only if the firmware
+               has given a name to the PCI device.
+Users:
+               Userspace applications interested in knowing the
+               firmware assigned name of the PCI device.
+
+What:          /sys/bus/pci/devices/.../index
+Date:          July 2010
+Contact:       Narendra K <narendra_k@dell.com>, linux-bugs@dell.com
+Description:
+               Reading this attribute will provide the firmware
+               given instance(SMBIOS type 41 device type instance)
+               of the PCI device. The attribute will be created
+               only if the firmware has given a device type instance
+               to the PCI device.
+Users:
+               Userspace applications interested in knowing the
+               firmware assigned device type instance of the PCI
+               device that can help in understanding the firmware
+               intended order of the PCI device.
index 1b2dd4fc3db24b57db4178d92fe2b9828c27b9ff..ecd35e9d4410a2b8c28241331f4f96f5197b6c3a 100644 (file)
@@ -111,6 +111,7 @@ X!Edrivers/base/attribute_container.c
 <!--
 X!Edrivers/base/interface.c
 -->
+!Iinclude/linux/platform_device.h
 !Edrivers/base/platform.c
 !Edrivers/base/bus.c
      </sect1>
index 55f12ac37acdf105f65bd3981b8e8c1e6cf720b7..490d862c5f0ddffc748ebb56de4255ef0769c115 100644 (file)
    may be configured as a kernel built-in or a kernel loadable module.
    You can only make use of <constant>kgdbwait</constant> and early
    debugging if you build kgdboc into the kernel as a built-in.
+   <para>Optionally you can elect to activate kms (Kernel Mode
+   Setting) integration.  When you use kms with kgdboc and you have a
+   video driver that has atomic mode setting hooks, it is possible to
+   enter the debugger on the graphics console.  When the kernel
+   execution is resumed, the previous graphics mode will be restored.
+   This integration can serve as a useful tool to aid in diagnosing
+   crashes or doing analysis of memory with kdb while allowing the
+   full graphics console applications to run.
+   </para>
    </para>
    <sect2 id="kgdbocArgs">
    <title>kgdboc arguments</title>
-   <para>Usage: <constant>kgdboc=[kbd][[,]serial_device][,baud]</constant></para>
+   <para>Usage: <constant>kgdboc=[kms][[,]kbd][[,]serial_device][,baud]</constant></para>
+   <para>The order listed above must be observed if you use any of the
+   optional configurations together.
+   </para>
+   <para>Abbreviations:
+   <itemizedlist>
+   <listitem><para>kms = Kernel Mode Setting</para></listitem>
+   <listitem><para>kbd = Keyboard</para></listitem>
+   </itemizedlist>
+   </para>
+   <para>You can configure kgdboc to use the keyboard, and or a serial
+   device depending on if you are using kdb and or kgdb, in one of the
+   following scenarios.  The order listed above must be observed if
+   you use any of the optional configurations together.  Using kms +
+   only gdb is generally not a useful combination.</para>
    <sect3 id="kgdbocArgs1">
    <title>Using loadable module or built-in</title>
    <para>
    <listitem>
    <para>As a kernel loadable module:</para>
    <para>Use the command: <constant>modprobe kgdboc kgdboc=&lt;tty-device&gt;,[baud]</constant></para>
-   <para>Here are two examples of how you might formate the kgdboc
+   <para>Here are two examples of how you might format the kgdboc
    string. The first is for an x86 target using the first serial port.
    The second example is for the ARM Versatile AB using the second
    serial port.
    </sect3>
    <sect3 id="kgdbocArgs3">
    <title>More examples</title>
+   <para>You can configure kgdboc to use the keyboard, and or a serial
+   device depending on if you are using kdb and or kgdb, in one of the
+   following scenarios.</para>
    <para>You can configure kgdboc to use the keyboard, and or a serial device
    depending on if you are using kdb and or kgdb, in one of the
    following scenarios.
    <listitem><para>kdb with a keyboard</para>
    <para><constant>kgdboc=kbd</constant></para>
    </listitem>
+   <listitem><para>kdb with kernel mode setting</para>
+   <para><constant>kgdboc=kms,kbd</constant></para>
+   </listitem>
+   <listitem><para>kdb with kernel mode setting and kgdb over a serial port</para>
+   <para><constant>kgdboc=kms,kbd,ttyS0,115200</constant></para>
+   </listitem>
    </orderedlist>
    </para>
    </sect3>
@@ -637,6 +669,8 @@ Task Addr       Pid   Parent [*] cpu State Thread     Command
       <listitem><para>The logic to perform safe memory reads and writes to memory while using the debugger</para></listitem>
       <listitem><para>A full implementation for software breakpoints unless overridden by the arch</para></listitem>
       <listitem><para>The API to invoke either the kdb or kgdb frontend to the debug core.</para></listitem>
+      <listitem><para>The structures and callback API for atomic kernel mode setting.</para>
+      <para>NOTE: kgdboc is where the kms callbacks are invoked.</para></listitem>
       </itemizedlist>
       </para>
       </listitem>
@@ -747,6 +781,8 @@ Task Addr       Pid   Parent [*] cpu State Thread     Command
   </sect1>
   <sect1 id="kgdbocDesign">
   <title>kgdboc internals</title>
+  <sect2>
+  <title>kgdboc and uarts</title>
   <para>
   The kgdboc driver is actually a very thin driver that relies on the
   underlying low level to the hardware driver having "polling hooks"
@@ -754,11 +790,8 @@ Task Addr       Pid   Parent [*] cpu State Thread     Command
   implementation of kgdboc it the serial_core was changed to expose a
   low level UART hook for doing polled mode reading and writing of a
   single character while in an atomic context.  When kgdb makes an I/O
-  request to the debugger, kgdboc invokes a call back in the serial
-  core which in turn uses the call back in the UART driver.  It is
-  certainly possible to extend kgdboc to work with non-UART based
-  consoles in the future.
-  </para>
+  request to the debugger, kgdboc invokes a callback in the serial
+  core which in turn uses the callback in the UART driver.</para>
   <para>
   When using kgdboc with a UART, the UART driver must implement two callbacks in the <constant>struct uart_ops</constant>. Example from drivers/8250.c:<programlisting>
 #ifdef CONFIG_CONSOLE_POLL
@@ -772,9 +805,68 @@ Task Addr       Pid   Parent [*] cpu State Thread     Command
   that they can be called from an atomic context and have to restore
   the state of the UART chip on return such that the system can return
   to normal when the debugger detaches.  You need to be very careful
-  with any kind of lock you consider, because failing here is most
+  with any kind of lock you consider, because failing here is most likely
   going to mean pressing the reset button.
   </para>
+  </sect2>
+  <sect2 id="kgdbocKbd">
+  <title>kgdboc and keyboards</title>
+  <para>The kgdboc driver contains logic to configure communications
+  with an attached keyboard.  The keyboard infrastructure is only
+  compiled into the kernel when CONFIG_KDB_KEYBOARD=y is set in the
+  kernel configuration.</para>
+  <para>The core polled keyboard driver driver for PS/2 type keyboards
+  is in drivers/char/kdb_keyboard.c.  This driver is hooked into the
+  debug core when kgdboc populates the callback in the array
+  called <constant>kdb_poll_funcs[]</constant>.  The
+  kdb_get_kbd_char() is the top-level function which polls hardware
+  for single character input.
+  </para>
+  </sect2>
+  <sect2 id="kgdbocKms">
+  <title>kgdboc and kms</title>
+  <para>The kgdboc driver contains logic to request the graphics
+  display to switch to a text context when you are using
+  "kgdboc=kms,kbd", provided that you have a video driver which has a
+  frame buffer console and atomic kernel mode setting support.</para>
+  <para>
+  Every time the kernel
+  debugger is entered it calls kgdboc_pre_exp_handler() which in turn
+  calls con_debug_enter() in the virtual console layer.  On resuming kernel
+  execution, the kernel debugger calls kgdboc_post_exp_handler() which
+  in turn calls con_debug_leave().</para>
+  <para>Any video driver that wants to be compatible with the kernel
+  debugger and the atomic kms callbacks must implement the
+  mode_set_base_atomic, fb_debug_enter and fb_debug_leave operations.
+  For the fb_debug_enter and fb_debug_leave the option exists to use
+  the generic drm fb helper functions or implement something custom for
+  the hardware.  The following example shows the initialization of the
+  .mode_set_base_atomic operation in
+  drivers/gpu/drm/i915/intel_display.c:
+  <informalexample>
+  <programlisting>
+static const struct drm_crtc_helper_funcs intel_helper_funcs = {
+[...]
+        .mode_set_base_atomic = intel_pipe_set_base_atomic,
+[...]
+};
+  </programlisting>
+  </informalexample>
+  </para>
+  <para>Here is an example of how the i915 driver initializes the fb_debug_enter and fb_debug_leave functions to use the generic drm helpers in
+  drivers/gpu/drm/i915/intel_fb.c:
+  <informalexample>
+  <programlisting>
+static struct fb_ops intelfb_ops = {
+[...]
+       .fb_debug_enter = drm_fb_helper_debug_enter,
+       .fb_debug_leave = drm_fb_helper_debug_leave,
+[...]
+};
+  </programlisting>
+  </informalexample>
+  </para>
+  </sect2>
   </sect1>
   </chapter>
   <chapter id="credits">
index 254c1d5d2e502f4cc1bc00fa2b5ec194fb23dd36..85b25275196ffab5d34e31e207b78a483128a3f1 100644 (file)
@@ -6,4 +6,5 @@
 <param name="callout.graphics">0</param>
 <!-- <param name="paper.type">A4</param> -->
 <param name="generate.section.toc.level">2</param>
+<param name="use.id.as.filename">1</param>
 </stylesheet>
diff --git a/Documentation/coccinelle.txt b/Documentation/coccinelle.txt
new file mode 100644 (file)
index 0000000..cd2b028
--- /dev/null
@@ -0,0 +1,258 @@
+Copyright 2010 Nicolas Palix <npalix@diku.dk>
+Copyright 2010 Julia Lawall <julia@diku.dk>
+Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
+
+
+ Getting Coccinelle
+~~~~~~~~~~~~~~~~~~~~
+
+The semantic patches included in the kernel use the 'virtual rule'
+feature which was introduced in Coccinelle version 0.1.11.
+
+Coccinelle (>=0.2.0) is available through the package manager
+of many distributions, e.g. :
+
+ - Debian (>=squeeze)
+ - Fedora (>=13)
+ - Ubuntu (>=10.04 Lucid Lynx)
+ - OpenSUSE
+ - Arch Linux
+ - NetBSD
+ - FreeBSD
+
+
+You can get the latest version released from the Coccinelle homepage at
+http://coccinelle.lip6.fr/
+
+Once you have it, run the following command:
+
+       ./configure
+        make
+
+as a regular user, and install it with
+
+        sudo make install
+
+
+ Using Coccinelle on the Linux kernel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A Coccinelle-specific target is defined in the top level
+Makefile. This target is named 'coccicheck' and calls the 'coccicheck'
+front-end in the 'scripts' directory.
+
+Four modes are defined: report, patch, context, and org. The mode to
+use is specified by setting the MODE variable with 'MODE=<mode>'.
+
+'report' generates a list in the following format:
+  file:line:column-column: message
+
+'patch' proposes a fix, when possible.
+
+'context' highlights lines of interest and their context in a
+diff-like style.Lines of interest are indicated with '-'.
+
+'org' generates a report in the Org mode format of Emacs.
+
+Note that not all semantic patches implement all modes.
+
+To make a report for every semantic patch, run the following command:
+
+       make coccicheck MODE=report
+
+NB: The 'report' mode is the default one.
+
+To produce patches, run:
+
+       make coccicheck MODE=patch
+
+
+The coccicheck target applies every semantic patch available in the
+subdirectories of 'scripts/coccinelle' to the entire Linux kernel.
+
+For each semantic patch, a changelog message is proposed.  It gives a
+description of the problem being checked by the semantic patch, and
+includes a reference to Coccinelle.
+
+As any static code analyzer, Coccinelle produces false
+positives. Thus, reports must be carefully checked, and patches
+reviewed.
+
+
+ Using Coccinelle with a single semantic patch
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The optional make variable COCCI can be used to check a single
+semantic patch. In that case, the variable must be initialized with
+the name of the semantic patch to apply.
+
+For instance:
+
+       make coccicheck COCCI=<my_SP.cocci> MODE=patch
+or
+       make coccicheck COCCI=<my_SP.cocci> MODE=report
+
+
+ Proposing new semantic patches
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+New semantic patches can be proposed and submitted by kernel
+developers. For sake of clarity, they should be organized in the
+subdirectories of 'scripts/coccinelle/'.
+
+
+ Detailed description of the 'report' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'report' generates a list in the following format:
+  file:line:column-column: message
+
+Example:
+
+Running
+
+       make coccicheck MODE=report COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@r depends on !context && !patch && (org || report)@
+expression x;
+position p;
+@@
+
+ ERR_PTR@p(PTR_ERR(x))
+
+@script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="ERR_CAST can be used with %s" % (x)
+coccilib.report.print_report(p[0], msg)
+</smpl>
+
+This SmPL excerpt generates entries on the standard output, as
+illustrated below:
+
+/home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
+/home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
+/home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
+
+
+ Detailed description of the 'patch' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When the 'patch' mode is available, it proposes a fix for each problem
+identified.
+
+Example:
+
+Running
+       make coccicheck MODE=patch COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@ depends on !context && patch && !org && !report @
+expression x;
+@@
+
+- ERR_PTR(PTR_ERR(x))
++ ERR_CAST(x)
+</smpl>
+
+This SmPL excerpt generates patch hunks on the standard output, as
+illustrated below:
+
+diff -u -p a/crypto/ctr.c b/crypto/ctr.c
+--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
++++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
+@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
+       alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
+                                 CRYPTO_ALG_TYPE_MASK);
+       if (IS_ERR(alg))
+-              return ERR_PTR(PTR_ERR(alg));
++              return ERR_CAST(alg);
+       /* Block size must be >= 4 bytes. */
+       err = -EINVAL;
+
+ Detailed description of the 'context' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'context' highlights lines of interest and their context
+in a diff-like style.
+
+NOTE: The diff-like output generated is NOT an applicable patch. The
+      intent of the 'context' mode is to highlight the important lines
+      (annotated with minus, '-') and gives some surrounding context
+      lines around. This output can be used with the diff mode of
+      Emacs to review the code.
+
+Example:
+
+Running
+       make coccicheck MODE=context COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@ depends on context && !patch && !org && !report@
+expression x;
+@@
+
+* ERR_PTR(PTR_ERR(x))
+</smpl>
+
+This SmPL excerpt generates diff hunks on the standard output, as
+illustrated below:
+
+diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
+--- /home/user/linux/crypto/ctr.c      2010-05-26 10:49:38.000000000 +0200
++++ /tmp/nothing
+@@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
+       alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
+                                 CRYPTO_ALG_TYPE_MASK);
+       if (IS_ERR(alg))
+-              return ERR_PTR(PTR_ERR(alg));
+       /* Block size must be >= 4 bytes. */
+       err = -EINVAL;
+
+ Detailed description of the 'org' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'org' generates a report in the Org mode format of Emacs.
+
+Example:
+
+Running
+       make coccicheck MODE=org COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@r depends on !context && !patch && (org || report)@
+expression x;
+position p;
+@@
+
+ ERR_PTR@p(PTR_ERR(x))
+
+@script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="ERR_CAST can be used with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+</smpl>
+
+This SmPL excerpt generates Org entries on the standard output, as
+illustrated below:
+
+* TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
+* TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
+* TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
index be7030e4dd73697ed5b979f02b6841dac7bb69c0..71f0fea1058f8d2b460596a8c8c15e18a275566d 100644 (file)
@@ -116,29 +116,6 @@ Who:       Mauro Carvalho Chehab <mchehab@infradead.org>
 
 ---------------------------
 
-What:  PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
-When:  2.6.35/2.6.36
-Files: drivers/pcmcia/: pcmcia_ioctl.c
-Why:   With the 16-bit PCMCIA subsystem now behaving (almost) like a
-       normal hotpluggable bus, and with it using the default kernel
-       infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA
-       control ioctl needed by cardmgr and cardctl from pcmcia-cs is
-       unnecessary and potentially harmful (it does not provide for
-       proper locking), and makes further cleanups and integration of the
-       PCMCIA subsystem into the Linux kernel device driver model more
-       difficult. The features provided by cardmgr and cardctl are either
-       handled by the kernel itself now or are available in the new
-       pcmciautils package available at
-       http://kernel.org/pub/linux/utils/kernel/pcmcia/
-
-       For all architectures except ARM, the associated config symbol
-       has been removed from kernel 2.6.34; for ARM, it will be likely
-       be removed from kernel 2.6.35. The actual code will then likely
-       be removed from kernel 2.6.36.
-Who:   Dominik Brodowski <linux@dominikbrodowski.net>
-
----------------------------
-
 What:  sys_sysctl
 When:  September 2010
 Option: CONFIG_SYSCTL_SYSCALL
@@ -468,16 +445,6 @@ Who:       Jan Kiszka <jan.kiszka@web.de>
 
 ----------------------------
 
-What:  xtime, wall_to_monotonic
-When:  2.6.36+
-Files: kernel/time/timekeeping.c include/linux/time.h
-Why:   Cleaning up timekeeping internal values. Please use
-       existing timekeeping accessor functions to access
-       the equivalent functionality.
-Who:   John Stultz <johnstul@us.ibm.com>
-
-----------------------------
-
 What:  KVM paravirt mmu host support
 When:  January 2011
 Why:   The paravirt mmu host support is slower than non-paravirt mmu, both
index a91e2e2095b09fcebca6f456fe7e1fe36263006d..770267af5b3e2c992eb081d2827a77acccd1ae7e 100644 (file)
@@ -343,8 +343,8 @@ This will look something like:
        [root@andromeda ~]# head /proc/fs/fscache/objects
        OBJECT   PARENT   STAT CHLDN OPS OOP IPR EX READS EM EV F S | NETFS_COOKIE_DEF TY FL NETFS_DATA       OBJECT_KEY, AUX_DATA
        ======== ======== ==== ===== === === === == ===== == == = = | ================ == == ================ ================
-          17e4b        2 ACTV     0   0   0   0  0     0 7b  4 0 8 | NFS.fh           DT  0 ffff88001dd82820 010006017edcf8bbc93b43298fdfbe71e50b57b13a172c0117f38472, e567634700000000000000000000000063f2404a000000000000000000000000c9030000000000000000000063f2404a
-          1693a        2 ACTV     0   0   0   0  0     0 7b  4 0 8 | NFS.fh           DT  0 ffff88002db23380 010006017edcf8bbc93b43298fdfbe71e50b57b1e0162c01a2df0ea6, 420ebc4a000000000000000000000000420ebc4a0000000000000000000000000e1801000000000000000000420ebc4a
+          17e4b        2 ACTV     0   0   0   0  0     0 7b  4 0 0 | NFS.fh           DT  0 ffff88001dd82820 010006017edcf8bbc93b43298fdfbe71e50b57b13a172c0117f38472, e567634700000000000000000000000063f2404a000000000000000000000000c9030000000000000000000063f2404a
+          1693a        2 ACTV     0   0   0   0  0     0 7b  4 0 0 | NFS.fh           DT  0 ffff88002db23380 010006017edcf8bbc93b43298fdfbe71e50b57b1e0162c01a2df0ea6, 420ebc4a000000000000000000000000420ebc4a0000000000000000000000000e1801000000000000000000420ebc4a
 
 where the first set of columns before the '|' describe the object:
 
@@ -362,7 +362,7 @@ where the first set of columns before the '|' describe the object:
        EM      Object's event mask
        EV      Events raised on this object
        F       Object flags
-       S       Object slow-work work item flags
+       S       Object work item busy state mask (1:pending 2:running)
 
 and the second set of columns describe the object's cookie, if present:
 
@@ -395,8 +395,8 @@ and the following paired letters:
        w       Show objects that don't have pending writes
        R       Show objects that have outstanding reads
        r       Show objects that don't have outstanding reads
-       S       Show objects that have slow work queued
-       s       Show objects that don't have slow work queued
+       S       Show objects that have work queued
+       s       Show objects that don't have work queued
 
 If neither side of a letter pair is given, then both are implied.  For example:
 
index 85354b32d731cc409dfcc082c30277fefdf11850..74eaac26f8b8c3c4f45b083fe5ffc1b76f5589dd 100644 (file)
@@ -39,7 +39,7 @@ files, each with their own function.
        local_cpus         nearby CPU mask (cpumask, ro)
        remove             remove device from kernel's list (ascii, wo)
        resource                   PCI resource host addresses (ascii, ro)
-       resource0..N       PCI resource N, if present (binary, mmap)
+       resource0..N       PCI resource N, if present (binary, mmap, rw[1])
        resource0_wc..N_wc  PCI WC map resource N, if prefetchable (binary, mmap)
        rom                PCI ROM resource, if present (binary, ro)
        subsystem_device           PCI subsystem device (ascii, ro)
@@ -54,13 +54,16 @@ files, each with their own function.
   binary - file contains binary data
   cpumask - file contains a cpumask type
 
+[1] rw for RESOURCE_IO (I/O port) regions only
+
 The read only files are informational, writes to them will be ignored, with
 the exception of the 'rom' file.  Writable files can be used to perform
 actions on the device (e.g. changing config space, detaching a device).
 mmapable files are available via an mmap of the file at offset 0 and can be
 used to do actual device programming from userspace.  Note that some platforms
 don't support mmapping of certain resources, so be sure to check the return
-value from any attempted mmap.
+value from any attempted mmap.  The most notable of these are I/O port
+resources, which also provide read/write access.
 
 The 'enable' file provides a counter that indicates how many times the device 
 has been enabled.  If the 'enable' file currently returns '4', and a '1' is
index 931c806642c5939a61c5f6ad01c7b9fedbd4a0a9..5d1335faec2df7eef54ae8ddf4f795889e79096b 100644 (file)
@@ -4,7 +4,7 @@ sysfs - _The_ filesystem for exporting kernel objects.
 Patrick Mochel <mochel@osdl.org>
 Mike Murphy <mamurph@cs.clemson.edu>
 
-Revised:    22 February 2009
+Revised:    15 July 2010
 Original:   10 January 2003
 
 
@@ -124,7 +124,7 @@ show and store methods of the attribute owners.
 
 struct sysfs_ops {
         ssize_t (*show)(struct kobject *, struct attribute *, char *);
-        ssize_t (*store)(struct kobject *, struct attribute *, const char *);
+        ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
 };
 
 [ Subsystems should have already defined a struct kobj_type as a
@@ -139,18 +139,22 @@ calls the associated methods.
 
 To illustrate:
 
+#define to_dev(obj) container_of(obj, struct device, kobj)
 #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
-#define to_dev(d) container_of(d, struct device, kobj)
 
-static ssize_t
-dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
+static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
+                             char *buf)
 {
-        struct device_attribute * dev_attr = to_dev_attr(attr);
-        struct device * dev = to_dev(kobj);
-        ssize_t ret = 0;
+        struct device_attribute *dev_attr = to_dev_attr(attr);
+        struct device *dev = to_dev(kobj);
+        ssize_t ret = -EIO;
 
         if (dev_attr->show)
-                ret = dev_attr->show(dev, buf);
+                ret = dev_attr->show(dev, dev_attr, buf);
+        if (ret >= (ssize_t)PAGE_SIZE) {
+                print_symbol("dev_attr_show: %s returned bad count\n",
+                                (unsigned long)dev_attr->show);
+        }
         return ret;
 }
 
@@ -163,10 +167,9 @@ To read or write attributes, show() or store() methods must be
 specified when declaring the attribute. The method types should be as
 simple as those defined for device attributes:
 
-ssize_t (*show)(struct device * dev, struct device_attribute * attr,
-                char * buf);
-ssize_t (*store)(struct device * dev, struct device_attribute * attr,
-                 const char * buf);
+ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
+ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+                 const char *buf, size_t count);
 
 IOW, they should take only an object, an attribute, and a buffer as parameters.
 
@@ -209,8 +212,8 @@ Other notes:
 
 - show() should always use snprintf(). 
 
-- store() should return the number of bytes used from the buffer. This
-  can be done using strlen().
+- store() should return the number of bytes used from the buffer. If the
+  entire buffer has been used, just return the count argument.
 
 - show() or store() can always return errors. If a bad value comes
   through, be sure to return an error.
@@ -223,15 +226,18 @@ Other notes:
 
 A very simple (and naive) implementation of a device attribute is:
 
-static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_name(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
        return snprintf(buf, PAGE_SIZE, "%s\n", dev->name);
 }
 
-static ssize_t store_name(struct device * dev, const char * buf)
+static ssize_t store_name(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
 {
-       sscanf(buf, "%20s", dev->name);
-       return strnlen(buf, PAGE_SIZE);
+        snprintf(dev->name, sizeof(dev->name), "%.*s",
+                 (int)min(count, sizeof(dev->name) - 1), buf);
+       return count;
 }
 
 static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);
@@ -327,7 +333,7 @@ Structure:
 struct bus_attribute {
         struct attribute        attr;
         ssize_t (*show)(struct bus_type *, char * buf);
-        ssize_t (*store)(struct bus_type *, const char * buf);
+        ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
 };
 
 Declaring:
index 1990130f2ab1bcd7706d3365e18d974bc1e044d2..8143a950b60789ce0b0ae9aab24c8a3d5da5b3d9 100644 (file)
@@ -6,11 +6,12 @@
 
 HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
 
-echo 1 > /sys/$DEVPATH/loading
-cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
-echo 0 > /sys/$DEVPATH/loading
-
-# To cancel the load in case of error:
-#
-#      echo -1 > /sys/$DEVPATH/loading
-#
+if [ "$SUBSYSTEM" == "firmware" -a "$ACTION" == "add" ]; then
+  if [ -f $HOTPLUG_FW_DIR/$FIRMWARE ]; then
+    echo 1 > /sys/$DEVPATH/loading
+    cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
+    echo 0 > /sys/$DEVPATH/loading
+  else
+    echo -1 > /sys/$DEVPATH/loading
+  fi
+fi
diff --git a/Documentation/hwmon/pkgtemp b/Documentation/hwmon/pkgtemp
new file mode 100644 (file)
index 0000000..c8e1fb0
--- /dev/null
@@ -0,0 +1,36 @@
+Kernel driver pkgtemp
+======================
+
+Supported chips:
+  * Intel family
+    Prefix: 'pkgtemp'
+    CPUID:
+    Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
+               Volume 3A: System Programming Guide
+
+Author: Fenghua Yu
+
+Description
+-----------
+
+This driver permits reading package level temperature sensor embedded inside
+Intel CPU package. The sensors can be in core, uncore, memory controller, or
+other components in a package. The feature is first implemented in Intel Sandy
+Bridge platform.
+
+Temperature is measured in degrees Celsius and measurement resolution is
+1 degree C. Valid temperatures are from 0 to TjMax degrees C, because the actual
+value of temperature register is in fact a delta from TjMax.
+
+Temperature known as TjMax is the maximum junction temperature of package.
+We get this from MSR_IA32_TEMPERATURE_TARGET. If the MSR is not accessible,
+we define TjMax as 100 degrees Celsius. At this temperature, protection
+mechanism will perform actions to forcibly cool down the package. Alarm
+may be raised, if the temperature grows enough (more than TjMax) to trigger
+the Out-Of-Spec bit. Following table summarizes the exported sysfs files:
+
+temp1_input      - Package temperature (in millidegrees Celsius).
+temp1_max        - All cooling devices should be turned on.
+temp1_crit       - Maximum junction temperature (in millidegrees Celsius).
+temp1_crit_alarm - Set when Out-of-spec bit is set, never clears.
+                   Correct CPU operation is no longer guaranteed.
index 634c625da8ce3435e23118e442c47d2d5b903898..1e5165aa9e4ef79eb007d39203524722aa7d21bb 100644 (file)
@@ -22,11 +22,33 @@ building C files and assembler files.
 
 KAFLAGS
 --------------------------------------------------
-Additional options to the assembler.
+Additional options to the assembler (for built-in and modules).
+
+AFLAGS_MODULE
+--------------------------------------------------
+Addtional module specific options to use for $(AS).
+
+AFLAGS_KERNEL
+--------------------------------------------------
+Addtional options for $(AS) when used for assembler
+code for code that is compiled as built-in.
 
 KCFLAGS
 --------------------------------------------------
-Additional options to the C compiler.
+Additional options to the C compiler (for built-in and modules).
+
+CFLAGS_KERNEL
+--------------------------------------------------
+Addtional options for $(CC) when used to compile
+code that is compiled as built-in.
+
+CFLAGS_MODULE
+--------------------------------------------------
+Addtional module specific options to use for $(CC).
+
+LDFLAGS_MODULE
+--------------------------------------------------
+Additional options used for $(LD) when linking modules.
 
 KBUILD_VERBOSE
 --------------------------------------------------
@@ -40,15 +62,15 @@ Set the directory to look for the kernel source when building external
 modules.
 The directory can be specified in several ways:
 1) Use "M=..." on the command line
-2) Environmnet variable KBUILD_EXTMOD
-3) Environmnet variable SUBDIRS
+2) Environment variable KBUILD_EXTMOD
+3) Environment variable SUBDIRS
 The possibilities are listed in the order they take precedence.
 Using "M=..." will always override the others.
 
 KBUILD_OUTPUT
 --------------------------------------------------
 Specify the output directory when building the kernel.
-The output directory can also be specificed using "O=...".
+The output directory can also be specified using "O=...".
 Setting "O=..." takes precedence over KBUILD_OUTPUT.
 
 ARCH
@@ -90,7 +112,7 @@ The script will be called with the following arguments:
     $3 - kernel map file
     $4 - default install path (use root directory if blank)
 
-The implmentation of "make install" is architecture specific
+The implementation of "make install" is architecture specific
 and it may differ from the above.
 
 INSTALLKERNEL is provided to enable the possibility to
index b2cb16ebcb161c7cc7751232411982e8deb395df..cca46b1a0f6c2a33f4a39ea87f49a4ae91585c2c 100644 (file)
@@ -65,7 +65,7 @@ also use the environment variable KCONFIG_ALLCONFIG as a flag or a
 filename that contains config symbols that the user requires to be
 set to a specific value.  If KCONFIG_ALLCONFIG is used without a
 filename, "make *config" checks for a file named
-"all{yes/mod/no/random}.config" (corresponding to the *config command
+"all{yes/mod/no/def/random}.config" (corresponding to the *config command
 that was used) for symbol values that are to be forced.  If this file
 is not found, it checks for a file named "all.config" to contain forced
 values.
index 71c602d61680d422694a81c08b0cd4f802e18e7c..c375313cb12882a956364664b22a927bc96b936e 100644 (file)
@@ -168,7 +168,7 @@ more details, with real examples.
                #drivers/isdn/i4l/Makefile
                # Makefile for the kernel ISDN subsystem and device drivers.
                # Each configuration option enables a list of files.
-               obj-$(CONFIG_ISDN)             += isdn.o
+               obj-$(CONFIG_ISDN_I4L)         += isdn.o
                obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
 
 --- 3.3 Loadable module goals - obj-m
@@ -187,34 +187,35 @@ more details, with real examples.
        Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm'
 
        If a kernel module is built from several source files, you specify
-       that you want to build a module in the same way as above.
-
-       Kbuild needs to know which the parts that you want to build your
-       module from, so you have to tell it by setting an
-       $(<module_name>-objs) variable.
+       that you want to build a module in the same way as above; however,
+       kbuild needs to know which object files you want to build your
+       module from, so you have to tell it by setting a $(<module_name>-y)
+       variable.
 
        Example:
                #drivers/isdn/i4l/Makefile
-               obj-$(CONFIG_ISDN) += isdn.o
-               isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
+               obj-$(CONFIG_ISDN_I4L) += isdn.o
+               isdn-y := isdn_net_lib.o isdn_v110.o isdn_common.o
 
        In this example, the module name will be isdn.o. Kbuild will
-       compile the objects listed in $(isdn-objs) and then run
+       compile the objects listed in $(isdn-y) and then run
        "$(LD) -r" on the list of these files to generate isdn.o.
 
-       Kbuild recognises objects used for composite objects by the suffix
-       -objs, and the suffix -y. This allows the Makefiles to use
-       the value of a CONFIG_ symbol to determine if an object is part
-       of a composite object.
+       Due to kbuild recognizing $(<module_name>-y) for composite objects,
+       you can use the value of a CONFIG_ symbol to optionally include an
+       object file as part of a composite object.
 
        Example:
                #fs/ext2/Makefile
-               obj-$(CONFIG_EXT2_FS)        += ext2.o
-               ext2-y                       := balloc.o bitmap.o
-               ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
+               obj-$(CONFIG_EXT2_FS) += ext2.o
+               ext2-y := balloc.o dir.o file.o ialloc.o inode.o ioctl.o \
+                         namei.o super.o symlink.o
+               ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o \
+                                               xattr_trusted.o
 
-       In this example, xattr.o is only part of the composite object
-       ext2.o if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'.
+       In this example, xattr.o, xattr_user.o and xattr_trusted.o are only
+       part of the composite object ext2.o if $(CONFIG_EXT2_FS_XATTR)
+       evaluates to 'y'.
 
        Note: Of course, when you are building objects into the kernel,
        the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
@@ -244,12 +245,12 @@ more details, with real examples.
        may contain both a built-in.o and a lib.a file.
 
        Example:
-               #arch/i386/lib/Makefile
-               lib-y    := checksum.o delay.o
+               #arch/x86/lib/Makefile
+               lib-y    := delay.o
 
-       This will create a library lib.a based on checksum.o and delay.o.
-       For kbuild to actually recognize that there is a lib.a being built,
-       the directory shall be listed in libs-y.
+       This will create a library lib.a based on delay.o. For kbuild to
+       actually recognize that there is a lib.a being built, the directory
+       shall be listed in libs-y.
        See also "6.3 List directories to visit when descending".
 
        Use of lib-y is normally restricted to lib/ and arch/*/lib.
@@ -284,43 +285,40 @@ more details, with real examples.
 --- 3.7 Compilation flags
 
     ccflags-y, asflags-y and ldflags-y
-       The three flags listed above applies only to the kbuild makefile
-       where they are assigned. They are used for all the normal
-       cc, as and ld invocation happenign during a recursive build.
+       These three flags apply only to the kbuild makefile in which they
+       are assigned. They are used for all the normal cc, as and ld
+       invocations happening during a recursive build.
        Note: Flags with the same behaviour were previously named:
        EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS.
-       They are yet supported but their use are deprecated.
+       They are still supported but their usage is deprecated.
 
-       ccflags-y specifies options for compiling C files with $(CC).
+       ccflags-y specifies options for compiling with $(CC).
 
        Example:
-               # drivers/sound/emu10k1/Makefile
-               ccflags-y += -I$(obj)
-               ccflags-$(DEBUG) += -DEMU10K1_DEBUG
-
+               # drivers/acpi/Makefile
+               ccflags-y := -Os
+               ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
 
        This variable is necessary because the top Makefile owns the
        variable $(KBUILD_CFLAGS) and uses it for compilation flags for the
        entire tree.
 
-       asflags-y is a similar string for per-directory options
-       when compiling assembly language source.
+       asflags-y specifies options for assembling with $(AS).
 
        Example:
-               #arch/x86_64/kernel/Makefile
-               asflags-y := -traditional
-
+               #arch/sparc/kernel/Makefile
+               asflags-y := -ansi
 
-       ldflags-y is a string for per-directory options to $(LD).
+       ldflags-y specifies options for linking with $(LD).
 
        Example:
-               #arch/m68k/fpsp040/Makefile
-               ldflags-y := -x
+               #arch/cris/boot/compressed/Makefile
+               ldflags-y += -T $(srctree)/$(src)/decompress_$(arch-y).lds
 
     subdir-ccflags-y, subdir-asflags-y
-       The two flags listed above are similar to ccflags-y and as-falgs-y.
-       The difference is that the subdir- variants has effect for the kbuild
-       file where tey are present and all subdirectories.
+       The two flags listed above are similar to ccflags-y and asflags-y.
+       The difference is that the subdir- variants have effect for the kbuild
+       file where they are present and all subdirectories.
        Options specified using subdir-* are added to the commandline before
        the options specified using the non-subdir variants.
 
@@ -340,18 +338,18 @@ more details, with real examples.
                CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
                CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
                                     -DGDTH_STATISTICS
-               CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
 
-       These three lines specify compilation flags for aha152x.o,
-       gdth.o, and seagate.o
+       These two lines specify compilation flags for aha152x.o and gdth.o.
 
        $(AFLAGS_$@) is a similar feature for source files in assembly
        languages.
 
        Example:
                # arch/arm/kernel/Makefile
-               AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
-               AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
+               AFLAGS_head.o        := -DTEXT_OFFSET=$(TEXT_OFFSET)
+               AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
+               AFLAGS_iwmmxt.o      := -Wa,-mcpu=iwmmxt
+
 
 --- 3.9 Dependency tracking
 
@@ -923,16 +921,33 @@ When kbuild executes, the following steps are followed (roughly):
        The first example utilises the trick that a config option expands
        to 'y' when selected.
 
-    CFLAGS_KERNEL      $(CC) options specific for built-in
+    KBUILD_AFLAGS_KERNEL       $(AS) options specific for built-in
+
+       $(KBUILD_AFLAGS_KERNEL) contains extra C compiler flags used to compile
+       resident kernel code.
+
+    KBUILD_AFLAGS_MODULE   Options for $(AS) when building modules
+
+       $(KBUILD_AFLAGS_MODULE) is used to add arch specific options that
+       are used for $(AS).
+       From commandline AFLAGS_MODULE shall be used (see kbuild.txt).
 
-       $(CFLAGS_KERNEL) contains extra C compiler flags used to compile
+    KBUILD_CFLAGS_KERNEL       $(CC) options specific for built-in
+
+       $(KBUILD_CFLAGS_KERNEL) contains extra C compiler flags used to compile
        resident kernel code.
 
-    CFLAGS_MODULE      $(CC) options specific for modules
+    KBUILD_CFLAGS_MODULE   Options for $(CC) when building modules
+
+       $(KBUILD_CFLAGS_MODULE) is used to add arch specific options that
+       are used for $(CC).
+       From commandline CFLAGS_MODULE shall be used (see kbuild.txt).
 
-       $(CFLAGS_MODULE) contains extra C compiler flags used to compile code
-       for loadable kernel modules.
+    KBUILD_LDFLAGS_MODULE   Options for $(LD) when linking modules
 
+       $(KBUILD_LDFLAGS_MODULE) is used to add arch specific options
+       used when linking modules. This is often a linker script.
+       From commandline LDFLAGS_MODULE shall be used (see kbuild.txt).
 
 --- 6.2 Add prerequisites to archprepare:
 
@@ -1176,14 +1191,14 @@ When kbuild executes, the following steps are followed (roughly):
 === 7 Kbuild syntax for exported headers
 
 The kernel include a set of headers that is exported to userspace.
-Many headers can be exported as-is but other headers require a
+Many headers can be exported as-is but other headers require a
 minimal pre-processing before they are ready for user-space.
 The pre-processing does:
 - drop kernel specific annotations
 - drop include of compiler.h
-- drop all sections that is kernel internat (guarded by ifdef __KERNEL__)
+- drop all sections that are kernel internal (guarded by ifdef __KERNEL__)
 
-Each relevant directory contain a file name "Kbuild" which specify the
+Each relevant directory contains a file name "Kbuild" which specifies the
 headers to be exported.
 See subsequent chapter for the syntax of the Kbuild file.
 
index d9239d5f3ad38ee2aca01e1c6cf25f4c1a6c82a5..71d286307cae64698e016e9ba3fbed79bcc3fdcd 100644 (file)
@@ -73,7 +73,6 @@ parameter is applicable:
        MTD     MTD (Memory Technology Device) support is enabled.
        NET     Appropriate network support is enabled.
        NUMA    NUMA support is enabled.
-       GENERIC_TIME The generic timeofday code is enabled.
        NFS     Appropriate NFS support is enabled.
        OSS     OSS sound support is enabled.
        PV_OPS  A paravirtualized kernel is enabled.
@@ -116,6 +115,7 @@ parameter is applicable:
                        More X86-64 boot options can be found in
                        Documentation/x86/x86_64/boot-options.txt .
        X86     Either 32bit or 64bit x86 (same as X86-32+X86-64)
+       XEN     Xen support is enabled
 
 In addition, the following text indicates that the option:
 
@@ -469,7 +469,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        clocksource is not available, it defaults to PIT.
                        Format: { pit | tsc | cyclone | pmtmr }
 
-       clocksource=    [GENERIC_TIME] Override the default clocksource
+       clocksource=    Override the default clocksource
                        Format: <string>
                        Override the default clocksource and use the clocksource
                        with the name specified.
@@ -1144,9 +1144,12 @@ and is between 256 and 4096 characters. It is defined in the file
        kgdboc=         [KGDB,HW] kgdb over consoles.
                        Requires a tty driver that supports console polling,
                        or a supported polling keyboard driver (non-usb).
-                       Serial only format: <serial_device>[,baud]
-                       keyboard only format: kbd
-                       keyboard and serial format: kbd,<serial_device>[,baud]
+                        Serial only format: <serial_device>[,baud]
+                        keyboard only format: kbd
+                        keyboard and serial format: kbd,<serial_device>[,baud]
+                       Optional Kernel mode setting:
+                        kms, kbd format: kms,kbd
+                        kms, kbd and serial format: kms,kbd,<ser_dev>[,baud]
 
        kgdbwait        [KGDB] Stop kernel execution and enter the
                        kernel debugger at the earliest opportunity.
@@ -1812,6 +1815,8 @@ and is between 256 and 4096 characters. It is defined in the file
 
        nousb           [USB] Disable the USB subsystem
 
+       nowatchdog      [KNL] Disable the lockup detector.
+
        nowb            [ARM]
 
        nox2apic        [X86-64,APIC] Do not enable x2APIC mode.
@@ -1970,6 +1975,8 @@ and is between 256 and 4096 characters. It is defined in the file
                norom           [X86] Do not assign address space to
                                expansion ROMs that do not already have
                                BIOS assigned address ranges.
+               nobar           [X86] Do not assign address space to the
+                               BARs that weren't assigned by the BIOS.
                irqmask=0xMMMM  [X86] Set a bit mask of IRQs allowed to be
                                assigned automatically to PCI devices. You can
                                make the kernel exclude IRQs of your ISA cards
@@ -2886,6 +2893,16 @@ and is between 256 and 4096 characters. It is defined in the file
        xd=             [HW,XT] Original XT pre-IDE (RLL encoded) disks.
        xd_geo=         See header of drivers/block/xd.c.
 
+       xen_emul_unplug=                [HW,X86,XEN]
+                       Unplug Xen emulated devices
+                       Format: [unplug0,][unplug1]
+                       ide-disks -- unplug primary master IDE devices
+                       aux-ide-disks -- unplug non-primary-master IDE devices
+                       nics -- unplug network devices
+                       all -- unplug all emulated devices (NICs and IDE disks)
+                       ignore -- continue loading the Xen platform PCI driver even
+                               if the version check failed
+
        xirc2ps_cs=     [NET,PCMCIA]
                        Format:
                        <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
index 61bc4e94311664ba7d11984620ca68ae8459de98..26c0f9c00545300aeef860eba18422ba79bd2e75 100644 (file)
@@ -1,4 +1,16 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
+* pcmcia_request_io changes (as of 2.6.36)
+   Instead of io_req_t, drivers are now requested to fill out
+   struct pcmcia_device *p_dev->resource[0,1] for up to two ioport
+   ranges. After a call to pcmcia_request_io(), the ports found there
+   are reserved, after calling pcmcia_request_configuration(), they may
+   be used.
+
+* No dev_info_t, no cs_types.h (as of 2.6.36)
+   dev_info_t and a few other typedefs are removed. No longer use them
+   in PCMCIA device drivers. Also, do not include pcmcia/cs_types.h, as
+   this file is gone.
+
 * No dev_node_t (as of 2.6.35)
    There is no more need to fill out a "dev_node_t" structure.
 
diff --git a/Documentation/slow-work.txt b/Documentation/slow-work.txt
deleted file mode 100644 (file)
index 9dbf447..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-                    ====================================
-                    SLOW WORK ITEM EXECUTION THREAD POOL
-                    ====================================
-
-By: David Howells <dhowells@redhat.com>
-
-The slow work item execution thread pool is a pool of threads for performing
-things that take a relatively long time, such as making mkdir calls.
-Typically, when processing something, these items will spend a lot of time
-blocking a thread on I/O, thus making that thread unavailable for doing other
-work.
-
-The standard workqueue model is unsuitable for this class of work item as that
-limits the owner to a single thread or a single thread per CPU.  For some
-tasks, however, more threads - or fewer - are required.
-
-There is just one pool per system.  It contains no threads unless something
-wants to use it - and that something must register its interest first.  When
-the pool is active, the number of threads it contains is dynamic, varying
-between a maximum and minimum setting, depending on the load.
-
-
-====================
-CLASSES OF WORK ITEM
-====================
-
-This pool support two classes of work items:
-
- (*) Slow work items.
-
- (*) Very slow work items.
-
-The former are expected to finish much quicker than the latter.
-
-An operation of the very slow class may do a batch combination of several
-lookups, mkdirs, and a create for instance.
-
-An operation of the ordinarily slow class may, for example, write stuff or
-expand files, provided the time taken to do so isn't too long.
-
-Operations of both types may sleep during execution, thus tying up the thread
-loaned to it.
-
-A further class of work item is available, based on the slow work item class:
-
- (*) Delayed slow work items.
-
-These are slow work items that have a timer to defer queueing of the item for
-a while.
-
-
-THREAD-TO-CLASS ALLOCATION
---------------------------
-
-Not all the threads in the pool are available to work on very slow work items.
-The number will be between one and one fewer than the number of active threads.
-This is configurable (see the "Pool Configuration" section).
-
-All the threads are available to work on ordinarily slow work items, but a
-percentage of the threads will prefer to work on very slow work items.
-
-The configuration ensures that at least one thread will be available to work on
-very slow work items, and at least one thread will be available that won't work
-on very slow work items at all.
-
-
-=====================
-USING SLOW WORK ITEMS
-=====================
-
-Firstly, a module or subsystem wanting to make use of slow work items must
-register its interest:
-
-        int ret = slow_work_register_user(struct module *module);
-
-This will return 0 if successful, or a -ve error upon failure.  The module
-pointer should be the module interested in using this facility (almost
-certainly THIS_MODULE).
-
-
-Slow work items may then be set up by:
-
- (1) Declaring a slow_work struct type variable:
-
-       #include <linux/slow-work.h>
-
-       struct slow_work myitem;
-
- (2) Declaring the operations to be used for this item:
-
-       struct slow_work_ops myitem_ops = {
-               .get_ref = myitem_get_ref,
-               .put_ref = myitem_put_ref,
-               .execute = myitem_execute,
-       };
-
-     [*] For a description of the ops, see section "Item Operations".
-
- (3) Initialising the item:
-
-       slow_work_init(&myitem, &myitem_ops);
-
-     or:
-
-       delayed_slow_work_init(&myitem, &myitem_ops);
-
-     or:
-
-       vslow_work_init(&myitem, &myitem_ops);
-
-     depending on its class.
-
-A suitably set up work item can then be enqueued for processing:
-
-       int ret = slow_work_enqueue(&myitem);
-
-This will return a -ve error if the thread pool is unable to gain a reference
-on the item, 0 otherwise, or (for delayed work):
-
-       int ret = delayed_slow_work_enqueue(&myitem, my_jiffy_delay);
-
-
-The items are reference counted, so there ought to be no need for a flush
-operation.  But as the reference counting is optional, means to cancel
-existing work items are also included:
-
-       cancel_slow_work(&myitem);
-       cancel_delayed_slow_work(&myitem);
-
-can be used to cancel pending work.  The above cancel function waits for
-existing work to have been executed (or prevent execution of them, depending
-on timing).
-
-
-When all a module's slow work items have been processed, and the
-module has no further interest in the facility, it should unregister its
-interest:
-
-       slow_work_unregister_user(struct module *module);
-
-The module pointer is used to wait for all outstanding work items for that
-module before completing the unregistration.  This prevents the put_ref() code
-from being taken away before it completes.  module should almost certainly be
-THIS_MODULE.
-
-
-================
-HELPER FUNCTIONS
-================
-
-The slow-work facility provides a function by which it can be determined
-whether or not an item is queued for later execution:
-
-       bool queued = slow_work_is_queued(struct slow_work *work);
-
-If it returns false, then the item is not on the queue (it may be executing
-with a requeue pending).  This can be used to work out whether an item on which
-another depends is on the queue, thus allowing a dependent item to be queued
-after it.
-
-If the above shows an item on which another depends not to be queued, then the
-owner of the dependent item might need to wait.  However, to avoid locking up
-the threads unnecessarily be sleeping in them, it can make sense under some
-circumstances to return the work item to the queue, thus deferring it until
-some other items have had a chance to make use of the yielded thread.
-
-To yield a thread and defer an item, the work function should simply enqueue
-the work item again and return.  However, this doesn't work if there's nothing
-actually on the queue, as the thread just vacated will jump straight back into
-the item's work function, thus busy waiting on a CPU.
-
-Instead, the item should use the thread to wait for the dependency to go away,
-but rather than using schedule() or schedule_timeout() to sleep, it should use
-the following function:
-
-       bool requeue = slow_work_sleep_till_thread_needed(
-                       struct slow_work *work,
-                       signed long *_timeout);
-
-This will add a second wait and then sleep, such that it will be woken up if
-either something appears on the queue that could usefully make use of the
-thread - and behind which this item can be queued, or if the event the caller
-set up to wait for happens.  True will be returned if something else appeared
-on the queue and this work function should perhaps return, of false if
-something else woke it up.  The timeout is as for schedule_timeout().
-
-For example:
-
-       wq = bit_waitqueue(&my_flags, MY_BIT);
-       init_wait(&wait);
-       requeue = false;
-       do {
-               prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
-               if (!test_bit(MY_BIT, &my_flags))
-                       break;
-               requeue = slow_work_sleep_till_thread_needed(&my_work,
-                                                            &timeout);
-       } while (timeout > 0 && !requeue);
-       finish_wait(wq, &wait);
-       if (!test_bit(MY_BIT, &my_flags)
-               goto do_my_thing;
-       if (requeue)
-               return; // to slow_work
-
-
-===============
-ITEM OPERATIONS
-===============
-
-Each work item requires a table of operations of type struct slow_work_ops.
-Only ->execute() is required; the getting and putting of a reference and the
-describing of an item are all optional.
-
- (*) Get a reference on an item:
-
-       int (*get_ref)(struct slow_work *work);
-
-     This allows the thread pool to attempt to pin an item by getting a
-     reference on it.  This function should return 0 if the reference was
-     granted, or a -ve error otherwise.  If an error is returned,
-     slow_work_enqueue() will fail.
-
-     The reference is held whilst the item is queued and whilst it is being
-     executed.  The item may then be requeued with the same reference held, or
-     the reference will be released.
-
- (*) Release a reference on an item:
-
-       void (*put_ref)(struct slow_work *work);
-
-     This allows the thread pool to unpin an item by releasing the reference on
-     it.  The thread pool will not touch the item again once this has been
-     called.
-
- (*) Execute an item:
-
-       void (*execute)(struct slow_work *work);
-
-     This should perform the work required of the item.  It may sleep, it may
-     perform disk I/O and it may wait for locks.
-
- (*) View an item through /proc:
-
-       void (*desc)(struct slow_work *work, struct seq_file *m);
-
-     If supplied, this should print to 'm' a small string describing the work
-     the item is to do.  This should be no more than about 40 characters, and
-     shouldn't include a newline character.
-
-     See the 'Viewing executing and queued items' section below.
-
-
-==================
-POOL CONFIGURATION
-==================
-
-The slow-work thread pool has a number of configurables:
-
- (*) /proc/sys/kernel/slow-work/min-threads
-
-     The minimum number of threads that should be in the pool whilst it is in
-     use.  This may be anywhere between 2 and max-threads.
-
- (*) /proc/sys/kernel/slow-work/max-threads
-
-     The maximum number of threads that should in the pool.  This may be
-     anywhere between min-threads and 255 or NR_CPUS * 2, whichever is greater.
-
- (*) /proc/sys/kernel/slow-work/vslow-percentage
-
-     The percentage of active threads in the pool that may be used to execute
-     very slow work items.  This may be between 1 and 99.  The resultant number
-     is bounded to between 1 and one fewer than the number of active threads.
-     This ensures there is always at least one thread that can process very
-     slow work items, and always at least one thread that won't.
-
-
-==================================
-VIEWING EXECUTING AND QUEUED ITEMS
-==================================
-
-If CONFIG_SLOW_WORK_DEBUG is enabled, a debugfs file is made available:
-
-       /sys/kernel/debug/slow_work/runqueue
-
-through which the list of work items being executed and the queues of items to
-be executed may be viewed.  The owner of a work item is given the chance to
-add some information of its own.
-
-The contents look something like the following:
-
-    THR PID   ITEM ADDR        FL MARK  DESC
-    === ===== ================ == ===== ==========
-      0  3005 ffff880023f52348  a 952ms FSC: OBJ17d3: LOOK
-      1  3006 ffff880024e33668  2 160ms FSC: OBJ17e5 OP60d3b: Write1/Store fl=2
-      2  3165 ffff8800296dd180  a 424ms FSC: OBJ17e4: LOOK
-      3  4089 ffff8800262c8d78  a 212ms FSC: OBJ17ea: CRTN
-      4  4090 ffff88002792bed8  2 388ms FSC: OBJ17e8 OP60d36: Write1/Store fl=2
-      5  4092 ffff88002a0ef308  2 388ms FSC: OBJ17e7 OP60d2e: Write1/Store fl=2
-      6  4094 ffff88002abaf4b8  2 132ms FSC: OBJ17e2 OP60d4e: Write1/Store fl=2
-      7  4095 ffff88002bb188e0  a 388ms FSC: OBJ17e9: CRTN
-    vsq     - ffff880023d99668  1 308ms FSC: OBJ17e0 OP60f91: Write1/EnQ fl=2
-    vsq     - ffff8800295d1740  1 212ms FSC: OBJ16be OP4d4b6: Write1/EnQ fl=2
-    vsq     - ffff880025ba3308  1 160ms FSC: OBJ179a OP58dec: Write1/EnQ fl=2
-    vsq     - ffff880024ec83e0  1 160ms FSC: OBJ17ae OP599f2: Write1/EnQ fl=2
-    vsq     - ffff880026618e00  1 160ms FSC: OBJ17e6 OP60d33: Write1/EnQ fl=2
-    vsq     - ffff880025a2a4b8  1 132ms FSC: OBJ16a2 OP4d583: Write1/EnQ fl=2
-    vsq     - ffff880023cbe6d8  9 212ms FSC: OBJ17eb: LOOK
-    vsq     - ffff880024d37590  9 212ms FSC: OBJ17ec: LOOK
-    vsq     - ffff880027746cb0  9 212ms FSC: OBJ17ed: LOOK
-    vsq     - ffff880024d37ae8  9 212ms FSC: OBJ17ee: LOOK
-    vsq     - ffff880024d37cb0  9 212ms FSC: OBJ17ef: LOOK
-    vsq     - ffff880025036550  9 212ms FSC: OBJ17f0: LOOK
-    vsq     - ffff8800250368e0  9 212ms FSC: OBJ17f1: LOOK
-    vsq     - ffff880025036aa8  9 212ms FSC: OBJ17f2: LOOK
-
-In the 'THR' column, executing items show the thread they're occupying and
-queued threads indicate which queue they're on.  'PID' shows the process ID of
-a slow-work thread that's executing something.  'FL' shows the work item flags.
-'MARK' indicates how long since an item was queued or began executing.  Lastly,
-the 'DESC' column permits the owner of an item to give some information.
-
diff --git a/Documentation/timers/timers-howto.txt b/Documentation/timers/timers-howto.txt
new file mode 100644 (file)
index 0000000..c9ef29d
--- /dev/null
@@ -0,0 +1,105 @@
+delays - Information on the various kernel delay / sleep mechanisms
+-------------------------------------------------------------------
+
+This document seeks to answer the common question: "What is the
+RightWay (TM) to insert a delay?"
+
+This question is most often faced by driver writers who have to
+deal with hardware delays and who may not be the most intimately
+familiar with the inner workings of the Linux Kernel.
+
+
+Inserting Delays
+----------------
+
+The first, and most important, question you need to ask is "Is my
+code in an atomic context?"  This should be followed closely by "Does
+it really need to delay in atomic context?" If so...
+
+ATOMIC CONTEXT:
+       You must use the *delay family of functions. These
+       functions use the jiffie estimation of clock speed
+       and will busy wait for enough loop cycles to achieve
+       the desired delay:
+
+       ndelay(unsigned long nsecs)
+       udelay(unsigned long usecs)
+       mdelay(unsgined long msecs)
+
+       udelay is the generally preferred API; ndelay-level
+       precision may not actually exist on many non-PC devices.
+
+       mdelay is macro wrapper around udelay, to account for
+       possible overflow when passing large arguments to udelay.
+       In general, use of mdelay is discouraged and code should
+       be refactored to allow for the use of msleep.
+
+NON-ATOMIC CONTEXT:
+       You should use the *sleep[_range] family of functions.
+       There are a few more options here, while any of them may
+       work correctly, using the "right" sleep function will
+       help the scheduler, power management, and just make your
+       driver better :)
+
+       -- Backed by busy-wait loop:
+               udelay(unsigned long usecs)
+       -- Backed by hrtimers:
+               usleep_range(unsigned long min, unsigned long max)
+       -- Backed by jiffies / legacy_timers
+               msleep(unsigned long msecs)
+               msleep_interruptible(unsigned long msecs)
+
+       Unlike the *delay family, the underlying mechanism
+       driving each of these calls varies, thus there are
+       quirks you should be aware of.
+
+
+       SLEEPING FOR "A FEW" USECS ( < ~10us? ):
+               * Use udelay
+
+               - Why not usleep?
+                       On slower systems, (embedded, OR perhaps a speed-
+                       stepped PC!) the overhead of setting up the hrtimers
+                       for usleep *may* not be worth it. Such an evaluation
+                       will obviously depend on your specific situation, but
+                       it is something to be aware of.
+
+       SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms):
+               * Use usleep_range
+
+               - Why not msleep for (1ms - 20ms)?
+                       Explained originally here:
+                               http://lkml.org/lkml/2007/8/3/250
+                       msleep(1~20) may not do what the caller intends, and
+                       will often sleep longer (~20 ms actual sleep for any
+                       value given in the 1~20ms range). In many cases this
+                       is not the desired behavior.
+
+               - Why is there no "usleep" / What is a good range?
+                       Since usleep_range is built on top of hrtimers, the
+                       wakeup will be very precise (ish), thus a simple
+                       usleep function would likely introduce a large number
+                       of undesired interrupts.
+
+                       With the introduction of a range, the scheduler is
+                       free to coalesce your wakeup with any other wakeup
+                       that may have happened for other reasons, or at the
+                       worst case, fire an interrupt for your upper bound.
+
+                       The larger a range you supply, the greater a chance
+                       that you will not trigger an interrupt; this should
+                       be balanced with what is an acceptable upper bound on
+                       delay / performance for your specific code path. Exact
+                       tolerances here are very situation specific, thus it
+                       is left to the caller to determine a reasonable range.
+
+       SLEEPING FOR LARGER MSECS ( 10ms+ )
+               * Use msleep or possibly msleep_interruptible
+
+               - What's the difference?
+                       msleep sets the current task to TASK_UNINTERRUPTIBLE
+                       whereas msleep_interruptible sets the current task to
+                       TASK_INTERRUPTIBLE before scheduling the sleep. In
+                       short, the difference is whether the sleep can be ended
+                       early by a signal. In general, just use msleep unless
+                       you know you have a need for the interruptible variant.
index f1f81afee8a04d19bc69a7231c25a91c0e0f17e0..dc52bd442c92aa11b5c717ad811bcd2f92a169fd 100644 (file)
@@ -13,6 +13,9 @@ Note that this focuses on architecture implementation details only.  If you
 want more explanation of a feature in terms of common code, review the common
 ftrace.txt file.
 
+Ideally, everyone who wishes to retain performance while supporting tracing in
+their kernel should make it all the way to dynamic ftrace support.
+
 
 Prerequisites
 -------------
@@ -215,7 +218,7 @@ An arch may pass in a unique value (frame pointer) to both the entering and
 exiting of a function.  On exit, the value is compared and if it does not
 match, then it will panic the kernel.  This is largely a sanity check for bad
 code generation with gcc.  If gcc for your port sanely updates the frame
-pointer under different opitmization levels, then ignore this option.
+pointer under different optimization levels, then ignore this option.
 
 However, adding support for it isn't terribly difficult.  In your assembly code
 that calls prepare_ftrace_return(), pass the frame pointer as the 3rd argument.
@@ -234,7 +237,7 @@ If you can't trace NMI functions, then skip this option.
 
 
 HAVE_SYSCALL_TRACEPOINTS
----------------------
+------------------------
 
 You need very few things to get the syscalls tracing in an arch.
 
@@ -250,12 +253,152 @@ You need very few things to get the syscalls tracing in an arch.
 HAVE_FTRACE_MCOUNT_RECORD
 -------------------------
 
-See scripts/recordmcount.pl for more info.
+See scripts/recordmcount.pl for more info.  Just fill in the arch-specific
+details for how to locate the addresses of mcount call sites via objdump.
+This option doesn't make much sense without also implementing dynamic ftrace.
 
+
+HAVE_DYNAMIC_FTRACE
+-------------------
+
+You will first need HAVE_FTRACE_MCOUNT_RECORD and HAVE_FUNCTION_TRACER, so
+scroll your reader back up if you got over eager.
+
+Once those are out of the way, you will need to implement:
+       - asm/ftrace.h:
+               - MCOUNT_ADDR
+               - ftrace_call_adjust()
+               - struct dyn_arch_ftrace{}
+       - asm code:
+               - mcount() (new stub)
+               - ftrace_caller()
+               - ftrace_call()
+               - ftrace_stub()
+       - C code:
+               - ftrace_dyn_arch_init()
+               - ftrace_make_nop()
+               - ftrace_make_call()
+               - ftrace_update_ftrace_func()
+
+First you will need to fill out some arch details in your asm/ftrace.h.
+
+Define MCOUNT_ADDR as the address of your mcount symbol similar to:
+       #define MCOUNT_ADDR ((unsigned long)mcount)
+Since no one else will have a decl for that function, you will need to:
+       extern void mcount(void);
+
+You will also need the helper function ftrace_call_adjust().  Most people
+will be able to stub it out like so:
+       static inline unsigned long ftrace_call_adjust(unsigned long addr)
+       {
+               return addr;
+       }
 <details to be filled>
 
+Lastly you will need the custom dyn_arch_ftrace structure.  If you need
+some extra state when runtime patching arbitrary call sites, this is the
+place.  For now though, create an empty struct:
+       struct dyn_arch_ftrace {
+               /* No extra data needed */
+       };
+
+With the header out of the way, we can fill out the assembly code.  While we
+did already create a mcount() function earlier, dynamic ftrace only wants a
+stub function.  This is because the mcount() will only be used during boot
+and then all references to it will be patched out never to return.  Instead,
+the guts of the old mcount() will be used to create a new ftrace_caller()
+function.  Because the two are hard to merge, it will most likely be a lot
+easier to have two separate definitions split up by #ifdefs.  Same goes for
+the ftrace_stub() as that will now be inlined in ftrace_caller().
+
+Before we get confused anymore, let's check out some pseudo code so you can
+implement your own stuff in assembly:
 
-HAVE_DYNAMIC_FTRACE
----------------------
+void mcount(void)
+{
+       return;
+}
+
+void ftrace_caller(void)
+{
+       /* implement HAVE_FUNCTION_TRACE_MCOUNT_TEST if you desire */
+
+       /* save all state needed by the ABI (see paragraph above) */
+
+       unsigned long frompc = ...;
+       unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
+
+ftrace_call:
+       ftrace_stub(frompc, selfpc);
+
+       /* restore all state needed by the ABI */
+
+ftrace_stub:
+       return;
+}
+
+This might look a little odd at first, but keep in mind that we will be runtime
+patching multiple things.  First, only functions that we actually want to trace
+will be patched to call ftrace_caller().  Second, since we only have one tracer
+active at a time, we will patch the ftrace_caller() function itself to call the
+specific tracer in question.  That is the point of the ftrace_call label.
+
+With that in mind, let's move on to the C code that will actually be doing the
+runtime patching.  You'll need a little knowledge of your arch's opcodes in
+order to make it through the next section.
+
+Every arch has an init callback function.  If you need to do something early on
+to initialize some state, this is the time to do that.  Otherwise, this simple
+function below should be sufficient for most people:
+
+int __init ftrace_dyn_arch_init(void *data)
+{
+       /* return value is done indirectly via data */
+       *(unsigned long *)data = 0;
+
+       return 0;
+}
+
+There are two functions that are used to do runtime patching of arbitrary
+functions.  The first is used to turn the mcount call site into a nop (which
+is what helps us retain runtime performance when not tracing).  The second is
+used to turn the mcount call site into a call to an arbitrary location (but
+typically that is ftracer_caller()).  See the general function definition in
+linux/ftrace.h for the functions:
+       ftrace_make_nop()
+       ftrace_make_call()
+The rec->ip value is the address of the mcount call site that was collected
+by the scripts/recordmcount.pl during build time.
+
+The last function is used to do runtime patching of the active tracer.  This
+will be modifying the assembly code at the location of the ftrace_call symbol
+inside of the ftrace_caller() function.  So you should have sufficient padding
+at that location to support the new function calls you'll be inserting.  Some
+people will be using a "call" type instruction while others will be using a
+"branch" type instruction.  Specifically, the function is:
+       ftrace_update_ftrace_func()
+
+
+HAVE_DYNAMIC_FTRACE + HAVE_FUNCTION_GRAPH_TRACER
+------------------------------------------------
+
+The function grapher needs a few tweaks in order to work with dynamic ftrace.
+Basically, you will need to:
+       - update:
+               - ftrace_caller()
+               - ftrace_graph_call()
+               - ftrace_graph_caller()
+       - implement:
+               - ftrace_enable_ftrace_graph_caller()
+               - ftrace_disable_ftrace_graph_caller()
 
 <details to be filled>
+Quick notes:
+       - add a nop stub after the ftrace_call location named ftrace_graph_call;
+         stub needs to be large enough to support a call to ftrace_graph_caller()
+       - update ftrace_graph_caller() to work with being called by the new
+         ftrace_caller() since some semantics may have changed
+       - ftrace_enable_ftrace_graph_caller() will runtime patch the
+         ftrace_graph_call location with a call to ftrace_graph_caller()
+       - ftrace_disable_ftrace_graph_caller() will runtime patch the
+         ftrace_graph_call location with nops
diff --git a/Documentation/trace/kmemtrace.txt b/Documentation/trace/kmemtrace.txt
deleted file mode 100644 (file)
index 6308735..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-                       kmemtrace - Kernel Memory Tracer
-
-                         by Eduard - Gabriel Munteanu
-                            <eduard.munteanu@linux360.ro>
-
-I. Introduction
-===============
-
-kmemtrace helps kernel developers figure out two things:
-1) how different allocators (SLAB, SLUB etc.) perform
-2) how kernel code allocates memory and how much
-
-To do this, we trace every allocation and export information to the userspace
-through the relay interface. We export things such as the number of requested
-bytes, the number of bytes actually allocated (i.e. including internal
-fragmentation), whether this is a slab allocation or a plain kmalloc() and so
-on.
-
-The actual analysis is performed by a userspace tool (see section III for
-details on where to get it from). It logs the data exported by the kernel,
-processes it and (as of writing this) can provide the following information:
-- the total amount of memory allocated and fragmentation per call-site
-- the amount of memory allocated and fragmentation per allocation
-- total memory allocated and fragmentation in the collected dataset
-- number of cross-CPU allocation and frees (makes sense in NUMA environments)
-
-Moreover, it can potentially find inconsistent and erroneous behavior in
-kernel code, such as using slab free functions on kmalloc'ed memory or
-allocating less memory than requested (but not truly failed allocations).
-
-kmemtrace also makes provisions for tracing on some arch and analysing the
-data on another.
-
-II. Design and goals
-====================
-
-kmemtrace was designed to handle rather large amounts of data. Thus, it uses
-the relay interface to export whatever is logged to userspace, which then
-stores it. Analysis and reporting is done asynchronously, that is, after the
-data is collected and stored. By design, it allows one to log and analyse
-on different machines and different arches.
-
-As of writing this, the ABI is not considered stable, though it might not
-change much. However, no guarantees are made about compatibility yet. When
-deemed stable, the ABI should still allow easy extension while maintaining
-backward compatibility. This is described further in Documentation/ABI.
-
-Summary of design goals:
-       - allow logging and analysis to be done across different machines
-       - be fast and anticipate usage in high-load environments (*)
-       - be reasonably extensible
-       - make it possible for GNU/Linux distributions to have kmemtrace
-       included in their repositories
-
-(*) - one of the reasons Pekka Enberg's original userspace data analysis
-    tool's code was rewritten from Perl to C (although this is more than a
-    simple conversion)
-
-
-III. Quick usage guide
-======================
-
-1) Get a kernel that supports kmemtrace and build it accordingly (i.e. enable
-CONFIG_KMEMTRACE).
-
-2) Get the userspace tool and build it:
-$ git clone git://repo.or.cz/kmemtrace-user.git                # current repository
-$ cd kmemtrace-user/
-$ ./autogen.sh
-$ ./configure
-$ make
-
-3) Boot the kmemtrace-enabled kernel if you haven't, preferably in the
-'single' runlevel (so that relay buffers don't fill up easily), and run
-kmemtrace:
-# '$' does not mean user, but root here.
-$ mount -t debugfs none /sys/kernel/debug
-$ mount -t proc none /proc
-$ cd path/to/kmemtrace-user/
-$ ./kmemtraced
-Wait a bit, then stop it with CTRL+C.
-$ cat /sys/kernel/debug/kmemtrace/total_overruns       # Check if we didn't
-                                                       # overrun, should
-                                                       # be zero.
-$ (Optionally) [Run kmemtrace_check separately on each cpu[0-9]*.out file to
-               check its correctness]
-$ ./kmemtrace-report
-
-Now you should have a nice and short summary of how the allocator performs.
-
-IV. FAQ and known issues
-========================
-
-Q: 'cat /sys/kernel/debug/kmemtrace/total_overruns' is non-zero, how do I fix
-this? Should I worry?
-A: If it's non-zero, this affects kmemtrace's accuracy, depending on how
-large the number is. You can fix it by supplying a higher
-'kmemtrace.subbufs=N' kernel parameter.
----
-
-Q: kmemtrace_check reports errors, how do I fix this? Should I worry?
-A: This is a bug and should be reported. It can occur for a variety of
-reasons:
-       - possible bugs in relay code
-       - possible misuse of relay by kmemtrace
-       - timestamps being collected unorderly
-Or you may fix it yourself and send us a patch.
----
-
-Q: kmemtrace_report shows many errors, how do I fix this? Should I worry?
-A: This is a known issue and I'm working on it. These might be true errors
-in kernel code, which may have inconsistent behavior (e.g. allocating memory
-with kmem_cache_alloc() and freeing it with kfree()). Pekka Enberg pointed
-out this behavior may work with SLAB, but may fail with other allocators.
-
-It may also be due to lack of tracing in some unusual allocator functions.
-
-We don't want bug reports regarding this issue yet.
----
-
-V. See also
-===========
-
-Documentation/kernel-parameters.txt
-Documentation/ABI/testing/debugfs-kmemtrace
-
index ec94748ae65bf1c55c1359c5c9d71aac714b2e5e..5f77d94598dd577aca9a9f36c9cdee13ca86fec6 100644 (file)
@@ -42,7 +42,7 @@ Synopsis of kprobe_events
   +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
   NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
   FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
-                 (u8/u16/u32/u64/s8/s16/s32/s64) are supported.
+                 (u8/u16/u32/u64/s8/s16/s32/s64) and string are supported.
 
   (*) only for return probe.
   (**) this is useful for fetching a field of data structures.
index 66e9358e2144233323e8b90ce75f9007999e7b2f..ccd951fa94eeda42a5a50c854b6b92e512fe6724 100644 (file)
@@ -694,7 +694,7 @@ static void usage(void)
 #endif
 "            -l|--list                  Show page details in ranges\n"
 "            -L|--list-each             Show page details one by one\n"
-"            -N|--no-summary            Don't show summay info\n"
+"            -N|--no-summary            Don't show summary info\n"
 "            -X|--hwpoison              hwpoison pages\n"
 "            -x|--unpoison              unpoison pages\n"
 "            -h|--help                  Show this usage message\n"
index feb37e177010517f8f1f1d1edee3a96ed77f793f..cf5437deda81a003864f9e8a5f4e533d276a189d 100644 (file)
@@ -18,6 +18,7 @@ Offset        Proto   Name            Meaning
 080/010        ALL     hd0_info        hd0 disk parameter, OBSOLETE!!
 090/010        ALL     hd1_info        hd1 disk parameter, OBSOLETE!!
 0A0/010        ALL     sys_desc_table  System description table (struct sys_desc_table)
+0B0/010        ALL     olpc_ofw_header OLPC's OpenFirmware CIF and friends
 140/080        ALL     edid_info       Video mode setup (struct edid_info)
 1C0/020        ALL     efi_info        EFI 32 information (struct efi_info)
 1E0/004        ALL     alk_mem_k       Alternative mem check, in KB
index 05741e0da46cd277ec32cce394b9c55e5a0e5076..100a3f535c9f579be993d6833b1a5939cc158b91 100644 (file)
@@ -1569,6 +1569,16 @@ L:       platform-driver-x86@vger.kernel.org
 S:     Supported
 F:     drivers/platform/x86/classmate-laptop.c
 
+COCCINELLE/Semantic Patches (SmPL)
+M:     Julia Lawall <julia@diku.dk>
+M:     Gilles Muller <Gilles.Muller@lip6.fr>
+M:     Nicolas Palix <npalix@diku.dk>
+L:     cocci@diku.dk (moderated for non-subscribers)
+W:     http://coccinelle.lip6.fr/
+S:     Supported
+F:     scripts/coccinelle/
+F:     scripts/coccicheck
+
 CODA FILE SYSTEM
 M:     Jan Harkes <jaharkes@cs.cmu.edu>
 M:     coda@cs.cmu.edu
@@ -3266,8 +3276,8 @@ F:        fs/autofs4/
 
 KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
 M:     Michal Marek <mmarek@suse.cz>
-T:     git git://repo.or.cz/linux-kbuild.git for-next
-T:     git git://repo.or.cz/linux-kbuild.git for-linus
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git for-next
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git rc-fixes
 L:     linux-kbuild@vger.kernel.org
 S:     Maintained
 F:     Documentation/kbuild/
@@ -3393,13 +3403,6 @@ F:       include/linux/kmemleak.h
 F:     mm/kmemleak.c
 F:     mm/kmemleak-test.c
 
-KMEMTRACE
-M:     Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
-S:     Maintained
-F:     Documentation/trace/kmemtrace.txt
-F:     include/linux/kmemtrace.h
-F:     kernel/trace/kmemtrace.c
-
 KPROBES
 M:     Ananth N Mavinakayanahalli <ananth@in.ibm.com>
 M:     Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
@@ -5675,7 +5678,7 @@ TRACING
 M:     Steven Rostedt <rostedt@goodmis.org>
 M:     Frederic Weisbecker <fweisbec@gmail.com>
 M:     Ingo Molnar <mingo@redhat.com>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git perf/core
 S:     Maintained
 F:     Documentation/trace/ftrace.txt
 F:     arch/*/*/*/ftrace.h
index 141da26fda4b87870ba19237f61ced915d0cebcb..7431c283f15b3efaed73050a0c33d721a9fc8a57 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -332,10 +332,9 @@ CHECK              = sparse
 
 CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
                  -Wbitwise -Wno-return-void $(CF)
-MODFLAGS       = -DMODULE
-CFLAGS_MODULE   = $(MODFLAGS)
-AFLAGS_MODULE   = $(MODFLAGS)
-LDFLAGS_MODULE  = -T $(srctree)/scripts/module-common.lds
+CFLAGS_MODULE   =
+AFLAGS_MODULE   =
+LDFLAGS_MODULE  =
 CFLAGS_KERNEL  =
 AFLAGS_KERNEL  =
 CFLAGS_GCOV    = -fprofile-arcs -ftest-coverage
@@ -354,7 +353,12 @@ KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -Werror-implicit-function-declaration \
                   -Wno-format-security \
                   -fno-delete-null-pointer-checks
+KBUILD_AFLAGS_KERNEL :=
+KBUILD_CFLAGS_KERNEL :=
 KBUILD_AFLAGS   := -D__ASSEMBLY__
+KBUILD_AFLAGS_MODULE  := -DMODULE
+KBUILD_CFLAGS_MODULE  := -DMODULE
+KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
 
 # Read KERNELRELEASE from include/config/kernel.release (if it exists)
 KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
@@ -369,6 +373,8 @@ export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
 export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
+export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
 
 # When compiling out-of-tree modules, put MODVERDIR in the module
 # tree rather than in the kernel tree. The kernel tree might
@@ -412,9 +418,9 @@ endif
 # of make so .config is not included in this case either (for *config).
 
 no-dot-config-targets := clean mrproper distclean \
-                        cscope TAGS tags help %docs check% \
+                        cscope TAGS tags help %docs check% coccicheck \
                         include/linux/version.h headers_% \
-                        kernelrelease kernelversion
+                        kernelversion %src-pkg
 
 config-targets := 0
 mixed-targets  := 0
@@ -526,7 +532,7 @@ endif # $(dot-config)
 # The all: target is the default when no target is given on the
 # command line.
 # This allow a user to issue only 'make' to build a kernel including modules
-# Defaults vmlinux but it is usually overridden in the arch makefile
+# Defaults to vmlinux, but the arch makefile usually adds further targets
 all: vmlinux
 
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
@@ -557,6 +563,10 @@ KBUILD_CFLAGS      += -g
 KBUILD_AFLAGS  += -gdwarf-2
 endif
 
+ifdef CONFIG_DEBUG_INFO_REDUCED
+KBUILD_CFLAGS  += $(call cc-option, -femit-struct-debug-baseonly)
+endif
+
 ifdef CONFIG_FUNCTION_TRACER
 KBUILD_CFLAGS  += -pg
 endif
@@ -603,7 +613,7 @@ endif
 # Use --build-id when available.
 LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
                              $(call cc-ldoption, -Wl$(comma)--build-id,))
-LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
+KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
 LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
 
 ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
@@ -1158,6 +1168,8 @@ distclean: mrproper
 # rpm target kept for backward compatibility
 package-dir    := $(srctree)/scripts/package
 
+%src-pkg: FORCE
+       $(Q)$(MAKE) $(build)=$(package-dir) $@
 %pkg: include/config/kernel.release FORCE
        $(Q)$(MAKE) $(build)=$(package-dir) $@
 rpm: include/config/kernel.release FORCE
@@ -1209,8 +1221,9 @@ help:
        @echo  '  includecheck    - Check for duplicate included header files'
        @echo  '  export_report   - List the usages of all exported symbols'
        @echo  '  headers_check   - Sanity check on exported headers'
-       @echo  '  headerdep       - Detect inclusion cycles in headers'; \
-        echo  ''
+       @echo  '  headerdep       - Detect inclusion cycles in headers'
+       @$(MAKE) -f $(srctree)/scripts/Makefile.help checker-help
+       @echo  ''
        @echo  'Kernel packaging:'
        @$(MAKE) $(build)=$(package-dir) help
        @echo  ''
@@ -1369,6 +1382,9 @@ versioncheck:
                -name '*.[hcS]' -type f -print | sort \
                | xargs $(PERL) -w $(srctree)/scripts/checkversion.pl
 
+coccicheck:
+       $(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@
+
 namespacecheck:
        $(PERL) $(srctree)/scripts/namespace.pl
 
@@ -1393,9 +1409,9 @@ checkstack:
        $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
        $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH)
 
-kernelrelease:
-       $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
-       $(error kernelrelease not valid - run 'make prepare' to update it))
+kernelrelease: include/config/kernel.release
+       @echo $(KERNELRELEASE)
+
 kernelversion:
        @echo $(KERNELVERSION)
 
@@ -1472,6 +1488,7 @@ cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
                   $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
 
 a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
+         $(KBUILD_AFLAGS_KERNEL)                              \
          $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CPPFLAGS) \
          $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
 
index acda512da2e21b52a972bb4255404fab3fce7015..4877a8c8ee1697599289f35107824f95ba8daf84 100644 (file)
@@ -151,4 +151,11 @@ config HAVE_MIXED_BREAKPOINTS_REGS
 config HAVE_USER_RETURN_NOTIFIER
        bool
 
+config HAVE_PERF_EVENTS_NMI
+       bool
+       help
+         System hardware can generate an NMI using the perf event
+         subsystem.  Also has support for calculating CPU cycle events
+         to determine how many clock cycles in a given period.
+
 source "kernel/gcov/Kconfig"
index 3e2e540a0f2a85ce92aa0a70f604bc4a461c3517..b9647bb66d1388d9c13503748252c2a1df4ac830 100644 (file)
@@ -47,10 +47,6 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
-config GENERIC_TIME
-       bool
-       default y
-
 config GENERIC_CMOS_UPDATE
         def_bool y
 
diff --git a/arch/alpha/include/asm/local64.h b/arch/alpha/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index e39caa8b0c93e323c9c1e2feda7bb90fd1a3a4a1..9e10882c81d7746e06f0908cb5ce0198e2d2654d 100644 (file)
@@ -43,10 +43,6 @@ config SYS_SUPPORTS_APM_EMULATION
 config GENERIC_GPIO
        bool
 
-config GENERIC_TIME
-       bool
-       default y
-
 config ARCH_USES_GETTIMEOFFSET
        bool
        default n
index 67af4b841984e44cab60be11686c423fe58a76f9..08265993227fc1d03bec79f7a420f63c005a3f2c 100644 (file)
@@ -70,11 +70,11 @@ extern int kgdb_fault_expected;
 #define _GP_REGS               16
 #define _FP_REGS               8
 #define _EXTRA_REGS            2
-#define GDB_MAX_REGS           (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define DBG_MAX_REG_NUM                (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
 
 #define KGDB_MAX_NO_CPUS       1
 #define BUFMAX                 400
-#define NUMREGBYTES            (GDB_MAX_REGS << 2)
+#define NUMREGBYTES            (DBG_MAX_REG_NUM << 2)
 #define NUMCRITREGBYTES                (32 << 2)
 
 #define _R0                    0
@@ -93,7 +93,7 @@ extern int kgdb_fault_expected;
 #define _SPT                   13
 #define _LR                    14
 #define _PC                    15
-#define _CPSR                  (GDB_MAX_REGS - 1)
+#define _CPSR                  (DBG_MAX_REG_NUM - 1)
 
 /*
  * So that we can denote the end of a frame for tracing,
diff --git a/arch/arm/include/asm/local64.h b/arch/arm/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index c868a8864117bbf0f3330ebd80150f263a3200ed..778c2f7024ff57304227ce67665e749f39b05fc7 100644 (file)
  *           Deepak Saxena <dsaxena@plexity.net>
  */
 #include <linux/irq.h>
+#include <linux/kdebug.h>
 #include <linux/kgdb.h>
 #include <asm/traps.h>
 
-/* Make a local copy of the registers passed into the handler (bletch) */
-void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
 {
-       int regno;
-
-       /* Initialize all to zero. */
-       for (regno = 0; regno < GDB_MAX_REGS; regno++)
-               gdb_regs[regno] = 0;
+       { "r0", 4, offsetof(struct pt_regs, ARM_r0)},
+       { "r1", 4, offsetof(struct pt_regs, ARM_r1)},
+       { "r2", 4, offsetof(struct pt_regs, ARM_r2)},
+       { "r3", 4, offsetof(struct pt_regs, ARM_r3)},
+       { "r4", 4, offsetof(struct pt_regs, ARM_r4)},
+       { "r5", 4, offsetof(struct pt_regs, ARM_r5)},
+       { "r6", 4, offsetof(struct pt_regs, ARM_r6)},
+       { "r7", 4, offsetof(struct pt_regs, ARM_r7)},
+       { "r8", 4, offsetof(struct pt_regs, ARM_r8)},
+       { "r9", 4, offsetof(struct pt_regs, ARM_r9)},
+       { "r10", 4, offsetof(struct pt_regs, ARM_r10)},
+       { "fp", 4, offsetof(struct pt_regs, ARM_fp)},
+       { "ip", 4, offsetof(struct pt_regs, ARM_ip)},
+       { "sp", 4, offsetof(struct pt_regs, ARM_sp)},
+       { "lr", 4, offsetof(struct pt_regs, ARM_lr)},
+       { "pc", 4, offsetof(struct pt_regs, ARM_pc)},
+       { "f0", 12, -1 },
+       { "f1", 12, -1 },
+       { "f2", 12, -1 },
+       { "f3", 12, -1 },
+       { "f4", 12, -1 },
+       { "f5", 12, -1 },
+       { "f6", 12, -1 },
+       { "f7", 12, -1 },
+       { "fps", 4, -1 },
+       { "cpsr", 4, offsetof(struct pt_regs, ARM_cpsr)},
+};
 
-       gdb_regs[_R0]           = kernel_regs->ARM_r0;
-       gdb_regs[_R1]           = kernel_regs->ARM_r1;
-       gdb_regs[_R2]           = kernel_regs->ARM_r2;
-       gdb_regs[_R3]           = kernel_regs->ARM_r3;
-       gdb_regs[_R4]           = kernel_regs->ARM_r4;
-       gdb_regs[_R5]           = kernel_regs->ARM_r5;
-       gdb_regs[_R6]           = kernel_regs->ARM_r6;
-       gdb_regs[_R7]           = kernel_regs->ARM_r7;
-       gdb_regs[_R8]           = kernel_regs->ARM_r8;
-       gdb_regs[_R9]           = kernel_regs->ARM_r9;
-       gdb_regs[_R10]          = kernel_regs->ARM_r10;
-       gdb_regs[_FP]           = kernel_regs->ARM_fp;
-       gdb_regs[_IP]           = kernel_regs->ARM_ip;
-       gdb_regs[_SPT]          = kernel_regs->ARM_sp;
-       gdb_regs[_LR]           = kernel_regs->ARM_lr;
-       gdb_regs[_PC]           = kernel_regs->ARM_pc;
-       gdb_regs[_CPSR]         = kernel_regs->ARM_cpsr;
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return NULL;
+
+       if (dbg_reg_def[regno].offset != -1)
+               memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+                      dbg_reg_def[regno].size);
+       else
+               memset(mem, 0, dbg_reg_def[regno].size);
+       return dbg_reg_def[regno].name;
 }
 
-/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
-void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
 {
-       kernel_regs->ARM_r0     = gdb_regs[_R0];
-       kernel_regs->ARM_r1     = gdb_regs[_R1];
-       kernel_regs->ARM_r2     = gdb_regs[_R2];
-       kernel_regs->ARM_r3     = gdb_regs[_R3];
-       kernel_regs->ARM_r4     = gdb_regs[_R4];
-       kernel_regs->ARM_r5     = gdb_regs[_R5];
-       kernel_regs->ARM_r6     = gdb_regs[_R6];
-       kernel_regs->ARM_r7     = gdb_regs[_R7];
-       kernel_regs->ARM_r8     = gdb_regs[_R8];
-       kernel_regs->ARM_r9     = gdb_regs[_R9];
-       kernel_regs->ARM_r10    = gdb_regs[_R10];
-       kernel_regs->ARM_fp     = gdb_regs[_FP];
-       kernel_regs->ARM_ip     = gdb_regs[_IP];
-       kernel_regs->ARM_sp     = gdb_regs[_SPT];
-       kernel_regs->ARM_lr     = gdb_regs[_LR];
-       kernel_regs->ARM_pc     = gdb_regs[_PC];
-       kernel_regs->ARM_cpsr   = gdb_regs[_CPSR];
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return -EINVAL;
+
+       if (dbg_reg_def[regno].offset != -1)
+               memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+                      dbg_reg_def[regno].size);
+       return 0;
 }
 
 void
@@ -176,6 +181,33 @@ void kgdb_roundup_cpus(unsigned long flags)
        local_irq_disable();
 }
 
+static int __kgdb_notify(struct die_args *args, unsigned long cmd)
+{
+       struct pt_regs *regs = args->regs;
+
+       if (kgdb_handle_exception(1, args->signr, cmd, regs))
+               return NOTIFY_DONE;
+       return NOTIFY_STOP;
+}
+static int
+kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
+{
+       unsigned long flags;
+       int ret;
+
+       local_irq_save(flags);
+       ret = __kgdb_notify(ptr, cmd);
+       local_irq_restore(flags);
+
+       return ret;
+}
+
+static struct notifier_block kgdb_notifier = {
+       .notifier_call  = kgdb_notify,
+       .priority       = -INT_MAX,
+};
+
+
 /**
  *     kgdb_arch_init - Perform any architecture specific initalization.
  *
@@ -184,6 +216,11 @@ void kgdb_roundup_cpus(unsigned long flags)
  */
 int kgdb_arch_init(void)
 {
+       int ret = register_die_notifier(&kgdb_notifier);
+
+       if (ret != 0)
+               return ret;
+
        register_undef_hook(&kgdb_brkpt_hook);
        register_undef_hook(&kgdb_compiled_brkpt_hook);
 
@@ -200,6 +237,7 @@ void kgdb_arch_exit(void)
 {
        unregister_undef_hook(&kgdb_brkpt_hook);
        unregister_undef_hook(&kgdb_compiled_brkpt_hook);
+       unregister_die_notifier(&kgdb_notifier);
 }
 
 /*
index de12536d687f69a6fa246038afe9754936d223d9..417c392ddf1cb55066fa5f99e83e77514bd89901 100644 (file)
@@ -164,20 +164,20 @@ armpmu_event_set_period(struct perf_event *event,
                        struct hw_perf_event *hwc,
                        int idx)
 {
-       s64 left = atomic64_read(&hwc->period_left);
+       s64 left = local64_read(&hwc->period_left);
        s64 period = hwc->sample_period;
        int ret = 0;
 
        if (unlikely(left <= -period)) {
                left = period;
-               atomic64_set(&hwc->period_left, left);
+               local64_set(&hwc->period_left, left);
                hwc->last_period = period;
                ret = 1;
        }
 
        if (unlikely(left <= 0)) {
                left += period;
-               atomic64_set(&hwc->period_left, left);
+               local64_set(&hwc->period_left, left);
                hwc->last_period = period;
                ret = 1;
        }
@@ -185,7 +185,7 @@ armpmu_event_set_period(struct perf_event *event,
        if (left > (s64)armpmu->max_period)
                left = armpmu->max_period;
 
-       atomic64_set(&hwc->prev_count, (u64)-left);
+       local64_set(&hwc->prev_count, (u64)-left);
 
        armpmu->write_counter(idx, (u64)(-left) & 0xffffffff);
 
@@ -204,18 +204,18 @@ armpmu_event_update(struct perf_event *event,
        u64 delta;
 
 again:
-       prev_raw_count = atomic64_read(&hwc->prev_count);
+       prev_raw_count = local64_read(&hwc->prev_count);
        new_raw_count = armpmu->read_counter(idx);
 
-       if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+       if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
                             new_raw_count) != prev_raw_count)
                goto again;
 
        delta = (new_raw_count << shift) - (prev_raw_count << shift);
        delta >>= shift;
 
-       atomic64_add(delta, &event->count);
-       atomic64_sub(delta, &hwc->period_left);
+       local64_add(delta, &event->count);
+       local64_sub(delta, &hwc->period_left);
 
        return new_raw_count;
 }
@@ -478,7 +478,7 @@ __hw_perf_event_init(struct perf_event *event)
        if (!hwc->sample_period) {
                hwc->sample_period  = armpmu->max_period;
                hwc->last_period    = hwc->sample_period;
-               atomic64_set(&hwc->period_left, hwc->sample_period);
+               local64_set(&hwc->period_left, hwc->sample_period);
        }
 
        err = 0;
index f2b3193331841b7ecec7263658de1590da42a9cc..f51572772e217d5ba9b674ffa2a5d68e5f13ca00 100644 (file)
@@ -45,9 +45,6 @@ config GENERIC_IRQ_PROBE
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_CLOCKEVENTS
        def_bool y
 
index ead8a75203a98e6dc94276c148871929fa452539..22fb66590dcd0e6f7339c9723a9128eb078cdb06 100644 (file)
@@ -13,7 +13,7 @@ KBUILD_DEFCONFIG      := atstk1002_defconfig
 
 KBUILD_CFLAGS  += -pipe -fno-builtin -mno-pic
 KBUILD_AFLAGS  += -mrelax -mno-pic
-CFLAGS_MODULE  += -mno-relax
+KBUILD_CFLAGS_MODULE += -mno-relax
 LDFLAGS_vmlinux        += --relax
 
 cpuflags-$(CONFIG_PLATFORM_AT32AP)     += -march=ap
diff --git a/arch/avr32/include/asm/local64.h b/arch/avr32/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index f66294b4f9d29d31fbec1075aabf3483be352309..c88fd3584122780dc32f8484901a7e38e460b988 100644 (file)
@@ -614,9 +614,6 @@ comment "Kernel Timer/Scheduler"
 
 source kernel/Kconfig.hz
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_CLOCKEVENTS
        bool "Generic clock events"
        default y
index 5a97a31d4bbd55f7d16b1f3e78def86a19a66906..9d5ffaf5492a2f749bd9d9a880956db46a0022f2 100644 (file)
@@ -18,8 +18,8 @@ ifeq ($(CONFIG_ROMKERNEL),y)
 KBUILD_CFLAGS           += -mlong-calls
 endif
 KBUILD_AFLAGS           += $(call cc-option,-mno-fdpic)
-CFLAGS_MODULE    += -mlong-calls
-LDFLAGS_MODULE   += -m elf32bfin
+KBUILD_CFLAGS_MODULE    += -mlong-calls
+KBUILD_LDFLAGS_MODULE   += -m elf32bfin
 KALLSYMS         += --symbol-prefix=_
 
 KBUILD_DEFCONFIG := BF537-STAMP_defconfig
diff --git a/arch/blackfin/include/asm/local64.h b/arch/blackfin/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index e25bf4440b513d215ae183736268178143289b1d..887ef855be2a59c0a61f513cfeaafc2df72cd802 100644 (file)
@@ -20,9 +20,6 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_CMOS_UPDATE
        def_bool y
 
diff --git a/arch/cris/include/asm/local64.h b/arch/cris/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 4b5830bcbe2e21d25f7eca0f4395a7b54b354d07..16399bd249930c1a9e2e06f7d0da247b288b6d34 100644 (file)
@@ -40,10 +40,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
        bool
        default y
 
-config GENERIC_TIME
-       bool
-       default y
-
 config TIME_LOW_RES
        bool
        default y
index 310c47a663f8ffc4d9f038494e49fcc44505cbc8..7ff84575b1865a21c3f97e86b710a303a5cf8347 100644 (file)
 # Copyright (C) 1994 by Hamish Macdonald
 #
 
-CCSPECS        := $(shell $(CC) -v 2>&1 | grep "^Reading specs from " | head -1 | cut -c20-)
-CCDIR  := $(strip $(patsubst %/specs,%,$(CCSPECS)))
-CPUCLASS := fr400
-
-# test for cross compiling
-COMPILE_ARCH = $(shell uname -m)
-
 ifdef CONFIG_MMU
 UTS_SYSNAME = -DUTS_SYSNAME=\"Linux\"
 else
 UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
 endif
 
-ARCHMODFLAGS   += -G0 -mlong-calls
+KBUILD_AFLAGS_MODULE += -G0 -mlong-calls
+KBUILD_CFLAGS_MODULE += -G0 -mlong-calls
 
 ifdef CONFIG_GPREL_DATA_8
 KBUILD_CFLAGS  += -G8
@@ -54,7 +48,6 @@ endif
 
 ifdef CONFIG_GC_SECTIONS
 KBUILD_CFLAGS  += -ffunction-sections -fdata-sections
-LINKFLAGS      += --gc-sections
 endif
 
 ifndef CONFIG_FRAME_POINTER
@@ -64,16 +57,13 @@ endif
 ifdef CONFIG_CPU_FR451_COMPILE
 KBUILD_CFLAGS  += -mcpu=fr450
 KBUILD_AFLAGS  += -mcpu=fr450
-ASFLAGS                += -mcpu=fr450
 else
 ifdef CONFIG_CPU_FR551_COMPILE
 KBUILD_CFLAGS  += -mcpu=fr550
 KBUILD_AFLAGS  += -mcpu=fr550
-ASFLAGS                += -mcpu=fr550
 else
 KBUILD_CFLAGS  += -mcpu=fr400
 KBUILD_AFLAGS  += -mcpu=fr400
-ASFLAGS                += -mcpu=fr400
 endif
 endif
 
@@ -83,14 +73,12 @@ endif
 KBUILD_CFLAGS  += -mno-fdpic -mgpr-32 -msoft-float -mno-media
 KBUILD_CFLAGS  += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2
 KBUILD_AFLAGS  += -mno-fdpic
-ASFLAGS                += -mno-fdpic
 
 # make sure the .S files get compiled with debug info
 # and disable optimisations that are unhelpful whilst debugging
 ifdef CONFIG_DEBUG_INFO
 #KBUILD_CFLAGS += -O1
 KBUILD_AFLAGS  += -Wa,--gdwarf2
-ASFLAGS                += -Wa,--gdwarf2
 endif
 
 head-y         := arch/frv/kernel/head.o arch/frv/kernel/init_task.o
@@ -105,11 +93,5 @@ all: Image
 Image: vmlinux
        $(Q)$(MAKE) $(build)=arch/frv/boot $@
 
-bootstrap:
-       $(Q)$(MAKEBOOT) bootstrap
-
 archclean:
        $(Q)$(MAKE) $(clean)=arch/frv/boot
-
-archdep: scripts/mkdep symlinks
-       $(Q)$(MAKE) $(build)=arch/frv/boot dep
diff --git a/arch/frv/include/asm/local64.h b/arch/frv/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/frv/kernel/local64.h b/arch/frv/kernel/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 53cc669e6d591e94891753fcd375e47fe5e9173b..988b6ff34cc4df77caed6cff53d093ab841c31f0 100644 (file)
@@ -62,10 +62,6 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
-config GENERIC_TIME
-       bool
-       default y
-
 config GENERIC_BUG
         bool
         depends on BUG
diff --git a/arch/h8300/include/asm/local64.h b/arch/h8300/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 95610820041ea33bf76f9097fcab9d2312a475ea..8711d13cd79f3e1a354115b467b83c13c738ef02 100644 (file)
@@ -82,10 +82,6 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
-config GENERIC_TIME
-       bool
-       default y
-
 config GENERIC_TIME_VSYSCALL
        bool
        default y
index 8ae0d2604ce1201bfe4156b70cc5a47344e8eff7..be7bfa12b7053263e903dd70e247a365fd05f917 100644 (file)
@@ -22,13 +22,13 @@ CHECKFLAGS  += -m64 -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__
 
 OBJCOPYFLAGS   := --strip-all
 LDFLAGS_vmlinux        := -static
-LDFLAGS_MODULE += -T $(srctree)/arch/ia64/module.lds
-AFLAGS_KERNEL  := -mconstant-gp
+KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/ia64/module.lds
+KBUILD_AFLAGS_KERNEL := -mconstant-gp
 EXTRA          :=
 
 cflags-y       := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \
                   -falign-functions=32 -frename-registers -fno-optimize-sibling-calls
-CFLAGS_KERNEL  := -mconstant-gp
+KBUILD_CFLAGS_KERNEL := -mconstant-gp
 
 GAS_STATUS     = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)")
 KBUILD_CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)")
diff --git a/arch/ia64/include/asm/local64.h b/arch/ia64/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 6c89228560493df8d17d6e0f7d1b65d28ee543ad..4a746ea838ff37b423f92f31a8eecc8207f6217a 100644 (file)
@@ -25,7 +25,7 @@ static int ia64_set_msi_irq_affinity(unsigned int irq,
        if (irq_prepare_move(irq, cpu))
                return -1;
 
-       read_msi_msg(irq, &msg);
+       get_cached_msi_msg(irq, &msg);
 
        addr = msg.address_lo;
        addr &= MSI_ADDR_DEST_ID_MASK;
index 6a1380e90f874b54573d880e72c9c46b88661fe7..99dcc85193c9890214c0aa9d20c0b564c6ad95f5 100644 (file)
@@ -519,7 +519,7 @@ do_boot_cpu (int sapicid, int cpu)
        /*
         * We can't use kernel_thread since we must avoid to reschedule the child.
         */
-       if (!keventd_up() || current_is_keventd())
+       if (!keventd_up())
                c_idle.work.func(&c_idle.work);
        else {
                schedule_work(&c_idle.work);
index 653b3c46ea82a86bb2e5092538bc5e094165a3f6..ed6f22eb5b12adcd647abb384a44ff55e4e14604 100644 (file)
@@ -471,7 +471,8 @@ void update_vsyscall_tz(void)
 {
 }
 
-void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
+void update_vsyscall(struct timespec *wall, struct timespec *wtm,
+                       struct clocksource *c, u32 mult)
 {
         unsigned long flags;
 
@@ -487,9 +488,9 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
        /* copy kernel time structures */
         fsyscall_gtod_data.wall_time.tv_sec = wall->tv_sec;
         fsyscall_gtod_data.wall_time.tv_nsec = wall->tv_nsec;
-        fsyscall_gtod_data.monotonic_time.tv_sec = wall_to_monotonic.tv_sec
+       fsyscall_gtod_data.monotonic_time.tv_sec = wtm->tv_sec
                                                        + wall->tv_sec;
-        fsyscall_gtod_data.monotonic_time.tv_nsec = wall_to_monotonic.tv_nsec
+       fsyscall_gtod_data.monotonic_time.tv_nsec = wtm->tv_nsec
                                                        + wall->tv_nsec;
 
        /* normalize */
index ebfdd6a9ae1a0ac6401581ab8de42592175a87c5..0c72dd4638314523eeb8a71b6204826fc9777303 100644 (file)
@@ -175,7 +175,7 @@ static int sn_set_msi_irq_affinity(unsigned int irq,
         * Release XIO resources for the old MSI PCI address
         */
 
-       read_msi_msg(irq, &msg);
+       get_cached_msi_msg(irq, &msg);
         sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
        pdev = sn_pdev->pdi_linux_pcidev;
        provider = SN_PCIDEV_BUSPROVIDER(pdev);
index 3a9319f93e89cdad744622eef5e2bed2aa2b3be7..836abbbc9c04c421ab3d6f4c7d433ed231e90f04 100644 (file)
@@ -44,9 +44,6 @@ config HZ
        int
        default 100
 
-config GENERIC_TIME
-       def_bool y
-
 config ARCH_USES_GETTIMEOFFSET
        def_bool y
 
index 469766b24e2286ca3495b39a9dbf194dd83ca423..8ff5ba0ea26c9c6e5f474bb245f9a59a66a42002 100644 (file)
@@ -12,8 +12,8 @@ OBJCOPYFLAGS  := -O binary -R .note -R .comment -S
 LDFLAGS_vmlinux        :=
 
 KBUILD_CFLAGS += -pipe -fno-schedule-insns
-CFLAGS_KERNEL += -mmodel=medium
-CFLAGS_MODULE += -mmodel=large
+KBUILD_CFLAGS_KERNEL += -mmodel=medium
+KBUILD_CFLAGS_MODULE += -mmodel=large
 
 ifdef CONFIG_CHIP_VDEC2
 cflags-$(CONFIG_ISA_M32R2)     += -DNO_FPU -Wa,-bitinst
diff --git a/arch/m32r/include/asm/local64.h b/arch/m32r/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 2e3737b92ffca3e36d0005317feee1d38dee526e..8030e2481d9758352a5c952bb34fc9715e330cc7 100644 (file)
@@ -59,9 +59,6 @@ config HZ
        int
        default 100
 
-config GENERIC_TIME
-       def_bool y
-
 config ARCH_USES_GETTIMEOFFSET
        def_bool y
 
index 570d85c3f97fbb9b3d2d47e39d5007c134794456..b06a7e3cbcd6491de55c409e9516a1d68d6ed527 100644 (file)
@@ -18,7 +18,7 @@ KBUILD_DEFCONFIG := multi_defconfig
 # override top level makefile
 AS += -m68020
 LDFLAGS := -m m68kelf
-LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
+KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
 ifneq ($(SUBARCH),$(ARCH))
        ifeq ($(CROSS_COMPILE),)
                CROSS_COMPILE := $(call cc-cross-prefix, \
diff --git a/arch/m68k/include/asm/local64.h b/arch/m68k/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index efeb6033fc1701621b418c4af5bd5046bd7bacaf..2609c394e1dfd11f6ea78c16c109cfac03c66836 100644 (file)
@@ -63,10 +63,6 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
-config GENERIC_TIME
-       bool
-       default y
-
 config GENERIC_CMOS_UPDATE
        bool
        default y
index be3855250db65625f68019449db839fbbc895e76..692fdfce2a2357122119429ceb36779f13640560 100644 (file)
@@ -18,6 +18,8 @@ config MICROBLAZE
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select TRACING_SUPPORT
+       select OF
+       select OF_FLATTREE
 
 config SWAP
        def_bool n
@@ -49,9 +51,6 @@ config GENERIC_IRQ_PROBE
 config GENERIC_CALIBRATE_DELAY
        def_bool y
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_TIME_VSYSCALL
        def_bool n
 
@@ -76,9 +75,6 @@ config LOCKDEP_SUPPORT
 config HAVE_LATENCYTOP_SUPPORT
        def_bool y
 
-config DTC
-       def_bool y
-
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -125,18 +121,6 @@ config CMDLINE_FORCE
          Set this to have arguments from the default kernel command string
          override those passed by the boot loader.
 
-config OF
-       def_bool y
-       select OF_FLATTREE
-
-config PROC_DEVICETREE
-       bool "Support for device tree in /proc"
-       depends on PROC_FS
-       help
-         This option adds a device-tree directory under /proc which contains
-         an image of the device tree that the kernel copies from Open
-         Firmware or other boot firmware. If unsure, say Y here.
-
 endmenu
 
 menu "Advanced setup"
index 31a35c33df6302c2be2509b777d262e24c02445d..ec5583d6111cc4a6f98d6c9c1e8e07d669db9aba 100644 (file)
@@ -27,17 +27,6 @@ extern unsigned int nr_irq;
 struct pt_regs;
 extern void do_IRQ(struct pt_regs *regs);
 
-/**
- * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
- * @device: Device node of the device whose interrupt is to be mapped
- * @index: Index of the interrupt to map
- *
- * This function is a wrapper that chains of_irq_map_one() and
- * irq_create_of_mapping() to make things easier to callers
- */
-struct device_node;
-extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
-
 /** FIXME - not implement
  * irq_dispose_mapping - Unmap an interrupt
  * @virq: linux virq number of the interrupt to unmap
@@ -62,17 +51,4 @@ struct irq_host;
 extern unsigned int irq_create_mapping(struct irq_host *host,
                                        irq_hw_number_t hwirq);
 
-/**
- * irq_create_of_mapping - Map a hardware interrupt into linux virq space
- * @controller: Device node of the interrupt controller
- * @inspec: Interrupt specifier from the device-tree
- * @intsize: Size of the interrupt specifier from the device-tree
- *
- * This function is identical to irq_create_mapping except that it takes
- * as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions.
- */
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
-                                       u32 *intspec, unsigned int intsize);
-
 #endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/include/asm/local64.h b/arch/microblaze/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h
deleted file mode 100644 (file)
index 73cb980..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
- *
- * based on PowerPC of_device.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_OF_DEVICE_H
-#define _ASM_MICROBLAZE_OF_DEVICE_H
-#ifdef __KERNEL__
-
-#include <linux/device.h>
-#include <linux/of.h>
-
-/*
- * The of_device is a kind of "base class" that is a superset of
- * struct device for use by devices attached to an OF node and
- * probed using OF properties.
- */
-struct of_device {
-       struct device           dev; /* Generic device interface */
-       struct pdev_archdata    archdata;
-};
-
-extern ssize_t of_device_get_modalias(struct of_device *ofdev,
-                                       char *str, ssize_t len);
-
-extern struct of_device *of_device_alloc(struct device_node *np,
-                                        const char *bus_id,
-                                        struct device *parent);
-
-extern int of_device_uevent(struct device *dev,
-                           struct kobj_uevent_env *env);
-
-extern void of_device_make_bus_id(struct of_device *dev);
-
-/* This is just here during the transition */
-#include <linux/of_device.h>
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */
diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h
deleted file mode 100644 (file)
index 3749127..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
- *                     <benh@kernel.crashing.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _ASM_MICROBLAZE_OF_PLATFORM_H
-#define _ASM_MICROBLAZE_OF_PLATFORM_H
-
-/* This is just here during the transition */
-#include <linux/of_platform.h>
-
-/*
- * The list of OF IDs below is used for matching bus types in the
- * system whose devices are to be exposed as of_platform_devices.
- *
- * This is the default list valid for most platforms. This file provides
- * functions who can take an explicit list if necessary though
- *
- * The search is always performed recursively looking for children of
- * the provided device_node and recursively if such a children matches
- * a bus type in the list
- */
-
-static const struct of_device_id of_default_bus_ids[] = {
-       { .type = "soc", },
-       { .compatible = "soc", },
-       { .type = "plb5", },
-       { .type = "plb4", },
-       { .type = "opb", },
-       { .type = "simple", },
-       {},
-};
-
-/* Platform devices and busses creation */
-extern struct of_device *of_platform_device_create(struct device_node *np,
-                                               const char *bus_id,
-                                               struct device *parent);
-/* pseudo "matches" value to not do deep probe */
-#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
-
-extern int of_platform_bus_probe(struct device_node *root,
-                               const struct of_device_id *matches,
-                               struct device *parent);
-
-extern struct of_device *of_find_device_by_phandle(phandle ph);
-
-extern void of_instantiate_rtc(void);
-
-#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */
index c12c6dfafd9f9bc503b16be2fe7bd026539930db..4f268faa0126eea67f76ee4523d2ce8d2c666151 100644 (file)
 #define PAGE_UP(addr)  (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
 #define PAGE_DOWN(addr)        ((addr)&(~((PAGE_SIZE)-1)))
 
-/* align addr on a size boundary - adjust address up/down if needed */
-#define _ALIGN_UP(addr, size)  (((addr)+((size)-1))&(~((size)-1)))
-#define _ALIGN_DOWN(addr, size)        ((addr)&(~((size)-1)))
-
-/* align addr on a size boundary - adjust address up if needed */
-#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
-
 #ifndef CONFIG_MMU
 /*
  * PAGE_OFFSET -- the first address of the first page of memory. When not
index 0c77cda9f5d80eb6de7b003c09c05ce7a1fea97b..0c68764ab547ea938f2e5210d37f27fd597b4b23 100644 (file)
@@ -172,13 +172,8 @@ static inline int pci_has_flag(int flag)
 
 extern struct list_head hose_list;
 
-extern unsigned long pci_address_to_pio(phys_addr_t address);
 extern int pcibios_vaddr_is_ioport(void __iomem *address);
 #else
-static inline unsigned long pci_address_to_pio(phys_addr_t address)
-{
-       return (unsigned long)-1;
-}
 static inline int pcibios_vaddr_is_ioport(void __iomem *address)
 {
        return 0;
index e7d67a329bd7d9046004a204864e277bdee92053..101fa098f62af7576f05b694a346e80349ae2c2d 100644 (file)
@@ -20,9 +20,6 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
-#include <linux/of_fdt.h>
-#include <linux/proc_fs.h>
-#include <linux/platform_device.h>
 #include <asm/irq.h>
 #include <asm/atomic.h>
 
@@ -50,29 +47,10 @@ extern void pci_create_OF_bus_map(void);
  * OF address retreival & translation
  */
 
-/* Translate an OF address block into a CPU physical address
- */
-extern u64 of_translate_address(struct device_node *np, const u32 *addr);
-
-/* Extract an address from a device, returns the region size and
- * the address space flags too. The PCI version uses a BAR number
- * instead of an absolute index
- */
-extern const u32 *of_get_address(struct device_node *dev, int index,
-                       u64 *size, unsigned int *flags);
-extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
-                       u64 *size, unsigned int *flags);
-
-/* Get an address as a resource. Note that if your address is
- * a PIO address, the conversion will fail if the physical address
- * can't be internally converted to an IO token with
- * pci_address_to_pio(), that is because it's either called to early
- * or it can't be matched to any host bridge IO space
- */
-extern int of_address_to_resource(struct device_node *dev, int index,
-                               struct resource *r);
-extern int of_pci_address_to_resource(struct device_node *dev, int bar,
-                               struct resource *r);
+#ifdef CONFIG_PCI
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+#define pci_address_to_pio pci_address_to_pio
+#endif /* CONFIG_PCI */
 
 /* Parse the ibm,dma-window property of an OF node into the busno, phys and
  * size parameters.
@@ -88,69 +66,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/*
- * OF interrupt mapping
- */
-
-/* This structure is returned when an interrupt is mapped. The controller
- * field needs to be put() after use
- */
-
-#define OF_MAX_IRQ_SPEC                4 /* We handle specifiers of at most 4 cells */
-
-struct of_irq {
-       struct device_node *controller; /* Interrupt controller node */
-       u32 size; /* Specifier size */
-       u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
-};
-
-/**
- * of_irq_map_init - Initialize the irq remapper
- * @flags:     flags defining workarounds to enable
- *
- * Some machines have bugs in the device-tree which require certain workarounds
- * to be applied. Call this before any interrupt mapping attempts to enable
- * those workarounds.
- */
-#define OF_IMAP_OLDWORLD_MAC   0x00000001
-#define OF_IMAP_NO_PHANDLE     0x00000002
-
-extern void of_irq_map_init(unsigned int flags);
-
-/**
- * of_irq_map_raw - Low level interrupt tree parsing
- * @parent:    the device interrupt parent
- * @intspec:   interrupt specifier ("interrupts" property of the device)
- * @ointsize:  size of the passed in interrupt specifier
- * @addr:      address specifier (start of "reg" property of the device)
- * @out_irq:   structure of_irq filled by this function
- *
- * Returns 0 on success and a negative number on error
- *
- * This function is a low-level interrupt tree walking function. It
- * can be used to do a partial walk with synthetized reg and interrupts
- * properties, for example when resolving PCI interrupts when no device
- * node exist for the parent.
- *
- */
-
-extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
-                       u32 ointsize, const u32 *addr,
-                       struct of_irq *out_irq);
-
-/**
- * of_irq_map_one - Resolve an interrupt for a device
- * @device:    the device whose interrupt is to be resolved
- * @index:     index of the interrupt to resolve
- * @out_irq:   structure of_irq filled by this function
- *
- * This function resolves an interrupt, walking the tree, for a given
- * device-tree node. It's the high level pendant to of_irq_map_raw().
- * It also implements the workarounds for OldWolrd Macs.
- */
-extern int of_irq_map_one(struct device_node *device, int index,
-                       struct of_irq *out_irq);
-
 /**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
  * @pdev:      the device whose interrupt is to be resolved
@@ -163,20 +78,18 @@ extern int of_irq_map_one(struct device_node *device, int index,
  * resolving using the OF tree walking.
  */
 struct pci_dev;
+struct of_irq;
 extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
 
-extern int of_irq_to_resource(struct device_node *dev, int index,
-                       struct resource *r);
-
-/**
- * of_iomap - Maps the memory mapped IO for a given device_node
- * @device:    the device whose io range will be mapped
- * @index:     index of the io range
- *
- * Returns a pointer to the mapped memory
- */
-extern void __iomem *of_iomap(struct device_node *device, int index);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
+
+/* These includes are put at the bottom because they may contain things
+ * that are overridden by this file.  Ideally they shouldn't be included
+ * by this file, but there are a bunch of .c files that currently depend
+ * on it.  Eventually they will be cleaned up. */
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
 #endif /* _ASM_MICROBLAZE_PROM_H */
index 96bcea5a99202c184337c37aadeb2fd042cd5d71..5428f333a02c701e9faba668173dda95181544db 100644 (file)
@@ -1,11 +1 @@
 #include <asm-generic/topology.h>
-
-#ifndef _ASM_MICROBLAZE_TOPOLOGY_H
-#define _ASM_MICROBLAZE_TOPOLOGY_H
-
-struct device_node;
-static inline int of_node_to_nid(struct device_node *device)
-{
-       return 0;
-}
-#endif /* _ASM_MICROBLAZE_TOPOLOGY_H */
index 5eecc9f1fbd9944dd741f239a40be6a159a385b9..f0cb5c26c81c2567d10646d596a9e864ee88b632 100644 (file)
@@ -15,8 +15,8 @@ endif
 extra-y := head.o vmlinux.lds
 
 obj-y += dma.o exceptions.o \
-       hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
-       of_platform.o process.o prom.o prom_parse.o ptrace.o \
+       hw_exception_handler.o init_task.o intc.o irq.o \
+       process.o prom.o prom_parse.o ptrace.o \
        reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
 
 obj-y += cpu/
index 598f1fd61c89036423b20ea1237826703255c150..a9345fb4906a8923afa8066a88c6837205b27f7b 100644 (file)
 #include <linux/seq_file.h>
 #include <linux/kernel_stat.h>
 #include <linux/irq.h>
+#include <linux/of_irq.h>
 
 #include <asm/prom.h>
 
-unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
-{
-       struct of_irq oirq;
-
-       if (of_irq_map_one(dev, index, &oirq))
-               return NO_IRQ;
-
-       return oirq.specifier[0];
-}
-EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
-
 static u32 concurrent_irq;
 
 void __irq_entry do_IRQ(struct pt_regs *regs)
@@ -106,7 +96,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
 EXPORT_SYMBOL_GPL(irq_create_mapping);
 
 unsigned int irq_create_of_mapping(struct device_node *controller,
-                                       u32 *intspec, unsigned int intsize)
+                                  const u32 *intspec, unsigned int intsize)
 {
        return intspec[0];
 }
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c
deleted file mode 100644 (file)
index b372787..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-
-#include <linux/errno.h>
-
-void of_device_make_bus_id(struct of_device *dev)
-{
-       static atomic_t bus_no_reg_magic;
-       struct device_node *node = dev->dev.of_node;
-       const u32 *reg;
-       u64 addr;
-       int magic;
-
-       /*
-        * For MMIO, get the physical address
-        */
-       reg = of_get_property(node, "reg", NULL);
-       if (reg) {
-               addr = of_translate_address(node, reg);
-               if (addr != OF_BAD_ADDR) {
-                       dev_set_name(&dev->dev, "%llx.%s",
-                                    (unsigned long long)addr, node->name);
-                       return;
-               }
-       }
-
-       /*
-        * No BusID, use the node name and add a globally incremented
-        * counter (and pray...)
-        */
-       magic = atomic_add_return(1, &bus_no_reg_magic);
-       dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
-}
-EXPORT_SYMBOL(of_device_make_bus_id);
-
-struct of_device *of_device_alloc(struct device_node *np,
-                                 const char *bus_id,
-                                 struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return NULL;
-
-       dev->dev.of_node = of_node_get(np);
-       dev->dev.dma_mask = &dev->archdata.dma_mask;
-       dev->dev.parent = parent;
-       dev->dev.release = of_release_dev;
-
-       if (bus_id)
-               dev_set_name(&dev->dev, bus_id);
-       else
-               of_device_make_bus_id(dev);
-
-       return dev;
-}
-EXPORT_SYMBOL(of_device_alloc);
-
-int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-       struct of_device *ofdev;
-       const char *compat;
-       int seen = 0, cplen, sl;
-
-       if (!dev)
-               return -ENODEV;
-
-       ofdev = to_of_device(dev);
-
-       if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name))
-               return -ENOMEM;
-
-       if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type))
-               return -ENOMEM;
-
-       /* Since the compatible field can contain pretty much anything
-        * it's not really legal to split it out with commas. We split it
-        * up using a number of environment variables instead. */
-
-       compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
-       while (compat && *compat && cplen > 0) {
-               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
-                       return -ENOMEM;
-
-               sl = strlen(compat) + 1;
-               compat += sl;
-               cplen -= sl;
-               seen++;
-       }
-
-       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
-               return -ENOMEM;
-
-       /* modalias is trickier, we add it in 2 steps */
-       if (add_uevent_var(env, "MODALIAS="))
-               return -ENOMEM;
-       sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
-                                   sizeof(env->buf) - env->buflen);
-       if (sl >= (sizeof(env->buf) - env->buflen))
-               return -ENOMEM;
-       env->buflen += sl;
-
-       return 0;
-}
-EXPORT_SYMBOL(of_device_uevent);
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c
deleted file mode 100644 (file)
index ccf6f42..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
- *                      <benh@kernel.crashing.org>
- *    and               Arnd Bergmann, IBM Corp.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- */
-
-#undef DEBUG
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/pci.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-
-#include <linux/errno.h>
-#include <linux/topology.h>
-#include <asm/atomic.h>
-
-struct bus_type of_platform_bus_type = {
-       .uevent = of_device_uevent,
-};
-EXPORT_SYMBOL(of_platform_bus_type);
-
-static int __init of_bus_driver_init(void)
-{
-       return of_bus_type_init(&of_platform_bus_type, "of_platform");
-}
-postcore_initcall(of_bus_driver_init);
-
-struct of_device *of_platform_device_create(struct device_node *np,
-                                           const char *bus_id,
-                                           struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = of_device_alloc(np, bus_id, parent);
-       if (!dev)
-               return NULL;
-
-       dev->archdata.dma_mask = 0xffffffffUL;
-       dev->dev.bus = &of_platform_bus_type;
-
-       /* We do not fill the DMA ops for platform devices by default.
-        * This is currently the responsibility of the platform code
-        * to do such, possibly using a device notifier
-        */
-
-       if (of_device_register(dev) != 0) {
-               of_device_free(dev);
-               return NULL;
-       }
-
-       return dev;
-}
-EXPORT_SYMBOL(of_platform_device_create);
-
-/**
- * of_platform_bus_create - Create an OF device for a bus node and all its
- * children. Optionally recursively instanciate matching busses.
- * @bus: device node of the bus to instanciate
- * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
- * disallow recursive creation of child busses
- */
-static int of_platform_bus_create(const struct device_node *bus,
-                                 const struct of_device_id *matches,
-                                 struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       for_each_child_of_node(bus, child) {
-               pr_debug("   create child: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else if (!of_match_node(matches, child))
-                       continue;
-               if (rc == 0) {
-                       pr_debug("   and sub busses\n");
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               }
-               if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
-       return rc;
-}
-
-
-/**
- * of_platform_bus_probe - Probe the device-tree for platform busses
- * @root: parent of the first level to probe or NULL for the root of the tree
- * @matches: match table, NULL to use the default
- * @parent: parent to hook devices from, NULL for toplevel
- *
- * Note that children of the provided root are not instanciated as devices
- * unless the specified root itself matches the bus list and is not NULL.
- */
-
-int of_platform_bus_probe(struct device_node *root,
-                         const struct of_device_id *matches,
-                         struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       if (matches == NULL)
-               matches = of_default_bus_ids;
-       if (matches == OF_NO_DEEP_PROBE)
-               return -EINVAL;
-       if (root == NULL)
-               root = of_find_node_by_path("/");
-       else
-               of_node_get(root);
-
-       pr_debug("of_platform_bus_probe()\n");
-       pr_debug(" starting at: %s\n", root->full_name);
-
-       /* Do a self check of bus type, if there's a match, create
-        * children
-        */
-       if (of_match_node(matches, root)) {
-               pr_debug(" root match, create all sub devices\n");
-               dev = of_platform_device_create(root, NULL, parent);
-               if (dev == NULL) {
-                       rc = -ENOMEM;
-                       goto bail;
-               }
-               pr_debug(" create all sub busses\n");
-               rc = of_platform_bus_create(root, matches, &dev->dev);
-               goto bail;
-       }
-       for_each_child_of_node(root, child) {
-               if (!of_match_node(matches, child))
-                       continue;
-
-               pr_debug("  match: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
- bail:
-       of_node_put(root);
-       return rc;
-}
-EXPORT_SYMBOL(of_platform_bus_probe);
-
-static int of_dev_node_match(struct device *dev, void *data)
-{
-       return to_of_device(dev)->dev.of_node == data;
-}
-
-struct of_device *of_find_device_by_node(struct device_node *np)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&of_platform_bus_type,
-                             NULL, np, of_dev_node_match);
-       if (dev)
-               return to_of_device(dev);
-       return NULL;
-}
-EXPORT_SYMBOL(of_find_device_by_node);
-
-static int of_dev_phandle_match(struct device *dev, void *data)
-{
-       phandle *ph = data;
-       return to_of_device(dev)->dev.of_node->phandle == *ph;
-}
-
-struct of_device *of_find_device_by_phandle(phandle ph)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&of_platform_bus_type,
-                             NULL, &ph, of_dev_phandle_match);
-       if (dev)
-               return to_of_device(dev);
-       return NULL;
-}
-EXPORT_SYMBOL(of_find_device_by_phandle);
index bf7e6c27e318f88a0cf5a8a352d7126f460f0be5..d33ba17601fa20d61c86c3ea982aab72ca6508e1 100644 (file)
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
+#include <linux/of_address.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 
-#define PRu64  "%llx"
-
-/* Max address size we deal with */
-#define OF_MAX_ADDR_CELLS      4
-#define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
-                       (ns) > 0)
-
-static struct of_bus *of_match_bus(struct device_node *np);
-static int __of_address_to_resource(struct device_node *dev,
-               const u32 *addrp, u64 size, unsigned int flags,
-               struct resource *r);
-
-/* Debug utility */
-#ifdef DEBUG
-static void of_dump_addr(const char *s, const u32 *addr, int na)
-{
-       printk(KERN_INFO "%s", s);
-       while (na--)
-               printk(KERN_INFO " %08x", *(addr++));
-       printk(KERN_INFO "\n");
-}
-#else
-static void of_dump_addr(const char *s, const u32 *addr, int na) { }
-#endif
-
-/* Callbacks for bus specific translators */
-struct of_bus {
-       const char      *name;
-       const char      *addresses;
-       int             (*match)(struct device_node *parent);
-       void            (*count_cells)(struct device_node *child,
-                                       int *addrc, int *sizec);
-       u64             (*map)(u32 *addr, const u32 *range,
-                               int na, int ns, int pna);
-       int             (*translate)(u32 *addr, u64 offset, int na);
-       unsigned int    (*get_flags)(const u32 *addr);
-};
-
-/*
- * Default translator (generic bus)
- */
-
-static void of_bus_default_count_cells(struct device_node *dev,
-                                       int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = of_n_addr_cells(dev);
-       if (sizec)
-               *sizec = of_n_size_cells(dev);
-}
-
-static u64 of_bus_default_map(u32 *addr, const u32 *range,
-               int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       cp = of_read_number(range, na);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr, na);
-
-       pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
-               cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_default_translate(u32 *addr, u64 offset, int na)
-{
-       u64 a = of_read_number(addr, na);
-       memset(addr, 0, na * 4);
-       a += offset;
-       if (na > 1)
-               addr[na - 2] = a >> 32;
-       addr[na - 1] = a & 0xffffffffu;
-
-       return 0;
-}
-
-static unsigned int of_bus_default_get_flags(const u32 *addr)
-{
-       return IORESOURCE_MEM;
-}
-
 #ifdef CONFIG_PCI
-/*
- * PCI bus specific translator
- */
-
-static int of_bus_pci_match(struct device_node *np)
-{
-       /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
-       return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
-}
-
-static void of_bus_pci_count_cells(struct device_node *np,
-                               int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 3;
-       if (sizec)
-               *sizec = 2;
-}
-
-static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       /* Check address type match */
-       if ((addr[0] ^ range[0]) & 0x03000000)
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       switch ((w >> 24) & 0x03) {
-       case 0x01:
-               flags |= IORESOURCE_IO;
-               break;
-       case 0x02: /* 32 bits */
-       case 0x03: /* 64 bits */
-               flags |= IORESOURCE_MEM;
-               break;
-       }
-       if (w & 0x40000000)
-               flags |= IORESOURCE_PREFETCH;
-       return flags;
-}
-
-const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
-                       unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       if (strcmp(bus->name, "pci")) {
-               of_node_put(parent);
-               return NULL;
-       }
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_pci_address);
-
-int of_pci_address_to_resource(struct device_node *dev, int bar,
-                               struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_pci_address(dev, bar, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
-
-static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
-{
-       return (((pin - 1) + slot) % 4) + 1;
-}
-
 int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 {
        struct device_node *dn, *ppnode;
@@ -293,331 +85,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 EXPORT_SYMBOL_GPL(of_irq_map_pci);
 #endif /* CONFIG_PCI */
 
-/*
- * ISA bus specific translator
- */
-
-static int of_bus_isa_match(struct device_node *np)
-{
-       return !strcmp(np->name, "isa");
-}
-
-static void of_bus_isa_count_cells(struct device_node *child,
-                               int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 2;
-       if (sizec)
-               *sizec = 1;
-}
-
-static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       /* Check address type match */
-       if ((addr[0] ^ range[0]) & 0x00000001)
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-static unsigned int of_bus_isa_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       if (w & 1)
-               flags |= IORESOURCE_IO;
-       else
-               flags |= IORESOURCE_MEM;
-       return flags;
-}
-
-/*
- * Array of bus specific translators
- */
-
-static struct of_bus of_busses[] = {
-#ifdef CONFIG_PCI
-       /* PCI */
-       {
-               .name = "pci",
-               .addresses = "assigned-addresses",
-               .match = of_bus_pci_match,
-               .count_cells = of_bus_pci_count_cells,
-               .map = of_bus_pci_map,
-               .translate = of_bus_pci_translate,
-               .get_flags = of_bus_pci_get_flags,
-       },
-#endif /* CONFIG_PCI */
-       /* ISA */
-       {
-               .name = "isa",
-               .addresses = "reg",
-               .match = of_bus_isa_match,
-               .count_cells = of_bus_isa_count_cells,
-               .map = of_bus_isa_map,
-               .translate = of_bus_isa_translate,
-               .get_flags = of_bus_isa_get_flags,
-       },
-       /* Default */
-       {
-               .name = "default",
-               .addresses = "reg",
-               .match = NULL,
-               .count_cells = of_bus_default_count_cells,
-               .map = of_bus_default_map,
-               .translate = of_bus_default_translate,
-               .get_flags = of_bus_default_get_flags,
-       },
-};
-
-static struct of_bus *of_match_bus(struct device_node *np)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(of_busses); i++)
-               if (!of_busses[i].match || of_busses[i].match(np))
-                       return &of_busses[i];
-       BUG();
-       return NULL;
-}
-
-static int of_translate_one(struct device_node *parent, struct of_bus *bus,
-                       struct of_bus *pbus, u32 *addr,
-                       int na, int ns, int pna)
-{
-       const u32 *ranges;
-       unsigned int rlen;
-       int rone;
-       u64 offset = OF_BAD_ADDR;
-
-       /* Normally, an absence of a "ranges" property means we are
-        * crossing a non-translatable boundary, and thus the addresses
-        * below the current not cannot be converted to CPU physical ones.
-        * Unfortunately, while this is very clear in the spec, it's not
-        * what Apple understood, and they do have things like /uni-n or
-        * /ht nodes with no "ranges" property and a lot of perfectly
-        * useable mapped devices below them. Thus we treat the absence of
-        * "ranges" as equivalent to an empty "ranges" property which means
-        * a 1:1 translation at that level. It's up to the caller not to try
-        * to translate addresses that aren't supposed to be translated in
-        * the first place. --BenH.
-        */
-       ranges = of_get_property(parent, "ranges", (int *) &rlen);
-       if (ranges == NULL || rlen == 0) {
-               offset = of_read_number(addr, na);
-               memset(addr, 0, pna * 4);
-               pr_debug("OF: no ranges, 1:1 translation\n");
-               goto finish;
-       }
-
-       pr_debug("OF: walking ranges...\n");
-
-       /* Now walk through the ranges */
-       rlen /= 4;
-       rone = na + pna + ns;
-       for (; rlen >= rone; rlen -= rone, ranges += rone) {
-               offset = bus->map(addr, ranges, na, ns, pna);
-               if (offset != OF_BAD_ADDR)
-                       break;
-       }
-       if (offset == OF_BAD_ADDR) {
-               pr_debug("OF: not found !\n");
-               return 1;
-       }
-       memcpy(addr, ranges + na, 4 * pna);
-
- finish:
-       of_dump_addr("OF: parent translation for:", addr, pna);
-       pr_debug("OF: with offset: "PRu64"\n", offset);
-
-       /* Translate it into parent bus space */
-       return pbus->translate(addr, offset, pna);
-}
-
-/*
- * Translate an address from the device-tree into a CPU physical address,
- * this walks up the tree and applies the various bus mappings on the
- * way.
- *
- * Note: We consider that crossing any level with #size-cells == 0 to mean
- * that translation is impossible (that is we are not dealing with a value
- * that can be mapped to a cpu physical address). This is not really specified
- * that way, but this is traditionally the way IBM at least do things
- */
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
-{
-       struct device_node *parent = NULL;
-       struct of_bus *bus, *pbus;
-       u32 addr[OF_MAX_ADDR_CELLS];
-       int na, ns, pna, pns;
-       u64 result = OF_BAD_ADDR;
-
-       pr_debug("OF: ** translation for device %s **\n", dev->full_name);
-
-       /* Increase refcount at current level */
-       of_node_get(dev);
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               goto bail;
-       bus = of_match_bus(parent);
-
-       /* Cound address cells & copy address locally */
-       bus->count_cells(dev, &na, &ns);
-       if (!OF_CHECK_COUNTS(na, ns)) {
-               printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                       dev->full_name);
-               goto bail;
-       }
-       memcpy(addr, in_addr, na * 4);
-
-       pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
-               bus->name, na, ns, parent->full_name);
-       of_dump_addr("OF: translating address:", addr, na);
-
-       /* Translate */
-       for (;;) {
-               /* Switch to parent bus */
-               of_node_put(dev);
-               dev = parent;
-               parent = of_get_parent(dev);
-
-               /* If root, we have finished */
-               if (parent == NULL) {
-                       pr_debug("OF: reached root node\n");
-                       result = of_read_number(addr, na);
-                       break;
-               }
-
-               /* Get new parent bus and counts */
-               pbus = of_match_bus(parent);
-               pbus->count_cells(dev, &pna, &pns);
-               if (!OF_CHECK_COUNTS(pna, pns)) {
-                       printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                               dev->full_name);
-                       break;
-               }
-
-               pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
-                       pbus->name, pna, pns, parent->full_name);
-
-               /* Apply bus translation */
-               if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
-                       break;
-
-               /* Complete the move up one level */
-               na = pna;
-               ns = pns;
-               bus = pbus;
-
-               of_dump_addr("OF: one level translation:", addr, na);
-       }
- bail:
-       of_node_put(parent);
-       of_node_put(dev);
-
-       return result;
-}
-EXPORT_SYMBOL(of_translate_address);
-
-const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
-                       unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, (int *) &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if (i == index) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_address);
-
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-                               u64 size, unsigned int flags,
-                               struct resource *r)
-{
-       u64 taddr;
-
-       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
-               return -EINVAL;
-       taddr = of_translate_address(dev, addrp);
-       if (taddr == OF_BAD_ADDR)
-               return -EINVAL;
-       memset(r, 0, sizeof(struct resource));
-       if (flags & IORESOURCE_IO) {
-               unsigned long port;
-               port = -1; /* pci_address_to_pio(taddr); */
-               if (port == (unsigned long)-1)
-                       return -EINVAL;
-               r->start = port;
-               r->end = port + size - 1;
-       } else {
-               r->start = taddr;
-               r->end = taddr + size - 1;
-       }
-       r->flags = flags;
-       r->name = dev->name;
-       return 0;
-}
-
-int of_address_to_resource(struct device_node *dev, int index,
-                       struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_address(dev, index, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_address_to_resource);
-
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
                unsigned long *busno, unsigned long *phys, unsigned long *size)
 {
@@ -644,308 +111,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
        *size = of_read_number(dma_window, cells);
 }
 
-/*
- * Interrupt remapper
- */
-
-static unsigned int of_irq_workarounds;
-static struct device_node *of_irq_dflt_pic;
-
-static struct device_node *of_irq_find_parent(struct device_node *child)
-{
-       struct device_node *p;
-       const phandle *parp;
-
-       if (!of_node_get(child))
-               return NULL;
-
-       do {
-               parp = of_get_property(child, "interrupt-parent", NULL);
-               if (parp == NULL)
-                       p = of_get_parent(child);
-               else {
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               p = of_node_get(of_irq_dflt_pic);
-                       else
-                               p = of_find_node_by_phandle(*parp);
-               }
-               of_node_put(child);
-               child = p;
-       } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
-
-       return p;
-}
-
-/* This doesn't need to be called if you don't have any special workaround
- * flags to pass
- */
-void of_irq_map_init(unsigned int flags)
-{
-       of_irq_workarounds = flags;
-
-       /* OldWorld, don't bother looking at other things */
-       if (flags & OF_IMAP_OLDWORLD_MAC)
-               return;
-
-       /* If we don't have phandles, let's try to locate a default interrupt
-        * controller (happens when booting with BootX). We do a first match
-        * here, hopefully, that only ever happens on machines with one
-        * controller.
-        */
-       if (flags & OF_IMAP_NO_PHANDLE) {
-               struct device_node *np;
-
-               for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
-                       if (of_get_property(np, "interrupt-controller", NULL)
-                               == NULL)
-                               continue;
-                       /* Skip /chosen/interrupt-controller */
-                       if (strcmp(np->name, "chosen") == 0)
-                               continue;
-                       /* It seems like at least one person on this planet
-                        * wants to use BootX on a machine with an AppleKiwi
-                        * controller which happens to pretend to be an
-                        * interrupt controller too.
-                        */
-                       if (strcmp(np->name, "AppleKiwi") == 0)
-                               continue;
-                       /* I think we found one ! */
-                       of_irq_dflt_pic = np;
-                       break;
-               }
-       }
-
-}
-
-int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
-               const u32 *addr, struct of_irq *out_irq)
-{
-       struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
-       const u32 *tmp, *imap, *imask;
-       u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
-       int imaplen, match, i;
-
-       pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
-               "ointsize=%d\n",
-               parent->full_name, intspec[0], intspec[1], ointsize);
-
-       ipar = of_node_get(parent);
-
-       /* First get the #interrupt-cells property of the current cursor
-        * that tells us how to interpret the passed-in intspec. If there
-        * is none, we are nice and just walk up the tree
-        */
-       do {
-               tmp = of_get_property(ipar, "#interrupt-cells", NULL);
-               if (tmp != NULL) {
-                       intsize = *tmp;
-                       break;
-               }
-               tnode = ipar;
-               ipar = of_irq_find_parent(ipar);
-               of_node_put(tnode);
-       } while (ipar);
-       if (ipar == NULL) {
-               pr_debug(" -> no parent found !\n");
-               goto fail;
-       }
-
-       pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
-                       ipar->full_name, intsize);
-
-       if (ointsize != intsize)
-               return -EINVAL;
-
-       /* Look for this #address-cells. We have to implement the old linux
-        * trick of looking for the parent here as some device-trees rely on it
-        */
-       old = of_node_get(ipar);
-       do {
-               tmp = of_get_property(old, "#address-cells", NULL);
-               tnode = of_get_parent(old);
-               of_node_put(old);
-               old = tnode;
-       } while (old && tmp == NULL);
-       of_node_put(old);
-       old = NULL;
-       addrsize = (tmp == NULL) ? 2 : *tmp;
-
-       pr_debug(" -> addrsize=%d\n", addrsize);
-
-       /* Now start the actual "proper" walk of the interrupt tree */
-       while (ipar != NULL) {
-               /* Now check if cursor is an interrupt-controller and if it is
-                * then we are done
-                */
-               if (of_get_property(ipar, "interrupt-controller", NULL) !=
-                               NULL) {
-                       pr_debug(" -> got it !\n");
-                       memcpy(out_irq->specifier, intspec,
-                               intsize * sizeof(u32));
-                       out_irq->size = intsize;
-                       out_irq->controller = ipar;
-                       of_node_put(old);
-                       return 0;
-               }
-
-               /* Now look for an interrupt-map */
-               imap = of_get_property(ipar, "interrupt-map", &imaplen);
-               /* No interrupt map, check for an interrupt parent */
-               if (imap == NULL) {
-                       pr_debug(" -> no map, getting parent\n");
-                       newpar = of_irq_find_parent(ipar);
-                       goto skiplevel;
-               }
-               imaplen /= sizeof(u32);
-
-               /* Look for a mask */
-               imask = of_get_property(ipar, "interrupt-map-mask", NULL);
-
-               /* If we were passed no "reg" property and we attempt to parse
-                * an interrupt-map, then #address-cells must be 0.
-                * Fail if it's not.
-                */
-               if (addr == NULL && addrsize != 0) {
-                       pr_debug(" -> no reg passed in when needed !\n");
-                       goto fail;
-               }
-
-               /* Parse interrupt-map */
-               match = 0;
-               while (imaplen > (addrsize + intsize + 1) && !match) {
-                       /* Compare specifiers */
-                       match = 1;
-                       for (i = 0; i < addrsize && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match = ((addr[i] ^ imap[i]) & mask) == 0;
-                       }
-                       for (; i < (addrsize + intsize) && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match =
-                                       ((intspec[i-addrsize] ^ imap[i])
-                                               & mask) == 0;
-                       }
-                       imap += addrsize + intsize;
-                       imaplen -= addrsize + intsize;
-
-                       pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
-
-                       /* Get the interrupt parent */
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               newpar = of_node_get(of_irq_dflt_pic);
-                       else
-                               newpar =
-                                       of_find_node_by_phandle((phandle)*imap);
-                       imap++;
-                       --imaplen;
-
-                       /* Check if not found */
-                       if (newpar == NULL) {
-                               pr_debug(" -> imap parent not found !\n");
-                               goto fail;
-                       }
-
-                       /* Get #interrupt-cells and #address-cells of new
-                        * parent
-                        */
-                       tmp = of_get_property(newpar, "#interrupt-cells", NULL);
-                       if (tmp == NULL) {
-                               pr_debug(" -> parent lacks "
-                                               "#interrupt-cells!\n");
-                               goto fail;
-                       }
-                       newintsize = *tmp;
-                       tmp = of_get_property(newpar, "#address-cells", NULL);
-                       newaddrsize = (tmp == NULL) ? 0 : *tmp;
-
-                       pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
-                               newintsize, newaddrsize);
-
-                       /* Check for malformed properties */
-                       if (imaplen < (newaddrsize + newintsize))
-                               goto fail;
-
-                       imap += newaddrsize + newintsize;
-                       imaplen -= newaddrsize + newintsize;
-
-                       pr_debug(" -> imaplen=%d\n", imaplen);
-               }
-               if (!match)
-                       goto fail;
-
-               of_node_put(old);
-               old = of_node_get(newpar);
-               addrsize = newaddrsize;
-               intsize = newintsize;
-               intspec = imap - intsize;
-               addr = intspec - addrsize;
-
-skiplevel:
-               /* Iterate again with new parent */
-               pr_debug(" -> new parent: %s\n",
-                               newpar ? newpar->full_name : "<>");
-               of_node_put(ipar);
-               ipar = newpar;
-               newpar = NULL;
-       }
-fail:
-       of_node_put(ipar);
-       of_node_put(old);
-       of_node_put(newpar);
-
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_raw);
-
-int of_irq_map_one(struct device_node *device,
-                       int index, struct of_irq *out_irq)
-{
-       struct device_node *p;
-       const u32 *intspec, *tmp, *addr;
-       u32 intsize, intlen;
-       int res;
-
-       pr_debug("of_irq_map_one: dev=%s, index=%d\n",
-                       device->full_name, index);
-
-       /* Get the interrupts property */
-       intspec = of_get_property(device, "interrupts", (int *) &intlen);
-       if (intspec == NULL)
-               return -EINVAL;
-       intlen /= sizeof(u32);
-
-       pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
-
-       /* Get the reg property (if any) */
-       addr = of_get_property(device, "reg", NULL);
-
-       /* Look for the interrupt parent. */
-       p = of_irq_find_parent(device);
-       if (p == NULL)
-               return -EINVAL;
-
-       /* Get size of interrupt specifier */
-       tmp = of_get_property(p, "#interrupt-cells", NULL);
-       if (tmp == NULL) {
-               of_node_put(p);
-               return -EINVAL;
-       }
-       intsize = *tmp;
-
-       pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
-
-       /* Check index */
-       if ((index + 1) * intsize > intlen)
-               return -EINVAL;
-
-       /* Get new specifier and map it */
-       res = of_irq_map_raw(p, intspec + index * intsize, intsize,
-                               addr, out_irq);
-       of_node_put(p);
-       return res;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_one);
-
 /**
  * Search the device tree for the best MAC address to use.  'mac-address' is
  * checked first, because that is supposed to contain to "most recent" MAC
@@ -983,43 +148,3 @@ const void *of_get_mac_address(struct device_node *np)
        return NULL;
 }
 EXPORT_SYMBOL(of_get_mac_address);
-
-int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
-       struct of_irq out_irq;
-       int irq;
-       int res;
-
-       res = of_irq_map_one(dev, index, &out_irq);
-
-       /* Get irq for the device */
-       if (res) {
-               pr_debug("IRQ not found... code = %d", res);
-               return NO_IRQ;
-       }
-       /* Assuming single interrupt controller... */
-       irq = out_irq.specifier[0];
-
-       pr_debug("IRQ found = %d", irq);
-
-       /* Only dereference the resource if both the
-        * resource and the irq are valid. */
-       if (r && irq != NO_IRQ) {
-               r->start = r->end = irq;
-               r->flags = IORESOURCE_IRQ;
-       }
-
-       return irq;
-}
-EXPORT_SYMBOL_GPL(of_irq_to_resource);
-
-void __iomem *of_iomap(struct device_node *np, int index)
-{
-       struct resource res;
-
-       if (of_address_to_resource(np, index, &res))
-               return NULL;
-
-       return ioremap(res.start, 1 + res.end - res.start);
-}
-EXPORT_SYMBOL(of_iomap);
index a1721a33042e3d17c25dbc3ec1fddd8d05402a18..bd8ccab5ceff407287d3114d444ac467812a225f 100644 (file)
@@ -24,8 +24,8 @@ static int of_reset_gpio_handle(void)
        int ret; /* variable which stored handle reset gpio pin */
        struct device_node *root; /* root node */
        struct device_node *gpio; /* gpio node */
-       struct of_gpio_chip *of_gc = NULL;
-       enum of_gpio_flags flags ;
+       struct gpio_chip *gc;
+       u32 flags;
        const void *gpio_spec;
 
        /* find out root node */
@@ -39,19 +39,19 @@ static int of_reset_gpio_handle(void)
                goto err0;
        }
 
-       of_gc = gpio->data;
-       if (!of_gc) {
+       gc = of_node_to_gpiochip(gpio);
+       if (!gc) {
                pr_debug("%s: gpio controller %s isn't registered\n",
                         root->full_name, gpio->full_name);
                ret = -ENODEV;
                goto err1;
        }
 
-       ret = of_gc->xlate(of_gc, root, gpio_spec, &flags);
+       ret = gc->of_xlate(gc, root, gpio_spec, &flags);
        if (ret < 0)
                goto err1;
 
-       ret += of_gc->gc.base;
+       ret += gc->base;
 err1:
        of_node_put(gpio);
 err0:
index 17c98dbcec888f698e2c038eee317ddef7e1f7da..f5f768842354201266bf0dce0e7209484f49a4fa 100644 (file)
@@ -213,15 +213,9 @@ static struct notifier_block dflt_plat_bus_notifier = {
        .priority = INT_MAX,
 };
 
-static struct notifier_block dflt_of_bus_notifier = {
-       .notifier_call = dflt_bus_notify,
-       .priority = INT_MAX,
-};
-
 static int __init setup_bus_notifier(void)
 {
        bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
-       bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier);
 
        return 0;
 }
index 36642df7d5f6117ed0d8d8fd1c991a3237ddb8b9..3ad59dde485209bce858c425e4fc8a2f64b04c09 100644 (file)
@@ -758,10 +758,6 @@ config GENERIC_CLOCKEVENTS
        bool
        default y
 
-config GENERIC_TIME
-       bool
-       default y
-
 config GENERIC_CMOS_UPDATE
        bool
        default y
index f0d196090e944b1c0af943a97322d0b033ba3d57..f4a4b663ebb3150400d5148ba25c108aac289b7d 100644 (file)
@@ -93,7 +93,8 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz
 cflags-y                       += -G 0 -mno-abicalls -fno-pic -pipe
 cflags-y                       += -msoft-float
 LDFLAGS_vmlinux                        += -G 0 -static -n -nostdlib
-MODFLAGS                       += -mlong-calls
+KBUILD_AFLAGS_MODULE           += -mlong-calls
+KBUILD_CFLAGS_MODULE           += -mlong-calls
 
 cflags-y += -ffreestanding
 
@@ -165,7 +166,8 @@ cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS)      += $(call cc-option,-mno-daddi,)
 
 ifdef CONFIG_CPU_SB1
 ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
-MODFLAGS       += -msb1-pass1-workarounds
+KBUILD_AFLAGS_MODULE += -msb1-pass1-workarounds
+KBUILD_CFLAGS_MODULE += -msb1-pass1-workarounds
 endif
 endif
 
index 19002d605ac45912603b4a94464d8c6cb5583a30..e6c0b0e14ccb989a3f8e0e72a1060222e68941e7 100644 (file)
@@ -8,28 +8,27 @@
 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
        (_MIPS_ISA == _MIPS_ISA_MIPS32)
 
-#define KGDB_GDB_REG_SIZE 32
+#define KGDB_GDB_REG_SIZE      32
+#define GDB_SIZEOF_REG         sizeof(u32)
 
 #elif (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
        (_MIPS_ISA == _MIPS_ISA_MIPS64)
 
 #ifdef CONFIG_32BIT
-#define KGDB_GDB_REG_SIZE 32
+#define KGDB_GDB_REG_SIZE      32
+#define GDB_SIZEOF_REG         sizeof(u32)
 #else /* CONFIG_CPU_32BIT */
-#define KGDB_GDB_REG_SIZE 64
+#define KGDB_GDB_REG_SIZE      64
+#define GDB_SIZEOF_REG         sizeof(u64)
 #endif
 #else
 #error "Need to set KGDB_GDB_REG_SIZE for MIPS ISA"
 #endif /* _MIPS_ISA */
 
 #define BUFMAX                 2048
-#if (KGDB_GDB_REG_SIZE == 32)
-#define NUMREGBYTES            (90*sizeof(u32))
-#define NUMCRITREGBYTES                (12*sizeof(u32))
-#else
-#define NUMREGBYTES            (90*sizeof(u64))
-#define NUMCRITREGBYTES                (12*sizeof(u64))
-#endif
+#define DBG_MAX_REG_NUM                72
+#define NUMREGBYTES            (DBG_MAX_REG_NUM * sizeof(GDB_SIZEOF_REG))
+#define NUMCRITREGBYTES                (12 * sizeof(GDB_SIZEOF_REG))
 #define BREAK_INSTR_SIZE       4
 #define CACHE_FLUSH_IS_SAFE    0
 
diff --git a/arch/mips/include/asm/local64.h b/arch/mips/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 9b78ff6e9b846fadcb135413b1f1ba7aa3c04fe4..1f4e2fa64140ee8204aed74ecf82eba7bab056be 100644 (file)
@@ -50,6 +50,151 @@ static struct hard_trap_info {
        { 0, 0}                 /* Must be last */
 };
 
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
+{
+       { "zero", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[0]) },
+       { "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[1]) },
+       { "v0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[2]) },
+       { "v1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[3]) },
+       { "a0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[4]) },
+       { "a1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[5]) },
+       { "a2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[6]) },
+       { "a3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[7]) },
+       { "t0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[8]) },
+       { "t1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[9]) },
+       { "t2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[10]) },
+       { "t3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[11]) },
+       { "t4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[12]) },
+       { "t5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[13]) },
+       { "t6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[14]) },
+       { "t7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[15]) },
+       { "s0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[16]) },
+       { "s1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[17]) },
+       { "s2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[18]) },
+       { "s3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[19]) },
+       { "s4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[20]) },
+       { "s5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[21]) },
+       { "s6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[22]) },
+       { "s7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[23]) },
+       { "t8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[24]) },
+       { "t9", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[25]) },
+       { "k0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[26]) },
+       { "k1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[27]) },
+       { "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[28]) },
+       { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[29]) },
+       { "s8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[30]) },
+       { "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[31]) },
+       { "sr", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_status) },
+       { "lo", GDB_SIZEOF_REG, offsetof(struct pt_regs, lo) },
+       { "hi", GDB_SIZEOF_REG, offsetof(struct pt_regs, hi) },
+       { "bad", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_badvaddr) },
+       { "cause", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_cause) },
+       { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_epc) },
+       { "f0", GDB_SIZEOF_REG, 0 },
+       { "f1", GDB_SIZEOF_REG, 1 },
+       { "f2", GDB_SIZEOF_REG, 2 },
+       { "f3", GDB_SIZEOF_REG, 3 },
+       { "f4", GDB_SIZEOF_REG, 4 },
+       { "f5", GDB_SIZEOF_REG, 5 },
+       { "f6", GDB_SIZEOF_REG, 6 },
+       { "f7", GDB_SIZEOF_REG, 7 },
+       { "f8", GDB_SIZEOF_REG, 8 },
+       { "f9", GDB_SIZEOF_REG, 9 },
+       { "f10", GDB_SIZEOF_REG, 10 },
+       { "f11", GDB_SIZEOF_REG, 11 },
+       { "f12", GDB_SIZEOF_REG, 12 },
+       { "f13", GDB_SIZEOF_REG, 13 },
+       { "f14", GDB_SIZEOF_REG, 14 },
+       { "f15", GDB_SIZEOF_REG, 15 },
+       { "f16", GDB_SIZEOF_REG, 16 },
+       { "f17", GDB_SIZEOF_REG, 17 },
+       { "f18", GDB_SIZEOF_REG, 18 },
+       { "f19", GDB_SIZEOF_REG, 19 },
+       { "f20", GDB_SIZEOF_REG, 20 },
+       { "f21", GDB_SIZEOF_REG, 21 },
+       { "f22", GDB_SIZEOF_REG, 22 },
+       { "f23", GDB_SIZEOF_REG, 23 },
+       { "f24", GDB_SIZEOF_REG, 24 },
+       { "f25", GDB_SIZEOF_REG, 25 },
+       { "f26", GDB_SIZEOF_REG, 26 },
+       { "f27", GDB_SIZEOF_REG, 27 },
+       { "f28", GDB_SIZEOF_REG, 28 },
+       { "f29", GDB_SIZEOF_REG, 29 },
+       { "f30", GDB_SIZEOF_REG, 30 },
+       { "f31", GDB_SIZEOF_REG, 31 },
+       { "fsr", GDB_SIZEOF_REG, 0 },
+       { "fir", GDB_SIZEOF_REG, 0 },
+};
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       int fp_reg;
+
+       if (regno < 0 || regno >= DBG_MAX_REG_NUM)
+               return -EINVAL;
+
+       if (dbg_reg_def[regno].offset != -1 && regno < 38) {
+               memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+                      dbg_reg_def[regno].size);
+       } else if (current && dbg_reg_def[regno].offset != -1 && regno < 72) {
+               /* FP registers 38 -> 69 */
+               if (!(regs->cp0_status & ST0_CU1))
+                       return 0;
+               if (regno == 70) {
+                       /* Process the fcr31/fsr (register 70) */
+                       memcpy((void *)&current->thread.fpu.fcr31, mem,
+                              dbg_reg_def[regno].size);
+                       goto out_save;
+               } else if (regno == 71) {
+                       /* Ignore the fir (register 71) */
+                       goto out_save;
+               }
+               fp_reg = dbg_reg_def[regno].offset;
+               memcpy((void *)&current->thread.fpu.fpr[fp_reg], mem,
+                      dbg_reg_def[regno].size);
+out_save:
+               restore_fp(current);
+       }
+
+       return 0;
+}
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       int fp_reg;
+
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return NULL;
+
+       if (dbg_reg_def[regno].offset != -1 && regno < 38) {
+               /* First 38 registers */
+               memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+                      dbg_reg_def[regno].size);
+       } else if (current && dbg_reg_def[regno].offset != -1 && regno < 72) {
+               /* FP registers 38 -> 69 */
+               if (!(regs->cp0_status & ST0_CU1))
+                       goto out;
+               save_fp(current);
+               if (regno == 70) {
+                       /* Process the fcr31/fsr (register 70) */
+                       memcpy(mem, (void *)&current->thread.fpu.fcr31,
+                              dbg_reg_def[regno].size);
+                       goto out;
+               } else if (regno == 71) {
+                       /* Ignore the fir (register 71) */
+                       memset(mem, 0, dbg_reg_def[regno].size);
+                       goto out;
+               }
+               fp_reg = dbg_reg_def[regno].offset;
+               memcpy(mem, (void *)&current->thread.fpu.fpr[fp_reg],
+                      dbg_reg_def[regno].size);
+       }
+
+out:
+       return dbg_reg_def[regno].name;
+
+}
+
 void arch_kgdb_breakpoint(void)
 {
        __asm__ __volatile__(
@@ -84,64 +229,6 @@ static int compute_signal(int tt)
        return SIGHUP;          /* default for things we don't know about */
 }
 
-void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
-       int reg;
-
-#if (KGDB_GDB_REG_SIZE == 32)
-       u32 *ptr = (u32 *)gdb_regs;
-#else
-       u64 *ptr = (u64 *)gdb_regs;
-#endif
-
-       for (reg = 0; reg < 32; reg++)
-               *(ptr++) = regs->regs[reg];
-
-       *(ptr++) = regs->cp0_status;
-       *(ptr++) = regs->lo;
-       *(ptr++) = regs->hi;
-       *(ptr++) = regs->cp0_badvaddr;
-       *(ptr++) = regs->cp0_cause;
-       *(ptr++) = regs->cp0_epc;
-
-       /* FP REGS */
-       if (!(current && (regs->cp0_status & ST0_CU1)))
-               return;
-
-       save_fp(current);
-       for (reg = 0; reg < 32; reg++)
-               *(ptr++) = current->thread.fpu.fpr[reg];
-}
-
-void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
-       int reg;
-
-#if (KGDB_GDB_REG_SIZE == 32)
-       const u32 *ptr = (u32 *)gdb_regs;
-#else
-       const u64 *ptr = (u64 *)gdb_regs;
-#endif
-
-       for (reg = 0; reg < 32; reg++)
-               regs->regs[reg] = *(ptr++);
-
-       regs->cp0_status = *(ptr++);
-       regs->lo = *(ptr++);
-       regs->hi = *(ptr++);
-       regs->cp0_badvaddr = *(ptr++);
-       regs->cp0_cause = *(ptr++);
-       regs->cp0_epc = *(ptr++);
-
-       /* FP REGS from current */
-       if (!(current && (regs->cp0_status & ST0_CU1)))
-               return;
-
-       for (reg = 0; reg < 32; reg++)
-               current->thread.fpu.fpr[reg] = *(ptr++);
-       restore_fp(current);
-}
-
 /*
  * Similar to regs_to_gdb_regs() except that process is sleeping and so
  * we may not be able to get all the info.
@@ -242,7 +329,7 @@ static struct notifier_block kgdb_notifier = {
 };
 
 /*
- * Handle the 's' and 'c' commands
+ * Handle the 'c' command
  */
 int kgdb_arch_handle_exception(int vector, int signo, int err_code,
                               char *remcom_in_buffer, char *remcom_out_buffer,
@@ -250,20 +337,14 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
 {
        char *ptr;
        unsigned long address;
-       int cpu = smp_processor_id();
 
        switch (remcom_in_buffer[0]) {
-       case 's':
        case 'c':
                /* handle the optional parameter */
                ptr = &remcom_in_buffer[1];
                if (kgdb_hex2long(&ptr, &address))
                        regs->cp0_epc = address;
 
-               atomic_set(&kgdb_cpu_doing_single_step, -1);
-               if (remcom_in_buffer[0] == 's')
-                       atomic_set(&kgdb_cpu_doing_single_step, cpu);
-
                return 0;
        }
 
index 1c4565a9102b269802129324f1b322eb8834cbbf..444b9f918fdf8f2d5dec64b9827d8d746bb1ade1 100644 (file)
@@ -46,9 +46,6 @@ config GENERIC_FIND_NEXT_BIT
 config GENERIC_HWEIGHT
        def_bool y
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_BUG
        def_bool y
 
diff --git a/arch/mn10300/include/asm/local64.h b/arch/mn10300/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 05a366a5c4d5c28431d3910aa69d993e7372e737..907417d187e15039bb4bb6d96075cd950a045dbd 100644 (file)
@@ -66,10 +66,6 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
-config GENERIC_TIME
-       bool
-       default y
-
 config TIME_LOW_RES
        bool
        depends on SMP
diff --git a/arch/parisc/include/asm/local64.h b/arch/parisc/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 9877372ffdba75b209d25e9be21210f19d5b91d9..5beb97bafbb1d5818e3ab83c058199353aaf2bb2 100644 (file)
@@ -82,7 +82,7 @@ unsigned long ftrace_return_to_handler(unsigned long retval0,
        unsigned long ret;
 
        pop_return_trace(&trace, &ret);
-       trace.rettime = cpu_clock(raw_smp_processor_id());
+       trace.rettime = local_clock();
        ftrace_graph_return(&trace);
 
        if (unlikely(!ret)) {
@@ -126,7 +126,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
                return;
        }
 
-       calltime = cpu_clock(raw_smp_processor_id());
+       calltime = local_clock();
 
        if (push_return_trace(old, calltime,
                                self_addr, &trace.depth) == -EBUSY) {
index e4545f85ee9fa5ef3dfb38985b428dc706f25158..631e5a0fb6abcf2e124f0dfc6d1ed95d9b9f4566 100644 (file)
@@ -29,9 +29,6 @@ config MMU
 config GENERIC_CMOS_UPDATE
        def_bool y
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_TIME_VSYSCALL
        def_bool y
 
@@ -120,6 +117,8 @@ config ARCH_NO_VIRT_TO_BUS
 config PPC
        bool
        default y
+       select OF
+       select OF_FLATTREE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_TRACER
@@ -173,10 +172,6 @@ config ARCH_MAY_HAVE_PC_FDC
 config PPC_OF
        def_bool y
 
-config OF
-       def_bool y
-       select OF_FLATTREE
-
 config PPC_UDBG_16550
        bool
        default n
@@ -199,10 +194,6 @@ config SYS_SUPPORTS_APM_EMULATION
        default y if PMAC_APM_EMU
        bool
 
-config DTC
-       bool
-       default y
-
 config DEFAULT_UIMAGE
        bool
        help
@@ -579,14 +570,6 @@ config SCHED_SMT
          when dealing with POWER5 cpus at a cost of slightly increased
          overhead in some places. If unsure say N here.
 
-config PROC_DEVICETREE
-       bool "Support for device tree in /proc"
-       depends on PROC_FS
-       help
-         This option adds a device-tree directory under /proc which contains
-         an image of the device tree that the kernel copies from Open
-         Firmware or other boot firmware. If unsure, say Y here.
-
 config CMDLINE_BOOL
        bool "Default bootloader kernel arguments"
 
index 77cfe7a29e2574a3601c0db1c9a58b96bedfd101..5d42f5eae70f43792d9c3e84ac0a0bb0e5833bcf 100644 (file)
@@ -94,7 +94,7 @@ else
 endif
 endif
 
-LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
+KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
 
 ifeq ($(CONFIG_TUNE_CELL),y)
        KBUILD_CFLAGS += $(call cc-option,-mtune=cell)
index 5e2e2cfcc81b5014737947c566a1670bae3d9735..3a40a992e5941ea73628aca26f12a30cd0d387d0 100644 (file)
@@ -197,6 +197,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_SAO                    LONG_ASM_CONST(0x0020000000000000)
 #define CPU_FTR_CP_USE_DCBTZ           LONG_ASM_CONST(0x0040000000000000)
 #define CPU_FTR_UNALIGNED_LD_STD       LONG_ASM_CONST(0x0080000000000000)
+#define CPU_FTR_ASYM_SMT               LONG_ASM_CONST(0x0100000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -412,7 +413,7 @@ extern const char *powerpc_base_platform;
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
            CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
-           CPU_FTR_DSCR | CPU_FTR_SAO)
+           CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT)
 #define CPU_FTRS_CELL  (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
index ecba37a91749a1e869ed26afff90563b85813cb6..67ab5fb7d153690fd4af621c493f2c294895077c 100644 (file)
@@ -300,34 +300,6 @@ extern unsigned int irq_alloc_virt(struct irq_host *host,
  */
 extern void irq_free_virt(unsigned int virq, unsigned int count);
 
-
-/* -- OF helpers -- */
-
-/**
- * irq_create_of_mapping - Map a hardware interrupt into linux virq space
- * @controller: Device node of the interrupt controller
- * @inspec: Interrupt specifier from the device-tree
- * @intsize: Size of the interrupt specifier from the device-tree
- *
- * This function is identical to irq_create_mapping except that it takes
- * as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions.
- */
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
-                                         const u32 *intspec, unsigned int intsize);
-
-/**
- * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
- * @device: Device node of the device whose interrupt is to be mapped
- * @index: Index of the interrupt to map
- *
- * This function is a wrapper that chains of_irq_map_one() and
- * irq_create_of_mapping() to make things easier to callers
- */
-extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
-
-/* -- End OF helpers -- */
-
 /**
  * irq_early_init - Init irq remapping subsystem
  */
diff --git a/arch/powerpc/include/asm/local64.h b/arch/powerpc/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 675e159b5ef42decbf2617870963547f07016870..7ab82c825a034f7af25c19f5d78a88880022e2a2 100644 (file)
@@ -38,7 +38,7 @@ struct macio_dev
 {
        struct macio_bus        *bus;           /* macio bus this device is on */
        struct macio_dev        *media_bay;     /* Device is part of a media bay */
-       struct of_device        ofdev;
+       struct platform_device  ofdev;
        struct device_dma_parameters dma_parms; /* ide needs that */
        int                     n_resources;
        struct resource         resource[MACIO_DEV_COUNT_RESOURCES];
diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h
deleted file mode 100644 (file)
index 444e97e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef _ASM_POWERPC_OF_DEVICE_H
-#define _ASM_POWERPC_OF_DEVICE_H
-#ifdef __KERNEL__
-
-#include <linux/device.h>
-#include <linux/of.h>
-
-/*
- * The of_device is a kind of "base class" that is a superset of
- * struct device for use by devices attached to an OF node and
- * probed using OF properties.
- */
-struct of_device
-{
-       struct device           dev;            /* Generic device interface */
-       struct pdev_archdata    archdata;
-};
-
-extern struct of_device *of_device_alloc(struct device_node *np,
-                                        const char *bus_id,
-                                        struct device *parent);
-
-extern int of_device_uevent(struct device *dev,
-                           struct kobj_uevent_env *env);
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_OF_DEVICE_H */
diff --git a/arch/powerpc/include/asm/of_platform.h b/arch/powerpc/include/asm/of_platform.h
deleted file mode 100644 (file)
index d4aaa34..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _ASM_POWERPC_OF_PLATFORM_H
-#define _ASM_POWERPC_OF_PLATFORM_H
-/*
- *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
- *                      <benh@kernel.crashing.org>
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- */
-
-/* Platform devices and busses creation */
-extern struct of_device *of_platform_device_create(struct device_node *np,
-                                                  const char *bus_id,
-                                                  struct device *parent);
-/* pseudo "matches" value to not do deep probe */
-#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
-
-extern int of_platform_bus_probe(struct device_node *root,
-                                const struct of_device_id *matches,
-                                struct device *parent);
-
-extern struct of_device *of_find_device_by_phandle(phandle ph);
-
-extern void of_instantiate_rtc(void);
-
-#endif /* _ASM_POWERPC_OF_PLATFORM_H */
index 76e1f313a58e2306451f6f933915690db1b4ddd9..51e9e6f90d12110aa70ae04cb8c922164947c121 100644 (file)
@@ -303,13 +303,8 @@ extern void pcibios_free_controller(struct pci_controller *phb);
 extern void pcibios_setup_phb_resources(struct pci_controller *hose);
 
 #ifdef CONFIG_PCI
-extern unsigned long pci_address_to_pio(phys_addr_t address);
 extern int pcibios_vaddr_is_ioport(void __iomem *address);
 #else
-static inline unsigned long pci_address_to_pio(phys_addr_t address)
-{
-       return (unsigned long)-1;
-}
 static inline int pcibios_vaddr_is_ioport(void __iomem *address)
 {
        return 0;
index e6d4ce69b126eef07a463fc144ef2020ed53ad05..5c16b891d501f8f3943a10311d1020da608843d1 100644 (file)
 #ifdef CONFIG_FSL_EMB_PERF_EVENT
 #include <asm/perf_event_fsl_emb.h>
 #endif
+
+#ifdef CONFIG_PERF_EVENTS
+#include <asm/ptrace.h>
+#include <asm/reg.h>
+
+#define perf_arch_fetch_caller_regs(regs, __ip)                        \
+       do {                                                    \
+               (regs)->nip = __ip;                             \
+               (regs)->gpr[1] = *(unsigned long *)__get_SP();  \
+               asm volatile("mfmsr %0" : "=r" ((regs)->msr));  \
+       } while (0)
+#endif
index ddd408a93b5a526c1c30d24c7c4d1a119365e338..ae26f2efd089c80d92f0c9b50ea434dd43464f91 100644 (file)
@@ -17,9 +17,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/types.h>
-#include <linux/of_fdt.h>
-#include <linux/proc_fs.h>
-#include <linux/platform_device.h>
 #include <asm/irq.h>
 #include <asm/atomic.h>
 
@@ -43,49 +40,14 @@ extern void pci_create_OF_bus_map(void);
  * OF address retreival & translation
  */
 
-/* Translate an OF address block into a CPU physical address
- */
-extern u64 of_translate_address(struct device_node *np, const u32 *addr);
-
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
                                    const u32 *in_addr);
 
-/* Extract an address from a device, returns the region size and
- * the address space flags too. The PCI version uses a BAR number
- * instead of an absolute index
- */
-extern const u32 *of_get_address(struct device_node *dev, int index,
-                          u64 *size, unsigned int *flags);
 #ifdef CONFIG_PCI
-extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
-                              u64 *size, unsigned int *flags);
-#else
-static inline const u32 *of_get_pci_address(struct device_node *dev,
-               int bar_no, u64 *size, unsigned int *flags)
-{
-       return NULL;
-}
-#endif /* CONFIG_PCI */
-
-/* Get an address as a resource. Note that if your address is
- * a PIO address, the conversion will fail if the physical address
- * can't be internally converted to an IO token with
- * pci_address_to_pio(), that is because it's either called to early
- * or it can't be matched to any host bridge IO space
- */
-extern int of_address_to_resource(struct device_node *dev, int index,
-                                 struct resource *r);
-#ifdef CONFIG_PCI
-extern int of_pci_address_to_resource(struct device_node *dev, int bar,
-                                     struct resource *r);
-#else
-static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
-               struct resource *r)
-{
-       return -ENOSYS;
-}
-#endif /* CONFIG_PCI */
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+#define pci_address_to_pio pci_address_to_pio
+#endif /* CONFIG_PCI */
 
 /* Parse the ibm,dma-window property of an OF node into the busno, phys and
  * size parameters.
@@ -104,69 +66,12 @@ struct device_node *of_find_next_cache_node(struct device_node *np);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/*
- * OF interrupt mapping
- */
-
-/* This structure is returned when an interrupt is mapped. The controller
- * field needs to be put() after use
- */
-
-#define OF_MAX_IRQ_SPEC                 4 /* We handle specifiers of at most 4 cells */
-
-struct of_irq {
-       struct device_node *controller; /* Interrupt controller node */
-       u32 size;                       /* Specifier size */
-       u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
-};
-
-/**
- * of_irq_map_init - Initialize the irq remapper
- * @flags:     flags defining workarounds to enable
- *
- * Some machines have bugs in the device-tree which require certain workarounds
- * to be applied. Call this before any interrupt mapping attempts to enable
- * those workarounds.
- */
-#define OF_IMAP_OLDWORLD_MAC   0x00000001
-#define OF_IMAP_NO_PHANDLE     0x00000002
-
-extern void of_irq_map_init(unsigned int flags);
-
-/**
- * of_irq_map_raw - Low level interrupt tree parsing
- * @parent:    the device interrupt parent
- * @intspec:   interrupt specifier ("interrupts" property of the device)
- * @ointsize:   size of the passed in interrupt specifier
- * @addr:      address specifier (start of "reg" property of the device)
- * @out_irq:   structure of_irq filled by this function
- *
- * Returns 0 on success and a negative number on error
- *
- * This function is a low-level interrupt tree walking function. It
- * can be used to do a partial walk with synthetized reg and interrupts
- * properties, for example when resolving PCI interrupts when no device
- * node exist for the parent.
- *
- */
-
-extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
-                         u32 ointsize, const u32 *addr,
-                         struct of_irq *out_irq);
-
-
-/**
- * of_irq_map_one - Resolve an interrupt for a device
- * @device:    the device whose interrupt is to be resolved
- * @index:             index of the interrupt to resolve
- * @out_irq:   structure of_irq filled by this function
- *
- * This function resolves an interrupt, walking the tree, for a given
- * device-tree node. It's the high level pendant to of_irq_map_raw().
- * It also implements the workarounds for OldWolrd Macs.
- */
-extern int of_irq_map_one(struct device_node *device, int index,
-                         struct of_irq *out_irq);
+#ifdef CONFIG_NUMA
+extern int of_node_to_nid(struct device_node *device);
+#else
+static inline int of_node_to_nid(struct device_node *device) { return 0; }
+#endif
+#define of_node_to_nid of_node_to_nid
 
 /**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
@@ -180,19 +85,19 @@ extern int of_irq_map_one(struct device_node *device, int index,
  * resolving using the OF tree walking.
  */
 struct pci_dev;
+struct of_irq;
 extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
 
-extern int of_irq_to_resource(struct device_node *dev, int index,
-                       struct resource *r);
+extern void of_instantiate_rtc(void);
 
-/**
- * of_iomap - Maps the memory mapped IO for a given device_node
- * @device:    the device whose io range will be mapped
- * @index:     index of the io range
- *
- * Returns a pointer to the mapped memory
- */
-extern void __iomem *of_iomap(struct device_node *device, int index);
+/* These includes are put at the bottom because they may contain things
+ * that are overridden by this file.  Ideally they shouldn't be included
+ * by this file, but there are a bunch of .c files that currently depend
+ * on it.  Eventually they will be cleaned up. */
+#include <linux/of_fdt.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
 
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
index 7ae2753da565d6435c05b8d0e9ff505ae94fa928..e3bdada8c542b732d619d5ac9192fe26180003ee 100644 (file)
@@ -457,8 +457,8 @@ extern void smu_poll(void);
  */
 extern int smu_init(void);
 extern int smu_present(void);
-struct of_device;
-extern struct of_device *smu_get_ofdev(void);
+struct platform_device;
+extern struct platform_device *smu_get_ofdev(void);
 
 
 /*
index 3033c1b307456e6e0ea53b6eea3910d0d2be9223..afe4aaa65c3b65b103b4a5f71e057f365b32ae65 100644 (file)
@@ -41,8 +41,6 @@ static inline int cpu_to_node(int cpu)
                               cpu_all_mask :                           \
                               node_to_cpumask_map[node])
 
-int of_node_to_nid(struct device_node *device);
-
 struct pci_bus;
 #ifdef CONFIG_PCI
 extern int pcibus_to_node(struct pci_bus *bus);
@@ -97,11 +95,6 @@ extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid);
 
 #else
 
-static inline int of_node_to_nid(struct device_node *device)
-{
-       return 0;
-}
-
 static inline void dump_numa_cpu_topology(void) {}
 
 static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid)
index 77d831a1cc32549dc4f528c43297f8230cf9bb05..1dda70129141d04656c65c3af27389491c5c9261 100644 (file)
@@ -41,7 +41,7 @@ obj-$(CONFIG_PPC_BOOK3E_64)   += exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC64)            += vdso64/
 obj-$(CONFIG_ALTIVEC)          += vecemu.o
 obj-$(CONFIG_PPC_970_NAP)      += idle_power4.o
-obj-$(CONFIG_PPC_OF)           += of_device.o of_platform.o prom_parse.o
+obj-$(CONFIG_PPC_OF)           += of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)                += clock.o
 procfs-y                       := proc_powerpc.o
 obj-$(CONFIG_PROC_FS)          += $(procfs-y)
index 02f724f367533ee60f6512a7453cb0f0e3024fbc..4295e0b94b2db31238f008c49756955fd4922702 100644 (file)
@@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = {
        .priority = 0,
 };
 
-static struct notifier_block ppc_swiotlb_of_bus_notifier = {
-       .notifier_call = ppc_swiotlb_bus_notify,
-       .priority = 0,
-};
-
 int __init swiotlb_setup_bus_notifier(void)
 {
        bus_register_notifier(&platform_bus_type,
                              &ppc_swiotlb_plat_bus_notifier);
-       bus_register_notifier(&of_platform_bus_type,
-                             &ppc_swiotlb_of_bus_notifier);
-
        return 0;
 }
index 21266abfbda64cb0a11fd2a10aa8f1af47c574a1..9b626cfffce17d2a8c487c15f50bdd5bc229695f 100644 (file)
@@ -140,19 +140,19 @@ static struct dma_map_ops ibmebus_dma_ops = {
 
 static int ibmebus_match_path(struct device *dev, void *data)
 {
-       struct device_node *dn = to_of_device(dev)->dev.of_node;
+       struct device_node *dn = to_platform_device(dev)->dev.of_node;
        return (dn->full_name &&
                (strcasecmp((char *)data, dn->full_name) == 0));
 }
 
 static int ibmebus_match_node(struct device *dev, void *data)
 {
-       return to_of_device(dev)->dev.of_node == data;
+       return to_platform_device(dev)->dev.of_node == data;
 }
 
 static int ibmebus_create_device(struct device_node *dn)
 {
-       struct of_device *dev;
+       struct platform_device *dev;
        int ret;
 
        dev = of_device_alloc(dn, NULL, &ibmebus_bus_device);
@@ -298,7 +298,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
 
        if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
                                   ibmebus_match_path))) {
-               of_device_unregister(to_of_device(dev));
+               of_device_unregister(to_platform_device(dev));
 
                kfree(path);
                return count;
index 8f96d3198905150a2a325ad0297f8d14336ef587..d3ce67cf03be35855394905009d6a39729f7ac92 100644 (file)
@@ -53,6 +53,8 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -820,18 +822,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 }
 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 
-unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
-{
-       struct of_irq oirq;
-
-       if (of_irq_map_one(dev, index, &oirq))
-               return NO_IRQ;
-
-       return irq_create_of_mapping(oirq.controller, oirq.specifier,
-                                    oirq.size);
-}
-EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
-
 void irq_dispose_mapping(unsigned int virq)
 {
        struct irq_host *host;
index 82a7b228c81a6e73f0a95a3d464a6a8abcf689c1..7f61a3ac787c9ae6f848939d311d8a8756733cfa 100644 (file)
@@ -129,7 +129,7 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)
                return 0;
 
        if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr))
-               regs->nip += 4;
+               regs->nip += BREAK_INSTR_SIZE;
 
        return 1;
 }
index 035ada5443ee4e17cc6c0fc3fd2165505820b43e..c1fd0f9658fd715536b3b2a7ce57ca34de67eee4 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/serial_core.h>
 #include <linux/console.h>
 #include <linux/pci.h>
+#include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <asm/io.h>
 #include <asm/mmu.h>
index 22e507c8a5566d1f4dfcfe9db67482e3c0e83e35..2d29752cbe169ea9398fbd1381cd9eff64ec28c8 100644 (file)
@@ -127,29 +127,3 @@ _GLOBAL(__setup_cpu_power7)
 _GLOBAL(__restore_cpu_power7)
        /* place holder */
        blr
-
-/*
- * Get a minimal set of registers for our caller's nth caller.
- * r3 = regs pointer, r5 = n.
- *
- * We only get R1 (stack pointer), NIP (next instruction pointer)
- * and LR (link register).  These are all we can get in the
- * general case without doing complicated stack unwinding, but
- * fortunately they are enough to do a stack backtrace, which
- * is all we need them for.
- */
-_GLOBAL(perf_arch_fetch_caller_regs)
-       mr      r6,r1
-       cmpwi   r5,0
-       mflr    r4
-       ble     2f
-       mtctr   r5
-1:     PPC_LL  r6,0(r6)
-       bdnz    1b
-       PPC_LL  r4,PPC_LR_STKOFF(r6)
-2:     PPC_LL  r7,0(r6)
-       PPC_LL  r7,PPC_LR_STKOFF(r7)
-       PPC_STL r6,GPR1-STACK_FRAME_OVERHEAD(r3)
-       PPC_STL r4,_NIP-STACK_FRAME_OVERHEAD(r3)
-       PPC_STL r7,_LINK-STACK_FRAME_OVERHEAD(r3)
-       blr
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
deleted file mode 100644 (file)
index df78e02..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-
-#include <asm/errno.h>
-#include <asm/dcr.h>
-
-static void of_device_make_bus_id(struct of_device *dev)
-{
-       static atomic_t bus_no_reg_magic;
-       struct device_node *node = dev->dev.of_node;
-       const u32 *reg;
-       u64 addr;
-       int magic;
-
-       /*
-        * If it's a DCR based device, use 'd' for native DCRs
-        * and 'D' for MMIO DCRs.
-        */
-#ifdef CONFIG_PPC_DCR
-       reg = of_get_property(node, "dcr-reg", NULL);
-       if (reg) {
-#ifdef CONFIG_PPC_DCR_NATIVE
-               dev_set_name(&dev->dev, "d%x.%s", *reg, node->name);
-#else /* CONFIG_PPC_DCR_NATIVE */
-               addr = of_translate_dcr_address(node, *reg, NULL);
-               if (addr != OF_BAD_ADDR) {
-                       dev_set_name(&dev->dev, "D%llx.%s",
-                                    (unsigned long long)addr, node->name);
-                       return;
-               }
-#endif /* !CONFIG_PPC_DCR_NATIVE */
-       }
-#endif /* CONFIG_PPC_DCR */
-
-       /*
-        * For MMIO, get the physical address
-        */
-       reg = of_get_property(node, "reg", NULL);
-       if (reg) {
-               addr = of_translate_address(node, reg);
-               if (addr != OF_BAD_ADDR) {
-                       dev_set_name(&dev->dev, "%llx.%s",
-                                    (unsigned long long)addr, node->name);
-                       return;
-               }
-       }
-
-       /*
-        * No BusID, use the node name and add a globally incremented
-        * counter (and pray...)
-        */
-       magic = atomic_add_return(1, &bus_no_reg_magic);
-       dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
-}
-
-struct of_device *of_device_alloc(struct device_node *np,
-                                 const char *bus_id,
-                                 struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return NULL;
-
-       dev->dev.of_node = of_node_get(np);
-       dev->dev.dma_mask = &dev->archdata.dma_mask;
-       dev->dev.parent = parent;
-       dev->dev.release = of_release_dev;
-
-       if (bus_id)
-               dev_set_name(&dev->dev, "%s", bus_id);
-       else
-               of_device_make_bus_id(dev);
-
-       return dev;
-}
-EXPORT_SYMBOL(of_device_alloc);
-
-int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-       struct of_device *ofdev;
-       const char *compat;
-       int seen = 0, cplen, sl;
-
-       if (!dev)
-               return -ENODEV;
-
-       ofdev = to_of_device(dev);
-
-       if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name))
-               return -ENOMEM;
-
-       if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type))
-               return -ENOMEM;
-
-        /* Since the compatible field can contain pretty much anything
-         * it's not really legal to split it out with commas. We split it
-         * up using a number of environment variables instead. */
-
-       compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
-       while (compat && *compat && cplen > 0) {
-               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
-                       return -ENOMEM;
-
-               sl = strlen (compat) + 1;
-               compat += sl;
-               cplen -= sl;
-               seen++;
-       }
-
-       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
-               return -ENOMEM;
-
-       /* modalias is trickier, we add it in 2 steps */
-       if (add_uevent_var(env, "MODALIAS="))
-               return -ENOMEM;
-       sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
-                                   sizeof(env->buf) - env->buflen);
-       if (sl >= (sizeof(env->buf) - env->buflen))
-               return -ENOMEM;
-       env->buflen += sl;
-
-       return 0;
-}
-EXPORT_SYMBOL(of_device_uevent);
-EXPORT_SYMBOL(of_device_get_modalias);
index 487a98851ba6f04f24fd50d200f712ba29df46ac..b2c363ef38ad7dce344c9058abdad4563e911b21 100644 (file)
 #include <asm/ppc-pci.h>
 #include <asm/atomic.h>
 
-/*
- * The list of OF IDs below is used for matching bus types in the
- * system whose devices are to be exposed as of_platform_devices.
- *
- * This is the default list valid for most platforms. This file provides
- * functions who can take an explicit list if necessary though
- *
- * The search is always performed recursively looking for children of
- * the provided device_node and recursively if such a children matches
- * a bus type in the list
- */
-
-static const struct of_device_id of_default_bus_ids[] = {
-       { .type = "soc", },
-       { .compatible = "soc", },
-       { .type = "spider", },
-       { .type = "axon", },
-       { .type = "plb5", },
-       { .type = "plb4", },
-       { .type = "opb", },
-       { .type = "ebc", },
-       {},
-};
-
-struct bus_type of_platform_bus_type = {
-       .uevent = of_device_uevent,
-};
-EXPORT_SYMBOL(of_platform_bus_type);
-
-static int __init of_bus_driver_init(void)
-{
-       return of_bus_type_init(&of_platform_bus_type, "of_platform");
-}
-
-postcore_initcall(of_bus_driver_init);
-
-struct of_device* of_platform_device_create(struct device_node *np,
-                                           const char *bus_id,
-                                           struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = of_device_alloc(np, bus_id, parent);
-       if (!dev)
-               return NULL;
-
-       dev->archdata.dma_mask = 0xffffffffUL;
-       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-
-       dev->dev.bus = &of_platform_bus_type;
-
-       /* We do not fill the DMA ops for platform devices by default.
-        * This is currently the responsibility of the platform code
-        * to do such, possibly using a device notifier
-        */
-
-       if (of_device_register(dev) != 0) {
-               of_device_free(dev);
-               return NULL;
-       }
-
-       return dev;
-}
-EXPORT_SYMBOL(of_platform_device_create);
-
-
-
-/**
- * of_platform_bus_create - Create an OF device for a bus node and all its
- * children. Optionally recursively instanciate matching busses.
- * @bus: device node of the bus to instanciate
- * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
- * disallow recursive creation of child busses
- */
-static int of_platform_bus_create(const struct device_node *bus,
-                                 const struct of_device_id *matches,
-                                 struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       for_each_child_of_node(bus, child) {
-               pr_debug("   create child: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else if (!of_match_node(matches, child))
-                       continue;
-               if (rc == 0) {
-                       pr_debug("   and sub busses\n");
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               } if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
-       return rc;
-}
-
-/**
- * of_platform_bus_probe - Probe the device-tree for platform busses
- * @root: parent of the first level to probe or NULL for the root of the tree
- * @matches: match table, NULL to use the default
- * @parent: parent to hook devices from, NULL for toplevel
- *
- * Note that children of the provided root are not instanciated as devices
- * unless the specified root itself matches the bus list and is not NULL.
- */
-
-int of_platform_bus_probe(struct device_node *root,
-                         const struct of_device_id *matches,
-                         struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       if (matches == NULL)
-               matches = of_default_bus_ids;
-       if (matches == OF_NO_DEEP_PROBE)
-               return -EINVAL;
-       if (root == NULL)
-               root = of_find_node_by_path("/");
-       else
-               of_node_get(root);
-
-       pr_debug("of_platform_bus_probe()\n");
-       pr_debug(" starting at: %s\n", root->full_name);
-
-       /* Do a self check of bus type, if there's a match, create
-        * children
-        */
-       if (of_match_node(matches, root)) {
-               pr_debug(" root match, create all sub devices\n");
-               dev = of_platform_device_create(root, NULL, parent);
-               if (dev == NULL) {
-                       rc = -ENOMEM;
-                       goto bail;
-               }
-               pr_debug(" create all sub busses\n");
-               rc = of_platform_bus_create(root, matches, &dev->dev);
-               goto bail;
-       }
-       for_each_child_of_node(root, child) {
-               if (!of_match_node(matches, child))
-                       continue;
-
-               pr_debug("  match: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
- bail:
-       of_node_put(root);
-       return rc;
-}
-EXPORT_SYMBOL(of_platform_bus_probe);
-
-static int of_dev_node_match(struct device *dev, void *data)
-{
-       return to_of_device(dev)->dev.of_node == data;
-}
-
-struct of_device *of_find_device_by_node(struct device_node *np)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&of_platform_bus_type,
-                             NULL, np, of_dev_node_match);
-       if (dev)
-               return to_of_device(dev);
-       return NULL;
-}
-EXPORT_SYMBOL(of_find_device_by_node);
-
-static int of_dev_phandle_match(struct device *dev, void *data)
-{
-       phandle *ph = data;
-       return to_of_device(dev)->dev.of_node->phandle == *ph;
-}
-
-struct of_device *of_find_device_by_phandle(phandle ph)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&of_platform_bus_type,
-                             NULL, &ph, of_dev_phandle_match);
-       if (dev)
-               return to_of_device(dev);
-       return NULL;
-}
-EXPORT_SYMBOL(of_find_device_by_phandle);
-
-
 #ifdef CONFIG_PPC_OF_PLATFORM_PCI
 
 /* The probing of PCI controllers from of_platform is currently
@@ -237,7 +36,7 @@ EXPORT_SYMBOL(of_find_device_by_phandle);
  * lacking some bits needed here.
  */
 
-static int __devinit of_pci_phb_probe(struct of_device *dev,
+static int __devinit of_pci_phb_probe(struct platform_device *dev,
                                      const struct of_device_id *match)
 {
        struct pci_controller *phb;
index 5b38f6ae2b299695139c25a21cff0b73f8857808..9021c4ad4bbd3ebdcda00af9de8bf59e6bfacc83 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/of_address.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
index 5c14ffe5125813d19e6793ebf69e132fa19dbffe..d301a30445e09a49cec4a3d4dcf2ea01529934b3 100644 (file)
@@ -410,15 +410,15 @@ static void power_pmu_read(struct perf_event *event)
         * Therefore we treat them like NMIs.
         */
        do {
-               prev = atomic64_read(&event->hw.prev_count);
+               prev = local64_read(&event->hw.prev_count);
                barrier();
                val = read_pmc(event->hw.idx);
-       } while (atomic64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
+       } while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
 
        /* The counters are only 32 bits wide */
        delta = (val - prev) & 0xfffffffful;
-       atomic64_add(delta, &event->count);
-       atomic64_sub(delta, &event->hw.period_left);
+       local64_add(delta, &event->count);
+       local64_sub(delta, &event->hw.period_left);
 }
 
 /*
@@ -444,10 +444,10 @@ static void freeze_limited_counters(struct cpu_hw_events *cpuhw,
                if (!event->hw.idx)
                        continue;
                val = (event->hw.idx == 5) ? pmc5 : pmc6;
-               prev = atomic64_read(&event->hw.prev_count);
+               prev = local64_read(&event->hw.prev_count);
                event->hw.idx = 0;
                delta = (val - prev) & 0xfffffffful;
-               atomic64_add(delta, &event->count);
+               local64_add(delta, &event->count);
        }
 }
 
@@ -462,7 +462,7 @@ static void thaw_limited_counters(struct cpu_hw_events *cpuhw,
                event = cpuhw->limited_counter[i];
                event->hw.idx = cpuhw->limited_hwidx[i];
                val = (event->hw.idx == 5) ? pmc5 : pmc6;
-               atomic64_set(&event->hw.prev_count, val);
+               local64_set(&event->hw.prev_count, val);
                perf_event_update_userpage(event);
        }
 }
@@ -666,11 +666,11 @@ void hw_perf_enable(void)
                }
                val = 0;
                if (event->hw.sample_period) {
-                       left = atomic64_read(&event->hw.period_left);
+                       left = local64_read(&event->hw.period_left);
                        if (left < 0x80000000L)
                                val = 0x80000000L - left;
                }
-               atomic64_set(&event->hw.prev_count, val);
+               local64_set(&event->hw.prev_count, val);
                event->hw.idx = idx;
                write_pmc(idx, val);
                perf_event_update_userpage(event);
@@ -754,7 +754,7 @@ static int power_pmu_enable(struct perf_event *event)
         * skip the schedulability test here, it will be peformed
         * at commit time(->commit_txn) as a whole
         */
-       if (cpuhw->group_flag & PERF_EVENT_TXN_STARTED)
+       if (cpuhw->group_flag & PERF_EVENT_TXN)
                goto nocheck;
 
        if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
@@ -845,8 +845,8 @@ static void power_pmu_unthrottle(struct perf_event *event)
        if (left < 0x80000000L)
                val = 0x80000000L - left;
        write_pmc(event->hw.idx, val);
-       atomic64_set(&event->hw.prev_count, val);
-       atomic64_set(&event->hw.period_left, left);
+       local64_set(&event->hw.prev_count, val);
+       local64_set(&event->hw.period_left, left);
        perf_event_update_userpage(event);
        perf_enable();
        local_irq_restore(flags);
@@ -861,7 +861,7 @@ void power_pmu_start_txn(const struct pmu *pmu)
 {
        struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
 
-       cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
+       cpuhw->group_flag |= PERF_EVENT_TXN;
        cpuhw->n_txn_start = cpuhw->n_events;
 }
 
@@ -874,7 +874,7 @@ void power_pmu_cancel_txn(const struct pmu *pmu)
 {
        struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
 
-       cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
+       cpuhw->group_flag &= ~PERF_EVENT_TXN;
 }
 
 /*
@@ -900,6 +900,7 @@ int power_pmu_commit_txn(const struct pmu *pmu)
        for (i = cpuhw->n_txn_start; i < n; ++i)
                cpuhw->event[i]->hw.config = cpuhw->events[i];
 
+       cpuhw->group_flag &= ~PERF_EVENT_TXN;
        return 0;
 }
 
@@ -1111,7 +1112,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
        event->hw.config = events[n];
        event->hw.event_base = cflags[n];
        event->hw.last_period = event->hw.sample_period;
-       atomic64_set(&event->hw.period_left, event->hw.last_period);
+       local64_set(&event->hw.period_left, event->hw.last_period);
 
        /*
         * See if we need to reserve the PMU.
@@ -1149,16 +1150,16 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
        int record = 0;
 
        /* we don't have to worry about interrupts here */
-       prev = atomic64_read(&event->hw.prev_count);
+       prev = local64_read(&event->hw.prev_count);
        delta = (val - prev) & 0xfffffffful;
-       atomic64_add(delta, &event->count);
+       local64_add(delta, &event->count);
 
        /*
         * See if the total period for this event has expired,
         * and update for the next period.
         */
        val = 0;
-       left = atomic64_read(&event->hw.period_left) - delta;
+       left = local64_read(&event->hw.period_left) - delta;
        if (period) {
                if (left <= 0) {
                        left += period;
@@ -1196,8 +1197,8 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
        }
 
        write_pmc(event->hw.idx, val);
-       atomic64_set(&event->hw.prev_count, val);
-       atomic64_set(&event->hw.period_left, left);
+       local64_set(&event->hw.prev_count, val);
+       local64_set(&event->hw.period_left, left);
        perf_event_update_userpage(event);
 }
 
index babcceecd2eab6335217d2434c6e91e5c7fe5884..1ba45471ae436617e1ecbf3654a5064ef15d1af7 100644 (file)
@@ -162,15 +162,15 @@ static void fsl_emb_pmu_read(struct perf_event *event)
         * Therefore we treat them like NMIs.
         */
        do {
-               prev = atomic64_read(&event->hw.prev_count);
+               prev = local64_read(&event->hw.prev_count);
                barrier();
                val = read_pmc(event->hw.idx);
-       } while (atomic64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
+       } while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
 
        /* The counters are only 32 bits wide */
        delta = (val - prev) & 0xfffffffful;
-       atomic64_add(delta, &event->count);
-       atomic64_sub(delta, &event->hw.period_left);
+       local64_add(delta, &event->count);
+       local64_sub(delta, &event->hw.period_left);
 }
 
 /*
@@ -296,11 +296,11 @@ static int fsl_emb_pmu_enable(struct perf_event *event)
 
        val = 0;
        if (event->hw.sample_period) {
-               s64 left = atomic64_read(&event->hw.period_left);
+               s64 left = local64_read(&event->hw.period_left);
                if (left < 0x80000000L)
                        val = 0x80000000L - left;
        }
-       atomic64_set(&event->hw.prev_count, val);
+       local64_set(&event->hw.prev_count, val);
        write_pmc(i, val);
        perf_event_update_userpage(event);
 
@@ -371,8 +371,8 @@ static void fsl_emb_pmu_unthrottle(struct perf_event *event)
        if (left < 0x80000000L)
                val = 0x80000000L - left;
        write_pmc(event->hw.idx, val);
-       atomic64_set(&event->hw.prev_count, val);
-       atomic64_set(&event->hw.period_left, left);
+       local64_set(&event->hw.prev_count, val);
+       local64_set(&event->hw.period_left, left);
        perf_event_update_userpage(event);
        perf_enable();
        local_irq_restore(flags);
@@ -500,7 +500,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
                return ERR_PTR(-ENOTSUPP);
 
        event->hw.last_period = event->hw.sample_period;
-       atomic64_set(&event->hw.period_left, event->hw.last_period);
+       local64_set(&event->hw.period_left, event->hw.last_period);
 
        /*
         * See if we need to reserve the PMU.
@@ -541,16 +541,16 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
        int record = 0;
 
        /* we don't have to worry about interrupts here */
-       prev = atomic64_read(&event->hw.prev_count);
+       prev = local64_read(&event->hw.prev_count);
        delta = (val - prev) & 0xfffffffful;
-       atomic64_add(delta, &event->count);
+       local64_add(delta, &event->count);
 
        /*
         * See if the total period for this event has expired,
         * and update for the next period.
         */
        val = 0;
-       left = atomic64_read(&event->hw.period_left) - delta;
+       left = local64_read(&event->hw.period_left) - delta;
        if (period) {
                if (left <= 0) {
                        left += period;
@@ -569,6 +569,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
                struct perf_sample_data data;
 
                perf_sample_data_init(&data, 0);
+               data.period = event->hw.last_period;
 
                if (perf_event_overflow(event, nmi, &data, regs)) {
                        /*
@@ -584,8 +585,8 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
        }
 
        write_pmc(event->hw.idx, val);
-       atomic64_set(&event->hw.prev_count, val);
-       atomic64_set(&event->hw.period_left, left);
+       local64_set(&event->hw.prev_count, val);
+       local64_set(&event->hw.period_left, left);
        perf_event_update_userpage(event);
 }
 
index 551f6713ff428930bcfa35556bd5ebd8676c30f4..e78a5add7f15e4b2fac02d962f839772ffc8e9fc 100644 (file)
@@ -1299,3 +1299,14 @@ unsigned long randomize_et_dyn(unsigned long base)
 
        return ret;
 }
+
+#ifdef CONFIG_SMP
+int arch_sd_sibling_asym_packing(void)
+{
+       if (cpu_has_feature(CPU_FTR_ASYM_SMT)) {
+               printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n");
+               return SD_ASYM_PACKING;
+       }
+       return 0;
+}
+#endif
index 8362620c9e6f449962b111f1537e767e87ea9df7..88334af038e58453dc2fc8d5cbb12bad0fc175e9 100644 (file)
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
+#include <linux/of_address.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 
-#ifdef DEBUG
-#define DBG(fmt...) do { printk(fmt); } while(0)
-#else
-#define DBG(fmt...) do { } while(0)
-#endif
-
-#ifdef CONFIG_PPC64
-#define PRu64  "%lx"
-#else
-#define PRu64  "%llx"
-#endif
-
-/* Max address size we deal with */
-#define OF_MAX_ADDR_CELLS      4
-#define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
-                       (ns) > 0)
-
-static struct of_bus *of_match_bus(struct device_node *np);
-static int __of_address_to_resource(struct device_node *dev,
-               const u32 *addrp, u64 size, unsigned int flags,
-               struct resource *r);
-
-
-/* Debug utility */
-#ifdef DEBUG
-static void of_dump_addr(const char *s, const u32 *addr, int na)
-{
-       printk("%s", s);
-       while(na--)
-               printk(" %08x", *(addr++));
-       printk("\n");
-}
-#else
-static void of_dump_addr(const char *s, const u32 *addr, int na) { }
-#endif
-
-
-/* Callbacks for bus specific translators */
-struct of_bus {
-       const char      *name;
-       const char      *addresses;
-       int             (*match)(struct device_node *parent);
-       void            (*count_cells)(struct device_node *child,
-                                      int *addrc, int *sizec);
-       u64             (*map)(u32 *addr, const u32 *range,
-                               int na, int ns, int pna);
-       int             (*translate)(u32 *addr, u64 offset, int na);
-       unsigned int    (*get_flags)(const u32 *addr);
-};
-
-
-/*
- * Default translator (generic bus)
- */
-
-static void of_bus_default_count_cells(struct device_node *dev,
-                                      int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = of_n_addr_cells(dev);
-       if (sizec)
-               *sizec = of_n_size_cells(dev);
-}
-
-static u64 of_bus_default_map(u32 *addr, const u32 *range,
-               int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       cp = of_read_number(range, na);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr, na);
-
-       DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
-           cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_default_translate(u32 *addr, u64 offset, int na)
-{
-       u64 a = of_read_number(addr, na);
-       memset(addr, 0, na * 4);
-       a += offset;
-       if (na > 1)
-               addr[na - 2] = a >> 32;
-       addr[na - 1] = a & 0xffffffffu;
-
-       return 0;
-}
-
-static unsigned int of_bus_default_get_flags(const u32 *addr)
-{
-       return IORESOURCE_MEM;
-}
-
-
 #ifdef CONFIG_PCI
-/*
- * PCI bus specific translator
- */
-
-static int of_bus_pci_match(struct device_node *np)
-{
-       /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
-       return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
-}
-
-static void of_bus_pci_count_cells(struct device_node *np,
-                                  int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 3;
-       if (sizec)
-               *sizec = 2;
-}
-
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       switch((w >> 24) & 0x03) {
-       case 0x01:
-               flags |= IORESOURCE_IO;
-               break;
-       case 0x02: /* 32 bits */
-       case 0x03: /* 64 bits */
-               flags |= IORESOURCE_MEM;
-               break;
-       }
-       if (w & 0x40000000)
-               flags |= IORESOURCE_PREFETCH;
-       return flags;
-}
-
-static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-       unsigned int af, rf;
-
-       af = of_bus_pci_get_flags(addr);
-       rf = of_bus_pci_get_flags(range);
-
-       /* Check address type match */
-       if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
-                       unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       if (strcmp(bus->name, "pci")) {
-               of_node_put(parent);
-               return NULL;
-       }
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_pci_address);
-
-int of_pci_address_to_resource(struct device_node *dev, int bar,
-                              struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_pci_address(dev, bar, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
-
 int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 {
        struct device_node *dn, *ppnode;
@@ -313,345 +92,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 EXPORT_SYMBOL_GPL(of_irq_map_pci);
 #endif /* CONFIG_PCI */
 
-/*
- * ISA bus specific translator
- */
-
-static int of_bus_isa_match(struct device_node *np)
-{
-       return !strcmp(np->name, "isa");
-}
-
-static void of_bus_isa_count_cells(struct device_node *child,
-                                  int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 2;
-       if (sizec)
-               *sizec = 1;
-}
-
-static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       /* Check address type match */
-       if ((addr[0] ^ range[0]) & 0x00000001)
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-static unsigned int of_bus_isa_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       if (w & 1)
-               flags |= IORESOURCE_IO;
-       else
-               flags |= IORESOURCE_MEM;
-       return flags;
-}
-
-
-/*
- * Array of bus specific translators
- */
-
-static struct of_bus of_busses[] = {
-#ifdef CONFIG_PCI
-       /* PCI */
-       {
-               .name = "pci",
-               .addresses = "assigned-addresses",
-               .match = of_bus_pci_match,
-               .count_cells = of_bus_pci_count_cells,
-               .map = of_bus_pci_map,
-               .translate = of_bus_pci_translate,
-               .get_flags = of_bus_pci_get_flags,
-       },
-#endif /* CONFIG_PCI */
-       /* ISA */
-       {
-               .name = "isa",
-               .addresses = "reg",
-               .match = of_bus_isa_match,
-               .count_cells = of_bus_isa_count_cells,
-               .map = of_bus_isa_map,
-               .translate = of_bus_isa_translate,
-               .get_flags = of_bus_isa_get_flags,
-       },
-       /* Default */
-       {
-               .name = "default",
-               .addresses = "reg",
-               .match = NULL,
-               .count_cells = of_bus_default_count_cells,
-               .map = of_bus_default_map,
-               .translate = of_bus_default_translate,
-               .get_flags = of_bus_default_get_flags,
-       },
-};
-
-static struct of_bus *of_match_bus(struct device_node *np)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
-               if (!of_busses[i].match || of_busses[i].match(np))
-                       return &of_busses[i];
-       BUG();
-       return NULL;
-}
-
-static int of_translate_one(struct device_node *parent, struct of_bus *bus,
-                           struct of_bus *pbus, u32 *addr,
-                           int na, int ns, int pna, const char *rprop)
-{
-       const u32 *ranges;
-       unsigned int rlen;
-       int rone;
-       u64 offset = OF_BAD_ADDR;
-
-       /* Normally, an absence of a "ranges" property means we are
-        * crossing a non-translatable boundary, and thus the addresses
-        * below the current not cannot be converted to CPU physical ones.
-        * Unfortunately, while this is very clear in the spec, it's not
-        * what Apple understood, and they do have things like /uni-n or
-        * /ht nodes with no "ranges" property and a lot of perfectly
-        * useable mapped devices below them. Thus we treat the absence of
-        * "ranges" as equivalent to an empty "ranges" property which means
-        * a 1:1 translation at that level. It's up to the caller not to try
-        * to translate addresses that aren't supposed to be translated in
-        * the first place. --BenH.
-        */
-       ranges = of_get_property(parent, rprop, &rlen);
-       if (ranges == NULL || rlen == 0) {
-               offset = of_read_number(addr, na);
-               memset(addr, 0, pna * 4);
-               DBG("OF: no ranges, 1:1 translation\n");
-               goto finish;
-       }
-
-       DBG("OF: walking ranges...\n");
-
-       /* Now walk through the ranges */
-       rlen /= 4;
-       rone = na + pna + ns;
-       for (; rlen >= rone; rlen -= rone, ranges += rone) {
-               offset = bus->map(addr, ranges, na, ns, pna);
-               if (offset != OF_BAD_ADDR)
-                       break;
-       }
-       if (offset == OF_BAD_ADDR) {
-               DBG("OF: not found !\n");
-               return 1;
-       }
-       memcpy(addr, ranges + na, 4 * pna);
-
- finish:
-       of_dump_addr("OF: parent translation for:", addr, pna);
-       DBG("OF: with offset: "PRu64"\n", offset);
-
-       /* Translate it into parent bus space */
-       return pbus->translate(addr, offset, pna);
-}
-
-
-/*
- * Translate an address from the device-tree into a CPU physical address,
- * this walks up the tree and applies the various bus mappings on the
- * way.
- *
- * Note: We consider that crossing any level with #size-cells == 0 to mean
- * that translation is impossible (that is we are not dealing with a value
- * that can be mapped to a cpu physical address). This is not really specified
- * that way, but this is traditionally the way IBM at least do things
- */
-u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
-                          const char *rprop)
-{
-       struct device_node *parent = NULL;
-       struct of_bus *bus, *pbus;
-       u32 addr[OF_MAX_ADDR_CELLS];
-       int na, ns, pna, pns;
-       u64 result = OF_BAD_ADDR;
-
-       DBG("OF: ** translation for device %s **\n", dev->full_name);
-
-       /* Increase refcount at current level */
-       of_node_get(dev);
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               goto bail;
-       bus = of_match_bus(parent);
-
-       /* Cound address cells & copy address locally */
-       bus->count_cells(dev, &na, &ns);
-       if (!OF_CHECK_COUNTS(na, ns)) {
-               printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                      dev->full_name);
-               goto bail;
-       }
-       memcpy(addr, in_addr, na * 4);
-
-       DBG("OF: bus is %s (na=%d, ns=%d) on %s\n",
-           bus->name, na, ns, parent->full_name);
-       of_dump_addr("OF: translating address:", addr, na);
-
-       /* Translate */
-       for (;;) {
-               /* Switch to parent bus */
-               of_node_put(dev);
-               dev = parent;
-               parent = of_get_parent(dev);
-
-               /* If root, we have finished */
-               if (parent == NULL) {
-                       DBG("OF: reached root node\n");
-                       result = of_read_number(addr, na);
-                       break;
-               }
-
-               /* Get new parent bus and counts */
-               pbus = of_match_bus(parent);
-               pbus->count_cells(dev, &pna, &pns);
-               if (!OF_CHECK_COUNTS(pna, pns)) {
-                       printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                              dev->full_name);
-                       break;
-               }
-
-               DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
-                   pbus->name, pna, pns, parent->full_name);
-
-               /* Apply bus translation */
-               if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
-                       break;
-
-               /* Complete the move up one level */
-               na = pna;
-               ns = pns;
-               bus = pbus;
-
-               of_dump_addr("OF: one level translation:", addr, na);
-       }
- bail:
-       of_node_put(parent);
-       of_node_put(dev);
-
-       return result;
-}
-
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
-{
-       return __of_translate_address(dev, in_addr, "ranges");
-}
-EXPORT_SYMBOL(of_translate_address);
-
-u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
-{
-       return __of_translate_address(dev, in_addr, "dma-ranges");
-}
-EXPORT_SYMBOL(of_translate_dma_address);
-
-const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
-                   unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if (i == index) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_address);
-
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-                                   u64 size, unsigned int flags,
-                                   struct resource *r)
-{
-       u64 taddr;
-
-       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
-               return -EINVAL;
-       taddr = of_translate_address(dev, addrp);
-       if (taddr == OF_BAD_ADDR)
-               return -EINVAL;
-       memset(r, 0, sizeof(struct resource));
-       if (flags & IORESOURCE_IO) {
-               unsigned long port;
-               port = pci_address_to_pio(taddr);
-               if (port == (unsigned long)-1)
-                       return -EINVAL;
-               r->start = port;
-               r->end = port + size - 1;
-       } else {
-               r->start = taddr;
-               r->end = taddr + size - 1;
-       }
-       r->flags = flags;
-       r->name = dev->name;
-       return 0;
-}
-
-int of_address_to_resource(struct device_node *dev, int index,
-                          struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_address(dev, index, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_address_to_resource);
-
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
                unsigned long *busno, unsigned long *phys, unsigned long *size)
 {
@@ -678,342 +118,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
        *size = of_read_number(dma_window, cells);
 }
 
-/*
- * Interrupt remapper
- */
-
-static unsigned int of_irq_workarounds;
-static struct device_node *of_irq_dflt_pic;
-
-static struct device_node *of_irq_find_parent(struct device_node *child)
-{
-       struct device_node *p;
-       const phandle *parp;
-
-       if (!of_node_get(child))
-               return NULL;
-
-       do {
-               parp = of_get_property(child, "interrupt-parent", NULL);
-               if (parp == NULL)
-                       p = of_get_parent(child);
-               else {
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               p = of_node_get(of_irq_dflt_pic);
-                       else
-                               p = of_find_node_by_phandle(*parp);
-               }
-               of_node_put(child);
-               child = p;
-       } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
-
-       return p;
-}
-
-/* This doesn't need to be called if you don't have any special workaround
- * flags to pass
- */
-void of_irq_map_init(unsigned int flags)
-{
-       of_irq_workarounds = flags;
-
-       /* OldWorld, don't bother looking at other things */
-       if (flags & OF_IMAP_OLDWORLD_MAC)
-               return;
-
-       /* If we don't have phandles, let's try to locate a default interrupt
-        * controller (happens when booting with BootX). We do a first match
-        * here, hopefully, that only ever happens on machines with one
-        * controller.
-        */
-       if (flags & OF_IMAP_NO_PHANDLE) {
-               struct device_node *np;
-
-               for_each_node_with_property(np, "interrupt-controller") {
-                       /* Skip /chosen/interrupt-controller */
-                       if (strcmp(np->name, "chosen") == 0)
-                               continue;
-                       /* It seems like at least one person on this planet wants
-                        * to use BootX on a machine with an AppleKiwi controller
-                        * which happens to pretend to be an interrupt
-                        * controller too.
-                        */
-                       if (strcmp(np->name, "AppleKiwi") == 0)
-                               continue;
-                       /* I think we found one ! */
-                       of_irq_dflt_pic = np;
-                       break;
-               }
-       }
-
-}
-
-int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
-               const u32 *addr, struct of_irq *out_irq)
-{
-       struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
-       const u32 *tmp, *imap, *imask;
-       u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
-       int imaplen, match, i;
-
-       DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
-           parent->full_name, intspec[0], intspec[1], ointsize);
-
-       ipar = of_node_get(parent);
-
-       /* First get the #interrupt-cells property of the current cursor
-        * that tells us how to interpret the passed-in intspec. If there
-        * is none, we are nice and just walk up the tree
-        */
-       do {
-               tmp = of_get_property(ipar, "#interrupt-cells", NULL);
-               if (tmp != NULL) {
-                       intsize = *tmp;
-                       break;
-               }
-               tnode = ipar;
-               ipar = of_irq_find_parent(ipar);
-               of_node_put(tnode);
-       } while (ipar);
-       if (ipar == NULL) {
-               DBG(" -> no parent found !\n");
-               goto fail;
-       }
-
-       DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
-
-       if (ointsize != intsize)
-               return -EINVAL;
-
-       /* Look for this #address-cells. We have to implement the old linux
-        * trick of looking for the parent here as some device-trees rely on it
-        */
-       old = of_node_get(ipar);
-       do {
-               tmp = of_get_property(old, "#address-cells", NULL);
-               tnode = of_get_parent(old);
-               of_node_put(old);
-               old = tnode;
-       } while(old && tmp == NULL);
-       of_node_put(old);
-       old = NULL;
-       addrsize = (tmp == NULL) ? 2 : *tmp;
-
-       DBG(" -> addrsize=%d\n", addrsize);
-
-       /* Now start the actual "proper" walk of the interrupt tree */
-       while (ipar != NULL) {
-               /* Now check if cursor is an interrupt-controller and if it is
-                * then we are done
-                */
-               if (of_get_property(ipar, "interrupt-controller", NULL) !=
-                               NULL) {
-                       DBG(" -> got it !\n");
-                       memcpy(out_irq->specifier, intspec,
-                              intsize * sizeof(u32));
-                       out_irq->size = intsize;
-                       out_irq->controller = ipar;
-                       of_node_put(old);
-                       return 0;
-               }
-
-               /* Now look for an interrupt-map */
-               imap = of_get_property(ipar, "interrupt-map", &imaplen);
-               /* No interrupt map, check for an interrupt parent */
-               if (imap == NULL) {
-                       DBG(" -> no map, getting parent\n");
-                       newpar = of_irq_find_parent(ipar);
-                       goto skiplevel;
-               }
-               imaplen /= sizeof(u32);
-
-               /* Look for a mask */
-               imask = of_get_property(ipar, "interrupt-map-mask", NULL);
-
-               /* If we were passed no "reg" property and we attempt to parse
-                * an interrupt-map, then #address-cells must be 0.
-                * Fail if it's not.
-                */
-               if (addr == NULL && addrsize != 0) {
-                       DBG(" -> no reg passed in when needed !\n");
-                       goto fail;
-               }
-
-               /* Parse interrupt-map */
-               match = 0;
-               while (imaplen > (addrsize + intsize + 1) && !match) {
-                       /* Compare specifiers */
-                       match = 1;
-                       for (i = 0; i < addrsize && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match = ((addr[i] ^ imap[i]) & mask) == 0;
-                       }
-                       for (; i < (addrsize + intsize) && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match =
-                                  ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
-                       }
-                       imap += addrsize + intsize;
-                       imaplen -= addrsize + intsize;
-
-                       DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
-
-                       /* Get the interrupt parent */
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               newpar = of_node_get(of_irq_dflt_pic);
-                       else
-                               newpar = of_find_node_by_phandle((phandle)*imap);
-                       imap++;
-                       --imaplen;
-
-                       /* Check if not found */
-                       if (newpar == NULL) {
-                               DBG(" -> imap parent not found !\n");
-                               goto fail;
-                       }
-
-                       /* Get #interrupt-cells and #address-cells of new
-                        * parent
-                        */
-                       tmp = of_get_property(newpar, "#interrupt-cells", NULL);
-                       if (tmp == NULL) {
-                               DBG(" -> parent lacks #interrupt-cells !\n");
-                               goto fail;
-                       }
-                       newintsize = *tmp;
-                       tmp = of_get_property(newpar, "#address-cells", NULL);
-                       newaddrsize = (tmp == NULL) ? 0 : *tmp;
-
-                       DBG(" -> newintsize=%d, newaddrsize=%d\n",
-                           newintsize, newaddrsize);
-
-                       /* Check for malformed properties */
-                       if (imaplen < (newaddrsize + newintsize))
-                               goto fail;
-
-                       imap += newaddrsize + newintsize;
-                       imaplen -= newaddrsize + newintsize;
-
-                       DBG(" -> imaplen=%d\n", imaplen);
-               }
-               if (!match)
-                       goto fail;
-
-               of_node_put(old);
-               old = of_node_get(newpar);
-               addrsize = newaddrsize;
-               intsize = newintsize;
-               intspec = imap - intsize;
-               addr = intspec - addrsize;
-
-       skiplevel:
-               /* Iterate again with new parent */
-               DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
-               of_node_put(ipar);
-               ipar = newpar;
-               newpar = NULL;
-       }
- fail:
-       of_node_put(ipar);
-       of_node_put(old);
-       of_node_put(newpar);
-
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_raw);
-
-#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
-static int of_irq_map_oldworld(struct device_node *device, int index,
-                              struct of_irq *out_irq)
-{
-       const u32 *ints = NULL;
-       int intlen;
-
-       /*
-        * Old machines just have a list of interrupt numbers
-        * and no interrupt-controller nodes. We also have dodgy
-        * cases where the APPL,interrupts property is completely
-        * missing behind pci-pci bridges and we have to get it
-        * from the parent (the bridge itself, as apple just wired
-        * everything together on these)
-        */
-       while (device) {
-               ints = of_get_property(device, "AAPL,interrupts", &intlen);
-               if (ints != NULL)
-                       break;
-               device = device->parent;
-               if (device && strcmp(device->type, "pci") != 0)
-                       break;
-       }
-       if (ints == NULL)
-               return -EINVAL;
-       intlen /= sizeof(u32);
-
-       if (index >= intlen)
-               return -EINVAL;
-
-       out_irq->controller = NULL;
-       out_irq->specifier[0] = ints[index];
-       out_irq->size = 1;
-
-       return 0;
-}
-#else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */
-static int of_irq_map_oldworld(struct device_node *device, int index,
-                              struct of_irq *out_irq)
-{
-       return -EINVAL;
-}
-#endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */
-
-int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
-{
-       struct device_node *p;
-       const u32 *intspec, *tmp, *addr;
-       u32 intsize, intlen;
-       int res = -EINVAL;
-
-       DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
-
-       /* OldWorld mac stuff is "special", handle out of line */
-       if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
-               return of_irq_map_oldworld(device, index, out_irq);
-
-       /* Get the interrupts property */
-       intspec = of_get_property(device, "interrupts", &intlen);
-       if (intspec == NULL)
-               return -EINVAL;
-       intlen /= sizeof(u32);
-
-       /* Get the reg property (if any) */
-       addr = of_get_property(device, "reg", NULL);
-
-       /* Look for the interrupt parent. */
-       p = of_irq_find_parent(device);
-       if (p == NULL)
-               return -EINVAL;
-
-       /* Get size of interrupt specifier */
-       tmp = of_get_property(p, "#interrupt-cells", NULL);
-       if (tmp == NULL)
-               goto out;
-       intsize = *tmp;
-
-       DBG(" intsize=%d intlen=%d\n", intsize, intlen);
-
-       /* Check index */
-       if ((index + 1) * intsize > intlen)
-               goto out;
-
-       /* Get new specifier and map it */
-       res = of_irq_map_raw(p, intspec + index * intsize, intsize,
-                            addr, out_irq);
-out:
-       of_node_put(p);
-       return res;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_one);
-
 /**
  * Search the device tree for the best MAC address to use.  'mac-address' is
  * checked first, because that is supposed to contain to "most recent" MAC
@@ -1051,29 +155,3 @@ const void *of_get_mac_address(struct device_node *np)
        return NULL;
 }
 EXPORT_SYMBOL(of_get_mac_address);
-
-int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
-       int irq = irq_of_parse_and_map(dev, index);
-
-       /* Only dereference the resource if both the
-        * resource and the irq are valid. */
-       if (r && irq != NO_IRQ) {
-               r->start = r->end = irq;
-               r->flags = IORESOURCE_IRQ;
-       }
-
-       return irq;
-}
-EXPORT_SYMBOL_GPL(of_irq_to_resource);
-
-void __iomem *of_iomap(struct device_node *np, int index)
-{
-       struct resource res;
-
-       if (of_address_to_resource(np, index, &res))
-               return NULL;
-
-       return ioremap(res.start, 1 + res.end - res.start);
-}
-EXPORT_SYMBOL(of_iomap);
index 70decd8068ca2a7802ca6c77f9b4ddf24089a801..15ade0d7bbb274b6327abb79fd1a275da4956acb 100644 (file)
@@ -714,16 +714,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = {
        .priority = INT_MAX,
 };
 
-static struct notifier_block ppc_dflt_of_bus_notifier = {
-       .notifier_call = ppc_dflt_bus_notify,
-       .priority = INT_MAX,
-};
-
 static int __init setup_bus_notifier(void)
 {
        bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier);
-       bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier);
-
        return 0;
 }
 
index ccb8759c8532e6955a0b5c1f05d2e3cdd83fee0b..ce53dfa7130dfc74f551c2360746f206154cf925 100644 (file)
@@ -796,10 +796,30 @@ static cycle_t timebase_read(struct clocksource *cs)
        return (cycle_t)get_tb();
 }
 
-static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
-                              u64 new_tb_to_xs, struct timespec *now,
-                              u32 frac_sec)
+void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
+                       struct clocksource *clock, u32 mult)
 {
+       u64 new_tb_to_xs, new_stamp_xsec;
+       u32 frac_sec;
+
+       if (clock != &clocksource_timebase)
+               return;
+
+       /* Make userspace gettimeofday spin until we're done. */
+       ++vdso_data->tb_update_count;
+       smp_mb();
+
+       /* XXX this assumes clock->shift == 22 */
+       /* 4611686018 ~= 2^(20+64-22) / 1e9 */
+       new_tb_to_xs = (u64) mult * 4611686018ULL;
+       new_stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
+       do_div(new_stamp_xsec, 1000000000);
+       new_stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC;
+
+       BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC);
+       /* this is tv_nsec / 1e9 as a 0.32 fraction */
+       frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32;
+
        /*
         * tb_update_count is used to allow the userspace gettimeofday code
         * to assure itself that it sees a consistent view of the tb_to_xs and
@@ -811,43 +831,17 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
         * We expect the caller to have done the first increment of
         * vdso_data->tb_update_count already.
         */
-       vdso_data->tb_orig_stamp = new_tb_stamp;
+       vdso_data->tb_orig_stamp = clock->cycle_last;
        vdso_data->stamp_xsec = new_stamp_xsec;
        vdso_data->tb_to_xs = new_tb_to_xs;
-       vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
-       vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
-       vdso_data->stamp_xtime = *now;
+       vdso_data->wtom_clock_sec = wtm->tv_sec;
+       vdso_data->wtom_clock_nsec = wtm->tv_nsec;
+       vdso_data->stamp_xtime = *wall_time;
        vdso_data->stamp_sec_fraction = frac_sec;
        smp_wmb();
        ++(vdso_data->tb_update_count);
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
-                    u32 mult)
-{
-       u64 t2x, stamp_xsec;
-       u32 frac_sec;
-
-       if (clock != &clocksource_timebase)
-               return;
-
-       /* Make userspace gettimeofday spin until we're done. */
-       ++vdso_data->tb_update_count;
-       smp_mb();
-
-       /* XXX this assumes clock->shift == 22 */
-       /* 4611686018 ~= 2^(20+64-22) / 1e9 */
-       t2x = (u64) mult * 4611686018ULL;
-       stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
-       do_div(stamp_xsec, 1000000000);
-       stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC;
-
-       BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC);
-       /* this is tv_nsec / 1e9 as a 0.32 fraction */
-       frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32;
-       update_gtod(clock->cycle_last, stamp_xsec, t2x, wall_time, frac_sec);
-}
-
 void update_vsyscall_tz(void)
 {
        /* Make userspace gettimeofday spin until we're done. */
index e1c5cd6650b12acea5b51d0e27f0fd995608c160..5b243bd3eb3b699ee6a0712340c9df51db2ed948 100644 (file)
@@ -678,7 +678,7 @@ static void psc_clks_init(void)
 {
        struct device_node *np;
        const u32 *cell_index;
-       struct of_device *ofdev;
+       struct platform_device *ofdev;
 
        for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") {
                cell_index = of_get_property(np, "cell-index", NULL);
index 6d584f4e3c9a1032b98e22e8f96cb91900158edf..de55bc0584b5d6cadaa24572db3302dbd0ea19ea 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/root_dev.h>
 #include <linux/initrd.h>
 #include <asm/time.h>
index ca5305a5bd61d8021c50dbb452db5adc376b4a0b..0dad9a935eb5f1f34d57c134c7441c3d26dfacdf 100644 (file)
@@ -147,26 +147,25 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
        return 0;
 }
 
-static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
+static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev,
                                        const struct of_device_id *match)
 {
        struct mpc52xx_gpiochip *chip;
        struct mpc52xx_gpio_wkup __iomem *regs;
-       struct of_gpio_chip *ofchip;
+       struct gpio_chip *gc;
        int ret;
 
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
 
-       ofchip = &chip->mmchip.of_gc;
+       gc = &chip->mmchip.gc;
 
-       ofchip->gpio_cells          = 2;
-       ofchip->gc.ngpio            = 8;
-       ofchip->gc.direction_input  = mpc52xx_wkup_gpio_dir_in;
-       ofchip->gc.direction_output = mpc52xx_wkup_gpio_dir_out;
-       ofchip->gc.get              = mpc52xx_wkup_gpio_get;
-       ofchip->gc.set              = mpc52xx_wkup_gpio_set;
+       gc->ngpio            = 8;
+       gc->direction_input  = mpc52xx_wkup_gpio_dir_in;
+       gc->direction_output = mpc52xx_wkup_gpio_dir_out;
+       gc->get              = mpc52xx_wkup_gpio_get;
+       gc->set              = mpc52xx_wkup_gpio_set;
 
        ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
        if (ret)
@@ -180,7 +179,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
        return 0;
 }
 
-static int mpc52xx_gpiochip_remove(struct of_device *ofdev)
+static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)
 {
        return -EBUSY;
 }
@@ -311,11 +310,11 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
        return 0;
 }
 
-static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
+static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev,
                                        const struct of_device_id *match)
 {
        struct mpc52xx_gpiochip *chip;
-       struct of_gpio_chip *ofchip;
+       struct gpio_chip *gc;
        struct mpc52xx_gpio __iomem *regs;
        int ret;
 
@@ -323,14 +322,13 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
        if (!chip)
                return -ENOMEM;
 
-       ofchip = &chip->mmchip.of_gc;
+       gc = &chip->mmchip.gc;
 
-       ofchip->gpio_cells          = 2;
-       ofchip->gc.ngpio            = 32;
-       ofchip->gc.direction_input  = mpc52xx_simple_gpio_dir_in;
-       ofchip->gc.direction_output = mpc52xx_simple_gpio_dir_out;
-       ofchip->gc.get              = mpc52xx_simple_gpio_get;
-       ofchip->gc.set              = mpc52xx_simple_gpio_set;
+       gc->ngpio            = 32;
+       gc->direction_input  = mpc52xx_simple_gpio_dir_in;
+       gc->direction_output = mpc52xx_simple_gpio_dir_out;
+       gc->get              = mpc52xx_simple_gpio_get;
+       gc->set              = mpc52xx_simple_gpio_set;
 
        ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
        if (ret)
index 46c93578cbf048230dc24fcd906a113872eb3bfb..fea833e18ad58ab92c78da66e35e2f23dcacd8ff 100644 (file)
@@ -78,7 +78,7 @@ MODULE_LICENSE("GPL");
  * @dev: pointer to device structure
  * @regs: virtual address of GPT registers
  * @lock: spinlock to coordinate between different functions.
- * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled
+ * @gc: gpio_chip instance structure; used when GPIO is enabled
  * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
  * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
  *   if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
@@ -94,7 +94,7 @@ struct mpc52xx_gpt_priv {
        u8 wdt_mode;
 
 #if defined(CONFIG_GPIOLIB)
-       struct of_gpio_chip of_gc;
+       struct gpio_chip gc;
 #endif
 };
 
@@ -280,7 +280,7 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
 #if defined(CONFIG_GPIOLIB)
 static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc)
 {
-       return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc);
+       return container_of(gc, struct mpc52xx_gpt_priv, gc);
 }
 
 static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
@@ -336,28 +336,25 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
        if (!of_find_property(node, "gpio-controller", NULL))
                return;
 
-       gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL);
-       if (!gpt->of_gc.gc.label) {
+       gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL);
+       if (!gpt->gc.label) {
                dev_err(gpt->dev, "out of memory\n");
                return;
        }
 
-       gpt->of_gc.gpio_cells = 2;
-       gpt->of_gc.gc.ngpio = 1;
-       gpt->of_gc.gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
-       gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out;
-       gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get;
-       gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set;
-       gpt->of_gc.gc.base = -1;
-       gpt->of_gc.xlate = of_gpio_simple_xlate;
-       node->data = &gpt->of_gc;
-       of_node_get(node);
+       gpt->gc.ngpio = 1;
+       gpt->gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
+       gpt->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
+       gpt->gc.get = mpc52xx_gpt_gpio_get;
+       gpt->gc.set = mpc52xx_gpt_gpio_set;
+       gpt->gc.base = -1;
+       gpt->gc.of_node = node;
 
        /* Setup external pin in GPIO mode */
        clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
                        MPC52xx_GPT_MODE_MS_GPIO);
 
-       rc = gpiochip_add(&gpt->of_gc.gc);
+       rc = gpiochip_add(&gpt->gc);
        if (rc)
                dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc);
 
@@ -723,7 +720,7 @@ static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
 /* ---------------------------------------------------------------------
  * of_platform bus binding code
  */
-static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
+static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev,
                                       const struct of_device_id *match)
 {
        struct mpc52xx_gpt_priv *gpt;
@@ -769,7 +766,7 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
        return 0;
 }
 
-static int mpc52xx_gpt_remove(struct of_device *ofdev)
+static int mpc52xx_gpt_remove(struct platform_device *ofdev)
 {
        return -EBUSY;
 }
index e86aec644501b26ff767379dfdc30a07df745e28..f4ac213c89c0b4fa190e7731813d3be40e44b9a3 100644 (file)
@@ -436,8 +436,8 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
 }
 EXPORT_SYMBOL(mpc52xx_lpbfifo_abort);
 
-static int __devinit
-mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op,
+                                          const struct of_device_id *match)
 {
        struct resource res;
        int rc = -ENOMEM;
@@ -507,7 +507,7 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
 }
 
 
-static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op)
+static int __devexit mpc52xx_lpbfifo_remove(struct platform_device *op)
 {
        if (lpbfifo.dev != &op->dev)
                return 0;
index 9f2e52b36f91673c4787c650bb1fe8b31ae3a09f..1565e0446dc822b2e3036e86077a0311f93d2cb3 100644 (file)
@@ -111,7 +111,7 @@ static struct mdiobb_ctrl ep8248e_mdio_ctrl = {
        .ops = &ep8248e_mdio_ops,
 };
 
-static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
+static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev,
                                         const struct of_device_id *match)
 {
        struct mii_bus *bus;
@@ -154,7 +154,7 @@ err_free_bus:
        return ret;
 }
 
-static int ep8248e_mdio_remove(struct of_device *ofdev)
+static int ep8248e_mdio_remove(struct platform_device *ofdev)
 {
        BUG();
        return 0;
index d119a7c1c17a970385aa43d975f45f59437053fc..70798ac911ef056b73eba4fccce9db0c157b37e8 100644 (file)
@@ -35,9 +35,8 @@
 
 struct mcu {
        struct mutex lock;
-       struct device_node *np;
        struct i2c_client *client;
-       struct of_gpio_chip of_gc;
+       struct gpio_chip gc;
        u8 reg_ctrl;
 };
 
@@ -56,8 +55,7 @@ static void mcu_power_off(void)
 
 static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 {
-       struct of_gpio_chip *of_gc = to_of_gpio_chip(gc);
-       struct mcu *mcu = container_of(of_gc, struct mcu, of_gc);
+       struct mcu *mcu = container_of(gc, struct mcu, gc);
        u8 bit = 1 << (4 + gpio);
 
        mutex_lock(&mcu->lock);
@@ -79,9 +77,7 @@ static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 static int mcu_gpiochip_add(struct mcu *mcu)
 {
        struct device_node *np;
-       struct of_gpio_chip *of_gc = &mcu->of_gc;
-       struct gpio_chip *gc = &of_gc->gc;
-       int ret;
+       struct gpio_chip *gc = &mcu->gc;
 
        np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx");
        if (!np)
@@ -94,32 +90,14 @@ static int mcu_gpiochip_add(struct mcu *mcu)
        gc->base = -1;
        gc->set = mcu_gpio_set;
        gc->direction_output = mcu_gpio_dir_out;
-       of_gc->gpio_cells = 2;
-       of_gc->xlate = of_gpio_simple_xlate;
+       gc->of_node = np;
 
-       np->data = of_gc;
-       mcu->np = np;
-
-       /*
-        * We don't want to lose the node, its ->data and ->full_name...
-        * So, if succeeded, we don't put the node here.
-        */
-       ret = gpiochip_add(gc);
-       if (ret)
-               of_node_put(np);
-       return ret;
+       return gpiochip_add(gc);
 }
 
 static int mcu_gpiochip_remove(struct mcu *mcu)
 {
-       int ret;
-
-       ret = gpiochip_remove(&mcu->of_gc.gc);
-       if (ret)
-               return ret;
-       of_node_put(mcu->np);
-
-       return 0;
+       return gpiochip_remove(&mcu->gc);
 }
 
 static int __devinit mcu_probe(struct i2c_client *client,
@@ -182,10 +160,16 @@ static const struct i2c_device_id mcu_ids[] = {
 };
 MODULE_DEVICE_TABLE(i2c, mcu_ids);
 
+static struct of_device_id mcu_of_match_table[] __devinitdata = {
+       { .compatible = "fsl,mcu-mpc8349emitx", },
+       { },
+};
+
 static struct i2c_driver mcu_driver = {
        .driver = {
                .name = "mcu-mpc8349emitx",
                .owner = THIS_MODULE,
+               .of_match_table = mcu_of_match_table,
        },
        .probe = mcu_probe,
        .remove = __devexit_p(mcu_remove),
index ebe6c353720972f992936da851bff121b651e9f2..75ae77f1af6a772e586a34d277bd9b5626ecac67 100644 (file)
@@ -99,7 +99,7 @@ struct pmc_type {
        int has_deep_sleep;
 };
 
-static struct of_device *pmc_dev;
+static struct platform_device *pmc_dev;
 static int has_deep_sleep, deep_sleeping;
 static int pmc_irq;
 static struct mpc83xx_pmc __iomem *pmc_regs;
@@ -318,7 +318,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = {
        .end = mpc83xx_suspend_end,
 };
 
-static int pmc_probe(struct of_device *ofdev,
+static int pmc_probe(struct platform_device *ofdev,
                      const struct of_device_id *match)
 {
        struct device_node *np = ofdev->dev.of_node;
@@ -396,7 +396,7 @@ out:
        return ret;
 }
 
-static int pmc_remove(struct of_device *ofdev)
+static int pmc_remove(struct platform_device *ofdev)
 {
        return -EPERM;
 };
index b8cb08dbd89c62b435b13a2fa69a2819a974d130..4ff7b1e7bbada2917bfd89e2950ac0c178f6a554 100644 (file)
@@ -118,12 +118,12 @@ static int __init gef_gpio_init(void)
                }
 
                /* Setup pointers to chip functions */
-               gef_gpio_chip->of_gc.gpio_cells = 2;
-               gef_gpio_chip->of_gc.gc.ngpio = 19;
-               gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
-               gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
-               gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
-               gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
+               gef_gpio_chip->gc.of_gpio_n_cells = 2;
+               gef_gpio_chip->gc.ngpio = 19;
+               gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
+               gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
+               gef_gpio_chip->gc.get = gef_gpio_get;
+               gef_gpio_chip->gc.set = gef_gpio_set;
 
                /* This function adds a memory mapped GPIO chip */
                retval = of_mm_gpiochip_add(np, gef_gpio_chip);
@@ -146,12 +146,12 @@ static int __init gef_gpio_init(void)
                }
 
                /* Setup pointers to chip functions */
-               gef_gpio_chip->of_gc.gpio_cells = 2;
-               gef_gpio_chip->of_gc.gc.ngpio = 6;
-               gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
-               gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
-               gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
-               gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
+               gef_gpio_chip->gc.of_gpio_n_cells = 2;
+               gef_gpio_chip->gc.ngpio = 6;
+               gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
+               gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
+               gef_gpio_chip->gc.get = gef_gpio_get;
+               gef_gpio_chip->gc.set = gef_gpio_set;
 
                /* This function adds a memory mapped GPIO chip */
                retval = of_mm_gpiochip_add(np, gef_gpio_chip);
index fb4eb0df054c0a701fe74df78990d40bd480e2df..03aabc0e16ac2f212ec6d5ae6a78909333e606c6 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/seq_file.h>
 #include <generated/utsrelease.h>
 
 #include <asm/machdep.h>
 #include <asm/cputable.h>
-#include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/i8259.h>
 #include <asm/time.h>
index 6257e5378615eeab7c687d7375490a48169c8cc6..97085530aa63b291c677dfbeb5e198b1859a0daf 100644 (file)
@@ -328,7 +328,7 @@ static struct irq_host_ops msic_host_ops = {
        .map    = msic_host_map,
 };
 
-static int axon_msi_shutdown(struct of_device *device)
+static int axon_msi_shutdown(struct platform_device *device)
 {
        struct axon_msic *msic = dev_get_drvdata(&device->dev);
        u32 tmp;
@@ -342,7 +342,7 @@ static int axon_msi_shutdown(struct of_device *device)
        return 0;
 }
 
-static int axon_msi_probe(struct of_device *device,
+static int axon_msi_probe(struct platform_device *device,
                          const struct of_device_id *device_id)
 {
        struct device_node *dn = device->dev.of_node;
index 39d361c5c6d2e73d4ca9f37d1c415b871ca30610..beec405eb6f8d47142959427e6ef97f9f08bc88c 100644 (file)
@@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void)
        celleb_init_direct_mapping();
        set_pci_dma_ops(&dma_direct_ops);
        ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
-       bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier);
+       bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier);
 
        return 0;
 }
index 3712900471ba2e9033419ab31d620ab8d2a983b2..58b13ce3847ec3c92453ef70d5ec4e653d6d886a 100644 (file)
@@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void)
        /* Register callbacks on OF platform device addition/removal
         * to handle linking them to the right DMA operations
         */
-       bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier);
+       bus_register_notifier(&platform_bus_type, &cell_of_bus_notifier);
 
        return 0;
 }
index c5ce02e84c8e421ae032fad6ad4ca569f03c8f6a..1b5749042756cc9e238431b5cb05bc69b5a5dde2 100644 (file)
@@ -61,12 +61,24 @@ static void qpace_progress(char *s, unsigned short hex)
        printk("*** %04x : %s\n", hex, s ? s : "");
 }
 
+static const struct of_device_id qpace_bus_ids[] __initdata = {
+       { .type = "soc", },
+       { .compatible = "soc", },
+       { .type = "spider", },
+       { .type = "axon", },
+       { .type = "plb5", },
+       { .type = "plb4", },
+       { .type = "opb", },
+       { .type = "ebc", },
+       {},
+};
+
 static int __init qpace_publish_devices(void)
 {
        int node;
 
        /* Publish OF platform devices for southbridge IOs */
-       of_platform_bus_probe(NULL, NULL, NULL);
+       of_platform_bus_probe(NULL, qpace_bus_ids, NULL);
 
        /* There is no device for the MIC memory controller, thus we create
         * a platform device for it to attach the EDAC driver to.
index 50385db586bd951c706f0820d352114abb8adea5..691995761b3d46cae9142eb5f27f66c1b60bd6a2 100644 (file)
@@ -141,6 +141,18 @@ static int __devinit cell_setup_phb(struct pci_controller *phb)
        return 0;
 }
 
+static const struct of_device_id cell_bus_ids[] __initdata = {
+       { .type = "soc", },
+       { .compatible = "soc", },
+       { .type = "spider", },
+       { .type = "axon", },
+       { .type = "plb5", },
+       { .type = "plb4", },
+       { .type = "opb", },
+       { .type = "ebc", },
+       {},
+};
+
 static int __init cell_publish_devices(void)
 {
        struct device_node *root = of_find_node_by_path("/");
@@ -148,7 +160,7 @@ static int __init cell_publish_devices(void)
        int node;
 
        /* Publish OF platform devices for southbridge IOs */
-       of_platform_bus_probe(NULL, NULL, NULL);
+       of_platform_bus_probe(NULL, cell_bus_ids, NULL);
 
        /* On spider based blades, we need to manually create the OF
         * platform devices for the PCI host bridges
index d2c1d497846e75f46f612d9c85043a56cadcbaa9..33e5fc7334fc508be63b52ce6cae473f24726a6c 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/proc_fs.h>
 #include <linux/dma-mapping.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
index 627ee089e75d4bde3b04b3d9ab1ee48d54c931d0..a5d907b5a4c2f0911bd5e3fe7d76dfaf139d9062 100644 (file)
@@ -216,7 +216,7 @@ static int gpio_mdio_reset(struct mii_bus *bus)
 }
 
 
-static int __devinit gpio_mdio_probe(struct of_device *ofdev,
+static int __devinit gpio_mdio_probe(struct platform_device *ofdev,
                                     const struct of_device_id *match)
 {
        struct device *dev = &ofdev->dev;
@@ -275,7 +275,7 @@ out:
 }
 
 
-static int gpio_mdio_remove(struct of_device *dev)
+static int gpio_mdio_remove(struct platform_device *dev)
 {
        struct mii_bus *bus = dev_get_drvdata(&dev->dev);
 
index 79bd3e89dbafd3ce88a31e8516bac96bf23dc87c..39df6ab1735a6161ff4d2581368d5127f6a8297a 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/spinlock.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
index 06a137c5b8bb43c7f90af3d21cc86d6320f3ff88..480567e5fa9ad38c6b9441e2a91228fa6a4a039d 100644 (file)
@@ -542,11 +542,12 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
        /* Make sure IRQ is disabled */
        kw_write_reg(reg_ier, 0);
 
-       /* Request chip interrupt. We set IRQF_TIMER because we don't
+       /* Request chip interrupt. We set IRQF_NO_SUSPEND because we don't
         * want that interrupt disabled between the 2 passes of driver
         * suspend or we'll have issues running the pfuncs
         */
-       if (request_irq(host->irq, kw_i2c_irq, IRQF_TIMER, "keywest i2c", host))
+       if (request_irq(host->irq, kw_i2c_irq, IRQF_NO_SUSPEND,
+                       "keywest i2c", host))
                host->irq = NO_IRQ;
 
        printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n",
index 630a533d0e5938a9ad28beb064587a3223a060c0..890d5f72b1988d4511a0aa7fc78db8614521ba17 100644 (file)
@@ -46,6 +46,10 @@ struct pmac_irq_hw {
         unsigned int    level;
 };
 
+/* Workaround flags for 32bit powermac machines */
+unsigned int of_irq_workarounds;
+struct device_node *of_irq_dflt_pic;
+
 /* Default addresses */
 static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
 
@@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void)
        setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
 #endif
 }
+
+int of_irq_map_oldworld(struct device_node *device, int index,
+                       struct of_irq *out_irq)
+{
+       const u32 *ints = NULL;
+       int intlen;
+
+       /*
+        * Old machines just have a list of interrupt numbers
+        * and no interrupt-controller nodes. We also have dodgy
+        * cases where the APPL,interrupts property is completely
+        * missing behind pci-pci bridges and we have to get it
+        * from the parent (the bridge itself, as apple just wired
+        * everything together on these)
+        */
+       while (device) {
+               ints = of_get_property(device, "AAPL,interrupts", &intlen);
+               if (ints != NULL)
+                       break;
+               device = device->parent;
+               if (device && strcmp(device->type, "pci") != 0)
+                       break;
+       }
+       if (ints == NULL)
+               return -EINVAL;
+       intlen /= sizeof(u32);
+
+       if (index >= intlen)
+               return -EINVAL;
+
+       out_irq->controller = NULL;
+       out_irq->specifier[0] = ints[index];
+       out_irq->size = 1;
+
+       return 0;
+}
 #endif /* CONFIG_PPC32 */
 
 static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
@@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void)
 
 void __init pmac_pic_init(void)
 {
-       unsigned int flags = 0;
-
        /* We configure the OF parsing based on our oldworld vs. newworld
         * platform type and wether we were booted by BootX.
         */
 #ifdef CONFIG_PPC32
        if (!pmac_newworld)
-               flags |= OF_IMAP_OLDWORLD_MAC;
+               of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC;
        if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)
-               flags |= OF_IMAP_NO_PHANDLE;
-#endif /* CONFIG_PPC_32 */
+               of_irq_workarounds |= OF_IMAP_NO_PHANDLE;
 
-       of_irq_map_init(flags);
+       /* If we don't have phandles on a newworld, then try to locate a
+        * default interrupt controller (happens when booting with BootX).
+        * We do a first match here, hopefully, that only ever happens on
+        * machines with one controller.
+        */
+       if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) {
+               struct device_node *np;
+
+               for_each_node_with_property(np, "interrupt-controller") {
+                       /* Skip /chosen/interrupt-controller */
+                       if (strcmp(np->name, "chosen") == 0)
+                               continue;
+                       /* It seems like at least one person wants
+                        * to use BootX on a machine with an AppleKiwi
+                        * controller which happens to pretend to be an
+                        * interrupt controller too. */
+                       if (strcmp(np->name, "AppleKiwi") == 0)
+                               continue;
+                       /* I think we found one ! */
+                       of_irq_dflt_pic = np;
+                       break;
+               }
+       }
+#endif /* CONFIG_PPC32 */
 
        /* We first try to detect Apple's new Core99 chipset, since mac-io
         * is quite different on those machines and contains an IBM MPIC2.
index 402d2212162f6bddc0a79506112448d6f6714461..2659a60bd7b864503ae2ab39b83fd991f5d90357 100644 (file)
@@ -60,7 +60,7 @@
 static int azfs_major, azfs_minor;
 
 struct axon_ram_bank {
-       struct of_device        *device;
+       struct platform_device  *device;
        struct gendisk          *disk;
        unsigned int            irq_id;
        unsigned long           ph_addr;
@@ -72,7 +72,7 @@ struct axon_ram_bank {
 static ssize_t
 axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct of_device *device = to_of_device(dev);
+       struct platform_device *device = to_platform_device(dev);
        struct axon_ram_bank *bank = device->dev.platform_data;
 
        BUG_ON(!bank);
@@ -90,7 +90,7 @@ static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL);
 static irqreturn_t
 axon_ram_irq_handler(int irq, void *dev)
 {
-       struct of_device *device = dev;
+       struct platform_device *device = dev;
        struct axon_ram_bank *bank = device->dev.platform_data;
 
        BUG_ON(!bank);
@@ -174,8 +174,8 @@ static const struct block_device_operations axon_ram_devops = {
  * axon_ram_probe - probe() method for platform driver
  * @device, @device_id: see of_platform_driver method
  */
-static int
-axon_ram_probe(struct of_device *device, const struct of_device_id *device_id)
+static int axon_ram_probe(struct platform_device *device,
+                         const struct of_device_id *device_id)
 {
        static int axon_ram_bank_id = -1;
        struct axon_ram_bank *bank;
@@ -304,7 +304,7 @@ failed:
  * @device: see of_platform_driver method
  */
 static int
-axon_ram_remove(struct of_device *device)
+axon_ram_remove(struct platform_device *device)
 {
        struct axon_ram_bank *bank = device->dev.platform_data;
 
index a7c5c470af147f73edb4a7448879b20fabf522cc..65025611506495447386e214112f3bf03e166599 100644 (file)
@@ -365,8 +365,8 @@ bcom_engine_cleanup(void)
 /* OF platform driver                                                       */
 /* ======================================================================== */
 
-static int __devinit
-mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit mpc52xx_bcom_probe(struct platform_device *op,
+                                       const struct of_device_id *match)
 {
        struct device_node *ofn_sram;
        struct resource res_bcom;
@@ -461,8 +461,7 @@ error_ofput:
 }
 
 
-static int
-mpc52xx_bcom_remove(struct of_device *op)
+static int mpc52xx_bcom_remove(struct platform_device *op)
 {
        /* Clean up the engine */
        bcom_engine_cleanup();
index 5d74ef7a651f6e6f4fb38837fe914bcbe4c0297c..1225012a681a01de66f5b80bdaf117451f2052d2 100644 (file)
@@ -11,6 +11,7 @@
  * kind, whether express or implied.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index 8d103ca6d6ab8821273519c04a65599785c31351..00852124ff4a4844a846ea847bd14e4f978f3533 100644 (file)
@@ -621,7 +621,6 @@ int cpm1_gpiochip_add16(struct device_node *np)
 {
        struct cpm1_gpio16_chip *cpm1_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
@@ -631,11 +630,9 @@ int cpm1_gpiochip_add16(struct device_node *np)
        spin_lock_init(&cpm1_gc->lock);
 
        mm_gc = &cpm1_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = cpm1_gpio16_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 16;
        gc->direction_input = cpm1_gpio16_dir_in;
        gc->direction_output = cpm1_gpio16_dir_out;
@@ -745,7 +742,6 @@ int cpm1_gpiochip_add32(struct device_node *np)
 {
        struct cpm1_gpio32_chip *cpm1_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
@@ -755,11 +751,9 @@ int cpm1_gpiochip_add32(struct device_node *np)
        spin_lock_init(&cpm1_gc->lock);
 
        mm_gc = &cpm1_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = cpm1_gpio32_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 32;
        gc->direction_input = cpm1_gpio32_dir_in;
        gc->direction_output = cpm1_gpio32_dir_out;
index 88b9812c854fdc2de978871012eeb3c507717569..2b69aa0315b3c5ec1ea9d87081209639d237aa6a 100644 (file)
@@ -325,7 +325,6 @@ int cpm2_gpiochip_add32(struct device_node *np)
 {
        struct cpm2_gpio32_chip *cpm2_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL);
@@ -335,11 +334,9 @@ int cpm2_gpiochip_add32(struct device_node *np)
        spin_lock_init(&cpm2_gc->lock);
 
        mm_gc = &cpm2_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = cpm2_gpio32_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 32;
        gc->direction_input = cpm2_gpio32_dir_in;
        gc->direction_output = cpm2_gpio32_dir_out;
index eca4545dd52ee0619b0bb0ad2b86597a5737d736..7dd2885321ad112cf88592e299d77ac4b2359d9b 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/list.h>
 #include <linux/io.h>
index 962c2d8dd8d927e0d2e03336dff954e42935ef86..87991d3abbab1c2e90268386be666764112cab38 100644 (file)
@@ -250,7 +250,7 @@ unlock:
        raw_spin_unlock(&desc->lock);
 }
 
-static int fsl_of_msi_remove(struct of_device *ofdev)
+static int fsl_of_msi_remove(struct platform_device *ofdev)
 {
        struct fsl_msi *msi = ofdev->dev.platform_data;
        int virq, i;
@@ -274,7 +274,7 @@ static int fsl_of_msi_remove(struct of_device *ofdev)
        return 0;
 }
 
-static int __devinit fsl_of_msi_probe(struct of_device *dev,
+static int __devinit fsl_of_msi_probe(struct platform_device *dev,
                                const struct of_device_id *match)
 {
        struct fsl_msi *msi;
index 9082eb921ad995f7caac8752d00f9dc91cf48381..44de8559c9759ff65cfd1bca3e4f14088ebff038 100644 (file)
@@ -58,7 +58,8 @@ static struct platform_suspend_ops pmc_suspend_ops = {
        .enter = pmc_suspend_enter,
 };
 
-static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id)
+static int pmc_probe(struct platform_device *ofdev,
+                    const struct of_device_id *id)
 {
        pmc_regs = of_iomap(ofdev->dev.of_node, 0);
        if (!pmc_regs)
index 30e1626b2e850c9f2d5f9d2137f3025cf05f4ea8..8bd86530ee252cfafa19d3c5866853385398104a 100644 (file)
@@ -1338,7 +1338,7 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr)
  * master port with system-specific info, and registers the
  * master port with the RapidIO subsystem.
  */
-int fsl_rio_setup(struct of_device *dev)
+int fsl_rio_setup(struct platform_device *dev)
 {
        struct rio_ops *ops;
        struct rio_mport *port;
@@ -1536,7 +1536,7 @@ err_ops:
 
 /* The probe function for RapidIO peer-to-peer network.
  */
-static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev,
+static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev,
                                     const struct of_device_id *match)
 {
        int rc;
index 83f519655fac0cd00286f3f121f9cd646f19fff2..2b69084d0f0cb7f9cc0acdb4a0d4d1c024bb1a69 100644 (file)
@@ -257,7 +257,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
 {
        struct mpc8xxx_gpio_chip *mpc8xxx_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
        unsigned hwirq;
        int ret;
@@ -271,11 +270,9 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        spin_lock_init(&mpc8xxx_gc->lock);
 
        mm_gc = &mpc8xxx_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = mpc8xxx_gpio_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = MPC8XXX_GPIO_PINS;
        gc->direction_input = mpc8xxx_gpio_dir_in;
        gc->direction_output = mpc8xxx_gpio_dir_out;
index 31acd3b1718b8f09be498fd2a15d82aa72464ca5..1398bc454999b2b10fae54972e5e92c69689b3eb 100644 (file)
 
 #include <asm/prom.h>
 
-/*
- * These functions provide the necessary setup for the mv64x60 drivers.
- * These drivers are unusual in that they work on both the MIPS and PowerPC
- * architectures.  Because of that, the drivers do not support the normal
- * PowerPC of_platform_bus_type.  They support platform_bus_type instead.
- */
+/* These functions provide the necessary setup for the mv64x60 drivers. */
 
 static struct of_device_id __initdata of_mv64x60_devices[] = {
        { .compatible = "marvell,mv64306-devctrl", },
index 198f288570cc3b966876a8fe737c3fdf274acdd4..77bb3f4d530a305f1301eb6fc571ecddfb37c5f8 100644 (file)
@@ -73,7 +73,6 @@ static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
        .attr = {
                .name = "hs_reg",
                .mode = S_IRUGO | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size  = MV64X60_VAL_LEN_MAX,
        .read  = mv64x60_hs_reg_read,
index d07137a07d7509b0e6cf082f5de6e421922f2091..24a0bb955b184bba92c6d0d9efda52ac568bee74 100644 (file)
@@ -43,7 +43,7 @@ struct pmi_data {
        struct mutex            msg_mutex;
        pmi_message_t           msg;
        struct completion       *completion;
-       struct of_device        *dev;
+       struct platform_device  *dev;
        int                     irq;
        u8 __iomem              *pmi_reg;
        struct work_struct      work;
@@ -121,7 +121,7 @@ static void pmi_notify_handlers(struct work_struct *work)
        spin_unlock(&data->handler_spinlock);
 }
 
-static int pmi_of_probe(struct of_device *dev,
+static int pmi_of_probe(struct platform_device *dev,
                        const struct of_device_id *match)
 {
        struct device_node *np = dev->dev.of_node;
@@ -185,7 +185,7 @@ out:
        return rc;
 }
 
-static int pmi_of_remove(struct of_device *dev)
+static int pmi_of_remove(struct platform_device *dev)
 {
        struct pmi_handler *handler, *tmp;
 
index 3812fc366becfcf92af075f9339338d5e3533008..fc65ad1b32931eb8bb60188ccf86b04af30c6ef8 100644 (file)
@@ -181,7 +181,6 @@ static int __init ppc4xx_add_gpiochips(void)
                int ret;
                struct ppc4xx_gpio_chip *ppc4xx_gc;
                struct of_mm_gpio_chip *mm_gc;
-               struct of_gpio_chip *of_gc;
                struct gpio_chip *gc;
 
                ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL);
@@ -193,10 +192,8 @@ static int __init ppc4xx_add_gpiochips(void)
                spin_lock_init(&ppc4xx_gc->lock);
 
                mm_gc = &ppc4xx_gc->mm_gc;
-               of_gc = &mm_gc->of_gc;
-               gc = &of_gc->gc;
+               gc = &mm_gc->gc;
 
-               of_gc->gpio_cells = 2;
                gc->ngpio = 32;
                gc->direction_input = ppc4xx_gpio_dir_in;
                gc->direction_output = ppc4xx_gpio_dir_out;
index dc8f8d61807480dc17faea46939dc30caec8ec39..36bf845df12779622d20c76733115488b1b60887 100644 (file)
@@ -138,8 +138,8 @@ struct qe_pin {
 struct qe_pin *qe_pin_request(struct device_node *np, int index)
 {
        struct qe_pin *qe_pin;
-       struct device_node *gc;
-       struct of_gpio_chip *of_gc = NULL;
+       struct device_node *gpio_np;
+       struct gpio_chip *gc;
        struct of_mm_gpio_chip *mm_gc;
        struct qe_gpio_chip *qe_gc;
        int err;
@@ -155,40 +155,40 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
        }
 
        err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
-                                         &gc, &gpio_spec);
+                                         &gpio_np, &gpio_spec);
        if (err) {
                pr_debug("%s: can't parse gpios property\n", __func__);
                goto err0;
        }
 
-       if (!of_device_is_compatible(gc, "fsl,mpc8323-qe-pario-bank")) {
+       if (!of_device_is_compatible(gpio_np, "fsl,mpc8323-qe-pario-bank")) {
                pr_debug("%s: tried to get a non-qe pin\n", __func__);
                err = -EINVAL;
                goto err1;
        }
 
-       of_gc = gc->data;
-       if (!of_gc) {
+       gc = of_node_to_gpiochip(gpio_np);
+       if (!gc) {
                pr_debug("%s: gpio controller %s isn't registered\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                err = -ENODEV;
                goto err1;
        }
 
-       gpio_cells = of_get_property(gc, "#gpio-cells", &size);
+       gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size);
        if (!gpio_cells || size != sizeof(*gpio_cells) ||
-                       *gpio_cells != of_gc->gpio_cells) {
+                       *gpio_cells != gc->of_gpio_n_cells) {
                pr_debug("%s: wrong #gpio-cells for %s\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                err = -EINVAL;
                goto err1;
        }
 
-       err = of_gc->xlate(of_gc, np, gpio_spec, NULL);
+       err = gc->of_xlate(gc, np, gpio_spec, NULL);
        if (err < 0)
                goto err1;
 
-       mm_gc = to_of_mm_gpio_chip(&of_gc->gc);
+       mm_gc = to_of_mm_gpio_chip(gc);
        qe_gc = to_qe_gpio_chip(mm_gc);
 
        spin_lock_irqsave(&qe_gc->lock, flags);
@@ -206,7 +206,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
        if (!err)
                return qe_pin;
 err1:
-       of_node_put(gc);
+       of_node_put(gpio_np);
 err0:
        kfree(qe_pin);
        pr_debug("%s failed with status %d\n", __func__, err);
@@ -307,7 +307,6 @@ static int __init qe_add_gpiochips(void)
                int ret;
                struct qe_gpio_chip *qe_gc;
                struct of_mm_gpio_chip *mm_gc;
-               struct of_gpio_chip *of_gc;
                struct gpio_chip *gc;
 
                qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
@@ -319,11 +318,9 @@ static int __init qe_add_gpiochips(void)
                spin_lock_init(&qe_gc->lock);
 
                mm_gc = &qe_gc->mm_gc;
-               of_gc = &mm_gc->of_gc;
-               gc = &of_gc->gc;
+               gc = &mm_gc->gc;
 
                mm_gc->save_regs = qe_gpio_save_regs;
-               of_gc->gpio_cells = 2;
                gc->ngpio = QE_PIO_PINS;
                gc->direction_input = qe_gpio_dir_in;
                gc->direction_output = qe_gpio_dir_out;
index 093e0ae1a9418fc0830be5c6bee35041c774d198..3da8014931c9c7a99afcebf52814b50d03d02f35 100644 (file)
@@ -651,14 +651,15 @@ unsigned int qe_get_num_of_snums(void)
 EXPORT_SYMBOL(qe_get_num_of_snums);
 
 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
-static int qe_resume(struct of_device *ofdev)
+static int qe_resume(struct platform_device *ofdev)
 {
        if (!qe_alive_during_sleep())
                qe_reset();
        return 0;
 }
 
-static int qe_probe(struct of_device *ofdev, const struct of_device_id *id)
+static int qe_probe(struct platform_device *ofdev,
+                   const struct of_device_id *id)
 {
        return 0;
 }
index d5fb173e588cbe602fdd202291f01fc72fd47d76..b6defda5ccc90834c732b946cd29334ae3c75249 100644 (file)
@@ -91,7 +91,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np)
        int ret;
        struct u8_gpio_chip *u8_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL);
@@ -101,11 +100,9 @@ static int __init u8_simple_gpiochip_add(struct device_node *np)
        spin_lock_init(&u8_gc->lock);
 
        mm_gc = &u8_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = u8_gpio_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 8;
        gc->direction_input = u8_gpio_dir_in;
        gc->direction_output = u8_gpio_dir_out;
index bee1c0f794cf0262b00032493c0b79426d1730e9..f0777a47e3a531c17156a76694648aaf89cacd44 100644 (file)
@@ -40,9 +40,6 @@ config ARCH_HAS_ILOG2_U64
 config GENERIC_HWEIGHT
        def_bool y
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_TIME_VSYSCALL
        def_bool y
 
index 30c5f01f93b0017741bb9c18f5035925d7d3869d..0c9e6c6d2a645f7df5f2f4f7f9f07824a327c0d1 100644 (file)
@@ -24,7 +24,8 @@ CHECKFLAGS    += -D__s390__ -msize-long
 else
 LD_BFD         := elf64-s390
 LDFLAGS                := -m elf64_s390
-MODFLAGS       += -fpic -D__PIC__
+KBUILD_AFLAGS_MODULE += -fpic -D__PIC__
+KBUILD_CFLAGS_MODULE += -fpic -D__PIC__
 KBUILD_CFLAGS  += -m64
 KBUILD_AFLAGS  += -m64
 UTS_MACHINE    := s390x
diff --git a/arch/s390/include/asm/local64.h b/arch/s390/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 15a7536452d508b7998d37d9b679f4545d670dc1..2896cac9c14a9cd5501067e36f254c308b27cee8 100644 (file)
@@ -207,8 +207,8 @@ struct clocksource * __init clocksource_default_clock(void)
        return &clocksource_tod;
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
-                    u32 mult)
+void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
+                       struct clocksource *clock, u32 mult)
 {
        if (clock != &clocksource_tod)
                return;
@@ -219,8 +219,8 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
        vdso_data->xtime_tod_stamp = clock->cycle_last;
        vdso_data->xtime_clock_sec = wall_time->tv_sec;
        vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
-       vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
-       vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+       vdso_data->wtom_clock_sec = wtm->tv_sec;
+       vdso_data->wtom_clock_nsec = wtm->tv_nsec;
        vdso_data->ntp_mult = mult;
        smp_wmb();
        ++vdso_data->tb_update_count;
index 55d413e6dcf2731976cf36de4fd878fc6e57effe..be4a155847519e04ce20ee8f5cfce309493b3b83 100644 (file)
@@ -55,9 +55,6 @@ config GENERIC_CALIBRATE_DELAY
 config GENERIC_CLOCKEVENTS
        def_bool y
 
-config GENERIC_TIME
-       def_bool y
-
 config SCHED_NO_NO_OMIT_FRAME_POINTER
        def_bool y
 
index 68e0cd06d5c9632daea2e525460a1459b9e1beb7..d77dc639d8e322ec8bfd0263f4849e4581670b9f 100644 (file)
@@ -20,7 +20,8 @@ cflags-y += -G0 -pipe -mel -mnhwloop -D__SCOREEL__ \
 #
 KBUILD_AFLAGS += $(cflags-y)
 KBUILD_CFLAGS += $(cflags-y)
-MODFLAGS += -mlong-calls
+KBUILD_AFLAGS_MODULE += -mlong-calls
+KBUILD_CFLAGS_MODULE += -mlong-calls
 LDFLAGS += --oformat elf32-littlescore
 LDFLAGS_vmlinux        += -G0 -static -nostdlib
 
diff --git a/arch/score/include/asm/local64.h b/arch/score/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 82868fee21fdbed9f670edde147032253f82f459..33990fa95af013a64e081c4bfc411f58228f64cb 100644 (file)
@@ -98,9 +98,6 @@ config GENERIC_CALIBRATE_DELAY
 config GENERIC_IOMAP
        bool
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_CLOCKEVENTS
        def_bool y
 
diff --git a/arch/sh/include/asm/local64.h b/arch/sh/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 81b6de41ae5d1c3bfb87c340acee5291a499a036..7a3dc356725839f2cf8579491efd8d02ba11b483 100644 (file)
@@ -185,10 +185,10 @@ static void sh_perf_event_update(struct perf_event *event,
         * this is the simplest approach for maintaining consistency.
         */
 again:
-       prev_raw_count = atomic64_read(&hwc->prev_count);
+       prev_raw_count = local64_read(&hwc->prev_count);
        new_raw_count = sh_pmu->read(idx);
 
-       if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+       if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
                             new_raw_count) != prev_raw_count)
                goto again;
 
@@ -203,7 +203,7 @@ again:
        delta = (new_raw_count << shift) - (prev_raw_count << shift);
        delta >>= shift;
 
-       atomic64_add(delta, &event->count);
+       local64_add(delta, &event->count);
 }
 
 static void sh_pmu_disable(struct perf_event *event)
index c0015db247ba46ed787b4b16b47f402a3de1152a..491e9d6de1912d56cea2b21f51bf8cfd7980e278 100644 (file)
@@ -18,6 +18,7 @@ config 64BIT
 config SPARC
        bool
        default y
+       select OF
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_ARCH_KGDB if !SMP || SPARC64
@@ -66,9 +67,6 @@ config BITS
        default 32 if SPARC32
        default 64 if SPARC64
 
-config GENERIC_TIME
-       def_bool y
-
 config ARCH_USES_GETTIMEOFFSET
        bool
        default y if SPARC32
@@ -148,9 +146,6 @@ config GENERIC_GPIO
 config ARCH_NO_VIRT_TO_BUS
        def_bool y
 
-config OF
-       def_bool y
-
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
        def_bool y if SPARC64
 
index d4c45214741252d7327daf0ba0f50c10dcef6f5f..daa6a8a5e9cd0d5dfa102ca89639d3eda8d53f5c 100644 (file)
@@ -6,18 +6,25 @@
 #ifndef _ASM_SPARC_DEVICE_H
 #define _ASM_SPARC_DEVICE_H
 
+#include <asm/openprom.h>
+
 struct device_node;
-struct of_device;
+struct platform_device;
 
 struct dev_archdata {
        void                    *iommu;
        void                    *stc;
        void                    *host_controller;
-       struct of_device        *op;
+       struct platform_device  *op;
        int                     numa_node;
 };
 
+extern void of_propagate_archdata(struct platform_device *bus);
+
 struct pdev_archdata {
+       struct resource         resource[PROMREG_MAX];
+       unsigned int            irqs[PROMINTR_MAX];
+       int                     num_irqs;
 };
 
 #endif /* _ASM_SPARC_DEVICE_H */
index 8fac3ab22f36f6ebde89a140ce08e4fd5d107099..6597ce874d78761147e7ae206bca34c444c3ad87 100644 (file)
@@ -43,7 +43,7 @@ struct sun_flpy_controller {
 /* You'll only ever find one controller on an Ultra anyways. */
 static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
 unsigned long fdc_status;
-static struct of_device *floppy_op = NULL;
+static struct platform_device *floppy_op = NULL;
 
 struct sun_floppy_ops {
        unsigned char   (*fd_inb) (unsigned long port);
@@ -548,7 +548,7 @@ static unsigned long __init sun_floppy_init(void)
 {
        static int initialized = 0;
        struct device_node *dp;
-       struct of_device *op;
+       struct platform_device *op;
        const char *prop;
        char state[128];
 
@@ -567,7 +567,7 @@ static unsigned long __init sun_floppy_init(void)
        }
        if (op) {
                floppy_op = op;
-               FLOPPY_IRQ = op->irqs[0];
+               FLOPPY_IRQ = op->archdata.irqs[0];
        } else {
                struct device_node *ebus_dp;
                void __iomem *auxio_reg;
@@ -593,7 +593,7 @@ static unsigned long __init sun_floppy_init(void)
                if (state_prop && !strncmp(state_prop, "disabled", 8))
                        return 0;
 
-               FLOPPY_IRQ = op->irqs[0];
+               FLOPPY_IRQ = op->archdata.irqs[0];
 
                /* Make sure the high density bit is set, some systems
                 * (most notably Ultra5/Ultra10) come up with it clear.
@@ -661,7 +661,7 @@ static unsigned long __init sun_floppy_init(void)
                config = 0;
                for (dp = ebus_dp->child; dp; dp = dp->sibling) {
                        if (!strcmp(dp->name, "ecpp")) {
-                               struct of_device *ecpp_op;
+                               struct platform_device *ecpp_op;
 
                                ecpp_op = of_find_device_by_node(dp);
                                if (ecpp_op)
diff --git a/arch/sparc/include/asm/local64.h b/arch/sparc/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h
deleted file mode 100644 (file)
index f320246..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _ASM_SPARC_OF_DEVICE_H
-#define _ASM_SPARC_OF_DEVICE_H
-#ifdef __KERNEL__
-
-#include <linux/device.h>
-#include <linux/of.h>
-#include <linux/mod_devicetable.h>
-#include <asm/openprom.h>
-
-/*
- * The of_device is a kind of "base class" that is a superset of
- * struct device for use by devices attached to an OF node and
- * probed using OF properties.
- */
-struct of_device
-{
-       struct device                   dev;
-       struct resource                 resource[PROMREG_MAX];
-       unsigned int                    irqs[PROMINTR_MAX];
-       int                             num_irqs;
-
-       void                            *sysdata;
-
-       int                             slot;
-       int                             portid;
-       int                             clock_freq;
-};
-
-extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
-extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
-
-extern void of_propagate_archdata(struct of_device *bus);
-
-/* This is just here during the transition */
-#include <linux/of_platform.h>
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_SPARC_OF_DEVICE_H */
diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h
deleted file mode 100644 (file)
index 90da990..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef ___ASM_SPARC_OF_PLATFORM_H
-#define ___ASM_SPARC_OF_PLATFORM_H
-/*
- *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
- *                      <benh@kernel.crashing.org>
- *    Modified for Sparc by merging parts of asm/of_device.h
- *             by Stephen Rothwell
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- */
-
-#define of_bus_type    of_platform_bus_type    /* for compatibility */
-
-#endif
index c333b8d0949bf199b9a88a8b406ff644ca69c74e..4f7afa01b2aeb0e3c15dfac8de1308bdcd5f5b77 100644 (file)
@@ -103,7 +103,7 @@ static inline unsigned int get_dma_residue(unsigned int dmanr)
        return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
 }
 
-static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit ecpp_probe(struct platform_device *op, const struct of_device_id *match)
 {
        unsigned long base = op->resource[0].start;
        unsigned long config = op->resource[1].start;
@@ -116,7 +116,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
        parent = op->dev.of_node->parent;
        if (!strcmp(parent->name, "dma")) {
                p = parport_pc_probe_port(base, base + 0x400,
-                                         op->irqs[0], PARPORT_DMA_NOFIFO,
+                                         op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
                                          op->dev.parent->parent, 0);
                if (!p)
                        return -ENOMEM;
@@ -166,7 +166,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
                       0, PTR_LPT_REG_DIR);
 
        p = parport_pc_probe_port(base, base + 0x400,
-                                 op->irqs[0],
+                                 op->archdata.irqs[0],
                                  slot,
                                  op->dev.parent,
                                  0);
@@ -192,7 +192,7 @@ out_err:
        return err;
 }
 
-static int __devexit ecpp_remove(struct of_device *op)
+static int __devexit ecpp_remove(struct platform_device *op)
 {
        struct parport *p = dev_get_drvdata(&op->dev);
        int slot = p->dma;
@@ -243,9 +243,7 @@ static struct of_platform_driver ecpp_driver = {
 
 static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
 {
-       of_register_driver(&ecpp_driver, &of_bus_type);
-
-       return 0;
+       return of_register_platform_driver(&ecpp_driver);
 }
 
 #endif /* !(_ASM_SPARC64_PARPORT_H */
index 7e2669894ce8346152ba1910e4122f954dd7a1a2..74c4e0cd889c700a0a901937bd716366fb882c10 100644 (file)
@@ -6,7 +6,15 @@ extern void set_perf_event_pending(void);
 #define        PERF_EVENT_INDEX_OFFSET 0
 
 #ifdef CONFIG_PERF_EVENTS
+#include <asm/ptrace.h>
+
 extern void init_hw_perf_events(void);
+
+extern void
+__perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip);
+
+#define perf_arch_fetch_caller_regs(pt_regs, ip)       \
+       __perf_arch_fetch_caller_regs(pt_regs, ip, 1);
 #else
 static inline void init_hw_perf_events(void)   { }
 #endif
index f845828ca4c6ab5bf2f5c6e1020e8a0f54984b8a..291f12575eddcd598aca91ce46dbe1c9e08b31e1 100644 (file)
@@ -43,20 +43,22 @@ extern int of_getintprop_default(struct device_node *np,
 extern int of_find_in_proplist(const char *list, const char *match, int len);
 #ifdef CONFIG_NUMA
 extern int of_node_to_nid(struct device_node *dp);
-#else
-#define of_node_to_nid(dp)     (-1)
+#define of_node_to_nid of_node_to_nid
 #endif
 
 extern void prom_build_devicetree(void);
 extern void of_populate_present_mask(void);
 extern void of_fill_in_cpu_data(void);
 
+struct resource;
+extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
+extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
+
 /* These routines are here to provide compatibility with how powerpc
  * handles IRQ mapping for OF device nodes.  We precompute and permanently
- * register them in the of_device objects, whereas powerpc computes them
+ * register them in the platform_device objects, whereas powerpc computes them
  * on request.
  */
-extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
 static inline void irq_dispose_mapping(unsigned int virq)
 {
 }
index b27476caa1333d4fbc2a85b380c4eb3c392c4c97..2c0046ecc7155592401d56c340c275e2697348a7 100644 (file)
@@ -68,7 +68,7 @@ static void apc_swift_idle(void)
 #endif
 } 
 
-static inline void apc_free(struct of_device *op)
+static inline void apc_free(struct platform_device *op)
 {
        of_iounmap(&op->resource[0], regs, resource_size(&op->resource[0]));
 }
@@ -136,7 +136,7 @@ static const struct file_operations apc_fops = {
 
 static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
 
-static int __devinit apc_probe(struct of_device *op,
+static int __devinit apc_probe(struct platform_device *op,
                               const struct of_device_id *match)
 {
        int err;
@@ -184,7 +184,7 @@ static struct of_platform_driver apc_driver = {
 
 static int __init apc_init(void)
 {
-       return of_register_driver(&apc_driver, &of_bus_type);
+       return of_register_platform_driver(&apc_driver);
 }
 
 /* This driver is not critical to the boot process
index ddc84128b3c2e4c9be06129f1aecc04f196a3dab..3efd3c5af6a910181c47ba0075d7a95ae036beaf 100644 (file)
@@ -102,7 +102,8 @@ static struct of_device_id __initdata auxio_match[] = {
 
 MODULE_DEVICE_TABLE(of, auxio_match);
 
-static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit auxio_probe(struct platform_device *dev,
+                                const struct of_device_id *match)
 {
        struct device_node *dp = dev->dev.of_node;
        unsigned long size;
@@ -142,7 +143,7 @@ static struct of_platform_driver auxio_driver = {
 
 static int __init auxio_init(void)
 {
-       return of_register_driver(&auxio_driver, &of_platform_bus_type);
+       return of_register_platform_driver(&auxio_driver);
 }
 
 /* Must be after subsys_initcall() so that busses are probed.  Must
index 434335f65823ec944626a9cbe0b9bbccb28bfd86..cfa2624c5332ea43f20c9232555b80a3e95fde59 100644 (file)
@@ -59,7 +59,7 @@ static int __devinit clock_board_calc_nslots(struct clock_board *p)
        }
 }
 
-static int __devinit clock_board_probe(struct of_device *op,
+static int __devinit clock_board_probe(struct platform_device *op,
                                       const struct of_device_id *match)
 {
        struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL);
@@ -157,7 +157,7 @@ static struct of_platform_driver clock_board_driver = {
        },
 };
 
-static int __devinit fhc_probe(struct of_device *op,
+static int __devinit fhc_probe(struct platform_device *op,
                               const struct of_device_id *match)
 {
        struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL);
@@ -265,8 +265,8 @@ static struct of_platform_driver fhc_driver = {
 
 static int __init sunfire_init(void)
 {
-       (void) of_register_driver(&fhc_driver, &of_platform_bus_type);
-       (void) of_register_driver(&clock_board_driver, &of_platform_bus_type);
+       (void) of_register_platform_driver(&fhc_driver);
+       (void) of_register_platform_driver(&clock_board_driver);
        return 0;
 }
 
index 870cb65b3f216e38b81fc6932afe145067f6aec9..08c466ebb32b6c677c386f543211e8663ec46ae7 100644 (file)
@@ -392,7 +392,7 @@ static void __devinit jbusmc_construct_dimm_groups(struct jbusmc *p,
        }
 }
 
-static int __devinit jbusmc_probe(struct of_device *op,
+static int __devinit jbusmc_probe(struct platform_device *op,
                                  const struct of_device_id *match)
 {
        const struct linux_prom64_registers *mem_regs;
@@ -690,7 +690,7 @@ static void chmc_fetch_decode_regs(struct chmc *p)
                                      chmc_read_mcreg(p, CHMCTRL_DECODE4));
 }
 
-static int __devinit chmc_probe(struct of_device *op,
+static int __devinit chmc_probe(struct platform_device *op,
                                const struct of_device_id *match)
 {
        struct device_node *dp = op->dev.of_node;
@@ -765,7 +765,7 @@ out_free:
        goto out;
 }
 
-static int __devinit us3mc_probe(struct of_device *op,
+static int __devinit us3mc_probe(struct platform_device *op,
                                const struct of_device_id *match)
 {
        if (mc_type == MC_TYPE_SAFARI)
@@ -775,21 +775,21 @@ static int __devinit us3mc_probe(struct of_device *op,
        return -ENODEV;
 }
 
-static void __devexit chmc_destroy(struct of_device *op, struct chmc *p)
+static void __devexit chmc_destroy(struct platform_device *op, struct chmc *p)
 {
        list_del(&p->list);
        of_iounmap(&op->resource[0], p->regs, 0x48);
        kfree(p);
 }
 
-static void __devexit jbusmc_destroy(struct of_device *op, struct jbusmc *p)
+static void __devexit jbusmc_destroy(struct platform_device *op, struct jbusmc *p)
 {
        mc_list_del(&p->list);
        of_iounmap(&op->resource[0], p->regs, JBUSMC_REGS_SIZE);
        kfree(p);
 }
 
-static int __devexit us3mc_remove(struct of_device *op)
+static int __devexit us3mc_remove(struct platform_device *op)
 {
        void *p = dev_get_drvdata(&op->dev);
 
@@ -848,7 +848,7 @@ static int __init us3mc_init(void)
        ret = register_dimm_printer(us3mc_dimm_printer);
 
        if (!ret) {
-               ret = of_register_driver(&us3mc_driver, &of_bus_type);
+               ret = of_register_platform_driver(&us3mc_driver);
                if (ret)
                        unregister_dimm_printer(us3mc_dimm_printer);
        }
@@ -859,7 +859,7 @@ static void __exit us3mc_cleanup(void)
 {
        if (us3mc_platform()) {
                unregister_dimm_printer(us3mc_dimm_printer);
-               of_unregister_driver(&us3mc_driver);
+               of_unregister_platform_driver(&us3mc_driver);
        }
 }
 
index 92090cc9e82937a2daf6730dca89668ce9e04869..682fee06a16b044e28275935f45fba73accee3a5 100644 (file)
@@ -47,9 +47,9 @@ stack_trace_flush:
        .size           stack_trace_flush,.-stack_trace_flush
 
 #ifdef CONFIG_PERF_EVENTS
-       .globl          perf_arch_fetch_caller_regs
-       .type           perf_arch_fetch_caller_regs,#function
-perf_arch_fetch_caller_regs:
+       .globl          __perf_arch_fetch_caller_regs
+       .type           __perf_arch_fetch_caller_regs,#function
+__perf_arch_fetch_caller_regs:
        /* We always read the %pstate into %o5 since we will use
         * that to construct a fake %tstate to store into the regs.
         */
index 703e4aa9bc38420fde79f7a7fdbc6b9bb60045b6..41f7e4e0f72a65a900985c485a816a4721206c89 100644 (file)
@@ -253,7 +253,7 @@ EXPORT_SYMBOL(sbus_set_sbus64);
 static void *sbus_alloc_coherent(struct device *dev, size_t len,
                                 dma_addr_t *dma_addrp, gfp_t gfp)
 {
-       struct of_device *op = to_of_device(dev);
+       struct platform_device *op = to_platform_device(dev);
        unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
        unsigned long va;
        struct resource *res;
index 47e63f1e719c7a2d9e4d4e757b1bf0a07e16d308..2d055a1e9cc2b483d2aebbae083b21ddea0bf5ec 100644 (file)
@@ -241,10 +241,10 @@ static int __init use_1to1_mapping(struct device_node *pp)
 
 static int of_resource_verbose;
 
-static void __init build_device_resources(struct of_device *op,
+static void __init build_device_resources(struct platform_device *op,
                                          struct device *parent)
 {
-       struct of_device *p_op;
+       struct platform_device *p_op;
        struct of_bus *bus;
        int na, ns;
        int index, num_reg;
@@ -253,7 +253,7 @@ static void __init build_device_resources(struct of_device *op,
        if (!parent)
                return;
 
-       p_op = to_of_device(parent);
+       p_op = to_platform_device(parent);
        bus = of_match_bus(p_op->dev.of_node);
        bus->count_cells(op->dev.of_node, &na, &ns);
 
@@ -267,6 +267,8 @@ static void __init build_device_resources(struct of_device *op,
        /* Conver to num-entries.  */
        num_reg /= na + ns;
 
+       op->resource = op->archdata.resource;
+       op->num_resources = num_reg;
        for (index = 0; index < num_reg; index++) {
                struct resource *r = &op->resource[index];
                u32 addr[OF_MAX_ADDR_CELLS];
@@ -333,10 +335,10 @@ static void __init build_device_resources(struct of_device *op,
        }
 }
 
-static struct of_device * __init scan_one_device(struct device_node *dp,
+static struct platform_device * __init scan_one_device(struct device_node *dp,
                                                 struct device *parent)
 {
-       struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
+       struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
        const struct linux_prom_irqs *intr;
        struct dev_archdata *sd;
        int len, i;
@@ -349,27 +351,21 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
 
        op->dev.of_node = dp;
 
-       op->clock_freq = of_getintprop_default(dp, "clock-frequency",
-                                              (25*1000*1000));
-       op->portid = of_getintprop_default(dp, "upa-portid", -1);
-       if (op->portid == -1)
-               op->portid = of_getintprop_default(dp, "portid", -1);
-
        intr = of_get_property(dp, "intr", &len);
        if (intr) {
-               op->num_irqs = len / sizeof(struct linux_prom_irqs);
-               for (i = 0; i < op->num_irqs; i++)
-                       op->irqs[i] = intr[i].pri;
+               op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
+               for (i = 0; i < op->archdata.num_irqs; i++)
+                       op->archdata.irqs[i] = intr[i].pri;
        } else {
                const unsigned int *irq =
                        of_get_property(dp, "interrupts", &len);
 
                if (irq) {
-                       op->num_irqs = len / sizeof(unsigned int);
-                       for (i = 0; i < op->num_irqs; i++)
-                               op->irqs[i] = irq[i];
+                       op->archdata.num_irqs = len / sizeof(unsigned int);
+                       for (i = 0; i < op->archdata.num_irqs; i++)
+                               op->archdata.irqs[i] = irq[i];
                } else {
-                       op->num_irqs = 0;
+                       op->archdata.num_irqs = 0;
                }
        }
        if (sparc_cpu_model == sun4d) {
@@ -411,8 +407,8 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
                        goto build_resources;
                }
 
-               for (i = 0; i < op->num_irqs; i++) {
-                       int this_irq = op->irqs[i];
+               for (i = 0; i < op->archdata.num_irqs; i++) {
+                       int this_irq = op->archdata.irqs[i];
                        int sbusl = pil_to_sbus[this_irq];
 
                        if (sbusl)
@@ -420,7 +416,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
                                            (sbusl << 2) +
                                            slot);
 
-                       op->irqs[i] = this_irq;
+                       op->archdata.irqs[i] = this_irq;
                }
        }
 
@@ -428,7 +424,7 @@ build_resources:
        build_device_resources(op, parent);
 
        op->dev.parent = parent;
-       op->dev.bus = &of_platform_bus_type;
+       op->dev.bus = &platform_bus_type;
        if (!parent)
                dev_set_name(&op->dev, "root");
        else
@@ -447,7 +443,7 @@ build_resources:
 static void __init scan_tree(struct device_node *dp, struct device *parent)
 {
        while (dp) {
-               struct of_device *op = scan_one_device(dp, parent);
+               struct platform_device *op = scan_one_device(dp, parent);
 
                if (op)
                        scan_tree(dp->child, &op->dev);
@@ -456,30 +452,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent)
        }
 }
 
-static void __init scan_of_devices(void)
+static int __init scan_of_devices(void)
 {
        struct device_node *root = of_find_node_by_path("/");
-       struct of_device *parent;
+       struct platform_device *parent;
 
        parent = scan_one_device(root, NULL);
        if (!parent)
-               return;
+               return 0;
 
        scan_tree(root->child, &parent->dev);
+       return 0;
 }
-
-static int __init of_bus_driver_init(void)
-{
-       int err;
-
-       err = of_bus_type_init(&of_platform_bus_type, "of");
-       if (!err)
-               scan_of_devices();
-
-       return err;
-}
-
-postcore_initcall(of_bus_driver_init);
+postcore_initcall(scan_of_devices);
 
 static int __init of_debug(char *str)
 {
index 1dae8079f7287a7d52631bb589899c93f3c146d0..63cd4e5d47c2a62eb9264b8e01334027a7ebcaeb 100644 (file)
@@ -310,10 +310,10 @@ static int __init use_1to1_mapping(struct device_node *pp)
 
 static int of_resource_verbose;
 
-static void __init build_device_resources(struct of_device *op,
+static void __init build_device_resources(struct platform_device *op,
                                          struct device *parent)
 {
-       struct of_device *p_op;
+       struct platform_device *p_op;
        struct of_bus *bus;
        int na, ns;
        int index, num_reg;
@@ -322,7 +322,7 @@ static void __init build_device_resources(struct of_device *op,
        if (!parent)
                return;
 
-       p_op = to_of_device(parent);
+       p_op = to_platform_device(parent);
        bus = of_match_bus(p_op->dev.of_node);
        bus->count_cells(op->dev.of_node, &na, &ns);
 
@@ -344,6 +344,8 @@ static void __init build_device_resources(struct of_device *op,
                num_reg = PROMREG_MAX;
        }
 
+       op->resource = op->archdata.resource;
+       op->num_resources = num_reg;
        for (index = 0; index < num_reg; index++) {
                struct resource *r = &op->resource[index];
                u32 addr[OF_MAX_ADDR_CELLS];
@@ -526,7 +528,7 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp,
 
 static int of_irq_verbose;
 
-static unsigned int __init build_one_device_irq(struct of_device *op,
+static unsigned int __init build_one_device_irq(struct platform_device *op,
                                                struct device *parent,
                                                unsigned int irq)
 {
@@ -628,10 +630,10 @@ out:
        return irq;
 }
 
-static struct of_device * __init scan_one_device(struct device_node *dp,
+static struct platform_device * __init scan_one_device(struct device_node *dp,
                                                 struct device *parent)
 {
-       struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
+       struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
        const unsigned int *irq;
        struct dev_archdata *sd;
        int len, i;
@@ -644,34 +646,28 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
 
        op->dev.of_node = dp;
 
-       op->clock_freq = of_getintprop_default(dp, "clock-frequency",
-                                              (25*1000*1000));
-       op->portid = of_getintprop_default(dp, "upa-portid", -1);
-       if (op->portid == -1)
-               op->portid = of_getintprop_default(dp, "portid", -1);
-
        irq = of_get_property(dp, "interrupts", &len);
        if (irq) {
-               op->num_irqs = len / 4;
+               op->archdata.num_irqs = len / 4;
 
                /* Prevent overrunning the op->irqs[] array.  */
-               if (op->num_irqs > PROMINTR_MAX) {
+               if (op->archdata.num_irqs > PROMINTR_MAX) {
                        printk(KERN_WARNING "%s: Too many irqs (%d), "
                               "limiting to %d.\n",
-                              dp->full_name, op->num_irqs, PROMINTR_MAX);
-                       op->num_irqs = PROMINTR_MAX;
+                              dp->full_name, op->archdata.num_irqs, PROMINTR_MAX);
+                       op->archdata.num_irqs = PROMINTR_MAX;
                }
-               memcpy(op->irqs, irq, op->num_irqs * 4);
+               memcpy(op->archdata.irqs, irq, op->archdata.num_irqs * 4);
        } else {
-               op->num_irqs = 0;
+               op->archdata.num_irqs = 0;
        }
 
        build_device_resources(op, parent);
-       for (i = 0; i < op->num_irqs; i++)
-               op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
+       for (i = 0; i < op->archdata.num_irqs; i++)
+               op->archdata.irqs[i] = build_one_device_irq(op, parent, op->archdata.irqs[i]);
 
        op->dev.parent = parent;
-       op->dev.bus = &of_platform_bus_type;
+       op->dev.bus = &platform_bus_type;
        if (!parent)
                dev_set_name(&op->dev, "root");
        else
@@ -690,7 +686,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
 static void __init scan_tree(struct device_node *dp, struct device *parent)
 {
        while (dp) {
-               struct of_device *op = scan_one_device(dp, parent);
+               struct platform_device *op = scan_one_device(dp, parent);
 
                if (op)
                        scan_tree(dp->child, &op->dev);
@@ -699,30 +695,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent)
        }
 }
 
-static void __init scan_of_devices(void)
+static int __init scan_of_devices(void)
 {
        struct device_node *root = of_find_node_by_path("/");
-       struct of_device *parent;
+       struct platform_device *parent;
 
        parent = scan_one_device(root, NULL);
        if (!parent)
-               return;
+               return 0;
 
        scan_tree(root->child, &parent->dev);
+       return 0;
 }
-
-static int __init of_bus_driver_init(void)
-{
-       int err;
-
-       err = of_bus_type_init(&of_platform_bus_type, "of");
-       if (!err)
-               scan_of_devices();
-
-       return err;
-}
-
-postcore_initcall(of_bus_driver_init);
+postcore_initcall(scan_of_devices);
 
 static int __init of_debug(char *str)
 {
index 10c6c36a6e7565a7716cb98c7107f089e232f3fa..49ddff56cb04130ce1a84ccb0ed152ebf6516e9a 100644 (file)
 
 #include "of_device_common.h"
 
-static int node_match(struct device *dev, void *data)
-{
-       struct of_device *op = to_of_device(dev);
-       struct device_node *dp = data;
-
-       return (op->dev.of_node == dp);
-}
-
-struct of_device *of_find_device_by_node(struct device_node *dp)
-{
-       struct device *dev = bus_find_device(&of_platform_bus_type, NULL,
-                                            dp, node_match);
-
-       if (dev)
-               return to_of_device(dev);
-
-       return NULL;
-}
-EXPORT_SYMBOL(of_find_device_by_node);
-
 unsigned int irq_of_parse_and_map(struct device_node *node, int index)
 {
-       struct of_device *op = of_find_device_by_node(node);
+       struct platform_device *op = of_find_device_by_node(node);
 
-       if (!op || index >= op->num_irqs)
+       if (!op || index >= op->archdata.num_irqs)
                return 0;
 
-       return op->irqs[index];
+       return op->archdata.irqs[index];
 }
 EXPORT_SYMBOL(irq_of_parse_and_map);
 
 /* Take the archdata values for IOMMU, STC, and HOSTDATA found in
- * BUS and propagate to all child of_device objects.
+ * BUS and propagate to all child platform_device objects.
  */
-void of_propagate_archdata(struct of_device *bus)
+void of_propagate_archdata(struct platform_device *bus)
 {
        struct dev_archdata *bus_sd = &bus->dev.archdata;
        struct device_node *bus_dp = bus->dev.of_node;
        struct device_node *dp;
 
        for (dp = bus_dp->child; dp; dp = dp->sibling) {
-               struct of_device *op = of_find_device_by_node(dp);
+               struct platform_device *op = of_find_device_by_node(dp);
 
                op->dev.archdata.iommu = bus_sd->iommu;
                op->dev.archdata.stc = bus_sd->stc;
@@ -64,9 +44,6 @@ void of_propagate_archdata(struct of_device *bus)
        }
 }
 
-struct bus_type of_platform_bus_type;
-EXPORT_SYMBOL(of_platform_bus_type);
-
 static void get_cells(struct device_node *dp, int *addrc, int *sizec)
 {
        if (addrc)
index 8a8363adb8bd1ac68c1ad49e6afba66dc7b43ae5..4137579d9adcd171157c5ebd9909c43b2b533547 100644 (file)
@@ -198,7 +198,7 @@ static unsigned long pci_parse_of_flags(u32 addr0)
  * into physical address resources, we only have to figure out the register
  * mapping.
  */
-static void pci_parse_of_addrs(struct of_device *op,
+static void pci_parse_of_addrs(struct platform_device *op,
                               struct device_node *node,
                               struct pci_dev *dev)
 {
@@ -248,7 +248,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
 {
        struct dev_archdata *sd;
        struct pci_slot *slot;
-       struct of_device *op;
+       struct platform_device *op;
        struct pci_dev *dev;
        const char *type;
        u32 class;
@@ -340,7 +340,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
                dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
                dev->rom_base_reg = PCI_ROM_ADDRESS;
 
-               dev->irq = sd->op->irqs[0];
+               dev->irq = sd->op->archdata.irqs[0];
                if (dev->irq == 0xffffffff)
                        dev->irq = PCI_IRQ_NONE;
        }
index 51cfa09e392ab13f67862c11460e856235b6b9dc..efb896d6875404da7d7d75d140198a24c7a9a849 100644 (file)
@@ -410,7 +410,7 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm)
 }
 
 static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm,
-                                      struct of_device *op, u32 portid)
+                                      struct platform_device *op, u32 portid)
 {
        const struct linux_prom64_registers *regs;
        struct device_node *dp = op->dev.of_node;
@@ -455,7 +455,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm,
        return 0;
 }
 
-static int __devinit fire_probe(struct of_device *op,
+static int __devinit fire_probe(struct platform_device *op,
                                const struct of_device_id *match)
 {
        struct device_node *dp = op->dev.of_node;
@@ -518,7 +518,7 @@ static struct of_platform_driver fire_driver = {
 
 static int __init fire_init(void)
 {
-       return of_register_driver(&fire_driver, &of_bus_type);
+       return of_register_platform_driver(&fire_driver);
 }
 
 subsys_initcall(fire_init);
index 03186824327ebc5f66d6a060704dff3e1becda23..e20ed5f06e9c999652af80a730b15455aa6bb773 100644 (file)
@@ -91,7 +91,7 @@ struct pci_pbm_info {
        char                            *name;
 
        /* OBP specific information. */
-       struct of_device                *op;
+       struct platform_device          *op;
        u64                             ino_bitmap;
 
        /* PBM I/O and Memory space resources. */
index 558a70512824252d00e7e8c61396bc10b266c7a2..22eab7cf3b11eacae552083daacd3afff488e7ef 100644 (file)
@@ -285,7 +285,7 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id)
 #define  PSYCHO_ECCCTRL_CE      0x2000000000000000UL /* Enable CE INterrupts */
 static void psycho_register_error_handlers(struct pci_pbm_info *pbm)
 {
-       struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node);
+       struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
        unsigned long base = pbm->controller_regs;
        u64 tmp;
        int err;
@@ -302,23 +302,23 @@ static void psycho_register_error_handlers(struct pci_pbm_info *pbm)
         * 5: POWER MANAGEMENT
         */
 
-       if (op->num_irqs < 6)
+       if (op->archdata.num_irqs < 6)
                return;
 
        /* We really mean to ignore the return result here.  Two
         * PCI controller share the same interrupt numbers and
         * drive the same front-end hardware.
         */
-       err = request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED,
+       err = request_irq(op->archdata.irqs[1], psycho_ue_intr, IRQF_SHARED,
                          "PSYCHO_UE", pbm);
-       err = request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED,
+       err = request_irq(op->archdata.irqs[2], psycho_ce_intr, IRQF_SHARED,
                          "PSYCHO_CE", pbm);
 
        /* This one, however, ought not to fail.  We can just warn
         * about it since the system can still operate properly even
         * if this fails.
         */
-       err = request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED,
+       err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, IRQF_SHARED,
                          "PSYCHO_PCIERR", pbm);
        if (err)
                printk(KERN_WARNING "%s: Could not register PCIERR, "
@@ -483,7 +483,7 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm,
 #define PSYCHO_MEMSPACE_SIZE   0x07fffffffUL
 
 static void __devinit psycho_pbm_init(struct pci_pbm_info *pbm,
-                                     struct of_device *op, int is_pbm_a)
+                                     struct platform_device *op, int is_pbm_a)
 {
        psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO);
        psycho_pbm_strbuf_init(pbm, is_pbm_a);
@@ -503,7 +503,7 @@ static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid)
 
 #define PSYCHO_CONFIGSPACE     0x001000000UL
 
-static int __devinit psycho_probe(struct of_device *op,
+static int __devinit psycho_probe(struct platform_device *op,
                                  const struct of_device_id *match)
 {
        const struct linux_prom64_registers *pr_regs;
@@ -612,7 +612,7 @@ static struct of_platform_driver psycho_driver = {
 
 static int __init psycho_init(void)
 {
-       return of_register_driver(&psycho_driver, &of_bus_type);
+       return of_register_platform_driver(&psycho_driver);
 }
 
 subsys_initcall(psycho_init);
index 6dad8e3b750666c433926d9a9d6963a42cc99de5..5c3f5ec4cabc0ee00d229be774d636eb17b24d77 100644 (file)
@@ -311,7 +311,7 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id)
 static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
 {
        struct device_node *dp = pbm->op->dev.of_node;
-       struct of_device *op;
+       struct platform_device *op;
        unsigned long base = pbm->controller_regs;
        u64 tmp;
        int err;
@@ -329,7 +329,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
         * 2: CE ERR
         * 3: POWER FAIL
         */
-       if (op->num_irqs < 4)
+       if (op->archdata.num_irqs < 4)
                return;
 
        /* We clear the error bits in the appropriate AFSR before
@@ -341,7 +341,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
                    SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE),
                   base + SABRE_UE_AFSR);
 
-       err = request_irq(op->irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm);
+       err = request_irq(op->archdata.irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm);
        if (err)
                printk(KERN_WARNING "%s: Couldn't register UE, err=%d.\n",
                       pbm->name, err);
@@ -351,11 +351,11 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
                   base + SABRE_CE_AFSR);
 
 
-       err = request_irq(op->irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm);
+       err = request_irq(op->archdata.irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm);
        if (err)
                printk(KERN_WARNING "%s: Couldn't register CE, err=%d.\n",
                       pbm->name, err);
-       err = request_irq(op->irqs[0], psycho_pcierr_intr, 0,
+       err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, 0,
                          "SABRE_PCIERR", pbm);
        if (err)
                printk(KERN_WARNING "%s: Couldn't register PCIERR, err=%d.\n",
@@ -443,7 +443,7 @@ static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm,
 }
 
 static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm,
-                                    struct of_device *op)
+                                    struct platform_device *op)
 {
        psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE);
        pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR;
@@ -452,7 +452,7 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm,
        sabre_scan_bus(pbm, &op->dev);
 }
 
-static int __devinit sabre_probe(struct of_device *op,
+static int __devinit sabre_probe(struct platform_device *op,
                                 const struct of_device_id *match)
 {
        const struct linux_prom64_registers *pr_regs;
@@ -606,7 +606,7 @@ static struct of_platform_driver sabre_driver = {
 
 static int __init sabre_init(void)
 {
-       return of_register_driver(&sabre_driver, &of_bus_type);
+       return of_register_platform_driver(&sabre_driver);
 }
 
 subsys_initcall(sabre_init);
index 97a1ae2e1c02ebee8bbcdd221254f80bb46b15b4..445a47a2fb3ddf91305a9004fc699f9e09384b99 100644 (file)
@@ -844,7 +844,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino)
  */
 static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
 {
-       struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node);
+       struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
        u64 tmp, err_mask, err_no_mask;
        int err;
 
@@ -857,14 +857,14 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
         */
 
        if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
-               err = request_irq(op->irqs[1], schizo_ue_intr, 0,
+               err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
                                  "TOMATILLO_UE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register UE, "
                               "err=%d\n", pbm->name, err);
        }
        if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
-               err = request_irq(op->irqs[2], schizo_ce_intr, 0,
+               err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
                                  "TOMATILLO_CE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register CE, "
@@ -872,10 +872,10 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
        }
        err = 0;
        if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "TOMATILLO_PCIERR", pbm);
        } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "TOMATILLO_PCIERR", pbm);
        }
        if (err)
@@ -883,7 +883,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
                       "err=%d\n", pbm->name, err);
 
        if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
-               err = request_irq(op->irqs[3], schizo_safarierr_intr, 0,
+               err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
                                  "TOMATILLO_SERR", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register SERR, "
@@ -939,7 +939,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
 
 static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
 {
-       struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node);
+       struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
        u64 tmp, err_mask, err_no_mask;
        int err;
 
@@ -952,14 +952,14 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
         */
 
        if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
-               err = request_irq(op->irqs[1], schizo_ue_intr, 0,
+               err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
                                  "SCHIZO_UE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register UE, "
                               "err=%d\n", pbm->name, err);
        }
        if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
-               err = request_irq(op->irqs[2], schizo_ce_intr, 0,
+               err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
                                  "SCHIZO_CE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register CE, "
@@ -967,10 +967,10 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
        }
        err = 0;
        if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "SCHIZO_PCIERR", pbm);
        } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "SCHIZO_PCIERR", pbm);
        }
        if (err)
@@ -978,7 +978,7 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
                       "err=%d\n", pbm->name, err);
 
        if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
-               err = request_irq(op->irqs[3], schizo_safarierr_intr, 0,
+               err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
                                  "SCHIZO_SERR", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register SERR, "
@@ -1307,7 +1307,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
 }
 
 static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm,
-                                    struct of_device *op, u32 portid,
+                                    struct platform_device *op, u32 portid,
                                     int chip_type)
 {
        const struct linux_prom64_registers *regs;
@@ -1413,7 +1413,7 @@ static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid,
        return NULL;
 }
 
-static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type)
+static int __devinit __schizo_init(struct platform_device *op, unsigned long chip_type)
 {
        struct device_node *dp = op->dev.of_node;
        struct pci_pbm_info *pbm;
@@ -1460,7 +1460,7 @@ out_err:
        return err;
 }
 
-static int __devinit schizo_probe(struct of_device *op,
+static int __devinit schizo_probe(struct platform_device *op,
                                  const struct of_device_id *match)
 {
        return __schizo_init(op, (unsigned long) match->data);
@@ -1501,7 +1501,7 @@ static struct of_platform_driver schizo_driver = {
 
 static int __init schizo_init(void)
 {
-       return of_register_driver(&schizo_driver, &of_bus_type);
+       return of_register_platform_driver(&schizo_driver);
 }
 
 subsys_initcall(schizo_init);
index a24af6f7e17f12b125f16d716690e02b663b5f88..743344aa6d8a6a1d6f32738b3e5c1f40352f67d9 100644 (file)
@@ -879,7 +879,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
 #endif /* !(CONFIG_PCI_MSI) */
 
 static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
-                                       struct of_device *op, u32 devhandle)
+                                       struct platform_device *op, u32 devhandle)
 {
        struct device_node *dp = op->dev.of_node;
        int err;
@@ -918,7 +918,7 @@ static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
        return 0;
 }
 
-static int __devinit pci_sun4v_probe(struct of_device *op,
+static int __devinit pci_sun4v_probe(struct platform_device *op,
                                     const struct of_device_id *match)
 {
        const struct linux_prom64_registers *regs;
@@ -1019,7 +1019,7 @@ static struct of_platform_driver pci_sun4v_driver = {
 
 static int __init pci_sun4v_init(void)
 {
-       return of_register_driver(&pci_sun4v_driver, &of_bus_type);
+       return of_register_platform_driver(&pci_sun4v_driver);
 }
 
 subsys_initcall(pci_sun4v_init);
index 44faabc3c02c920bba1b9f12272d1a907895161e..357ced3c33ffac87a992e01b6820a77084cfb8de 100644 (file)
@@ -572,18 +572,18 @@ static u64 sparc_perf_event_update(struct perf_event *event,
        s64 delta;
 
 again:
-       prev_raw_count = atomic64_read(&hwc->prev_count);
+       prev_raw_count = local64_read(&hwc->prev_count);
        new_raw_count = read_pmc(idx);
 
-       if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+       if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
                             new_raw_count) != prev_raw_count)
                goto again;
 
        delta = (new_raw_count << shift) - (prev_raw_count << shift);
        delta >>= shift;
 
-       atomic64_add(delta, &event->count);
-       atomic64_sub(delta, &hwc->period_left);
+       local64_add(delta, &event->count);
+       local64_sub(delta, &hwc->period_left);
 
        return new_raw_count;
 }
@@ -591,27 +591,27 @@ again:
 static int sparc_perf_event_set_period(struct perf_event *event,
                                       struct hw_perf_event *hwc, int idx)
 {
-       s64 left = atomic64_read(&hwc->period_left);
+       s64 left = local64_read(&hwc->period_left);
        s64 period = hwc->sample_period;
        int ret = 0;
 
        if (unlikely(left <= -period)) {
                left = period;
-               atomic64_set(&hwc->period_left, left);
+               local64_set(&hwc->period_left, left);
                hwc->last_period = period;
                ret = 1;
        }
 
        if (unlikely(left <= 0)) {
                left += period;
-               atomic64_set(&hwc->period_left, left);
+               local64_set(&hwc->period_left, left);
                hwc->last_period = period;
                ret = 1;
        }
        if (left > MAX_PERIOD)
                left = MAX_PERIOD;
 
-       atomic64_set(&hwc->prev_count, (u64)-left);
+       local64_set(&hwc->prev_count, (u64)-left);
 
        write_pmc(idx, (u64)(-left) & 0xffffffff);
 
@@ -1006,7 +1006,7 @@ static int sparc_pmu_enable(struct perf_event *event)
         * skip the schedulability test here, it will be peformed
         * at commit time(->commit_txn) as a whole
         */
-       if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
+       if (cpuc->group_flag & PERF_EVENT_TXN)
                goto nocheck;
 
        if (check_excludes(cpuc->event, n0, 1))
@@ -1088,7 +1088,7 @@ static int __hw_perf_event_init(struct perf_event *event)
        if (!hwc->sample_period) {
                hwc->sample_period = MAX_PERIOD;
                hwc->last_period = hwc->sample_period;
-               atomic64_set(&hwc->period_left, hwc->sample_period);
+               local64_set(&hwc->period_left, hwc->sample_period);
        }
 
        return 0;
@@ -1103,7 +1103,7 @@ static void sparc_pmu_start_txn(const struct pmu *pmu)
 {
        struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
 
-       cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
+       cpuhw->group_flag |= PERF_EVENT_TXN;
 }
 
 /*
@@ -1115,7 +1115,7 @@ static void sparc_pmu_cancel_txn(const struct pmu *pmu)
 {
        struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
 
-       cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
+       cpuhw->group_flag &= ~PERF_EVENT_TXN;
 }
 
 /*
@@ -1138,6 +1138,7 @@ static int sparc_pmu_commit_txn(const struct pmu *pmu)
        if (sparc_check_constraints(cpuc->event, cpuc->events, n))
                return -EAGAIN;
 
+       cpuc->group_flag &= ~PERF_EVENT_TXN;
        return 0;
 }
 
index 9589d8b9b0c17eb59f5d0d2d1b66a94ac3fd655e..94536a85f16110f69aa89520f574404bc2438daa 100644 (file)
@@ -51,7 +51,7 @@ static void pmc_swift_idle(void)
 #endif
 }
 
-static int __devinit pmc_probe(struct of_device *op,
+static int __devinit pmc_probe(struct platform_device *op,
                               const struct of_device_id *match)
 {
        regs = of_ioremap(&op->resource[0], 0,
@@ -89,7 +89,7 @@ static struct of_platform_driver pmc_driver = {
 
 static int __init pmc_init(void)
 {
-       return of_register_driver(&pmc_driver, &of_bus_type);
+       return of_register_platform_driver(&pmc_driver);
 }
 
 /* This driver is not critical to the boot process
index 168d4cb63f5b34e110f021769adb1f199bee9a1e..2c59f4d387dd6cf68e0c8bcd140be5bb67e551d5 100644 (file)
@@ -33,10 +33,10 @@ static int __devinit has_button_interrupt(unsigned int irq, struct device_node *
        return 1;
 }
 
-static int __devinit power_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit power_probe(struct platform_device *op, const struct of_device_id *match)
 {
        struct resource *res = &op->resource[0];
-       unsigned int irq= op->irqs[0];
+       unsigned int irq = op->archdata.irqs[0];
 
        power_reg = of_ioremap(res, 0, 0x4, "power");
 
@@ -70,7 +70,7 @@ static struct of_platform_driver power_driver = {
 
 static int __init power_init(void)
 {
-       return of_register_driver(&power_driver, &of_platform_bus_type);
+       return of_register_platform_driver(&power_driver);
 }
 
 device_initcall(power_init);
index a8591ef2636d4e55a64738e836c4a084a840d71c..eeb04a782ec81d3c870d99f64299b5a8f991698e 100644 (file)
@@ -9,14 +9,6 @@ extern void irq_trans_init(struct device_node *dp);
 
 extern unsigned int prom_unique_id;
 
-static inline int is_root_node(const struct device_node *dp)
-{
-       if (!dp)
-               return 0;
-
-       return (dp->parent == NULL);
-}
-
 extern char *build_path_component(struct device_node *dp);
 extern void of_console_init(void);
 
index 466a32763ea82fbe0bd644fb5468459a7fe4196f..86597d9867fd3768dcca56ec3a9263db1deed6fc 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/memblock.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 
 #include <asm/prom.h>
 #include <asm/oplib.h>
@@ -81,7 +81,7 @@ static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
                return;
 
        regs = rprop->value;
-       if (!is_root_node(dp->parent)) {
+       if (!of_node_is_root(dp->parent)) {
                sprintf(tmp_buf, "%s@%x,%x",
                        dp->name,
                        (unsigned int) (regs->phys_addr >> 32UL),
@@ -121,7 +121,7 @@ static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
                return;
 
        regs = prop->value;
-       if (!is_root_node(dp->parent)) {
+       if (!of_node_is_root(dp->parent)) {
                sprintf(tmp_buf, "%s@%x,%x",
                        dp->name,
                        (unsigned int) (regs->phys_addr >> 32UL),
index 57ac9e28be0caff3b08be55f0228fa8655863739..1f830da2ddf2317df09c8b62340c41050ba55883 100644 (file)
@@ -244,7 +244,7 @@ char * __init build_full_name(struct device_node *dp)
 
        n = prom_early_alloc(len);
        strcpy(n, dp->parent->full_name);
-       if (!is_root_node(dp->parent)) {
+       if (!of_node_is_root(dp->parent)) {
                strcpy(n + plen, "/");
                plen++;
        }
index 5702ad4710cb17e758d01b26c98375df19e9ae41..ce651147fabc7080c29987eba1bb1d8367d61673 100644 (file)
@@ -719,7 +719,7 @@ static unsigned int central_build_irq(struct device_node *dp,
                                      void *_data)
 {
        struct device_node *central_dp = _data;
-       struct of_device *central_op = of_find_device_by_node(central_dp);
+       struct platform_device *central_op = of_find_device_by_node(central_dp);
        struct resource *res;
        unsigned long imap, iclr;
        u32 tmp;
index 3f34ac853931c816d7e004d57d44d7663f859524..fe2af66bb1988ee3eff896223b5f131e06ca06e6 100644 (file)
@@ -447,7 +447,7 @@ int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
 
 }
 
-void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct of_device *op,
+void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct platform_device *op,
                            const char *chip_name, int chip_type)
 {
        struct device_node *dp = op->dev.of_node;
index 092c278ef28dce5e575daa94723e3e8bd807f758..590b4ed8ab5e844d59a6485355d0b0f04e558c66 100644 (file)
@@ -42,7 +42,7 @@ extern int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
                             unsigned long write_complete_offset);
 
 extern void psycho_pbm_init_common(struct pci_pbm_info *pbm,
-                                  struct of_device *op,
+                                  struct platform_device *op,
                                   const char *chip_name, int chip_type);
 
 #endif /* _PSYCHO_COMMON_H */
index cfeaf04b9cdf4204cfc5d21f1d8d84bfddb0367d..2ca32d13abcfdbbfbe0a81de61e706d292248b0f 100644 (file)
@@ -57,7 +57,7 @@
 void sbus_set_sbus64(struct device *dev, int bursts)
 {
        struct iommu *iommu = dev->archdata.iommu;
-       struct of_device *op = to_of_device(dev);
+       struct platform_device *op = to_platform_device(dev);
        const struct linux_prom_registers *regs;
        unsigned long cfg_reg;
        int slot;
@@ -204,7 +204,7 @@ static unsigned long sysio_imap_to_iclr(unsigned long imap)
        return imap + diff;
 }
 
-static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino)
+static unsigned int sbus_build_irq(struct platform_device *op, unsigned int ino)
 {
        struct iommu *iommu = op->dev.archdata.iommu;
        unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
@@ -267,7 +267,7 @@ static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino)
 #define  SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved                  */
 static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
 {
-       struct of_device *op = dev_id;
+       struct platform_device *op = dev_id;
        struct iommu *iommu = op->dev.archdata.iommu;
        unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
        unsigned long afsr_reg, afar_reg;
@@ -341,7 +341,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
 #define  SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved                  */
 static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
 {
-       struct of_device *op = dev_id;
+       struct platform_device *op = dev_id;
        struct iommu *iommu = op->dev.archdata.iommu;
        unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
        unsigned long afsr_reg, afar_reg;
@@ -420,7 +420,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
 #define  SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved                  */
 static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
 {
-       struct of_device *op = dev_id;
+       struct platform_device *op = dev_id;
        struct iommu *iommu = op->dev.archdata.iommu;
        unsigned long afsr_reg, afar_reg, reg_base;
        unsigned long afsr, afar, error_bits;
@@ -488,7 +488,7 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
 #define SYSIO_CE_INO           0x35
 #define SYSIO_SBUSERR_INO      0x36
 
-static void __init sysio_register_error_handlers(struct of_device *op)
+static void __init sysio_register_error_handlers(struct platform_device *op)
 {
        struct iommu *iommu = op->dev.archdata.iommu;
        unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
@@ -534,7 +534,7 @@ static void __init sysio_register_error_handlers(struct of_device *op)
 }
 
 /* Boot time initialization. */
-static void __init sbus_iommu_init(struct of_device *op)
+static void __init sbus_iommu_init(struct platform_device *op)
 {
        const struct linux_prom64_registers *pr;
        struct device_node *dp = op->dev.of_node;
@@ -663,7 +663,7 @@ static int __init sbus_init(void)
        struct device_node *dp;
 
        for_each_node_by_name(dp, "sbus") {
-               struct of_device *op = of_find_device_by_node(dp);
+               struct platform_device *op = of_find_device_by_node(dp);
 
                sbus_iommu_init(op);
                of_propagate_archdata(op);
index e404b063be2cbc1d141c899c2e91f1ad79463989..9c743b1886fff4314caf7487065aa8852f8db1e7 100644 (file)
@@ -142,7 +142,7 @@ static struct platform_device m48t59_rtc = {
        },
 };
 
-static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit clock_probe(struct platform_device *op, const struct of_device_id *match)
 {
        struct device_node *dp = op->dev.of_node;
        const char *model = of_get_property(dp, "model", NULL);
@@ -189,7 +189,7 @@ static struct of_platform_driver clock_driver = {
 /* Probe for the mostek real time clock chip. */
 static int __init clock_init(void)
 {
-       return of_register_driver(&clock_driver, &of_platform_bus_type);
+       return of_register_platform_driver(&clock_driver);
 }
 /* Must be after subsys_initcall() so that busses are probed.  Must
  * be before device_initcall() because things like the RTC driver
index 21e9fcae0668cdb7994ca856b428fa4a7a74b6e1..3bc9c9979b92fd1533caab3a5d1b8959c4c8855e 100644 (file)
@@ -419,7 +419,7 @@ static struct platform_device rtc_cmos_device = {
        .num_resources  = 1,
 };
 
-static int __devinit rtc_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit rtc_probe(struct platform_device *op, const struct of_device_id *match)
 {
        struct resource *r;
 
@@ -477,7 +477,7 @@ static struct platform_device rtc_bq4802_device = {
        .num_resources  = 1,
 };
 
-static int __devinit bq4802_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit bq4802_probe(struct platform_device *op, const struct of_device_id *match)
 {
 
        printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n",
@@ -534,7 +534,7 @@ static struct platform_device m48t59_rtc = {
        },
 };
 
-static int __devinit mostek_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit mostek_probe(struct platform_device *op, const struct of_device_id *match)
 {
        struct device_node *dp = op->dev.of_node;
 
@@ -586,9 +586,9 @@ static int __init clock_init(void)
        if (tlb_type == hypervisor)
                return platform_device_register(&rtc_sun4v_device);
 
-       (void) of_register_driver(&rtc_driver, &of_platform_bus_type);
-       (void) of_register_driver(&mostek_driver, &of_platform_bus_type);
-       (void) of_register_driver(&bq4802_driver, &of_platform_bus_type);
+       (void) of_register_platform_driver(&rtc_driver);
+       (void) of_register_platform_driver(&mostek_driver);
+       (void) of_register_platform_driver(&bq4802_driver);
 
        return 0;
 }
index 005e758a4db7fe9cb381c3ddd3955137298e4fad..fc58c3e917dfeb87bb6674136f6531617782dbe9 100644 (file)
@@ -35,7 +35,7 @@
 #define IOPERM        (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID)
 #define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM)
 
-static void __init iounit_iommu_init(struct of_device *op)
+static void __init iounit_iommu_init(struct platform_device *op)
 {
        struct iounit_struct *iounit;
        iopte_t *xpt, *xptend;
@@ -74,7 +74,7 @@ static int __init iounit_init(void)
        struct device_node *dp;
 
        for_each_node_by_name(dp, "sbi") {
-               struct of_device *op = of_find_device_by_node(dp);
+               struct platform_device *op = of_find_device_by_node(dp);
 
                iounit_iommu_init(op);
                of_propagate_archdata(op);
index 0e8ae298b3c3a7e8fedd26e93a6204915b887775..07fc6a65d9b622f6b1fccb73d559567cdeb8a18f 100644 (file)
@@ -56,7 +56,7 @@ static pgprot_t dvma_prot;            /* Consistent mapping pte flags */
 #define IOPERM        (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID)
 #define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ)
 
-static void __init sbus_iommu_init(struct of_device *op)
+static void __init sbus_iommu_init(struct platform_device *op)
 {
        struct iommu_struct *iommu;
        unsigned int impl, vers;
@@ -132,7 +132,7 @@ static int __init iommu_init(void)
        struct device_node *dp;
 
        for_each_node_by_name(dp, "iommu") {
-               struct of_device *op = of_find_device_by_node(dp);
+               struct platform_device *op = of_find_device_by_node(dp);
 
                sbus_iommu_init(op);
                of_propagate_archdata(op);
index 0d207e73a75821df92dfc443c546530650a43e96..7c8e277f6d342a295d37bad076a6fb61588dbae6 100644 (file)
@@ -55,10 +55,6 @@ config GENERIC_BUG
        default y
        depends on BUG
 
-config GENERIC_TIME
-       bool
-       default y
-
 config GENERIC_CLOCKEVENTS
        bool
        default y
index 084de4a9fc701412492b315e4162e693884beb8b..0032f9212e74a2b8b4722427611a29aeb5cd62c7 100644 (file)
@@ -60,7 +60,7 @@
        set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
 
 #ifdef CONFIG_64BIT
-#define set_pud(pudptr, pudval) set_64bit((phys_t *) (pudptr), pud_val(pudval))
+#define set_pud(pudptr, pudval) set_64bit((u64 *) (pudptr), pud_val(pudval))
 #else
 #define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
 #endif
@@ -73,7 +73,7 @@ static inline int pgd_newpage(pgd_t pgd)
 static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; }
 
 #ifdef CONFIG_64BIT
-#define set_pmd(pmdptr, pmdval) set_64bit((phys_t *) (pmdptr), pmd_val(pmdval))
+#define set_pmd(pmdptr, pmdval) set_64bit((u64 *) (pmdptr), pmd_val(pmdval))
 #else
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
 #endif
index c8b9c469fcd7995822d7a25c02be9fe2e0d45e4e..a08d9fab81f2025c008c23e8b4ed229ff6c65525 100644 (file)
@@ -102,16 +102,16 @@ static void __init setup_itimer(void)
        clockevents_register_device(&itimer_clockevent);
 }
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
-       long long nsecs;
-
-       timer_init();
+       long long nsecs = os_nsecs();
 
-       nsecs = os_nsecs();
-       set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC,
-                               -nsecs % NSEC_PER_SEC);
-       set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC,
+       set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
                                nsecs % NSEC_PER_SEC);
+}
+
+void __init time_init(void)
+{
+       timer_init();
        late_time_init = setup_itimer;
 }
index dcb0593b4a66348a204a44fee3366c5da0848ad1..a84fc34c8f777c54eb707abe6b43c19a025c75f0 100644 (file)
@@ -55,6 +55,7 @@ config X86
        select HAVE_HW_BREAKPOINT
        select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS
+       select HAVE_PERF_EVENTS_NMI
        select ANON_INODES
        select HAVE_ARCH_KMEMCHECK
        select HAVE_USER_RETURN_NOTIFIER
@@ -72,9 +73,6 @@ config ARCH_DEFCONFIG
        default "arch/x86/configs/i386_defconfig" if X86_32
        default "arch/x86/configs/x86_64_defconfig" if X86_64
 
-config GENERIC_TIME
-       def_bool y
-
 config GENERIC_CMOS_UPDATE
        def_bool y
 
@@ -2046,7 +2044,7 @@ config SCx200
 
 config SCx200HR_TIMER
        tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
-       depends on SCx200 && GENERIC_TIME
+       depends on SCx200
        default y
        ---help---
          This driver provides a clocksource built upon the on-chip
@@ -2062,6 +2060,15 @@ config OLPC
          Add support for detecting the unique features of the OLPC
          XO hardware.
 
+config OLPC_OPENFIRMWARE
+       bool "Support for OLPC's Open Firmware"
+       depends on !X86_64 && !X86_PAE
+       default y if OLPC
+       help
+         This option adds support for the implementation of Open Firmware
+         that is used on the OLPC XO-1 Children's Machine.
+         If unsure, say N here.
+
 endif # X86_32
 
 config K8_NB
index ec749c2bfdd7b10e3a15ccb237b803bd8b412f6e..f7cb086b4add7f8f5adaa7ff904f8bf1c7ffadd3 100644 (file)
@@ -26,10 +26,10 @@ targets             := vmlinux.bin setup.bin setup.elf bzImage
 targets                += fdimage fdimage144 fdimage288 image.iso mtools.conf
 subdir-                := compressed
 
-setup-y                += a20.o bioscall.o cmdline.o copy.o cpu.o cpucheck.o edd.o
-setup-y                += header.o main.o mca.o memory.o pm.o pmjump.o
-setup-y                += printf.o regs.o string.o tty.o video.o video-mode.o
-setup-y                += version.o
+setup-y                += a20.o bioscall.o cmdline.o copy.o cpu.o cpucheck.o
+setup-y                += early_serial_console.o edd.o header.o main.o mca.o memory.o
+setup-y                += pm.o pmjump.o printf.o regs.o string.o tty.o video.o
+setup-y                += video-mode.o version.o
 setup-$(CONFIG_X86_APM_BOOT) += apm.o
 
 # The link order of the video-*.o modules can matter.  In particular,
index 98239d2658f27b3ed3494ea1b0ad3d6cd0a01624..c7093bd9f2d34f834267ccace3557e8f399f154f 100644 (file)
@@ -28,6 +28,7 @@
 #include "bitops.h"
 #include <asm/cpufeature.h>
 #include <asm/processor-flags.h>
+#include "ctype.h"
 
 /* Useful macros */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
@@ -37,6 +38,8 @@
 extern struct setup_header hdr;
 extern struct boot_params boot_params;
 
+#define cpu_relax()    asm volatile("rep; nop")
+
 /* Basic port I/O */
 static inline void outb(u8 v, u16 port)
 {
@@ -198,11 +201,6 @@ static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
        return diff;
 }
 
-static inline int isdigit(int ch)
-{
-       return (ch >= '0') && (ch <= '9');
-}
-
 /* Heap -- available for dynamic lists. */
 extern char _end[];
 extern char *HEAP;
@@ -287,8 +285,18 @@ struct biosregs {
 void intcall(u8 int_no, const struct biosregs *ireg, struct biosregs *oreg);
 
 /* cmdline.c */
-int cmdline_find_option(const char *option, char *buffer, int bufsize);
-int cmdline_find_option_bool(const char *option);
+int __cmdline_find_option(u32 cmdline_ptr, const char *option, char *buffer, int bufsize);
+int __cmdline_find_option_bool(u32 cmdline_ptr, const char *option);
+static inline int cmdline_find_option(const char *option, char *buffer, int bufsize)
+{
+       return __cmdline_find_option(boot_params.hdr.cmd_line_ptr, option, buffer, bufsize);
+}
+
+static inline int cmdline_find_option_bool(const char *option)
+{
+       return __cmdline_find_option_bool(boot_params.hdr.cmd_line_ptr, option);
+}
+
 
 /* cpu.c, cpucheck.c */
 struct cpu_features {
@@ -300,6 +308,10 @@ extern struct cpu_features cpu;
 int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
 int validate_cpu(void);
 
+/* early_serial_console.c */
+extern int early_serial_base;
+void console_init(void);
+
 /* edd.c */
 void query_edd(void);
 
@@ -329,8 +341,10 @@ void initregs(struct biosregs *regs);
 
 /* string.c */
 int strcmp(const char *str1, const char *str2);
+int strncmp(const char *cs, const char *ct, size_t count);
 size_t strnlen(const char *s, size_t maxlen);
 unsigned int atou(const char *s);
+unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base);
 
 /* tty.c */
 void puts(const char *);
index a1d35634bce0097d6ea32110f4285d0c1a9225b8..6b3b6f708c04262c02a788f815d1feac7d25786b 100644 (file)
@@ -27,9 +27,8 @@ static inline int myisspace(u8 c)
  * Returns the length of the argument (regardless of if it was
  * truncated to fit in the buffer), or -1 on not found.
  */
-int cmdline_find_option(const char *option, char *buffer, int bufsize)
+int __cmdline_find_option(u32 cmdline_ptr, const char *option, char *buffer, int bufsize)
 {
-       u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
        addr_t cptr;
        char c;
        int len = -1;
@@ -100,9 +99,8 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize)
  * Returns the position of that option (starts counting with 1)
  * or 0 on not found
  */
-int cmdline_find_option_bool(const char *option)
+int __cmdline_find_option_bool(u32 cmdline_ptr, const char *option)
 {
-       u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
        addr_t cptr;
        char c;
        int pos = 0, wstart = 0;
index fbb47daf2459d4aed21a1ef1d106965199a98436..0c229551eead15adb41e5636aa7fce7233ebc555 100644 (file)
@@ -4,7 +4,7 @@
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o
+targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
@@ -23,7 +23,7 @@ LDFLAGS_vmlinux := -T
 
 hostprogs-y    := mkpiggy
 
-$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o $(obj)/piggy.o FORCE
        $(call if_changed,ld)
        @:
 
diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c
new file mode 100644 (file)
index 0000000..cb62f78
--- /dev/null
@@ -0,0 +1,21 @@
+#include "misc.h"
+
+static unsigned long fs;
+static inline void set_fs(unsigned long seg)
+{
+       fs = seg << 4;  /* shift it back */
+}
+typedef unsigned long addr_t;
+static inline char rdfs8(addr_t addr)
+{
+       return *((char *)(fs + addr));
+}
+#include "../cmdline.c"
+int cmdline_find_option(const char *option, char *buffer, int bufsize)
+{
+       return __cmdline_find_option(real_mode->hdr.cmd_line_ptr, option, buffer, bufsize);
+}
+int cmdline_find_option_bool(const char *option)
+{
+       return __cmdline_find_option_bool(real_mode->hdr.cmd_line_ptr, option);
+}
diff --git a/arch/x86/boot/compressed/early_serial_console.c b/arch/x86/boot/compressed/early_serial_console.c
new file mode 100644 (file)
index 0000000..261e81f
--- /dev/null
@@ -0,0 +1,5 @@
+#include "misc.h"
+
+int early_serial_base;
+
+#include "../early_serial_console.c"
index f543b70ffae25b24e89c15bc03b17576124efc7b..67a655a39ce43d3da454b7fd8f230b70d8a9c6bc 100644 (file)
@@ -123,6 +123,19 @@ relocated:
        shrl    $2, %ecx
        rep     stosl
 
+/*
+ * Adjust our own GOT
+ */
+       leal    _got(%ebx), %edx
+       leal    _egot(%ebx), %ecx
+1:
+       cmpl    %ecx, %edx
+       jae     2f
+       addl    %ebx, (%edx)
+       addl    $4, %edx
+       jmp     1b
+2:
+
 /*
  * Do the decompression, and jump to the new kernel..
  */
index faff0dc9c06a2389a405cdcb3e089baf8c7ad285..52f85a196fa033df961d20349ce6b7437409e843 100644 (file)
@@ -279,6 +279,19 @@ relocated:
        shrq    $3, %rcx
        rep     stosq
 
+/*
+ * Adjust our own GOT
+ */
+       leaq    _got(%rip), %rdx
+       leaq    _egot(%rip), %rcx
+1:
+       cmpq    %rcx, %rdx
+       jae     2f
+       addq    %rbx, (%rdx)
+       addq    $8, %rdx
+       jmp     1b
+2:
+       
 /*
  * Do the decompression, and jump to the new kernel..
  */
index 51e240779a44c5b912957c31c7e877b29d058d9c..8f7bef8e9fff530318e64cef59702d740323d545 100644 (file)
@@ -9,23 +9,7 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 
-/*
- * we have to be careful, because no indirections are allowed here, and
- * paravirt_ops is a kind of one. As it will only run in baremetal anyway,
- * we just keep it from happening
- */
-#undef CONFIG_PARAVIRT
-#ifdef CONFIG_X86_32
-#define _ASM_X86_DESC_H 1
-#endif
-
-#include <linux/linkage.h>
-#include <linux/screen_info.h>
-#include <linux/elf.h>
-#include <linux/io.h>
-#include <asm/page.h>
-#include <asm/boot.h>
-#include <asm/bootparam.h>
+#include "misc.h"
 
 /* WARNING!!
  * This code is compiled with -fPIC and it is relocated dynamically
@@ -123,15 +107,13 @@ static void error(char *m);
 /*
  * This is set up by the setup-routine at boot-time
  */
-static struct boot_params *real_mode;          /* Pointer to real-mode data */
+struct boot_params *real_mode;         /* Pointer to real-mode data */
 static int quiet;
+static int debug;
 
 void *memset(void *s, int c, size_t n);
 void *memcpy(void *dest, const void *src, size_t n);
 
-static void __putstr(int, const char *);
-#define putstr(__x)  __putstr(0, __x)
-
 #ifdef CONFIG_X86_64
 #define memptr long
 #else
@@ -170,7 +152,21 @@ static void scroll(void)
                vidmem[i] = ' ';
 }
 
-static void __putstr(int error, const char *s)
+#define XMTRDY          0x20
+
+#define TXR             0       /*  Transmit register (WRITE) */
+#define LSR             5       /*  Line Status               */
+static void serial_putchar(int ch)
+{
+       unsigned timeout = 0xffff;
+
+       while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
+               cpu_relax();
+
+       outb(ch, early_serial_base + TXR);
+}
+
+void __putstr(int error, const char *s)
 {
        int x, y, pos;
        char c;
@@ -179,6 +175,14 @@ static void __putstr(int error, const char *s)
        if (!error)
                return;
 #endif
+       if (early_serial_base) {
+               const char *str = s;
+               while (*str) {
+                       if (*str == '\n')
+                               serial_putchar('\r');
+                       serial_putchar(*str++);
+               }
+       }
 
        if (real_mode->screen_info.orig_video_mode == 0 &&
            lines == 0 && cols == 0)
@@ -305,8 +309,10 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
 {
        real_mode = rmode;
 
-       if (real_mode->hdr.loadflags & QUIET_FLAG)
+       if (cmdline_find_option_bool("quiet"))
                quiet = 1;
+       if (cmdline_find_option_bool("debug"))
+               debug = 1;
 
        if (real_mode->screen_info.orig_video_mode == 7) {
                vidmem = (char *) 0xb0000;
@@ -319,6 +325,10 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
        lines = real_mode->screen_info.orig_video_lines;
        cols = real_mode->screen_info.orig_video_cols;
 
+       console_init();
+       if (debug)
+               putstr("early console in decompress_kernel\n");
+
        free_mem_ptr     = heap;        /* Heap */
        free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
 
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
new file mode 100644 (file)
index 0000000..3f19c81
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef BOOT_COMPRESSED_MISC_H
+#define BOOT_COMPRESSED_MISC_H
+
+/*
+ * we have to be careful, because no indirections are allowed here, and
+ * paravirt_ops is a kind of one. As it will only run in baremetal anyway,
+ * we just keep it from happening
+ */
+#undef CONFIG_PARAVIRT
+#ifdef CONFIG_X86_32
+#define _ASM_X86_DESC_H 1
+#endif
+
+#include <linux/linkage.h>
+#include <linux/screen_info.h>
+#include <linux/elf.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <asm/boot.h>
+#include <asm/bootparam.h>
+
+#define BOOT_BOOT_H
+#include "../ctype.h"
+
+/* misc.c */
+extern struct boot_params *real_mode;          /* Pointer to real-mode data */
+void __putstr(int error, const char *s);
+#define putstr(__x)  __putstr(0, __x)
+#define puts(__x)  __putstr(0, __x)
+
+/* cmdline.c */
+int cmdline_find_option(const char *option, char *buffer, int bufsize);
+int cmdline_find_option_bool(const char *option);
+
+/* early_serial_console.c */
+extern int early_serial_base;
+void console_init(void);
+
+#endif
diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c
new file mode 100644 (file)
index 0000000..19b3e69
--- /dev/null
@@ -0,0 +1,2 @@
+#include "misc.h"
+#include "../string.c"
index 5ddabceee12408d55f22b6412bbd4617dc684c55..34d047c982848439e7ed907cbea7b4398bf860cd 100644 (file)
@@ -41,6 +41,12 @@ SECTIONS
                *(.rodata.*)
                _erodata = . ;
        }
+       .got : {
+               _got = .;
+               KEEP(*(.got.plt))
+               KEEP(*(.got))
+               _egot = .;
+       }
        .data : {
                _data = . ;
                *(.data)
diff --git a/arch/x86/boot/ctype.h b/arch/x86/boot/ctype.h
new file mode 100644 (file)
index 0000000..25e1340
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef BOOT_ISDIGIT_H
+
+#define BOOT_ISDIGIT_H
+
+static inline int isdigit(int ch)
+{
+       return (ch >= '0') && (ch <= '9');
+}
+
+static inline int isxdigit(int ch)
+{
+       if (isdigit(ch))
+               return true;
+
+       if ((ch >= 'a') && (ch <= 'f'))
+               return true;
+
+       return (ch >= 'A') && (ch <= 'F');
+}
+
+#endif
diff --git a/arch/x86/boot/early_serial_console.c b/arch/x86/boot/early_serial_console.c
new file mode 100644 (file)
index 0000000..030f4b9
--- /dev/null
@@ -0,0 +1,139 @@
+#include "boot.h"
+
+#define DEFAULT_SERIAL_PORT 0x3f8 /* ttyS0 */
+
+#define XMTRDY          0x20
+
+#define DLAB           0x80
+
+#define TXR             0       /*  Transmit register (WRITE) */
+#define RXR             0       /*  Receive register  (READ)  */
+#define IER             1       /*  Interrupt Enable          */
+#define IIR             2       /*  Interrupt ID              */
+#define FCR             2       /*  FIFO control              */
+#define LCR             3       /*  Line control              */
+#define MCR             4       /*  Modem control             */
+#define LSR             5       /*  Line Status               */
+#define MSR             6       /*  Modem Status              */
+#define DLL             0       /*  Divisor Latch Low         */
+#define DLH             1       /*  Divisor latch High        */
+
+#define DEFAULT_BAUD 9600
+
+static void early_serial_init(int port, int baud)
+{
+       unsigned char c;
+       unsigned divisor;
+
+       outb(0x3, port + LCR);  /* 8n1 */
+       outb(0, port + IER);    /* no interrupt */
+       outb(0, port + FCR);    /* no fifo */
+       outb(0x3, port + MCR);  /* DTR + RTS */
+
+       divisor = 115200 / baud;
+       c = inb(port + LCR);
+       outb(c | DLAB, port + LCR);
+       outb(divisor & 0xff, port + DLL);
+       outb((divisor >> 8) & 0xff, port + DLH);
+       outb(c & ~DLAB, port + LCR);
+
+       early_serial_base = port;
+}
+
+static void parse_earlyprintk(void)
+{
+       int baud = DEFAULT_BAUD;
+       char arg[32];
+       int pos = 0;
+       int port = 0;
+
+       if (cmdline_find_option("earlyprintk", arg, sizeof arg) > 0) {
+               char *e;
+
+               if (!strncmp(arg, "serial", 6)) {
+                       port = DEFAULT_SERIAL_PORT;
+                       pos += 6;
+               }
+
+               if (arg[pos] == ',')
+                       pos++;
+
+               if (!strncmp(arg, "ttyS", 4)) {
+                       static const int bases[] = { 0x3f8, 0x2f8 };
+                       int idx = 0;
+
+                       if (!strncmp(arg + pos, "ttyS", 4))
+                               pos += 4;
+
+                       if (arg[pos++] == '1')
+                               idx = 1;
+
+                       port = bases[idx];
+               }
+
+               if (arg[pos] == ',')
+                       pos++;
+
+               baud = simple_strtoull(arg + pos, &e, 0);
+               if (baud == 0 || arg + pos == e)
+                       baud = DEFAULT_BAUD;
+       }
+
+       if (port)
+               early_serial_init(port, baud);
+}
+
+#define BASE_BAUD (1843200/16)
+static unsigned int probe_baud(int port)
+{
+       unsigned char lcr, dll, dlh;
+       unsigned int quot;
+
+       lcr = inb(port + LCR);
+       outb(lcr | DLAB, port + LCR);
+       dll = inb(port + DLL);
+       dlh = inb(port + DLH);
+       outb(lcr, port + LCR);
+       quot = (dlh << 8) | dll;
+
+       return BASE_BAUD / quot;
+}
+
+static void parse_console_uart8250(void)
+{
+       char optstr[64], *options;
+       int baud = DEFAULT_BAUD;
+       int port = 0;
+
+       /*
+        * console=uart8250,io,0x3f8,115200n8
+        * need to make sure it is last one console !
+        */
+       if (cmdline_find_option("console", optstr, sizeof optstr) <= 0)
+               return;
+
+       options = optstr;
+
+       if (!strncmp(options, "uart8250,io,", 12))
+               port = simple_strtoull(options + 12, &options, 0);
+       else if (!strncmp(options, "uart,io,", 8))
+               port = simple_strtoull(options + 8, &options, 0);
+       else
+               return;
+
+       if (options && (options[0] == ','))
+               baud = simple_strtoull(options + 1, &options, 0);
+       else
+               baud = probe_baud(port);
+
+       if (port)
+               early_serial_init(port, baud);
+}
+
+void console_init(void)
+{
+       parse_earlyprintk();
+
+       if (!early_serial_base)
+               parse_console_uart8250();
+}
index 140172b895bd32c32ca2819ef776718f77df3103..40358c8905befe2cdf8c8ef6055300e00e08a3a0 100644 (file)
@@ -130,6 +130,11 @@ void main(void)
        /* First, copy the boot header into the "zeropage" */
        copy_boot_params();
 
+       /* Initialize the early-boot console */
+       console_init();
+       if (cmdline_find_option_bool("debug"))
+               puts("early console in setup code\n");
+
        /* End of heap check */
        init_heap();
 
@@ -168,10 +173,6 @@ void main(void)
        /* Set the video mode */
        set_video();
 
-       /* Parse command line for 'quiet' and pass it to decompressor. */
-       if (cmdline_find_option_bool("quiet"))
-               boot_params.hdr.loadflags |= QUIET_FLAG;
-
        /* Do the last things and invoke protected mode */
        go_to_protected_mode();
 }
index 50e47cdbdddd4234f78ab88028407c0aeccd8497..cdac91ca55d384e0e9cca2ff4e43ded437a44557 100644 (file)
@@ -34,7 +34,7 @@ static int skip_atoi(const char **s)
 #define SMALL  32              /* Must be 32 == 0x20 */
 #define SPECIAL        64              /* 0x */
 
-#define do_div(n,base) ({ \
+#define __do_div(n, base) ({ \
 int __res; \
 __res = ((unsigned long) n) % (unsigned) base; \
 n = ((unsigned long) n) / (unsigned) base; \
@@ -83,7 +83,7 @@ static char *number(char *str, long num, int base, int size, int precision,
                tmp[i++] = '0';
        else
                while (num != 0)
-                       tmp[i++] = (digits[do_div(num, base)] | locase);
+                       tmp[i++] = (digits[__do_div(num, base)] | locase);
        if (i > precision)
                precision = i;
        size -= precision;
index f94b7a0c2abf8e2477ec5589a54ba682872f680b..3cbc4058dd26c1e74e633b95680aa30667b5fff4 100644 (file)
@@ -30,6 +30,22 @@ int strcmp(const char *str1, const char *str2)
        return 0;
 }
 
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+       unsigned char c1, c2;
+
+       while (count) {
+               c1 = *cs++;
+               c2 = *ct++;
+               if (c1 != c2)
+                       return c1 < c2 ? -1 : 1;
+               if (!c1)
+                       break;
+               count--;
+       }
+       return 0;
+}
+
 size_t strnlen(const char *s, size_t maxlen)
 {
        const char *es = s;
@@ -48,3 +64,50 @@ unsigned int atou(const char *s)
                i = i * 10 + (*s++ - '0');
        return i;
 }
+
+/* Works only for digits and letters, but small and fast */
+#define TOLOWER(x) ((x) | 0x20)
+
+static unsigned int simple_guess_base(const char *cp)
+{
+       if (cp[0] == '0') {
+               if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
+                       return 16;
+               else
+                       return 8;
+       } else {
+               return 10;
+       }
+}
+
+/**
+ * simple_strtoull - convert a string to an unsigned long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+
+unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
+{
+       unsigned long long result = 0;
+
+       if (!base)
+               base = simple_guess_base(cp);
+
+       if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
+               cp += 2;
+
+       while (isxdigit(*cp)) {
+               unsigned int value;
+
+               value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
+               if (value >= base)
+                       break;
+               result = result * base + value;
+               cp++;
+       }
+       if (endp)
+               *endp = (char *)cp;
+
+       return result;
+}
index 01ec69c901c7a595e88748f24880a5104af553fe..def2451f46aefe70fe38d5ed3554a380f710a6e2 100644 (file)
  * ----------------------------------------------------------------------- */
 
 /*
- * Very simple screen I/O
- * XXX: Probably should add very simple serial I/O?
+ * Very simple screen and serial I/O
  */
 
 #include "boot.h"
 
+int early_serial_base;
+
+#define XMTRDY          0x20
+
+#define TXR             0       /*  Transmit register (WRITE) */
+#define LSR             5       /*  Line Status               */
+
 /*
  * These functions are in .inittext so they can be used to signal
  * error during initialization.
  */
 
-void __attribute__((section(".inittext"))) putchar(int ch)
+static void __attribute__((section(".inittext"))) serial_putchar(int ch)
 {
-       struct biosregs ireg;
+       unsigned timeout = 0xffff;
 
-       if (ch == '\n')
-               putchar('\r');  /* \n -> \r\n */
+       while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
+               cpu_relax();
+
+       outb(ch, early_serial_base + TXR);
+}
+
+static void __attribute__((section(".inittext"))) bios_putchar(int ch)
+{
+       struct biosregs ireg;
 
        initregs(&ireg);
        ireg.bx = 0x0007;
@@ -36,6 +49,17 @@ void __attribute__((section(".inittext"))) putchar(int ch)
        intcall(0x10, &ireg, NULL);
 }
 
+void __attribute__((section(".inittext"))) putchar(int ch)
+{
+       if (ch == '\n')
+               putchar('\r');  /* \n -> \r\n */
+
+       bios_putchar(ch);
+
+       if (early_serial_base != 0)
+               serial_putchar(ch);
+}
+
 void __attribute__((section(".inittext"))) puts(const char *str)
 {
        while (*str)
@@ -112,3 +136,4 @@ int getchar_timeout(void)
 
        return 0;               /* Timeout! */
 }
+
index d28fad19654aa0bc203b034bd0e9051f46a3cc45..e3a32431ca1efaf30333217cda7e4af4d5b64a6a 100644 (file)
@@ -1471,6 +1471,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_CORETEMP is not set
+# CONFIG_SENSORS_PKGTEMP is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
index 6c86acd847a4e28c09d951b34d488b13d44df3c7..4251f8372050edefaa209b71a4fefb91d80507e6 100644 (file)
@@ -1456,6 +1456,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_CORETEMP is not set
+# CONFIG_SENSORS_PKGTEMP is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
index aa2c39d968fc7a9235d4f3009d38ddf566a33154..92091de11113367894501e82c9d3363f05c5232e 100644 (file)
@@ -134,7 +134,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
            boot_cpu_data.x86_model <= 0x05 &&
            boot_cpu_data.x86_mask < 0x0A)
                return 1;
-       else if (boot_cpu_has(X86_FEATURE_AMDC1E))
+       else if (c1e_detected)
                return 1;
        else
                return max_cstate;
index 03b6bb5394a02d7211f79a00d0b87e2f74e5cbc7..bc6abb7bc7ee3084aa8b5d87ae19244715469990 100644 (file)
 struct alt_instr {
        u8 *instr;              /* original instruction */
        u8 *replacement;
-       u cpuid;              /* cpuid bit set for replacement */
+       u16 cpuid;              /* cpuid bit set for replacement */
        u8  instrlen;           /* length of original instruction */
        u8  replacementlen;     /* length of new instruction, <= instrlen */
-       u8  pad1;
 #ifdef CONFIG_X86_64
        u32 pad2;
 #endif
@@ -86,9 +85,11 @@ static inline int alternatives_text_reserved(void *start, void *end)
       _ASM_ALIGN "\n"                                                  \
       _ASM_PTR "661b\n"                                /* label           */   \
       _ASM_PTR "663f\n"                                /* new instruction */   \
-      "         .byte " __stringify(feature) "\n"      /* feature bit     */   \
+      "         .word " __stringify(feature) "\n"      /* feature bit     */   \
       "         .byte 662b-661b\n"                     /* sourcelen       */   \
       "         .byte 664f-663f\n"                     /* replacementlen  */   \
+      ".previous\n"                                                    \
+      ".section .discard,\"aw\",@progbits\n"                           \
       "         .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */   \
       ".previous\n"                                                    \
       ".section .altinstr_replacement, \"ax\"\n"                       \
index c74a2eebe570e5fef9c5bb7d9891b997e7f5c000..a69b1ac9eaf82d639fd0ae51459d2dfdc79fbd1b 100644 (file)
@@ -55,7 +55,6 @@ extern unsigned long apbt_quick_calibrate(void);
 extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu);
 extern void apbt_setup_secondary_clock(void);
 extern unsigned int boot_cpu_id;
-extern int disable_apbt_percpu;
 
 extern struct sfi_timer_table_entry *sfi_get_mtmr(int hint);
 extern void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr);
index 6be33d83c7168cd9fea62149e7124310fbacbb02..8e6218550e774b56fd30f3171bc163bfb511b947 100644 (file)
@@ -70,6 +70,14 @@ struct sys_desc_table {
        __u8  table[14];
 };
 
+/* Gleaned from OFW's set-parameters in cpu/x86/pc/linux.fth */
+struct olpc_ofw_header {
+       __u32 ofw_magic;        /* OFW signature */
+       __u32 ofw_version;
+       __u32 cif_handler;      /* callback into OFW */
+       __u32 irq_desc_table;
+} __attribute__((packed));
+
 struct efi_info {
        __u32 efi_loader_signature;
        __u32 efi_systab;
@@ -92,7 +100,8 @@ struct boot_params {
        __u8  hd0_info[16];     /* obsolete! */         /* 0x080 */
        __u8  hd1_info[16];     /* obsolete! */         /* 0x090 */
        struct sys_desc_table sys_desc_table;           /* 0x0a0 */
-       __u8  _pad4[144];                               /* 0x0b0 */
+       struct olpc_ofw_header olpc_ofw_header;         /* 0x0b0 */
+       __u8  _pad4[128];                               /* 0x0c0 */
        struct edid_info edid_info;                     /* 0x140 */
        struct efi_info efi_info;                       /* 0x1c0 */
        __u32 alt_mem_k;                                /* 0x1e0 */
index 8859e12dd3cf85a6f6c9aa1d8ccda53cb799c018..284a6e8f7ce167e8e854f47db895a44ee2cfbefa 100644 (file)
 extern void __xchg_wrong_size(void);
 
 /*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- *       but generally the primitive is invalid, *ptr is output argument. --ANK
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
+ * Since this is generally used to protect other memory information, we
+ * use "asm volatile" and "memory" clobbers to prevent gcc from moving
+ * information around.
  */
-
-struct __xchg_dummy {
-       unsigned long a[100];
-};
-#define __xg(x) ((struct __xchg_dummy *)(x))
-
 #define __xchg(x, ptr, size)                                           \
 ({                                                                     \
        __typeof(*(ptr)) __x = (x);                                     \
        switch (size) {                                                 \
        case 1:                                                         \
-               asm volatile("xchgb %b0,%1"                             \
-                            : "=q" (__x)                               \
-                            : "m" (*__xg(ptr)), "0" (__x)              \
+       {                                                               \
+               volatile u8 *__ptr = (volatile u8 *)(ptr);              \
+               asm volatile("xchgb %0,%1"                              \
+                            : "=q" (__x), "+m" (*__ptr)                \
+                            : "0" (__x)                                \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 2:                                                         \
-               asm volatile("xchgw %w0,%1"                             \
-                            : "=r" (__x)                               \
-                            : "m" (*__xg(ptr)), "0" (__x)              \
+       {                                                               \
+               volatile u16 *__ptr = (volatile u16 *)(ptr);            \
+               asm volatile("xchgw %0,%1"                              \
+                            : "=r" (__x), "+m" (*__ptr)                \
+                            : "0" (__x)                                \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 4:                                                         \
+       {                                                               \
+               volatile u32 *__ptr = (volatile u32 *)(ptr);            \
                asm volatile("xchgl %0,%1"                              \
-                            : "=r" (__x)                               \
-                            : "m" (*__xg(ptr)), "0" (__x)              \
+                            : "=r" (__x), "+m" (*__ptr)                \
+                            : "0" (__x)                                \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        default:                                                        \
                __xchg_wrong_size();                                    \
        }                                                               \
@@ -53,60 +57,33 @@ struct __xchg_dummy {
        __xchg((v), (ptr), sizeof(*ptr))
 
 /*
- * The semantics of XCHGCMP8B are a bit strange, this is why
- * there is a loop and the loading of %%eax and %%edx has to
- * be inside. This inlines well in most cases, the cached
- * cost is around ~38 cycles. (in the future we might want
- * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
- * might have an implicit FPU-save as a cost, so it's not
- * clear which path to go.)
+ * CMPXCHG8B only writes to the target if we had the previous
+ * value in registers, otherwise it acts as a read and gives us the
+ * "new previous" value.  That is why there is a loop.  Preloading
+ * EDX:EAX is a performance optimization: in the common case it means
+ * we need only one locked operation.
  *
- * cmpxchg8b must be used with the lock prefix here to allow
- * the instruction to be executed atomically, see page 3-102
- * of the instruction set reference 24319102.pdf. We need
- * the reader side to see the coherent 64bit value.
+ * A SIMD/3DNOW!/MMX/FPU 64-bit store here would require at the very
+ * least an FPU save and/or %cr0.ts manipulation.
+ *
+ * cmpxchg8b must be used with the lock prefix here to allow the
+ * instruction to be executed atomically.  We need to have the reader
+ * side to see the coherent 64bit value.
  */
-static inline void __set_64bit(unsigned long long *ptr,
-                              unsigned int low, unsigned int high)
+static inline void set_64bit(volatile u64 *ptr, u64 value)
 {
+       u32 low  = value;
+       u32 high = value >> 32;
+       u64 prev = *ptr;
+
        asm volatile("\n1:\t"
-                    "movl (%0), %%eax\n\t"
-                    "movl 4(%0), %%edx\n\t"
-                    LOCK_PREFIX "cmpxchg8b (%0)\n\t"
+                    LOCK_PREFIX "cmpxchg8b %0\n\t"
                     "jnz 1b"
-                    : /* no outputs */
-                    : "D"(ptr),
-                      "b"(low),
-                      "c"(high)
-                    : "ax", "dx", "memory");
-}
-
-static inline void __set_64bit_constant(unsigned long long *ptr,
-                                       unsigned long long value)
-{
-       __set_64bit(ptr, (unsigned int)value, (unsigned int)(value >> 32));
-}
-
-#define ll_low(x)      *(((unsigned int *)&(x)) + 0)
-#define ll_high(x)     *(((unsigned int *)&(x)) + 1)
-
-static inline void __set_64bit_var(unsigned long long *ptr,
-                                  unsigned long long value)
-{
-       __set_64bit(ptr, ll_low(value), ll_high(value));
+                    : "=m" (*ptr), "+A" (prev)
+                    : "b" (low), "c" (high)
+                    : "memory");
 }
 
-#define set_64bit(ptr, value)                  \
-       (__builtin_constant_p((value))          \
-        ? __set_64bit_constant((ptr), (value)) \
-        : __set_64bit_var((ptr), (value)))
-
-#define _set_64bit(ptr, value)                                         \
-       (__builtin_constant_p(value)                                    \
-        ? __set_64bit(ptr, (unsigned int)(value),                      \
-                      (unsigned int)((value) >> 32))                   \
-        : __set_64bit(ptr, ll_low((value)), ll_high((value))))
-
 extern void __cmpxchg_wrong_size(void);
 
 /*
@@ -121,23 +98,32 @@ extern void __cmpxchg_wrong_size(void);
        __typeof__(*(ptr)) __new = (new);                               \
        switch (size) {                                                 \
        case 1:                                                         \
-               asm volatile(lock "cmpxchgb %b1,%2"                     \
-                            : "=a"(__ret)                              \
-                            : "q"(__new), "m"(*__xg(ptr)), "0"(__old)  \
+       {                                                               \
+               volatile u8 *__ptr = (volatile u8 *)(ptr);              \
+               asm volatile(lock "cmpxchgb %2,%1"                      \
+                            : "=a" (__ret), "+m" (*__ptr)              \
+                            : "q" (__new), "0" (__old)                 \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 2:                                                         \
-               asm volatile(lock "cmpxchgw %w1,%2"                     \
-                            : "=a"(__ret)                              \
-                            : "r"(__new), "m"(*__xg(ptr)), "0"(__old)  \
+       {                                                               \
+               volatile u16 *__ptr = (volatile u16 *)(ptr);            \
+               asm volatile(lock "cmpxchgw %2,%1"                      \
+                            : "=a" (__ret), "+m" (*__ptr)              \
+                            : "r" (__new), "0" (__old)                 \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 4:                                                         \
-               asm volatile(lock "cmpxchgl %1,%2"                      \
-                            : "=a"(__ret)                              \
-                            : "r"(__new), "m"(*__xg(ptr)), "0"(__old)  \
+       {                                                               \
+               volatile u32 *__ptr = (volatile u32 *)(ptr);            \
+               asm volatile(lock "cmpxchgl %2,%1"                      \
+                            : "=a" (__ret), "+m" (*__ptr)              \
+                            : "r" (__new), "0" (__old)                 \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        default:                                                        \
                __cmpxchg_wrong_size();                                 \
        }                                                               \
@@ -175,32 +161,28 @@ extern void __cmpxchg_wrong_size(void);
                                               (unsigned long long)(n)))
 #endif
 
-static inline unsigned long long __cmpxchg64(volatile void *ptr,
-                                            unsigned long long old,
-                                            unsigned long long new)
+static inline u64 __cmpxchg64(volatile u64 *ptr, u64 old, u64 new)
 {
-       unsigned long long prev;
-       asm volatile(LOCK_PREFIX "cmpxchg8b %3"
-                    : "=A"(prev)
-                    : "b"((unsigned long)new),
-                      "c"((unsigned long)(new >> 32)),
-                      "m"(*__xg(ptr)),
-                      "0"(old)
+       u64 prev;
+       asm volatile(LOCK_PREFIX "cmpxchg8b %1"
+                    : "=A" (prev),
+                      "+m" (*ptr)
+                    : "b" ((u32)new),
+                      "c" ((u32)(new >> 32)),
+                      "0" (old)
                     : "memory");
        return prev;
 }
 
-static inline unsigned long long __cmpxchg64_local(volatile void *ptr,
-                                                  unsigned long long old,
-                                                  unsigned long long new)
+static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
 {
-       unsigned long long prev;
-       asm volatile("cmpxchg8b %3"
-                    : "=A"(prev)
-                    : "b"((unsigned long)new),
-                      "c"((unsigned long)(new >> 32)),
-                      "m"(*__xg(ptr)),
-                      "0"(old)
+       u64 prev;
+       asm volatile("cmpxchg8b %1"
+                    : "=A" (prev),
+                      "+m" (*ptr)
+                    : "b" ((u32)new),
+                      "c" ((u32)(new >> 32)),
+                      "0" (old)
                     : "memory");
        return prev;
 }
@@ -264,8 +246,6 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
  * to simulate the cmpxchg8b on the 80386 and 80486 CPU.
  */
 
-extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
-
 #define cmpxchg64(ptr, o, n)                                   \
 ({                                                             \
        __typeof__(*(ptr)) __ret;                               \
@@ -283,20 +263,20 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
        __ret; })
 
 
-
-#define cmpxchg64_local(ptr, o, n)                                     \
-({                                                                     \
-       __typeof__(*(ptr)) __ret;                                       \
-       if (likely(boot_cpu_data.x86 > 4))                              \
-               __ret = (__typeof__(*(ptr)))__cmpxchg64_local((ptr),    \
-                               (unsigned long long)(o),                \
-                               (unsigned long long)(n));               \
-       else                                                            \
-               __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr),      \
-                               (unsigned long long)(o),                \
-                               (unsigned long long)(n));               \
-       __ret;                                                          \
-})
+#define cmpxchg64_local(ptr, o, n)                             \
+({                                                             \
+       __typeof__(*(ptr)) __ret;                               \
+       __typeof__(*(ptr)) __old = (o);                         \
+       __typeof__(*(ptr)) __new = (n);                         \
+       alternative_io("call cmpxchg8b_emu",                    \
+                      "cmpxchg8b (%%esi)" ,                    \
+                      X86_FEATURE_CX8,                         \
+                      "=A" (__ret),                            \
+                      "S" ((ptr)), "0" (__old),                \
+                      "b" ((unsigned int)__new),               \
+                      "c" ((unsigned int)(__new>>32))          \
+                      : "memory");                             \
+       __ret; })
 
 #endif
 
index 485ae415faecd5c70705e456e892c1cdf72f7b5f..423ae58aa0203cf2116b8474609c848ba70694c7 100644 (file)
@@ -3,51 +3,60 @@
 
 #include <asm/alternative.h> /* Provides LOCK_PREFIX */
 
-#define __xg(x) ((volatile long *)(x))
-
-static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
+static inline void set_64bit(volatile u64 *ptr, u64 val)
 {
        *ptr = val;
 }
 
-#define _set_64bit set_64bit
-
 extern void __xchg_wrong_size(void);
 extern void __cmpxchg_wrong_size(void);
 
 /*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- *       but generally the primitive is invalid, *ptr is output argument. --ANK
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
+ * Since this is generally used to protect other memory information, we
+ * use "asm volatile" and "memory" clobbers to prevent gcc from moving
+ * information around.
  */
 #define __xchg(x, ptr, size)                                           \
 ({                                                                     \
        __typeof(*(ptr)) __x = (x);                                     \
        switch (size) {                                                 \
        case 1:                                                         \
-               asm volatile("xchgb %b0,%1"                             \
-                            : "=q" (__x)                               \
-                            : "m" (*__xg(ptr)), "0" (__x)              \
+       {                                                               \
+               volatile u8 *__ptr = (volatile u8 *)(ptr);              \
+               asm volatile("xchgb %0,%1"                              \
+                            : "=q" (__x), "+m" (*__ptr)                \
+                            : "0" (__x)                                \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 2:                                                         \
-               asm volatile("xchgw %w0,%1"                             \
-                            : "=r" (__x)                               \
-                            : "m" (*__xg(ptr)), "0" (__x)              \
+       {                                                               \
+               volatile u16 *__ptr = (volatile u16 *)(ptr);            \
+               asm volatile("xchgw %0,%1"                              \
+                            : "=r" (__x), "+m" (*__ptr)                \
+                            : "0" (__x)                                \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 4:                                                         \
-               asm volatile("xchgl %k0,%1"                             \
-                            : "=r" (__x)                               \
-                            : "m" (*__xg(ptr)), "0" (__x)              \
+       {                                                               \
+               volatile u32 *__ptr = (volatile u32 *)(ptr);            \
+               asm volatile("xchgl %0,%1"                              \
+                            : "=r" (__x), "+m" (*__ptr)                \
+                            : "0" (__x)                                \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 8:                                                         \
+       {                                                               \
+               volatile u64 *__ptr = (volatile u64 *)(ptr);            \
                asm volatile("xchgq %0,%1"                              \
-                            : "=r" (__x)                               \
-                            : "m" (*__xg(ptr)), "0" (__x)              \
+                            : "=r" (__x), "+m" (*__ptr)                \
+                            : "0" (__x)                                \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        default:                                                        \
                __xchg_wrong_size();                                    \
        }                                                               \
@@ -71,29 +80,41 @@ extern void __cmpxchg_wrong_size(void);
        __typeof__(*(ptr)) __new = (new);                               \
        switch (size) {                                                 \
        case 1:                                                         \
-               asm volatile(lock "cmpxchgb %b1,%2"                     \
-                            : "=a"(__ret)                              \
-                            : "q"(__new), "m"(*__xg(ptr)), "0"(__old)  \
+       {                                                               \
+               volatile u8 *__ptr = (volatile u8 *)(ptr);              \
+               asm volatile(lock "cmpxchgb %2,%1"                      \
+                            : "=a" (__ret), "+m" (*__ptr)              \
+                            : "q" (__new), "0" (__old)                 \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 2:                                                         \
-               asm volatile(lock "cmpxchgw %w1,%2"                     \
-                            : "=a"(__ret)                              \
-                            : "r"(__new), "m"(*__xg(ptr)), "0"(__old)  \
+       {                                                               \
+               volatile u16 *__ptr = (volatile u16 *)(ptr);            \
+               asm volatile(lock "cmpxchgw %2,%1"                      \
+                            : "=a" (__ret), "+m" (*__ptr)              \
+                            : "r" (__new), "0" (__old)                 \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 4:                                                         \
-               asm volatile(lock "cmpxchgl %k1,%2"                     \
-                            : "=a"(__ret)                              \
-                            : "r"(__new), "m"(*__xg(ptr)), "0"(__old)  \
+       {                                                               \
+               volatile u32 *__ptr = (volatile u32 *)(ptr);            \
+               asm volatile(lock "cmpxchgl %2,%1"                      \
+                            : "=a" (__ret), "+m" (*__ptr)              \
+                            : "r" (__new), "0" (__old)                 \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        case 8:                                                         \
-               asm volatile(lock "cmpxchgq %1,%2"                      \
-                            : "=a"(__ret)                              \
-                            : "r"(__new), "m"(*__xg(ptr)), "0"(__old)  \
+       {                                                               \
+               volatile u64 *__ptr = (volatile u64 *)(ptr);            \
+               asm volatile(lock "cmpxchgq %2,%1"                      \
+                            : "=a" (__ret), "+m" (*__ptr)              \
+                            : "r" (__new), "0" (__old)                 \
                             : "memory");                               \
                break;                                                  \
+       }                                                               \
        default:                                                        \
                __cmpxchg_wrong_size();                                 \
        }                                                               \
index 468145914389942273f2d68c5b9d57b48bf84a8e..781a50b29a4917545e71c3e74bdcbbda7faa383d 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <asm/required-features.h>
 
-#define NCAPINTS             /* N 32-bit words worth of info */
+#define NCAPINTS       10      /* N 32-bit words worth of info */
 
 /*
  * Note: If the comment begins with a quoted string, that string is used
@@ -89,7 +89,7 @@
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* "" Lfence synchronizes RDTSC */
 #define X86_FEATURE_11AP       (3*32+19) /* "" Bad local APIC aka 11AP */
 #define X86_FEATURE_NOPL       (3*32+20) /* The NOPL (0F 1F) instructions */
-#define X86_FEATURE_AMDC1E     (3*32+21) /* AMD C1E detected */
+                                         /* 21 available, was AMD_C1E */
 #define X86_FEATURE_XTOPOLOGY  (3*32+22) /* cpu topology enum extensions */
 #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */
 #define X86_FEATURE_NONSTOP_TSC        (3*32+24) /* TSC does not stop in C states */
 #define X86_FEATURE_XSAVE      (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
 #define X86_FEATURE_OSXSAVE    (4*32+27) /* "" XSAVE enabled in the OS */
 #define X86_FEATURE_AVX                (4*32+28) /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C       (4*32+29) /* 16-bit fp conversions */
+#define X86_FEATURE_RDRND      (4*32+30) /* The RDRAND instruction */
 #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
 
 /*
  * Auxiliary flags: Linux defined - For features scattered in various
- * CPUID levels like 0x6, 0xA etc
+ * CPUID levels like 0x6, 0xA etc, word 7
  */
 #define X86_FEATURE_IDA                (7*32+ 0) /* Intel Dynamic Acceleration */
 #define X86_FEATURE_ARAT       (7*32+ 1) /* Always Running APIC Timer */
 #define X86_FEATURE_CPB                (7*32+ 2) /* AMD Core Performance Boost */
+#define X86_FEATURE_EPB                (7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
+#define X86_FEATURE_XSAVEOPT   (7*32+ 4) /* Optimized Xsave */
+#define X86_FEATURE_PLN                (7*32+ 5) /* Intel Power Limit Notification */
+#define X86_FEATURE_PTS                (7*32+ 6) /* Intel Package Thermal Status */
 
-/* Virtualization flags: Linux defined */
+/* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
 #define X86_FEATURE_VNMI        (8*32+ 1) /* Intel Virtual NMI */
 #define X86_FEATURE_FLEXPRIORITY (8*32+ 2) /* Intel FlexPriority */
 #define X86_FEATURE_EPT         (8*32+ 3) /* Intel Extended Page Table */
 #define X86_FEATURE_VPID        (8*32+ 4) /* Intel Virtual Processor ID */
-#define X86_FEATURE_NPT                (8*32+5)  /* AMD Nested Page Table support */
-#define X86_FEATURE_LBRV       (8*32+6)  /* AMD LBR Virtualization support */
-#define X86_FEATURE_SVML       (8*32+7)  /* "svm_lock" AMD SVM locking MSR */
-#define X86_FEATURE_NRIPS      (8*32+8)  /* "nrip_save" AMD SVM next_rip save */
+#define X86_FEATURE_NPT                (8*32+ 5) /* AMD Nested Page Table support */
+#define X86_FEATURE_LBRV       (8*32+ 6) /* AMD LBR Virtualization support */
+#define X86_FEATURE_SVML       (8*32+ 7) /* "svm_lock" AMD SVM locking MSR */
+#define X86_FEATURE_NRIPS      (8*32+ 8) /* "nrip_save" AMD SVM next_rip save */
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+#define X86_FEATURE_FSGSBASE   (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
@@ -194,7 +203,9 @@ extern const char * const x86_power_flags[32];
           (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||     \
           (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||     \
           (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
-          (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )      \
+          (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ||     \
+          (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) ||     \
+          (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )      \
          ? 1 :                                                         \
         test_cpu_cap(c, bit))
 
@@ -291,7 +302,7 @@ extern const char * const x86_power_flags[32];
  * patch the target code for additional performance.
  *
  */
-static __always_inline __pure bool __static_cpu_has(u8 bit)
+static __always_inline __pure bool __static_cpu_has(u16 bit)
 {
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
                asm goto("1: jmp %l[t_no]\n"
@@ -300,11 +311,11 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
                         _ASM_ALIGN "\n"
                         _ASM_PTR "1b\n"
                         _ASM_PTR "0\n"         /* no replacement */
-                        " .byte %P0\n"         /* feature bit */
+                        " .word %P0\n"         /* feature bit */
                         " .byte 2b - 1b\n"     /* source len */
                         " .byte 0\n"           /* replacement len */
-                        " .byte 0xff + 0 - (2b-1b)\n"  /* padding */
                         ".previous\n"
+                        /* skipping size check since replacement size = 0 */
                         : : "i" (bit) : : t_no);
                return true;
        t_no:
@@ -318,10 +329,12 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
                             _ASM_ALIGN "\n"
                             _ASM_PTR "1b\n"
                             _ASM_PTR "3f\n"
-                            " .byte %P1\n"             /* feature bit */
+                            " .word %P1\n"             /* feature bit */
                             " .byte 2b - 1b\n"         /* source len */
                             " .byte 4f - 3f\n"         /* replacement len */
-                            " .byte 0xff + (4f-3f) - (2b-1b)\n" /* padding */
+                            ".previous\n"
+                            ".section .discard,\"aw\",@progbits\n"
+                            " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
                             ".previous\n"
                             ".section .altinstr_replacement,\"ax\"\n"
                             "3: movb $1,%0\n"
@@ -337,7 +350,7 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
 (                                                              \
        __builtin_constant_p(boot_cpu_has(bit)) ?               \
                boot_cpu_has(bit) :                             \
-       (__builtin_constant_p(bit) && !((bit) & ~0xff)) ?       \
+       __builtin_constant_p(bit) ?                             \
                __static_cpu_has(bit) :                         \
                boot_cpu_has(bit)                               \
 )
index 942255310e6a16391b3e0a5bcbcd59ccafece3d6..528a11e8d3e35f64fea90202d6f196d77d48e708 100644 (file)
@@ -20,10 +20,10 @@ struct arch_hw_breakpoint {
 #include <linux/list.h>
 
 /* Available HW breakpoint length encodings */
+#define X86_BREAKPOINT_LEN_X           0x00
 #define X86_BREAKPOINT_LEN_1           0x40
 #define X86_BREAKPOINT_LEN_2           0x44
 #define X86_BREAKPOINT_LEN_4           0x4c
-#define X86_BREAKPOINT_LEN_EXECUTE     0x40
 
 #ifdef CONFIG_X86_64
 #define X86_BREAKPOINT_LEN_8           0x48
index 70abda7058c81c791946e0e1e78afa963a260a7a..ff2546ce7178e83e105ca9eadc9ddfcc71b636cf 100644 (file)
@@ -45,5 +45,6 @@ extern const struct hypervisor_x86 *x86_hyper;
 /* Recognized hypervisors */
 extern const struct hypervisor_x86 x86_hyper_vmware;
 extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
+extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 
 #endif
index 815c5b2b9f57de3011c4cbfa1aba663a2c0033f1..a73a8d5a5e6963e6fef9b52c28666e913a74160c 100644 (file)
@@ -31,7 +31,6 @@ extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
 extern asmlinkage void math_state_restore(void);
 extern void __math_state_restore(void);
-extern void init_thread_xstate(void);
 extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
 extern user_regset_active_fn fpregs_active, xfpregs_active;
@@ -58,11 +57,25 @@ extern int restore_i387_xstate_ia32(void __user *buf);
 
 #define X87_FSW_ES (1 << 7)    /* Exception Summary */
 
+static __always_inline __pure bool use_xsaveopt(void)
+{
+       return static_cpu_has(X86_FEATURE_XSAVEOPT);
+}
+
 static __always_inline __pure bool use_xsave(void)
 {
        return static_cpu_has(X86_FEATURE_XSAVE);
 }
 
+extern void __sanitize_i387_state(struct task_struct *);
+
+static inline void sanitize_i387_state(struct task_struct *tsk)
+{
+       if (!use_xsaveopt())
+               return;
+       __sanitize_i387_state(tsk);
+}
+
 #ifdef CONFIG_X86_64
 
 /* Ignore delayed exceptions from user space */
@@ -127,6 +140,15 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
 {
        int err;
 
+       /*
+        * Clear the bytes not touched by the fxsave and reserved
+        * for the SW usage.
+        */
+       err = __clear_user(&fx->sw_reserved,
+                          sizeof(struct _fpx_sw_bytes));
+       if (unlikely(err))
+               return -EFAULT;
+
        asm volatile("1:  rex64/fxsave (%[fx])\n\t"
                     "2:\n"
                     ".section .fixup,\"ax\"\n"
index 8767d99c4f64d9a7fc70a17d338ffe4770a5e969..e2ca3009255706910d1ddc407232f4d09f011f24 100644 (file)
  */
 #define MCE_SELF_VECTOR                        0xeb
 
+/* Xen vector callback to receive events in a HVM domain */
+#define XEN_HVM_EVTCHN_CALLBACK                0xe9
+
 #define NR_VECTORS                      256
 
 #define FPU_IRQ                                  13
index 006da3687cdcccfc44adff4726edbef9230088d9..396f5b5fc4d714e4babdb916565731264a312ec8 100644 (file)
@@ -39,9 +39,11 @@ enum regnames {
        GDB_FS,                 /* 14 */
        GDB_GS,                 /* 15 */
 };
+#define GDB_ORIG_AX            41
+#define DBG_MAX_REG_NUM                16
 #define NUMREGBYTES            ((GDB_GS+1)*4)
 #else /* ! CONFIG_X86_32 */
-enum regnames64 {
+enum regnames {
        GDB_AX,                 /* 0 */
        GDB_BX,                 /* 1 */
        GDB_CX,                 /* 2 */
@@ -59,15 +61,15 @@ enum regnames64 {
        GDB_R14,                /* 14 */
        GDB_R15,                /* 15 */
        GDB_PC,                 /* 16 */
+       GDB_PS,                 /* 17 */
+       GDB_CS,                 /* 18 */
+       GDB_SS,                 /* 19 */
 };
-
-enum regnames32 {
-       GDB_PS = 34,
-       GDB_CS,
-       GDB_SS,
-};
-#define NUMREGBYTES            ((GDB_SS+1)*4)
-#endif /* CONFIG_X86_32 */
+#define GDB_ORIG_AX            57
+#define DBG_MAX_REG_NUM                20
+/* 17 64 bit regs and 3 32 bit regs */
+#define NUMREGBYTES            ((17 * 8) + (3 * 4))
+#endif /* ! CONFIG_X86_32 */
 
 static inline void arch_kgdb_breakpoint(void)
 {
diff --git a/arch/x86/include/asm/local64.h b/arch/x86/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index f32a4301c4d4559157e1ac72f79a239025ccc1e0..c62c13cb9788f0a1ea664fed073ebbca1ed02f15 100644 (file)
 #define MCM_ADDR_MEM    3      /* memory address */
 #define MCM_ADDR_GENERIC 7     /* generic */
 
+/* CTL2 register defines */
+#define MCI_CTL2_CMCI_EN               (1ULL << 30)
+#define MCI_CTL2_CMCI_THRESHOLD_MASK   0x7fffULL
+
 #define MCJ_CTX_MASK           3
 #define MCJ_CTX(flags)         ((flags) & MCJ_CTX_MASK)
 #define MCJ_CTX_RANDOM         0    /* inject context: random */
index 451d30e7f62defa446a864fb2ccd67e454697180..16350740edf600436d4990fec8a5fc9ce62abafc 100644 (file)
 extern int pci_mrst_init(void);
 int __init sfi_parse_mrtc(struct sfi_table_header *table);
 
+/*
+ * Medfield is the follow-up of Moorestown, it combines two chip solution into
+ * one. Other than that it also added always-on and constant tsc and lapic
+ * timers. Medfield is the platform name, and the chip name is called Penwell
+ * we treat Medfield/Penwell as a variant of Moorestown. Penwell can be
+ * identified via MSRs.
+ */
+enum mrst_cpu_type {
+       MRST_CPU_CHIP_LINCROFT = 1,
+       MRST_CPU_CHIP_PENWELL,
+};
+
+extern enum mrst_cpu_type __mrst_cpu_chip;
+static enum mrst_cpu_type mrst_identify_cpu(void)
+{
+       return __mrst_cpu_chip;
+}
+
+enum mrst_timer_options {
+       MRST_TIMER_DEFAULT,
+       MRST_TIMER_APBT_ONLY,
+       MRST_TIMER_LAPIC_APBT,
+};
+
+extern enum mrst_timer_options mrst_timer_options;
+
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX   8
 
index 509a42187dc25db56aaabd5bcb5652235ec27e8c..986f7790fdb2880c4f9efda864a489a0edb83892 100644 (file)
@@ -96,9 +96,6 @@
 #define MSR_IA32_MC0_CTL2              0x00000280
 #define MSR_IA32_MCx_CTL2(x)           (MSR_IA32_MC0_CTL2 + (x))
 
-#define CMCI_EN                        (1ULL << 30)
-#define CMCI_THRESHOLD_MASK            0xffffULL
-
 #define MSR_P6_PERFCTR0                        0x000000c1
 #define MSR_P6_PERFCTR1                        0x000000c2
 #define MSR_P6_EVNTSEL0                        0x00000186
 #define MSR_K7_FID_VID_STATUS          0xc0010042
 
 /* K6 MSRs */
-#define MSR_K6_EFER                    0xc0000080
-#define MSR_K6_STAR                    0xc0000081
 #define MSR_K6_WHCR                    0xc0000082
 #define MSR_K6_UWCCR                   0xc0000085
 #define MSR_K6_EPMR                    0xc0000086
 #define MSR_IA32_THERM_CONTROL         0x0000019a
 #define MSR_IA32_THERM_INTERRUPT       0x0000019b
 
-#define THERM_INT_LOW_ENABLE           (1 << 0)
-#define THERM_INT_HIGH_ENABLE          (1 << 1)
+#define THERM_INT_HIGH_ENABLE          (1 << 0)
+#define THERM_INT_LOW_ENABLE           (1 << 1)
+#define THERM_INT_PLN_ENABLE           (1 << 24)
 
 #define MSR_IA32_THERM_STATUS          0x0000019c
 
 #define THERM_STATUS_PROCHOT           (1 << 0)
+#define THERM_STATUS_POWER_LIMIT       (1 << 10)
 
 #define MSR_THERM2_CTL                 0x0000019d
 
 
 #define MSR_IA32_TEMPERATURE_TARGET    0x000001a2
 
+#define MSR_IA32_ENERGY_PERF_BIAS      0x000001b0
+
+#define MSR_IA32_PACKAGE_THERM_STATUS          0x000001b1
+
+#define PACKAGE_THERM_STATUS_PROCHOT           (1 << 0)
+#define PACKAGE_THERM_STATUS_POWER_LIMIT       (1 << 10)
+
+#define MSR_IA32_PACKAGE_THERM_INTERRUPT       0x000001b2
+
+#define PACKAGE_THERM_INT_HIGH_ENABLE          (1 << 0)
+#define PACKAGE_THERM_INT_LOW_ENABLE           (1 << 1)
+#define PACKAGE_THERM_INT_PLN_ENABLE           (1 << 24)
+
 /* MISC_ENABLE bits: architectural */
 #define MSR_IA32_MISC_ENABLE_FAST_STRING       (1ULL << 0)
 #define MSR_IA32_MISC_ENABLE_TCC               (1ULL << 1)
index c5bc4c2d33f56399f98b55975abc23b3d694ea85..084ef95274cd78ceb51b1ea7a208a7a5e486199a 100644 (file)
@@ -148,8 +148,8 @@ static inline unsigned long long native_read_pmc(int counter)
 #define rdmsr(msr, val1, val2)                                 \
 do {                                                           \
        u64 __val = native_read_msr((msr));                     \
-       (val1) = (u32)__val;                                    \
-       (val2) = (u32)(__val >> 32);                            \
+       (void)((val1) = (u32)__val);                            \
+       (void)((val2) = (u32)(__val >> 32));                    \
 } while (0)
 
 static inline void wrmsr(unsigned msr, unsigned low, unsigned high)
index 93da9c3f334120b64165a8124b79b09e71365bf4..932f0f86b4b76252e6e6434ab9c15d81c3b17004 100644 (file)
@@ -17,7 +17,9 @@ int do_nmi_callback(struct pt_regs *regs, int cpu);
 
 extern void die_nmi(char *str, struct pt_regs *regs, int do_panic);
 extern int check_nmi_watchdog(void);
+#if !defined(CONFIG_LOCKUP_DETECTOR)
 extern int nmi_watchdog_enabled;
+#endif
 extern int avail_to_resrv_perfctr_nmi_bit(unsigned int);
 extern int reserve_perfctr_nmi(unsigned int);
 extern void release_perfctr_nmi(unsigned int);
diff --git a/arch/x86/include/asm/olpc_ofw.h b/arch/x86/include/asm/olpc_ofw.h
new file mode 100644 (file)
index 0000000..08fde47
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _ASM_X86_OLPC_OFW_H
+#define _ASM_X86_OLPC_OFW_H
+
+/* index into the page table containing the entry OFW occupies */
+#define OLPC_OFW_PDE_NR 1022
+
+#define OLPC_OFW_SIG 0x2057464F        /* aka "OFW " */
+
+#ifdef CONFIG_OLPC_OPENFIRMWARE
+
+/* run an OFW command by calling into the firmware */
+#define olpc_ofw(name, args, res) \
+       __olpc_ofw((name), ARRAY_SIZE(args), args, ARRAY_SIZE(res), res)
+
+extern int __olpc_ofw(const char *name, int nr_args, const void **args, int nr_res,
+               void **res);
+
+/* determine whether OFW is available and lives in the proper memory */
+extern void olpc_ofw_detect(void);
+
+/* install OFW's pde permanently into the kernel's pgtable */
+extern void setup_olpc_ofw_pgd(void);
+
+#else /* !CONFIG_OLPC_OPENFIRMWARE */
+
+static inline void olpc_ofw_detect(void) { }
+static inline void setup_olpc_ofw_pgd(void) { }
+
+#endif /* !CONFIG_OLPC_OPENFIRMWARE */
+
+#endif /* _ASM_X86_OLPC_OFW_H */
index cd2a31dc5fb8e4a956c8c34125534540d51b08f4..49c7219826f918d10dae4f08d4c474988706a6ae 100644 (file)
@@ -30,6 +30,7 @@
 #define PCI_HAS_IO_ECS         0x40000
 #define PCI_NOASSIGN_ROMS      0x80000
 #define PCI_ROOT_NO_CRS                0x100000
+#define PCI_NOASSIGN_BARS      0x200000
 
 extern unsigned int pci_probe;
 extern unsigned long pirq_table_addr;
index 254883d0c7e088424ed983154613b4ad889435e1..6e742cc4251b49b2474830107da0378951c874be 100644 (file)
@@ -68,8 +68,9 @@ union cpuid10_eax {
 
 union cpuid10_edx {
        struct {
-               unsigned int num_counters_fixed:4;
-               unsigned int reserved:28;
+               unsigned int num_counters_fixed:5;
+               unsigned int bit_width_fixed:8;
+               unsigned int reserved:19;
        } split;
        unsigned int full;
 };
@@ -140,6 +141,19 @@ extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
 extern unsigned long perf_misc_flags(struct pt_regs *regs);
 #define perf_misc_flags(regs)  perf_misc_flags(regs)
 
+#include <asm/stacktrace.h>
+
+/*
+ * We abuse bit 3 from flags to pass exact information, see perf_misc_flags
+ * and the comment with PERF_EFLAGS_EXACT.
+ */
+#define perf_arch_fetch_caller_regs(regs, __ip)                {       \
+       (regs)->ip = (__ip);                                    \
+       (regs)->bp = caller_frame_pointer();                    \
+       (regs)->cs = __KERNEL_CS;                               \
+       regs->flags = 0;                                        \
+}
+
 #else
 static inline void init_hw_perf_events(void)           { }
 static inline void perf_events_lapic_init(void)        { }
index 64a8ebff06fcef47dc36301e038ea2d63acad27b..def500776b16a3b63d34da569021722e4d82f18a 100644 (file)
@@ -19,7 +19,6 @@
 #define ARCH_P4_RESERVED_ESCR  (2) /* IQ_ESCR(0,1) not always present */
 #define ARCH_P4_MAX_ESCR       (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR)
 #define ARCH_P4_MAX_CCCR       (18)
-#define ARCH_P4_MAX_COUNTER    (ARCH_P4_MAX_CCCR / 2)
 
 #define P4_ESCR_EVENT_MASK     0x7e000000U
 #define P4_ESCR_EVENT_SHIFT    25
 #define P4_CCCR_THRESHOLD(v)           ((v) << P4_CCCR_THRESHOLD_SHIFT)
 #define P4_CCCR_ESEL(v)                        ((v) << P4_CCCR_ESCR_SELECT_SHIFT)
 
-/* Custom bits in reerved CCCR area */
-#define P4_CCCR_CACHE_OPS_MASK         0x0000003fU
-
-
 /* Non HT mask */
 #define P4_CCCR_MASK                           \
        (P4_CCCR_OVF                    |       \
  * ESCR and CCCR but rather an only packed value should
  * be unpacked and written to a proper addresses
  *
- * the base idea is to pack as much info as
- * possible
+ * the base idea is to pack as much info as possible
  */
 #define p4_config_pack_escr(v)         (((u64)(v)) << 32)
 #define p4_config_pack_cccr(v)         (((u64)(v)) & 0xffffffffULL)
                t;                                      \
        })
 
-#define p4_config_unpack_cache_event(v)        (((u64)(v)) & P4_CCCR_CACHE_OPS_MASK)
-
 #define P4_CONFIG_HT_SHIFT             63
 #define P4_CONFIG_HT                   (1ULL << P4_CONFIG_HT_SHIFT)
 
@@ -214,6 +206,12 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr)
        return escr;
 }
 
+/*
+ * This are the events which should be used in "Event Select"
+ * field of ESCR register, they are like unique keys which allow
+ * the kernel to determinate which CCCR and COUNTER should be
+ * used to track an event
+ */
 enum P4_EVENTS {
        P4_EVENT_TC_DELIVER_MODE,
        P4_EVENT_BPU_FETCH_REQUEST,
@@ -561,7 +559,7 @@ enum P4_EVENT_OPCODES {
  * a caller should use P4_ESCR_EMASK_NAME helper to
  * pick the EventMask needed, for example
  *
- *     P4_ESCR_EMASK_NAME(P4_EVENT_TC_DELIVER_MODE, DD)
+ *     P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD)
  */
 enum P4_ESCR_EMASKS {
        P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DD, 0),
@@ -753,43 +751,50 @@ enum P4_ESCR_EMASKS {
        P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, BOGUS, 1),
 };
 
-/* P4 PEBS: stale for a while */
-#define P4_PEBS_METRIC_MASK    0x00001fffU
-#define P4_PEBS_UOB_TAG                0x01000000U
-#define P4_PEBS_ENABLE         0x02000000U
-
-/* Replay metrics for MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT */
-#define P4_PEBS__1stl_cache_load_miss_retired  0x3000001
-#define P4_PEBS__2ndl_cache_load_miss_retired  0x3000002
-#define P4_PEBS__dtlb_load_miss_retired                0x3000004
-#define P4_PEBS__dtlb_store_miss_retired       0x3000004
-#define P4_PEBS__dtlb_all_miss_retired         0x3000004
-#define P4_PEBS__tagged_mispred_branch         0x3018000
-#define P4_PEBS__mob_load_replay_retired       0x3000200
-#define P4_PEBS__split_load_retired            0x3000400
-#define P4_PEBS__split_store_retired           0x3000400
-
-#define P4_VERT__1stl_cache_load_miss_retired  0x0000001
-#define P4_VERT__2ndl_cache_load_miss_retired  0x0000001
-#define P4_VERT__dtlb_load_miss_retired                0x0000001
-#define P4_VERT__dtlb_store_miss_retired       0x0000002
-#define P4_VERT__dtlb_all_miss_retired         0x0000003
-#define P4_VERT__tagged_mispred_branch         0x0000010
-#define P4_VERT__mob_load_replay_retired       0x0000001
-#define P4_VERT__split_load_retired            0x0000001
-#define P4_VERT__split_store_retired           0x0000002
-
-enum P4_CACHE_EVENTS {
-       P4_CACHE__NONE,
-
-       P4_CACHE__1stl_cache_load_miss_retired,
-       P4_CACHE__2ndl_cache_load_miss_retired,
-       P4_CACHE__dtlb_load_miss_retired,
-       P4_CACHE__dtlb_store_miss_retired,
-       P4_CACHE__itlb_reference_hit,
-       P4_CACHE__itlb_reference_miss,
-
-       P4_CACHE__MAX
+/*
+ * P4 PEBS specifics (Replay Event only)
+ *
+ * Format (bits):
+ *   0-6: metric from P4_PEBS_METRIC enum
+ *    7 : reserved
+ *    8 : reserved
+ * 9-11 : reserved
+ *
+ * Note we have UOP and PEBS bits reserved for now
+ * just in case if we will need them once
+ */
+#define P4_PEBS_CONFIG_ENABLE          (1 << 7)
+#define P4_PEBS_CONFIG_UOP_TAG         (1 << 8)
+#define P4_PEBS_CONFIG_METRIC_MASK     0x3f
+#define P4_PEBS_CONFIG_MASK            0xff
+
+/*
+ * mem: Only counters MSR_IQ_COUNTER4 (16) and
+ * MSR_IQ_COUNTER5 (17) are allowed for PEBS sampling
+ */
+#define P4_PEBS_ENABLE                 0x02000000U
+#define P4_PEBS_ENABLE_UOP_TAG         0x01000000U
+
+#define p4_config_unpack_metric(v)     (((u64)(v)) & P4_PEBS_CONFIG_METRIC_MASK)
+#define p4_config_unpack_pebs(v)       (((u64)(v)) & P4_PEBS_CONFIG_MASK)
+
+#define p4_config_pebs_has(v, mask)    (p4_config_unpack_pebs(v) & (mask))
+
+enum P4_PEBS_METRIC {
+       P4_PEBS_METRIC__none,
+
+       P4_PEBS_METRIC__1stl_cache_load_miss_retired,
+       P4_PEBS_METRIC__2ndl_cache_load_miss_retired,
+       P4_PEBS_METRIC__dtlb_load_miss_retired,
+       P4_PEBS_METRIC__dtlb_store_miss_retired,
+       P4_PEBS_METRIC__dtlb_all_miss_retired,
+       P4_PEBS_METRIC__tagged_mispred_branch,
+       P4_PEBS_METRIC__mob_load_replay_retired,
+       P4_PEBS_METRIC__split_load_retired,
+       P4_PEBS_METRIC__split_store_retired,
+
+       P4_PEBS_METRIC__max
 };
 
 #endif /* PERF_EVENT_P4_H */
+
index 7e5c6a60b8ee190ab85b8ed88503ec2436197ea9..325b7bdbebaa9494b3e3e4c08a314aed72f88dc4 100644 (file)
@@ -762,6 +762,7 @@ extern void init_c1e_mask(void);
 extern unsigned long           boot_option_idle_override;
 extern unsigned long           idle_halt;
 extern unsigned long           idle_nomwait;
+extern bool                    c1e_detected;
 
 /*
  * on systems with caches, caches must be flashed as the absolute
@@ -1025,4 +1026,24 @@ unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
        return ratio;
 }
 
+/*
+ * AMD errata checking
+ */
+#ifdef CONFIG_CPU_SUP_AMD
+extern const int amd_erratum_383[];
+extern const int amd_erratum_400[];
+extern bool cpu_has_amd_erratum(const int *);
+
+#define AMD_LEGACY_ERRATUM(...)                { -1, __VA_ARGS__, 0 }
+#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 }
+#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
+       ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
+#define AMD_MODEL_RANGE_FAMILY(range)  (((range) >> 24) & 0xff)
+#define AMD_MODEL_RANGE_START(range)   (((range) >> 12) & 0xfff)
+#define AMD_MODEL_RANGE_END(range)     ((range) & 0xfff)
+
+#else
+#define cpu_has_amd_erratum(x) (false)
+#endif /* CONFIG_CPU_SUP_AMD */
+
 #endif /* _ASM_X86_PROCESSOR_H */
index 64cf2d24fad1c2605c16b528cc10e8e37c9bc77c..6c7fc25f2c34a0eab822c2d6ab17c3b1cacbf0a0 100644 (file)
@@ -84,5 +84,7 @@
 #define REQUIRED_MASK5 0
 #define REQUIRED_MASK6 0
 #define REQUIRED_MASK7 0
+#define REQUIRED_MASK8 0
+#define REQUIRED_MASK9 0
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
index 606ede126972e568b992268da3df6f64b7e98480..d1e41b0f9b60b37eb061caec5661fc6fb9e1cbbf 100644 (file)
@@ -118,7 +118,7 @@ static inline void __down_read(struct rw_semaphore *sem)
 {
        asm volatile("# beginning down_read\n\t"
                     LOCK_PREFIX _ASM_INC "(%1)\n\t"
-                    /* adds 0x00000001, returns the old value */
+                    /* adds 0x00000001 */
                     "  jns        1f\n"
                     "  call call_rwsem_down_read_failed\n"
                     "1:\n\t"
@@ -156,11 +156,9 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
 static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
 {
        rwsem_count_t tmp;
-
-       tmp = RWSEM_ACTIVE_WRITE_BIAS;
        asm volatile("# beginning down_write\n\t"
                     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
-                    /* subtract 0x0000ffff, returns the old value */
+                    /* adds 0xffff0001, returns the old value */
                     "  test      %1,%1\n\t"
                     /* was the count 0 before? */
                     "  jz        1f\n"
@@ -168,7 +166,7 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
                     "1:\n"
                     "# ending down_write"
                     : "+m" (sem->count), "=d" (tmp)
-                    : "a" (sem), "1" (tmp)
+                    : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS)
                     : "memory", "cc");
 }
 
@@ -195,16 +193,16 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
  */
 static inline void __up_read(struct rw_semaphore *sem)
 {
-       rwsem_count_t tmp = -RWSEM_ACTIVE_READ_BIAS;
+       rwsem_count_t tmp;
        asm volatile("# beginning __up_read\n\t"
                     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
                     /* subtracts 1, returns the old value */
                     "  jns        1f\n\t"
-                    "  call call_rwsem_wake\n"
+                    "  call call_rwsem_wake\n" /* expects old value in %edx */
                     "1:\n"
                     "# ending __up_read\n"
                     : "+m" (sem->count), "=d" (tmp)
-                    : "a" (sem), "1" (tmp)
+                    : "a" (sem), "1" (-RWSEM_ACTIVE_READ_BIAS)
                     : "memory", "cc");
 }
 
@@ -216,10 +214,9 @@ static inline void __up_write(struct rw_semaphore *sem)
        rwsem_count_t tmp;
        asm volatile("# beginning __up_write\n\t"
                     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
-                    /* tries to transition
-                       0xffff0001 -> 0x00000000 */
-                    "  jz       1f\n"
-                    "  call call_rwsem_wake\n"
+                    /* subtracts 0xffff0001, returns the old value */
+                    "  jns        1f\n\t"
+                    "  call call_rwsem_wake\n" /* expects old value in %edx */
                     "1:\n\t"
                     "# ending __up_write\n"
                     : "+m" (sem->count), "=d" (tmp)
index 86b1506f4179f87e4efcf5faada578ec14e0aa3f..ef292c792d742cb35b1a48ac7f18f97a6546860c 100644 (file)
@@ -82,7 +82,7 @@ void *extend_brk(size_t size, size_t align);
  * executable.)
  */
 #define RESERVE_BRK(name,sz)                                           \
-       static void __section(.discard) __used                          \
+       static void __section(.discard.text) __used                     \
        __brk_reservation_fn_##name##__(void) {                         \
                asm volatile (                                          \
                        ".pushsection .brk_reservation,\"aw\",@nobits;" \
index 4dab78edbad9ff7315a8c30aebeb734f4e87da1e..2b16a2ad23dc6b9647028c0808f8f45b094e74ac 100644 (file)
@@ -1,6 +1,13 @@
+/*
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
+ */
+
 #ifndef _ASM_X86_STACKTRACE_H
 #define _ASM_X86_STACKTRACE_H
 
+#include <linux/uaccess.h>
+
 extern int kstack_depth_to_print;
 
 struct thread_info;
@@ -42,4 +49,46 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp,
                const struct stacktrace_ops *ops, void *data);
 
+#ifdef CONFIG_X86_32
+#define STACKSLOTS_PER_LINE 8
+#define get_bp(bp) asm("movl %%ebp, %0" : "=r" (bp) :)
+#else
+#define STACKSLOTS_PER_LINE 4
+#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
+#endif
+
+extern void
+show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+               unsigned long *stack, unsigned long bp, char *log_lvl);
+
+extern void
+show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+               unsigned long *sp, unsigned long bp, char *log_lvl);
+
+extern unsigned int code_bytes;
+
+/* The form of the top of the frame on the stack */
+struct stack_frame {
+       struct stack_frame *next_frame;
+       unsigned long return_address;
+};
+
+struct stack_frame_ia32 {
+    u32 next_frame;
+    u32 return_address;
+};
+
+static inline unsigned long caller_frame_pointer(void)
+{
+       struct stack_frame *frame;
+
+       get_bp(frame);
+
+#ifdef CONFIG_FRAME_POINTER
+       frame = frame->next_frame;
+#endif
+
+       return (unsigned long)frame;
+}
+
 #endif /* _ASM_X86_STACKTRACE_H */
index 9c371e4a9fa6e122a25b6cf745fde11b027ba313..7fda040a76cd7cae4e9caa3bbc9cf37661694993 100644 (file)
@@ -417,6 +417,12 @@ HYPERVISOR_nmi_op(unsigned long op, unsigned long arg)
        return _hypercall2(int, nmi_op, op, arg);
 }
 
+static inline unsigned long __must_check
+HYPERVISOR_hvm_op(int op, void *arg)
+{
+       return _hypercall2(unsigned long, hvm_op, op, arg);
+}
+
 static inline void
 MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
 {
index 32c36668fa7bc1b6b3cc5fd31b1ddbdf3d0a9fa5..c6ce2452f10ce2dba165593d3492a9eb5056f4d3 100644 (file)
@@ -3,7 +3,8 @@
 
 #include <linux/types.h>
 #include <asm/processor.h>
-#include <asm/i387.h>
+
+#define XSTATE_CPUID           0x0000000d
 
 #define XSTATE_FP      0x1
 #define XSTATE_SSE     0x2
 
 extern unsigned int xstate_size;
 extern u64 pcntxt_mask;
-extern struct xsave_struct *init_xstate_buf;
 extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
 
-extern void xsave_cntxt_init(void);
 extern void xsave_init(void);
 extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
 extern int init_fpu(struct task_struct *child);
@@ -65,6 +64,16 @@ static inline int fpu_xrstor_checking(struct fpu *fpu)
 static inline int xsave_user(struct xsave_struct __user *buf)
 {
        int err;
+
+       /*
+        * Clear the xsave header first, so that reserved fields are
+        * initialized to zero.
+        */
+       err = __clear_user(&buf->xsave_hdr,
+                          sizeof(struct xsave_hdr_struct));
+       if (unlikely(err))
+               return -EFAULT;
+
        __asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x27\n"
                             "2:\n"
                             ".section .fixup,\"ax\"\n"
@@ -117,12 +126,25 @@ static inline void xrstor_state(struct xsave_struct *fx, u64 mask)
                     :   "memory");
 }
 
+static inline void xsave_state(struct xsave_struct *fx, u64 mask)
+{
+       u32 lmask = mask;
+       u32 hmask = mask >> 32;
+
+       asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x27\n\t"
+                    : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask)
+                    :   "memory");
+}
+
 static inline void fpu_xsave(struct fpu *fpu)
 {
        /* This, however, we can work around by forcing the compiler to select
           an addressing mode that doesn't require extended registers. */
-       __asm__ __volatile__(".byte " REX_PREFIX "0x0f,0xae,0x27"
-                            : : "D" (&(fpu->state->xsave)),
-                                "a" (-1), "d"(-1) : "memory");
+       alternative_input(
+               ".byte " REX_PREFIX "0x0f,0xae,0x27",
+               ".byte " REX_PREFIX "0x0f,0xae,0x37",
+               X86_FEATURE_XSAVEOPT,
+               [fx] "D" (&fpu->state->xsave), "a" (-1), "d" (-1) :
+               "memory");
 }
 #endif
index e77b220837214cef81deff278e2f79ef1ed202a7..0925676266bdbc9cbcf03811916b9f8b9b9e627e 100644 (file)
@@ -104,6 +104,7 @@ obj-$(CONFIG_SCx200)                += scx200.o
 scx200-y                       += scx200_32.o
 
 obj-$(CONFIG_OLPC)             += olpc.o
+obj-$(CONFIG_OLPC_OPENFIRMWARE)        += olpc_ofw.o
 obj-$(CONFIG_X86_MRST)         += mrst.o
 
 microcode-y                            := microcode_core.o
index 580b4e29601005abf25adc6dfc011ce6fb6ef1bd..28595d6df47c112668d9bf085f1ec35690f8b7b7 100644 (file)
@@ -104,7 +104,7 @@ _start:
        movl    %eax, %ecx
        orl     %edx, %ecx
        jz      1f
-       movl    $0xc0000080, %ecx
+       movl    $MSR_EFER, %ecx
        wrmsr
 1:
 
index 70237732a6c7c5f62f941d5df0594f7386ca6a10..f65ab8b014c4f42421d77200243c39c7fd252165 100644 (file)
@@ -214,6 +214,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
                u8 *instr = a->instr;
                BUG_ON(a->replacementlen > a->instrlen);
                BUG_ON(a->instrlen > sizeof(insnbuf));
+               BUG_ON(a->cpuid >= NCAPINTS*32);
                if (!boot_cpu_has(a->cpuid))
                        continue;
 #ifdef CONFIG_X86_64
index 0d20286d78c6f6b6b4307ef35dc5001cccc480a9..fa044e1e30a2ed081175480dccec352a7e381392 100644 (file)
@@ -2572,6 +2572,11 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
 static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
                                    unsigned long cap)
 {
+       switch (cap) {
+       case IOMMU_CAP_CACHE_COHERENCY:
+               return 1;
+       }
+
        return 0;
 }
 
@@ -2609,8 +2614,7 @@ int __init amd_iommu_init_passthrough(void)
 
        pt_domain->mode |= PAGE_MODE_NONE;
 
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-
+       for_each_pci_dev(dev) {
                if (!check_device(&dev->dev))
                        continue;
 
index a35347501d36883b802c6471ed466b4e271ce8c8..8dd77800ff5d7b444742ae02cc5168ccf8855fcd 100644 (file)
 
 #include <asm/fixmap.h>
 #include <asm/apb_timer.h>
+#include <asm/mrst.h>
 
 #define APBT_MASK                      CLOCKSOURCE_MASK(32)
 #define APBT_SHIFT                     22
-#define APBT_CLOCKEVENT_RATING         150
+#define APBT_CLOCKEVENT_RATING         110
 #define APBT_CLOCKSOURCE_RATING                250
 #define APBT_MIN_DELTA_USEC            200
 
@@ -83,8 +84,6 @@ struct apbt_dev {
        char name[10];
 };
 
-int disable_apbt_percpu __cpuinitdata;
-
 static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);
 
 #ifdef CONFIG_SMP
@@ -194,29 +193,6 @@ static struct clock_event_device apbt_clockevent = {
        .rating         = APBT_CLOCKEVENT_RATING,
 };
 
-/*
- * if user does not want to use per CPU apb timer, just give it a lower rating
- * than local apic timer and skip the late per cpu timer init.
- */
-static inline int __init setup_x86_mrst_timer(char *arg)
-{
-       if (!arg)
-               return -EINVAL;
-
-       if (strcmp("apbt_only", arg) == 0)
-               disable_apbt_percpu = 0;
-       else if (strcmp("lapic_and_apbt", arg) == 0)
-               disable_apbt_percpu = 1;
-       else {
-               pr_warning("X86 MRST timer option %s not recognised"
-                          " use x86_mrst_timer=apbt_only or lapic_and_apbt\n",
-                          arg);
-               return -EINVAL;
-       }
-       return 0;
-}
-__setup("x86_mrst_timer=", setup_x86_mrst_timer);
-
 /*
  * start count down from 0xffff_ffff. this is done by toggling the enable bit
  * then load initial load count to ~0.
@@ -335,7 +311,7 @@ static int __init apbt_clockevent_register(void)
        adev->num = smp_processor_id();
        memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device));
 
-       if (disable_apbt_percpu) {
+       if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) {
                apbt_clockevent.rating = APBT_CLOCKEVENT_RATING - 100;
                global_clock_event = &adev->evt;
                printk(KERN_DEBUG "%s clockevent registered as global\n",
@@ -429,7 +405,8 @@ static int apbt_cpuhp_notify(struct notifier_block *n,
 
 static __init int apbt_late_init(void)
 {
-       if (disable_apbt_percpu || !apb_timer_block_enabled)
+       if (mrst_timer_options == MRST_TIMER_LAPIC_APBT ||
+               !apb_timer_block_enabled)
                return 0;
        /* This notifier should be called after workqueue is ready */
        hotcpu_notifier(apbt_cpuhp_notify, -20);
@@ -450,6 +427,8 @@ static void apbt_set_mode(enum clock_event_mode mode,
        int timer_num;
        struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
 
+       BUG_ON(!apbt_virt_address);
+
        timer_num = adev->num;
        pr_debug("%s CPU %d timer %d mode=%d\n",
                 __func__, first_cpu(*evt->cpumask), timer_num, mode);
@@ -676,7 +655,7 @@ void __init apbt_time_init(void)
        }
 #ifdef CONFIG_SMP
        /* kernel cmdline disable apb timer, so we will use lapic timers */
-       if (disable_apbt_percpu) {
+       if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) {
                printk(KERN_INFO "apbt: disabled per cpu timer\n");
                return;
        }
index b5d8b0bcf23588a413d5766d160e24ac6c811441..a2e0caf26e172c8f7b18231e4f4a072161ed66fe 100644 (file)
@@ -280,7 +280,7 @@ void __init early_gart_iommu_check(void)
         * or BIOS forget to put that in reserved.
         * try to update e820 to make that region as reserved.
         */
-       u32 agp_aper_base = 0, agp_aper_order = 0;
+       u32 agp_aper_order = 0;
        int i, fix, slot, valid_agp = 0;
        u32 ctl;
        u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
@@ -291,7 +291,7 @@ void __init early_gart_iommu_check(void)
                return;
 
        /* This is mostly duplicate of iommu_hole_init */
-       agp_aper_base = search_agp_bridge(&agp_aper_order, &valid_agp);
+       search_agp_bridge(&agp_aper_order, &valid_agp);
 
        fix = 0;
        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
index 565c1bfc507d41b8387eea7cc7e6ffd22f3f114a..910f20b457c464d34f1e9874269d652ea0da325e 100644 (file)
@@ -2,7 +2,12 @@
 # Makefile for local APIC drivers and for the IO-APIC code
 #
 
-obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o apic_noop.o probe_$(BITS).o ipi.o nmi.o
+obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o apic_noop.o probe_$(BITS).o ipi.o
+ifneq ($(CONFIG_HARDLOCKUP_DETECTOR),y)
+obj-$(CONFIG_X86_LOCAL_APIC)   += nmi.o
+endif
+obj-$(CONFIG_HARDLOCKUP_DETECTOR)      += hw_nmi.o
+
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o
 obj-$(CONFIG_SMP)              += ipi.o
 
index 425e53a87febe983ab07533d17d4d10e4f24a726..8593582d8022bed84972fe6bde245035778d7c80 100644 (file)
@@ -129,7 +129,6 @@ int                                 es7000_plat;
  * GSI override for ES7000 platforms.
  */
 
-static unsigned int                    base;
 
 static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c
new file mode 100644 (file)
index 0000000..cefd694
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  HW NMI watchdog support
+ *
+ *  started by Don Zickus, Copyright (C) 2010 Red Hat, Inc.
+ *
+ *  Arch specific calls to support NMI watchdog
+ *
+ *  Bits copied from original nmi.c file
+ *
+ */
+#include <asm/apic.h>
+
+#include <linux/cpumask.h>
+#include <linux/kdebug.h>
+#include <linux/notifier.h>
+#include <linux/kprobes.h>
+#include <linux/nmi.h>
+#include <linux/module.h>
+
+/* For reliability, we're prepared to waste bits here. */
+static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
+
+u64 hw_nmi_get_sample_period(void)
+{
+       return (u64)(cpu_khz) * 1000 * 60;
+}
+
+#ifdef ARCH_HAS_NMI_WATCHDOG
+void arch_trigger_all_cpu_backtrace(void)
+{
+       int i;
+
+       cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask);
+
+       printk(KERN_INFO "sending NMI to all CPUs:\n");
+       apic->send_IPI_all(NMI_VECTOR);
+
+       /* Wait for up to 10 seconds for all CPUs to do the backtrace */
+       for (i = 0; i < 10 * 1000; i++) {
+               if (cpumask_empty(to_cpumask(backtrace_mask)))
+                       break;
+               mdelay(1);
+       }
+}
+
+static int __kprobes
+arch_trigger_all_cpu_backtrace_handler(struct notifier_block *self,
+                        unsigned long cmd, void *__args)
+{
+       struct die_args *args = __args;
+       struct pt_regs *regs;
+       int cpu = smp_processor_id();
+
+       switch (cmd) {
+       case DIE_NMI:
+       case DIE_NMI_IPI:
+               break;
+
+       default:
+               return NOTIFY_DONE;
+       }
+
+       regs = args->regs;
+
+       if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
+               static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED;
+
+               arch_spin_lock(&lock);
+               printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
+               show_regs(regs);
+               dump_stack();
+               arch_spin_unlock(&lock);
+               cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
+               return NOTIFY_STOP;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static __read_mostly struct notifier_block backtrace_notifier = {
+       .notifier_call          = arch_trigger_all_cpu_backtrace_handler,
+       .next                   = NULL,
+       .priority               = 1
+};
+
+static int __init register_trigger_all_cpu_backtrace(void)
+{
+       register_die_notifier(&backtrace_notifier);
+       return 0;
+}
+early_initcall(register_trigger_all_cpu_backtrace);
+#endif
+
+/* STUB calls to mimic old nmi_watchdog behaviour */
+#if defined(CONFIG_X86_LOCAL_APIC)
+unsigned int nmi_watchdog = NMI_NONE;
+EXPORT_SYMBOL(nmi_watchdog);
+void acpi_nmi_enable(void) { return; }
+void acpi_nmi_disable(void) { return; }
+#endif
+atomic_t nmi_active = ATOMIC_INIT(0);           /* oprofile uses this */
+EXPORT_SYMBOL(nmi_active);
+int unknown_nmi_panic;
+void cpu_nmi_set_wd_enabled(void) { return; }
+void stop_apic_nmi_watchdog(void *unused) { return; }
+void setup_apic_nmi_watchdog(void *unused) { return; }
+int __init check_nmi_watchdog(void) { return 0; }
index e41ed24ab26d5b51490ffa8f9a7c58a653b829d8..4dc0084ec1b108c6325f7df782c5a4b562035f63 100644 (file)
@@ -3397,7 +3397,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
 
        cfg = desc->chip_data;
 
-       read_msi_msg_desc(desc, &msg);
+       get_cached_msi_msg_desc(desc, &msg);
 
        msg.data &= ~MSI_DATA_VECTOR_MASK;
        msg.data |= MSI_DATA_VECTOR(cfg->vector);
index 1edaf15c0b8eef05b36653a0ed9087a9b3717f9e..a43f71cb30f8709595fe77c80be19d36c24aae29 100644 (file)
@@ -401,13 +401,6 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
        int cpu = smp_processor_id();
        int rc = 0;
 
-       /* check for other users first */
-       if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
-                       == NOTIFY_STOP) {
-               rc = 1;
-               touched = 1;
-       }
-
        sum = get_timer_irqs(cpu);
 
        if (__get_cpu_var(nmi_touch)) {
index 3a785da34b6f981dd678f217c5f75f728a30d8ae..3f0ebe429a01c14e67d252e475f34252fcf0f105 100644 (file)
@@ -12,11 +12,11 @@ endif
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_common.o                := $(nostackp)
 
-obj-y                  := intel_cacheinfo.o addon_cpuid_features.o
+obj-y                  := intel_cacheinfo.o scattered.o topology.o
 obj-y                  += proc.o capflags.o powerflags.o common.o
 obj-y                  += vmware.o hypervisor.o sched.o mshyperv.o
 
-obj-$(CONFIG_X86_32)   += bugs.o cmpxchg.o
+obj-$(CONFIG_X86_32)   += bugs.o
 obj-$(CONFIG_X86_64)   += bugs_64.o
 
 obj-$(CONFIG_CPU_SUP_INTEL)            += intel.o
index e485825130d2c8ee9b5d278717deca21ae2116f4..60a57b13082d2658e32da03193a071a4b314cc73 100644 (file)
@@ -466,7 +466,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                }
 
        }
-       if (c->x86 == 0x10 || c->x86 == 0x11)
+       if (c->x86 >= 0x10)
                set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 
        /* get apicid instead of initial apic id from cpuid */
@@ -529,7 +529,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                        num_cache_leaves = 3;
        }
 
-       if (c->x86 >= 0xf && c->x86 <= 0x11)
+       if (c->x86 >= 0xf)
                set_cpu_cap(c, X86_FEATURE_K8);
 
        if (cpu_has_xmm2) {
@@ -546,7 +546,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                fam10h_check_enable_mmcfg();
        }
 
-       if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) {
+       if (c == &boot_cpu_data && c->x86 >= 0xf) {
                unsigned long long tseg;
 
                /*
@@ -609,3 +609,74 @@ static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
 };
 
 cpu_dev_register(amd_cpu_dev);
+
+/*
+ * AMD errata checking
+ *
+ * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or
+ * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that
+ * have an OSVW id assigned, which it takes as first argument. Both take a
+ * variable number of family-specific model-stepping ranges created by
+ * AMD_MODEL_RANGE(). Each erratum also has to be declared as extern const
+ * int[] in arch/x86/include/asm/processor.h.
+ *
+ * Example:
+ *
+ * const int amd_erratum_319[] =
+ *     AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2),
+ *                        AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0),
+ *                        AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0));
+ */
+
+const int amd_erratum_400[] =
+       AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),
+                           AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
+EXPORT_SYMBOL_GPL(amd_erratum_400);
+
+const int amd_erratum_383[] =
+       AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
+EXPORT_SYMBOL_GPL(amd_erratum_383);
+
+bool cpu_has_amd_erratum(const int *erratum)
+{
+       struct cpuinfo_x86 *cpu = &current_cpu_data;
+       int osvw_id = *erratum++;
+       u32 range;
+       u32 ms;
+
+       /*
+        * If called early enough that current_cpu_data hasn't been initialized
+        * yet, fall back to boot_cpu_data.
+        */
+       if (cpu->x86 == 0)
+               cpu = &boot_cpu_data;
+
+       if (cpu->x86_vendor != X86_VENDOR_AMD)
+               return false;
+
+       if (osvw_id >= 0 && osvw_id < 65536 &&
+           cpu_has(cpu, X86_FEATURE_OSVW)) {
+               u64 osvw_len;
+
+               rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len);
+               if (osvw_id < osvw_len) {
+                       u64 osvw_bits;
+
+                       rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6),
+                           osvw_bits);
+                       return osvw_bits & (1ULL << (osvw_id & 0x3f));
+               }
+       }
+
+       /* OSVW unavailable or ID unknown, match family-model-stepping range */
+       ms = (cpu->x86_model << 8) | cpu->x86_mask;
+       while ((range = *erratum++))
+               if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
+                   (ms >= AMD_MODEL_RANGE_START(range)) &&
+                   (ms <= AMD_MODEL_RANGE_END(range)))
+                       return true;
+
+       return false;
+}
+
+EXPORT_SYMBOL_GPL(cpu_has_amd_erratum);
index 68e4a6f2211e2e8ea52015e5c4a8861f4f5269d9..490dac63c2d21e90ab3af70c543b012f1c3f43b5 100644 (file)
@@ -140,10 +140,18 @@ EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 static int __init x86_xsave_setup(char *s)
 {
        setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+       setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
        return 1;
 }
 __setup("noxsave", x86_xsave_setup);
 
+static int __init x86_xsaveopt_setup(char *s)
+{
+       setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
+       return 1;
+}
+__setup("noxsaveopt", x86_xsaveopt_setup);
+
 #ifdef CONFIG_X86_32
 static int cachesize_override __cpuinitdata = -1;
 static int disable_x86_serial_nr __cpuinitdata = 1;
@@ -551,6 +559,16 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
                c->x86_capability[4] = excap;
        }
 
+       /* Additional Intel-defined flags: level 0x00000007 */
+       if (c->cpuid_level >= 0x00000007) {
+               u32 eax, ebx, ecx, edx;
+
+               cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);
+
+               if (eax > 0)
+                       c->x86_capability[9] = ebx;
+       }
+
        /* AMD-defined flags: level 0x80000001 */
        xlvl = cpuid_eax(0x80000000);
        c->extended_cpuid_level = xlvl;
@@ -576,6 +594,7 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
        if (c->extended_cpuid_level >= 0x80000007)
                c->x86_power = cpuid_edx(0x80000007);
 
+       init_scattered_cpuid_features(c);
 }
 
 static void __cpuinit identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
@@ -731,7 +750,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
 
        get_model_name(c); /* Default name */
 
-       init_scattered_cpuid_features(c);
        detect_nopl(c);
 }
 
@@ -1192,6 +1210,7 @@ void __cpuinit cpu_init(void)
        dbg_restore_debug_regs();
 
        fpu_init();
+       xsave_init();
 
        raw_local_save_flags(kernel_eflags);
 
@@ -1252,12 +1271,7 @@ void __cpuinit cpu_init(void)
        clear_used_math();
        mxcsr_feature_mask_init();
 
-       /*
-        * Boot processor to setup the FP and extended state context info.
-        */
-       if (smp_processor_id() == boot_cpu_id)
-               init_thread_xstate();
-
+       fpu_init();
        xsave_init();
 }
 #endif
index dd531cc56a8f2c2f6da4acd545f413d869ee5869..8095f8611f8ab1d2c51efcb45d0929842065bc47 100644 (file)
@@ -34,6 +34,9 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
        &x86_hyper_vmware,
        &x86_hyper_ms_hyperv,
+#ifdef CONFIG_XEN_PVHVM
+       &x86_hyper_xen_hvm,
+#endif
 };
 
 const struct hypervisor_x86 *x86_hyper;
index 33eae2062cf55b06c864ad8511062440f37f10fe..898c2f4eab88b28cb74719b943cad01ec06efa29 100644 (file)
@@ -347,8 +347,8 @@ static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node)
        return l3;
 }
 
-static void __cpuinit
-amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
+static void __cpuinit amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf,
+                                          int index)
 {
        int node;
 
@@ -396,20 +396,39 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
        this_leaf->l3 = l3_caches[node];
 }
 
+/*
+ * check whether a slot used for disabling an L3 index is occupied.
+ * @l3: L3 cache descriptor
+ * @slot: slot number (0..1)
+ *
+ * @returns: the disabled index if used or negative value if slot free.
+ */
+int amd_get_l3_disable_slot(struct amd_l3_cache *l3, unsigned slot)
+{
+       unsigned int reg = 0;
+
+       pci_read_config_dword(l3->dev, 0x1BC + slot * 4, &reg);
+
+       /* check whether this slot is activated already */
+       if (reg & (3UL << 30))
+               return reg & 0xfff;
+
+       return -1;
+}
+
 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
                                  unsigned int slot)
 {
-       struct pci_dev *dev = this_leaf->l3->dev;
-       unsigned int reg = 0;
+       int index;
 
        if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
-       if (!dev)
-               return -EINVAL;
+       index = amd_get_l3_disable_slot(this_leaf->l3, slot);
+       if (index >= 0)
+               return sprintf(buf, "%d\n", index);
 
-       pci_read_config_dword(dev, 0x1BC + slot * 4, &reg);
-       return sprintf(buf, "0x%08x\n", reg);
+       return sprintf(buf, "FREE\n");
 }
 
 #define SHOW_CACHE_DISABLE(slot)                                       \
@@ -451,37 +470,74 @@ static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu,
        }
 }
 
-
-static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
-                                  const char *buf, size_t count,
-                                  unsigned int slot)
+/*
+ * disable a L3 cache index by using a disable-slot
+ *
+ * @l3:    L3 cache descriptor
+ * @cpu:   A CPU on the node containing the L3 cache
+ * @slot:  slot number (0..1)
+ * @index: index to disable
+ *
+ * @return: 0 on success, error status on failure
+ */
+int amd_set_l3_disable_slot(struct amd_l3_cache *l3, int cpu, unsigned slot,
+                           unsigned long index)
 {
-       struct pci_dev *dev = this_leaf->l3->dev;
-       int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-       unsigned long val = 0;
+       int ret = 0;
 
 #define SUBCACHE_MASK  (3UL << 20)
 #define SUBCACHE_INDEX 0xfff
 
-       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
+       /*
+        * check whether this slot is already used or
+        * the index is already disabled
+        */
+       ret = amd_get_l3_disable_slot(l3, slot);
+       if (ret >= 0)
                return -EINVAL;
 
+       /*
+        * check whether the other slot has disabled the
+        * same index already
+        */
+       if (index == amd_get_l3_disable_slot(l3, !slot))
+               return -EINVAL;
+
+       /* do not allow writes outside of allowed bits */
+       if ((index & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
+           ((index & SUBCACHE_INDEX) > l3->indices))
+               return -EINVAL;
+
+       amd_l3_disable_index(l3, cpu, slot, index);
+
+       return 0;
+}
+
+static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
+                                 const char *buf, size_t count,
+                                 unsigned int slot)
+{
+       unsigned long val = 0;
+       int cpu, err = 0;
+
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (!dev)
+       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
-       if (strict_strtoul(buf, 10, &val) < 0)
-               return -EINVAL;
+       cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
 
-       /* do not allow writes outside of allowed bits */
-       if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
-           ((val & SUBCACHE_INDEX) > this_leaf->l3->indices))
+       if (strict_strtoul(buf, 10, &val) < 0)
                return -EINVAL;
 
-       amd_l3_disable_index(this_leaf->l3, cpu, slot, val);
-
+       err = amd_set_l3_disable_slot(this_leaf->l3, cpu, slot, val);
+       if (err) {
+               if (err == -EEXIST)
+                       printk(KERN_WARNING "L3 disable slot %d in use!\n",
+                                           slot);
+               return err;
+       }
        return count;
 }
 
@@ -502,7 +558,7 @@ static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
 
 #else  /* CONFIG_CPU_SUP_AMD */
 static void __cpuinit
-amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
+amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf, int index)
 {
 };
 #endif /* CONFIG_CPU_SUP_AMD */
@@ -518,7 +574,7 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
 
        if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
                amd_cpuid4(index, &eax, &ebx, &ecx);
-               amd_check_l3_disable(index, this_leaf);
+               amd_check_l3_disable(this_leaf, index);
        } else {
                cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
        }
index 1970ef911c99b368e2f1f9e947bcdae71d2a2d84..ed41562909fe6d368f9f2c50a6c3000c6d9c9f5e 100644 (file)
@@ -51,7 +51,7 @@
 static DEFINE_MUTEX(mce_read_mutex);
 
 #define rcu_dereference_check_mce(p) \
-       rcu_dereference_check((p), \
+       rcu_dereference_index_check((p), \
                              rcu_read_lock_sched_held() || \
                              lockdep_is_held(&mce_read_mutex))
 
@@ -107,8 +107,8 @@ EXPORT_SYMBOL_GPL(x86_mce_decoder_chain);
 static int default_decode_mce(struct notifier_block *nb, unsigned long val,
                               void *data)
 {
-       pr_emerg("No human readable MCE decoding support on this CPU type.\n");
-       pr_emerg("Run the message through 'mcelog --ascii' to decode.\n");
+       pr_emerg(HW_ERR "No human readable MCE decoding support on this CPU type.\n");
+       pr_emerg(HW_ERR "Run the message through 'mcelog --ascii' to decode.\n");
 
        return NOTIFY_STOP;
 }
@@ -211,11 +211,11 @@ void mce_log(struct mce *mce)
 
 static void print_mce(struct mce *m)
 {
-       pr_emerg("CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
+       pr_emerg(HW_ERR "CPU %d: Machine Check Exception: %Lx Bank %d: %016Lx\n",
               m->extcpu, m->mcgstatus, m->bank, m->status);
 
        if (m->ip) {
-               pr_emerg("RIP%s %02x:<%016Lx> ",
+               pr_emerg(HW_ERR "RIP%s %02x:<%016Lx> ",
                        !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
                                m->cs, m->ip);
 
@@ -224,14 +224,14 @@ static void print_mce(struct mce *m)
                pr_cont("\n");
        }
 
-       pr_emerg("TSC %llx ", m->tsc);
+       pr_emerg(HW_ERR "TSC %llx ", m->tsc);
        if (m->addr)
                pr_cont("ADDR %llx ", m->addr);
        if (m->misc)
                pr_cont("MISC %llx ", m->misc);
 
        pr_cont("\n");
-       pr_emerg("PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
+       pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
                m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid);
 
        /*
@@ -241,16 +241,6 @@ static void print_mce(struct mce *m)
        atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
 }
 
-static void print_mce_head(void)
-{
-       pr_emerg("\nHARDWARE ERROR\n");
-}
-
-static void print_mce_tail(void)
-{
-       pr_emerg("This is not a software problem!\n");
-}
-
 #define PANIC_TIMEOUT 5 /* 5 seconds */
 
 static atomic_t mce_paniced;
@@ -291,7 +281,6 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
                if (atomic_inc_return(&mce_fake_paniced) > 1)
                        return;
        }
-       print_mce_head();
        /* First print corrected ones that are still unlogged */
        for (i = 0; i < MCE_LOG_LEN; i++) {
                struct mce *m = &mcelog.entry[i];
@@ -322,16 +311,15 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
                        apei_err = apei_write_mce(final);
        }
        if (cpu_missing)
-               printk(KERN_EMERG "Some CPUs didn't answer in synchronization\n");
-       print_mce_tail();
+               pr_emerg(HW_ERR "Some CPUs didn't answer in synchronization\n");
        if (exp)
-               printk(KERN_EMERG "Machine check: %s\n", exp);
+               pr_emerg(HW_ERR "Machine check: %s\n", exp);
        if (!fake_panic) {
                if (panic_timeout == 0)
                        panic_timeout = mce_panic_timeout;
                panic(msg);
        } else
-               printk(KERN_EMERG "Fake kernel panic: %s\n", msg);
+               pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg);
 }
 
 /* Support code for software error injection */
@@ -1221,7 +1209,7 @@ int mce_notify_irq(void)
                        schedule_work(&mce_trigger_work);
 
                if (__ratelimit(&ratelimit))
-                       printk(KERN_INFO "Machine check events logged\n");
+                       pr_info(HW_ERR "Machine check events logged\n");
 
                return 1;
        }
index 62b48e40920a2fe2445bc68ba562fcc2e4d8c987..6fcd0936194ff195cd78b14cdce76b997dd45ec9 100644 (file)
@@ -95,19 +95,20 @@ static void cmci_discover(int banks, int boot)
                rdmsrl(MSR_IA32_MCx_CTL2(i), val);
 
                /* Already owned by someone else? */
-               if (val & CMCI_EN) {
+               if (val & MCI_CTL2_CMCI_EN) {
                        if (test_and_clear_bit(i, owned) && !boot)
                                print_update("SHD", &hdr, i);
                        __clear_bit(i, __get_cpu_var(mce_poll_banks));
                        continue;
                }
 
-               val |= CMCI_EN | CMCI_THRESHOLD;
+               val &= ~MCI_CTL2_CMCI_THRESHOLD_MASK;
+               val |= MCI_CTL2_CMCI_EN | CMCI_THRESHOLD;
                wrmsrl(MSR_IA32_MCx_CTL2(i), val);
                rdmsrl(MSR_IA32_MCx_CTL2(i), val);
 
                /* Did the enable bit stick? -- the bank supports CMCI */
-               if (val & CMCI_EN) {
+               if (val & MCI_CTL2_CMCI_EN) {
                        if (!test_and_set_bit(i, owned) && !boot)
                                print_update("CMCI", &hdr, i);
                        __clear_bit(i, __get_cpu_var(mce_poll_banks));
@@ -155,7 +156,7 @@ void cmci_clear(void)
                        continue;
                /* Disable CMCI */
                rdmsrl(MSR_IA32_MCx_CTL2(i), val);
-               val &= ~(CMCI_EN|CMCI_THRESHOLD_MASK);
+               val &= ~(MCI_CTL2_CMCI_EN|MCI_CTL2_CMCI_THRESHOLD_MASK);
                wrmsrl(MSR_IA32_MCx_CTL2(i), val);
                __clear_bit(i, __get_cpu_var(mce_banks_owned));
        }
index e1a0a3bf9716722671325212dceb559db2a47bf3..c2a8b26d4feacf4ac6b6b022c0a9c590fbbcef85 100644 (file)
 /* How long to wait between reporting thermal events */
 #define CHECK_INTERVAL         (300 * HZ)
 
+#define THERMAL_THROTTLING_EVENT       0
+#define POWER_LIMIT_EVENT              1
+
 /*
- * Current thermal throttling state:
+ * Current thermal event state:
  */
-struct thermal_state {
-       bool                    is_throttled;
-
+struct _thermal_state {
+       bool                    new_event;
+       int                     event;
        u64                     next_check;
-       unsigned long           throttle_count;
-       unsigned long           last_throttle_count;
+       unsigned long           count;
+       unsigned long           last_count;
+};
+
+struct thermal_state {
+       struct _thermal_state core_throttle;
+       struct _thermal_state core_power_limit;
+       struct _thermal_state package_throttle;
+       struct _thermal_state package_power_limit;
 };
 
 static DEFINE_PER_CPU(struct thermal_state, thermal_state);
@@ -53,11 +63,13 @@ static u32 lvtthmr_init __read_mostly;
 
 #ifdef CONFIG_SYSFS
 #define define_therm_throt_sysdev_one_ro(_name)                                \
-       static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL)
+       static SYSDEV_ATTR(_name, 0444,                                 \
+                          therm_throt_sysdev_show_##_name,             \
+                                  NULL)                                \
 
-#define define_therm_throt_sysdev_show_func(name)                      \
+#define define_therm_throt_sysdev_show_func(event, name)               \
                                                                        \
-static ssize_t therm_throt_sysdev_show_##name(                         \
+static ssize_t therm_throt_sysdev_show_##event##_##name(               \
                        struct sys_device *dev,                         \
                        struct sysdev_attribute *attr,                  \
                        char *buf)                                      \
@@ -66,30 +78,42 @@ static ssize_t therm_throt_sysdev_show_##name(                              \
        ssize_t ret;                                                    \
                                                                        \
        preempt_disable();      /* CPU hotplug */                       \
-       if (cpu_online(cpu))                                            \
+       if (cpu_online(cpu)) {                                          \
                ret = sprintf(buf, "%lu\n",                             \
-                             per_cpu(thermal_state, cpu).name);        \
-       else                                                            \
+                             per_cpu(thermal_state, cpu).event.name);  \
+       } else                                                          \
                ret = 0;                                                \
        preempt_enable();                                               \
                                                                        \
        return ret;                                                     \
 }
 
-define_therm_throt_sysdev_show_func(throttle_count);
-define_therm_throt_sysdev_one_ro(throttle_count);
+define_therm_throt_sysdev_show_func(core_throttle, count);
+define_therm_throt_sysdev_one_ro(core_throttle_count);
+
+define_therm_throt_sysdev_show_func(core_power_limit, count);
+define_therm_throt_sysdev_one_ro(core_power_limit_count);
+
+define_therm_throt_sysdev_show_func(package_throttle, count);
+define_therm_throt_sysdev_one_ro(package_throttle_count);
+
+define_therm_throt_sysdev_show_func(package_power_limit, count);
+define_therm_throt_sysdev_one_ro(package_power_limit_count);
 
 static struct attribute *thermal_throttle_attrs[] = {
-       &attr_throttle_count.attr,
+       &attr_core_throttle_count.attr,
        NULL
 };
 
-static struct attribute_group thermal_throttle_attr_group = {
+static struct attribute_group thermal_attr_group = {
        .attrs  = thermal_throttle_attrs,
        .name   = "thermal_throttle"
 };
 #endif /* CONFIG_SYSFS */
 
+#define CORE_LEVEL     0
+#define PACKAGE_LEVEL  1
+
 /***
  * therm_throt_process - Process thermal throttling event from interrupt
  * @curr: Whether the condition is current or not (boolean), since the
@@ -106,39 +130,70 @@ static struct attribute_group thermal_throttle_attr_group = {
  *          1 : Event should be logged further, and a message has been
  *              printed to the syslog.
  */
-static int therm_throt_process(bool is_throttled)
+static int therm_throt_process(bool new_event, int event, int level)
 {
-       struct thermal_state *state;
-       unsigned int this_cpu;
-       bool was_throttled;
+       struct _thermal_state *state;
+       unsigned int this_cpu = smp_processor_id();
+       bool old_event;
        u64 now;
+       struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu);
 
-       this_cpu = smp_processor_id();
        now = get_jiffies_64();
-       state = &per_cpu(thermal_state, this_cpu);
+       if (level == CORE_LEVEL) {
+               if (event == THERMAL_THROTTLING_EVENT)
+                       state = &pstate->core_throttle;
+               else if (event == POWER_LIMIT_EVENT)
+                       state = &pstate->core_power_limit;
+               else
+                        return 0;
+       } else if (level == PACKAGE_LEVEL) {
+               if (event == THERMAL_THROTTLING_EVENT)
+                       state = &pstate->package_throttle;
+               else if (event == POWER_LIMIT_EVENT)
+                       state = &pstate->package_power_limit;
+               else
+                       return 0;
+       } else
+               return 0;
 
-       was_throttled = state->is_throttled;
-       state->is_throttled = is_throttled;
+       old_event = state->new_event;
+       state->new_event = new_event;
 
-       if (is_throttled)
-               state->throttle_count++;
+       if (new_event)
+               state->count++;
 
        if (time_before64(now, state->next_check) &&
-                       state->throttle_count != state->last_throttle_count)
+                       state->count != state->last_count)
                return 0;
 
        state->next_check = now + CHECK_INTERVAL;
-       state->last_throttle_count = state->throttle_count;
+       state->last_count = state->count;
 
        /* if we just entered the thermal event */
-       if (is_throttled) {
-               printk(KERN_CRIT "CPU%d: Temperature above threshold, cpu clock throttled (total events = %lu)\n", this_cpu, state->throttle_count);
+       if (new_event) {
+               if (event == THERMAL_THROTTLING_EVENT)
+                       printk(KERN_CRIT "CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n",
+                               this_cpu,
+                               level == CORE_LEVEL ? "Core" : "Package",
+                               state->count);
+               else
+                       printk(KERN_CRIT "CPU%d: %s power limit notification (total events = %lu)\n",
+                               this_cpu,
+                               level == CORE_LEVEL ? "Core" : "Package",
+                               state->count);
 
                add_taint(TAINT_MACHINE_CHECK);
                return 1;
        }
-       if (was_throttled) {
-               printk(KERN_INFO "CPU%d: Temperature/speed normal\n", this_cpu);
+       if (old_event) {
+               if (event == THERMAL_THROTTLING_EVENT)
+                       printk(KERN_INFO "CPU%d: %s temperature/speed normal\n",
+                               this_cpu,
+                               level == CORE_LEVEL ? "Core" : "Package");
+               else
+                       printk(KERN_INFO "CPU%d: %s power limit normal\n",
+                               this_cpu,
+                               level == CORE_LEVEL ? "Core" : "Package");
                return 1;
        }
 
@@ -149,13 +204,32 @@ static int therm_throt_process(bool is_throttled)
 /* Add/Remove thermal_throttle interface for CPU device: */
 static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev)
 {
-       return sysfs_create_group(&sys_dev->kobj,
-                                 &thermal_throttle_attr_group);
+       int err;
+       struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
+
+       err = sysfs_create_group(&sys_dev->kobj, &thermal_attr_group);
+       if (err)
+               return err;
+
+       if (cpu_has(c, X86_FEATURE_PLN))
+               err = sysfs_add_file_to_group(&sys_dev->kobj,
+                                             &attr_core_power_limit_count.attr,
+                                             thermal_attr_group.name);
+       if (cpu_has(c, X86_FEATURE_PTS))
+               err = sysfs_add_file_to_group(&sys_dev->kobj,
+                                             &attr_package_throttle_count.attr,
+                                             thermal_attr_group.name);
+               if (cpu_has(c, X86_FEATURE_PLN))
+                       err = sysfs_add_file_to_group(&sys_dev->kobj,
+                                       &attr_package_power_limit_count.attr,
+                                       thermal_attr_group.name);
+
+       return err;
 }
 
 static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev)
 {
-       sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group);
+       sysfs_remove_group(&sys_dev->kobj, &thermal_attr_group);
 }
 
 /* Mutex protecting device creation against CPU hotplug: */
@@ -226,14 +300,50 @@ device_initcall(thermal_throttle_init_device);
 
 #endif /* CONFIG_SYSFS */
 
+/*
+ * Set up the most two significant bit to notify mce log that this thermal
+ * event type.
+ * This is a temp solution. May be changed in the future with mce log
+ * infrasture.
+ */
+#define CORE_THROTTLED         (0)
+#define CORE_POWER_LIMIT       ((__u64)1 << 62)
+#define PACKAGE_THROTTLED      ((__u64)2 << 62)
+#define PACKAGE_POWER_LIMIT    ((__u64)3 << 62)
+
 /* Thermal transition interrupt handler */
 static void intel_thermal_interrupt(void)
 {
        __u64 msr_val;
+       struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
 
        rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
-       if (therm_throt_process((msr_val & THERM_STATUS_PROCHOT) != 0))
-               mce_log_therm_throt_event(msr_val);
+
+       if (therm_throt_process(msr_val & THERM_STATUS_PROCHOT,
+                               THERMAL_THROTTLING_EVENT,
+                               CORE_LEVEL) != 0)
+               mce_log_therm_throt_event(CORE_THROTTLED | msr_val);
+
+       if (cpu_has(c, X86_FEATURE_PLN))
+               if (therm_throt_process(msr_val & THERM_STATUS_POWER_LIMIT,
+                                       POWER_LIMIT_EVENT,
+                                       CORE_LEVEL) != 0)
+                       mce_log_therm_throt_event(CORE_POWER_LIMIT | msr_val);
+
+       if (cpu_has(c, X86_FEATURE_PTS)) {
+               rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
+               if (therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
+                                       THERMAL_THROTTLING_EVENT,
+                                       PACKAGE_LEVEL) != 0)
+                       mce_log_therm_throt_event(PACKAGE_THROTTLED | msr_val);
+               if (cpu_has(c, X86_FEATURE_PLN))
+                       if (therm_throt_process(msr_val &
+                                       PACKAGE_THERM_STATUS_POWER_LIMIT,
+                                       POWER_LIMIT_EVENT,
+                                       PACKAGE_LEVEL) != 0)
+                               mce_log_therm_throt_event(PACKAGE_POWER_LIMIT
+                                                         | msr_val);
+       }
 }
 
 static void unexpected_thermal_interrupt(void)
@@ -335,8 +445,26 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
        apic_write(APIC_LVTTHMR, h);
 
        rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
-       wrmsr(MSR_IA32_THERM_INTERRUPT,
-               l | (THERM_INT_LOW_ENABLE | THERM_INT_HIGH_ENABLE), h);
+       if (cpu_has(c, X86_FEATURE_PLN))
+               wrmsr(MSR_IA32_THERM_INTERRUPT,
+                     l | (THERM_INT_LOW_ENABLE
+                       | THERM_INT_HIGH_ENABLE | THERM_INT_PLN_ENABLE), h);
+       else
+               wrmsr(MSR_IA32_THERM_INTERRUPT,
+                     l | (THERM_INT_LOW_ENABLE | THERM_INT_HIGH_ENABLE), h);
+
+       if (cpu_has(c, X86_FEATURE_PTS)) {
+               rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
+               if (cpu_has(c, X86_FEATURE_PLN))
+                       wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
+                             l | (PACKAGE_THERM_INT_LOW_ENABLE
+                               | PACKAGE_THERM_INT_HIGH_ENABLE
+                               | PACKAGE_THERM_INT_PLN_ENABLE), h);
+               else
+                       wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
+                             l | (PACKAGE_THERM_INT_LOW_ENABLE
+                               | PACKAGE_THERM_INT_HIGH_ENABLE), h);
+       }
 
        smp_thermal_vector = intel_thermal_interrupt;
 
index 16f41bbe46b6b3ae6f4d6754b735d967f098394e..d944bf6c50e9257e94742136a6d6d4b1e5cedcc6 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/mshyperv.h>
 
 struct ms_hyperv_info ms_hyperv;
+EXPORT_SYMBOL_GPL(ms_hyperv);
 
 static bool __init ms_hyperv_platform(void)
 {
index 06130b52f0129fd863e8b4ce504a3c2cd1d40d75..c5f59d07142562e9c673572970ae79fca1e3622e 100644 (file)
@@ -632,9 +632,9 @@ static void __init mtrr_print_out_one_result(int i)
        unsigned long gran_base, chunk_base, lose_base;
        char gran_factor, chunk_factor, lose_factor;
 
-       gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
-       chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
-       lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
+       gran_base = to_size_factor(result[i].gran_sizek, &gran_factor);
+       chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor);
+       lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor);
 
        pr_info("%sgran_size: %ld%c \tchunk_size: %ld%c \t",
                result[i].bad ? "*BAD*" : " ",
index fd31a441c61cbecf51e554d2292a2600b7a70295..7d28d7d03885a1d28e0785221f8e0197b89f957f 100644 (file)
@@ -433,13 +433,12 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
 {
        unsigned int mask_lo, mask_hi, base_lo, base_hi;
        unsigned int tmp, hi;
-       int cpu;
 
        /*
         * get_mtrr doesn't need to update mtrr_state, also it could be called
         * from any cpu, so try to print it out directly.
         */
-       cpu = get_cpu();
+       get_cpu();
 
        rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
 
index 79556bd9b602a41b3ef3bc5502eccb05ed8dba1d..01c0f3ee6cc3a2cfe90de789e5e440a3e2ca3593 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/types.h> /* FIXME: kvm_para.h needs this */
 
+#include <linux/stop_machine.h>
 #include <linux/kvm_para.h>
 #include <linux/uaccess.h>
 #include <linux/module.h>
@@ -143,22 +144,28 @@ struct set_mtrr_data {
        mtrr_type       smp_type;
 };
 
+static DEFINE_PER_CPU(struct cpu_stop_work, mtrr_work);
+
 /**
- * ipi_handler - Synchronisation handler. Executed by "other" CPUs.
+ * mtrr_work_handler - Synchronisation handler. Executed by "other" CPUs.
  * @info: pointer to mtrr configuration data
  *
  * Returns nothing.
  */
-static void ipi_handler(void *info)
+static int mtrr_work_handler(void *info)
 {
 #ifdef CONFIG_SMP
        struct set_mtrr_data *data = info;
        unsigned long flags;
 
+       atomic_dec(&data->count);
+       while (!atomic_read(&data->gate))
+               cpu_relax();
+
        local_irq_save(flags);
 
        atomic_dec(&data->count);
-       while (!atomic_read(&data->gate))
+       while (atomic_read(&data->gate))
                cpu_relax();
 
        /*  The master has cleared me to execute  */
@@ -173,12 +180,13 @@ static void ipi_handler(void *info)
        }
 
        atomic_dec(&data->count);
-       while (atomic_read(&data->gate))
+       while (!atomic_read(&data->gate))
                cpu_relax();
 
        atomic_dec(&data->count);
        local_irq_restore(flags);
 #endif
+       return 0;
 }
 
 static inline int types_compatible(mtrr_type type1, mtrr_type type2)
@@ -198,7 +206,7 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2)
  *
  * This is kinda tricky, but fortunately, Intel spelled it out for us cleanly:
  *
- * 1. Send IPI to do the following:
+ * 1. Queue work to do the following on all processors:
  * 2. Disable Interrupts
  * 3. Wait for all procs to do so
  * 4. Enter no-fill cache mode
@@ -215,14 +223,17 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2)
  * 15. Enable interrupts.
  *
  * What does that mean for us? Well, first we set data.count to the number
- * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait
- * until it hits 0 and proceed. We set the data.gate flag and reset data.count.
- * Meanwhile, they are waiting for that flag to be set. Once it's set, each
+ * of CPUs. As each CPU announces that it started the rendezvous handler by
+ * decrementing the count, We reset data.count and set the data.gate flag
+ * allowing all the cpu's to proceed with the work. As each cpu disables
+ * interrupts, it'll decrement data.count once. We wait until it hits 0 and
+ * proceed. We clear the data.gate flag and reset data.count. Meanwhile, they
+ * are waiting for that flag to be cleared. Once it's cleared, each
  * CPU goes through the transition of updating MTRRs.
  * The CPU vendors may each do it differently,
  * so we call mtrr_if->set() callback and let them take care of it.
  * When they're done, they again decrement data->count and wait for data.gate
- * to be reset.
+ * to be set.
  * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag
  * Everyone then enables interrupts and we all continue on.
  *
@@ -234,6 +245,9 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
 {
        struct set_mtrr_data data;
        unsigned long flags;
+       int cpu;
+
+       preempt_disable();
 
        data.smp_reg = reg;
        data.smp_base = base;
@@ -246,10 +260,15 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
        atomic_set(&data.gate, 0);
 
        /* Start the ball rolling on other CPUs */
-       if (smp_call_function(ipi_handler, &data, 0) != 0)
-               panic("mtrr: timed out waiting for other CPUs\n");
+       for_each_online_cpu(cpu) {
+               struct cpu_stop_work *work = &per_cpu(mtrr_work, cpu);
+
+               if (cpu == smp_processor_id())
+                       continue;
+
+               stop_one_cpu_nowait(cpu, mtrr_work_handler, &data, work);
+       }
 
-       local_irq_save(flags);
 
        while (atomic_read(&data.count))
                cpu_relax();
@@ -259,6 +278,16 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
        smp_wmb();
        atomic_set(&data.gate, 1);
 
+       local_irq_save(flags);
+
+       while (atomic_read(&data.count))
+               cpu_relax();
+
+       /* Ok, reset count and toggle gate */
+       atomic_set(&data.count, num_booting_cpus() - 1);
+       smp_wmb();
+       atomic_set(&data.gate, 0);
+
        /* Do our MTRR business */
 
        /*
@@ -279,7 +308,7 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
 
        atomic_set(&data.count, num_booting_cpus() - 1);
        smp_wmb();
-       atomic_set(&data.gate, 0);
+       atomic_set(&data.gate, 1);
 
        /*
         * Wait here for everyone to have seen the gate change
@@ -289,6 +318,7 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
                cpu_relax();
 
        local_irq_restore(flags);
+       preempt_enable();
 }
 
 /**
index 5db5b7d65a180f6a7f0c2cb970d63e04129add2a..f2da20fda02ddf6fcd449a88ba399fe4ed44af2a 100644 (file)
@@ -220,6 +220,7 @@ struct x86_pmu {
                                                 struct perf_event *event);
        struct event_constraint *event_constraints;
        void            (*quirks)(void);
+       int             perfctr_second_write;
 
        int             (*cpu_prepare)(int cpu);
        void            (*cpu_starting)(int cpu);
@@ -295,10 +296,10 @@ x86_perf_event_update(struct perf_event *event)
         * count to the generic event atomically:
         */
 again:
-       prev_raw_count = atomic64_read(&hwc->prev_count);
+       prev_raw_count = local64_read(&hwc->prev_count);
        rdmsrl(hwc->event_base + idx, new_raw_count);
 
-       if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+       if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
                                        new_raw_count) != prev_raw_count)
                goto again;
 
@@ -313,8 +314,8 @@ again:
        delta = (new_raw_count << shift) - (prev_raw_count << shift);
        delta >>= shift;
 
-       atomic64_add(delta, &event->count);
-       atomic64_sub(delta, &hwc->period_left);
+       local64_add(delta, &event->count);
+       local64_sub(delta, &hwc->period_left);
 
        return new_raw_count;
 }
@@ -438,7 +439,7 @@ static int x86_setup_perfctr(struct perf_event *event)
        if (!hwc->sample_period) {
                hwc->sample_period = x86_pmu.max_period;
                hwc->last_period = hwc->sample_period;
-               atomic64_set(&hwc->period_left, hwc->sample_period);
+               local64_set(&hwc->period_left, hwc->sample_period);
        } else {
                /*
                 * If we have a PMU initialized but no APIC
@@ -885,7 +886,7 @@ static int
 x86_perf_event_set_period(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
-       s64 left = atomic64_read(&hwc->period_left);
+       s64 left = local64_read(&hwc->period_left);
        s64 period = hwc->sample_period;
        int ret = 0, idx = hwc->idx;
 
@@ -897,14 +898,14 @@ x86_perf_event_set_period(struct perf_event *event)
         */
        if (unlikely(left <= -period)) {
                left = period;
-               atomic64_set(&hwc->period_left, left);
+               local64_set(&hwc->period_left, left);
                hwc->last_period = period;
                ret = 1;
        }
 
        if (unlikely(left <= 0)) {
                left += period;
-               atomic64_set(&hwc->period_left, left);
+               local64_set(&hwc->period_left, left);
                hwc->last_period = period;
                ret = 1;
        }
@@ -923,10 +924,19 @@ x86_perf_event_set_period(struct perf_event *event)
         * The hw event starts counting from this event offset,
         * mark it to be able to extra future deltas:
         */
-       atomic64_set(&hwc->prev_count, (u64)-left);
+       local64_set(&hwc->prev_count, (u64)-left);
 
-       wrmsrl(hwc->event_base + idx,
+       wrmsrl(hwc->event_base + idx, (u64)(-left) & x86_pmu.cntval_mask);
+
+       /*
+        * Due to erratum on certan cpu we need
+        * a second write to be sure the register
+        * is updated properly
+        */
+       if (x86_pmu.perfctr_second_write) {
+               wrmsrl(hwc->event_base + idx,
                        (u64)(-left) & x86_pmu.cntval_mask);
+       }
 
        perf_event_update_userpage(event);
 
@@ -969,7 +979,7 @@ static int x86_pmu_enable(struct perf_event *event)
         * skip the schedulability test here, it will be peformed
         * at commit time(->commit_txn) as a whole
         */
-       if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
+       if (cpuc->group_flag & PERF_EVENT_TXN)
                goto out;
 
        ret = x86_pmu.schedule_events(cpuc, n, assign);
@@ -1096,7 +1106,7 @@ static void x86_pmu_disable(struct perf_event *event)
         * The events never got scheduled and ->cancel_txn will truncate
         * the event_list.
         */
-       if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
+       if (cpuc->group_flag & PERF_EVENT_TXN)
                return;
 
        x86_pmu_stop(event);
@@ -1388,7 +1398,7 @@ static void x86_pmu_start_txn(const struct pmu *pmu)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
-       cpuc->group_flag |= PERF_EVENT_TXN_STARTED;
+       cpuc->group_flag |= PERF_EVENT_TXN;
        cpuc->n_txn = 0;
 }
 
@@ -1401,7 +1411,7 @@ static void x86_pmu_cancel_txn(const struct pmu *pmu)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
-       cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED;
+       cpuc->group_flag &= ~PERF_EVENT_TXN;
        /*
         * Truncate the collected events.
         */
@@ -1435,11 +1445,7 @@ static int x86_pmu_commit_txn(const struct pmu *pmu)
         */
        memcpy(cpuc->assign, assign, n*sizeof(int));
 
-       /*
-        * Clear out the txn count so that ->cancel_txn() which gets
-        * run after ->commit_txn() doesn't undo things.
-        */
-       cpuc->n_txn = 0;
+       cpuc->group_flag &= ~PERF_EVENT_TXN;
 
        return 0;
 }
@@ -1607,8 +1613,6 @@ static const struct stacktrace_ops backtrace_ops = {
        .walk_stack             = print_context_stack_bp,
 };
 
-#include "../dumpstack.h"
-
 static void
 perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
 {
@@ -1730,22 +1734,6 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
        return entry;
 }
 
-void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
-{
-       regs->ip = ip;
-       /*
-        * perf_arch_fetch_caller_regs adds another call, we need to increment
-        * the skip level
-        */
-       regs->bp = rewind_frame_pointer(skip + 1);
-       regs->cs = __KERNEL_CS;
-       /*
-        * We abuse bit 3 to pass exact information, see perf_misc_flags
-        * and the comment with PERF_EFLAGS_EXACT.
-        */
-       regs->flags = 0;
-}
-
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
        unsigned long ip;
index ae85d69644d182f31c9711eba6c5ddb21862bcec..107711bf0ee8f9ff05e886b2143f1f69123d0d41 100644 (file)
@@ -21,22 +21,36 @@ struct p4_event_bind {
        char cntr[2][P4_CNTR_LIMIT];            /* counter index (offset), -1 on abscence */
 };
 
-struct p4_cache_event_bind {
+struct p4_pebs_bind {
        unsigned int metric_pebs;
        unsigned int metric_vert;
 };
 
-#define P4_GEN_CACHE_EVENT_BIND(name)          \
-       [P4_CACHE__##name] = {                  \
-               .metric_pebs = P4_PEBS__##name, \
-               .metric_vert = P4_VERT__##name, \
+/* it sets P4_PEBS_ENABLE_UOP_TAG as well */
+#define P4_GEN_PEBS_BIND(name, pebs, vert)                     \
+       [P4_PEBS_METRIC__##name] = {                            \
+               .metric_pebs = pebs | P4_PEBS_ENABLE_UOP_TAG,   \
+               .metric_vert = vert,                            \
        }
 
-static struct p4_cache_event_bind p4_cache_event_bind_map[] = {
-       P4_GEN_CACHE_EVENT_BIND(1stl_cache_load_miss_retired),
-       P4_GEN_CACHE_EVENT_BIND(2ndl_cache_load_miss_retired),
-       P4_GEN_CACHE_EVENT_BIND(dtlb_load_miss_retired),
-       P4_GEN_CACHE_EVENT_BIND(dtlb_store_miss_retired),
+/*
+ * note we have P4_PEBS_ENABLE_UOP_TAG always set here
+ *
+ * it's needed for mapping P4_PEBS_CONFIG_METRIC_MASK bits of
+ * event configuration to find out which values are to be
+ * written into MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT
+ * resgisters
+ */
+static struct p4_pebs_bind p4_pebs_bind_map[] = {
+       P4_GEN_PEBS_BIND(1stl_cache_load_miss_retired,  0x0000001, 0x0000001),
+       P4_GEN_PEBS_BIND(2ndl_cache_load_miss_retired,  0x0000002, 0x0000001),
+       P4_GEN_PEBS_BIND(dtlb_load_miss_retired,        0x0000004, 0x0000001),
+       P4_GEN_PEBS_BIND(dtlb_store_miss_retired,       0x0000004, 0x0000002),
+       P4_GEN_PEBS_BIND(dtlb_all_miss_retired,         0x0000004, 0x0000003),
+       P4_GEN_PEBS_BIND(tagged_mispred_branch,         0x0018000, 0x0000010),
+       P4_GEN_PEBS_BIND(mob_load_replay_retired,       0x0000200, 0x0000001),
+       P4_GEN_PEBS_BIND(split_load_retired,            0x0000400, 0x0000001),
+       P4_GEN_PEBS_BIND(split_store_retired,           0x0000400, 0x0000002),
 };
 
 /*
@@ -281,10 +295,10 @@ static struct p4_event_bind p4_event_bind_map[] = {
        },
 };
 
-#define P4_GEN_CACHE_EVENT(event, bit, cache_event)                      \
+#define P4_GEN_CACHE_EVENT(event, bit, metric)                           \
        p4_config_pack_escr(P4_ESCR_EVENT(event)                        | \
                            P4_ESCR_EMASK_BIT(event, bit))              | \
-       p4_config_pack_cccr(cache_event                                 | \
+       p4_config_pack_cccr(metric                                      | \
                            P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
 
 static __initconst const u64 p4_hw_cache_event_ids
@@ -296,34 +310,34 @@ static __initconst const u64 p4_hw_cache_event_ids
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = 0x0,
                [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-                                               P4_CACHE__1stl_cache_load_miss_retired),
+                                               P4_PEBS_METRIC__1stl_cache_load_miss_retired),
        },
  },
  [ C(LL  ) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = 0x0,
                [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-                                               P4_CACHE__2ndl_cache_load_miss_retired),
+                                               P4_PEBS_METRIC__2ndl_cache_load_miss_retired),
        },
 },
  [ C(DTLB) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = 0x0,
                [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-                                               P4_CACHE__dtlb_load_miss_retired),
+                                               P4_PEBS_METRIC__dtlb_load_miss_retired),
        },
        [ C(OP_WRITE) ] = {
                [ C(RESULT_ACCESS) ] = 0x0,
                [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-                                               P4_CACHE__dtlb_store_miss_retired),
+                                               P4_PEBS_METRIC__dtlb_store_miss_retired),
        },
  },
  [ C(ITLB) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
-                                               P4_CACHE__itlb_reference_hit),
+                                               P4_PEBS_METRIC__none),
                [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
-                                               P4_CACHE__itlb_reference_miss),
+                                               P4_PEBS_METRIC__none),
        },
        [ C(OP_WRITE) ] = {
                [ C(RESULT_ACCESS) ] = -1,
@@ -414,11 +428,37 @@ static u64 p4_pmu_event_map(int hw_event)
        return config;
 }
 
+static int p4_validate_raw_event(struct perf_event *event)
+{
+       unsigned int v;
+
+       /* user data may have out-of-bound event index */
+       v = p4_config_unpack_event(event->attr.config);
+       if (v >= ARRAY_SIZE(p4_event_bind_map)) {
+               pr_warning("P4 PMU: Unknown event code: %d\n", v);
+               return -EINVAL;
+       }
+
+       /*
+        * it may have some screwed PEBS bits
+        */
+       if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE)) {
+               pr_warning("P4 PMU: PEBS are not supported yet\n");
+               return -EINVAL;
+       }
+       v = p4_config_unpack_metric(event->attr.config);
+       if (v >= ARRAY_SIZE(p4_pebs_bind_map)) {
+               pr_warning("P4 PMU: Unknown metric code: %d\n", v);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int p4_hw_config(struct perf_event *event)
 {
        int cpu = get_cpu();
        int rc = 0;
-       unsigned int evnt;
        u32 escr, cccr;
 
        /*
@@ -438,12 +478,9 @@ static int p4_hw_config(struct perf_event *event)
 
        if (event->attr.type == PERF_TYPE_RAW) {
 
-               /* user data may have out-of-bound event index */
-               evnt = p4_config_unpack_event(event->attr.config);
-               if (evnt >= ARRAY_SIZE(p4_event_bind_map)) {
-                       rc = -EINVAL;
+               rc = p4_validate_raw_event(event);
+               if (rc)
                        goto out;
-               }
 
                /*
                 * We don't control raw events so it's up to the caller
@@ -451,12 +488,15 @@ static int p4_hw_config(struct perf_event *event)
                 * on HT machine but allow HT-compatible specifics to be
                 * passed on)
                 *
+                * Note that for RAW events we allow user to use P4_CCCR_RESERVED
+                * bits since we keep additional info here (for cache events and etc)
+                *
                 * XXX: HT wide things should check perf_paranoid_cpu() &&
                 *      CAP_SYS_ADMIN
                 */
                event->hw.config |= event->attr.config &
                        (p4_config_pack_escr(P4_ESCR_MASK_HT) |
-                        p4_config_pack_cccr(P4_CCCR_MASK_HT));
+                        p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED));
        }
 
        rc = x86_setup_perfctr(event);
@@ -482,6 +522,29 @@ static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
        return overflow;
 }
 
+static void p4_pmu_disable_pebs(void)
+{
+       /*
+        * FIXME
+        *
+        * It's still allowed that two threads setup same cache
+        * events so we can't simply clear metrics until we knew
+        * noone is depending on us, so we need kind of counter
+        * for "ReplayEvent" users.
+        *
+        * What is more complex -- RAW events, if user (for some
+        * reason) will pass some cache event metric with improper
+        * event opcode -- it's fine from hardware point of view
+        * but completely nonsence from "meaning" of such action.
+        *
+        * So at moment let leave metrics turned on forever -- it's
+        * ok for now but need to be revisited!
+        *
+        * (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)0);
+        * (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)0);
+        */
+}
+
 static inline void p4_pmu_disable_event(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
@@ -507,6 +570,26 @@ static void p4_pmu_disable_all(void)
                        continue;
                p4_pmu_disable_event(event);
        }
+
+       p4_pmu_disable_pebs();
+}
+
+/* configuration must be valid */
+static void p4_pmu_enable_pebs(u64 config)
+{
+       struct p4_pebs_bind *bind;
+       unsigned int idx;
+
+       BUILD_BUG_ON(P4_PEBS_METRIC__max > P4_PEBS_CONFIG_METRIC_MASK);
+
+       idx = p4_config_unpack_metric(config);
+       if (idx == P4_PEBS_METRIC__none)
+               return;
+
+       bind = &p4_pebs_bind_map[idx];
+
+       (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE,     (u64)bind->metric_pebs);
+       (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT,  (u64)bind->metric_vert);
 }
 
 static void p4_pmu_enable_event(struct perf_event *event)
@@ -515,9 +598,7 @@ static void p4_pmu_enable_event(struct perf_event *event)
        int thread = p4_ht_config_thread(hwc->config);
        u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
        unsigned int idx = p4_config_unpack_event(hwc->config);
-       unsigned int idx_cache = p4_config_unpack_cache_event(hwc->config);
        struct p4_event_bind *bind;
-       struct p4_cache_event_bind *bind_cache;
        u64 escr_addr, cccr;
 
        bind = &p4_event_bind_map[idx];
@@ -537,16 +618,10 @@ static void p4_pmu_enable_event(struct perf_event *event)
        cccr = p4_config_unpack_cccr(hwc->config);
 
        /*
-        * it could be Cache event so that we need to
-        * set metrics into additional MSRs
+        * it could be Cache event so we need to write metrics
+        * into additional MSRs
         */
-       BUILD_BUG_ON(P4_CACHE__MAX > P4_CCCR_CACHE_OPS_MASK);
-       if (idx_cache > P4_CACHE__NONE &&
-               idx_cache < ARRAY_SIZE(p4_cache_event_bind_map)) {
-               bind_cache = &p4_cache_event_bind_map[idx_cache];
-               (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind_cache->metric_pebs);
-               (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind_cache->metric_vert);
-       }
+       p4_pmu_enable_pebs(hwc->config);
 
        (void)checking_wrmsrl(escr_addr, escr_conf);
        (void)checking_wrmsrl(hwc->config_base + hwc->idx,
@@ -829,6 +904,15 @@ static __initconst const struct x86_pmu p4_pmu = {
        .max_period             = (1ULL << 39) - 1,
        .hw_config              = p4_hw_config,
        .schedule_events        = p4_pmu_schedule_events,
+       /*
+        * This handles erratum N15 in intel doc 249199-029,
+        * the counter may not be updated correctly on write
+        * so we need a second write operation to do the trick
+        * (the official workaround didn't work)
+        *
+        * the former idea is taken from OProfile code
+        */
+       .perfctr_second_write   = 1,
 };
 
 static __init int p4_pmu_init(void)
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
new file mode 100644 (file)
index 0000000..34b4dad
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *     Routines to indentify additional cpu features that are scattered in
+ *     cpuid space.
+ */
+#include <linux/cpu.h>
+
+#include <asm/pat.h>
+#include <asm/processor.h>
+
+#include <asm/apic.h>
+
+struct cpuid_bit {
+       u16 feature;
+       u8 reg;
+       u8 bit;
+       u32 level;
+       u32 sub_leaf;
+};
+
+enum cpuid_regs {
+       CR_EAX = 0,
+       CR_ECX,
+       CR_EDX,
+       CR_EBX
+};
+
+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+{
+       u32 max_level;
+       u32 regs[4];
+       const struct cpuid_bit *cb;
+
+       static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
+               { X86_FEATURE_IDA,              CR_EAX, 1, 0x00000006, 0 },
+               { X86_FEATURE_ARAT,             CR_EAX, 2, 0x00000006, 0 },
+               { X86_FEATURE_PLN,              CR_EAX, 4, 0x00000006, 0 },
+               { X86_FEATURE_PTS,              CR_EAX, 6, 0x00000006, 0 },
+               { X86_FEATURE_APERFMPERF,       CR_ECX, 0, 0x00000006, 0 },
+               { X86_FEATURE_EPB,              CR_ECX, 3, 0x00000006, 0 },
+               { X86_FEATURE_XSAVEOPT,         CR_EAX, 0, 0x0000000d, 1 },
+               { X86_FEATURE_CPB,              CR_EDX, 9, 0x80000007, 0 },
+               { X86_FEATURE_NPT,              CR_EDX, 0, 0x8000000a, 0 },
+               { X86_FEATURE_LBRV,             CR_EDX, 1, 0x8000000a, 0 },
+               { X86_FEATURE_SVML,             CR_EDX, 2, 0x8000000a, 0 },
+               { X86_FEATURE_NRIPS,            CR_EDX, 3, 0x8000000a, 0 },
+               { 0, 0, 0, 0, 0 }
+       };
+
+       for (cb = cpuid_bits; cb->feature; cb++) {
+
+               /* Verify that the level is valid */
+               max_level = cpuid_eax(cb->level & 0xffff0000);
+               if (max_level < cb->level ||
+                   max_level > (cb->level | 0xffff))
+                       continue;
+
+               cpuid_count(cb->level, cb->sub_leaf, &regs[CR_EAX],
+                           &regs[CR_EBX], &regs[CR_ECX], &regs[CR_EDX]);
+
+               if (regs[cb->reg] & (1 << cb->bit))
+                       set_cpu_cap(c, cb->feature);
+       }
+}
similarity index 66%
rename from arch/x86/kernel/cpu/addon_cpuid_features.c
rename to arch/x86/kernel/cpu/topology.c
index 10fa5684a6628e5e095a698d8bc8065748bc4534..4397e987a1cfbc062dbf087e7d6a5b6577abeafb 100644 (file)
@@ -1,62 +1,14 @@
 /*
- *     Routines to indentify additional cpu features that are scattered in
- *     cpuid space.
+ * Check for extended topology enumeration cpuid leaf 0xb and if it
+ * exists, use it for populating initial_apicid and cpu topology
+ * detection.
  */
-#include <linux/cpu.h>
 
+#include <linux/cpu.h>
+#include <asm/apic.h>
 #include <asm/pat.h>
 #include <asm/processor.h>
 
-#include <asm/apic.h>
-
-struct cpuid_bit {
-       u16 feature;
-       u8 reg;
-       u8 bit;
-       u32 level;
-};
-
-enum cpuid_regs {
-       CR_EAX = 0,
-       CR_ECX,
-       CR_EDX,
-       CR_EBX
-};
-
-void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
-{
-       u32 max_level;
-       u32 regs[4];
-       const struct cpuid_bit *cb;
-
-       static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
-               { X86_FEATURE_IDA,              CR_EAX, 1, 0x00000006 },
-               { X86_FEATURE_ARAT,             CR_EAX, 2, 0x00000006 },
-               { X86_FEATURE_APERFMPERF,       CR_ECX, 0, 0x00000006 },
-               { X86_FEATURE_CPB,              CR_EDX, 9, 0x80000007 },
-               { X86_FEATURE_NPT,              CR_EDX, 0, 0x8000000a },
-               { X86_FEATURE_LBRV,             CR_EDX, 1, 0x8000000a },
-               { X86_FEATURE_SVML,             CR_EDX, 2, 0x8000000a },
-               { X86_FEATURE_NRIPS,            CR_EDX, 3, 0x8000000a },
-               { 0, 0, 0, 0 }
-       };
-
-       for (cb = cpuid_bits; cb->feature; cb++) {
-
-               /* Verify that the level is valid */
-               max_level = cpuid_eax(cb->level & 0xffff0000);
-               if (max_level < cb->level ||
-                   max_level > (cb->level | 0xffff))
-                       continue;
-
-               cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
-                       &regs[CR_ECX], &regs[CR_EDX]);
-
-               if (regs[cb->reg] & (1 << cb->bit))
-                       set_cpu_cap(c, cb->feature);
-       }
-}
-
 /* leaf 0xb SMT level */
 #define SMT_LEVEL      0
 
index b9d1ff588445db7659ffd3d4d0e4414e846081d6..227b0448960d6076d5034e57a10d2d85d7fc13df 100644 (file)
@@ -51,7 +51,7 @@ static inline int __vmware_platform(void)
 
 static unsigned long vmware_get_tsc_khz(void)
 {
-       uint64_t tsc_hz;
+       uint64_t tsc_hz, lpj;
        uint32_t eax, ebx, ecx, edx;
 
        VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
@@ -62,6 +62,13 @@ static unsigned long vmware_get_tsc_khz(void)
        printk(KERN_INFO "TSC freq read from hypervisor : %lu.%03lu MHz\n",
                         (unsigned long) tsc_hz / 1000,
                         (unsigned long) tsc_hz % 1000);
+
+       if (!preset_lpj) {
+               lpj = ((u64)tsc_hz * 1000);
+               do_div(lpj, HZ);
+               preset_lpj = lpj;
+       }
+
        return tsc_hz;
 }
 
index c89a386930b7f4d9bc9c74dc0fa0151056860493..6e8752c1bd5241fc9e7e63ee088f06c84d0526fb 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <asm/stacktrace.h>
 
-#include "dumpstack.h"
 
 int panic_on_unrecovered_nmi;
 int panic_on_io_nmi;
diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h
deleted file mode 100644 (file)
index e1a93be..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
- */
-
-#ifndef DUMPSTACK_H
-#define DUMPSTACK_H
-
-#ifdef CONFIG_X86_32
-#define STACKSLOTS_PER_LINE 8
-#define get_bp(bp) asm("movl %%ebp, %0" : "=r" (bp) :)
-#else
-#define STACKSLOTS_PER_LINE 4
-#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
-#endif
-
-#include <linux/uaccess.h>
-
-extern void
-show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
-               unsigned long *stack, unsigned long bp, char *log_lvl);
-
-extern void
-show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
-               unsigned long *sp, unsigned long bp, char *log_lvl);
-
-extern unsigned int code_bytes;
-
-/* The form of the top of the frame on the stack */
-struct stack_frame {
-       struct stack_frame *next_frame;
-       unsigned long return_address;
-};
-
-struct stack_frame_ia32 {
-    u32 next_frame;
-    u32 return_address;
-};
-
-static inline unsigned long rewind_frame_pointer(int n)
-{
-       struct stack_frame *frame;
-
-       get_bp(frame);
-
-#ifdef CONFIG_FRAME_POINTER
-       while (n--) {
-               if (probe_kernel_address(&frame->next_frame, frame))
-                       break;
-       }
-#endif
-
-       return (unsigned long)frame;
-}
-
-#endif /* DUMPSTACK_H */
index 11540a189d9311e6a0fb4c44e685fc82799fdd0e..0f6376ffa2d9b6da338a6145c38f8b3307fa6e36 100644 (file)
@@ -16,8 +16,6 @@
 
 #include <asm/stacktrace.h>
 
-#include "dumpstack.h"
-
 
 void dump_trace(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp,
index 272c9f1f05f31bf20492dfb6be35bed716be26b1..57a21f11c791b38a2b88559349cd041935e262da 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <asm/stacktrace.h>
 
-#include "dumpstack.h"
 
 #define N_EXCEPTION_STACKS_END \
                (N_EXCEPTION_STACKS + DEBUG_STKSZ/EXCEPTION_STKSZ - 2)
index cd49141cf153fb124dc46a6497dbc863a3c81ad9..227d00920d2f8eaa1d90340ced0261ffe0a8f859 100644 (file)
@@ -611,14 +611,14 @@ ldt_ss:
  * compensating for the offset by changing to the ESPFIX segment with
  * a base address that matches for the difference.
  */
+#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
        mov %esp, %edx                  /* load kernel esp */
        mov PT_OLDESP(%esp), %eax       /* load userspace esp */
        mov %dx, %ax                    /* eax: new kernel esp */
        sub %eax, %edx                  /* offset (low word is 0) */
-       PER_CPU(gdt_page, %ebx)
        shr $16, %edx
-       mov %dl, GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx) /* bits 16..23 */
-       mov %dh, GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx) /* bits 24..31 */
+       mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
+       mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
        pushl $__ESPFIX_SS
        CFI_ADJUST_CFA_OFFSET 4
        push %eax                       /* new kernel esp */
@@ -791,9 +791,8 @@ ptregs_clone:
  * normal stack and adjusts ESP with the matching offset.
  */
        /* fixup the stack */
-       PER_CPU(gdt_page, %ebx)
-       mov GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx), %al /* bits 16..23 */
-       mov GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx), %ah /* bits 24..31 */
+       mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
+       mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
        shl $16, %eax
        addl %esp, %eax                 /* the adjusted stack pointer */
        pushl $__KERNEL_DS
@@ -914,7 +913,7 @@ ENTRY(simd_coprocessor_error)
        .balign 4
        .long 661b
        .long 663f
-       .byte X86_FEATURE_XMM
+       .word X86_FEATURE_XMM
        .byte 662b-661b
        .byte 664f-663f
 .previous
@@ -1166,6 +1165,9 @@ ENTRY(xen_failsafe_callback)
 .previous
 ENDPROC(xen_failsafe_callback)
 
+BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
+               xen_evtchn_do_upcall)
+
 #endif /* CONFIG_XEN */
 
 #ifdef CONFIG_FUNCTION_TRACER
index 4db7c4d12ffacb0ac5bdfe8d26c2ee1c181e52fc..c5ea5cdbe7b3d86a927f82835147c42c6d93fabf 100644 (file)
@@ -1065,6 +1065,7 @@ ENTRY(\sym)
 END(\sym)
 .endm
 
+#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
 .macro paranoidzeroentry_ist sym do_sym ist
 ENTRY(\sym)
        INTR_FRAME
@@ -1076,10 +1077,9 @@ ENTRY(\sym)
        TRACE_IRQS_OFF
        movq %rsp,%rdi          /* pt_regs pointer */
        xorl %esi,%esi          /* no error code */
-       PER_CPU(init_tss, %r12)
-       subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
+       subq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
        call \do_sym
-       addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
+       addq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
        jmp paranoid_exit       /* %ebx: no swapgs flag */
        CFI_ENDPROC
 END(\sym)
@@ -1329,6 +1329,9 @@ ENTRY(xen_failsafe_callback)
        CFI_ENDPROC
 END(xen_failsafe_callback)
 
+apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
+       xen_hvm_callback_vector xen_evtchn_do_upcall
+
 #endif /* CONFIG_XEN */
 
 /*
index 37c3d4b17d859d6ee38029a83f2abcaee6d4dc05..ff4c453e13f3807344fff90bd2741078dc90481c 100644 (file)
@@ -131,6 +131,12 @@ ENTRY(startup_32)
        movsl
 1:
 
+#ifdef CONFIG_OLPC_OPENFIRMWARE
+       /* save OFW's pgdir table for later use when calling into OFW */
+       movl %cr3, %eax
+       movl %eax, pa(olpc_ofw_pgd)
+#endif
+
 #ifdef CONFIG_PARAVIRT
        /* This is can only trip for a broken bootloader... */
        cmpw $0x207, pa(boot_params + BP_version)
index 3d1e6f16b7a6cbaa92761bede7d9c20b73b8c178..239046bd447f9320d92fb0832cac6eeac4335685 100644 (file)
@@ -234,9 +234,8 @@ ENTRY(secondary_startup_64)
         * init data section till per cpu areas are set up.
         */
        movl    $MSR_GS_BASE,%ecx
-       movq    initial_gs(%rip),%rax
-       movq    %rax,%rdx
-       shrq    $32,%rdx
+       movl    initial_gs(%rip),%eax
+       movl    initial_gs+4(%rip),%edx
        wrmsr   
 
        /* esi is pointer to real mode structure with interesting info.
index ba390d731175a492686643dd873786eafda9521b..33dbcc4ec5ff285435c7c184be50e485c58a9ca2 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/hpet.h>
 
 #define HPET_MASK                      CLOCKSOURCE_MASK(32)
-#define HPET_SHIFT                     22
 
 /* FSEC = 10^-15
    NSEC = 10^-9 */
@@ -787,7 +786,6 @@ static struct clocksource clocksource_hpet = {
        .rating         = 250,
        .read           = read_hpet,
        .mask           = HPET_MASK,
-       .shift          = HPET_SHIFT,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
        .resume         = hpet_resume_counter,
 #ifdef CONFIG_X86_64
@@ -798,6 +796,7 @@ static struct clocksource clocksource_hpet = {
 static int hpet_clocksource_register(void)
 {
        u64 start, now;
+       u64 hpet_freq;
        cycle_t t1;
 
        /* Start the counter */
@@ -832,9 +831,15 @@ static int hpet_clocksource_register(void)
         *  mult = (hpet_period * 2^shift)/10^6
         *  mult = (hpet_period << shift)/FSEC_PER_NSEC
         */
-       clocksource_hpet.mult = div_sc(hpet_period, FSEC_PER_NSEC, HPET_SHIFT);
 
-       clocksource_register(&clocksource_hpet);
+       /* Need to convert hpet_period (fsec/cyc) to cyc/sec:
+        *
+        * cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc)
+        * cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period
+        */
+       hpet_freq = FSEC_PER_NSEC * NSEC_PER_SEC;
+       do_div(hpet_freq, hpet_period);
+       clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
 
        return 0;
 }
index a8f1b803d2fd916c7aacf4952ff33b620f790852..a474ec37c32f84df372d39eac5730532d60d0228 100644 (file)
@@ -208,6 +208,9 @@ int arch_bp_generic_fields(int x86_len, int x86_type,
 {
        /* Len */
        switch (x86_len) {
+       case X86_BREAKPOINT_LEN_X:
+               *gen_len = sizeof(long);
+               break;
        case X86_BREAKPOINT_LEN_1:
                *gen_len = HW_BREAKPOINT_LEN_1;
                break;
@@ -251,6 +254,29 @@ static int arch_build_bp_info(struct perf_event *bp)
 
        info->address = bp->attr.bp_addr;
 
+       /* Type */
+       switch (bp->attr.bp_type) {
+       case HW_BREAKPOINT_W:
+               info->type = X86_BREAKPOINT_WRITE;
+               break;
+       case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
+               info->type = X86_BREAKPOINT_RW;
+               break;
+       case HW_BREAKPOINT_X:
+               info->type = X86_BREAKPOINT_EXECUTE;
+               /*
+                * x86 inst breakpoints need to have a specific undefined len.
+                * But we still need to check userspace is not trying to setup
+                * an unsupported length, to get a range breakpoint for example.
+                */
+               if (bp->attr.bp_len == sizeof(long)) {
+                       info->len = X86_BREAKPOINT_LEN_X;
+                       return 0;
+               }
+       default:
+               return -EINVAL;
+       }
+
        /* Len */
        switch (bp->attr.bp_len) {
        case HW_BREAKPOINT_LEN_1:
@@ -271,21 +297,6 @@ static int arch_build_bp_info(struct perf_event *bp)
                return -EINVAL;
        }
 
-       /* Type */
-       switch (bp->attr.bp_type) {
-       case HW_BREAKPOINT_W:
-               info->type = X86_BREAKPOINT_WRITE;
-               break;
-       case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
-               info->type = X86_BREAKPOINT_RW;
-               break;
-       case HW_BREAKPOINT_X:
-               info->type = X86_BREAKPOINT_EXECUTE;
-               break;
-       default:
-               return -EINVAL;
-       }
-
        return 0;
 }
 /*
@@ -305,6 +316,9 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
        ret = -EINVAL;
 
        switch (info->len) {
+       case X86_BREAKPOINT_LEN_X:
+               align = sizeof(long) -1;
+               break;
        case X86_BREAKPOINT_LEN_1:
                align = 0;
                break;
@@ -466,6 +480,13 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
 
                perf_bp_event(bp, args->regs);
 
+               /*
+                * Set up resume flag to avoid breakpoint recursion when
+                * returning back to origin.
+                */
+               if (bp->hw.info.type == X86_BREAKPOINT_EXECUTE)
+                       args->regs->flags |= X86_EFLAGS_RF;
+
                rcu_read_unlock();
        }
        /*
index c4444bce8469876b2a4a43089cad8a97c3198b73..1f11f5ce668f93aadff67c425fae359da6efc6a8 100644 (file)
@@ -59,18 +59,18 @@ void __cpuinit mxcsr_feature_mask_init(void)
        stts();
 }
 
-void __cpuinit init_thread_xstate(void)
+static void __cpuinit init_thread_xstate(void)
 {
+       /*
+        * Note that xstate_size might be overwriten later during
+        * xsave_init().
+        */
+
        if (!HAVE_HWFP) {
                xstate_size = sizeof(struct i387_soft_struct);
                return;
        }
 
-       if (cpu_has_xsave) {
-               xsave_cntxt_init();
-               return;
-       }
-
        if (cpu_has_fxsr)
                xstate_size = sizeof(struct i387_fxsave_struct);
 #ifdef CONFIG_X86_32
@@ -84,6 +84,7 @@ void __cpuinit init_thread_xstate(void)
  * Called at bootup to set up the initial FPU state that is later cloned
  * into all processes.
  */
+
 void __cpuinit fpu_init(void)
 {
        unsigned long oldcr0 = read_cr0();
@@ -93,19 +94,24 @@ void __cpuinit fpu_init(void)
 
        write_cr0(oldcr0 & ~(X86_CR0_TS|X86_CR0_EM)); /* clear TS and EM */
 
-       /*
-        * Boot processor to setup the FP and extended state context info.
-        */
        if (!smp_processor_id())
                init_thread_xstate();
-       xsave_init();
 
        mxcsr_feature_mask_init();
        /* clean state in init */
        current_thread_info()->status = 0;
        clear_used_math();
 }
-#endif /* CONFIG_X86_64 */
+
+#else  /* CONFIG_X86_64 */
+
+void __cpuinit fpu_init(void)
+{
+       if (!smp_processor_id())
+               init_thread_xstate();
+}
+
+#endif /* CONFIG_X86_32 */
 
 void fpu_finit(struct fpu *fpu)
 {
@@ -191,6 +197,8 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
        if (ret)
                return ret;
 
+       sanitize_i387_state(target);
+
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                   &target->thread.fpu.state->fxsave, 0, -1);
 }
@@ -208,6 +216,8 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
        if (ret)
                return ret;
 
+       sanitize_i387_state(target);
+
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 &target->thread.fpu.state->fxsave, 0, -1);
 
@@ -447,6 +457,8 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
                                           -1);
        }
 
+       sanitize_i387_state(target);
+
        if (kbuf && pos == 0 && count == sizeof(env)) {
                convert_from_fxsr(kbuf, target);
                return 0;
@@ -468,6 +480,8 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
        if (ret)
                return ret;
 
+       sanitize_i387_state(target);
+
        if (!HAVE_HWFP)
                return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
 
@@ -534,6 +548,9 @@ static int save_i387_xsave(void __user *buf)
        struct _fpstate_ia32 __user *fx = buf;
        int err = 0;
 
+
+       sanitize_i387_state(tsk);
+
        /*
         * For legacy compatible, we always set FP/SSE bits in the bit
         * vector while saving the state to the user context.
index 01ab17ae2ae72c7bdf2d2c4de2a51f19f59755bf..ef10940e1af0534e18c88635d79e25eff73797cf 100644 (file)
 #include <asm/system.h>
 #include <asm/apic.h>
 
-/**
- *     pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs
- *     @gdb_regs: A pointer to hold the registers in the order GDB wants.
- *     @regs: The &struct pt_regs of the current process.
- *
- *     Convert the pt_regs in @regs into the format for registers that
- *     GDB expects, stored in @gdb_regs.
- */
-void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
 {
-#ifndef CONFIG_X86_32
-       u32 *gdb_regs32 = (u32 *)gdb_regs;
+#ifdef CONFIG_X86_32
+       { "ax", 4, offsetof(struct pt_regs, ax) },
+       { "cx", 4, offsetof(struct pt_regs, cx) },
+       { "dx", 4, offsetof(struct pt_regs, dx) },
+       { "bx", 4, offsetof(struct pt_regs, bx) },
+       { "sp", 4, offsetof(struct pt_regs, sp) },
+       { "bp", 4, offsetof(struct pt_regs, bp) },
+       { "si", 4, offsetof(struct pt_regs, si) },
+       { "di", 4, offsetof(struct pt_regs, di) },
+       { "ip", 4, offsetof(struct pt_regs, ip) },
+       { "flags", 4, offsetof(struct pt_regs, flags) },
+       { "cs", 4, offsetof(struct pt_regs, cs) },
+       { "ss", 4, offsetof(struct pt_regs, ss) },
+       { "ds", 4, offsetof(struct pt_regs, ds) },
+       { "es", 4, offsetof(struct pt_regs, es) },
+       { "fs", 4, -1 },
+       { "gs", 4, -1 },
+#else
+       { "ax", 8, offsetof(struct pt_regs, ax) },
+       { "bx", 8, offsetof(struct pt_regs, bx) },
+       { "cx", 8, offsetof(struct pt_regs, cx) },
+       { "dx", 8, offsetof(struct pt_regs, dx) },
+       { "si", 8, offsetof(struct pt_regs, dx) },
+       { "di", 8, offsetof(struct pt_regs, di) },
+       { "bp", 8, offsetof(struct pt_regs, bp) },
+       { "sp", 8, offsetof(struct pt_regs, sp) },
+       { "r8", 8, offsetof(struct pt_regs, r8) },
+       { "r9", 8, offsetof(struct pt_regs, r9) },
+       { "r10", 8, offsetof(struct pt_regs, r10) },
+       { "r11", 8, offsetof(struct pt_regs, r11) },
+       { "r12", 8, offsetof(struct pt_regs, r12) },
+       { "r13", 8, offsetof(struct pt_regs, r13) },
+       { "r14", 8, offsetof(struct pt_regs, r14) },
+       { "r15", 8, offsetof(struct pt_regs, r15) },
+       { "ip", 8, offsetof(struct pt_regs, ip) },
+       { "flags", 4, offsetof(struct pt_regs, flags) },
+       { "cs", 4, offsetof(struct pt_regs, cs) },
+       { "ss", 4, offsetof(struct pt_regs, ss) },
 #endif
-       gdb_regs[GDB_AX]        = regs->ax;
-       gdb_regs[GDB_BX]        = regs->bx;
-       gdb_regs[GDB_CX]        = regs->cx;
-       gdb_regs[GDB_DX]        = regs->dx;
-       gdb_regs[GDB_SI]        = regs->si;
-       gdb_regs[GDB_DI]        = regs->di;
-       gdb_regs[GDB_BP]        = regs->bp;
-       gdb_regs[GDB_PC]        = regs->ip;
+};
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       if (
 #ifdef CONFIG_X86_32
-       gdb_regs[GDB_PS]        = regs->flags;
-       gdb_regs[GDB_DS]        = regs->ds;
-       gdb_regs[GDB_ES]        = regs->es;
-       gdb_regs[GDB_CS]        = regs->cs;
-       gdb_regs[GDB_FS]        = 0xFFFF;
-       gdb_regs[GDB_GS]        = 0xFFFF;
-       if (user_mode_vm(regs)) {
-               gdb_regs[GDB_SS] = regs->ss;
-               gdb_regs[GDB_SP] = regs->sp;
-       } else {
-               gdb_regs[GDB_SS] = __KERNEL_DS;
-               gdb_regs[GDB_SP] = kernel_stack_pointer(regs);
+           regno == GDB_SS || regno == GDB_FS || regno == GDB_GS ||
+#endif
+           regno == GDB_SP || regno == GDB_ORIG_AX)
+               return 0;
+
+       if (dbg_reg_def[regno].offset != -1)
+               memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+                      dbg_reg_def[regno].size);
+       return 0;
+}
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       if (regno == GDB_ORIG_AX) {
+               memcpy(mem, &regs->orig_ax, sizeof(regs->orig_ax));
+               return "orig_ax";
        }
-#else
-       gdb_regs[GDB_R8]        = regs->r8;
-       gdb_regs[GDB_R9]        = regs->r9;
-       gdb_regs[GDB_R10]       = regs->r10;
-       gdb_regs[GDB_R11]       = regs->r11;
-       gdb_regs[GDB_R12]       = regs->r12;
-       gdb_regs[GDB_R13]       = regs->r13;
-       gdb_regs[GDB_R14]       = regs->r14;
-       gdb_regs[GDB_R15]       = regs->r15;
-       gdb_regs32[GDB_PS]      = regs->flags;
-       gdb_regs32[GDB_CS]      = regs->cs;
-       gdb_regs32[GDB_SS]      = regs->ss;
-       gdb_regs[GDB_SP]        = kernel_stack_pointer(regs);
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return NULL;
+
+       if (dbg_reg_def[regno].offset != -1)
+               memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+                      dbg_reg_def[regno].size);
+
+       switch (regno) {
+#ifdef CONFIG_X86_32
+       case GDB_SS:
+               if (!user_mode_vm(regs))
+                       *(unsigned long *)mem = __KERNEL_DS;
+               break;
+       case GDB_SP:
+               if (!user_mode_vm(regs))
+                       *(unsigned long *)mem = kernel_stack_pointer(regs);
+               break;
+       case GDB_GS:
+       case GDB_FS:
+               *(unsigned long *)mem = 0xFFFF;
+               break;
 #endif
+       }
+       return dbg_reg_def[regno].name;
 }
 
 /**
@@ -150,54 +189,13 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
        gdb_regs[GDB_SP]        = p->thread.sp;
 }
 
-/**
- *     gdb_regs_to_pt_regs - Convert GDB regs to ptrace regs.
- *     @gdb_regs: A pointer to hold the registers we've received from GDB.
- *     @regs: A pointer to a &struct pt_regs to hold these values in.
- *
- *     Convert the GDB regs in @gdb_regs into the pt_regs, and store them
- *     in @regs.
- */
-void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
-#ifndef CONFIG_X86_32
-       u32 *gdb_regs32 = (u32 *)gdb_regs;
-#endif
-       regs->ax                = gdb_regs[GDB_AX];
-       regs->bx                = gdb_regs[GDB_BX];
-       regs->cx                = gdb_regs[GDB_CX];
-       regs->dx                = gdb_regs[GDB_DX];
-       regs->si                = gdb_regs[GDB_SI];
-       regs->di                = gdb_regs[GDB_DI];
-       regs->bp                = gdb_regs[GDB_BP];
-       regs->ip                = gdb_regs[GDB_PC];
-#ifdef CONFIG_X86_32
-       regs->flags             = gdb_regs[GDB_PS];
-       regs->ds                = gdb_regs[GDB_DS];
-       regs->es                = gdb_regs[GDB_ES];
-       regs->cs                = gdb_regs[GDB_CS];
-#else
-       regs->r8                = gdb_regs[GDB_R8];
-       regs->r9                = gdb_regs[GDB_R9];
-       regs->r10               = gdb_regs[GDB_R10];
-       regs->r11               = gdb_regs[GDB_R11];
-       regs->r12               = gdb_regs[GDB_R12];
-       regs->r13               = gdb_regs[GDB_R13];
-       regs->r14               = gdb_regs[GDB_R14];
-       regs->r15               = gdb_regs[GDB_R15];
-       regs->flags             = gdb_regs32[GDB_PS];
-       regs->cs                = gdb_regs32[GDB_CS];
-       regs->ss                = gdb_regs32[GDB_SS];
-#endif
-}
-
 static struct hw_breakpoint {
        unsigned                enabled;
        unsigned long           addr;
        int                     len;
        int                     type;
        struct perf_event       **pev;
-} breakinfo[4];
+} breakinfo[HBP_NUM];
 
 static unsigned long early_dr7;
 
@@ -205,7 +203,7 @@ static void kgdb_correct_hw_break(void)
 {
        int breakno;
 
-       for (breakno = 0; breakno < 4; breakno++) {
+       for (breakno = 0; breakno < HBP_NUM; breakno++) {
                struct perf_event *bp;
                struct arch_hw_breakpoint *info;
                int val;
@@ -292,10 +290,10 @@ kgdb_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
 {
        int i;
 
-       for (i = 0; i < 4; i++)
+       for (i = 0; i < HBP_NUM; i++)
                if (breakinfo[i].addr == addr && breakinfo[i].enabled)
                        break;
-       if (i == 4)
+       if (i == HBP_NUM)
                return -1;
 
        if (hw_break_release_slot(i)) {
@@ -313,7 +311,7 @@ static void kgdb_remove_all_hw_break(void)
        int cpu = raw_smp_processor_id();
        struct perf_event *bp;
 
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < HBP_NUM; i++) {
                if (!breakinfo[i].enabled)
                        continue;
                bp = *per_cpu_ptr(breakinfo[i].pev, cpu);
@@ -333,10 +331,10 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
 {
        int i;
 
-       for (i = 0; i < 4; i++)
+       for (i = 0; i < HBP_NUM; i++)
                if (!breakinfo[i].enabled)
                        break;
-       if (i == 4)
+       if (i == HBP_NUM)
                return -1;
 
        switch (bptype) {
@@ -397,7 +395,7 @@ void kgdb_disable_hw_debug(struct pt_regs *regs)
 
        /* Disable hardware debugging while we are in kgdb: */
        set_debugreg(0UL, 7);
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < HBP_NUM; i++) {
                if (!breakinfo[i].enabled)
                        continue;
                if (dbg_is_early) {
@@ -458,7 +456,6 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
 {
        unsigned long addr;
        char *ptr;
-       int newPC;
 
        switch (remcomInBuffer[0]) {
        case 'c':
@@ -469,8 +466,6 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
                        linux_regs->ip = addr;
        case 'D':
        case 'k':
-               newPC = linux_regs->ip;
-
                /* clear the trace bit */
                linux_regs->flags &= ~X86_EFLAGS_TF;
                atomic_set(&kgdb_cpu_doing_single_step, -1);
@@ -645,7 +640,7 @@ void kgdb_arch_late(void)
        attr.bp_len = HW_BREAKPOINT_LEN_1;
        attr.bp_type = HW_BREAKPOINT_W;
        attr.disabled = 1;
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < HBP_NUM; i++) {
                if (breakinfo[i].pev)
                        continue;
                breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL);
index 675879b65ce666c91b868c96972ea35f107810f4..1bfb6cf4dd55d67aeeebbbf89d0bb60283a94c94 100644 (file)
@@ -126,16 +126,22 @@ static void __kprobes synthesize_reljump(void *from, void *to)
 }
 
 /*
- * Check for the REX prefix which can only exist on X86_64
- * X86_32 always returns 0
+ * Skip the prefixes of the instruction.
  */
-static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
+static kprobe_opcode_t *__kprobes skip_prefixes(kprobe_opcode_t *insn)
 {
+       insn_attr_t attr;
+
+       attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+       while (inat_is_legacy_prefix(attr)) {
+               insn++;
+               attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+       }
 #ifdef CONFIG_X86_64
-       if ((*insn & 0xf0) == 0x40)
-               return 1;
+       if (inat_is_rex_prefix(attr))
+               insn++;
 #endif
-       return 0;
+       return insn;
 }
 
 /*
@@ -272,6 +278,9 @@ static int __kprobes can_probe(unsigned long paddr)
  */
 static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
 {
+       /* Skip prefixes */
+       insn = skip_prefixes(insn);
+
        switch (*insn) {
        case 0xfa:              /* cli */
        case 0xfb:              /* sti */
@@ -280,13 +289,6 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
                return 1;
        }
 
-       /*
-        * on X86_64, 0x40-0x4f are REX prefixes so we need to look
-        * at the next byte instead.. but of course not recurse infinitely
-        */
-       if (is_REX_prefix(insn))
-               return is_IF_modifier(++insn);
-
        return 0;
 }
 
@@ -803,9 +805,8 @@ static void __kprobes resume_execution(struct kprobe *p,
        unsigned long orig_ip = (unsigned long)p->addr;
        kprobe_opcode_t *insn = p->ainsn.insn;
 
-       /*skip the REX prefix*/
-       if (is_REX_prefix(insn))
-               insn++;
+       /* Skip prefixes */
+       insn = skip_prefixes(insn);
 
        regs->flags &= ~X86_EFLAGS_TF;
        switch (*insn) {
index 5915e0b333033471fa27c8056a6dae2795bbe6ee..79ae68154e871fe208ff5fcfd809daf3b03c4ab5 100644 (file)
 #include <asm/i8259.h>
 #include <asm/apb_timer.h>
 
+/*
+ * the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock,
+ * cmdline option x86_mrst_timer can be used to override the configuration
+ * to prefer one or the other.
+ * at runtime, there are basically three timer configurations:
+ * 1. per cpu apbt clock only
+ * 2. per cpu always-on lapic clocks only, this is Penwell/Medfield only
+ * 3. per cpu lapic clock (C3STOP) and one apbt clock, with broadcast.
+ *
+ * by default (without cmdline option), platform code first detects cpu type
+ * to see if we are on lincroft or penwell, then set up both lapic or apbt
+ * clocks accordingly.
+ * i.e. by default, medfield uses configuration #2, moorestown uses #1.
+ * config #3 is supported but not recommended on medfield.
+ *
+ * rating and feature summary:
+ * lapic (with C3STOP) --------- 100
+ * apbt (always-on) ------------ 110
+ * lapic (always-on,ARAT) ------ 150
+ */
+
+__cpuinitdata enum mrst_timer_options mrst_timer_options;
+
 static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
 static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
+enum mrst_cpu_type __mrst_cpu_chip;
+EXPORT_SYMBOL_GPL(__mrst_cpu_chip);
+
 int sfi_mtimer_num;
 
 struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
@@ -167,18 +193,6 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table)
        return 0;
 }
 
-/*
- * the secondary clock in Moorestown can be APBT or LAPIC clock, default to
- * APBT but cmdline option can also override it.
- */
-static void __cpuinit mrst_setup_secondary_clock(void)
-{
-       /* restore default lapic clock if disabled by cmdline */
-       if (disable_apbt_percpu)
-               return setup_secondary_APIC_clock();
-       apbt_setup_secondary_clock();
-}
-
 static unsigned long __init mrst_calibrate_tsc(void)
 {
        unsigned long flags, fast_calibrate;
@@ -195,6 +209,21 @@ static unsigned long __init mrst_calibrate_tsc(void)
 
 void __init mrst_time_init(void)
 {
+       switch (mrst_timer_options) {
+       case MRST_TIMER_APBT_ONLY:
+               break;
+       case MRST_TIMER_LAPIC_APBT:
+               x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock;
+               x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
+               break;
+       default:
+               if (!boot_cpu_has(X86_FEATURE_ARAT))
+                       break;
+               x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock;
+               x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
+               return;
+       }
+       /* we need at least one APB timer */
        sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr);
        pre_init_apic_IRQ0();
        apbt_time_init();
@@ -205,16 +234,21 @@ void __init mrst_rtc_init(void)
        sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
 }
 
-/*
- * if we use per cpu apb timer, the bootclock already setup. if we use lapic
- * timer and one apbt timer for broadcast, we need to set up lapic boot clock.
- */
-static void __init mrst_setup_boot_clock(void)
+void __cpuinit mrst_arch_setup(void)
 {
-       pr_info("%s: per cpu apbt flag %d \n", __func__, disable_apbt_percpu);
-       if (disable_apbt_percpu)
-               setup_boot_APIC_clock();
-};
+       if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x27)
+               __mrst_cpu_chip = MRST_CPU_CHIP_PENWELL;
+       else if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x26)
+               __mrst_cpu_chip = MRST_CPU_CHIP_LINCROFT;
+       else {
+               pr_err("Unknown Moorestown CPU (%d:%d), default to Lincroft\n",
+                       boot_cpu_data.x86, boot_cpu_data.x86_model);
+               __mrst_cpu_chip = MRST_CPU_CHIP_LINCROFT;
+       }
+       pr_debug("Moorestown CPU %s identified\n",
+               (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT) ?
+               "Lincroft" : "Penwell");
+}
 
 /* MID systems don't have i8042 controller */
 static int mrst_i8042_detect(void)
@@ -232,11 +266,13 @@ void __init x86_mrst_early_setup(void)
        x86_init.resources.reserve_resources = x86_init_noop;
 
        x86_init.timers.timer_init = mrst_time_init;
-       x86_init.timers.setup_percpu_clockev = mrst_setup_boot_clock;
+       x86_init.timers.setup_percpu_clockev = x86_init_noop;
 
        x86_init.irqs.pre_vector_init = x86_init_noop;
 
-       x86_cpuinit.setup_percpu_clockev = mrst_setup_secondary_clock;
+       x86_init.oem.arch_setup = mrst_arch_setup;
+
+       x86_cpuinit.setup_percpu_clockev = apbt_setup_secondary_clock;
 
        x86_platform.calibrate_tsc = mrst_calibrate_tsc;
        x86_platform.i8042_detect = mrst_i8042_detect;
@@ -250,3 +286,26 @@ void __init x86_mrst_early_setup(void)
        x86_init.mpparse.get_smp_config = x86_init_uint_noop;
 
 }
+
+/*
+ * if user does not want to use per CPU apb timer, just give it a lower rating
+ * than local apic timer and skip the late per cpu timer init.
+ */
+static inline int __init setup_x86_mrst_timer(char *arg)
+{
+       if (!arg)
+               return -EINVAL;
+
+       if (strcmp("apbt_only", arg) == 0)
+               mrst_timer_options = MRST_TIMER_APBT_ONLY;
+       else if (strcmp("lapic_and_apbt", arg) == 0)
+               mrst_timer_options = MRST_TIMER_LAPIC_APBT;
+       else {
+               pr_warning("X86 MRST timer option %s not recognised"
+                          " use x86_mrst_timer=apbt_only or lapic_and_apbt\n",
+                          arg);
+               return -EINVAL;
+       }
+       return 0;
+}
+__setup("x86_mrst_timer=", setup_x86_mrst_timer);
index 8297160c41b3949058e1a6a55bcb9979d0cfa88a..0e0cdde519be93a3cda8bab4ba6d8637632171ef 100644 (file)
 #include <asm/geode.h>
 #include <asm/setup.h>
 #include <asm/olpc.h>
-
-#ifdef CONFIG_OPEN_FIRMWARE
-#include <asm/ofw.h>
-#endif
+#include <asm/olpc_ofw.h>
 
 struct olpc_platform_t olpc_platform_info;
 EXPORT_SYMBOL_GPL(olpc_platform_info);
@@ -145,7 +142,7 @@ restart:
         * The OBF flag will sometimes misbehave due to what we believe
         * is a hardware quirk..
         */
-       printk(KERN_DEBUG "olpc-ec:  running cmd 0x%x\n", cmd);
+       pr_devel("olpc-ec:  running cmd 0x%x\n", cmd);
        outb(cmd, 0x6c);
 
        if (wait_on_ibf(0x6c, 0)) {
@@ -162,8 +159,7 @@ restart:
                                                " EC accept data!\n");
                                goto err;
                        }
-                       printk(KERN_DEBUG "olpc-ec:  sending cmd arg 0x%x\n",
-                                       inbuf[i]);
+                       pr_devel("olpc-ec:  sending cmd arg 0x%x\n", inbuf[i]);
                        outb(inbuf[i], 0x68);
                }
        }
@@ -176,8 +172,7 @@ restart:
                                goto restart;
                        }
                        outbuf[i] = inb(0x68);
-                       printk(KERN_DEBUG "olpc-ec:  received 0x%x\n",
-                                       outbuf[i]);
+                       pr_devel("olpc-ec:  received 0x%x\n", outbuf[i]);
                }
        }
 
@@ -188,14 +183,15 @@ err:
 }
 EXPORT_SYMBOL_GPL(olpc_ec_cmd);
 
-#ifdef CONFIG_OPEN_FIRMWARE
+#ifdef CONFIG_OLPC_OPENFIRMWARE
 static void __init platform_detect(void)
 {
        size_t propsize;
        __be32 rev;
+       const void *args[] = { NULL, "board-revision-int", &rev, (void *)4 };
+       void *res[] = { &propsize };
 
-       if (ofw("getprop", 4, 1, NULL, "board-revision-int", &rev, 4,
-                       &propsize) || propsize != 4) {
+       if (olpc_ofw("getprop", args, res) || propsize != 4) {
                printk(KERN_ERR "ofw: getprop call failed!\n");
                rev = cpu_to_be32(0);
        }
diff --git a/arch/x86/kernel/olpc_ofw.c b/arch/x86/kernel/olpc_ofw.c
new file mode 100644 (file)
index 0000000..3218aa7
--- /dev/null
@@ -0,0 +1,106 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/olpc_ofw.h>
+
+/* address of OFW callback interface; will be NULL if OFW isn't found */
+static int (*olpc_ofw_cif)(int *);
+
+/* page dir entry containing OFW's pgdir table; filled in by head_32.S */
+u32 olpc_ofw_pgd __initdata;
+
+static DEFINE_SPINLOCK(ofw_lock);
+
+#define MAXARGS 10
+
+void __init setup_olpc_ofw_pgd(void)
+{
+       pgd_t *base, *ofw_pde;
+
+       if (!olpc_ofw_cif)
+               return;
+
+       /* fetch OFW's PDE */
+       base = early_ioremap(olpc_ofw_pgd, sizeof(olpc_ofw_pgd) * PTRS_PER_PGD);
+       if (!base) {
+               printk(KERN_ERR "failed to remap OFW's pgd - disabling OFW!\n");
+               olpc_ofw_cif = NULL;
+               return;
+       }
+       ofw_pde = &base[OLPC_OFW_PDE_NR];
+
+       /* install OFW's PDE permanently into the kernel's pgtable */
+       set_pgd(&swapper_pg_dir[OLPC_OFW_PDE_NR], *ofw_pde);
+       /* implicit optimization barrier here due to uninline function return */
+
+       early_iounmap(base, sizeof(olpc_ofw_pgd) * PTRS_PER_PGD);
+}
+
+int __olpc_ofw(const char *name, int nr_args, const void **args, int nr_res,
+               void **res)
+{
+       int ofw_args[MAXARGS + 3];
+       unsigned long flags;
+       int ret, i, *p;
+
+       BUG_ON(nr_args + nr_res > MAXARGS);
+
+       if (!olpc_ofw_cif)
+               return -EIO;
+
+       ofw_args[0] = (int)name;
+       ofw_args[1] = nr_args;
+       ofw_args[2] = nr_res;
+
+       p = &ofw_args[3];
+       for (i = 0; i < nr_args; i++, p++)
+               *p = (int)args[i];
+
+       /* call into ofw */
+       spin_lock_irqsave(&ofw_lock, flags);
+       ret = olpc_ofw_cif(ofw_args);
+       spin_unlock_irqrestore(&ofw_lock, flags);
+
+       if (!ret) {
+               for (i = 0; i < nr_res; i++, p++)
+                       *((int *)res[i]) = *p;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__olpc_ofw);
+
+/* OFW cif _should_ be above this address */
+#define OFW_MIN 0xff000000
+
+/* OFW starts on a 1MB boundary */
+#define OFW_BOUND (1<<20)
+
+void __init olpc_ofw_detect(void)
+{
+       struct olpc_ofw_header *hdr = &boot_params.olpc_ofw_header;
+       unsigned long start;
+
+       /* ensure OFW booted us by checking for "OFW " string */
+       if (hdr->ofw_magic != OLPC_OFW_SIG)
+               return;
+
+       olpc_ofw_cif = (int (*)(int *))hdr->cif_handler;
+
+       if ((unsigned long)olpc_ofw_cif < OFW_MIN) {
+               printk(KERN_ERR "OFW detected, but cif has invalid address 0x%lx - disabling.\n",
+                               (unsigned long)olpc_ofw_cif);
+               olpc_ofw_cif = NULL;
+               return;
+       }
+
+       /* determine where OFW starts in memory */
+       start = round_down((unsigned long)olpc_ofw_cif, OFW_BOUND);
+       printk(KERN_INFO "OFW detected in memory, cif @ 0x%lx (reserving top %ldMB)\n",
+                       (unsigned long)olpc_ofw_cif, (-start) >> 20);
+       reserve_top_address(-start);
+}
index cbcf013a0ec6b4e384f4d7acf4756ea3958326a8..d401f1d2d06ef47c1dba0a33f86679a33ab24fa9 100644 (file)
@@ -526,44 +526,10 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
        return (edx & MWAIT_EDX_C1);
 }
 
-/*
- * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e.
- * For more information see
- * - Erratum #400 for NPT family 0xf and family 0x10 CPUs
- * - Erratum #365 for family 0x11 (not affected because C1e not in use)
- */
-static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
-{
-       u64 val;
-       if (c->x86_vendor != X86_VENDOR_AMD)
-               goto no_c1e_idle;
-
-       /* Family 0x0f models < rev F do not have C1E */
-       if (c->x86 == 0x0F && c->x86_model >= 0x40)
-               return 1;
-
-       if (c->x86 == 0x10) {
-               /*
-                * check OSVW bit for CPUs that are not affected
-                * by erratum #400
-                */
-               if (cpu_has(c, X86_FEATURE_OSVW)) {
-                       rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
-                       if (val >= 2) {
-                               rdmsrl(MSR_AMD64_OSVW_STATUS, val);
-                               if (!(val & BIT(1)))
-                                       goto no_c1e_idle;
-                       }
-               }
-               return 1;
-       }
-
-no_c1e_idle:
-       return 0;
-}
+bool c1e_detected;
+EXPORT_SYMBOL(c1e_detected);
 
 static cpumask_var_t c1e_mask;
-static int c1e_detected;
 
 void c1e_remove_cpu(int cpu)
 {
@@ -585,12 +551,12 @@ static void c1e_idle(void)
                u32 lo, hi;
 
                rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
+
                if (lo & K8_INTP_C1E_ACTIVE_MASK) {
-                       c1e_detected = 1;
+                       c1e_detected = true;
                        if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
                                mark_tsc_unstable("TSC halt in AMD C1E");
                        printk(KERN_INFO "System has AMD C1E enabled\n");
-                       set_cpu_cap(&boot_cpu_data, X86_FEATURE_AMDC1E);
                }
        }
 
@@ -639,7 +605,8 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
                 */
                printk(KERN_INFO "using mwait in idle threads.\n");
                pm_idle = mwait_idle;
-       } else if (check_c1e_idle(c)) {
+       } else if (cpu_has_amd_erratum(amd_erratum_400)) {
+               /* E400: APIC timer interrupt does not wake up CPU from C1e */
                printk(KERN_INFO "using C1E aware idle routine\n");
                pm_idle = c1e_idle;
        } else
index 8d128783af47374e56412d01d0488aa12af1647b..96586c3cbbbf88dd6479ed250b24ea1112154a22 100644 (file)
@@ -57,6 +57,8 @@
 #include <asm/syscalls.h>
 #include <asm/debugreg.h>
 
+#include <trace/events/power.h>
+
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 /*
@@ -111,6 +113,8 @@ void cpu_idle(void)
                        stop_critical_timings();
                        pm_idle();
                        start_critical_timings();
+
+                       trace_power_end(smp_processor_id());
                }
                tick_nohz_restart_sched_tick();
                preempt_enable_no_resched();
index 3c2422a99f1f8293480ad436551cfac8c600d326..3d9ea531ddd1bfa8cc9e2e28fbfa8a22f461bc20 100644 (file)
@@ -51,6 +51,8 @@
 #include <asm/syscalls.h>
 #include <asm/debugreg.h>
 
+#include <trace/events/power.h>
+
 asmlinkage extern void ret_from_fork(void);
 
 DEFINE_PER_CPU(unsigned long, old_rsp);
@@ -138,6 +140,9 @@ void cpu_idle(void)
                        stop_critical_timings();
                        pm_idle();
                        start_critical_timings();
+
+                       trace_power_end(smp_processor_id());
+
                        /* In many cases the interrupt that ended idle
                           has already called exit_idle. But some idle
                           loops can be woken up without interrupt. */
index b4ae4acbd031061d022a0c3e2873b7fd346a9263..b008e7883207abe580a696e9b418dbddec84dabb 100644 (file)
 
 #include <asm/paravirt.h>
 #include <asm/hypervisor.h>
+#include <asm/olpc_ofw.h>
 
 #include <asm/percpu.h>
 #include <asm/topology.h>
@@ -736,10 +737,15 @@ void __init setup_arch(char **cmdline_p)
        /* VMI may relocate the fixmap; do this before touching ioremap area */
        vmi_init();
 
+       /* OFW also may relocate the fixmap */
+       olpc_ofw_detect();
+
        early_trap_init();
        early_cpu_init();
        early_ioremap_init();
 
+       setup_olpc_ofw_pgd();
+
        ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
        screen_info = boot_params.screen_info;
        edid_info = boot_params.edid_info;
index c4f33b2e77d6076cef4bb7d337eceecb95b1bbff..51620953b18ac53967d47bb28b555ecacf906aeb 100644 (file)
@@ -735,7 +735,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
                goto do_rest;
        }
 
-       if (!keventd_up() || current_is_keventd())
+       if (!keventd_up())
                c_idle.work.func(&c_idle.work);
        else {
                schedule_work(&c_idle.work);
@@ -816,6 +816,13 @@ do_rest:
                        if (cpumask_test_cpu(cpu, cpu_callin_mask))
                                break;  /* It has booted */
                        udelay(100);
+                       /*
+                        * Allow other tasks to run while we wait for the
+                        * AP to come online. This also gives a chance
+                        * for the MTRR work(triggered by the AP coming online)
+                        * to be completed in the stop machine context.
+                        */
+                       schedule();
                }
 
                if (cpumask_test_cpu(cpu, cpu_callin_mask))
index 922eefbb3f6c72b7b511791b083b916040b9f95e..b53c525368a75cf07489b0327de138bfab5b16d5 100644 (file)
@@ -23,11 +23,16 @@ static int save_stack_stack(void *data, char *name)
        return 0;
 }
 
-static void save_stack_address(void *data, unsigned long addr, int reliable)
+static void
+__save_stack_address(void *data, unsigned long addr, bool reliable, bool nosched)
 {
        struct stack_trace *trace = data;
+#ifdef CONFIG_FRAME_POINTER
        if (!reliable)
                return;
+#endif
+       if (nosched && in_sched_functions(addr))
+               return;
        if (trace->skip > 0) {
                trace->skip--;
                return;
@@ -36,20 +41,15 @@ static void save_stack_address(void *data, unsigned long addr, int reliable)
                trace->entries[trace->nr_entries++] = addr;
 }
 
+static void save_stack_address(void *data, unsigned long addr, int reliable)
+{
+       return __save_stack_address(data, addr, reliable, false);
+}
+
 static void
 save_stack_address_nosched(void *data, unsigned long addr, int reliable)
 {
-       struct stack_trace *trace = (struct stack_trace *)data;
-       if (!reliable)
-               return;
-       if (in_sched_functions(addr))
-               return;
-       if (trace->skip > 0) {
-               trace->skip--;
-               return;
-       }
-       if (trace->nr_entries < trace->max_entries)
-               trace->entries[trace->nr_entries++] = addr;
+       return __save_stack_address(data, addr, reliable, true);
 }
 
 static const struct stacktrace_ops save_stack_ops = {
@@ -96,12 +96,13 @@ EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
 
 /* Userspace stacktrace - based on kernel/trace/trace_sysprof.c */
 
-struct stack_frame {
+struct stack_frame_user {
        const void __user       *next_fp;
        unsigned long           ret_addr;
 };
 
-static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
+static int
+copy_stack_frame(const void __user *fp, struct stack_frame_user *frame)
 {
        int ret;
 
@@ -126,7 +127,7 @@ static inline void __save_stack_trace_user(struct stack_trace *trace)
                trace->entries[trace->nr_entries++] = regs->ip;
 
        while (trace->nr_entries < trace->max_entries) {
-               struct stack_frame frame;
+               struct stack_frame_user frame;
 
                frame.next_fp = NULL;
                frame.ret_addr = 0;
index 725ef4d17cd5922289b24e515c8b030e86cf6c18..60788dee0f8a74f53d547c462d5694201b6d609d 100644 (file)
@@ -392,7 +392,13 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
                if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
                                                                == NOTIFY_STOP)
                        return;
+
 #ifdef CONFIG_X86_LOCAL_APIC
+               if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
+                                                       == NOTIFY_STOP)
+                       return;
+
+#ifndef CONFIG_LOCKUP_DETECTOR
                /*
                 * Ok, so this is none of the documented NMI sources,
                 * so it must be the NMI watchdog.
@@ -400,6 +406,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
                if (nmi_watchdog_tick(regs, reason))
                        return;
                if (!do_nmi_callback(regs, cpu))
+#endif /* !CONFIG_LOCKUP_DETECTOR */
                        unknown_nmi_error(reason, regs);
 #else
                unknown_nmi_error(reason, regs);
index 9faf91ae1841e3530f611b136ad058a0efbcfa67..ce8e50239332470ba329dd3045692fee42f69a16 100644 (file)
@@ -751,7 +751,6 @@ static struct clocksource clocksource_tsc = {
        .read                   = read_tsc,
        .resume                 = resume_tsc,
        .mask                   = CLOCKSOURCE_MASK(64),
-       .shift                  = 22,
        .flags                  = CLOCK_SOURCE_IS_CONTINUOUS |
                                  CLOCK_SOURCE_MUST_VERIFY,
 #ifdef CONFIG_X86_64
@@ -845,8 +844,6 @@ __cpuinit int unsynchronized_tsc(void)
 
 static void __init init_tsc_clocksource(void)
 {
-       clocksource_tsc.mult = clocksource_khz2mult(tsc_khz,
-                       clocksource_tsc.shift);
        if (tsc_clocksource_reliable)
                clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
        /* lower the rating if we already know its unstable: */
@@ -854,7 +851,7 @@ static void __init init_tsc_clocksource(void)
                clocksource_tsc.rating = 0;
                clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
        }
-       clocksource_register(&clocksource_tsc);
+       clocksource_register_khz(&clocksource_tsc, tsc_khz);
 }
 
 #ifdef CONFIG_X86_64
index 45b6f8a975a152b1e1a9466cd9c64fa61d1a3020..56a8c2a867d9af28e0c24ee6a7dff4122f73685b 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <asm/cpufeature.h>
+#include <asm/msr-index.h>
 
 verify_cpu:
        pushfl                          # Save caller passed flags
@@ -88,7 +89,7 @@ verify_cpu_sse_test:
        je      verify_cpu_sse_ok
        test    %di,%di
        jz      verify_cpu_no_longmode  # only try to force SSE on AMD
-       movl    $0xc0010015,%ecx        # HWCR
+       movl    $MSR_K7_HWCR,%ecx
        rdmsr
        btr     $15,%eax                # enable SSE
        wrmsr
index 1c0c6ab9c60f03394af20e57b3a09186a6cba57d..dcbb28c4b69461723147e2b863919301083b68b5 100644 (file)
@@ -73,8 +73,8 @@ void update_vsyscall_tz(void)
        write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
-                    u32 mult)
+void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
+                       struct clocksource *clock, u32 mult)
 {
        unsigned long flags;
 
@@ -87,7 +87,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
        vsyscall_gtod_data.clock.shift = clock->shift;
        vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
        vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
-       vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
+       vsyscall_gtod_data.wall_to_monotonic = *wtm;
        vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
        write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
@@ -169,13 +169,18 @@ int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
  * unlikely */
 time_t __vsyscall(1) vtime(time_t *t)
 {
-       struct timeval tv;
+       unsigned seq;
        time_t result;
        if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
                return time_syscall(t);
 
-       vgettimeofday(&tv, NULL);
-       result = tv.tv_sec;
+       do {
+               seq = read_seqbegin(&__vsyscall_gtod_data.lock);
+
+               result = __vsyscall_gtod_data.wall_time_sec;
+
+       } while (read_seqretry(&__vsyscall_gtod_data.lock, seq));
+
        if (t)
                *t = result;
        return result;
index 37e68fc5e24a4daa33bcb6c730162a0969c91430..9c253bd65e24ba3e803b044fca3ad57224a41c52 100644 (file)
  */
 u64 pcntxt_mask;
 
+/*
+ * Represents init state for the supported extended state.
+ */
+static struct xsave_struct *init_xstate_buf;
+
 struct _fpx_sw_bytes fx_sw_reserved;
 #ifdef CONFIG_IA32_EMULATION
 struct _fpx_sw_bytes fx_sw_reserved_ia32;
 #endif
 
+static unsigned int *xstate_offsets, *xstate_sizes, xstate_features;
+
+/*
+ * If a processor implementation discern that a processor state component is
+ * in its initialized state it may modify the corresponding bit in the
+ * xsave_hdr.xstate_bv as '0', with out modifying the corresponding memory
+ * layout in the case of xsaveopt. While presenting the xstate information to
+ * the user, we always ensure that the memory layout of a feature will be in
+ * the init state if the corresponding header bit is zero. This is to ensure
+ * that the user doesn't see some stale state in the memory layout during
+ * signal handling, debugging etc.
+ */
+void __sanitize_i387_state(struct task_struct *tsk)
+{
+       u64 xstate_bv;
+       int feature_bit = 0x2;
+       struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave;
+
+       if (!fx)
+               return;
+
+       BUG_ON(task_thread_info(tsk)->status & TS_USEDFPU);
+
+       xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv;
+
+       /*
+        * None of the feature bits are in init state. So nothing else
+        * to do for us, as the memory layout is upto date.
+        */
+       if ((xstate_bv & pcntxt_mask) == pcntxt_mask)
+               return;
+
+       /*
+        * FP is in init state
+        */
+       if (!(xstate_bv & XSTATE_FP)) {
+               fx->cwd = 0x37f;
+               fx->swd = 0;
+               fx->twd = 0;
+               fx->fop = 0;
+               fx->rip = 0;
+               fx->rdp = 0;
+               memset(&fx->st_space[0], 0, 128);
+       }
+
+       /*
+        * SSE is in init state
+        */
+       if (!(xstate_bv & XSTATE_SSE))
+               memset(&fx->xmm_space[0], 0, 256);
+
+       xstate_bv = (pcntxt_mask & ~xstate_bv) >> 2;
+
+       /*
+        * Update all the other memory layouts for which the corresponding
+        * header bit is in the init state.
+        */
+       while (xstate_bv) {
+               if (xstate_bv & 0x1) {
+                       int offset = xstate_offsets[feature_bit];
+                       int size = xstate_sizes[feature_bit];
+
+                       memcpy(((void *) fx) + offset,
+                              ((void *) init_xstate_buf) + offset,
+                              size);
+               }
+
+               xstate_bv >>= 1;
+               feature_bit++;
+       }
+}
+
 /*
  * Check for the presence of extended state information in the
  * user fpstate pointer in the sigcontext.
@@ -36,15 +113,14 @@ int check_for_xstate(struct i387_fxsave_struct __user *buf,
 
        err = __copy_from_user(fx_sw_user, &buf->sw_reserved[0],
                               sizeof(struct _fpx_sw_bytes));
-
        if (err)
-               return err;
+               return -EFAULT;
 
        /*
         * First Magic check failed.
         */
        if (fx_sw_user->magic1 != FP_XSTATE_MAGIC1)
-               return -1;
+               return -EINVAL;
 
        /*
         * Check for error scenarios.
@@ -52,19 +128,21 @@ int check_for_xstate(struct i387_fxsave_struct __user *buf,
        if (fx_sw_user->xstate_size < min_xstate_size ||
            fx_sw_user->xstate_size > xstate_size ||
            fx_sw_user->xstate_size > fx_sw_user->extended_size)
-               return -1;
+               return -EINVAL;
 
        err = __get_user(magic2, (__u32 *) (((void *)fpstate) +
                                            fx_sw_user->extended_size -
                                            FP_XSTATE_MAGIC2_SIZE));
+       if (err)
+               return err;
        /*
         * Check for the presence of second magic word at the end of memory
         * layout. This detects the case where the user just copied the legacy
         * fpstate layout with out copying the extended state information
         * in the memory layout.
         */
-       if (err || magic2 != FP_XSTATE_MAGIC2)
-               return -1;
+       if (magic2 != FP_XSTATE_MAGIC2)
+               return -EFAULT;
 
        return 0;
 }
@@ -91,14 +169,6 @@ int save_i387_xstate(void __user *buf)
                return 0;
 
        if (task_thread_info(tsk)->status & TS_USEDFPU) {
-               /*
-                * Start with clearing the user buffer. This will present a
-                * clean context for the bytes not touched by the fxsave/xsave.
-                */
-               err = __clear_user(buf, sig_xstate_size);
-               if (err)
-                       return err;
-
                if (use_xsave())
                        err = xsave_user(buf);
                else
@@ -109,6 +179,7 @@ int save_i387_xstate(void __user *buf)
                task_thread_info(tsk)->status &= ~TS_USEDFPU;
                stts();
        } else {
+               sanitize_i387_state(tsk);
                if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave,
                                   xstate_size))
                        return -1;
@@ -184,8 +255,8 @@ static int restore_user_xstate(void __user *buf)
         * init the state skipped by the user.
         */
        mask = pcntxt_mask & ~mask;
-
-       xrstor_state(init_xstate_buf, mask);
+       if (unlikely(mask))
+               xrstor_state(init_xstate_buf, mask);
 
        return 0;
 
@@ -274,11 +345,6 @@ static void prepare_fx_sw_frame(void)
 #endif
 }
 
-/*
- * Represents init state for the supported extended state.
- */
-struct xsave_struct *init_xstate_buf;
-
 #ifdef CONFIG_X86_64
 unsigned int sig_xstate_size = sizeof(struct _fpstate);
 #endif
@@ -286,37 +352,77 @@ unsigned int sig_xstate_size = sizeof(struct _fpstate);
 /*
  * Enable the extended processor state save/restore feature
  */
-void __cpuinit xsave_init(void)
+static inline void xstate_enable(void)
 {
-       if (!cpu_has_xsave)
-               return;
-
        set_in_cr4(X86_CR4_OSXSAVE);
-
-       /*
-        * Enable all the features that the HW is capable of
-        * and the Linux kernel is aware of.
-        */
        xsetbv(XCR_XFEATURE_ENABLED_MASK, pcntxt_mask);
 }
 
+/*
+ * Record the offsets and sizes of different state managed by the xsave
+ * memory layout.
+ */
+static void __init setup_xstate_features(void)
+{
+       int eax, ebx, ecx, edx, leaf = 0x2;
+
+       xstate_features = fls64(pcntxt_mask);
+       xstate_offsets = alloc_bootmem(xstate_features * sizeof(int));
+       xstate_sizes = alloc_bootmem(xstate_features * sizeof(int));
+
+       do {
+               cpuid_count(XSTATE_CPUID, leaf, &eax, &ebx, &ecx, &edx);
+
+               if (eax == 0)
+                       break;
+
+               xstate_offsets[leaf] = ebx;
+               xstate_sizes[leaf] = eax;
+
+               leaf++;
+       } while (1);
+}
+
 /*
  * setup the xstate image representing the init state
  */
 static void __init setup_xstate_init(void)
 {
+       setup_xstate_features();
+
+       /*
+        * Setup init_xstate_buf to represent the init state of
+        * all the features managed by the xsave
+        */
        init_xstate_buf = alloc_bootmem(xstate_size);
        init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
+
+       clts();
+       /*
+        * Init all the features state with header_bv being 0x0
+        */
+       xrstor_state(init_xstate_buf, -1);
+       /*
+        * Dump the init state again. This is to identify the init state
+        * of any feature which is not represented by all zero's.
+        */
+       xsave_state(init_xstate_buf, -1);
+       stts();
 }
 
 /*
  * Enable and initialize the xsave feature.
  */
-void __ref xsave_cntxt_init(void)
+static void __init xstate_enable_boot_cpu(void)
 {
        unsigned int eax, ebx, ecx, edx;
 
-       cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx);
+       if (boot_cpu_data.cpuid_level < XSTATE_CPUID) {
+               WARN(1, KERN_ERR "XSTATE_CPUID missing\n");
+               return;
+       }
+
+       cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
        pcntxt_mask = eax + ((u64)edx << 32);
 
        if ((pcntxt_mask & XSTATE_FPSSE) != XSTATE_FPSSE) {
@@ -329,12 +435,13 @@ void __ref xsave_cntxt_init(void)
         * Support only the state known to OS.
         */
        pcntxt_mask = pcntxt_mask & XCNTXT_MASK;
-       xsave_init();
+
+       xstate_enable();
 
        /*
         * Recompute the context size for enabled features
         */
-       cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx);
+       cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
        xstate_size = ebx;
 
        update_regset_xstate_info(xstate_size, pcntxt_mask);
@@ -346,3 +453,23 @@ void __ref xsave_cntxt_init(void)
               "cntxt size 0x%x\n",
               pcntxt_mask, xstate_size);
 }
+
+/*
+ * For the very first instance, this calls xstate_enable_boot_cpu();
+ * for all subsequent instances, this calls xstate_enable().
+ *
+ * This is somewhat obfuscated due to the lack of powerful enough
+ * overrides for the section checks.
+ */
+void __cpuinit xsave_init(void)
+{
+       static __refdata void (*next_func)(void) = xstate_enable_boot_cpu;
+       void (*this_func)(void);
+
+       if (!cpu_has_xsave)
+               return;
+
+       this_func = next_func;
+       next_func = xstate_enable;
+       this_func();
+}
index 0dcc95e09876fc7094bc9b05bf3acf34ede51439..311f6dad89513385a8f9de804baa651a02b84e39 100644 (file)
@@ -281,11 +281,7 @@ static gfn_t pse36_gfn_delta(u32 gpte)
 
 static void __set_spte(u64 *sptep, u64 spte)
 {
-#ifdef CONFIG_X86_64
-       set_64bit((unsigned long *)sptep, spte);
-#else
-       set_64bit((unsigned long long *)sptep, spte);
-#endif
+       set_64bit(sptep, spte);
 }
 
 static u64 __xchg_spte(u64 *sptep, u64 new_spte)
index 56c9b6bd7655baadf70b88a54977acbe1a7ed58f..bc5b9b8d4a33117259882835bfb884f4f8f37656 100644 (file)
@@ -131,7 +131,7 @@ static struct svm_direct_access_msrs {
        u32 index;   /* Index of the MSR */
        bool always; /* True if intercept is always on */
 } direct_access_msrs[] = {
-       { .index = MSR_K6_STAR,                         .always = true  },
+       { .index = MSR_STAR,                            .always = true  },
        { .index = MSR_IA32_SYSENTER_CS,                .always = true  },
 #ifdef CONFIG_X86_64
        { .index = MSR_GS_BASE,                         .always = true  },
@@ -384,8 +384,7 @@ static void svm_init_erratum_383(void)
        int err;
        u64 val;
 
-       /* Only Fam10h is affected */
-       if (boot_cpu_data.x86 != 0x10)
+       if (!cpu_has_amd_erratum(amd_erratum_383))
                return;
 
        /* Use _safe variants to not break nested virtualization */
@@ -2433,7 +2432,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
                *data = tsc_offset + native_read_tsc();
                break;
        }
-       case MSR_K6_STAR:
+       case MSR_STAR:
                *data = svm->vmcb->save.star;
                break;
 #ifdef CONFIG_X86_64
@@ -2557,7 +2556,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 
                break;
        }
-       case MSR_K6_STAR:
+       case MSR_STAR:
                svm->vmcb->save.star = data;
                break;
 #ifdef CONFIG_X86_64
index 27a0222c29460d79e6e65992ac00fc2845f8f25b..49b25eee25acc075538a411fc24c23a326f02fd4 100644 (file)
@@ -240,14 +240,14 @@ static u64 host_efer;
 static void ept_save_pdptrs(struct kvm_vcpu *vcpu);
 
 /*
- * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it
+ * Keep MSR_STAR at the end, as setup_msrs() will try to optimize it
  * away by decrementing the array size.
  */
 static const u32 vmx_msr_index[] = {
 #ifdef CONFIG_X86_64
        MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR,
 #endif
-       MSR_EFER, MSR_TSC_AUX, MSR_K6_STAR,
+       MSR_EFER, MSR_TSC_AUX, MSR_STAR,
 };
 #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
 
@@ -1117,10 +1117,10 @@ static void setup_msrs(struct vcpu_vmx *vmx)
                if (index >= 0 && vmx->rdtscp_enabled)
                        move_msr_up(vmx, index, save_nmsrs++);
                /*
-                * MSR_K6_STAR is only needed on long mode guests, and only
+                * MSR_STAR is only needed on long mode guests, and only
                 * if efer.sce is enabled.
                 */
-               index = __find_msr_index(vmx, MSR_K6_STAR);
+               index = __find_msr_index(vmx, MSR_STAR);
                if ((index >= 0) && (vmx->vcpu.arch.efer & EFER_SCE))
                        move_msr_up(vmx, index, save_nmsrs++);
        }
index 97aab036dabfa1260a812f460345e58869bdd571..25f19078b3210424b091fea80bd8c82b0a9ef254 100644 (file)
@@ -733,7 +733,7 @@ static u32 msrs_to_save[] = {
        HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
        HV_X64_MSR_APIC_ASSIST_PAGE,
        MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
-       MSR_K6_STAR,
+       MSR_STAR,
 #ifdef CONFIG_X86_64
        MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
 #endif
index f871e04b6965b828045b08d183dadd0c2aaa487f..e10cf070ede0bbb6b169dbd76289054c32becc18 100644 (file)
@@ -30,6 +30,7 @@ ifeq ($(CONFIG_X86_32),y)
         lib-y += checksum_32.o
         lib-y += strstr_32.o
         lib-y += semaphore_32.o string_32.o
+        lib-y += cmpxchg.o
 ifneq ($(CONFIG_X86_CMPXCHG64),y)
         lib-y += cmpxchg8b_emu.o atomic64_386_32.o
 endif
index ebeafcce04a9bd595b645af6941429fe8fc26c62..aa4326bfb24a1dc6dbe2b131dd7c7c19bb58d58d 100644 (file)
@@ -52,7 +52,7 @@ ENDPROC(clear_page)
        .align 8
        .quad clear_page
        .quad 1b
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
        .byte .Lclear_page_end - clear_page
        .byte 2b - 1b
        .previous
similarity index 75%
rename from arch/x86/kernel/cpu/cmpxchg.c
rename to arch/x86/lib/cmpxchg.c
index 2056ccf572ccac780978100ff28836d9d52d8296..5d619f6df3ee5fb1906559b3e4d8da1adce728ab 100644 (file)
@@ -52,21 +52,3 @@ unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
 }
 EXPORT_SYMBOL(cmpxchg_386_u32);
 #endif
-
-#ifndef CONFIG_X86_CMPXCHG64
-unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new)
-{
-       u64 prev;
-       unsigned long flags;
-
-       /* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */
-       local_irq_save(flags);
-       prev = *(u64 *)ptr;
-       if (prev == old)
-               *(u64 *)ptr = new;
-       local_irq_restore(flags);
-       return prev;
-}
-EXPORT_SYMBOL(cmpxchg_486_u64);
-#endif
-
index 727a5d46d2fc0cfb6888053a698841fb6e9732f9..6fec2d1cebe111a5d9a5be1528e2370743088dcc 100644 (file)
@@ -113,7 +113,7 @@ ENDPROC(copy_page)
        .align 8
        .quad copy_page
        .quad 1b
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
        .byte .Lcopy_page_end - copy_page
        .byte 2b - 1b
        .previous
index 71100c98e337026e39afbb059c520f95edb9a01e..a460158b5ac5b76b8d5086b7d1d5a058aa4feef4 100644 (file)
@@ -29,7 +29,7 @@
        .align 8
        .quad  0b
        .quad  2b
-       .byte  \feature                 /* when feature is set */
+       .word  \feature                 /* when feature is set */
        .byte  5
        .byte  5
        .previous
index f82e884928af6643854f64df5899c42ab6fee9b2..bcbcd1e0f7d57fe4b3972adc24785dc6837386f6 100644 (file)
@@ -131,7 +131,7 @@ ENDPROC(__memcpy)
        .align 8
        .quad memcpy
        .quad .Lmemcpy_c
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
 
        /*
         * Replace only beginning, memcpy is used to apply alternatives,
index e88d3b81644a8736bcba56acaef56328c39e77ff..09d3442696522e19aea8adb9efdbfd051d8d57aa 100644 (file)
@@ -121,7 +121,7 @@ ENDPROC(__memset)
        .align 8
        .quad memset
        .quad .Lmemset_c
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
        .byte .Lfinal - memset
        .byte .Lmemset_e - .Lmemset_c
        .previous
index a725b7f760ae4ba860e93b9af99b40931621430b..0002a3a33081c77134569c1872e5a70684dbd646 100644 (file)
@@ -37,6 +37,28 @@ struct addr_marker {
        const char *name;
 };
 
+/* indices for address_markers; keep sync'd w/ address_markers below */
+enum address_markers_idx {
+       USER_SPACE_NR = 0,
+#ifdef CONFIG_X86_64
+       KERNEL_SPACE_NR,
+       LOW_KERNEL_NR,
+       VMALLOC_START_NR,
+       VMEMMAP_START_NR,
+       HIGH_KERNEL_NR,
+       MODULES_VADDR_NR,
+       MODULES_END_NR,
+#else
+       KERNEL_SPACE_NR,
+       VMALLOC_START_NR,
+       VMALLOC_END_NR,
+# ifdef CONFIG_HIGHMEM
+       PKMAP_BASE_NR,
+# endif
+       FIXADDR_START_NR,
+#endif
+};
+
 /* Address space markers hints */
 static struct addr_marker address_markers[] = {
        { 0, "User Space" },
@@ -331,14 +353,12 @@ static int pt_dump_init(void)
 
 #ifdef CONFIG_X86_32
        /* Not a compile-time constant on x86-32 */
-       address_markers[2].start_address = VMALLOC_START;
-       address_markers[3].start_address = VMALLOC_END;
+       address_markers[VMALLOC_START_NR].start_address = VMALLOC_START;
+       address_markers[VMALLOC_END_NR].start_address = VMALLOC_END;
 # ifdef CONFIG_HIGHMEM
-       address_markers[4].start_address = PKMAP_BASE;
-       address_markers[5].start_address = FIXADDR_START;
-# else
-       address_markers[4].start_address = FIXADDR_START;
+       address_markers[PKMAP_BASE_NR].start_address = PKMAP_BASE;
 # endif
+       address_markers[FIXADDR_START_NR].start_address = FIXADDR_START;
 #endif
 
        pe = debugfs_create_file("kernel_page_tables", 0600, NULL, NULL,
index 12e4d2d3c1105e24990808cd898897bdefebb403..3ba6e0608c55c3b81300db30e465093f58367f0a 100644 (file)
@@ -62,8 +62,8 @@ int ioremap_change_attr(unsigned long vaddr, unsigned long size,
 static void __iomem *__ioremap_caller(resource_size_t phys_addr,
                unsigned long size, unsigned long prot_val, void *caller)
 {
-       unsigned long pfn, offset, vaddr;
-       resource_size_t last_addr;
+       unsigned long offset, vaddr;
+       resource_size_t pfn, last_pfn, last_addr;
        const resource_size_t unaligned_phys_addr = phys_addr;
        const unsigned long unaligned_size = size;
        struct vm_struct *area;
@@ -100,10 +100,8 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
        /*
         * Don't allow anybody to remap normal RAM that we're using..
         */
-       for (pfn = phys_addr >> PAGE_SHIFT;
-                               (pfn << PAGE_SHIFT) < (last_addr & PAGE_MASK);
-                               pfn++) {
-
+       last_pfn = last_addr >> PAGE_SHIFT;
+       for (pfn = phys_addr >> PAGE_SHIFT; pfn <= last_pfn; pfn++) {
                int is_ram = page_is_ram(pfn);
 
                if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
@@ -115,7 +113,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
         * Mappings have to be page-aligned
         */
        offset = phys_addr & ~PAGE_MASK;
-       phys_addr &= PAGE_MASK;
+       phys_addr &= PHYSICAL_PAGE_MASK;
        size = PAGE_ALIGN(last_addr+1) - phys_addr;
 
        retval = reserve_memtype(phys_addr, (u64)phys_addr + size,
@@ -613,7 +611,7 @@ void __init early_iounmap(void __iomem *addr, unsigned long size)
                return;
        }
        offset = virt_addr & ~PAGE_MASK;
-       nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
+       nrpages = PAGE_ALIGN(offset + size) >> PAGE_SHIFT;
 
        idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
        while (nrpages > 0) {
index 5d0e67fff1a655454145c945ffe65a87ec7331a9..e5d5e2ce9f7734036b7b411b5b357ff84788fa52 100644 (file)
@@ -45,6 +45,8 @@ struct kmmio_fault_page {
         * Protected by kmmio_lock, when linked into kmmio_page_table.
         */
        int count;
+
+       bool scheduled_for_release;
 };
 
 struct kmmio_delayed_release {
@@ -398,8 +400,11 @@ static void release_kmmio_fault_page(unsigned long page,
        BUG_ON(f->count < 0);
        if (!f->count) {
                disarm_kmmio_fault_page(f);
-               f->release_next = *release_list;
-               *release_list = f;
+               if (!f->scheduled_for_release) {
+                       f->release_next = *release_list;
+                       *release_list = f;
+                       f->scheduled_for_release = true;
+               }
        }
 }
 
@@ -471,8 +476,10 @@ static void remove_kmmio_fault_pages(struct rcu_head *head)
                        prevp = &f->release_next;
                } else {
                        *prevp = f->release_next;
+                       f->release_next = NULL;
+                       f->scheduled_for_release = false;
                }
-               f = f->release_next;
+               f = *prevp;
        }
        spin_unlock_irqrestore(&kmmio_lock, flags);
 
@@ -510,6 +517,9 @@ void unregister_kmmio_probe(struct kmmio_probe *p)
        kmmio_count--;
        spin_unlock_irqrestore(&kmmio_lock, flags);
 
+       if (!release_list)
+               return;
+
        drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC);
        if (!drelease) {
                pr_crit("leaking kmmio_fault_page objects.\n");
index 64121a18b8cb33902b6161435136aa86b619a152..f6ff57b7efa514e0a7e1ec47ac8472ea868c13fa 100644 (file)
@@ -158,7 +158,7 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end, unsigned long req_type)
        return req_type;
 }
 
-static int pat_pagerange_is_ram(unsigned long start, unsigned long end)
+static int pat_pagerange_is_ram(resource_size_t start, resource_size_t end)
 {
        int ram_page = 0, not_rampage = 0;
        unsigned long page_nr;
index 308e32570d846f3eeb339bc662de5b2c50c3cb0e..38e6d174c497ec7127a70cb778f7034e83605737 100644 (file)
@@ -40,16 +40,16 @@ static unsigned char prefix_codes[] = {
 static unsigned int reg_rop[] = {
        0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F
 };
-static unsigned int reg_wop[] = { 0x88, 0x89 };
+static unsigned int reg_wop[] = { 0x88, 0x89, 0xAA, 0xAB };
 static unsigned int imm_wop[] = { 0xC6, 0xC7 };
 /* IA32 Manual 3, 3-432*/
-static unsigned int rw8[] = { 0x88, 0x8A, 0xC6 };
+static unsigned int rw8[] = { 0x88, 0x8A, 0xC6, 0xAA };
 static unsigned int rw32[] = {
-       0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F
+       0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F, 0xAB
 };
-static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F };
+static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F, 0xAA };
 static unsigned int mw16[] = { 0xB70F, 0xBF0F };
-static unsigned int mw32[] = { 0x89, 0x8B, 0xC7 };
+static unsigned int mw32[] = { 0x89, 0x8B, 0xC7, 0xAB };
 static unsigned int mw64[] = {};
 #else /* not __i386__ */
 static unsigned char prefix_codes[] = {
@@ -63,20 +63,20 @@ static unsigned char prefix_codes[] = {
 static unsigned int reg_rop[] = {
        0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F
 };
-static unsigned int reg_wop[] = { 0x88, 0x89 };
+static unsigned int reg_wop[] = { 0x88, 0x89, 0xAA, 0xAB };
 static unsigned int imm_wop[] = { 0xC6, 0xC7 };
-static unsigned int rw8[] = { 0xC6, 0x88, 0x8A };
+static unsigned int rw8[] = { 0xC6, 0x88, 0x8A, 0xAA };
 static unsigned int rw32[] = {
-       0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F
+       0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F, 0xAB
 };
 /* 8 bit only */
-static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F };
+static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F, 0xAA };
 /* 16 bit only */
 static unsigned int mw16[] = { 0xB70F, 0xBF0F };
 /* 16 or 32 bit */
 static unsigned int mw32[] = { 0xC7 };
 /* 16, 32 or 64 bit */
-static unsigned int mw64[] = { 0x89, 0x8B };
+static unsigned int mw64[] = { 0x89, 0x8B, 0xAB };
 #endif /* not __i386__ */
 
 struct prefix_bits {
@@ -410,7 +410,6 @@ static unsigned long *get_reg_w32(int no, struct pt_regs *regs)
 unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
 {
        unsigned int opcode;
-       unsigned char mod_rm;
        int reg;
        unsigned char *p;
        struct prefix_bits prf;
@@ -437,8 +436,13 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
        goto err;
 
 do_work:
-       mod_rm = *p;
-       reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3);
+       /* for STOS, source register is fixed */
+       if (opcode == 0xAA || opcode == 0xAB) {
+               reg = arg_AX;
+       } else {
+               unsigned char mod_rm = *p;
+               reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3);
+       }
        switch (get_ins_reg_width(ins_addr)) {
        case 1:
                return *get_reg_w8(reg, prf.rex, regs);
index 8565d944f7cf3df171a5c2f0250f5810cde0bb44..38868adf07ea9d68e4f23b486f636575d728687c 100644 (file)
@@ -90,6 +90,27 @@ static void do_test(unsigned long size)
        iounmap(p);
 }
 
+/*
+ * Tests how mmiotrace behaves in face of multiple ioremap / iounmaps in
+ * a short time. We had a bug in deferred freeing procedure which tried
+ * to free this region multiple times (ioremap can reuse the same address
+ * for many mappings).
+ */
+static void do_test_bulk_ioremapping(void)
+{
+       void __iomem *p;
+       int i;
+
+       for (i = 0; i < 10; ++i) {
+               p = ioremap_nocache(mmio_address, PAGE_SIZE);
+               if (p)
+                       iounmap(p);
+       }
+
+       /* Force freeing. If it will crash we will know why. */
+       synchronize_rcu();
+}
+
 static int __init init(void)
 {
        unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
@@ -104,6 +125,7 @@ static int __init init(void)
                   "and writing 16 kB of rubbish in there.\n",
                   size >> 10, mmio_address);
        do_test(size);
+       do_test_bulk_ioremapping();
        pr_info("All done.\n");
        return 0;
 }
index 426f3a1a64d3d73efa7a4aaea70cba37a8c5f9d3..c03f14ab666742d6960ff3339ebcfe28a003308b 100644 (file)
@@ -278,11 +278,9 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
 
 static void do_flush_tlb_all(void *info)
 {
-       unsigned long cpu = smp_processor_id();
-
        __flush_tlb_all();
        if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY)
-               leave_mm(cpu);
+               leave_mm(smp_processor_id());
 }
 
 void flush_tlb_all(void)
index b28d2f1253bbc927731afa08022fdef21a598a24..1ba67dc8006ab700170afb6964954c33c5705591 100644 (file)
@@ -634,6 +634,18 @@ static int __init ppro_init(char **cpu_type)
        if (force_arch_perfmon && cpu_has_arch_perfmon)
                return 0;
 
+       /*
+        * Documentation on identifying Intel processors by CPU family
+        * and model can be found in the Intel Software Developer's
+        * Manuals (SDM):
+        *
+        *  http://www.intel.com/products/processor/manuals/
+        *
+        * As of May 2010 the documentation for this was in the:
+        * "Intel 64 and IA-32 Architectures Software Developer's
+        * Manual Volume 3B: System Programming Guide", "Table B-1
+        * CPUID Signature Values of DisplayFamily_DisplayModel".
+        */
        switch (cpu_model) {
        case 0 ... 2:
                *cpu_type = "i386/ppro";
@@ -655,12 +667,12 @@ static int __init ppro_init(char **cpu_type)
        case 15: case 23:
                *cpu_type = "i386/core_2";
                break;
+       case 0x1a:
        case 0x2e:
-       case 26:
                spec = &op_arch_perfmon_spec;
                *cpu_type = "i386/core_i7";
                break;
-       case 28:
+       case 0x1c:
                *cpu_type = "i386/atom";
                break;
        default:
index 2ec04c424a6229f7d830e78fb49f5532b804d212..15466c096ba5f56fabc7f174eabd1c40996e4b6d 100644 (file)
@@ -34,6 +34,15 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
                },
        },
+       /* https://bugzilla.kernel.org/show_bug.cgi?id=16007 */
+       /* 2006 AMD HT/VIA system with two host bridges */
+        {
+               .callback = set_use_crs,
+               .ident = "ASRock ALiveSATA2-GLAN",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ALiveSATA2-GLAN"),
+                },
+        },
        {}
 };
 
index 215a27ae050d430c0deac4a29f75c08449249c96..a0772af64efbef7de6f230bea7c5ccd47d1c0951 100644 (file)
@@ -125,6 +125,23 @@ void __init dmi_check_skip_isa_align(void)
 static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 {
        struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
+       struct resource *bar_r;
+       int bar;
+
+       if (pci_probe & PCI_NOASSIGN_BARS) {
+               /*
+               * If the BIOS did not assign the BAR, zero out the
+               * resource so the kernel doesn't attmept to assign
+               * it later on in pci_assign_unassigned_resources
+               */
+               for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) {
+                       bar_r = &dev->resource[bar];
+                       if (bar_r->start == 0 && bar_r->end != 0) {
+                               bar_r->flags = 0;
+                               bar_r->end = 0;
+                       }
+               }
+       }
 
        if (pci_probe & PCI_NOASSIGN_ROMS) {
                if (rom_r->parent)
@@ -509,6 +526,9 @@ char * __devinit  pcibios_setup(char *str)
        } else if (!strcmp(str, "norom")) {
                pci_probe |= PCI_NOASSIGN_ROMS;
                return NULL;
+       } else if (!strcmp(str, "nobar")) {
+               pci_probe |= PCI_NOASSIGN_BARS;
+               return NULL;
        } else if (!strcmp(str, "assign-busses")) {
                pci_probe |= PCI_ASSIGN_ALL_BUSSES;
                return NULL;
index 9810a0f76c91ccd58491e36051678fcf6dd40ad3..f547ee05f7150aa30a1b3f052e22a6e959e17b5d 100644 (file)
@@ -989,7 +989,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
        dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin - 1, irq);
 
        /* Update IRQ for all devices with the same pirq value */
-       while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
+       for_each_pci_dev(dev2) {
                pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
                if (!pin)
                        continue;
@@ -1028,7 +1028,7 @@ void __init pcibios_fixup_irqs(void)
        u8 pin;
 
        DBG(KERN_DEBUG "PCI: IRQ fixup\n");
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
                /*
                 * If the BIOS has set an out of range IRQ number, just
                 * ignore it.  Also keep track of which IRQ's are
@@ -1052,7 +1052,7 @@ void __init pcibios_fixup_irqs(void)
                return;
 
        dev = NULL;
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
                pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
                if (!pin)
                        continue;
index 8d460eaf524f1d6f1a54b3853de221e7b38d9e6d..c89266be6048ec0794d85047eabf7714096cee5d 100644 (file)
@@ -36,7 +36,7 @@ int __init pci_legacy_init(void)
        return 0;
 }
 
-void pcibios_scan_specific_bus(int busn)
+void __devinit pcibios_scan_specific_bus(int busn)
 {
        int devfn;
        long node;
index 6b4ffedb93c9f62e2d65874c7d27ef056fd9e8b9..4a2afa1bac51f58d35e27ff6ffd18c4efc064f4b 100644 (file)
@@ -120,7 +120,8 @@ $(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
 quiet_cmd_vdso = VDSO    $@
       cmd_vdso = $(CC) -nostdlib -o $@ \
                       $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
-                      -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^)
+                      -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
+                sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
 
 VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
 GCOV_PROFILE := n
diff --git a/arch/x86/vdso/checkundef.sh b/arch/x86/vdso/checkundef.sh
new file mode 100755 (executable)
index 0000000..7ee90a9
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+nm="$1"
+file="$2"
+$nm "$file" | grep '^ *U' > /dev/null 2>&1
+if [ $? -eq 1 ]; then
+    exit 0
+else
+    echo "$file: undefined symbols found" >&2
+    exit 1
+fi
index 02b442e92007ba90e0264d597124154f17683afa..36df991985b2356188cee6c5e1409bcf28ed649e 100644 (file)
@@ -374,7 +374,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
 #ifdef CONFIG_X86_64
 
-__initcall(sysenter_setup);
+subsys_initcall(sysenter_setup);
 
 #ifdef CONFIG_SYSCTL
 /* Register vsyscall32 into the ABI table */
index ac74869b8140754b45277126fb6f5dcc5a9e6834..4b5d26f108bbb21f9ff1ac494388b70fa610c247 100644 (file)
@@ -67,6 +67,7 @@ static int __init init_vdso_vars(void)
        *(typeof(__ ## x) **) var_ref(VDSO64_SYMBOL(vbase, x), #x) = &__ ## x;
 #include "vextern.h"
 #undef VEXTERN
+       vunmap(vbase);
        return 0;
 
  oom:
@@ -74,7 +75,7 @@ static int __init init_vdso_vars(void)
        vdso_enabled = 0;
        return -ENOMEM;
 }
-__initcall(init_vdso_vars);
+subsys_initcall(init_vdso_vars);
 
 struct linux_binprm;
 
index b83e119fbeb0d29a832d68d67409ae72bb3a7400..68128a1b401a30a9316b0a9cfa35369c88f9e81a 100644 (file)
@@ -13,6 +13,11 @@ config XEN
          kernel to boot in a paravirtualized environment under the
          Xen hypervisor.
 
+config XEN_PVHVM
+       def_bool y
+       depends on XEN
+       depends on X86_LOCAL_APIC
+
 config XEN_MAX_DOMAIN_MEMORY
        int "Maximum allowed size of a domain in gigabytes"
        default 8 if X86_32
index 3bb4fc21f4f28b79eff0fb6f8b0ae50b112842ef..930954685980bbdbbf58af280b4729c85211f596 100644 (file)
@@ -12,7 +12,7 @@ CFLAGS_mmu.o                  := $(nostackp)
 
 obj-y          := enlighten.o setup.o multicalls.o mmu.o irq.o \
                        time.o xen-asm.o xen-asm_$(BITS).o \
-                       grant-table.o suspend.o
+                       grant-table.o suspend.o platform-pci-unplug.o
 
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
index 65d8d79b46a8467cbc11c4495a160d7b416a0b32..d4ff5e83621d14d75e1fe3f7632fe09a5ab8670c 100644 (file)
@@ -11,6 +11,7 @@
  * Jeremy Fitzhardinge <jeremy@xensource.com>, XenSource Inc, 2007
  */
 
+#include <linux/cpu.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <xen/interface/version.h>
 #include <xen/interface/physdev.h>
 #include <xen/interface/vcpu.h>
+#include <xen/interface/memory.h>
 #include <xen/features.h>
 #include <xen/page.h>
+#include <xen/hvm.h>
 #include <xen/hvc-console.h>
 
 #include <asm/paravirt.h>
@@ -55,7 +58,9 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/reboot.h>
+#include <asm/setup.h>
 #include <asm/stackprotector.h>
+#include <asm/hypervisor.h>
 
 #include "xen-ops.h"
 #include "mmu.h"
@@ -76,6 +81,10 @@ struct shared_info xen_dummy_shared_info;
 
 void *xen_initial_gdt;
 
+RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
+__read_mostly int xen_have_vector_callback;
+EXPORT_SYMBOL_GPL(xen_have_vector_callback);
+
 /*
  * Point at some empty memory to start with. We map the real shared_info
  * page as soon as fixmap is up and running.
@@ -97,6 +106,14 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
  */
 static int have_vcpu_info_placement = 1;
 
+static void clamp_max_cpus(void)
+{
+#ifdef CONFIG_SMP
+       if (setup_max_cpus > MAX_VIRT_CPUS)
+               setup_max_cpus = MAX_VIRT_CPUS;
+#endif
+}
+
 static void xen_vcpu_setup(int cpu)
 {
        struct vcpu_register_vcpu_info info;
@@ -104,13 +121,17 @@ static void xen_vcpu_setup(int cpu)
        struct vcpu_info *vcpup;
 
        BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
-       per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
 
-       if (!have_vcpu_info_placement)
-               return;         /* already tested, not available */
+       if (cpu < MAX_VIRT_CPUS)
+               per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
 
-       vcpup = &per_cpu(xen_vcpu_info, cpu);
+       if (!have_vcpu_info_placement) {
+               if (cpu >= MAX_VIRT_CPUS)
+                       clamp_max_cpus();
+               return;
+       }
 
+       vcpup = &per_cpu(xen_vcpu_info, cpu);
        info.mfn = arbitrary_virt_to_mfn(vcpup);
        info.offset = offset_in_page(vcpup);
 
@@ -125,6 +146,7 @@ static void xen_vcpu_setup(int cpu)
        if (err) {
                printk(KERN_DEBUG "register_vcpu_info failed: err=%d\n", err);
                have_vcpu_info_placement = 0;
+               clamp_max_cpus();
        } else {
                /* This cpu is using the registered vcpu info, even if
                   later ones fail to. */
@@ -731,7 +753,6 @@ static void set_xen_basic_apic_ops(void)
 
 #endif
 
-
 static void xen_clts(void)
 {
        struct multicall_space mcs;
@@ -926,10 +947,6 @@ static const struct pv_init_ops xen_init_ops __initdata = {
        .patch = xen_patch,
 };
 
-static const struct pv_time_ops xen_time_ops __initdata = {
-       .sched_clock = xen_sched_clock,
-};
-
 static const struct pv_cpu_ops xen_cpu_ops __initdata = {
        .cpuid = xen_cpuid,
 
@@ -1028,6 +1045,23 @@ static void xen_crash_shutdown(struct pt_regs *regs)
        xen_reboot(SHUTDOWN_crash);
 }
 
+static int
+xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+       xen_reboot(SHUTDOWN_crash);
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block xen_panic_block = {
+       .notifier_call= xen_panic_event,
+};
+
+int xen_panic_handler_init(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
+       return 0;
+}
+
 static const struct machine_ops __initdata xen_machine_ops = {
        .restart = xen_restart,
        .halt = xen_machine_halt,
@@ -1067,7 +1101,6 @@ asmlinkage void __init xen_start_kernel(void)
        /* Install Xen paravirt ops */
        pv_info = xen_info;
        pv_init_ops = xen_init_ops;
-       pv_time_ops = xen_time_ops;
        pv_cpu_ops = xen_cpu_ops;
        pv_apic_ops = xen_apic_ops;
 
@@ -1075,13 +1108,7 @@ asmlinkage void __init xen_start_kernel(void)
        x86_init.oem.arch_setup = xen_arch_setup;
        x86_init.oem.banner = xen_banner;
 
-       x86_init.timers.timer_init = xen_time_init;
-       x86_init.timers.setup_percpu_clockev = x86_init_noop;
-       x86_cpuinit.setup_percpu_clockev = x86_init_noop;
-
-       x86_platform.calibrate_tsc = xen_tsc_khz;
-       x86_platform.get_wallclock = xen_get_wallclock;
-       x86_platform.set_wallclock = xen_set_wallclock;
+       xen_init_time_ops();
 
        /*
         * Set up some pagetable state before starting to set any ptes.
@@ -1206,3 +1233,139 @@ asmlinkage void __init xen_start_kernel(void)
        x86_64_start_reservations((char *)__pa_symbol(&boot_params));
 #endif
 }
+
+static uint32_t xen_cpuid_base(void)
+{
+       uint32_t base, eax, ebx, ecx, edx;
+       char signature[13];
+
+       for (base = 0x40000000; base < 0x40010000; base += 0x100) {
+               cpuid(base, &eax, &ebx, &ecx, &edx);
+               *(uint32_t *)(signature + 0) = ebx;
+               *(uint32_t *)(signature + 4) = ecx;
+               *(uint32_t *)(signature + 8) = edx;
+               signature[12] = 0;
+
+               if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2))
+                       return base;
+       }
+
+       return 0;
+}
+
+static int init_hvm_pv_info(int *major, int *minor)
+{
+       uint32_t eax, ebx, ecx, edx, pages, msr, base;
+       u64 pfn;
+
+       base = xen_cpuid_base();
+       cpuid(base + 1, &eax, &ebx, &ecx, &edx);
+
+       *major = eax >> 16;
+       *minor = eax & 0xffff;
+       printk(KERN_INFO "Xen version %d.%d.\n", *major, *minor);
+
+       cpuid(base + 2, &pages, &msr, &ecx, &edx);
+
+       pfn = __pa(hypercall_page);
+       wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
+
+       xen_setup_features();
+
+       pv_info = xen_info;
+       pv_info.kernel_rpl = 0;
+
+       xen_domain_type = XEN_HVM_DOMAIN;
+
+       return 0;
+}
+
+void xen_hvm_init_shared_info(void)
+{
+       int cpu;
+       struct xen_add_to_physmap xatp;
+       static struct shared_info *shared_info_page = 0;
+
+       if (!shared_info_page)
+               shared_info_page = (struct shared_info *)
+                       extend_brk(PAGE_SIZE, PAGE_SIZE);
+       xatp.domid = DOMID_SELF;
+       xatp.idx = 0;
+       xatp.space = XENMAPSPACE_shared_info;
+       xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
+       if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+               BUG();
+
+       HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
+
+       /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
+        * page, we use it in the event channel upcall and in some pvclock
+        * related functions. We don't need the vcpu_info placement
+        * optimizations because we don't use any pv_mmu or pv_irq op on
+        * HVM.
+        * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is
+        * online but xen_hvm_init_shared_info is run at resume time too and
+        * in that case multiple vcpus might be online. */
+       for_each_online_cpu(cpu) {
+               per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
+       }
+}
+
+#ifdef CONFIG_XEN_PVHVM
+static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
+                                   unsigned long action, void *hcpu)
+{
+       int cpu = (long)hcpu;
+       switch (action) {
+       case CPU_UP_PREPARE:
+               per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata xen_hvm_cpu_notifier = {
+       .notifier_call  = xen_hvm_cpu_notify,
+};
+
+static void __init xen_hvm_guest_init(void)
+{
+       int r;
+       int major, minor;
+
+       r = init_hvm_pv_info(&major, &minor);
+       if (r < 0)
+               return;
+
+       xen_hvm_init_shared_info();
+
+       if (xen_feature(XENFEAT_hvm_callback_vector))
+               xen_have_vector_callback = 1;
+       register_cpu_notifier(&xen_hvm_cpu_notifier);
+       xen_unplug_emulated_devices();
+       have_vcpu_info_placement = 0;
+       x86_init.irqs.intr_init = xen_init_IRQ;
+       xen_hvm_init_time_ops();
+       xen_hvm_init_mmu_ops();
+}
+
+static bool __init xen_hvm_platform(void)
+{
+       if (xen_pv_domain())
+               return false;
+
+       if (!xen_cpuid_base())
+               return false;
+
+       return true;
+}
+
+const __refconst struct hypervisor_x86 x86_hyper_xen_hvm = {
+       .name                   = "Xen HVM",
+       .detect                 = xen_hvm_platform,
+       .init_platform          = xen_hvm_guest_init,
+};
+EXPORT_SYMBOL(x86_hyper_xen_hvm);
+#endif
index 914f04695ce5e1a917e786ab2ac231369083ec1e..413b19b3d0fe5322ebe5a492d432eb132304aadf 100644 (file)
@@ -58,6 +58,7 @@
 
 #include <xen/page.h>
 #include <xen/interface/xen.h>
+#include <xen/interface/hvm/hvm_op.h>
 #include <xen/interface/version.h>
 #include <xen/hvc-console.h>
 
@@ -1941,6 +1942,40 @@ void __init xen_init_mmu_ops(void)
        pv_mmu_ops = xen_mmu_ops;
 }
 
+#ifdef CONFIG_XEN_PVHVM
+static void xen_hvm_exit_mmap(struct mm_struct *mm)
+{
+       struct xen_hvm_pagetable_dying a;
+       int rc;
+
+       a.domid = DOMID_SELF;
+       a.gpa = __pa(mm->pgd);
+       rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
+       WARN_ON_ONCE(rc < 0);
+}
+
+static int is_pagetable_dying_supported(void)
+{
+       struct xen_hvm_pagetable_dying a;
+       int rc = 0;
+
+       a.domid = DOMID_SELF;
+       a.gpa = 0x00;
+       rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
+       if (rc < 0) {
+               printk(KERN_DEBUG "HVMOP_pagetable_dying not supported\n");
+               return 0;
+       }
+       return 1;
+}
+
+void __init xen_hvm_init_mmu_ops(void)
+{
+       if (is_pagetable_dying_supported())
+               pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap;
+}
+#endif
+
 #ifdef CONFIG_XEN_DEBUG_FS
 
 static struct dentry *d_mmu_debug;
index 5fe6bc7f5ecfe6626755183a88959818c3a3981f..fa938c4aa2f72940e56c439f01d4e14f6aa499ba 100644 (file)
@@ -60,4 +60,5 @@ void  xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
 unsigned long xen_read_cr2_direct(void);
 
 extern void xen_init_mmu_ops(void);
+extern void xen_hvm_init_mmu_ops(void);
 #endif /* _XEN_MMU_H */
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c
new file mode 100644 (file)
index 0000000..554c002
--- /dev/null
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * platform-pci-unplug.c
+ *
+ * Xen platform PCI device driver
+ * Copyright (c) 2010, Citrix
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <xen/platform_pci.h>
+
+#define XEN_PLATFORM_ERR_MAGIC -1
+#define XEN_PLATFORM_ERR_PROTOCOL -2
+#define XEN_PLATFORM_ERR_BLACKLIST -3
+
+/* store the value of xen_emul_unplug after the unplug is done */
+int xen_platform_pci_unplug;
+EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
+#ifdef CONFIG_XEN_PVHVM
+static int xen_emul_unplug;
+
+static int __init check_platform_magic(void)
+{
+       short magic;
+       char protocol;
+
+       magic = inw(XEN_IOPORT_MAGIC);
+       if (magic != XEN_IOPORT_MAGIC_VAL) {
+               printk(KERN_ERR "Xen Platform PCI: unrecognised magic value\n");
+               return XEN_PLATFORM_ERR_MAGIC;
+       }
+
+       protocol = inb(XEN_IOPORT_PROTOVER);
+
+       printk(KERN_DEBUG "Xen Platform PCI: I/O protocol version %d\n",
+                       protocol);
+
+       switch (protocol) {
+       case 1:
+               outw(XEN_IOPORT_LINUX_PRODNUM, XEN_IOPORT_PRODNUM);
+               outl(XEN_IOPORT_LINUX_DRVVER, XEN_IOPORT_DRVVER);
+               if (inw(XEN_IOPORT_MAGIC) != XEN_IOPORT_MAGIC_VAL) {
+                       printk(KERN_ERR "Xen Platform: blacklisted by host\n");
+                       return XEN_PLATFORM_ERR_BLACKLIST;
+               }
+               break;
+       default:
+               printk(KERN_WARNING "Xen Platform PCI: unknown I/O protocol version");
+               return XEN_PLATFORM_ERR_PROTOCOL;
+       }
+
+       return 0;
+}
+
+void __init xen_unplug_emulated_devices(void)
+{
+       int r;
+
+       /* check the version of the xen platform PCI device */
+       r = check_platform_magic();
+       /* If the version matches enable the Xen platform PCI driver.
+        * Also enable the Xen platform PCI driver if the version is really old
+        * and the user told us to ignore it. */
+       if (r && !(r == XEN_PLATFORM_ERR_MAGIC &&
+                       (xen_emul_unplug & XEN_UNPLUG_IGNORE)))
+               return;
+       /* Set the default value of xen_emul_unplug depending on whether or
+        * not the Xen PV frontends and the Xen platform PCI driver have
+        * been compiled for this kernel (modules or built-in are both OK). */
+       if (!xen_emul_unplug) {
+               if (xen_must_unplug_nics()) {
+                       printk(KERN_INFO "Netfront and the Xen platform PCI driver have "
+                                       "been compiled for this kernel: unplug emulated NICs.\n");
+                       xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
+               }
+               if (xen_must_unplug_disks()) {
+                       printk(KERN_INFO "Blkfront and the Xen platform PCI driver have "
+                                       "been compiled for this kernel: unplug emulated disks.\n"
+                                       "You might have to change the root device\n"
+                                       "from /dev/hd[a-d] to /dev/xvd[a-d]\n"
+                                       "in your root= kernel command line option\n");
+                       xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
+               }
+       }
+       /* Now unplug the emulated devices */
+       if (!(xen_emul_unplug & XEN_UNPLUG_IGNORE))
+               outw(xen_emul_unplug, XEN_IOPORT_UNPLUG);
+       xen_platform_pci_unplug = xen_emul_unplug;
+}
+
+static int __init parse_xen_emul_unplug(char *arg)
+{
+       char *p, *q;
+       int l;
+
+       for (p = arg; p; p = q) {
+               q = strchr(p, ',');
+               if (q) {
+                       l = q - p;
+                       q++;
+               } else {
+                       l = strlen(p);
+               }
+               if (!strncmp(p, "all", l))
+                       xen_emul_unplug |= XEN_UNPLUG_ALL;
+               else if (!strncmp(p, "ide-disks", l))
+                       xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
+               else if (!strncmp(p, "aux-ide-disks", l))
+                       xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS;
+               else if (!strncmp(p, "nics", l))
+                       xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
+               else if (!strncmp(p, "ignore", l))
+                       xen_emul_unplug |= XEN_UNPLUG_IGNORE;
+               else
+                       printk(KERN_WARNING "unrecognised option '%s' "
+                                "in parameter 'xen_emul_unplug'\n", p);
+       }
+       return 0;
+}
+early_param("xen_emul_unplug", parse_xen_emul_unplug);
+#endif
index ad0047f47cd476004c99485877f6d62a7db20d86..328b003054267d074610fdce51c39b063fae48e6 100644 (file)
@@ -20,6 +20,7 @@
 #include <xen/page.h>
 #include <xen/interface/callback.h>
 #include <xen/interface/physdev.h>
+#include <xen/interface/memory.h>
 #include <xen/features.h>
 
 #include "xen-ops.h"
@@ -32,6 +33,73 @@ extern void xen_sysenter_target(void);
 extern void xen_syscall_target(void);
 extern void xen_syscall32_target(void);
 
+static unsigned long __init xen_release_chunk(phys_addr_t start_addr,
+                                             phys_addr_t end_addr)
+{
+       struct xen_memory_reservation reservation = {
+               .address_bits = 0,
+               .extent_order = 0,
+               .domid        = DOMID_SELF
+       };
+       unsigned long start, end;
+       unsigned long len = 0;
+       unsigned long pfn;
+       int ret;
+
+       start = PFN_UP(start_addr);
+       end = PFN_DOWN(end_addr);
+
+       if (end <= start)
+               return 0;
+
+       printk(KERN_INFO "xen_release_chunk: looking at area pfn %lx-%lx: ",
+              start, end);
+       for(pfn = start; pfn < end; pfn++) {
+               unsigned long mfn = pfn_to_mfn(pfn);
+
+               /* Make sure pfn exists to start with */
+               if (mfn == INVALID_P2M_ENTRY || mfn_to_pfn(mfn) != pfn)
+                       continue;
+
+               set_xen_guest_handle(reservation.extent_start, &mfn);
+               reservation.nr_extents = 1;
+
+               ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                          &reservation);
+               WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n",
+                    start, end, ret);
+               if (ret == 1) {
+                       set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
+                       len++;
+               }
+       }
+       printk(KERN_CONT "%ld pages freed\n", len);
+
+       return len;
+}
+
+static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
+                                                    const struct e820map *e820)
+{
+       phys_addr_t max_addr = PFN_PHYS(max_pfn);
+       phys_addr_t last_end = 0;
+       unsigned long released = 0;
+       int i;
+
+       for (i = 0; i < e820->nr_map && last_end < max_addr; i++) {
+               phys_addr_t end = e820->map[i].addr;
+               end = min(max_addr, end);
+
+               released += xen_release_chunk(last_end, end);
+               last_end = e820->map[i].addr + e820->map[i].size;
+       }
+
+       if (last_end < max_addr)
+               released += xen_release_chunk(last_end, max_addr);
+
+       printk(KERN_INFO "released %ld pages of unused memory\n", released);
+       return released;
+}
 
 /**
  * machine_specific_memory_setup - Hook for machine specific memory setup.
@@ -67,6 +135,8 @@ char * __init xen_memory_setup(void)
 
        sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
 
+       xen_return_unused_memory(xen_start_info->nr_pages, &e820);
+
        return "Xen";
 }
 
@@ -156,6 +226,8 @@ void __init xen_arch_setup(void)
        struct physdev_set_iopl set_iopl;
        int rc;
 
+       xen_panic_handler_init();
+
        HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
        HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
 
index a29693fd3138e06bbd46ad875249da6c5a35cdce..25f232b18a823a5e3f015c2dfac4b38a39dcb2ed 100644 (file)
@@ -394,6 +394,8 @@ static void stop_self(void *v)
        load_cr3(swapper_pg_dir);
        /* should set up a minimal gdt */
 
+       set_cpu_online(cpu, false);
+
        HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL);
        BUG();
 }
index a9c6611080347bd4368beff2ab582d07347fa256..1d789d56877cd509a11a4aff08f38952b892c79f 100644 (file)
@@ -26,6 +26,18 @@ void xen_pre_suspend(void)
                BUG();
 }
 
+void xen_hvm_post_suspend(int suspend_cancelled)
+{
+       int cpu;
+       xen_hvm_init_shared_info();
+       xen_callback_vector();
+       if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
+               for_each_online_cpu(cpu) {
+                       xen_setup_runstate_info(cpu);
+               }
+       }
+}
+
 void xen_post_suspend(int suspend_cancelled)
 {
        xen_build_mfn_list_list();
index b3c6c59ed302862ecde2b2b78f88287954db991d..1a5353a753fcd10e1330c03d1af43a6fe9c5a5b7 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/xen/hypercall.h>
 
 #include <xen/events.h>
+#include <xen/features.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/vcpu.h>
 
@@ -155,47 +156,8 @@ static void do_stolen_accounting(void)
        account_idle_ticks(ticks);
 }
 
-/*
- * Xen sched_clock implementation.  Returns the number of unstolen
- * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED
- * states.
- */
-unsigned long long xen_sched_clock(void)
-{
-       struct vcpu_runstate_info state;
-       cycle_t now;
-       u64 ret;
-       s64 offset;
-
-       /*
-        * Ideally sched_clock should be called on a per-cpu basis
-        * anyway, so preempt should already be disabled, but that's
-        * not current practice at the moment.
-        */
-       preempt_disable();
-
-       now = xen_clocksource_read();
-
-       get_runstate_snapshot(&state);
-
-       WARN_ON(state.state != RUNSTATE_running);
-
-       offset = now - state.state_entry_time;
-       if (offset < 0)
-               offset = 0;
-
-       ret = state.time[RUNSTATE_blocked] +
-               state.time[RUNSTATE_running] +
-               offset;
-
-       preempt_enable();
-
-       return ret;
-}
-
-
 /* Get the TSC speed from Xen */
-unsigned long xen_tsc_khz(void)
+static unsigned long xen_tsc_khz(void)
 {
        struct pvclock_vcpu_time_info *info =
                &HYPERVISOR_shared_info->vcpu_info[0].time;
@@ -230,7 +192,7 @@ static void xen_read_wallclock(struct timespec *ts)
        put_cpu_var(xen_vcpu);
 }
 
-unsigned long xen_get_wallclock(void)
+static unsigned long xen_get_wallclock(void)
 {
        struct timespec ts;
 
@@ -238,7 +200,7 @@ unsigned long xen_get_wallclock(void)
        return ts.tv_sec;
 }
 
-int xen_set_wallclock(unsigned long now)
+static int xen_set_wallclock(unsigned long now)
 {
        /* do nothing for domU */
        return -1;
@@ -473,7 +435,11 @@ void xen_timer_resume(void)
        }
 }
 
-__init void xen_time_init(void)
+static const struct pv_time_ops xen_time_ops __initdata = {
+       .sched_clock = xen_clocksource_read,
+};
+
+static __init void xen_time_init(void)
 {
        int cpu = smp_processor_id();
        struct timespec tp;
@@ -497,3 +463,47 @@ __init void xen_time_init(void)
        xen_setup_timer(cpu);
        xen_setup_cpu_clockevents();
 }
+
+__init void xen_init_time_ops(void)
+{
+       pv_time_ops = xen_time_ops;
+
+       x86_init.timers.timer_init = xen_time_init;
+       x86_init.timers.setup_percpu_clockev = x86_init_noop;
+       x86_cpuinit.setup_percpu_clockev = x86_init_noop;
+
+       x86_platform.calibrate_tsc = xen_tsc_khz;
+       x86_platform.get_wallclock = xen_get_wallclock;
+       x86_platform.set_wallclock = xen_set_wallclock;
+}
+
+#ifdef CONFIG_XEN_PVHVM
+static void xen_hvm_setup_cpu_clockevents(void)
+{
+       int cpu = smp_processor_id();
+       xen_setup_runstate_info(cpu);
+       xen_setup_timer(cpu);
+       xen_setup_cpu_clockevents();
+}
+
+__init void xen_hvm_init_time_ops(void)
+{
+       /* vector callback is needed otherwise we cannot receive interrupts
+        * on cpu > 0 */
+       if (!xen_have_vector_callback && num_present_cpus() > 1)
+               return;
+       if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
+               printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
+                               "disable pv timer\n");
+               return;
+       }
+
+       pv_time_ops = xen_time_ops;
+       x86_init.timers.setup_percpu_clockev = xen_time_init;
+       x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents;
+
+       x86_platform.calibrate_tsc = xen_tsc_khz;
+       x86_platform.get_wallclock = xen_get_wallclock;
+       x86_platform.set_wallclock = xen_set_wallclock;
+}
+#endif
index f9153a300bcee998e1f78f95a202cc9036df79ca..7c8ab86163e9142b1c49c6c1ddad13ff203b7a59 100644 (file)
@@ -38,6 +38,10 @@ void xen_enable_sysenter(void);
 void xen_enable_syscall(void);
 void xen_vcpu_restore(void);
 
+void xen_callback_vector(void);
+void xen_hvm_init_shared_info(void);
+void __init xen_unplug_emulated_devices(void);
+
 void __init xen_build_dynamic_phys_to_machine(void);
 
 void xen_init_irq_ops(void);
@@ -46,11 +50,8 @@ void xen_setup_runstate_info(int cpu);
 void xen_teardown_timer(int cpu);
 cycle_t xen_clocksource_read(void);
 void xen_setup_cpu_clockevents(void);
-unsigned long xen_tsc_khz(void);
-void __init xen_time_init(void);
-unsigned long xen_get_wallclock(void);
-int xen_set_wallclock(unsigned long time);
-unsigned long long xen_sched_clock(void);
+void __init xen_init_time_ops(void);
+void __init xen_hvm_init_time_ops(void);
 
 irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
 
@@ -101,4 +102,6 @@ void xen_sysret32(void);
 void xen_sysret64(void);
 void xen_adjust_exception_frame(void);
 
+extern int xen_panic_handler_init(void);
+
 #endif /* XEN_OPS_H */
index ebe228d02b08d6265723306b970a7fd338c5f9ec..0859bfd8ae93382909420ff1c2076fb170a46469 100644 (file)
@@ -48,9 +48,6 @@ config HZ
        int
        default 100
 
-config GENERIC_TIME
-       def_bool y
-
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 
diff --git a/arch/xtensa/include/asm/local64.h b/arch/xtensa/include/asm/local64.h
new file mode 100644 (file)
index 0000000..36c93b5
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
index 91874e048552364280d7905aa817e957be2f9c48..ae473445ad6daf11254ee269c3194c9ed03e0cb1 100644 (file)
@@ -101,7 +101,9 @@ obj-y                               += firmware/
 obj-$(CONFIG_CRYPTO)           += crypto/
 obj-$(CONFIG_SUPERH)           += sh/
 obj-$(CONFIG_ARCH_SHMOBILE)    += sh/
-obj-$(CONFIG_GENERIC_TIME)     += clocksource/
+ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
+obj-y                          += clocksource/
+endif
 obj-$(CONFIG_DMA_ENGINE)       += dma/
 obj-$(CONFIG_DCA)              += dca/
 obj-$(CONFIG_HID)              += hid/
index 446aced33aff81d7a2c4a949abce8979006db720..b76848c80be34729c56bd20d04f75f9f534cbb36 100644 (file)
@@ -77,7 +77,7 @@ static void power_saving_mwait_init(void)
        power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
                (highest_subcstate - 1);
 
-#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86)
+#if defined(CONFIG_X86)
        switch (boot_cpu_data.x86_vendor) {
        case X86_VENDOR_AMD:
        case X86_VENDOR_INTEL:
index 78418ce4fc78a5cf99203e7890f81f36e23a10a8..46cce391fa462000aeec64396691382e3a04f15b 100644 (file)
@@ -191,36 +191,11 @@ acpi_status __init acpi_os_initialize(void)
        return AE_OK;
 }
 
-static void bind_to_cpu0(struct work_struct *work)
-{
-       set_cpus_allowed_ptr(current, cpumask_of(0));
-       kfree(work);
-}
-
-static void bind_workqueue(struct workqueue_struct *wq)
-{
-       struct work_struct *work;
-
-       work = kzalloc(sizeof(struct work_struct), GFP_KERNEL);
-       INIT_WORK(work, bind_to_cpu0);
-       queue_work(wq, work);
-}
-
 acpi_status acpi_os_initialize1(void)
 {
-       /*
-        * On some machines, a software-initiated SMI causes corruption unless
-        * the SMI runs on CPU 0.  An SMI can be initiated by any AML, but
-        * typically it's done in GPE-related methods that are run via
-        * workqueues, so we can avoid the known corruption cases by binding
-        * the workqueues to CPU 0.
-        */
-       kacpid_wq = create_singlethread_workqueue("kacpid");
-       bind_workqueue(kacpid_wq);
-       kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
-       bind_workqueue(kacpi_notify_wq);
-       kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug");
-       bind_workqueue(kacpi_hotplug_wq);
+       kacpid_wq = create_workqueue("kacpid");
+       kacpi_notify_wq = create_workqueue("kacpi_notify");
+       kacpi_hotplug_wq = create_workqueue("kacpi_hotplug");
        BUG_ON(!kacpid_wq);
        BUG_ON(!kacpi_notify_wq);
        BUG_ON(!kacpi_hotplug_wq);
@@ -766,7 +741,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
        else
                INIT_WORK(&dpc->work, acpi_os_execute_deferred);
 
-       ret = queue_work(queue, &dpc->work);
+       /*
+        * On some machines, a software-initiated SMI causes corruption unless
+        * the SMI runs on CPU 0.  An SMI can be initiated by any AML, but
+        * typically it's done in GPE-related methods that are run via
+        * workqueues, so we can avoid the known corruption cases by always
+        * queueing on CPU 0.
+        */
+       ret = queue_work_on(0, queue, &dpc->work);
 
        if (!ret) {
                printk(KERN_ERR PREFIX
index 4eac59393edc5b13e3c25283f08e6cf899fb61d7..1f67057af2a571991481bb761d157320b9d3f329 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/pci.h>
 #include <linux/pci-acpi.h>
+#include <linux/pci-aspm.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
 #include <acpi/acpi_bus.h>
@@ -543,6 +544,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
        if (flags != base_flags)
                acpi_pci_osc_support(root, flags);
 
+       status = acpi_pci_osc_control_set(root->device->handle,
+                                         OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+
+       if (ACPI_FAILURE(status)) {
+               printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n");
+               pcie_no_aspm();
+       }
+
        pci_acpi_add_bus_pm_notifier(device, root->bus);
        if (device->wakeup.flags.run_wake)
                device_set_run_wake(root->bus->bridge, true);
index e9a8026d39f091444ddcf90446f008fc407cc9c8..b4c2f3bdadebc9ad6b23ce3ea1d2a8114b5c022f 100644 (file)
@@ -164,7 +164,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
        if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
                return;
 
-       if (boot_cpu_has(X86_FEATURE_AMDC1E))
+       if (c1e_detected)
                type = ACPI_STATE_C1;
 
        /*
@@ -264,7 +264,7 @@ int acpi_processor_resume(struct acpi_device * device)
        return 0;
 }
 
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
+#if defined(CONFIG_X86)
 static void tsc_check_state(int state)
 {
        switch (boot_cpu_data.x86_vendor) {
index aa85a98d3a4ff7da59a23d95fb7e361d4bcfa7b3..8fae6afd6a3d0db3484d050dd3e19027f48fb753 100644 (file)
@@ -187,6 +187,15 @@ config ATA_PIIX
 
          If unsure, say N.
 
+config SATA_DWC
+       tristate "DesignWare Cores SATA support"
+       depends on 460EX
+       help
+         This option enables support for the on-chip SATA controller of the
+         AppliedMicro processor 460EX.
+
+         If unsure, say N.
+
 config SATA_MV
        tristate "Marvell SATA support"
        help
@@ -796,6 +805,15 @@ config PATA_RZ1000
 
          If unsure, say N.
 
+config PATA_SAMSUNG_CF
+       tristate "Samsung SoC PATA support"
+       depends on SAMSUNG_DEV_IDE
+       help
+         This option enables basic support for Samsung's S3C/S5P board
+         PATA controllers via the new ATA layer
+
+         If unsure, say N.
+
 config PATA_WINBOND_VLB
        tristate "Winbond W83759A VLB PATA support (Experimental)"
        depends on ISA && EXPERIMENTAL
index 7ef89d73df63d21323e4e47786e33ed51039ca5b..6540632bda082d51ca656ae25b36641848c07814 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
 obj-$(CONFIG_SATA_FSL)         += sata_fsl.o
 obj-$(CONFIG_SATA_INIC162X)    += sata_inic162x.o
 obj-$(CONFIG_SATA_SIL24)       += sata_sil24.o
+obj-$(CONFIG_SATA_DWC)         += sata_dwc_460ex.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)         += pdc_adma.o
@@ -87,6 +88,7 @@ obj-$(CONFIG_PATA_OF_PLATFORM)        += pata_of_platform.o
 obj-$(CONFIG_PATA_QDI)         += pata_qdi.o
 obj-$(CONFIG_PATA_RB532)       += pata_rb532_cf.o
 obj-$(CONFIG_PATA_RZ1000)      += pata_rz1000.o
+obj-$(CONFIG_PATA_SAMSUNG_CF)  += pata_samsung_cf.o
 obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
 
 # Should be last but two libata driver
index f2522534ae6327a94678afb080eafc5dac2d9f4c..fe75d8befc3a27aaa5d6c8048cbaa498416c7322 100644 (file)
@@ -1042,7 +1042,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        VPRINTK("ENTER\n");
 
-       WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS);
+       WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS);
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
index 5e11b160f247a10c6ae456f7d9bb02ec0ba743a4..4e97f33cca4406212b9769c6c13fc11afc02bc4a 100644 (file)
@@ -54,19 +54,13 @@ static int __init ahci_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       if (pdata && pdata->init) {
-               rc = pdata->init(dev);
-               if (rc)
-                       return rc;
-       }
-
        if (pdata && pdata->ata_port_info)
                pi = *pdata->ata_port_info;
 
        hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv) {
-               rc = -ENOMEM;
-               goto err0;
+               dev_err(dev, "can't alloc ahci_host_priv\n");
+               return -ENOMEM;
        }
 
        hpriv->flags |= (unsigned long)pi.private_data;
@@ -74,8 +68,19 @@ static int __init ahci_probe(struct platform_device *pdev)
        hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
        if (!hpriv->mmio) {
                dev_err(dev, "can't map %pR\n", mem);
-               rc = -ENOMEM;
-               goto err0;
+               return -ENOMEM;
+       }
+
+       /*
+        * Some platforms might need to prepare for mmio region access,
+        * which could be done in the following init call. So, the mmio
+        * region shouldn't be accessed before init (if provided) has
+        * returned successfully.
+        */
+       if (pdata && pdata->init) {
+               rc = pdata->init(dev, hpriv->mmio);
+               if (rc)
+                       return rc;
        }
 
        ahci_save_initial_config(dev, hpriv,
@@ -166,7 +171,6 @@ static int __devexit ahci_remove(struct platform_device *pdev)
 }
 
 static struct platform_driver ahci_driver = {
-       .probe = ahci_probe,
        .remove = __devexit_p(ahci_remove),
        .driver = {
                .name = "ahci",
index 7107a6929deb8816121afb4ce1048bcedc2c588b..cc5f7726bde704bb4931bfce4d58666e41555db5 100644 (file)
@@ -54,7 +54,6 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused)
        const struct pci_device_id *id = ap->host->private_data;
        int dma_enabled = 0;
        struct ata_device *dev;
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
        if (id->driver_data & ATA_GEN_FORCE_DMA) {
                dma_enabled = 0xff;
@@ -63,9 +62,6 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused)
                dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
        }
 
-       if (pdev->vendor == PCI_VENDOR_ID_CENATEK)
-               dma_enabled = 0xFF;
-
        ata_for_each_dev(dev, link, ENABLED) {
                /* We don't really care */
                dev->pio_mode = XFER_PIO_0;
index 7409f98d2ae63ba4683d440b60942d774a04318b..3971bc0a4838235ea26f4bff0b97ec7dd3335b69 100644 (file)
@@ -158,6 +158,7 @@ struct piix_map_db {
 struct piix_host_priv {
        const int *map;
        u32 saved_iocfg;
+       spinlock_t sidpr_lock;  /* FIXME: remove once locking in EH is fixed */
        void __iomem *sidpr;
 };
 
@@ -951,12 +952,15 @@ static int piix_sidpr_scr_read(struct ata_link *link,
                               unsigned int reg, u32 *val)
 {
        struct piix_host_priv *hpriv = link->ap->host->private_data;
+       unsigned long flags;
 
        if (reg >= ARRAY_SIZE(piix_sidx_map))
                return -EINVAL;
 
+       spin_lock_irqsave(&hpriv->sidpr_lock, flags);
        piix_sidpr_sel(link, reg);
        *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
+       spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
        return 0;
 }
 
@@ -964,12 +968,15 @@ static int piix_sidpr_scr_write(struct ata_link *link,
                                unsigned int reg, u32 val)
 {
        struct piix_host_priv *hpriv = link->ap->host->private_data;
+       unsigned long flags;
 
        if (reg >= ARRAY_SIZE(piix_sidx_map))
                return -EINVAL;
 
+       spin_lock_irqsave(&hpriv->sidpr_lock, flags);
        piix_sidpr_sel(link, reg);
        iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
+       spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
        return 0;
 }
 
@@ -1566,6 +1573,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
        hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv)
                return -ENOMEM;
+       spin_lock_init(&hpriv->sidpr_lock);
 
        /* Save IOCFG, this will be used for cable detection, quirk
         * detection and restoration on detach.  This is necessary
index ddf8e48627878999c17f686fcfb05dce669a2b9c..4972fdf4bd31ae225e5ef11b1ee7b4921f24f3d0 100644 (file)
@@ -98,8 +98,6 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
 unsigned int ata_print_id = 1;
 
-struct workqueue_struct *ata_aux_wq;
-
 struct ata_force_param {
        const char      *name;
        unsigned int    cbl;
@@ -4167,15 +4165,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "WDC AC23200L",       "21.10N21",     ATA_HORKAGE_NODMA },
        { "Compaq CRD-8241B",   NULL,           ATA_HORKAGE_NODMA },
        { "CRD-8400B",          NULL,           ATA_HORKAGE_NODMA },
-       { "CRD-8480B",          NULL,           ATA_HORKAGE_NODMA },
-       { "CRD-8482B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-848[02]B",       NULL,           ATA_HORKAGE_NODMA },
        { "CRD-84",             NULL,           ATA_HORKAGE_NODMA },
        { "SanDisk SDP3B",      NULL,           ATA_HORKAGE_NODMA },
        { "SanDisk SDP3B-64",   NULL,           ATA_HORKAGE_NODMA },
        { "SANYO CD-ROM CRD",   NULL,           ATA_HORKAGE_NODMA },
        { "HITACHI CDR-8",      NULL,           ATA_HORKAGE_NODMA },
-       { "HITACHI CDR-8335",   NULL,           ATA_HORKAGE_NODMA },
-       { "HITACHI CDR-8435",   NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8[34]35",NULL,           ATA_HORKAGE_NODMA },
        { "Toshiba CD-ROM XM-6202B", NULL,      ATA_HORKAGE_NODMA },
        { "TOSHIBA CD-ROM XM-1702BC", NULL,     ATA_HORKAGE_NODMA },
        { "CD-532E-A",          NULL,           ATA_HORKAGE_NODMA },
@@ -4211,70 +4207,16 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "OCZ CORE_SSD",       "02.10104",     ATA_HORKAGE_NONCQ },
 
        /* Seagate NCQ + FLUSH CACHE firmware bug */
-       { "ST31500341AS",       "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD19",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-
-       { "ST31000333AS",       "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD19",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-
-       { "ST3640623AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST31500341AS",       "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
-       { "ST3640323AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST31000333AS",       "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
-       { "ST3320813AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST3640[36]23AS",     "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
-       { "ST3320613AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST3320[68]13AS",     "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
        /* Blacklist entries taken from Silicon Image 3124/3132
@@ -4303,12 +4245,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* Devices which get the IVB wrong */
        { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
        /* Maybe we should just blacklist TSSTcorp... */
-       { "TSSTcorp CDDVDW SH-S202H", "SB00",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202H", "SB01",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202J", "SB00",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202J", "SB01",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202N", "SB00",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202N", "SB01",     ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202[HJN]", "SB0[01]",  ATA_HORKAGE_IVB, },
 
        /* Devices that do not need bridging limits applied */
        { "MTRON MSP-SATA*",            NULL,   ATA_HORKAGE_BRIDGE_OK, },
@@ -4326,29 +4263,73 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { }
 };
 
-static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
+/**
+ *     glob_match - match a text string against a glob-style pattern
+ *     @text: the string to be examined
+ *     @pattern: the glob-style pattern to be matched against
+ *
+ *     Either/both of text and pattern can be empty strings.
+ *
+ *     Match text against a glob-style pattern, with wildcards and simple sets:
+ *
+ *             ?       matches any single character.
+ *             *       matches any run of characters.
+ *             [xyz]   matches a single character from the set: x, y, or z.
+ *             [a-d]   matches a single character from the range: a, b, c, or d.
+ *             [a-d0-9] matches a single character from either range.
+ *
+ *     The special characters ?, [, -, or *, can be matched using a set, eg. [*]
+ *     Behaviour with malformed patterns is undefined, though generally reasonable.
+ *
+ *     Example patterns:  "SD1?",  "SD1[0-5]",  "*R0",  SD*1?[012]*xx"
+ *
+ *     This function uses one level of recursion per '*' in pattern.
+ *     Since it calls _nothing_ else, and has _no_ explicit local variables,
+ *     this will not cause stack problems for any reasonable use here.
+ *
+ *     RETURNS:
+ *     0 on match, 1 otherwise.
+ */
+static int glob_match (const char *text, const char *pattern)
 {
-       const char *p;
-       int len;
-
-       /*
-        * check for trailing wildcard: *\0
-        */
-       p = strchr(patt, wildchar);
-       if (p && ((*(p + 1)) == 0))
-               len = p - patt;
-       else {
-               len = strlen(name);
-               if (!len) {
-                       if (!*patt)
-                               return 0;
-                       return -1;
+       do {
+               /* Match single character or a '?' wildcard */
+               if (*text == *pattern || *pattern == '?') {
+                       if (!*pattern++)
+                               return 0;  /* End of both strings: match */
+               } else {
+                       /* Match single char against a '[' bracketed ']' pattern set */
+                       if (!*text || *pattern != '[')
+                               break;  /* Not a pattern set */
+                       while (*++pattern && *pattern != ']' && *text != *pattern) {
+                               if (*pattern == '-' && *(pattern - 1) != '[')
+                                       if (*text > *(pattern - 1) && *text < *(pattern + 1)) {
+                                               ++pattern;
+                                               break;
+                                       }
+                       }
+                       if (!*pattern || *pattern == ']')
+                               return 1;  /* No match */
+                       while (*pattern && *pattern++ != ']');
+               }
+       } while (*++text && *pattern);
+
+       /* Match any run of chars against a '*' wildcard */
+       if (*pattern == '*') {
+               if (!*++pattern)
+                       return 0;  /* Match: avoid recursion at end of pattern */
+               /* Loop to handle additional pattern chars after the wildcard */
+               while (*text) {
+                       if (glob_match(text, pattern) == 0)
+                               return 0;  /* Remainder matched */
+                       ++text;  /* Absorb (match) this char and try again */
                }
        }
-
-       return strncmp(patt, name, len);
+       if (!*text && !*pattern)
+               return 0;  /* End of both strings: match */
+       return 1;  /* No match */
 }
-
 static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
 {
        unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -4359,10 +4340,10 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
        ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
 
        while (ad->model_num) {
-               if (!strn_pattern_cmp(ad->model_num, model_num, '*')) {
+               if (!glob_match(model_num, ad->model_num)) {
                        if (ad->model_rev == NULL)
                                return ad->horkage;
-                       if (!strn_pattern_cmp(ad->model_rev, model_rev, '*'))
+                       if (!glob_match(model_rev, ad->model_rev))
                                return ad->horkage;
                }
                ad++;
@@ -5611,6 +5592,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN;
 #endif
 
+       mutex_init(&ap->scsi_scan_mutex);
        INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
        INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
        INIT_LIST_HEAD(&ap->eh_done_q);
@@ -6549,29 +6531,20 @@ static int __init ata_init(void)
 
        ata_parse_force_param();
 
-       ata_aux_wq = create_singlethread_workqueue("ata_aux");
-       if (!ata_aux_wq)
-               goto fail;
-
        rc = ata_sff_init();
-       if (rc)
-               goto fail;
+       if (rc) {
+               kfree(ata_force_tbl);
+               return rc;
+       }
 
        printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
        return 0;
-
-fail:
-       kfree(ata_force_tbl);
-       if (ata_aux_wq)
-               destroy_workqueue(ata_aux_wq);
-       return rc;
 }
 
 static void __exit ata_exit(void)
 {
        ata_sff_exit();
        kfree(ata_force_tbl);
-       destroy_workqueue(ata_aux_wq);
 }
 
 subsys_initcall(ata_init);
index f77a67303f8b3d0d724e4fccd3510a269a72b0c8..c9ae299b83428d039c13cce845e7acc497bcff13 100644 (file)
@@ -727,7 +727,7 @@ void ata_scsi_error(struct Scsi_Host *host)
        if (ap->pflags & ATA_PFLAG_LOADING)
                ap->pflags &= ~ATA_PFLAG_LOADING;
        else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG)
-               queue_delayed_work(ata_aux_wq, &ap->hotplug_task, 0);
+               schedule_delayed_work(&ap->hotplug_task, 0);
 
        if (ap->pflags & ATA_PFLAG_RECOVERED)
                ata_port_printk(ap, KERN_INFO, "EH complete\n");
@@ -2214,6 +2214,7 @@ const char *ata_get_cmd_descript(u8 command)
                { ATA_CMD_SMART,                "SMART" },
                { ATA_CMD_MEDIA_LOCK,           "DOOR LOCK" },
                { ATA_CMD_MEDIA_UNLOCK,         "DOOR UNLOCK" },
+               { ATA_CMD_DSM,                  "DATA SET MANAGEMENT" },
                { ATA_CMD_CHK_MED_CRD_TYP,      "CHECK MEDIA CARD TYPE" },
                { ATA_CMD_CFA_REQ_EXT_ERR,      "CFA REQUEST EXTENDED ERROR" },
                { ATA_CMD_CFA_WRITE_NE,         "CFA WRITE SECTORS WITHOUT ERASE" },
@@ -2944,7 +2945,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
                        ehc->i.flags |= ATA_EHI_SETMODE;
 
                        /* schedule the scsi_rescan_device() here */
-                       queue_work(ata_aux_wq, &(ap->scsi_rescan_task));
+                       schedule_work(&(ap->scsi_rescan_task));
                } else if (dev->class == ATA_DEV_UNKNOWN &&
                           ehc->tries[dev->devno] &&
                           ata_class_enabled(ehc->classes[dev->devno])) {
index a54273d2c3c6a9f432ae60d49496335452ecc1d6..d75c9c479d1a2dda6f545852d8c3f4161c162cb1 100644 (file)
@@ -3435,7 +3435,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
                                "                  switching to async\n");
        }
 
-       queue_delayed_work(ata_aux_wq, &ap->hotplug_task,
+       queue_delayed_work(system_long_wq, &ap->hotplug_task,
                           round_jiffies_relative(HZ));
 }
 
@@ -3582,6 +3582,7 @@ void ata_scsi_hotplug(struct work_struct *work)
        }
 
        DPRINTK("ENTER\n");
+       mutex_lock(&ap->scsi_scan_mutex);
 
        /* Unplug detached devices.  We cannot use link iterator here
         * because PMP links have to be scanned even if PMP is
@@ -3595,6 +3596,7 @@ void ata_scsi_hotplug(struct work_struct *work)
        /* scan for new ones */
        ata_scsi_scan_host(ap, 0);
 
+       mutex_unlock(&ap->scsi_scan_mutex);
        DPRINTK("EXIT\n");
 }
 
@@ -3673,9 +3675,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
  *     @work: Pointer to ATA port to perform scsi_rescan_device()
  *
  *     After ATA pass thru (SAT) commands are executed successfully,
- *     libata need to propagate the changes to SCSI layer.  This
- *     function must be executed from ata_aux_wq such that sdev
- *     attach/detach don't race with rescan.
+ *     libata need to propagate the changes to SCSI layer.
  *
  *     LOCKING:
  *     Kernel thread context (may sleep).
@@ -3688,6 +3688,7 @@ void ata_scsi_dev_rescan(struct work_struct *work)
        struct ata_device *dev;
        unsigned long flags;
 
+       mutex_lock(&ap->scsi_scan_mutex);
        spin_lock_irqsave(ap->lock, flags);
 
        ata_for_each_link(link, ap, EDGE) {
@@ -3707,6 +3708,7 @@ void ata_scsi_dev_rescan(struct work_struct *work)
        }
 
        spin_unlock_irqrestore(ap->lock, flags);
+       mutex_unlock(&ap->scsi_scan_mutex);
 }
 
 /**
index efa4a18cfb9d92fb9a79670abf69669f96f2d436..674c1436491f5e5e6df3a2334ee7f995775f7634 100644 (file)
@@ -3318,14 +3318,7 @@ void ata_sff_port_init(struct ata_port *ap)
 
 int __init ata_sff_init(void)
 {
-       /*
-        * FIXME: In UP case, there is only one workqueue thread and if you
-        * have more than one PIO device, latency is bloody awful, with
-        * occasional multi-second "hiccups" as one PIO device waits for
-        * another.  It's an ugly wart that users DO occasionally complain
-        * about; luckily most users have at most one PIO polled device.
-        */
-       ata_sff_wq = create_workqueue("ata_sff");
+       ata_sff_wq = alloc_workqueue("ata_sff", WQ_RESCUER, WQ_MAX_ACTIVE);
        if (!ata_sff_wq)
                return -ENOMEM;
 
index 4b84ed60324a4956cc031bc6b9e68fa6efdb6872..9ce1ecc63e394227348aae2a513a6cd204748748 100644 (file)
@@ -54,7 +54,6 @@ enum {
 };
 
 extern unsigned int ata_print_id;
-extern struct workqueue_struct *ata_aux_wq;
 extern int atapi_passthru16;
 extern int libata_fua;
 extern int libata_noacpi;
index 118c28e8abaf22205bfa1589fc854a6deda9ae1e..e944aa0c5517caaed7fc3cb8f10639245e8a3e3f 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/ata.h>
 #include <linux/libata.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -201,23 +200,25 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev,
 
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               pdev->io.BasePort1 = io->win[0].base;
-               pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               pdev->resource[0]->start = io->win[0].base;
+               if (!(io->flags & CISTPL_IO_16BIT)) {
+                       pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+                       pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+               }
                if (io->nwin == 2) {
-                       pdev->io.NumPorts1 = 8;
-                       pdev->io.BasePort2 = io->win[1].base;
-                       pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
-                       if (pcmcia_request_io(pdev, &pdev->io) != 0)
+                       pdev->resource[0]->end = 8;
+                       pdev->resource[1]->start = io->win[1].base;
+                       pdev->resource[1]->end = (stk->is_kme) ? 2 : 1;
+                       if (pcmcia_request_io(pdev) != 0)
                                return -ENODEV;
-                       stk->ctl_base = pdev->io.BasePort2;
+                       stk->ctl_base = pdev->resource[1]->start;
                } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
-                       pdev->io.NumPorts1 = io->win[0].len;
-                       pdev->io.NumPorts2 = 0;
-                       if (pcmcia_request_io(pdev, &pdev->io) != 0)
+                       pdev->resource[0]->end = io->win[0].len;
+                       pdev->resource[1]->end = 0;
+                       if (pcmcia_request_io(pdev) != 0)
                                return -ENODEV;
-                       stk->ctl_base = pdev->io.BasePort1 + 0x0e;
+                       stk->ctl_base = pdev->resource[0]->start + 0x0e;
                } else
                        return -ENODEV;
                /* If we've got this far, we're done */
@@ -246,9 +247,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
        struct ata_port_operations *ops = &pcmcia_port_ops;
 
        /* Set up attributes in order to probe card and get resources */
-       pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-       pdev->io.IOAddrLines = 3;
+       pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+       pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
        pdev->conf.Attributes = CONF_ENABLE_IRQ;
        pdev->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -271,7 +271,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
                if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
                        goto failed; /* No suitable config found */
        }
-       io_base = pdev->io.BasePort1;
+       io_base = pdev->resource[0]->start;
        ctl_base = stk->ctl_base;
        if (!pdev->irq)
                goto failed;
@@ -294,7 +294,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
 
        /* FIXME: Could be more ports at base + 0x10 but we only deal with
           one right now */
-       if (pdev->io.NumPorts1 >= 0x20)
+       if (resource_size(pdev->resource[0]) >= 0x20)
                n_ports = 2;
 
        if (pdev->manf_id == 0x0097 && pdev->card_id == 0x1620)
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c
new file mode 100644 (file)
index 0000000..6f9cfb2
--- /dev/null
@@ -0,0 +1,683 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * PATA driver for Samsung SoCs.
+ * Supports CF Interface in True IDE mode. Currently only PIO mode has been
+ * implemented; UDMA support has to be added.
+ *
+ * Based on:
+ *     PATA driver for AT91SAM9260 Static Memory Controller
+ *     PATA driver for Toshiba SCC controller
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/libata.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <plat/ata.h>
+#include <plat/regs-ata.h>
+
+#define DRV_NAME "pata_samsung_cf"
+#define DRV_VERSION "0.1"
+
+enum s3c_cpu_type {
+       TYPE_S3C64XX,
+       TYPE_S5PC100,
+       TYPE_S5PV210,
+};
+
+/*
+ * struct s3c_ide_info - S3C PATA instance.
+ * @clk: The clock resource for this controller.
+ * @ide_addr: The area mapped for the hardware registers.
+ * @sfr_addr: The area mapped for the special function registers.
+ * @irq: The IRQ number we are using.
+ * @cpu_type: The exact type of this controller.
+ * @fifo_status_reg: The ATA_FIFO_STATUS register offset.
+ */
+struct s3c_ide_info {
+       struct clk *clk;
+       void __iomem *ide_addr;
+       void __iomem *sfr_addr;
+       unsigned int irq;
+       enum s3c_cpu_type cpu_type;
+       unsigned int fifo_status_reg;
+};
+
+static void pata_s3c_set_endian(void __iomem *s3c_ide_regbase, u8 mode)
+{
+       u32 reg = readl(s3c_ide_regbase + S3C_ATA_CFG);
+       reg = mode ? (reg & ~S3C_ATA_CFG_SWAP) : (reg | S3C_ATA_CFG_SWAP);
+       writel(reg, s3c_ide_regbase + S3C_ATA_CFG);
+}
+
+static void pata_s3c_cfg_mode(void __iomem *s3c_ide_sfrbase)
+{
+       /* Select true-ide as the internal operating mode */
+       writel(readl(s3c_ide_sfrbase + S3C_CFATA_MUX) | S3C_CFATA_MUX_TRUEIDE,
+               s3c_ide_sfrbase + S3C_CFATA_MUX);
+}
+
+static unsigned long
+pata_s3c_setup_timing(struct s3c_ide_info *info, const struct ata_timing *ata)
+{
+       int t1 = ata->setup;
+       int t2 = ata->act8b;
+       int t2i = ata->rec8b;
+       ulong piotime;
+
+       piotime = ((t2i & 0xff) << 12) | ((t2 & 0xff) << 4) | (t1 & 0xf);
+
+       return piotime;
+}
+
+static void pata_s3c_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+       struct s3c_ide_info *info = ap->host->private_data;
+       struct ata_timing timing;
+       int cycle_time;
+       ulong ata_cfg = readl(info->ide_addr + S3C_ATA_CFG);
+       ulong piotime;
+
+       /* Enables IORDY if mode requires it */
+       if (ata_pio_need_iordy(adev))
+               ata_cfg |= S3C_ATA_CFG_IORDYEN;
+       else
+               ata_cfg &= ~S3C_ATA_CFG_IORDYEN;
+
+       cycle_time = (int)(1000000000UL / clk_get_rate(info->clk));
+
+       ata_timing_compute(adev, adev->pio_mode, &timing,
+                                       cycle_time * 1000, 0);
+
+       piotime = pata_s3c_setup_timing(info, &timing);
+
+       writel(ata_cfg, info->ide_addr + S3C_ATA_CFG);
+       writel(piotime, info->ide_addr + S3C_ATA_PIO_TIME);
+}
+
+/*
+ * Waits until the IDE controller is able to perform next read/write
+ * operation to the disk. Needed for 64XX series boards only.
+ */
+static int wait_for_host_ready(struct s3c_ide_info *info)
+{
+       ulong timeout;
+       void __iomem *fifo_reg = info->ide_addr + info->fifo_status_reg;
+
+       /* wait for maximum of 20 msec */
+       timeout = jiffies + msecs_to_jiffies(20);
+       while (time_before(jiffies, timeout)) {
+               if ((readl(fifo_reg) >> 28) == 0)
+                       return 0;
+       }
+       return -EBUSY;
+}
+
+/*
+ * Writes to one of the task file registers.
+ */
+static void ata_outb(struct ata_host *host, u8 addr, void __iomem *reg)
+{
+       struct s3c_ide_info *info = host->private_data;
+
+       wait_for_host_ready(info);
+       writeb(addr, reg);
+}
+
+/*
+ * Reads from one of the task file registers.
+ */
+static u8 ata_inb(struct ata_host *host, void __iomem *reg)
+{
+       struct s3c_ide_info *info = host->private_data;
+       u8 temp;
+
+       wait_for_host_ready(info);
+       (void) readb(reg);
+       wait_for_host_ready(info);
+       temp = readb(info->ide_addr + S3C_ATA_PIO_RDATA);
+       return temp;
+}
+
+/*
+ * pata_s3c_tf_load - send taskfile registers to host controller
+ */
+static void pata_s3c_tf_load(struct ata_port *ap,
+                               const struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+
+       if (tf->ctl != ap->last_ctl) {
+               ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr);
+               ap->last_ctl = tf->ctl;
+               ata_wait_idle(ap);
+       }
+
+       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+               ata_outb(ap->host, tf->hob_feature, ioaddr->feature_addr);
+               ata_outb(ap->host, tf->hob_nsect, ioaddr->nsect_addr);
+               ata_outb(ap->host, tf->hob_lbal, ioaddr->lbal_addr);
+               ata_outb(ap->host, tf->hob_lbam, ioaddr->lbam_addr);
+               ata_outb(ap->host, tf->hob_lbah, ioaddr->lbah_addr);
+       }
+
+       if (is_addr) {
+               ata_outb(ap->host, tf->feature, ioaddr->feature_addr);
+               ata_outb(ap->host, tf->nsect, ioaddr->nsect_addr);
+               ata_outb(ap->host, tf->lbal, ioaddr->lbal_addr);
+               ata_outb(ap->host, tf->lbam, ioaddr->lbam_addr);
+               ata_outb(ap->host, tf->lbah, ioaddr->lbah_addr);
+       }
+
+       if (tf->flags & ATA_TFLAG_DEVICE)
+               ata_outb(ap->host, tf->device, ioaddr->device_addr);
+
+       ata_wait_idle(ap);
+}
+
+/*
+ * pata_s3c_tf_read - input device's ATA taskfile shadow registers
+ */
+static void pata_s3c_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+
+       tf->feature = ata_inb(ap->host, ioaddr->error_addr);
+       tf->nsect = ata_inb(ap->host, ioaddr->nsect_addr);
+       tf->lbal = ata_inb(ap->host, ioaddr->lbal_addr);
+       tf->lbam = ata_inb(ap->host, ioaddr->lbam_addr);
+       tf->lbah = ata_inb(ap->host, ioaddr->lbah_addr);
+       tf->device = ata_inb(ap->host, ioaddr->device_addr);
+
+       if (tf->flags & ATA_TFLAG_LBA48) {
+               ata_outb(ap->host, tf->ctl | ATA_HOB, ioaddr->ctl_addr);
+               tf->hob_feature = ata_inb(ap->host, ioaddr->error_addr);
+               tf->hob_nsect = ata_inb(ap->host, ioaddr->nsect_addr);
+               tf->hob_lbal = ata_inb(ap->host, ioaddr->lbal_addr);
+               tf->hob_lbam = ata_inb(ap->host, ioaddr->lbam_addr);
+               tf->hob_lbah = ata_inb(ap->host, ioaddr->lbah_addr);
+               ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr);
+               ap->last_ctl = tf->ctl;
+       }
+}
+
+/*
+ * pata_s3c_exec_command - issue ATA command to host controller
+ */
+static void pata_s3c_exec_command(struct ata_port *ap,
+                               const struct ata_taskfile *tf)
+{
+       ata_outb(ap->host, tf->command, ap->ioaddr.command_addr);
+       ata_sff_pause(ap);
+}
+
+/*
+ * pata_s3c_check_status - Read device status register
+ */
+static u8 pata_s3c_check_status(struct ata_port *ap)
+{
+       return ata_inb(ap->host, ap->ioaddr.status_addr);
+}
+
+/*
+ * pata_s3c_check_altstatus - Read alternate device status register
+ */
+static u8 pata_s3c_check_altstatus(struct ata_port *ap)
+{
+       return ata_inb(ap->host, ap->ioaddr.altstatus_addr);
+}
+
+/*
+ * pata_s3c_data_xfer - Transfer data by PIO
+ */
+unsigned int pata_s3c_data_xfer(struct ata_device *dev, unsigned char *buf,
+                               unsigned int buflen, int rw)
+{
+       struct ata_port *ap = dev->link->ap;
+       struct s3c_ide_info *info = ap->host->private_data;
+       void __iomem *data_addr = ap->ioaddr.data_addr;
+       unsigned int words = buflen >> 1, i;
+       u16 *data_ptr = (u16 *)buf;
+
+       /* Requires wait same as in ata_inb/ata_outb */
+       if (rw == READ)
+               for (i = 0; i < words; i++, data_ptr++) {
+                       wait_for_host_ready(info);
+                       (void) readw(data_addr);
+                       wait_for_host_ready(info);
+                       *data_ptr = readw(info->ide_addr
+                                       + S3C_ATA_PIO_RDATA);
+               }
+       else
+               for (i = 0; i < words; i++, data_ptr++) {
+                       wait_for_host_ready(info);
+                       writew(*data_ptr, data_addr);
+               }
+
+       if (buflen & 0x01)
+               dev_err(ap->dev, "unexpected trailing data\n");
+
+       return words << 1;
+}
+
+/*
+ * pata_s3c_dev_select - Select device on ATA bus
+ */
+static void pata_s3c_dev_select(struct ata_port *ap, unsigned int device)
+{
+       u8 tmp = ATA_DEVICE_OBS;
+
+       if (device != 0)
+               tmp |= ATA_DEV1;
+
+       ata_outb(ap->host, tmp, ap->ioaddr.device_addr);
+       ata_sff_pause(ap);
+}
+
+/*
+ * pata_s3c_devchk - PATA device presence detection
+ */
+static unsigned int pata_s3c_devchk(struct ata_port *ap,
+                               unsigned int device)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       u8 nsect, lbal;
+
+       pata_s3c_dev_select(ap, device);
+
+       ata_outb(ap->host, 0x55, ioaddr->nsect_addr);
+       ata_outb(ap->host, 0xaa, ioaddr->lbal_addr);
+
+       ata_outb(ap->host, 0xaa, ioaddr->nsect_addr);
+       ata_outb(ap->host, 0x55, ioaddr->lbal_addr);
+
+       ata_outb(ap->host, 0x55, ioaddr->nsect_addr);
+       ata_outb(ap->host, 0xaa, ioaddr->lbal_addr);
+
+       nsect = ata_inb(ap->host, ioaddr->nsect_addr);
+       lbal = ata_inb(ap->host, ioaddr->lbal_addr);
+
+       if ((nsect == 0x55) && (lbal == 0xaa))
+               return 1;       /* we found a device */
+
+       return 0;               /* nothing found */
+}
+
+/*
+ * pata_s3c_wait_after_reset - wait for devices to become ready after reset
+ */
+static int pata_s3c_wait_after_reset(struct ata_link *link,
+               unsigned long deadline)
+{
+       int rc;
+
+       msleep(ATA_WAIT_AFTER_RESET);
+
+       /* always check readiness of the master device */
+       rc = ata_sff_wait_ready(link, deadline);
+       /* -ENODEV means the odd clown forgot the D7 pulldown resistor
+        * and TF status is 0xff, bail out on it too.
+        */
+       if (rc)
+               return rc;
+
+       return 0;
+}
+
+/*
+ * pata_s3c_bus_softreset - PATA device software reset
+ */
+static unsigned int pata_s3c_bus_softreset(struct ata_port *ap,
+               unsigned long deadline)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+
+       /* software reset.  causes dev0 to be selected */
+       ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr);
+       udelay(20);
+       ata_outb(ap->host, ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+       udelay(20);
+       ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr);
+       ap->last_ctl = ap->ctl;
+
+       return pata_s3c_wait_after_reset(&ap->link, deadline);
+}
+
+/*
+ * pata_s3c_softreset - reset host port via ATA SRST
+ */
+static int pata_s3c_softreset(struct ata_link *link, unsigned int *classes,
+                        unsigned long deadline)
+{
+       struct ata_port *ap = link->ap;
+       unsigned int devmask = 0;
+       int rc;
+       u8 err;
+
+       /* determine if device 0 is present */
+       if (pata_s3c_devchk(ap, 0))
+               devmask |= (1 << 0);
+
+       /* select device 0 again */
+       pata_s3c_dev_select(ap, 0);
+
+       /* issue bus reset */
+       rc = pata_s3c_bus_softreset(ap, deadline);
+       /* if link is occupied, -ENODEV too is an error */
+       if (rc && rc != -ENODEV) {
+               ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc);
+               return rc;
+       }
+
+       /* determine by signature whether we have ATA or ATAPI devices */
+       classes[0] = ata_sff_dev_classify(&ap->link.device[0],
+                                         devmask & (1 << 0), &err);
+
+       return 0;
+}
+
+/*
+ * pata_s3c_set_devctl - Write device control register
+ */
+static void pata_s3c_set_devctl(struct ata_port *ap, u8 ctl)
+{
+       ata_outb(ap->host, ctl, ap->ioaddr.ctl_addr);
+}
+
+static struct scsi_host_template pata_s3c_sht = {
+       ATA_PIO_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations pata_s3c_port_ops = {
+       .inherits               = &ata_sff_port_ops,
+       .sff_check_status       = pata_s3c_check_status,
+       .sff_check_altstatus    = pata_s3c_check_altstatus,
+       .sff_tf_load            = pata_s3c_tf_load,
+       .sff_tf_read            = pata_s3c_tf_read,
+       .sff_data_xfer          = pata_s3c_data_xfer,
+       .sff_exec_command       = pata_s3c_exec_command,
+       .sff_dev_select         = pata_s3c_dev_select,
+       .sff_set_devctl         = pata_s3c_set_devctl,
+       .softreset              = pata_s3c_softreset,
+       .set_piomode            = pata_s3c_set_piomode,
+};
+
+static struct ata_port_operations pata_s5p_port_ops = {
+       .inherits               = &ata_sff_port_ops,
+       .set_piomode            = pata_s3c_set_piomode,
+};
+
+static void pata_s3c_enable(void *s3c_ide_regbase, bool state)
+{
+       u32 temp = readl(s3c_ide_regbase + S3C_ATA_CTRL);
+       temp = state ? (temp | 1) : (temp & ~1);
+       writel(temp, s3c_ide_regbase + S3C_ATA_CTRL);
+}
+
+static irqreturn_t pata_s3c_irq(int irq, void *dev_instance)
+{
+       struct ata_host *host = dev_instance;
+       struct s3c_ide_info *info = host->private_data;
+       u32 reg;
+
+       reg = readl(info->ide_addr + S3C_ATA_IRQ);
+       writel(reg, info->ide_addr + S3C_ATA_IRQ);
+
+       return ata_sff_interrupt(irq, dev_instance);
+}
+
+static void pata_s3c_hwinit(struct s3c_ide_info *info,
+                               struct s3c_ide_platdata *pdata)
+{
+       switch (info->cpu_type) {
+       case TYPE_S3C64XX:
+               /* Configure as big endian */
+               pata_s3c_cfg_mode(info->sfr_addr);
+               pata_s3c_set_endian(info->ide_addr, 1);
+               pata_s3c_enable(info->ide_addr, true);
+               msleep(100);
+
+               /* Remove IRQ Status */
+               writel(0x1f, info->ide_addr + S3C_ATA_IRQ);
+               writel(0x1b, info->ide_addr + S3C_ATA_IRQ_MSK);
+               break;
+
+       case TYPE_S5PC100:
+               pata_s3c_cfg_mode(info->sfr_addr);
+               /* FALLTHROUGH */
+
+       case TYPE_S5PV210:
+               /* Configure as little endian */
+               pata_s3c_set_endian(info->ide_addr, 0);
+               pata_s3c_enable(info->ide_addr, true);
+               msleep(100);
+
+               /* Remove IRQ Status */
+               writel(0x3f, info->ide_addr + S3C_ATA_IRQ);
+               writel(0x3f, info->ide_addr + S3C_ATA_IRQ_MSK);
+               break;
+
+       default:
+               BUG();
+       }
+}
+
+static int __init pata_s3c_probe(struct platform_device *pdev)
+{
+       struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
+       struct device *dev = &pdev->dev;
+       struct s3c_ide_info *info;
+       struct resource *res;
+       struct ata_port *ap;
+       struct ata_host *host;
+       enum s3c_cpu_type cpu_type;
+       int ret;
+
+       cpu_type = platform_get_device_id(pdev)->driver_data;
+
+       info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+       if (!info) {
+               dev_err(dev, "failed to allocate memory for device data\n");
+               return -ENOMEM;
+       }
+
+       info->irq = platform_get_irq(pdev, 0);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(dev, "failed to get mem resource\n");
+               return -EINVAL;
+       }
+
+       if (!devm_request_mem_region(dev, res->start,
+                               resource_size(res), DRV_NAME)) {
+               dev_err(dev, "error requesting register region\n");
+               return -EBUSY;
+       }
+
+       info->ide_addr = devm_ioremap(dev, res->start, resource_size(res));
+       if (!info->ide_addr) {
+               dev_err(dev, "failed to map IO base address\n");
+               return -ENOMEM;
+       }
+
+       info->clk = clk_get(&pdev->dev, "cfcon");
+       if (IS_ERR(info->clk)) {
+               dev_err(dev, "failed to get access to cf controller clock\n");
+               ret = PTR_ERR(info->clk);
+               info->clk = NULL;
+               return ret;
+       }
+
+       clk_enable(info->clk);
+
+       /* init ata host */
+       host = ata_host_alloc(dev, 1);
+       if (!host) {
+               dev_err(dev, "failed to allocate ide host\n");
+               ret = -ENOMEM;
+               goto stop_clk;
+       }
+
+       ap = host->ports[0];
+       ap->flags |= ATA_FLAG_MMIO;
+       ap->pio_mask = ATA_PIO4;
+
+       if (cpu_type == TYPE_S3C64XX) {
+               ap->ops = &pata_s3c_port_ops;
+               info->sfr_addr = info->ide_addr + 0x1800;
+               info->ide_addr += 0x1900;
+               info->fifo_status_reg = 0x94;
+       } else if (cpu_type == TYPE_S5PC100) {
+               ap->ops = &pata_s5p_port_ops;
+               info->sfr_addr = info->ide_addr + 0x1800;
+               info->ide_addr += 0x1900;
+               info->fifo_status_reg = 0x84;
+       } else {
+               ap->ops = &pata_s5p_port_ops;
+               info->fifo_status_reg = 0x84;
+       }
+
+       info->cpu_type = cpu_type;
+
+       if (info->irq <= 0) {
+               ap->flags |= ATA_FLAG_PIO_POLLING;
+               info->irq = 0;
+               ata_port_desc(ap, "no IRQ, using PIO polling\n");
+       }
+
+       ap->ioaddr.cmd_addr =  info->ide_addr + S3C_ATA_CMD;
+       ap->ioaddr.data_addr = info->ide_addr + S3C_ATA_PIO_DTR;
+       ap->ioaddr.error_addr = info->ide_addr + S3C_ATA_PIO_FED;
+       ap->ioaddr.feature_addr = info->ide_addr + S3C_ATA_PIO_FED;
+       ap->ioaddr.nsect_addr = info->ide_addr + S3C_ATA_PIO_SCR;
+       ap->ioaddr.lbal_addr = info->ide_addr + S3C_ATA_PIO_LLR;
+       ap->ioaddr.lbam_addr = info->ide_addr + S3C_ATA_PIO_LMR;
+       ap->ioaddr.lbah_addr = info->ide_addr + S3C_ATA_PIO_LHR;
+       ap->ioaddr.device_addr = info->ide_addr + S3C_ATA_PIO_DVR;
+       ap->ioaddr.status_addr = info->ide_addr + S3C_ATA_PIO_CSD;
+       ap->ioaddr.command_addr = info->ide_addr + S3C_ATA_PIO_CSD;
+       ap->ioaddr.altstatus_addr = info->ide_addr + S3C_ATA_PIO_DAD;
+       ap->ioaddr.ctl_addr = info->ide_addr + S3C_ATA_PIO_DAD;
+
+       ata_port_desc(ap, "mmio cmd 0x%llx ",
+                       (unsigned long long)res->start);
+
+       host->private_data = info;
+
+       if (pdata && pdata->setup_gpio)
+               pdata->setup_gpio();
+
+       /* Set endianness and enable the interface */
+       pata_s3c_hwinit(info, pdata);
+
+       platform_set_drvdata(pdev, host);
+
+       return ata_host_activate(host, info->irq,
+                       info->irq ? pata_s3c_irq : NULL,
+                       0, &pata_s3c_sht);
+
+stop_clk:
+       clk_disable(info->clk);
+       clk_put(info->clk);
+       return ret;
+}
+
+static int __exit pata_s3c_remove(struct platform_device *pdev)
+{
+       struct ata_host *host = platform_get_drvdata(pdev);
+       struct s3c_ide_info *info = host->private_data;
+
+       ata_host_detach(host);
+
+       clk_disable(info->clk);
+       clk_put(info->clk);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int pata_s3c_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct ata_host *host = platform_get_drvdata(pdev);
+
+       return ata_host_suspend(host, PMSG_SUSPEND);
+}
+
+static int pata_s3c_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct ata_host *host = platform_get_drvdata(pdev);
+       struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
+       struct s3c_ide_info *info = host->private_data;
+
+       pata_s3c_hwinit(info, pdata);
+       ata_host_resume(host);
+
+       return 0;
+}
+
+static const struct dev_pm_ops pata_s3c_pm_ops = {
+       .suspend        = pata_s3c_suspend,
+       .resume         = pata_s3c_resume,
+};
+#endif
+
+/* driver device registration */
+static struct platform_device_id pata_s3c_driver_ids[] = {
+       {
+               .name           = "s3c64xx-pata",
+               .driver_data    = TYPE_S3C64XX,
+       }, {
+               .name           = "s5pc100-pata",
+               .driver_data    = TYPE_S5PC100,
+       }, {
+               .name           = "s5pv210-pata",
+               .driver_data    = TYPE_S5PV210,
+       },
+       { }
+};
+
+MODULE_DEVICE_TABLE(platform, pata_s3c_driver_ids);
+
+static struct platform_driver pata_s3c_driver = {
+       .remove         = __exit_p(pata_s3c_remove),
+       .id_table       = pata_s3c_driver_ids,
+       .driver         = {
+               .name   = DRV_NAME,
+               .owner  = THIS_MODULE,
+#ifdef CONFIG_PM
+               .pm     = &pata_s3c_pm_ops,
+#endif
+       },
+};
+
+static int __init pata_s3c_init(void)
+{
+       return platform_driver_probe(&pata_s3c_driver, pata_s3c_probe);
+}
+
+static void __exit pata_s3c_exit(void)
+{
+       platform_driver_unregister(&pata_s3c_driver);
+}
+
+module_init(pata_s3c_init);
+module_exit(pata_s3c_exit);
+
+MODULE_AUTHOR("Abhilash Kesavan, <a.kesavan@samsung.com>");
+MODULE_DESCRIPTION("low-level driver for Samsung PATA controller");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
index d9db3f8d60efa53de94332293a466ab0cc159678..fe36966f7e347dedd4781cef96fcec5ff79e62f3 100644 (file)
@@ -168,8 +168,7 @@ static const unsigned long JCACTSELtbl[2][7] = {
 };
 
 static const struct pci_device_id scc_pci_tbl[] = {
-       {PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA,
-        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0},
        { }     /* terminate list */
 };
 
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
new file mode 100644 (file)
index 0000000..ea24c1e
--- /dev/null
@@ -0,0 +1,1756 @@
+/*
+ * drivers/ata/sata_dwc_460ex.c
+ *
+ * Synopsys DesignWare Cores (DWC) SATA host driver
+ *
+ * Author: Mark Miesfeld <mmiesfeld@amcc.com>
+ *
+ * Ported from 2.6.19.2 to 2.6.25/26 by Stefan Roese <sr@denx.de>
+ * Copyright 2008 DENX Software Engineering
+ *
+ * Based on versions provided by AMCC and Synopsys which are:
+ *          Copyright 2006 Applied Micro Circuits Corporation
+ *          COPYRIGHT (C) 2005  SYNOPSYS, INC.  ALL RIGHTS RESERVED
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifdef CONFIG_SATA_DWC_DEBUG
+#define DEBUG
+#endif
+
+#ifdef CONFIG_SATA_DWC_VDEBUG
+#define VERBOSE_DEBUG
+#define DEBUG_NCQ
+#endif
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include <linux/slab.h>
+#include "libata.h"
+
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+
+#define DRV_NAME        "sata-dwc"
+#define DRV_VERSION     "1.0"
+
+/* SATA DMA driver Globals */
+#define DMA_NUM_CHANS          1
+#define DMA_NUM_CHAN_REGS      8
+
+/* SATA DMA Register definitions */
+#define AHB_DMA_BRST_DFLT      64      /* 16 data items burst length*/
+
+struct dmareg {
+       u32 low;                /* Low bits 0-31 */
+       u32 high;               /* High bits 32-63 */
+};
+
+/* DMA Per Channel registers */
+struct dma_chan_regs {
+       struct dmareg sar;      /* Source Address */
+       struct dmareg dar;      /* Destination address */
+       struct dmareg llp;      /* Linked List Pointer */
+       struct dmareg ctl;      /* Control */
+       struct dmareg sstat;    /* Source Status not implemented in core */
+       struct dmareg dstat;    /* Destination Status not implemented in core*/
+       struct dmareg sstatar;  /* Source Status Address not impl in core */
+       struct dmareg dstatar;  /* Destination Status Address not implemente */
+       struct dmareg cfg;      /* Config */
+       struct dmareg sgr;      /* Source Gather */
+       struct dmareg dsr;      /* Destination Scatter */
+};
+
+/* Generic Interrupt Registers */
+struct dma_interrupt_regs {
+       struct dmareg tfr;      /* Transfer Interrupt */
+       struct dmareg block;    /* Block Interrupt */
+       struct dmareg srctran;  /* Source Transfer Interrupt */
+       struct dmareg dsttran;  /* Dest Transfer Interrupt */
+       struct dmareg error;    /* Error */
+};
+
+struct ahb_dma_regs {
+       struct dma_chan_regs    chan_regs[DMA_NUM_CHAN_REGS];
+       struct dma_interrupt_regs interrupt_raw;        /* Raw Interrupt */
+       struct dma_interrupt_regs interrupt_status;     /* Interrupt Status */
+       struct dma_interrupt_regs interrupt_mask;       /* Interrupt Mask */
+       struct dma_interrupt_regs interrupt_clear;      /* Interrupt Clear */
+       struct dmareg           statusInt;      /* Interrupt combined*/
+       struct dmareg           rq_srcreg;      /* Src Trans Req */
+       struct dmareg           rq_dstreg;      /* Dst Trans Req */
+       struct dmareg           rq_sgl_srcreg;  /* Sngl Src Trans Req*/
+       struct dmareg           rq_sgl_dstreg;  /* Sngl Dst Trans Req*/
+       struct dmareg           rq_lst_srcreg;  /* Last Src Trans Req*/
+       struct dmareg           rq_lst_dstreg;  /* Last Dst Trans Req*/
+       struct dmareg           dma_cfg;                /* DMA Config */
+       struct dmareg           dma_chan_en;            /* DMA Channel Enable*/
+       struct dmareg           dma_id;                 /* DMA ID */
+       struct dmareg           dma_test;               /* DMA Test */
+       struct dmareg           res1;                   /* reserved */
+       struct dmareg           res2;                   /* reserved */
+       /*
+        * DMA Comp Params
+        * Param 6 = dma_param[0], Param 5 = dma_param[1],
+        * Param 4 = dma_param[2] ...
+        */
+       struct dmareg           dma_params[6];
+};
+
+/* Data structure for linked list item */
+struct lli {
+       u32             sar;            /* Source Address */
+       u32             dar;            /* Destination address */
+       u32             llp;            /* Linked List Pointer */
+       struct dmareg   ctl;            /* Control */
+       struct dmareg   dstat;          /* Destination Status */
+};
+
+enum {
+       SATA_DWC_DMAC_LLI_SZ =  (sizeof(struct lli)),
+       SATA_DWC_DMAC_LLI_NUM = 256,
+       SATA_DWC_DMAC_LLI_TBL_SZ = (SATA_DWC_DMAC_LLI_SZ * \
+                                       SATA_DWC_DMAC_LLI_NUM),
+       SATA_DWC_DMAC_TWIDTH_BYTES = 4,
+       SATA_DWC_DMAC_CTRL_TSIZE_MAX = (0x00000800 * \
+                                               SATA_DWC_DMAC_TWIDTH_BYTES),
+};
+
+/* DMA Register Operation Bits */
+enum {
+       DMA_EN  =               0x00000001, /* Enable AHB DMA */
+       DMA_CTL_LLP_SRCEN =     0x10000000, /* Blk chain enable Src */
+       DMA_CTL_LLP_DSTEN =     0x08000000, /* Blk chain enable Dst */
+};
+
+#define        DMA_CTL_BLK_TS(size)    ((size) & 0x000000FFF)  /* Blk Transfer size */
+#define DMA_CHANNEL(ch)                (0x00000001 << (ch))    /* Select channel */
+       /* Enable channel */
+#define        DMA_ENABLE_CHAN(ch)     ((0x00000001 << (ch)) |                 \
+                                ((0x000000001 << (ch)) << 8))
+       /* Disable channel */
+#define        DMA_DISABLE_CHAN(ch)    (0x00000000 | ((0x000000001 << (ch)) << 8))
+       /* Transfer Type & Flow Controller */
+#define        DMA_CTL_TTFC(type)      (((type) & 0x7) << 20)
+#define        DMA_CTL_SMS(num)        (((num) & 0x3) << 25) /* Src Master Select */
+#define        DMA_CTL_DMS(num)        (((num) & 0x3) << 23)/* Dst Master Select */
+       /* Src Burst Transaction Length */
+#define DMA_CTL_SRC_MSIZE(size) (((size) & 0x7) << 14)
+       /* Dst Burst Transaction Length */
+#define        DMA_CTL_DST_MSIZE(size) (((size) & 0x7) << 11)
+       /* Source Transfer Width */
+#define        DMA_CTL_SRC_TRWID(size) (((size) & 0x7) << 4)
+       /* Destination Transfer Width */
+#define        DMA_CTL_DST_TRWID(size) (((size) & 0x7) << 1)
+
+/* Assign HW handshaking interface (x) to destination / source peripheral */
+#define        DMA_CFG_HW_HS_DEST(int_num) (((int_num) & 0xF) << 11)
+#define        DMA_CFG_HW_HS_SRC(int_num) (((int_num) & 0xF) << 7)
+#define        DMA_LLP_LMS(addr, master) (((addr) & 0xfffffffc) | (master))
+
+/*
+ * This define is used to set block chaining disabled in the control low
+ * register.  It is already in little endian format so it can be &'d dirctly.
+ * It is essentially: cpu_to_le32(~(DMA_CTL_LLP_SRCEN | DMA_CTL_LLP_DSTEN))
+ */
+enum {
+       DMA_CTL_LLP_DISABLE_LE32 = 0xffffffe7,
+       DMA_CTL_TTFC_P2M_DMAC = 0x00000002, /* Per to mem, DMAC cntr */
+       DMA_CTL_TTFC_M2P_PER =  0x00000003, /* Mem to per, peripheral cntr */
+       DMA_CTL_SINC_INC =      0x00000000, /* Source Address Increment */
+       DMA_CTL_SINC_DEC =      0x00000200,
+       DMA_CTL_SINC_NOCHANGE = 0x00000400,
+       DMA_CTL_DINC_INC =      0x00000000, /* Destination Address Increment */
+       DMA_CTL_DINC_DEC =      0x00000080,
+       DMA_CTL_DINC_NOCHANGE = 0x00000100,
+       DMA_CTL_INT_EN =        0x00000001, /* Interrupt Enable */
+
+/* Channel Configuration Register high bits */
+       DMA_CFG_FCMOD_REQ =     0x00000001, /* Flow Control - request based */
+       DMA_CFG_PROTCTL =       (0x00000003 << 2),/* Protection Control */
+
+/* Channel Configuration Register low bits */
+       DMA_CFG_RELD_DST =      0x80000000, /* Reload Dest / Src Addr */
+       DMA_CFG_RELD_SRC =      0x40000000,
+       DMA_CFG_HS_SELSRC =     0x00000800, /* Software handshake Src/ Dest */
+       DMA_CFG_HS_SELDST =     0x00000400,
+       DMA_CFG_FIFOEMPTY =     (0x00000001 << 9), /* FIFO Empty bit */
+
+/* Channel Linked List Pointer Register */
+       DMA_LLP_AHBMASTER1 =    0,      /* List Master Select */
+       DMA_LLP_AHBMASTER2 =    1,
+
+       SATA_DWC_MAX_PORTS = 1,
+
+       SATA_DWC_SCR_OFFSET = 0x24,
+       SATA_DWC_REG_OFFSET = 0x64,
+};
+
+/* DWC SATA Registers */
+struct sata_dwc_regs {
+       u32 fptagr;             /* 1st party DMA tag */
+       u32 fpbor;              /* 1st party DMA buffer offset */
+       u32 fptcr;              /* 1st party DMA Xfr count */
+       u32 dmacr;              /* DMA Control */
+       u32 dbtsr;              /* DMA Burst Transac size */
+       u32 intpr;              /* Interrupt Pending */
+       u32 intmr;              /* Interrupt Mask */
+       u32 errmr;              /* Error Mask */
+       u32 llcr;               /* Link Layer Control */
+       u32 phycr;              /* PHY Control */
+       u32 physr;              /* PHY Status */
+       u32 rxbistpd;           /* Recvd BIST pattern def register */
+       u32 rxbistpd1;          /* Recvd BIST data dword1 */
+       u32 rxbistpd2;          /* Recvd BIST pattern data dword2 */
+       u32 txbistpd;           /* Trans BIST pattern def register */
+       u32 txbistpd1;          /* Trans BIST data dword1 */
+       u32 txbistpd2;          /* Trans BIST data dword2 */
+       u32 bistcr;             /* BIST Control Register */
+       u32 bistfctr;           /* BIST FIS Count Register */
+       u32 bistsr;             /* BIST Status Register */
+       u32 bistdecr;           /* BIST Dword Error count register */
+       u32 res[15];            /* Reserved locations */
+       u32 testr;              /* Test Register */
+       u32 versionr;           /* Version Register */
+       u32 idr;                /* ID Register */
+       u32 unimpl[192];        /* Unimplemented */
+       u32 dmadr[256]; /* FIFO Locations in DMA Mode */
+};
+
+enum {
+       SCR_SCONTROL_DET_ENABLE =       0x00000001,
+       SCR_SSTATUS_DET_PRESENT =       0x00000001,
+       SCR_SERROR_DIAG_X       =       0x04000000,
+/* DWC SATA Register Operations */
+       SATA_DWC_TXFIFO_DEPTH   =       0x01FF,
+       SATA_DWC_RXFIFO_DEPTH   =       0x01FF,
+       SATA_DWC_DMACR_TMOD_TXCHEN =    0x00000004,
+       SATA_DWC_DMACR_TXCHEN   = (0x00000001 | SATA_DWC_DMACR_TMOD_TXCHEN),
+       SATA_DWC_DMACR_RXCHEN   = (0x00000002 | SATA_DWC_DMACR_TMOD_TXCHEN),
+       SATA_DWC_DMACR_TXRXCH_CLEAR =   SATA_DWC_DMACR_TMOD_TXCHEN,
+       SATA_DWC_INTPR_DMAT     =       0x00000001,
+       SATA_DWC_INTPR_NEWFP    =       0x00000002,
+       SATA_DWC_INTPR_PMABRT   =       0x00000004,
+       SATA_DWC_INTPR_ERR      =       0x00000008,
+       SATA_DWC_INTPR_NEWBIST  =       0x00000010,
+       SATA_DWC_INTPR_IPF      =       0x10000000,
+       SATA_DWC_INTMR_DMATM    =       0x00000001,
+       SATA_DWC_INTMR_NEWFPM   =       0x00000002,
+       SATA_DWC_INTMR_PMABRTM  =       0x00000004,
+       SATA_DWC_INTMR_ERRM     =       0x00000008,
+       SATA_DWC_INTMR_NEWBISTM =       0x00000010,
+       SATA_DWC_LLCR_SCRAMEN   =       0x00000001,
+       SATA_DWC_LLCR_DESCRAMEN =       0x00000002,
+       SATA_DWC_LLCR_RPDEN     =       0x00000004,
+/* This is all error bits, zero's are reserved fields. */
+       SATA_DWC_SERROR_ERR_BITS =      0x0FFF0F03
+};
+
+#define SATA_DWC_SCR0_SPD_GET(v)       (((v) >> 4) & 0x0000000F)
+#define SATA_DWC_DMACR_TX_CLEAR(v)     (((v) & ~SATA_DWC_DMACR_TXCHEN) |\
+                                                SATA_DWC_DMACR_TMOD_TXCHEN)
+#define SATA_DWC_DMACR_RX_CLEAR(v)     (((v) & ~SATA_DWC_DMACR_RXCHEN) |\
+                                                SATA_DWC_DMACR_TMOD_TXCHEN)
+#define SATA_DWC_DBTSR_MWR(size)       (((size)/4) & SATA_DWC_TXFIFO_DEPTH)
+#define SATA_DWC_DBTSR_MRD(size)       ((((size)/4) & SATA_DWC_RXFIFO_DEPTH)\
+                                                << 16)
+struct sata_dwc_device {
+       struct device           *dev;           /* generic device struct */
+       struct ata_probe_ent    *pe;            /* ptr to probe-ent */
+       struct ata_host         *host;
+       u8                      *reg_base;
+       struct sata_dwc_regs    *sata_dwc_regs; /* DW Synopsys SATA specific */
+       int                     irq_dma;
+};
+
+#define SATA_DWC_QCMD_MAX      32
+
+struct sata_dwc_device_port {
+       struct sata_dwc_device  *hsdev;
+       int                     cmd_issued[SATA_DWC_QCMD_MAX];
+       struct lli              *llit[SATA_DWC_QCMD_MAX];  /* DMA LLI table */
+       dma_addr_t              llit_dma[SATA_DWC_QCMD_MAX];
+       u32                     dma_chan[SATA_DWC_QCMD_MAX];
+       int                     dma_pending[SATA_DWC_QCMD_MAX];
+};
+
+/*
+ * Commonly used DWC SATA driver Macros
+ */
+#define HSDEV_FROM_HOST(host)  ((struct sata_dwc_device *)\
+                                       (host)->private_data)
+#define HSDEV_FROM_AP(ap)  ((struct sata_dwc_device *)\
+                                       (ap)->host->private_data)
+#define HSDEVP_FROM_AP(ap)   ((struct sata_dwc_device_port *)\
+                                       (ap)->private_data)
+#define HSDEV_FROM_QC(qc)      ((struct sata_dwc_device *)\
+                                       (qc)->ap->host->private_data)
+#define HSDEV_FROM_HSDEVP(p)   ((struct sata_dwc_device *)\
+                                               (hsdevp)->hsdev)
+
+enum {
+       SATA_DWC_CMD_ISSUED_NOT         = 0,
+       SATA_DWC_CMD_ISSUED_PEND        = 1,
+       SATA_DWC_CMD_ISSUED_EXEC        = 2,
+       SATA_DWC_CMD_ISSUED_NODATA      = 3,
+
+       SATA_DWC_DMA_PENDING_NONE       = 0,
+       SATA_DWC_DMA_PENDING_TX         = 1,
+       SATA_DWC_DMA_PENDING_RX         = 2,
+};
+
+struct sata_dwc_host_priv {
+       void    __iomem  *scr_addr_sstatus;
+       u32     sata_dwc_sactive_issued ;
+       u32     sata_dwc_sactive_queued ;
+       u32     dma_interrupt_count;
+       struct  ahb_dma_regs    *sata_dma_regs;
+       struct  device  *dwc_dev;
+};
+struct sata_dwc_host_priv host_pvt;
+/*
+ * Prototypes
+ */
+static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag);
+static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc,
+                               u32 check_status);
+static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status);
+static void sata_dwc_port_stop(struct ata_port *ap);
+static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag);
+static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq);
+static void dma_dwc_exit(struct sata_dwc_device *hsdev);
+static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems,
+                             struct lli *lli, dma_addr_t dma_lli,
+                             void __iomem *addr, int dir);
+static void dma_dwc_xfer_start(int dma_ch);
+
+static void sata_dwc_tf_dump(struct ata_taskfile *tf)
+{
+       dev_vdbg(host_pvt.dwc_dev, "taskfile cmd: 0x%02x protocol: %s flags:"
+               "0x%lx device: %x\n", tf->command, ata_get_cmd_descript\
+               (tf->protocol), tf->flags, tf->device);
+       dev_vdbg(host_pvt.dwc_dev, "feature: 0x%02x nsect: 0x%x lbal: 0x%x "
+               "lbam: 0x%x lbah: 0x%x\n", tf->feature, tf->nsect, tf->lbal,
+                tf->lbam, tf->lbah);
+       dev_vdbg(host_pvt.dwc_dev, "hob_feature: 0x%02x hob_nsect: 0x%x "
+               "hob_lbal: 0x%x hob_lbam: 0x%x hob_lbah: 0x%x\n",
+               tf->hob_feature, tf->hob_nsect, tf->hob_lbal, tf->hob_lbam,
+               tf->hob_lbah);
+}
+
+/*
+ * Function: get_burst_length_encode
+ * arguments: datalength: length in bytes of data
+ * returns value to be programmed in register corrresponding to data length
+ * This value is effectively the log(base 2) of the length
+ */
+static  int get_burst_length_encode(int datalength)
+{
+       int items = datalength >> 2;    /* div by 4 to get lword count */
+
+       if (items >= 64)
+               return 5;
+
+       if (items >= 32)
+               return 4;
+
+       if (items >= 16)
+               return 3;
+
+       if (items >= 8)
+               return 2;
+
+       if (items >= 4)
+               return 1;
+
+       return 0;
+}
+
+static  void clear_chan_interrupts(int c)
+{
+       out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.tfr.low),
+                DMA_CHANNEL(c));
+       out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.block.low),
+                DMA_CHANNEL(c));
+       out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.srctran.low),
+                DMA_CHANNEL(c));
+       out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.dsttran.low),
+                DMA_CHANNEL(c));
+       out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.error.low),
+                DMA_CHANNEL(c));
+}
+
+/*
+ * Function: dma_request_channel
+ * arguments: None
+ * returns channel number if available else -1
+ * This function assigns the next available DMA channel from the list to the
+ * requester
+ */
+static int dma_request_channel(void)
+{
+       int i;
+
+       for (i = 0; i < DMA_NUM_CHANS; i++) {
+               if (!(in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) &\
+                       DMA_CHANNEL(i)))
+                       return i;
+       }
+       dev_err(host_pvt.dwc_dev, "%s NO channel chan_en: 0x%08x\n", __func__,
+               in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)));
+       return -1;
+}
+
+/*
+ * Function: dma_dwc_interrupt
+ * arguments: irq, dev_id, pt_regs
+ * returns channel number if available else -1
+ * Interrupt Handler for DW AHB SATA DMA
+ */
+static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance)
+{
+       int chan;
+       u32 tfr_reg, err_reg;
+       unsigned long flags;
+       struct sata_dwc_device *hsdev =
+               (struct sata_dwc_device *)hsdev_instance;
+       struct ata_host *host = (struct ata_host *)hsdev->host;
+       struct ata_port *ap;
+       struct sata_dwc_device_port *hsdevp;
+       u8 tag = 0;
+       unsigned int port = 0;
+
+       spin_lock_irqsave(&host->lock, flags);
+       ap = host->ports[port];
+       hsdevp = HSDEVP_FROM_AP(ap);
+       tag = ap->link.active_tag;
+
+       tfr_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.tfr\
+                       .low));
+       err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error\
+                       .low));
+
+       dev_dbg(ap->dev, "eot=0x%08x err=0x%08x pending=%d active port=%d\n",
+               tfr_reg, err_reg, hsdevp->dma_pending[tag], port);
+
+       for (chan = 0; chan < DMA_NUM_CHANS; chan++) {
+               /* Check for end-of-transfer interrupt. */
+               if (tfr_reg & DMA_CHANNEL(chan)) {
+                       /*
+                        * Each DMA command produces 2 interrupts.  Only
+                        * complete the command after both interrupts have been
+                        * seen. (See sata_dwc_isr())
+                        */
+                       host_pvt.dma_interrupt_count++;
+                       sata_dwc_clear_dmacr(hsdevp, tag);
+
+                       if (hsdevp->dma_pending[tag] ==
+                           SATA_DWC_DMA_PENDING_NONE) {
+                               dev_err(ap->dev, "DMA not pending eot=0x%08x "
+                                       "err=0x%08x tag=0x%02x pending=%d\n",
+                                       tfr_reg, err_reg, tag,
+                                       hsdevp->dma_pending[tag]);
+                       }
+
+                       if ((host_pvt.dma_interrupt_count % 2) == 0)
+                               sata_dwc_dma_xfer_complete(ap, 1);
+
+                       /* Clear the interrupt */
+                       out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
+                               .tfr.low),
+                                DMA_CHANNEL(chan));
+               }
+
+               /* Check for error interrupt. */
+               if (err_reg & DMA_CHANNEL(chan)) {
+                       /* TODO Need error handler ! */
+                       dev_err(ap->dev, "error interrupt err_reg=0x%08x\n",
+                               err_reg);
+
+                       /* Clear the interrupt. */
+                       out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
+                               .error.low),
+                                DMA_CHANNEL(chan));
+               }
+       }
+       spin_unlock_irqrestore(&host->lock, flags);
+       return IRQ_HANDLED;
+}
+
+/*
+ * Function: dma_request_interrupts
+ * arguments: hsdev
+ * returns status
+ * This function registers ISR for a particular DMA channel interrupt
+ */
+static int dma_request_interrupts(struct sata_dwc_device *hsdev, int irq)
+{
+       int retval = 0;
+       int chan;
+
+       for (chan = 0; chan < DMA_NUM_CHANS; chan++) {
+               /* Unmask error interrupt */
+               out_le32(&(host_pvt.sata_dma_regs)->interrupt_mask.error.low,
+                        DMA_ENABLE_CHAN(chan));
+
+               /* Unmask end-of-transfer interrupt */
+               out_le32(&(host_pvt.sata_dma_regs)->interrupt_mask.tfr.low,
+                        DMA_ENABLE_CHAN(chan));
+       }
+
+       retval = request_irq(irq, dma_dwc_interrupt, 0, "SATA DMA", hsdev);
+       if (retval) {
+               dev_err(host_pvt.dwc_dev, "%s: could not get IRQ %d\n",
+               __func__, irq);
+               return -ENODEV;
+       }
+
+       /* Mark this interrupt as requested */
+       hsdev->irq_dma = irq;
+       return 0;
+}
+
+/*
+ * Function: map_sg_to_lli
+ * The Synopsis driver has a comment proposing that better performance
+ * is possible by only enabling interrupts on the last item in the linked list.
+ * However, it seems that could be a problem if an error happened on one of the
+ * first items.  The transfer would halt, but no error interrupt would occur.
+ * Currently this function sets interrupts enabled for each linked list item:
+ * DMA_CTL_INT_EN.
+ */
+static int map_sg_to_lli(struct scatterlist *sg, int num_elems,
+                       struct lli *lli, dma_addr_t dma_lli,
+                       void __iomem *dmadr_addr, int dir)
+{
+       int i, idx = 0;
+       int fis_len = 0;
+       dma_addr_t next_llp;
+       int bl;
+
+       dev_dbg(host_pvt.dwc_dev, "%s: sg=%p nelem=%d lli=%p dma_lli=0x%08x"
+               " dmadr=0x%08x\n", __func__, sg, num_elems, lli, (u32)dma_lli,
+               (u32)dmadr_addr);
+
+       bl = get_burst_length_encode(AHB_DMA_BRST_DFLT);
+
+       for (i = 0; i < num_elems; i++, sg++) {
+               u32 addr, offset;
+               u32 sg_len, len;
+
+               addr = (u32) sg_dma_address(sg);
+               sg_len = sg_dma_len(sg);
+
+               dev_dbg(host_pvt.dwc_dev, "%s: elem=%d sg_addr=0x%x sg_len"
+                       "=%d\n", __func__, i, addr, sg_len);
+
+               while (sg_len) {
+                       if (idx >= SATA_DWC_DMAC_LLI_NUM) {
+                               /* The LLI table is not large enough. */
+                               dev_err(host_pvt.dwc_dev, "LLI table overrun "
+                               "(idx=%d)\n", idx);
+                               break;
+                       }
+                       len = (sg_len > SATA_DWC_DMAC_CTRL_TSIZE_MAX) ?
+                               SATA_DWC_DMAC_CTRL_TSIZE_MAX : sg_len;
+
+                       offset = addr & 0xffff;
+                       if ((offset + sg_len) > 0x10000)
+                               len = 0x10000 - offset;
+
+                       /*
+                        * Make sure a LLI block is not created that will span
+                        * 8K max FIS boundary.  If the block spans such a FIS
+                        * boundary, there is a chance that a DMA burst will
+                        * cross that boundary -- this results in an error in
+                        * the host controller.
+                        */
+                       if (fis_len + len > 8192) {
+                               dev_dbg(host_pvt.dwc_dev, "SPLITTING: fis_len="
+                                       "%d(0x%x) len=%d(0x%x)\n", fis_len,
+                                        fis_len, len, len);
+                               len = 8192 - fis_len;
+                               fis_len = 0;
+                       } else {
+                               fis_len += len;
+                       }
+                       if (fis_len == 8192)
+                               fis_len = 0;
+
+                       /*
+                        * Set DMA addresses and lower half of control register
+                        * based on direction.
+                        */
+                       if (dir == DMA_FROM_DEVICE) {
+                               lli[idx].dar = cpu_to_le32(addr);
+                               lli[idx].sar = cpu_to_le32((u32)dmadr_addr);
+
+                               lli[idx].ctl.low = cpu_to_le32(
+                                       DMA_CTL_TTFC(DMA_CTL_TTFC_P2M_DMAC) |
+                                       DMA_CTL_SMS(0) |
+                                       DMA_CTL_DMS(1) |
+                                       DMA_CTL_SRC_MSIZE(bl) |
+                                       DMA_CTL_DST_MSIZE(bl) |
+                                       DMA_CTL_SINC_NOCHANGE |
+                                       DMA_CTL_SRC_TRWID(2) |
+                                       DMA_CTL_DST_TRWID(2) |
+                                       DMA_CTL_INT_EN |
+                                       DMA_CTL_LLP_SRCEN |
+                                       DMA_CTL_LLP_DSTEN);
+                       } else {        /* DMA_TO_DEVICE */
+                               lli[idx].sar = cpu_to_le32(addr);
+                               lli[idx].dar = cpu_to_le32((u32)dmadr_addr);
+
+                               lli[idx].ctl.low = cpu_to_le32(
+                                       DMA_CTL_TTFC(DMA_CTL_TTFC_M2P_PER) |
+                                       DMA_CTL_SMS(1) |
+                                       DMA_CTL_DMS(0) |
+                                       DMA_CTL_SRC_MSIZE(bl) |
+                                       DMA_CTL_DST_MSIZE(bl) |
+                                       DMA_CTL_DINC_NOCHANGE |
+                                       DMA_CTL_SRC_TRWID(2) |
+                                       DMA_CTL_DST_TRWID(2) |
+                                       DMA_CTL_INT_EN |
+                                       DMA_CTL_LLP_SRCEN |
+                                       DMA_CTL_LLP_DSTEN);
+                       }
+
+                       dev_dbg(host_pvt.dwc_dev, "%s setting ctl.high len: "
+                               "0x%08x val: 0x%08x\n", __func__,
+                               len, DMA_CTL_BLK_TS(len / 4));
+
+                       /* Program the LLI CTL high register */
+                       lli[idx].ctl.high = cpu_to_le32(DMA_CTL_BLK_TS\
+                                               (len / 4));
+
+                       /* Program the next pointer.  The next pointer must be
+                        * the physical address, not the virtual address.
+                        */
+                       next_llp = (dma_lli + ((idx + 1) * sizeof(struct \
+                                                       lli)));
+
+                       /* The last 2 bits encode the list master select. */
+                       next_llp = DMA_LLP_LMS(next_llp, DMA_LLP_AHBMASTER2);
+
+                       lli[idx].llp = cpu_to_le32(next_llp);
+                       idx++;
+                       sg_len -= len;
+                       addr += len;
+               }
+       }
+
+       /*
+        * The last next ptr has to be zero and the last control low register
+        * has to have LLP_SRC_EN and LLP_DST_EN (linked list pointer source
+        * and destination enable) set back to 0 (disabled.) This is what tells
+        * the core that this is the last item in the linked list.
+        */
+       if (idx) {
+               lli[idx-1].llp = 0x00000000;
+               lli[idx-1].ctl.low &= DMA_CTL_LLP_DISABLE_LE32;
+
+               /* Flush cache to memory */
+               dma_cache_sync(NULL, lli, (sizeof(struct lli) * idx),
+                              DMA_BIDIRECTIONAL);
+       }
+
+       return idx;
+}
+
+/*
+ * Function: dma_dwc_xfer_start
+ * arguments: Channel number
+ * Return : None
+ * Enables the DMA channel
+ */
+static void dma_dwc_xfer_start(int dma_ch)
+{
+       /* Enable the DMA channel */
+       out_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low),
+                in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) |
+                DMA_ENABLE_CHAN(dma_ch));
+}
+
+static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems,
+                             struct lli *lli, dma_addr_t dma_lli,
+                             void __iomem *addr, int dir)
+{
+       int dma_ch;
+       int num_lli;
+       /* Acquire DMA channel */
+       dma_ch = dma_request_channel();
+       if (dma_ch == -1) {
+               dev_err(host_pvt.dwc_dev, "%s: dma channel unavailable\n",
+                        __func__);
+               return -EAGAIN;
+       }
+
+       /* Convert SG list to linked list of items (LLIs) for AHB DMA */
+       num_lli = map_sg_to_lli(sg, num_elems, lli, dma_lli, addr, dir);
+
+       dev_dbg(host_pvt.dwc_dev, "%s sg: 0x%p, count: %d lli: %p dma_lli:"
+               " 0x%0xlx addr: %p lli count: %d\n", __func__, sg, num_elems,
+                lli, (u32)dma_lli, addr, num_lli);
+
+       clear_chan_interrupts(dma_ch);
+
+       /* Program the CFG register. */
+       out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.high),
+                DMA_CFG_PROTCTL | DMA_CFG_FCMOD_REQ);
+       out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.low), 0);
+
+       /* Program the address of the linked list */
+       out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].llp.low),
+                DMA_LLP_LMS(dma_lli, DMA_LLP_AHBMASTER2));
+
+       /* Program the CTL register with src enable / dst enable */
+       out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].ctl.low),
+                DMA_CTL_LLP_SRCEN | DMA_CTL_LLP_DSTEN);
+       return 0;
+}
+
+/*
+ * Function: dma_dwc_exit
+ * arguments: None
+ * returns status
+ * This function exits the SATA DMA driver
+ */
+static void dma_dwc_exit(struct sata_dwc_device *hsdev)
+{
+       dev_dbg(host_pvt.dwc_dev, "%s:\n", __func__);
+       if (host_pvt.sata_dma_regs)
+               iounmap(host_pvt.sata_dma_regs);
+
+       if (hsdev->irq_dma)
+               free_irq(hsdev->irq_dma, hsdev);
+}
+
+/*
+ * Function: dma_dwc_init
+ * arguments: hsdev
+ * returns status
+ * This function initializes the SATA DMA driver
+ */
+static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq)
+{
+       int err;
+
+       err = dma_request_interrupts(hsdev, irq);
+       if (err) {
+               dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns"
+                       " %d\n", __func__, err);
+               goto error_out;
+       }
+
+       /* Enabe DMA */
+       out_le32(&(host_pvt.sata_dma_regs->dma_cfg.low), DMA_EN);
+
+       dev_notice(host_pvt.dwc_dev, "DMA initialized\n");
+       dev_dbg(host_pvt.dwc_dev, "SATA DMA registers=0x%p\n", host_pvt.\
+               sata_dma_regs);
+
+       return 0;
+
+error_out:
+       dma_dwc_exit(hsdev);
+
+       return err;
+}
+
+static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val)
+{
+       if (scr > SCR_NOTIFICATION) {
+               dev_err(link->ap->dev, "%s: Incorrect SCR offset 0x%02x\n",
+                       __func__, scr);
+               return -EINVAL;
+       }
+
+       *val = in_le32((void *)link->ap->ioaddr.scr_addr + (scr * 4));
+       dev_dbg(link->ap->dev, "%s: id=%d reg=%d val=val=0x%08x\n",
+               __func__, link->ap->print_id, scr, *val);
+
+       return 0;
+}
+
+static int sata_dwc_scr_write(struct ata_link *link, unsigned int scr, u32 val)
+{
+       dev_dbg(link->ap->dev, "%s: id=%d reg=%d val=val=0x%08x\n",
+               __func__, link->ap->print_id, scr, val);
+       if (scr > SCR_NOTIFICATION) {
+               dev_err(link->ap->dev, "%s: Incorrect SCR offset 0x%02x\n",
+                        __func__, scr);
+               return -EINVAL;
+       }
+       out_le32((void *)link->ap->ioaddr.scr_addr + (scr * 4), val);
+
+       return 0;
+}
+
+static u32 core_scr_read(unsigned int scr)
+{
+       return in_le32((void __iomem *)(host_pvt.scr_addr_sstatus) +\
+                       (scr * 4));
+}
+
+static void core_scr_write(unsigned int scr, u32 val)
+{
+       out_le32((void __iomem *)(host_pvt.scr_addr_sstatus) + (scr * 4),
+               val);
+}
+
+static void clear_serror(void)
+{
+       u32 val;
+       val = core_scr_read(SCR_ERROR);
+       core_scr_write(SCR_ERROR, val);
+
+}
+
+static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+{
+       out_le32(&hsdev->sata_dwc_regs->intpr,
+                in_le32(&hsdev->sata_dwc_regs->intpr));
+}
+
+static u32 qcmd_tag_to_mask(u8 tag)
+{
+       return 0x00000001 << (tag & 0x1f);
+}
+
+/* See ahci.c */
+static void sata_dwc_error_intr(struct ata_port *ap,
+                               struct sata_dwc_device *hsdev, uint intpr)
+{
+       struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
+       struct ata_eh_info *ehi = &ap->link.eh_info;
+       unsigned int err_mask = 0, action = 0;
+       struct ata_queued_cmd *qc;
+       u32 serror;
+       u8 status, tag;
+       u32 err_reg;
+
+       ata_ehi_clear_desc(ehi);
+
+       serror = core_scr_read(SCR_ERROR);
+       status = ap->ops->sff_check_status(ap);
+
+       err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error.\
+                       low));
+       tag = ap->link.active_tag;
+
+       dev_err(ap->dev, "%s SCR_ERROR=0x%08x intpr=0x%08x status=0x%08x "
+               "dma_intp=%d pending=%d issued=%d dma_err_status=0x%08x\n",
+               __func__, serror, intpr, status, host_pvt.dma_interrupt_count,
+               hsdevp->dma_pending[tag], hsdevp->cmd_issued[tag], err_reg);
+
+       /* Clear error register and interrupt bit */
+       clear_serror();
+       clear_interrupt_bit(hsdev, SATA_DWC_INTPR_ERR);
+
+       /* This is the only error happening now.  TODO check for exact error */
+
+       err_mask |= AC_ERR_HOST_BUS;
+       action |= ATA_EH_RESET;
+
+       /* Pass this on to EH */
+       ehi->serror |= serror;
+       ehi->action |= action;
+
+       qc = ata_qc_from_tag(ap, tag);
+       if (qc)
+               qc->err_mask |= err_mask;
+       else
+               ehi->err_mask |= err_mask;
+
+       ata_port_abort(ap);
+}
+
+/*
+ * Function : sata_dwc_isr
+ * arguments : irq, void *dev_instance, struct pt_regs *regs
+ * Return value : irqreturn_t - status of IRQ
+ * This Interrupt handler called via port ops registered function.
+ * .irq_handler = sata_dwc_isr
+ */
+static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+{
+       struct ata_host *host = (struct ata_host *)dev_instance;
+       struct sata_dwc_device *hsdev = HSDEV_FROM_HOST(host);
+       struct ata_port *ap;
+       struct ata_queued_cmd *qc;
+       unsigned long flags;
+       u8 status, tag;
+       int handled, num_processed, port = 0;
+       uint intpr, sactive, sactive2, tag_mask;
+       struct sata_dwc_device_port *hsdevp;
+       host_pvt.sata_dwc_sactive_issued = 0;
+
+       spin_lock_irqsave(&host->lock, flags);
+
+       /* Read the interrupt register */
+       intpr = in_le32(&hsdev->sata_dwc_regs->intpr);
+
+       ap = host->ports[port];
+       hsdevp = HSDEVP_FROM_AP(ap);
+
+       dev_dbg(ap->dev, "%s intpr=0x%08x active_tag=%d\n", __func__, intpr,
+               ap->link.active_tag);
+
+       /* Check for error interrupt */
+       if (intpr & SATA_DWC_INTPR_ERR) {
+               sata_dwc_error_intr(ap, hsdev, intpr);
+               handled = 1;
+               goto DONE;
+       }
+
+       /* Check for DMA SETUP FIS (FP DMA) interrupt */
+       if (intpr & SATA_DWC_INTPR_NEWFP) {
+               clear_interrupt_bit(hsdev, SATA_DWC_INTPR_NEWFP);
+
+               tag = (u8)(in_le32(&hsdev->sata_dwc_regs->fptagr));
+               dev_dbg(ap->dev, "%s: NEWFP tag=%d\n", __func__, tag);
+               if (hsdevp->cmd_issued[tag] != SATA_DWC_CMD_ISSUED_PEND)
+                       dev_warn(ap->dev, "CMD tag=%d not pending?\n", tag);
+
+               host_pvt.sata_dwc_sactive_issued |= qcmd_tag_to_mask(tag);
+
+               qc = ata_qc_from_tag(ap, tag);
+               /*
+                * Start FP DMA for NCQ command.  At this point the tag is the
+                * active tag.  It is the tag that matches the command about to
+                * be completed.
+                */
+               qc->ap->link.active_tag = tag;
+               sata_dwc_bmdma_start_by_tag(qc, tag);
+
+               handled = 1;
+               goto DONE;
+       }
+       sactive = core_scr_read(SCR_ACTIVE);
+       tag_mask = (host_pvt.sata_dwc_sactive_issued | sactive) ^ sactive;
+
+       /* If no sactive issued and tag_mask is zero then this is not NCQ */
+       if (host_pvt.sata_dwc_sactive_issued == 0 && tag_mask == 0) {
+               if (ap->link.active_tag == ATA_TAG_POISON)
+                       tag = 0;
+               else
+                       tag = ap->link.active_tag;
+               qc = ata_qc_from_tag(ap, tag);
+
+               /* DEV interrupt w/ no active qc? */
+               if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
+                       dev_err(ap->dev, "%s interrupt with no active qc "
+                               "qc=%p\n", __func__, qc);
+                       ap->ops->sff_check_status(ap);
+                       handled = 1;
+                       goto DONE;
+               }
+               status = ap->ops->sff_check_status(ap);
+
+               qc->ap->link.active_tag = tag;
+               hsdevp->cmd_issued[tag] = SATA_DWC_CMD_ISSUED_NOT;
+
+               if (status & ATA_ERR) {
+                       dev_dbg(ap->dev, "interrupt ATA_ERR (0x%x)\n", status);
+                       sata_dwc_qc_complete(ap, qc, 1);
+                       handled = 1;
+                       goto DONE;
+               }
+
+               dev_dbg(ap->dev, "%s non-NCQ cmd interrupt, protocol: %s\n",
+                       __func__, ata_get_cmd_descript(qc->tf.protocol));
+DRVSTILLBUSY:
+               if (ata_is_dma(qc->tf.protocol)) {
+                       /*
+                        * Each DMA transaction produces 2 interrupts. The DMAC
+                        * transfer complete interrupt and the SATA controller
+                        * operation done interrupt. The command should be
+                        * completed only after both interrupts are seen.
+                        */
+                       host_pvt.dma_interrupt_count++;
+                       if (hsdevp->dma_pending[tag] == \
+                                       SATA_DWC_DMA_PENDING_NONE) {
+                               dev_err(ap->dev, "%s: DMA not pending "
+                                       "intpr=0x%08x status=0x%08x pending"
+                                       "=%d\n", __func__, intpr, status,
+                                       hsdevp->dma_pending[tag]);
+                       }
+
+                       if ((host_pvt.dma_interrupt_count % 2) == 0)
+                               sata_dwc_dma_xfer_complete(ap, 1);
+               } else if (ata_is_pio(qc->tf.protocol)) {
+                       ata_sff_hsm_move(ap, qc, status, 0);
+                       handled = 1;
+                       goto DONE;
+               } else {
+                       if (unlikely(sata_dwc_qc_complete(ap, qc, 1)))
+                               goto DRVSTILLBUSY;
+               }
+
+               handled = 1;
+               goto DONE;
+       }
+
+       /*
+        * This is a NCQ command. At this point we need to figure out for which
+        * tags we have gotten a completion interrupt.  One interrupt may serve
+        * as completion for more than one operation when commands are queued
+        * (NCQ).  We need to process each completed command.
+        */
+
+        /* process completed commands */
+       sactive = core_scr_read(SCR_ACTIVE);
+       tag_mask = (host_pvt.sata_dwc_sactive_issued | sactive) ^ sactive;
+
+       if (sactive != 0 || (host_pvt.sata_dwc_sactive_issued) > 1 || \
+                                                       tag_mask > 1) {
+               dev_dbg(ap->dev, "%s NCQ:sactive=0x%08x  sactive_issued=0x%08x"
+                       "tag_mask=0x%08x\n", __func__, sactive,
+                       host_pvt.sata_dwc_sactive_issued, tag_mask);
+       }
+
+       if ((tag_mask | (host_pvt.sata_dwc_sactive_issued)) != \
+                                       (host_pvt.sata_dwc_sactive_issued)) {
+               dev_warn(ap->dev, "Bad tag mask?  sactive=0x%08x "
+                        "(host_pvt.sata_dwc_sactive_issued)=0x%08x  tag_mask"
+                        "=0x%08x\n", sactive, host_pvt.sata_dwc_sactive_issued,
+                         tag_mask);
+       }
+
+       /* read just to clear ... not bad if currently still busy */
+       status = ap->ops->sff_check_status(ap);
+       dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+       tag = 0;
+       num_processed = 0;
+       while (tag_mask) {
+               num_processed++;
+               while (!(tag_mask & 0x00000001)) {
+                       tag++;
+                       tag_mask <<= 1;
+               }
+
+               tag_mask &= (~0x00000001);
+               qc = ata_qc_from_tag(ap, tag);
+
+               /* To be picked up by completion functions */
+               qc->ap->link.active_tag = tag;
+               hsdevp->cmd_issued[tag] = SATA_DWC_CMD_ISSUED_NOT;
+
+               /* Let libata/scsi layers handle error */
+               if (status & ATA_ERR) {
+                       dev_dbg(ap->dev, "%s ATA_ERR (0x%x)\n", __func__,
+                               status);
+                       sata_dwc_qc_complete(ap, qc, 1);
+                       handled = 1;
+                       goto DONE;
+               }
+
+               /* Process completed command */
+               dev_dbg(ap->dev, "%s NCQ command, protocol: %s\n", __func__,
+                       ata_get_cmd_descript(qc->tf.protocol));
+               if (ata_is_dma(qc->tf.protocol)) {
+                       host_pvt.dma_interrupt_count++;
+                       if (hsdevp->dma_pending[tag] == \
+                                       SATA_DWC_DMA_PENDING_NONE)
+                               dev_warn(ap->dev, "%s: DMA not pending?\n",
+                                       __func__);
+                       if ((host_pvt.dma_interrupt_count % 2) == 0)
+                               sata_dwc_dma_xfer_complete(ap, 1);
+               } else {
+                       if (unlikely(sata_dwc_qc_complete(ap, qc, 1)))
+                               goto STILLBUSY;
+               }
+               continue;
+
+STILLBUSY:
+               ap->stats.idle_irq++;
+               dev_warn(ap->dev, "STILL BUSY IRQ ata%d: irq trap\n",
+                       ap->print_id);
+       } /* while tag_mask */
+
+       /*
+        * Check to see if any commands completed while we were processing our
+        * initial set of completed commands (read status clears interrupts,
+        * so we might miss a completed command interrupt if one came in while
+        * we were processing --we read status as part of processing a completed
+        * command).
+        */
+       sactive2 = core_scr_read(SCR_ACTIVE);
+       if (sactive2 != sactive) {
+               dev_dbg(ap->dev, "More completed - sactive=0x%x sactive2"
+                       "=0x%x\n", sactive, sactive2);
+       }
+       handled = 1;
+
+DONE:
+       spin_unlock_irqrestore(&host->lock, flags);
+       return IRQ_RETVAL(handled);
+}
+
+static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag)
+{
+       struct sata_dwc_device *hsdev = HSDEV_FROM_HSDEVP(hsdevp);
+
+       if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_RX) {
+               out_le32(&(hsdev->sata_dwc_regs->dmacr),
+                        SATA_DWC_DMACR_RX_CLEAR(
+                                in_le32(&(hsdev->sata_dwc_regs->dmacr))));
+       } else if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_TX) {
+               out_le32(&(hsdev->sata_dwc_regs->dmacr),
+                        SATA_DWC_DMACR_TX_CLEAR(
+                                in_le32(&(hsdev->sata_dwc_regs->dmacr))));
+       } else {
+               /*
+                * This should not happen, it indicates the driver is out of
+                * sync.  If it does happen, clear dmacr anyway.
+                */
+               dev_err(host_pvt.dwc_dev, "%s DMA protocol RX and"
+                       "TX DMA not pending tag=0x%02x pending=%d"
+                       " dmacr: 0x%08x\n", __func__, tag,
+                       hsdevp->dma_pending[tag],
+                       in_le32(&(hsdev->sata_dwc_regs->dmacr)));
+               out_le32(&(hsdev->sata_dwc_regs->dmacr),
+                       SATA_DWC_DMACR_TXRXCH_CLEAR);
+       }
+}
+
+static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status)
+{
+       struct ata_queued_cmd *qc;
+       struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
+       struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap);
+       u8 tag = 0;
+
+       tag = ap->link.active_tag;
+       qc = ata_qc_from_tag(ap, tag);
+       if (!qc) {
+               dev_err(ap->dev, "failed to get qc");
+               return;
+       }
+
+#ifdef DEBUG_NCQ
+       if (tag > 0) {
+               dev_info(ap->dev, "%s tag=%u cmd=0x%02x dma dir=%s proto=%s "
+                        "dmacr=0x%08x\n", __func__, qc->tag, qc->tf.command,
+                        ata_get_cmd_descript(qc->dma_dir),
+                        ata_get_cmd_descript(qc->tf.protocol),
+                        in_le32(&(hsdev->sata_dwc_regs->dmacr)));
+       }
+#endif
+
+       if (ata_is_dma(qc->tf.protocol)) {
+               if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_NONE) {
+                       dev_err(ap->dev, "%s DMA protocol RX and TX DMA not "
+                               "pending dmacr: 0x%08x\n", __func__,
+                               in_le32(&(hsdev->sata_dwc_regs->dmacr)));
+               }
+
+               hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_NONE;
+               sata_dwc_qc_complete(ap, qc, check_status);
+               ap->link.active_tag = ATA_TAG_POISON;
+       } else {
+               sata_dwc_qc_complete(ap, qc, check_status);
+       }
+}
+
+static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc,
+                               u32 check_status)
+{
+       u8 status = 0;
+       u32 mask = 0x0;
+       u8 tag = qc->tag;
+       struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
+       host_pvt.sata_dwc_sactive_queued = 0;
+       dev_dbg(ap->dev, "%s checkstatus? %x\n", __func__, check_status);
+
+       if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_TX)
+               dev_err(ap->dev, "TX DMA PENDING\n");
+       else if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_RX)
+               dev_err(ap->dev, "RX DMA PENDING\n");
+       dev_dbg(ap->dev, "QC complete cmd=0x%02x status=0x%02x ata%u:"
+               " protocol=%d\n", qc->tf.command, status, ap->print_id,
+                qc->tf.protocol);
+
+       /* clear active bit */
+       mask = (~(qcmd_tag_to_mask(tag)));
+       host_pvt.sata_dwc_sactive_queued = (host_pvt.sata_dwc_sactive_queued) \
+                                               & mask;
+       host_pvt.sata_dwc_sactive_issued = (host_pvt.sata_dwc_sactive_issued) \
+                                               & mask;
+       ata_qc_complete(qc);
+       return 0;
+}
+
+static void sata_dwc_enable_interrupts(struct sata_dwc_device *hsdev)
+{
+       /* Enable selective interrupts by setting the interrupt maskregister*/
+       out_le32(&hsdev->sata_dwc_regs->intmr,
+                SATA_DWC_INTMR_ERRM |
+                SATA_DWC_INTMR_NEWFPM |
+                SATA_DWC_INTMR_PMABRTM |
+                SATA_DWC_INTMR_DMATM);
+       /*
+        * Unmask the error bits that should trigger an error interrupt by
+        * setting the error mask register.
+        */
+       out_le32(&hsdev->sata_dwc_regs->errmr, SATA_DWC_SERROR_ERR_BITS);
+
+       dev_dbg(host_pvt.dwc_dev, "%s: INTMR = 0x%08x, ERRMR = 0x%08x\n",
+                __func__, in_le32(&hsdev->sata_dwc_regs->intmr),
+               in_le32(&hsdev->sata_dwc_regs->errmr));
+}
+
+static void sata_dwc_setup_port(struct ata_ioports *port, unsigned long base)
+{
+       port->cmd_addr = (void *)base + 0x00;
+       port->data_addr = (void *)base + 0x00;
+
+       port->error_addr = (void *)base + 0x04;
+       port->feature_addr = (void *)base + 0x04;
+
+       port->nsect_addr = (void *)base + 0x08;
+
+       port->lbal_addr = (void *)base + 0x0c;
+       port->lbam_addr = (void *)base + 0x10;
+       port->lbah_addr = (void *)base + 0x14;
+
+       port->device_addr = (void *)base + 0x18;
+       port->command_addr = (void *)base + 0x1c;
+       port->status_addr = (void *)base + 0x1c;
+
+       port->altstatus_addr = (void *)base + 0x20;
+       port->ctl_addr = (void *)base + 0x20;
+}
+
+/*
+ * Function : sata_dwc_port_start
+ * arguments : struct ata_ioports *port
+ * Return value : returns 0 if success, error code otherwise
+ * This function allocates the scatter gather LLI table for AHB DMA
+ */
+static int sata_dwc_port_start(struct ata_port *ap)
+{
+       int err = 0;
+       struct sata_dwc_device *hsdev;
+       struct sata_dwc_device_port *hsdevp = NULL;
+       struct device *pdev;
+       int i;
+
+       hsdev = HSDEV_FROM_AP(ap);
+
+       dev_dbg(ap->dev, "%s: port_no=%d\n", __func__, ap->port_no);
+
+       hsdev->host = ap->host;
+       pdev = ap->host->dev;
+       if (!pdev) {
+               dev_err(ap->dev, "%s: no ap->host->dev\n", __func__);
+               err = -ENODEV;
+               goto CLEANUP;
+       }
+
+       /* Allocate Port Struct */
+       hsdevp = kzalloc(sizeof(*hsdevp), GFP_KERNEL);
+       if (!hsdevp) {
+               dev_err(ap->dev, "%s: kmalloc failed for hsdevp\n", __func__);
+               err = -ENOMEM;
+               goto CLEANUP;
+       }
+       hsdevp->hsdev = hsdev;
+
+       for (i = 0; i < SATA_DWC_QCMD_MAX; i++)
+               hsdevp->cmd_issued[i] = SATA_DWC_CMD_ISSUED_NOT;
+
+       ap->bmdma_prd = 0;      /* set these so libata doesn't use them */
+       ap->bmdma_prd_dma = 0;
+
+       /*
+        * DMA - Assign scatter gather LLI table. We can't use the libata
+        * version since it's PRD is IDE PCI specific.
+        */
+       for (i = 0; i < SATA_DWC_QCMD_MAX; i++) {
+               hsdevp->llit[i] = dma_alloc_coherent(pdev,
+                                                    SATA_DWC_DMAC_LLI_TBL_SZ,
+                                                    &(hsdevp->llit_dma[i]),
+                                                    GFP_ATOMIC);
+               if (!hsdevp->llit[i]) {
+                       dev_err(ap->dev, "%s: dma_alloc_coherent failed\n",
+                                __func__);
+                       err = -ENOMEM;
+                       goto CLEANUP;
+               }
+       }
+
+       if (ap->port_no == 0)  {
+               dev_dbg(ap->dev, "%s: clearing TXCHEN, RXCHEN in DMAC\n",
+                       __func__);
+               out_le32(&hsdev->sata_dwc_regs->dmacr,
+                        SATA_DWC_DMACR_TXRXCH_CLEAR);
+
+               dev_dbg(ap->dev, "%s: setting burst size in DBTSR\n",
+                        __func__);
+               out_le32(&hsdev->sata_dwc_regs->dbtsr,
+                        (SATA_DWC_DBTSR_MWR(AHB_DMA_BRST_DFLT) |
+                         SATA_DWC_DBTSR_MRD(AHB_DMA_BRST_DFLT)));
+       }
+
+       /* Clear any error bits before libata starts issuing commands */
+       clear_serror();
+       ap->private_data = hsdevp;
+
+CLEANUP:
+       if (err) {
+               sata_dwc_port_stop(ap);
+               dev_dbg(ap->dev, "%s: fail\n", __func__);
+       } else {
+               dev_dbg(ap->dev, "%s: done\n", __func__);
+       }
+
+       return err;
+}
+
+static void sata_dwc_port_stop(struct ata_port *ap)
+{
+       int i;
+       struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap);
+       struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
+
+       dev_dbg(ap->dev, "%s: ap->id = %d\n", __func__, ap->print_id);
+
+       if (hsdevp && hsdev) {
+               /* deallocate LLI table */
+               for (i = 0; i < SATA_DWC_QCMD_MAX; i++) {
+                       dma_free_coherent(ap->host->dev,
+                                         SATA_DWC_DMAC_LLI_TBL_SZ,
+                                        hsdevp->llit[i], hsdevp->llit_dma[i]);
+               }
+
+               kfree(hsdevp);
+       }
+       ap->private_data = NULL;
+}
+
+/*
+ * Function : sata_dwc_exec_command_by_tag
+ * arguments : ata_port *ap, ata_taskfile *tf, u8 tag, u32 cmd_issued
+ * Return value : None
+ * This function keeps track of individual command tag ids and calls
+ * ata_exec_command in libata
+ */
+static void sata_dwc_exec_command_by_tag(struct ata_port *ap,
+                                        struct ata_taskfile *tf,
+                                        u8 tag, u32 cmd_issued)
+{
+       unsigned long flags;
+       struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
+
+       dev_dbg(ap->dev, "%s cmd(0x%02x): %s tag=%d\n", __func__, tf->command,
+               ata_get_cmd_descript(tf), tag);
+
+       spin_lock_irqsave(&ap->host->lock, flags);
+       hsdevp->cmd_issued[tag] = cmd_issued;
+       spin_unlock_irqrestore(&ap->host->lock, flags);
+       /*
+        * Clear SError before executing a new command.
+        * sata_dwc_scr_write and read can not be used here. Clearing the PM
+        * managed SError register for the disk needs to be done before the
+        * task file is loaded.
+        */
+       clear_serror();
+       ata_sff_exec_command(ap, tf);
+}
+
+static void sata_dwc_bmdma_setup_by_tag(struct ata_queued_cmd *qc, u8 tag)
+{
+       sata_dwc_exec_command_by_tag(qc->ap, &qc->tf, tag,
+                                    SATA_DWC_CMD_ISSUED_PEND);
+}
+
+static void sata_dwc_bmdma_setup(struct ata_queued_cmd *qc)
+{
+       u8 tag = qc->tag;
+
+       if (ata_is_ncq(qc->tf.protocol)) {
+               dev_dbg(qc->ap->dev, "%s: ap->link.sactive=0x%08x tag=%d\n",
+                       __func__, qc->ap->link.sactive, tag);
+       } else {
+               tag = 0;
+       }
+       sata_dwc_bmdma_setup_by_tag(qc, tag);
+}
+
+static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag)
+{
+       int start_dma;
+       u32 reg, dma_chan;
+       struct sata_dwc_device *hsdev = HSDEV_FROM_QC(qc);
+       struct ata_port *ap = qc->ap;
+       struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
+       int dir = qc->dma_dir;
+       dma_chan = hsdevp->dma_chan[tag];
+
+       if (hsdevp->cmd_issued[tag] != SATA_DWC_CMD_ISSUED_NOT) {
+               start_dma = 1;
+               if (dir == DMA_TO_DEVICE)
+                       hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_TX;
+               else
+                       hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_RX;
+       } else {
+               dev_err(ap->dev, "%s: Command not pending cmd_issued=%d "
+                       "(tag=%d) DMA NOT started\n", __func__,
+                       hsdevp->cmd_issued[tag], tag);
+               start_dma = 0;
+       }
+
+       dev_dbg(ap->dev, "%s qc=%p tag: %x cmd: 0x%02x dma_dir: %s "
+               "start_dma? %x\n", __func__, qc, tag, qc->tf.command,
+               ata_get_cmd_descript(qc->dma_dir), start_dma);
+       sata_dwc_tf_dump(&(qc->tf));
+
+       if (start_dma) {
+               reg = core_scr_read(SCR_ERROR);
+               if (reg & SATA_DWC_SERROR_ERR_BITS) {
+                       dev_err(ap->dev, "%s: ****** SError=0x%08x ******\n",
+                               __func__, reg);
+               }
+
+               if (dir == DMA_TO_DEVICE)
+                       out_le32(&hsdev->sata_dwc_regs->dmacr,
+                               SATA_DWC_DMACR_TXCHEN);
+               else
+                       out_le32(&hsdev->sata_dwc_regs->dmacr,
+                               SATA_DWC_DMACR_RXCHEN);
+
+               /* Enable AHB DMA transfer on the specified channel */
+               dma_dwc_xfer_start(dma_chan);
+       }
+}
+
+static void sata_dwc_bmdma_start(struct ata_queued_cmd *qc)
+{
+       u8 tag = qc->tag;
+
+       if (ata_is_ncq(qc->tf.protocol)) {
+               dev_dbg(qc->ap->dev, "%s: ap->link.sactive=0x%08x tag=%d\n",
+                       __func__, qc->ap->link.sactive, tag);
+       } else {
+               tag = 0;
+       }
+       dev_dbg(qc->ap->dev, "%s\n", __func__);
+       sata_dwc_bmdma_start_by_tag(qc, tag);
+}
+
+/*
+ * Function : sata_dwc_qc_prep_by_tag
+ * arguments : ata_queued_cmd *qc, u8 tag
+ * Return value : None
+ * qc_prep for a particular queued command based on tag
+ */
+static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag)
+{
+       struct scatterlist *sg = qc->sg;
+       struct ata_port *ap = qc->ap;
+       u32 dma_chan;
+       struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap);
+       struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
+       int err;
+
+       dev_dbg(ap->dev, "%s: port=%d dma dir=%s n_elem=%d\n",
+               __func__, ap->port_no, ata_get_cmd_descript(qc->dma_dir),
+                qc->n_elem);
+
+       dma_chan = dma_dwc_xfer_setup(sg, qc->n_elem, hsdevp->llit[tag],
+                                     hsdevp->llit_dma[tag],
+                                     (void *__iomem)(&hsdev->sata_dwc_regs->\
+                                     dmadr), qc->dma_dir);
+       if (dma_chan < 0) {
+               dev_err(ap->dev, "%s: dma_dwc_xfer_setup returns err %d\n",
+                       __func__, err);
+               return;
+       }
+       hsdevp->dma_chan[tag] = dma_chan;
+}
+
+static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc)
+{
+       u32 sactive;
+       u8 tag = qc->tag;
+       struct ata_port *ap = qc->ap;
+
+#ifdef DEBUG_NCQ
+       if (qc->tag > 0 || ap->link.sactive > 1)
+               dev_info(ap->dev, "%s ap id=%d cmd(0x%02x)=%s qc tag=%d "
+                        "prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n",
+                        __func__, ap->print_id, qc->tf.command,
+                        ata_get_cmd_descript(&qc->tf),
+                        qc->tag, ata_get_cmd_descript(qc->tf.protocol),
+                        ap->link.active_tag, ap->link.sactive);
+#endif
+
+       if (!ata_is_ncq(qc->tf.protocol))
+               tag = 0;
+       sata_dwc_qc_prep_by_tag(qc, tag);
+
+       if (ata_is_ncq(qc->tf.protocol)) {
+               sactive = core_scr_read(SCR_ACTIVE);
+               sactive |= (0x00000001 << tag);
+               core_scr_write(SCR_ACTIVE, sactive);
+
+               dev_dbg(qc->ap->dev, "%s: tag=%d ap->link.sactive = 0x%08x "
+                       "sactive=0x%08x\n", __func__, tag, qc->ap->link.sactive,
+                       sactive);
+
+               ap->ops->sff_tf_load(ap, &qc->tf);
+               sata_dwc_exec_command_by_tag(ap, &qc->tf, qc->tag,
+                                            SATA_DWC_CMD_ISSUED_PEND);
+       } else {
+               ata_sff_qc_issue(qc);
+       }
+       return 0;
+}
+
+/*
+ * Function : sata_dwc_qc_prep
+ * arguments : ata_queued_cmd *qc
+ * Return value : None
+ * qc_prep for a particular queued command
+ */
+
+static void sata_dwc_qc_prep(struct ata_queued_cmd *qc)
+{
+       if ((qc->dma_dir == DMA_NONE) || (qc->tf.protocol == ATA_PROT_PIO))
+               return;
+
+#ifdef DEBUG_NCQ
+       if (qc->tag > 0)
+               dev_info(qc->ap->dev, "%s: qc->tag=%d ap->active_tag=0x%08x\n",
+                        __func__, tag, qc->ap->link.active_tag);
+
+       return ;
+#endif
+}
+
+static void sata_dwc_error_handler(struct ata_port *ap)
+{
+       ap->link.flags |= ATA_LFLAG_NO_HRST;
+       ata_sff_error_handler(ap);
+}
+
+/*
+ * scsi mid-layer and libata interface structures
+ */
+static struct scsi_host_template sata_dwc_sht = {
+       ATA_NCQ_SHT(DRV_NAME),
+       /*
+        * test-only: Currently this driver doesn't handle NCQ
+        * correctly. We enable NCQ but set the queue depth to a
+        * max of 1. This will get fixed in in a future release.
+        */
+       .sg_tablesize           = LIBATA_MAX_PRD,
+       .can_queue              = ATA_DEF_QUEUE,        /* ATA_MAX_QUEUE */
+       .dma_boundary           = ATA_DMA_BOUNDARY,
+};
+
+static struct ata_port_operations sata_dwc_ops = {
+       .inherits               = &ata_sff_port_ops,
+
+       .error_handler          = sata_dwc_error_handler,
+
+       .qc_prep                = sata_dwc_qc_prep,
+       .qc_issue               = sata_dwc_qc_issue,
+
+       .scr_read               = sata_dwc_scr_read,
+       .scr_write              = sata_dwc_scr_write,
+
+       .port_start             = sata_dwc_port_start,
+       .port_stop              = sata_dwc_port_stop,
+
+       .bmdma_setup            = sata_dwc_bmdma_setup,
+       .bmdma_start            = sata_dwc_bmdma_start,
+};
+
+static const struct ata_port_info sata_dwc_port_info[] = {
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | ATA_FLAG_NCQ,
+               .pio_mask       = 0x1f, /* pio 0-4 */
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &sata_dwc_ops,
+       },
+};
+
+static int sata_dwc_probe(struct of_device *ofdev,
+                       const struct of_device_id *match)
+{
+       struct sata_dwc_device *hsdev;
+       u32 idr, versionr;
+       char *ver = (char *)&versionr;
+       u8 *base = NULL;
+       int err = 0;
+       int irq, rc;
+       struct ata_host *host;
+       struct ata_port_info pi = sata_dwc_port_info[0];
+       const struct ata_port_info *ppi[] = { &pi, NULL };
+
+       /* Allocate DWC SATA device */
+       hsdev = kmalloc(sizeof(*hsdev), GFP_KERNEL);
+       if (hsdev == NULL) {
+               dev_err(&ofdev->dev, "kmalloc failed for hsdev\n");
+               err = -ENOMEM;
+               goto error_out;
+       }
+       memset(hsdev, 0, sizeof(*hsdev));
+
+       /* Ioremap SATA registers */
+       base = of_iomap(ofdev->dev.of_node, 0);
+       if (!base) {
+               dev_err(&ofdev->dev, "ioremap failed for SATA register"
+                       " address\n");
+               err = -ENODEV;
+               goto error_out;
+       }
+       hsdev->reg_base = base;
+       dev_dbg(&ofdev->dev, "ioremap done for SATA register address\n");
+
+       /* Synopsys DWC SATA specific Registers */
+       hsdev->sata_dwc_regs = (void *__iomem)(base + SATA_DWC_REG_OFFSET);
+
+       /* Allocate and fill host */
+       host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_DWC_MAX_PORTS);
+       if (!host) {
+               dev_err(&ofdev->dev, "ata_host_alloc_pinfo failed\n");
+               err = -ENOMEM;
+               goto error_out;
+       }
+
+       host->private_data = hsdev;
+
+       /* Setup port */
+       host->ports[0]->ioaddr.cmd_addr = base;
+       host->ports[0]->ioaddr.scr_addr = base + SATA_DWC_SCR_OFFSET;
+       host_pvt.scr_addr_sstatus = base + SATA_DWC_SCR_OFFSET;
+       sata_dwc_setup_port(&host->ports[0]->ioaddr, (unsigned long)base);
+
+       /* Read the ID and Version Registers */
+       idr = in_le32(&hsdev->sata_dwc_regs->idr);
+       versionr = in_le32(&hsdev->sata_dwc_regs->versionr);
+       dev_notice(&ofdev->dev, "id %d, controller version %c.%c%c\n",
+                  idr, ver[0], ver[1], ver[2]);
+
+       /* Get SATA DMA interrupt number */
+       irq = irq_of_parse_and_map(ofdev->dev.of_node, 1);
+       if (irq == NO_IRQ) {
+               dev_err(&ofdev->dev, "no SATA DMA irq\n");
+               err = -ENODEV;
+               goto error_out;
+       }
+
+       /* Get physical SATA DMA register base address */
+       host_pvt.sata_dma_regs = of_iomap(ofdev->dev.of_node, 1);
+       if (!(host_pvt.sata_dma_regs)) {
+               dev_err(&ofdev->dev, "ioremap failed for AHBDMA register"
+                       " address\n");
+               err = -ENODEV;
+               goto error_out;
+       }
+
+       /* Save dev for later use in dev_xxx() routines */
+       host_pvt.dwc_dev = &ofdev->dev;
+
+       /* Initialize AHB DMAC */
+       dma_dwc_init(hsdev, irq);
+
+       /* Enable SATA Interrupts */
+       sata_dwc_enable_interrupts(hsdev);
+
+       /* Get SATA interrupt number */
+       irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+       if (irq == NO_IRQ) {
+               dev_err(&ofdev->dev, "no SATA DMA irq\n");
+               err = -ENODEV;
+               goto error_out;
+       }
+
+       /*
+        * Now, register with libATA core, this will also initiate the
+        * device discovery process, invoking our port_start() handler &
+        * error_handler() to execute a dummy Softreset EH session
+        */
+       rc = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht);
+
+       if (rc != 0)
+               dev_err(&ofdev->dev, "failed to activate host");
+
+       dev_set_drvdata(&ofdev->dev, host);
+       return 0;
+
+error_out:
+       /* Free SATA DMA resources */
+       dma_dwc_exit(hsdev);
+
+       if (base)
+               iounmap(base);
+       return err;
+}
+
+static int sata_dwc_remove(struct of_device *ofdev)
+{
+       struct device *dev = &ofdev->dev;
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct sata_dwc_device *hsdev = host->private_data;
+
+       ata_host_detach(host);
+       dev_set_drvdata(dev, NULL);
+
+       /* Free SATA DMA resources */
+       dma_dwc_exit(hsdev);
+
+       iounmap(hsdev->reg_base);
+       kfree(hsdev);
+       kfree(host);
+       dev_dbg(&ofdev->dev, "done\n");
+       return 0;
+}
+
+static const struct of_device_id sata_dwc_match[] = {
+       { .compatible = "amcc,sata-460ex", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, sata_dwc_match);
+
+static struct of_platform_driver sata_dwc_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = sata_dwc_match,
+       },
+       .probe = sata_dwc_probe,
+       .remove = sata_dwc_remove,
+};
+
+static int __init sata_dwc_init(void)
+{
+       return  of_register_platform_driver(&sata_dwc_driver);
+}
+
+static void __exit sata_dwc_exit(void)
+{
+       of_unregister_platform_driver(&sata_dwc_driver);
+}
+
+module_init(sata_dwc_init);
+module_exit(sata_dwc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Miesfeld <mmiesfeld@amcc.com>");
+MODULE_DESCRIPTION("DesignWare Cores SATA controller low lever driver");
+MODULE_VERSION(DRV_VERSION);
index 61c89b54ea23941fd937a25ec4228eca56648e10..18c986dbb7f145cbd04399e313029d71dae3a459 100644 (file)
@@ -1096,7 +1096,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)
 {
        struct sata_fsl_host_priv *host_priv = ap->host->private_data;
        void __iomem *hcr_base = host_priv->hcr_base;
-       u32 hstatus, qc_active = 0;
+       u32 hstatus, done_mask = 0;
        struct ata_queued_cmd *qc;
        u32 SError;
 
@@ -1116,28 +1116,28 @@ static void sata_fsl_host_intr(struct ata_port *ap)
        }
 
        /* Read command completed register */
-       qc_active = ioread32(hcr_base + CC);
+       done_mask = ioread32(hcr_base + CC);
 
        VPRINTK("Status of all queues :\n");
-       VPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n",
-               qc_active,
+       VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n",
+               done_mask,
                ioread32(hcr_base + CA),
                ioread32(hcr_base + CE),
                ioread32(hcr_base + CQ),
                ap->qc_active);
 
-       if (qc_active & ap->qc_active) {
+       if (done_mask & ap->qc_active) {
                int i;
                /* clear CC bit, this will also complete the interrupt */
-               iowrite32(qc_active, hcr_base + CC);
+               iowrite32(done_mask, hcr_base + CC);
 
                DPRINTK("Status of all queues :\n");
-               DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n",
-                       qc_active, ioread32(hcr_base + CA),
+               DPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x\n",
+                       done_mask, ioread32(hcr_base + CA),
                        ioread32(hcr_base + CE));
 
                for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
-                       if (qc_active & (1 << i)) {
+                       if (done_mask & (1 << i)) {
                                qc = ata_qc_from_tag(ap, i);
                                if (qc) {
                                        ata_qc_complete(qc);
@@ -1164,7 +1164,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)
                /* Spurious Interrupt!! */
                DPRINTK("spurious interrupt!!, CC = 0x%x\n",
                        ioread32(hcr_base + CC));
-               iowrite32(qc_active, hcr_base + CC);
+               iowrite32(done_mask, hcr_base + CC);
                return;
        }
 }
index a476cd99b95d42ce666e38c17d2dd767cac4f6db..9463c71dd38ece66e4ad777208381573754e3f64 100644 (file)
@@ -2716,34 +2716,35 @@ static void mv_err_intr(struct ata_port *ap)
 static void mv_process_crpb_response(struct ata_port *ap,
                struct mv_crpb *response, unsigned int tag, int ncq_enabled)
 {
+       u8 ata_status;
+       u16 edma_status = le16_to_cpu(response->flags);
        struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
 
-       if (qc) {
-               u8 ata_status;
-               u16 edma_status = le16_to_cpu(response->flags);
-               /*
-                * edma_status from a response queue entry:
-                *   LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only).
-                *   MSB is saved ATA status from command completion.
-                */
-               if (!ncq_enabled) {
-                       u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV;
-                       if (err_cause) {
-                               /*
-                                * Error will be seen/handled by mv_err_intr().
-                                * So do nothing at all here.
-                                */
-                               return;
-                       }
-               }
-               ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
-               if (!ac_err_mask(ata_status))
-                       ata_qc_complete(qc);
-               /* else: leave it for mv_err_intr() */
-       } else {
+       if (unlikely(!qc)) {
                ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
                                __func__, tag);
+               return;
+       }
+
+       /*
+        * edma_status from a response queue entry:
+        *   LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only).
+        *   MSB is saved ATA status from command completion.
+        */
+       if (!ncq_enabled) {
+               u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV;
+               if (err_cause) {
+                       /*
+                        * Error will be seen/handled by
+                        * mv_err_intr().  So do nothing at all here.
+                        */
+                       return;
+               }
        }
+       ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
+       if (!ac_err_mask(ata_status))
+               ata_qc_complete(qc);
+       /* else: leave it for mv_err_intr() */
 }
 
 static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp)
index 21161136cad0c12d91608a79f429b4e296a67f8f..cb89ef8d99d94468ed2cfba330f19b65d413d524 100644 (file)
@@ -1018,7 +1018,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
                              NV_ADMA_STAT_CPBERR |
                              NV_ADMA_STAT_CMD_COMPLETE)) {
                        u32 check_commands = notifier_clears[i];
-                       int pos, error = 0;
+                       int pos, rc;
 
                        if (status & NV_ADMA_STAT_CPBERR) {
                                /* check all active commands */
@@ -1030,10 +1030,12 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
                        }
 
                        /* check CPBs for completed commands */
-                       while ((pos = ffs(check_commands)) && !error) {
+                       while ((pos = ffs(check_commands))) {
                                pos--;
-                               error = nv_adma_check_cpb(ap, pos,
+                               rc = nv_adma_check_cpb(ap, pos,
                                                notifier_error & (1 << pos));
+                               if (unlikely(rc))
+                                       check_commands = 0;
                                check_commands &= ~(1 << pos);
                        }
                }
@@ -2129,7 +2131,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
        struct nv_swncq_port_priv *pp = ap->private_data;
        struct ata_eh_info *ehi = &ap->link.eh_info;
        u32 sactive;
-       int nr_done = 0;
        u32 done_mask;
        int i;
        u8 host_stat;
@@ -2170,22 +2171,21 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
                        pp->dhfis_bits &= ~(1 << i);
                        pp->dmafis_bits &= ~(1 << i);
                        pp->sdbfis_bits |= (1 << i);
-                       nr_done++;
                }
        }
 
        if (!ap->qc_active) {
                DPRINTK("over\n");
                nv_swncq_pp_reinit(ap);
-               return nr_done;
+               return 0;
        }
 
        if (pp->qc_active & pp->dhfis_bits)
-               return nr_done;
+               return 0;
 
        if ((pp->ncq_flags & ncq_saw_backout) ||
            (pp->qc_active ^ pp->dhfis_bits))
-               /* if the controller cann't get a device to host register FIS,
+               /* if the controller can't get a device to host register FIS,
                 * The driver needs to reissue the new command.
                 */
                lack_dhfis = 1;
@@ -2202,7 +2202,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
        if (lack_dhfis) {
                qc = ata_qc_from_tag(ap, pp->last_issue_tag);
                nv_swncq_issue_atacmd(ap, qc);
-               return nr_done;
+               return 0;
        }
 
        if (pp->defer_queue.defer_bits) {
@@ -2212,7 +2212,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
                nv_swncq_issue_atacmd(ap, qc);
        }
 
-       return nr_done;
+       return 0;
 }
 
 static inline u32 nv_swncq_tag(struct ata_port *ap)
@@ -2224,7 +2224,7 @@ static inline u32 nv_swncq_tag(struct ata_port *ap)
        return (tag & 0x1f);
 }
 
-static int nv_swncq_dmafis(struct ata_port *ap)
+static void nv_swncq_dmafis(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc;
        unsigned int rw;
@@ -2239,7 +2239,7 @@ static int nv_swncq_dmafis(struct ata_port *ap)
        qc = ata_qc_from_tag(ap, tag);
 
        if (unlikely(!qc))
-               return 0;
+               return;
 
        rw = qc->tf.flags & ATA_TFLAG_WRITE;
 
@@ -2254,8 +2254,6 @@ static int nv_swncq_dmafis(struct ata_port *ap)
                dmactl |= ATA_DMA_WR;
 
        iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
-       return 1;
 }
 
 static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
@@ -2265,7 +2263,6 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
        struct ata_eh_info *ehi = &ap->link.eh_info;
        u32 serror;
        u8 ata_stat;
-       int rc = 0;
 
        ata_stat = ap->ops->sff_check_status(ap);
        nv_swncq_irq_clear(ap, fis);
@@ -2310,8 +2307,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
                        "dhfis 0x%X dmafis 0x%X sactive 0x%X\n",
                        ap->print_id, pp->qc_active, pp->dhfis_bits,
                        pp->dmafis_bits, readl(pp->sactive_block));
-               rc = nv_swncq_sdbfis(ap);
-               if (rc < 0)
+               if (nv_swncq_sdbfis(ap) < 0)
                        goto irq_error;
        }
 
@@ -2348,7 +2344,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
                 */
                pp->dmafis_bits |= (0x1 << nv_swncq_tag(ap));
                pp->ncq_flags |= ncq_saw_dmas;
-               rc = nv_swncq_dmafis(ap);
+               nv_swncq_dmafis(ap);
        }
 
 irq_exit:
index da8f176c051e19e164b0fdc362b3ba77d3e89738..b7385e0777176413c2497b780797e81189888632 100644 (file)
@@ -2657,7 +2657,7 @@ static int __devinit fore200e_sba_probe(struct of_device *op,
 
        fore200e->bus = bus;
        fore200e->bus_dev = op;
-       fore200e->irq = op->irqs[0];
+       fore200e->irq = op->archdata.irqs[0];
        fore200e->phys_base = op->resource[0].start;
 
        sprintf(fore200e->name, "%s-%d", bus->model_name, index);
@@ -2795,7 +2795,7 @@ static int __init fore200e_module_init(void)
        printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
 
 #ifdef CONFIG_SBUS
-       err = of_register_driver(&fore200e_sba_driver, &of_bus_type);
+       err = of_register_platform_driver(&fore200e_sba_driver);
        if (err)
                return err;
 #endif
@@ -2806,7 +2806,7 @@ static int __init fore200e_module_init(void)
 
 #ifdef CONFIG_SBUS
        if (err)
-               of_unregister_driver(&fore200e_sba_driver);
+               of_unregister_platform_driver(&fore200e_sba_driver);
 #endif
 
        return err;
@@ -2818,7 +2818,7 @@ static void __exit fore200e_module_cleanup(void)
        pci_unregister_driver(&fore200e_pca_driver);
 #endif
 #ifdef CONFIG_SBUS
-       of_unregister_driver(&fore200e_sba_driver);
+       of_unregister_platform_driver(&fore200e_sba_driver);
 #endif
 }
 
index 12eec3f633b13f0b6e6544a6ce895ff298d4cd84..eb1b7fa20dce5af66c6711d05e97642ce4c568a1 100644 (file)
@@ -945,8 +945,8 @@ bus_devices_fail:
        bus_remove_file(bus, &bus_attr_uevent);
 bus_uevent_fail:
        kset_unregister(&bus->p->subsys);
-       kfree(bus->p);
 out:
+       kfree(bus->p);
        bus->p = NULL;
        return retval;
 }
index f8e72724dd4b78c0d7048f552a5be29bb189956b..d1b2c9adc2718ebcf8979d19b0c065803020836e 100644 (file)
@@ -1599,7 +1599,7 @@ EXPORT_SYMBOL_GPL(device_destroy);
  * on the same device to ensure that new_name is valid and
  * won't conflict with other devices.
  */
-int device_rename(struct device *dev, char *new_name)
+int device_rename(struct device *dev, const char *new_name)
 {
        char *old_class_name = NULL;
        char *new_class_name = NULL;
index 503c2620bbcc995cebe5f455405ee2f436cf9241..da57ee9d63febb2d525883a84a137962ca3a07c0 100644 (file)
@@ -51,6 +51,10 @@ static int driver_sysfs_add(struct device *dev)
 {
        int ret;
 
+       if (dev->bus)
+               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
+                                            BUS_NOTIFY_BIND_DRIVER, dev);
+
        ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
                          kobject_name(&dev->kobj));
        if (ret == 0) {
index d4d8ce53886aa8276165ef151aab2dca46b2ecac..f369e2795985a66d0e00c399464bef711acbf697 100644 (file)
@@ -8,7 +8,7 @@
 
 struct dma_coherent_mem {
        void            *virt_base;
-       u32             device_base;
+       dma_addr_t      device_base;
        int             size;
        int             flags;
        unsigned long   *bitmap;
index 3f093b0dd217bd529d67ba4b7984c3435aac8c01..c8a44f5e0584bec3d72e4bbada17ebb80efdd20b 100644 (file)
@@ -87,29 +87,32 @@ static DEFINE_MUTEX(fw_lock);
 
 struct firmware_priv {
        struct completion completion;
-       struct bin_attribute attr_data;
        struct firmware *fw;
        unsigned long status;
        struct page **pages;
        int nr_pages;
        int page_array_size;
        struct timer_list timeout;
+       struct device dev;
        bool nowait;
        char fw_id[];
 };
 
-static void
-fw_load_abort(struct firmware_priv *fw_priv)
+static struct firmware_priv *to_firmware_priv(struct device *dev)
+{
+       return container_of(dev, struct firmware_priv, dev);
+}
+
+static void fw_load_abort(struct firmware_priv *fw_priv)
 {
        set_bit(FW_STATUS_ABORT, &fw_priv->status);
        wmb();
        complete(&fw_priv->completion);
 }
 
-static ssize_t
-firmware_timeout_show(struct class *class,
-                     struct class_attribute *attr,
-                     char *buf)
+static ssize_t firmware_timeout_show(struct class *class,
+                                    struct class_attribute *attr,
+                                    char *buf)
 {
        return sprintf(buf, "%d\n", loading_timeout);
 }
@@ -127,14 +130,14 @@ firmware_timeout_show(struct class *class,
  *
  *     Note: zero means 'wait forever'.
  **/
-static ssize_t
-firmware_timeout_store(struct class *class,
-                       struct class_attribute *attr,
-                       const char *buf, size_t count)
+static ssize_t firmware_timeout_store(struct class *class,
+                                     struct class_attribute *attr,
+                                     const char *buf, size_t count)
 {
        loading_timeout = simple_strtol(buf, NULL, 10);
        if (loading_timeout < 0)
                loading_timeout = 0;
+
        return count;
 }
 
@@ -146,21 +149,20 @@ static struct class_attribute firmware_class_attrs[] = {
 
 static void fw_dev_release(struct device *dev)
 {
-       struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+       struct firmware_priv *fw_priv = to_firmware_priv(dev);
        int i;
 
        for (i = 0; i < fw_priv->nr_pages; i++)
                __free_page(fw_priv->pages[i]);
        kfree(fw_priv->pages);
        kfree(fw_priv);
-       kfree(dev);
 
        module_put(THIS_MODULE);
 }
 
 static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-       struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+       struct firmware_priv *fw_priv = to_firmware_priv(dev);
 
        if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id))
                return -ENOMEM;
@@ -182,8 +184,9 @@ static struct class firmware_class = {
 static ssize_t firmware_loading_show(struct device *dev,
                                     struct device_attribute *attr, char *buf)
 {
-       struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+       struct firmware_priv *fw_priv = to_firmware_priv(dev);
        int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status);
+
        return sprintf(buf, "%d\n", loading);
 }
 
@@ -219,7 +222,7 @@ static ssize_t firmware_loading_store(struct device *dev,
                                      struct device_attribute *attr,
                                      const char *buf, size_t count)
 {
-       struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+       struct firmware_priv *fw_priv = to_firmware_priv(dev);
        int loading = simple_strtol(buf, NULL, 10);
        int i;
 
@@ -277,13 +280,12 @@ static ssize_t firmware_loading_store(struct device *dev,
 
 static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
 
-static ssize_t
-firmware_data_read(struct file *filp, struct kobject *kobj,
-                  struct bin_attribute *bin_attr, char *buffer, loff_t offset,
-                  size_t count)
+static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,
+                                 struct bin_attribute *bin_attr,
+                                 char *buffer, loff_t offset, size_t count)
 {
        struct device *dev = to_dev(kobj);
-       struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+       struct firmware_priv *fw_priv = to_firmware_priv(dev);
        struct firmware *fw;
        ssize_t ret_count;
 
@@ -322,8 +324,7 @@ out:
        return ret_count;
 }
 
-static int
-fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
+static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
 {
        int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT;
 
@@ -373,13 +374,12 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
  *     Data written to the 'data' attribute will be later handed to
  *     the driver as a firmware image.
  **/
-static ssize_t
-firmware_data_write(struct file* filp, struct kobject *kobj,
-                   struct bin_attribute *bin_attr, char *buffer,
-                   loff_t offset, size_t count)
+static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
+                                  struct bin_attribute *bin_attr,
+                                  char *buffer, loff_t offset, size_t count)
 {
        struct device *dev = to_dev(kobj);
-       struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+       struct firmware_priv *fw_priv = to_firmware_priv(dev);
        struct firmware *fw;
        ssize_t retval;
 
@@ -420,116 +420,103 @@ out:
        return retval;
 }
 
-static struct bin_attribute firmware_attr_data_tmpl = {
-       .attr = {.name = "data", .mode = 0644},
+static struct bin_attribute firmware_attr_data = {
+       .attr = { .name = "data", .mode = 0644 },
        .size = 0,
        .read = firmware_data_read,
        .write = firmware_data_write,
 };
 
-static void
-firmware_class_timeout(u_long data)
+static void firmware_class_timeout(u_long data)
 {
        struct firmware_priv *fw_priv = (struct firmware_priv *) data;
+
        fw_load_abort(fw_priv);
 }
 
-static int fw_register_device(struct device **dev_p, const char *fw_name,
-                             struct device *device)
+static struct firmware_priv *
+fw_create_instance(struct firmware *firmware, const char *fw_name,
+                  struct device *device, bool uevent, bool nowait)
 {
-       int retval;
-       struct firmware_priv *fw_priv =
-               kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL);
-       struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL);
-
-       *dev_p = NULL;
+       struct firmware_priv *fw_priv;
+       struct device *f_dev;
+       int error;
 
-       if (!fw_priv || !f_dev) {
+       fw_priv = kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL);
+       if (!fw_priv) {
                dev_err(device, "%s: kmalloc failed\n", __func__);
-               retval = -ENOMEM;
-               goto error_kfree;
+               error = -ENOMEM;
+               goto err_out;
        }
 
+       fw_priv->fw = firmware;
+       fw_priv->nowait = nowait;
        strcpy(fw_priv->fw_id, fw_name);
        init_completion(&fw_priv->completion);
-       fw_priv->attr_data = firmware_attr_data_tmpl;
-       fw_priv->timeout.function = firmware_class_timeout;
-       fw_priv->timeout.data = (u_long) fw_priv;
-       init_timer(&fw_priv->timeout);
+       setup_timer(&fw_priv->timeout,
+                   firmware_class_timeout, (u_long) fw_priv);
 
+       f_dev = &fw_priv->dev;
+
+       device_initialize(f_dev);
        dev_set_name(f_dev, "%s", dev_name(device));
        f_dev->parent = device;
        f_dev->class = &firmware_class;
-       dev_set_drvdata(f_dev, fw_priv);
-       dev_set_uevent_suppress(f_dev, 1);
-       retval = device_register(f_dev);
-       if (retval) {
-               dev_err(device, "%s: device_register failed\n", __func__);
-               put_device(f_dev);
-               return retval;
-       }
-       *dev_p = f_dev;
-       return 0;
-
-error_kfree:
-       kfree(f_dev);
-       kfree(fw_priv);
-       return retval;
-}
 
-static int fw_setup_device(struct firmware *fw, struct device **dev_p,
-                          const char *fw_name, struct device *device,
-                          int uevent, bool nowait)
-{
-       struct device *f_dev;
-       struct firmware_priv *fw_priv;
-       int retval;
-
-       *dev_p = NULL;
-       retval = fw_register_device(&f_dev, fw_name, device);
-       if (retval)
-               goto out;
+       dev_set_uevent_suppress(f_dev, true);
 
        /* Need to pin this module until class device is destroyed */
        __module_get(THIS_MODULE);
 
-       fw_priv = dev_get_drvdata(f_dev);
-
-       fw_priv->nowait = nowait;
+       error = device_add(f_dev);
+       if (error) {
+               dev_err(device, "%s: device_register failed\n", __func__);
+               goto err_put_dev;
+       }
 
-       fw_priv->fw = fw;
-       sysfs_bin_attr_init(&fw_priv->attr_data);
-       retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
-       if (retval) {
+       error = device_create_bin_file(f_dev, &firmware_attr_data);
+       if (error) {
                dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
-               goto error_unreg;
+               goto err_del_dev;
        }
 
-       retval = device_create_file(f_dev, &dev_attr_loading);
-       if (retval) {
+       error = device_create_file(f_dev, &dev_attr_loading);
+       if (error) {
                dev_err(device, "%s: device_create_file failed\n", __func__);
-               goto error_unreg;
+               goto err_del_bin_attr;
        }
 
        if (uevent)
-               dev_set_uevent_suppress(f_dev, 0);
-       *dev_p = f_dev;
-       goto out;
+               dev_set_uevent_suppress(f_dev, false);
+
+       return fw_priv;
+
+err_del_bin_attr:
+       device_remove_bin_file(f_dev, &firmware_attr_data);
+err_del_dev:
+       device_del(f_dev);
+err_put_dev:
+       put_device(f_dev);
+err_out:
+       return ERR_PTR(error);
+}
+
+static void fw_destroy_instance(struct firmware_priv *fw_priv)
+{
+       struct device *f_dev = &fw_priv->dev;
 
-error_unreg:
+       device_remove_file(f_dev, &dev_attr_loading);
+       device_remove_bin_file(f_dev, &firmware_attr_data);
        device_unregister(f_dev);
-out:
-       return retval;
 }
 
-static int
-_request_firmware(const struct firmware **firmware_p, const char *name,
-                struct device *device, int uevent, bool nowait)
+static int _request_firmware(const struct firmware **firmware_p,
+                            const char *name, struct device *device,
+                            bool uevent, bool nowait)
 {
-       struct device *f_dev;
        struct firmware_priv *fw_priv;
        struct firmware *firmware;
-       int retval;
+       int retval = 0;
 
        if (!firmware_p)
                return -EINVAL;
@@ -550,41 +537,40 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
        if (uevent)
                dev_dbg(device, "firmware: requesting %s\n", name);
 
-       retval = fw_setup_device(firmware, &f_dev, name, device,
-                                uevent, nowait);
-       if (retval)
-               goto error_kfree_fw;
-
-       fw_priv = dev_get_drvdata(f_dev);
+       fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
+       if (IS_ERR(fw_priv)) {
+               retval = PTR_ERR(fw_priv);
+               goto out;
+       }
 
        if (uevent) {
-               if (loading_timeout > 0) {
-                       fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
-                       add_timer(&fw_priv->timeout);
-               }
+               if (loading_timeout > 0)
+                       mod_timer(&fw_priv->timeout,
+                                 round_jiffies_up(jiffies +
+                                                  loading_timeout * HZ));
+
+               kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
+       }
+
+       wait_for_completion(&fw_priv->completion);
 
-               kobject_uevent(&f_dev->kobj, KOBJ_ADD);
-               wait_for_completion(&fw_priv->completion);
-               set_bit(FW_STATUS_DONE, &fw_priv->status);
-               del_timer_sync(&fw_priv->timeout);
-       } else
-               wait_for_completion(&fw_priv->completion);
+       set_bit(FW_STATUS_DONE, &fw_priv->status);
+       del_timer_sync(&fw_priv->timeout);
 
        mutex_lock(&fw_lock);
-       if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
+       if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status))
                retval = -ENOENT;
-               release_firmware(fw_priv->fw);
-               *firmware_p = NULL;
-       }
        fw_priv->fw = NULL;
        mutex_unlock(&fw_lock);
-       device_unregister(f_dev);
-       goto out;
 
-error_kfree_fw:
-       kfree(firmware);
-       *firmware_p = NULL;
+       fw_destroy_instance(fw_priv);
+
 out:
+       if (retval) {
+               release_firmware(firmware);
+               firmware_p = NULL;
+       }
+
        return retval;
 }
 
@@ -635,23 +621,24 @@ struct firmware_work {
        int uevent;
 };
 
-static int
-request_firmware_work_func(void *arg)
+static int request_firmware_work_func(void *arg)
 {
        struct firmware_work *fw_work = arg;
        const struct firmware *fw;
        int ret;
+
        if (!arg) {
                WARN_ON(1);
                return 0;
        }
-       ret = _request_firmware(&fw, fw_work->name, fw_work->device,
-               fw_work->uevent, true);
 
+       ret = _request_firmware(&fw, fw_work->name, fw_work->device,
+                               fw_work->uevent, true);
        fw_work->cont(fw, fw_work->context);
 
        module_put(fw_work->module);
        kfree(fw_work);
+
        return ret;
 }
 
@@ -679,34 +666,33 @@ request_firmware_nowait(
        void (*cont)(const struct firmware *fw, void *context))
 {
        struct task_struct *task;
-       struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-                                               gfp);
+       struct firmware_work *fw_work;
 
+       fw_work = kzalloc(sizeof (struct firmware_work), gfp);
        if (!fw_work)
                return -ENOMEM;
+
+       fw_work->module = module;
+       fw_work->name = name;
+       fw_work->device = device;
+       fw_work->context = context;
+       fw_work->cont = cont;
+       fw_work->uevent = uevent;
+
        if (!try_module_get(module)) {
                kfree(fw_work);
                return -EFAULT;
        }
 
-       *fw_work = (struct firmware_work) {
-               .module = module,
-               .name = name,
-               .device = device,
-               .context = context,
-               .cont = cont,
-               .uevent = uevent,
-       };
-
        task = kthread_run(request_firmware_work_func, fw_work,
                            "firmware/%s", name);
-
        if (IS_ERR(task)) {
                fw_work->cont(NULL, fw_work->context);
                module_put(fw_work->module);
                kfree(fw_work);
                return PTR_ERR(task);
        }
+
        return 0;
 }
 
index 4d99c8bdfedcd8f062c9e7924e0698cf692b81de..c6c933f58102370d8ed738e2778cb11dad2e93fb 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/string.h>
 #include <linux/platform_device.h>
+#include <linux/of_device.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
@@ -191,13 +192,13 @@ int platform_device_add_resources(struct platform_device *pdev,
 {
        struct resource *r;
 
-       r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL);
+       r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
        if (r) {
-               memcpy(r, res, sizeof(struct resource) * num);
                pdev->resource = r;
                pdev->num_resources = num;
+               return 0;
        }
-       return r ? 0 : -ENOMEM;
+       return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(platform_device_add_resources);
 
@@ -344,108 +345,56 @@ void platform_device_unregister(struct platform_device *pdev)
 EXPORT_SYMBOL_GPL(platform_device_unregister);
 
 /**
- * platform_device_register_simple - add a platform-level device and its resources
- * @name: base name of the device we're adding
- * @id: instance id
- * @res: set of resources that needs to be allocated for the device
- * @num: number of resources
+ * platform_device_register_resndata - add a platform-level device with
+ * resources and platform-specific data
  *
- * This function creates a simple platform device that requires minimal
- * resource and memory management. Canned release function freeing memory
- * allocated for the device allows drivers using such devices to be
- * unloaded without waiting for the last reference to the device to be
- * dropped.
- *
- * This interface is primarily intended for use with legacy drivers which
- * probe hardware directly.  Because such drivers create sysfs device nodes
- * themselves, rather than letting system infrastructure handle such device
- * enumeration tasks, they don't fully conform to the Linux driver model.
- * In particular, when such drivers are built as modules, they can't be
- * "hotplugged".
- *
- * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
- */
-struct platform_device *platform_device_register_simple(const char *name,
-                                                       int id,
-                                                       const struct resource *res,
-                                                       unsigned int num)
-{
-       struct platform_device *pdev;
-       int retval;
-
-       pdev = platform_device_alloc(name, id);
-       if (!pdev) {
-               retval = -ENOMEM;
-               goto error;
-       }
-
-       if (num) {
-               retval = platform_device_add_resources(pdev, res, num);
-               if (retval)
-                       goto error;
-       }
-
-       retval = platform_device_add(pdev);
-       if (retval)
-               goto error;
-
-       return pdev;
-
-error:
-       platform_device_put(pdev);
-       return ERR_PTR(retval);
-}
-EXPORT_SYMBOL_GPL(platform_device_register_simple);
-
-/**
- * platform_device_register_data - add a platform-level device with platform-specific data
  * @parent: parent device for the device we're adding
  * @name: base name of the device we're adding
  * @id: instance id
+ * @res: set of resources that needs to be allocated for the device
+ * @num: number of resources
  * @data: platform specific data for this platform device
  * @size: size of platform specific data
  *
- * This function creates a simple platform device that requires minimal
- * resource and memory management. Canned release function freeing memory
- * allocated for the device allows drivers using such devices to be
- * unloaded without waiting for the last reference to the device to be
- * dropped.
- *
  * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
-struct platform_device *platform_device_register_data(
+struct platform_device *__init_or_module platform_device_register_resndata(
                struct device *parent,
                const char *name, int id,
+               const struct resource *res, unsigned int num,
                const void *data, size_t size)
 {
+       int ret = -ENOMEM;
        struct platform_device *pdev;
-       int retval;
 
        pdev = platform_device_alloc(name, id);
-       if (!pdev) {
-               retval = -ENOMEM;
-               goto error;
-       }
+       if (!pdev)
+               goto err;
 
        pdev->dev.parent = parent;
 
-       if (size) {
-               retval = platform_device_add_data(pdev, data, size);
-               if (retval)
-                       goto error;
+       if (res) {
+               ret = platform_device_add_resources(pdev, res, num);
+               if (ret)
+                       goto err;
        }
 
-       retval = platform_device_add(pdev);
-       if (retval)
-               goto error;
+       if (data) {
+               ret = platform_device_add_data(pdev, data, size);
+               if (ret)
+                       goto err;
+       }
 
-       return pdev;
+       ret = platform_device_add(pdev);
+       if (ret) {
+err:
+               platform_device_put(pdev);
+               return ERR_PTR(ret);
+       }
 
-error:
-       platform_device_put(pdev);
-       return ERR_PTR(retval);
+       return pdev;
 }
-EXPORT_SYMBOL_GPL(platform_device_register_data);
+EXPORT_SYMBOL_GPL(platform_device_register_resndata);
 
 static int platform_drv_probe(struct device *_dev)
 {
@@ -635,6 +584,12 @@ static struct device_attribute platform_dev_attrs[] = {
 static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
        struct platform_device  *pdev = to_platform_device(dev);
+       int rc;
+
+       /* Some devices have extra OF data and an OF-style MODALIAS */
+       rc = of_device_uevent(dev,env);
+       if (rc != -ENODEV)
+               return rc;
 
        add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
                (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
@@ -673,7 +628,11 @@ static int platform_match(struct device *dev, struct device_driver *drv)
        struct platform_device *pdev = to_platform_device(dev);
        struct platform_driver *pdrv = to_platform_driver(drv);
 
-       /* match against the id table first */
+       /* Attempt an OF style match first */
+       if (of_driver_match_device(dev, drv))
+               return 1;
+
+       /* Then try to match against the id table */
        if (pdrv->id_table)
                return platform_match_id(pdrv->id_table, pdev) != NULL;
 
index 258bc2ae2885625a1650cebcabb4b9eb975092bb..23b7c48df843c88ffb00f383c4110a86b5efffdd 100644 (file)
@@ -225,16 +225,6 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
        struct gendisk *disk = bdev->bd_disk;
        struct virtio_blk *vblk = disk->private_data;
 
-       if (cmd == 0x56424944) { /* 'VBID' */
-               void __user *usr_data = (void __user *)data;
-               char id_str[VIRTIO_BLK_ID_BYTES];
-               int err;
-
-               err = virtblk_get_id(disk, id_str);
-               if (!err && copy_to_user(usr_data, id_str, VIRTIO_BLK_ID_BYTES))
-                       err = -EFAULT;
-               return err;
-       }
        /*
         * Only allow the generic SCSI ioctls if the host can support it.
         */
@@ -281,6 +271,27 @@ static int index_to_minor(int index)
        return index << PART_BITS;
 }
 
+static ssize_t virtblk_serial_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct gendisk *disk = dev_to_disk(dev);
+       int err;
+
+       /* sysfs gives us a PAGE_SIZE buffer */
+       BUILD_BUG_ON(PAGE_SIZE < VIRTIO_BLK_ID_BYTES);
+
+       buf[VIRTIO_BLK_ID_BYTES] = '\0';
+       err = virtblk_get_id(disk, buf);
+       if (!err)
+               return strlen(buf);
+
+       if (err == -EIO) /* Unsupported? Make it empty. */
+               return 0;
+
+       return err;
+}
+DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
+
 static int __devinit virtblk_probe(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk;
@@ -366,12 +377,32 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
        vblk->disk->driverfs_dev = &vdev->dev;
        index++;
 
-       /* If barriers are supported, tell block layer that queue is ordered */
-       if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
+       if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) {
+               /*
+                * If the FLUSH feature is supported we do have support for
+                * flushing a volatile write cache on the host.  Use that
+                * to implement write barrier support.
+                */
                blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH,
                                  virtblk_prepare_flush);
-       else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
+       } else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) {
+               /*
+                * If the BARRIER feature is supported the host expects us
+                * to order request by tags.  This implies there is not
+                * volatile write cache on the host, and that the host
+                * never re-orders outstanding I/O.  This feature is not
+                * useful for real life scenarious and deprecated.
+                */
                blk_queue_ordered(q, QUEUE_ORDERED_TAG, NULL);
+       } else {
+               /*
+                * If the FLUSH feature is not supported we must assume that
+                * the host does not perform any kind of volatile write
+                * caching. We still need to drain the queue to provider
+                * proper barrier semantics.
+                */
+               blk_queue_ordered(q, QUEUE_ORDERED_DRAIN, NULL);
+       }
 
        /* If disk is read-only in the host, the guest should obey */
        if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO))
@@ -445,8 +476,15 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
 
 
        add_disk(vblk->disk);
+       err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial);
+       if (err)
+               goto out_del_disk;
+
        return 0;
 
+out_del_disk:
+       del_gendisk(vblk->disk);
+       blk_cleanup_queue(vblk->disk->queue);
 out_put_disk:
        put_disk(vblk->disk);
 out_mempool:
index 82ed403147c06c66143b0d5fdbcf5ddfccdc8232..f63ac3d1f8a411b23574fbc221f2d3edd0a12738 100644 (file)
@@ -48,6 +48,7 @@
 #include <xen/grant_table.h>
 #include <xen/events.h>
 #include <xen/page.h>
+#include <xen/platform_pci.h>
 
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/blkif.h>
@@ -737,6 +738,35 @@ static int blkfront_probe(struct xenbus_device *dev,
                }
        }
 
+       if (xen_hvm_domain()) {
+               char *type;
+               int len;
+               /* no unplug has been done: do not hook devices != xen vbds */
+               if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) {
+                       int major;
+
+                       if (!VDEV_IS_EXTENDED(vdevice))
+                               major = BLKIF_MAJOR(vdevice);
+                       else
+                               major = XENVBD_MAJOR;
+
+                       if (major != XENVBD_MAJOR) {
+                               printk(KERN_INFO
+                                               "%s: HVM does not support vbd %d as xen block device\n",
+                                               __FUNCTION__, vdevice);
+                               return -ENODEV;
+                       }
+               }
+               /* do not create a PV cdrom device if we are an HVM guest */
+               type = xenbus_read(XBT_NIL, dev->nodename, "device-type", &len);
+               if (IS_ERR(type))
+                       return -ENODEV;
+               if (strncmp(type, "cdrom", 5) == 0) {
+                       kfree(type);
+                       return -ENODEV;
+               }
+               kfree(type);
+       }
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
                xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
index 6d34f405a2f37424976a685c669217bbd17fbca9..d52e90a5a61750494a6c740e4dd4565fb00f788e 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/skbuff.h>
 #include <linux/io.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -160,7 +159,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev);
 static void bluecard_activity_led_timeout(u_long arg)
 {
        bluecard_info_t *info = (bluecard_info_t *)arg;
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
 
        if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
                return;
@@ -177,7 +176,7 @@ static void bluecard_activity_led_timeout(u_long arg)
 
 static void bluecard_enable_activity_led(bluecard_info_t *info)
 {
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
 
        if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
                return;
@@ -233,7 +232,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
        }
 
        do {
-               register unsigned int iobase = info->p_dev->io.BasePort1;
+               register unsigned int iobase = info->p_dev->resource[0]->start;
                register unsigned int offset;
                register unsigned char command;
                register unsigned long ready_bit;
@@ -380,7 +379,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
                return;
        }
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
                bluecard_enable_activity_led(info);
@@ -509,7 +508,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
        if (!test_bit(CARD_READY, &(info->hw_state)))
                return IRQ_HANDLED;
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        spin_lock(&(info->lock));
 
@@ -623,7 +622,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
 static int bluecard_hci_open(struct hci_dev *hdev)
 {
        bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
 
        if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
                bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
@@ -643,7 +642,7 @@ static int bluecard_hci_open(struct hci_dev *hdev)
 static int bluecard_hci_close(struct hci_dev *hdev)
 {
        bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
 
        if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
                return 0;
@@ -710,7 +709,7 @@ static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned l
 
 static int bluecard_open(bluecard_info_t *info)
 {
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
        struct hci_dev *hdev;
        unsigned char id;
 
@@ -829,7 +828,7 @@ static int bluecard_open(bluecard_info_t *info)
 
 static int bluecard_close(bluecard_info_t *info)
 {
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
        struct hci_dev *hdev = info->hdev;
 
        if (!hdev)
@@ -866,9 +865,6 @@ static int bluecard_probe(struct pcmcia_device *link)
        info->p_dev = link;
        link->priv = info;
 
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.NumPorts1 = 8;
-
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -891,12 +887,14 @@ static int bluecard_config(struct pcmcia_device *link)
        int i, n;
 
        link->conf.ConfigIndex = 0x20;
-       link->io.NumPorts1 = 64;
-       link->io.IOAddrLines = 6;
+
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[0]->end = 64;
+       link->io_lines = 6;
 
        for (n = 0; n < 0x400; n += 0x40) {
-               link->io.BasePort1 = n ^ 0x300;
-               i = pcmcia_request_io(link, &link->io);
+               link->resource[0]->start = n ^ 0x300;
+               i = pcmcia_request_io(link);
                if (i == 0)
                        break;
        }
index 21e05fdc912196d38f7ce5e73389338f9cd5b672..7ab8f29d5e0dcb8df750bab81fc0bcce4494b12e 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -189,7 +188,7 @@ static void bt3c_write_wakeup(bt3c_info_t *info)
                return;
 
        do {
-               register unsigned int iobase = info->p_dev->io.BasePort1;
+               register unsigned int iobase = info->p_dev->resource[0]->start;
                register struct sk_buff *skb;
                register int len;
 
@@ -227,7 +226,7 @@ static void bt3c_receive(bt3c_info_t *info)
                return;
        }
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        avail = bt3c_read(iobase, 0x7006);
        //printk("bt3c_cs: receiving %d bytes\n", avail);
@@ -348,7 +347,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
                /* our irq handler is shared */
                return IRQ_NONE;
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        spin_lock(&(info->lock));
 
@@ -481,7 +480,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware,
        unsigned int iobase, size, addr, fcs, tmp;
        int i, err = 0;
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        /* Reset */
        bt3c_io_write(iobase, 0x8040, 0x0404);
@@ -658,8 +657,8 @@ static int bt3c_probe(struct pcmcia_device *link)
        info->p_dev = link;
        link->priv = info;
 
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.NumPorts1 = 8;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[0]->end = 8;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -684,14 +683,14 @@ static int bt3c_check_config(struct pcmcia_device *p_dev,
 {
        unsigned long try = (unsigned long) priv_data;
 
+       p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+
        if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
                p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
        if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
            (cf->io.win[0].base != 0)) {
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               p_dev->io.IOAddrLines = (try == 0) ? 16 :
-                       cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               p_dev->resource[0]->start = cf->io.win[0].base;
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        }
        return -ENODEV;
@@ -708,9 +707,9 @@ static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
 
        if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
                for (j = 0; j < 5; j++) {
-                       p_dev->io.BasePort1 = base[j];
-                       p_dev->io.IOAddrLines = base[j] ? 16 : 3;
-                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       p_dev->resource[0]->start = base[j];
+                       p_dev->io_lines = base[j] ? 16 : 3;
+                       if (!pcmcia_request_io(p_dev))
                                return 0;
                }
        }
index 4ed7288f99db26b34f0790eb1dd1f33309cc0731..1c4f5e863b032d21d8a765a4d3b97c1ca1bb73e4 100644 (file)
@@ -41,7 +41,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -143,7 +142,7 @@ static void btuart_write_wakeup(btuart_info_t *info)
        }
 
        do {
-               register unsigned int iobase = info->p_dev->io.BasePort1;
+               register unsigned int iobase = info->p_dev->resource[0]->start;
                register struct sk_buff *skb;
                register int len;
 
@@ -184,7 +183,7 @@ static void btuart_receive(btuart_info_t *info)
                return;
        }
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        do {
                info->hdev->stat.byte_rx++;
@@ -298,7 +297,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
                /* our irq handler is shared */
                return IRQ_NONE;
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        spin_lock(&(info->lock));
 
@@ -355,7 +354,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
                return;
        }
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        spin_lock_irqsave(&(info->lock), flags);
 
@@ -479,7 +478,7 @@ static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned lon
 static int btuart_open(btuart_info_t *info)
 {
        unsigned long flags;
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
        struct hci_dev *hdev;
 
        spin_lock_init(&(info->lock));
@@ -549,7 +548,7 @@ static int btuart_open(btuart_info_t *info)
 static int btuart_close(btuart_info_t *info)
 {
        unsigned long flags;
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
        struct hci_dev *hdev = info->hdev;
 
        if (!hdev)
@@ -587,8 +586,8 @@ static int btuart_probe(struct pcmcia_device *link)
        info->p_dev = link;
        link->priv = info;
 
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.NumPorts1 = 8;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[0]->end = 8;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -613,14 +612,14 @@ static int btuart_check_config(struct pcmcia_device *p_dev,
 {
        int *try = priv_data;
 
+       p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+
        if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
                p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
        if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
            (cf->io.win[0].base != 0)) {
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               p_dev->io.IOAddrLines = (*try == 0) ? 16 :
-                       cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               p_dev->resource[0]->start = cf->io.win[0].base;
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        }
        return -ENODEV;
@@ -637,9 +636,9 @@ static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
 
        if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
                for (j = 0; j < 5; j++) {
-                       p_dev->io.BasePort1 = base[j];
-                       p_dev->io.IOAddrLines = base[j] ? 16 : 3;
-                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       p_dev->resource[0]->start = base[j];
+                       p_dev->io_lines = base[j] ? 16 : 3;
+                       if (!pcmcia_request_io(p_dev))
                                return 0;
                }
        }
index cbe9e44a42e96d44bfb4224d284838f90b919060..db7c8db695fc643cff089670b721ef801dd14090 100644 (file)
@@ -41,7 +41,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -150,7 +149,7 @@ static void dtl1_write_wakeup(dtl1_info_t *info)
        }
 
        do {
-               register unsigned int iobase = info->p_dev->io.BasePort1;
+               register unsigned int iobase = info->p_dev->resource[0]->start;
                register struct sk_buff *skb;
                register int len;
 
@@ -215,7 +214,7 @@ static void dtl1_receive(dtl1_info_t *info)
                return;
        }
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        do {
                info->hdev->stat.byte_rx++;
@@ -302,7 +301,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
                /* our irq handler is shared */
                return IRQ_NONE;
 
-       iobase = info->p_dev->io.BasePort1;
+       iobase = info->p_dev->resource[0]->start;
 
        spin_lock(&(info->lock));
 
@@ -462,7 +461,7 @@ static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd,  unsigned long
 static int dtl1_open(dtl1_info_t *info)
 {
        unsigned long flags;
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
        struct hci_dev *hdev;
 
        spin_lock_init(&(info->lock));
@@ -509,7 +508,8 @@ static int dtl1_open(dtl1_info_t *info)
        outb(UART_LCR_WLEN8, iobase + UART_LCR);        /* Reset DLAB */
        outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
 
-       info->ri_latch = inb(info->p_dev->io.BasePort1 + UART_MSR) & UART_MSR_RI;
+       info->ri_latch = inb(info->p_dev->resource[0]->start + UART_MSR)
+                               & UART_MSR_RI;
 
        /* Turn on interrupts */
        outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
@@ -534,7 +534,7 @@ static int dtl1_open(dtl1_info_t *info)
 static int dtl1_close(dtl1_info_t *info)
 {
        unsigned long flags;
-       unsigned int iobase = info->p_dev->io.BasePort1;
+       unsigned int iobase = info->p_dev->resource[0]->start;
        struct hci_dev *hdev = info->hdev;
 
        if (!hdev)
@@ -572,8 +572,8 @@ static int dtl1_probe(struct pcmcia_device *link)
        info->p_dev = link;
        link->priv = info;
 
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.NumPorts1 = 8;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[0]->end = 8;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -597,14 +597,13 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev,
                          unsigned int vcc,
                          void *priv_data)
 {
-       if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               p_dev->io.NumPorts1 = cf->io.win[0].len;        /*yo */
-               p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
-                       return 0;
-       }
-       return -ENODEV;
+       if ((cf->io.nwin != 1) || (cf->io.win[0].len <= 8))
+               return -ENODEV;
+
+       p_dev->resource[0]->start = cf->io.win[0].base;
+       p_dev->resource[0]->end = cf->io.win[0].len;    /*yo */
+       p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
+       return pcmcia_request_io(p_dev);
 }
 
 static int dtl1_config(struct pcmcia_device *link)
@@ -613,7 +612,7 @@ static int dtl1_config(struct pcmcia_device *link)
        int i;
 
        /* Look for a generic full-sized window */
-       link->io.NumPorts1 = 8;
+       link->resource[0]->end = 8;
        if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0)
                goto failed;
 
index aa109cbe0e6e0c5e3884d84a24334c7a2da04a42..d607f53d8afcc7b3594c2629ab887b4ec5643b72 100644 (file)
@@ -371,6 +371,17 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
        bridge->dev = pdev;
        bridge->capndx = cap_ptr;
 
+       /*
+       * If the device has not been properly setup, the following will catch
+       * the problem and should stop the system from crashing.
+       * 20030610 - hamish@zot.org
+       */
+       if (pci_enable_device(pdev)) {
+               printk(KERN_ERR PFX "Unable to Enable PCI device\n");
+               agp_put_bridge(bridge);
+               return -ENODEV;
+       }
+
        /*
        * The following fixes the case where the BIOS has "forgotten" to
        * provide an address range for the GART.
@@ -385,17 +396,6 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
                }
        }
 
-       /*
-       * If the device has not been properly setup, the following will catch
-       * the problem and should stop the system from crashing.
-       * 20030610 - hamish@zot.org
-       */
-       if (pci_enable_device(pdev)) {
-               printk(KERN_ERR PFX "Unable to Enable PCI device\n");
-               agp_put_bridge(bridge);
-               return -ENODEV;
-       }
-
        /* Fill in the mode register */
        if (cap_ptr) {
                pci_read_config_dword(pdev,
index d836a71bf06db79f5df5b1fb1ddbd6b79e660081..ddf5def1b0da04632151fd20d43759d0f5a4f1ae 100644 (file)
@@ -816,9 +816,9 @@ static const struct intel_driver_description {
        { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG,
            "HD Graphics", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG,
-           "Sandybridge", NULL, &intel_i965_driver },
+           "Sandybridge", NULL, &intel_gen6_driver },
        { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG,
-           "Sandybridge", NULL, &intel_i965_driver },
+           "Sandybridge", NULL, &intel_gen6_driver },
        { 0, 0, NULL, NULL, NULL }
 };
 
@@ -907,6 +907,17 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
 
        dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
 
+       /*
+       * If the device has not been properly setup, the following will catch
+       * the problem and should stop the system from crashing.
+       * 20030610 - hamish@zot.org
+       */
+       if (pci_enable_device(pdev)) {
+               dev_err(&pdev->dev, "can't enable PCI device\n");
+               agp_put_bridge(bridge);
+               return -ENODEV;
+       }
+
        /*
        * The following fixes the case where the BIOS has "forgotten" to
        * provide an address range for the GART.
@@ -921,17 +932,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
                }
        }
 
-       /*
-       * If the device has not been properly setup, the following will catch
-       * the problem and should stop the system from crashing.
-       * 20030610 - hamish@zot.org
-       */
-       if (pci_enable_device(pdev)) {
-               dev_err(&pdev->dev, "can't enable PCI device\n");
-               agp_put_bridge(bridge);
-               return -ENODEV;
-       }
-
        /* Fill in the mode register */
        if (cap_ptr) {
                pci_read_config_dword(pdev,
index 2547465d46584e15c8993086e2546f78872055de..c05e3e518268ac3cab497970f55371cc2c06acba 100644 (file)
 #define I810_PTE_LOCAL         0x00000002
 #define I810_PTE_VALID         0x00000001
 #define I830_PTE_SYSTEM_CACHED  0x00000006
+/* GT PTE cache control fields */
+#define GEN6_PTE_UNCACHED      0x00000002
+#define GEN6_PTE_LLC           0x00000004
+#define GEN6_PTE_LLC_MLC       0x00000006
+#define GEN6_PTE_GFDT          0x00000008
+
 #define I810_SMRAM_MISCC       0x70
 #define I810_GFX_MEM_WIN_SIZE  0x00010000
 #define I810_GFX_MEM_WIN_32M   0x00010000
index a7547150a705235f75f7949f89ebd99a8e3ba329..d22ffb811bf2cea4001a97d485327d668ff9d85a 100644 (file)
 #define USE_PCI_DMA_API 1
 #endif
 
+/* Max amount of stolen space, anything above will be returned to Linux */
+int intel_max_stolen = 32 * 1024 * 1024;
+EXPORT_SYMBOL(intel_max_stolen);
+
 static const struct aper_size_info_fixed intel_i810_sizes[] =
 {
        {64, 16384, 4},
@@ -104,7 +108,7 @@ static int intel_agp_map_memory(struct agp_memory *mem)
        DBG("try mapping %lu pages\n", (unsigned long)mem->page_count);
 
        if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL))
-               return -ENOMEM;
+               goto err;
 
        mem->sg_list = sg = st.sgl;
 
@@ -113,11 +117,14 @@ static int intel_agp_map_memory(struct agp_memory *mem)
 
        mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list,
                                 mem->page_count, PCI_DMA_BIDIRECTIONAL);
-       if (unlikely(!mem->num_sg)) {
-               intel_agp_free_sglist(mem);
-               return -ENOMEM;
-       }
+       if (unlikely(!mem->num_sg))
+               goto err;
+
        return 0;
+
+err:
+       sg_free_table(&st);
+       return -ENOMEM;
 }
 
 static void intel_agp_unmap_memory(struct agp_memory *mem)
@@ -176,7 +183,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
        if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
            agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
        {
-               cache_bits = I830_PTE_SYSTEM_CACHED;
+               cache_bits = GEN6_PTE_LLC_MLC;
        }
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
@@ -710,7 +717,12 @@ static void intel_i830_init_gtt_entries(void)
                        break;
                }
        }
-       if (gtt_entries > 0) {
+       if (!local && gtt_entries > intel_max_stolen) {
+               dev_info(&agp_bridge->dev->dev,
+                        "detected %dK stolen memory, trimming to %dK\n",
+                        gtt_entries / KB(1), intel_max_stolen / KB(1));
+               gtt_entries = intel_max_stolen / KB(4);
+       } else if (gtt_entries > 0) {
                dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n",
                       gtt_entries / KB(1), local ? "local" : "stolen");
                gtt_entries /= KB(4);
@@ -797,6 +809,10 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
 
        /* we have to call this as early as possible after the MMIO base address is known */
        intel_i830_init_gtt_entries();
+       if (intel_private.gtt_entries == 0) {
+               iounmap(intel_private.registers);
+               return -ENOMEM;
+       }
 
        agp_bridge->gatt_table = NULL;
 
@@ -1282,6 +1298,11 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
 
        /* we have to call this as early as possible after the MMIO base address is known */
        intel_i830_init_gtt_entries();
+       if (intel_private.gtt_entries == 0) {
+               iounmap(intel_private.gtt);
+               iounmap(intel_private.registers);
+               return -ENOMEM;
+       }
 
        agp_bridge->gatt_table = NULL;
 
@@ -1309,6 +1330,16 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
        return addr | bridge->driver->masks[type].mask;
 }
 
+static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge,
+                                           dma_addr_t addr, int type)
+{
+       /* Shift high bits down */
+       addr |= (addr >> 28) & 0xff;
+
+       /* Type checking must be done elsewhere */
+       return addr | bridge->driver->masks[type].mask;
+}
+
 static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
 {
        u16 snb_gmch_ctl;
@@ -1390,6 +1421,11 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
 
        /* we have to call this as early as possible after the MMIO base address is known */
        intel_i830_init_gtt_entries();
+       if (intel_private.gtt_entries == 0) {
+               iounmap(intel_private.gtt);
+               iounmap(intel_private.registers);
+               return -ENOMEM;
+       }
 
        agp_bridge->gatt_table = NULL;
 
@@ -1517,6 +1553,39 @@ static const struct agp_bridge_driver intel_i965_driver = {
 #endif
 };
 
+static const struct agp_bridge_driver intel_gen6_driver = {
+       .owner                  = THIS_MODULE,
+       .aperture_sizes         = intel_i830_sizes,
+       .size_type              = FIXED_APER_SIZE,
+       .num_aperture_sizes     = 4,
+       .needs_scratch_page     = true,
+       .configure              = intel_i9xx_configure,
+       .fetch_size             = intel_i9xx_fetch_size,
+       .cleanup                = intel_i915_cleanup,
+       .mask_memory            = intel_gen6_mask_memory,
+       .masks                  = intel_i810_masks,
+       .agp_enable             = intel_i810_agp_enable,
+       .cache_flush            = global_cache_flush,
+       .create_gatt_table      = intel_i965_create_gatt_table,
+       .free_gatt_table        = intel_i830_free_gatt_table,
+       .insert_memory          = intel_i915_insert_entries,
+       .remove_memory          = intel_i915_remove_entries,
+       .alloc_by_type          = intel_i830_alloc_by_type,
+       .free_by_type           = intel_i810_free_by_type,
+       .agp_alloc_page         = agp_generic_alloc_page,
+       .agp_alloc_pages        = agp_generic_alloc_pages,
+       .agp_destroy_page       = agp_generic_destroy_page,
+       .agp_destroy_pages      = agp_generic_destroy_pages,
+       .agp_type_to_mask_type  = intel_i830_type_to_mask_type,
+       .chipset_flush          = intel_i915_chipset_flush,
+#ifdef USE_PCI_DMA_API
+       .agp_map_page           = intel_agp_map_page,
+       .agp_unmap_page         = intel_agp_unmap_page,
+       .agp_map_memory         = intel_agp_map_memory,
+       .agp_unmap_memory       = intel_agp_unmap_memory,
+#endif
+};
+
 static const struct agp_bridge_driver intel_g33_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_i830_sizes,
index 89d871ef8c2f814dbaecc390bd47fa34ad14574c..91917133ae0ad7de08d58a9379e943c9ecef2988 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/cdev.h>
 #include <linux/list.h>
index 101d5f2355470b8e62b148cefd27e70807bd33e1..7a4f080f8356e7657375debd0a0e9cf7c8b15a6e 100644 (file)
@@ -762,12 +762,12 @@ static struct of_platform_driver n2rng_driver = {
 
 static int __init n2rng_init(void)
 {
-       return of_register_driver(&n2rng_driver, &of_bus_type);
+       return of_register_platform_driver(&n2rng_driver);
 }
 
 static void __exit n2rng_exit(void)
 {
-       of_unregister_driver(&n2rng_driver);
+       of_unregister_platform_driver(&n2rng_driver);
 }
 
 module_init(n2rng_init);
index f54dab8acdcd6561c742b0541afdae3828dedfd9..a398ecdbd758058104e81223f1cbdfe7057e9a4b 100644 (file)
@@ -916,7 +916,7 @@ static int __init chr_dev_init(void)
                              NULL, devlist[minor].name);
        }
 
-       return 0;
+       return tty_init();
 }
 
 fs_initcall(chr_dev_init);
index e7956acf2ad618d6878c5df423827d26aeb06814..ec73d9f6d9ed92c9fa527718ff44871bd7d64669 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -422,7 +421,7 @@ static struct card_fixup card_fixups[] = {
 static void set_cardparameter(struct cm4000_dev *dev)
 {
        int i;
-       unsigned int iobase = dev->p_dev->io.BasePort1;
+       unsigned int iobase = dev->p_dev->resource[0]->start;
        u_int8_t stopbits = 0x02; /* ISO default */
 
        DEBUGP(3, dev, "-> set_cardparameter\n");
@@ -455,7 +454,7 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
        unsigned short num_bytes_read;
        unsigned char pts_reply[4];
        ssize_t rc;
-       unsigned int iobase = dev->p_dev->io.BasePort1;
+       unsigned int iobase = dev->p_dev->resource[0]->start;
 
        rc = 0;
 
@@ -664,7 +663,7 @@ static void terminate_monitor(struct cm4000_dev *dev)
 static void monitor_card(unsigned long p)
 {
        struct cm4000_dev *dev = (struct cm4000_dev *) p;
-       unsigned int iobase = dev->p_dev->io.BasePort1;
+       unsigned int iobase = dev->p_dev->resource[0]->start;
        unsigned short s;
        struct ptsreq ptsreq;
        int i, atrc;
@@ -925,7 +924,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
                        loff_t *ppos)
 {
        struct cm4000_dev *dev = filp->private_data;
-       unsigned int iobase = dev->p_dev->io.BasePort1;
+       unsigned int iobase = dev->p_dev->resource[0]->start;
        ssize_t rc;
        int i, j, k;
 
@@ -1048,7 +1047,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf,
                         size_t count, loff_t *ppos)
 {
        struct cm4000_dev *dev = filp->private_data;
-       unsigned int iobase = dev->p_dev->io.BasePort1;
+       unsigned int iobase = dev->p_dev->resource[0]->start;
        unsigned short s;
        unsigned char tmp;
        unsigned char infolen;
@@ -1401,7 +1400,7 @@ static void stop_monitor(struct cm4000_dev *dev)
 static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct cm4000_dev *dev = filp->private_data;
-       unsigned int iobase = dev->p_dev->io.BasePort1;
+       unsigned int iobase = dev->p_dev->resource[0]->start;
        struct inode *inode = filp->f_path.dentry->d_inode;
        struct pcmcia_device *link;
        int size;
@@ -1752,17 +1751,12 @@ static int cm4000_config_check(struct pcmcia_device *p_dev,
        if (!cfg->io.nwin)
                return -ENODEV;
 
-       /* Get the IOaddr */
-       p_dev->io.BasePort1 = cfg->io.win[0].base;
-       p_dev->io.NumPorts1 = cfg->io.win[0].len;
-       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       if (!(cfg->io.flags & CISTPL_IO_8BIT))
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-       if (!(cfg->io.flags & CISTPL_IO_16BIT))
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
-
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
+       p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
+       p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+
+       return pcmcia_request_io(p_dev);
 }
 
 static int cm4000_config(struct pcmcia_device * link, int devno)
index c0775c844e08f48095646d23f80bea7d9d04242f..815cde1d0570e86d4ba0e8970ef60248997a3302 100644 (file)
@@ -29,7 +29,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -110,7 +109,7 @@ static inline unsigned char xinb(unsigned short port)
 static void cm4040_do_poll(unsigned long dummy)
 {
        struct reader_dev *dev = (struct reader_dev *) dummy;
-       unsigned int obs = xinb(dev->p_dev->io.BasePort1
+       unsigned int obs = xinb(dev->p_dev->resource[0]->start
                                + REG_OFFSET_BUFFER_STATUS);
 
        if ((obs & BSR_BULK_IN_FULL)) {
@@ -141,7 +140,7 @@ static void cm4040_stop_poll(struct reader_dev *dev)
 static int wait_for_bulk_out_ready(struct reader_dev *dev)
 {
        int i, rc;
-       int iobase = dev->p_dev->io.BasePort1;
+       int iobase = dev->p_dev->resource[0]->start;
 
        for (i = 0; i < POLL_LOOP_COUNT; i++) {
                if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
@@ -171,7 +170,7 @@ static int wait_for_bulk_out_ready(struct reader_dev *dev)
 /* Write to Sync Control Register */
 static int write_sync_reg(unsigned char val, struct reader_dev *dev)
 {
-       int iobase = dev->p_dev->io.BasePort1;
+       int iobase = dev->p_dev->resource[0]->start;
        int rc;
 
        rc = wait_for_bulk_out_ready(dev);
@@ -189,7 +188,7 @@ static int write_sync_reg(unsigned char val, struct reader_dev *dev)
 static int wait_for_bulk_in_ready(struct reader_dev *dev)
 {
        int i, rc;
-       int iobase = dev->p_dev->io.BasePort1;
+       int iobase = dev->p_dev->resource[0]->start;
 
        for (i = 0; i < POLL_LOOP_COUNT; i++) {
                if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
@@ -219,7 +218,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
                        size_t count, loff_t *ppos)
 {
        struct reader_dev *dev = filp->private_data;
-       int iobase = dev->p_dev->io.BasePort1;
+       int iobase = dev->p_dev->resource[0]->start;
        size_t bytes_to_read;
        unsigned long i;
        size_t min_bytes_to_read;
@@ -321,7 +320,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf,
                         size_t count, loff_t *ppos)
 {
        struct reader_dev *dev = filp->private_data;
-       int iobase = dev->p_dev->io.BasePort1;
+       int iobase = dev->p_dev->resource[0]->start;
        ssize_t rc;
        int i;
        unsigned int bytes_to_write;
@@ -528,16 +527,12 @@ static int cm4040_config_check(struct pcmcia_device *p_dev,
                return -ENODEV;
 
        /* Get the IOaddr */
-       p_dev->io.BasePort1 = cfg->io.win[0].base;
-       p_dev->io.NumPorts1 = cfg->io.win[0].len;
-       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       if (!(cfg->io.flags & CISTPL_IO_8BIT))
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-       if (!(cfg->io.flags & CISTPL_IO_16BIT))
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
-
-       rc = pcmcia_request_io(p_dev, &p_dev->io);
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
+       p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
+       p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+       rc = pcmcia_request_io(p_dev);
+
        dev_printk(KERN_INFO, &p_dev->dev,
                   "pcmcia_request_io returned 0x%x\n", rc);
        return rc;
@@ -549,10 +544,6 @@ static int reader_config(struct pcmcia_device *link, int devno)
        struct reader_dev *dev;
        int fail_rc;
 
-       link->io.BasePort2 = 0;
-       link->io.NumPorts2 = 0;
-       link->io.Attributes2 = 0;
-
        if (pcmcia_loop_config(link, cm4040_config_check, NULL))
                goto cs_release;
 
@@ -568,8 +559,8 @@ static int reader_config(struct pcmcia_device *link, int devno)
 
        dev = link->priv;
 
-       DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
-             link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);
+       DEBUGP(2, dev, "device " DEVICE_NAME "%d at %pR\n", devno,
+             link->resource[0]);
        DEBUGP(2, dev, "<- reader_config (succ)\n");
 
        return 0;
index 63c32e3f23ba811fac644b38506c1ebe83bbd71a..67bdb05798b1943c8c2242f85494f70c6e2c7e3c 100644 (file)
@@ -84,23 +84,22 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
 {
        struct ipw_dev *ipw = priv_data;
        struct resource *io_resource;
-       memreq_t memreq_attr_memory;
-       memreq_t memreq_common_memory;
        int ret;
 
-       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       p_dev->io.BasePort1 = cfg->io.win[0].base;
-       p_dev->io.NumPorts1 = cfg->io.win[0].len;
-       p_dev->io.IOAddrLines = 16;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
 
        /* 0x40 causes it to generate level mode interrupts. */
        /* 0x04 enables IREQ pin. */
        p_dev->conf.ConfigIndex = cfg->index | 0x44;
-       ret = pcmcia_request_io(p_dev, &p_dev->io);
+       p_dev->io_lines = 16;
+       ret = pcmcia_request_io(p_dev);
        if (ret)
                return ret;
 
-       io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1,
+       io_resource = request_region(p_dev->resource[0]->start,
+                               resource_size(p_dev->resource[0]),
                                IPWIRELESS_PCCARD_NAME);
 
        if (cfg->mem.nwin == 0)
@@ -120,11 +119,8 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
        if (ret != 0)
                goto exit1;
 
-       memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr;
-       memreq_common_memory.Page = 0;
-
        ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory,
-                               &memreq_common_memory);
+                               cfg->mem.win[0].card_addr);
 
        if (ret != 0)
                goto exit2;
@@ -149,12 +145,7 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
        if (ret != 0)
                goto exit2;
 
-       memreq_attr_memory.CardOffset = 0;
-       memreq_attr_memory.Page = 0;
-
-       ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory,
-                               &memreq_attr_memory);
-
+       ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory, 0);
        if (ret != 0)
                goto exit3;
 
@@ -166,15 +157,12 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
        return 0;
 
 exit3:
-       pcmcia_release_window(p_dev, ipw->handle_attr_memory);
 exit2:
        if (ipw->common_memory) {
                release_mem_region(ipw->request_common_memory.Base,
                                ipw->request_common_memory.Size);
                iounmap(ipw->common_memory);
-               pcmcia_release_window(p_dev, ipw->handle_common_memory);
-       } else
-               pcmcia_release_window(p_dev, ipw->handle_common_memory);
+       }
 exit1:
        release_resource(io_resource);
        pcmcia_disable_device(p_dev);
@@ -197,7 +185,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
 
        INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
 
-       ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1,
+       ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start,
                                    ipw->attr_memory, ipw->common_memory,
                                    ipw->is_v2_card, signalled_reboot_callback,
                                    ipw);
@@ -209,10 +197,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
        printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
                        ipw->is_v2_card ? "V2/V3" : "V1");
        printk(KERN_INFO IPWIRELESS_PCCARD_NAME
-                       ": I/O ports 0x%04x-0x%04x, irq %d\n",
-                       (unsigned int) link->io.BasePort1,
-                       (unsigned int) (link->io.BasePort1 +
-                               link->io.NumPorts1 - 1),
+               ": I/O ports %pR, irq %d\n", link->resource[0],
                        (unsigned int) link->irq);
        if (ipw->attr_memory && ipw->common_memory)
                printk(KERN_INFO IPWIRELESS_PCCARD_NAME
@@ -250,13 +235,12 @@ exit:
                release_mem_region(ipw->request_attr_memory.Base,
                                ipw->request_attr_memory.Size);
                iounmap(ipw->attr_memory);
-               pcmcia_release_window(link, ipw->handle_attr_memory);
+
        }
        if (ipw->common_memory) {
                release_mem_region(ipw->request_common_memory.Base,
                                ipw->request_common_memory.Size);
                iounmap(ipw->common_memory);
-               pcmcia_release_window(link, ipw->handle_common_memory);
        }
        pcmcia_disable_device(link);
        return -1;
@@ -274,11 +258,6 @@ static void release_ipwireless(struct ipw_dev *ipw)
                                ipw->request_attr_memory.Size);
                iounmap(ipw->attr_memory);
        }
-       if (ipw->common_memory)
-               pcmcia_release_window(ipw->link, ipw->handle_common_memory);
-       if (ipw->attr_memory)
-               pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
-
        pcmcia_disable_device(ipw->link);
 }
 
index 96d0ef31b1720b35eb666894838576c1dd68d57e..c207be87b597fe3cecfec61da71d8fdf3386b36f 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <linux/types.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index 4da6c201f7274aaa78409f47011719f649d92a83..3e163d4cab15b034d14153d5dcb2d1f6bdeae36e 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index 308903ec8bf8464187e22ba14cc39ffe988dc4d0..9ecd6bef5d3b5457ec5bcc6566db7621c1d791f3 100644 (file)
@@ -70,7 +70,6 @@
 #include <linux/workqueue.h>
 #include <linux/hdlc.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -572,18 +571,15 @@ static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
                          unsigned int vcc,
                          void *priv_data)
 {
-       if (cfg->io.nwin > 0) {
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(cfg->io.flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(cfg->io.flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = cfg->io.win[0].base;
-               p_dev->io.NumPorts1 = cfg->io.win[0].len;
-               return pcmcia_request_io(p_dev, &p_dev->io);
-       }
-       return -ENODEV;
+       if (!cfg->io.nwin)
+               return -ENODEV;
+
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
+       p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
+       p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+
+       return pcmcia_request_io(p_dev);
 }
 
 static int mgslpc_config(struct pcmcia_device *link)
@@ -610,16 +606,15 @@ static int mgslpc_config(struct pcmcia_device *link)
     if (ret)
            goto failed;
 
-    info->io_base = link->io.BasePort1;
+    info->io_base = link->resource[0]->start;
     info->irq_level = link->irq;
 
     dev_info(&link->dev, "index 0x%02x:",
            link->conf.ConfigIndex);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
            printk(", irq %d", link->irq);
-    if (link->io.NumPorts1)
-           printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                  link->io.BasePort1+link->io.NumPorts1-1);
+    if (link->resource[0])
+           printk(", io %pR", link->resource[0]);
     printk("\n");
     return 0;
 
index d71f0fc34b467c6e7a7c25c0762321f90b7e3fa0..507441ac6edbcdb9c8fcb58da5d0ba34383eadbc 100644 (file)
@@ -3128,7 +3128,7 @@ static struct cdev tty_cdev, console_cdev;
  * Ok, now we can initialize the rest of the tty devices and can count
  * on memory allocations, interrupts etc..
  */
-static int __init tty_init(void)
+int __init tty_init(void)
 {
        cdev_init(&tty_cdev, &tty_fops);
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
@@ -3149,4 +3149,4 @@ static int __init tty_init(void)
 #endif
        return 0;
 }
-module_init(tty_init);
+
index 7cdb6ee569cd7ca592bedfea458f0b676ec937af..4a9eb3044e52c068641d1a3ddccd3682fdf228c3 100644 (file)
 #include <linux/io.h>
 #include <asm/system.h>
 #include <linux/uaccess.h>
+#include <linux/kdb.h>
 
 #define MAX_NR_CON_DRIVER 16
 
@@ -187,10 +188,15 @@ static DECLARE_WORK(console_work, console_callback);
  * fg_console is the current virtual console,
  * last_console is the last used one,
  * want_console is the console we want to switch to,
+ * saved_* variants are for save/restore around kernel debugger enter/leave
  */
 int fg_console;
 int last_console;
 int want_console = -1;
+int saved_fg_console;
+int saved_last_console;
+int saved_want_console;
+int saved_vc_mode;
 
 /*
  * For each existing display, we have a pointer to console currently visible
@@ -3413,6 +3419,78 @@ int con_is_bound(const struct consw *csw)
 }
 EXPORT_SYMBOL(con_is_bound);
 
+/**
+ * con_debug_enter - prepare the console for the kernel debugger
+ * @sw: console driver
+ *
+ * Called when the console is taken over by the kernel debugger, this
+ * function needs to save the current console state, then put the console
+ * into a state suitable for the kernel debugger.
+ *
+ * RETURNS:
+ * Zero on success, nonzero if a failure occurred when trying to prepare
+ * the console for the debugger.
+ */
+int con_debug_enter(struct vc_data *vc)
+{
+       int ret = 0;
+
+       saved_fg_console = fg_console;
+       saved_last_console = last_console;
+       saved_want_console = want_console;
+       saved_vc_mode = vc->vc_mode;
+       vc->vc_mode = KD_TEXT;
+       console_blanked = 0;
+       if (vc->vc_sw->con_debug_enter)
+               ret = vc->vc_sw->con_debug_enter(vc);
+#ifdef CONFIG_KGDB_KDB
+       /* Set the initial LINES variable if it is not already set */
+       if (vc->vc_rows < 999) {
+               int linecount;
+               char lns[4];
+               const char *setargs[3] = {
+                       "set",
+                       "LINES",
+                       lns,
+               };
+               if (kdbgetintenv(setargs[0], &linecount)) {
+                       snprintf(lns, 4, "%i", vc->vc_rows);
+                       kdb_set(2, setargs);
+               }
+       }
+#endif /* CONFIG_KGDB_KDB */
+       return ret;
+}
+EXPORT_SYMBOL_GPL(con_debug_enter);
+
+/**
+ * con_debug_leave - restore console state
+ * @sw: console driver
+ *
+ * Restore the console state to what it was before the kernel debugger
+ * was invoked.
+ *
+ * RETURNS:
+ * Zero on success, nonzero if a failure occurred when trying to restore
+ * the console.
+ */
+int con_debug_leave(void)
+{
+       struct vc_data *vc;
+       int ret = 0;
+
+       fg_console = saved_fg_console;
+       last_console = saved_last_console;
+       want_console = saved_want_console;
+       vc_cons[fg_console].d->vc_mode = saved_vc_mode;
+
+       vc = vc_cons[fg_console].d;
+       if (vc->vc_sw->con_debug_leave)
+               ret = vc->vc_sw->con_debug_leave(vc);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(con_debug_leave);
+
 /**
  * register_con_driver - register console driver to console layer
  * @csw: console driver
index 72a633a6ec982e74153235e8f015ddba65d84af4..cfb0f5278415a2d371f2a6902ec0670183f6bc10 100644 (file)
@@ -68,10 +68,7 @@ static struct clocksource clocksource_acpi_pm = {
        .rating         = 200,
        .read           = acpi_pm_read,
        .mask           = (cycle_t)ACPI_PM_MASK,
-       .mult           = 0, /*to be calculated*/
-       .shift          = 22,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-
 };
 
 
@@ -190,9 +187,6 @@ static int __init init_acpi_pm_clocksource(void)
        if (!pmtmr_ioport)
                return -ENODEV;
 
-       clocksource_acpi_pm.mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC,
-                                               clocksource_acpi_pm.shift);
-
        /* "verify" this timing source: */
        for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
                udelay(100 * j);
@@ -220,7 +214,8 @@ static int __init init_acpi_pm_clocksource(void)
        if (verify_pmtmr_rate() != 0)
                return -ENODEV;
 
-       return clocksource_register(&clocksource_acpi_pm);
+       return clocksource_register_hz(&clocksource_acpi_pm,
+                                               PMTMR_TICKS_PER_SEC);
 }
 
 /* We use fs_initcall because we want the PCI fixups to have run
index b99c38f23d6137337a7c4f49270a31fd9fa1de36..26af2dd5d8316e73cf95f966aa215ae7ebb1dd37 100644 (file)
@@ -2247,20 +2247,20 @@ static struct of_platform_driver n2_mau_driver = {
 
 static int __init n2_init(void)
 {
-       int err = of_register_driver(&n2_crypto_driver, &of_bus_type);
+       int err = of_register_platform_driver(&n2_crypto_driver);
 
        if (!err) {
-               err = of_register_driver(&n2_mau_driver, &of_bus_type);
+               err = of_register_platform_driver(&n2_mau_driver);
                if (err)
-                       of_unregister_driver(&n2_crypto_driver);
+                       of_unregister_platform_driver(&n2_crypto_driver);
        }
        return err;
 }
 
 static void __exit n2_exit(void)
 {
-       of_unregister_driver(&n2_mau_driver);
-       of_unregister_driver(&n2_crypto_driver);
+       of_unregister_platform_driver(&n2_mau_driver);
+       of_unregister_platform_driver(&n2_crypto_driver);
 }
 
 module_init(n2_init);
index aa9bc9e980e1b8a3bbdbe189c16aef8545886fe6..69ad529d92fbb83d56694402710eebe1941391e8 100644 (file)
@@ -634,9 +634,6 @@ static void __exit dcdbas_exit(void)
         * before platform_device_unregister
         */
        unregister_reboot_notifier(&dcdbas_reboot_nb);
-       smi_data_buf_free();
-       platform_device_unregister(dcdbas_pdev);
-       platform_driver_unregister(&dcdbas_driver);
 
        /*
         * We have to free the buffer here instead of dcdbas_remove
@@ -645,6 +642,8 @@ static void __exit dcdbas_exit(void)
         * released.
         */
        smi_data_buf_free();
+       platform_device_unregister(dcdbas_pdev);
+       platform_driver_unregister(&dcdbas_driver);
 }
 
 module_init(dcdbas_init);
index a777a35381d2ca80ac0dd8846d860d650ef7bf00..94a58a082b9930a2acc05192273c6941ef003ef6 100644 (file)
@@ -229,10 +229,12 @@ static int __init dmi_id_init(void)
 
        ret = device_register(dmi_dev);
        if (ret)
-               goto fail_class_unregister;
+               goto fail_free_dmi_dev;
 
        return 0;
 
+fail_free_dmi_dev:
+       kfree(dmi_dev);
 fail_class_unregister:
 
        class_unregister(&dmi_class);
index d46467271349d79adbabd04a76bb55a7b7cff19f..b3d22d6599901756a694d8eac124cf0326eba399 100644 (file)
@@ -277,6 +277,29 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm)
        list_add_tail(&dev->list, &dmi_devices);
 }
 
+static void __init dmi_save_dev_onboard(int instance, int segment, int bus,
+                                       int devfn, const char *name)
+{
+       struct dmi_dev_onboard *onboard_dev;
+
+       onboard_dev = dmi_alloc(sizeof(*onboard_dev) + strlen(name) + 1);
+       if (!onboard_dev) {
+               printk(KERN_ERR "dmi_save_dev_onboard: out of memory.\n");
+               return;
+       }
+       onboard_dev->instance = instance;
+       onboard_dev->segment = segment;
+       onboard_dev->bus = bus;
+       onboard_dev->devfn = devfn;
+
+       strcpy((char *)&onboard_dev[1], name);
+       onboard_dev->dev.type = DMI_DEV_TYPE_DEV_ONBOARD;
+       onboard_dev->dev.name = (char *)&onboard_dev[1];
+       onboard_dev->dev.device_data = onboard_dev;
+
+       list_add(&onboard_dev->dev.list, &dmi_devices);
+}
+
 static void __init dmi_save_extended_devices(const struct dmi_header *dm)
 {
        const u8 *d = (u8*) dm + 5;
@@ -285,6 +308,8 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
        if ((*d & 0x80) == 0)
                return;
 
+       dmi_save_dev_onboard(*(d+1), *(u16 *)(d+2), *(d+4), *(d+5),
+                            dmi_string_nosave(dm, *(d-1)));
        dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
 }
 
index 4e51fe3c1fc4f97594d96fcb9a4e719fa40b8edc..6a6bd569e1f8c80851a553b9a4b1c98a76de9faa 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
 
@@ -1100,16 +1101,24 @@ int gpiochip_add(struct gpio_chip *chip)
                }
        }
 
+       of_gpiochip_add(chip);
+
 unlock:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status == 0)
-               status = gpiochip_export(chip);
+
+       if (status)
+               goto fail;
+
+       status = gpiochip_export(chip);
+       if (status)
+               goto fail;
+
+       return 0;
 fail:
        /* failures here can mean systems won't boot... */
-       if (status)
-               pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
-                       chip->base, chip->base + chip->ngpio - 1,
-                       chip->label ? : "generic");
+       pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
+               chip->base, chip->base + chip->ngpio - 1,
+               chip->label ? : "generic");
        return status;
 }
 EXPORT_SYMBOL_GPL(gpiochip_add);
@@ -1128,6 +1137,8 @@ int gpiochip_remove(struct gpio_chip *chip)
 
        spin_lock_irqsave(&gpio_lock, flags);
 
+       of_gpiochip_remove(chip);
+
        for (id = chip->base; id < chip->base + chip->ngpio; id++) {
                if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
                        status = -EBUSY;
@@ -1148,6 +1159,38 @@ int gpiochip_remove(struct gpio_chip *chip)
 }
 EXPORT_SYMBOL_GPL(gpiochip_remove);
 
+/**
+ * gpiochip_find() - iterator for locating a specific gpio_chip
+ * @data: data to pass to match function
+ * @callback: Callback function to check gpio_chip
+ *
+ * Similar to bus_find_device.  It returns a reference to a gpio_chip as
+ * determined by a user supplied @match callback.  The callback should return
+ * 0 if the device doesn't match and non-zero if it does.  If the callback is
+ * non-zero, this function will return to the caller and not iterate over any
+ * more gpio_chips.
+ */
+struct gpio_chip *gpiochip_find(void *data,
+                               int (*match)(struct gpio_chip *chip, void *data))
+{
+       struct gpio_chip *chip = NULL;
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+       for (i = 0; i < ARCH_NR_GPIOS; i++) {
+               if (!gpio_desc[i].chip)
+                       continue;
+
+               if (match(gpio_desc[i].chip, data)) {
+                       chip = gpio_desc[i].chip;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&gpio_lock, flags);
+
+       return chip;
+}
 
 /* These "optional" allocation calls help prevent drivers from stomping
  * on each other, and help provide better diagnostics in debugfs.
index b8fa65b5bfca56ca8320e23916d45dbc56a68b1c..709690995d0d729efd8994a342f06bc402fff0cd 100644 (file)
@@ -161,14 +161,12 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 static int __devinit xgpio_of_probe(struct device_node *np)
 {
        struct xgpio_instance *chip;
-       struct of_gpio_chip *ofchip;
        int status = 0;
        const u32 *tree_info;
 
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
-       ofchip = &chip->mmchip.of_gc;
 
        /* Update GPIO state shadow register with default value */
        tree_info = of_get_property(np, "xlnx,dout-default", NULL);
@@ -182,21 +180,20 @@ static int __devinit xgpio_of_probe(struct device_node *np)
                chip->gpio_dir = *tree_info;
 
        /* Check device node and parent device node for device width */
-       ofchip->gc.ngpio = 32; /* By default assume full GPIO controller */
+       chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */
        tree_info = of_get_property(np, "xlnx,gpio-width", NULL);
        if (!tree_info)
                tree_info = of_get_property(np->parent,
                                            "xlnx,gpio-width", NULL);
        if (tree_info)
-               ofchip->gc.ngpio = *tree_info;
+               chip->mmchip.gc.ngpio = *tree_info;
 
        spin_lock_init(&chip->gpio_lock);
 
-       ofchip->gpio_cells = 2;
-       ofchip->gc.direction_input = xgpio_dir_in;
-       ofchip->gc.direction_output = xgpio_dir_out;
-       ofchip->gc.get = xgpio_get;
-       ofchip->gc.set = xgpio_set;
+       chip->mmchip.gc.direction_input = xgpio_dir_in;
+       chip->mmchip.gc.direction_output = xgpio_dir_out;
+       chip->mmchip.gc.get = xgpio_get;
+       chip->mmchip.gc.set = xgpio_set;
 
        chip->mmchip.save_regs = xgpio_save_regs;
 
index 88910e5a2c77275654e8b431d96a93b07e438685..4cab0c6397e34654086f57433e1de471d1d87b30 100644 (file)
@@ -6,7 +6,7 @@
 #
 menuconfig DRM
        tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
-       depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU
+       depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
        select I2C
        select I2C_ALGOBIT
        select SLOW_WORK
@@ -17,7 +17,7 @@ menuconfig DRM
          These modules provide support for synchronization, security, and
          DMA transfers. Please see <http://dri.sourceforge.net/> for more
          details.  You should also select and configure AGP
-         (/dev/agpgart) support.
+         (/dev/agpgart) support if it is available for your platform.
 
 config DRM_KMS_HELPER
        tristate
@@ -61,6 +61,7 @@ config DRM_RADEON
         select DRM_KMS_HELPER
         select DRM_TTM
        select POWER_SUPPLY
+       select HWMON
        help
          Choose this option if you have an ATI Radeon graphics card.  There
          are both PCI and AGP versions.  You don't need to choose this to
@@ -130,7 +131,7 @@ endchoice
 
 config DRM_MGA
        tristate "Matrox g200/g400"
-       depends on DRM
+       depends on DRM && PCI
        select FW_LOADER
        help
          Choose this option if you have a Matrox G200, G400 or G450 graphics
@@ -148,14 +149,14 @@ config DRM_SIS
 
 config DRM_VIA
        tristate "Via unichrome video cards"
-       depends on DRM
+       depends on DRM && PCI
        help
          Choose this option if you have a Via unichrome or compatible video
          chipset. If M is selected the module will be called via.
 
 config DRM_SAVAGE
        tristate "Savage video cards"
-       depends on DRM
+       depends on DRM && PCI
        help
          Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
          chipset. If M is selected the module will be called savage.
index abe3f446ca48efe06d7896d00b4c347a2e6daead..f3a23a329f4e29e7817755bf7f9f367cbdd74d0a 100644 (file)
@@ -9,9 +9,10 @@ drm-y       := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
                drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
                drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
                drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
-               drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
+               drm_platform.o drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
                drm_crtc.o drm_modes.o drm_edid.o \
-               drm_info.o drm_debugfs.o drm_encoder_slave.o
+               drm_info.o drm_debugfs.o drm_encoder_slave.o \
+               drm_trace_points.o drm_global.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 
@@ -19,6 +20,8 @@ drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o
 
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
+CFLAGS_drm_trace_points.o := -I$(src)
+
 obj-$(CONFIG_DRM)      += drm.o
 obj-$(CONFIG_DRM_TTM)  += ttm/
 obj-$(CONFIG_DRM_TDFX) += tdfx/
index 2092e7bb788f90302ff226c69a383c1a6a5aea67..a5c9ce93bbcba1cf4d7390cfa3f7fe1c1e504078 100644 (file)
 #include <asm/shmparam.h>
 #include "drmP.h"
 
-resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource)
-{
-       return pci_resource_start(dev->pdev, resource);
-}
-EXPORT_SYMBOL(drm_get_resource_start);
-
-resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource)
-{
-       return pci_resource_len(dev->pdev, resource);
-}
-
-EXPORT_SYMBOL(drm_get_resource_len);
-
 static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
                                                  struct drm_local_map *map)
 {
@@ -189,7 +176,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
        switch (map->type) {
        case _DRM_REGISTERS:
        case _DRM_FRAME_BUFFER:
-#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
+#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__)
                if (map->offset + (map->size-1) < map->offset ||
                    map->offset < virt_to_phys(high_memory)) {
                        kfree(map);
index 57cea01c4ffb25cb62b7b46007853c506a5c15a3..4c68f76993d8eee831717b7939ccd8af1c59d76b 100644 (file)
@@ -80,6 +80,7 @@ static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
 {
        { DRM_MODE_DITHERING_OFF, "Off" },
        { DRM_MODE_DITHERING_ON, "On" },
+       { DRM_MODE_DITHERING_AUTO, "Automatic" },
 };
 
 /*
@@ -1126,7 +1127,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
                        list_for_each_entry(crtc, &dev->mode_config.crtc_list,
                                            head) {
-                               DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
+                               DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
                                if (put_user(crtc->base.id, crtc_id + copied)) {
                                        ret = -EFAULT;
                                        goto out;
@@ -1154,8 +1155,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                        list_for_each_entry(encoder,
                                            &dev->mode_config.encoder_list,
                                            head) {
-                               DRM_DEBUG_KMS("ENCODER ID is %d\n",
-                                         encoder->base.id);
+                               DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
+                                               drm_get_encoder_name(encoder));
                                if (put_user(encoder->base.id, encoder_id +
                                             copied)) {
                                        ret = -EFAULT;
@@ -1185,8 +1186,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                        list_for_each_entry(connector,
                                            &dev->mode_config.connector_list,
                                            head) {
-                               DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
-                                         connector->base.id);
+                               DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+                                       connector->base.id,
+                                       drm_get_connector_name(connector));
                                if (put_user(connector->base.id,
                                             connector_id + copied)) {
                                        ret = -EFAULT;
@@ -1209,7 +1211,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
        }
        card_res->count_connectors = connector_count;
 
-       DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
+       DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
                  card_res->count_connectors, card_res->count_encoders);
 
 out:
@@ -1312,7 +1314,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 
        memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
 
-       DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id);
+       DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
 
        mutex_lock(&dev->mode_config.mutex);
 
@@ -1493,6 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
                goto out;
        }
        crtc = obj_to_crtc(obj);
+       DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
        if (crtc_req->mode_valid) {
                /* If we have a mode we need a framebuffer. */
@@ -1569,6 +1572,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
                                goto out;
                        }
                        connector = obj_to_connector(obj);
+                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+                                       connector->base.id,
+                                       drm_get_connector_name(connector));
 
                        connector_set[i] = connector;
                }
@@ -1684,6 +1690,7 @@ int drm_mode_addfb(struct drm_device *dev,
 
        r->fb_id = fb->base.id;
        list_add(&fb->filp_head, &file_priv->fbs);
+       DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
 
 out:
        mutex_unlock(&dev->mode_config.mutex);
@@ -2610,6 +2617,15 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
                goto out;
        crtc = obj_to_crtc(obj);
 
+       if (crtc->fb == NULL) {
+               /* The framebuffer is currently unbound, presumably
+                * due to a hotplug event, that userspace has not
+                * yet discovered.
+                */
+               ret = -EBUSY;
+               goto out;
+       }
+
        if (crtc->funcs->page_flip == NULL)
                goto out;
 
index 9b2a54117c91c0a306c41c7eb437b641bbd58b31..45981304feb810c3d1cb1a68f07fce6640b5e0a0 100644 (file)
@@ -86,7 +86,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
        int count = 0;
        int mode_flags = 0;
 
-       DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector));
+       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
+                       drm_get_connector_name(connector));
        /* set all modes to the unverified state */
        list_for_each_entry_safe(mode, t, &connector->modes, head)
                mode->status = MODE_UNVERIFIED;
@@ -102,8 +103,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
                connector->status = connector->funcs->detect(connector);
 
        if (connector->status == connector_status_disconnected) {
-               DRM_DEBUG_KMS("%s is disconnected\n",
-                         drm_get_connector_name(connector));
+               DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
+                       connector->base.id, drm_get_connector_name(connector));
                drm_mode_connector_update_edid_property(connector, NULL);
                goto prune;
        }
@@ -141,8 +142,8 @@ prune:
 
        drm_mode_sort(&connector->modes);
 
-       DRM_DEBUG_KMS("Probed modes for %s\n",
-                               drm_get_connector_name(connector));
+       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
+                       drm_get_connector_name(connector));
        list_for_each_entry_safe(mode, t, &connector->modes, head) {
                mode->vrefresh = drm_mode_vrefresh(mode);
 
@@ -201,6 +202,17 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_helper_crtc_in_use);
 
+static void
+drm_encoder_disable(struct drm_encoder *encoder)
+{
+       struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+
+       if (encoder_funcs->disable)
+               (*encoder_funcs->disable)(encoder);
+       else
+               (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+}
+
 /**
  * drm_helper_disable_unused_functions - disable unused objects
  * @dev: DRM device
@@ -215,7 +227,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
 {
        struct drm_encoder *encoder;
        struct drm_connector *connector;
-       struct drm_encoder_helper_funcs *encoder_funcs;
        struct drm_crtc *crtc;
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -226,12 +237,8 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
        }
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               encoder_funcs = encoder->helper_private;
                if (!drm_helper_encoder_in_use(encoder)) {
-                       if (encoder_funcs->disable)
-                               (*encoder_funcs->disable)(encoder);
-                       else
-                               (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+                       drm_encoder_disable(encoder);
                        /* disconnector encoder from any connector */
                        encoder->crtc = NULL;
                }
@@ -241,7 +248,10 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
                struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
                crtc->enabled = drm_helper_crtc_in_use(crtc);
                if (!crtc->enabled) {
-                       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+                       if (crtc_funcs->disable)
+                               (*crtc_funcs->disable)(crtc);
+                       else
+                               (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
                        crtc->fb = NULL;
                }
        }
@@ -292,11 +302,11 @@ drm_crtc_prepare_encoders(struct drm_device *dev)
                encoder_funcs = encoder->helper_private;
                /* Disable unused encoders */
                if (encoder->crtc == NULL)
-                       (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+                       drm_encoder_disable(encoder);
                /* Disable encoders whose CRTC is about to change */
                if (encoder_funcs->get_crtc &&
                    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
-                       (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+                       drm_encoder_disable(encoder);
        }
 }
 
@@ -365,6 +375,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
        if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
                goto done;
        }
+       DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
        /* Prepare the encoders and CRTCs before setting the mode. */
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -392,8 +403,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
                if (encoder->crtc != crtc)
                        continue;
 
-               DRM_DEBUG("%s: set mode %s %x\n", drm_get_encoder_name(encoder),
-                        mode->name, mode->base.id);
+               DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
+                       encoder->base.id, drm_get_encoder_name(encoder),
+                       mode->base.id, mode->name);
                encoder_funcs = encoder->helper_private;
                encoder_funcs->mode_set(encoder, mode, adjusted_mode);
        }
@@ -469,10 +481,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
        crtc_funcs = set->crtc->helper_private;
 
-       DRM_DEBUG_KMS("crtc: %p %d fb: %p connectors: %p num_connectors:"
-                       " %d (x, y) (%i, %i)\n",
-                 set->crtc, set->crtc->base.id, set->fb, set->connectors,
-                 (int)set->num_connectors, set->x, set->y);
+       if (set->fb) {
+               DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
+                               set->crtc->base.id, set->fb->base.id,
+                               (int)set->num_connectors, set->x, set->y);
+       } else {
+               DRM_DEBUG_KMS("[CRTC:%d] [NOFB] #connectors=%d (x y) (%i %i)\n",
+                               set->crtc->base.id, (int)set->num_connectors,
+                               set->x, set->y);
+       }
 
        dev = set->crtc->dev;
 
@@ -601,8 +618,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                        mode_changed = true;
                        connector->encoder->crtc = new_crtc;
                }
-               DRM_DEBUG_KMS("setting connector %d crtc to %p\n",
-                         connector->base.id, new_crtc);
+               if (new_crtc) {
+                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
+                               connector->base.id, drm_get_connector_name(connector),
+                               new_crtc->base.id);
+               } else {
+                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
+                               connector->base.id, drm_get_connector_name(connector));
+               }
        }
 
        /* mode_set_base is not a required function */
@@ -620,8 +643,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                        if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
                                                      set->x, set->y,
                                                      old_fb)) {
-                               DRM_ERROR("failed to set mode on crtc %p\n",
-                                         set->crtc);
+                               DRM_ERROR("failed to set mode on [CRTC:%d]\n",
+                                         set->crtc->base.id);
                                ret = -EINVAL;
                                goto fail;
                        }
@@ -808,13 +831,11 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_helper_resume_force_mode);
 
-static struct slow_work_ops output_poll_ops;
-
 #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
-static void output_poll_execute(struct slow_work *work)
+static void output_poll_execute(struct work_struct *work)
 {
-       struct delayed_slow_work *delayed_work = container_of(work, struct delayed_slow_work, work);
-       struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_slow_work);
+       struct delayed_work *delayed_work = to_delayed_work(work);
+       struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
        struct drm_connector *connector;
        enum drm_connector_status old_status, status;
        bool repoll = false, changed = false;
@@ -854,7 +875,7 @@ static void output_poll_execute(struct slow_work *work)
        }
 
        if (repoll) {
-               ret = delayed_slow_work_enqueue(delayed_work, DRM_OUTPUT_POLL_PERIOD);
+               ret = queue_delayed_work(system_nrt_wq, delayed_work, DRM_OUTPUT_POLL_PERIOD);
                if (ret)
                        DRM_ERROR("delayed enqueue failed %d\n", ret);
        }
@@ -864,7 +885,7 @@ void drm_kms_helper_poll_disable(struct drm_device *dev)
 {
        if (!dev->mode_config.poll_enabled)
                return;
-       delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
+       cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
 }
 EXPORT_SYMBOL(drm_kms_helper_poll_disable);
 
@@ -880,7 +901,7 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
        }
 
        if (poll) {
-               ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD);
+               ret = queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
                if (ret)
                        DRM_ERROR("delayed enqueue failed %d\n", ret);
        }
@@ -889,9 +910,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_enable);
 
 void drm_kms_helper_poll_init(struct drm_device *dev)
 {
-       slow_work_register_user(THIS_MODULE);
-       delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
-                              &output_poll_ops);
+       INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
        dev->mode_config.poll_enabled = true;
 
        drm_kms_helper_poll_enable(dev);
@@ -901,7 +920,6 @@ EXPORT_SYMBOL(drm_kms_helper_poll_init);
 void drm_kms_helper_poll_fini(struct drm_device *dev)
 {
        drm_kms_helper_poll_disable(dev);
-       slow_work_unregister_user(THIS_MODULE);
 }
 EXPORT_SYMBOL(drm_kms_helper_poll_fini);
 
@@ -909,12 +927,8 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
 {
        if (!dev->mode_config.poll_enabled)
                return;
-       delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
-       /* schedule a slow work asap */
-       delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
+       /* kill timer and schedule immediate execution, this doesn't block */
+       cancel_delayed_work(&dev->mode_config.output_poll_work);
+       queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
 }
 EXPORT_SYMBOL(drm_helper_hpd_irq_event);
-
-static struct slow_work_ops output_poll_ops = {
-       .execute = output_poll_execute,
-};
index 4a66201edaec0ea89ccc9d791a67f29d2ea58245..90288ec7c28420133d0deea13e3ba2f1f98d413c 100644 (file)
@@ -243,47 +243,20 @@ int drm_lastclose(struct drm_device * dev)
  *
  * Initializes an array of drm_device structures, and attempts to
  * initialize all available devices, using consecutive minors, registering the
- * stubs and initializing the AGP device.
+ * stubs and initializing the device.
  *
  * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
  * after the initialization for driver customization.
  */
 int drm_init(struct drm_driver *driver)
 {
-       struct pci_dev *pdev = NULL;
-       const struct pci_device_id *pid;
-       int i;
-
        DRM_DEBUG("\n");
-
        INIT_LIST_HEAD(&driver->device_list);
 
-       if (driver->driver_features & DRIVER_MODESET)
-               return pci_register_driver(&driver->pci_driver);
-
-       /* If not using KMS, fall back to stealth mode manual scanning. */
-       for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
-               pid = &driver->pci_driver.id_table[i];
-
-               /* Loop around setting up a DRM device for each PCI device
-                * matching our ID and device class.  If we had the internal
-                * function that pci_get_subsys and pci_get_class used, we'd
-                * be able to just pass pid in instead of doing a two-stage
-                * thing.
-                */
-               pdev = NULL;
-               while ((pdev =
-                       pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
-                                      pid->subdevice, pdev)) != NULL) {
-                       if ((pdev->class & pid->class_mask) != pid->class)
-                               continue;
-
-                       /* stealth mode requires a manual probe */
-                       pci_dev_get(pdev);
-                       drm_get_dev(pdev, pid, driver);
-               }
-       }
-       return 0;
+       if (driver->driver_features & DRIVER_USE_PLATFORM_DEVICE)
+               return drm_platform_init(driver);
+       else
+               return drm_pci_init(driver);
 }
 
 EXPORT_SYMBOL(drm_init);
@@ -315,6 +288,7 @@ static int __init drm_core_init(void)
 {
        int ret = -ENOMEM;
 
+       drm_global_init();
        idr_init(&drm_minors_idr);
 
        if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
@@ -362,6 +336,7 @@ static void __exit drm_core_exit(void)
 
        unregister_chrdev(DRM_MAJOR, "drm");
 
+       idr_remove_all(&drm_minors_idr);
        idr_destroy(&drm_minors_idr);
 }
 
@@ -506,9 +481,9 @@ long drm_ioctl(struct file *filp,
                if (ioctl->flags & DRM_UNLOCKED)
                        retcode = func(dev, kdata, file_priv);
                else {
-                       lock_kernel();
+                       mutex_lock(&drm_global_mutex);
                        retcode = func(dev, kdata, file_priv);
-                       unlock_kernel();
+                       mutex_unlock(&drm_global_mutex);
                }
 
                if (cmd & IOC_OUT) {
index 9585e531ac6bdc51c9cf2cfbd2e4a41bb7dadff6..dce5c4a97f8d3d933791164abfdf0156e2badca5 100644 (file)
@@ -282,7 +282,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
        return block;
 
 carp:
-       dev_warn(&connector->dev->pdev->dev, "%s: EDID block %d invalid.\n",
+       dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
                 drm_get_connector_name(connector), j);
 
 out:
@@ -1623,7 +1623,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
                return 0;
        }
        if (!drm_edid_is_valid(edid)) {
-               dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+               dev_warn(connector->dev->dev, "%s: EDID invalid.\n",
                         drm_get_connector_name(connector));
                return 0;
        }
index f0184696edf3bef667b786e53488f0ed9c08aaa2..d62c064fbaa02e747328d8a932fa58eef96cbedb 100644 (file)
@@ -41,6 +41,9 @@
  * &drm_encoder_slave. The @slave_funcs field will be initialized with
  * the hooks provided by the slave driver.
  *
+ * If @info->platform_data is non-NULL it will be used as the initial
+ * slave config.
+ *
  * Returns 0 on success or a negative errno on failure, in particular,
  * -ENODEV is returned when no matching driver is found.
  */
@@ -85,6 +88,10 @@ int drm_i2c_encoder_init(struct drm_device *dev,
        if (err)
                goto fail_unregister;
 
+       if (info->platform_data)
+               encoder->slave_funcs->set_config(&encoder->base,
+                                                info->platform_data);
+
        return 0;
 
 fail_unregister:
index 719662034bbfee9d9d1f2be26bfe1199c985d0a0..de82e201d6826d8ac0e422b22a2d0a93f8312d82 100644 (file)
@@ -241,6 +241,80 @@ static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
        return 0;
 }
 
+int drm_fb_helper_debug_enter(struct fb_info *info)
+{
+       struct drm_fb_helper *helper = info->par;
+       struct drm_crtc_helper_funcs *funcs;
+       int i;
+
+       if (list_empty(&kernel_fb_helper_list))
+               return false;
+
+       list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
+               for (i = 0; i < helper->crtc_count; i++) {
+                       struct drm_mode_set *mode_set =
+                               &helper->crtc_info[i].mode_set;
+
+                       if (!mode_set->crtc->enabled)
+                               continue;
+
+                       funcs = mode_set->crtc->helper_private;
+                       funcs->mode_set_base_atomic(mode_set->crtc,
+                                                   mode_set->fb,
+                                                   mode_set->x,
+                                                   mode_set->y);
+
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_debug_enter);
+
+/* Find the real fb for a given fb helper CRTC */
+static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_crtc *c;
+
+       list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
+               if (crtc->base.id == c->base.id)
+                       return c->fb;
+       }
+
+       return NULL;
+}
+
+int drm_fb_helper_debug_leave(struct fb_info *info)
+{
+       struct drm_fb_helper *helper = info->par;
+       struct drm_crtc *crtc;
+       struct drm_crtc_helper_funcs *funcs;
+       struct drm_framebuffer *fb;
+       int i;
+
+       for (i = 0; i < helper->crtc_count; i++) {
+               struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
+               crtc = mode_set->crtc;
+               funcs = crtc->helper_private;
+               fb = drm_mode_config_fb(crtc);
+
+               if (!crtc->enabled)
+                       continue;
+
+               if (!fb) {
+                       DRM_ERROR("no fb to restore??\n");
+                       continue;
+               }
+
+               funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
+                                           crtc->y);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_debug_leave);
+
 bool drm_fb_helper_force_kernel_mode(void)
 {
        int i = 0;
@@ -611,7 +685,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
        struct drm_framebuffer *fb = fb_helper->fb;
        int depth;
 
-       if (var->pixclock != 0)
+       if (var->pixclock != 0 || in_dbg_master())
                return -EINVAL;
 
        /* Need to resize the fb object !!! */
index e7aace20981f36b9d7c8632207954995cf4d4513..2ca8df8b6102a0002cda630460333e94bc3c47c0 100644 (file)
@@ -39,6 +39,9 @@
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 
+/* from BKL pushdown: note that nothing else serializes idr_find() */
+DEFINE_MUTEX(drm_global_mutex);
+
 static int drm_open_helper(struct inode *inode, struct file *filp,
                           struct drm_device * dev);
 
@@ -175,8 +178,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
 
        DRM_DEBUG("\n");
 
-       /* BKL pushdown: note that nothing else serializes idr_find() */
-       lock_kernel();
+       mutex_lock(&drm_global_mutex);
        minor = idr_find(&drm_minors_idr, minor_id);
        if (!minor)
                goto out;
@@ -197,7 +199,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
        fops_put(old_fops);
 
 out:
-       unlock_kernel();
+       mutex_unlock(&drm_global_mutex);
        return err;
 }
 
@@ -472,7 +474,7 @@ int drm_release(struct inode *inode, struct file *filp)
        struct drm_device *dev = file_priv->minor->dev;
        int retcode = 0;
 
-       lock_kernel();
+       mutex_lock(&drm_global_mutex);
 
        DRM_DEBUG("open_count = %d\n", dev->open_count);
 
@@ -573,17 +575,14 @@ int drm_release(struct inode *inode, struct file *filp)
                if (atomic_read(&dev->ioctl_count)) {
                        DRM_ERROR("Device busy: %d\n",
                                  atomic_read(&dev->ioctl_count));
-                       spin_unlock(&dev->count_lock);
-                       unlock_kernel();
-                       return -EBUSY;
+                       retcode = -EBUSY;
+                       goto out;
                }
-               spin_unlock(&dev->count_lock);
-               unlock_kernel();
-               return drm_lastclose(dev);
+               retcode = drm_lastclose(dev);
        }
+out:
        spin_unlock(&dev->count_lock);
-
-       unlock_kernel();
+       mutex_unlock(&drm_global_mutex);
 
        return retcode;
 }
index 33dad3fa60439e0b39daca428f8b062ddfca8276..4f1b8671448921dc74b4a7e201d2a03309f495d5 100644 (file)
  * We make up offsets for buffer objects so we can recognize them at
  * mmap time.
  */
+
+/* pgoff in mmap is an unsigned long, so we need to make sure that
+ * the faked up offset will fit
+ */
+
+#if BITS_PER_LONG == 64
 #define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1)
 #define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16)
+#else
+#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1)
+#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16)
+#endif
 
 /**
  * Initialize the GEM device fields
@@ -419,6 +429,7 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
        idr_for_each(&file_private->object_idr,
                     &drm_gem_object_release_handle, NULL);
 
+       idr_remove_all(&file_private->object_idr);
        idr_destroy(&file_private->object_idr);
 }
 
similarity index 79%
rename from drivers/gpu/drm/ttm/ttm_global.c
rename to drivers/gpu/drm/drm_global.c
index b17007178a36e57bb59c82e8f3378fe9f5741d29..c87dc96444de6f1b314f5919ae37c99b2542832b 100644 (file)
  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  */
 
-#include "ttm/ttm_module.h"
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include "drm_global.h"
 
-struct ttm_global_item {
+struct drm_global_item {
        struct mutex mutex;
        void *object;
        int refcount;
 };
 
-static struct ttm_global_item glob[TTM_GLOBAL_NUM];
+static struct drm_global_item glob[DRM_GLOBAL_NUM];
 
-void ttm_global_init(void)
+void drm_global_init(void)
 {
        int i;
 
-       for (i = 0; i < TTM_GLOBAL_NUM; ++i) {
-               struct ttm_global_item *item = &glob[i];
+       for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
+               struct drm_global_item *item = &glob[i];
                mutex_init(&item->mutex);
                item->object = NULL;
                item->refcount = 0;
        }
 }
 
-void ttm_global_release(void)
+void drm_global_release(void)
 {
        int i;
-       for (i = 0; i < TTM_GLOBAL_NUM; ++i) {
-               struct ttm_global_item *item = &glob[i];
+       for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
+               struct drm_global_item *item = &glob[i];
                BUG_ON(item->object != NULL);
                BUG_ON(item->refcount != 0);
        }
 }
 
-int ttm_global_item_ref(struct ttm_global_reference *ref)
+int drm_global_item_ref(struct drm_global_reference *ref)
 {
        int ret;
-       struct ttm_global_item *item = &glob[ref->global_type];
+       struct drm_global_item *item = &glob[ref->global_type];
        void *object;
 
        mutex_lock(&item->mutex);
@@ -93,11 +93,11 @@ out_err:
        item->object = NULL;
        return ret;
 }
-EXPORT_SYMBOL(ttm_global_item_ref);
+EXPORT_SYMBOL(drm_global_item_ref);
 
-void ttm_global_item_unref(struct ttm_global_reference *ref)
+void drm_global_item_unref(struct drm_global_reference *ref)
 {
-       struct ttm_global_item *item = &glob[ref->global_type];
+       struct drm_global_item *item = &glob[ref->global_type];
 
        mutex_lock(&item->mutex);
        BUG_ON(item->refcount == 0);
@@ -108,5 +108,5 @@ void ttm_global_item_unref(struct ttm_global_reference *ref)
        }
        mutex_unlock(&item->mutex);
 }
-EXPORT_SYMBOL(ttm_global_item_unref);
+EXPORT_SYMBOL(drm_global_item_unref);
 
index f0f6c6b93f3a235a4a667bcac27a56f5667b4562..2ef2c78272434dcb6b32dc17fd96e34dd7a8d959 100644 (file)
@@ -51,13 +51,24 @@ int drm_name_info(struct seq_file *m, void *data)
        if (!master)
                return 0;
 
-       if (master->unique) {
-               seq_printf(m, "%s %s %s\n",
-                          dev->driver->pci_driver.name,
-                          pci_name(dev->pdev), master->unique);
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) {
+               if (master->unique) {
+                       seq_printf(m, "%s %s %s\n",
+                                       dev->driver->platform_device->name,
+                                       dev_name(dev->dev), master->unique);
+               } else {
+                       seq_printf(m, "%s\n",
+                               dev->driver->platform_device->name);
+               }
        } else {
-               seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
-                          pci_name(dev->pdev));
+               if (master->unique) {
+                       seq_printf(m, "%s %s %s\n",
+                               dev->driver->pci_driver.name,
+                               dev_name(dev->dev), master->unique);
+               } else {
+                       seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
+                               dev_name(dev->dev));
+               }
        }
 
        return 0;
index 9b9ff46c2378b8601661e8dacbd176f7e40d979d..7b03b197fc0066f5521e20b90c06e372e41e4c3f 100644 (file)
@@ -64,6 +64,19 @@ int drm_getunique(struct drm_device *dev, void *data,
        return 0;
 }
 
+static void
+drm_unset_busid(struct drm_device *dev,
+               struct drm_master *master)
+{
+       kfree(dev->devname);
+       dev->devname = NULL;
+
+       kfree(master->unique);
+       master->unique = NULL;
+       master->unique_len = 0;
+       master->unique_size = 0;
+}
+
 /**
  * Set the bus id.
  *
@@ -94,17 +107,24 @@ int drm_setunique(struct drm_device *dev, void *data,
        master->unique_len = u->unique_len;
        master->unique_size = u->unique_len + 1;
        master->unique = kmalloc(master->unique_size, GFP_KERNEL);
-       if (!master->unique)
-               return -ENOMEM;
-       if (copy_from_user(master->unique, u->unique, master->unique_len))
-               return -EFAULT;
+       if (!master->unique) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       if (copy_from_user(master->unique, u->unique, master->unique_len)) {
+               ret = -EFAULT;
+               goto err;
+       }
 
        master->unique[master->unique_len] = '\0';
 
        dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) +
                               strlen(master->unique) + 2, GFP_KERNEL);
-       if (!dev->devname)
-               return -ENOMEM;
+       if (!dev->devname) {
+               ret = -ENOMEM;
+               goto err;
+       }
 
        sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
                master->unique);
@@ -113,53 +133,103 @@ int drm_setunique(struct drm_device *dev, void *data,
         * busid.
         */
        ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
-       if (ret != 3)
-               return -EINVAL;
+       if (ret != 3) {
+               ret = -EINVAL;
+               goto err;
+       }
+
        domain = bus >> 8;
        bus &= 0xff;
 
        if ((domain != drm_get_pci_domain(dev)) ||
            (bus != dev->pdev->bus->number) ||
            (slot != PCI_SLOT(dev->pdev->devfn)) ||
-           (func != PCI_FUNC(dev->pdev->devfn)))
-               return -EINVAL;
+           (func != PCI_FUNC(dev->pdev->devfn))) {
+               ret = -EINVAL;
+               goto err;
+       }
 
        return 0;
+
+err:
+       drm_unset_busid(dev, master);
+       return ret;
 }
 
 static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
 {
        struct drm_master *master = file_priv->master;
-       int len;
+       int len, ret;
 
        if (master->unique != NULL)
-               return -EBUSY;
+               drm_unset_busid(dev, master);
 
-       master->unique_len = 40;
-       master->unique_size = master->unique_len;
-       master->unique = kmalloc(master->unique_size, GFP_KERNEL);
-       if (master->unique == NULL)
-               return -ENOMEM;
-
-       len = snprintf(master->unique, master->unique_len, "pci:%04x:%02x:%02x.%d",
-                      drm_get_pci_domain(dev),
-                      dev->pdev->bus->number,
-                      PCI_SLOT(dev->pdev->devfn),
-                      PCI_FUNC(dev->pdev->devfn));
-       if (len >= master->unique_len)
-               DRM_ERROR("buffer overflow");
-       else
-               master->unique_len = len;
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) {
+               master->unique_len = 10 + strlen(dev->platformdev->name);
+               master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
 
-       dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) +
-                              master->unique_len + 2, GFP_KERNEL);
-       if (dev->devname == NULL)
-               return -ENOMEM;
+               if (master->unique == NULL)
+                       return -ENOMEM;
 
-       sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
-               master->unique);
+               len = snprintf(master->unique, master->unique_len,
+                       "platform:%s", dev->platformdev->name);
+
+               if (len > master->unique_len) {
+                       DRM_ERROR("Unique buffer overflowed\n");
+                       ret = -EINVAL;
+                       goto err;
+               }
+
+               dev->devname =
+                       kmalloc(strlen(dev->platformdev->name) +
+                               master->unique_len + 2, GFP_KERNEL);
+
+               if (dev->devname == NULL) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               sprintf(dev->devname, "%s@%s", dev->platformdev->name,
+                       master->unique);
+
+       } else {
+               master->unique_len = 40;
+               master->unique_size = master->unique_len;
+               master->unique = kmalloc(master->unique_size, GFP_KERNEL);
+               if (master->unique == NULL)
+                       return -ENOMEM;
+
+               len = snprintf(master->unique, master->unique_len,
+                       "pci:%04x:%02x:%02x.%d",
+                       drm_get_pci_domain(dev),
+                       dev->pdev->bus->number,
+                       PCI_SLOT(dev->pdev->devfn),
+                       PCI_FUNC(dev->pdev->devfn));
+               if (len >= master->unique_len) {
+                       DRM_ERROR("buffer overflow");
+                       ret = -EINVAL;
+                       goto err;
+               } else
+                       master->unique_len = len;
+
+               dev->devname =
+                       kmalloc(strlen(dev->driver->pci_driver.name) +
+                               master->unique_len + 2, GFP_KERNEL);
+
+               if (dev->devname == NULL) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
+                       master->unique);
+       }
 
        return 0;
+
+err:
+       drm_unset_busid(dev, master);
+       return ret;
 }
 
 /**
@@ -323,7 +393,9 @@ int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_pri
                        /*
                         * Version 1.1 includes tying of DRM to specific device
                         */
-                       drm_set_busid(dev, file_priv);
+                       retcode = drm_set_busid(dev, file_priv);
+                       if (retcode)
+                               goto done;
                }
        }
 
index a263b7070fc6f81b227d77a3befbd11b6efc8be0..9d3a5030b6e1dfcfbf522a783d24f14816c7b813 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include "drmP.h"
+#include "drm_trace.h"
 
 #include <linux/interrupt.h>   /* For task queue support */
 #include <linux/slab.h>
@@ -57,6 +58,9 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
 {
        struct drm_irq_busid *p = data;
 
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return -EINVAL;
+
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
@@ -211,7 +215,7 @@ int drm_irq_install(struct drm_device *dev)
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
-       if (dev->pdev->irq == 0)
+       if (drm_dev_to_irq(dev) == 0)
                return -EINVAL;
 
        mutex_lock(&dev->struct_mutex);
@@ -229,7 +233,7 @@ int drm_irq_install(struct drm_device *dev)
        dev->irq_enabled = 1;
        mutex_unlock(&dev->struct_mutex);
 
-       DRM_DEBUG("irq=%d\n", dev->pdev->irq);
+       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
 
        /* Before installing handler */
        dev->driver->irq_preinstall(dev);
@@ -302,14 +306,14 @@ int drm_irq_uninstall(struct drm_device * dev)
        if (!irq_enabled)
                return -EINVAL;
 
-       DRM_DEBUG("irq=%d\n", dev->pdev->irq);
+       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                vga_client_register(dev->pdev, NULL, NULL, NULL);
 
        dev->driver->irq_uninstall(dev);
 
-       free_irq(dev->pdev->irq, dev);
+       free_irq(drm_dev_to_irq(dev), dev);
 
        return 0;
 }
@@ -341,7 +345,7 @@ int drm_control(struct drm_device *dev, void *data,
                if (drm_core_check_feature(dev, DRIVER_MODESET))
                        return 0;
                if (dev->if_version < DRM_IF_VERSION(1, 2) &&
-                   ctl->irq != dev->pdev->irq)
+                   ctl->irq != drm_dev_to_irq(dev))
                        return -EINVAL;
                return drm_irq_install(dev);
        case DRM_UNINST_HANDLER:
@@ -587,6 +591,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
                return -ENOMEM;
 
        e->pipe = pipe;
+       e->base.pid = current->pid;
        e->event.base.type = DRM_EVENT_VBLANK;
        e->event.base.length = sizeof e->event;
        e->event.user_data = vblwait->request.signal;
@@ -614,6 +619,9 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n",
                  vblwait->request.sequence, seq, pipe);
 
+       trace_drm_vblank_event_queued(current->pid, pipe,
+                                     vblwait->request.sequence);
+
        e->event.sequence = vblwait->request.sequence;
        if ((seq - vblwait->request.sequence) <= (1 << 23)) {
                e->event.tv_sec = now.tv_sec;
@@ -621,6 +629,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
                drm_vblank_put(dev, e->pipe);
                list_add_tail(&e->base.link, &e->base.file_priv->event_list);
                wake_up_interruptible(&e->base.file_priv->event_wait);
+               trace_drm_vblank_event_delivered(current->pid, pipe,
+                                                vblwait->request.sequence);
        } else {
                list_add_tail(&e->base.link, &dev->vblank_event_list);
        }
@@ -651,7 +661,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
        int ret = 0;
        unsigned int flags, seq, crtc;
 
-       if ((!dev->pdev->irq) || (!dev->irq_enabled))
+       if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
                return -EINVAL;
 
        if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
@@ -751,9 +761,13 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc)
                drm_vblank_put(dev, e->pipe);
                list_move_tail(&e->base.link, &e->base.file_priv->event_list);
                wake_up_interruptible(&e->base.file_priv->event_wait);
+               trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
+                                                e->event.sequence);
        }
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
+
+       trace_drm_vblank_event(crtc, seq);
 }
 
 /**
index 2ac074c8f5d2e546d40ff53fa3fe54c83547773d..da99edc50888f2168c510054305e1c847e1fbefb 100644 (file)
 
 #define MM_UNUSED_TARGET 4
 
-unsigned long drm_mm_tail_space(struct drm_mm *mm)
-{
-       struct list_head *tail_node;
-       struct drm_mm_node *entry;
-
-       tail_node = mm->ml_entry.prev;
-       entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
-       if (!entry->free)
-               return 0;
-
-       return entry->size;
-}
-
-int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size)
-{
-       struct list_head *tail_node;
-       struct drm_mm_node *entry;
-
-       tail_node = mm->ml_entry.prev;
-       entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
-       if (!entry->free)
-               return -ENOMEM;
-
-       if (entry->size <= size)
-               return -ENOMEM;
-
-       entry->size -= size;
-       return 0;
-}
-
 static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
 {
        struct drm_mm_node *child;
 
        if (atomic)
-               child = kmalloc(sizeof(*child), GFP_ATOMIC);
+               child = kzalloc(sizeof(*child), GFP_ATOMIC);
        else
-               child = kmalloc(sizeof(*child), GFP_KERNEL);
+               child = kzalloc(sizeof(*child), GFP_KERNEL);
 
        if (unlikely(child == NULL)) {
                spin_lock(&mm->unused_lock);
@@ -94,8 +64,8 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
                else {
                        child =
                            list_entry(mm->unused_nodes.next,
-                                      struct drm_mm_node, fl_entry);
-                       list_del(&child->fl_entry);
+                                      struct drm_mm_node, free_stack);
+                       list_del(&child->free_stack);
                        --mm->num_unused;
                }
                spin_unlock(&mm->unused_lock);
@@ -115,7 +85,7 @@ int drm_mm_pre_get(struct drm_mm *mm)
        spin_lock(&mm->unused_lock);
        while (mm->num_unused < MM_UNUSED_TARGET) {
                spin_unlock(&mm->unused_lock);
-               node = kmalloc(sizeof(*node), GFP_KERNEL);
+               node = kzalloc(sizeof(*node), GFP_KERNEL);
                spin_lock(&mm->unused_lock);
 
                if (unlikely(node == NULL)) {
@@ -124,7 +94,7 @@ int drm_mm_pre_get(struct drm_mm *mm)
                        return ret;
                }
                ++mm->num_unused;
-               list_add_tail(&node->fl_entry, &mm->unused_nodes);
+               list_add_tail(&node->free_stack, &mm->unused_nodes);
        }
        spin_unlock(&mm->unused_lock);
        return 0;
@@ -146,27 +116,12 @@ static int drm_mm_create_tail_node(struct drm_mm *mm,
        child->start = start;
        child->mm = mm;
 
-       list_add_tail(&child->ml_entry, &mm->ml_entry);
-       list_add_tail(&child->fl_entry, &mm->fl_entry);
+       list_add_tail(&child->node_list, &mm->node_list);
+       list_add_tail(&child->free_stack, &mm->free_stack);
 
        return 0;
 }
 
-int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic)
-{
-       struct list_head *tail_node;
-       struct drm_mm_node *entry;
-
-       tail_node = mm->ml_entry.prev;
-       entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
-       if (!entry->free) {
-               return drm_mm_create_tail_node(mm, entry->start + entry->size,
-                                              size, atomic);
-       }
-       entry->size += size;
-       return 0;
-}
-
 static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
                                                 unsigned long size,
                                                 int atomic)
@@ -177,15 +132,14 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
        if (unlikely(child == NULL))
                return NULL;
 
-       INIT_LIST_HEAD(&child->fl_entry);
+       INIT_LIST_HEAD(&child->free_stack);
 
-       child->free = 0;
        child->size = size;
        child->start = parent->start;
        child->mm = parent->mm;
 
-       list_add_tail(&child->ml_entry, &parent->ml_entry);
-       INIT_LIST_HEAD(&child->fl_entry);
+       list_add_tail(&child->node_list, &parent->node_list);
+       INIT_LIST_HEAD(&child->free_stack);
 
        parent->size -= size;
        parent->start += size;
@@ -213,7 +167,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
        }
 
        if (node->size == size) {
-               list_del_init(&node->fl_entry);
+               list_del_init(&node->free_stack);
                node->free = 0;
        } else {
                node = drm_mm_split_at_start(node, size, atomic);
@@ -251,7 +205,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node,
        }
 
        if (node->size == size) {
-               list_del_init(&node->fl_entry);
+               list_del_init(&node->free_stack);
                node->free = 0;
        } else {
                node = drm_mm_split_at_start(node, size, atomic);
@@ -273,16 +227,19 @@ void drm_mm_put_block(struct drm_mm_node *cur)
 {
 
        struct drm_mm *mm = cur->mm;
-       struct list_head *cur_head = &cur->ml_entry;
-       struct list_head *root_head = &mm->ml_entry;
+       struct list_head *cur_head = &cur->node_list;
+       struct list_head *root_head = &mm->node_list;
        struct drm_mm_node *prev_node = NULL;
        struct drm_mm_node *next_node;
 
        int merged = 0;
 
+       BUG_ON(cur->scanned_block || cur->scanned_prev_free
+                                 || cur->scanned_next_free);
+
        if (cur_head->prev != root_head) {
                prev_node =
-                   list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
+                   list_entry(cur_head->prev, struct drm_mm_node, node_list);
                if (prev_node->free) {
                        prev_node->size += cur->size;
                        merged = 1;
@@ -290,15 +247,15 @@ void drm_mm_put_block(struct drm_mm_node *cur)
        }
        if (cur_head->next != root_head) {
                next_node =
-                   list_entry(cur_head->next, struct drm_mm_node, ml_entry);
+                   list_entry(cur_head->next, struct drm_mm_node, node_list);
                if (next_node->free) {
                        if (merged) {
                                prev_node->size += next_node->size;
-                               list_del(&next_node->ml_entry);
-                               list_del(&next_node->fl_entry);
+                               list_del(&next_node->node_list);
+                               list_del(&next_node->free_stack);
                                spin_lock(&mm->unused_lock);
                                if (mm->num_unused < MM_UNUSED_TARGET) {
-                                       list_add(&next_node->fl_entry,
+                                       list_add(&next_node->free_stack,
                                                 &mm->unused_nodes);
                                        ++mm->num_unused;
                                } else
@@ -313,12 +270,12 @@ void drm_mm_put_block(struct drm_mm_node *cur)
        }
        if (!merged) {
                cur->free = 1;
-               list_add(&cur->fl_entry, &mm->fl_entry);
+               list_add(&cur->free_stack, &mm->free_stack);
        } else {
-               list_del(&cur->ml_entry);
+               list_del(&cur->node_list);
                spin_lock(&mm->unused_lock);
                if (mm->num_unused < MM_UNUSED_TARGET) {
-                       list_add(&cur->fl_entry, &mm->unused_nodes);
+                       list_add(&cur->free_stack, &mm->unused_nodes);
                        ++mm->num_unused;
                } else
                        kfree(cur);
@@ -328,40 +285,50 @@ void drm_mm_put_block(struct drm_mm_node *cur)
 
 EXPORT_SYMBOL(drm_mm_put_block);
 
+static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size,
+                             unsigned alignment)
+{
+       unsigned wasted = 0;
+
+       if (entry->size < size)
+               return 0;
+
+       if (alignment) {
+               register unsigned tmp = entry->start % alignment;
+               if (tmp)
+                       wasted = alignment - tmp;
+       }
+
+       if (entry->size >= size + wasted) {
+               return 1;
+       }
+
+       return 0;
+}
+
 struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
                                       unsigned long size,
                                       unsigned alignment, int best_match)
 {
-       struct list_head *list;
-       const struct list_head *free_stack = &mm->fl_entry;
        struct drm_mm_node *entry;
        struct drm_mm_node *best;
        unsigned long best_size;
-       unsigned wasted;
+
+       BUG_ON(mm->scanned_blocks);
 
        best = NULL;
        best_size = ~0UL;
 
-       list_for_each(list, free_stack) {
-               entry = list_entry(list, struct drm_mm_node, fl_entry);
-               wasted = 0;
-
-               if (entry->size < size)
+       list_for_each_entry(entry, &mm->free_stack, free_stack) {
+               if (!check_free_mm_node(entry, size, alignment))
                        continue;
 
-               if (alignment) {
-                       register unsigned tmp = entry->start % alignment;
-                       if (tmp)
-                               wasted += alignment - tmp;
-               }
+               if (!best_match)
+                       return entry;
 
-               if (entry->size >= size + wasted) {
-                       if (!best_match)
-                               return entry;
-                       if (entry->size < best_size) {
-                               best = entry;
-                               best_size = entry->size;
-                       }
+               if (entry->size < best_size) {
+                       best = entry;
+                       best_size = entry->size;
                }
        }
 
@@ -376,43 +343,28 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
                                                unsigned long end,
                                                int best_match)
 {
-       struct list_head *list;
-       const struct list_head *free_stack = &mm->fl_entry;
        struct drm_mm_node *entry;
        struct drm_mm_node *best;
        unsigned long best_size;
-       unsigned wasted;
+
+       BUG_ON(mm->scanned_blocks);
 
        best = NULL;
        best_size = ~0UL;
 
-       list_for_each(list, free_stack) {
-               entry = list_entry(list, struct drm_mm_node, fl_entry);
-               wasted = 0;
-
-               if (entry->size < size)
-                       continue;
-
+       list_for_each_entry(entry, &mm->free_stack, free_stack) {
                if (entry->start > end || (entry->start+entry->size) < start)
                        continue;
 
-               if (entry->start < start)
-                       wasted += start - entry->start;
+               if (!check_free_mm_node(entry, size, alignment))
+                       continue;
 
-               if (alignment) {
-                       register unsigned tmp = (entry->start + wasted) % alignment;
-                       if (tmp)
-                               wasted += alignment - tmp;
-               }
+               if (!best_match)
+                       return entry;
 
-               if (entry->size >= size + wasted &&
-                   (entry->start + wasted + size) <= end) {
-                       if (!best_match)
-                               return entry;
-                       if (entry->size < best_size) {
-                               best = entry;
-                               best_size = entry->size;
-                       }
+               if (entry->size < best_size) {
+                       best = entry;
+                       best_size = entry->size;
                }
        }
 
@@ -420,9 +372,161 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
 }
 EXPORT_SYMBOL(drm_mm_search_free_in_range);
 
+/**
+ * Initializa lru scanning.
+ *
+ * This simply sets up the scanning routines with the parameters for the desired
+ * hole.
+ *
+ * Warning: As long as the scan list is non-empty, no other operations than
+ * adding/removing nodes to/from the scan list are allowed.
+ */
+void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
+                     unsigned alignment)
+{
+       mm->scan_alignment = alignment;
+       mm->scan_size = size;
+       mm->scanned_blocks = 0;
+       mm->scan_hit_start = 0;
+       mm->scan_hit_size = 0;
+}
+EXPORT_SYMBOL(drm_mm_init_scan);
+
+/**
+ * Add a node to the scan list that might be freed to make space for the desired
+ * hole.
+ *
+ * Returns non-zero, if a hole has been found, zero otherwise.
+ */
+int drm_mm_scan_add_block(struct drm_mm_node *node)
+{
+       struct drm_mm *mm = node->mm;
+       struct list_head *prev_free, *next_free;
+       struct drm_mm_node *prev_node, *next_node;
+
+       mm->scanned_blocks++;
+
+       prev_free = next_free = NULL;
+
+       BUG_ON(node->free);
+       node->scanned_block = 1;
+       node->free = 1;
+
+       if (node->node_list.prev != &mm->node_list) {
+               prev_node = list_entry(node->node_list.prev, struct drm_mm_node,
+                                      node_list);
+
+               if (prev_node->free) {
+                       list_del(&prev_node->node_list);
+
+                       node->start = prev_node->start;
+                       node->size += prev_node->size;
+
+                       prev_node->scanned_prev_free = 1;
+
+                       prev_free = &prev_node->free_stack;
+               }
+       }
+
+       if (node->node_list.next != &mm->node_list) {
+               next_node = list_entry(node->node_list.next, struct drm_mm_node,
+                                      node_list);
+
+               if (next_node->free) {
+                       list_del(&next_node->node_list);
+
+                       node->size += next_node->size;
+
+                       next_node->scanned_next_free = 1;
+
+                       next_free = &next_node->free_stack;
+               }
+       }
+
+       /* The free_stack list is not used for allocated objects, so these two
+        * pointers can be abused (as long as no allocations in this memory
+        * manager happens). */
+       node->free_stack.prev = prev_free;
+       node->free_stack.next = next_free;
+
+       if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) {
+               mm->scan_hit_start = node->start;
+               mm->scan_hit_size = node->size;
+
+               return 1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_mm_scan_add_block);
+
+/**
+ * Remove a node from the scan list.
+ *
+ * Nodes _must_ be removed in the exact same order from the scan list as they
+ * have been added, otherwise the internal state of the memory manager will be
+ * corrupted.
+ *
+ * When the scan list is empty, the selected memory nodes can be freed. An
+ * immediatly following drm_mm_search_free with best_match = 0 will then return
+ * the just freed block (because its at the top of the free_stack list).
+ *
+ * Returns one if this block should be evicted, zero otherwise. Will always
+ * return zero when no hole has been found.
+ */
+int drm_mm_scan_remove_block(struct drm_mm_node *node)
+{
+       struct drm_mm *mm = node->mm;
+       struct drm_mm_node *prev_node, *next_node;
+
+       mm->scanned_blocks--;
+
+       BUG_ON(!node->scanned_block);
+       node->scanned_block = 0;
+       node->free = 0;
+
+       prev_node = list_entry(node->free_stack.prev, struct drm_mm_node,
+                              free_stack);
+       next_node = list_entry(node->free_stack.next, struct drm_mm_node,
+                              free_stack);
+
+       if (prev_node) {
+               BUG_ON(!prev_node->scanned_prev_free);
+               prev_node->scanned_prev_free = 0;
+
+               list_add_tail(&prev_node->node_list, &node->node_list);
+
+               node->start = prev_node->start + prev_node->size;
+               node->size -= prev_node->size;
+       }
+
+       if (next_node) {
+               BUG_ON(!next_node->scanned_next_free);
+               next_node->scanned_next_free = 0;
+
+               list_add(&next_node->node_list, &node->node_list);
+
+               node->size -= next_node->size;
+       }
+
+       INIT_LIST_HEAD(&node->free_stack);
+
+       /* Only need to check for containement because start&size for the
+        * complete resulting free block (not just the desired part) is
+        * stored. */
+       if (node->start >= mm->scan_hit_start &&
+           node->start + node->size
+                       <= mm->scan_hit_start + mm->scan_hit_size) {
+               return 1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_mm_scan_remove_block);
+
 int drm_mm_clean(struct drm_mm * mm)
 {
-       struct list_head *head = &mm->ml_entry;
+       struct list_head *head = &mm->node_list;
 
        return (head->next->next == head);
 }
@@ -430,10 +534,11 @@ EXPORT_SYMBOL(drm_mm_clean);
 
 int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
 {
-       INIT_LIST_HEAD(&mm->ml_entry);
-       INIT_LIST_HEAD(&mm->fl_entry);
+       INIT_LIST_HEAD(&mm->node_list);
+       INIT_LIST_HEAD(&mm->free_stack);
        INIT_LIST_HEAD(&mm->unused_nodes);
        mm->num_unused = 0;
+       mm->scanned_blocks = 0;
        spin_lock_init(&mm->unused_lock);
 
        return drm_mm_create_tail_node(mm, start, size, 0);
@@ -442,25 +547,25 @@ EXPORT_SYMBOL(drm_mm_init);
 
 void drm_mm_takedown(struct drm_mm * mm)
 {
-       struct list_head *bnode = mm->fl_entry.next;
+       struct list_head *bnode = mm->free_stack.next;
        struct drm_mm_node *entry;
        struct drm_mm_node *next;
 
-       entry = list_entry(bnode, struct drm_mm_node, fl_entry);
+       entry = list_entry(bnode, struct drm_mm_node, free_stack);
 
-       if (entry->ml_entry.next != &mm->ml_entry ||
-           entry->fl_entry.next != &mm->fl_entry) {
+       if (entry->node_list.next != &mm->node_list ||
+           entry->free_stack.next != &mm->free_stack) {
                DRM_ERROR("Memory manager not clean. Delaying takedown\n");
                return;
        }
 
-       list_del(&entry->fl_entry);
-       list_del(&entry->ml_entry);
+       list_del(&entry->free_stack);
+       list_del(&entry->node_list);
        kfree(entry);
 
        spin_lock(&mm->unused_lock);
-       list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) {
-               list_del(&entry->fl_entry);
+       list_for_each_entry_safe(entry, next, &mm->unused_nodes, free_stack) {
+               list_del(&entry->free_stack);
                kfree(entry);
                --mm->num_unused;
        }
@@ -475,7 +580,7 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
        struct drm_mm_node *entry;
        int total_used = 0, total_free = 0, total = 0;
 
-       list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
+       list_for_each_entry(entry, &mm->node_list, node_list) {
                printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n",
                        prefix, entry->start, entry->start + entry->size,
                        entry->size, entry->free ? "free" : "used");
@@ -496,7 +601,7 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
        struct drm_mm_node *entry;
        int total_used = 0, total_free = 0, total = 0;
 
-       list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
+       list_for_each_entry(entry, &mm->node_list, node_list) {
                seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used");
                total += entry->size;
                if (entry->free)
index 2ea9ad4a8d699847bb4e8a7d0f1e7dc58ace90e4..e20f78b542a756644a29693c8da5927dd72f5a7d 100644 (file)
@@ -124,4 +124,147 @@ void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
 
 EXPORT_SYMBOL(drm_pci_free);
 
+#ifdef CONFIG_PCI
+/**
+ * Register.
+ *
+ * \param pdev - PCI device structure
+ * \param ent entry from the PCI ID table with device type flags
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+                   struct drm_driver *driver)
+{
+       struct drm_device *dev;
+       int ret;
+
+       DRM_DEBUG("\n");
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       ret = pci_enable_device(pdev);
+       if (ret)
+               goto err_g1;
+
+       pci_set_master(pdev);
+
+       dev->pdev = pdev;
+       dev->dev = &pdev->dev;
+
+       dev->pci_device = pdev->device;
+       dev->pci_vendor = pdev->vendor;
+
+#ifdef __alpha__
+       dev->hose = pdev->sysdata;
+#endif
+
+       if ((ret = drm_fill_in_dev(dev, ent, driver))) {
+               printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+               goto err_g2;
+       }
+
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               pci_set_drvdata(pdev, dev);
+               ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+               if (ret)
+                       goto err_g2;
+       }
+
+       if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
+               goto err_g3;
+
+       if (dev->driver->load) {
+               ret = dev->driver->load(dev, ent->driver_data);
+               if (ret)
+                       goto err_g4;
+       }
+
+       /* setup the grouping for the legacy output */
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               ret = drm_mode_group_init_legacy_group(dev,
+                                               &dev->primary->mode_group);
+               if (ret)
+                       goto err_g4;
+       }
+
+       list_add_tail(&dev->driver_item, &driver->device_list);
+
+       DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
+                driver->name, driver->major, driver->minor, driver->patchlevel,
+                driver->date, pci_name(pdev), dev->primary->index);
+
+       return 0;
+
+err_g4:
+       drm_put_minor(&dev->primary);
+err_g3:
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               drm_put_minor(&dev->control);
+err_g2:
+       pci_disable_device(pdev);
+err_g1:
+       kfree(dev);
+       return ret;
+}
+EXPORT_SYMBOL(drm_get_pci_dev);
+
+/**
+ * PCI device initialization. Called via drm_init at module load time,
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Initializes a drm_device structures,registering the
+ * stubs and initializing the AGP device.
+ *
+ * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+ * after the initialization for driver customization.
+ */
+int drm_pci_init(struct drm_driver *driver)
+{
+       struct pci_dev *pdev = NULL;
+       const struct pci_device_id *pid;
+       int i;
+
+       if (driver->driver_features & DRIVER_MODESET)
+               return pci_register_driver(&driver->pci_driver);
+
+       /* If not using KMS, fall back to stealth mode manual scanning. */
+       for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
+               pid = &driver->pci_driver.id_table[i];
+
+               /* Loop around setting up a DRM device for each PCI device
+                * matching our ID and device class.  If we had the internal
+                * function that pci_get_subsys and pci_get_class used, we'd
+                * be able to just pass pid in instead of doing a two-stage
+                * thing.
+                */
+               pdev = NULL;
+               while ((pdev =
+                       pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
+                                      pid->subdevice, pdev)) != NULL) {
+                       if ((pdev->class & pid->class_mask) != pid->class)
+                               continue;
+
+                       /* stealth mode requires a manual probe */
+                       pci_dev_get(pdev);
+                       drm_get_pci_dev(pdev, pid, driver);
+               }
+       }
+       return 0;
+}
+
+#else
+
+int drm_pci_init(struct drm_driver *driver)
+{
+       return -1;
+}
+
+#endif
 /*@}*/
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
new file mode 100644 (file)
index 0000000..460e9a3
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Derived from drm_pci.c
+ *
+ * Copyright 2003 José Fonseca.
+ * Copyright 2003 Leif Delgass.
+ * Copyright (c) 2009, Code Aurora Forum.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/**
+ * Register.
+ *
+ * \param platdev - Platform device struture
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+
+int drm_get_platform_dev(struct platform_device *platdev,
+                        struct drm_driver *driver)
+{
+       struct drm_device *dev;
+       int ret;
+
+       DRM_DEBUG("\n");
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       dev->platformdev = platdev;
+       dev->dev = &platdev->dev;
+
+       ret = drm_fill_in_dev(dev, NULL, driver);
+
+       if (ret) {
+               printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+               goto err_g1;
+       }
+
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               dev_set_drvdata(&platdev->dev, dev);
+               ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+               if (ret)
+                       goto err_g1;
+       }
+
+       ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
+       if (ret)
+               goto err_g2;
+
+       if (dev->driver->load) {
+               ret = dev->driver->load(dev, 0);
+               if (ret)
+                       goto err_g3;
+       }
+
+       /* setup the grouping for the legacy output */
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               ret = drm_mode_group_init_legacy_group(dev,
+                               &dev->primary->mode_group);
+               if (ret)
+                       goto err_g3;
+       }
+
+       list_add_tail(&dev->driver_item, &driver->device_list);
+
+       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+                driver->name, driver->major, driver->minor, driver->patchlevel,
+                driver->date, dev->primary->index);
+
+       return 0;
+
+err_g3:
+       drm_put_minor(&dev->primary);
+err_g2:
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               drm_put_minor(&dev->control);
+err_g1:
+       kfree(dev);
+       return ret;
+}
+EXPORT_SYMBOL(drm_get_platform_dev);
+
+/**
+ * Platform device initialization. Called via drm_init at module load time,
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Initializes a drm_device structures,registering the
+ * stubs
+ *
+ * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+ * after the initialization for driver customization.
+ */
+
+int drm_platform_init(struct drm_driver *driver)
+{
+       return drm_get_platform_dev(driver->platform_device, driver);
+}
index a0c365f2e521a393ead336e55950ba8aa966c11e..d1ad57450df1543af9cc502a281b23661075b331 100644 (file)
@@ -156,6 +156,9 @@ static void drm_master_destroy(struct kref *kref)
                master->unique_len = 0;
        }
 
+       kfree(dev->devname);
+       dev->devname = NULL;
+
        list_for_each_entry_safe(pt, next, &master->magicfree, head) {
                list_del(&pt->head);
                drm_ht_remove_item(&master->magiclist, &pt->hash_item);
@@ -224,7 +227,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
        return 0;
 }
 
-static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
+int drm_fill_in_dev(struct drm_device *dev,
                           const struct pci_device_id *ent,
                           struct drm_driver *driver)
 {
@@ -245,14 +248,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
 
        idr_init(&dev->drw_idr);
 
-       dev->pdev = pdev;
-       dev->pci_device = pdev->device;
-       dev->pci_vendor = pdev->vendor;
-
-#ifdef __alpha__
-       dev->hose = pdev->sysdata;
-#endif
-
        if (drm_ht_create(&dev->map_hash, 12)) {
                return -ENOMEM;
        }
@@ -321,7 +316,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
  * create the proc init entry via proc_init(). This routines assigns
  * minor numbers to secondary heads of multi-headed cards
  */
-static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
+int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
 {
        struct drm_minor *new_minor;
        int ret;
@@ -387,83 +382,6 @@ err_idr:
        return ret;
 }
 
-/**
- * Register.
- *
- * \param pdev - PCI device structure
- * \param ent entry from the PCI ID table with device type flags
- * \return zero on success or a negative number on failure.
- *
- * Attempt to gets inter module "drm" information. If we are first
- * then register the character device and inter module information.
- * Try and register, if we fail to register, backout previous work.
- */
-int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
-               struct drm_driver *driver)
-{
-       struct drm_device *dev;
-       int ret;
-
-       DRM_DEBUG("\n");
-
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return -ENOMEM;
-
-       ret = pci_enable_device(pdev);
-       if (ret)
-               goto err_g1;
-
-       pci_set_master(pdev);
-       if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
-               printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
-               goto err_g2;
-       }
-
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               pci_set_drvdata(pdev, dev);
-               ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
-               if (ret)
-                       goto err_g2;
-       }
-
-       if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
-               goto err_g3;
-
-       if (dev->driver->load) {
-               ret = dev->driver->load(dev, ent->driver_data);
-               if (ret)
-                       goto err_g4;
-       }
-
-        /* setup the grouping for the legacy output */
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
-               if (ret)
-                       goto err_g4;
-       }
-
-       list_add_tail(&dev->driver_item, &driver->device_list);
-
-       DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
-                driver->name, driver->major, driver->minor, driver->patchlevel,
-                driver->date, pci_name(pdev), dev->primary->index);
-
-       return 0;
-
-err_g4:
-       drm_put_minor(&dev->primary);
-err_g3:
-       if (drm_core_check_feature(dev, DRIVER_MODESET))
-               drm_put_minor(&dev->control);
-err_g2:
-       pci_disable_device(pdev);
-err_g1:
-       kfree(dev);
-       return ret;
-}
-EXPORT_SYMBOL(drm_get_dev);
-
 /**
  * Put a secondary minor number.
  *
index 101d381e9d86ced4967677d639753297df43ae77..86118a742231b42fd711f18b64deb182a8d60d3a 100644 (file)
@@ -489,7 +489,8 @@ int drm_sysfs_device_add(struct drm_minor *minor)
        int err;
        char *minor_str;
 
-       minor->kdev.parent = &minor->dev->pdev->dev;
+       minor->kdev.parent = minor->dev->dev;
+
        minor->kdev.class = drm_class;
        minor->kdev.release = drm_sysfs_device_release;
        minor->kdev.devt = minor->device;
diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h
new file mode 100644 (file)
index 0000000..03ea964
--- /dev/null
@@ -0,0 +1,66 @@
+#if !defined(_DRM_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _DRM_TRACE_H_
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM drm
+#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM)
+#define TRACE_INCLUDE_FILE drm_trace
+
+TRACE_EVENT(drm_vblank_event,
+           TP_PROTO(int crtc, unsigned int seq),
+           TP_ARGS(crtc, seq),
+           TP_STRUCT__entry(
+                   __field(int, crtc)
+                   __field(unsigned int, seq)
+                   ),
+           TP_fast_assign(
+                   __entry->crtc = crtc;
+                   __entry->seq = seq;
+                   ),
+           TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq)
+);
+
+TRACE_EVENT(drm_vblank_event_queued,
+           TP_PROTO(pid_t pid, int crtc, unsigned int seq),
+           TP_ARGS(pid, crtc, seq),
+           TP_STRUCT__entry(
+                   __field(pid_t, pid)
+                   __field(int, crtc)
+                   __field(unsigned int, seq)
+                   ),
+           TP_fast_assign(
+                   __entry->pid = pid;
+                   __entry->crtc = crtc;
+                   __entry->seq = seq;
+                   ),
+           TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \
+                     __entry->seq)
+);
+
+TRACE_EVENT(drm_vblank_event_delivered,
+           TP_PROTO(pid_t pid, int crtc, unsigned int seq),
+           TP_ARGS(pid, crtc, seq),
+           TP_STRUCT__entry(
+                   __field(pid_t, pid)
+                   __field(int, crtc)
+                   __field(unsigned int, seq)
+                   ),
+           TP_fast_assign(
+                   __entry->pid = pid;
+                   __entry->crtc = crtc;
+                   __entry->seq = seq;
+                   ),
+           TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \
+                     __entry->seq)
+);
+
+#endif /* _DRM_TRACE_H_ */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/drm_trace_points.c b/drivers/gpu/drm/drm_trace_points.c
new file mode 100644 (file)
index 0000000..0d0eb90
--- /dev/null
@@ -0,0 +1,4 @@
+#include "drmP.h"
+
+#define CREATE_TRACE_POINTS
+#include "drm_trace.h"
index c3b13fb41d0cd557dcf1bf2897d9a5b331356828..3778360eceea0cc44d2f2213090d5e1ed2e670f4 100644 (file)
@@ -61,7 +61,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
                tmp = pgprot_writecombine(tmp);
        else
                tmp = pgprot_noncached(tmp);
-#elif defined(__sparc__)
+#elif defined(__sparc__) || defined(__arm__)
        tmp = pgprot_noncached(tmp);
 #endif
        return tmp;
@@ -601,6 +601,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
        }
 
        switch (map->type) {
+#if !defined(__arm__)
        case _DRM_AGP:
                if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
                        /*
@@ -615,20 +616,31 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
                        break;
                }
                /* fall through to _DRM_FRAME_BUFFER... */
+#endif
        case _DRM_FRAME_BUFFER:
        case _DRM_REGISTERS:
                offset = dev->driver->get_reg_ofs(dev);
                vma->vm_flags |= VM_IO; /* not in core dump */
                vma->vm_page_prot = drm_io_prot(map->type, vma);
+#if !defined(__arm__)
                if (io_remap_pfn_range(vma, vma->vm_start,
                                       (map->offset + offset) >> PAGE_SHIFT,
                                       vma->vm_end - vma->vm_start,
                                       vma->vm_page_prot))
                        return -EAGAIN;
+#else
+               if (remap_pfn_range(vma, vma->vm_start,
+                                       (map->offset + offset) >> PAGE_SHIFT,
+                                       vma->vm_end - vma->vm_start,
+                                       vma->vm_page_prot))
+                       return -EAGAIN;
+#endif
+
                DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
                          " offset = 0x%llx\n",
                          map->type,
                          vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset));
+
                vma->vm_ops = &drm_vm_ops;
                break;
        case _DRM_CONSISTENT:
index 6d2abaf35ba22641a3a8e2d6677ff64fb5571b6e..92862563e7ee3dd8fbafb46d7d319b9dfb432514 100644 (file)
@@ -2,3 +2,6 @@ ccflags-y := -Iinclude/drm
 
 ch7006-y := ch7006_drv.o ch7006_mode.o
 obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o
+
+sil164-y := sil164_drv.o
+obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o
index 81681a07a8060cbdb980765fca9edfc3a270d7ca..833b35f44a7705a336d432940c393016de7cd77d 100644 (file)
@@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder,
 {
        struct ch7006_priv *priv = to_ch7006_priv(encoder);
 
-       priv->params = params;
+       priv->params = *(struct ch7006_encoder_params *)params;
 }
 
 static void ch7006_encoder_destroy(struct drm_encoder *encoder)
@@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder,
 {
        struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
        struct ch7006_priv *priv = to_ch7006_priv(encoder);
-       struct ch7006_encoder_params *params = priv->params;
+       struct ch7006_encoder_params *params = &priv->params;
        struct ch7006_state *state = &priv->state;
        uint8_t *regs = state->regs;
        struct ch7006_mode *mode = priv->mode;
@@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client)
        return 0;
 }
 
+static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+       ch7006_dbg(client, "\n");
+
+       return 0;
+}
+
+static int ch7006_resume(struct i2c_client *client)
+{
+       ch7006_dbg(client, "\n");
+
+       ch7006_write(client, 0x3d, 0x0);
+
+       return 0;
+}
+
 static int ch7006_encoder_init(struct i2c_client *client,
                               struct drm_device *dev,
                               struct drm_encoder_slave *encoder)
@@ -487,6 +503,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = {
        .i2c_driver = {
                .probe = ch7006_probe,
                .remove = ch7006_remove,
+               .suspend = ch7006_suspend,
+               .resume = ch7006_resume,
 
                .driver = {
                        .name = "ch7006",
index b06d3d93d8acb3facfb607691a2d61f11409a025..1c6d2e3bd96f154b636f5b15b34766565143ebd1 100644 (file)
@@ -77,7 +77,7 @@ struct ch7006_state {
 };
 
 struct ch7006_priv {
-       struct ch7006_encoder_params *params;
+       struct ch7006_encoder_params params;
        struct ch7006_mode *mode;
 
        struct ch7006_state state;
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c
new file mode 100644 (file)
index 0000000..0b67732
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "drm_encoder_slave.h"
+#include "i2c/sil164.h"
+
+struct sil164_priv {
+       struct sil164_encoder_params config;
+       struct i2c_client *duallink_slave;
+
+       uint8_t saved_state[0x10];
+       uint8_t saved_slave_state[0x10];
+};
+
+#define to_sil164_priv(x) \
+       ((struct sil164_priv *)to_encoder_slave(x)->slave_priv)
+
+#define sil164_dbg(client, format, ...) do {                           \
+               if (drm_debug & DRM_UT_KMS)                             \
+                       dev_printk(KERN_DEBUG, &client->dev,            \
+                                  "%s: " format, __func__, ## __VA_ARGS__); \
+       } while (0)
+#define sil164_info(client, format, ...)               \
+       dev_info(&client->dev, format, __VA_ARGS__)
+#define sil164_err(client, format, ...)                        \
+       dev_err(&client->dev, format, __VA_ARGS__)
+
+#define SIL164_I2C_ADDR_MASTER                 0x38
+#define SIL164_I2C_ADDR_SLAVE                  0x39
+
+/* HW register definitions */
+
+#define SIL164_VENDOR_LO                       0x0
+#define SIL164_VENDOR_HI                       0x1
+#define SIL164_DEVICE_LO                       0x2
+#define SIL164_DEVICE_HI                       0x3
+#define SIL164_REVISION                                0x4
+#define SIL164_FREQ_MIN                                0x6
+#define SIL164_FREQ_MAX                                0x7
+#define SIL164_CONTROL0                                0x8
+#  define SIL164_CONTROL0_POWER_ON             0x01
+#  define SIL164_CONTROL0_EDGE_RISING          0x02
+#  define SIL164_CONTROL0_INPUT_24BIT          0x04
+#  define SIL164_CONTROL0_DUAL_EDGE            0x08
+#  define SIL164_CONTROL0_HSYNC_ON             0x10
+#  define SIL164_CONTROL0_VSYNC_ON             0x20
+#define SIL164_DETECT                          0x9
+#  define SIL164_DETECT_INTR_STAT              0x01
+#  define SIL164_DETECT_HOTPLUG_STAT           0x02
+#  define SIL164_DETECT_RECEIVER_STAT          0x04
+#  define SIL164_DETECT_INTR_MODE_RECEIVER     0x00
+#  define SIL164_DETECT_INTR_MODE_HOTPLUG      0x08
+#  define SIL164_DETECT_OUT_MODE_HIGH          0x00
+#  define SIL164_DETECT_OUT_MODE_INTR          0x10
+#  define SIL164_DETECT_OUT_MODE_RECEIVER      0x20
+#  define SIL164_DETECT_OUT_MODE_HOTPLUG       0x30
+#  define SIL164_DETECT_VSWING_STAT            0x80
+#define SIL164_CONTROL1                                0xa
+#  define SIL164_CONTROL1_DESKEW_ENABLE                0x10
+#  define SIL164_CONTROL1_DESKEW_INCR_SHIFT    5
+#define SIL164_GPIO                            0xb
+#define SIL164_CONTROL2                                0xc
+#  define SIL164_CONTROL2_FILTER_ENABLE                0x01
+#  define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1
+#  define SIL164_CONTROL2_DUALLINK_MASTER      0x40
+#  define SIL164_CONTROL2_SYNC_CONT            0x80
+#define SIL164_DUALLINK                                0xd
+#  define SIL164_DUALLINK_ENABLE               0x10
+#  define SIL164_DUALLINK_SKEW_SHIFT           5
+#define SIL164_PLLZONE                         0xe
+#  define SIL164_PLLZONE_STAT                  0x08
+#  define SIL164_PLLZONE_FORCE_ON              0x10
+#  define SIL164_PLLZONE_FORCE_HIGH            0x20
+
+/* HW access functions */
+
+static void
+sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val)
+{
+       uint8_t buf[] = {addr, val};
+       int ret;
+
+       ret = i2c_master_send(client, buf, ARRAY_SIZE(buf));
+       if (ret < 0)
+               sil164_err(client, "Error %d writing to subaddress 0x%x\n",
+                          ret, addr);
+}
+
+static uint8_t
+sil164_read(struct i2c_client *client, uint8_t addr)
+{
+       uint8_t val;
+       int ret;
+
+       ret = i2c_master_send(client, &addr, sizeof(addr));
+       if (ret < 0)
+               goto fail;
+
+       ret = i2c_master_recv(client, &val, sizeof(val));
+       if (ret < 0)
+               goto fail;
+
+       return val;
+
+fail:
+       sil164_err(client, "Error %d reading from subaddress 0x%x\n",
+                  ret, addr);
+       return 0;
+}
+
+static void
+sil164_save_state(struct i2c_client *client, uint8_t *state)
+{
+       int i;
+
+       for (i = 0x8; i <= 0xe; i++)
+               state[i] = sil164_read(client, i);
+}
+
+static void
+sil164_restore_state(struct i2c_client *client, uint8_t *state)
+{
+       int i;
+
+       for (i = 0x8; i <= 0xe; i++)
+               sil164_write(client, i, state[i]);
+}
+
+static void
+sil164_set_power_state(struct i2c_client *client, bool on)
+{
+       uint8_t control0 = sil164_read(client, SIL164_CONTROL0);
+
+       if (on)
+               control0 |= SIL164_CONTROL0_POWER_ON;
+       else
+               control0 &= ~SIL164_CONTROL0_POWER_ON;
+
+       sil164_write(client, SIL164_CONTROL0, control0);
+}
+
+static void
+sil164_init_state(struct i2c_client *client,
+                 struct sil164_encoder_params *config,
+                 bool duallink)
+{
+       sil164_write(client, SIL164_CONTROL0,
+                    SIL164_CONTROL0_HSYNC_ON |
+                    SIL164_CONTROL0_VSYNC_ON |
+                    (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) |
+                    (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) |
+                    (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0));
+
+       sil164_write(client, SIL164_DETECT,
+                    SIL164_DETECT_INTR_STAT |
+                    SIL164_DETECT_OUT_MODE_RECEIVER);
+
+       sil164_write(client, SIL164_CONTROL1,
+                    (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) |
+                    (((config->input_skew + 4) & 0x7)
+                     << SIL164_CONTROL1_DESKEW_INCR_SHIFT));
+
+       sil164_write(client, SIL164_CONTROL2,
+                    SIL164_CONTROL2_SYNC_CONT |
+                    (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) |
+                    (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT));
+
+       sil164_write(client, SIL164_PLLZONE, 0);
+
+       if (duallink)
+               sil164_write(client, SIL164_DUALLINK,
+                            SIL164_DUALLINK_ENABLE |
+                            (((config->duallink_skew + 4) & 0x7)
+                             << SIL164_DUALLINK_SKEW_SHIFT));
+       else
+               sil164_write(client, SIL164_DUALLINK, 0);
+}
+
+/* DRM encoder functions */
+
+static void
+sil164_encoder_set_config(struct drm_encoder *encoder, void *params)
+{
+       struct sil164_priv *priv = to_sil164_priv(encoder);
+
+       priv->config = *(struct sil164_encoder_params *)params;
+}
+
+static void
+sil164_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct sil164_priv *priv = to_sil164_priv(encoder);
+       bool on = (mode == DRM_MODE_DPMS_ON);
+       bool duallink = (on && encoder->crtc->mode.clock > 165000);
+
+       sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on);
+
+       if (priv->duallink_slave)
+               sil164_set_power_state(priv->duallink_slave, duallink);
+}
+
+static void
+sil164_encoder_save(struct drm_encoder *encoder)
+{
+       struct sil164_priv *priv = to_sil164_priv(encoder);
+
+       sil164_save_state(drm_i2c_encoder_get_client(encoder),
+                         priv->saved_state);
+
+       if (priv->duallink_slave)
+               sil164_save_state(priv->duallink_slave,
+                                 priv->saved_slave_state);
+}
+
+static void
+sil164_encoder_restore(struct drm_encoder *encoder)
+{
+       struct sil164_priv *priv = to_sil164_priv(encoder);
+
+       sil164_restore_state(drm_i2c_encoder_get_client(encoder),
+                            priv->saved_state);
+
+       if (priv->duallink_slave)
+               sil164_restore_state(priv->duallink_slave,
+                                    priv->saved_slave_state);
+}
+
+static bool
+sil164_encoder_mode_fixup(struct drm_encoder *encoder,
+                         struct drm_display_mode *mode,
+                         struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static int
+sil164_encoder_mode_valid(struct drm_encoder *encoder,
+                         struct drm_display_mode *mode)
+{
+       struct sil164_priv *priv = to_sil164_priv(encoder);
+
+       if (mode->clock < 32000)
+               return MODE_CLOCK_LOW;
+
+       if (mode->clock > 330000 ||
+           (mode->clock > 165000 && !priv->duallink_slave))
+               return MODE_CLOCK_HIGH;
+
+       return MODE_OK;
+}
+
+static void
+sil164_encoder_mode_set(struct drm_encoder *encoder,
+                       struct drm_display_mode *mode,
+                       struct drm_display_mode *adjusted_mode)
+{
+       struct sil164_priv *priv = to_sil164_priv(encoder);
+       bool duallink = adjusted_mode->clock > 165000;
+
+       sil164_init_state(drm_i2c_encoder_get_client(encoder),
+                         &priv->config, duallink);
+
+       if (priv->duallink_slave)
+               sil164_init_state(priv->duallink_slave,
+                                 &priv->config, duallink);
+
+       sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
+}
+
+static enum drm_connector_status
+sil164_encoder_detect(struct drm_encoder *encoder,
+                     struct drm_connector *connector)
+{
+       struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+
+       if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT)
+               return connector_status_connected;
+       else
+               return connector_status_disconnected;
+}
+
+static int
+sil164_encoder_get_modes(struct drm_encoder *encoder,
+                        struct drm_connector *connector)
+{
+       return 0;
+}
+
+static int
+sil164_encoder_create_resources(struct drm_encoder *encoder,
+                               struct drm_connector *connector)
+{
+       return 0;
+}
+
+static int
+sil164_encoder_set_property(struct drm_encoder *encoder,
+                           struct drm_connector *connector,
+                           struct drm_property *property,
+                           uint64_t val)
+{
+       return 0;
+}
+
+static void
+sil164_encoder_destroy(struct drm_encoder *encoder)
+{
+       struct sil164_priv *priv = to_sil164_priv(encoder);
+
+       if (priv->duallink_slave)
+               i2c_unregister_device(priv->duallink_slave);
+
+       kfree(priv);
+       drm_i2c_encoder_destroy(encoder);
+}
+
+static struct drm_encoder_slave_funcs sil164_encoder_funcs = {
+       .set_config = sil164_encoder_set_config,
+       .destroy = sil164_encoder_destroy,
+       .dpms = sil164_encoder_dpms,
+       .save = sil164_encoder_save,
+       .restore = sil164_encoder_restore,
+       .mode_fixup = sil164_encoder_mode_fixup,
+       .mode_valid = sil164_encoder_mode_valid,
+       .mode_set = sil164_encoder_mode_set,
+       .detect = sil164_encoder_detect,
+       .get_modes = sil164_encoder_get_modes,
+       .create_resources = sil164_encoder_create_resources,
+       .set_property = sil164_encoder_set_property,
+};
+
+/* I2C driver functions */
+
+static int
+sil164_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+       int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 |
+               sil164_read(client, SIL164_VENDOR_LO);
+       int device = sil164_read(client, SIL164_DEVICE_HI) << 8 |
+               sil164_read(client, SIL164_DEVICE_LO);
+       int rev = sil164_read(client, SIL164_REVISION);
+
+       if (vendor != 0x1 || device != 0x6) {
+               sil164_dbg(client, "Unknown device %x:%x.%x\n",
+                          vendor, device, rev);
+               return -ENODEV;
+       }
+
+       sil164_info(client, "Detected device %x:%x.%x\n",
+                   vendor, device, rev);
+
+       return 0;
+}
+
+static int
+sil164_remove(struct i2c_client *client)
+{
+       return 0;
+}
+
+static struct i2c_client *
+sil164_detect_slave(struct i2c_client *client)
+{
+       struct i2c_adapter *adap = client->adapter;
+       struct i2c_msg msg = {
+               .addr = SIL164_I2C_ADDR_SLAVE,
+               .len = 0,
+       };
+       const struct i2c_board_info info = {
+               I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE)
+       };
+
+       if (i2c_transfer(adap, &msg, 1) != 1) {
+               sil164_dbg(adap, "No dual-link slave found.");
+               return NULL;
+       }
+
+       return i2c_new_device(adap, &info);
+}
+
+static int
+sil164_encoder_init(struct i2c_client *client,
+                   struct drm_device *dev,
+                   struct drm_encoder_slave *encoder)
+{
+       struct sil164_priv *priv;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       encoder->slave_priv = priv;
+       encoder->slave_funcs = &sil164_encoder_funcs;
+
+       priv->duallink_slave = sil164_detect_slave(client);
+
+       return 0;
+}
+
+static struct i2c_device_id sil164_ids[] = {
+       { "sil164", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, sil164_ids);
+
+static struct drm_i2c_encoder_driver sil164_driver = {
+       .i2c_driver = {
+               .probe = sil164_probe,
+               .remove = sil164_remove,
+               .driver = {
+                       .name = "sil164",
+               },
+               .id_table = sil164_ids,
+       },
+       .encoder_init = sil164_encoder_init,
+};
+
+/* Module initialization */
+
+static int __init
+sil164_init(void)
+{
+       return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver);
+}
+
+static void __exit
+sil164_exit(void)
+{
+       drm_i2c_encoder_unregister(&sil164_driver);
+}
+
+MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>");
+MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver");
+MODULE_LICENSE("GPL and additional rights");
+
+module_init(sil164_init);
+module_exit(sil164_exit);
index 997d91707ad217f545c9720c0b0b9a604617f7e2..0e6c131313d95b48e62a6dab63730049c7332355 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/interrupt.h>   /* For task queue support */
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 
 #define I810_BUF_FREE          2
@@ -60,9 +61,8 @@ static struct drm_buf *i810_freelist_get(struct drm_device * dev)
                /* In use is already a pointer */
                used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
                               I810_BUF_CLIENT);
-               if (used == I810_BUF_FREE) {
+               if (used == I810_BUF_FREE)
                        return buf;
-               }
        }
        return NULL;
 }
@@ -71,7 +71,7 @@ static struct drm_buf *i810_freelist_get(struct drm_device * dev)
  * yet, the hardware updates in use for us once its on the ring buffer.
  */
 
-static int i810_freelist_put(struct drm_device * dev, struct drm_buf * buf)
+static int i810_freelist_put(struct drm_device *dev, struct drm_buf *buf)
 {
        drm_i810_buf_priv_t *buf_priv = buf->dev_private;
        int used;
@@ -121,7 +121,7 @@ static const struct file_operations i810_buffer_fops = {
        .fasync = drm_fasync,
 };
 
-static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
+static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
 {
        struct drm_device *dev = file_priv->minor->dev;
        drm_i810_buf_priv_t *buf_priv = buf->dev_private;
@@ -152,7 +152,7 @@ static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
        return retcode;
 }
 
-static int i810_unmap_buffer(struct drm_buf * buf)
+static int i810_unmap_buffer(struct drm_buf *buf)
 {
        drm_i810_buf_priv_t *buf_priv = buf->dev_private;
        int retcode = 0;
@@ -172,7 +172,7 @@ static int i810_unmap_buffer(struct drm_buf * buf)
        return retcode;
 }
 
-static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d,
+static int i810_dma_get_buffer(struct drm_device *dev, drm_i810_dma_t *d,
                               struct drm_file *file_priv)
 {
        struct drm_buf *buf;
@@ -202,7 +202,7 @@ static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d,
        return retcode;
 }
 
-static int i810_dma_cleanup(struct drm_device * dev)
+static int i810_dma_cleanup(struct drm_device *dev)
 {
        struct drm_device_dma *dma = dev->dma;
 
@@ -218,9 +218,8 @@ static int i810_dma_cleanup(struct drm_device * dev)
                drm_i810_private_t *dev_priv =
                    (drm_i810_private_t *) dev->dev_private;
 
-               if (dev_priv->ring.virtual_start) {
+               if (dev_priv->ring.virtual_start)
                        drm_core_ioremapfree(&dev_priv->ring.map, dev);
-               }
                if (dev_priv->hw_status_page) {
                        pci_free_consistent(dev->pdev, PAGE_SIZE,
                                            dev_priv->hw_status_page,
@@ -242,7 +241,7 @@ static int i810_dma_cleanup(struct drm_device * dev)
        return 0;
 }
 
-static int i810_wait_ring(struct drm_device * dev, int n)
+static int i810_wait_ring(struct drm_device *dev, int n)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
@@ -271,11 +270,11 @@ static int i810_wait_ring(struct drm_device * dev, int n)
                udelay(1);
        }
 
-      out_wait_ring:
+out_wait_ring:
        return iters;
 }
 
-static void i810_kernel_lost_context(struct drm_device * dev)
+static void i810_kernel_lost_context(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
@@ -287,7 +286,7 @@ static void i810_kernel_lost_context(struct drm_device * dev)
                ring->space += ring->Size;
 }
 
-static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_priv)
+static int i810_freelist_init(struct drm_device *dev, drm_i810_private_t *dev_priv)
 {
        struct drm_device_dma *dma = dev->dma;
        int my_idx = 24;
@@ -322,9 +321,9 @@ static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_
        return 0;
 }
 
-static int i810_dma_initialize(struct drm_device * dev,
-                              drm_i810_private_t * dev_priv,
-                              drm_i810_init_t * init)
+static int i810_dma_initialize(struct drm_device *dev,
+                              drm_i810_private_t *dev_priv,
+                              drm_i810_init_t *init)
 {
        struct drm_map_list *r_list;
        memset(dev_priv, 0, sizeof(drm_i810_private_t));
@@ -462,7 +461,7 @@ static int i810_dma_init(struct drm_device *dev, void *data,
  * Use 'volatile' & local var tmp to force the emitted values to be
  * identical to the verified ones.
  */
-static void i810EmitContextVerified(struct drm_device * dev,
+static void i810EmitContextVerified(struct drm_device *dev,
                                    volatile unsigned int *code)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
@@ -495,7 +494,7 @@ static void i810EmitContextVerified(struct drm_device * dev,
        ADVANCE_LP_RING();
 }
 
-static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int *code)
+static void i810EmitTexVerified(struct drm_device *dev, volatile unsigned int *code)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        int i, j = 0;
@@ -528,7 +527,7 @@ static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int *
 
 /* Need to do some additional checking when setting the dest buffer.
  */
-static void i810EmitDestVerified(struct drm_device * dev,
+static void i810EmitDestVerified(struct drm_device *dev,
                                 volatile unsigned int *code)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
@@ -563,7 +562,7 @@ static void i810EmitDestVerified(struct drm_device * dev,
        ADVANCE_LP_RING();
 }
 
-static void i810EmitState(struct drm_device * dev)
+static void i810EmitState(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -594,7 +593,7 @@ static void i810EmitState(struct drm_device * dev)
 
 /* need to verify
  */
-static void i810_dma_dispatch_clear(struct drm_device * dev, int flags,
+static void i810_dma_dispatch_clear(struct drm_device *dev, int flags,
                                    unsigned int clear_color,
                                    unsigned int clear_zval)
 {
@@ -669,7 +668,7 @@ static void i810_dma_dispatch_clear(struct drm_device * dev, int flags,
        }
 }
 
-static void i810_dma_dispatch_swap(struct drm_device * dev)
+static void i810_dma_dispatch_swap(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -715,8 +714,8 @@ static void i810_dma_dispatch_swap(struct drm_device * dev)
        }
 }
 
-static void i810_dma_dispatch_vertex(struct drm_device * dev,
-                                    struct drm_buf * buf, int discard, int used)
+static void i810_dma_dispatch_vertex(struct drm_device *dev,
+                                    struct drm_buf *buf, int discard, int used)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        drm_i810_buf_priv_t *buf_priv = buf->dev_private;
@@ -795,7 +794,7 @@ static void i810_dma_dispatch_vertex(struct drm_device * dev,
        }
 }
 
-static void i810_dma_dispatch_flip(struct drm_device * dev)
+static void i810_dma_dispatch_flip(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        int pitch = dev_priv->pitch;
@@ -841,7 +840,7 @@ static void i810_dma_dispatch_flip(struct drm_device * dev)
 
 }
 
-static void i810_dma_quiescent(struct drm_device * dev)
+static void i810_dma_quiescent(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
@@ -858,7 +857,7 @@ static void i810_dma_quiescent(struct drm_device * dev)
        i810_wait_ring(dev, dev_priv->ring.Size - 8);
 }
 
-static int i810_flush_queue(struct drm_device * dev)
+static int i810_flush_queue(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        struct drm_device_dma *dma = dev->dma;
@@ -891,7 +890,7 @@ static int i810_flush_queue(struct drm_device * dev)
 }
 
 /* Must be called with the lock held */
-static void i810_reclaim_buffers(struct drm_device * dev,
+static void i810_reclaim_buffers(struct drm_device *dev,
                                 struct drm_file *file_priv)
 {
        struct drm_device_dma *dma = dev->dma;
@@ -969,9 +968,8 @@ static int i810_clear_bufs(struct drm_device *dev, void *data,
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        /* GH: Someone's doing nasty things... */
-       if (!dev->dev_private) {
+       if (!dev->dev_private)
                return -EINVAL;
-       }
 
        i810_dma_dispatch_clear(dev, clear->flags,
                                clear->clear_color, clear->clear_depth);
@@ -1039,7 +1037,7 @@ static int i810_docopy(struct drm_device *dev, void *data,
        return 0;
 }
 
-static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, int used,
+static void i810_dma_dispatch_mc(struct drm_device *dev, struct drm_buf *buf, int used,
                                 unsigned int last_render)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1053,9 +1051,8 @@ static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf,
        i810_kernel_lost_context(dev);
 
        u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE);
-       if (u != I810_BUF_CLIENT) {
+       if (u != I810_BUF_CLIENT)
                DRM_DEBUG("MC found buffer that isn't mine!\n");
-       }
 
        if (used > 4 * 1024)
                used = 0;
@@ -1160,7 +1157,7 @@ static int i810_ov0_flip(struct drm_device *dev, void *data,
 
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-       //Tell the overlay to update
+       /* Tell the overlay to update */
        I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000);
 
        return 0;
@@ -1168,7 +1165,7 @@ static int i810_ov0_flip(struct drm_device *dev, void *data,
 
 /* Not sure why this isn't set all the time:
  */
-static void i810_do_init_pageflip(struct drm_device * dev)
+static void i810_do_init_pageflip(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
 
@@ -1178,7 +1175,7 @@ static void i810_do_init_pageflip(struct drm_device * dev)
        dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
 }
 
-static int i810_do_cleanup_pageflip(struct drm_device * dev)
+static int i810_do_cleanup_pageflip(struct drm_device *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
 
@@ -1218,49 +1215,61 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags)
        return 0;
 }
 
-void i810_driver_lastclose(struct drm_device * dev)
+void i810_driver_lastclose(struct drm_device *dev)
 {
        i810_dma_cleanup(dev);
 }
 
-void i810_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
+void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
 {
        if (dev->dev_private) {
                drm_i810_private_t *dev_priv = dev->dev_private;
-               if (dev_priv->page_flipping) {
+               if (dev_priv->page_flipping)
                        i810_do_cleanup_pageflip(dev);
-               }
        }
 }
 
-void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
+void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
                                        struct drm_file *file_priv)
 {
        i810_reclaim_buffers(dev, file_priv);
 }
 
-int i810_driver_dma_quiescent(struct drm_device * dev)
+int i810_driver_dma_quiescent(struct drm_device *dev)
 {
        i810_dma_quiescent(dev);
        return 0;
 }
 
+/*
+ * call the drm_ioctl under the big kernel lock because
+ * to lock against the i810_mmap_buffers function.
+ */
+long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       int ret;
+       lock_kernel();
+       ret = drm_ioctl(file, cmd, arg);
+       unlock_kernel();
+       return ret;
+}
+
 struct drm_ioctl_desc i810_ioctls[] = {
-       DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH)
+       DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
 };
 
 int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
@@ -1276,7 +1285,7 @@ int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
  * \returns
  * A value of 1 is always retured to indictate every i810 is AGP.
  */
-int i810_driver_device_is_agp(struct drm_device * dev)
+int i810_driver_device_is_agp(struct drm_device *dev)
 {
        return 1;
 }
index c1e02752e023cdf13107e88d3825235e91411cdd..b4250b2cac1ff446d1a1f5e67a77fd1a1572ded6 100644 (file)
@@ -59,7 +59,7 @@ static struct drm_driver driver = {
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .unlocked_ioctl = drm_ioctl,
+                .unlocked_ioctl = i810_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
index 21e2691f28f953c2ab84234b65c4bae0a1bc11bb..c9339f48179551dacd84b03bd74bd327d4750d80 100644 (file)
@@ -115,56 +115,59 @@ typedef struct drm_i810_private {
 } drm_i810_private_t;
 
                                /* i810_dma.c */
-extern int i810_driver_dma_quiescent(struct drm_device * dev);
-extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
+extern int i810_driver_dma_quiescent(struct drm_device *dev);
+extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
                                               struct drm_file *file_priv);
 extern int i810_driver_load(struct drm_device *, unsigned long flags);
-extern void i810_driver_lastclose(struct drm_device * dev);
-extern void i810_driver_preclose(struct drm_device * dev,
+extern void i810_driver_lastclose(struct drm_device *dev);
+extern void i810_driver_preclose(struct drm_device *dev,
                                 struct drm_file *file_priv);
-extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
+extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
                                               struct drm_file *file_priv);
-extern int i810_driver_device_is_agp(struct drm_device * dev);
+extern int i810_driver_device_is_agp(struct drm_device *dev);
 
+extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 extern struct drm_ioctl_desc i810_ioctls[];
 extern int i810_max_ioctl;
 
 #define I810_BASE(reg)         ((unsigned long) \
                                dev_priv->mmio_map->handle)
 #define I810_ADDR(reg)         (I810_BASE(reg) + reg)
-#define I810_DEREF(reg)                *(__volatile__ int *)I810_ADDR(reg)
+#define I810_DEREF(reg)                (*(__volatile__ int *)I810_ADDR(reg))
 #define I810_READ(reg)         I810_DEREF(reg)
-#define I810_WRITE(reg,val)    do { I810_DEREF(reg) = val; } while (0)
-#define I810_DEREF16(reg)      *(__volatile__ u16 *)I810_ADDR(reg)
+#define I810_WRITE(reg, val)   do { I810_DEREF(reg) = val; } while (0)
+#define I810_DEREF16(reg)      (*(__volatile__ u16 *)I810_ADDR(reg))
 #define I810_READ16(reg)       I810_DEREF16(reg)
-#define I810_WRITE16(reg,val)  do { I810_DEREF16(reg) = val; } while (0)
+#define I810_WRITE16(reg, val) do { I810_DEREF16(reg) = val; } while (0)
 
 #define I810_VERBOSE 0
 #define RING_LOCALS    unsigned int outring, ringmask; \
-                        volatile char *virt;
-
-#define BEGIN_LP_RING(n) do {                                          \
-       if (I810_VERBOSE)                                               \
-               DRM_DEBUG("BEGIN_LP_RING(%d)\n", n);                    \
-       if (dev_priv->ring.space < n*4)                                 \
-               i810_wait_ring(dev, n*4);                               \
-       dev_priv->ring.space -= n*4;                                    \
-       outring = dev_priv->ring.tail;                                  \
-       ringmask = dev_priv->ring.tail_mask;                            \
-       virt = dev_priv->ring.virtual_start;                            \
+                       volatile char *virt;
+
+#define BEGIN_LP_RING(n) do {                                  \
+       if (I810_VERBOSE)                                       \
+               DRM_DEBUG("BEGIN_LP_RING(%d)\n", n);            \
+       if (dev_priv->ring.space < n*4)                         \
+               i810_wait_ring(dev, n*4);                       \
+       dev_priv->ring.space -= n*4;                            \
+       outring = dev_priv->ring.tail;                          \
+       ringmask = dev_priv->ring.tail_mask;                    \
+       virt = dev_priv->ring.virtual_start;                    \
 } while (0)
 
-#define ADVANCE_LP_RING() do {                                 \
-       if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n");       \
+#define ADVANCE_LP_RING() do {                                 \
+       if (I810_VERBOSE)                                       \
+               DRM_DEBUG("ADVANCE_LP_RING\n");                 \
        dev_priv->ring.tail = outring;                          \
-       I810_WRITE(LP_RING + RING_TAIL, outring);               \
-} while(0)
-
-#define OUT_RING(n) do {                                               \
-       if (I810_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));      \
-       *(volatile unsigned int *)(virt + outring) = n;                 \
-       outring += 4;                                                   \
-       outring &= ringmask;                                            \
+       I810_WRITE(LP_RING + RING_TAIL, outring);               \
+} while (0)
+
+#define OUT_RING(n) do {                                       \
+       if (I810_VERBOSE)                                       \
+               DRM_DEBUG("   OUT_RING %x\n", (int)(n));        \
+       *(volatile unsigned int *)(virt + outring) = n;         \
+       outring += 4;                                           \
+       outring &= ringmask;                                    \
 } while (0)
 
 #define GFX_OP_USER_INTERRUPT          ((0<<29)|(2<<23))
index 65759a9a85c8e425714c3281f080880eaaf8d0fc..5168862c92271e5d7fddfb48d3470f4f70113d92 100644 (file)
@@ -36,6 +36,7 @@
 #include "i830_drm.h"
 #include "i830_drv.h"
 #include <linux/interrupt.h>   /* For task queue support */
+#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
@@ -62,9 +63,8 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev)
                /* In use is already a pointer */
                used = cmpxchg(buf_priv->in_use, I830_BUF_FREE,
                               I830_BUF_CLIENT);
-               if (used == I830_BUF_FREE) {
+               if (used == I830_BUF_FREE)
                        return buf;
-               }
        }
        return NULL;
 }
@@ -73,7 +73,7 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev)
  * yet, the hardware updates in use for us once its on the ring buffer.
  */
 
-static int i830_freelist_put(struct drm_device * dev, struct drm_buf * buf)
+static int i830_freelist_put(struct drm_device *dev, struct drm_buf *buf)
 {
        drm_i830_buf_priv_t *buf_priv = buf->dev_private;
        int used;
@@ -123,7 +123,7 @@ static const struct file_operations i830_buffer_fops = {
        .fasync = drm_fasync,
 };
 
-static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
+static int i830_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
 {
        struct drm_device *dev = file_priv->minor->dev;
        drm_i830_buf_priv_t *buf_priv = buf->dev_private;
@@ -156,7 +156,7 @@ static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
        return retcode;
 }
 
-static int i830_unmap_buffer(struct drm_buf * buf)
+static int i830_unmap_buffer(struct drm_buf *buf)
 {
        drm_i830_buf_priv_t *buf_priv = buf->dev_private;
        int retcode = 0;
@@ -176,7 +176,7 @@ static int i830_unmap_buffer(struct drm_buf * buf)
        return retcode;
 }
 
-static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d,
+static int i830_dma_get_buffer(struct drm_device *dev, drm_i830_dma_t *d,
                               struct drm_file *file_priv)
 {
        struct drm_buf *buf;
@@ -206,7 +206,7 @@ static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d,
        return retcode;
 }
 
-static int i830_dma_cleanup(struct drm_device * dev)
+static int i830_dma_cleanup(struct drm_device *dev)
 {
        struct drm_device_dma *dma = dev->dma;
 
@@ -222,9 +222,8 @@ static int i830_dma_cleanup(struct drm_device * dev)
                drm_i830_private_t *dev_priv =
                    (drm_i830_private_t *) dev->dev_private;
 
-               if (dev_priv->ring.virtual_start) {
+               if (dev_priv->ring.virtual_start)
                        drm_core_ioremapfree(&dev_priv->ring.map, dev);
-               }
                if (dev_priv->hw_status_page) {
                        pci_free_consistent(dev->pdev, PAGE_SIZE,
                                            dev_priv->hw_status_page,
@@ -246,7 +245,7 @@ static int i830_dma_cleanup(struct drm_device * dev)
        return 0;
 }
 
-int i830_wait_ring(struct drm_device * dev, int n, const char *caller)
+int i830_wait_ring(struct drm_device *dev, int n, const char *caller)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
@@ -276,11 +275,11 @@ int i830_wait_ring(struct drm_device * dev, int n, const char *caller)
                dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
        }
 
-      out_wait_ring:
+out_wait_ring:
        return iters;
 }
 
-static void i830_kernel_lost_context(struct drm_device * dev)
+static void i830_kernel_lost_context(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
@@ -295,7 +294,7 @@ static void i830_kernel_lost_context(struct drm_device * dev)
                dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
 }
 
-static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_priv)
+static int i830_freelist_init(struct drm_device *dev, drm_i830_private_t *dev_priv)
 {
        struct drm_device_dma *dma = dev->dma;
        int my_idx = 36;
@@ -329,9 +328,9 @@ static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_
        return 0;
 }
 
-static int i830_dma_initialize(struct drm_device * dev,
-                              drm_i830_private_t * dev_priv,
-                              drm_i830_init_t * init)
+static int i830_dma_initialize(struct drm_device *dev,
+                              drm_i830_private_t *dev_priv,
+                              drm_i830_init_t *init)
 {
        struct drm_map_list *r_list;
 
@@ -482,7 +481,7 @@ static int i830_dma_init(struct drm_device *dev, void *data,
 /* Most efficient way to verify state for the i830 is as it is
  * emitted.  Non-conformant state is silently dropped.
  */
-static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code)
+static void i830EmitContextVerified(struct drm_device *dev, unsigned int *code)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        int i, j = 0;
@@ -527,7 +526,7 @@ static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code)
        ADVANCE_LP_RING();
 }
 
-static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code)
+static void i830EmitTexVerified(struct drm_device *dev, unsigned int *code)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        int i, j = 0;
@@ -561,7 +560,7 @@ static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code)
                printk("rejected packet %x\n", code[0]);
 }
 
-static void i830EmitTexBlendVerified(struct drm_device * dev,
+static void i830EmitTexBlendVerified(struct drm_device *dev,
                                     unsigned int *code, unsigned int num)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
@@ -586,7 +585,7 @@ static void i830EmitTexBlendVerified(struct drm_device * dev,
        ADVANCE_LP_RING();
 }
 
-static void i830EmitTexPalette(struct drm_device * dev,
+static void i830EmitTexPalette(struct drm_device *dev,
                               unsigned int *palette, int number, int is_shared)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
@@ -603,9 +602,8 @@ static void i830EmitTexPalette(struct drm_device * dev,
        } else {
                OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number));
        }
-       for (i = 0; i < 256; i++) {
+       for (i = 0; i < 256; i++)
                OUT_RING(palette[i]);
-       }
        OUT_RING(0);
        /* KW:  WHERE IS THE ADVANCE_LP_RING?  This is effectively a noop!
         */
@@ -613,7 +611,7 @@ static void i830EmitTexPalette(struct drm_device * dev,
 
 /* Need to do some additional checking when setting the dest buffer.
  */
-static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code)
+static void i830EmitDestVerified(struct drm_device *dev, unsigned int *code)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        unsigned int tmp;
@@ -674,7 +672,7 @@ static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code)
        ADVANCE_LP_RING();
 }
 
-static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code)
+static void i830EmitStippleVerified(struct drm_device *dev, unsigned int *code)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
@@ -685,7 +683,7 @@ static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code)
        ADVANCE_LP_RING();
 }
 
-static void i830EmitState(struct drm_device * dev)
+static void i830EmitState(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -788,7 +786,7 @@ static void i830EmitState(struct drm_device * dev)
  * Performance monitoring functions
  */
 
-static void i830_fill_box(struct drm_device * dev,
+static void i830_fill_box(struct drm_device *dev,
                          int x, int y, int w, int h, int r, int g, int b)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
@@ -816,17 +814,16 @@ static void i830_fill_box(struct drm_device * dev,
        OUT_RING((y << 16) | x);
        OUT_RING(((y + h) << 16) | (x + w));
 
-       if (dev_priv->current_page == 1) {
+       if (dev_priv->current_page == 1)
                OUT_RING(dev_priv->front_offset);
-       } else {
+       else
                OUT_RING(dev_priv->back_offset);
-       }
 
        OUT_RING(color);
        ADVANCE_LP_RING();
 }
 
-static void i830_cp_performance_boxes(struct drm_device * dev)
+static void i830_cp_performance_boxes(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
 
@@ -871,7 +868,7 @@ static void i830_cp_performance_boxes(struct drm_device * dev)
        dev_priv->sarea_priv->perf_boxes = 0;
 }
 
-static void i830_dma_dispatch_clear(struct drm_device * dev, int flags,
+static void i830_dma_dispatch_clear(struct drm_device *dev, int flags,
                                    unsigned int clear_color,
                                    unsigned int clear_zval,
                                    unsigned int clear_depthmask)
@@ -966,7 +963,7 @@ static void i830_dma_dispatch_clear(struct drm_device * dev, int flags,
        }
 }
 
-static void i830_dma_dispatch_swap(struct drm_device * dev)
+static void i830_dma_dispatch_swap(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -1036,7 +1033,7 @@ static void i830_dma_dispatch_swap(struct drm_device * dev)
        }
 }
 
-static void i830_dma_dispatch_flip(struct drm_device * dev)
+static void i830_dma_dispatch_flip(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
@@ -1079,8 +1076,8 @@ static void i830_dma_dispatch_flip(struct drm_device * dev)
        dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
 }
 
-static void i830_dma_dispatch_vertex(struct drm_device * dev,
-                                    struct drm_buf * buf, int discard, int used)
+static void i830_dma_dispatch_vertex(struct drm_device *dev,
+                                    struct drm_buf *buf, int discard, int used)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        drm_i830_buf_priv_t *buf_priv = buf->dev_private;
@@ -1100,9 +1097,8 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev,
        if (discard) {
                u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
                            I830_BUF_HARDWARE);
-               if (u != I830_BUF_CLIENT) {
+               if (u != I830_BUF_CLIENT)
                        DRM_DEBUG("xxxx 2\n");
-               }
        }
 
        if (used > 4 * 1023)
@@ -1191,7 +1187,7 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev,
        }
 }
 
-static void i830_dma_quiescent(struct drm_device * dev)
+static void i830_dma_quiescent(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
@@ -1208,7 +1204,7 @@ static void i830_dma_quiescent(struct drm_device * dev)
        i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
 }
 
-static int i830_flush_queue(struct drm_device * dev)
+static int i830_flush_queue(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        struct drm_device_dma *dma = dev->dma;
@@ -1241,7 +1237,7 @@ static int i830_flush_queue(struct drm_device * dev)
 }
 
 /* Must be called with the lock held */
-static void i830_reclaim_buffers(struct drm_device * dev, struct drm_file *file_priv)
+static void i830_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv)
 {
        struct drm_device_dma *dma = dev->dma;
        int i;
@@ -1316,9 +1312,8 @@ static int i830_clear_bufs(struct drm_device *dev, void *data,
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        /* GH: Someone's doing nasty things... */
-       if (!dev->dev_private) {
+       if (!dev->dev_private)
                return -EINVAL;
-       }
 
        i830_dma_dispatch_clear(dev, clear->flags,
                                clear->clear_color,
@@ -1339,7 +1334,7 @@ static int i830_swap_bufs(struct drm_device *dev, void *data,
 
 /* Not sure why this isn't set all the time:
  */
-static void i830_do_init_pageflip(struct drm_device * dev)
+static void i830_do_init_pageflip(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
 
@@ -1349,7 +1344,7 @@ static void i830_do_init_pageflip(struct drm_device * dev)
        dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
 }
 
-static int i830_do_cleanup_pageflip(struct drm_device * dev)
+static int i830_do_cleanup_pageflip(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
 
@@ -1490,47 +1485,59 @@ int i830_driver_load(struct drm_device *dev, unsigned long flags)
        return 0;
 }
 
-void i830_driver_lastclose(struct drm_device * dev)
+void i830_driver_lastclose(struct drm_device *dev)
 {
        i830_dma_cleanup(dev);
 }
 
-void i830_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
+void i830_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
 {
        if (dev->dev_private) {
                drm_i830_private_t *dev_priv = dev->dev_private;
-               if (dev_priv->page_flipping) {
+               if (dev_priv->page_flipping)
                        i830_do_cleanup_pageflip(dev);
-               }
        }
 }
 
-void i830_driver_reclaim_buffers_locked(struct drm_device * dev, struct drm_file *file_priv)
+void i830_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv)
 {
        i830_reclaim_buffers(dev, file_priv);
 }
 
-int i830_driver_dma_quiescent(struct drm_device * dev)
+int i830_driver_dma_quiescent(struct drm_device *dev)
 {
        i830_dma_quiescent(dev);
        return 0;
 }
 
+/*
+ * call the drm_ioctl under the big kernel lock because
+ * to lock against the i830_mmap_buffers function.
+ */
+long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       int ret;
+       lock_kernel();
+       ret = drm_ioctl(file, cmd, arg);
+       unlock_kernel();
+       return ret;
+}
+
 struct drm_ioctl_desc i830_ioctls[] = {
-       DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH)
+       DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED),
 };
 
 int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
@@ -1546,7 +1553,7 @@ int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
  * \returns
  * A value of 1 is always retured to indictate every i8xx is AGP.
  */
-int i830_driver_device_is_agp(struct drm_device * dev)
+int i830_driver_device_is_agp(struct drm_device *dev)
 {
        return 1;
 }
index 44f990bed8f42347fa7404bf117fad9b3bb9a159..a5c66aa82f0c1cd9246b8ea3c66c29f0bc7cd1e2 100644 (file)
@@ -70,7 +70,7 @@ static struct drm_driver driver = {
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .unlocked_ioctl = drm_ioctl,
+                .unlocked_ioctl = i830_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
index da82afe4ded5664734bc8869b055206dcb245a1c..0df1c720560b84c2bc2547fc7c1a0dfba18d8132 100644 (file)
@@ -122,6 +122,7 @@ typedef struct drm_i830_private {
 
 } drm_i830_private_t;
 
+long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 extern struct drm_ioctl_desc i830_ioctls[];
 extern int i830_max_ioctl;
 
@@ -132,33 +133,33 @@ extern int i830_irq_wait(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
 
 extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
-extern void i830_driver_irq_preinstall(struct drm_device * dev);
-extern void i830_driver_irq_postinstall(struct drm_device * dev);
-extern void i830_driver_irq_uninstall(struct drm_device * dev);
+extern void i830_driver_irq_preinstall(struct drm_device *dev);
+extern void i830_driver_irq_postinstall(struct drm_device *dev);
+extern void i830_driver_irq_uninstall(struct drm_device *dev);
 extern int i830_driver_load(struct drm_device *, unsigned long flags);
-extern void i830_driver_preclose(struct drm_device * dev,
+extern void i830_driver_preclose(struct drm_device *dev,
                                 struct drm_file *file_priv);
-extern void i830_driver_lastclose(struct drm_device * dev);
-extern void i830_driver_reclaim_buffers_locked(struct drm_device * dev,
+extern void i830_driver_lastclose(struct drm_device *dev);
+extern void i830_driver_reclaim_buffers_locked(struct drm_device *dev,
                                               struct drm_file *file_priv);
-extern int i830_driver_dma_quiescent(struct drm_device * dev);
-extern int i830_driver_device_is_agp(struct drm_device * dev);
+extern int i830_driver_dma_quiescent(struct drm_device *dev);
+extern int i830_driver_device_is_agp(struct drm_device *dev);
 
-#define I830_READ(reg)          DRM_READ32(dev_priv->mmio_map, reg)
-#define I830_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, reg, val)
-#define I830_READ16(reg)        DRM_READ16(dev_priv->mmio_map, reg)
-#define I830_WRITE16(reg,val)   DRM_WRITE16(dev_priv->mmio_map, reg, val)
+#define I830_READ(reg)         DRM_READ32(dev_priv->mmio_map, reg)
+#define I830_WRITE(reg, val)   DRM_WRITE32(dev_priv->mmio_map, reg, val)
+#define I830_READ16(reg)       DRM_READ16(dev_priv->mmio_map, reg)
+#define I830_WRITE16(reg, val) DRM_WRITE16(dev_priv->mmio_map, reg, val)
 
 #define I830_VERBOSE 0
 
 #define RING_LOCALS    unsigned int outring, ringmask, outcount; \
-                        volatile char *virt;
+                       volatile char *virt;
 
 #define BEGIN_LP_RING(n) do {                          \
        if (I830_VERBOSE)                               \
                printk("BEGIN_LP_RING(%d)\n", (n));     \
        if (dev_priv->ring.space < n*4)                 \
-               i830_wait_ring(dev, n*4, __func__);             \
+               i830_wait_ring(dev, n*4, __func__);     \
        outcount = 0;                                   \
        outring = dev_priv->ring.tail;                  \
        ringmask = dev_priv->ring.tail_mask;            \
@@ -166,21 +167,23 @@ extern int i830_driver_device_is_agp(struct drm_device * dev);
 } while (0)
 
 #define OUT_RING(n) do {                                       \
-       if (I830_VERBOSE) printk("   OUT_RING %x\n", (int)(n)); \
+       if (I830_VERBOSE)                                       \
+               printk("   OUT_RING %x\n", (int)(n));           \
        *(volatile unsigned int *)(virt + outring) = n;         \
-        outcount++;                                            \
+       outcount++;                                             \
        outring += 4;                                           \
        outring &= ringmask;                                    \
 } while (0)
 
-#define ADVANCE_LP_RING() do {                                         \
-       if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring);      \
-       dev_priv->ring.tail = outring;                                  \
-       dev_priv->ring.space -= outcount * 4;                           \
-       I830_WRITE(LP_RING + RING_TAIL, outring);                       \
-} while(0)
+#define ADVANCE_LP_RING() do {                                 \
+       if (I830_VERBOSE)                                       \
+               printk("ADVANCE_LP_RING %x\n", outring);        \
+       dev_priv->ring.tail = outring;                          \
+       dev_priv->ring.space -= outcount * 4;                   \
+       I830_WRITE(LP_RING + RING_TAIL, outring);               \
+} while (0)
 
-extern int i830_wait_ring(struct drm_device * dev, int n, const char *caller);
+extern int i830_wait_ring(struct drm_device *dev, int n, const char *caller);
 
 #define GFX_OP_USER_INTERRUPT          ((0<<29)|(2<<23))
 #define GFX_OP_BREAKPOINT_INTERRUPT    ((0<<29)|(1<<23))
index 91ec2bb497e97d6622be7f38c048360402f4caf9..d1a6b95d631d7ea819299f5010866306111070d2 100644 (file)
@@ -53,7 +53,7 @@ irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS)
        return IRQ_HANDLED;
 }
 
-static int i830_emit_irq(struct drm_device * dev)
+static int i830_emit_irq(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
@@ -70,7 +70,7 @@ static int i830_emit_irq(struct drm_device * dev)
        return atomic_read(&dev_priv->irq_emitted);
 }
 
-static int i830_wait_irq(struct drm_device * dev, int irq_nr)
+static int i830_wait_irq(struct drm_device *dev, int irq_nr)
 {
        drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
        DECLARE_WAITQUEUE(entry, current);
@@ -156,7 +156,7 @@ int i830_irq_wait(struct drm_device *dev, void *data,
 
 /* drm_dma.h hooks
 */
-void i830_driver_irq_preinstall(struct drm_device * dev)
+void i830_driver_irq_preinstall(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
 
@@ -168,14 +168,14 @@ void i830_driver_irq_preinstall(struct drm_device * dev)
        init_waitqueue_head(&dev_priv->irq_queue);
 }
 
-void i830_driver_irq_postinstall(struct drm_device * dev)
+void i830_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
 
        I830_WRITE16(I830REG_INT_ENABLE_R, 0x2);
 }
 
-void i830_driver_irq_uninstall(struct drm_device * dev)
+void i830_driver_irq_uninstall(struct drm_device *dev)
 {
        drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
        if (!dev_priv)
index 2305a1234f1e5727cf835227ff2422ed930ce097..f19ffe87af3c3fbcef67e03a25a6e4a22e5fe133 100644 (file)
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "i915_trace.h"
+#include <linux/pci.h>
 #include <linux/vgaarb.h>
 #include <linux/acpi.h>
 #include <linux/pnp.h>
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
 
+extern int intel_max_stolen; /* from AGP driver */
+
 /**
  * Sets up the hardware status page for devices that need a physical address
  * in the register.
@@ -1256,7 +1259,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
                drm_mm_put_block(compressed_fb);
        }
 
-       if (!IS_GM45(dev)) {
+       if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) {
                compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096,
                                                    4096, 0);
                if (!compressed_llb) {
@@ -1282,8 +1285,9 @@ static void i915_setup_compression(struct drm_device *dev, int size)
 
        intel_disable_fbc(dev);
        dev_priv->compressed_fb = compressed_fb;
-
-       if (IS_GM45(dev)) {
+       if (IS_IRONLAKE_M(dev))
+               I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
+       else if (IS_GM45(dev)) {
                I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
        } else {
                I915_WRITE(FBC_CFB_BASE, cfb_base);
@@ -1291,7 +1295,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
                dev_priv->compressed_llb = compressed_llb;
        }
 
-       DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
+       DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
                  ll_base, size >> 20);
 }
 
@@ -1354,7 +1358,7 @@ static int i915_load_modeset_init(struct drm_device *dev,
        int fb_bar = IS_I9XX(dev) ? 2 : 0;
        int ret = 0;
 
-       dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
+       dev->mode_config.fb_base = pci_resource_start(dev->pdev, fb_bar) &
                0xff000000;
 
        /* Basic memrange allocator for stolen space (aka vram) */
@@ -2063,8 +2067,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        /* Add register map (needed for suspend/resume) */
        mmio_bar = IS_I9XX(dev) ? 0 : 1;
-       base = drm_get_resource_start(dev, mmio_bar);
-       size = drm_get_resource_len(dev, mmio_bar);
+       base = pci_resource_start(dev->pdev, mmio_bar);
+       size = pci_resource_len(dev->pdev, mmio_bar);
 
        if (i915_get_bridge_dev(dev)) {
                ret = -EIO;
@@ -2104,6 +2108,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        if (ret)
                goto out_iomapfree;
 
+       if (prealloc_size > intel_max_stolen) {
+               DRM_INFO("detected %dM stolen memory, trimming to %dM\n",
+                        prealloc_size >> 20, intel_max_stolen >> 20);
+               prealloc_size = intel_max_stolen;
+       }
+
        dev_priv->wq = create_singlethread_workqueue("i915");
        if (dev_priv->wq == NULL) {
                DRM_ERROR("Failed to create our workqueue.\n");
index 423dc90c1e20589e7669f1ba41880308af9fb044..5044f653e8ea981d46729360b5dc609836a319ab 100644 (file)
@@ -93,11 +93,11 @@ static const struct intel_device_info intel_i945gm_info = {
 };
 
 static const struct intel_device_info intel_i965g_info = {
-       .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
+       .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
 };
 
 static const struct intel_device_info intel_i965gm_info = {
-       .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1,
+       .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1,
        .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
        .has_hotplug = 1,
 };
@@ -114,7 +114,7 @@ static const struct intel_device_info intel_g45_info = {
 };
 
 static const struct intel_device_info intel_gm45_info = {
-       .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1,
+       .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1,
        .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
        .has_pipe_cxsr = 1,
        .has_hotplug = 1,
@@ -134,7 +134,7 @@ static const struct intel_device_info intel_ironlake_d_info = {
 
 static const struct intel_device_info intel_ironlake_m_info = {
        .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
-       .need_gfx_hws = 1, .has_rc6 = 1,
+       .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
        .has_hotplug = 1,
 };
 
@@ -148,33 +148,33 @@ static const struct intel_device_info intel_sandybridge_m_info = {
        .has_hotplug = 1, .is_gen6 = 1,
 };
 
-static const struct pci_device_id pciidlist[] = {
-       INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
-       INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
-       INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
+static const struct pci_device_id pciidlist[] = {              /* aka */
+       INTEL_VGA_DEVICE(0x3577, &intel_i830_info),             /* I830_M */
+       INTEL_VGA_DEVICE(0x2562, &intel_845g_info),             /* 845_G */
+       INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),             /* I855_GM */
        INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
-       INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
-       INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
-       INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
-       INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),
-       INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),
-       INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),
-       INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),
-       INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),
-       INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),
-       INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),
-       INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),
-       INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),
-       INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),
-       INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),
-       INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),
-       INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),
-       INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),
-       INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),
-       INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),
-       INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),
-       INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),
-       INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),
+       INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),            /* I865_G */
+       INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),            /* I915_G */
+       INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),            /* E7221_G */
+       INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),           /* I915_GM */
+       INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),            /* I945_G */
+       INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),           /* I945_GM */
+       INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),           /* I945_GME */
+       INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),            /* I946_GZ */
+       INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),            /* G35_G */
+       INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),            /* I965_Q */
+       INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),            /* I965_G */
+       INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),              /* Q35_G */
+       INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),              /* G33_G */
+       INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),              /* Q33_G */
+       INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),           /* I965_GM */
+       INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),           /* I965_GME */
+       INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),             /* GM45_G */
+       INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),              /* IGD_E_G */
+       INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),              /* Q45_G */
+       INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),              /* G45_G */
+       INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),              /* G41_G */
+       INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),              /* B43_G */
        INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
        INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
        INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
@@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
        /*
         * Clear request list
         */
-       i915_gem_retire_requests(dev, &dev_priv->render_ring);
+       i915_gem_retire_requests(dev);
 
        if (need_display)
                i915_save_display(dev);
@@ -413,7 +413,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
 static int __devinit
 i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &driver);
+       return drm_get_pci_dev(pdev, ent, &driver);
 }
 
 static void
@@ -482,7 +482,7 @@ static int i915_pm_poweroff(struct device *dev)
        return i915_drm_freeze(drm_dev);
 }
 
-const struct dev_pm_ops i915_pm_ops = {
+static const struct dev_pm_ops i915_pm_ops = {
      .suspend = i915_pm_suspend,
      .resume = i915_pm_resume,
      .freeze = i915_pm_freeze,
index 2e1744d37ad59e055f37f5c413c6ad3d6c56e02f..906663b9929e7cf6b951bf3d91b135b0219b38fc 100644 (file)
@@ -176,7 +176,8 @@ struct drm_i915_display_funcs {
        int (*get_display_clock_speed)(struct drm_device *dev);
        int (*get_fifo_size)(struct drm_device *dev, int plane);
        void (*update_wm)(struct drm_device *dev, int planea_clock,
-                         int planeb_clock, int sr_hdisplay, int pixel_size);
+                         int planeb_clock, int sr_hdisplay, int sr_htotal,
+                         int pixel_size);
        /* clock updates for mode set */
        /* cursor updates */
        /* render clock increase/decrease */
@@ -200,6 +201,8 @@ struct intel_device_info {
        u8 need_gfx_hws : 1;
        u8 is_g4x : 1;
        u8 is_pineview : 1;
+       u8 is_broadwater : 1;
+       u8 is_crestline : 1;
        u8 is_ironlake : 1;
        u8 is_gen6 : 1;
        u8 has_fbc : 1;
@@ -288,6 +291,8 @@ typedef struct drm_i915_private {
        struct timer_list hangcheck_timer;
        int hangcheck_count;
        uint32_t last_acthd;
+       uint32_t last_instdone;
+       uint32_t last_instdone1;
 
        struct drm_mm vram;
 
@@ -546,6 +551,14 @@ typedef struct drm_i915_private {
                /** LRU list of objects with fence regs on them. */
                struct list_head fence_list;
 
+               /**
+                * List of objects currently pending being freed.
+                *
+                * These objects are no longer in use, but due to a signal
+                * we were prevented from freeing them at the appointed time.
+                */
+               struct list_head deferred_free_list;
+
                /**
                 * We leave the user IRQ off as much as possible,
                 * but this means that requests will finish and never
@@ -677,7 +690,7 @@ struct drm_i915_gem_object {
         *
         * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
         */
-       int fence_reg : 5;
+       signed int fence_reg : 5;
 
        /**
         * Used for checking the object doesn't appear more than once
@@ -713,7 +726,7 @@ struct drm_i915_gem_object {
         *
         * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
         * bits with absolutely no headroom. So use 4 bits. */
-       int pin_count : 4;
+       unsigned int pin_count : 4;
 #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
 
        /** AGP memory structure for our GTT binding. */
@@ -743,7 +756,7 @@ struct drm_i915_gem_object {
        uint32_t stride;
 
        /** Record of address bit 17 of each page at last unbind. */
-       long *bit_17;
+       unsigned long *bit_17;
 
        /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
        uint32_t agp_type;
@@ -955,8 +968,7 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev,
 bool i915_seqno_passed(uint32_t seq1, uint32_t seq2);
 int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
 int i915_gem_object_put_fence_reg(struct drm_gem_object *obj);
-void i915_gem_retire_requests(struct drm_device *dev,
-                struct intel_ring_buffer *ring);
+void i915_gem_retire_requests(struct drm_device *dev);
 void i915_gem_retire_work_handler(struct work_struct *work);
 void i915_gem_clflush_object(struct drm_gem_object *obj);
 int i915_gem_object_set_domain(struct drm_gem_object *obj,
@@ -986,7 +998,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev);
 int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
 void i915_gem_object_put_pages(struct drm_gem_object *obj);
 void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
-void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
+int i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
 
 void i915_gem_shrinker_init(void);
 void i915_gem_shrinker_exit(void);
@@ -1046,6 +1058,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
 extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
 extern void i8xx_disable_fbc(struct drm_device *dev);
 extern void g4x_disable_fbc(struct drm_device *dev);
+extern void ironlake_disable_fbc(struct drm_device *dev);
 extern void intel_disable_fbc(struct drm_device *dev);
 extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
 extern bool intel_fbc_enabled(struct drm_device *dev);
@@ -1135,6 +1148,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
 #define IS_I945GM(dev)         (INTEL_INFO(dev)->is_i945gm)
 #define IS_I965G(dev)          (INTEL_INFO(dev)->is_i965g)
 #define IS_I965GM(dev)         (INTEL_INFO(dev)->is_i965gm)
+#define IS_BROADWATER(dev)     (INTEL_INFO(dev)->is_broadwater)
+#define IS_CRESTLINE(dev)      (INTEL_INFO(dev)->is_crestline)
 #define IS_GM45(dev)           ((dev)->pci_device == 0x2A42)
 #define IS_G4X(dev)            (INTEL_INFO(dev)->is_g4x)
 #define IS_PINEVIEW_G(dev)     ((dev)->pci_device == 0xa001)
index 5aa747fc25a9b34161ead103fff6bdba37c092a8..2a4ed7ca8b4ec6b1e415c2367144a4c6af158ae5 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/swap.h>
 #include <linux/pci.h>
 
-static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
+static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
 static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj,
@@ -53,6 +53,7 @@ static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
 static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
                                struct drm_i915_gem_pwrite *args,
                                struct drm_file *file_priv);
+static void i915_gem_free_object_tail(struct drm_gem_object *obj);
 
 static LIST_HEAD(shrink_list);
 static DEFINE_SPINLOCK(shrink_list_lock);
@@ -127,8 +128,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
                return -ENOMEM;
 
        ret = drm_gem_handle_create(file_priv, obj, &handle);
-       drm_gem_object_handle_unreference_unlocked(obj);
-
+       drm_gem_object_unreference_unlocked(obj);
        if (ret)
                return ret;
 
@@ -496,10 +496,10 @@ fast_user_write(struct io_mapping *mapping,
        char *vaddr_atomic;
        unsigned long unwritten;
 
-       vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base);
+       vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base, KM_USER0);
        unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset,
                                                      user_data, length);
-       io_mapping_unmap_atomic(vaddr_atomic);
+       io_mapping_unmap_atomic(vaddr_atomic, KM_USER0);
        if (unwritten)
                return -EFAULT;
        return 0;
@@ -1709,9 +1709,9 @@ i915_get_gem_seqno(struct drm_device *dev,
 /**
  * This function clears the request list as sequence numbers are passed.
  */
-void
-i915_gem_retire_requests(struct drm_device *dev,
-               struct intel_ring_buffer *ring)
+static void
+i915_gem_retire_requests_ring(struct drm_device *dev,
+                             struct intel_ring_buffer *ring)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        uint32_t seqno;
@@ -1750,6 +1750,30 @@ i915_gem_retire_requests(struct drm_device *dev,
        }
 }
 
+void
+i915_gem_retire_requests(struct drm_device *dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+
+       if (!list_empty(&dev_priv->mm.deferred_free_list)) {
+           struct drm_i915_gem_object *obj_priv, *tmp;
+
+           /* We must be careful that during unbind() we do not
+            * accidentally infinitely recurse into retire requests.
+            * Currently:
+            *   retire -> free -> unbind -> wait -> retire_ring
+            */
+           list_for_each_entry_safe(obj_priv, tmp,
+                                    &dev_priv->mm.deferred_free_list,
+                                    list)
+                   i915_gem_free_object_tail(&obj_priv->base);
+       }
+
+       i915_gem_retire_requests_ring(dev, &dev_priv->render_ring);
+       if (HAS_BSD(dev))
+               i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring);
+}
+
 void
 i915_gem_retire_work_handler(struct work_struct *work)
 {
@@ -1761,10 +1785,7 @@ i915_gem_retire_work_handler(struct work_struct *work)
        dev = dev_priv->dev;
 
        mutex_lock(&dev->struct_mutex);
-       i915_gem_retire_requests(dev, &dev_priv->render_ring);
-
-       if (HAS_BSD(dev))
-               i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
+       i915_gem_retire_requests(dev);
 
        if (!dev_priv->mm.suspended &&
                (!list_empty(&dev_priv->render_ring.request_list) ||
@@ -1832,7 +1853,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno,
         * a separate wait queue to handle that.
         */
        if (ret == 0)
-               i915_gem_retire_requests(dev, ring);
+               i915_gem_retire_requests_ring(dev, ring);
 
        return ret;
 }
@@ -1945,11 +1966,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
         * before we unbind.
         */
        ret = i915_gem_object_set_to_cpu_domain(obj, 1);
-       if (ret) {
-               if (ret != -ERESTARTSYS)
-                       DRM_ERROR("set_domain failed: %d\n", ret);
+       if (ret == -ERESTARTSYS)
                return ret;
-       }
+       /* Continue on if we fail due to EIO, the GPU is hung so we
+        * should be safe and we need to cleanup or else we might
+        * cause memory corruption through use-after-free.
+        */
 
        BUG_ON(obj_priv->active);
 
@@ -1985,7 +2007,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
 
        trace_i915_gem_object_unbind(obj);
 
-       return 0;
+       return ret;
 }
 
 static struct drm_gem_object *
@@ -2107,10 +2129,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
        struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
        struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring;
        for (;;) {
-               i915_gem_retire_requests(dev, render_ring);
-
-               if (HAS_BSD(dev))
-                       i915_gem_retire_requests(dev, bsd_ring);
+               i915_gem_retire_requests(dev);
 
                /* If there's an inactive buffer available now, grab it
                 * and be done.
@@ -2583,7 +2602,10 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
        if (!IS_I965G(dev)) {
                int ret;
 
-               i915_gem_object_flush_gpu_write_domain(obj);
+               ret = i915_gem_object_flush_gpu_write_domain(obj);
+               if (ret != 0)
+                       return ret;
+
                ret = i915_gem_object_wait_rendering(obj);
                if (ret != 0)
                        return ret;
@@ -2634,10 +2656,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
        if (free_space != NULL) {
                obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
                                                       alignment);
-               if (obj_priv->gtt_space != NULL) {
-                       obj_priv->gtt_space->private = obj;
+               if (obj_priv->gtt_space != NULL)
                        obj_priv->gtt_offset = obj_priv->gtt_space->start;
-               }
        }
        if (obj_priv->gtt_space == NULL) {
                /* If the gtt is empty and we're still having trouble
@@ -2733,7 +2753,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
 }
 
 /** Flushes any GPU write domain for the object if it's dirty. */
-static void
+static int
 i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
@@ -2741,17 +2761,18 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
        struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0)
-               return;
+               return 0;
 
        /* Queue the GPU write cache flushing we need. */
        old_write_domain = obj->write_domain;
        i915_gem_flush(dev, 0, obj->write_domain);
-       (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring);
-       BUG_ON(obj->write_domain);
+       if (i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring) == 0)
+               return -ENOMEM;
 
        trace_i915_gem_object_change_domain(obj,
                                            obj->read_domains,
                                            old_write_domain);
+       return 0;
 }
 
 /** Flushes the GTT write domain for the object if it's dirty. */
@@ -2795,9 +2816,11 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
                                            old_write_domain);
 }
 
-void
+int
 i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
 {
+       int ret = 0;
+
        switch (obj->write_domain) {
        case I915_GEM_DOMAIN_GTT:
                i915_gem_object_flush_gtt_write_domain(obj);
@@ -2806,9 +2829,11 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
                i915_gem_object_flush_cpu_write_domain(obj);
                break;
        default:
-               i915_gem_object_flush_gpu_write_domain(obj);
+               ret = i915_gem_object_flush_gpu_write_domain(obj);
                break;
        }
+
+       return ret;
 }
 
 /**
@@ -2828,7 +2853,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
        if (obj_priv->gtt_space == NULL)
                return -EINVAL;
 
-       i915_gem_object_flush_gpu_write_domain(obj);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
+       if (ret != 0)
+               return ret;
+
        /* Wait on any GPU rendering and flushing to occur. */
        ret = i915_gem_object_wait_rendering(obj);
        if (ret != 0)
@@ -2878,7 +2906,9 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
        if (obj_priv->gtt_space == NULL)
                return -EINVAL;
 
-       i915_gem_object_flush_gpu_write_domain(obj);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
+       if (ret)
+               return ret;
 
        /* Wait on any GPU rendering and flushing to occur. */
        if (obj_priv->active) {
@@ -2926,7 +2956,10 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
-       i915_gem_object_flush_gpu_write_domain(obj);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
+       if (ret)
+               return ret;
+
        /* Wait on any GPU rendering and flushing to occur. */
        ret = i915_gem_object_wait_rendering(obj);
        if (ret != 0)
@@ -3216,7 +3249,10 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
        if (offset == 0 && size == obj->size)
                return i915_gem_object_set_to_cpu_domain(obj, 0);
 
-       i915_gem_object_flush_gpu_write_domain(obj);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
+       if (ret)
+               return ret;
+
        /* Wait on any GPU rendering and flushing to occur. */
        ret = i915_gem_object_wait_rendering(obj);
        if (ret != 0)
@@ -3451,7 +3487,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
                reloc_offset = obj_priv->gtt_offset + reloc->offset;
                reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
                                                      (reloc_offset &
-                                                      ~(PAGE_SIZE - 1)));
+                                                      ~(PAGE_SIZE - 1)),
+                                                     KM_USER0);
                reloc_entry = (uint32_t __iomem *)(reloc_page +
                                                   (reloc_offset & (PAGE_SIZE - 1)));
                reloc_val = target_obj_priv->gtt_offset + reloc->delta;
@@ -3462,7 +3499,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
                          readl(reloc_entry), reloc_val);
 #endif
                writel(reloc_val, reloc_entry);
-               io_mapping_unmap_atomic(reloc_page);
+               io_mapping_unmap_atomic(reloc_page, KM_USER0);
 
                /* The updated presumed offset for this entry will be
                 * copied back out to the user.
@@ -4313,7 +4350,6 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
        struct drm_i915_gem_busy *args = data;
        struct drm_gem_object *obj;
        struct drm_i915_gem_object *obj_priv;
-       drm_i915_private_t *dev_priv = dev->dev_private;
 
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL) {
@@ -4328,10 +4364,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
         * actually unmasked, and our working set ends up being larger than
         * required.
         */
-       i915_gem_retire_requests(dev, &dev_priv->render_ring);
-
-       if (HAS_BSD(dev))
-               i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
+       i915_gem_retire_requests(dev);
 
        obj_priv = to_intel_bo(obj);
        /* Don't count being on the flushing list against the object being
@@ -4441,20 +4474,19 @@ int i915_gem_init_object(struct drm_gem_object *obj)
        return 0;
 }
 
-void i915_gem_free_object(struct drm_gem_object *obj)
+static void i915_gem_free_object_tail(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
+       drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
+       int ret;
 
-       trace_i915_gem_object_destroy(obj);
-
-       while (obj_priv->pin_count > 0)
-               i915_gem_object_unpin(obj);
-
-       if (obj_priv->phys_obj)
-               i915_gem_detach_phys_object(dev, obj);
-
-       i915_gem_object_unbind(obj);
+       ret = i915_gem_object_unbind(obj);
+       if (ret == -ERESTARTSYS) {
+               list_move(&obj_priv->list,
+                         &dev_priv->mm.deferred_free_list);
+               return;
+       }
 
        if (obj_priv->mmap_offset)
                i915_gem_free_mmap_offset(obj);
@@ -4466,6 +4498,22 @@ void i915_gem_free_object(struct drm_gem_object *obj)
        kfree(obj_priv);
 }
 
+void i915_gem_free_object(struct drm_gem_object *obj)
+{
+       struct drm_device *dev = obj->dev;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
+
+       trace_i915_gem_object_destroy(obj);
+
+       while (obj_priv->pin_count > 0)
+               i915_gem_object_unpin(obj);
+
+       if (obj_priv->phys_obj)
+               i915_gem_detach_phys_object(dev, obj);
+
+       i915_gem_free_object_tail(obj);
+}
+
 /** Unbinds all inactive objects. */
 static int
 i915_gem_evict_from_inactive_list(struct drm_device *dev)
@@ -4689,9 +4737,19 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
        BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list));
        mutex_unlock(&dev->struct_mutex);
 
-       drm_irq_install(dev);
+       ret = drm_irq_install(dev);
+       if (ret)
+               goto cleanup_ringbuffer;
 
        return 0;
+
+cleanup_ringbuffer:
+       mutex_lock(&dev->struct_mutex);
+       i915_gem_cleanup_ringbuffer(dev);
+       dev_priv->mm.suspended = 1;
+       mutex_unlock(&dev->struct_mutex);
+
+       return ret;
 }
 
 int
@@ -4729,6 +4787,7 @@ i915_gem_load(struct drm_device *dev)
        INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
        INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
        INIT_LIST_HEAD(&dev_priv->mm.fence_list);
+       INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list);
        INIT_LIST_HEAD(&dev_priv->render_ring.active_list);
        INIT_LIST_HEAD(&dev_priv->render_ring.request_list);
        if (HAS_BSD(dev)) {
@@ -5027,10 +5086,7 @@ rescan:
                        continue;
 
                spin_unlock(&shrink_list_lock);
-               i915_gem_retire_requests(dev, &dev_priv->render_ring);
-
-               if (HAS_BSD(dev))
-                       i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
+               i915_gem_retire_requests(dev);
 
                list_for_each_entry_safe(obj_priv, next_obj,
                                         &dev_priv->mm.inactive_list,
index 4b7c49d4257d3de8d938680280762e1b2e1e4ab6..155719e4d16fa899745bbf2ee757c9fdd65cc827 100644 (file)
@@ -333,8 +333,6 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
                        i915_gem_release_mmap(obj);
 
                if (ret != 0) {
-                       WARN(ret != -ERESTARTSYS,
-                            "failed to reset object for tiling switch");
                        args->tiling_mode = obj_priv->tiling_mode;
                        args->stride = obj_priv->stride;
                        goto err;
index dba53d4b9fb3a11b7b76194e0fa6aec97211e966..85785a8844ed5e422c99ca96a4a88e5d6a404a1a 100644 (file)
@@ -171,10 +171,10 @@ void intel_enable_asle (struct drm_device *dev)
                ironlake_enable_display_irq(dev_priv, DE_GSE);
        else {
                i915_enable_pipestat(dev_priv, 1,
-                                    I915_LEGACY_BLC_EVENT_ENABLE);
+                                    PIPE_LEGACY_BLC_EVENT_ENABLE);
                if (IS_I965G(dev))
                        i915_enable_pipestat(dev_priv, 0,
-                                            I915_LEGACY_BLC_EVENT_ENABLE);
+                                            PIPE_LEGACY_BLC_EVENT_ENABLE);
        }
 }
 
@@ -842,7 +842,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
        u32 iir, new_iir;
        u32 pipea_stats, pipeb_stats;
        u32 vblank_status;
-       u32 vblank_enable;
        int vblank = 0;
        unsigned long irqflags;
        int irq_received;
@@ -856,13 +855,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 
        iir = I915_READ(IIR);
 
-       if (IS_I965G(dev)) {
-               vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
-               vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
-       } else {
-               vblank_status = I915_VBLANK_INTERRUPT_STATUS;
-               vblank_enable = I915_VBLANK_INTERRUPT_ENABLE;
-       }
+       if (IS_I965G(dev))
+               vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS;
+       else
+               vblank_status = PIPE_VBLANK_INTERRUPT_STATUS;
 
        for (;;) {
                irq_received = iir != 0;
@@ -966,8 +962,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
                                intel_finish_page_flip(dev, 1);
                }
 
-               if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
-                   (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
+               if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
+                   (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
                    (iir & I915_ASLE_INTERRUPT))
                        opregion_asle_intr(dev);
 
@@ -1233,16 +1229,21 @@ void i915_hangcheck_elapsed(unsigned long data)
 {
        struct drm_device *dev = (struct drm_device *)data;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       uint32_t acthd;
+       uint32_t acthd, instdone, instdone1;
 
        /* No reset support on this chip yet. */
        if (IS_GEN6(dev))
                return;
 
-       if (!IS_I965G(dev))
+       if (!IS_I965G(dev)) {
                acthd = I915_READ(ACTHD);
-       else
+               instdone = I915_READ(INSTDONE);
+               instdone1 = 0;
+       } else {
                acthd = I915_READ(ACTHD_I965);
+               instdone = I915_READ(INSTDONE_I965);
+               instdone1 = I915_READ(INSTDONE1);
+       }
 
        /* If all work is done then ACTHD clearly hasn't advanced. */
        if (list_empty(&dev_priv->render_ring.request_list) ||
@@ -1253,21 +1254,24 @@ void i915_hangcheck_elapsed(unsigned long data)
                return;
        }
 
-       if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) {
-               DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
-               i915_handle_error(dev, true);
-               return;
-       } 
+       if (dev_priv->last_acthd == acthd &&
+           dev_priv->last_instdone == instdone &&
+           dev_priv->last_instdone1 == instdone1) {
+               if (dev_priv->hangcheck_count++ > 1) {
+                       DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
+                       i915_handle_error(dev, true);
+                       return;
+               }
+       } else {
+               dev_priv->hangcheck_count = 0;
+
+               dev_priv->last_acthd = acthd;
+               dev_priv->last_instdone = instdone;
+               dev_priv->last_instdone1 = instdone1;
+       }
 
        /* Reset timer case chip hangs without another request being added */
        mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
-
-       if (acthd != dev_priv->last_acthd)
-               dev_priv->hangcheck_count = 0;
-       else
-               dev_priv->hangcheck_count++;
-
-       dev_priv->last_acthd = acthd;
 }
 
 /* drm_dma.h hooks
index cf41c672defe9415fc0b656357cb44af00758b7d..281db6e5403ad1d9ed024e2924cfbc0344c1951a 100644 (file)
 #define GEN6_RENDER_IMR                0x20a8
 #define   GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT         (1 << 8)
 #define   GEN6_RENDER_PPGTT_PAGE_FAULT                 (1 << 7)
-#define   GEN6_RENDER TIMEOUT_COUNTER_EXPIRED          (1 << 6)
+#define   GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED          (1 << 6)
 #define   GEN6_RENDER_L3_PARITY_ERROR                  (1 << 5)
 #define   GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT    (1 << 4)
 #define   GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR      (1 << 3)
 #define DPFC_CHICKEN           0x3224
 #define   DPFC_HT_MODIFY       (1<<31)
 
+/* Framebuffer compression for Ironlake */
+#define ILK_DPFC_CB_BASE       0x43200
+#define ILK_DPFC_CONTROL       0x43208
+/* The bit 28-8 is reserved */
+#define   DPFC_RESERVED                (0x1FFFFF00)
+#define ILK_DPFC_RECOMP_CTL    0x4320c
+#define ILK_DPFC_STATUS                0x43210
+#define ILK_DPFC_FENCE_YOFF    0x43218
+#define ILK_DPFC_CHICKEN       0x43224
+#define ILK_FBC_RT_BASE                0x2128
+#define   ILK_FBC_RT_VALID     (1<<0)
+
+#define ILK_DISPLAY_CHICKEN1   0x42000
+#define   ILK_FBCQ_DIS         (1<<22)
+
 /*
  * GPIO regs
  */
 #define   DPLL_FPA01_P1_POST_DIV_MASK  0x00ff0000 /* i915 */
 #define   DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */
 
-#define I915_FIFO_UNDERRUN_STATUS              (1UL<<31)
-#define I915_CRC_ERROR_ENABLE                  (1UL<<29)
-#define I915_CRC_DONE_ENABLE                   (1UL<<28)
-#define I915_GMBUS_EVENT_ENABLE                        (1UL<<27)
-#define I915_VSYNC_INTERRUPT_ENABLE            (1UL<<25)
-#define I915_DISPLAY_LINE_COMPARE_ENABLE       (1UL<<24)
-#define I915_DPST_EVENT_ENABLE                 (1UL<<23)
-#define I915_LEGACY_BLC_EVENT_ENABLE           (1UL<<22)
-#define I915_ODD_FIELD_INTERRUPT_ENABLE                (1UL<<21)
-#define I915_EVEN_FIELD_INTERRUPT_ENABLE       (1UL<<20)
-#define I915_START_VBLANK_INTERRUPT_ENABLE     (1UL<<18)       /* 965 or later */
-#define I915_VBLANK_INTERRUPT_ENABLE           (1UL<<17)
-#define I915_OVERLAY_UPDATED_ENABLE            (1UL<<16)
-#define I915_CRC_ERROR_INTERRUPT_STATUS                (1UL<<13)
-#define I915_CRC_DONE_INTERRUPT_STATUS         (1UL<<12)
-#define I915_GMBUS_INTERRUPT_STATUS            (1UL<<11)
-#define I915_VSYNC_INTERRUPT_STATUS            (1UL<<9)
-#define I915_DISPLAY_LINE_COMPARE_STATUS       (1UL<<8)
-#define I915_DPST_EVENT_STATUS                 (1UL<<7)
-#define I915_LEGACY_BLC_EVENT_STATUS           (1UL<<6)
-#define I915_ODD_FIELD_INTERRUPT_STATUS                (1UL<<5)
-#define I915_EVEN_FIELD_INTERRUPT_STATUS       (1UL<<4)
-#define I915_START_VBLANK_INTERRUPT_STATUS     (1UL<<2)        /* 965 or later */
-#define I915_VBLANK_INTERRUPT_STATUS           (1UL<<1)
-#define I915_OVERLAY_UPDATED_STATUS            (1UL<<0)
-
 #define SRX_INDEX              0x3c4
 #define SRX_DATA               0x3c5
 #define SR01                   1
 #define I830_FIFO_LINE_SIZE    32
 
 #define G4X_FIFO_SIZE          127
-#define I945_FIFO_SIZE         127 /* 945 & 965 */
+#define I965_FIFO_SIZE         512
+#define I945_FIFO_SIZE         127
 #define I915_FIFO_SIZE         95
 #define I855GM_FIFO_SIZE       127 /* In cachelines */
 #define I830_FIFO_SIZE         95
 #define PINEVIEW_CURSOR_DFT_WM 0
 #define PINEVIEW_CURSOR_GUARD_WM       5
 
+#define I965_CURSOR_FIFO       64
+#define I965_CURSOR_MAX_WM     32
+#define I965_CURSOR_DFT_WM     8
 
 /* define the Watermark register on Ironlake */
 #define WM0_PIPEA_ILK          0x45100
 #define ILK_DISPLAY_FIFO       128
 #define ILK_DISPLAY_MAXWM      64
 #define ILK_DISPLAY_DFTWM      8
+#define ILK_CURSOR_FIFO                32
+#define ILK_CURSOR_MAXWM       16
+#define ILK_CURSOR_DFTWM       8
 
 #define ILK_DISPLAY_SR_FIFO    512
 #define ILK_DISPLAY_MAX_SRWM   0x1ff
 #define  ILK_VSDPFD_FULL       (1<<21)
 #define ILK_DSPCLK_GATE                0x42020
 #define  ILK_DPARB_CLK_GATE    (1<<5)
+/* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */
+#define   ILK_CLK_FBC          (1<<7)
+#define   ILK_DPFC_DIS1                (1<<8)
+#define   ILK_DPFC_DIS2                (1<<9)
 
 #define DISP_ARB_CTL   0x45000
 #define  DISP_TILE_SURFACE_SWIZZLING   (1<<13)
index 60a5800fba6e33c6638dc7fc455a33b041a3df8d..6e2025274db500e9d11c5ace422000196e457dd6 100644 (file)
@@ -602,7 +602,9 @@ void i915_save_display(struct drm_device *dev)
 
        /* Only save FBC state on the platform that supports FBC */
        if (I915_HAS_FBC(dev)) {
-               if (IS_GM45(dev)) {
+               if (IS_IRONLAKE_M(dev)) {
+                       dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE);
+               } else if (IS_GM45(dev)) {
                        dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
                } else {
                        dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
@@ -706,7 +708,10 @@ void i915_restore_display(struct drm_device *dev)
 
        /* only restore FBC info on the platform that supports FBC*/
        if (I915_HAS_FBC(dev)) {
-               if (IS_GM45(dev)) {
+               if (IS_IRONLAKE_M(dev)) {
+                       ironlake_disable_fbc(dev);
+                       I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
+               } else if (IS_GM45(dev)) {
                        g4x_disable_fbc(dev);
                        I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
                } else {
index fab21760dd57857cef544f205c44766d08a923ff..fea97a21cc1435a67a95563e786cf41a4acc7858 100644 (file)
@@ -262,6 +262,42 @@ DEFINE_EVENT(i915_ring, i915_ring_wait_end,
            TP_ARGS(dev)
 );
 
+TRACE_EVENT(i915_flip_request,
+           TP_PROTO(int plane, struct drm_gem_object *obj),
+
+           TP_ARGS(plane, obj),
+
+           TP_STRUCT__entry(
+                   __field(int, plane)
+                   __field(struct drm_gem_object *, obj)
+                   ),
+
+           TP_fast_assign(
+                   __entry->plane = plane;
+                   __entry->obj = obj;
+                   ),
+
+           TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
+);
+
+TRACE_EVENT(i915_flip_complete,
+           TP_PROTO(int plane, struct drm_gem_object *obj),
+
+           TP_ARGS(plane, obj),
+
+           TP_STRUCT__entry(
+                   __field(int, plane)
+                   __field(struct drm_gem_object *, obj)
+                   ),
+
+           TP_fast_assign(
+                   __entry->plane = plane;
+                   __entry->obj = obj;
+                   ),
+
+           TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
+);
+
 #endif /* _I915_TRACE_H_ */
 
 /* This part must be outside protection */
index 5e21b31198249349dc5e69265dbe20c8b0a23d02..1e5e0d379fa9a684670a073adfffcc0f6fbee338 100644 (file)
@@ -33,6 +33,7 @@
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
+#include "i915_trace.h"
 #include "drm_dp_helper.h"
 
 #include "drm_crtc_helper.h"
@@ -42,6 +43,7 @@
 bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
 static void intel_update_watermarks(struct drm_device *dev);
 static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule);
+static void intel_crtc_update_cursor(struct drm_crtc *crtc);
 
 typedef struct {
     /* given values */
@@ -322,6 +324,9 @@ struct intel_limit {
 #define IRONLAKE_DP_P1_MIN             1
 #define IRONLAKE_DP_P1_MAX             2
 
+/* FDI */
+#define IRONLAKE_FDI_FREQ              2700000 /* in kHz for mode->clock */
+
 static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
                    int target, int refclk, intel_clock_t *best_clock);
@@ -975,7 +980,10 @@ void
 intel_wait_for_vblank(struct drm_device *dev)
 {
        /* Wait for 20ms, i.e. one cycle at 50hz. */
-       msleep(20);
+       if (in_dbg_master())
+               mdelay(20); /* The kernel debugger cannot call msleep() */
+       else
+               msleep(20);
 }
 
 /* Parameters have changed, update FBC info */
@@ -1122,6 +1130,67 @@ static bool g4x_fbc_enabled(struct drm_device *dev)
        return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
 }
 
+static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_framebuffer *fb = crtc->fb;
+       struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int plane = (intel_crtc->plane == 0) ? DPFC_CTL_PLANEA :
+                                              DPFC_CTL_PLANEB;
+       unsigned long stall_watermark = 200;
+       u32 dpfc_ctl;
+
+       dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1;
+       dev_priv->cfb_fence = obj_priv->fence_reg;
+       dev_priv->cfb_plane = intel_crtc->plane;
+
+       dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
+       dpfc_ctl &= DPFC_RESERVED;
+       dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X);
+       if (obj_priv->tiling_mode != I915_TILING_NONE) {
+               dpfc_ctl |= (DPFC_CTL_FENCE_EN | dev_priv->cfb_fence);
+               I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY);
+       } else {
+               I915_WRITE(ILK_DPFC_CHICKEN, ~DPFC_HT_MODIFY);
+       }
+
+       I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
+       I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN |
+                  (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) |
+                  (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT));
+       I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y);
+       I915_WRITE(ILK_FBC_RT_BASE, obj_priv->gtt_offset | ILK_FBC_RT_VALID);
+       /* enable it... */
+       I915_WRITE(ILK_DPFC_CONTROL, I915_READ(ILK_DPFC_CONTROL) |
+                  DPFC_CTL_EN);
+
+       DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
+}
+
+void ironlake_disable_fbc(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 dpfc_ctl;
+
+       /* Disable compression */
+       dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
+       dpfc_ctl &= ~DPFC_CTL_EN;
+       I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
+       intel_wait_for_vblank(dev);
+
+       DRM_DEBUG_KMS("disabled FBC\n");
+}
+
+static bool ironlake_fbc_enabled(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
+}
+
 bool intel_fbc_enabled(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1248,6 +1317,10 @@ static void intel_update_fbc(struct drm_crtc *crtc,
                goto out_disable;
        }
 
+       /* If the kernel debugger is active, always disable compression */
+       if (in_dbg_master())
+               goto out_disable;
+
        if (intel_fbc_enabled(dev)) {
                /* We can re-enable it in this case, but need to update pitch */
                if ((fb->pitch > dev_priv->cfb_pitch) ||
@@ -1279,7 +1352,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
 
        switch (obj_priv->tiling_mode) {
        case I915_TILING_NONE:
-               alignment = 64 * 1024;
+               if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
+                       alignment = 128 * 1024;
+               else if (IS_I965G(dev))
+                       alignment = 4 * 1024;
+               else
+                       alignment = 64 * 1024;
                break;
        case I915_TILING_X:
                /* pin() will align the object as required by fence */
@@ -1314,6 +1392,98 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
        return 0;
 }
 
+/* Assume fb object is pinned & idle & fenced and just update base pointers */
+static int
+intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+                          int x, int y)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_framebuffer *intel_fb;
+       struct drm_i915_gem_object *obj_priv;
+       struct drm_gem_object *obj;
+       int plane = intel_crtc->plane;
+       unsigned long Start, Offset;
+       int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR);
+       int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
+       int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
+       int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
+       int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
+       u32 dspcntr;
+
+       switch (plane) {
+       case 0:
+       case 1:
+               break;
+       default:
+               DRM_ERROR("Can't update plane %d in SAREA\n", plane);
+               return -EINVAL;
+       }
+
+       intel_fb = to_intel_framebuffer(fb);
+       obj = intel_fb->obj;
+       obj_priv = to_intel_bo(obj);
+
+       dspcntr = I915_READ(dspcntr_reg);
+       /* Mask out pixel format bits in case we change it */
+       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+       switch (fb->bits_per_pixel) {
+       case 8:
+               dspcntr |= DISPPLANE_8BPP;
+               break;
+       case 16:
+               if (fb->depth == 15)
+                       dspcntr |= DISPPLANE_15_16BPP;
+               else
+                       dspcntr |= DISPPLANE_16BPP;
+               break;
+       case 24:
+       case 32:
+               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+               break;
+       default:
+               DRM_ERROR("Unknown color depth\n");
+               return -EINVAL;
+       }
+       if (IS_I965G(dev)) {
+               if (obj_priv->tiling_mode != I915_TILING_NONE)
+                       dspcntr |= DISPPLANE_TILED;
+               else
+                       dspcntr &= ~DISPPLANE_TILED;
+       }
+
+       if (IS_IRONLAKE(dev))
+               /* must disable */
+               dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+
+       I915_WRITE(dspcntr_reg, dspcntr);
+
+       Start = obj_priv->gtt_offset;
+       Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+       DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+       I915_WRITE(dspstride, fb->pitch);
+       if (IS_I965G(dev)) {
+               I915_WRITE(dspbase, Offset);
+               I915_READ(dspbase);
+               I915_WRITE(dspsurf, Start);
+               I915_READ(dspsurf);
+               I915_WRITE(dsptileoff, (y << 16) | x);
+       } else {
+               I915_WRITE(dspbase, Start + Offset);
+               I915_READ(dspbase);
+       }
+
+       if ((IS_I965G(dev) || plane == 0))
+               intel_update_fbc(crtc, &crtc->mode);
+
+       intel_wait_for_vblank(dev);
+       intel_increase_pllclock(crtc, true);
+
+       return 0;
+}
+
 static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                    struct drm_framebuffer *old_fb)
@@ -1554,6 +1724,15 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
        int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR;
        u32 temp, tries = 0;
 
+       /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
+          for train result */
+       temp = I915_READ(fdi_rx_imr_reg);
+       temp &= ~FDI_RX_SYMBOL_LOCK;
+       temp &= ~FDI_RX_BIT_LOCK;
+       I915_WRITE(fdi_rx_imr_reg, temp);
+       I915_READ(fdi_rx_imr_reg);
+       udelay(150);
+
        /* enable CPU FDI TX and PCH FDI RX */
        temp = I915_READ(fdi_tx_reg);
        temp |= FDI_TX_ENABLE;
@@ -1571,16 +1750,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
        I915_READ(fdi_rx_reg);
        udelay(150);
 
-       /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
-          for train result */
-       temp = I915_READ(fdi_rx_imr_reg);
-       temp &= ~FDI_RX_SYMBOL_LOCK;
-       temp &= ~FDI_RX_BIT_LOCK;
-       I915_WRITE(fdi_rx_imr_reg, temp);
-       I915_READ(fdi_rx_imr_reg);
-       udelay(150);
-
-       for (;;) {
+       for (tries = 0; tries < 5; tries++) {
                temp = I915_READ(fdi_rx_iir_reg);
                DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
 
@@ -1590,14 +1760,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
                                   temp | FDI_RX_BIT_LOCK);
                        break;
                }
-
-               tries++;
-
-               if (tries > 5) {
-                       DRM_DEBUG_KMS("FDI train 1 fail!\n");
-                       break;
-               }
        }
+       if (tries == 5)
+               DRM_DEBUG_KMS("FDI train 1 fail!\n");
 
        /* Train 2 */
        temp = I915_READ(fdi_tx_reg);
@@ -1613,7 +1778,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 
        tries = 0;
 
-       for (;;) {
+       for (tries = 0; tries < 5; tries++) {
                temp = I915_READ(fdi_rx_iir_reg);
                DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
 
@@ -1623,14 +1788,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
                        DRM_DEBUG_KMS("FDI train 2 done.\n");
                        break;
                }
-
-               tries++;
-
-               if (tries > 5) {
-                       DRM_DEBUG_KMS("FDI train 2 fail!\n");
-                       break;
-               }
        }
+       if (tries == 5)
+               DRM_DEBUG_KMS("FDI train 2 fail!\n");
 
        DRM_DEBUG_KMS("FDI train done\n");
 }
@@ -1655,6 +1815,15 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
        int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR;
        u32 temp, i;
 
+       /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
+          for train result */
+       temp = I915_READ(fdi_rx_imr_reg);
+       temp &= ~FDI_RX_SYMBOL_LOCK;
+       temp &= ~FDI_RX_BIT_LOCK;
+       I915_WRITE(fdi_rx_imr_reg, temp);
+       I915_READ(fdi_rx_imr_reg);
+       udelay(150);
+
        /* enable CPU FDI TX and PCH FDI RX */
        temp = I915_READ(fdi_tx_reg);
        temp |= FDI_TX_ENABLE;
@@ -1680,15 +1849,6 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
        I915_READ(fdi_rx_reg);
        udelay(150);
 
-       /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
-          for train result */
-       temp = I915_READ(fdi_rx_imr_reg);
-       temp &= ~FDI_RX_SYMBOL_LOCK;
-       temp &= ~FDI_RX_BIT_LOCK;
-       I915_WRITE(fdi_rx_imr_reg, temp);
-       I915_READ(fdi_rx_imr_reg);
-       udelay(150);
-
        for (i = 0; i < 4; i++ ) {
                temp = I915_READ(fdi_tx_reg);
                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
@@ -1843,7 +2003,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
                }
 
                /* Enable panel fitting for LVDS */
-               if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+               if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
+                   || HAS_eDP || intel_pch_has_edp(crtc)) {
                        temp = I915_READ(pf_ctl_reg);
                        I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);
 
@@ -1938,9 +2099,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
                                reg = I915_READ(trans_dp_ctl);
                                reg &= ~TRANS_DP_PORT_SEL_MASK;
                                reg = TRANS_DP_OUTPUT_ENABLE |
-                                     TRANS_DP_ENH_FRAMING |
-                                     TRANS_DP_VSYNC_ACTIVE_HIGH |
-                                     TRANS_DP_HSYNC_ACTIVE_HIGH;
+                                     TRANS_DP_ENH_FRAMING;
+
+                               if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
+                                     reg |= TRANS_DP_HSYNC_ACTIVE_HIGH;
+                               if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
+                                     reg |= TRANS_DP_VSYNC_ACTIVE_HIGH;
 
                                switch (intel_trans_dp_port_sel(crtc)) {
                                case PCH_DP_B:
@@ -1980,6 +2144,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
 
                intel_crtc_load_lut(crtc);
 
+               intel_update_fbc(crtc, &crtc->mode);
+
        break;
        case DRM_MODE_DPMS_OFF:
                DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);
@@ -1994,6 +2160,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
                        I915_READ(dspbase_reg);
                }
 
+               if (dev_priv->cfb_plane == plane &&
+                   dev_priv->display.disable_fbc)
+                       dev_priv->display.disable_fbc(dev);
+
                i915_disable_vga(dev);
 
                /* disable cpu pipe, disable after all planes disabled */
@@ -2373,8 +2543,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
        struct drm_device *dev = crtc->dev;
        if (HAS_PCH_SPLIT(dev)) {
                /* FDI link clock is fixed at 2.7G */
-               if (mode->clock * 3 > 27000 * 4)
-                       return MODE_CLOCK_HIGH;
+               if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
+                       return false;
        }
        return true;
 }
@@ -2556,6 +2726,20 @@ static struct intel_watermark_params g4x_wm_info = {
        2,
        G4X_FIFO_LINE_SIZE,
 };
+static struct intel_watermark_params g4x_cursor_wm_info = {
+       I965_CURSOR_FIFO,
+       I965_CURSOR_MAX_WM,
+       I965_CURSOR_DFT_WM,
+       2,
+       G4X_FIFO_LINE_SIZE,
+};
+static struct intel_watermark_params i965_cursor_wm_info = {
+       I965_CURSOR_FIFO,
+       I965_CURSOR_MAX_WM,
+       I965_CURSOR_DFT_WM,
+       2,
+       I915_FIFO_LINE_SIZE,
+};
 static struct intel_watermark_params i945_wm_info = {
        I945_FIFO_SIZE,
        I915_MAX_WM,
@@ -2593,6 +2777,14 @@ static struct intel_watermark_params ironlake_display_wm_info = {
        ILK_FIFO_LINE_SIZE
 };
 
+static struct intel_watermark_params ironlake_cursor_wm_info = {
+       ILK_CURSOR_FIFO,
+       ILK_CURSOR_MAXWM,
+       ILK_CURSOR_DFTWM,
+       2,
+       ILK_FIFO_LINE_SIZE
+};
+
 static struct intel_watermark_params ironlake_display_srwm_info = {
        ILK_DISPLAY_SR_FIFO,
        ILK_DISPLAY_MAX_SRWM,
@@ -2642,7 +2834,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
         */
        entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) /
                1000;
-       entries_required /= wm->cacheline_size;
+       entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size);
 
        DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required);
 
@@ -2653,8 +2845,14 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
        /* Don't promote wm_size to unsigned... */
        if (wm_size > (long)wm->max_wm)
                wm_size = wm->max_wm;
-       if (wm_size <= 0)
+       if (wm_size <= 0) {
                wm_size = wm->default_wm;
+               DRM_ERROR("Insufficient FIFO for plane, expect flickering:"
+                         " entries required = %ld, available = %lu.\n",
+                         entries_required + wm->guard_size,
+                         wm->fifo_size);
+       }
+
        return wm_size;
 }
 
@@ -2763,11 +2961,9 @@ static int i9xx_get_fifo_size(struct drm_device *dev, int plane)
        uint32_t dsparb = I915_READ(DSPARB);
        int size;
 
-       if (plane == 0)
-               size = dsparb & 0x7f;
-       else
-               size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) -
-                       (dsparb & 0x7f);
+       size = dsparb & 0x7f;
+       if (plane)
+               size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size;
 
        DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
                        plane ? "B" : "A", size);
@@ -2781,11 +2977,9 @@ static int i85x_get_fifo_size(struct drm_device *dev, int plane)
        uint32_t dsparb = I915_READ(DSPARB);
        int size;
 
-       if (plane == 0)
-               size = dsparb & 0x1ff;
-       else
-               size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) -
-                       (dsparb & 0x1ff);
+       size = dsparb & 0x1ff;
+       if (plane)
+               size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size;
        size >>= 1; /* Convert to cachelines */
 
        DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
@@ -2826,7 +3020,8 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
 }
 
 static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
-                         int planeb_clock, int sr_hdisplay, int pixel_size)
+                         int planeb_clock, int sr_hdisplay, int unused,
+                         int pixel_size)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 reg;
@@ -2891,7 +3086,8 @@ static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
 }
 
 static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
-                         int planeb_clock, int sr_hdisplay, int pixel_size)
+                         int planeb_clock, int sr_hdisplay, int sr_htotal,
+                         int pixel_size)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int total_size, cacheline_size;
@@ -2915,12 +3111,12 @@ static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
         */
        entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) /
                1000;
-       entries_required /= G4X_FIFO_LINE_SIZE;
+       entries_required = DIV_ROUND_UP(entries_required, G4X_FIFO_LINE_SIZE);
        planea_wm = entries_required + planea_params.guard_size;
 
        entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) /
                1000;
-       entries_required /= G4X_FIFO_LINE_SIZE;
+       entries_required = DIV_ROUND_UP(entries_required, G4X_FIFO_LINE_SIZE);
        planeb_wm = entries_required + planeb_params.guard_size;
 
        cursora_wm = cursorb_wm = 16;
@@ -2934,13 +3130,24 @@ static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
                static const int sr_latency_ns = 12000;
 
                sr_clock = planea_clock ? planea_clock : planeb_clock;
-               line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+               line_time_us = ((sr_htotal * 1000) / sr_clock);
 
                /* Use ns/us then divide to preserve precision */
-               sr_entries = (((sr_latency_ns / line_time_us) + 1) *
-                             pixel_size * sr_hdisplay) / 1000;
-               sr_entries = roundup(sr_entries / cacheline_size, 1);
-               DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+               sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
+                             pixel_size * sr_hdisplay;
+               sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size);
+
+               entries_required = (((sr_latency_ns / line_time_us) +
+                                    1000) / 1000) * pixel_size * 64;
+               entries_required = DIV_ROUND_UP(entries_required,
+                                          g4x_cursor_wm_info.cacheline_size);
+               cursor_sr = entries_required + g4x_cursor_wm_info.guard_size;
+
+               if (cursor_sr > g4x_cursor_wm_info.max_wm)
+                       cursor_sr = g4x_cursor_wm_info.max_wm;
+               DRM_DEBUG_KMS("self-refresh watermark: display plane %d "
+                             "cursor %d\n", sr_entries, cursor_sr);
+
                I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
        } else {
                /* Turn off self refresh if both pipes are enabled */
@@ -2965,11 +3172,13 @@ static void g4x_update_wm(struct drm_device *dev,  int planea_clock,
 }
 
 static void i965_update_wm(struct drm_device *dev, int planea_clock,
-                          int planeb_clock, int sr_hdisplay, int pixel_size)
+                          int planeb_clock, int sr_hdisplay, int sr_htotal,
+                          int pixel_size)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long line_time_us;
        int sr_clock, sr_entries, srwm = 1;
+       int cursor_sr = 16;
 
        /* Calc sr entries for one plane configs */
        if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
@@ -2977,17 +3186,31 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock,
                static const int sr_latency_ns = 12000;
 
                sr_clock = planea_clock ? planea_clock : planeb_clock;
-               line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+               line_time_us = ((sr_htotal * 1000) / sr_clock);
 
                /* Use ns/us then divide to preserve precision */
-               sr_entries = (((sr_latency_ns / line_time_us) + 1) *
-                             pixel_size * sr_hdisplay) / 1000;
-               sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1);
+               sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
+                             pixel_size * sr_hdisplay;
+               sr_entries = DIV_ROUND_UP(sr_entries, I915_FIFO_LINE_SIZE);
                DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
-               srwm = I945_FIFO_SIZE - sr_entries;
+               srwm = I965_FIFO_SIZE - sr_entries;
                if (srwm < 0)
                        srwm = 1;
-               srwm &= 0x3f;
+               srwm &= 0x1ff;
+
+               sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
+                            pixel_size * 64;
+               sr_entries = DIV_ROUND_UP(sr_entries,
+                                         i965_cursor_wm_info.cacheline_size);
+               cursor_sr = i965_cursor_wm_info.fifo_size -
+                           (sr_entries + i965_cursor_wm_info.guard_size);
+
+               if (cursor_sr > i965_cursor_wm_info.max_wm)
+                       cursor_sr = i965_cursor_wm_info.max_wm;
+
+               DRM_DEBUG_KMS("self-refresh watermark: display plane %d "
+                             "cursor %d\n", srwm, cursor_sr);
+
                if (IS_I965GM(dev))
                        I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
        } else {
@@ -3004,10 +3227,13 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock,
        I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) |
                   (8 << 0));
        I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
+       /* update cursor SR watermark */
+       I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
 }
 
 static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
-                          int planeb_clock, int sr_hdisplay, int pixel_size)
+                          int planeb_clock, int sr_hdisplay, int sr_htotal,
+                          int pixel_size)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t fwater_lo;
@@ -3052,12 +3278,12 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
                static const int sr_latency_ns = 6000;
 
                sr_clock = planea_clock ? planea_clock : planeb_clock;
-               line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+               line_time_us = ((sr_htotal * 1000) / sr_clock);
 
                /* Use ns/us then divide to preserve precision */
-               sr_entries = (((sr_latency_ns / line_time_us) + 1) *
-                             pixel_size * sr_hdisplay) / 1000;
-               sr_entries = roundup(sr_entries / cacheline_size, 1);
+               sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
+                             pixel_size * sr_hdisplay;
+               sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size);
                DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries);
                srwm = total_size - sr_entries;
                if (srwm < 0)
@@ -3095,7 +3321,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
 }
 
 static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused,
-                          int unused2, int pixel_size)
+                          int unused2, int unused3, int pixel_size)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff;
@@ -3113,9 +3339,11 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused,
 }
 
 #define ILK_LP0_PLANE_LATENCY          700
+#define ILK_LP0_CURSOR_LATENCY         1300
 
 static void ironlake_update_wm(struct drm_device *dev,  int planea_clock,
-                      int planeb_clock, int sr_hdisplay, int pixel_size)
+                      int planeb_clock, int sr_hdisplay, int sr_htotal,
+                      int pixel_size)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
@@ -3123,20 +3351,48 @@ static void ironlake_update_wm(struct drm_device *dev,  int planea_clock,
        unsigned long line_time_us;
        int sr_clock, entries_required;
        u32 reg_value;
+       int line_count;
+       int planea_htotal = 0, planeb_htotal = 0;
+       struct drm_crtc *crtc;
+       struct intel_crtc *intel_crtc;
+
+       /* Need htotal for all active display plane */
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               intel_crtc = to_intel_crtc(crtc);
+               if (crtc->enabled) {
+                       if (intel_crtc->plane == 0)
+                               planea_htotal = crtc->mode.htotal;
+                       else
+                               planeb_htotal = crtc->mode.htotal;
+               }
+       }
 
        /* Calculate and update the watermark for plane A */
        if (planea_clock) {
                entries_required = ((planea_clock / 1000) * pixel_size *
                                     ILK_LP0_PLANE_LATENCY) / 1000;
                entries_required = DIV_ROUND_UP(entries_required,
-                                  ironlake_display_wm_info.cacheline_size);
+                                               ironlake_display_wm_info.cacheline_size);
                planea_wm = entries_required +
                            ironlake_display_wm_info.guard_size;
 
                if (planea_wm > (int)ironlake_display_wm_info.max_wm)
                        planea_wm = ironlake_display_wm_info.max_wm;
 
-               cursora_wm = 16;
+               /* Use the large buffer method to calculate cursor watermark */
+               line_time_us = (planea_htotal * 1000) / planea_clock;
+
+               /* Use ns/us then divide to preserve precision */
+               line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000;
+
+               /* calculate the cursor watermark for cursor A */
+               entries_required = line_count * 64 * pixel_size;
+               entries_required = DIV_ROUND_UP(entries_required,
+                                               ironlake_cursor_wm_info.cacheline_size);
+               cursora_wm = entries_required + ironlake_cursor_wm_info.guard_size;
+               if (cursora_wm > ironlake_cursor_wm_info.max_wm)
+                       cursora_wm = ironlake_cursor_wm_info.max_wm;
+
                reg_value = I915_READ(WM0_PIPEA_ILK);
                reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
                reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) |
@@ -3150,14 +3406,27 @@ static void ironlake_update_wm(struct drm_device *dev,  int planea_clock,
                entries_required = ((planeb_clock / 1000) * pixel_size *
                                     ILK_LP0_PLANE_LATENCY) / 1000;
                entries_required = DIV_ROUND_UP(entries_required,
-                                  ironlake_display_wm_info.cacheline_size);
+                                               ironlake_display_wm_info.cacheline_size);
                planeb_wm = entries_required +
                            ironlake_display_wm_info.guard_size;
 
                if (planeb_wm > (int)ironlake_display_wm_info.max_wm)
                        planeb_wm = ironlake_display_wm_info.max_wm;
 
-               cursorb_wm = 16;
+               /* Use the large buffer method to calculate cursor watermark */
+               line_time_us = (planeb_htotal * 1000) / planeb_clock;
+
+               /* Use ns/us then divide to preserve precision */
+               line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000;
+
+               /* calculate the cursor watermark for cursor B */
+               entries_required = line_count * 64 * pixel_size;
+               entries_required = DIV_ROUND_UP(entries_required,
+                                               ironlake_cursor_wm_info.cacheline_size);
+               cursorb_wm = entries_required + ironlake_cursor_wm_info.guard_size;
+               if (cursorb_wm > ironlake_cursor_wm_info.max_wm)
+                       cursorb_wm = ironlake_cursor_wm_info.max_wm;
+
                reg_value = I915_READ(WM0_PIPEB_ILK);
                reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
                reg_value |= (planeb_wm << WM0_PIPE_PLANE_SHIFT) |
@@ -3172,12 +3441,12 @@ static void ironlake_update_wm(struct drm_device *dev,  int planea_clock,
         * display plane is used.
         */
        if (!planea_clock || !planeb_clock) {
-               int line_count;
+
                /* Read the self-refresh latency. The unit is 0.5us */
                int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK;
 
                sr_clock = planea_clock ? planea_clock : planeb_clock;
-               line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+               line_time_us = ((sr_htotal * 1000) / sr_clock);
 
                /* Use ns/us then divide to preserve precision */
                line_count = ((ilk_sr_latency * 500) / line_time_us + 1000)
@@ -3186,14 +3455,14 @@ static void ironlake_update_wm(struct drm_device *dev,  int planea_clock,
                /* calculate the self-refresh watermark for display plane */
                entries_required = line_count * sr_hdisplay * pixel_size;
                entries_required = DIV_ROUND_UP(entries_required,
-                                  ironlake_display_srwm_info.cacheline_size);
+                                               ironlake_display_srwm_info.cacheline_size);
                sr_wm = entries_required +
                        ironlake_display_srwm_info.guard_size;
 
                /* calculate the self-refresh watermark for display cursor */
                entries_required = line_count * pixel_size * 64;
                entries_required = DIV_ROUND_UP(entries_required,
-                                  ironlake_cursor_srwm_info.cacheline_size);
+                                               ironlake_cursor_srwm_info.cacheline_size);
                cursor_wm = entries_required +
                            ironlake_cursor_srwm_info.guard_size;
 
@@ -3237,6 +3506,7 @@ static void ironlake_update_wm(struct drm_device *dev,  int planea_clock,
  *       bytes per pixel
  *   where
  *     line time = htotal / dotclock
+ *     surface width = hdisplay for normal plane and 64 for cursor
  *   and latency is assumed to be high, as above.
  *
  * The final value programmed to the register should always be rounded up,
@@ -3253,6 +3523,7 @@ static void intel_update_watermarks(struct drm_device *dev)
        int sr_hdisplay = 0;
        unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
        int enabled = 0, pixel_size = 0;
+       int sr_htotal = 0;
 
        if (!dev_priv->display.update_wm)
                return;
@@ -3273,6 +3544,7 @@ static void intel_update_watermarks(struct drm_device *dev)
                        }
                        sr_hdisplay = crtc->mode.hdisplay;
                        sr_clock = crtc->mode.clock;
+                       sr_htotal = crtc->mode.htotal;
                        if (crtc->fb)
                                pixel_size = crtc->fb->bits_per_pixel / 8;
                        else
@@ -3284,7 +3556,7 @@ static void intel_update_watermarks(struct drm_device *dev)
                return;
 
        dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
-                                   sr_hdisplay, pixel_size);
+                                   sr_hdisplay, sr_htotal, pixel_size);
 }
 
 static int intel_crtc_mode_set(struct drm_crtc *crtc,
@@ -3403,6 +3675,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                return -EINVAL;
        }
 
+       /* Ensure that the cursor is valid for the new mode before changing... */
+       intel_crtc_update_cursor(crtc);
+
        if (is_lvds && dev_priv->lvds_downclock_avail) {
                has_reduced_clock = limit->find_pll(limit, crtc,
                                                            dev_priv->lvds_downclock,
@@ -3469,7 +3744,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                                temp |= PIPE_8BPC;
                        else
                                temp |= PIPE_6BPC;
-               } else if (is_edp) {
+               } else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) {
                        switch (dev_priv->edp_bpp/3) {
                        case 8:
                                temp |= PIPE_8BPC;
@@ -3712,6 +3987,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                udelay(150);
        }
 
+       if (HAS_PCH_SPLIT(dev)) {
+               pipeconf &= ~PIPE_ENABLE_DITHER;
+               pipeconf &= ~PIPE_DITHER_TYPE_MASK;
+       }
+
        /* The LVDS pin pair needs to be on before the DPLLs are enabled.
         * This is an exception to the general rule that mode_set doesn't turn
         * things on.
@@ -3754,16 +4034,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                        if (dev_priv->lvds_dither) {
                                if (HAS_PCH_SPLIT(dev)) {
                                        pipeconf |= PIPE_ENABLE_DITHER;
-                                       pipeconf &= ~PIPE_DITHER_TYPE_MASK;
                                        pipeconf |= PIPE_DITHER_TYPE_ST01;
                                } else
                                        lvds |= LVDS_ENABLE_DITHER;
                        } else {
-                               if (HAS_PCH_SPLIT(dev)) {
-                                       pipeconf &= ~PIPE_ENABLE_DITHER;
-                                       pipeconf &= ~PIPE_DITHER_TYPE_MASK;
-                               } else
+                               if (!HAS_PCH_SPLIT(dev)) {
                                        lvds &= ~LVDS_ENABLE_DITHER;
+                               }
                        }
                }
                I915_WRITE(lvds_reg, lvds);
@@ -3939,6 +4216,85 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
        }
 }
 
+/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
+static void intel_crtc_update_cursor(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int pipe = intel_crtc->pipe;
+       int x = intel_crtc->cursor_x;
+       int y = intel_crtc->cursor_y;
+       uint32_t base, pos;
+       bool visible;
+
+       pos = 0;
+
+       if (crtc->fb) {
+               base = intel_crtc->cursor_addr;
+               if (x > (int) crtc->fb->width)
+                       base = 0;
+
+               if (y > (int) crtc->fb->height)
+                       base = 0;
+       } else
+               base = 0;
+
+       if (x < 0) {
+               if (x + intel_crtc->cursor_width < 0)
+                       base = 0;
+
+               pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
+               x = -x;
+       }
+       pos |= x << CURSOR_X_SHIFT;
+
+       if (y < 0) {
+               if (y + intel_crtc->cursor_height < 0)
+                       base = 0;
+
+               pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
+               y = -y;
+       }
+       pos |= y << CURSOR_Y_SHIFT;
+
+       visible = base != 0;
+       if (!visible && !intel_crtc->cursor_visble)
+               return;
+
+       I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos);
+       if (intel_crtc->cursor_visble != visible) {
+               uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR);
+               if (base) {
+                       /* Hooray for CUR*CNTR differences */
+                       if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+                               cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+                               cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+                               cntl |= pipe << 28; /* Connect to correct pipe */
+                       } else {
+                               cntl &= ~(CURSOR_FORMAT_MASK);
+                               cntl |= CURSOR_ENABLE;
+                               cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+                       }
+               } else {
+                       if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+                               cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
+                               cntl |= CURSOR_MODE_DISABLE;
+                       } else {
+                               cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
+                       }
+               }
+               I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl);
+
+               intel_crtc->cursor_visble = visible;
+       }
+       /* and commit changes on next vblank */
+       I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base);
+
+       if (visible)
+               intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj);
+}
+
 static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                                 struct drm_file *file_priv,
                                 uint32_t handle,
@@ -3949,11 +4305,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct drm_gem_object *bo;
        struct drm_i915_gem_object *obj_priv;
-       int pipe = intel_crtc->pipe;
-       uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
-       uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-       uint32_t temp = I915_READ(control);
-       size_t addr;
+       uint32_t addr;
        int ret;
 
        DRM_DEBUG_KMS("\n");
@@ -3961,12 +4313,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        /* if we want to turn off the cursor ignore width and height */
        if (!handle) {
                DRM_DEBUG_KMS("cursor off\n");
-               if (IS_MOBILE(dev) || IS_I9XX(dev)) {
-                       temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
-                       temp |= CURSOR_MODE_DISABLE;
-               } else {
-                       temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
-               }
                addr = 0;
                bo = NULL;
                mutex_lock(&dev->struct_mutex);
@@ -4008,7 +4354,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 
                addr = obj_priv->gtt_offset;
        } else {
-               ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
+               ret = i915_gem_attach_phys_object(dev, bo,
+                                                 (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
                if (ret) {
                        DRM_ERROR("failed to attach phys object\n");
                        goto fail_locked;
@@ -4019,21 +4366,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        if (!IS_I9XX(dev))
                I915_WRITE(CURSIZE, (height << 12) | width);
 
-       /* Hooray for CUR*CNTR differences */
-       if (IS_MOBILE(dev) || IS_I9XX(dev)) {
-               temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
-               temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-               temp |= (pipe << 28); /* Connect to correct pipe */
-       } else {
-               temp &= ~(CURSOR_FORMAT_MASK);
-               temp |= CURSOR_ENABLE;
-               temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
-       }
-
  finish:
-       I915_WRITE(control, temp);
-       I915_WRITE(base, addr);
-
        if (intel_crtc->cursor_bo) {
                if (dev_priv->info->cursor_needs_physical) {
                        if (intel_crtc->cursor_bo != bo)
@@ -4047,6 +4380,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 
        intel_crtc->cursor_addr = addr;
        intel_crtc->cursor_bo = bo;
+       intel_crtc->cursor_width = width;
+       intel_crtc->cursor_height = height;
+
+       intel_crtc_update_cursor(crtc);
 
        return 0;
 fail_unpin:
@@ -4060,34 +4397,12 @@ fail:
 
 static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_framebuffer *intel_fb;
-       int pipe = intel_crtc->pipe;
-       uint32_t temp = 0;
-       uint32_t adder;
-
-       if (crtc->fb) {
-               intel_fb = to_intel_framebuffer(crtc->fb);
-               intel_mark_busy(dev, intel_fb->obj);
-       }
-
-       if (x < 0) {
-               temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
-               x = -x;
-       }
-       if (y < 0) {
-               temp |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
-               y = -y;
-       }
 
-       temp |= x << CURSOR_X_SHIFT;
-       temp |= y << CURSOR_Y_SHIFT;
+       intel_crtc->cursor_x = x;
+       intel_crtc->cursor_y = y;
 
-       adder = intel_crtc->cursor_addr;
-       I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
-       I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
+       intel_crtc_update_cursor(crtc);
 
        return 0;
 }
@@ -4671,6 +4986,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
            atomic_dec_and_test(&obj_priv->pending_flip))
                DRM_WAKEUP(&dev_priv->pending_flip_queue);
        schedule_work(&work->work);
+
+       trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
 }
 
 void intel_finish_page_flip(struct drm_device *dev, int pipe)
@@ -4748,27 +5065,22 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        mutex_lock(&dev->struct_mutex);
        ret = intel_pin_and_fence_fb_obj(dev, obj);
-       if (ret != 0) {
-               mutex_unlock(&dev->struct_mutex);
-
-               spin_lock_irqsave(&dev->event_lock, flags);
-               intel_crtc->unpin_work = NULL;
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-
-               kfree(work);
-
-               DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
-                                to_intel_bo(obj));
-               return ret;
-       }
+       if (ret)
+               goto cleanup_work;
 
        /* Reference the objects for the scheduled work. */
        drm_gem_object_reference(work->old_fb_obj);
        drm_gem_object_reference(obj);
 
        crtc->fb = fb;
-       i915_gem_object_flush_write_domain(obj);
-       drm_vblank_get(dev, intel_crtc->pipe);
+       ret = i915_gem_object_flush_write_domain(obj);
+       if (ret)
+               goto cleanup_objs;
+
+       ret = drm_vblank_get(dev, intel_crtc->pipe);
+       if (ret)
+               goto cleanup_objs;
+
        obj_priv = to_intel_bo(obj);
        atomic_inc(&obj_priv->pending_flip);
        work->pending_flip_obj = obj;
@@ -4806,7 +5118,23 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        mutex_unlock(&dev->struct_mutex);
 
+       trace_i915_flip_request(intel_crtc->plane, obj);
+
        return 0;
+
+cleanup_objs:
+       drm_gem_object_unreference(work->old_fb_obj);
+       drm_gem_object_unreference(obj);
+cleanup_work:
+       mutex_unlock(&dev->struct_mutex);
+
+       spin_lock_irqsave(&dev->event_lock, flags);
+       intel_crtc->unpin_work = NULL;
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+
+       kfree(work);
+
+       return ret;
 }
 
 static const struct drm_crtc_helper_funcs intel_helper_funcs = {
@@ -4814,6 +5142,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
        .mode_fixup = intel_crtc_mode_fixup,
        .mode_set = intel_crtc_mode_set,
        .mode_set_base = intel_pipe_set_base,
+       .mode_set_base_atomic = intel_pipe_set_base_atomic,
        .prepare = intel_crtc_prepare,
        .commit = intel_crtc_commit,
        .load_lut = intel_crtc_load_lut,
@@ -4932,19 +5261,26 @@ static void intel_setup_outputs(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_encoder *encoder;
+       bool dpd_is_edp = false;
 
-       intel_crt_init(dev);
-
-       /* Set up integrated LVDS */
        if (IS_MOBILE(dev) && !IS_I830(dev))
                intel_lvds_init(dev);
 
        if (HAS_PCH_SPLIT(dev)) {
-               int found;
+               dpd_is_edp = intel_dpd_is_edp(dev);
 
                if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
                        intel_dp_init(dev, DP_A);
 
+               if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
+                       intel_dp_init(dev, PCH_DP_D);
+       }
+
+       intel_crt_init(dev);
+
+       if (HAS_PCH_SPLIT(dev)) {
+               int found;
+
                if (I915_READ(HDMIB) & PORT_DETECTED) {
                        /* PCH SDVOB multiplex with HDMIB */
                        found = intel_sdvo_init(dev, PCH_SDVOB);
@@ -4963,7 +5299,7 @@ static void intel_setup_outputs(struct drm_device *dev)
                if (I915_READ(PCH_DP_C) & DP_DETECTED)
                        intel_dp_init(dev, PCH_DP_C);
 
-               if (I915_READ(PCH_DP_D) & DP_DETECTED)
+               if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
                        intel_dp_init(dev, PCH_DP_D);
 
        } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
@@ -5372,6 +5708,26 @@ void intel_init_clock_gating(struct drm_device *dev)
                                        (I915_READ(DISP_ARB_CTL) |
                                                DISP_FBC_WM_DIS));
                }
+               /*
+                * Based on the document from hardware guys the following bits
+                * should be set unconditionally in order to enable FBC.
+                * The bit 22 of 0x42000
+                * The bit 22 of 0x42004
+                * The bit 7,8,9 of 0x42020.
+                */
+               if (IS_IRONLAKE_M(dev)) {
+                       I915_WRITE(ILK_DISPLAY_CHICKEN1,
+                                  I915_READ(ILK_DISPLAY_CHICKEN1) |
+                                  ILK_FBCQ_DIS);
+                       I915_WRITE(ILK_DISPLAY_CHICKEN2,
+                                  I915_READ(ILK_DISPLAY_CHICKEN2) |
+                                  ILK_DPARB_GATE);
+                       I915_WRITE(ILK_DSPCLK_GATE,
+                                  I915_READ(ILK_DSPCLK_GATE) |
+                                  ILK_DPFC_DIS1 |
+                                  ILK_DPFC_DIS2 |
+                                  ILK_CLK_FBC);
+               }
                return;
        } else if (IS_G4X(dev)) {
                uint32_t dspclk_gate;
@@ -5450,7 +5806,11 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.dpms = i9xx_crtc_dpms;
 
        if (I915_HAS_FBC(dev)) {
-               if (IS_GM45(dev)) {
+               if (IS_IRONLAKE_M(dev)) {
+                       dev_priv->display.fbc_enabled = ironlake_fbc_enabled;
+                       dev_priv->display.enable_fbc = ironlake_enable_fbc;
+                       dev_priv->display.disable_fbc = ironlake_disable_fbc;
+               } else if (IS_GM45(dev)) {
                        dev_priv->display.fbc_enabled = g4x_fbc_enabled;
                        dev_priv->display.enable_fbc = g4x_enable_fbc;
                        dev_priv->display.disable_fbc = g4x_disable_fbc;
index 5dde80f9e652ecc213353c59d6969c277869c874..40be1fa65be18fa730347b3da0f248a2b35b19e6 100644 (file)
@@ -43,6 +43,7 @@
 #define DP_LINK_CONFIGURATION_SIZE     9
 
 #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP)
+#define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp)
 
 struct intel_dp_priv {
        uint32_t output_reg;
@@ -56,6 +57,7 @@ struct intel_dp_priv {
        struct intel_encoder *intel_encoder;
        struct i2c_adapter adapter;
        struct i2c_algo_dp_aux_data algo;
+       bool is_pch_edp;
 };
 
 static void
@@ -128,8 +130,9 @@ intel_dp_link_required(struct drm_device *dev,
                       struct intel_encoder *intel_encoder, int pixel_clock)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
-       if (IS_eDP(intel_encoder))
+       if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv))
                return (pixel_clock * dev_priv->edp_bpp) / 8;
        else
                return pixel_clock * 3;
@@ -147,9 +150,21 @@ intel_dp_mode_valid(struct drm_connector *connector,
 {
        struct drm_encoder *encoder = intel_attached_encoder(connector);
        struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+       struct drm_device *dev = connector->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
        int max_lanes = intel_dp_max_lane_count(intel_encoder);
 
+       if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
+           dev_priv->panel_fixed_mode) {
+               if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay)
+                       return MODE_PANEL;
+
+               if (mode->vdisplay > dev_priv->panel_fixed_mode->vdisplay)
+                       return MODE_PANEL;
+       }
+
        /* only refuse the mode on non eDP since we have seen some wierd eDP panels
           which are outside spec tolerances but somehow work by magic */
        if (!IS_eDP(intel_encoder) &&
@@ -508,11 +523,37 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 {
        struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
        struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
+       struct drm_device *dev = encoder->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int lane_count, clock;
        int max_lane_count = intel_dp_max_lane_count(intel_encoder);
        int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
+       if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
+           dev_priv->panel_fixed_mode) {
+               struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
+
+               adjusted_mode->hdisplay = fixed_mode->hdisplay;
+               adjusted_mode->hsync_start = fixed_mode->hsync_start;
+               adjusted_mode->hsync_end = fixed_mode->hsync_end;
+               adjusted_mode->htotal = fixed_mode->htotal;
+
+               adjusted_mode->vdisplay = fixed_mode->vdisplay;
+               adjusted_mode->vsync_start = fixed_mode->vsync_start;
+               adjusted_mode->vsync_end = fixed_mode->vsync_end;
+               adjusted_mode->vtotal = fixed_mode->vtotal;
+
+               adjusted_mode->clock = fixed_mode->clock;
+               drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+
+               /*
+                * the mode->clock is used to calculate the Data&Link M/N
+                * of the pipe. For the eDP the fixed clock should be used.
+                */
+               mode->clock = dev_priv->panel_fixed_mode->clock;
+       }
+
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
@@ -531,7 +572,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                }
        }
 
-       if (IS_eDP(intel_encoder)) {
+       if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
                /* okay we failed just pick the highest */
                dp_priv->lane_count = max_lane_count;
                dp_priv->link_bw = bws[max_clock];
@@ -563,14 +604,14 @@ intel_reduce_ratio(uint32_t *num, uint32_t *den)
 }
 
 static void
-intel_dp_compute_m_n(int bytes_per_pixel,
+intel_dp_compute_m_n(int bpp,
                     int nlanes,
                     int pixel_clock,
                     int link_clock,
                     struct intel_dp_m_n *m_n)
 {
        m_n->tu = 64;
-       m_n->gmch_m = pixel_clock * bytes_per_pixel;
+       m_n->gmch_m = (pixel_clock * bpp) >> 3;
        m_n->gmch_n = link_clock * nlanes;
        intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
        m_n->link_m = pixel_clock;
@@ -578,6 +619,28 @@ intel_dp_compute_m_n(int bytes_per_pixel,
        intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
 }
 
+bool intel_pch_has_edp(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_mode_config *mode_config = &dev->mode_config;
+       struct drm_encoder *encoder;
+
+       list_for_each_entry(encoder, &mode_config->encoder_list, head) {
+               struct intel_encoder *intel_encoder;
+               struct intel_dp_priv *dp_priv;
+
+               if (!encoder || encoder->crtc != crtc)
+                       continue;
+
+               intel_encoder = enc_to_intel_encoder(encoder);
+               dp_priv = intel_encoder->dev_priv;
+
+               if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT)
+                       return dp_priv->is_pch_edp;
+       }
+       return false;
+}
+
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                 struct drm_display_mode *adjusted_mode)
@@ -587,7 +650,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
        struct drm_encoder *encoder;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int lane_count = 4;
+       int lane_count = 4, bpp = 24;
        struct intel_dp_m_n m_n;
 
        /*
@@ -605,6 +668,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 
                if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
                        lane_count = dp_priv->lane_count;
+                       if (IS_PCH_eDP(dp_priv))
+                               bpp = dev_priv->edp_bpp;
                        break;
                }
        }
@@ -614,7 +679,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
         * the number of bytes_per_pixel post-LUT, which we always
         * set up for 8-bits of R/G/B, or 3 bytes total.
         */
-       intel_dp_compute_m_n(3, lane_count,
+       intel_dp_compute_m_n(bpp, lane_count,
                             mode->clock, adjusted_mode->clock, &m_n);
 
        if (HAS_PCH_SPLIT(dev)) {
@@ -796,7 +861,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        if (mode != DRM_MODE_DPMS_ON) {
                if (dp_reg & DP_PORT_EN) {
                        intel_dp_link_down(intel_encoder, dp_priv->DP);
-                       if (IS_eDP(intel_encoder)) {
+                       if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
                                ironlake_edp_backlight_off(dev);
                                ironlake_edp_panel_off(dev);
                        }
@@ -804,7 +869,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        } else {
                if (!(dp_reg & DP_PORT_EN)) {
                        intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
-                       if (IS_eDP(intel_encoder)) {
+                       if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
                                ironlake_edp_panel_on(dev);
                                ironlake_edp_backlight_on(dev);
                        }
@@ -1340,17 +1405,32 @@ static int intel_dp_get_modes(struct drm_connector *connector)
        struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
        struct drm_device *dev = intel_encoder->enc.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        int ret;
 
        /* We should parse the EDID data and find out if it has an audio sink
         */
 
        ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
-       if (ret)
+       if (ret) {
+               if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
+                   !dev_priv->panel_fixed_mode) {
+                       struct drm_display_mode *newmode;
+                       list_for_each_entry(newmode, &connector->probed_modes,
+                                           head) {
+                               if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
+                                       dev_priv->panel_fixed_mode =
+                                               drm_mode_duplicate(dev, newmode);
+                                       break;
+                               }
+                       }
+               }
+
                return ret;
+       }
 
        /* if eDP has no EDID, try to use fixed panel mode from VBT */
-       if (IS_eDP(intel_encoder)) {
+       if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
                if (dev_priv->panel_fixed_mode != NULL) {
                        struct drm_display_mode *mode;
                        mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1435,6 +1515,26 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc)
        return -1;
 }
 
+/* check the VBT to see whether the eDP is on DP-D port */
+bool intel_dpd_is_edp(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct child_device_config *p_child;
+       int i;
+
+       if (!dev_priv->child_dev_num)
+               return false;
+
+       for (i = 0; i < dev_priv->child_dev_num; i++) {
+               p_child = dev_priv->child_dev + i;
+
+               if (p_child->dvo_port == PORT_IDPD &&
+                   p_child->device_type == DEVICE_TYPE_eDP)
+                       return true;
+       }
+       return false;
+}
+
 void
 intel_dp_init(struct drm_device *dev, int output_reg)
 {
@@ -1444,6 +1544,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
        struct intel_connector *intel_connector;
        struct intel_dp_priv *dp_priv;
        const char *name = NULL;
+       int type;
 
        intel_encoder = kcalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
@@ -1458,18 +1559,24 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
        dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
 
+       if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D))
+               if (intel_dpd_is_edp(dev))
+                       dp_priv->is_pch_edp = true;
+
+       if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
+               type = DRM_MODE_CONNECTOR_eDP;
+               intel_encoder->type = INTEL_OUTPUT_EDP;
+       } else {
+               type = DRM_MODE_CONNECTOR_DisplayPort;
+               intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+       }
+
        connector = &intel_connector->base;
-       drm_connector_init(dev, connector, &intel_dp_connector_funcs,
-                          DRM_MODE_CONNECTOR_DisplayPort);
+       drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
        drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
        connector->polled = DRM_CONNECTOR_POLL_HPD;
 
-       if (output_reg == DP_A)
-               intel_encoder->type = INTEL_OUTPUT_EDP;
-       else
-               intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
-
        if (output_reg == DP_B || output_reg == PCH_DP_B)
                intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
        else if (output_reg == DP_C || output_reg == PCH_DP_C)
@@ -1528,7 +1635,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
        intel_encoder->ddc_bus = &dp_priv->adapter;
        intel_encoder->hot_plug = intel_dp_hot_plug;
 
-       if (output_reg == DP_A) {
+       if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
                /* initialize panel mode from VBT if available for eDP */
                if (dev_priv->lfp_lvds_vbt_mode) {
                        dev_priv->panel_fixed_mode =
index 2f7970be9051a2c5eb308b9a5a4eebc09e6b636c..b2190148703a0c7c2b9a507783a056ac8a3d7814 100644 (file)
@@ -143,8 +143,6 @@ struct intel_crtc {
        struct drm_crtc base;
        enum pipe pipe;
        enum plane plane;
-       struct drm_gem_object *cursor_bo;
-       uint32_t cursor_addr;
        u8 lut_r[256], lut_g[256], lut_b[256];
        int dpms_mode;
        bool busy; /* is scanout buffer being updated frequently? */
@@ -153,6 +151,12 @@ struct intel_crtc {
        struct intel_overlay *overlay;
        struct intel_unpin_work *unpin_work;
        int fdi_lanes;
+
+       struct drm_gem_object *cursor_bo;
+       uint32_t cursor_addr;
+       int16_t cursor_x, cursor_y;
+       int16_t cursor_width, cursor_height;
+       bool cursor_visble;
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -179,6 +183,8 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                 struct drm_display_mode *adjusted_mode);
+extern bool intel_pch_has_edp(struct drm_crtc *crtc);
+extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 
 
index 3e18c9e7729b6a475ce270d3329acf3d54288f1c..54acd8b534df4bd092c71f4e8ce0998b7cd9dc09 100644 (file)
@@ -61,6 +61,8 @@ static struct fb_ops intelfb_ops = {
        .fb_pan_display = drm_fb_helper_pan_display,
        .fb_blank = drm_fb_helper_blank,
        .fb_setcmap = drm_fb_helper_setcmap,
+       .fb_debug_enter = drm_fb_helper_debug_enter,
+       .fb_debug_leave = drm_fb_helper_debug_leave,
 };
 
 static int intelfb_create(struct intel_fbdev *ifbdev,
index 83bd764b000e51cff80ac0a79a14b8cc5f05fcb4..197887ed1823fcc4e1023d3fbcc2900488b2796c 100644 (file)
@@ -54,10 +54,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
        struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        u32 sdvox;
 
-       sdvox = SDVO_ENCODING_HDMI |
-               SDVO_BORDER_ENABLE |
-               SDVO_VSYNC_ACTIVE_HIGH |
-               SDVO_HSYNC_ACTIVE_HIGH;
+       sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE;
+       if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+               sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
+       if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+               sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
 
        if (hdmi_priv->has_hdmi_sink) {
                sdvox |= SDVO_AUDIO_ENABLE;
index 0eab8df5bf7e1c679b52752311e665e51d3ab21d..0a2e60059fb31fc9ab9cd8ef208191b94b74e055 100644 (file)
@@ -156,31 +156,73 @@ static int intel_lvds_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
+static void
+centre_horizontally(struct drm_display_mode *mode,
+                   int width)
+{
+       u32 border, sync_pos, blank_width, sync_width;
+
+       /* keep the hsync and hblank widths constant */
+       sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
+       blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
+       sync_pos = (blank_width - sync_width + 1) / 2;
+
+       border = (mode->hdisplay - width + 1) / 2;
+       border += border & 1; /* make the border even */
+
+       mode->crtc_hdisplay = width;
+       mode->crtc_hblank_start = width + border;
+       mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
+
+       mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
+       mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
+}
+
+static void
+centre_vertically(struct drm_display_mode *mode,
+                 int height)
+{
+       u32 border, sync_pos, blank_width, sync_width;
+
+       /* keep the vsync and vblank widths constant */
+       sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
+       blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
+       sync_pos = (blank_width - sync_width + 1) / 2;
+
+       border = (mode->vdisplay - height + 1) / 2;
+
+       mode->crtc_vdisplay = height;
+       mode->crtc_vblank_start = height + border;
+       mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width;
+
+       mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
+       mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
+}
+
+static inline u32 panel_fitter_scaling(u32 source, u32 target)
+{
+       /*
+        * Floating point operation is not supported. So the FACTOR
+        * is defined, which can avoid the floating point computation
+        * when calculating the panel ratio.
+        */
+#define ACCURACY 12
+#define FACTOR (1 << ACCURACY)
+       u32 ratio = source * FACTOR / target;
+       return (FACTOR * ratio + FACTOR/2) / FACTOR;
+}
+
 static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
                                  struct drm_display_mode *mode,
                                  struct drm_display_mode *adjusted_mode)
 {
-       /*
-        * float point operation is not supported . So the PANEL_RATIO_FACTOR
-        * is defined, which can avoid the float point computation when
-        * calculating the panel ratio.
-        */
-#define PANEL_RATIO_FACTOR 8192
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
        struct drm_encoder *tmp_encoder;
        struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
        struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
-       u32 pfit_control = 0, pfit_pgm_ratios = 0;
-       int left_border = 0, right_border = 0, top_border = 0;
-       int bottom_border = 0;
-       bool border = 0;
-       int panel_ratio, desired_ratio, vert_scale, horiz_scale;
-       int horiz_ratio, vert_ratio;
-       u32 hsync_width, vsync_width;
-       u32 hblank_width, vblank_width;
-       u32 hsync_pos, vsync_pos;
+       u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
 
        /* Should never happen!! */
        if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
@@ -200,27 +242,25 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        if (dev_priv->panel_fixed_mode == NULL)
                return true;
        /*
-        * If we have timings from the BIOS for the panel, put them in
+        * We have timings from the BIOS for the panel, put them in
         * to the adjusted mode.  The CRTC will be set up for this mode,
         * with the panel scaling set up to source from the H/VDisplay
         * of the original mode.
         */
-       if (dev_priv->panel_fixed_mode != NULL) {
-               adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
-               adjusted_mode->hsync_start =
-                       dev_priv->panel_fixed_mode->hsync_start;
-               adjusted_mode->hsync_end =
-                       dev_priv->panel_fixed_mode->hsync_end;
-               adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
-               adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
-               adjusted_mode->vsync_start =
-                       dev_priv->panel_fixed_mode->vsync_start;
-               adjusted_mode->vsync_end =
-                       dev_priv->panel_fixed_mode->vsync_end;
-               adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
-               adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
-               drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-       }
+       adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
+       adjusted_mode->hsync_start =
+               dev_priv->panel_fixed_mode->hsync_start;
+       adjusted_mode->hsync_end =
+               dev_priv->panel_fixed_mode->hsync_end;
+       adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
+       adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
+       adjusted_mode->vsync_start =
+               dev_priv->panel_fixed_mode->vsync_start;
+       adjusted_mode->vsync_end =
+               dev_priv->panel_fixed_mode->vsync_end;
+       adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
+       adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
+       drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
 
        /* Make sure pre-965s set dither correctly */
        if (!IS_I965G(dev)) {
@@ -230,11 +270,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
 
        /* Native modes don't need fitting */
        if (adjusted_mode->hdisplay == mode->hdisplay &&
-                       adjusted_mode->vdisplay == mode->vdisplay) {
-               pfit_pgm_ratios = 0;
-               border = 0;
+           adjusted_mode->vdisplay == mode->vdisplay)
                goto out;
-       }
 
        /* full screen scale for now */
        if (HAS_PCH_SPLIT(dev))
@@ -242,25 +279,9 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
 
        /* 965+ wants fuzzy fitting */
        if (IS_I965G(dev))
-               pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) |
-                                       PFIT_FILTER_FUZZY;
-
-       hsync_width = adjusted_mode->crtc_hsync_end -
-                                       adjusted_mode->crtc_hsync_start;
-       vsync_width = adjusted_mode->crtc_vsync_end -
-                                       adjusted_mode->crtc_vsync_start;
-       hblank_width = adjusted_mode->crtc_hblank_end -
-                                       adjusted_mode->crtc_hblank_start;
-       vblank_width = adjusted_mode->crtc_vblank_end -
-                                       adjusted_mode->crtc_vblank_start;
-       /*
-        * Deal with panel fitting options. Figure out how to stretch the
-        * image based on its aspect ratio & the current panel fitting mode.
-        */
-       panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR /
-                               adjusted_mode->vdisplay;
-       desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR /
-                               mode->vdisplay;
+               pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
+                                PFIT_FILTER_FUZZY);
+
        /*
         * Enable automatic panel scaling for non-native modes so that they fill
         * the screen.  Should be enabled before the pipe is enabled, according
@@ -278,170 +299,63 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
                 * For centered modes, we have to calculate border widths &
                 * heights and modify the values programmed into the CRTC.
                 */
-               left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2;
-               right_border = left_border;
-               if (mode->hdisplay & 1)
-                       right_border++;
-               top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2;
-               bottom_border = top_border;
-               if (mode->vdisplay & 1)
-                       bottom_border++;
-               /* Set active & border values */
-               adjusted_mode->crtc_hdisplay = mode->hdisplay;
-               /* Keep the boder be even */
-               if (right_border & 1)
-                       right_border++;
-               /* use the border directly instead of border minuse one */
-               adjusted_mode->crtc_hblank_start = mode->hdisplay +
-                                               right_border;
-               /* keep the blank width constant */
-               adjusted_mode->crtc_hblank_end =
-                       adjusted_mode->crtc_hblank_start + hblank_width;
-               /* get the hsync pos relative to hblank start */
-               hsync_pos = (hblank_width - hsync_width) / 2;
-               /* keep the hsync pos be even */
-               if (hsync_pos & 1)
-                       hsync_pos++;
-               adjusted_mode->crtc_hsync_start =
-                               adjusted_mode->crtc_hblank_start + hsync_pos;
-               /* keep the hsync width constant */
-               adjusted_mode->crtc_hsync_end =
-                               adjusted_mode->crtc_hsync_start + hsync_width;
-               adjusted_mode->crtc_vdisplay = mode->vdisplay;
-               /* use the border instead of border minus one */
-               adjusted_mode->crtc_vblank_start = mode->vdisplay +
-                                               bottom_border;
-               /* keep the vblank width constant */
-               adjusted_mode->crtc_vblank_end =
-                               adjusted_mode->crtc_vblank_start + vblank_width;
-               /* get the vsync start postion relative to vblank start */
-               vsync_pos = (vblank_width - vsync_width) / 2;
-               adjusted_mode->crtc_vsync_start =
-                               adjusted_mode->crtc_vblank_start + vsync_pos;
-               /* keep the vsync width constant */
-               adjusted_mode->crtc_vsync_end =
-                               adjusted_mode->crtc_vsync_start + vsync_width;
-               border = 1;
+               centre_horizontally(adjusted_mode, mode->hdisplay);
+               centre_vertically(adjusted_mode, mode->vdisplay);
+               border = LVDS_BORDER_ENABLE;
                break;
+
        case DRM_MODE_SCALE_ASPECT:
-               /* Scale but preserve the spect ratio */
-               pfit_control |= PFIT_ENABLE;
+               /* Scale but preserve the aspect ratio */
                if (IS_I965G(dev)) {
+                       u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
+                       u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
+
+                       pfit_control |= PFIT_ENABLE;
                        /* 965+ is easy, it does everything in hw */
-                       if (panel_ratio > desired_ratio)
+                       if (scaled_width > scaled_height)
                                pfit_control |= PFIT_SCALING_PILLAR;
-                       else if (panel_ratio < desired_ratio)
+                       else if (scaled_width < scaled_height)
                                pfit_control |= PFIT_SCALING_LETTER;
                        else
                                pfit_control |= PFIT_SCALING_AUTO;
                } else {
+                       u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
+                       u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
                        /*
                         * For earlier chips we have to calculate the scaling
                         * ratio by hand and program it into the
                         * PFIT_PGM_RATIO register
                         */
-                       u32 horiz_bits, vert_bits, bits = 12;
-                       horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/
-                                               adjusted_mode->hdisplay;
-                       vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/
-                                               adjusted_mode->vdisplay;
-                       horiz_scale = adjusted_mode->hdisplay *
-                                       PANEL_RATIO_FACTOR / mode->hdisplay;
-                       vert_scale = adjusted_mode->vdisplay *
-                                       PANEL_RATIO_FACTOR / mode->vdisplay;
-
-                       /* retain aspect ratio */
-                       if (panel_ratio > desired_ratio) { /* Pillar */
-                               u32 scaled_width;
-                               scaled_width = mode->hdisplay * vert_scale /
-                                               PANEL_RATIO_FACTOR;
-                               horiz_ratio = vert_ratio;
-                               pfit_control |= (VERT_AUTO_SCALE |
-                                                VERT_INTERP_BILINEAR |
-                                                HORIZ_INTERP_BILINEAR);
-                               /* Pillar will have left/right borders */
-                               left_border = (adjusted_mode->hdisplay -
-                                               scaled_width) / 2;
-                               right_border = left_border;
-                               if (mode->hdisplay & 1) /* odd resolutions */
-                                       right_border++;
-                               /* keep the border be even */
-                               if (right_border & 1)
-                                       right_border++;
-                               adjusted_mode->crtc_hdisplay = scaled_width;
-                               /* use border instead of border minus one */
-                               adjusted_mode->crtc_hblank_start =
-                                       scaled_width + right_border;
-                               /* keep the hblank width constant */
-                               adjusted_mode->crtc_hblank_end =
-                                       adjusted_mode->crtc_hblank_start +
-                                                       hblank_width;
-                               /*
-                                * get the hsync start pos relative to
-                                * hblank start
-                                */
-                               hsync_pos = (hblank_width - hsync_width) / 2;
-                               /* keep the hsync_pos be even */
-                               if (hsync_pos & 1)
-                                       hsync_pos++;
-                               adjusted_mode->crtc_hsync_start =
-                                       adjusted_mode->crtc_hblank_start +
-                                                       hsync_pos;
-                               /* keept hsync width constant */
-                               adjusted_mode->crtc_hsync_end =
-                                       adjusted_mode->crtc_hsync_start +
-                                                       hsync_width;
-                               border = 1;
-                       } else if (panel_ratio < desired_ratio) { /* letter */
-                               u32 scaled_height = mode->vdisplay *
-                                       horiz_scale / PANEL_RATIO_FACTOR;
-                               vert_ratio = horiz_ratio;
-                               pfit_control |= (HORIZ_AUTO_SCALE |
-                                                VERT_INTERP_BILINEAR |
-                                                HORIZ_INTERP_BILINEAR);
-                               /* Letterbox will have top/bottom border */
-                               top_border = (adjusted_mode->vdisplay -
-                                       scaled_height) / 2;
-                               bottom_border = top_border;
-                               if (mode->vdisplay & 1)
-                                       bottom_border++;
-                               adjusted_mode->crtc_vdisplay = scaled_height;
-                               /* use border instead of border minus one */
-                               adjusted_mode->crtc_vblank_start =
-                                       scaled_height + bottom_border;
-                               /* keep the vblank width constant */
-                               adjusted_mode->crtc_vblank_end =
-                                       adjusted_mode->crtc_vblank_start +
-                                                       vblank_width;
-                               /*
-                                * get the vsync start pos relative to
-                                * vblank start
-                                */
-                               vsync_pos = (vblank_width - vsync_width) / 2;
-                               adjusted_mode->crtc_vsync_start =
-                                       adjusted_mode->crtc_vblank_start +
-                                                       vsync_pos;
-                               /* keep the vsync width constant */
-                               adjusted_mode->crtc_vsync_end =
-                                       adjusted_mode->crtc_vsync_start +
-                                                       vsync_width;
-                               border = 1;
-                       } else {
-                       /* Aspects match, Let hw scale both directions */
-                               pfit_control |= (VERT_AUTO_SCALE |
-                                                HORIZ_AUTO_SCALE |
+                       if (scaled_width > scaled_height) { /* pillar */
+                               centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay);
+
+                               border = LVDS_BORDER_ENABLE;
+                               if (mode->vdisplay != adjusted_mode->vdisplay) {
+                                       u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay);
+                                       pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+                                                           bits << PFIT_VERT_SCALE_SHIFT);
+                                       pfit_control |= (PFIT_ENABLE |
+                                                        VERT_INTERP_BILINEAR |
+                                                        HORIZ_INTERP_BILINEAR);
+                               }
+                       } else if (scaled_width < scaled_height) { /* letter */
+                               centre_vertically(adjusted_mode, scaled_width / mode->hdisplay);
+
+                               border = LVDS_BORDER_ENABLE;
+                               if (mode->hdisplay != adjusted_mode->hdisplay) {
+                                       u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay);
+                                       pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+                                                           bits << PFIT_VERT_SCALE_SHIFT);
+                                       pfit_control |= (PFIT_ENABLE |
+                                                        VERT_INTERP_BILINEAR |
+                                                        HORIZ_INTERP_BILINEAR);
+                               }
+                       } else
+                               /* Aspects match, Let hw scale both directions */
+                               pfit_control |= (PFIT_ENABLE |
+                                                VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
                                                 VERT_INTERP_BILINEAR |
                                                 HORIZ_INTERP_BILINEAR);
-                       }
-                       horiz_bits = (1 << bits) * horiz_ratio /
-                                       PANEL_RATIO_FACTOR;
-                       vert_bits = (1 << bits) * vert_ratio /
-                                       PANEL_RATIO_FACTOR;
-                       pfit_pgm_ratios =
-                               ((vert_bits << PFIT_VERT_SCALE_SHIFT) &
-                                               PFIT_VERT_SCALE_MASK) |
-                               ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) &
-                                               PFIT_HORIZ_SCALE_MASK);
                }
                break;
 
@@ -458,6 +372,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
                                         VERT_INTERP_BILINEAR |
                                         HORIZ_INTERP_BILINEAR);
                break;
+
        default:
                break;
        }
@@ -465,14 +380,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
 out:
        lvds_priv->pfit_control = pfit_control;
        lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios;
-       /*
-        * When there exists the border, it means that the LVDS_BORDR
-        * should be enabled.
-        */
-       if (border)
-               dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE;
-       else
-               dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE);
+       dev_priv->lvds_border_bits = border;
+
        /*
         * XXX: It would be nice to support lower refresh rates on the
         * panels to reduce power consumption, and perhaps match the
index d7ad5139d17cefa543ae30652757b81ff48b407b..d39aea24eabe3b2d0bc9bf42bc6344d6457bd3ec 100644 (file)
@@ -65,7 +65,7 @@
 #define OCMD_YUV_410_PLANAR    (0xe<<10) /* also 411 */
 #define OCMD_TVSYNCFLIP_PARITY (0x1<<9)
 #define OCMD_TVSYNCFLIP_ENABLE (0x1<<7)
-#define OCMD_BUF_TYPE_MASK     (Ox1<<5)
+#define OCMD_BUF_TYPE_MASK     (0x1<<5)
 #define OCMD_BUF_TYPE_FRAME    (0x0<<5)
 #define OCMD_BUF_TYPE_FIELD    (0x1<<5)
 #define OCMD_TEST_MODE         (0x1<<4)
@@ -185,7 +185,8 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over
 
        if (OVERLAY_NONPHYSICAL(overlay->dev)) {
                regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
-                               overlay->reg_bo->gtt_offset);
+                                               overlay->reg_bo->gtt_offset,
+                                               KM_USER0);
 
                if (!regs) {
                        DRM_ERROR("failed to map overlay regs in GTT\n");
@@ -200,7 +201,7 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over
 static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
 {
        if (OVERLAY_NONPHYSICAL(overlay->dev))
-               io_mapping_unmap_atomic(overlay->virt_addr);
+               io_mapping_unmap_atomic(overlay->virt_addr, KM_USER0);
 
        overlay->virt_addr = NULL;
 
@@ -958,7 +959,7 @@ static int check_overlay_src(struct drm_device *dev,
            || rec->src_width < N_HORIZ_Y_TAPS*4)
                return -EINVAL;
 
-       /* check alingment constrains */
+       /* check alignment constraints */
        switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
                case I915_OVERLAY_RGB:
                        /* not implemented */
@@ -990,7 +991,10 @@ static int check_overlay_src(struct drm_device *dev,
                return -EINVAL;
 
        /* stride checking */
-       stride_mask = 63;
+       if (IS_I830(dev) || IS_845G(dev))
+               stride_mask = 255;
+       else
+               stride_mask = 63;
 
        if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
                return -EINVAL;
index 03c231be22736082d89a4b69aeb593f5e6b3b127..d9d4d51aa89e618ca6056db3f35a3e7666e65853 100644 (file)
@@ -1237,9 +1237,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
 
        /* Set the SDVO control regs. */
        if (IS_I965G(dev)) {
-               sdvox |= SDVO_BORDER_ENABLE |
-                       SDVO_VSYNC_ACTIVE_HIGH |
-                       SDVO_HSYNC_ACTIVE_HIGH;
+               sdvox |= SDVO_BORDER_ENABLE;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+                       sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+                       sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
        } else {
                sdvox |= I915_READ(sdvo_priv->sdvo_reg);
                switch (sdvo_priv->sdvo_reg) {
index d2d4e4045ca9b74788257385b4d8178aac41a1ac..cc3726a4a1cb12cf0acb69baf1bce7f81586b111 100644 (file)
@@ -476,7 +476,7 @@ static const struct tv_mode tv_modes[] = {
                .vi_end_f1      = 20,               .vi_end_f2          = 21,
                .nbr_end        = 240,
 
-               .burst_ena      = 8,
+               .burst_ena      = true,
                .hburst_start   = 72,               .hburst_len         = 34,
                .vburst_start_f1 = 9,               .vburst_end_f1      = 240,
                .vburst_start_f2 = 10,              .vburst_end_f2      = 240,
@@ -896,8 +896,6 @@ static const struct tv_mode tv_modes[] = {
        },
 };
 
-#define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0])
-
 static void
 intel_tv_dpms(struct drm_encoder *encoder, int mode)
 {
@@ -1512,7 +1510,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
                tv_priv->margin[TV_MARGIN_BOTTOM] = val;
                changed = true;
        } else if (property == dev->mode_config.tv_mode_property) {
-               if (val >= NUM_TV_MODES) {
+               if (val >= ARRAY_SIZE(tv_modes)) {
                        ret = -EINVAL;
                        goto out;
                }
@@ -1693,13 +1691,13 @@ intel_tv_init(struct drm_device *dev)
        connector->doublescan_allowed = false;
 
        /* Create TV properties then attach current values */
-       tv_format_names = kmalloc(sizeof(char *) * NUM_TV_MODES,
+       tv_format_names = kmalloc(sizeof(char *) * ARRAY_SIZE(tv_modes),
                                  GFP_KERNEL);
        if (!tv_format_names)
                goto out;
-       for (i = 0; i < NUM_TV_MODES; i++)
+       for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
                tv_format_names[i] = tv_modes[i].name;
-       drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
+       drm_mode_create_tv_properties(dev, ARRAY_SIZE(tv_modes), tv_format_names);
 
        drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
                                   initial_mode);
index 3c917fb3a60b85398d84d456d36093d02924525b..08868ac3048aec326ce203ba82d6af1f83ff3ac0 100644 (file)
@@ -52,7 +52,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup);
  * Engine control
  */
 
-int mga_do_wait_for_idle(drm_mga_private_t * dev_priv)
+int mga_do_wait_for_idle(drm_mga_private_t *dev_priv)
 {
        u32 status = 0;
        int i;
@@ -74,7 +74,7 @@ int mga_do_wait_for_idle(drm_mga_private_t * dev_priv)
        return -EBUSY;
 }
 
-static int mga_do_dma_reset(drm_mga_private_t * dev_priv)
+static int mga_do_dma_reset(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_primary_buffer_t *primary = &dev_priv->prim;
@@ -102,7 +102,7 @@ static int mga_do_dma_reset(drm_mga_private_t * dev_priv)
  * Primary DMA stream
  */
 
-void mga_do_dma_flush(drm_mga_private_t * dev_priv)
+void mga_do_dma_flush(drm_mga_private_t *dev_priv)
 {
        drm_mga_primary_buffer_t *primary = &dev_priv->prim;
        u32 head, tail;
@@ -142,11 +142,10 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv)
 
        head = MGA_READ(MGA_PRIMADDRESS);
 
-       if (head <= tail) {
+       if (head <= tail)
                primary->space = primary->size - primary->tail;
-       } else {
+       else
                primary->space = head - tail;
-       }
 
        DRM_DEBUG("   head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
        DRM_DEBUG("   tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset));
@@ -158,7 +157,7 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv)
        DRM_DEBUG("done.\n");
 }
 
-void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
+void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv)
 {
        drm_mga_primary_buffer_t *primary = &dev_priv->prim;
        u32 head, tail;
@@ -181,11 +180,10 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
 
        head = MGA_READ(MGA_PRIMADDRESS);
 
-       if (head == dev_priv->primary->offset) {
+       if (head == dev_priv->primary->offset)
                primary->space = primary->size;
-       } else {
+       else
                primary->space = head - dev_priv->primary->offset;
-       }
 
        DRM_DEBUG("   head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
        DRM_DEBUG("   tail = 0x%06x\n", primary->tail);
@@ -199,7 +197,7 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
        DRM_DEBUG("done.\n");
 }
 
-void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv)
+void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv)
 {
        drm_mga_primary_buffer_t *primary = &dev_priv->prim;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -220,11 +218,11 @@ void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv)
  * Freelist management
  */
 
-#define MGA_BUFFER_USED                ~0
+#define MGA_BUFFER_USED                (~0)
 #define MGA_BUFFER_FREE                0
 
 #if MGA_FREELIST_DEBUG
-static void mga_freelist_print(struct drm_device * dev)
+static void mga_freelist_print(struct drm_device *dev)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_freelist_t *entry;
@@ -245,7 +243,7 @@ static void mga_freelist_print(struct drm_device * dev)
 }
 #endif
 
-static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_priv)
+static int mga_freelist_init(struct drm_device *dev, drm_mga_private_t *dev_priv)
 {
        struct drm_device_dma *dma = dev->dma;
        struct drm_buf *buf;
@@ -288,7 +286,7 @@ static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_pr
        return 0;
 }
 
-static void mga_freelist_cleanup(struct drm_device * dev)
+static void mga_freelist_cleanup(struct drm_device *dev)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_freelist_t *entry;
@@ -308,7 +306,7 @@ static void mga_freelist_cleanup(struct drm_device * dev)
 #if 0
 /* FIXME: Still needed?
  */
-static void mga_freelist_reset(struct drm_device * dev)
+static void mga_freelist_reset(struct drm_device *dev)
 {
        struct drm_device_dma *dma = dev->dma;
        struct drm_buf *buf;
@@ -356,7 +354,7 @@ static struct drm_buf *mga_freelist_get(struct drm_device * dev)
        return NULL;
 }
 
-int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
+int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_buf_priv_t *buf_priv = buf->dev_private;
@@ -391,7 +389,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
  * DMA initialization, cleanup
  */
 
-int mga_driver_load(struct drm_device * dev, unsigned long flags)
+int mga_driver_load(struct drm_device *dev, unsigned long flags)
 {
        drm_mga_private_t *dev_priv;
        int ret;
@@ -405,8 +403,8 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags)
        dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
        dev_priv->chipset = flags;
 
-       dev_priv->mmio_base = drm_get_resource_start(dev, 1);
-       dev_priv->mmio_size = drm_get_resource_len(dev, 1);
+       dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
+       dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
 
        dev->counters += 3;
        dev->types[6] = _DRM_STAT_IRQ;
@@ -439,8 +437,8 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags)
  *
  * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap
  */
-static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
-                                   drm_mga_dma_bootstrap_t * dma_bs)
+static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
+                                   drm_mga_dma_bootstrap_t *dma_bs)
 {
        drm_mga_private_t *const dev_priv =
            (drm_mga_private_t *) dev->dev_private;
@@ -481,11 +479,10 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
         */
 
        if (dev_priv->chipset == MGA_CARD_TYPE_G200) {
-               if (mode.mode & 0x02) {
+               if (mode.mode & 0x02)
                        MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE);
-               } else {
+               else
                        MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE);
-               }
        }
 
        /* Allocate and bind AGP memory. */
@@ -593,8 +590,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
        return 0;
 }
 #else
-static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
-                                   drm_mga_dma_bootstrap_t * dma_bs)
+static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
+                                   drm_mga_dma_bootstrap_t *dma_bs)
 {
        return -EINVAL;
 }
@@ -614,8 +611,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
  *
  * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap
  */
-static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
-                                   drm_mga_dma_bootstrap_t * dma_bs)
+static int mga_do_pci_dma_bootstrap(struct drm_device *dev,
+                                   drm_mga_dma_bootstrap_t *dma_bs)
 {
        drm_mga_private_t *const dev_priv =
            (drm_mga_private_t *) dev->dev_private;
@@ -678,9 +675,8 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
                req.size = dma_bs->secondary_bin_size;
 
                err = drm_addbufs_pci(dev, &req);
-               if (!err) {
+               if (!err)
                        break;
-               }
        }
 
        if (bin_count == 0) {
@@ -704,8 +700,8 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
        return 0;
 }
 
-static int mga_do_dma_bootstrap(struct drm_device * dev,
-                               drm_mga_dma_bootstrap_t * dma_bs)
+static int mga_do_dma_bootstrap(struct drm_device *dev,
+                               drm_mga_dma_bootstrap_t *dma_bs)
 {
        const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev);
        int err;
@@ -737,17 +733,15 @@ static int mga_do_dma_bootstrap(struct drm_device * dev,
         * carve off portions of it for internal uses.  The remaining memory
         * is returned to user-mode to be used for AGP textures.
         */
-       if (is_agp) {
+       if (is_agp)
                err = mga_do_agp_dma_bootstrap(dev, dma_bs);
-       }
 
        /* If we attempted to initialize the card for AGP DMA but failed,
         * clean-up any mess that may have been created.
         */
 
-       if (err) {
+       if (err)
                mga_do_cleanup_dma(dev, MINIMAL_CLEANUP);
-       }
 
        /* Not only do we want to try and initialized PCI cards for PCI DMA,
         * but we also try to initialized AGP cards that could not be
@@ -757,9 +751,8 @@ static int mga_do_dma_bootstrap(struct drm_device * dev,
         * AGP memory, etc.
         */
 
-       if (!is_agp || err) {
+       if (!is_agp || err)
                err = mga_do_pci_dma_bootstrap(dev, dma_bs);
-       }
 
        return err;
 }
@@ -792,7 +785,7 @@ int mga_dma_bootstrap(struct drm_device *dev, void *data,
        return err;
 }
 
-static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
+static int mga_do_init_dma(struct drm_device *dev, drm_mga_init_t *init)
 {
        drm_mga_private_t *dev_priv;
        int ret;
@@ -800,11 +793,10 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
 
        dev_priv = dev->dev_private;
 
-       if (init->sgram) {
+       if (init->sgram)
                dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;
-       } else {
+       else
                dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
-       }
        dev_priv->maccess = init->maccess;
 
        dev_priv->fb_cpp = init->fb_cpp;
@@ -975,9 +967,8 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
                                dev_priv->agp_handle = 0;
                        }
 
-                       if ((dev->agp != NULL) && dev->agp->acquired) {
+                       if ((dev->agp != NULL) && dev->agp->acquired)
                                err = drm_agp_release(dev);
-                       }
 #endif
                }
 
@@ -998,9 +989,8 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
                memset(dev_priv->warp_pipe_phys, 0,
                       sizeof(dev_priv->warp_pipe_phys));
 
-               if (dev_priv->head != NULL) {
+               if (dev_priv->head != NULL)
                        mga_freelist_cleanup(dev);
-               }
        }
 
        return err;
@@ -1017,9 +1007,8 @@ int mga_dma_init(struct drm_device *dev, void *data,
        switch (init->func) {
        case MGA_INIT_DMA:
                err = mga_do_init_dma(dev, init);
-               if (err) {
+               if (err)
                        (void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
-               }
                return err;
        case MGA_CLEANUP_DMA:
                return mga_do_cleanup_dma(dev, FULL_CLEANUP);
@@ -1047,9 +1036,8 @@ int mga_dma_flush(struct drm_device *dev, void *data,
 
        WRAP_WAIT_WITH_RETURN(dev_priv);
 
-       if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) {
+       if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL))
                mga_do_dma_flush(dev_priv);
-       }
 
        if (lock->flags & _DRM_LOCK_QUIESCENT) {
 #if MGA_DMA_DEBUG
@@ -1079,8 +1067,8 @@ int mga_dma_reset(struct drm_device *dev, void *data,
  * DMA buffer management
  */
 
-static int mga_dma_get_buffers(struct drm_device * dev,
-                              struct drm_file *file_priv, struct drm_dma * d)
+static int mga_dma_get_buffers(struct drm_device *dev,
+                              struct drm_file *file_priv, struct drm_dma *d)
 {
        struct drm_buf *buf;
        int i;
@@ -1134,9 +1122,8 @@ int mga_dma_buffers(struct drm_device *dev, void *data,
 
        d->granted_count = 0;
 
-       if (d->request_count) {
+       if (d->request_count)
                ret = mga_dma_get_buffers(dev, file_priv, d);
-       }
 
        return ret;
 }
@@ -1144,7 +1131,7 @@ int mga_dma_buffers(struct drm_device *dev, void *data,
 /**
  * Called just before the module is unloaded.
  */
-int mga_driver_unload(struct drm_device * dev)
+int mga_driver_unload(struct drm_device *dev)
 {
        kfree(dev->dev_private);
        dev->dev_private = NULL;
@@ -1155,12 +1142,12 @@ int mga_driver_unload(struct drm_device * dev)
 /**
  * Called when the last opener of the device is closed.
  */
-void mga_driver_lastclose(struct drm_device * dev)
+void mga_driver_lastclose(struct drm_device *dev)
 {
        mga_do_cleanup_dma(dev, FULL_CLEANUP);
 }
 
-int mga_driver_dma_quiescent(struct drm_device * dev)
+int mga_driver_dma_quiescent(struct drm_device *dev)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        return mga_do_wait_for_idle(dev_priv);
index ddfe16197b59336e6d9c874e9e1b855a8222c430..26d0d8ced80d4357421875b4c7344f53e21d96b4 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "drm_pciids.h"
 
-static int mga_driver_device_is_agp(struct drm_device * dev);
+static int mga_driver_device_is_agp(struct drm_device *dev);
 
 static struct pci_device_id pciidlist[] = {
        mga_PCI_IDS
@@ -119,7 +119,7 @@ MODULE_LICENSE("GPL and additional rights");
  * \returns
  * If the device is a PCI G450, zero is returned.  Otherwise 2 is returned.
  */
-static int mga_driver_device_is_agp(struct drm_device * dev)
+static int mga_driver_device_is_agp(struct drm_device *dev)
 {
        const struct pci_dev *const pdev = dev->pdev;
 
index be6c6b9b0e89a3b3d3af7c2cf134744f210571ce..1084fa4d261b7c9d6638d965a5a4c401c9949720 100644 (file)
@@ -164,59 +164,59 @@ extern int mga_dma_reset(struct drm_device *dev, void *data,
 extern int mga_dma_buffers(struct drm_device *dev, void *data,
                           struct drm_file *file_priv);
 extern int mga_driver_load(struct drm_device *dev, unsigned long flags);
-extern int mga_driver_unload(struct drm_device * dev);
-extern void mga_driver_lastclose(struct drm_device * dev);
-extern int mga_driver_dma_quiescent(struct drm_device * dev);
+extern int mga_driver_unload(struct drm_device *dev);
+extern void mga_driver_lastclose(struct drm_device *dev);
+extern int mga_driver_dma_quiescent(struct drm_device *dev);
 
-extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);
+extern int mga_do_wait_for_idle(drm_mga_private_t *dev_priv);
 
-extern void mga_do_dma_flush(drm_mga_private_t * dev_priv);
-extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv);
-extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
+extern void mga_do_dma_flush(drm_mga_private_t *dev_priv);
+extern void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv);
+extern void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv);
 
-extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf);
+extern int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf);
 
                                /* mga_warp.c */
-extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
-extern int mga_warp_init(drm_mga_private_t * dev_priv);
+extern int mga_warp_install_microcode(drm_mga_private_t *dev_priv);
+extern int mga_warp_init(drm_mga_private_t *dev_priv);
 
                                /* mga_irq.c */
 extern int mga_enable_vblank(struct drm_device *dev, int crtc);
 extern void mga_disable_vblank(struct drm_device *dev, int crtc);
 extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
-extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
-extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
+extern int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence);
+extern int mga_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
 extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
-extern void mga_driver_irq_preinstall(struct drm_device * dev);
+extern void mga_driver_irq_preinstall(struct drm_device *dev);
 extern int mga_driver_irq_postinstall(struct drm_device *dev);
-extern void mga_driver_irq_uninstall(struct drm_device * dev);
+extern void mga_driver_irq_uninstall(struct drm_device *dev);
 extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
                             unsigned long arg);
 
 #define mga_flush_write_combine()      DRM_WRITEMEMORYBARRIER()
 
 #if defined(__linux__) && defined(__alpha__)
-#define MGA_BASE( reg )                ((unsigned long)(dev_priv->mmio->handle))
-#define MGA_ADDR( reg )                (MGA_BASE(reg) + reg)
+#define MGA_BASE(reg)          ((unsigned long)(dev_priv->mmio->handle))
+#define MGA_ADDR(reg)          (MGA_BASE(reg) + reg)
 
-#define MGA_DEREF( reg )       *(volatile u32 *)MGA_ADDR( reg )
-#define MGA_DEREF8( reg )      *(volatile u8 *)MGA_ADDR( reg )
+#define MGA_DEREF(reg)         (*(volatile u32 *)MGA_ADDR(reg))
+#define MGA_DEREF8(reg)                (*(volatile u8 *)MGA_ADDR(reg))
 
-#define MGA_READ( reg )                (_MGA_READ((u32 *)MGA_ADDR(reg)))
-#define MGA_READ8( reg )       (_MGA_READ((u8 *)MGA_ADDR(reg)))
-#define MGA_WRITE( reg, val )  do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
-#define MGA_WRITE8( reg, val )  do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
+#define MGA_READ(reg)          (_MGA_READ((u32 *)MGA_ADDR(reg)))
+#define MGA_READ8(reg)         (_MGA_READ((u8 *)MGA_ADDR(reg)))
+#define MGA_WRITE(reg, val)    do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF(reg) = val; } while (0)
+#define MGA_WRITE8(reg, val)   do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8(reg) = val; } while (0)
 
-static inline u32 _MGA_READ(u32 * addr)
+static inline u32 _MGA_READ(u32 *addr)
 {
        DRM_MEMORYBARRIER();
        return *(volatile u32 *)addr;
 }
 #else
-#define MGA_READ8( reg )       DRM_READ8(dev_priv->mmio, (reg))
-#define MGA_READ( reg )                DRM_READ32(dev_priv->mmio, (reg))
-#define MGA_WRITE8( reg, val )  DRM_WRITE8(dev_priv->mmio, (reg), (val))
-#define MGA_WRITE( reg, val )  DRM_WRITE32(dev_priv->mmio, (reg), (val))
+#define MGA_READ8(reg)         DRM_READ8(dev_priv->mmio, (reg))
+#define MGA_READ(reg)          DRM_READ32(dev_priv->mmio, (reg))
+#define MGA_WRITE8(reg, val)   DRM_WRITE8(dev_priv->mmio, (reg), (val))
+#define MGA_WRITE(reg, val)    DRM_WRITE32(dev_priv->mmio, (reg), (val))
 #endif
 
 #define DWGREG0                0x1c00
@@ -233,40 +233,39 @@ static inline u32 _MGA_READ(u32 * addr)
  * Helper macross...
  */
 
-#define MGA_EMIT_STATE( dev_priv, dirty )                              \
+#define MGA_EMIT_STATE(dev_priv, dirty)                                        \
 do {                                                                   \
-       if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) {                        \
-               if ( dev_priv->chipset >= MGA_CARD_TYPE_G400 ) {        \
-                       mga_g400_emit_state( dev_priv );                \
-               } else {                                                \
-                       mga_g200_emit_state( dev_priv );                \
-               }                                                       \
+       if ((dirty) & ~MGA_UPLOAD_CLIPRECTS) {                          \
+               if (dev_priv->chipset >= MGA_CARD_TYPE_G400)            \
+                       mga_g400_emit_state(dev_priv);                  \
+               else                                                    \
+                       mga_g200_emit_state(dev_priv);                  \
        }                                                               \
 } while (0)
 
-#define WRAP_TEST_WITH_RETURN( dev_priv )                              \
+#define WRAP_TEST_WITH_RETURN(dev_priv)                                        \
 do {                                                                   \
-       if ( test_bit( 0, &dev_priv->prim.wrapped ) ) {                 \
-               if ( mga_is_idle( dev_priv ) ) {                        \
-                       mga_do_dma_wrap_end( dev_priv );                \
-               } else if ( dev_priv->prim.space <                      \
-                           dev_priv->prim.high_mark ) {                \
-                       if ( MGA_DMA_DEBUG )                            \
-                               DRM_INFO( "wrap...\n");         \
-                       return -EBUSY;                  \
+       if (test_bit(0, &dev_priv->prim.wrapped)) {                     \
+               if (mga_is_idle(dev_priv)) {                            \
+                       mga_do_dma_wrap_end(dev_priv);                  \
+               } else if (dev_priv->prim.space <                       \
+                          dev_priv->prim.high_mark) {                  \
+                       if (MGA_DMA_DEBUG)                              \
+                               DRM_INFO("wrap...\n");                  \
+                       return -EBUSY;                                  \
                }                                                       \
        }                                                               \
 } while (0)
 
-#define WRAP_WAIT_WITH_RETURN( dev_priv )                              \
+#define WRAP_WAIT_WITH_RETURN(dev_priv)                                        \
 do {                                                                   \
-       if ( test_bit( 0, &dev_priv->prim.wrapped ) ) {                 \
-               if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {           \
-                       if ( MGA_DMA_DEBUG )                            \
-                               DRM_INFO( "wrap...\n");         \
-                       return -EBUSY;                  \
+       if (test_bit(0, &dev_priv->prim.wrapped)) {                     \
+               if (mga_do_wait_for_idle(dev_priv) < 0) {               \
+                       if (MGA_DMA_DEBUG)                              \
+                               DRM_INFO("wrap...\n");                  \
+                       return -EBUSY;                                  \
                }                                                       \
-               mga_do_dma_wrap_end( dev_priv );                        \
+               mga_do_dma_wrap_end(dev_priv);                          \
        }                                                               \
 } while (0)
 
@@ -280,12 +279,12 @@ do {                                                                      \
 
 #define DMA_BLOCK_SIZE (5 * sizeof(u32))
 
-#define BEGIN_DMA( n )                                                 \
+#define BEGIN_DMA(n)                                                   \
 do {                                                                   \
-       if ( MGA_VERBOSE ) {                                            \
-               DRM_INFO( "BEGIN_DMA( %d )\n", (n) );           \
-               DRM_INFO( "   space=0x%x req=0x%Zx\n",                  \
-                         dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
+       if (MGA_VERBOSE) {                                              \
+               DRM_INFO("BEGIN_DMA(%d)\n", (n));                       \
+               DRM_INFO("   space=0x%x req=0x%Zx\n",                   \
+                        dev_priv->prim.space, (n) * DMA_BLOCK_SIZE);   \
        }                                                               \
        prim = dev_priv->prim.start;                                    \
        write = dev_priv->prim.tail;                                    \
@@ -293,9 +292,9 @@ do {                                                                        \
 
 #define BEGIN_DMA_WRAP()                                               \
 do {                                                                   \
-       if ( MGA_VERBOSE ) {                                            \
-               DRM_INFO( "BEGIN_DMA()\n" );                            \
-               DRM_INFO( "   space=0x%x\n", dev_priv->prim.space );    \
+       if (MGA_VERBOSE) {                                              \
+               DRM_INFO("BEGIN_DMA()\n");                              \
+               DRM_INFO("   space=0x%x\n", dev_priv->prim.space);      \
        }                                                               \
        prim = dev_priv->prim.start;                                    \
        write = dev_priv->prim.tail;                                    \
@@ -304,72 +303,68 @@ do {                                                                      \
 #define ADVANCE_DMA()                                                  \
 do {                                                                   \
        dev_priv->prim.tail = write;                                    \
-       if ( MGA_VERBOSE ) {                                            \
-               DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n",        \
-                         write, dev_priv->prim.space );                \
-       }                                                               \
+       if (MGA_VERBOSE)                                                \
+               DRM_INFO("ADVANCE_DMA() tail=0x%05x sp=0x%x\n",         \
+                        write, dev_priv->prim.space);                  \
 } while (0)
 
 #define FLUSH_DMA()                                                    \
 do {                                                                   \
-       if ( 0 ) {                                                      \
-               DRM_INFO( "\n" );                                       \
-               DRM_INFO( "   tail=0x%06x head=0x%06lx\n",              \
-                         dev_priv->prim.tail,                          \
-                         (unsigned long)(MGA_READ(MGA_PRIMADDRESS) -   \
-                                         dev_priv->primary->offset));  \
+       if (0) {                                                        \
+               DRM_INFO("\n");                                         \
+               DRM_INFO("   tail=0x%06x head=0x%06lx\n",               \
+                        dev_priv->prim.tail,                           \
+                        (unsigned long)(MGA_READ(MGA_PRIMADDRESS) -    \
+                                        dev_priv->primary->offset));   \
        }                                                               \
-       if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) {                \
-               if ( dev_priv->prim.space <                             \
-                    dev_priv->prim.high_mark ) {                       \
-                       mga_do_dma_wrap_start( dev_priv );              \
-               } else {                                                \
-                       mga_do_dma_flush( dev_priv );                   \
-               }                                                       \
+       if (!test_bit(0, &dev_priv->prim.wrapped)) {                    \
+               if (dev_priv->prim.space < dev_priv->prim.high_mark)    \
+                       mga_do_dma_wrap_start(dev_priv);                \
+               else                                                    \
+                       mga_do_dma_flush(dev_priv);                     \
        }                                                               \
 } while (0)
 
 /* Never use this, always use DMA_BLOCK(...) for primary DMA output.
  */
-#define DMA_WRITE( offset, val )                                       \
+#define DMA_WRITE(offset, val)                                         \
 do {                                                                   \
-       if ( MGA_VERBOSE ) {                                            \
-               DRM_INFO( "   DMA_WRITE( 0x%08x ) at 0x%04Zx\n",        \
-                         (u32)(val), write + (offset) * sizeof(u32) ); \
-       }                                                               \
+       if (MGA_VERBOSE)                                                \
+               DRM_INFO("   DMA_WRITE( 0x%08x ) at 0x%04Zx\n",         \
+                        (u32)(val), write + (offset) * sizeof(u32));   \
        *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \
 } while (0)
 
-#define DMA_BLOCK( reg0, val0, reg1, val1, reg2, val2, reg3, val3 )    \
+#define DMA_BLOCK(reg0, val0, reg1, val1, reg2, val2, reg3, val3)      \
 do {                                                                   \
-       DMA_WRITE( 0, ((DMAREG( reg0 ) << 0) |                          \
-                      (DMAREG( reg1 ) << 8) |                          \
-                      (DMAREG( reg2 ) << 16) |                         \
-                      (DMAREG( reg3 ) << 24)) );                       \
-       DMA_WRITE( 1, val0 );                                           \
-       DMA_WRITE( 2, val1 );                                           \
-       DMA_WRITE( 3, val2 );                                           \
-       DMA_WRITE( 4, val3 );                                           \
+       DMA_WRITE(0, ((DMAREG(reg0) << 0) |                             \
+                     (DMAREG(reg1) << 8) |                             \
+                     (DMAREG(reg2) << 16) |                            \
+                     (DMAREG(reg3) << 24)));                           \
+       DMA_WRITE(1, val0);                                             \
+       DMA_WRITE(2, val1);                                             \
+       DMA_WRITE(3, val2);                                             \
+       DMA_WRITE(4, val3);                                             \
        write += DMA_BLOCK_SIZE;                                        \
 } while (0)
 
 /* Buffer aging via primary DMA stream head pointer.
  */
 
-#define SET_AGE( age, h, w )                                           \
+#define SET_AGE(age, h, w)                                             \
 do {                                                                   \
        (age)->head = h;                                                \
        (age)->wrap = w;                                                \
 } while (0)
 
-#define TEST_AGE( age, h, w )          ( (age)->wrap < w ||            \
-                                         ( (age)->wrap == w &&         \
-                                           (age)->head < h ) )
+#define TEST_AGE(age, h, w)            ((age)->wrap < w ||             \
+                                        ((age)->wrap == w &&           \
+                                         (age)->head < h))
 
-#define AGE_BUFFER( buf_priv )                                         \
+#define AGE_BUFFER(buf_priv)                                           \
 do {                                                                   \
        drm_mga_freelist_t *entry = (buf_priv)->list_entry;             \
-       if ( (buf_priv)->dispatched ) {                                 \
+       if ((buf_priv)->dispatched) {                                   \
                entry->age.head = (dev_priv->prim.tail +                \
                                   dev_priv->primary->offset);          \
                entry->age.wrap = dev_priv->sarea_priv->last_wrap;      \
@@ -681,7 +676,7 @@ do {                                                                        \
 
 /* Simple idle test.
  */
-static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv)
+static __inline__ int mga_is_idle(drm_mga_private_t *dev_priv)
 {
        u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
        return (status == MGA_ENDPRDMASTS);
index daa6041a483ad8be9f608b72f4c3f79db7f63e01..2581202297e4e973e48d22e4c76e4997022d7eb4 100644 (file)
@@ -76,9 +76,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
                /* In addition to clearing the interrupt-pending bit, we
                 * have to write to MGA_PRIMEND to re-start the DMA operation.
                 */
-               if ((prim_start & ~0x03) != (prim_end & ~0x03)) {
+               if ((prim_start & ~0x03) != (prim_end & ~0x03))
                        MGA_WRITE(MGA_PRIMEND, prim_end);
-               }
 
                atomic_inc(&dev_priv->last_fence_retired);
                DRM_WAKEUP(&dev_priv->fence_queue);
@@ -120,7 +119,7 @@ void mga_disable_vblank(struct drm_device *dev, int crtc)
        /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
 }
 
-int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
+int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence)
 {
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
        unsigned int cur_fence;
@@ -139,7 +138,7 @@ int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
        return ret;
 }
 
-void mga_driver_irq_preinstall(struct drm_device * dev)
+void mga_driver_irq_preinstall(struct drm_device *dev)
 {
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
 
@@ -162,7 +161,7 @@ int mga_driver_irq_postinstall(struct drm_device *dev)
        return 0;
 }
 
-void mga_driver_irq_uninstall(struct drm_device * dev)
+void mga_driver_irq_uninstall(struct drm_device *dev)
 {
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
        if (!dev_priv)
index a53b848e0f17cbbceb062d3b8ff648098deb0985..fff82045c427eec5372c6ca3747f64bd16dcabd0 100644 (file)
@@ -41,8 +41,8 @@
  * DMA hardware state programming functions
  */
 
-static void mga_emit_clip_rect(drm_mga_private_t * dev_priv,
-                              struct drm_clip_rect * box)
+static void mga_emit_clip_rect(drm_mga_private_t *dev_priv,
+                              struct drm_clip_rect *box)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
@@ -66,7 +66,7 @@ static void mga_emit_clip_rect(drm_mga_private_t * dev_priv,
        ADVANCE_DMA();
 }
 
-static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv)
+static __inline__ void mga_g200_emit_context(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
@@ -89,7 +89,7 @@ static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv)
        ADVANCE_DMA();
 }
 
-static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv)
+static __inline__ void mga_g400_emit_context(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
@@ -116,7 +116,7 @@ static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv)
        ADVANCE_DMA();
 }
 
-static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv)
+static __inline__ void mga_g200_emit_tex0(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
@@ -144,7 +144,7 @@ static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv)
        ADVANCE_DMA();
 }
 
-static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv)
+static __inline__ void mga_g400_emit_tex0(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
@@ -184,7 +184,7 @@ static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv)
        ADVANCE_DMA();
 }
 
-static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv)
+static __inline__ void mga_g400_emit_tex1(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1];
@@ -223,7 +223,7 @@ static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv)
        ADVANCE_DMA();
 }
 
-static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv)
+static __inline__ void mga_g200_emit_pipe(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int pipe = sarea_priv->warp_pipe;
@@ -250,7 +250,7 @@ static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv)
        ADVANCE_DMA();
 }
 
-static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv)
+static __inline__ void mga_g400_emit_pipe(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int pipe = sarea_priv->warp_pipe;
@@ -327,7 +327,7 @@ static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv)
        ADVANCE_DMA();
 }
 
-static void mga_g200_emit_state(drm_mga_private_t * dev_priv)
+static void mga_g200_emit_state(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int dirty = sarea_priv->dirty;
@@ -348,7 +348,7 @@ static void mga_g200_emit_state(drm_mga_private_t * dev_priv)
        }
 }
 
-static void mga_g400_emit_state(drm_mga_private_t * dev_priv)
+static void mga_g400_emit_state(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int dirty = sarea_priv->dirty;
@@ -381,7 +381,7 @@ static void mga_g400_emit_state(drm_mga_private_t * dev_priv)
 
 /* Disallow all write destinations except the front and backbuffer.
  */
-static int mga_verify_context(drm_mga_private_t * dev_priv)
+static int mga_verify_context(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
@@ -400,7 +400,7 @@ static int mga_verify_context(drm_mga_private_t * dev_priv)
 
 /* Disallow texture reads from PCI space.
  */
-static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit)
+static int mga_verify_tex(drm_mga_private_t *dev_priv, int unit)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit];
@@ -417,7 +417,7 @@ static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit)
        return 0;
 }
 
-static int mga_verify_state(drm_mga_private_t * dev_priv)
+static int mga_verify_state(drm_mga_private_t *dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int dirty = sarea_priv->dirty;
@@ -446,7 +446,7 @@ static int mga_verify_state(drm_mga_private_t * dev_priv)
        return (ret == 0);
 }
 
-static int mga_verify_iload(drm_mga_private_t * dev_priv,
+static int mga_verify_iload(drm_mga_private_t *dev_priv,
                            unsigned int dstorg, unsigned int length)
 {
        if (dstorg < dev_priv->texture_offset ||
@@ -465,7 +465,7 @@ static int mga_verify_iload(drm_mga_private_t * dev_priv,
        return 0;
 }
 
-static int mga_verify_blit(drm_mga_private_t * dev_priv,
+static int mga_verify_blit(drm_mga_private_t *dev_priv,
                           unsigned int srcorg, unsigned int dstorg)
 {
        if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
@@ -480,7 +480,7 @@ static int mga_verify_blit(drm_mga_private_t * dev_priv,
  *
  */
 
-static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * clear)
+static void mga_dma_dispatch_clear(struct drm_device *dev, drm_mga_clear_t *clear)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -568,7 +568,7 @@ static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * cl
        FLUSH_DMA();
 }
 
-static void mga_dma_dispatch_swap(struct drm_device * dev)
+static void mga_dma_dispatch_swap(struct drm_device *dev)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -622,7 +622,7 @@ static void mga_dma_dispatch_swap(struct drm_device * dev)
        DRM_DEBUG("... done.\n");
 }
 
-static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf)
+static void mga_dma_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_buf_priv_t *buf_priv = buf->dev_private;
@@ -669,7 +669,7 @@ static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * bu
        FLUSH_DMA();
 }
 
-static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * buf,
+static void mga_dma_dispatch_indices(struct drm_device *dev, struct drm_buf *buf,
                                     unsigned int start, unsigned int end)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
@@ -718,7 +718,7 @@ static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * b
 /* This copies a 64 byte aligned agp region to the frambuffer with a
  * standard blit, the ioctl needs to do checking.
  */
-static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf,
+static void mga_dma_dispatch_iload(struct drm_device *dev, struct drm_buf *buf,
                                   unsigned int dstorg, unsigned int length)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
@@ -766,7 +766,7 @@ static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf
        FLUSH_DMA();
 }
 
-static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit)
+static void mga_dma_dispatch_blit(struct drm_device *dev, drm_mga_blit_t *blit)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -801,9 +801,8 @@ static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit
                int w = pbox[i].x2 - pbox[i].x1 - 1;
                int start;
 
-               if (blit->ydir == -1) {
+               if (blit->ydir == -1)
                        srcy = blit->height - srcy - 1;
-               }
 
                start = srcy * blit->src_pitch + srcx;
 
index 9aad4847afdf31cbd3c7c695195581d2745dafb1..f172bd5c257f48600c4ab17c991460dd99b02ea8 100644 (file)
@@ -46,7 +46,7 @@ MODULE_FIRMWARE(FIRMWARE_G400);
 
 #define WARP_UCODE_SIZE(size)          ALIGN(size, MGA_WARP_CODE_ALIGN)
 
-int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
+int mga_warp_install_microcode(drm_mga_private_t *dev_priv)
 {
        unsigned char *vcbase = dev_priv->warp->handle;
        unsigned long pcbase = dev_priv->warp->offset;
@@ -133,7 +133,7 @@ out:
 
 #define WMISC_EXPECTED         (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
 
-int mga_warp_init(drm_mga_private_t * dev_priv)
+int mga_warp_init(drm_mga_private_t *dev_priv)
 {
        u32 wmisc;
 
index 1175429da1029bf18feb23813aaa223cae651283..d2d28048efb23e1759c4368a2dbb2a64ac12675e 100644 (file)
@@ -1,6 +1,6 @@
 config DRM_NOUVEAU
        tristate "Nouveau (nVidia) cards"
-       depends on DRM
+       depends on DRM && PCI
         select FW_LOADER
        select DRM_KMS_HELPER
        select DRM_TTM
@@ -41,4 +41,13 @@ config DRM_I2C_CH7006
 
          This driver is currently only useful if you're also using
          the nouveau driver.
+
+config DRM_I2C_SIL164
+       tristate "Silicon Image sil164 TMDS transmitter"
+       default m if DRM_NOUVEAU
+       help
+         Support for sil164 and similar single-link (or dual-link
+         when used in pairs) TMDS transmitters, used in some nVidia
+         video cards.
+
 endmenu
index acd31ed861eff4d366a528fec79f37f60b4d77ec..2405d5ef0ca735c351a677064575c838d9000e42 100644 (file)
@@ -9,10 +9,10 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
              nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
              nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
              nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
-             nouveau_dp.o nouveau_grctx.o \
+             nouveau_dp.o \
              nv04_timer.o \
              nv04_mc.o nv40_mc.o nv50_mc.o \
-             nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
+             nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o \
              nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
              nv04_graph.o nv10_graph.o nv20_graph.o \
              nv40_graph.o nv50_graph.o \
@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
              nv50_cursor.o nv50_display.o nv50_fbcon.o \
              nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
              nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
-             nv17_gpio.o nv50_gpio.o \
+             nv10_gpio.o nv50_gpio.o \
             nv50_calc.o
 
 nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
index d4bcca8a5133b2a4565b8f7d794b4d558da5557e..c17a055ee3e57c3a356f2fd4d3b85d4432f7d4e5 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
+#include <acpi/video.h>
 
 #include "drmP.h"
 #include "drm.h"
@@ -11,6 +12,7 @@
 #include "nouveau_drv.h"
 #include "nouveau_drm.h"
 #include "nv50_display.h"
+#include "nouveau_connector.h"
 
 #include <linux/vga_switcheroo.h>
 
@@ -42,7 +44,7 @@ static const char nouveau_dsm_muid[] = {
        0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
 };
 
-static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result)
+static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
 {
        struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
        struct acpi_object_list input;
@@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
 {
        return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
 }
+
+int
+nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
+{
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct acpi_device *acpidev;
+       acpi_handle handle;
+       int type, ret;
+       void *edid;
+
+       switch (connector->connector_type) {
+       case DRM_MODE_CONNECTOR_LVDS:
+       case DRM_MODE_CONNECTOR_eDP:
+               type = ACPI_VIDEO_DISPLAY_LCD;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
+       if (!handle)
+               return -ENODEV;
+
+       ret = acpi_bus_get_device(handle, &acpidev);
+       if (ret)
+               return -ENODEV;
+
+       ret = acpi_video_get_edid(acpidev, type, -1, &edid);
+       if (ret < 0)
+               return ret;
+
+       nv_connector->edid = edid;
+       return 0;
+}
index e492919faf44167b14b97da9537f4aa881eb7969..7369b5e7364946975294928ba13b65510fb54d47 100644 (file)
@@ -28,6 +28,8 @@
 #include "nouveau_hw.h"
 #include "nouveau_encoder.h"
 
+#include <linux/io-mapping.h>
+
 /* these defines are made up */
 #define NV_CIO_CRE_44_HEADA 0x0
 #define NV_CIO_CRE_44_HEADB 0x3
@@ -209,20 +211,20 @@ static struct methods shadow_methods[] = {
        { "PCIROM", load_vbios_pci, true },
        { "ACPI", load_vbios_acpi, true },
 };
+#define NUM_SHADOW_METHODS ARRAY_SIZE(shadow_methods)
 
 static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
 {
-       const int nr_methods = ARRAY_SIZE(shadow_methods);
        struct methods *methods = shadow_methods;
        int testscore = 3;
-       int scores[nr_methods], i;
+       int scores[NUM_SHADOW_METHODS], i;
 
        if (nouveau_vbios) {
-               for (i = 0; i < nr_methods; i++)
+               for (i = 0; i < NUM_SHADOW_METHODS; i++)
                        if (!strcasecmp(nouveau_vbios, methods[i].desc))
                                break;
 
-               if (i < nr_methods) {
+               if (i < NUM_SHADOW_METHODS) {
                        NV_INFO(dev, "Attempting to use BIOS image from %s\n",
                                methods[i].desc);
 
@@ -234,7 +236,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
                NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios);
        }
 
-       for (i = 0; i < nr_methods; i++) {
+       for (i = 0; i < NUM_SHADOW_METHODS; i++) {
                NV_TRACE(dev, "Attempting to load BIOS image from %s\n",
                         methods[i].desc);
                data[0] = data[1] = 0;  /* avoid reuse of previous image */
@@ -245,7 +247,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
        }
 
        while (--testscore > 0) {
-               for (i = 0; i < nr_methods; i++) {
+               for (i = 0; i < NUM_SHADOW_METHODS; i++) {
                        if (scores[i] == testscore) {
                                NV_TRACE(dev, "Using BIOS image from %s\n",
                                         methods[i].desc);
@@ -920,7 +922,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
                NV_ERROR(bios->dev,
                         "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
                         offset, config, count);
-               return -EINVAL;
+               return len;
        }
 
        configval = ROM32(bios->data[offset + 11 + config * 4]);
@@ -1022,7 +1024,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
                NV_ERROR(bios->dev,
                         "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
                         offset, config, count);
-               return -EINVAL;
+               return len;
        }
 
        freq = ROM16(bios->data[offset + 12 + config * 2]);
@@ -1194,7 +1196,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
        dpe = nouveau_bios_dp_table(dev, dcb, &dummy);
        if (!dpe) {
                NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
-               return -EINVAL;
+               return 3;
        }
 
        switch (cond) {
@@ -1218,12 +1220,16 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                int ret;
 
                auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index);
-               if (!auxch)
-                       return -ENODEV;
+               if (!auxch) {
+                       NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset);
+                       return 3;
+               }
 
                ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1);
-               if (ret)
-                       return ret;
+               if (ret) {
+                       NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret);
+                       return 3;
+               }
 
                if (cond & 1)
                        iexec->execute = false;
@@ -1392,7 +1398,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
                NV_ERROR(bios->dev,
                         "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
                         offset, config, count);
-               return -EINVAL;
+               return len;
        }
 
        freq = ROM32(bios->data[offset + 11 + config * 4]);
@@ -1452,6 +1458,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         * "mask n" and OR it with "data n" before writing it back to the device
         */
 
+       struct drm_device *dev = bios->dev;
        uint8_t i2c_index = bios->data[offset + 1];
        uint8_t i2c_address = bios->data[offset + 2] >> 1;
        uint8_t count = bios->data[offset + 3];
@@ -1466,9 +1473,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                      "Count: 0x%02X\n",
                offset, i2c_index, i2c_address, count);
 
-       chan = init_i2c_device_find(bios->dev, i2c_index);
-       if (!chan)
-               return -ENODEV;
+       chan = init_i2c_device_find(dev, i2c_index);
+       if (!chan) {
+               NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
+               return len;
+       }
 
        for (i = 0; i < count; i++) {
                uint8_t reg = bios->data[offset + 4 + i * 3];
@@ -1479,8 +1488,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
                                     I2C_SMBUS_READ, reg,
                                     I2C_SMBUS_BYTE_DATA, &val);
-               if (ret < 0)
-                       return ret;
+               if (ret < 0) {
+                       NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret);
+                       return len;
+               }
 
                BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
                              "Mask: 0x%02X, Data: 0x%02X\n",
@@ -1494,8 +1505,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
                                     I2C_SMBUS_WRITE, reg,
                                     I2C_SMBUS_BYTE_DATA, &val);
-               if (ret < 0)
-                       return ret;
+               if (ret < 0) {
+                       NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
+                       return len;
+               }
        }
 
        return len;
@@ -1520,6 +1533,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         * "DCB I2C table entry index", set the register to "data n"
         */
 
+       struct drm_device *dev = bios->dev;
        uint8_t i2c_index = bios->data[offset + 1];
        uint8_t i2c_address = bios->data[offset + 2] >> 1;
        uint8_t count = bios->data[offset + 3];
@@ -1534,9 +1548,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                      "Count: 0x%02X\n",
                offset, i2c_index, i2c_address, count);
 
-       chan = init_i2c_device_find(bios->dev, i2c_index);
-       if (!chan)
-               return -ENODEV;
+       chan = init_i2c_device_find(dev, i2c_index);
+       if (!chan) {
+               NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
+               return len;
+       }
 
        for (i = 0; i < count; i++) {
                uint8_t reg = bios->data[offset + 4 + i * 2];
@@ -1553,8 +1569,10 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
                                     I2C_SMBUS_WRITE, reg,
                                     I2C_SMBUS_BYTE_DATA, &val);
-               if (ret < 0)
-                       return ret;
+               if (ret < 0) {
+                       NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
+                       return len;
+               }
        }
 
        return len;
@@ -1577,6 +1595,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         * address" on the I2C bus given by "DCB I2C table entry index"
         */
 
+       struct drm_device *dev = bios->dev;
        uint8_t i2c_index = bios->data[offset + 1];
        uint8_t i2c_address = bios->data[offset + 2] >> 1;
        uint8_t count = bios->data[offset + 3];
@@ -1584,7 +1603,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
        struct nouveau_i2c_chan *chan;
        struct i2c_msg msg;
        uint8_t data[256];
-       int i;
+       int ret, i;
 
        if (!iexec->execute)
                return len;
@@ -1593,9 +1612,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                      "Count: 0x%02X\n",
                offset, i2c_index, i2c_address, count);
 
-       chan = init_i2c_device_find(bios->dev, i2c_index);
-       if (!chan)
-               return -ENODEV;
+       chan = init_i2c_device_find(dev, i2c_index);
+       if (!chan) {
+               NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
+               return len;
+       }
 
        for (i = 0; i < count; i++) {
                data[i] = bios->data[offset + 4 + i];
@@ -1608,8 +1629,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                msg.flags = 0;
                msg.len = count;
                msg.buf = data;
-               if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
-                       return -EIO;
+               ret = i2c_transfer(&chan->adapter, &msg, 1);
+               if (ret != 1) {
+                       NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
+                       return len;
+               }
        }
 
        return len;
@@ -1633,6 +1657,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         * used -- see get_tmds_index_reg()
         */
 
+       struct drm_device *dev = bios->dev;
        uint8_t mlv = bios->data[offset + 1];
        uint32_t tmdsaddr = bios->data[offset + 2];
        uint8_t mask = bios->data[offset + 3];
@@ -1647,8 +1672,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                offset, mlv, tmdsaddr, mask, data);
 
        reg = get_tmds_index_reg(bios->dev, mlv);
-       if (!reg)
-               return -EINVAL;
+       if (!reg) {
+               NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
+               return 5;
+       }
 
        bios_wr32(bios, reg,
                  tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
@@ -1678,6 +1705,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
         * register is used -- see get_tmds_index_reg()
         */
 
+       struct drm_device *dev = bios->dev;
        uint8_t mlv = bios->data[offset + 1];
        uint8_t count = bios->data[offset + 2];
        int len = 3 + count * 2;
@@ -1691,8 +1719,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
                offset, mlv, count);
 
        reg = get_tmds_index_reg(bios->dev, mlv);
-       if (!reg)
-               return -EINVAL;
+       if (!reg) {
+               NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
+               return len;
+       }
 
        for (i = 0; i < count; i++) {
                uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
@@ -2039,6 +2069,323 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
        return 5;
 }
 
+static inline void
+bios_md32(struct nvbios *bios, uint32_t reg,
+         uint32_t mask, uint32_t val)
+{
+       bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val);
+}
+
+static uint32_t
+peek_fb(struct drm_device *dev, struct io_mapping *fb,
+       uint32_t off)
+{
+       uint32_t val = 0;
+
+       if (off < pci_resource_len(dev->pdev, 1)) {
+               uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0);
+
+               val = ioread32(p);
+
+               io_mapping_unmap_atomic(p, KM_USER0);
+       }
+
+       return val;
+}
+
+static void
+poke_fb(struct drm_device *dev, struct io_mapping *fb,
+       uint32_t off, uint32_t val)
+{
+       if (off < pci_resource_len(dev->pdev, 1)) {
+               uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0);
+
+               iowrite32(val, p);
+               wmb();
+
+               io_mapping_unmap_atomic(p, KM_USER0);
+       }
+}
+
+static inline bool
+read_back_fb(struct drm_device *dev, struct io_mapping *fb,
+            uint32_t off, uint32_t val)
+{
+       poke_fb(dev, fb, off, val);
+       return val == peek_fb(dev, fb, off);
+}
+
+static int
+nv04_init_compute_mem(struct nvbios *bios)
+{
+       struct drm_device *dev = bios->dev;
+       uint32_t patt = 0xdeadbeef;
+       struct io_mapping *fb;
+       int i;
+
+       /* Map the framebuffer aperture */
+       fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
+                                 pci_resource_len(dev->pdev, 1));
+       if (!fb)
+               return -ENOMEM;
+
+       /* Sequencer and refresh off */
+       NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
+       bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF);
+
+       bios_md32(bios, NV04_PFB_BOOT_0, ~0,
+                 NV04_PFB_BOOT_0_RAM_AMOUNT_16MB |
+                 NV04_PFB_BOOT_0_RAM_WIDTH_128 |
+                 NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT);
+
+       for (i = 0; i < 4; i++)
+               poke_fb(dev, fb, 4 * i, patt);
+
+       poke_fb(dev, fb, 0x400000, patt + 1);
+
+       if (peek_fb(dev, fb, 0) == patt + 1) {
+               bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
+                         NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT);
+               bios_md32(bios, NV04_PFB_DEBUG_0,
+                         NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
+
+               for (i = 0; i < 4; i++)
+                       poke_fb(dev, fb, 4 * i, patt);
+
+               if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff))
+                       bios_md32(bios, NV04_PFB_BOOT_0,
+                                 NV04_PFB_BOOT_0_RAM_WIDTH_128 |
+                                 NV04_PFB_BOOT_0_RAM_AMOUNT,
+                                 NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+
+       } else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) !=
+                  (patt & 0xffff0000)) {
+               bios_md32(bios, NV04_PFB_BOOT_0,
+                         NV04_PFB_BOOT_0_RAM_WIDTH_128 |
+                         NV04_PFB_BOOT_0_RAM_AMOUNT,
+                         NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
+
+       } else if (peek_fb(dev, fb, 0) == patt) {
+               if (read_back_fb(dev, fb, 0x800000, patt))
+                       bios_md32(bios, NV04_PFB_BOOT_0,
+                                 NV04_PFB_BOOT_0_RAM_AMOUNT,
+                                 NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+               else
+                       bios_md32(bios, NV04_PFB_BOOT_0,
+                                 NV04_PFB_BOOT_0_RAM_AMOUNT,
+                                 NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
+
+               bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
+                         NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT);
+
+       } else if (!read_back_fb(dev, fb, 0x800000, patt)) {
+               bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+                         NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+
+       }
+
+       /* Refresh on, sequencer on */
+       bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
+       NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
+
+       io_mapping_free(fb);
+       return 0;
+}
+
+static const uint8_t *
+nv05_memory_config(struct nvbios *bios)
+{
+       /* Defaults for BIOSes lacking a memory config table */
+       static const uint8_t default_config_tab[][2] = {
+               { 0x24, 0x00 },
+               { 0x28, 0x00 },
+               { 0x24, 0x01 },
+               { 0x1f, 0x00 },
+               { 0x0f, 0x00 },
+               { 0x17, 0x00 },
+               { 0x06, 0x00 },
+               { 0x00, 0x00 }
+       };
+       int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) &
+                NV_PEXTDEV_BOOT_0_RAMCFG) >> 2;
+
+       if (bios->legacy.mem_init_tbl_ptr)
+               return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i];
+       else
+               return default_config_tab[i];
+}
+
+static int
+nv05_init_compute_mem(struct nvbios *bios)
+{
+       struct drm_device *dev = bios->dev;
+       const uint8_t *ramcfg = nv05_memory_config(bios);
+       uint32_t patt = 0xdeadbeef;
+       struct io_mapping *fb;
+       int i, v;
+
+       /* Map the framebuffer aperture */
+       fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
+                                 pci_resource_len(dev->pdev, 1));
+       if (!fb)
+               return -ENOMEM;
+
+       /* Sequencer off */
+       NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
+
+       if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE)
+               goto out;
+
+       bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
+
+       /* If present load the hardcoded scrambling table */
+       if (bios->legacy.mem_init_tbl_ptr) {
+               uint32_t *scramble_tab = (uint32_t *)&bios->data[
+                       bios->legacy.mem_init_tbl_ptr + 0x10];
+
+               for (i = 0; i < 8; i++)
+                       bios_wr32(bios, NV04_PFB_SCRAMBLE(i),
+                                 ROM32(scramble_tab[i]));
+       }
+
+       /* Set memory type/width/length defaults depending on the straps */
+       bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]);
+
+       if (ramcfg[1] & 0x80)
+               bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE);
+
+       bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20);
+       bios_md32(bios, NV04_PFB_CFG1, 0, 1);
+
+       /* Probe memory bus width */
+       for (i = 0; i < 4; i++)
+               poke_fb(dev, fb, 4 * i, patt);
+
+       if (peek_fb(dev, fb, 0xc) != patt)
+               bios_md32(bios, NV04_PFB_BOOT_0,
+                         NV04_PFB_BOOT_0_RAM_WIDTH_128, 0);
+
+       /* Probe memory length */
+       v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT;
+
+       if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB &&
+           (!read_back_fb(dev, fb, 0x1000000, ++patt) ||
+            !read_back_fb(dev, fb, 0, ++patt)))
+               bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+                         NV04_PFB_BOOT_0_RAM_AMOUNT_16MB);
+
+       if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB &&
+           !read_back_fb(dev, fb, 0x800000, ++patt))
+               bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+                         NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+
+       if (!read_back_fb(dev, fb, 0x400000, ++patt))
+               bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+                         NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
+
+out:
+       /* Sequencer on */
+       NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
+
+       io_mapping_free(fb);
+       return 0;
+}
+
+static int
+nv10_init_compute_mem(struct nvbios *bios)
+{
+       struct drm_device *dev = bios->dev;
+       struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+       const int mem_width[] = { 0x10, 0x00, 0x20 };
+       const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2);
+       uint32_t patt = 0xdeadbeef;
+       struct io_mapping *fb;
+       int i, j, k;
+
+       /* Map the framebuffer aperture */
+       fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
+                                 pci_resource_len(dev->pdev, 1));
+       if (!fb)
+               return -ENOMEM;
+
+       bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
+
+       /* Probe memory bus width */
+       for (i = 0; i < mem_width_count; i++) {
+               bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]);
+
+               for (j = 0; j < 4; j++) {
+                       for (k = 0; k < 4; k++)
+                               poke_fb(dev, fb, 0x1c, 0);
+
+                       poke_fb(dev, fb, 0x1c, patt);
+                       poke_fb(dev, fb, 0x3c, 0);
+
+                       if (peek_fb(dev, fb, 0x1c) == patt)
+                               goto mem_width_found;
+               }
+       }
+
+mem_width_found:
+       patt <<= 1;
+
+       /* Probe amount of installed memory */
+       for (i = 0; i < 4; i++) {
+               int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000;
+
+               poke_fb(dev, fb, off, patt);
+               poke_fb(dev, fb, 0, 0);
+
+               peek_fb(dev, fb, 0);
+               peek_fb(dev, fb, 0);
+               peek_fb(dev, fb, 0);
+               peek_fb(dev, fb, 0);
+
+               if (peek_fb(dev, fb, off) == patt)
+                       goto amount_found;
+       }
+
+       /* IC missing - disable the upper half memory space. */
+       bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0);
+
+amount_found:
+       io_mapping_free(fb);
+       return 0;
+}
+
+static int
+nv20_init_compute_mem(struct nvbios *bios)
+{
+       struct drm_device *dev = bios->dev;
+       struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+       uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900);
+       uint32_t amount, off;
+       struct io_mapping *fb;
+
+       /* Map the framebuffer aperture */
+       fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
+                                 pci_resource_len(dev->pdev, 1));
+       if (!fb)
+               return -ENOMEM;
+
+       bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
+
+       /* Allow full addressing */
+       bios_md32(bios, NV04_PFB_CFG0, 0, mask);
+
+       amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
+       for (off = amount; off > 0x2000000; off -= 0x2000000)
+               poke_fb(dev, fb, off - 4, off);
+
+       amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
+       if (amount != peek_fb(dev, fb, amount - 4))
+               /* IC missing - disable the upper half memory space. */
+               bios_md32(bios, NV04_PFB_CFG0, mask, 0);
+
+       io_mapping_free(fb);
+       return 0;
+}
+
 static int
 init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
 {
@@ -2047,64 +2394,57 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         *
         * offset      (8 bit): opcode
         *
-        * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so
-        * that the hardware can correctly calculate how much VRAM it has
-        * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C))
+        * This opcode is meant to set the PFB memory config registers
+        * appropriately so that we can correctly calculate how much VRAM it
+        * has (on nv10 and better chipsets the amount of installed VRAM is
+        * subsequently reported in NV_PFB_CSTATUS (0x10020C)).
         *
-        * The implementation of this opcode in general consists of two parts:
-        * 1) determination of the memory bus width
-        * 2) determination of how many of the card's RAM pads have ICs attached
+        * The implementation of this opcode in general consists of several
+        * parts:
         *
-        * 1) is done by a cunning combination of writes to offsets 0x1c and
-        * 0x3c in the framebuffer, and seeing whether the written values are
-        * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0
+        * 1) Determination of memory type and density. Only necessary for
+        *    really old chipsets, the memory type reported by the strap bits
+        *    (0x101000) is assumed to be accurate on nv05 and newer.
         *
-        * 2) is done by a cunning combination of writes to an offset slightly
-        * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing
-        * if the test pattern can be read back. This then affects bits 12-15 of
-        * NV_PFB_CFG0
+        * 2) Determination of the memory bus width. Usually done by a cunning
+        *    combination of writes to offsets 0x1c and 0x3c in the fb, and
+        *    seeing whether the written values are read back correctly.
         *
-        * In this context a "cunning combination" may include multiple reads
-        * and writes to varying locations, often alternating the test pattern
-        * and 0, doubtless to make sure buffers are filled, residual charges
-        * on tracks are removed etc.
+        *    Only necessary on nv0x-nv1x and nv34, on the other cards we can
+        *    trust the straps.
         *
-        * Unfortunately, the "cunning combination"s mentioned above, and the
-        * changes to the bits in NV_PFB_CFG0 differ with nearly every bios
-        * trace I have.
+        * 3) Determination of how many of the card's RAM pads have ICs
+        *    attached, usually done by a cunning combination of writes to an
+        *    offset slightly less than the maximum memory reported by
+        *    NV_PFB_CSTATUS, then seeing if the test pattern can be read back.
         *
-        * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which
-        * we started was correct, and use that instead
+        * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io
+        * logs of the VBIOS and kmmio traces of the binary driver POSTing the
+        * card show nothing being done for this opcode. Why is it still listed
+        * in the table?!
         */
 
        /* no iexec->execute check by design */
 
-       /*
-        * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS
-        * and kmmio traces of the binary driver POSTing the card show nothing
-        * being done for this opcode.  why is it still listed in the table?!
-        */
-
        struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+       int ret;
 
-       if (dev_priv->card_type >= NV_40)
-               return 1;
-
-       /*
-        * On every card I've seen, this step gets done for us earlier in
-        * the init scripts
-       uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01);
-       bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20);
-        */
-
-       /*
-        * This also has probably been done in the scripts, but an mmio trace of
-        * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write)
-        */
-       bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1);
+       if (dev_priv->chipset >= 0x40 ||
+           dev_priv->chipset == 0x1a ||
+           dev_priv->chipset == 0x1f)
+               ret = 0;
+       else if (dev_priv->chipset >= 0x20 &&
+                dev_priv->chipset != 0x34)
+               ret = nv20_init_compute_mem(bios);
+       else if (dev_priv->chipset >= 0x10)
+               ret = nv10_init_compute_mem(bios);
+       else if (dev_priv->chipset >= 0x5)
+               ret = nv05_init_compute_mem(bios);
+       else
+               ret = nv04_init_compute_mem(bios);
 
-       /* write back the saved configuration value */
-       bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0);
+       if (ret)
+               return ret;
 
        return 1;
 }
@@ -2131,7 +2471,8 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
        /* no iexec->execute check by design */
 
        pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19);
-       bios_wr32(bios, NV_PBUS_PCI_NV_19, 0);
+       bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00);
+
        bios_wr32(bios, reg, value1);
 
        udelay(10);
@@ -2167,7 +2508,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset,
        uint32_t reg, data;
 
        if (bios->major_version > 2)
-               return -ENODEV;
+               return 0;
 
        bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd(
                       bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
@@ -2180,14 +2521,14 @@ init_configure_mem(struct nvbios *bios, uint16_t offset,
             reg = ROM32(bios->data[seqtbloffs += 4])) {
 
                switch (reg) {
-               case NV_PFB_PRE:
-                       data = NV_PFB_PRE_CMD_PRECHARGE;
+               case NV04_PFB_PRE:
+                       data = NV04_PFB_PRE_CMD_PRECHARGE;
                        break;
-               case NV_PFB_PAD:
-                       data = NV_PFB_PAD_CKE_NORMAL;
+               case NV04_PFB_PAD:
+                       data = NV04_PFB_PAD_CKE_NORMAL;
                        break;
-               case NV_PFB_REF:
-                       data = NV_PFB_REF_CMD_REFRESH;
+               case NV04_PFB_REF:
+                       data = NV04_PFB_REF_CMD_REFRESH;
                        break;
                default:
                        data = ROM32(bios->data[meminitdata]);
@@ -2222,7 +2563,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset,
        int clock;
 
        if (bios->major_version > 2)
-               return -ENODEV;
+               return 0;
 
        clock = ROM16(bios->data[meminitoffs + 4]) * 10;
        setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock);
@@ -2255,7 +2596,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset,
        uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6));
 
        if (bios->major_version > 2)
-               return -ENODEV;
+               return 0;
 
        bios_idxprt_wr(bios, NV_CIO_CRX__COLOR,
                             NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
@@ -2389,7 +2730,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset,
         * offset + 1  (8 bit): mask
         * offset + 2  (8 bit): cmpval
         *
-        * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval".
+        * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval".
         * If condition not met skip subsequent opcodes until condition is
         * inverted (INIT_NOT), or we hit INIT_RESUME
         */
@@ -2401,7 +2742,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset,
        if (!iexec->execute)
                return 3;
 
-       data = bios_rd32(bios, NV_PFB_BOOT_0) & mask;
+       data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask;
 
        BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
                offset, data, cmpval);
@@ -2795,12 +3136,13 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         */
 
        struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+       struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
        const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
        int i;
 
        if (dev_priv->card_type != NV_50) {
                NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
-               return -ENODEV;
+               return 1;
        }
 
        if (!iexec->execute)
@@ -2815,7 +3157,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n",
                        offset, gpio->tag, gpio->state_default);
                if (bios->execute)
-                       nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
+                       pgpio->set(bios->dev, gpio->tag, gpio->state_default);
 
                /* The NVIDIA binary driver doesn't appear to actually do
                 * any of this, my VBIOS does however.
@@ -2872,10 +3214,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
        uint8_t index;
        int i;
 
-
-       if (!iexec->execute)
-               return len;
-
+       /* critical! to know the length of the opcode */;
        if (!blocklen) {
                NV_ERROR(bios->dev,
                         "0x%04X: Zero block length - has the M table "
@@ -2883,6 +3222,9 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
                return -EINVAL;
        }
 
+       if (!iexec->execute)
+               return len;
+
        strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
        index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
 
@@ -3064,14 +3406,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
 
        if (!bios->display.output) {
                NV_ERROR(dev, "INIT_AUXCH: no active output\n");
-               return -EINVAL;
+               return len;
        }
 
        auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
        if (!auxch) {
                NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
                         bios->display.output->i2c_index);
-               return -ENODEV;
+               return len;
        }
 
        if (!iexec->execute)
@@ -3084,7 +3426,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
                if (ret) {
                        NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
-                       return ret;
+                       return len;
                }
 
                data &= bios->data[offset + 0];
@@ -3093,7 +3435,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
                if (ret) {
                        NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
-                       return ret;
+                       return len;
                }
        }
 
@@ -3123,14 +3465,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
 
        if (!bios->display.output) {
                NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
-               return -EINVAL;
+               return len;
        }
 
        auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
        if (!auxch) {
                NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
                         bios->display.output->i2c_index);
-               return -ENODEV;
+               return len;
        }
 
        if (!iexec->execute)
@@ -3141,7 +3483,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
                ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
                if (ret) {
                        NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
-                       return ret;
+                       return len;
                }
        }
 
@@ -5151,10 +5493,14 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
        bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
        bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
        bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
-       bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
-       bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
-       bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
-       bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
+       if (bios->data[legacy_i2c_offset + 4])
+               bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
+       if (bios->data[legacy_i2c_offset + 5])
+               bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
+       if (bios->data[legacy_i2c_offset + 6])
+               bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
+       if (bios->data[legacy_i2c_offset + 7])
+               bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
 
        if (bmplength > 74) {
                bios->fmaxvco = ROM32(bmp[67]);
@@ -5589,9 +5935,12 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
                        if (conf & 0x4 || conf & 0x8)
                                entry->lvdsconf.use_power_scripts = true;
                } else {
-                       mask = ~0x5;
+                       mask = ~0x7;
+                       if (conf & 0x2)
+                               entry->lvdsconf.use_acpi_for_edid = true;
                        if (conf & 0x4)
                                entry->lvdsconf.use_power_scripts = true;
+                       entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4;
                }
                if (conf & mask) {
                        /*
@@ -5706,13 +6055,6 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb,
        case OUTPUT_TV:
                entry->tvconf.has_component_output = false;
                break;
-       case OUTPUT_TMDS:
-               /*
-                * Invent a DVI-A output, by copying the fields of the DVI-D
-                * output; reported to work by math_b on an NV20(!).
-                */
-               fabricate_vga_output(dcb, entry->i2c_index, entry->heads);
-               break;
        case OUTPUT_LVDS:
                if ((conn & 0x00003f00) != 0x10)
                        entry->lvdsconf.use_straps_for_mode = true;
@@ -5793,6 +6135,31 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
        dcb->entries = newentries;
 }
 
+static bool
+apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
+{
+       /* Dell Precision M6300
+        *   DCB entry 2: 02025312 00000010
+        *   DCB entry 3: 02026312 00000020
+        *
+        * Identical, except apparently a different connector on a
+        * different SOR link.  Not a clue how we're supposed to know
+        * which one is in use if it even shares an i2c line...
+        *
+        * Ignore the connector on the second SOR link to prevent
+        * nasty problems until this is sorted (assuming it's not a
+        * VBIOS bug).
+        */
+       if ((dev->pdev->device == 0x040d) &&
+           (dev->pdev->subsystem_vendor == 0x1028) &&
+           (dev->pdev->subsystem_device == 0x019b)) {
+               if (*conn == 0x02026312 && *conf == 0x00000020)
+                       return false;
+       }
+
+       return true;
+}
+
 static int
 parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
 {
@@ -5926,6 +6293,9 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
                if ((connection & 0x0000000f) == 0x0000000f)
                        continue;
 
+               if (!apply_dcb_encoder_quirks(dev, i, &connection, &config))
+                       continue;
+
                NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n",
                             dcb->entries, connection, config);
 
@@ -6181,9 +6551,8 @@ nouveau_run_vbios_init(struct drm_device *dev)
        struct nvbios *bios = &dev_priv->vbios;
        int i, ret = 0;
 
-       NVLockVgaCrtcs(dev, false);
-       if (nv_two_heads(dev))
-               NVSetOwner(dev, bios->state.crtchead);
+       /* Reset the BIOS head to 0. */
+       bios->state.crtchead = 0;
 
        if (bios->major_version < 5)    /* BMP only */
                load_nv17_hw_sequencer_ucode(dev, bios);
@@ -6216,8 +6585,6 @@ nouveau_run_vbios_init(struct drm_device *dev)
                }
        }
 
-       NVLockVgaCrtcs(dev, true);
-
        return ret;
 }
 
@@ -6238,7 +6605,6 @@ static bool
 nouveau_bios_posted(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       bool was_locked;
        unsigned htotal;
 
        if (dev_priv->chipset >= NV_50) {
@@ -6248,13 +6614,12 @@ nouveau_bios_posted(struct drm_device *dev)
                return true;
        }
 
-       was_locked = NVLockVgaCrtcs(dev, false);
        htotal  = NVReadVgaCrtc(dev, 0, 0x06);
        htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
        htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
        htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
        htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
-       NVLockVgaCrtcs(dev, was_locked);
+
        return (htotal != 0);
 }
 
@@ -6263,8 +6628,6 @@ nouveau_bios_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nvbios *bios = &dev_priv->vbios;
-       uint32_t saved_nv_pextdev_boot_0;
-       bool was_locked;
        int ret;
 
        if (!NVInitVBIOS(dev))
@@ -6284,40 +6647,27 @@ nouveau_bios_init(struct drm_device *dev)
        if (!bios->major_version)       /* we don't run version 0 bios */
                return 0;
 
-       /* these will need remembering across a suspend */
-       saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
-       bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0);
-
        /* init script execution disabled */
        bios->execute = false;
 
        /* ... unless card isn't POSTed already */
        if (!nouveau_bios_posted(dev)) {
-               NV_INFO(dev, "Adaptor not initialised\n");
-               if (dev_priv->card_type < NV_40) {
-                       NV_ERROR(dev, "Unable to POST this chipset\n");
-                       return -ENODEV;
-               }
-
-               NV_INFO(dev, "Running VBIOS init tables\n");
+               NV_INFO(dev, "Adaptor not initialised, "
+                       "running VBIOS init tables.\n");
                bios->execute = true;
        }
 
-       bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0);
-
        ret = nouveau_run_vbios_init(dev);
        if (ret)
                return ret;
 
        /* feature_byte on BMP is poor, but init always sets CR4B */
-       was_locked = NVLockVgaCrtcs(dev, false);
        if (bios->major_version < 5)
                bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
 
        /* all BIT systems need p_f_m_t for digital_min_front_porch */
        if (bios->is_mobile || bios->major_version >= 5)
                ret = parse_fp_mode_table(dev, bios);
-       NVLockVgaCrtcs(dev, was_locked);
 
        /* allow subsequent scripts to execute */
        bios->execute = true;
index adf4ec2d06c0cd7086ce327bb8a71c87fe1b9dd2..024458a8d060193043852670b12beba84efa3c01 100644 (file)
@@ -81,6 +81,7 @@ struct dcb_connector_table_entry {
        enum dcb_connector_type type;
        uint8_t index2;
        uint8_t gpio_tag;
+       void *drm;
 };
 
 struct dcb_connector_table {
@@ -117,6 +118,7 @@ struct dcb_entry {
                struct {
                        struct sor_conf sor;
                        bool use_straps_for_mode;
+                       bool use_acpi_for_edid;
                        bool use_power_scripts;
                } lvdsconf;
                struct {
@@ -249,8 +251,6 @@ struct nvbios {
 
        struct {
                int crtchead;
-               /* these need remembering across suspend */
-               uint32_t saved_nv_pfb_cfg0;
        } state;
 
        struct {
index 6f3c195223772bf9adc6884db52b24711fdb32a1..3ca8343c15df9608c444140d9853603a94fd49a6 100644 (file)
@@ -461,9 +461,9 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
                return ret;
 
        ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL,
-                                       evict, no_wait_reserve, no_wait_gpu, new_mem);
-       if (nvbo->channel && nvbo->channel != chan)
-               ret = nouveau_fence_wait(fence, NULL, false, false);
+                                       evict || (nvbo->channel &&
+                                                 nvbo->channel != chan),
+                                       no_wait_reserve, no_wait_gpu, new_mem);
        nouveau_fence_unref((void *)&fence);
        return ret;
 }
@@ -711,8 +711,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
                return ret;
 
        /* Software copy if the card isn't up and running yet. */
-       if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE ||
-           !dev_priv->channel) {
+       if (!dev_priv->channel) {
                ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
                goto out;
        }
@@ -783,7 +782,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
                break;
        case TTM_PL_VRAM:
                mem->bus.offset = mem->mm_node->start << PAGE_SHIFT;
-               mem->bus.base = drm_get_resource_start(dev, 1);
+               mem->bus.base = pci_resource_start(dev->pdev, 1);
                mem->bus.is_iomem = true;
                break;
        default:
index 88f9bc0941eb293a7cf727f261740900da5e14ba..ca85da78484653180ef6c03b64655df3e8117202 100644 (file)
@@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
        struct nv_sim_state sim_data;
        int MClk = nouveau_hw_get_clock(dev, MPLL);
        int NVClk = nouveau_hw_get_clock(dev, NVPLL);
-       uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1);
+       uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1);
 
        sim_data.pclk_khz = VClk;
        sim_data.mclk_khz = MClk;
@@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
                sim_data.mem_latency = 3;
                sim_data.mem_page_miss = 10;
        } else {
-               sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1;
+               sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1;
                sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
                sim_data.mem_latency = cfg1 & 0xf;
                sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
index 1fc57ef58295091eef1e8ad979ad50b17c2fb9a4..90fdcda332be360ab07cb862c9a6ad533724a55c 100644 (file)
@@ -62,7 +62,8 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
                 * VRAM.
                 */
                ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
-                                            drm_get_resource_start(dev, 1),
+                                            pci_resource_start(dev->pdev,
+                                            1),
                                             dev_priv->fb_available_size,
                                             NV_DMA_ACCESS_RO,
                                             NV_DMA_TARGET_PCI, &pushbuf);
@@ -257,9 +258,7 @@ nouveau_channel_free(struct nouveau_channel *chan)
        nouveau_debugfs_channel_fini(chan);
 
        /* Give outstanding push buffers a chance to complete */
-       spin_lock_irqsave(&chan->fence.lock, flags);
        nouveau_fence_update(chan);
-       spin_unlock_irqrestore(&chan->fence.lock, flags);
        if (chan->fence.sequence != chan->fence.sequence_ack) {
                struct nouveau_fence *fence = NULL;
 
@@ -368,8 +367,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
        struct nouveau_channel *chan;
        int ret;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
        if (dev_priv->engine.graph.accel_blocked)
                return -ENODEV;
 
@@ -418,7 +415,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
        struct drm_nouveau_channel_free *cfree = data;
        struct nouveau_channel *chan;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
        NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan);
 
        nouveau_channel_free(chan);
index 149ed224c3cb48c86c56e2f4b9bb18a599190d10..734e92635e83f103885cecbf8674d077a9df5cd9 100644 (file)
@@ -102,63 +102,15 @@ nouveau_connector_destroy(struct drm_connector *drm_connector)
        kfree(drm_connector);
 }
 
-static void
-nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
-{
-       struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
-
-       if (dev_priv->card_type >= NV_50)
-               return;
-
-       *flags = 0;
-       if (NVLockVgaCrtcs(dev_priv->dev, false))
-               *flags |= 1;
-       if (nv_heads_tied(dev_priv->dev))
-               *flags |= 2;
-
-       if (*flags & 2)
-               NVSetOwner(dev_priv->dev, 0); /* necessary? */
-}
-
-static void
-nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
-{
-       struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
-
-       if (dev_priv->card_type >= NV_50)
-               return;
-
-       if (flags & 2)
-               NVSetOwner(dev_priv->dev, 4);
-       if (flags & 1)
-               NVLockVgaCrtcs(dev_priv->dev, true);
-}
-
 static struct nouveau_i2c_chan *
 nouveau_connector_ddc_detect(struct drm_connector *connector,
                             struct nouveau_encoder **pnv_encoder)
 {
        struct drm_device *dev = connector->dev;
-       uint8_t out_buf[] = { 0x0, 0x0}, buf[2];
-       int ret, flags, i;
-
-       struct i2c_msg msgs[] = {
-               {
-                       .addr = 0x50,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = out_buf,
-               },
-               {
-                       .addr = 0x50,
-                       .flags = I2C_M_RD,
-                       .len = 1,
-                       .buf = buf,
-               }
-       };
+       int i;
 
        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
-               struct nouveau_i2c_chan *i2c = NULL;
+               struct nouveau_i2c_chan *i2c;
                struct nouveau_encoder *nv_encoder;
                struct drm_mode_object *obj;
                int id;
@@ -171,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
                if (!obj)
                        continue;
                nv_encoder = nouveau_encoder(obj_to_encoder(obj));
+               i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
 
-               if (nv_encoder->dcb->i2c_index < 0xf)
-                       i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
-               if (!i2c)
-                       continue;
-
-               nouveau_connector_ddc_prepare(connector, &flags);
-               ret = i2c_transfer(&i2c->adapter, msgs, 2);
-               nouveau_connector_ddc_finish(connector, flags);
-
-               if (ret == 2) {
+               if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
                        *pnv_encoder = nv_encoder;
                        return i2c;
                }
@@ -234,21 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector)
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
        struct nouveau_encoder *nv_encoder = NULL;
        struct nouveau_i2c_chan *i2c;
-       int type, flags;
-
-       if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS)
-               nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
-       if (nv_encoder && nv_connector->native_mode) {
-               unsigned status = connector_status_connected;
-
-#if defined(CONFIG_ACPI_BUTTON) || \
-       (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
-               if (!nouveau_ignorelid && !acpi_lid_open())
-                       status = connector_status_unknown;
-#endif
-               nouveau_connector_set_encoder(connector, nv_encoder);
-               return status;
-       }
+       int type;
 
        /* Cleanup the previous EDID block. */
        if (nv_connector->edid) {
@@ -259,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector)
 
        i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
        if (i2c) {
-               nouveau_connector_ddc_prepare(connector, &flags);
                nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
-               nouveau_connector_ddc_finish(connector, flags);
                drm_mode_connector_update_edid_property(connector,
                                                        nv_connector->edid);
                if (!nv_connector->edid) {
@@ -321,6 +249,85 @@ detect_analog:
        return connector_status_disconnected;
 }
 
+static enum drm_connector_status
+nouveau_connector_detect_lvds(struct drm_connector *connector)
+{
+       struct drm_device *dev = connector->dev;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct nouveau_encoder *nv_encoder = NULL;
+       enum drm_connector_status status = connector_status_disconnected;
+
+       /* Cleanup the previous EDID block. */
+       if (nv_connector->edid) {
+               drm_mode_connector_update_edid_property(connector, NULL);
+               kfree(nv_connector->edid);
+               nv_connector->edid = NULL;
+       }
+
+       nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
+       if (!nv_encoder)
+               return connector_status_disconnected;
+
+       /* Try retrieving EDID via DDC */
+       if (!dev_priv->vbios.fp_no_ddc) {
+               status = nouveau_connector_detect(connector);
+               if (status == connector_status_connected)
+                       goto out;
+       }
+
+       /* On some laptops (Sony, i'm looking at you) there appears to
+        * be no direct way of accessing the panel's EDID.  The only
+        * option available to us appears to be to ask ACPI for help..
+        *
+        * It's important this check's before trying straps, one of the
+        * said manufacturer's laptops are configured in such a way
+        * the nouveau decides an entry in the VBIOS FP mode table is
+        * valid - it's not (rh#613284)
+        */
+       if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
+               if (!nouveau_acpi_edid(dev, connector)) {
+                       status = connector_status_connected;
+                       goto out;
+               }
+       }
+
+       /* If no EDID found above, and the VBIOS indicates a hardcoded
+        * modeline is avalilable for the panel, set it as the panel's
+        * native mode and exit.
+        */
+       if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc ||
+           nv_encoder->dcb->lvdsconf.use_straps_for_mode)) {
+               status = connector_status_connected;
+               goto out;
+       }
+
+       /* Still nothing, some VBIOS images have a hardcoded EDID block
+        * stored for the panel stored in them.
+        */
+       if (!dev_priv->vbios.fp_no_ddc) {
+               struct edid *edid =
+                       (struct edid *)nouveau_bios_embedded_edid(dev);
+               if (edid) {
+                       nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+                       *(nv_connector->edid) = *edid;
+                       status = connector_status_connected;
+               }
+       }
+
+out:
+#if defined(CONFIG_ACPI_BUTTON) || \
+       (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
+       if (status == connector_status_connected &&
+           !nouveau_ignorelid && !acpi_lid_open())
+               status = connector_status_unknown;
+#endif
+
+       drm_mode_connector_update_edid_property(connector, nv_connector->edid);
+       nouveau_connector_set_encoder(connector, nv_encoder);
+       return status;
+}
+
 static void
 nouveau_connector_force(struct drm_connector *connector)
 {
@@ -441,7 +448,8 @@ nouveau_connector_native_mode(struct drm_connector *connector)
        int high_w = 0, high_h = 0, high_v = 0;
 
        list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
-               if (helper->mode_valid(connector, mode) != MODE_OK)
+               if (helper->mode_valid(connector, mode) != MODE_OK ||
+                   (mode->flags & DRM_MODE_FLAG_INTERLACE))
                        continue;
 
                /* Use preferred mode if there is one.. */
@@ -534,21 +542,27 @@ static int
 nouveau_connector_get_modes(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
        struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
        int ret = 0;
 
-       /* If we're not LVDS, destroy the previous native mode, the attached
-        * monitor could have changed.
+       /* destroy the native mode, the attached monitor could have changed.
         */
-       if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS &&
-           nv_connector->native_mode) {
+       if (nv_connector->native_mode) {
                drm_mode_destroy(dev, nv_connector->native_mode);
                nv_connector->native_mode = NULL;
        }
 
        if (nv_connector->edid)
                ret = drm_add_edid_modes(connector, nv_connector->edid);
+       else
+       if (nv_encoder->dcb->type == OUTPUT_LVDS &&
+           (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
+            dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
+               nv_connector->native_mode = drm_mode_create(dev);
+               nouveau_bios_fp_mode(dev, nv_connector->native_mode);
+       }
 
        /* Find the native mode if this is a digital panel, if we didn't
         * find any modes through DDC previously add the native mode to
@@ -569,7 +583,8 @@ nouveau_connector_get_modes(struct drm_connector *connector)
                ret = get_slave_funcs(nv_encoder)->
                        get_modes(to_drm_encoder(nv_encoder), connector);
 
-       if (nv_encoder->dcb->type == OUTPUT_LVDS)
+       if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS ||
+           nv_connector->dcb->type == DCB_CONNECTOR_eDP)
                ret += nouveau_connector_scaler_modes_add(connector);
 
        return ret;
@@ -643,6 +658,44 @@ nouveau_connector_best_encoder(struct drm_connector *connector)
        return NULL;
 }
 
+void
+nouveau_connector_set_polling(struct drm_connector *connector)
+{
+       struct drm_device *dev = connector->dev;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct drm_crtc *crtc;
+       bool spare_crtc = false;
+
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+               spare_crtc |= !crtc->enabled;
+
+       connector->polled = 0;
+
+       switch (connector->connector_type) {
+       case DRM_MODE_CONNECTOR_VGA:
+       case DRM_MODE_CONNECTOR_TV:
+               if (dev_priv->card_type >= NV_50 ||
+                   (nv_gf4_disp_arch(dev) && spare_crtc))
+                       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               break;
+
+       case DRM_MODE_CONNECTOR_DVII:
+       case DRM_MODE_CONNECTOR_DVID:
+       case DRM_MODE_CONNECTOR_HDMIA:
+       case DRM_MODE_CONNECTOR_DisplayPort:
+       case DRM_MODE_CONNECTOR_eDP:
+               if (dev_priv->card_type >= NV_50)
+                       connector->polled = DRM_CONNECTOR_POLL_HPD;
+               else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
+                        spare_crtc)
+                       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               break;
+
+       default:
+               break;
+       }
+}
+
 static const struct drm_connector_helper_funcs
 nouveau_connector_helper_funcs = {
        .get_modes = nouveau_connector_get_modes,
@@ -662,148 +715,74 @@ nouveau_connector_funcs = {
        .force = nouveau_connector_force
 };
 
-static int
-nouveau_connector_create_lvds(struct drm_device *dev,
-                             struct drm_connector *connector)
-{
-       struct nouveau_connector *nv_connector = nouveau_connector(connector);
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_i2c_chan *i2c = NULL;
-       struct nouveau_encoder *nv_encoder;
-       struct drm_display_mode native, *mode, *temp;
-       bool dummy, if_is_24bit = false;
-       int ret, flags;
-
-       nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
-       if (!nv_encoder)
-               return -ENODEV;
-
-       ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit);
-       if (ret) {
-               NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n");
-               return ret;
-       }
-       nv_connector->use_dithering = !if_is_24bit;
-
-       /* Firstly try getting EDID over DDC, if allowed and I2C channel
-        * is available.
-        */
-       if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
-               i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
-
-       if (i2c) {
-               nouveau_connector_ddc_prepare(connector, &flags);
-               nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
-               nouveau_connector_ddc_finish(connector, flags);
-       }
-
-       /* If no EDID found above, and the VBIOS indicates a hardcoded
-        * modeline is avalilable for the panel, set it as the panel's
-        * native mode and exit.
-        */
-       if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
-            (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
-             dev_priv->vbios.fp_no_ddc)) {
-               nv_connector->native_mode = drm_mode_duplicate(dev, &native);
-               goto out;
-       }
-
-       /* Still nothing, some VBIOS images have a hardcoded EDID block
-        * stored for the panel stored in them.
-        */
-       if (!nv_connector->edid && !nv_connector->native_mode &&
-           !dev_priv->vbios.fp_no_ddc) {
-               struct edid *edid =
-                       (struct edid *)nouveau_bios_embedded_edid(dev);
-               if (edid) {
-                       nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-                       *(nv_connector->edid) = *edid;
-               }
-       }
-
-       if (!nv_connector->edid)
-               goto out;
-
-       /* We didn't find/use a panel mode from the VBIOS, so parse the EDID
-        * block and look for the preferred mode there.
-        */
-       ret = drm_add_edid_modes(connector, nv_connector->edid);
-       if (ret == 0)
-               goto out;
-       nv_connector->detected_encoder = nv_encoder;
-       nv_connector->native_mode = nouveau_connector_native_mode(connector);
-       list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
-               drm_mode_remove(connector, mode);
-
-out:
-       if (!nv_connector->native_mode) {
-               NV_ERROR(dev, "LVDS present in DCB table, but couldn't "
-                             "determine its native mode.  Disabling.\n");
-               return -ENODEV;
-       }
-
-       drm_mode_connector_update_edid_property(connector, nv_connector->edid);
-       return 0;
-}
+static const struct drm_connector_funcs
+nouveau_connector_funcs_lvds = {
+       .dpms = drm_helper_connector_dpms,
+       .save = NULL,
+       .restore = NULL,
+       .detect = nouveau_connector_detect_lvds,
+       .destroy = nouveau_connector_destroy,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .set_property = nouveau_connector_set_property,
+       .force = nouveau_connector_force
+};
 
-int
-nouveau_connector_create(struct drm_device *dev,
-                        struct dcb_connector_table_entry *dcb)
+struct drm_connector *
+nouveau_connector_create(struct drm_device *dev, int index)
 {
+       const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_connector *nv_connector = NULL;
+       struct dcb_connector_table_entry *dcb = NULL;
        struct drm_connector *connector;
-       struct drm_encoder *encoder;
-       int ret, type;
+       int type, ret = 0;
 
        NV_DEBUG_KMS(dev, "\n");
 
+       if (index >= dev_priv->vbios.dcb.connector.entries)
+               return ERR_PTR(-EINVAL);
+
+       dcb = &dev_priv->vbios.dcb.connector.entry[index];
+       if (dcb->drm)
+               return dcb->drm;
+
        switch (dcb->type) {
-       case DCB_CONNECTOR_NONE:
-               return 0;
        case DCB_CONNECTOR_VGA:
-               NV_INFO(dev, "Detected a VGA connector\n");
                type = DRM_MODE_CONNECTOR_VGA;
                break;
        case DCB_CONNECTOR_TV_0:
        case DCB_CONNECTOR_TV_1:
        case DCB_CONNECTOR_TV_3:
-               NV_INFO(dev, "Detected a TV connector\n");
                type = DRM_MODE_CONNECTOR_TV;
                break;
        case DCB_CONNECTOR_DVI_I:
-               NV_INFO(dev, "Detected a DVI-I connector\n");
                type = DRM_MODE_CONNECTOR_DVII;
                break;
        case DCB_CONNECTOR_DVI_D:
-               NV_INFO(dev, "Detected a DVI-D connector\n");
                type = DRM_MODE_CONNECTOR_DVID;
                break;
        case DCB_CONNECTOR_HDMI_0:
        case DCB_CONNECTOR_HDMI_1:
-               NV_INFO(dev, "Detected a HDMI connector\n");
                type = DRM_MODE_CONNECTOR_HDMIA;
                break;
        case DCB_CONNECTOR_LVDS:
-               NV_INFO(dev, "Detected a LVDS connector\n");
                type = DRM_MODE_CONNECTOR_LVDS;
+               funcs = &nouveau_connector_funcs_lvds;
                break;
        case DCB_CONNECTOR_DP:
-               NV_INFO(dev, "Detected a DisplayPort connector\n");
                type = DRM_MODE_CONNECTOR_DisplayPort;
                break;
        case DCB_CONNECTOR_eDP:
-               NV_INFO(dev, "Detected an eDP connector\n");
                type = DRM_MODE_CONNECTOR_eDP;
                break;
        default:
                NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
        }
 
        nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
        if (!nv_connector)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
        nv_connector->dcb = dcb;
        connector = &nv_connector->base;
 
@@ -811,27 +790,21 @@ nouveau_connector_create(struct drm_device *dev,
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
 
-       drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
+       drm_connector_init(dev, connector, funcs, type);
        drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
 
-       /* attach encoders */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-
-               if (nv_encoder->dcb->connector != dcb->index)
-                       continue;
-
-               if (get_slave_funcs(nv_encoder))
-                       get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
+       /* Check if we need dithering enabled */
+       if (dcb->type == DCB_CONNECTOR_LVDS) {
+               bool dummy, is_24bit = false;
 
-               drm_mode_connector_attach_encoder(connector, encoder);
-       }
+               ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit);
+               if (ret) {
+                       NV_ERROR(dev, "Error parsing LVDS table, disabling "
+                                "LVDS\n");
+                       goto fail;
+               }
 
-       if (!connector->encoder_ids[0]) {
-               NV_WARN(dev, "  no encoders, ignoring\n");
-               drm_connector_cleanup(connector);
-               kfree(connector);
-               return 0;
+               nv_connector->use_dithering = !is_24bit;
        }
 
        /* Init DVI-I specific properties */
@@ -841,12 +814,8 @@ nouveau_connector_create(struct drm_device *dev,
                drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
        }
 
-       if (dcb->type != DCB_CONNECTOR_LVDS)
-               nv_connector->use_dithering = false;
-
        switch (dcb->type) {
        case DCB_CONNECTOR_VGA:
-               connector->polled = DRM_CONNECTOR_POLL_CONNECT;
                if (dev_priv->card_type >= NV_50) {
                        drm_connector_attach_property(connector,
                                        dev->mode_config.scaling_mode_property,
@@ -858,17 +827,6 @@ nouveau_connector_create(struct drm_device *dev,
        case DCB_CONNECTOR_TV_3:
                nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
                break;
-       case DCB_CONNECTOR_DP:
-       case DCB_CONNECTOR_eDP:
-       case DCB_CONNECTOR_HDMI_0:
-       case DCB_CONNECTOR_HDMI_1:
-       case DCB_CONNECTOR_DVI_I:
-       case DCB_CONNECTOR_DVI_D:
-               if (dev_priv->card_type >= NV_50)
-                       connector->polled = DRM_CONNECTOR_POLL_HPD;
-               else
-                       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-               /* fall-through */
        default:
                nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
 
@@ -882,15 +840,15 @@ nouveau_connector_create(struct drm_device *dev,
                break;
        }
 
+       nouveau_connector_set_polling(connector);
+
        drm_sysfs_connector_add(connector);
+       dcb->drm = connector;
+       return dcb->drm;
 
-       if (dcb->type == DCB_CONNECTOR_LVDS) {
-               ret = nouveau_connector_create_lvds(dev, connector);
-               if (ret) {
-                       connector->funcs->destroy(connector);
-                       return ret;
-               }
-       }
+fail:
+       drm_connector_cleanup(connector);
+       kfree(connector);
+       return ERR_PTR(ret);
 
-       return 0;
 }
index 4ef38abc2d9cfa85b2f569b22e01d4c3f596c753..0d2e668ccfe5c52525117ca83a9e3791e0fef936 100644 (file)
@@ -49,7 +49,10 @@ static inline struct nouveau_connector *nouveau_connector(
        return container_of(con, struct nouveau_connector, base);
 }
 
-int nouveau_connector_create(struct drm_device *,
-                            struct dcb_connector_table_entry *);
+struct drm_connector *
+nouveau_connector_create(struct drm_device *, int index);
+
+void
+nouveau_connector_set_polling(struct drm_connector *);
 
 #endif /* __NOUVEAU_CONNECTOR_H__ */
index 65c441a1999facfeeb3b9ca191198fad732583d8..2e3c6caa97eeefb70eda2b06f633aae520c19ceb 100644 (file)
@@ -92,11 +92,9 @@ nouveau_dma_init(struct nouveau_channel *chan)
                return ret;
 
        /* Map M2MF notifier object - fbcon. */
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               ret = nouveau_bo_map(chan->notifier_bo);
-               if (ret)
-                       return ret;
-       }
+       ret = nouveau_bo_map(chan->notifier_bo);
+       if (ret)
+               return ret;
 
        /* Insert NOPS for NOUVEAU_DMA_SKIPS */
        ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
index deeb21c6865c84d6f490e7bc5e82fa7acf5cfc99..33742b11188bdcddbee6e6b51cb77de15718281a 100644 (file)
  */
 
 #include "drmP.h"
+
 #include "nouveau_drv.h"
 #include "nouveau_i2c.h"
+#include "nouveau_connector.h"
 #include "nouveau_encoder.h"
 
 static int
@@ -270,13 +272,39 @@ bool
 nouveau_dp_link_train(struct drm_encoder *encoder)
 {
        struct drm_device *dev = encoder->dev;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-       uint8_t config[4];
-       uint8_t status[3];
+       struct nouveau_connector *nv_connector;
+       struct bit_displayport_encoder_table *dpe;
+       int dpe_headerlen;
+       uint8_t config[4], status[3];
        bool cr_done, cr_max_vs, eq_done;
        int ret = 0, i, tries, voltage;
 
        NV_DEBUG_KMS(dev, "link training!!\n");
+
+       nv_connector = nouveau_encoder_connector_get(nv_encoder);
+       if (!nv_connector)
+               return false;
+
+       dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+       if (!dpe) {
+               NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
+               return false;
+       }
+
+       /* disable hotplug detect, this flips around on some panels during
+        * link training.
+        */
+       pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false);
+
+       if (dpe->script0) {
+               NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
+               nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
+                                           nv_encoder->dcb);
+       }
+
 train:
        cr_done = eq_done = false;
 
@@ -403,6 +431,15 @@ stop:
                }
        }
 
+       if (dpe->script1) {
+               NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
+               nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
+                                           nv_encoder->dcb);
+       }
+
+       /* re-enable hotplug detect */
+       pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true);
+
        return eq_done;
 }
 
index 273770432298b72ae5687505e156fe5b03e0e4e4..1de5eb53e0164be3cc81cf5a17f7969bc211e4ef 100644 (file)
 
 #include "drm_pciids.h"
 
-MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)");
-int nouveau_ctxfw = 0;
-module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
-
 MODULE_PARM_DESC(noagp, "Disable AGP");
 int nouveau_noagp;
 module_param_named(noagp, nouveau_noagp, int, 0400);
@@ -56,7 +52,7 @@ int nouveau_vram_pushbuf;
 module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
 
 MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM");
-int nouveau_vram_notify = 1;
+int nouveau_vram_notify = 0;
 module_param_named(vram_notify, nouveau_vram_notify, int, 0400);
 
 MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)");
@@ -132,7 +128,7 @@ static struct drm_driver driver;
 static int __devinit
 nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &driver);
+       return drm_get_pci_dev(pdev, ent, &driver);
 }
 
 static void
@@ -155,9 +151,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
        struct drm_crtc *crtc;
        int ret, i;
 
-       if (!drm_core_check_feature(dev, DRIVER_MODESET))
-               return -ENODEV;
-
        if (pm_state.event == PM_EVENT_PRETHAW)
                return 0;
 
@@ -257,9 +250,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
        struct drm_crtc *crtc;
        int ret, i;
 
-       if (!drm_core_check_feature(dev, DRIVER_MODESET))
-               return -ENODEV;
-
        nouveau_fbcon_save_disable_accel(dev);
 
        NV_INFO(dev, "We're back, enabling device...\n");
@@ -269,6 +259,13 @@ nouveau_pci_resume(struct pci_dev *pdev)
                return -1;
        pci_set_master(dev->pdev);
 
+       /* Make sure the AGP controller is in a consistent state */
+       if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
+               nouveau_mem_reset_agp(dev);
+
+       /* Make the CRTCs accessible */
+       engine->display.early_init(dev);
+
        NV_INFO(dev, "POSTing device...\n");
        ret = nouveau_run_vbios_init(dev);
        if (ret)
@@ -323,7 +320,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
 
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-               int ret;
 
                ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
                if (!ret)
@@ -332,11 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
                        NV_ERROR(dev, "Could not pin/map cursor.\n");
        }
 
-       if (dev_priv->card_type < NV_50) {
-               nv04_display_restore(dev);
-               NVLockVgaCrtcs(dev, false);
-       } else
-               nv50_display_init(dev);
+       engine->display.init(dev);
 
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
@@ -371,7 +363,8 @@ nouveau_pci_resume(struct pci_dev *pdev)
 static struct drm_driver driver = {
        .driver_features =
                DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
-               DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
+               DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
+               DRIVER_MODESET,
        .load = nouveau_load,
        .firstopen = nouveau_firstopen,
        .lastclose = nouveau_lastclose,
@@ -438,16 +431,18 @@ static int __init nouveau_init(void)
                        nouveau_modeset = 1;
        }
 
-       if (nouveau_modeset == 1) {
-               driver.driver_features |= DRIVER_MODESET;
-               nouveau_register_dsm_handler();
-       }
+       if (!nouveau_modeset)
+               return 0;
 
+       nouveau_register_dsm_handler();
        return drm_init(&driver);
 }
 
 static void __exit nouveau_exit(void)
 {
+       if (!nouveau_modeset)
+               return;
+
        drm_exit(&driver);
        nouveau_unregister_dsm_handler();
 }
index c697191064894345efbbf76bf3bfd1fc83188270..e15db15dca77507ec13614ecc2cac5d2ec147bd4 100644 (file)
@@ -123,14 +123,6 @@ nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
        return ioptr;
 }
 
-struct mem_block {
-       struct mem_block *next;
-       struct mem_block *prev;
-       uint64_t start;
-       uint64_t size;
-       struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
-};
-
 enum nouveau_flags {
        NV_NFORCE   = 0x10000000,
        NV_NFORCE2  = 0x20000000
@@ -149,7 +141,7 @@ struct nouveau_gpuobj {
        struct list_head list;
 
        struct nouveau_channel *im_channel;
-       struct mem_block *im_pramin;
+       struct drm_mm_node *im_pramin;
        struct nouveau_bo *im_backing;
        uint32_t im_backing_start;
        uint32_t *im_backing_suspend;
@@ -196,7 +188,7 @@ struct nouveau_channel {
                struct list_head pending;
                uint32_t sequence;
                uint32_t sequence_ack;
-               uint32_t last_sequence_irq;
+               atomic_t last_sequence_irq;
        } fence;
 
        /* DMA push buffer */
@@ -206,7 +198,7 @@ struct nouveau_channel {
 
        /* Notifier memory */
        struct nouveau_bo *notifier_bo;
-       struct mem_block *notifier_heap;
+       struct drm_mm notifier_heap;
 
        /* PFIFO context */
        struct nouveau_gpuobj_ref *ramfc;
@@ -224,7 +216,7 @@ struct nouveau_channel {
 
        /* Objects */
        struct nouveau_gpuobj_ref *ramin; /* Private instmem */
-       struct mem_block          *ramin_heap; /* Private PRAMIN heap */
+       struct drm_mm              ramin_heap; /* Private PRAMIN heap */
        struct nouveau_gpuobj_ref *ramht; /* Hash table */
        struct list_head           ramht_refs; /* Objects referenced by RAMHT */
 
@@ -277,8 +269,7 @@ struct nouveau_instmem_engine {
        void    (*clear)(struct drm_device *, struct nouveau_gpuobj *);
        int     (*bind)(struct drm_device *, struct nouveau_gpuobj *);
        int     (*unbind)(struct drm_device *, struct nouveau_gpuobj *);
-       void    (*prepare_access)(struct drm_device *, bool write);
-       void    (*finish_access)(struct drm_device *);
+       void    (*flush)(struct drm_device *);
 };
 
 struct nouveau_mc_engine {
@@ -303,10 +294,11 @@ struct nouveau_fb_engine {
 };
 
 struct nouveau_fifo_engine {
-       void *priv;
-
        int  channels;
 
+       struct nouveau_gpuobj_ref *playlist[2];
+       int cur_playlist;
+
        int  (*init)(struct drm_device *);
        void (*takedown)(struct drm_device *);
 
@@ -339,10 +331,11 @@ struct nouveau_pgraph_object_class {
 struct nouveau_pgraph_engine {
        struct nouveau_pgraph_object_class *grclass;
        bool accel_blocked;
-       void *ctxprog;
-       void *ctxvals;
        int grctx_size;
 
+       /* NV2x/NV3x context table (0x400780) */
+       struct nouveau_gpuobj_ref *ctx_table;
+
        int  (*init)(struct drm_device *);
        void (*takedown)(struct drm_device *);
 
@@ -358,6 +351,24 @@ struct nouveau_pgraph_engine {
                                  uint32_t size, uint32_t pitch);
 };
 
+struct nouveau_display_engine {
+       int (*early_init)(struct drm_device *);
+       void (*late_takedown)(struct drm_device *);
+       int (*create)(struct drm_device *);
+       int (*init)(struct drm_device *);
+       void (*destroy)(struct drm_device *);
+};
+
+struct nouveau_gpio_engine {
+       int  (*init)(struct drm_device *);
+       void (*takedown)(struct drm_device *);
+
+       int  (*get)(struct drm_device *, enum dcb_gpio_tag);
+       int  (*set)(struct drm_device *, enum dcb_gpio_tag, int state);
+
+       void (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on);
+};
+
 struct nouveau_engine {
        struct nouveau_instmem_engine instmem;
        struct nouveau_mc_engine      mc;
@@ -365,6 +376,8 @@ struct nouveau_engine {
        struct nouveau_fb_engine      fb;
        struct nouveau_pgraph_engine  graph;
        struct nouveau_fifo_engine    fifo;
+       struct nouveau_display_engine display;
+       struct nouveau_gpio_engine    gpio;
 };
 
 struct nouveau_pll_vals {
@@ -500,11 +513,6 @@ enum nouveau_card_type {
 
 struct drm_nouveau_private {
        struct drm_device *dev;
-       enum {
-               NOUVEAU_CARD_INIT_DOWN,
-               NOUVEAU_CARD_INIT_DONE,
-               NOUVEAU_CARD_INIT_FAILED
-       } init_state;
 
        /* the card type, takes NV_* as values */
        enum nouveau_card_type card_type;
@@ -525,7 +533,7 @@ struct drm_nouveau_private {
        struct list_head vbl_waiting;
 
        struct {
-               struct ttm_global_reference mem_global_ref;
+               struct drm_global_reference mem_global_ref;
                struct ttm_bo_global_ref bo_global_ref;
                struct ttm_bo_device bdev;
                spinlock_t bo_list_lock;
@@ -533,8 +541,6 @@ struct drm_nouveau_private {
                atomic_t validate_sequence;
        } ttm;
 
-       struct fb_info *fbdev_info;
-
        int fifo_alloc_count;
        struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
 
@@ -595,11 +601,7 @@ struct drm_nouveau_private {
        struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
        int vm_vram_pt_nr;
 
-       struct mem_block *ramin_heap;
-
-       /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */
-       uint32_t ctx_table_size;
-       struct nouveau_gpuobj_ref *ctx_table;
+       struct drm_mm ramin_heap;
 
        struct list_head gpuobj_list;
 
@@ -618,6 +620,11 @@ struct drm_nouveau_private {
        struct backlight_device *backlight;
 
        struct nouveau_channel *evo;
+       struct {
+               struct dcb_entry *dcb;
+               u16 script;
+               u32 pclk;
+       } evo_irq;
 
        struct {
                struct dentry *channel_root;
@@ -652,14 +659,6 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
        return 0;
 }
 
-#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do {            \
-       struct drm_nouveau_private *nv = dev->dev_private;    \
-       if (nv->init_state != NOUVEAU_CARD_INIT_DONE) {       \
-               NV_ERROR(dev, "called without init\n");       \
-               return -EINVAL;                               \
-       }                                                     \
-} while (0)
-
 #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do {    \
        struct drm_nouveau_private *nv = dev->dev_private;       \
        if (!nouveau_channel_owner(dev, (cl), (id))) {           \
@@ -682,7 +681,6 @@ extern int nouveau_tv_disable;
 extern char *nouveau_tv_norm;
 extern int nouveau_reg_debug;
 extern char *nouveau_vbios;
-extern int nouveau_ctxfw;
 extern int nouveau_ignorelid;
 extern int nouveau_nofbaccel;
 extern int nouveau_noaccel;
@@ -707,17 +705,10 @@ extern bool nouveau_wait_for_idle(struct drm_device *);
 extern int  nouveau_card_init(struct drm_device *);
 
 /* nouveau_mem.c */
-extern int  nouveau_mem_init_heap(struct mem_block **, uint64_t start,
-                                uint64_t size);
-extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
-                                                uint64_t size, int align2,
-                                                struct drm_file *, int tail);
-extern void nouveau_mem_takedown(struct mem_block **heap);
-extern void nouveau_mem_free_block(struct mem_block *);
 extern int  nouveau_mem_detect(struct drm_device *dev);
-extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
 extern int  nouveau_mem_init(struct drm_device *);
 extern int  nouveau_mem_init_agp(struct drm_device *);
+extern int  nouveau_mem_reset_agp(struct drm_device *);
 extern void nouveau_mem_close(struct drm_device *);
 extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev,
                                                    uint32_t addr,
@@ -857,11 +848,13 @@ void nouveau_register_dsm_handler(void);
 void nouveau_unregister_dsm_handler(void);
 int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
 bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
+int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
 #else
 static inline void nouveau_register_dsm_handler(void) {}
 static inline void nouveau_unregister_dsm_handler(void) {}
 static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
 static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
+static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; }
 #endif
 
 /* nouveau_backlight.c */
@@ -924,6 +917,10 @@ extern void nv10_fb_takedown(struct drm_device *);
 extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t,
                                      uint32_t, uint32_t);
 
+/* nv30_fb.c */
+extern int  nv30_fb_init(struct drm_device *);
+extern void nv30_fb_takedown(struct drm_device *);
+
 /* nv40_fb.c */
 extern int  nv40_fb_init(struct drm_device *);
 extern void nv40_fb_takedown(struct drm_device *);
@@ -1035,12 +1032,6 @@ extern int  nv50_graph_unload_context(struct drm_device *);
 extern void nv50_graph_context_switch(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
 
-/* nouveau_grctx.c */
-extern int  nouveau_grctx_prog_load(struct drm_device *);
-extern void nouveau_grctx_vals_load(struct drm_device *,
-                                   struct nouveau_gpuobj *);
-extern void nouveau_grctx_fini(struct drm_device *);
-
 /* nv04_instmem.c */
 extern int  nv04_instmem_init(struct drm_device *);
 extern void nv04_instmem_takedown(struct drm_device *);
@@ -1051,8 +1042,7 @@ extern int  nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
 extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
 extern int  nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
 extern int  nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
-extern void nv04_instmem_prepare_access(struct drm_device *, bool write);
-extern void nv04_instmem_finish_access(struct drm_device *);
+extern void nv04_instmem_flush(struct drm_device *);
 
 /* nv50_instmem.c */
 extern int  nv50_instmem_init(struct drm_device *);
@@ -1064,8 +1054,9 @@ extern int  nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
 extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
 extern int  nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
 extern int  nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
-extern void nv50_instmem_prepare_access(struct drm_device *, bool write);
-extern void nv50_instmem_finish_access(struct drm_device *);
+extern void nv50_instmem_flush(struct drm_device *);
+extern void nv84_instmem_flush(struct drm_device *);
+extern void nv50_vm_flush(struct drm_device *, int engine);
 
 /* nv04_mc.c */
 extern int  nv04_mc_init(struct drm_device *);
@@ -1088,13 +1079,14 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
                                 unsigned long arg);
 
 /* nv04_dac.c */
-extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *);
 extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
 extern int nv04_dac_output_offset(struct drm_encoder *encoder);
 extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
+extern bool nv04_dac_in_use(struct drm_encoder *encoder);
 
 /* nv04_dfp.c */
-extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *);
 extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
 extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
                               int head, bool dl);
@@ -1103,15 +1095,17 @@ extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
 
 /* nv04_tv.c */
 extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
-extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
 
 /* nv17_tv.c */
-extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
 
 /* nv04_display.c */
+extern int nv04_display_early_init(struct drm_device *);
+extern void nv04_display_late_takedown(struct drm_device *);
 extern int nv04_display_create(struct drm_device *);
+extern int nv04_display_init(struct drm_device *);
 extern void nv04_display_destroy(struct drm_device *);
-extern void nv04_display_restore(struct drm_device *);
 
 /* nv04_crtc.c */
 extern int nv04_crtc_create(struct drm_device *, int index);
@@ -1147,7 +1141,6 @@ extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
 extern int nouveau_fence_flush(void *obj, void *arg);
 extern void nouveau_fence_unref(void **obj);
 extern void *nouveau_fence_ref(void *obj);
-extern void nouveau_fence_handler(struct drm_device *dev, int channel);
 
 /* nouveau_gem.c */
 extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *,
@@ -1167,13 +1160,15 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
 extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
                                  struct drm_file *);
 
-/* nv17_gpio.c */
-int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
-int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+/* nv10_gpio.c */
+int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
+int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
 
 /* nv50_gpio.c */
+int nv50_gpio_init(struct drm_device *dev);
 int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
 int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on);
 
 /* nv50_calc. */
 int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
@@ -1220,6 +1215,14 @@ static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val)
        iowrite32_native(val, dev_priv->mmio + reg);
 }
 
+static inline void nv_mask(struct drm_device *dev, u32 reg, u32 mask, u32 val)
+{
+       u32 tmp = nv_rd32(dev, reg);
+       tmp &= ~mask;
+       tmp |= val;
+       nv_wr32(dev, reg, tmp);
+}
+
 static inline u8 nv_rd08(struct drm_device *dev, unsigned reg)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
index e1df8209cd0f58424c41fea37c4758801e1f4aad..a1a0d48ae70c04b95fd6e75b3d494e5a16e8ba12 100644 (file)
@@ -38,13 +38,15 @@ struct nouveau_encoder {
        struct dcb_entry *dcb;
        int or;
 
+       /* different to drm_encoder.crtc, this reflects what's
+        * actually programmed on the hw, not the proposed crtc */
+       struct drm_crtc *crtc;
+
        struct drm_display_mode mode;
        int last_dpms;
 
        struct nv04_output_reg restore;
 
-       void (*disconnect)(struct nouveau_encoder *encoder);
-
        union {
                struct {
                        int mc_unknown;
@@ -71,8 +73,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
 
 struct nouveau_connector *
 nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
-int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry);
-int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
+int nv50_dac_create(struct drm_connector *, struct dcb_entry *);
 
 struct bit_displayport_encoder_table {
        uint32_t match;
index 257ea130ae13a3c7fa0c8d2ca5b60ab5ce79d706..2fb2444d23221d8684683dedb036b14f3034220d 100644 (file)
@@ -333,7 +333,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev)
        drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
 }
 
-int
+static int
 nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
 {
        struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb;
index faddf53ff9ed79f0804735c151a28c3fb2d9a7ec..6b208ffafa8de1df0bdd5dd6ff6aede30f929341 100644 (file)
@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan)
        if (USE_REFCNT)
                sequence = nvchan_rd32(chan, 0x48);
        else
-               sequence = chan->fence.last_sequence_irq;
+               sequence = atomic_read(&chan->fence.last_sequence_irq);
 
        if (chan->fence.sequence_ack == sequence)
                return;
        chan->fence.sequence_ack = sequence;
 
+       spin_lock(&chan->fence.lock);
        list_for_each_safe(entry, tmp, &chan->fence.pending) {
                fence = list_entry(entry, struct nouveau_fence, entry);
 
@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
                if (sequence == chan->fence.sequence_ack)
                        break;
        }
+       spin_unlock(&chan->fence.lock);
 }
 
 int
@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence)
 {
        struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private;
        struct nouveau_channel *chan = fence->channel;
-       unsigned long flags;
        int ret;
 
        ret = RING_SPACE(chan, 2);
@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
                return ret;
 
        if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) {
-               spin_lock_irqsave(&chan->fence.lock, flags);
                nouveau_fence_update(chan);
-               spin_unlock_irqrestore(&chan->fence.lock, flags);
 
                BUG_ON(chan->fence.sequence ==
                       chan->fence.sequence_ack - 1);
@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
        fence->sequence = ++chan->fence.sequence;
 
        kref_get(&fence->refcount);
-       spin_lock_irqsave(&chan->fence.lock, flags);
+       spin_lock(&chan->fence.lock);
        list_add_tail(&fence->entry, &chan->fence.pending);
-       spin_unlock_irqrestore(&chan->fence.lock, flags);
+       spin_unlock(&chan->fence.lock);
 
        BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1);
        OUT_RING(chan, fence->sequence);
@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg)
 {
        struct nouveau_fence *fence = nouveau_fence(sync_obj);
        struct nouveau_channel *chan = fence->channel;
-       unsigned long flags;
 
        if (fence->signalled)
                return true;
 
-       spin_lock_irqsave(&chan->fence.lock, flags);
        nouveau_fence_update(chan);
-       spin_unlock_irqrestore(&chan->fence.lock, flags);
        return fence->signalled;
 }
 
@@ -190,8 +186,6 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
        unsigned long timeout = jiffies + (3 * DRM_HZ);
        int ret = 0;
 
-       __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
-
        while (1) {
                if (nouveau_fence_signalled(sync_obj, sync_arg))
                        break;
@@ -201,6 +195,8 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
                        break;
                }
 
+               __set_current_state(intr ? TASK_INTERRUPTIBLE
+                       : TASK_UNINTERRUPTIBLE);
                if (lazy)
                        schedule_timeout(1);
 
@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg)
        return 0;
 }
 
-void
-nouveau_fence_handler(struct drm_device *dev, int channel)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_channel *chan = NULL;
-
-       if (channel >= 0 && channel < dev_priv->engine.fifo.channels)
-               chan = dev_priv->fifos[channel];
-
-       if (chan) {
-               spin_lock_irq(&chan->fence.lock);
-               nouveau_fence_update(chan);
-               spin_unlock_irq(&chan->fence.lock);
-       }
-}
-
 int
 nouveau_fence_init(struct nouveau_channel *chan)
 {
        INIT_LIST_HEAD(&chan->fence.pending);
        spin_lock_init(&chan->fence.lock);
+       atomic_set(&chan->fence.last_sequence_irq, 0);
        return 0;
 }
 
index 69c76cf934074b9ef962dc3f1e4c78f40b4bdf28..547f2c24c1e76ac38eaab50db207e5eaa5c59395 100644 (file)
@@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
        uint32_t flags = 0;
        int ret = 0;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
        if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
                dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
 
@@ -577,10 +575,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
        struct drm_nouveau_gem_pushbuf_bo *bo;
        struct nouveau_channel *chan;
        struct validate_op op;
-       struct nouveau_fence *fence = 0;
+       struct nouveau_fence *fence = NULL;
        int i, j, ret = 0, do_reloc = 0;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
        NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
 
        req->vram_available = dev_priv->fb_aper_free;
@@ -760,8 +757,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
        bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
        int ret = -EINVAL;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
        gem = drm_gem_object_lookup(dev, file_priv, req->handle);
        if (!gem)
                return ret;
@@ -800,8 +795,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
        struct nouveau_bo *nvbo;
        int ret = -EINVAL;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
        gem = drm_gem_object_lookup(dev, file_priv, req->handle);
        if (!gem)
                return ret;
@@ -827,8 +820,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
        struct drm_gem_object *gem;
        int ret;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
        gem = drm_gem_object_lookup(dev, file_priv, req->handle);
        if (!gem)
                return -EINVAL;
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c
deleted file mode 100644 (file)
index f731c5f..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2009 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/firmware.h>
-#include <linux/slab.h>
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-
-struct nouveau_ctxprog {
-       uint32_t signature;
-       uint8_t  version;
-       uint16_t length;
-       uint32_t data[];
-} __attribute__ ((packed));
-
-struct nouveau_ctxvals {
-       uint32_t signature;
-       uint8_t  version;
-       uint32_t length;
-       struct {
-               uint32_t offset;
-               uint32_t value;
-       } data[];
-} __attribute__ ((packed));
-
-int
-nouveau_grctx_prog_load(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-       const int chipset = dev_priv->chipset;
-       const struct firmware *fw;
-       const struct nouveau_ctxprog *cp;
-       const struct nouveau_ctxvals *cv;
-       char name[32];
-       int ret, i;
-
-       if (pgraph->accel_blocked)
-               return -ENODEV;
-
-       if (!pgraph->ctxprog) {
-               sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
-               ret = request_firmware(&fw, name, &dev->pdev->dev);
-               if (ret) {
-                       NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
-                       return ret;
-               }
-
-               pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL);
-               if (!pgraph->ctxprog) {
-                       NV_ERROR(dev, "OOM copying ctxprog\n");
-                       release_firmware(fw);
-                       return -ENOMEM;
-               }
-
-               cp = pgraph->ctxprog;
-               if (le32_to_cpu(cp->signature) != 0x5043564e ||
-                   cp->version != 0 ||
-                   le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
-                       NV_ERROR(dev, "ctxprog invalid\n");
-                       release_firmware(fw);
-                       nouveau_grctx_fini(dev);
-                       return -EINVAL;
-               }
-               release_firmware(fw);
-       }
-
-       if (!pgraph->ctxvals) {
-               sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
-               ret = request_firmware(&fw, name, &dev->pdev->dev);
-               if (ret) {
-                       NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
-                       nouveau_grctx_fini(dev);
-                       return ret;
-               }
-
-               pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL);
-               if (!pgraph->ctxvals) {
-                       NV_ERROR(dev, "OOM copying ctxvals\n");
-                       release_firmware(fw);
-                       nouveau_grctx_fini(dev);
-                       return -ENOMEM;
-               }
-
-               cv = (void *)pgraph->ctxvals;
-               if (le32_to_cpu(cv->signature) != 0x5643564e ||
-                   cv->version != 0 ||
-                   le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
-                       NV_ERROR(dev, "ctxvals invalid\n");
-                       release_firmware(fw);
-                       nouveau_grctx_fini(dev);
-                       return -EINVAL;
-               }
-               release_firmware(fw);
-       }
-
-       cp = pgraph->ctxprog;
-
-       nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
-       for (i = 0; i < le16_to_cpu(cp->length); i++)
-               nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
-                       le32_to_cpu(cp->data[i]));
-
-       return 0;
-}
-
-void
-nouveau_grctx_fini(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-
-       if (pgraph->ctxprog) {
-               kfree(pgraph->ctxprog);
-               pgraph->ctxprog = NULL;
-       }
-
-       if (pgraph->ctxvals) {
-               kfree(pgraph->ctxprog);
-               pgraph->ctxvals = NULL;
-       }
-}
-
-void
-nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-       struct nouveau_ctxvals *cv = pgraph->ctxvals;
-       int i;
-
-       if (!cv)
-               return;
-
-       for (i = 0; i < le32_to_cpu(cv->length); i++)
-               nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
-                       le32_to_cpu(cv->data[i].value));
-}
index 316a3c7e6eb492e6763fe6ec863a0c1347396eeb..cb0cb34440c6e835246136cd7f6ade3f29e71d21 100644 (file)
@@ -278,3 +278,45 @@ nouveau_i2c_find(struct drm_device *dev, int index)
        return i2c->chan;
 }
 
+bool
+nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
+{
+       uint8_t buf[] = { 0 };
+       struct i2c_msg msgs[] = {
+               {
+                       .addr = addr,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = buf,
+               },
+               {
+                       .addr = addr,
+                       .flags = I2C_M_RD,
+                       .len = 1,
+                       .buf = buf,
+               }
+       };
+
+       return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
+}
+
+int
+nouveau_i2c_identify(struct drm_device *dev, const char *what,
+                    struct i2c_board_info *info, int index)
+{
+       struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
+       int i;
+
+       NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
+
+       for (i = 0; info[i].addr; i++) {
+               if (nouveau_probe_i2c_addr(i2c, info[i].addr)) {
+                       NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
+                       return i;
+               }
+       }
+
+       NV_DEBUG(dev, "No devices found.\n");
+
+       return -ENODEV;
+}
index c8eaf7a9fcbbad17b7bea504d0613f2e6c75de9e..6dd2f8713cd16befce5d0ce9b75bc5f5a20d662c 100644 (file)
@@ -45,6 +45,9 @@ struct nouveau_i2c_chan {
 int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index);
 void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
 struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
+bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
+int nouveau_i2c_identify(struct drm_device *dev, const char *what,
+                        struct i2c_board_info *info, int index);
 
 int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte,
                          uint8_t *read_byte);
index c1fd42b0dad19cb18e34463548c8ff4b60093747..a9f36ab256b72b535a098c8dd3aeed06dc9c2ea6 100644 (file)
 #include "drm_sarea.h"
 #include "nouveau_drv.h"
 
-static struct mem_block *
-split_block(struct mem_block *p, uint64_t start, uint64_t size,
-           struct drm_file *file_priv)
-{
-       /* Maybe cut off the start of an existing block */
-       if (start > p->start) {
-               struct mem_block *newblock =
-                       kmalloc(sizeof(*newblock), GFP_KERNEL);
-               if (!newblock)
-                       goto out;
-               newblock->start = start;
-               newblock->size = p->size - (start - p->start);
-               newblock->file_priv = NULL;
-               newblock->next = p->next;
-               newblock->prev = p;
-               p->next->prev = newblock;
-               p->next = newblock;
-               p->size -= newblock->size;
-               p = newblock;
-       }
-
-       /* Maybe cut off the end of an existing block */
-       if (size < p->size) {
-               struct mem_block *newblock =
-                       kmalloc(sizeof(*newblock), GFP_KERNEL);
-               if (!newblock)
-                       goto out;
-               newblock->start = start + size;
-               newblock->size = p->size - size;
-               newblock->file_priv = NULL;
-               newblock->next = p->next;
-               newblock->prev = p;
-               p->next->prev = newblock;
-               p->next = newblock;
-               p->size = size;
-       }
-
-out:
-       /* Our block is in the middle */
-       p->file_priv = file_priv;
-       return p;
-}
-
-struct mem_block *
-nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size,
-                       int align2, struct drm_file *file_priv, int tail)
-{
-       struct mem_block *p;
-       uint64_t mask = (1 << align2) - 1;
-
-       if (!heap)
-               return NULL;
-
-       if (tail) {
-               list_for_each_prev(p, heap) {
-                       uint64_t start = ((p->start + p->size) - size) & ~mask;
-
-                       if (p->file_priv == NULL && start >= p->start &&
-                           start + size <= p->start + p->size)
-                               return split_block(p, start, size, file_priv);
-               }
-       } else {
-               list_for_each(p, heap) {
-                       uint64_t start = (p->start + mask) & ~mask;
-
-                       if (p->file_priv == NULL &&
-                           start + size <= p->start + p->size)
-                               return split_block(p, start, size, file_priv);
-               }
-       }
-
-       return NULL;
-}
-
-void nouveau_mem_free_block(struct mem_block *p)
-{
-       p->file_priv = NULL;
-
-       /* Assumes a single contiguous range.  Needs a special file_priv in
-        * 'heap' to stop it being subsumed.
-        */
-       if (p->next->file_priv == NULL) {
-               struct mem_block *q = p->next;
-               p->size += q->size;
-               p->next = q->next;
-               p->next->prev = p;
-               kfree(q);
-       }
-
-       if (p->prev->file_priv == NULL) {
-               struct mem_block *q = p->prev;
-               q->size += p->size;
-               q->next = p->next;
-               q->next->prev = q;
-               kfree(p);
-       }
-}
-
-/* Initialize.  How to check for an uninitialized heap?
- */
-int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start,
-                         uint64_t size)
-{
-       struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL);
-
-       if (!blocks)
-               return -ENOMEM;
-
-       *heap = kmalloc(sizeof(**heap), GFP_KERNEL);
-       if (!*heap) {
-               kfree(blocks);
-               return -ENOMEM;
-       }
-
-       blocks->start = start;
-       blocks->size = size;
-       blocks->file_priv = NULL;
-       blocks->next = blocks->prev = *heap;
-
-       memset(*heap, 0, sizeof(**heap));
-       (*heap)->file_priv = (struct drm_file *) -1;
-       (*heap)->next = (*heap)->prev = blocks;
-       return 0;
-}
-
-/*
- * Free all blocks associated with the releasing file_priv
- */
-void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap)
-{
-       struct mem_block *p;
-
-       if (!heap || !heap->next)
-               return;
-
-       list_for_each(p, heap) {
-               if (p->file_priv == file_priv)
-                       p->file_priv = NULL;
-       }
-
-       /* Assumes a single contiguous range.  Needs a special file_priv in
-        * 'heap' to stop it being subsumed.
-        */
-       list_for_each(p, heap) {
-               while ((p->file_priv == NULL) &&
-                                       (p->next->file_priv == NULL) &&
-                                       (p->next != heap)) {
-                       struct mem_block *q = p->next;
-                       p->size += q->size;
-                       p->next = q->next;
-                       p->next->prev = p;
-                       kfree(q);
-               }
-       }
-}
-
 /*
  * NV10-NV40 tiling helpers
  */
@@ -299,7 +143,6 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
                phys |= 0x30;
        }
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        while (size) {
                unsigned offset_h = upper_32_bits(phys);
                unsigned offset_l = lower_32_bits(phys);
@@ -331,36 +174,12 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
                        }
                }
        }
-       dev_priv->engine.instmem.finish_access(dev);
-
-       nv_wr32(dev, 0x100c80, 0x00050001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return -EBUSY;
-       }
-
-       nv_wr32(dev, 0x100c80, 0x00000001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return -EBUSY;
-       }
-
-       nv_wr32(dev, 0x100c80, 0x00040001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return -EBUSY;
-       }
-
-       nv_wr32(dev, 0x100c80, 0x00060001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return -EBUSY;
-       }
+       dev_priv->engine.instmem.flush(dev);
 
+       nv50_vm_flush(dev, 5);
+       nv50_vm_flush(dev, 0);
+       nv50_vm_flush(dev, 4);
+       nv50_vm_flush(dev, 6);
        return 0;
 }
 
@@ -374,7 +193,6 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
        virt -= dev_priv->vm_vram_base;
        pages = (size >> 16) << 1;
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        while (pages) {
                pgt = dev_priv->vm_vram_pt[virt >> 29];
                pte = (virt & 0x1ffe0000ULL) >> 15;
@@ -388,57 +206,19 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
                while (pte < end)
                        nv_wo32(dev, pgt, pte++, 0);
        }
-       dev_priv->engine.instmem.finish_access(dev);
-
-       nv_wr32(dev, 0x100c80, 0x00050001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return;
-       }
-
-       nv_wr32(dev, 0x100c80, 0x00000001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return;
-       }
-
-       nv_wr32(dev, 0x100c80, 0x00040001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return;
-       }
+       dev_priv->engine.instmem.flush(dev);
 
-       nv_wr32(dev, 0x100c80, 0x00060001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-       }
+       nv50_vm_flush(dev, 5);
+       nv50_vm_flush(dev, 0);
+       nv50_vm_flush(dev, 4);
+       nv50_vm_flush(dev, 6);
 }
 
 /*
  * Cleanup everything
  */
-void nouveau_mem_takedown(struct mem_block **heap)
-{
-       struct mem_block *p;
-
-       if (!*heap)
-               return;
-
-       for (p = (*heap)->next; p != *heap;) {
-               struct mem_block *q = p;
-               p = p->next;
-               kfree(q);
-       }
-
-       kfree(*heap);
-       *heap = NULL;
-}
-
-void nouveau_mem_close(struct drm_device *dev)
+void
+nouveau_mem_close(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
 
@@ -449,8 +229,7 @@ void nouveau_mem_close(struct drm_device *dev)
 
        nouveau_ttm_global_release(dev_priv);
 
-       if (drm_core_has_AGP(dev) && dev->agp &&
-           drm_core_check_feature(dev, DRIVER_MODESET)) {
+       if (drm_core_has_AGP(dev) && dev->agp) {
                struct drm_agp_mem *entry, *tempe;
 
                /* Remove AGP resources, but leave dev->agp
@@ -471,28 +250,29 @@ void nouveau_mem_close(struct drm_device *dev)
        }
 
        if (dev_priv->fb_mtrr) {
-               drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),
-                            drm_get_resource_len(dev, 1), DRM_MTRR_WC);
-               dev_priv->fb_mtrr = 0;
+               drm_mtrr_del(dev_priv->fb_mtrr,
+                            pci_resource_start(dev->pdev, 1),
+                            pci_resource_len(dev->pdev, 1), DRM_MTRR_WC);
+               dev_priv->fb_mtrr = -1;
        }
 }
 
 static uint32_t
 nouveau_mem_detect_nv04(struct drm_device *dev)
 {
-       uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
+       uint32_t boot0 = nv_rd32(dev, NV04_PFB_BOOT_0);
 
        if (boot0 & 0x00000100)
                return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
 
-       switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
-       case NV04_BOOT_0_RAM_AMOUNT_32MB:
+       switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
+       case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
                return 32 * 1024 * 1024;
-       case NV04_BOOT_0_RAM_AMOUNT_16MB:
+       case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
                return 16 * 1024 * 1024;
-       case NV04_BOOT_0_RAM_AMOUNT_8MB:
+       case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
                return 8 * 1024 * 1024;
-       case NV04_BOOT_0_RAM_AMOUNT_4MB:
+       case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
                return 4 * 1024 * 1024;
        }
 
@@ -536,12 +316,18 @@ nouveau_mem_detect(struct drm_device *dev)
        } else
        if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
                dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
+       } else
+       if (dev_priv->card_type < NV_50) {
+               dev_priv->vram_size  = nv_rd32(dev, NV04_PFB_FIFO_DATA);
+               dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
        } else {
-               dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
-               dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
-               if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
+               dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA);
+               dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
+               dev_priv->vram_size &= 0xffffffff00ll;
+               if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) {
                        dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
                        dev_priv->vram_sys_base <<= 12;
+               }
        }
 
        NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
@@ -555,18 +341,36 @@ nouveau_mem_detect(struct drm_device *dev)
        return -ENOMEM;
 }
 
-#if __OS_HAS_AGP
-static void nouveau_mem_reset_agp(struct drm_device *dev)
+int
+nouveau_mem_reset_agp(struct drm_device *dev)
 {
-       uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable;
+#if __OS_HAS_AGP
+       uint32_t saved_pci_nv_1, pmc_enable;
+       int ret;
+
+       /* First of all, disable fast writes, otherwise if it's
+        * already enabled in the AGP bridge and we disable the card's
+        * AGP controller we might be locking ourselves out of it. */
+       if (dev->agp->acquired) {
+               struct drm_agp_info info;
+               struct drm_agp_mode mode;
+
+               ret = drm_agp_info(dev, &info);
+               if (ret)
+                       return ret;
+
+               mode.mode = info.mode & ~0x10;
+               ret = drm_agp_enable(dev, mode);
+               if (ret)
+                       return ret;
+       }
 
        saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1);
-       saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19);
 
        /* clear busmaster bit */
        nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
-       /* clear SBA and AGP bits */
-       nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff);
+       /* disable AGP */
+       nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0);
 
        /* power cycle pgraph, if enabled */
        pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
@@ -578,11 +382,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev)
        }
 
        /* and restore (gives effect of resetting AGP) */
-       nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
        nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
-}
 #endif
 
+       return 0;
+}
+
 int
 nouveau_mem_init_agp(struct drm_device *dev)
 {
@@ -592,11 +397,6 @@ nouveau_mem_init_agp(struct drm_device *dev)
        struct drm_agp_mode mode;
        int ret;
 
-       if (nouveau_noagp)
-               return 0;
-
-       nouveau_mem_reset_agp(dev);
-
        if (!dev->agp->acquired) {
                ret = drm_agp_acquire(dev);
                if (ret) {
@@ -633,7 +433,7 @@ nouveau_mem_init(struct drm_device *dev)
        struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
        int ret, dma_bits = 32;
 
-       dev_priv->fb_phys = drm_get_resource_start(dev, 1);
+       dev_priv->fb_phys = pci_resource_start(dev->pdev, 1);
        dev_priv->gart_info.type = NOUVEAU_GART_NONE;
 
        if (dev_priv->card_type >= NV_50 &&
@@ -665,8 +465,9 @@ nouveau_mem_init(struct drm_device *dev)
 
        dev_priv->fb_available_size = dev_priv->vram_size;
        dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
-       if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
-               dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
+       if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1))
+               dev_priv->fb_mappable_pages =
+                       pci_resource_len(dev->pdev, 1);
        dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
 
        /* remove reserved space at end of vram from available amount */
@@ -692,7 +493,8 @@ nouveau_mem_init(struct drm_device *dev)
 
        /* GART */
 #if !defined(__powerpc__) && !defined(__ia64__)
-       if (drm_device_is_agp(dev) && dev->agp) {
+       if (drm_device_is_agp(dev) && dev->agp && !nouveau_noagp) {
+               nouveau_mem_reset_agp(dev);
                ret = nouveau_mem_init_agp(dev);
                if (ret)
                        NV_ERROR(dev, "Error initialising AGP: %d\n", ret);
@@ -718,8 +520,8 @@ nouveau_mem_init(struct drm_device *dev)
                return ret;
        }
 
-       dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1),
-                                        drm_get_resource_len(dev, 1),
+       dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1),
+                                        pci_resource_len(dev->pdev, 1),
                                         DRM_MTRR_WC);
 
        return 0;
index 9537f3e30115fb16135794aa674fa2a65da7ecb7..3ec181ff50cea7a45b22a28a6ed43857b2a841cb 100644 (file)
@@ -55,7 +55,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan)
        if (ret)
                goto out_err;
 
-       ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size);
+       ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size);
        if (ret)
                goto out_err;
 
@@ -80,7 +80,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
        nouveau_bo_unpin(chan->notifier_bo);
        mutex_unlock(&dev->struct_mutex);
        drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
-       nouveau_mem_takedown(&chan->notifier_heap);
+       drm_mm_takedown(&chan->notifier_heap);
 }
 
 static void
@@ -90,7 +90,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
        NV_DEBUG(dev, "\n");
 
        if (gpuobj->priv)
-               nouveau_mem_free_block(gpuobj->priv);
+               drm_mm_put_block(gpuobj->priv);
 }
 
 int
@@ -100,18 +100,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_gpuobj *nobj = NULL;
-       struct mem_block *mem;
+       struct drm_mm_node *mem;
        uint32_t offset;
        int target, ret;
 
-       if (!chan->notifier_heap) {
-               NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n",
-                        chan->id);
-               return -EINVAL;
-       }
-
-       mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0,
-                                     (struct drm_file *)-2, 0);
+       mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0);
+       if (mem)
+               mem = drm_mm_get_block(mem, size, 0);
        if (!mem) {
                NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
                return -ENOMEM;
@@ -144,17 +139,17 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
                                     mem->size, NV_DMA_ACCESS_RW, target,
                                     &nobj);
        if (ret) {
-               nouveau_mem_free_block(mem);
+               drm_mm_put_block(mem);
                NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret);
                return ret;
        }
-       nobj->dtor   = nouveau_notifier_gpuobj_dtor;
-       nobj->priv   = mem;
+       nobj->dtor = nouveau_notifier_gpuobj_dtor;
+       nobj->priv = mem;
 
        ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL);
        if (ret) {
                nouveau_gpuobj_del(dev, &nobj);
-               nouveau_mem_free_block(mem);
+               drm_mm_put_block(mem);
                NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret);
                return ret;
        }
@@ -170,7 +165,7 @@ nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset)
                return -EINVAL;
 
        if (poffset) {
-               struct mem_block *mem = nobj->priv;
+               struct drm_mm_node *mem = nobj->priv;
 
                if (*poffset >= mem->size)
                        return false;
@@ -189,7 +184,6 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,
        struct nouveau_channel *chan;
        int ret;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
        NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan);
 
        ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset);
index e7c100ba63a16d2d3b45284de22f1073767758de..b6bcb254f4ab49ab123834d78f4e62e58ac0398a 100644 (file)
@@ -132,7 +132,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
                }
        }
 
-       instmem->prepare_access(dev, true);
        co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
        do {
                if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
@@ -143,7 +142,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
                        nv_wo32(dev, ramht, (co + 4)/4, ctx);
 
                        list_add_tail(&ref->list, &chan->ramht_refs);
-                       instmem->finish_access(dev);
+                       instmem->flush(dev);
                        return 0;
                }
                NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n",
@@ -153,7 +152,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
                if (co >= dev_priv->ramht_size)
                        co = 0;
        } while (co != ho);
-       instmem->finish_access(dev);
 
        NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id);
        return -ENOMEM;
@@ -173,7 +171,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
                return;
        }
 
-       instmem->prepare_access(dev, true);
        co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
        do {
                if (nouveau_ramht_entry_valid(dev, ramht, co) &&
@@ -186,7 +183,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
                        nv_wo32(dev, ramht, (co + 4)/4, 0x00000000);
 
                        list_del(&ref->list);
-                       instmem->finish_access(dev);
+                       instmem->flush(dev);
                        return;
                }
 
@@ -195,7 +192,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
                        co = 0;
        } while (co != ho);
        list_del(&ref->list);
-       instmem->finish_access(dev);
 
        NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
                 chan->id, ref->handle);
@@ -209,7 +205,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_engine *engine = &dev_priv->engine;
        struct nouveau_gpuobj *gpuobj;
-       struct mem_block *pramin = NULL;
+       struct drm_mm *pramin = NULL;
        int ret;
 
        NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
@@ -233,25 +229,12 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
         * available.
         */
        if (chan) {
-               if (chan->ramin_heap) {
-                       NV_DEBUG(dev, "private heap\n");
-                       pramin = chan->ramin_heap;
-               } else
-               if (dev_priv->card_type < NV_50) {
-                       NV_DEBUG(dev, "global heap fallback\n");
-                       pramin = dev_priv->ramin_heap;
-               }
+               NV_DEBUG(dev, "channel heap\n");
+               pramin = &chan->ramin_heap;
        } else {
                NV_DEBUG(dev, "global heap\n");
-               pramin = dev_priv->ramin_heap;
-       }
-
-       if (!pramin) {
-               NV_ERROR(dev, "No PRAMIN heap!\n");
-               return -EINVAL;
-       }
+               pramin = &dev_priv->ramin_heap;
 
-       if (!chan) {
                ret = engine->instmem.populate(dev, gpuobj, &size);
                if (ret) {
                        nouveau_gpuobj_del(dev, &gpuobj);
@@ -260,9 +243,10 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
        }
 
        /* Allocate a chunk of the PRAMIN aperture */
-       gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size,
-                                                   drm_order(align),
-                                                   (struct drm_file *)-2, 0);
+       gpuobj->im_pramin = drm_mm_search_free(pramin, size, align, 0);
+       if (gpuobj->im_pramin)
+               gpuobj->im_pramin = drm_mm_get_block(gpuobj->im_pramin, size, align);
+
        if (!gpuobj->im_pramin) {
                nouveau_gpuobj_del(dev, &gpuobj);
                return -ENOMEM;
@@ -279,10 +263,9 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
        if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
                int i;
 
-               engine->instmem.prepare_access(dev, true);
                for (i = 0; i < gpuobj->im_pramin->size; i += 4)
                        nv_wo32(dev, gpuobj, i/4, 0);
-               engine->instmem.finish_access(dev);
+               engine->instmem.flush(dev);
        }
 
        *gpuobj_ret = gpuobj;
@@ -370,10 +353,9 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
        }
 
        if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
-               engine->instmem.prepare_access(dev, true);
                for (i = 0; i < gpuobj->im_pramin->size; i += 4)
                        nv_wo32(dev, gpuobj, i/4, 0);
-               engine->instmem.finish_access(dev);
+               engine->instmem.flush(dev);
        }
 
        if (gpuobj->dtor)
@@ -386,7 +368,7 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
                if (gpuobj->flags & NVOBJ_FLAG_FAKE)
                        kfree(gpuobj->im_pramin);
                else
-                       nouveau_mem_free_block(gpuobj->im_pramin);
+                       drm_mm_put_block(gpuobj->im_pramin);
        }
 
        list_del(&gpuobj->list);
@@ -589,7 +571,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
        list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
 
        if (p_offset != ~0) {
-               gpuobj->im_pramin = kzalloc(sizeof(struct mem_block),
+               gpuobj->im_pramin = kzalloc(sizeof(struct drm_mm_node),
                                            GFP_KERNEL);
                if (!gpuobj->im_pramin) {
                        nouveau_gpuobj_del(dev, &gpuobj);
@@ -605,10 +587,9 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
        }
 
        if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
-               dev_priv->engine.instmem.prepare_access(dev, true);
                for (i = 0; i < gpuobj->im_pramin->size; i += 4)
                        nv_wo32(dev, gpuobj, i/4, 0);
-               dev_priv->engine.instmem.finish_access(dev);
+               dev_priv->engine.instmem.flush(dev);
        }
 
        if (pref) {
@@ -696,8 +677,6 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
                return ret;
        }
 
-       instmem->prepare_access(dev, true);
-
        if (dev_priv->card_type < NV_50) {
                uint32_t frame, adjust, pte_flags = 0;
 
@@ -734,7 +713,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
                nv_wo32(dev, *gpuobj, 5, flags5);
        }
 
-       instmem->finish_access(dev);
+       instmem->flush(dev);
 
        (*gpuobj)->engine = NVOBJ_ENGINE_SW;
        (*gpuobj)->class  = class;
@@ -849,7 +828,6 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
                return ret;
        }
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        if (dev_priv->card_type >= NV_50) {
                nv_wo32(dev, *gpuobj, 0, class);
                nv_wo32(dev, *gpuobj, 5, 0x00010000);
@@ -874,7 +852,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
                        }
                }
        }
-       dev_priv->engine.instmem.finish_access(dev);
+       dev_priv->engine.instmem.flush(dev);
 
        (*gpuobj)->engine = NVOBJ_ENGINE_GR;
        (*gpuobj)->class  = class;
@@ -920,6 +898,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
        base = 0;
 
        /* PGRAPH context */
+       size += dev_priv->engine.graph.grctx_size;
 
        if (dev_priv->card_type == NV_50) {
                /* Various fixed table thingos */
@@ -930,12 +909,8 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
                size += 0x8000;
                /* RAMFC */
                size += 0x1000;
-               /* PGRAPH context */
-               size += 0x70000;
        }
 
-       NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n",
-                chan->id, size, base);
        ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0,
                                     &chan->ramin);
        if (ret) {
@@ -944,8 +919,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
        }
        pramin = chan->ramin->gpuobj;
 
-       ret = nouveau_mem_init_heap(&chan->ramin_heap,
-                                   pramin->im_pramin->start + base, size);
+       ret = drm_mm_init(&chan->ramin_heap, pramin->im_pramin->start + base, size);
        if (ret) {
                NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
                nouveau_gpuobj_ref_del(dev, &chan->ramin);
@@ -969,15 +943,11 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
 
        NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
 
-       /* Reserve a block of PRAMIN for the channel
-        *XXX: maybe on <NV50 too at some point
-        */
-       if (0 || dev_priv->card_type == NV_50) {
-               ret = nouveau_gpuobj_channel_init_pramin(chan);
-               if (ret) {
-                       NV_ERROR(dev, "init pramin\n");
-                       return ret;
-               }
+       /* Allocate a chunk of memory for per-channel object storage */
+       ret = nouveau_gpuobj_channel_init_pramin(chan);
+       if (ret) {
+               NV_ERROR(dev, "init pramin\n");
+               return ret;
        }
 
        /* NV50 VM
@@ -988,17 +958,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
        if (dev_priv->card_type >= NV_50) {
                uint32_t vm_offset, pde;
 
-               instmem->prepare_access(dev, true);
-
                vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200;
                vm_offset += chan->ramin->gpuobj->im_pramin->start;
 
                ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
                                                        0, &chan->vm_pd, NULL);
-               if (ret) {
-                       instmem->finish_access(dev);
+               if (ret)
                        return ret;
-               }
                for (i = 0; i < 0x4000; i += 8) {
                        nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000);
                        nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe);
@@ -1008,10 +974,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
                ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
                                             dev_priv->gart_info.sg_ctxdma,
                                             &chan->vm_gart_pt);
-               if (ret) {
-                       instmem->finish_access(dev);
+               if (ret)
                        return ret;
-               }
                nv_wo32(dev, chan->vm_pd, pde++,
                            chan->vm_gart_pt->instance | 0x03);
                nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
@@ -1021,17 +985,15 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
                        ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
                                                     dev_priv->vm_vram_pt[i],
                                                     &chan->vm_vram_pt[i]);
-                       if (ret) {
-                               instmem->finish_access(dev);
+                       if (ret)
                                return ret;
-                       }
 
                        nv_wo32(dev, chan->vm_pd, pde++,
                                    chan->vm_vram_pt[i]->instance | 0x61);
                        nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
                }
 
-               instmem->finish_access(dev);
+               instmem->flush(dev);
        }
 
        /* RAMHT */
@@ -1130,8 +1092,8 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
        for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
                nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);
 
-       if (chan->ramin_heap)
-               nouveau_mem_takedown(&chan->ramin_heap);
+       if (chan->ramin_heap.free_stack.next)
+               drm_mm_takedown(&chan->ramin_heap);
        if (chan->ramin)
                nouveau_gpuobj_ref_del(dev, &chan->ramin);
 
@@ -1164,10 +1126,8 @@ nouveau_gpuobj_suspend(struct drm_device *dev)
                        return -ENOMEM;
                }
 
-               dev_priv->engine.instmem.prepare_access(dev, false);
                for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
                        gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i);
-               dev_priv->engine.instmem.finish_access(dev);
        }
 
        return 0;
@@ -1212,10 +1172,9 @@ nouveau_gpuobj_resume(struct drm_device *dev)
                if (!gpuobj->im_backing_suspend)
                        continue;
 
-               dev_priv->engine.instmem.prepare_access(dev, true);
                for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
                        nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]);
-               dev_priv->engine.instmem.finish_access(dev);
+               dev_priv->engine.instmem.flush(dev);
        }
 
        nouveau_gpuobj_suspend_cleanup(dev);
@@ -1232,7 +1191,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
        struct nouveau_channel *chan;
        int ret;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
        NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);
 
        if (init->handle == ~0)
@@ -1283,7 +1241,6 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
        struct nouveau_channel *chan;
        int ret;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
        NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan);
 
        ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref);
index 6ca80a3fe70db02084ed9730fe857b92345dd16f..9c1056cb8a90761415bd2f8e96303cd8ded234cf 100644 (file)
@@ -1,19 +1,64 @@
 
+#define NV04_PFB_BOOT_0                                                0x00100000
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT                       0x00000003
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB                  0x00000000
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB                   0x00000001
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB                   0x00000002
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB                  0x00000003
+#      define NV04_PFB_BOOT_0_RAM_WIDTH_128                    0x00000004
+#      define NV04_PFB_BOOT_0_RAM_TYPE                         0x00000028
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT             0x00000000
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT            0x00000008
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK      0x00000010
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT            0x00000018
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT            0x00000020
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16         0x00000028
+#      define NV04_PFB_BOOT_0_UMA_ENABLE                       0x00000100
+#      define NV04_PFB_BOOT_0_UMA_SIZE                         0x0000f000
+#define NV04_PFB_DEBUG_0                                       0x00100080
+#      define NV04_PFB_DEBUG_0_PAGE_MODE                       0x00000001
+#      define NV04_PFB_DEBUG_0_REFRESH_OFF                     0x00000010
+#      define NV04_PFB_DEBUG_0_REFRESH_COUNTX64                0x00003f00
+#      define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK                0x00004000
+#      define NV04_PFB_DEBUG_0_SAFE_MODE                       0x00008000
+#      define NV04_PFB_DEBUG_0_ALOM_ENABLE                     0x00010000
+#      define NV04_PFB_DEBUG_0_CASOE                           0x00100000
+#      define NV04_PFB_DEBUG_0_CKE_INVERT                      0x10000000
+#      define NV04_PFB_DEBUG_0_REFINC                          0x20000000
+#      define NV04_PFB_DEBUG_0_SAVE_POWER_OFF                  0x40000000
+#define NV04_PFB_CFG0                                          0x00100200
+#      define NV04_PFB_CFG0_SCRAMBLE                           0x20000000
+#define NV04_PFB_CFG1                                          0x00100204
+#define NV04_PFB_FIFO_DATA                                     0x0010020c
+#      define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK            0xfff00000
+#      define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT           20
+#define NV10_PFB_REFCTRL                                       0x00100210
+#      define NV10_PFB_REFCTRL_VALID_1                         (1 << 31)
+#define NV04_PFB_PAD                                           0x0010021c
+#      define NV04_PFB_PAD_CKE_NORMAL                          (1 << 0)
+#define NV10_PFB_TILE(i)                              (0x00100240 + (i*16))
+#define NV10_PFB_TILE__SIZE                                    8
+#define NV10_PFB_TLIMIT(i)                            (0x00100244 + (i*16))
+#define NV10_PFB_TSIZE(i)                             (0x00100248 + (i*16))
+#define NV10_PFB_TSTATUS(i)                           (0x0010024c + (i*16))
+#define NV04_PFB_REF                                           0x001002d0
+#      define NV04_PFB_REF_CMD_REFRESH                         (1 << 0)
+#define NV04_PFB_PRE                                           0x001002d4
+#      define NV04_PFB_PRE_CMD_PRECHARGE                       (1 << 0)
+#define NV10_PFB_CLOSE_PAGE2                                   0x0010033c
+#define NV04_PFB_SCRAMBLE(i)                         (0x00100400 + 4 * (i))
+#define NV40_PFB_TILE(i)                              (0x00100600 + (i*16))
+#define NV40_PFB_TILE__SIZE_0                                  12
+#define NV40_PFB_TILE__SIZE_1                                  15
+#define NV40_PFB_TLIMIT(i)                            (0x00100604 + (i*16))
+#define NV40_PFB_TSIZE(i)                             (0x00100608 + (i*16))
+#define NV40_PFB_TSTATUS(i)                           (0x0010060c + (i*16))
+#define NV40_PFB_UNK_800                                       0x00100800
 
-#define NV03_BOOT_0                                        0x00100000
-#    define NV03_BOOT_0_RAM_AMOUNT                         0x00000003
-#    define NV03_BOOT_0_RAM_AMOUNT_8MB                     0x00000000
-#    define NV03_BOOT_0_RAM_AMOUNT_2MB                     0x00000001
-#    define NV03_BOOT_0_RAM_AMOUNT_4MB                     0x00000002
-#    define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM               0x00000003
-#    define NV04_BOOT_0_RAM_AMOUNT_32MB                    0x00000000
-#    define NV04_BOOT_0_RAM_AMOUNT_4MB                     0x00000001
-#    define NV04_BOOT_0_RAM_AMOUNT_8MB                     0x00000002
-#    define NV04_BOOT_0_RAM_AMOUNT_16MB                    0x00000003
-
-#define NV04_FIFO_DATA                                     0x0010020c
-#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK              0xfff00000
-#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT             20
+#define NV_PEXTDEV_BOOT_0                                      0x00101000
+#define NV_PEXTDEV_BOOT_0_RAMCFG                               0x0000003c
+#      define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT           (8 << 12)
+#define NV_PEXTDEV_BOOT_3                                      0x0010100c
 
 #define NV_RAMIN                                           0x00700000
 
 #define NV04_PTIMER_TIME_1                                 0x00009410
 #define NV04_PTIMER_ALARM_0                                0x00009420
 
-#define NV04_PFB_CFG0                                      0x00100200
-#define NV04_PFB_CFG1                                      0x00100204
-#define NV40_PFB_020C                                      0x0010020C
-#define NV10_PFB_TILE(i)                                   (0x00100240 + (i*16))
-#define NV10_PFB_TILE__SIZE                                8
-#define NV10_PFB_TLIMIT(i)                                 (0x00100244 + (i*16))
-#define NV10_PFB_TSIZE(i)                                  (0x00100248 + (i*16))
-#define NV10_PFB_TSTATUS(i)                                (0x0010024C + (i*16))
-#define NV10_PFB_CLOSE_PAGE2                               0x0010033C
-#define NV40_PFB_TILE(i)                                   (0x00100600 + (i*16))
-#define NV40_PFB_TILE__SIZE_0                              12
-#define NV40_PFB_TILE__SIZE_1                              15
-#define NV40_PFB_TLIMIT(i)                                 (0x00100604 + (i*16))
-#define NV40_PFB_TSIZE(i)                                  (0x00100608 + (i*16))
-#define NV40_PFB_TSTATUS(i)                                (0x0010060C + (i*16))
-#define NV40_PFB_UNK_800                                       0x00100800
-
 #define NV04_PGRAPH_DEBUG_0                                0x00400080
 #define NV04_PGRAPH_DEBUG_1                                0x00400084
 #define NV04_PGRAPH_DEBUG_2                                0x00400088
 #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE                           0x80000000
 #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL                            0x00000fff
 #define NV50_SOR_DP_CTRL(i,l)            (0x0061c10c + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_CTRL_ENABLED                                     0x00000001
 #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED                      0x00004000
 #define NV50_SOR_DP_CTRL_LANE_MASK                                   0x001f0000
 #define NV50_SOR_DP_CTRL_LANE_0_ENABLED                              0x00010000
index 1d6ee8b55154c95aa763ed278c31b14da32fa9a7..491767fe4fcfd3b705c3bdb82b4ebeded1bfe9bb 100644 (file)
@@ -97,7 +97,6 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
 
        NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start);
 
-       dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
        pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT);
        nvbe->pte_start = pte;
        for (i = 0; i < nvbe->nr_pages; i++) {
@@ -116,24 +115,11 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
                        dma_offset += NV_CTXDMA_PAGE_SIZE;
                }
        }
-       dev_priv->engine.instmem.finish_access(nvbe->dev);
+       dev_priv->engine.instmem.flush(nvbe->dev);
 
        if (dev_priv->card_type == NV_50) {
-               nv_wr32(dev, 0x100c80, 0x00050001);
-               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
-                                               nv_rd32(dev, 0x100c80));
-                       return -EBUSY;
-               }
-
-               nv_wr32(dev, 0x100c80, 0x00000001);
-               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
-                                               nv_rd32(dev, 0x100c80));
-                       return -EBUSY;
-               }
+               nv50_vm_flush(dev, 5); /* PGRAPH */
+               nv50_vm_flush(dev, 0); /* PFIFO */
        }
 
        nvbe->bound = true;
@@ -154,7 +140,6 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
        if (!nvbe->bound)
                return 0;
 
-       dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
        pte = nvbe->pte_start;
        for (i = 0; i < nvbe->nr_pages; i++) {
                dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus;
@@ -170,24 +155,11 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
                        dma_offset += NV_CTXDMA_PAGE_SIZE;
                }
        }
-       dev_priv->engine.instmem.finish_access(nvbe->dev);
+       dev_priv->engine.instmem.flush(nvbe->dev);
 
        if (dev_priv->card_type == NV_50) {
-               nv_wr32(dev, 0x100c80, 0x00050001);
-               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
-                                               nv_rd32(dev, 0x100c80));
-                       return -EBUSY;
-               }
-
-               nv_wr32(dev, 0x100c80, 0x00000001);
-               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
-                                               nv_rd32(dev, 0x100c80));
-                       return -EBUSY;
-               }
+               nv50_vm_flush(dev, 5);
+               nv50_vm_flush(dev, 0);
        }
 
        nvbe->bound = false;
@@ -272,7 +244,6 @@ nouveau_sgdma_init(struct drm_device *dev)
                pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
                             PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        if (dev_priv->card_type < NV_50) {
                /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
                 * confirmed to work on c51.  Perhaps means NV_DMA_TARGET_PCIE
@@ -294,7 +265,7 @@ nouveau_sgdma_init(struct drm_device *dev)
                        nv_wo32(dev, gpuobj, (i+4)/4, 0);
                }
        }
-       dev_priv->engine.instmem.finish_access(dev);
+       dev_priv->engine.instmem.flush(dev);
 
        dev_priv->gart_info.type      = NOUVEAU_GART_SGDMA;
        dev_priv->gart_info.aper_base = 0;
@@ -325,14 +296,11 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
-       struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
        int pte;
 
        pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
        if (dev_priv->card_type < NV_50) {
-               instmem->prepare_access(dev, false);
                *page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
-               instmem->finish_access(dev);
                return 0;
        }
 
index b02a231d6937489fe972bfc813dc72d5d421aa70..ee3729e7823ba312001985790e54f4844610416d 100644 (file)
@@ -38,6 +38,7 @@
 #include "nv50_display.h"
 
 static void nouveau_stub_takedown(struct drm_device *dev) {}
+static int nouveau_stub_init(struct drm_device *dev) { return 0; }
 
 static int nouveau_init_engine_ptrs(struct drm_device *dev)
 {
@@ -54,8 +55,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.clear           = nv04_instmem_clear;
                engine->instmem.bind            = nv04_instmem_bind;
                engine->instmem.unbind          = nv04_instmem_unbind;
-               engine->instmem.prepare_access  = nv04_instmem_prepare_access;
-               engine->instmem.finish_access   = nv04_instmem_finish_access;
+               engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
                engine->timer.init              = nv04_timer_init;
@@ -85,6 +85,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv04_fifo_destroy_context;
                engine->fifo.load_context       = nv04_fifo_load_context;
                engine->fifo.unload_context     = nv04_fifo_unload_context;
+               engine->display.early_init      = nv04_display_early_init;
+               engine->display.late_takedown   = nv04_display_late_takedown;
+               engine->display.create          = nv04_display_create;
+               engine->display.init            = nv04_display_init;
+               engine->display.destroy         = nv04_display_destroy;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = NULL;
+               engine->gpio.set                = NULL;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x10:
                engine->instmem.init            = nv04_instmem_init;
@@ -95,8 +105,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.clear           = nv04_instmem_clear;
                engine->instmem.bind            = nv04_instmem_bind;
                engine->instmem.unbind          = nv04_instmem_unbind;
-               engine->instmem.prepare_access  = nv04_instmem_prepare_access;
-               engine->instmem.finish_access   = nv04_instmem_finish_access;
+               engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
                engine->timer.init              = nv04_timer_init;
@@ -128,6 +137,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv10_fifo_destroy_context;
                engine->fifo.load_context       = nv10_fifo_load_context;
                engine->fifo.unload_context     = nv10_fifo_unload_context;
+               engine->display.early_init      = nv04_display_early_init;
+               engine->display.late_takedown   = nv04_display_late_takedown;
+               engine->display.create          = nv04_display_create;
+               engine->display.init            = nv04_display_init;
+               engine->display.destroy         = nv04_display_destroy;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x20:
                engine->instmem.init            = nv04_instmem_init;
@@ -138,8 +157,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.clear           = nv04_instmem_clear;
                engine->instmem.bind            = nv04_instmem_bind;
                engine->instmem.unbind          = nv04_instmem_unbind;
-               engine->instmem.prepare_access  = nv04_instmem_prepare_access;
-               engine->instmem.finish_access   = nv04_instmem_finish_access;
+               engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
                engine->timer.init              = nv04_timer_init;
@@ -171,6 +189,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv10_fifo_destroy_context;
                engine->fifo.load_context       = nv10_fifo_load_context;
                engine->fifo.unload_context     = nv10_fifo_unload_context;
+               engine->display.early_init      = nv04_display_early_init;
+               engine->display.late_takedown   = nv04_display_late_takedown;
+               engine->display.create          = nv04_display_create;
+               engine->display.init            = nv04_display_init;
+               engine->display.destroy         = nv04_display_destroy;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x30:
                engine->instmem.init            = nv04_instmem_init;
@@ -181,15 +209,14 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.clear           = nv04_instmem_clear;
                engine->instmem.bind            = nv04_instmem_bind;
                engine->instmem.unbind          = nv04_instmem_unbind;
-               engine->instmem.prepare_access  = nv04_instmem_prepare_access;
-               engine->instmem.finish_access   = nv04_instmem_finish_access;
+               engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
                engine->timer.init              = nv04_timer_init;
                engine->timer.read              = nv04_timer_read;
                engine->timer.takedown          = nv04_timer_takedown;
-               engine->fb.init                 = nv10_fb_init;
-               engine->fb.takedown             = nv10_fb_takedown;
+               engine->fb.init                 = nv30_fb_init;
+               engine->fb.takedown             = nv30_fb_takedown;
                engine->fb.set_region_tiling    = nv10_fb_set_region_tiling;
                engine->graph.grclass           = nv30_graph_grclass;
                engine->graph.init              = nv30_graph_init;
@@ -214,6 +241,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv10_fifo_destroy_context;
                engine->fifo.load_context       = nv10_fifo_load_context;
                engine->fifo.unload_context     = nv10_fifo_unload_context;
+               engine->display.early_init      = nv04_display_early_init;
+               engine->display.late_takedown   = nv04_display_late_takedown;
+               engine->display.create          = nv04_display_create;
+               engine->display.init            = nv04_display_init;
+               engine->display.destroy         = nv04_display_destroy;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x40:
        case 0x60:
@@ -225,8 +262,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.clear           = nv04_instmem_clear;
                engine->instmem.bind            = nv04_instmem_bind;
                engine->instmem.unbind          = nv04_instmem_unbind;
-               engine->instmem.prepare_access  = nv04_instmem_prepare_access;
-               engine->instmem.finish_access   = nv04_instmem_finish_access;
+               engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv40_mc_init;
                engine->mc.takedown             = nv40_mc_takedown;
                engine->timer.init              = nv04_timer_init;
@@ -258,6 +294,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv40_fifo_destroy_context;
                engine->fifo.load_context       = nv40_fifo_load_context;
                engine->fifo.unload_context     = nv40_fifo_unload_context;
+               engine->display.early_init      = nv04_display_early_init;
+               engine->display.late_takedown   = nv04_display_late_takedown;
+               engine->display.create          = nv04_display_create;
+               engine->display.init            = nv04_display_init;
+               engine->display.destroy         = nv04_display_destroy;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x50:
        case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -271,8 +317,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.clear           = nv50_instmem_clear;
                engine->instmem.bind            = nv50_instmem_bind;
                engine->instmem.unbind          = nv50_instmem_unbind;
-               engine->instmem.prepare_access  = nv50_instmem_prepare_access;
-               engine->instmem.finish_access   = nv50_instmem_finish_access;
+               if (dev_priv->chipset == 0x50)
+                       engine->instmem.flush   = nv50_instmem_flush;
+               else
+                       engine->instmem.flush   = nv84_instmem_flush;
                engine->mc.init                 = nv50_mc_init;
                engine->mc.takedown             = nv50_mc_takedown;
                engine->timer.init              = nv04_timer_init;
@@ -300,6 +348,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv50_fifo_destroy_context;
                engine->fifo.load_context       = nv50_fifo_load_context;
                engine->fifo.unload_context     = nv50_fifo_unload_context;
+               engine->display.early_init      = nv50_display_early_init;
+               engine->display.late_takedown   = nv50_display_late_takedown;
+               engine->display.create          = nv50_display_create;
+               engine->display.init            = nv50_display_init;
+               engine->display.destroy         = nv50_display_destroy;
+               engine->gpio.init               = nv50_gpio_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv50_gpio_get;
+               engine->gpio.set                = nv50_gpio_set;
+               engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                break;
        default:
                NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -407,11 +465,6 @@ nouveau_card_init(struct drm_device *dev)
        struct nouveau_engine *engine;
        int ret;
 
-       NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
-
-       if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
-               return 0;
-
        vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
        vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
                                       nouveau_switcheroo_can_switch);
@@ -421,15 +474,17 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out;
        engine = &dev_priv->engine;
-       dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
        spin_lock_init(&dev_priv->context_switch_lock);
 
+       /* Make the CRTCs and I2C buses accessible */
+       ret = engine->display.early_init(dev);
+       if (ret)
+               goto out;
+
        /* Parse BIOS tables / Run init tables if card not POSTed */
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               ret = nouveau_bios_init(dev);
-               if (ret)
-                       goto out;
-       }
+       ret = nouveau_bios_init(dev);
+       if (ret)
+               goto out_display_early;
 
        ret = nouveau_mem_detect(dev);
        if (ret)
@@ -461,10 +516,15 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out_gpuobj;
 
+       /* PGPIO */
+       ret = engine->gpio.init(dev);
+       if (ret)
+               goto out_mc;
+
        /* PTIMER */
        ret = engine->timer.init(dev);
        if (ret)
-               goto out_mc;
+               goto out_gpio;
 
        /* PFB */
        ret = engine->fb.init(dev);
@@ -485,12 +545,16 @@ nouveau_card_init(struct drm_device *dev)
                        goto out_graph;
        }
 
+       ret = engine->display.create(dev);
+       if (ret)
+               goto out_fifo;
+
        /* this call irq_preinstall, register irq handler and
         * call irq_postinstall
         */
        ret = drm_irq_install(dev);
        if (ret)
-               goto out_fifo;
+               goto out_display;
 
        ret = drm_vblank_init(dev, 0);
        if (ret)
@@ -504,35 +568,18 @@ nouveau_card_init(struct drm_device *dev)
                        goto out_irq;
        }
 
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               if (dev_priv->card_type >= NV_50)
-                       ret = nv50_display_create(dev);
-               else
-                       ret = nv04_display_create(dev);
-               if (ret)
-                       goto out_channel;
-       }
-
        ret = nouveau_backlight_init(dev);
        if (ret)
                NV_ERROR(dev, "Error %d registering backlight\n", ret);
 
-       dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
-
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               nouveau_fbcon_init(dev);
-               drm_kms_helper_poll_init(dev);
-       }
-
+       nouveau_fbcon_init(dev);
+       drm_kms_helper_poll_init(dev);
        return 0;
 
-out_channel:
-       if (dev_priv->channel) {
-               nouveau_channel_free(dev_priv->channel);
-               dev_priv->channel = NULL;
-       }
 out_irq:
        drm_irq_uninstall(dev);
+out_display:
+       engine->display.destroy(dev);
 out_fifo:
        if (!nouveau_noaccel)
                engine->fifo.takedown(dev);
@@ -543,6 +590,8 @@ out_fb:
        engine->fb.takedown(dev);
 out_timer:
        engine->timer.takedown(dev);
+out_gpio:
+       engine->gpio.takedown(dev);
 out_mc:
        engine->mc.takedown(dev);
 out_gpuobj:
@@ -556,6 +605,8 @@ out_gpuobj_early:
        nouveau_gpuobj_late_takedown(dev);
 out_bios:
        nouveau_bios_takedown(dev);
+out_display_early:
+       engine->display.late_takedown(dev);
 out:
        vga_client_register(dev->pdev, NULL, NULL, NULL);
        return ret;
@@ -566,45 +617,39 @@ static void nouveau_card_takedown(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_engine *engine = &dev_priv->engine;
 
-       NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
-
-       if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
-
-               nouveau_backlight_exit(dev);
-
-               if (dev_priv->channel) {
-                       nouveau_channel_free(dev_priv->channel);
-                       dev_priv->channel = NULL;
-               }
+       nouveau_backlight_exit(dev);
 
-               if (!nouveau_noaccel) {
-                       engine->fifo.takedown(dev);
-                       engine->graph.takedown(dev);
-               }
-               engine->fb.takedown(dev);
-               engine->timer.takedown(dev);
-               engine->mc.takedown(dev);
+       if (dev_priv->channel) {
+               nouveau_channel_free(dev_priv->channel);
+               dev_priv->channel = NULL;
+       }
 
-               mutex_lock(&dev->struct_mutex);
-               ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
-               ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
-               mutex_unlock(&dev->struct_mutex);
-               nouveau_sgdma_takedown(dev);
+       if (!nouveau_noaccel) {
+               engine->fifo.takedown(dev);
+               engine->graph.takedown(dev);
+       }
+       engine->fb.takedown(dev);
+       engine->timer.takedown(dev);
+       engine->gpio.takedown(dev);
+       engine->mc.takedown(dev);
+       engine->display.late_takedown(dev);
 
-               nouveau_gpuobj_takedown(dev);
-               nouveau_mem_close(dev);
-               engine->instmem.takedown(dev);
+       mutex_lock(&dev->struct_mutex);
+       ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
+       ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
+       mutex_unlock(&dev->struct_mutex);
+       nouveau_sgdma_takedown(dev);
 
-               if (drm_core_check_feature(dev, DRIVER_MODESET))
-                       drm_irq_uninstall(dev);
+       nouveau_gpuobj_takedown(dev);
+       nouveau_mem_close(dev);
+       engine->instmem.takedown(dev);
 
-               nouveau_gpuobj_late_takedown(dev);
-               nouveau_bios_takedown(dev);
+       drm_irq_uninstall(dev);
 
-               vga_client_register(dev->pdev, NULL, NULL, NULL);
+       nouveau_gpuobj_late_takedown(dev);
+       nouveau_bios_takedown(dev);
 
-               dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
-       }
+       vga_client_register(dev->pdev, NULL, NULL, NULL);
 }
 
 /* here a client dies, release the stuff that was allocated for its
@@ -691,6 +736,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
        struct drm_nouveau_private *dev_priv;
        uint32_t reg0;
        resource_size_t mmio_start_offs;
+       int ret;
 
        dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
        if (!dev_priv)
@@ -699,7 +745,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
        dev_priv->dev = dev;
 
        dev_priv->flags = flags & NOUVEAU_FLAGS;
-       dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
 
        NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
                 dev->pci_vendor, dev->pci_device, dev->pdev->class);
@@ -773,11 +818,9 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
        NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
                dev_priv->card_type, reg0);
 
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               int ret = nouveau_remove_conflicting_drivers(dev);
-               if (ret)
-                       return ret;
-       }
+       ret = nouveau_remove_conflicting_drivers(dev);
+       if (ret)
+               return ret;
 
        /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */
        if (dev_priv->card_type >= NV_40) {
@@ -812,46 +855,26 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
                dev_priv->flags |= NV_NFORCE2;
 
        /* For kernel modesetting, init card now and bring up fbcon */
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               int ret = nouveau_card_init(dev);
-               if (ret)
-                       return ret;
-       }
+       ret = nouveau_card_init(dev);
+       if (ret)
+               return ret;
 
        return 0;
 }
 
-static void nouveau_close(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-       /* In the case of an error dev_priv may not be allocated yet */
-       if (dev_priv)
-               nouveau_card_takedown(dev);
-}
-
-/* KMS: we need mmio at load time, not when the first drm client opens. */
 void nouveau_lastclose(struct drm_device *dev)
 {
-       if (drm_core_check_feature(dev, DRIVER_MODESET))
-               return;
-
-       nouveau_close(dev);
 }
 
 int nouveau_unload(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_engine *engine = &dev_priv->engine;
 
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               drm_kms_helper_poll_fini(dev);
-               nouveau_fbcon_fini(dev);
-               if (dev_priv->card_type >= NV_50)
-                       nv50_display_destroy(dev);
-               else
-                       nv04_display_destroy(dev);
-               nouveau_close(dev);
-       }
+       drm_kms_helper_poll_fini(dev);
+       nouveau_fbcon_fini(dev);
+       engine->display.destroy(dev);
+       nouveau_card_takedown(dev);
 
        iounmap(dev_priv->mmio);
        iounmap(dev_priv->ramin);
@@ -867,8 +890,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct drm_nouveau_getparam *getparam = data;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
        switch (getparam->param) {
        case NOUVEAU_GETPARAM_CHIPSET_ID:
                getparam->value = dev_priv->chipset;
@@ -937,8 +958,6 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
 {
        struct drm_nouveau_setparam *setparam = data;
 
-       NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
        switch (setparam->param) {
        default:
                NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
index c385d50f041b0f6ecf6e08cb6c58effba677c942..bd35f930568c922b9b275aa3de418c502e543e7f 100644 (file)
@@ -42,13 +42,13 @@ nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma)
 }
 
 static int
-nouveau_ttm_mem_global_init(struct ttm_global_reference *ref)
+nouveau_ttm_mem_global_init(struct drm_global_reference *ref)
 {
        return ttm_mem_global_init(ref->object);
 }
 
 static void
-nouveau_ttm_mem_global_release(struct ttm_global_reference *ref)
+nouveau_ttm_mem_global_release(struct drm_global_reference *ref)
 {
        ttm_mem_global_release(ref->object);
 }
@@ -56,16 +56,16 @@ nouveau_ttm_mem_global_release(struct ttm_global_reference *ref)
 int
 nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
 {
-       struct ttm_global_reference *global_ref;
+       struct drm_global_reference *global_ref;
        int ret;
 
        global_ref = &dev_priv->ttm.mem_global_ref;
-       global_ref->global_type = TTM_GLOBAL_TTM_MEM;
+       global_ref->global_type = DRM_GLOBAL_TTM_MEM;
        global_ref->size = sizeof(struct ttm_mem_global);
        global_ref->init = &nouveau_ttm_mem_global_init;
        global_ref->release = &nouveau_ttm_mem_global_release;
 
-       ret = ttm_global_item_ref(global_ref);
+       ret = drm_global_item_ref(global_ref);
        if (unlikely(ret != 0)) {
                DRM_ERROR("Failed setting up TTM memory accounting\n");
                dev_priv->ttm.mem_global_ref.release = NULL;
@@ -74,15 +74,15 @@ nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
 
        dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object;
        global_ref = &dev_priv->ttm.bo_global_ref.ref;
-       global_ref->global_type = TTM_GLOBAL_TTM_BO;
+       global_ref->global_type = DRM_GLOBAL_TTM_BO;
        global_ref->size = sizeof(struct ttm_bo_global);
        global_ref->init = &ttm_bo_global_init;
        global_ref->release = &ttm_bo_global_release;
 
-       ret = ttm_global_item_ref(global_ref);
+       ret = drm_global_item_ref(global_ref);
        if (unlikely(ret != 0)) {
                DRM_ERROR("Failed setting up TTM BO subsystem\n");
-               ttm_global_item_unref(&dev_priv->ttm.mem_global_ref);
+               drm_global_item_unref(&dev_priv->ttm.mem_global_ref);
                dev_priv->ttm.mem_global_ref.release = NULL;
                return ret;
        }
@@ -96,8 +96,8 @@ nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv)
        if (dev_priv->ttm.mem_global_ref.release == NULL)
                return;
 
-       ttm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref);
-       ttm_global_item_unref(&dev_priv->ttm.mem_global_ref);
+       drm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref);
+       drm_global_item_unref(&dev_priv->ttm.mem_global_ref);
        dev_priv->ttm.mem_global_ref.release = NULL;
 }
 
index eba687f1099e24fcb164eb7a3f3e18550acc0508..1c20c08ce67c33685eb433644679209bf31874ba 100644 (file)
@@ -157,6 +157,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct drm_device *dev = crtc->dev;
+       struct drm_connector *connector;
        unsigned char seq1 = 0, crtc17 = 0;
        unsigned char crtc1A;
 
@@ -211,6 +212,10 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
        NVVgaSeqReset(dev, nv_crtc->index, false);
 
        NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
+
+       /* Update connector polling modes */
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+               nouveau_connector_set_polling(connector);
 }
 
 static bool
index 1cb19e3acb554a998765c98a4aa31c708cd36caf..ea3627041ecf8e7eb4a59199d8c1c7e1e64fd437 100644 (file)
@@ -220,6 +220,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
        struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
        uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder);
        uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
@@ -251,22 +252,21 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
                nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
        }
 
-       saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1);
-       saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0);
+       saved_gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1);
+       saved_gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0);
 
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
+       gpio->set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
+       gpio->set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
 
        msleep(4);
 
        saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
        head = (saved_routput & 0x100) >> 8;
-#if 0
-       /* if there's a spare crtc, using it will minimise flicker for the case
-        * where the in-use crtc is in use by an off-chip tmds encoder */
-       if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
+
+       /* if there's a spare crtc, using it will minimise flicker */
+       if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0))
                head ^= 1;
-#endif
+
        /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
        routput = (saved_routput & 0xfffffece) | head << 8;
 
@@ -304,8 +304,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
                nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
        nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
 
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
+       gpio->set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
+       gpio->set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
 
        return sample;
 }
@@ -315,9 +315,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 {
        struct drm_device *dev = encoder->dev;
        struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
-       uint32_t sample = nv17_dac_sample_load(encoder);
 
-       if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
+       if (nv04_dac_in_use(encoder))
+               return connector_status_disconnected;
+
+       if (nv17_dac_sample_load(encoder) &
+           NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
                NV_INFO(dev, "Load detected on output %c\n",
                        '@' + ffs(dcb->or));
                return connector_status_connected;
@@ -330,6 +333,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder,
                                struct drm_display_mode *mode,
                                struct drm_display_mode *adjusted_mode)
 {
+       if (nv04_dac_in_use(encoder))
+               return false;
+
        return true;
 }
 
@@ -428,6 +434,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
        }
 }
 
+/* Check if the DAC corresponding to 'encoder' is being used by
+ * someone else. */
+bool nv04_dac_in_use(struct drm_encoder *encoder)
+{
+       struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
+       struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+
+       return nv_gf4_disp_arch(encoder->dev) &&
+               (dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index));
+}
+
 static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
@@ -501,11 +518,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = {
        .destroy = nv04_dac_destroy,
 };
 
-int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+int
+nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        const struct drm_encoder_helper_funcs *helper;
-       struct drm_encoder *encoder;
        struct nouveau_encoder *nv_encoder = NULL;
+       struct drm_device *dev = connector->dev;
+       struct drm_encoder *encoder;
 
        nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
        if (!nv_encoder)
@@ -527,5 +546,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
index 41634d4752fe08f6309d81c0b81ff0b7a65cc64f..3311f3a8c8180b9bd3eeee6e5571f7703a6d9bdf 100644 (file)
@@ -413,10 +413,6 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
        struct dcb_entry *dcbe = nv_encoder->dcb;
        int head = nouveau_crtc(encoder->crtc)->index;
 
-       NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
-               drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
-               nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
-
        if (dcbe->type == OUTPUT_TMDS)
                run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
        else if (dcbe->type == OUTPUT_LVDS)
@@ -584,11 +580,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = {
        .destroy = nv04_dfp_destroy,
 };
 
-int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
+int
+nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        const struct drm_encoder_helper_funcs *helper;
-       struct drm_encoder *encoder;
        struct nouveau_encoder *nv_encoder = NULL;
+       struct drm_encoder *encoder;
        int type;
 
        switch (entry->type) {
@@ -613,11 +610,12 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
        nv_encoder->dcb = entry;
        nv_encoder->or = ffs(entry->or) - 1;
 
-       drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type);
+       drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type);
        drm_encoder_helper_add(encoder, helper);
 
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
index c7898b4f6dfbe0e1fb440452368d22077a0b083d..9e28cf772e3cd482af0c1d048634470d0bdf3b2d 100644 (file)
@@ -32,8 +32,6 @@
 #include "nouveau_encoder.h"
 #include "nouveau_connector.h"
 
-#define MULTIPLE_ENCODERS(e) (e & (e - 1))
-
 static void
 nv04_display_store_initial_head_owner(struct drm_device *dev)
 {
@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
 
        if (dev_priv->chipset != 0x11) {
                dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
-               goto ownerknown;
+               return;
        }
 
        /* reading CR44 is broken on nv11, so we attempt to infer it */
@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
                bool tvA = false;
                bool tvB = false;
 
-               NVLockVgaCrtcs(dev, false);
-
                slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
                                                                        0x80;
                if (slaved_on_B)
@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
                        tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
                                        MASK(NV_CIO_CRE_LCD_LCD_SELECT));
 
-               NVLockVgaCrtcs(dev, true);
-
                if (slaved_on_A && !tvA)
                        dev_priv->crtc_owner = 0x0;
                else if (slaved_on_B && !tvB)
@@ -79,14 +73,40 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
                else
                        dev_priv->crtc_owner = 0x0;
        }
+}
+
+int
+nv04_display_early_init(struct drm_device *dev)
+{
+       /* Make the I2C buses accessible. */
+       if (!nv_gf4_disp_arch(dev)) {
+               uint32_t pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
+
+               if (!(pmc_enable & 1))
+                       nv_wr32(dev, NV03_PMC_ENABLE, pmc_enable | 1);
+       }
 
-ownerknown:
-       NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner);
+       /* Unlock the VGA CRTCs. */
+       NVLockVgaCrtcs(dev, false);
+
+       /* Make sure the CRTCs aren't in slaved mode. */
+       if (nv_two_heads(dev)) {
+               nv04_display_store_initial_head_owner(dev);
+               NVSetOwner(dev, 0);
+       }
+
+       return 0;
+}
+
+void
+nv04_display_late_takedown(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       if (nv_two_heads(dev))
+               NVSetOwner(dev, dev_priv->crtc_owner);
 
-       /* we need to ensure the heads are not tied henceforth, or reading any
-        * 8 bit reg on head B will fail
-        * setting a single arbitrary head solves that */
-       NVSetOwner(dev, 0);
+       NVLockVgaCrtcs(dev, true);
 }
 
 int
@@ -94,14 +114,13 @@ nv04_display_create(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct dcb_table *dcb = &dev_priv->vbios.dcb;
+       struct drm_connector *connector, *ct;
        struct drm_encoder *encoder;
        struct drm_crtc *crtc;
        int i, ret;
 
        NV_DEBUG_KMS(dev, "\n");
 
-       if (nv_two_heads(dev))
-               nv04_display_store_initial_head_owner(dev);
        nouveau_hw_save_vga_fonts(dev, 1);
 
        drm_mode_config_init(dev);
@@ -132,19 +151,23 @@ nv04_display_create(struct drm_device *dev)
        for (i = 0; i < dcb->entries; i++) {
                struct dcb_entry *dcbent = &dcb->entry[i];
 
+               connector = nouveau_connector_create(dev, dcbent->connector);
+               if (IS_ERR(connector))
+                       continue;
+
                switch (dcbent->type) {
                case OUTPUT_ANALOG:
-                       ret = nv04_dac_create(dev, dcbent);
+                       ret = nv04_dac_create(connector, dcbent);
                        break;
                case OUTPUT_LVDS:
                case OUTPUT_TMDS:
-                       ret = nv04_dfp_create(dev, dcbent);
+                       ret = nv04_dfp_create(connector, dcbent);
                        break;
                case OUTPUT_TV:
                        if (dcbent->location == DCB_LOC_ON_CHIP)
-                               ret = nv17_tv_create(dev, dcbent);
+                               ret = nv17_tv_create(connector, dcbent);
                        else
-                               ret = nv04_tv_create(dev, dcbent);
+                               ret = nv04_tv_create(connector, dcbent);
                        break;
                default:
                        NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
@@ -155,12 +178,16 @@ nv04_display_create(struct drm_device *dev)
                        continue;
        }
 
-       for (i = 0; i < dcb->connector.entries; i++)
-               nouveau_connector_create(dev, &dcb->connector.entry[i]);
+       list_for_each_entry_safe(connector, ct,
+                                &dev->mode_config.connector_list, head) {
+               if (!connector->encoder_ids[0]) {
+                       NV_WARN(dev, "%s has no encoders, removing\n",
+                               drm_get_connector_name(connector));
+                       connector->funcs->destroy(connector);
+               }
+       }
 
        /* Save previous state */
-       NVLockVgaCrtcs(dev, false);
-
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
                crtc->funcs->save(crtc);
 
@@ -191,8 +218,6 @@ nv04_display_destroy(struct drm_device *dev)
        }
 
        /* Restore state */
-       NVLockVgaCrtcs(dev, false);
-
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                struct drm_encoder_helper_funcs *func = encoder->helper_private;
 
@@ -207,15 +232,12 @@ nv04_display_destroy(struct drm_device *dev)
        nouveau_hw_save_vga_fonts(dev, 0);
 }
 
-void
-nv04_display_restore(struct drm_device *dev)
+int
+nv04_display_init(struct drm_device *dev)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct drm_encoder *encoder;
        struct drm_crtc *crtc;
 
-       NVLockVgaCrtcs(dev, false);
-
        /* meh.. modeset apparently doesn't setup all the regs and depends
         * on pre-existing state, for now load the state of the card *before*
         * nouveau was loaded, and then do a modeset.
@@ -233,12 +255,6 @@ nv04_display_restore(struct drm_device *dev)
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
                crtc->funcs->restore(crtc);
 
-       if (nv_two_heads(dev)) {
-               NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n",
-                       dev_priv->crtc_owner);
-               NVSetOwner(dev, dev_priv->crtc_owner);
-       }
-
-       NVLockVgaCrtcs(dev, true);
+       return 0;
 }
 
index 66fe55983b6e3b7b9cf7b14700a7c1ba5b5681c9..06cedd99c26a3a72e4fc18d1f743a19a374a8706 100644 (file)
@@ -112,6 +112,12 @@ nv04_fifo_channel_id(struct drm_device *dev)
                        NV03_PFIFO_CACHE1_PUSH1_CHID_MASK;
 }
 
+#ifdef __BIG_ENDIAN
+#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN
+#else
+#define DMA_FETCH_ENDIANNESS 0
+#endif
+
 int
 nv04_fifo_create_context(struct nouveau_channel *chan)
 {
@@ -131,18 +137,13 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
 
        /* Setup initial state */
-       dev_priv->engine.instmem.prepare_access(dev, true);
        RAMFC_WR(DMA_PUT, chan->pushbuf_base);
        RAMFC_WR(DMA_GET, chan->pushbuf_base);
        RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4);
        RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
                             NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
                             NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
-#ifdef __BIG_ENDIAN
-                            NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
-                            0));
-       dev_priv->engine.instmem.finish_access(dev);
+                            DMA_FETCH_ENDIANNESS));
 
        /* enable the fifo dma operation */
        nv_wr32(dev, NV04_PFIFO_MODE,
@@ -169,8 +170,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t fc = NV04_RAMFC(chid), tmp;
 
-       dev_priv->engine.instmem.prepare_access(dev, false);
-
        nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
        nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
        tmp = nv_ri32(dev, fc + 8);
@@ -181,8 +180,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid)
        nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20));
        nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24));
 
-       dev_priv->engine.instmem.finish_access(dev);
-
        nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
 }
@@ -223,7 +220,6 @@ nv04_fifo_unload_context(struct drm_device *dev)
                return -EINVAL;
        }
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
        RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
        tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16;
@@ -233,7 +229,6 @@ nv04_fifo_unload_context(struct drm_device *dev)
        RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH));
        RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
        RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
-       dev_priv->engine.instmem.finish_access(dev);
 
        nv04_fifo_do_load_context(dev, pfifo->channels - 1);
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
@@ -297,6 +292,7 @@ nv04_fifo_init(struct drm_device *dev)
 
        nv04_fifo_init_intr(dev);
        pfifo->enable(dev);
+       pfifo->reassign(dev, true);
 
        for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
                if (dev_priv->fifos[i]) {
index 618355e9cdd5602f7ea57e8c31afbcaaf2d4b1b5..c8973421b635529fcb027539aa2f7bbffde81546 100644 (file)
@@ -342,7 +342,7 @@ static uint32_t nv04_graph_ctx_regs[] = {
 };
 
 struct graph_state {
-       int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
+       uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
 };
 
 struct nouveau_channel *
@@ -527,8 +527,7 @@ static int
 nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass,
                        int mthd, uint32_t data)
 {
-       chan->fence.last_sequence_irq = data;
-       nouveau_fence_handler(chan->dev, chan->id);
+       atomic_set(&chan->fence.last_sequence_irq, data);
        return 0;
 }
 
index a3b9563a6f60c4f933cd9caf687da307eaac90ae..4408232d33f179805205763974beede957ddd6f1 100644 (file)
@@ -49,10 +49,8 @@ nv04_instmem_determine_amount(struct drm_device *dev)
        NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10);
 
        /* Clear all of it, except the BIOS image that's in the first 64KiB */
-       dev_priv->engine.instmem.prepare_access(dev, true);
        for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4)
                nv_wi32(dev, i, 0x00000000);
-       dev_priv->engine.instmem.finish_access(dev);
 }
 
 static void
@@ -106,7 +104,7 @@ int nv04_instmem_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t offset;
-       int ret = 0;
+       int ret;
 
        nv04_instmem_determine_amount(dev);
        nv04_instmem_configure_fixed_tables(dev);
@@ -129,14 +127,14 @@ int nv04_instmem_init(struct drm_device *dev)
                        offset = 0x40000;
        }
 
-       ret = nouveau_mem_init_heap(&dev_priv->ramin_heap,
-                                   offset, dev_priv->ramin_rsvd_vram - offset);
+       ret = drm_mm_init(&dev_priv->ramin_heap, offset,
+                         dev_priv->ramin_rsvd_vram - offset);
        if (ret) {
-               dev_priv->ramin_heap = NULL;
-               NV_ERROR(dev, "Failed to init RAMIN heap\n");
+               NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
+               return ret;
        }
 
-       return ret;
+       return 0;
 }
 
 void
@@ -186,12 +184,7 @@ nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
 }
 
 void
-nv04_instmem_prepare_access(struct drm_device *dev, bool write)
-{
-}
-
-void
-nv04_instmem_finish_access(struct drm_device *dev)
+nv04_instmem_flush(struct drm_device *dev)
 {
 }
 
index 617ed1e052692cc6f80746560e0b2d494c58d776..2af43a1cb2ec00e698dbbd320e1bdffeaee3dab3 100644 (file)
@@ -11,6 +11,10 @@ nv04_mc_init(struct drm_device *dev)
         */
 
        nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
+
+       /* Disable PROM access. */
+       nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
+
        return 0;
 }
 
index c4e3404337d4708e7b60c57e538908455f2ac235..94e299cef0b2624521b69251e4e1452945238728 100644 (file)
 
 #include "i2c/ch7006.h"
 
-static struct {
-       struct i2c_board_info board_info;
-       struct drm_encoder_funcs funcs;
-       struct drm_encoder_helper_funcs hfuncs;
-       void *params;
-
-} nv04_tv_encoder_info[] = {
+static struct i2c_board_info nv04_tv_encoder_info[] = {
        {
-               .board_info = { I2C_BOARD_INFO("ch7006", 0x75) },
-               .params = &(struct ch7006_encoder_params) {
+               I2C_BOARD_INFO("ch7006", 0x75),
+               .platform_data = &(struct ch7006_encoder_params) {
                        CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
                        0, 0, 0,
                        CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
                        CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
-               },
+               }
        },
+       { }
 };
 
-static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr)
-{
-       struct i2c_msg msg = {
-               .addr = addr,
-               .len = 0,
-       };
-
-       return i2c_transfer(adapter, &msg, 1) == 1;
-}
-
 int nv04_tv_identify(struct drm_device *dev, int i2c_index)
 {
-       struct nouveau_i2c_chan *i2c;
-       bool was_locked;
-       int i, ret;
-
-       NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index);
-
-       i2c = nouveau_i2c_find(dev, i2c_index);
-       if (!i2c)
-               return -ENODEV;
-
-       was_locked = NVLockVgaCrtcs(dev, false);
-
-       for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) {
-               if (probe_i2c_addr(&i2c->adapter,
-                                  nv04_tv_encoder_info[i].board_info.addr)) {
-                       ret = i;
-                       break;
-               }
-       }
-
-       if (i < ARRAY_SIZE(nv04_tv_encoder_info)) {
-               NV_TRACE(dev, "Detected TV encoder: %s\n",
-                        nv04_tv_encoder_info[i].board_info.type);
-
-       } else {
-               NV_TRACE(dev, "No TV encoders found.\n");
-               i = -ENODEV;
-       }
-
-       NVLockVgaCrtcs(dev, was_locked);
-       return i;
+       return nouveau_i2c_identify(dev, "TV encoder",
+                                   nv04_tv_encoder_info, i2c_index);
 }
 
+
 #define PLLSEL_TV_CRTC1_MASK                           \
        (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1          \
         | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1)
@@ -214,30 +171,32 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
 
 static void nv04_tv_destroy(struct drm_encoder *encoder)
 {
-       struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-
        to_encoder_slave(encoder)->slave_funcs->destroy(encoder);
 
        drm_encoder_cleanup(encoder);
 
-       kfree(nv_encoder);
+       kfree(encoder->helper_private);
+       kfree(nouveau_encoder(encoder));
 }
 
-int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+static const struct drm_encoder_funcs nv04_tv_funcs = {
+       .destroy = nv04_tv_destroy,
+};
+
+int
+nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        struct nouveau_encoder *nv_encoder;
        struct drm_encoder *encoder;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct i2c_adapter *adap;
-       struct drm_encoder_funcs *funcs = NULL;
-       struct drm_encoder_helper_funcs *hfuncs = NULL;
-       struct drm_encoder_slave_funcs *sfuncs = NULL;
-       int i2c_index = entry->i2c_index;
+       struct drm_device *dev = connector->dev;
+       struct drm_encoder_helper_funcs *hfuncs;
+       struct drm_encoder_slave_funcs *sfuncs;
+       struct nouveau_i2c_chan *i2c =
+               nouveau_i2c_find(dev, entry->i2c_index);
        int type, ret;
-       bool was_locked;
 
        /* Ensure that we can talk to this encoder */
-       type = nv04_tv_identify(dev, i2c_index);
+       type = nv04_tv_identify(dev, entry->i2c_index);
        if (type < 0)
                return type;
 
@@ -246,41 +205,32 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
        if (!nv_encoder)
                return -ENOMEM;
 
+       hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL);
+       if (!hfuncs) {
+               ret = -ENOMEM;
+               goto fail_free;
+       }
+
        /* Initialize the common members */
        encoder = to_drm_encoder(nv_encoder);
 
-       funcs = &nv04_tv_encoder_info[type].funcs;
-       hfuncs = &nv04_tv_encoder_info[type].hfuncs;
-
-       drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC);
+       drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC);
        drm_encoder_helper_add(encoder, hfuncs);
 
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
-
        nv_encoder->dcb = entry;
        nv_encoder->or = ffs(entry->or) - 1;
 
        /* Run the slave-specific initialization */
-       adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter;
-
-       was_locked = NVLockVgaCrtcs(dev, false);
-
-       ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap,
-                                  &nv04_tv_encoder_info[type].board_info);
-
-       NVLockVgaCrtcs(dev, was_locked);
-
+       ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
+                                  &i2c->adapter, &nv04_tv_encoder_info[type]);
        if (ret < 0)
-               goto fail;
+               goto fail_cleanup;
 
        /* Fill the function pointers */
        sfuncs = to_encoder_slave(encoder)->slave_funcs;
 
-       *funcs = (struct drm_encoder_funcs) {
-               .destroy = nv04_tv_destroy,
-       };
-
        *hfuncs = (struct drm_encoder_helper_funcs) {
                .dpms = nv04_tv_dpms,
                .save = sfuncs->save,
@@ -292,14 +242,17 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
                .detect = sfuncs->detect,
        };
 
-       /* Set the slave encoder configuration */
-       sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params);
+       /* Attach it to the specified connector. */
+       sfuncs->set_config(encoder, nv04_tv_encoder_info[type].platform_data);
+       sfuncs->create_resources(encoder, connector);
+       drm_mode_connector_attach_encoder(connector, encoder);
 
        return 0;
 
-fail:
+fail_cleanup:
        drm_encoder_cleanup(encoder);
-
+       kfree(hfuncs);
+fail_free:
        kfree(nv_encoder);
        return ret;
 }
index 7aeabf262bc0a43affe3c1fdad393e9301d95263..7a4069cf5d0b835caccd983722bb640df7f6e351 100644 (file)
@@ -55,7 +55,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
        /* Fill entries that are seen filled in dumps of nvidia driver just
         * after channel's is put into DMA mode
         */
-       dev_priv->engine.instmem.prepare_access(dev, true);
        nv_wi32(dev, fc +  0, chan->pushbuf_base);
        nv_wi32(dev, fc +  4, chan->pushbuf_base);
        nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
@@ -66,7 +65,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
                              NV_PFIFO_CACHE1_BIG_ENDIAN |
 #endif
                              0);
-       dev_priv->engine.instmem.finish_access(dev);
 
        /* enable the fifo dma operation */
        nv_wr32(dev, NV04_PFIFO_MODE,
@@ -91,8 +89,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t fc = NV10_RAMFC(chid), tmp;
 
-       dev_priv->engine.instmem.prepare_access(dev, false);
-
        nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
        nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
        nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
@@ -117,8 +113,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid)
        nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48));
 
 out:
-       dev_priv->engine.instmem.finish_access(dev);
-
        nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
 }
@@ -155,8 +149,6 @@ nv10_fifo_unload_context(struct drm_device *dev)
                return 0;
        fc = NV10_RAMFC(chid);
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
-
        nv_wi32(dev, fc +  0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
        nv_wi32(dev, fc +  4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
        nv_wi32(dev, fc +  8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
@@ -179,8 +171,6 @@ nv10_fifo_unload_context(struct drm_device *dev)
        nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
 
 out:
-       dev_priv->engine.instmem.finish_access(dev);
-
        nv10_fifo_do_load_context(dev, pfifo->channels - 1);
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
        return 0;
similarity index 95%
rename from drivers/gpu/drm/nouveau/nv17_gpio.c
rename to drivers/gpu/drm/nouveau/nv10_gpio.c
index 2e58c331e9b7dcc6830a63d3d8988d375a9d5179..007fc29e2f86130987ee5759894ed447f2fa1d93 100644 (file)
@@ -55,7 +55,7 @@ get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift,
 }
 
 int
-nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
+nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
 {
        struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
        uint32_t reg, shift, mask, value;
@@ -72,7 +72,7 @@ nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
 }
 
 int
-nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
+nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
 {
        struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
        uint32_t reg, shift, mask, value;
index 74c880374fb92a5593583b4d077bac002ec76c3c..44fefb0c7083caf5c4e77011675927dc3d60aec6 100644 (file)
@@ -37,6 +37,7 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
        uint32_t testval, regoffset = nv04_dac_output_offset(encoder);
        uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end,
                fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c;
@@ -52,8 +53,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
        head = (dacclk & 0x100) >> 8;
 
        /* Save the previous state. */
-       gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1);
-       gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0);
+       gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1);
+       gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0);
        fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL);
        fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START);
        fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END);
@@ -64,8 +65,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
        ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c);
 
        /* Prepare the DAC for load detection.  */
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true);
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true);
+       gpio->set(dev, DCB_GPIO_TVDAC1, true);
+       gpio->set(dev, DCB_GPIO_TVDAC0, true);
 
        NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343);
        NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047);
@@ -110,12 +111,27 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
        NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end);
        NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start);
        NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal);
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1);
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0);
+       gpio->set(dev, DCB_GPIO_TVDAC1, gpio1);
+       gpio->set(dev, DCB_GPIO_TVDAC0, gpio0);
 
        return sample;
 }
 
+static bool
+get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
+{
+       /* Zotac FX5200 */
+       if (dev->pdev->device == 0x0322 &&
+           dev->pdev->subsystem_vendor == 0x19da &&
+           (dev->pdev->subsystem_device == 0x1035 ||
+            dev->pdev->subsystem_device == 0x2035)) {
+               *pin_mask = 0xc;
+               return false;
+       }
+
+       return true;
+}
+
 static enum drm_connector_status
 nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 {
@@ -124,12 +140,20 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
        struct drm_mode_config *conf = &dev->mode_config;
        struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
        struct dcb_entry *dcb = tv_enc->base.dcb;
+       bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask);
 
-       if (dev_priv->chipset == 0x42 ||
-           dev_priv->chipset == 0x43)
-               tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe;
-       else
-               tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe;
+       if (nv04_dac_in_use(encoder))
+               return connector_status_disconnected;
+
+       if (reliable) {
+               if (dev_priv->chipset == 0x42 ||
+                   dev_priv->chipset == 0x43)
+                       tv_enc->pin_mask =
+                               nv42_tv_sample_load(encoder) >> 28 & 0xe;
+               else
+                       tv_enc->pin_mask =
+                               nv17_dac_sample_load(encoder) >> 28 & 0xe;
+       }
 
        switch (tv_enc->pin_mask) {
        case 0x2:
@@ -154,7 +178,9 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
                                         conf->tv_subconnector_property,
                                         tv_enc->subconnector);
 
-       if (tv_enc->subconnector) {
+       if (!reliable) {
+               return connector_status_unknown;
+       } else if (tv_enc->subconnector) {
                NV_INFO(dev, "Load detected on output %c\n",
                        '@' + ffs(dcb->or));
                return connector_status_connected;
@@ -296,6 +322,9 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
 {
        struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 
+       if (nv04_dac_in_use(encoder))
+               return false;
+
        if (tv_norm->kind == CTV_ENC_MODE)
                adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock;
        else
@@ -307,6 +336,8 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
 static void  nv17_tv_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
        struct nv17_tv_state *regs = &to_tv_enc(encoder)->state;
        struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 
@@ -331,8 +362,8 @@ static void  nv17_tv_dpms(struct drm_encoder *encoder, int mode)
 
        nv_load_ptv(dev, regs, 200);
 
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON);
-       nv17_gpio_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON);
+       gpio->set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON);
+       gpio->set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON);
 
        nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
 }
@@ -744,8 +775,10 @@ static struct drm_encoder_funcs nv17_tv_funcs = {
        .destroy = nv17_tv_destroy,
 };
 
-int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+int
+nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
+       struct drm_device *dev = connector->dev;
        struct drm_encoder *encoder;
        struct nv17_tv_encoder *tv_enc = NULL;
 
@@ -774,5 +807,7 @@ int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       nv17_tv_create_resources(encoder, connector);
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
index d6fc0a82f03dd20ea8b7c21da48d75c98ebb0ad9..17f309b36c910060a355af6d1ada2e6ca6fc7cfd 100644 (file)
@@ -370,68 +370,54 @@ nv20_graph_create_context(struct nouveau_channel *chan)
 {
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
        void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *);
-       unsigned int ctx_size;
        unsigned int idoffs = 0x28/4;
        int ret;
 
        switch (dev_priv->chipset) {
        case 0x20:
-               ctx_size = NV20_GRCTX_SIZE;
                ctx_init = nv20_graph_context_init;
                idoffs = 0;
                break;
        case 0x25:
        case 0x28:
-               ctx_size = NV25_GRCTX_SIZE;
                ctx_init = nv25_graph_context_init;
                break;
        case 0x2a:
-               ctx_size = NV2A_GRCTX_SIZE;
                ctx_init = nv2a_graph_context_init;
                idoffs = 0;
                break;
        case 0x30:
        case 0x31:
-               ctx_size = NV30_31_GRCTX_SIZE;
                ctx_init = nv30_31_graph_context_init;
                break;
        case 0x34:
-               ctx_size = NV34_GRCTX_SIZE;
                ctx_init = nv34_graph_context_init;
                break;
        case 0x35:
        case 0x36:
-               ctx_size = NV35_36_GRCTX_SIZE;
                ctx_init = nv35_36_graph_context_init;
                break;
        default:
-               ctx_size = 0;
-               ctx_init = nv35_36_graph_context_init;
-               NV_ERROR(dev, "Please contact the devs if you want your NV%x"
-                             " card to work\n", dev_priv->chipset);
-               return -ENOSYS;
-               break;
+               BUG_ON(1);
        }
 
-       ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
-                                         NVOBJ_FLAG_ZERO_ALLOC,
-                                         &chan->ramin_grctx);
+       ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
+                                    16, NVOBJ_FLAG_ZERO_ALLOC,
+                                    &chan->ramin_grctx);
        if (ret)
                return ret;
 
        /* Initialise default context values */
-       dev_priv->engine.instmem.prepare_access(dev, true);
        ctx_init(dev, chan->ramin_grctx->gpuobj);
 
        /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
        nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs,
                                        (chan->id << 24) | 0x1); /* CTX_USER */
 
-       nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id,
-                       chan->ramin_grctx->instance >> 4);
-
-       dev_priv->engine.instmem.finish_access(dev);
+       nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id,
+                    chan->ramin_grctx->instance >> 4);
        return 0;
 }
 
@@ -440,13 +426,12 @@ nv20_graph_destroy_context(struct nouveau_channel *chan)
 {
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 
        if (chan->ramin_grctx)
                nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
-       nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0);
-       dev_priv->engine.instmem.finish_access(dev);
+       nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id, 0);
 }
 
 int
@@ -538,29 +523,44 @@ nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
 int
 nv20_graph_init(struct drm_device *dev)
 {
-       struct drm_nouveau_private *dev_priv =
-               (struct drm_nouveau_private *)dev->dev_private;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
        uint32_t tmp, vramsz;
        int ret, i;
 
+       switch (dev_priv->chipset) {
+       case 0x20:
+               pgraph->grctx_size = NV20_GRCTX_SIZE;
+               break;
+       case 0x25:
+       case 0x28:
+               pgraph->grctx_size = NV25_GRCTX_SIZE;
+               break;
+       case 0x2a:
+               pgraph->grctx_size = NV2A_GRCTX_SIZE;
+               break;
+       default:
+               NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
+               pgraph->accel_blocked = true;
+               return 0;
+       }
+
        nv_wr32(dev, NV03_PMC_ENABLE,
                nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
        nv_wr32(dev, NV03_PMC_ENABLE,
                nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
 
-       if (!dev_priv->ctx_table) {
+       if (!pgraph->ctx_table) {
                /* Create Context Pointer Table */
-               dev_priv->ctx_table_size = 32 * 4;
-               ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
-                                                 dev_priv->ctx_table_size, 16,
+               ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16,
                                                  NVOBJ_FLAG_ZERO_ALLOC,
-                                                 &dev_priv->ctx_table);
+                                                 &pgraph->ctx_table);
                if (ret)
                        return ret;
        }
 
        nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
-                dev_priv->ctx_table->instance >> 4);
+                    pgraph->ctx_table->instance >> 4);
 
        nv20_graph_rdi(dev);
 
@@ -616,7 +616,7 @@ nv20_graph_init(struct drm_device *dev)
        nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
 
        /* begin RAM config */
-       vramsz = drm_get_resource_len(dev, 0) - 1;
+       vramsz = pci_resource_len(dev->pdev, 0) - 1;
        nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
        nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
        nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
@@ -644,34 +644,52 @@ void
 nv20_graph_takedown(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 
-       nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table);
+       nouveau_gpuobj_ref_del(dev, &pgraph->ctx_table);
 }
 
 int
 nv30_graph_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
        int ret, i;
 
+       switch (dev_priv->chipset) {
+       case 0x30:
+       case 0x31:
+               pgraph->grctx_size = NV30_31_GRCTX_SIZE;
+               break;
+       case 0x34:
+               pgraph->grctx_size = NV34_GRCTX_SIZE;
+               break;
+       case 0x35:
+       case 0x36:
+               pgraph->grctx_size = NV35_36_GRCTX_SIZE;
+               break;
+       default:
+               NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
+               pgraph->accel_blocked = true;
+               return 0;
+       }
+
        nv_wr32(dev, NV03_PMC_ENABLE,
                nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
        nv_wr32(dev, NV03_PMC_ENABLE,
                nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
 
-       if (!dev_priv->ctx_table) {
+       if (!pgraph->ctx_table) {
                /* Create Context Pointer Table */
-               dev_priv->ctx_table_size = 32 * 4;
-               ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
-                                                 dev_priv->ctx_table_size, 16,
+               ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16,
                                                  NVOBJ_FLAG_ZERO_ALLOC,
-                                                 &dev_priv->ctx_table);
+                                                 &pgraph->ctx_table);
                if (ret)
                        return ret;
        }
 
        nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
-                       dev_priv->ctx_table->instance >> 4);
+                    pgraph->ctx_table->instance >> 4);
 
        nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
        nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
@@ -717,7 +735,7 @@ nv30_graph_init(struct drm_device *dev)
        nv_wr32(dev, 0x0040075c             , 0x00000001);
 
        /* begin RAM config */
-       /* vramsz = drm_get_resource_len(dev, 0) - 1; */
+       /* vramsz = pci_resource_len(dev->pdev, 0) - 1; */
        nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
        nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
        if (dev_priv->chipset != 0x34) {
diff --git a/drivers/gpu/drm/nouveau/nv30_fb.c b/drivers/gpu/drm/nouveau/nv30_fb.c
new file mode 100644 (file)
index 0000000..9d35c8b
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+static int
+calc_ref(int b, int l, int i)
+{
+       int j, x = 0;
+
+       for (j = 0; j < 4; j++) {
+               int n = (b >> (8 * j) & 0xf);
+               int m = (l >> (8 * i) & 0xff) + 2 * (n & 0x8 ? n - 0x10 : n);
+
+               x |= (0x80 | (m & 0x1f)) << (8 * j);
+       }
+
+       return x;
+}
+
+int
+nv30_fb_init(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
+       int i, j;
+
+       pfb->num_tiles = NV10_PFB_TILE__SIZE;
+
+       /* Turn all the tiling regions off. */
+       for (i = 0; i < pfb->num_tiles; i++)
+               pfb->set_region_tiling(dev, i, 0, 0, 0);
+
+       /* Init the memory timing regs at 0x10037c/0x1003ac */
+       if (dev_priv->chipset == 0x30 ||
+           dev_priv->chipset == 0x31 ||
+           dev_priv->chipset == 0x35) {
+               /* Related to ROP count */
+               int n = (dev_priv->chipset == 0x31 ? 2 : 4);
+               int b = (dev_priv->chipset > 0x30 ?
+                        nv_rd32(dev, 0x122c) & 0xf : 0);
+               int l = nv_rd32(dev, 0x1003d0);
+
+               for (i = 0; i < n; i++) {
+                       for (j = 0; j < 3; j++)
+                               nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j,
+                                       calc_ref(b, l, j));
+
+                       for (j = 0; j < 2; j++)
+                               nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j,
+                                       calc_ref(b, l, j));
+               }
+       }
+
+       return 0;
+}
+
+void
+nv30_fb_takedown(struct drm_device *dev)
+{
+}
index 500ccfd3a0b8c664b62cdc308ebaff0cc95d3042..2b67f1835c3942c4fddbe63b2b84a9050df81134 100644 (file)
@@ -48,7 +48,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        nv_wi32(dev, fc +  0, chan->pushbuf_base);
        nv_wi32(dev, fc +  4, chan->pushbuf_base);
        nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
@@ -61,7 +60,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
                              0x30000000 /* no idea.. */);
        nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4);
        nv_wi32(dev, fc + 60, 0x0001FFFF);
-       dev_priv->engine.instmem.finish_access(dev);
 
        /* enable the fifo dma operation */
        nv_wr32(dev, NV04_PFIFO_MODE,
@@ -89,8 +87,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t fc = NV40_RAMFC(chid), tmp, tmp2;
 
-       dev_priv->engine.instmem.prepare_access(dev, false);
-
        nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
        nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
        nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
@@ -127,8 +123,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid)
        nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76));
        nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80));
 
-       dev_priv->engine.instmem.finish_access(dev);
-
        nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
 }
@@ -166,7 +160,6 @@ nv40_fifo_unload_context(struct drm_device *dev)
                return 0;
        fc = NV40_RAMFC(chid);
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
        nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
        nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
@@ -200,7 +193,6 @@ nv40_fifo_unload_context(struct drm_device *dev)
        tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16);
        nv_wi32(dev, fc + 72, tmp);
 #endif
-       dev_priv->engine.instmem.finish_access(dev);
 
        nv40_fifo_do_load_context(dev, pfifo->channels - 1);
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
index 704a25d04ac92c75a20fe4f019a808c91ccd7304..fd7d2b5013167f58e92b0c5859fd965564f2e53d 100644 (file)
@@ -58,6 +58,7 @@ nv40_graph_create_context(struct nouveau_channel *chan)
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+       struct nouveau_grctx ctx = {};
        int ret;
 
        ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
@@ -67,20 +68,13 @@ nv40_graph_create_context(struct nouveau_channel *chan)
                return ret;
 
        /* Initialise default context values */
-       dev_priv->engine.instmem.prepare_access(dev, true);
-       if (!pgraph->ctxprog) {
-               struct nouveau_grctx ctx = {};
-
-               ctx.dev = chan->dev;
-               ctx.mode = NOUVEAU_GRCTX_VALS;
-               ctx.data = chan->ramin_grctx->gpuobj;
-               nv40_grctx_init(&ctx);
-       } else {
-               nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj);
-       }
+       ctx.dev = chan->dev;
+       ctx.mode = NOUVEAU_GRCTX_VALS;
+       ctx.data = chan->ramin_grctx->gpuobj;
+       nv40_grctx_init(&ctx);
+
        nv_wo32(dev, chan->ramin_grctx->gpuobj, 0,
                     chan->ramin_grctx->gpuobj->im_pramin->start);
-       dev_priv->engine.instmem.finish_access(dev);
        return 0;
 }
 
@@ -238,7 +232,8 @@ nv40_graph_init(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv =
                (struct drm_nouveau_private *)dev->dev_private;
        struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       uint32_t vramsz;
+       struct nouveau_grctx ctx = {};
+       uint32_t vramsz, *cp;
        int i, j;
 
        nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
@@ -246,32 +241,22 @@ nv40_graph_init(struct drm_device *dev)
        nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
                         NV_PMC_ENABLE_PGRAPH);
 
-       if (nouveau_ctxfw) {
-               nouveau_grctx_prog_load(dev);
-               dev_priv->engine.graph.grctx_size = 175 * 1024;
-       }
+       cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL);
+       if (!cp)
+               return -ENOMEM;
 
-       if (!dev_priv->engine.graph.ctxprog) {
-               struct nouveau_grctx ctx = {};
-               uint32_t *cp;
+       ctx.dev = dev;
+       ctx.mode = NOUVEAU_GRCTX_PROG;
+       ctx.data = cp;
+       ctx.ctxprog_max = 256;
+       nv40_grctx_init(&ctx);
+       dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
 
-               cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL);
-               if (!cp)
-                       return -ENOMEM;
+       nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+       for (i = 0; i < ctx.ctxprog_len; i++)
+               nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
 
-               ctx.dev = dev;
-               ctx.mode = NOUVEAU_GRCTX_PROG;
-               ctx.data = cp;
-               ctx.ctxprog_max = 256;
-               nv40_grctx_init(&ctx);
-               dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
-
-               nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
-               for (i = 0; i < ctx.ctxprog_len; i++)
-                       nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
-
-               kfree(cp);
-       }
+       kfree(cp);
 
        /* No context present currently */
        nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
@@ -367,7 +352,7 @@ nv40_graph_init(struct drm_device *dev)
                nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
 
        /* begin RAM config */
-       vramsz = drm_get_resource_len(dev, 0) - 1;
+       vramsz = pci_resource_len(dev->pdev, 0) - 1;
        switch (dev_priv->chipset) {
        case 0x40:
                nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
@@ -407,7 +392,6 @@ nv40_graph_init(struct drm_device *dev)
 
 void nv40_graph_takedown(struct drm_device *dev)
 {
-       nouveau_grctx_fini(dev);
 }
 
 struct nouveau_pgraph_object_class nv40_graph_grclass[] = {
index 2a3495e848e9b96e548339e5d41eb1fd5a7c2985..e4e72c12ab6ac3c10a73661b5be8a871101bf714 100644 (file)
@@ -19,7 +19,7 @@ nv40_mc_init(struct drm_device *dev)
        case 0x46: /* G72 */
        case 0x4e:
        case 0x4c: /* C51_G7X */
-               tmp = nv_rd32(dev, NV40_PFB_020C);
+               tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA);
                nv_wr32(dev, NV40_PMC_1700, tmp);
                nv_wr32(dev, NV40_PMC_1704, 0);
                nv_wr32(dev, NV40_PMC_1708, 0);
index b4e4a3b05eaef64151a1b8317774bd9c2863e34e..5d11ea101666dc6eb3e39bfeeaee035f44c633c0 100644 (file)
@@ -440,47 +440,15 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
 {
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct drm_device *dev = crtc->dev;
-       struct drm_encoder *encoder;
-       uint32_t dac = 0, sor = 0;
 
        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
 
-       /* Disconnect all unused encoders. */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-
-               if (!drm_helper_encoder_in_use(encoder))
-                       continue;
-
-               if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
-                   nv_encoder->dcb->type == OUTPUT_TV)
-                       dac |= (1 << nv_encoder->or);
-               else
-                       sor |= (1 << nv_encoder->or);
-       }
-
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-
-               if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
-                   nv_encoder->dcb->type == OUTPUT_TV) {
-                       if (dac & (1 << nv_encoder->or))
-                               continue;
-               } else {
-                       if (sor & (1 << nv_encoder->or))
-                               continue;
-               }
-
-               nv_encoder->disconnect(nv_encoder);
-       }
-
        nv50_crtc_blank(nv_crtc, true);
 }
 
 static void
 nv50_crtc_commit(struct drm_crtc *crtc)
 {
-       struct drm_crtc *crtc2;
        struct drm_device *dev = crtc->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *evo = dev_priv->evo;
@@ -491,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc)
 
        nv50_crtc_blank(nv_crtc, false);
 
-       /* Explicitly blank all unused crtc's. */
-       list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) {
-               if (!drm_helper_crtc_in_use(crtc2))
-                       nv50_crtc_blank(nouveau_crtc(crtc2), true);
-       }
-
        ret = RING_SPACE(evo, 2);
        if (ret) {
                NV_ERROR(dev, "no space while committing crtc\n");
                return;
        }
        BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
-       OUT_RING(evo, 0);
-       FIRE_RING(evo);
+       OUT_RING  (evo, 0);
+       FIRE_RING (evo);
 }
 
 static bool
index 1fd9537beff60c404ebded245764edb3e1845802..1bc085962945056aba2e5ea5acfc8c72a5ca5da2 100644 (file)
 #include "nv50_display.h"
 
 static void
-nv50_dac_disconnect(struct nouveau_encoder *nv_encoder)
+nv50_dac_disconnect(struct drm_encoder *encoder)
 {
-       struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
+       struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+       struct drm_device *dev = encoder->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *evo = dev_priv->evo;
        int ret;
 
+       if (!nv_encoder->crtc)
+               return;
+       nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
+
        NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
 
-       ret = RING_SPACE(evo, 2);
+       ret = RING_SPACE(evo, 4);
        if (ret) {
                NV_ERROR(dev, "no space while disconnecting DAC\n");
                return;
        }
        BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1);
-       OUT_RING(evo, 0);
+       OUT_RING  (evo, 0);
+       BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+       OUT_RING  (evo, 0);
+
+       nv_encoder->crtc = NULL;
 }
 
 static enum drm_connector_status
@@ -213,7 +222,8 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        uint32_t mode_ctl = 0, mode_ctl2 = 0;
        int ret;
 
-       NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or);
+       NV_DEBUG_KMS(dev, "or %d type %d crtc %d\n",
+                    nv_encoder->or, nv_encoder->dcb->type, crtc->index);
 
        nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON);
 
@@ -243,6 +253,14 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2);
        OUT_RING(evo, mode_ctl);
        OUT_RING(evo, mode_ctl2);
+
+       nv_encoder->crtc = encoder->crtc;
+}
+
+static struct drm_crtc *
+nv50_dac_crtc_get(struct drm_encoder *encoder)
+{
+       return nouveau_encoder(encoder)->crtc;
 }
 
 static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
@@ -253,7 +271,9 @@ static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
        .prepare = nv50_dac_prepare,
        .commit = nv50_dac_commit,
        .mode_set = nv50_dac_mode_set,
-       .detect = nv50_dac_detect
+       .get_crtc = nv50_dac_crtc_get,
+       .detect = nv50_dac_detect,
+       .disable = nv50_dac_disconnect
 };
 
 static void
@@ -275,14 +295,11 @@ static const struct drm_encoder_funcs nv50_dac_encoder_funcs = {
 };
 
 int
-nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        struct nouveau_encoder *nv_encoder;
        struct drm_encoder *encoder;
 
-       NV_DEBUG_KMS(dev, "\n");
-       NV_INFO(dev, "Detected a DAC output\n");
-
        nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
        if (!nv_encoder)
                return -ENOMEM;
@@ -291,14 +308,14 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
        nv_encoder->dcb = entry;
        nv_encoder->or = ffs(entry->or) - 1;
 
-       nv_encoder->disconnect = nv50_dac_disconnect;
-
-       drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs,
+       drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs,
                         DRM_MODE_ENCODER_DAC);
        drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs);
 
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
+
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
 
index 580a5d10be9322cb581fc357a3b5215e7a3fcf10..f13ad0de9c8ff8a4b1d55e0d4329c7e6b1c9e997 100644 (file)
@@ -71,14 +71,13 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name,
                return ret;
        }
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class);
        nv_wo32(dev, obj, 1, limit);
        nv_wo32(dev, obj, 2, offset);
        nv_wo32(dev, obj, 3, 0x00000000);
        nv_wo32(dev, obj, 4, 0x00000000);
        nv_wo32(dev, obj, 5, 0x00010000);
-       dev_priv->engine.instmem.finish_access(dev);
+       dev_priv->engine.instmem.flush(dev);
 
        return 0;
 }
@@ -110,8 +109,8 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
                return ret;
        }
 
-       ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj->
-                                   im_pramin->start, 32768);
+       ret = drm_mm_init(&chan->ramin_heap,
+                         chan->ramin->gpuobj->im_pramin->start, 32768);
        if (ret) {
                NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
                nv50_evo_channel_del(pchan);
@@ -178,14 +177,26 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
        return 0;
 }
 
+int
+nv50_display_early_init(struct drm_device *dev)
+{
+       return 0;
+}
+
+void
+nv50_display_late_takedown(struct drm_device *dev)
+{
+}
+
 int
 nv50_display_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+       struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
        struct nouveau_channel *evo = dev_priv->evo;
        struct drm_connector *connector;
-       uint32_t val, ram_amount, hpd_en[2];
+       uint32_t val, ram_amount;
        uint64_t start;
        int ret, i;
 
@@ -366,26 +377,13 @@ nv50_display_init(struct drm_device *dev)
                                             NV50_PDISPLAY_INTR_EN_CLK_UNK40));
 
        /* enable hotplug interrupts */
-       hpd_en[0] = hpd_en[1] = 0;
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                struct nouveau_connector *conn = nouveau_connector(connector);
-               struct dcb_gpio_entry *gpio;
 
                if (conn->dcb->gpio_tag == 0xff)
                        continue;
 
-               gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
-               if (!gpio)
-                       continue;
-
-               hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf));
-       }
-
-       nv_wr32(dev, 0xe054, 0xffffffff);
-       nv_wr32(dev, 0xe050, hpd_en[0]);
-       if (dev_priv->chipset >= 0x90) {
-               nv_wr32(dev, 0xe074, 0xffffffff);
-               nv_wr32(dev, 0xe070, hpd_en[1]);
+               pgpio->irq_enable(dev, conn->dcb->gpio_tag, true);
        }
 
        return 0;
@@ -465,6 +463,7 @@ int nv50_display_create(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct dcb_table *dcb = &dev_priv->vbios.dcb;
+       struct drm_connector *connector, *ct;
        int ret, i;
 
        NV_DEBUG_KMS(dev, "\n");
@@ -507,14 +506,18 @@ int nv50_display_create(struct drm_device *dev)
                        continue;
                }
 
+               connector = nouveau_connector_create(dev, entry->connector);
+               if (IS_ERR(connector))
+                       continue;
+
                switch (entry->type) {
                case OUTPUT_TMDS:
                case OUTPUT_LVDS:
                case OUTPUT_DP:
-                       nv50_sor_create(dev, entry);
+                       nv50_sor_create(connector, entry);
                        break;
                case OUTPUT_ANALOG:
-                       nv50_dac_create(dev, entry);
+                       nv50_dac_create(connector, entry);
                        break;
                default:
                        NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
@@ -522,11 +525,13 @@ int nv50_display_create(struct drm_device *dev)
                }
        }
 
-       for (i = 0 ; i < dcb->connector.entries; i++) {
-               if (i != 0 && dcb->connector.entry[i].index2 ==
-                             dcb->connector.entry[i - 1].index2)
-                       continue;
-               nouveau_connector_create(dev, &dcb->connector.entry[i]);
+       list_for_each_entry_safe(connector, ct,
+                                &dev->mode_config.connector_list, head) {
+               if (!connector->encoder_ids[0]) {
+                       NV_WARN(dev, "%s has no encoders, removing\n",
+                               drm_get_connector_name(connector));
+                       connector->funcs->destroy(connector);
+               }
        }
 
        ret = nv50_display_init(dev);
@@ -538,7 +543,8 @@ int nv50_display_create(struct drm_device *dev)
        return 0;
 }
 
-int nv50_display_destroy(struct drm_device *dev)
+void
+nv50_display_destroy(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
 
@@ -548,135 +554,30 @@ int nv50_display_destroy(struct drm_device *dev)
 
        nv50_display_disable(dev);
        nv50_evo_channel_del(&dev_priv->evo);
-
-       return 0;
-}
-
-static inline uint32_t
-nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       uint32_t mc;
-
-       if (sor) {
-               if (dev_priv->chipset < 0x90 ||
-                   dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
-                       mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or));
-               else
-                       mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or));
-       } else {
-               mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or));
-       }
-
-       return mc;
-}
-
-static int
-nv50_display_irq_head(struct drm_device *dev, int *phead,
-                     struct dcb_entry **pdcbent)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL);
-       uint32_t dac = 0, sor = 0;
-       int head, i, or = 0, type = OUTPUT_ANY;
-
-       /* We're assuming that head 0 *or* head 1 will be active here,
-        * and not both.  I'm not sure if the hw will even signal both
-        * ever, but it definitely shouldn't for us as we commit each
-        * CRTC separately, and submission will be blocked by the GPU
-        * until we handle each in turn.
-        */
-       NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
-       head = ffs((unk30 >> 9) & 3) - 1;
-       if (head < 0)
-               return -EINVAL;
-
-       /* This assumes CRTCs are never bound to multiple encoders, which
-        * should be the case.
-        */
-       for (i = 0; i < 3 && type == OUTPUT_ANY; i++) {
-               uint32_t mc = nv50_display_mode_ctrl(dev, false, i);
-               if (!(mc & (1 << head)))
-                       continue;
-
-               switch ((mc >> 8) & 0xf) {
-               case 0: type = OUTPUT_ANALOG; break;
-               case 1: type = OUTPUT_TV; break;
-               default:
-                       NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac);
-                       return -1;
-               }
-
-               or = i;
-       }
-
-       for (i = 0; i < 4 && type == OUTPUT_ANY; i++) {
-               uint32_t mc = nv50_display_mode_ctrl(dev, true, i);
-               if (!(mc & (1 << head)))
-                       continue;
-
-               switch ((mc >> 8) & 0xf) {
-               case 0: type = OUTPUT_LVDS; break;
-               case 1: type = OUTPUT_TMDS; break;
-               case 2: type = OUTPUT_TMDS; break;
-               case 5: type = OUTPUT_TMDS; break;
-               case 8: type = OUTPUT_DP; break;
-               case 9: type = OUTPUT_DP; break;
-               default:
-                       NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor);
-                       return -1;
-               }
-
-               or = i;
-       }
-
-       NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or);
-       if (type == OUTPUT_ANY) {
-               NV_ERROR(dev, "unknown encoder!!\n");
-               return -1;
-       }
-
-       for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
-               struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i];
-
-               if (dcbent->type != type)
-                       continue;
-
-               if (!(dcbent->or & (1 << or)))
-                       continue;
-
-               *phead = head;
-               *pdcbent = dcbent;
-               return 0;
-       }
-
-       NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or);
-       return 0;
 }
 
-static uint32_t
-nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent,
-                          int pxclk)
+static u16
+nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
+                          u32 mc, int pxclk)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_connector *nv_connector = NULL;
        struct drm_encoder *encoder;
        struct nvbios *bios = &dev_priv->vbios;
-       uint32_t mc, script = 0, or;
+       u32 script = 0, or;
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
 
-               if (nv_encoder->dcb != dcbent)
+               if (nv_encoder->dcb != dcb)
                        continue;
 
                nv_connector = nouveau_encoder_connector_get(nv_encoder);
                break;
        }
 
-       or = ffs(dcbent->or) - 1;
-       mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or);
-       switch (dcbent->type) {
+       or = ffs(dcb->or) - 1;
+       switch (dcb->type) {
        case OUTPUT_LVDS:
                script = (mc >> 8) & 0xf;
                if (bios->fp_no_ddc) {
@@ -767,17 +668,88 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
 static void
 nv50_display_unk10_handler(struct drm_device *dev)
 {
-       struct dcb_entry *dcbent;
-       int head, ret;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       u32 unk30 = nv_rd32(dev, 0x610030), mc;
+       int i, crtc, or, type = OUTPUT_ANY;
 
-       ret = nv50_display_irq_head(dev, &head, &dcbent);
-       if (ret)
-               goto ack;
+       NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
+       dev_priv->evo_irq.dcb = NULL;
 
        nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8);
 
-       nouveau_bios_run_display_table(dev, dcbent, 0, -1);
+       /* Determine which CRTC we're dealing with, only 1 ever will be
+        * signalled at the same time with the current nouveau code.
+        */
+       crtc = ffs((unk30 & 0x00000060) >> 5) - 1;
+       if (crtc < 0)
+               goto ack;
+
+       /* Nothing needs to be done for the encoder */
+       crtc = ffs((unk30 & 0x00000180) >> 7) - 1;
+       if (crtc < 0)
+               goto ack;
 
+       /* Find which encoder was connected to the CRTC */
+       for (i = 0; type == OUTPUT_ANY && i < 3; i++) {
+               mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
+               NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc);
+               if (!(mc & (1 << crtc)))
+                       continue;
+
+               switch ((mc & 0x00000f00) >> 8) {
+               case 0: type = OUTPUT_ANALOG; break;
+               case 1: type = OUTPUT_TV; break;
+               default:
+                       NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
+                       goto ack;
+               }
+
+               or = i;
+       }
+
+       for (i = 0; type == OUTPUT_ANY && i < 4; i++) {
+               if (dev_priv->chipset  < 0x90 ||
+                   dev_priv->chipset == 0x92 ||
+                   dev_priv->chipset == 0xa0)
+                       mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
+               else
+                       mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
+
+               NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc);
+               if (!(mc & (1 << crtc)))
+                       continue;
+
+               switch ((mc & 0x00000f00) >> 8) {
+               case 0: type = OUTPUT_LVDS; break;
+               case 1: type = OUTPUT_TMDS; break;
+               case 2: type = OUTPUT_TMDS; break;
+               case 5: type = OUTPUT_TMDS; break;
+               case 8: type = OUTPUT_DP; break;
+               case 9: type = OUTPUT_DP; break;
+               default:
+                       NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
+                       goto ack;
+               }
+
+               or = i;
+       }
+
+       /* There was no encoder to disable */
+       if (type == OUTPUT_ANY)
+               goto ack;
+
+       /* Disable the encoder */
+       for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
+               struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i];
+
+               if (dcb->type == type && (dcb->or & (1 << or))) {
+                       nouveau_bios_run_display_table(dev, dcb, 0, -1);
+                       dev_priv->evo_irq.dcb = dcb;
+                       goto ack;
+               }
+       }
+
+       NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc);
 ack:
        nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10);
        nv_wr32(dev, 0x610030, 0x80000000);
@@ -817,33 +789,103 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb)
 static void
 nv50_display_unk20_handler(struct drm_device *dev)
 {
-       struct dcb_entry *dcbent;
-       uint32_t tmp, pclk, script;
-       int head, or, ret;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc;
+       struct dcb_entry *dcb;
+       int i, crtc, or, type = OUTPUT_ANY;
 
-       ret = nv50_display_irq_head(dev, &head, &dcbent);
-       if (ret)
+       NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
+       dcb = dev_priv->evo_irq.dcb;
+       if (dcb) {
+               nouveau_bios_run_display_table(dev, dcb, 0, -2);
+               dev_priv->evo_irq.dcb = NULL;
+       }
+
+       /* CRTC clock change requested? */
+       crtc = ffs((unk30 & 0x00000600) >> 9) - 1;
+       if (crtc >= 0) {
+               pclk  = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK));
+               pclk &= 0x003fffff;
+
+               nv50_crtc_set_clock(dev, crtc, pclk);
+
+               tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc));
+               tmp &= ~0x000000f;
+               nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp);
+       }
+
+       /* Nothing needs to be done for the encoder */
+       crtc = ffs((unk30 & 0x00000180) >> 7) - 1;
+       if (crtc < 0)
                goto ack;
-       or = ffs(dcbent->or) - 1;
-       pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
-       script = nv50_display_script_select(dev, dcbent, pclk);
+       pclk  = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff;
 
-       NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk);
+       /* Find which encoder is connected to the CRTC */
+       for (i = 0; type == OUTPUT_ANY && i < 3; i++) {
+               mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i));
+               NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc);
+               if (!(mc & (1 << crtc)))
+                       continue;
 
-       if (dcbent->type != OUTPUT_DP)
-               nouveau_bios_run_display_table(dev, dcbent, 0, -2);
+               switch ((mc & 0x00000f00) >> 8) {
+               case 0: type = OUTPUT_ANALOG; break;
+               case 1: type = OUTPUT_TV; break;
+               default:
+                       NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
+                       goto ack;
+               }
 
-       nv50_crtc_set_clock(dev, head, pclk);
+               or = i;
+       }
 
-       nouveau_bios_run_display_table(dev, dcbent, script, pclk);
+       for (i = 0; type == OUTPUT_ANY && i < 4; i++) {
+               if (dev_priv->chipset  < 0x90 ||
+                   dev_priv->chipset == 0x92 ||
+                   dev_priv->chipset == 0xa0)
+                       mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i));
+               else
+                       mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i));
 
-       nv50_display_unk20_dp_hack(dev, dcbent);
+               NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc);
+               if (!(mc & (1 << crtc)))
+                       continue;
+
+               switch ((mc & 0x00000f00) >> 8) {
+               case 0: type = OUTPUT_LVDS; break;
+               case 1: type = OUTPUT_TMDS; break;
+               case 2: type = OUTPUT_TMDS; break;
+               case 5: type = OUTPUT_TMDS; break;
+               case 8: type = OUTPUT_DP; break;
+               case 9: type = OUTPUT_DP; break;
+               default:
+                       NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
+                       goto ack;
+               }
+
+               or = i;
+       }
+
+       if (type == OUTPUT_ANY)
+               goto ack;
+
+       /* Enable the encoder */
+       for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
+               dcb = &dev_priv->vbios.dcb.entry[i];
+               if (dcb->type == type && (dcb->or & (1 << or)))
+                       break;
+       }
+
+       if (i == dev_priv->vbios.dcb.entries) {
+               NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc);
+               goto ack;
+       }
 
-       tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head));
-       tmp &= ~0x000000f;
-       nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp);
+       script = nv50_display_script_select(dev, dcb, mc, pclk);
+       nouveau_bios_run_display_table(dev, dcb, script, pclk);
 
-       if (dcbent->type != OUTPUT_ANALOG) {
+       nv50_display_unk20_dp_hack(dev, dcb);
+
+       if (dcb->type != OUTPUT_ANALOG) {
                tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
                tmp &= ~0x00000f0f;
                if (script & 0x0100)
@@ -853,24 +895,61 @@ nv50_display_unk20_handler(struct drm_device *dev)
                nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
        }
 
+       dev_priv->evo_irq.dcb = dcb;
+       dev_priv->evo_irq.pclk = pclk;
+       dev_priv->evo_irq.script = script;
+
 ack:
        nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
        nv_wr32(dev, 0x610030, 0x80000000);
 }
 
+/* If programming a TMDS output on a SOR that can also be configured for
+ * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
+ *
+ * It looks like the VBIOS TMDS scripts make an attempt at this, however,
+ * the VBIOS scripts on at least one board I have only switch it off on
+ * link 0, causing a blank display if the output has previously been
+ * programmed for DisplayPort.
+ */
+static void
+nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb)
+{
+       int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1);
+       struct drm_encoder *encoder;
+       u32 tmp;
+
+       if (dcb->type != OUTPUT_TMDS)
+               return;
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+               if (nv_encoder->dcb->type == OUTPUT_DP &&
+                   nv_encoder->dcb->or & (1 << or)) {
+                       tmp  = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
+                       tmp &= ~NV50_SOR_DP_CTRL_ENABLED;
+                       nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
+                       break;
+               }
+       }
+}
+
 static void
 nv50_display_unk40_handler(struct drm_device *dev)
 {
-       struct dcb_entry *dcbent;
-       int head, pclk, script, ret;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct dcb_entry *dcb = dev_priv->evo_irq.dcb;
+       u16 script = dev_priv->evo_irq.script;
+       u32 unk30 = nv_rd32(dev, 0x610030), pclk = dev_priv->evo_irq.pclk;
 
-       ret = nv50_display_irq_head(dev, &head, &dcbent);
-       if (ret)
+       NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
+       dev_priv->evo_irq.dcb = NULL;
+       if (!dcb)
                goto ack;
-       pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
-       script = nv50_display_script_select(dev, dcbent, pclk);
 
-       nouveau_bios_run_display_table(dev, dcbent, script, -pclk);
+       nouveau_bios_run_display_table(dev, dcb, script, -pclk);
+       nv50_display_unk40_dp_set_tmds(dev, dcb);
 
 ack:
        nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
index 581d405ac014606041e253c7830c137569e63af6..c551f0b85ee02124bdf66b9e28fc0574f7e3caa8 100644 (file)
 void nv50_display_irq_handler(struct drm_device *dev);
 void nv50_display_irq_handler_bh(struct work_struct *work);
 void nv50_display_irq_hotplug_bh(struct work_struct *work);
-int nv50_display_init(struct drm_device *dev);
+int nv50_display_early_init(struct drm_device *dev);
+void nv50_display_late_takedown(struct drm_device *dev);
 int nv50_display_create(struct drm_device *dev);
-int nv50_display_destroy(struct drm_device *dev);
+int nv50_display_init(struct drm_device *dev);
+void nv50_display_destroy(struct drm_device *dev);
 int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
 int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
 
index e20c0e2474f3b56035b3c6391b86a17e4c693f0f..fb0281ae8f90569508711a5edd275cea064da6df 100644 (file)
 #include "drm.h"
 #include "nouveau_drv.h"
 
-struct nv50_fifo_priv {
-       struct nouveau_gpuobj_ref *thingo[2];
-       int cur_thingo;
-};
-
-#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
-
 static void
-nv50_fifo_init_thingo(struct drm_device *dev)
+nv50_fifo_playlist_update(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
+       struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
        struct nouveau_gpuobj_ref *cur;
        int i, nr;
 
        NV_DEBUG(dev, "\n");
 
-       cur = priv->thingo[priv->cur_thingo];
-       priv->cur_thingo = !priv->cur_thingo;
+       cur = pfifo->playlist[pfifo->cur_playlist];
+       pfifo->cur_playlist = !pfifo->cur_playlist;
 
        /* We never schedule channel 0 or 127 */
-       dev_priv->engine.instmem.prepare_access(dev, true);
        for (i = 1, nr = 0; i < 127; i++) {
                if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc)
                        nv_wo32(dev, cur->gpuobj, nr++, i);
        }
-       dev_priv->engine.instmem.finish_access(dev);
+       dev_priv->engine.instmem.flush(dev);
 
        nv_wr32(dev, 0x32f4, cur->instance >> 12);
        nv_wr32(dev, 0x32ec, nr);
        nv_wr32(dev, 0x2500, 0x101);
 }
 
-static int
-nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt)
+static void
+nv50_fifo_channel_enable(struct drm_device *dev, int channel)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *chan = dev_priv->fifos[channel];
@@ -70,37 +62,28 @@ nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt)
 
        NV_DEBUG(dev, "ch%d\n", channel);
 
-       if (!chan->ramfc)
-               return -EINVAL;
-
-       if (IS_G80)
+       if (dev_priv->chipset == 0x50)
                inst = chan->ramfc->instance >> 12;
        else
                inst = chan->ramfc->instance >> 8;
-       nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel),
-                inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
 
-       if (!nt)
-               nv50_fifo_init_thingo(dev);
-       return 0;
+       nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst |
+                    NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
 }
 
 static void
-nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt)
+nv50_fifo_channel_disable(struct drm_device *dev, int channel)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t inst;
 
-       NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt);
+       NV_DEBUG(dev, "ch%d\n", channel);
 
-       if (IS_G80)
+       if (dev_priv->chipset == 0x50)
                inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80;
        else
                inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84;
        nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst);
-
-       if (!nt)
-               nv50_fifo_init_thingo(dev);
 }
 
 static void
@@ -133,12 +116,12 @@ nv50_fifo_init_context_table(struct drm_device *dev)
 
        for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) {
                if (dev_priv->fifos[i])
-                       nv50_fifo_channel_enable(dev, i, true);
+                       nv50_fifo_channel_enable(dev, i);
                else
-                       nv50_fifo_channel_disable(dev, i, true);
+                       nv50_fifo_channel_disable(dev, i);
        }
 
-       nv50_fifo_init_thingo(dev);
+       nv50_fifo_playlist_update(dev);
 }
 
 static void
@@ -162,41 +145,38 @@ nv50_fifo_init_regs(struct drm_device *dev)
        nv_wr32(dev, 0x3270, 0);
 
        /* Enable dummy channels setup by nv50_instmem.c */
-       nv50_fifo_channel_enable(dev, 0, true);
-       nv50_fifo_channel_enable(dev, 127, true);
+       nv50_fifo_channel_enable(dev, 0);
+       nv50_fifo_channel_enable(dev, 127);
 }
 
 int
 nv50_fifo_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nv50_fifo_priv *priv;
+       struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
        int ret;
 
        NV_DEBUG(dev, "\n");
 
-       priv = dev_priv->engine.fifo.priv;
-       if (priv) {
-               priv->cur_thingo = !priv->cur_thingo;
+       if (pfifo->playlist[0]) {
+               pfifo->cur_playlist = !pfifo->cur_playlist;
                goto just_reset;
        }
 
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-       dev_priv->engine.fifo.priv = priv;
-
        ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
-                                    NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]);
+                                    NVOBJ_FLAG_ZERO_ALLOC,
+                                    &pfifo->playlist[0]);
        if (ret) {
-               NV_ERROR(dev, "error creating thingo0: %d\n", ret);
+               NV_ERROR(dev, "error creating playlist 0: %d\n", ret);
                return ret;
        }
 
        ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
-                                    NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]);
+                                    NVOBJ_FLAG_ZERO_ALLOC,
+                                    &pfifo->playlist[1]);
        if (ret) {
-               NV_ERROR(dev, "error creating thingo1: %d\n", ret);
+               nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]);
+               NV_ERROR(dev, "error creating playlist 1: %d\n", ret);
                return ret;
        }
 
@@ -216,18 +196,15 @@ void
 nv50_fifo_takedown(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
+       struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
 
        NV_DEBUG(dev, "\n");
 
-       if (!priv)
+       if (!pfifo->playlist[0])
                return;
 
-       nouveau_gpuobj_ref_del(dev, &priv->thingo[0]);
-       nouveau_gpuobj_ref_del(dev, &priv->thingo[1]);
-
-       dev_priv->engine.fifo.priv = NULL;
-       kfree(priv);
+       nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]);
+       nouveau_gpuobj_ref_del(dev, &pfifo->playlist[1]);
 }
 
 int
@@ -248,7 +225,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
 
        NV_DEBUG(dev, "ch%d\n", chan->id);
 
-       if (IS_G80) {
+       if (dev_priv->chipset == 0x50) {
                uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start;
                uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start;
 
@@ -281,10 +258,10 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
-
        nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4);
-       nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4));
+       nv_wo32(dev, ramfc, 0x80/4, (0 << 27) /* 4KiB */ |
+                                   (4 << 24) /* SEARCH_FULL */ |
+                                   (chan->ramht->instance >> 4));
        nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff);
        nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff);
        nv_wo32(dev, ramfc, 0x40/4, 0x00000000);
@@ -295,7 +272,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
                                    chan->dma.ib_base * 4);
        nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16);
 
-       if (!IS_G80) {
+       if (dev_priv->chipset != 0x50) {
                nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id);
                nv_wo32(dev, chan->ramin->gpuobj, 1,
                                                chan->ramfc->instance >> 8);
@@ -304,16 +281,10 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
                nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12);
        }
 
-       dev_priv->engine.instmem.finish_access(dev);
-
-       ret = nv50_fifo_channel_enable(dev, chan->id, false);
-       if (ret) {
-               NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret);
-               spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-               nouveau_gpuobj_ref_del(dev, &chan->ramfc);
-               return ret;
-       }
+       dev_priv->engine.instmem.flush(dev);
 
+       nv50_fifo_channel_enable(dev, chan->id);
+       nv50_fifo_playlist_update(dev);
        spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
        return 0;
 }
@@ -328,11 +299,12 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan)
 
        /* This will ensure the channel is seen as disabled. */
        chan->ramfc = NULL;
-       nv50_fifo_channel_disable(dev, chan->id, false);
+       nv50_fifo_channel_disable(dev, chan->id);
 
        /* Dummy channel, also used on ch 127 */
        if (chan->id == 0)
-               nv50_fifo_channel_disable(dev, 127, false);
+               nv50_fifo_channel_disable(dev, 127);
+       nv50_fifo_playlist_update(dev);
 
        nouveau_gpuobj_ref_del(dev, &ramfc);
        nouveau_gpuobj_ref_del(dev, &chan->cache);
@@ -349,8 +321,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
 
        NV_DEBUG(dev, "ch%d\n", chan->id);
 
-       dev_priv->engine.instmem.prepare_access(dev, false);
-
        nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4));
        nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4));
        nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4));
@@ -396,7 +366,7 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
        nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
 
        /* guessing that all the 0x34xx regs aren't on NV50 */
-       if (!IS_G80) {
+       if (dev_priv->chipset != 0x50) {
                nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4));
                nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4));
                nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4));
@@ -404,8 +374,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
                nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4));
        }
 
-       dev_priv->engine.instmem.finish_access(dev);
-
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16));
        return 0;
 }
@@ -434,8 +402,6 @@ nv50_fifo_unload_context(struct drm_device *dev)
        ramfc = chan->ramfc->gpuobj;
        cache = chan->cache->gpuobj;
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
-
        nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330));
        nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334));
        nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240));
@@ -482,7 +448,7 @@ nv50_fifo_unload_context(struct drm_device *dev)
        }
 
        /* guessing that all the 0x34xx regs aren't on NV50 */
-       if (!IS_G80) {
+       if (dev_priv->chipset != 0x50) {
                nv_wo32(dev, ramfc, 0x84/4, ptr >> 1);
                nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c));
                nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400));
@@ -491,7 +457,7 @@ nv50_fifo_unload_context(struct drm_device *dev)
                nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410));
        }
 
-       dev_priv->engine.instmem.finish_access(dev);
+       dev_priv->engine.instmem.flush(dev);
 
        /*XXX: probably reload ch127 (NULL) state back too */
        nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127);
index bb47ad737267a07ecfdc1071a6ebf7f2fdb6f9ec..b2fab2bf3d6116f881d4900e30da61a4fd72dc93 100644 (file)
@@ -74,3 +74,38 @@ nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
        nv_wr32(dev, r, v);
        return 0;
 }
+
+void
+nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on)
+{
+       struct dcb_gpio_entry *gpio;
+       u32 reg, mask;
+
+       gpio = nouveau_bios_gpio_entry(dev, tag);
+       if (!gpio) {
+               NV_ERROR(dev, "gpio tag 0x%02x not found\n", tag);
+               return;
+       }
+
+       reg  = gpio->line < 16 ? 0xe050 : 0xe070;
+       mask = 0x00010001 << (gpio->line & 0xf);
+
+       nv_wr32(dev, reg + 4, mask);
+       nv_mask(dev, reg + 0, mask, on ? mask : 0);
+}
+
+int
+nv50_gpio_init(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       /* disable, and ack any pending gpio interrupts */
+       nv_wr32(dev, 0xe050, 0x00000000);
+       nv_wr32(dev, 0xe054, 0xffffffff);
+       if (dev_priv->chipset >= 0x90) {
+               nv_wr32(dev, 0xe070, 0x00000000);
+               nv_wr32(dev, 0xe074, 0xffffffff);
+       }
+
+       return 0;
+}
index b203d06f601f4ad9e314d4eadd21a25813cf8bce..1413028e15808b8f9ea476bd7e0d81f948801b40 100644 (file)
@@ -30,8 +30,6 @@
 
 #include "nouveau_grctx.h"
 
-#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
-
 static void
 nv50_graph_init_reset(struct drm_device *dev)
 {
@@ -103,37 +101,33 @@ static int
 nv50_graph_init_ctxctl(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_grctx ctx = {};
+       uint32_t *cp;
+       int i;
 
        NV_DEBUG(dev, "\n");
 
-       if (nouveau_ctxfw) {
-               nouveau_grctx_prog_load(dev);
-               dev_priv->engine.graph.grctx_size = 0x70000;
+       cp = kmalloc(512 * 4, GFP_KERNEL);
+       if (!cp) {
+               NV_ERROR(dev, "failed to allocate ctxprog\n");
+               dev_priv->engine.graph.accel_blocked = true;
+               return 0;
        }
-       if (!dev_priv->engine.graph.ctxprog) {
-               struct nouveau_grctx ctx = {};
-               uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL);
-               int i;
-               if (!cp) {
-                       NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n");
-                       dev_priv->engine.graph.accel_blocked = true;
-                       return 0;
-               }
-               ctx.dev = dev;
-               ctx.mode = NOUVEAU_GRCTX_PROG;
-               ctx.data = cp;
-               ctx.ctxprog_max = 512;
-               if (!nv50_grctx_init(&ctx)) {
-                       dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
-
-                       nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
-                       for (i = 0; i < ctx.ctxprog_len; i++)
-                               nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
-               } else {
-                       dev_priv->engine.graph.accel_blocked = true;
-               }
-               kfree(cp);
+
+       ctx.dev = dev;
+       ctx.mode = NOUVEAU_GRCTX_PROG;
+       ctx.data = cp;
+       ctx.ctxprog_max = 512;
+       if (!nv50_grctx_init(&ctx)) {
+               dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
+
+               nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+               for (i = 0; i < ctx.ctxprog_len; i++)
+                       nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
+       } else {
+               dev_priv->engine.graph.accel_blocked = true;
        }
+       kfree(cp);
 
        nv_wr32(dev, 0x400320, 4);
        nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
@@ -164,7 +158,6 @@ void
 nv50_graph_takedown(struct drm_device *dev)
 {
        NV_DEBUG(dev, "\n");
-       nouveau_grctx_fini(dev);
 }
 
 void
@@ -212,8 +205,9 @@ nv50_graph_create_context(struct nouveau_channel *chan)
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
-       struct nouveau_gpuobj *ctx;
+       struct nouveau_gpuobj *obj;
        struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+       struct nouveau_grctx ctx = {};
        int hdr, ret;
 
        NV_DEBUG(dev, "ch%d\n", chan->id);
@@ -223,10 +217,9 @@ nv50_graph_create_context(struct nouveau_channel *chan)
                                     NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
        if (ret)
                return ret;
-       ctx = chan->ramin_grctx->gpuobj;
+       obj = chan->ramin_grctx->gpuobj;
 
-       hdr = IS_G80 ? 0x200 : 0x20;
-       dev_priv->engine.instmem.prepare_access(dev, true);
+       hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
        nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002);
        nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
                                           pgraph->grctx_size - 1);
@@ -234,21 +227,15 @@ nv50_graph_create_context(struct nouveau_channel *chan)
        nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0);
        nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
        nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000);
-       dev_priv->engine.instmem.finish_access(dev);
-
-       dev_priv->engine.instmem.prepare_access(dev, true);
-       if (!pgraph->ctxprog) {
-               struct nouveau_grctx ctx = {};
-               ctx.dev = chan->dev;
-               ctx.mode = NOUVEAU_GRCTX_VALS;
-               ctx.data = chan->ramin_grctx->gpuobj;
-               nv50_grctx_init(&ctx);
-       } else {
-               nouveau_grctx_vals_load(dev, ctx);
-       }
-       nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
-       dev_priv->engine.instmem.finish_access(dev);
 
+       ctx.dev = chan->dev;
+       ctx.mode = NOUVEAU_GRCTX_VALS;
+       ctx.data = obj;
+       nv50_grctx_init(&ctx);
+
+       nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12);
+
+       dev_priv->engine.instmem.flush(dev);
        return 0;
 }
 
@@ -257,17 +244,16 @@ nv50_graph_destroy_context(struct nouveau_channel *chan)
 {
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       int i, hdr = IS_G80 ? 0x200 : 0x20;
+       int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
 
        NV_DEBUG(dev, "ch%d\n", chan->id);
 
        if (!chan->ramin || !chan->ramin->gpuobj)
                return;
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        for (i = hdr; i < hdr + 24; i += 4)
                nv_wo32(dev, chan->ramin->gpuobj, i/4, 0);
-       dev_priv->engine.instmem.finish_access(dev);
+       dev_priv->engine.instmem.flush(dev);
 
        nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
 }
index 5f21df31f3aa7f69beac46ff65dc11885a5f02bd..37c7b48ab24af8a37c3e8ac29656b989ec5935f5 100644 (file)
@@ -35,8 +35,6 @@ struct nv50_instmem_priv {
        struct nouveau_gpuobj_ref *pramin_pt;
        struct nouveau_gpuobj_ref *pramin_bar;
        struct nouveau_gpuobj_ref *fb_bar;
-
-       bool last_access_wr;
 };
 
 #define NV50_INSTMEM_PAGE_SHIFT 12
@@ -147,7 +145,7 @@ nv50_instmem_init(struct drm_device *dev)
        if (ret)
                return ret;
 
-       if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base))
+       if (drm_mm_init(&chan->ramin_heap, c_base, c_size - c_base))
                return -ENOMEM;
 
        /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */
@@ -241,7 +239,7 @@ nv50_instmem_init(struct drm_device *dev)
                return ret;
        BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 +
-                                             drm_get_resource_len(dev, 1) - 1);
+                                             pci_resource_len(dev->pdev, 1) - 1);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000);
@@ -262,23 +260,18 @@ nv50_instmem_init(struct drm_device *dev)
 
        /* Assume that praying isn't enough, check that we can re-read the
         * entire fake channel back from the PRAMIN BAR */
-       dev_priv->engine.instmem.prepare_access(dev, false);
        for (i = 0; i < c_size; i += 4) {
                if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) {
                        NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n",
                                                                        i);
-                       dev_priv->engine.instmem.finish_access(dev);
                        return -EINVAL;
                }
        }
-       dev_priv->engine.instmem.finish_access(dev);
 
        nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700);
 
        /* Global PRAMIN heap */
-       if (nouveau_mem_init_heap(&dev_priv->ramin_heap,
-                                 c_size, dev_priv->ramin_size - c_size)) {
-               dev_priv->ramin_heap = NULL;
+       if (drm_mm_init(&dev_priv->ramin_heap, c_size, dev_priv->ramin_size - c_size)) {
                NV_ERROR(dev, "Failed to init RAMIN heap\n");
        }
 
@@ -321,7 +314,7 @@ nv50_instmem_takedown(struct drm_device *dev)
                nouveau_gpuobj_del(dev, &chan->vm_pd);
                nouveau_gpuobj_ref_del(dev, &chan->ramfc);
                nouveau_gpuobj_ref_del(dev, &chan->ramin);
-               nouveau_mem_takedown(&chan->ramin_heap);
+               drm_mm_takedown(&chan->ramin_heap);
 
                dev_priv->fifos[0] = dev_priv->fifos[127] = NULL;
                kfree(chan);
@@ -436,14 +429,14 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
        if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
                return -EINVAL;
 
-       NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n",
+       NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n",
                 gpuobj->im_pramin->start, gpuobj->im_pramin->size);
 
        pte     = (gpuobj->im_pramin->start >> 12) << 1;
        pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
        vram    = gpuobj->im_backing_start;
 
-       NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n",
+       NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n",
                 gpuobj->im_pramin->start, pte, pte_end);
        NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start);
 
@@ -453,27 +446,15 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
                vram |= 0x30;
        }
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        while (pte < pte_end) {
                nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram));
                nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram));
                vram += NV50_INSTMEM_PAGE_SIZE;
        }
-       dev_priv->engine.instmem.finish_access(dev);
-
-       nv_wr32(dev, 0x100c80, 0x00040001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return -EBUSY;
-       }
+       dev_priv->engine.instmem.flush(dev);
 
-       nv_wr32(dev, 0x100c80, 0x00060001);
-       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
-               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
-               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
-               return -EBUSY;
-       }
+       nv50_vm_flush(dev, 4);
+       nv50_vm_flush(dev, 6);
 
        gpuobj->im_bound = 1;
        return 0;
@@ -492,36 +473,37 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
        pte     = (gpuobj->im_pramin->start >> 12) << 1;
        pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
 
-       dev_priv->engine.instmem.prepare_access(dev, true);
        while (pte < pte_end) {
                nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
                nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
        }
-       dev_priv->engine.instmem.finish_access(dev);
+       dev_priv->engine.instmem.flush(dev);
 
        gpuobj->im_bound = 0;
        return 0;
 }
 
 void
-nv50_instmem_prepare_access(struct drm_device *dev, bool write)
+nv50_instmem_flush(struct drm_device *dev)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
-
-       priv->last_access_wr = write;
+       nv_wr32(dev, 0x00330c, 0x00000001);
+       if (!nv_wait(0x00330c, 0x00000002, 0x00000000))
+               NV_ERROR(dev, "PRAMIN flush timeout\n");
 }
 
 void
-nv50_instmem_finish_access(struct drm_device *dev)
+nv84_instmem_flush(struct drm_device *dev)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+       nv_wr32(dev, 0x070000, 0x00000001);
+       if (!nv_wait(0x070000, 0x00000002, 0x00000000))
+               NV_ERROR(dev, "PRAMIN flush timeout\n");
+}
 
-       if (priv->last_access_wr) {
-               nv_wr32(dev, 0x070000, 0x00000001);
-               if (!nv_wait(0x070000, 0x00000001, 0x00000000))
-                       NV_ERROR(dev, "PRAMIN flush timeout\n");
-       }
+void
+nv50_vm_flush(struct drm_device *dev, int engine)
+{
+       nv_wr32(dev, 0x100c80, (engine << 16) | 1);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000))
+               NV_ERROR(dev, "vm flush timeout: engine %d\n", engine);
 }
 
index 812778db76ac185b5943a8257ae401ff82f27202..bcd4cf84a7e641cb0d79d5b1d67a8604110a9af3 100644 (file)
 #include "nv50_display.h"
 
 static void
-nv50_sor_disconnect(struct nouveau_encoder *nv_encoder)
+nv50_sor_disconnect(struct drm_encoder *encoder)
 {
-       struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
+       struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+       struct drm_device *dev = encoder->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *evo = dev_priv->evo;
        int ret;
 
+       if (!nv_encoder->crtc)
+               return;
+       nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
+
        NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or);
 
-       ret = RING_SPACE(evo, 2);
+       ret = RING_SPACE(evo, 4);
        if (ret) {
                NV_ERROR(dev, "no space while disconnecting SOR\n");
                return;
        }
        BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
-       OUT_RING(evo, 0);
-}
-
-static void
-nv50_sor_dp_link_train(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-       struct bit_displayport_encoder_table *dpe;
-       int dpe_headerlen;
-
-       dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
-       if (!dpe) {
-               NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
-               return;
-       }
+       OUT_RING  (evo, 0);
+       BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+       OUT_RING  (evo, 0);
 
-       if (dpe->script0) {
-               NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
-               nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
-                                           nv_encoder->dcb);
-       }
-
-       if (!nouveau_dp_link_train(encoder))
-               NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or);
-
-       if (dpe->script1) {
-               NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
-               nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
-                                           nv_encoder->dcb);
-       }
+       nv_encoder->crtc = NULL;
+       nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
 }
 
 static void
@@ -94,14 +74,16 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
        uint32_t val;
        int or = nv_encoder->or;
 
-       NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode);
+       NV_DEBUG_KMS(dev, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
 
        nv_encoder->last_dpms = mode;
        list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
                struct nouveau_encoder *nvenc = nouveau_encoder(enc);
 
                if (nvenc == nv_encoder ||
-                   nvenc->disconnect != nv50_sor_disconnect ||
+                   (nvenc->dcb->type != OUTPUT_TMDS &&
+                    nvenc->dcb->type != OUTPUT_LVDS &&
+                    nvenc->dcb->type != OUTPUT_DP) ||
                    nvenc->dcb->or != nv_encoder->dcb->or)
                        continue;
 
@@ -133,8 +115,22 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
                         nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or)));
        }
 
-       if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON)
-               nv50_sor_dp_link_train(encoder);
+       if (nv_encoder->dcb->type == OUTPUT_DP) {
+               struct nouveau_i2c_chan *auxch;
+
+               auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+               if (!auxch)
+                       return;
+
+               if (mode == DRM_MODE_DPMS_ON) {
+                       u8 status = DP_SET_POWER_D0;
+                       nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1);
+                       nouveau_dp_link_train(encoder);
+               } else {
+                       u8 status = DP_SET_POWER_D3;
+                       nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1);
+               }
+       }
 }
 
 static void
@@ -196,7 +192,8 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        uint32_t mode_ctl = 0;
        int ret;
 
-       NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or);
+       NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n",
+                    nv_encoder->or, nv_encoder->dcb->type, crtc->index);
 
        nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
 
@@ -239,6 +236,14 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        }
        BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
        OUT_RING(evo, mode_ctl);
+
+       nv_encoder->crtc = encoder->crtc;
+}
+
+static struct drm_crtc *
+nv50_sor_crtc_get(struct drm_encoder *encoder)
+{
+       return nouveau_encoder(encoder)->crtc;
 }
 
 static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
@@ -249,7 +254,9 @@ static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
        .prepare = nv50_sor_prepare,
        .commit = nv50_sor_commit,
        .mode_set = nv50_sor_mode_set,
-       .detect = NULL
+       .get_crtc = nv50_sor_crtc_get,
+       .detect = NULL,
+       .disable = nv50_sor_disconnect
 };
 
 static void
@@ -272,32 +279,22 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
 };
 
 int
-nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
+nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        struct nouveau_encoder *nv_encoder = NULL;
+       struct drm_device *dev = connector->dev;
        struct drm_encoder *encoder;
-       bool dum;
        int type;
 
        NV_DEBUG_KMS(dev, "\n");
 
        switch (entry->type) {
        case OUTPUT_TMDS:
-               NV_INFO(dev, "Detected a TMDS output\n");
+       case OUTPUT_DP:
                type = DRM_MODE_ENCODER_TMDS;
                break;
        case OUTPUT_LVDS:
-               NV_INFO(dev, "Detected a LVDS output\n");
                type = DRM_MODE_ENCODER_LVDS;
-
-               if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) {
-                       NV_ERROR(dev, "Failed parsing LVDS table\n");
-                       return -EINVAL;
-               }
-               break;
-       case OUTPUT_DP:
-               NV_INFO(dev, "Detected a DP output\n");
-               type = DRM_MODE_ENCODER_TMDS;
                break;
        default:
                return -EINVAL;
@@ -310,8 +307,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
 
        nv_encoder->dcb = entry;
        nv_encoder->or = ffs(entry->or) - 1;
-
-       nv_encoder->disconnect = nv50_sor_disconnect;
+       nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
 
        drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type);
        drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs);
@@ -342,5 +338,6 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
                        nv_encoder->dp.mc_unknown = 5;
        }
 
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
index 5998c35237b0c6ed5657a1f85b443a5903de1537..ad64673ace1fc955d650a2c6f8645ec0aba2a402 100644 (file)
 #      define NV_VIO_GX_DONT_CARE_INDEX        0x07
 #      define NV_VIO_GX_BIT_MASK_INDEX         0x08
 
-#define NV_PFB_BOOT_0                  0x00100000
-#define NV_PFB_CFG0                    0x00100200
-#define NV_PFB_CFG1                    0x00100204
-#define NV_PFB_CSTATUS                 0x0010020C
-#define NV_PFB_REFCTRL                 0x00100210
-#      define NV_PFB_REFCTRL_VALID_1                   (1 << 31)
-#define NV_PFB_PAD                     0x0010021C
-#      define NV_PFB_PAD_CKE_NORMAL                    (1 << 0)
-#define NV_PFB_TILE_NV10               0x00100240
-#define NV_PFB_TILE_SIZE_NV10          0x00100244
-#define NV_PFB_REF                     0x001002D0
-#      define NV_PFB_REF_CMD_REFRESH                   (1 << 0)
-#define NV_PFB_PRE                     0x001002D4
-#      define NV_PFB_PRE_CMD_PRECHARGE                 (1 << 0)
-#define NV_PFB_CLOSE_PAGE2             0x0010033C
-#define NV_PFB_TILE_NV40               0x00100600
-#define NV_PFB_TILE_SIZE_NV40          0x00100604
-
-#define NV_PEXTDEV_BOOT_0              0x00101000
-#      define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT   (8 << 12)
-#define NV_PEXTDEV_BOOT_3              0x0010100c
-
 #define NV_PCRTC_INTR_0                                        0x00600100
 #      define NV_PCRTC_INTR_0_VBLANK                           (1 << 0)
 #define NV_PCRTC_INTR_EN_0                             0x00600140
index e671d0e74d4c2c626b12d2daf0e2f7faf09b05c6..570e190710bd0cb0afa4ed36b1a5cb22f940197b 100644 (file)
@@ -44,7 +44,7 @@
 
 MODULE_FIRMWARE(FIRMWARE_NAME);
 
-static int R128_READ_PLL(struct drm_device * dev, int addr)
+static int R128_READ_PLL(struct drm_device *dev, int addr)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
 
@@ -53,7 +53,7 @@ static int R128_READ_PLL(struct drm_device * dev, int addr)
 }
 
 #if R128_FIFO_DEBUG
-static void r128_status(drm_r128_private_t * dev_priv)
+static void r128_status(drm_r128_private_t *dev_priv)
 {
        printk("GUI_STAT           = 0x%08x\n",
               (unsigned int)R128_READ(R128_GUI_STAT));
@@ -74,7 +74,7 @@ static void r128_status(drm_r128_private_t * dev_priv)
  * Engine, FIFO control
  */
 
-static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv)
+static int r128_do_pixcache_flush(drm_r128_private_t *dev_priv)
 {
        u32 tmp;
        int i;
@@ -83,9 +83,8 @@ static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv)
        R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp);
 
        for (i = 0; i < dev_priv->usec_timeout; i++) {
-               if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) {
+               if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY))
                        return 0;
-               }
                DRM_UDELAY(1);
        }
 
@@ -95,7 +94,7 @@ static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv)
        return -EBUSY;
 }
 
-static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries)
+static int r128_do_wait_for_fifo(drm_r128_private_t *dev_priv, int entries)
 {
        int i;
 
@@ -112,7 +111,7 @@ static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries)
        return -EBUSY;
 }
 
-static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv)
+static int r128_do_wait_for_idle(drm_r128_private_t *dev_priv)
 {
        int i, ret;
 
@@ -189,7 +188,7 @@ out_release:
  * prior to a wait for idle, as it informs the engine that the command
  * stream is ending.
  */
-static void r128_do_cce_flush(drm_r128_private_t * dev_priv)
+static void r128_do_cce_flush(drm_r128_private_t *dev_priv)
 {
        u32 tmp;
 
@@ -199,7 +198,7 @@ static void r128_do_cce_flush(drm_r128_private_t * dev_priv)
 
 /* Wait for the CCE to go idle.
  */
-int r128_do_cce_idle(drm_r128_private_t * dev_priv)
+int r128_do_cce_idle(drm_r128_private_t *dev_priv)
 {
        int i;
 
@@ -225,7 +224,7 @@ int r128_do_cce_idle(drm_r128_private_t * dev_priv)
 
 /* Start the Concurrent Command Engine.
  */
-static void r128_do_cce_start(drm_r128_private_t * dev_priv)
+static void r128_do_cce_start(drm_r128_private_t *dev_priv)
 {
        r128_do_wait_for_idle(dev_priv);
 
@@ -242,7 +241,7 @@ static void r128_do_cce_start(drm_r128_private_t * dev_priv)
  * commands, so you must wait for the CCE command stream to complete
  * before calling this routine.
  */
-static void r128_do_cce_reset(drm_r128_private_t * dev_priv)
+static void r128_do_cce_reset(drm_r128_private_t *dev_priv)
 {
        R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
        R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
@@ -253,7 +252,7 @@ static void r128_do_cce_reset(drm_r128_private_t * dev_priv)
  * commands, so you must flush the command stream and wait for the CCE
  * to go idle before calling this routine.
  */
-static void r128_do_cce_stop(drm_r128_private_t * dev_priv)
+static void r128_do_cce_stop(drm_r128_private_t *dev_priv)
 {
        R128_WRITE(R128_PM4_MICRO_CNTL, 0);
        R128_WRITE(R128_PM4_BUFFER_CNTL,
@@ -264,7 +263,7 @@ static void r128_do_cce_stop(drm_r128_private_t * dev_priv)
 
 /* Reset the engine.  This will stop the CCE if it is running.
  */
-static int r128_do_engine_reset(struct drm_device * dev)
+static int r128_do_engine_reset(struct drm_device *dev)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
@@ -301,8 +300,8 @@ static int r128_do_engine_reset(struct drm_device * dev)
        return 0;
 }
 
-static void r128_cce_init_ring_buffer(struct drm_device * dev,
-                                     drm_r128_private_t * dev_priv)
+static void r128_cce_init_ring_buffer(struct drm_device *dev,
+                                     drm_r128_private_t *dev_priv)
 {
        u32 ring_start;
        u32 tmp;
@@ -340,7 +339,7 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev,
        R128_WRITE(R128_BUS_CNTL, tmp);
 }
 
-static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
+static int r128_do_init_cce(struct drm_device *dev, drm_r128_init_t *init)
 {
        drm_r128_private_t *dev_priv;
        int rc;
@@ -588,7 +587,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
        return rc;
 }
 
-int r128_do_cleanup_cce(struct drm_device * dev)
+int r128_do_cleanup_cce(struct drm_device *dev)
 {
 
        /* Make sure interrupts are disabled here because the uninstall ioctl
@@ -682,9 +681,8 @@ int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv
        /* Flush any pending CCE commands.  This ensures any outstanding
         * commands are exectuted by the engine before we turn it off.
         */
-       if (stop->flush) {
+       if (stop->flush)
                r128_do_cce_flush(dev_priv);
-       }
 
        /* If we fail to make the engine go idle, we return an error
         * code so that the DRM ioctl wrapper can try again.
@@ -735,9 +733,8 @@ int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv
 
        DEV_INIT_TEST_WITH_RETURN(dev_priv);
 
-       if (dev_priv->cce_running) {
+       if (dev_priv->cce_running)
                r128_do_cce_flush(dev_priv);
-       }
 
        return r128_do_cce_idle(dev_priv);
 }
@@ -765,7 +762,7 @@ int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_pr
 #define R128_BUFFER_FREE       0
 
 #if 0
-static int r128_freelist_init(struct drm_device * dev)
+static int r128_freelist_init(struct drm_device *dev)
 {
        struct drm_device_dma *dma = dev->dma;
        drm_r128_private_t *dev_priv = dev->dev_private;
@@ -848,7 +845,7 @@ static struct drm_buf *r128_freelist_get(struct drm_device * dev)
        return NULL;
 }
 
-void r128_freelist_reset(struct drm_device * dev)
+void r128_freelist_reset(struct drm_device *dev)
 {
        struct drm_device_dma *dma = dev->dma;
        int i;
@@ -864,7 +861,7 @@ void r128_freelist_reset(struct drm_device * dev)
  * CCE command submission
  */
 
-int r128_wait_ring(drm_r128_private_t * dev_priv, int n)
+int r128_wait_ring(drm_r128_private_t *dev_priv, int n)
 {
        drm_r128_ring_buffer_t *ring = &dev_priv->ring;
        int i;
@@ -881,9 +878,9 @@ int r128_wait_ring(drm_r128_private_t * dev_priv, int n)
        return -EBUSY;
 }
 
-static int r128_cce_get_buffers(struct drm_device * dev,
+static int r128_cce_get_buffers(struct drm_device *dev,
                                struct drm_file *file_priv,
-                               struct drm_dma * d)
+                               struct drm_dma *d)
 {
        int i;
        struct drm_buf *buf;
@@ -933,9 +930,8 @@ int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_p
 
        d->granted_count = 0;
 
-       if (d->request_count) {
+       if (d->request_count)
                ret = r128_cce_get_buffers(dev, file_priv, d);
-       }
 
        return ret;
 }
index b806fdcc717037fcbc8352be15cf3e08fd92908e..1e2971f13aa1f5775f518db92967c5c5a6c83ddf 100644 (file)
@@ -85,7 +85,7 @@ static struct drm_driver driver = {
        .patchlevel = DRIVER_PATCHLEVEL,
 };
 
-int r128_driver_load(struct drm_device * dev, unsigned long flags)
+int r128_driver_load(struct drm_device *dev, unsigned long flags)
 {
        return drm_vblank_init(dev, 1);
 }
index 3c60829d82e9627394a2b6f946d710f5ffe4c2b6..930c71b2fb5e3b5dae831ab388b93721622181da 100644 (file)
@@ -53,7 +53,7 @@
 #define DRIVER_MINOR           5
 #define DRIVER_PATCHLEVEL      0
 
-#define GET_RING_HEAD(dev_priv)                R128_READ( R128_PM4_BUFFER_DL_RPTR )
+#define GET_RING_HEAD(dev_priv)                R128_READ(R128_PM4_BUFFER_DL_RPTR)
 
 typedef struct drm_r128_freelist {
        unsigned int age;
@@ -144,23 +144,23 @@ extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file
 extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
 
-extern void r128_freelist_reset(struct drm_device * dev);
+extern void r128_freelist_reset(struct drm_device *dev);
 
-extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
+extern int r128_wait_ring(drm_r128_private_t *dev_priv, int n);
 
-extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
-extern int r128_do_cleanup_cce(struct drm_device * dev);
+extern int r128_do_cce_idle(drm_r128_private_t *dev_priv);
+extern int r128_do_cleanup_cce(struct drm_device *dev);
 
 extern int r128_enable_vblank(struct drm_device *dev, int crtc);
 extern void r128_disable_vblank(struct drm_device *dev, int crtc);
 extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
 extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
-extern void r128_driver_irq_preinstall(struct drm_device * dev);
+extern void r128_driver_irq_preinstall(struct drm_device *dev);
 extern int r128_driver_irq_postinstall(struct drm_device *dev);
-extern void r128_driver_irq_uninstall(struct drm_device * dev);
-extern void r128_driver_lastclose(struct drm_device * dev);
-extern int r128_driver_load(struct drm_device * dev, unsigned long flags);
-extern void r128_driver_preclose(struct drm_device * dev,
+extern void r128_driver_irq_uninstall(struct drm_device *dev);
+extern void r128_driver_lastclose(struct drm_device *dev);
+extern int r128_driver_load(struct drm_device *dev, unsigned long flags);
+extern void r128_driver_preclose(struct drm_device *dev,
                                 struct drm_file *file_priv);
 
 extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
@@ -390,27 +390,27 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
 
 #define R128_PCIGART_TABLE_SIZE         32768
 
-#define R128_READ(reg)         DRM_READ32(  dev_priv->mmio, (reg) )
-#define R128_WRITE(reg,val)    DRM_WRITE32( dev_priv->mmio, (reg), (val) )
-#define R128_READ8(reg)                DRM_READ8(   dev_priv->mmio, (reg) )
-#define R128_WRITE8(reg,val)   DRM_WRITE8(  dev_priv->mmio, (reg), (val) )
+#define R128_READ(reg)         DRM_READ32(dev_priv->mmio, (reg))
+#define R128_WRITE(reg, val)   DRM_WRITE32(dev_priv->mmio, (reg), (val))
+#define R128_READ8(reg)                DRM_READ8(dev_priv->mmio, (reg))
+#define R128_WRITE8(reg, val)  DRM_WRITE8(dev_priv->mmio, (reg), (val))
 
-#define R128_WRITE_PLL(addr,val)                                       \
+#define R128_WRITE_PLL(addr, val)                                      \
 do {                                                                   \
        R128_WRITE8(R128_CLOCK_CNTL_INDEX,                              \
                    ((addr) & 0x1f) | R128_PLL_WR_EN);                  \
        R128_WRITE(R128_CLOCK_CNTL_DATA, (val));                        \
 } while (0)
 
-#define CCE_PACKET0( reg, n )          (R128_CCE_PACKET0 |             \
+#define CCE_PACKET0(reg, n)            (R128_CCE_PACKET0 |             \
                                         ((n) << 16) | ((reg) >> 2))
-#define CCE_PACKET1( reg0, reg1 )      (R128_CCE_PACKET1 |             \
+#define CCE_PACKET1(reg0, reg1)                (R128_CCE_PACKET1 |             \
                                         (((reg1) >> 2) << 11) | ((reg0) >> 2))
 #define CCE_PACKET2()                  (R128_CCE_PACKET2)
-#define CCE_PACKET3( pkt, n )          (R128_CCE_PACKET3 |             \
+#define CCE_PACKET3(pkt, n)            (R128_CCE_PACKET3 |             \
                                         (pkt) | ((n) << 16))
 
-static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv)
+static __inline__ void r128_update_ring_snapshot(drm_r128_private_t *dev_priv)
 {
        drm_r128_ring_buffer_t *ring = &dev_priv->ring;
        ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32);
@@ -430,37 +430,38 @@ do {                                                                      \
        }                                                               \
 } while (0)
 
-#define RING_SPACE_TEST_WITH_RETURN( dev_priv )                                \
+#define RING_SPACE_TEST_WITH_RETURN(dev_priv)                          \
 do {                                                                   \
        drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i;          \
-       if ( ring->space < ring->high_mark ) {                          \
-               for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {      \
-                       r128_update_ring_snapshot( dev_priv );          \
-                       if ( ring->space >= ring->high_mark )           \
+       if (ring->space < ring->high_mark) {                            \
+               for (i = 0 ; i < dev_priv->usec_timeout ; i++) {        \
+                       r128_update_ring_snapshot(dev_priv);            \
+                       if (ring->space >= ring->high_mark)             \
                                goto __ring_space_done;                 \
-                       DRM_UDELAY(1);                          \
+                       DRM_UDELAY(1);                                  \
                }                                                       \
-               DRM_ERROR( "ring space check failed!\n" );              \
-               return -EBUSY;                          \
+               DRM_ERROR("ring space check failed!\n");                \
+               return -EBUSY;                                          \
        }                                                               \
  __ring_space_done:                                                    \
        ;                                                               \
 } while (0)
 
-#define VB_AGE_TEST_WITH_RETURN( dev_priv )                            \
+#define VB_AGE_TEST_WITH_RETURN(dev_priv)                              \
 do {                                                                   \
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;            \
-       if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) {           \
-               int __ret = r128_do_cce_idle( dev_priv );               \
-               if ( __ret ) return __ret;                              \
+       if (sarea_priv->last_dispatch >= R128_MAX_VB_AGE) {             \
+               int __ret = r128_do_cce_idle(dev_priv);                 \
+               if (__ret)                                              \
+                       return __ret;                                   \
                sarea_priv->last_dispatch = 0;                          \
-               r128_freelist_reset( dev );                             \
+               r128_freelist_reset(dev);                               \
        }                                                               \
 } while (0)
 
 #define R128_WAIT_UNTIL_PAGE_FLIPPED() do {                            \
-       OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) );                  \
-       OUT_RING( R128_EVENT_CRTC_OFFSET );                             \
+       OUT_RING(CCE_PACKET0(R128_WAIT_UNTIL, 0));                      \
+       OUT_RING(R128_EVENT_CRTC_OFFSET);                               \
 } while (0)
 
 /* ================================================================
@@ -472,13 +473,12 @@ do {                                                                      \
 #define RING_LOCALS                                                    \
        int write, _nr; unsigned int tail_mask; volatile u32 *ring;
 
-#define BEGIN_RING( n ) do {                                           \
-       if ( R128_VERBOSE ) {                                           \
-               DRM_INFO( "BEGIN_RING( %d )\n", (n));                   \
-       }                                                               \
-       if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {              \
+#define BEGIN_RING(n) do {                                             \
+       if (R128_VERBOSE)                                               \
+               DRM_INFO("BEGIN_RING(%d)\n", (n));                      \
+       if (dev_priv->ring.space <= (n) * sizeof(u32)) {                \
                COMMIT_RING();                                          \
-               r128_wait_ring( dev_priv, (n) * sizeof(u32) );          \
+               r128_wait_ring(dev_priv, (n) * sizeof(u32));            \
        }                                                               \
        _nr = n; dev_priv->ring.space -= (n) * sizeof(u32);             \
        ring = dev_priv->ring.start;                                    \
@@ -494,40 +494,36 @@ do {                                                                      \
 #define R128_BROKEN_CCE        1
 
 #define ADVANCE_RING() do {                                            \
-       if ( R128_VERBOSE ) {                                           \
-               DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",     \
-                         write, dev_priv->ring.tail );                 \
-       }                                                               \
-       if ( R128_BROKEN_CCE && write < 32 ) {                          \
-               memcpy( dev_priv->ring.end,                             \
-                       dev_priv->ring.start,                           \
-                       write * sizeof(u32) );                          \
-       }                                                               \
-       if (((dev_priv->ring.tail + _nr) & tail_mask) != write) {       \
+       if (R128_VERBOSE)                                               \
+               DRM_INFO("ADVANCE_RING() wr=0x%06x tail=0x%06x\n",      \
+                        write, dev_priv->ring.tail);                   \
+       if (R128_BROKEN_CCE && write < 32)                              \
+               memcpy(dev_priv->ring.end,                              \
+                      dev_priv->ring.start,                            \
+                      write * sizeof(u32));                            \
+       if (((dev_priv->ring.tail + _nr) & tail_mask) != write)         \
                DRM_ERROR(                                              \
                        "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n",        \
                        ((dev_priv->ring.tail + _nr) & tail_mask),      \
                        write, __LINE__);                               \
-       } else                                                          \
+       else                                                            \
                dev_priv->ring.tail = write;                            \
 } while (0)
 
 #define COMMIT_RING() do {                                             \
-       if ( R128_VERBOSE ) {                                           \
-               DRM_INFO( "COMMIT_RING() tail=0x%06x\n",                \
-                       dev_priv->ring.tail );                          \
-       }                                                               \
+       if (R128_VERBOSE)                                               \
+               DRM_INFO("COMMIT_RING() tail=0x%06x\n",                 \
+                        dev_priv->ring.tail);                          \
        DRM_MEMORYBARRIER();                                            \
-       R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail );     \
-       R128_READ( R128_PM4_BUFFER_DL_WPTR );                           \
+       R128_WRITE(R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail);       \
+       R128_READ(R128_PM4_BUFFER_DL_WPTR);                             \
 } while (0)
 
-#define OUT_RING( x ) do {                                             \
-       if ( R128_VERBOSE ) {                                           \
-               DRM_INFO( "   OUT_RING( 0x%08x ) at 0x%x\n",            \
-                          (unsigned int)(x), write );                  \
-       }                                                               \
-       ring[write++] = cpu_to_le32( x );                               \
+#define OUT_RING(x) do {                                               \
+       if (R128_VERBOSE)                                               \
+               DRM_INFO("   OUT_RING( 0x%08x ) at 0x%x\n",             \
+                        (unsigned int)(x), write);                     \
+       ring[write++] = cpu_to_le32(x);                                 \
        write &= tail_mask;                                             \
 } while (0)
 
index 69810fb8ac49101a36645061adc93ca265e19cd8..429d5a02695f7e203fdec455637e92d8aa58225b 100644 (file)
@@ -90,7 +90,7 @@ void r128_disable_vblank(struct drm_device *dev, int crtc)
         */
 }
 
-void r128_driver_irq_preinstall(struct drm_device * dev)
+void r128_driver_irq_preinstall(struct drm_device *dev)
 {
        drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
 
@@ -105,7 +105,7 @@ int r128_driver_irq_postinstall(struct drm_device *dev)
        return 0;
 }
 
-void r128_driver_irq_uninstall(struct drm_device * dev)
+void r128_driver_irq_uninstall(struct drm_device *dev)
 {
        drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
        if (!dev_priv)
index af2665cf4718ca8b92c56130e9a5aec0f80845a6..077af1f2f9b4faee1f3e840f8e4a52813cb05108 100644 (file)
@@ -37,8 +37,8 @@
  * CCE hardware state programming functions
  */
 
-static void r128_emit_clip_rects(drm_r128_private_t * dev_priv,
-                                struct drm_clip_rect * boxes, int count)
+static void r128_emit_clip_rects(drm_r128_private_t *dev_priv,
+                                struct drm_clip_rect *boxes, int count)
 {
        u32 aux_sc_cntl = 0x00000000;
        RING_LOCALS;
@@ -80,7 +80,7 @@ static void r128_emit_clip_rects(drm_r128_private_t * dev_priv,
        ADVANCE_RING();
 }
 
-static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv)
+static __inline__ void r128_emit_core(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
@@ -95,7 +95,7 @@ static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv)
        ADVANCE_RING();
 }
 
-static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv)
+static __inline__ void r128_emit_context(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
@@ -121,7 +121,7 @@ static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv)
        ADVANCE_RING();
 }
 
-static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv)
+static __inline__ void r128_emit_setup(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
@@ -137,7 +137,7 @@ static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv)
        ADVANCE_RING();
 }
 
-static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv)
+static __inline__ void r128_emit_masks(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
@@ -156,7 +156,7 @@ static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv)
        ADVANCE_RING();
 }
 
-static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv)
+static __inline__ void r128_emit_window(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
@@ -171,7 +171,7 @@ static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv)
        ADVANCE_RING();
 }
 
-static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
+static __inline__ void r128_emit_tex0(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
@@ -187,9 +187,8 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
        OUT_RING(tex->tex_cntl);
        OUT_RING(tex->tex_combine_cntl);
        OUT_RING(ctx->tex_size_pitch_c);
-       for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
+       for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++)
                OUT_RING(tex->tex_offset[i]);
-       }
 
        OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1));
        OUT_RING(ctx->constant_color_c);
@@ -198,7 +197,7 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
        ADVANCE_RING();
 }
 
-static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
+static __inline__ void r128_emit_tex1(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
@@ -211,9 +210,8 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
        OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS));
        OUT_RING(tex->tex_cntl);
        OUT_RING(tex->tex_combine_cntl);
-       for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
+       for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++)
                OUT_RING(tex->tex_offset[i]);
-       }
 
        OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0));
        OUT_RING(tex->tex_border_color);
@@ -221,7 +219,7 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
        ADVANCE_RING();
 }
 
-static void r128_emit_state(drm_r128_private_t * dev_priv)
+static void r128_emit_state(drm_r128_private_t *dev_priv)
 {
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int dirty = sarea_priv->dirty;
@@ -274,7 +272,7 @@ static void r128_emit_state(drm_r128_private_t * dev_priv)
  * Performance monitoring functions
  */
 
-static void r128_clear_box(drm_r128_private_t * dev_priv,
+static void r128_clear_box(drm_r128_private_t *dev_priv,
                           int x, int y, int w, int h, int r, int g, int b)
 {
        u32 pitch, offset;
@@ -321,13 +319,12 @@ static void r128_clear_box(drm_r128_private_t * dev_priv,
        ADVANCE_RING();
 }
 
-static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv)
+static void r128_cce_performance_boxes(drm_r128_private_t *dev_priv)
 {
-       if (atomic_read(&dev_priv->idle_count) == 0) {
+       if (atomic_read(&dev_priv->idle_count) == 0)
                r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
-       } else {
+       else
                atomic_set(&dev_priv->idle_count, 0);
-       }
 }
 
 #endif
@@ -352,8 +349,8 @@ static void r128_print_dirty(const char *msg, unsigned int flags)
                 (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "");
 }
 
-static void r128_cce_dispatch_clear(struct drm_device * dev,
-                                   drm_r128_clear_t * clear)
+static void r128_cce_dispatch_clear(struct drm_device *dev,
+                                   drm_r128_clear_t *clear)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -458,7 +455,7 @@ static void r128_cce_dispatch_clear(struct drm_device * dev,
        }
 }
 
-static void r128_cce_dispatch_swap(struct drm_device * dev)
+static void r128_cce_dispatch_swap(struct drm_device *dev)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -524,7 +521,7 @@ static void r128_cce_dispatch_swap(struct drm_device * dev)
        ADVANCE_RING();
 }
 
-static void r128_cce_dispatch_flip(struct drm_device * dev)
+static void r128_cce_dispatch_flip(struct drm_device *dev)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
@@ -542,11 +539,10 @@ static void r128_cce_dispatch_flip(struct drm_device * dev)
        R128_WAIT_UNTIL_PAGE_FLIPPED();
        OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0));
 
-       if (dev_priv->current_page == 0) {
+       if (dev_priv->current_page == 0)
                OUT_RING(dev_priv->back_offset);
-       } else {
+       else
                OUT_RING(dev_priv->front_offset);
-       }
 
        ADVANCE_RING();
 
@@ -566,7 +562,7 @@ static void r128_cce_dispatch_flip(struct drm_device * dev)
        ADVANCE_RING();
 }
 
-static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf)
+static void r128_cce_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_buf_priv_t *buf_priv = buf->dev_private;
@@ -585,9 +581,8 @@ static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * b
        if (buf->used) {
                buf_priv->dispatched = 1;
 
-               if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
+               if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS)
                        r128_emit_state(dev_priv);
-               }
 
                do {
                        /* Emit the next set of up to three cliprects */
@@ -636,8 +631,8 @@ static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * b
        sarea_priv->nbox = 0;
 }
 
-static void r128_cce_dispatch_indirect(struct drm_device * dev,
-                                      struct drm_buf * buf, int start, int end)
+static void r128_cce_dispatch_indirect(struct drm_device *dev,
+                                      struct drm_buf *buf, int start, int end)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_buf_priv_t *buf_priv = buf->dev_private;
@@ -691,8 +686,8 @@ static void r128_cce_dispatch_indirect(struct drm_device * dev,
        dev_priv->sarea_priv->last_dispatch++;
 }
 
-static void r128_cce_dispatch_indices(struct drm_device * dev,
-                                     struct drm_buf * buf,
+static void r128_cce_dispatch_indices(struct drm_device *dev,
+                                     struct drm_buf *buf,
                                      int start, int end, int count)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
@@ -713,9 +708,8 @@ static void r128_cce_dispatch_indices(struct drm_device * dev,
        if (start != end) {
                buf_priv->dispatched = 1;
 
-               if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
+               if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS)
                        r128_emit_state(dev_priv);
-               }
 
                dwords = (end - start + 3) / sizeof(u32);
 
@@ -775,9 +769,9 @@ static void r128_cce_dispatch_indices(struct drm_device * dev,
        sarea_priv->nbox = 0;
 }
 
-static int r128_cce_dispatch_blit(struct drm_device * dev,
+static int r128_cce_dispatch_blit(struct drm_device *dev,
                                  struct drm_file *file_priv,
-                                 drm_r128_blit_t * blit)
+                                 drm_r128_blit_t *blit)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        struct drm_device_dma *dma = dev->dma;
@@ -887,8 +881,8 @@ static int r128_cce_dispatch_blit(struct drm_device * dev,
  * have hardware stencil support.
  */
 
-static int r128_cce_dispatch_write_span(struct drm_device * dev,
-                                       drm_r128_depth_t * depth)
+static int r128_cce_dispatch_write_span(struct drm_device *dev,
+                                       drm_r128_depth_t *depth)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        int count, x, y;
@@ -902,12 +896,10 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev,
        if (count > 4096 || count <= 0)
                return -EMSGSIZE;
 
-       if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
+       if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x)))
                return -EFAULT;
-       }
-       if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
+       if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y)))
                return -EFAULT;
-       }
 
        buffer_size = depth->n * sizeof(u32);
        buffer = kmalloc(buffer_size, GFP_KERNEL);
@@ -983,8 +975,8 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev,
        return 0;
 }
 
-static int r128_cce_dispatch_write_pixels(struct drm_device * dev,
-                                         drm_r128_depth_t * depth)
+static int r128_cce_dispatch_write_pixels(struct drm_device *dev,
+                                         drm_r128_depth_t *depth)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        int count, *x, *y;
@@ -1001,9 +993,8 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev,
        xbuf_size = count * sizeof(*x);
        ybuf_size = count * sizeof(*y);
        x = kmalloc(xbuf_size, GFP_KERNEL);
-       if (x == NULL) {
+       if (x == NULL)
                return -ENOMEM;
-       }
        y = kmalloc(ybuf_size, GFP_KERNEL);
        if (y == NULL) {
                kfree(x);
@@ -1105,8 +1096,8 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev,
        return 0;
 }
 
-static int r128_cce_dispatch_read_span(struct drm_device * dev,
-                                      drm_r128_depth_t * depth)
+static int r128_cce_dispatch_read_span(struct drm_device *dev,
+                                      drm_r128_depth_t *depth)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        int count, x, y;
@@ -1117,12 +1108,10 @@ static int r128_cce_dispatch_read_span(struct drm_device * dev,
        if (count > 4096 || count <= 0)
                return -EMSGSIZE;
 
-       if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
+       if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x)))
                return -EFAULT;
-       }
-       if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
+       if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y)))
                return -EFAULT;
-       }
 
        BEGIN_RING(7);
 
@@ -1148,8 +1137,8 @@ static int r128_cce_dispatch_read_span(struct drm_device * dev,
        return 0;
 }
 
-static int r128_cce_dispatch_read_pixels(struct drm_device * dev,
-                                        drm_r128_depth_t * depth)
+static int r128_cce_dispatch_read_pixels(struct drm_device *dev,
+                                        drm_r128_depth_t *depth)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        int count, *x, *y;
@@ -1161,16 +1150,14 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev,
        if (count > 4096 || count <= 0)
                return -EMSGSIZE;
 
-       if (count > dev_priv->depth_pitch) {
+       if (count > dev_priv->depth_pitch)
                count = dev_priv->depth_pitch;
-       }
 
        xbuf_size = count * sizeof(*x);
        ybuf_size = count * sizeof(*y);
        x = kmalloc(xbuf_size, GFP_KERNEL);
-       if (x == NULL) {
+       if (x == NULL)
                return -ENOMEM;
-       }
        y = kmalloc(ybuf_size, GFP_KERNEL);
        if (y == NULL) {
                kfree(x);
@@ -1220,7 +1207,7 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev,
  * Polygon stipple
  */
 
-static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple)
+static void r128_cce_dispatch_stipple(struct drm_device *dev, u32 *stipple)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        int i;
@@ -1230,9 +1217,8 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple)
        BEGIN_RING(33);
 
        OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31));
-       for (i = 0; i < 32; i++) {
+       for (i = 0; i < 32; i++)
                OUT_RING(stipple[i]);
-       }
 
        ADVANCE_RING();
 }
@@ -1269,7 +1255,7 @@ static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *f
        return 0;
 }
 
-static int r128_do_init_pageflip(struct drm_device * dev)
+static int r128_do_init_pageflip(struct drm_device *dev)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG("\n");
@@ -1288,7 +1274,7 @@ static int r128_do_init_pageflip(struct drm_device * dev)
        return 0;
 }
 
-static int r128_do_cleanup_pageflip(struct drm_device * dev)
+static int r128_do_cleanup_pageflip(struct drm_device *dev)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG("\n");
@@ -1645,17 +1631,16 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi
        return 0;
 }
 
-void r128_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
+void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
 {
        if (dev->dev_private) {
                drm_r128_private_t *dev_priv = dev->dev_private;
-               if (dev_priv->page_flipping) {
+               if (dev_priv->page_flipping)
                        r128_do_cleanup_pageflip(dev);
-               }
        }
 }
 
-void r128_driver_lastclose(struct drm_device * dev)
+void r128_driver_lastclose(struct drm_device *dev)
 {
        r128_do_cleanup_cce(dev);
 }
index 84b1f2729d430deaddcf6e4241a1886339c0123b..aebe00875041448351bb129b7a131baab66f4e9e 100644 (file)
@@ -69,5 +69,6 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
+radeon-$(CONFIG_ACPI) += radeon_acpi.o
 
 obj-$(CONFIG_DRM_RADEON)+= radeon.o
index 1d569830ed99f0b278e5ae96de52971d020d7a8d..8e421f644a5435d44b6a0bc26f0edf3039b78c21 100644 (file)
@@ -108,12 +108,11 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
                        base++;
                        break;
                case ATOM_IIO_READ:
-                       temp = ctx->card->reg_read(ctx->card, CU16(base + 1));
+                       temp = ctx->card->ioreg_read(ctx->card, CU16(base + 1));
                        base += 3;
                        break;
                case ATOM_IIO_WRITE:
-                       (void)ctx->card->reg_read(ctx->card, CU16(base + 1));
-                       ctx->card->reg_write(ctx->card, CU16(base + 1), temp);
+                       ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
                        base += 3;
                        break;
                case ATOM_IIO_CLEAR:
@@ -715,8 +714,8 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
                        cjiffies = jiffies;
                        if (time_after(cjiffies, ctx->last_jump_jiffies)) {
                                cjiffies -= ctx->last_jump_jiffies;
-                               if ((jiffies_to_msecs(cjiffies) > 1000)) {
-                                       DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n");
+                               if ((jiffies_to_msecs(cjiffies) > 5000)) {
+                                       DRM_ERROR("atombios stuck in loop for more than 5secs aborting\n");
                                        ctx->abort = true;
                                }
                        } else {
index cd1b64ab5ca7c0c4b24e29bd4dd04e8b52387b16..a589a55b223e660576a9e393be36c371ed7f2f71 100644 (file)
@@ -113,6 +113,8 @@ struct card_info {
        struct drm_device *dev;
        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
         uint32_t (* reg_read)(struct card_info *, uint32_t);          /*  filled by driver */
+       void (* ioreg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
+        uint32_t (* ioreg_read)(struct card_info *, uint32_t);          /*  filled by driver */
        void (* mc_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
         uint32_t (* mc_read)(struct card_info *, uint32_t);          /*  filled by driver */
        void (* pll_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
index 8c2d6478a2213d82637a4270b4215a676481896b..12ad512bd3d33ad316655400212626585126c6de 100644 (file)
@@ -44,10 +44,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc,
 
        memset(&args, 0, sizeof(args));
 
-       args.usOverscanRight = 0;
-       args.usOverscanLeft = 0;
-       args.usOverscanBottom = 0;
-       args.usOverscanTop = 0;
        args.ucCRTC = radeon_crtc->crtc_id;
 
        switch (radeon_crtc->rmx_type) {
@@ -56,7 +52,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc,
                args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
                args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
                args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
-               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
                break;
        case RMX_ASPECT:
                a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
@@ -69,17 +64,16 @@ static void atombios_overscan_setup(struct drm_crtc *crtc,
                        args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
                        args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
                }
-               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
                break;
        case RMX_FULL:
        default:
-               args.usOverscanRight = 0;
-               args.usOverscanLeft = 0;
-               args.usOverscanBottom = 0;
-               args.usOverscanTop = 0;
-               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               args.usOverscanRight = radeon_crtc->h_border;
+               args.usOverscanLeft = radeon_crtc->h_border;
+               args.usOverscanBottom = radeon_crtc->v_border;
+               args.usOverscanTop = radeon_crtc->v_border;
                break;
        }
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
 static void atombios_scaler_setup(struct drm_crtc *crtc)
@@ -282,22 +276,22 @@ atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
        u16 misc = 0;
 
        memset(&args, 0, sizeof(args));
-       args.usH_Size = cpu_to_le16(mode->crtc_hdisplay);
+       args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2));
        args.usH_Blanking_Time =
-               cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay);
-       args.usV_Size = cpu_to_le16(mode->crtc_vdisplay);
+               cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2));
+       args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2));
        args.usV_Blanking_Time =
-           cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay);
+               cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2));
        args.usH_SyncOffset =
-               cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay);
+               cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border);
        args.usH_SyncWidth =
                cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
        args.usV_SyncOffset =
-               cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay);
+               cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border);
        args.usV_SyncWidth =
                cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
-       /*args.ucH_Border = mode->hborder;*/
-       /*args.ucV_Border = mode->vborder;*/
+       args.ucH_Border = radeon_crtc->h_border;
+       args.ucV_Border = radeon_crtc->v_border;
 
        if (mode->flags & DRM_MODE_FLAG_NVSYNC)
                misc |= ATOM_VSYNC_POLARITY;
@@ -669,56 +663,25 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+static void atombios_crtc_program_pll(struct drm_crtc *crtc,
+                                     int crtc_id,
+                                     int pll_id,
+                                     u32 encoder_mode,
+                                     u32 encoder_id,
+                                     u32 clock,
+                                     u32 ref_div,
+                                     u32 fb_div,
+                                     u32 frac_fb_div,
+                                     u32 post_div)
 {
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
-       struct drm_encoder *encoder = NULL;
-       struct radeon_encoder *radeon_encoder = NULL;
        u8 frev, crev;
-       int index;
+       int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
        union set_pixel_clock args;
-       u32 pll_clock = mode->clock;
-       u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
-       struct radeon_pll *pll;
-       u32 adjusted_clock;
-       int encoder_mode = 0;
 
        memset(&args, 0, sizeof(args));
 
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               if (encoder->crtc == crtc) {
-                       radeon_encoder = to_radeon_encoder(encoder);
-                       encoder_mode = atombios_get_encoder_mode(encoder);
-                       break;
-               }
-       }
-
-       if (!radeon_encoder)
-               return;
-
-       switch (radeon_crtc->pll_id) {
-       case ATOM_PPLL1:
-               pll = &rdev->clock.p1pll;
-               break;
-       case ATOM_PPLL2:
-               pll = &rdev->clock.p2pll;
-               break;
-       case ATOM_DCPLL:
-       case ATOM_PPLL_INVALID:
-       default:
-               pll = &rdev->clock.dcpll;
-               break;
-       }
-
-       /* adjust pixel clock as needed */
-       adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
-
-       radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-                          &ref_div, &post_div);
-
-       index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
                                   &crev))
                return;
@@ -727,47 +690,49 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        case 1:
                switch (crev) {
                case 1:
-                       args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       if (clock == ATOM_DISABLE)
+                               return;
+                       args.v1.usPixelClock = cpu_to_le16(clock / 10);
                        args.v1.usRefDiv = cpu_to_le16(ref_div);
                        args.v1.usFbDiv = cpu_to_le16(fb_div);
                        args.v1.ucFracFbDiv = frac_fb_div;
                        args.v1.ucPostDiv = post_div;
-                       args.v1.ucPpll = radeon_crtc->pll_id;
-                       args.v1.ucCRTC = radeon_crtc->crtc_id;
+                       args.v1.ucPpll = pll_id;
+                       args.v1.ucCRTC = crtc_id;
                        args.v1.ucRefDivSrc = 1;
                        break;
                case 2:
-                       args.v2.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       args.v2.usPixelClock = cpu_to_le16(clock / 10);
                        args.v2.usRefDiv = cpu_to_le16(ref_div);
                        args.v2.usFbDiv = cpu_to_le16(fb_div);
                        args.v2.ucFracFbDiv = frac_fb_div;
                        args.v2.ucPostDiv = post_div;
-                       args.v2.ucPpll = radeon_crtc->pll_id;
-                       args.v2.ucCRTC = radeon_crtc->crtc_id;
+                       args.v2.ucPpll = pll_id;
+                       args.v2.ucCRTC = crtc_id;
                        args.v2.ucRefDivSrc = 1;
                        break;
                case 3:
-                       args.v3.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       args.v3.usPixelClock = cpu_to_le16(clock / 10);
                        args.v3.usRefDiv = cpu_to_le16(ref_div);
                        args.v3.usFbDiv = cpu_to_le16(fb_div);
                        args.v3.ucFracFbDiv = frac_fb_div;
                        args.v3.ucPostDiv = post_div;
-                       args.v3.ucPpll = radeon_crtc->pll_id;
-                       args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2);
-                       args.v3.ucTransmitterId = radeon_encoder->encoder_id;
+                       args.v3.ucPpll = pll_id;
+                       args.v3.ucMiscInfo = (pll_id << 2);
+                       args.v3.ucTransmitterId = encoder_id;
                        args.v3.ucEncoderMode = encoder_mode;
                        break;
                case 5:
-                       args.v5.ucCRTC = radeon_crtc->crtc_id;
-                       args.v5.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       args.v5.ucCRTC = crtc_id;
+                       args.v5.usPixelClock = cpu_to_le16(clock / 10);
                        args.v5.ucRefDiv = ref_div;
                        args.v5.usFbDiv = cpu_to_le16(fb_div);
                        args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
                        args.v5.ucPostDiv = post_div;
                        args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
-                       args.v5.ucTransmitterID = radeon_encoder->encoder_id;
+                       args.v5.ucTransmitterID = encoder_id;
                        args.v5.ucEncoderMode = encoder_mode;
-                       args.v5.ucPpll = radeon_crtc->pll_id;
+                       args.v5.ucPpll = pll_id;
                        break;
                default:
                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
@@ -782,6 +747,56 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+{
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct drm_encoder *encoder = NULL;
+       struct radeon_encoder *radeon_encoder = NULL;
+       u32 pll_clock = mode->clock;
+       u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
+       struct radeon_pll *pll;
+       u32 adjusted_clock;
+       int encoder_mode = 0;
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               if (encoder->crtc == crtc) {
+                       radeon_encoder = to_radeon_encoder(encoder);
+                       encoder_mode = atombios_get_encoder_mode(encoder);
+                       break;
+               }
+       }
+
+       if (!radeon_encoder)
+               return;
+
+       switch (radeon_crtc->pll_id) {
+       case ATOM_PPLL1:
+               pll = &rdev->clock.p1pll;
+               break;
+       case ATOM_PPLL2:
+               pll = &rdev->clock.p2pll;
+               break;
+       case ATOM_DCPLL:
+       case ATOM_PPLL_INVALID:
+       default:
+               pll = &rdev->clock.dcpll;
+               break;
+       }
+
+       /* adjust pixel clock as needed */
+       adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
+
+       radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+                          &ref_div, &post_div);
+
+       atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
+                                 encoder_mode, radeon_encoder->encoder_id, mode->clock,
+                                 ref_div, fb_div, frac_fb_div, post_div);
+
+}
+
 static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                                   struct drm_framebuffer *old_fb)
 {
@@ -797,7 +812,7 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 
        /* no fb bound */
        if (!crtc->fb) {
-               DRM_DEBUG("No FB bound\n");
+               DRM_DEBUG_KMS("No FB bound\n");
                return 0;
        }
 
@@ -841,6 +856,11 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                return -EINVAL;
        }
 
+       if (tiling_flags & RADEON_TILING_MACRO)
+               fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
+       else if (tiling_flags & RADEON_TILING_MICRO)
+               fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
+
        switch (radeon_crtc->crtc_id) {
        case 0:
                WREG32(AVIVO_D1VGA_CONTROL, 0);
@@ -931,7 +951,7 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 
        /* no fb bound */
        if (!crtc->fb) {
-               DRM_DEBUG("No FB bound\n");
+               DRM_DEBUG_KMS("No FB bound\n");
                return 0;
        }
 
@@ -979,11 +999,18 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                return -EINVAL;
        }
 
-       if (tiling_flags & RADEON_TILING_MACRO)
-               fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
+       if (rdev->family >= CHIP_R600) {
+               if (tiling_flags & RADEON_TILING_MACRO)
+                       fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1;
+               else if (tiling_flags & RADEON_TILING_MICRO)
+                       fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1;
+       } else {
+               if (tiling_flags & RADEON_TILING_MACRO)
+                       fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
 
-       if (tiling_flags & RADEON_TILING_MICRO)
-               fb_format |= AVIVO_D1GRPH_TILED;
+               if (tiling_flags & RADEON_TILING_MICRO)
+                       fb_format |= AVIVO_D1GRPH_TILED;
+       }
 
        if (radeon_crtc->crtc_id == 0)
                WREG32(AVIVO_D1VGA_CONTROL, 0);
@@ -1143,10 +1170,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
        atombios_crtc_set_pll(crtc, adjusted_mode);
        atombios_enable_ss(crtc);
 
-       if (ASIC_IS_DCE4(rdev))
+       if (ASIC_IS_AVIVO(rdev))
                atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
-       else if (ASIC_IS_AVIVO(rdev))
-               atombios_crtc_set_timing(crtc, adjusted_mode);
        else {
                atombios_crtc_set_timing(crtc, adjusted_mode);
                if (radeon_crtc->crtc_id == 0)
@@ -1191,6 +1216,24 @@ static void atombios_crtc_commit(struct drm_crtc *crtc)
        atombios_lock_crtc(crtc, ATOM_DISABLE);
 }
 
+static void atombios_crtc_disable(struct drm_crtc *crtc)
+{
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+
+       switch (radeon_crtc->pll_id) {
+       case ATOM_PPLL1:
+       case ATOM_PPLL2:
+               /* disable the ppll */
+               atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
+                                         0, 0, ATOM_DISABLE, 0, 0, 0, 0);
+               break;
+       default:
+               break;
+       }
+       radeon_crtc->pll_id = -1;
+}
+
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
        .dpms = atombios_crtc_dpms,
        .mode_fixup = atombios_crtc_mode_fixup,
@@ -1199,6 +1242,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
        .prepare = atombios_crtc_prepare,
        .commit = atombios_crtc_commit,
        .load_lut = radeon_crtc_load_lut,
+       .disable = atombios_crtc_disable,
 };
 
 void radeon_atombios_init_crtc(struct drm_device *dev,
index abffb1499e227a39b24170c3c0212d0613c41961..36e0d4b545e60b674380746496525fed8b88ad39 100644 (file)
@@ -296,7 +296,7 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
                u8 this_v = dp_get_adjust_request_voltage(link_status, lane);
                u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane);
 
-               DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n",
+               DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
                          lane,
                          voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
                          pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
@@ -313,7 +313,7 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
        if (p >= dp_pre_emphasis_max(v))
                p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
-       DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n",
+       DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n",
                  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
                  pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
 
@@ -358,7 +358,7 @@ retry:
        if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
                if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
                        goto retry;
-               DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
+               DRM_DEBUG_KMS("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
                          req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
                          chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count);
                return false;
@@ -461,10 +461,10 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
                memcpy(dig_connector->dpcd, msg, 8);
                {
                        int i;
-                       DRM_DEBUG("DPCD: ");
+                       DRM_DEBUG_KMS("DPCD: ");
                        for (i = 0; i < 8; i++)
-                               DRM_DEBUG("%02x ", msg[i]);
-                       DRM_DEBUG("\n");
+                               DRM_DEBUG_KMS("%02x ", msg[i]);
+                       DRM_DEBUG_KMS("\n");
                }
                return true;
        }
@@ -512,7 +512,7 @@ static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
                return false;
        }
 
-       DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n",
+       DRM_DEBUG_KMS("link status %02x %02x %02x %02x %02x %02x\n",
                  link_status[0], link_status[1], link_status[2],
                  link_status[3], link_status[4], link_status[5]);
        return true;
@@ -695,7 +695,7 @@ void dp_link_train(struct drm_encoder *encoder,
        if (!clock_recovery)
                DRM_ERROR("clock recovery failed\n");
        else
-               DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n",
+               DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n",
                          train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
                          (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
                          DP_TRAIN_PRE_EMPHASIS_SHIFT);
@@ -739,7 +739,7 @@ void dp_link_train(struct drm_encoder *encoder,
        if (!channel_eq)
                DRM_ERROR("channel eq failed\n");
        else
-               DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n",
+               DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n",
                          train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
                          (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
                          >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
index 1caf625e472b607b92b2841f0dcf7fae44785cde..957d5067ad9cc1495984f909d724fbf64c8d8856 100644 (file)
 static void evergreen_gpu_init(struct radeon_device *rdev);
 void evergreen_fini(struct radeon_device *rdev);
 
+/* get temperature in millidegrees */
+u32 evergreen_get_temp(struct radeon_device *rdev)
+{
+       u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
+               ASIC_T_SHIFT;
+       u32 actual_temp = 0;
+
+       if ((temp >> 10) & 1)
+               actual_temp = 0;
+       else if ((temp >> 9) & 1)
+               actual_temp = 255;
+       else
+               actual_temp = (temp >> 1) & 0xff;
+
+       return actual_temp * 1000;
+}
+
 void evergreen_pm_misc(struct radeon_device *rdev)
 {
        int req_ps_idx = rdev->pm.requested_power_state_index;
@@ -1115,6 +1132,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                                                                 rdev->config.evergreen.max_backends) &
                                                                EVERGREEN_MAX_BACKENDS_MASK));
 
+       rdev->config.evergreen.tile_config = gb_addr_config;
        WREG32(GB_BACKEND_MAP, gb_backend_map);
        WREG32(GB_ADDR_CONFIG, gb_addr_config);
        WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
@@ -1334,8 +1352,8 @@ int evergreen_mc_init(struct radeon_device *rdev)
        }
        rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        /* Setup GPU memory space */
        /* size in MB on evergreen */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
index e028c1cd9d9b7732d8eeaf1c8773df35e13c93fa..2330f3a36fd5c44d02d8a2d96b057db56ef9f079 100644 (file)
 #       define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102     5
 #       define EVERGREEN_GRPH_FORMAT_RGB111110          6
 #       define EVERGREEN_GRPH_FORMAT_BGR101111          7
+#       define EVERGREEN_GRPH_ARRAY_MODE(x)             (((x) & 0x7) << 20)
+#       define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL      0
+#       define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED      1
+#       define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1      2
+#       define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1      4
 #define EVERGREEN_GRPH_SWAP_CONTROL                     0x680c
 #       define EVERGREEN_GRPH_ENDIAN_SWAP(x)            (((x) & 0x3) << 0)
 #       define EVERGREEN_GRPH_ENDIAN_NONE               0
index a1cd621780e21bc5fdd7251c397dfc362d3c5ec3..9b7532dd30f754d4ad2e3e02915006ae823538f2 100644 (file)
 #define                SE_DB_BUSY                                      (1 << 30)
 #define                SE_CB_BUSY                                      (1 << 31)
 
+#define        CG_MULT_THERMAL_STATUS                          0x740
+#define                ASIC_T(x)                               ((x) << 16)
+#define                ASIC_T_MASK                             0x7FF0000
+#define                ASIC_T_SHIFT                            16
+
 #define        HDP_HOST_PATH_CNTL                              0x2C00
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08
index a89a15ab524d87d64f734b9475418b0538525dd2..e817a0bb5eb4a71550d0c9f6f8697cd80c31914e 100644 (file)
@@ -141,7 +141,7 @@ void r100_pm_get_dynpm_state(struct radeon_device *rdev)
        /* only one clock mode per power state */
        rdev->pm.requested_clock_mode_index = 0;
 
-       DRM_DEBUG("Requested: e: %d m: %d p: %d\n",
+       DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n",
                  rdev->pm.power_state[rdev->pm.requested_power_state_index].
                  clock_info[rdev->pm.requested_clock_mode_index].sclk,
                  rdev->pm.power_state[rdev->pm.requested_power_state_index].
@@ -276,7 +276,7 @@ void r100_pm_misc(struct radeon_device *rdev)
             rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) {
                radeon_set_pcie_lanes(rdev,
                                      ps->pcie_lanes);
-               DRM_DEBUG("Setting: p: %d\n", ps->pcie_lanes);
+               DRM_DEBUG_DRIVER("Setting: p: %d\n", ps->pcie_lanes);
        }
 }
 
@@ -849,7 +849,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
        const char *fw_name = NULL;
        int err;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
        err = IS_ERR(pdev);
@@ -1803,6 +1803,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
                        return r;
                break;
                /* triggers drawing using indices to vertex buffer */
+       case PACKET3_3D_CLEAR_HIZ:
+       case PACKET3_3D_CLEAR_ZMASK:
+               if (p->rdev->hyperz_filp != p->filp)
+                       return -EINVAL;
+               break;
        case PACKET3_NOP:
                break;
        default:
@@ -2295,8 +2300,8 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
        u64 config_aper_size;
 
        /* work out accessible VRAM */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev);
        /* FIXME we don't use the second aperture yet when we could use it */
        if (rdev->mc.visible_vram_size > rdev->mc.aper_size)
@@ -2364,11 +2369,10 @@ void r100_mc_init(struct radeon_device *rdev)
  */
 void r100_pll_errata_after_index(struct radeon_device *rdev)
 {
-       if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) {
-               return;
+       if (rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS) {
+               (void)RREG32(RADEON_CLOCK_CNTL_DATA);
+               (void)RREG32(RADEON_CRTC_GEN_CNTL);
        }
-       (void)RREG32(RADEON_CLOCK_CNTL_DATA);
-       (void)RREG32(RADEON_CRTC_GEN_CNTL);
 }
 
 static void r100_pll_errata_after_data(struct radeon_device *rdev)
@@ -2643,7 +2647,7 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
                flags |= pitch / 8;
 
 
-       DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
+       DRM_DEBUG_KMS("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
        WREG32(RADEON_SURFACE0_INFO + surf_index, flags);
        WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);
        WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1);
@@ -3039,7 +3043,7 @@ void r100_bandwidth_update(struct radeon_device *rdev)
                }
 #endif
 
-               DRM_DEBUG("GRPH_BUFFER_CNTL from to %x\n",
+               DRM_DEBUG_KMS("GRPH_BUFFER_CNTL from to %x\n",
                          /*      (unsigned int)info->SavedReg->grph_buffer_cntl, */
                          (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL));
        }
@@ -3135,7 +3139,7 @@ void r100_bandwidth_update(struct radeon_device *rdev)
                        WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC);
                }
 
-               DRM_DEBUG("GRPH2_BUFFER_CNTL from to %x\n",
+               DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n",
                          (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL));
        }
 }
@@ -3809,6 +3813,31 @@ void r100_fini(struct radeon_device *rdev)
        rdev->bios = NULL;
 }
 
+/*
+ * Due to how kexec works, it can leave the hw fully initialised when it
+ * boots the new kernel. However doing our init sequence with the CP and
+ * WB stuff setup causes GPU hangs on the RN50 at least. So at startup
+ * do some quick sanity checks and restore sane values to avoid this
+ * problem.
+ */
+void r100_restore_sanity(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       tmp = RREG32(RADEON_CP_CSQ_CNTL);
+       if (tmp) {
+               WREG32(RADEON_CP_CSQ_CNTL, 0);
+       }
+       tmp = RREG32(RADEON_CP_RB_CNTL);
+       if (tmp) {
+               WREG32(RADEON_CP_RB_CNTL, 0);
+       }
+       tmp = RREG32(RADEON_SCRATCH_UMSK);
+       if (tmp) {
+               WREG32(RADEON_SCRATCH_UMSK, 0);
+       }
+}
+
 int r100_init(struct radeon_device *rdev)
 {
        int r;
@@ -3821,6 +3850,8 @@ int r100_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* sanity check some register to avoid hangs like after kexec */
+       r100_restore_sanity(rdev);
        /* TODO: disable VGA need to use VGA request */
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
index d016b16fa116148518fee22d805342f733ccc63a..b121b6c678d4846566e79aa4f387fdfc116408a5 100644 (file)
 #define                PACKET3_3D_DRAW_IMMD            0x29
 #define                PACKET3_3D_DRAW_INDX            0x2A
 #define                PACKET3_3D_LOAD_VBPNTR          0x2F
+#define                PACKET3_3D_CLEAR_ZMASK          0x32
 #define                PACKET3_INDX_BUFFER             0x33
 #define                PACKET3_3D_DRAW_VBUF_2          0x34
 #define                PACKET3_3D_DRAW_IMMD_2          0x35
 #define                PACKET3_3D_DRAW_INDX_2          0x36
+#define                PACKET3_3D_CLEAR_HIZ            0x37
 #define                PACKET3_BITBLT_MULTI            0x9B
 
 #define PACKET0(reg, n)        (CP_PACKET0 |                                   \
index 19a7ef7ee3448f867ec11ab4a0f57f9dfa047013..c827738ad7ddbe620323937f97c5cc8953365338 100644 (file)
@@ -1048,14 +1048,47 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                /* RB3D_COLOR_CHANNEL_MASK */
                track->color_channel_mask = idx_value;
                break;
-       case 0x4d1c:
+       case 0x43a4:
+               /* SC_HYPERZ_EN */
+               /* r300c emits this register - we need to disable hyperz for it
+                * without complaining */
+               if (p->rdev->hyperz_filp != p->filp) {
+                       if (idx_value & 0x1)
+                               ib[idx] = idx_value & ~1;
+               }
+               break;
+       case 0x4f1c:
                /* ZB_BW_CNTL */
                track->zb_cb_clear = !!(idx_value & (1 << 5));
+               if (p->rdev->hyperz_filp != p->filp) {
+                       if (idx_value & (R300_HIZ_ENABLE |
+                                        R300_RD_COMP_ENABLE |
+                                        R300_WR_COMP_ENABLE |
+                                        R300_FAST_FILL_ENABLE))
+                               goto fail;
+               }
                break;
        case 0x4e04:
                /* RB3D_BLENDCNTL */
                track->blend_read_enable = !!(idx_value & (1 << 2));
                break;
+       case 0x4f28: /* ZB_DEPTHCLEARVALUE */
+               break;
+       case 0x4f30: /* ZB_MASK_OFFSET */
+       case 0x4f34: /* ZB_ZMASK_PITCH */
+       case 0x4f44: /* ZB_HIZ_OFFSET */
+       case 0x4f54: /* ZB_HIZ_PITCH */
+               if (idx_value && (p->rdev->hyperz_filp != p->filp))
+                       goto fail;
+               break;
+       case 0x4028:
+               if (idx_value && (p->rdev->hyperz_filp != p->filp))
+                       goto fail;
+               /* GB_Z_PEQ_CONFIG */
+               if (p->rdev->family >= CHIP_RV350)
+                       break;
+               goto fail;
+               break;
        case 0x4be8:
                /* valid register only on RV530 */
                if (p->rdev->family == CHIP_RV530)
@@ -1066,8 +1099,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
        }
        return 0;
 fail:
-       printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
-              reg, idx);
+       printk(KERN_ERR "Forbidden register 0x%04X in cs at %d (val=%08x)\n",
+              reg, idx, idx_value);
        return -EINVAL;
 }
 
@@ -1161,6 +1194,11 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
                        return r;
                }
                break;
+       case PACKET3_3D_CLEAR_HIZ:
+       case PACKET3_3D_CLEAR_ZMASK:
+               if (p->rdev->hyperz_filp != p->filp)
+                       return -EINVAL;
+               break;
        case PACKET3_NOP:
                break;
        default:
@@ -1380,6 +1418,8 @@ int r300_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index 968a33317fbf64cfdb39738d03de3d0ba524ae45..0c036c60d9df4f8d167ece6b9dfe4909f67c583e 100644 (file)
 #define                PACKET3_3D_DRAW_IMMD            0x29
 #define                PACKET3_3D_DRAW_INDX            0x2A
 #define                PACKET3_3D_LOAD_VBPNTR          0x2F
+#define                PACKET3_3D_CLEAR_ZMASK          0x32
 #define                PACKET3_INDX_BUFFER             0x33
 #define                PACKET3_3D_DRAW_VBUF_2          0x34
 #define                PACKET3_3D_DRAW_IMMD_2          0x35
 #define                PACKET3_3D_DRAW_INDX_2          0x36
+#define                PACKET3_3D_CLEAR_HIZ            0x37
 #define                PACKET3_BITBLT_MULTI            0x9B
 
 #define PACKET0(reg, n)        (CP_PACKET0 |                                   \
index e6c89142bb4d24323920636cf0e2499c5e17cf59..59f7bccc5be0a291dcf0fcfb9487080ea93d5693 100644 (file)
@@ -343,6 +343,8 @@ int r420_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index 93c9a2bbccf88b856eaf3c9a2cc6e0592cb7fb32..6ac1f604e29be8afd2eb7d16cd43ffd1c4817458 100644 (file)
 #       define AVIVO_D1GRPH_TILED                               (1 << 20)
 #       define AVIVO_D1GRPH_MACRO_ADDRESS_MODE                  (1 << 21)
 
+#       define R600_D1GRPH_ARRAY_MODE_LINEAR_GENERAL            (0 << 20)
+#       define R600_D1GRPH_ARRAY_MODE_LINEAR_ALIGNED            (1 << 20)
+#       define R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1            (2 << 20)
+#       define R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1            (4 << 20)
+
 /* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2
  * block and vice versa.  This applies to GRPH, CUR, etc.
  */
index 694af7cc23ac1b3ce91b8abb71ca1d3fdbb58ae2..1458dee902dd6124db7c11d3c74911220c7648de 100644 (file)
@@ -231,6 +231,8 @@ int r520_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* TODO: disable VGA need to use VGA request */
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
index e100f69faeec80a0c447ee186774a14ea95620c4..d0ebae9dde25ba400778b210dfc2e6a86179d682 100644 (file)
@@ -92,6 +92,21 @@ void r600_gpu_init(struct radeon_device *rdev);
 void r600_fini(struct radeon_device *rdev);
 void r600_irq_disable(struct radeon_device *rdev);
 
+/* get temperature in millidegrees */
+u32 rv6xx_get_temp(struct radeon_device *rdev)
+{
+       u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >>
+               ASIC_T_SHIFT;
+       u32 actual_temp = 0;
+
+       if ((temp >> 7) & 1)
+               actual_temp = 0;
+       else
+               actual_temp = (temp >> 1) & 0xff;
+
+       return actual_temp * 1000;
+}
+
 void r600_pm_get_dynpm_state(struct radeon_device *rdev)
 {
        int i;
@@ -256,7 +271,7 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev)
                }
        }
 
-       DRM_DEBUG("Requested: e: %d m: %d p: %d\n",
+       DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n",
                  rdev->pm.power_state[rdev->pm.requested_power_state_index].
                  clock_info[rdev->pm.requested_clock_mode_index].sclk,
                  rdev->pm.power_state[rdev->pm.requested_power_state_index].
@@ -571,7 +586,7 @@ void r600_pm_misc(struct radeon_device *rdev)
                if (voltage->voltage != rdev->pm.current_vddc) {
                        radeon_atom_set_voltage(rdev, voltage->voltage);
                        rdev->pm.current_vddc = voltage->voltage;
-                       DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
+                       DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage);
                }
        }
 }
@@ -869,7 +884,17 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
        u32 tmp;
 
        /* flush hdp cache so updates hit vram */
-       WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+               void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+               u32 tmp;
+
+               /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
+                * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+                */
+               WREG32(HDP_DEBUG1, 0);
+               tmp = readl((void __iomem *)ptr);
+       } else
+               WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
 
        WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12);
        WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12);
@@ -1217,8 +1242,8 @@ int r600_mc_init(struct radeon_device *rdev)
        }
        rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        /* Setup GPU memory space */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
@@ -1609,7 +1634,7 @@ void r600_gpu_init(struct radeon_device *rdev)
                                                         r600_count_pipe_bits((cc_rb_backend_disable &
                                                                               R6XX_MAX_BACKENDS_MASK) >> 16)),
                                                        (cc_rb_backend_disable >> 16));
-
+       rdev->config.r600.tile_config = tiling_config;
        tiling_config |= BACKEND_MAP(backend_map);
        WREG32(GB_TILING_CONFIG, tiling_config);
        WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
@@ -3512,5 +3537,15 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
  */
 void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
 {
-       WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+       /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
+        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+        */
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+               void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+               u32 tmp;
+
+               WREG32(HDP_DEBUG1, 0);
+               tmp = readl((void __iomem *)ptr);
+       } else
+               WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
 }
index 2b26553c352cdf6bd63495ae9f40b3f95a259030..b5443fe1c1d1173c653483bec8a142832fe16509 100644 (file)
@@ -63,7 +63,8 @@ int r600_audio_bits_per_sample(struct radeon_device *rdev)
        case 0x4: return 32;
        }
 
-       DRM_ERROR("Unknown bits per sample 0x%x using 16 instead.\n", (int)value);
+       dev_err(rdev->dev, "Unknown bits per sample 0x%x using 16 instead\n",
+               (int)value);
 
        return 16;
 }
@@ -150,7 +151,8 @@ static void r600_audio_update_hdmi(unsigned long param)
                        r600_hdmi_update_audio_settings(encoder);
        }
 
-       if(still_going) r600_audio_schedule_polling(rdev);
+       if (still_going)
+               r600_audio_schedule_polling(rdev);
 }
 
 /*
@@ -158,8 +160,9 @@ static void r600_audio_update_hdmi(unsigned long param)
  */
 static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable)
 {
-       DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling");
+       DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling");
        WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000);
+       rdev->audio_enabled = enable;
 }
 
 /*
@@ -195,12 +198,14 @@ void r600_audio_enable_polling(struct drm_encoder *encoder)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
-       DRM_DEBUG("r600_audio_enable_polling: %d", radeon_encoder->audio_polling_active);
+       DRM_DEBUG("r600_audio_enable_polling: %d\n",
+               radeon_encoder->audio_polling_active);
        if (radeon_encoder->audio_polling_active)
                return;
 
        radeon_encoder->audio_polling_active = 1;
-       mod_timer(&rdev->audio_timer, jiffies + 1);
+       if (rdev->audio_enabled)
+               mod_timer(&rdev->audio_timer, jiffies + 1);
 }
 
 /*
@@ -209,7 +214,8 @@ void r600_audio_enable_polling(struct drm_encoder *encoder)
 void r600_audio_disable_polling(struct drm_encoder *encoder)
 {
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       DRM_DEBUG("r600_audio_disable_polling: %d", radeon_encoder->audio_polling_active);
+       DRM_DEBUG("r600_audio_disable_polling: %d\n",
+               radeon_encoder->audio_polling_active);
        radeon_encoder->audio_polling_active = 0;
 }
 
@@ -236,7 +242,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
                WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
                break;
        default:
-               DRM_ERROR("Unsupported encoder type 0x%02X\n",
+               dev_err(rdev->dev, "Unsupported encoder type 0x%02X\n",
                          radeon_encoder->encoder_id);
                return;
        }
@@ -266,7 +272,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
  */
 void r600_audio_fini(struct radeon_device *rdev)
 {
-       if (!radeon_audio || !r600_audio_chipset_supported(rdev))
+       if (!rdev->audio_enabled)
                return;
 
        del_timer(&rdev->audio_timer);
index 0271b53fa2ddb0b49f7c99539287827d38197fb7..e8151c1d55b2be1d7668be216173138518e88ab6 100644 (file)
 
 const u32 r6xx_default_state[] =
 {
-       0xc0002400,
+       0xc0002400, /* START_3D_CMDBUF */
        0x00000000,
-       0xc0012800,
+
+       0xc0012800, /* CONTEXT_CONTROL */
        0x80000000,
        0x80000000,
+
        0xc0016800,
        0x00000010,
-       0x00008000,
+       0x00008000, /* WAIT_UNTIL */
+
        0xc0016800,
        0x00000542,
-       0x07000003,
+       0x07000003, /* TA_CNTL_AUX */
+
        0xc0016800,
        0x000005c5,
-       0x00000000,
+       0x00000000, /* VC_ENHANCE */
+
        0xc0016800,
        0x00000363,
-       0x00000000,
+       0x00000000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */
+
        0xc0016800,
        0x0000060c,
-       0x82000000,
+       0x82000000, /* DB_DEBUG */
+
        0xc0016800,
        0x0000060e,
-       0x01020204,
-       0xc0016f00,
-       0x00000000,
-       0x00000000,
-       0xc0016f00,
-       0x00000001,
+       0x01020204, /* DB_WATERMARKS */
+
+       0xc0026f00,
        0x00000000,
+       0x00000000, /* SQ_VTX_BASE_VTX_LOC */
+       0x00000000, /* SQ_VTX_START_INST_LOC */
+
        0xc0096900,
        0x0000022a,
+       0x00000000, /* SQ_ESGS_RING_ITEMSIZE */
        0x00000000,
        0x00000000,
        0x00000000,
@@ -78,515 +86,317 @@ const u32 r6xx_default_state[] =
        0x00000000,
        0x00000000,
        0x00000000,
-       0x00000000,
+
        0xc0016900,
        0x00000004,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* DB_DEPTH_INFO */
+
+       0xc0026900,
        0x0000000a,
-       0x00000000,
-       0xc0016900,
-       0x0000000b,
-       0x00000000,
-       0xc0016900,
-       0x0000010c,
-       0x00000000,
-       0xc0016900,
-       0x0000010d,
-       0x00000000,
+       0x00000000, /* DB_STENCIL_CLEAR */
+       0x00000000, /* DB_DEPTH_CLEAR */
+
        0xc0016900,
        0x00000200,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* DB_DEPTH_CONTROL */
+
+       0xc0026900,
        0x00000343,
-       0x00000060,
-       0xc0016900,
-       0x00000344,
-       0x00000040,
+       0x00000060, /* DB_RENDER_CONTROL */
+       0x00000040, /* DB_RENDER_OVERRIDE */
+
        0xc0016900,
        0x00000351,
-       0x0000aa00,
-       0xc0016900,
-       0x00000104,
-       0x00000000,
-       0xc0016900,
-       0x0000010e,
-       0x00000000,
-       0xc0046900,
-       0x00000105,
-       0x00000000,
-       0x00000000,
+       0x0000aa00, /* DB_ALPHA_TO_MASK */
+
+       0xc00f6900,
+       0x00000100,
+       0x00000800, /* VGT_MAX_VTX_INDX */
+       0x00000000, /* VGT_MIN_VTX_INDX */
+       0x00000000, /* VGT_INDX_OFFSET */
+       0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */
+       0x00000000, /* SX_ALPHA_TEST_CONTROL */
+       0x00000000, /* CB_BLEND_RED */
        0x00000000,
        0x00000000,
-       0xc0036900,
-       0x00000109,
        0x00000000,
+       0x00000000, /* CB_FOG_RED */
        0x00000000,
        0x00000000,
+       0x00000000, /* DB_STENCILREFMASK */
+       0x00000000, /* DB_STENCILREFMASK_BF */
+       0x00000000, /* SX_ALPHA_REF */
+
        0xc0046900,
        0x0000030c,
-       0x01000000,
+       0x01000000, /* CB_CLRCMP_CNTL */
        0x00000000,
        0x00000000,
        0x00000000,
+
        0xc0046900,
        0x00000048,
-       0x3f800000,
+       0x3f800000, /* CB_CLEAR_RED */
        0x00000000,
        0x3f800000,
        0x3f800000,
-       0xc0016900,
-       0x0000008e,
-       0x0000000f,
+
        0xc0016900,
        0x00000080,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* PA_SC_WINDOW_OFFSET */
+
+       0xc00a6900,
        0x00000083,
-       0x0000ffff,
-       0xc0016900,
-       0x00000084,
-       0x00000000,
-       0xc0016900,
-       0x00000085,
+       0x0000ffff, /* PA_SC_CLIP_RECT_RULE */
+       0x00000000, /* PA_SC_CLIPRECT_0_TL */
        0x20002000,
-       0xc0016900,
-       0x00000086,
        0x00000000,
-       0xc0016900,
-       0x00000087,
        0x20002000,
-       0xc0016900,
-       0x00000088,
        0x00000000,
-       0xc0016900,
-       0x00000089,
        0x20002000,
-       0xc0016900,
-       0x0000008a,
        0x00000000,
-       0xc0016900,
-       0x0000008b,
        0x20002000,
-       0xc0016900,
-       0x0000008c,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* PA_SC_EDGERULE */
+
+       0xc0406900,
        0x00000094,
-       0x80000000,
-       0xc0016900,
-       0x00000095,
+       0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */
+       0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */
+       0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */
        0x20002000,
-       0xc0026900,
-       0x000000b4,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x00000096,
        0x80000000,
-       0xc0016900,
-       0x00000097,
        0x20002000,
-       0xc0026900,
-       0x000000b6,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x00000098,
        0x80000000,
-       0xc0016900,
-       0x00000099,
        0x20002000,
-       0xc0026900,
-       0x000000b8,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x0000009a,
        0x80000000,
-       0xc0016900,
-       0x0000009b,
        0x20002000,
-       0xc0026900,
-       0x000000ba,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x0000009c,
        0x80000000,
-       0xc0016900,
-       0x0000009d,
        0x20002000,
-       0xc0026900,
-       0x000000bc,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x0000009e,
        0x80000000,
-       0xc0016900,
-       0x0000009f,
        0x20002000,
-       0xc0026900,
-       0x000000be,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a0,
        0x80000000,
-       0xc0016900,
-       0x000000a1,
        0x20002000,
-       0xc0026900,
-       0x000000c0,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a2,
        0x80000000,
-       0xc0016900,
-       0x000000a3,
        0x20002000,
-       0xc0026900,
-       0x000000c2,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a4,
        0x80000000,
-       0xc0016900,
-       0x000000a5,
        0x20002000,
-       0xc0026900,
-       0x000000c4,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a6,
        0x80000000,
-       0xc0016900,
-       0x000000a7,
        0x20002000,
-       0xc0026900,
-       0x000000c6,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a8,
        0x80000000,
-       0xc0016900,
-       0x000000a9,
        0x20002000,
-       0xc0026900,
-       0x000000c8,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000aa,
        0x80000000,
-       0xc0016900,
-       0x000000ab,
        0x20002000,
-       0xc0026900,
-       0x000000ca,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000ac,
        0x80000000,
-       0xc0016900,
-       0x000000ad,
        0x20002000,
-       0xc0026900,
-       0x000000cc,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000ae,
        0x80000000,
-       0xc0016900,
-       0x000000af,
        0x20002000,
-       0xc0026900,
-       0x000000ce,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000b0,
        0x80000000,
-       0xc0016900,
-       0x000000b1,
        0x20002000,
-       0xc0026900,
-       0x000000d0,
-       0x00000000,
+       0x00000000, /* PA_SC_VPORT_ZMIN_0 */
        0x3f800000,
-       0xc0016900,
-       0x000000b2,
-       0x80000000,
-       0xc0016900,
-       0x000000b3,
-       0x20002000,
-       0xc0026900,
-       0x000000d2,
        0x00000000,
        0x3f800000,
-       0xc0016900,
-       0x00000293,
-       0x00004010,
-       0xc0016900,
-       0x00000300,
-       0x00000000,
-       0xc0016900,
-       0x00000301,
        0x00000000,
-       0xc0016900,
-       0x00000312,
-       0xffffffff,
-       0xc0016900,
-       0x00000307,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000308,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000283,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000292,
+       0x3f800000,
        0x00000000,
-       0xc0066900,
-       0x0000010f,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000206,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000207,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000208,
+       0x3f800000,
        0x00000000,
-       0xc0046900,
-       0x00000303,
        0x3f800000,
+
+       0xc0026900,
+       0x00000292,
+       0x00000000, /* PA_SC_MPASS_PS_CNTL */
+       0x00004010, /* PA_SC_MODE_CNTL */
+
+       0xc0096900,
+       0x00000300,
+       0x00000000, /* PA_SC_LINE_CNTL */
+       0x00000000, /* PA_SC_AA_CONFIG */
+       0x0000002d, /* PA_SU_VTX_CNTL */
+       0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */
        0x3f800000,
        0x3f800000,
        0x3f800000,
-       0xc0016900,
-       0x00000205,
-       0x00000004,
-       0xc0016900,
-       0x00000280,
-       0x00000000,
-       0xc0016900,
-       0x00000281,
+       0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */
        0x00000000,
+
        0xc0016900,
+       0x00000312,
+       0xffffffff, /* PA_SC_AA_MASK */
+
+       0xc0066900,
        0x0000037e,
-       0x00000000,
-       0xc0016900,
-       0x00000382,
-       0x00000000,
-       0xc0016900,
-       0x00000380,
-       0x00000000,
-       0xc0016900,
-       0x00000383,
-       0x00000000,
-       0xc0016900,
-       0x00000381,
-       0x00000000,
-       0xc0016900,
-       0x00000282,
-       0x00000008,
-       0xc0016900,
-       0x00000302,
-       0x0000002d,
-       0xc0016900,
-       0x0000037f,
-       0x00000000,
-       0xc0016900,
-       0x000001b2,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */
+       0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */
+       0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */
+       0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */
+       0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */
+       0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */
+
+       0xc0046900,
        0x000001b6,
-       0x00000000,
-       0xc0016900,
-       0x000001b7,
-       0x00000000,
-       0xc0016900,
-       0x000001b8,
-       0x00000000,
-       0xc0016900,
-       0x000001b9,
-       0x00000000,
+       0x00000000, /* SPI_INPUT_Z */
+       0x00000000, /* SPI_FOG_CNTL */
+       0x00000000, /* SPI_FOG_FUNC_SCALE */
+       0x00000000, /* SPI_FOG_FUNC_BIAS */
+
        0xc0016900,
        0x00000225,
-       0x00000000,
+       0x00000000, /* SQ_PGM_START_FS */
+
        0xc0016900,
        0x00000229,
-       0x00000000,
+       0x00000000, /* SQ_PGM_RESOURCES_FS */
+
        0xc0016900,
        0x00000237,
-       0x00000000,
-       0xc0016900,
-       0x00000100,
-       0x00000800,
-       0xc0016900,
-       0x00000101,
-       0x00000000,
-       0xc0016900,
-       0x00000102,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* SQ_PGM_CF_OFFSET_FS */
+
+       0xc0026900,
        0x000002a8,
-       0x00000000,
+       0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */
+       0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */
+
+       0xc0116900,
+       0x00000280,
+       0x00000000, /* PA_SU_POINT_SIZE */
+       0x00000000, /* PA_SU_POINT_MINMAX */
+       0x00000008, /* PA_SU_LINE_CNTL */
+       0x00000000, /* PA_SC_LINE_STIPPLE */
+       0x00000000, /* VGT_OUTPUT_PATH_CNTL */
+       0x00000000, /* VGT_HOS_CNTL */
+       0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */
+       0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */
+       0x00000000, /* VGT_HOS_REUSE_DEPTH */
+       0x00000000, /* VGT_GROUP_PRIM_TYPE */
+       0x00000000, /* VGT_GROUP_FIRST_DECR */
+       0x00000000, /* VGT_GROUP_DECR */
+       0x00000000, /* VGT_GROUP_VECT_0_CNTL */
+       0x00000000, /* VGT_GROUP_VECT_1_CNTL */
+       0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */
+       0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */
+       0x00000000, /* VGT_GS_MODE */
+
        0xc0016900,
-       0x000002a9,
-       0x00000000,
+       0x000002a1,
+       0x00000000, /* VGT_PRIMITIVEID_EN */
+
        0xc0016900,
-       0x00000103,
-       0x00000000,
+       0x000002a5,
+       0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */
+
+       0xc0036900,
+       0x000002ac,
+       0x00000000, /* VGT_STRMOUT_EN */
+       0x00000000, /* VGT_REUSE_OFF */
+       0x00000000, /* VGT_VTX_CNT_EN */
+
        0xc0016900,
-       0x00000284,
-       0x00000000,
+       0x000002c8,
+       0x00000000, /* VGT_STRMOUT_BUFFER_EN */
+
+       0xc0076900,
+       0x00000202,
+       0x00cc0000, /* CB_COLOR_CONTROL */
+       0x00000210, /* DB_SHADER_CNTL */
+       0x00010000, /* PA_CL_CLIP_CNTL */
+       0x00000244, /* PA_SU_SC_MODE_CNTL */
+       0x00000100, /* PA_CL_VTE_CNTL */
+       0x00000000, /* PA_CL_VS_OUT_CNTL */
+       0x00000000, /* PA_CL_NANINF_CNTL */
+
+       0xc0026900,
+       0x0000008e,
+       0x0000000f, /* CB_TARGET_MASK */
+       0x0000000f, /* CB_SHADER_MASK */
+
        0xc0016900,
-       0x00000290,
-       0x00000000,
+       0x000001e8,
+       0x00000001, /* CB_SHADER_CONTROL */
+
        0xc0016900,
-       0x00000285,
-       0x00000000,
-       0xc0016900,
-       0x00000286,
-       0x00000000,
-       0xc0016900,
-       0x00000287,
-       0x00000000,
-       0xc0016900,
-       0x00000288,
-       0x00000000,
-       0xc0016900,
-       0x00000289,
-       0x00000000,
-       0xc0016900,
-       0x0000028a,
-       0x00000000,
-       0xc0016900,
-       0x0000028b,
-       0x00000000,
-       0xc0016900,
-       0x0000028c,
-       0x00000000,
-       0xc0016900,
-       0x0000028d,
-       0x00000000,
-       0xc0016900,
-       0x0000028e,
-       0x00000000,
-       0xc0016900,
-       0x0000028f,
-       0x00000000,
-       0xc0016900,
-       0x000002a1,
-       0x00000000,
-       0xc0016900,
-       0x000002a5,
-       0x00000000,
-       0xc0016900,
-       0x000002ac,
-       0x00000000,
-       0xc0016900,
-       0x000002ad,
-       0x00000000,
-       0xc0016900,
-       0x000002ae,
-       0x00000000,
-       0xc0016900,
-       0x000002c8,
-       0x00000000,
-       0xc0016900,
-       0x00000206,
-       0x00000100,
-       0xc0016900,
-       0x00000204,
-       0x00010000,
-       0xc0036e00,
-       0x00000000,
-       0x00000012,
-       0x00000000,
-       0x00000000,
-       0xc0016900,
-       0x0000008f,
-       0x0000000f,
-       0xc0016900,
-       0x000001e8,
-       0x00000001,
-       0xc0016900,
-       0x00000202,
-       0x00cc0000,
-       0xc0016900,
-       0x00000205,
-       0x00000244,
-       0xc0016900,
-       0x00000203,
-       0x00000210,
+       0x00000185,
+       0x00000000, /* SPI_VS_OUT_ID_0 */
+
        0xc0016900,
+       0x00000191,
+       0x00000b00, /* SPI_PS_INPUT_CNTL_0 */
+
+       0xc0056900,
        0x000001b1,
+       0x00000000, /* SPI_VS_OUT_CONFIG */
+       0x00000000, /* SPI_THREAD_GROUPING */
+       0x00000001, /* SPI_PS_IN_CONTROL_0 */
+       0x00000000, /* SPI_PS_IN_CONTROL_1 */
+       0x00000000, /* SPI_INTERP_CONTROL_0 */
+
+       0xc0036e00, /* SET_SAMPLER */
        0x00000000,
-       0xc0016900,
-       0x00000185,
-       0x00000000,
-       0xc0016900,
-       0x000001b3,
-       0x00000001,
-       0xc0016900,
-       0x000001b4,
+       0x00000012,
        0x00000000,
-       0xc0016900,
-       0x00000191,
-       0x00000b00,
-       0xc0016900,
-       0x000001b5,
        0x00000000,
 };
 
 const u32 r7xx_default_state[] =
 {
-       0xc0012800,
+       0xc0012800, /* CONTEXT_CONTROL */
        0x80000000,
        0x80000000,
+
        0xc0016800,
        0x00000010,
-       0x00008000,
+       0x00008000, /* WAIT_UNTIL */
+
        0xc0016800,
        0x00000542,
-       0x07000002,
+       0x07000002, /* TA_CNTL_AUX */
+
        0xc0016800,
        0x000005c5,
-       0x00000000,
+       0x00000000, /* VC_ENHANCE */
+
        0xc0016800,
        0x00000363,
-       0x00004000,
+       0x00004000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */
+
        0xc0016800,
        0x0000060c,
-       0x00000000,
+       0x00000000, /* DB_DEBUG */
+
        0xc0016800,
        0x0000060e,
-       0x00420204,
-       0xc0016f00,
-       0x00000000,
-       0x00000000,
-       0xc0016f00,
-       0x00000001,
+       0x00420204, /* DB_WATERMARKS */
+
+       0xc0026f00,
        0x00000000,
+       0x00000000, /* SQ_VTX_BASE_VTX_LOC */
+       0x00000000, /* SQ_VTX_START_INST_LOC */
+
        0xc0096900,
        0x0000022a,
+       0x00000000, /* SQ_ESGS_RING_ITEMSIZE */
        0x00000000,
        0x00000000,
        0x00000000,
@@ -595,470 +405,269 @@ const u32 r7xx_default_state[] =
        0x00000000,
        0x00000000,
        0x00000000,
-       0x00000000,
+
        0xc0016900,
        0x00000004,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* DB_DEPTH_INFO */
+
+       0xc0026900,
        0x0000000a,
-       0x00000000,
-       0xc0016900,
-       0x0000000b,
-       0x00000000,
-       0xc0016900,
-       0x0000010c,
-       0x00000000,
-       0xc0016900,
-       0x0000010d,
-       0x00000000,
+       0x00000000, /* DB_STENCIL_CLEAR */
+       0x00000000, /* DB_DEPTH_CLEAR */
+
        0xc0016900,
        0x00000200,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* DB_DEPTH_CONTROL */
+
+       0xc0026900,
        0x00000343,
-       0x00000060,
-       0xc0016900,
-       0x00000344,
-       0x00000000,
+       0x00000060, /* DB_RENDER_CONTROL */
+       0x00000000, /* DB_RENDER_OVERRIDE */
+
        0xc0016900,
        0x00000351,
-       0x0000aa00,
-       0xc0016900,
-       0x00000104,
-       0x00000000,
-       0xc0016900,
-       0x0000010e,
-       0x00000000,
-       0xc0046900,
-       0x00000105,
-       0x00000000,
+       0x0000aa00, /* DB_ALPHA_TO_MASK */
+
+       0xc0096900,
+       0x00000100,
+       0x00000800, /* VGT_MAX_VTX_INDX */
+       0x00000000, /* VGT_MIN_VTX_INDX */
+       0x00000000, /* VGT_INDX_OFFSET */
+       0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */
+       0x00000000, /* SX_ALPHA_TEST_CONTROL */
+       0x00000000, /* CB_BLEND_RED */
        0x00000000,
        0x00000000,
        0x00000000,
+
+       0xc0036900,
+       0x0000010c,
+       0x00000000, /* DB_STENCILREFMASK */
+       0x00000000, /* DB_STENCILREFMASK_BF */
+       0x00000000, /* SX_ALPHA_REF */
+
        0xc0046900,
-       0x0000030c,
+       0x0000030c, /* CB_CLRCMP_CNTL */
        0x01000000,
        0x00000000,
        0x00000000,
        0x00000000,
-       0xc0016900,
-       0x0000008e,
-       0x0000000f,
+
        0xc0016900,
        0x00000080,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* PA_SC_WINDOW_OFFSET */
+
+       0xc00a6900,
        0x00000083,
-       0x0000ffff,
-       0xc0016900,
-       0x00000084,
-       0x00000000,
-       0xc0016900,
-       0x00000085,
+       0x0000ffff, /* PA_SC_CLIP_RECT_RULE */
+       0x00000000, /* PA_SC_CLIPRECT_0_TL */
        0x20002000,
-       0xc0016900,
-       0x00000086,
        0x00000000,
-       0xc0016900,
-       0x00000087,
        0x20002000,
-       0xc0016900,
-       0x00000088,
        0x00000000,
-       0xc0016900,
-       0x00000089,
        0x20002000,
-       0xc0016900,
-       0x0000008a,
        0x00000000,
-       0xc0016900,
-       0x0000008b,
        0x20002000,
-       0xc0016900,
-       0x0000008c,
-       0xaaaaaaaa,
-       0xc0016900,
+       0xaaaaaaaa, /* PA_SC_EDGERULE */
+
+       0xc0406900,
        0x00000094,
-       0x80000000,
-       0xc0016900,
-       0x00000095,
+       0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */
+       0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */
+       0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */
        0x20002000,
-       0xc0026900,
-       0x000000b4,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x00000096,
        0x80000000,
-       0xc0016900,
-       0x00000097,
        0x20002000,
-       0xc0026900,
-       0x000000b6,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x00000098,
        0x80000000,
-       0xc0016900,
-       0x00000099,
        0x20002000,
-       0xc0026900,
-       0x000000b8,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x0000009a,
        0x80000000,
-       0xc0016900,
-       0x0000009b,
        0x20002000,
-       0xc0026900,
-       0x000000ba,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x0000009c,
        0x80000000,
-       0xc0016900,
-       0x0000009d,
        0x20002000,
-       0xc0026900,
-       0x000000bc,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x0000009e,
        0x80000000,
-       0xc0016900,
-       0x0000009f,
        0x20002000,
-       0xc0026900,
-       0x000000be,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a0,
        0x80000000,
-       0xc0016900,
-       0x000000a1,
        0x20002000,
-       0xc0026900,
-       0x000000c0,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a2,
        0x80000000,
-       0xc0016900,
-       0x000000a3,
        0x20002000,
-       0xc0026900,
-       0x000000c2,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a4,
        0x80000000,
-       0xc0016900,
-       0x000000a5,
        0x20002000,
-       0xc0026900,
-       0x000000c4,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a6,
        0x80000000,
-       0xc0016900,
-       0x000000a7,
        0x20002000,
-       0xc0026900,
-       0x000000c6,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000a8,
        0x80000000,
-       0xc0016900,
-       0x000000a9,
        0x20002000,
-       0xc0026900,
-       0x000000c8,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000aa,
        0x80000000,
-       0xc0016900,
-       0x000000ab,
        0x20002000,
-       0xc0026900,
-       0x000000ca,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000ac,
        0x80000000,
-       0xc0016900,
-       0x000000ad,
        0x20002000,
-       0xc0026900,
-       0x000000cc,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000ae,
        0x80000000,
-       0xc0016900,
-       0x000000af,
        0x20002000,
-       0xc0026900,
-       0x000000ce,
-       0x00000000,
-       0x3f800000,
-       0xc0016900,
-       0x000000b0,
        0x80000000,
-       0xc0016900,
-       0x000000b1,
        0x20002000,
-       0xc0026900,
-       0x000000d0,
-       0x00000000,
+       0x00000000, /* PA_SC_VPORT_ZMIN_0 */
        0x3f800000,
-       0xc0016900,
-       0x000000b2,
-       0x80000000,
-       0xc0016900,
-       0x000000b3,
-       0x20002000,
-       0xc0026900,
-       0x000000d2,
        0x00000000,
        0x3f800000,
-       0xc0016900,
-       0x00000293,
-       0x00514000,
-       0xc0016900,
-       0x00000300,
-       0x00000000,
-       0xc0016900,
-       0x00000301,
        0x00000000,
-       0xc0016900,
-       0x00000312,
-       0xffffffff,
-       0xc0016900,
-       0x00000307,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000308,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000283,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000292,
+       0x3f800000,
        0x00000000,
-       0xc0066900,
-       0x0000010f,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000206,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000207,
+       0x3f800000,
        0x00000000,
-       0xc0016900,
-       0x00000208,
+       0x3f800000,
        0x00000000,
-       0xc0046900,
-       0x00000303,
        0x3f800000,
+
+       0xc0026900,
+       0x00000292,
+       0x00000000, /* PA_SC_MPASS_PS_CNTL */
+       0x00514000, /* PA_SC_MODE_CNTL */
+
+       0xc0096900,
+       0x00000300,
+       0x00000000, /* PA_SC_LINE_CNTL */
+       0x00000000, /* PA_SC_AA_CONFIG */
+       0x0000002d, /* PA_SU_VTX_CNTL */
+       0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */
        0x3f800000,
        0x3f800000,
        0x3f800000,
-       0xc0016900,
-       0x00000205,
-       0x00000004,
-       0xc0016900,
-       0x00000280,
-       0x00000000,
-       0xc0016900,
-       0x00000281,
+       0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */
        0x00000000,
+
        0xc0016900,
+       0x00000312,
+       0xffffffff, /* PA_SC_AA_MASK */
+
+       0xc0066900,
        0x0000037e,
-       0x00000000,
-       0xc0016900,
-       0x00000382,
-       0x00000000,
-       0xc0016900,
-       0x00000380,
-       0x00000000,
-       0xc0016900,
-       0x00000383,
-       0x00000000,
-       0xc0016900,
-       0x00000381,
-       0x00000000,
-       0xc0016900,
-       0x00000282,
-       0x00000008,
-       0xc0016900,
-       0x00000302,
-       0x0000002d,
-       0xc0016900,
-       0x0000037f,
-       0x00000000,
-       0xc0016900,
-       0x000001b2,
-       0x00000001,
-       0xc0016900,
+       0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */
+       0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */
+       0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */
+       0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */
+       0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */
+       0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */
+
+       0xc0046900,
        0x000001b6,
-       0x00000000,
-       0xc0016900,
-       0x000001b7,
-       0x00000000,
-       0xc0016900,
-       0x000001b8,
-       0x00000000,
-       0xc0016900,
-       0x000001b9,
-       0x00000000,
+       0x00000000, /* SPI_INPUT_Z */
+       0x00000000, /* SPI_FOG_CNTL */
+       0x00000000, /* SPI_FOG_FUNC_SCALE */
+       0x00000000, /* SPI_FOG_FUNC_BIAS */
+
        0xc0016900,
        0x00000225,
-       0x00000000,
+       0x00000000, /* SQ_PGM_START_FS */
+
        0xc0016900,
        0x00000229,
-       0x00000000,
+       0x00000000, /* SQ_PGM_RESOURCES_FS */
+
        0xc0016900,
        0x00000237,
-       0x00000000,
-       0xc0016900,
-       0x00000100,
-       0x00000800,
-       0xc0016900,
-       0x00000101,
-       0x00000000,
-       0xc0016900,
-       0x00000102,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* SQ_PGM_CF_OFFSET_FS */
+
+       0xc0026900,
        0x000002a8,
-       0x00000000,
-       0xc0016900,
-       0x000002a9,
-       0x00000000,
-       0xc0016900,
-       0x00000103,
-       0x00000000,
-       0xc0016900,
-       0x00000284,
-       0x00000000,
-       0xc0016900,
-       0x00000290,
-       0x00000000,
-       0xc0016900,
-       0x00000285,
-       0x00000000,
-       0xc0016900,
-       0x00000286,
-       0x00000000,
-       0xc0016900,
-       0x00000287,
-       0x00000000,
-       0xc0016900,
-       0x00000288,
-       0x00000000,
-       0xc0016900,
-       0x00000289,
-       0x00000000,
-       0xc0016900,
-       0x0000028a,
-       0x00000000,
-       0xc0016900,
-       0x0000028b,
-       0x00000000,
-       0xc0016900,
-       0x0000028c,
-       0x00000000,
-       0xc0016900,
-       0x0000028d,
-       0x00000000,
-       0xc0016900,
-       0x0000028e,
-       0x00000000,
-       0xc0016900,
-       0x0000028f,
-       0x00000000,
+       0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */
+       0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */
+
+       0xc0116900,
+       0x00000280,
+       0x00000000, /* PA_SU_POINT_SIZE */
+       0x00000000, /* PA_SU_POINT_MINMAX */
+       0x00000008, /* PA_SU_LINE_CNTL */
+       0x00000000, /* PA_SC_LINE_STIPPLE */
+       0x00000000, /* VGT_OUTPUT_PATH_CNTL */
+       0x00000000, /* VGT_HOS_CNTL */
+       0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */
+       0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */
+       0x00000000, /* VGT_HOS_REUSE_DEPTH */
+       0x00000000, /* VGT_GROUP_PRIM_TYPE */
+       0x00000000, /* VGT_GROUP_FIRST_DECR */
+       0x00000000, /* VGT_GROUP_DECR */
+       0x00000000, /* VGT_GROUP_VECT_0_CNTL */
+       0x00000000, /* VGT_GROUP_VECT_1_CNTL */
+       0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */
+       0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */
+       0x00000000, /* VGT_GS_MODE */
+
        0xc0016900,
        0x000002a1,
-       0x00000000,
+       0x00000000, /* VGT_PRIMITIVEID_EN */
+
        0xc0016900,
        0x000002a5,
-       0x00000000,
-       0xc0016900,
+       0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */
+
+       0xc0036900,
        0x000002ac,
-       0x00000000,
-       0xc0016900,
-       0x000002ad,
-       0x00000000,
-       0xc0016900,
-       0x000002ae,
-       0x00000000,
+       0x00000000, /* VGT_STRMOUT_EN */
+       0x00000000, /* VGT_REUSE_OFF */
+       0x00000000, /* VGT_VTX_CNT_EN */
+
        0xc0016900,
        0x000002c8,
-       0x00000000,
-       0xc0016900,
-       0x00000206,
-       0x00000100,
-       0xc0016900,
-       0x00000204,
-       0x00010000,
-       0xc0036e00,
-       0x00000000,
-       0x00000012,
-       0x00000000,
-       0x00000000,
-       0xc0016900,
-       0x0000008f,
-       0x0000000f,
-       0xc0016900,
-       0x000001e8,
-       0x00000001,
-       0xc0016900,
+       0x00000000, /* VGT_STRMOUT_BUFFER_EN */
+
+       0xc0076900,
        0x00000202,
-       0x00cc0000,
+       0x00cc0000, /* CB_COLOR_CONTROL */
+       0x00000210, /* DB_SHADER_CNTL */
+       0x00010000, /* PA_CL_CLIP_CNTL */
+       0x00000244, /* PA_SU_SC_MODE_CNTL */
+       0x00000100, /* PA_CL_VTE_CNTL */
+       0x00000000, /* PA_CL_VS_OUT_CNTL */
+       0x00000000, /* PA_CL_NANINF_CNTL */
+
+       0xc0026900,
+       0x0000008e,
+       0x0000000f, /* CB_TARGET_MASK */
+       0x0000000f, /* CB_SHADER_MASK */
+
        0xc0016900,
-       0x00000205,
-       0x00000244,
+       0x000001e8,
+       0x00000001, /* CB_SHADER_CONTROL */
+
        0xc0016900,
-       0x00000203,
-       0x00000210,
+       0x00000185,
+       0x00000000, /* SPI_VS_OUT_ID_0 */
+
        0xc0016900,
+       0x00000191,
+       0x00000b00, /* SPI_PS_INPUT_CNTL_0 */
+
+       0xc0056900,
        0x000001b1,
+       0x00000000, /* SPI_VS_OUT_CONFIG */
+       0x00000001, /* SPI_THREAD_GROUPING */
+       0x00000001, /* SPI_PS_IN_CONTROL_0 */
+       0x00000000, /* SPI_PS_IN_CONTROL_1 */
+       0x00000000, /* SPI_INTERP_CONTROL_0 */
+
+       0xc0036e00, /* SET_SAMPLER */
        0x00000000,
-       0xc0016900,
-       0x00000185,
-       0x00000000,
-       0xc0016900,
-       0x000001b3,
-       0x00000001,
-       0xc0016900,
-       0x000001b4,
+       0x00000012,
        0x00000000,
-       0xc0016900,
-       0x00000191,
-       0x00000b00,
-       0xc0016900,
-       0x000001b5,
        0x00000000,
 };
 
index 144c32d371362b0a167e1dc9bd95322ddc8614e7..c3ea212e0c3c28284271d64e617b3cebedc0e173 100644 (file)
@@ -25,6 +25,7 @@
  *          Alex Deucher
  *          Jerome Glisse
  */
+#include <linux/kernel.h>
 #include "drmP.h"
 #include "radeon.h"
 #include "r600d.h"
@@ -166,7 +167,7 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 {
        struct r600_cs_track *track = p->track;
-       u32 bpe = 0, pitch, slice_tile_max, size, tmp, height;
+       u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align;
        volatile u32 *ib = p->ib->ptr;
 
        if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
@@ -180,56 +181,57 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        i, track->cb_color_info[i]);
                return -EINVAL;
        }
-       pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) << 3;
+       /* pitch is the number of 8x8 tiles per row */
+       pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1;
        slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
-       if (!pitch) {
-               dev_warn(p->dev, "%s:%d cb pitch (%d) for %d invalid (0x%08X)\n",
-                       __func__, __LINE__, pitch, i, track->cb_color_size[i]);
-               return -EINVAL;
-       }
-       height = size / (pitch * bpe);
+       height = size / (pitch * 8 * bpe);
        if (height > 8192)
                height = 8192;
+       if (height > 7)
+               height &= ~0x7;
        switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) {
        case V_0280A0_ARRAY_LINEAR_GENERAL:
+               /* technically height & 0x7 */
+               break;
        case V_0280A0_ARRAY_LINEAR_ALIGNED:
-               if (pitch & 0x3f) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d x %d = %d) invalid\n",
-                               __func__, __LINE__, pitch, bpe, pitch * bpe);
+               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+                                __func__, __LINE__, pitch);
                        return -EINVAL;
                }
-               if ((pitch * bpe) & (track->group_size - 1)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
+               if (!IS_ALIGNED(height, 8)) {
+                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                                __func__, __LINE__, height);
                        return -EINVAL;
                }
                break;
        case V_0280A0_ARRAY_1D_TILED_THIN1:
-               if ((pitch * 8 * bpe * track->nsamples) & (track->group_size - 1)) {
+               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
                        dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
+                                __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               if (!IS_ALIGNED(height, 8)) {
+                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                                __func__, __LINE__, height);
                        return -EINVAL;
                }
-               height &= ~0x7;
-               if (!height)
-                       height = 8;
                break;
        case V_0280A0_ARRAY_2D_TILED_THIN1:
-               if (pitch & ((8 * track->nbanks) - 1)) {
+               pitch_align = max((u32)track->nbanks,
+                                 (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks));
+               if (!IS_ALIGNED(pitch, pitch_align)) {
                        dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
                                __func__, __LINE__, pitch);
                        return -EINVAL;
                }
-               tmp = pitch * 8 * bpe * track->nsamples;
-               tmp = tmp / track->nbanks;
-               if (tmp & (track->group_size - 1)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
+               if (!IS_ALIGNED((height / 8), track->nbanks)) {
+                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                                __func__, __LINE__, height);
                        return -EINVAL;
                }
-               height &= ~((16 * track->npipes) - 1);
-               if (!height)
-                       height = 16 * track->npipes;
                break;
        default:
                dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@@ -238,16 +240,20 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                return -EINVAL;
        }
        /* check offset */
-       tmp = height * pitch;
+       tmp = height * pitch * 8 * bpe;
        if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
-               dev_warn(p->dev, "%s offset[%d] %d to big\n", __func__, i, track->cb_color_bo_offset[i]);
+               dev_warn(p->dev, "%s offset[%d] %d too big\n", __func__, i, track->cb_color_bo_offset[i]);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) {
+               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]);
                return -EINVAL;
        }
        /* limit max tile */
-       tmp = (height * pitch) >> 6;
+       tmp = (height * pitch * 8) >> 6;
        if (tmp < slice_tile_max)
                slice_tile_max = tmp;
-       tmp = S_028060_PITCH_TILE_MAX((pitch >> 3) - 1) |
+       tmp = S_028060_PITCH_TILE_MAX(pitch - 1) |
                S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
        ib[track->cb_color_size_idx[i]] = tmp;
        return 0;
@@ -289,7 +295,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
        /* Check depth buffer */
        if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
                G_028800_Z_ENABLE(track->db_depth_control)) {
-               u32 nviews, bpe, ntiles;
+               u32 nviews, bpe, ntiles, pitch, pitch_align, height, size;
                if (track->db_bo == NULL) {
                        dev_warn(p->dev, "z/stencil with no depth buffer\n");
                        return -EINVAL;
@@ -332,6 +338,51 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                        }
                        ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
                } else {
+                       size = radeon_bo_size(track->db_bo);
+                       pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1;
+                       height = size / (pitch * 8 * bpe);
+                       height &= ~0x7;
+                       if (!height)
+                               height = 8;
+
+                       switch (G_028010_ARRAY_MODE(track->db_depth_info)) {
+                       case V_028010_ARRAY_1D_TILED_THIN1:
+                               pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8);
+                               if (!IS_ALIGNED(pitch, pitch_align)) {
+                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
+                                                __func__, __LINE__, pitch);
+                                       return -EINVAL;
+                               }
+                               if (!IS_ALIGNED(height, 8)) {
+                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
+                                                __func__, __LINE__, height);
+                                       return -EINVAL;
+                               }
+                               break;
+                       case V_028010_ARRAY_2D_TILED_THIN1:
+                               pitch_align = max((u32)track->nbanks,
+                                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks));
+                               if (!IS_ALIGNED(pitch, pitch_align)) {
+                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
+                                                __func__, __LINE__, pitch);
+                                       return -EINVAL;
+                               }
+                               if ((height / 8) & (track->nbanks - 1)) {
+                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
+                                                __func__, __LINE__, height);
+                                       return -EINVAL;
+                               }
+                               break;
+                       default:
+                               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                                        G_028010_ARRAY_MODE(track->db_depth_info),
+                                        track->db_depth_info);
+                               return -EINVAL;
+                       }
+                       if (!IS_ALIGNED(track->db_offset, track->group_size)) {
+                               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset);
+                               return -EINVAL;
+                       }
                        ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
                        nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
                        tmp = ntiles * bpe * 64 * nviews;
@@ -724,7 +775,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                track->db_depth_control = radeon_get_ib_value(p, idx);
                break;
        case R_028010_DB_DEPTH_INFO:
-               track->db_depth_info = radeon_get_ib_value(p, idx);
+               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+                       r = r600_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                        "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       track->db_depth_info = radeon_get_ib_value(p, idx);
+                       ib[idx] &= C_028010_ARRAY_MODE;
+                       track->db_depth_info &= C_028010_ARRAY_MODE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
+                               track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
+                       } else {
+                               ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
+                               track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
+                       }
+               } else
+                       track->db_depth_info = radeon_get_ib_value(p, idx);
                break;
        case R_028004_DB_DEPTH_VIEW:
                track->db_depth_view = radeon_get_ib_value(p, idx);
@@ -757,8 +826,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
        case R_0280B4_CB_COLOR5_INFO:
        case R_0280B8_CB_COLOR6_INFO:
        case R_0280BC_CB_COLOR7_INFO:
-               tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
-               track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+                       r = r600_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
+                       track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
+                       } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+                               ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
+                       }
+               } else {
+                       tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
+                       track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+               }
                break;
        case R_028060_CB_COLOR0_SIZE:
        case R_028064_CB_COLOR1_SIZE:
@@ -946,8 +1032,9 @@ static inline unsigned minify(unsigned size, unsigned levels)
 }
 
 static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels,
-                               unsigned w0, unsigned h0, unsigned d0, unsigned bpe,
-                               unsigned *l0_size, unsigned *mipmap_size)
+                             unsigned w0, unsigned h0, unsigned d0, unsigned bpe,
+                             unsigned pitch_align,
+                             unsigned *l0_size, unsigned *mipmap_size)
 {
        unsigned offset, i, level, face;
        unsigned width, height, depth, rowstride, size;
@@ -960,13 +1047,13 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
                height = minify(h0, i);
                depth = minify(d0, i);
                for(face = 0; face < nfaces; face++) {
-                       rowstride = ((width * bpe) + 255) & ~255;
+                       rowstride = ALIGN((width * bpe), pitch_align);
                        size = height * rowstride * depth;
                        offset += size;
                        offset = (offset + 0x1f) & ~0x1f;
                }
        }
-       *l0_size = (((w0 * bpe) + 255) & ~255) * h0 * d0;
+       *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0;
        *mipmap_size = offset;
        if (!blevel)
                *mipmap_size -= *l0_size;
@@ -985,16 +1072,23 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
  * the texture and mipmap bo object are big enough to cover this resource.
  */
 static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
-                                               struct radeon_bo *texture,
-                                               struct radeon_bo *mipmap)
+                                             struct radeon_bo *texture,
+                                             struct radeon_bo *mipmap,
+                                             u32 tiling_flags)
 {
+       struct r600_cs_track *track = p->track;
        u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0;
-       u32 word0, word1, l0_size, mipmap_size;
+       u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align;
 
        /* on legacy kernel we don't perform advanced check */
        if (p->rdev == NULL)
                return 0;
+
        word0 = radeon_get_ib_value(p, idx + 0);
+       if (tiling_flags & RADEON_TILING_MACRO)
+               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+       else if (tiling_flags & RADEON_TILING_MICRO)
+               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
        word1 = radeon_get_ib_value(p, idx + 1);
        w0 = G_038000_TEX_WIDTH(word0) + 1;
        h0 = G_038004_TEX_HEIGHT(word1) + 1;
@@ -1021,11 +1115,55 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
                         __func__, __LINE__, G_038004_DATA_FORMAT(word1));
                return -EINVAL;
        }
+
+       pitch = G_038000_PITCH(word0) + 1;
+       switch (G_038000_TILE_MODE(word0)) {
+       case V_038000_ARRAY_LINEAR_GENERAL:
+               pitch_align = 1;
+               /* XXX check height align */
+               break;
+       case V_038000_ARRAY_LINEAR_ALIGNED:
+               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                                __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               /* XXX check height align */
+               break;
+       case V_038000_ARRAY_1D_TILED_THIN1:
+               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                                __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               /* XXX check height align */
+               break;
+       case V_038000_ARRAY_2D_TILED_THIN1:
+               pitch_align = max((u32)track->nbanks,
+                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks));
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                               __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               /* XXX check height align */
+               break;
+       default:
+               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                        G_038000_TILE_MODE(word0), word0);
+               return -EINVAL;
+       }
+       /* XXX check offset align */
+
        word0 = radeon_get_ib_value(p, idx + 4);
        word1 = radeon_get_ib_value(p, idx + 5);
        blevel = G_038010_BASE_LEVEL(word0);
        nlevels = G_038014_LAST_LEVEL(word1);
-       r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, &l0_size, &mipmap_size);
+       r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe,
+                         (pitch_align * bpe),
+                         &l0_size, &mipmap_size);
        /* using get ib will give us the offset into the texture bo */
        word0 = radeon_get_ib_value(p, idx + 2);
        if ((l0_size + word0) > radeon_bo_size(texture)) {
@@ -1239,6 +1377,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                        return -EINVAL;
                                }
                                ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+                               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+                               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
                                texture = reloc->robj;
                                /* tex mip base */
                                r = r600_cs_packet_next_reloc(p, &reloc);
@@ -1249,7 +1391,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                                mipmap = reloc->robj;
                                r = r600_check_texture_resource(p,  idx+(i*7)+1,
-                                               texture, mipmap);
+                                                               texture, mipmap, reloc->lobj.tiling_flags);
                                if (r)
                                        return r;
                                break;
index 26b4bc9d89a574d048dfcfc190e5c11b2de341ee..e6a58ed48dcf255d70189306551d4bddc91db22e 100644 (file)
@@ -435,7 +435,8 @@ static int r600_hdmi_find_free_block(struct drm_device *dev)
                }
        }
 
-       if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
+       if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 ||
+           rdev->family == CHIP_RS740) {
                return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
        } else if (rdev->family >= CHIP_R600) {
                if (free_blocks[0])
@@ -466,7 +467,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder)
                if (ASIC_IS_DCE32(rdev))
                        radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
                                R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
-       } else if (rdev->family >= CHIP_R600) {
+       } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 ||
+                  rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
                radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
        }
 }
index 59c1f8793e608df971466a9545ccc32c81e529fd..858a1920c0d76bb2c916c847c8b2751058d7e9d5 100644 (file)
 #define        GRBM_SOFT_RESET                                 0x8020
 #define                SOFT_RESET_CP                                   (1<<0)
 
+#define        CG_THERMAL_STATUS                               0x7F4
+#define                ASIC_T(x)                               ((x) << 0)
+#define                ASIC_T_MASK                             0x1FF
+#define                ASIC_T_SHIFT                            0
+
 #define        HDP_HOST_PATH_CNTL                              0x2C00
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08
 #define        HDP_NONSURFACE_SIZE                             0x2C0C
 #define HDP_REG_COHERENCY_FLUSH_CNTL                   0x54A0
 #define        HDP_TILING_CONFIG                               0x2F3C
+#define HDP_DEBUG1                                      0x2F34
 
 #define MC_VM_AGP_TOP                                  0x2184
 #define MC_VM_AGP_BOT                                  0x2188
 #define   S_038000_TILE_MODE(x)                        (((x) & 0xF) << 3)
 #define   G_038000_TILE_MODE(x)                        (((x) >> 3) & 0xF)
 #define   C_038000_TILE_MODE                           0xFFFFFF87
+#define     V_038000_ARRAY_LINEAR_GENERAL              0x00000000
+#define     V_038000_ARRAY_LINEAR_ALIGNED              0x00000001
+#define     V_038000_ARRAY_1D_TILED_THIN1              0x00000002
+#define     V_038000_ARRAY_2D_TILED_THIN1              0x00000004
 #define   S_038000_TILE_TYPE(x)                        (((x) & 0x1) << 7)
 #define   G_038000_TILE_TYPE(x)                        (((x) >> 7) & 0x1)
 #define   C_038000_TILE_TYPE                           0xFFFFFF7F
 #define   S_028010_ARRAY_MODE(x)                       (((x) & 0xF) << 15)
 #define   G_028010_ARRAY_MODE(x)                       (((x) >> 15) & 0xF)
 #define   C_028010_ARRAY_MODE                          0xFFF87FFF
+#define     V_028010_ARRAY_1D_TILED_THIN1              0x00000002
+#define     V_028010_ARRAY_2D_TILED_THIN1              0x00000004
 #define   S_028010_TILE_SURFACE_ENABLE(x)              (((x) & 0x1) << 25)
 #define   G_028010_TILE_SURFACE_ENABLE(x)              (((x) >> 25) & 0x1)
 #define   C_028010_TILE_SURFACE_ENABLE                 0xFDFFFFFF
index 2f94dc66c1836f4bf5d6814bb51b5730a13945ad..3cd1c470b7770639c44151d6c9d627da435db07e 100644 (file)
@@ -178,6 +178,9 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev);
 void radeon_atombios_get_power_modes(struct radeon_device *rdev);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level);
 void rs690_pm_info(struct radeon_device *rdev);
+extern u32 rv6xx_get_temp(struct radeon_device *rdev);
+extern u32 rv770_get_temp(struct radeon_device *rdev);
+extern u32 evergreen_get_temp(struct radeon_device *rdev);
 
 /*
  * Fences.
@@ -232,7 +235,7 @@ struct radeon_surface_reg {
  */
 struct radeon_mman {
        struct ttm_bo_global_ref        bo_global_ref;
-       struct ttm_global_reference     mem_global_ref;
+       struct drm_global_reference     mem_global_ref;
        struct ttm_bo_device            bdev;
        bool                            mem_global_referenced;
        bool                            initialized;
@@ -671,6 +674,13 @@ struct radeon_pm_profile {
        int dpms_on_cm_idx;
 };
 
+enum radeon_int_thermal_type {
+       THERMAL_TYPE_NONE,
+       THERMAL_TYPE_RV6XX,
+       THERMAL_TYPE_RV770,
+       THERMAL_TYPE_EVERGREEN,
+};
+
 struct radeon_voltage {
        enum radeon_voltage_type type;
        /* gpio voltage */
@@ -766,6 +776,9 @@ struct radeon_pm {
        enum radeon_pm_profile_type profile;
        int                     profile_index;
        struct radeon_pm_profile profiles[PM_PROFILE_MAX];
+       /* internal thermal controller on rv6xx+ */
+       enum radeon_int_thermal_type int_thermal_type;
+       struct device           *int_hwmon_dev;
 };
 
 
@@ -902,6 +915,7 @@ struct r600_asic {
        unsigned                tiling_nbanks;
        unsigned                tiling_npipes;
        unsigned                tiling_group_size;
+       unsigned                tile_config;
        struct r100_gpu_lockup  lockup;
 };
 
@@ -926,6 +940,7 @@ struct rv770_asic {
        unsigned                tiling_nbanks;
        unsigned                tiling_npipes;
        unsigned                tiling_group_size;
+       unsigned                tile_config;
        struct r100_gpu_lockup  lockup;
 };
 
@@ -951,6 +966,7 @@ struct evergreen_asic {
        unsigned tiling_nbanks;
        unsigned tiling_npipes;
        unsigned tiling_group_size;
+       unsigned tile_config;
 };
 
 union radeon_asic_config {
@@ -1033,6 +1049,9 @@ struct radeon_device {
        uint32_t                        pcie_reg_mask;
        radeon_rreg_t                   pciep_rreg;
        radeon_wreg_t                   pciep_wreg;
+       /* io port */
+       void __iomem                    *rio_mem;
+       resource_size_t                 rio_mem_size;
        struct radeon_clock             clock;
        struct radeon_mc                mc;
        struct radeon_gart              gart;
@@ -1069,6 +1088,7 @@ struct radeon_device {
        struct mutex vram_mutex;
 
        /* audio stuff */
+       bool                    audio_enabled;
        struct timer_list       audio_timer;
        int                     audio_channels;
        int                     audio_rate;
@@ -1078,6 +1098,8 @@ struct radeon_device {
 
        bool powered_down;
        struct notifier_block acpi_nb;
+       /* only one userspace can use Hyperz features at a time */
+       struct drm_file *hyperz_filp;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -1114,6 +1136,26 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
        }
 }
 
+static inline u32 r100_io_rreg(struct radeon_device *rdev, u32 reg)
+{
+       if (reg < rdev->rio_mem_size)
+               return ioread32(rdev->rio_mem + reg);
+       else {
+               iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX);
+               return ioread32(rdev->rio_mem + RADEON_MM_DATA);
+       }
+}
+
+static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+       if (reg < rdev->rio_mem_size)
+               iowrite32(v, rdev->rio_mem + reg);
+       else {
+               iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX);
+               iowrite32(v, rdev->rio_mem + RADEON_MM_DATA);
+       }
+}
+
 /*
  * Cast helper
  */
@@ -1152,6 +1194,8 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
                WREG32_PLL(reg, tmp_);                          \
        } while (0)
 #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg)))
+#define RREG32_IO(reg) r100_io_rreg(rdev, (reg))
+#define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v))
 
 /*
  * Indirect registers accessor
@@ -1415,6 +1459,13 @@ extern void r700_cp_fini(struct radeon_device *rdev);
 extern void evergreen_disable_interrupt_state(struct radeon_device *rdev);
 extern int evergreen_irq_set(struct radeon_device *rdev);
 
+/* radeon_acpi.c */ 
+#if defined(CONFIG_ACPI) 
+extern int radeon_acpi_init(struct radeon_device *rdev); 
+#else 
+static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } 
+#endif 
+
 /* evergreen */
 struct evergreen_mc_save {
        u32 vga_control[6];
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
new file mode 100644 (file)
index 0000000..3f6636b
--- /dev/null
@@ -0,0 +1,67 @@
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/slab.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "drm_crtc_helper.h"
+#include "radeon.h"
+
+#include <linux/vga_switcheroo.h>
+
+/* Call the ATIF method
+ *
+ * Note: currently we discard the output
+ */
+static int radeon_atif_call(acpi_handle handle)
+{
+       acpi_status status;
+       union acpi_object atif_arg_elements[2];
+       struct acpi_object_list atif_arg;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+       atif_arg.count = 2;
+       atif_arg.pointer = &atif_arg_elements[0];
+
+       atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
+       atif_arg_elements[0].integer.value = 0;
+       atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
+       atif_arg_elements[1].integer.value = 0;
+
+       status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
+
+       /* Fail only if calling the method fails and ATIF is supported */
+       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+               printk(KERN_DEBUG "failed to evaluate ATIF got %s\n", acpi_format_exception(status));
+               kfree(buffer.pointer);
+               return 1;
+       }
+
+       kfree(buffer.pointer);
+       return 0;
+}
+
+/* Call all ACPI methods here */
+int radeon_acpi_init(struct radeon_device *rdev)
+{
+       acpi_handle handle;
+       int ret;
+
+       /* No need to proceed if we're sure that ATIF is not supported */
+       if (!ASIC_IS_AVIVO(rdev) || !rdev->bios)
+               return 0;
+
+       /* Get the device handle */
+       handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
+
+       /* Call the ATIF method */
+       ret = radeon_atif_call(handle);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
index c0bbaa64157a466efb81990431903dc8fbe2dc33..a5aff755f0d2e185dbdd4a1efd541dea5dae78fa 100644 (file)
@@ -113,6 +113,7 @@ void r100_wb_fini(struct radeon_device *rdev);
 int r100_wb_init(struct radeon_device *rdev);
 int r100_cp_reset(struct radeon_device *rdev);
 void r100_vga_render_disable(struct radeon_device *rdev);
+void r100_restore_sanity(struct radeon_device *rdev);
 int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
                                         struct radeon_cs_packet *pkt,
                                         struct radeon_bo *robj);
index 10673ae59cfa10ee8e408de3a9f84e54e2cab7ed..3bc2bcdf530815635c351743a6db7b95f1688462 100644 (file)
@@ -723,7 +723,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
                }
 
                if (i == ATOM_DEVICE_CV_INDEX) {
-                       DRM_DEBUG("Skipping Component Video\n");
+                       DRM_DEBUG_KMS("Skipping Component Video\n");
                        continue;
                }
 
@@ -1032,21 +1032,18 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)
        u8 frev, crev;
        u16 data_offset;
 
+       /* sideport is AMD only */
+       if (rdev->family == CHIP_RS600)
+               return false;
+
        if (atom_parse_data_header(mode_info->atom_context, index, NULL,
                                   &frev, &crev, &data_offset)) {
                igp_info = (union igp_info *)(mode_info->atom_context->bios +
                                      data_offset);
                switch (crev) {
                case 1:
-                       /* AMD IGPS */
-                       if ((rdev->family == CHIP_RS690) ||
-                           (rdev->family == CHIP_RS740)) {
-                               if (igp_info->info.ulBootUpMemoryClock)
-                                       return true;
-                       } else {
-                               if (igp_info->info.ucMemoryType & 0xf0)
-                                       return true;
-                       }
+                       if (igp_info->info.ulBootUpMemoryClock)
+                               return true;
                        break;
                case 2:
                        if (igp_info->info_2.ucMemoryType & 0x0f)
@@ -1095,7 +1092,7 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
                            (tmds_info->asMiscInfo[i].
                             ucPLL_VoltageSwing & 0xf) << 16;
 
-                       DRM_DEBUG("TMDS PLL From ATOMBIOS %u %x\n",
+                       DRM_DEBUG_KMS("TMDS PLL From ATOMBIOS %u %x\n",
                                  tmds->tmds_pll[i].freq,
                                  tmds->tmds_pll[i].value);
 
@@ -1789,14 +1786,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                        }
 
                        /* add the i2c bus for thermal/fan chip */
-                       /* no support for internal controller yet */
                        if (controller->ucType > 0) {
-                               if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) ||
-                                   (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) ||
-                                   (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN)) {
+                               if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
+                                       DRM_INFO("Internal thermal controller %s fan control\n",
+                                                (controller->ucFanParameters &
+                                                 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                                       rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;
+                               } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
+                                       DRM_INFO("Internal thermal controller %s fan control\n",
+                                                (controller->ucFanParameters &
+                                                 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                                       rdev->pm.int_thermal_type = THERMAL_TYPE_RV770;
+                               } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
                                        DRM_INFO("Internal thermal controller %s fan control\n",
                                                 (controller->ucFanParameters &
                                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                                       rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
                                } else if ((controller->ucType ==
                                            ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) ||
                                           (controller->ucType ==
@@ -2179,11 +2184,11 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("TV1 connected\n");
+                       DRM_DEBUG_KMS("TV1 connected\n");
                        bios_3_scratch |= ATOM_S3_TV1_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_TV1;
                } else {
-                       DRM_DEBUG("TV1 disconnected\n");
+                       DRM_DEBUG_KMS("TV1 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_TV1_MASK;
                        bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1;
@@ -2192,11 +2197,11 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("CV connected\n");
+                       DRM_DEBUG_KMS("CV connected\n");
                        bios_3_scratch |= ATOM_S3_CV_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_CV;
                } else {
-                       DRM_DEBUG("CV disconnected\n");
+                       DRM_DEBUG_KMS("CV disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_CV_MASK;
                        bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV;
@@ -2205,12 +2210,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("LCD1 connected\n");
+                       DRM_DEBUG_KMS("LCD1 connected\n");
                        bios_0_scratch |= ATOM_S0_LCD1;
                        bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1;
                } else {
-                       DRM_DEBUG("LCD1 disconnected\n");
+                       DRM_DEBUG_KMS("LCD1 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_LCD1;
                        bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1;
@@ -2219,12 +2224,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("CRT1 connected\n");
+                       DRM_DEBUG_KMS("CRT1 connected\n");
                        bios_0_scratch |= ATOM_S0_CRT1_COLOR;
                        bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1;
                } else {
-                       DRM_DEBUG("CRT1 disconnected\n");
+                       DRM_DEBUG_KMS("CRT1 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_CRT1_MASK;
                        bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1;
@@ -2233,12 +2238,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("CRT2 connected\n");
+                       DRM_DEBUG_KMS("CRT2 connected\n");
                        bios_0_scratch |= ATOM_S0_CRT2_COLOR;
                        bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2;
                } else {
-                       DRM_DEBUG("CRT2 disconnected\n");
+                       DRM_DEBUG_KMS("CRT2 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_CRT2_MASK;
                        bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2;
@@ -2247,12 +2252,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("DFP1 connected\n");
+                       DRM_DEBUG_KMS("DFP1 connected\n");
                        bios_0_scratch |= ATOM_S0_DFP1;
                        bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1;
                } else {
-                       DRM_DEBUG("DFP1 disconnected\n");
+                       DRM_DEBUG_KMS("DFP1 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_DFP1;
                        bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1;
@@ -2261,12 +2266,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("DFP2 connected\n");
+                       DRM_DEBUG_KMS("DFP2 connected\n");
                        bios_0_scratch |= ATOM_S0_DFP2;
                        bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2;
                } else {
-                       DRM_DEBUG("DFP2 disconnected\n");
+                       DRM_DEBUG_KMS("DFP2 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_DFP2;
                        bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2;
@@ -2275,12 +2280,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("DFP3 connected\n");
+                       DRM_DEBUG_KMS("DFP3 connected\n");
                        bios_0_scratch |= ATOM_S0_DFP3;
                        bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3;
                } else {
-                       DRM_DEBUG("DFP3 disconnected\n");
+                       DRM_DEBUG_KMS("DFP3 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_DFP3;
                        bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3;
@@ -2289,12 +2294,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("DFP4 connected\n");
+                       DRM_DEBUG_KMS("DFP4 connected\n");
                        bios_0_scratch |= ATOM_S0_DFP4;
                        bios_3_scratch |= ATOM_S3_DFP4_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4;
                } else {
-                       DRM_DEBUG("DFP4 disconnected\n");
+                       DRM_DEBUG_KMS("DFP4 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_DFP4;
                        bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4;
@@ -2303,12 +2308,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("DFP5 connected\n");
+                       DRM_DEBUG_KMS("DFP5 connected\n");
                        bios_0_scratch |= ATOM_S0_DFP5;
                        bios_3_scratch |= ATOM_S3_DFP5_ACTIVE;
                        bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5;
                } else {
-                       DRM_DEBUG("DFP5 disconnected\n");
+                       DRM_DEBUG_KMS("DFP5 disconnected\n");
                        bios_0_scratch &= ~ATOM_S0_DFP5;
                        bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE;
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5;
index 2c92137399995f17d9df664c2ae28aa9ad8bbefa..654787ec43f4d33687f2c7dd0e0318c17be92dd6 100644 (file)
@@ -53,7 +53,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
                        return false;
 
        rdev->bios = NULL;
-       vram_base = drm_get_resource_start(rdev->ddev, 0);
+       vram_base = pci_resource_start(rdev->pdev, 0);
        bios = ioremap(vram_base, size);
        if (!bios) {
                return false;
index 2417d7b06fdb6dae3a6f486fad9a37a6e967b4ed..5e1474cde4b4245b7ce8c6b6968da03568a6dc5f 100644 (file)
@@ -693,6 +693,10 @@ bool radeon_combios_sideport_present(struct radeon_device *rdev)
        struct drm_device *dev = rdev->ddev;
        u16 igp_info;
 
+       /* sideport is AMD only */
+       if (rdev->family == CHIP_RS400)
+               return false;
+
        igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE);
 
        if (igp_info) {
@@ -1205,7 +1209,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
                                    RBIOS32(tmds_info + i * 10 + 0x08);
                                tmds->tmds_pll[i].freq =
                                    RBIOS16(tmds_info + i * 10 + 0x10);
-                               DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n",
+                               DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
                                          tmds->tmds_pll[i].freq,
                                          tmds->tmds_pll[i].value);
                        }
@@ -1223,7 +1227,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
                                        stride += 10;
                                else
                                        stride += 6;
-                               DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n",
+                               DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
                                          tmds->tmds_pll[i].freq,
                                          tmds->tmds_pll[i].value);
                        }
@@ -2208,7 +2212,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                uint16_t tmds_info =
                    combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
                if (tmds_info) {
-                       DRM_DEBUG("Found DFP table, assuming DVI connector\n");
+                       DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n");
 
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
@@ -2234,7 +2238,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                } else {
                        uint16_t crt_info =
                                combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
-                       DRM_DEBUG("Found CRT table, assuming VGA connector\n");
+                       DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n");
                        if (crt_info) {
                                radeon_add_legacy_encoder(dev,
                                                          radeon_get_encoder_id(dev,
@@ -2251,7 +2255,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            CONNECTOR_OBJECT_ID_VGA,
                                                            &hpd);
                        } else {
-                               DRM_DEBUG("No connector info found\n");
+                               DRM_DEBUG_KMS("No connector info found\n");
                                return false;
                        }
                }
@@ -2340,7 +2344,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                        ddc_i2c.valid = false;
                                        break;
                                }
-                               DRM_DEBUG("LCD DDC Info Table found!\n");
+                               DRM_DEBUG_KMS("LCD DDC Info Table found!\n");
                        } else
                                ddc_i2c.valid = false;
 
@@ -2941,9 +2945,8 @@ static void combios_write_ram_size(struct drm_device *dev)
                if (rev < 3) {
                        mem_cntl = RBIOS32(offset + 1);
                        mem_size = RBIOS16(offset + 5);
-                       if (((rdev->flags & RADEON_FAMILY_MASK) < CHIP_R200) &&
-                           ((dev->pdev->device != 0x515e)
-                            && (dev->pdev->device != 0x5969)))
+                       if ((rdev->family < CHIP_R200) &&
+                           !ASIC_IS_RN50(rdev))
                                WREG32(RADEON_MEM_CNTL, mem_cntl);
                }
        }
@@ -2954,10 +2957,8 @@ static void combios_write_ram_size(struct drm_device *dev)
                if (offset) {
                        rev = RBIOS8(offset - 1);
                        if (rev < 1) {
-                               if (((rdev->flags & RADEON_FAMILY_MASK) <
-                                    CHIP_R200)
-                                   && ((dev->pdev->device != 0x515e)
-                                       && (dev->pdev->device != 0x5969))) {
+                               if ((rdev->family < CHIP_R200)
+                                   && !ASIC_IS_RN50(rdev)) {
                                        int ram = 0;
                                        int mem_addr_mapping = 0;
 
@@ -3121,14 +3122,14 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("TV1 connected\n");
+                       DRM_DEBUG_KMS("TV1 connected\n");
                        /* fix me */
                        bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
                        /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */
                        bios_5_scratch |= RADEON_TV1_ON;
                        bios_5_scratch |= RADEON_ACC_REQ_TV1;
                } else {
-                       DRM_DEBUG("TV1 disconnected\n");
+                       DRM_DEBUG_KMS("TV1 disconnected\n");
                        bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK;
                        bios_5_scratch &= ~RADEON_TV1_ON;
                        bios_5_scratch &= ~RADEON_ACC_REQ_TV1;
@@ -3137,12 +3138,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("LCD1 connected\n");
+                       DRM_DEBUG_KMS("LCD1 connected\n");
                        bios_4_scratch |= RADEON_LCD1_ATTACHED;
                        bios_5_scratch |= RADEON_LCD1_ON;
                        bios_5_scratch |= RADEON_ACC_REQ_LCD1;
                } else {
-                       DRM_DEBUG("LCD1 disconnected\n");
+                       DRM_DEBUG_KMS("LCD1 disconnected\n");
                        bios_4_scratch &= ~RADEON_LCD1_ATTACHED;
                        bios_5_scratch &= ~RADEON_LCD1_ON;
                        bios_5_scratch &= ~RADEON_ACC_REQ_LCD1;
@@ -3151,12 +3152,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("CRT1 connected\n");
+                       DRM_DEBUG_KMS("CRT1 connected\n");
                        bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
                        bios_5_scratch |= RADEON_CRT1_ON;
                        bios_5_scratch |= RADEON_ACC_REQ_CRT1;
                } else {
-                       DRM_DEBUG("CRT1 disconnected\n");
+                       DRM_DEBUG_KMS("CRT1 disconnected\n");
                        bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
                        bios_5_scratch &= ~RADEON_CRT1_ON;
                        bios_5_scratch &= ~RADEON_ACC_REQ_CRT1;
@@ -3165,12 +3166,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("CRT2 connected\n");
+                       DRM_DEBUG_KMS("CRT2 connected\n");
                        bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
                        bios_5_scratch |= RADEON_CRT2_ON;
                        bios_5_scratch |= RADEON_ACC_REQ_CRT2;
                } else {
-                       DRM_DEBUG("CRT2 disconnected\n");
+                       DRM_DEBUG_KMS("CRT2 disconnected\n");
                        bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
                        bios_5_scratch &= ~RADEON_CRT2_ON;
                        bios_5_scratch &= ~RADEON_ACC_REQ_CRT2;
@@ -3179,12 +3180,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("DFP1 connected\n");
+                       DRM_DEBUG_KMS("DFP1 connected\n");
                        bios_4_scratch |= RADEON_DFP1_ATTACHED;
                        bios_5_scratch |= RADEON_DFP1_ON;
                        bios_5_scratch |= RADEON_ACC_REQ_DFP1;
                } else {
-                       DRM_DEBUG("DFP1 disconnected\n");
+                       DRM_DEBUG_KMS("DFP1 disconnected\n");
                        bios_4_scratch &= ~RADEON_DFP1_ATTACHED;
                        bios_5_scratch &= ~RADEON_DFP1_ON;
                        bios_5_scratch &= ~RADEON_ACC_REQ_DFP1;
@@ -3193,12 +3194,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector,
        if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
            (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
                if (connected) {
-                       DRM_DEBUG("DFP2 connected\n");
+                       DRM_DEBUG_KMS("DFP2 connected\n");
                        bios_4_scratch |= RADEON_DFP2_ATTACHED;
                        bios_5_scratch |= RADEON_DFP2_ON;
                        bios_5_scratch |= RADEON_ACC_REQ_DFP2;
                } else {
-                       DRM_DEBUG("DFP2 disconnected\n");
+                       DRM_DEBUG_KMS("DFP2 disconnected\n");
                        bios_4_scratch &= ~RADEON_DFP2_ATTACHED;
                        bios_5_scratch &= ~RADEON_DFP2_ON;
                        bios_5_scratch &= ~RADEON_ACC_REQ_DFP2;
index adccbc2c202c6b01e22cca3f1ae27dc0334e351b..2395c8600cf44d721644eef4d8648946512b1afb 100644 (file)
@@ -214,7 +214,7 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
                mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
                drm_mode_set_name(mode);
 
-               DRM_DEBUG("Adding native panel mode %s\n", mode->name);
+               DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name);
        } else if (native_mode->hdisplay != 0 &&
                   native_mode->vdisplay != 0) {
                /* mac laptops without an edid */
@@ -226,7 +226,7 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
                 */
                mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);
                mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
-               DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name);
+               DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name);
        }
        return mode;
 }
@@ -312,6 +312,20 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
                }
        }
 
+       if (property == rdev->mode_info.underscan_property) {
+               /* need to find digital encoder on connector */
+               encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
+               if (!encoder)
+                       return 0;
+
+               radeon_encoder = to_radeon_encoder(encoder);
+
+               if (radeon_encoder->underscan_type != val) {
+                       radeon_encoder->underscan_type = val;
+                       radeon_property_change_mode(&radeon_encoder->base);
+               }
+       }
+
        if (property == rdev->mode_info.tv_std_property) {
                encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC);
                if (!encoder) {
@@ -522,7 +536,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector,
        struct radeon_encoder *radeon_encoder;
        enum radeon_rmx_type rmx_type;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
        if (property != dev->mode_config.scaling_mode_property)
                return 0;
 
@@ -1082,6 +1096,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              rdev->mode_info.load_detect_property,
                                              1);
+               /* no HPD on analog connectors */
+               radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
                break;
        case DRM_MODE_CONNECTOR_DVIA:
@@ -1096,6 +1112,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              rdev->mode_info.load_detect_property,
                                              1);
+               /* no HPD on analog connectors */
+               radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                break;
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_DVID:
@@ -1116,6 +1134,10 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              rdev->mode_info.coherent_mode_property,
                                              1);
+               if (ASIC_IS_AVIVO(rdev))
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     rdev->mode_info.underscan_property,
+                                                     UNDERSCAN_AUTO);
                if (connector_type == DRM_MODE_CONNECTOR_DVII) {
                        radeon_connector->dac_load_detect = true;
                        drm_connector_attach_property(&radeon_connector->base,
@@ -1141,6 +1163,10 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              rdev->mode_info.coherent_mode_property,
                                              1);
+               if (ASIC_IS_AVIVO(rdev))
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     rdev->mode_info.underscan_property,
+                                                     UNDERSCAN_AUTO);
                subpixel_order = SubPixelHorizontalRGB;
                break;
        case DRM_MODE_CONNECTOR_DisplayPort:
@@ -1172,6 +1198,10 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              rdev->mode_info.coherent_mode_property,
                                              1);
+               if (ASIC_IS_AVIVO(rdev))
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     rdev->mode_info.underscan_property,
+                                                     UNDERSCAN_AUTO);
                break;
        case DRM_MODE_CONNECTOR_SVIDEO:
        case DRM_MODE_CONNECTOR_Composite:
@@ -1186,6 +1216,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                        drm_connector_attach_property(&radeon_connector->base,
                                                      rdev->mode_info.tv_std_property,
                                                      radeon_atombios_get_tv_info(rdev));
+                       /* no HPD on analog connectors */
+                       radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                }
                break;
        case DRM_MODE_CONNECTOR_LVDS:
@@ -1209,7 +1241,7 @@ radeon_add_atom_connector(struct drm_device *dev,
                break;
        }
 
-       if (hpd->hpd == RADEON_HPD_NONE) {
+       if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
                if (i2c_bus->valid)
                        connector->polled = DRM_CONNECTOR_POLL_CONNECT;
        } else
@@ -1276,6 +1308,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              rdev->mode_info.load_detect_property,
                                              1);
+               /* no HPD on analog connectors */
+               radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
                break;
        case DRM_MODE_CONNECTOR_DVIA:
@@ -1290,6 +1324,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              rdev->mode_info.load_detect_property,
                                              1);
+               /* no HPD on analog connectors */
+               radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                break;
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_DVID:
@@ -1328,6 +1364,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                        drm_connector_attach_property(&radeon_connector->base,
                                                      rdev->mode_info.tv_std_property,
                                                      radeon_combios_get_tv_info(rdev));
+                       /* no HPD on analog connectors */
+                       radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                }
                break;
        case DRM_MODE_CONNECTOR_LVDS:
@@ -1345,7 +1383,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
                break;
        }
 
-       if (hpd->hpd == RADEON_HPD_NONE) {
+       if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
                if (i2c_bus->valid)
                        connector->polled = DRM_CONNECTOR_POLL_CONNECT;
        } else
index 2f042a3c0e62bb7bbe86fefa478109be033f1bb8..eb6b9eed7349264f29e5f498221b127942f51ec2 100644 (file)
@@ -2120,8 +2120,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
        else
                dev_priv->flags |= RADEON_IS_PCI;
 
-       ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
-                        drm_get_resource_len(dev, 2), _DRM_REGISTERS,
+       ret = drm_addmap(dev, pci_resource_start(dev->pdev, 2),
+                        pci_resource_len(dev->pdev, 2), _DRM_REGISTERS,
                         _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio);
        if (ret != 0)
                return ret;
@@ -2194,9 +2194,9 @@ int radeon_driver_firstopen(struct drm_device *dev)
 
        dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
 
-       dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
+       dev_priv->fb_aper_offset = pci_resource_start(dev->pdev, 0);
        ret = drm_addmap(dev, dev_priv->fb_aper_offset,
-                        drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
+                        pci_resource_len(dev->pdev, 0), _DRM_FRAME_BUFFER,
                         _DRM_WRITE_COMBINING, &map);
        if (ret != 0)
                return ret;
index dd279da90546ee03929b02b8bd7095683ef31caf..a64811a94519a1ce5bd245d7f2c864e0d68ecf3d 100644 (file)
@@ -415,6 +415,22 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
        return r;
 }
 
+static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val)
+{
+       struct radeon_device *rdev = info->dev->dev_private;
+
+       WREG32_IO(reg*4, val);
+}
+
+static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
+{
+       struct radeon_device *rdev = info->dev->dev_private;
+       uint32_t r;
+
+       r = RREG32_IO(reg*4);
+       return r;
+}
+
 int radeon_atombios_init(struct radeon_device *rdev)
 {
        struct card_info *atom_card_info =
@@ -427,6 +443,15 @@ int radeon_atombios_init(struct radeon_device *rdev)
        atom_card_info->dev = rdev->ddev;
        atom_card_info->reg_read = cail_reg_read;
        atom_card_info->reg_write = cail_reg_write;
+       /* needed for iio ops */
+       if (rdev->rio_mem) {
+               atom_card_info->ioreg_read = cail_ioreg_read;
+               atom_card_info->ioreg_write = cail_ioreg_write;
+       } else {
+               DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n");
+               atom_card_info->ioreg_read = cail_reg_read;
+               atom_card_info->ioreg_write = cail_reg_write;
+       }
        atom_card_info->mc_read = cail_mc_read;
        atom_card_info->mc_write = cail_mc_write;
        atom_card_info->pll_read = cail_pll_read;
@@ -573,7 +598,7 @@ int radeon_device_init(struct radeon_device *rdev,
                       struct pci_dev *pdev,
                       uint32_t flags)
 {
-       int r;
+       int r, i;
        int dma_bits;
 
        rdev->shutdown = false;
@@ -650,8 +675,8 @@ int radeon_device_init(struct radeon_device *rdev,
 
        /* Registers mapping */
        /* TODO: block userspace mapping of io register */
-       rdev->rmmio_base = drm_get_resource_start(rdev->ddev, 2);
-       rdev->rmmio_size = drm_get_resource_len(rdev->ddev, 2);
+       rdev->rmmio_base = pci_resource_start(rdev->pdev, 2);
+       rdev->rmmio_size = pci_resource_len(rdev->pdev, 2);
        rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size);
        if (rdev->rmmio == NULL) {
                return -ENOMEM;
@@ -659,6 +684,17 @@ int radeon_device_init(struct radeon_device *rdev,
        DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
        DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
 
+       /* io port mapping */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) {
+                       rdev->rio_mem_size = pci_resource_len(rdev->pdev, i);
+                       rdev->rio_mem = pci_iomap(rdev->pdev, i, rdev->rio_mem_size);
+                       break;
+               }
+       }
+       if (rdev->rio_mem == NULL)
+               DRM_ERROR("Unable to find PCI I/O BAR\n");
+
        /* if we have > 1 VGA cards, then disable the radeon VGA resources */
        /* this will fail for cards that aren't VGA class devices, just
         * ignore it */
@@ -701,6 +737,9 @@ void radeon_device_fini(struct radeon_device *rdev)
        destroy_workqueue(rdev->wq);
        vga_switcheroo_unregister_client(rdev->pdev);
        vga_client_register(rdev->pdev, NULL, NULL, NULL);
+       if (rdev->rio_mem)
+               pci_iounmap(rdev->pdev, rdev->rio_mem);
+       rdev->rio_mem = NULL;
        iounmap(rdev->rmmio);
        rdev->rmmio = NULL;
 }
index 8154cdf796e4a752a0a33d6983852cabee7acf4a..74dac9635d7010ac4d3dc2cc715922d4da2d7974 100644 (file)
@@ -42,7 +42,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
        struct radeon_device *rdev = dev->dev_private;
        int i;
 
-       DRM_DEBUG("%d\n", radeon_crtc->crtc_id);
+       DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
        WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0);
 
        WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
@@ -75,7 +75,7 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
        struct radeon_device *rdev = dev->dev_private;
        int i;
 
-       DRM_DEBUG("%d\n", radeon_crtc->crtc_id);
+       DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
        WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
 
        WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
@@ -469,7 +469,7 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
        uint32_t post_div;
        u32 pll_out_min, pll_out_max;
 
-       DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
+       DRM_DEBUG_KMS("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
        freq = freq * 1000;
 
        if (pll->flags & RADEON_PLL_IS_LCD) {
@@ -558,15 +558,17 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
                                        current_freq = radeon_div(tmp, ref_div * post_div);
 
                                        if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
-                                               error = freq - current_freq;
-                                               error = error < 0 ? 0xffffffff : error;
+                                               if (freq < current_freq)
+                                                       error = 0xffffffff;
+                                               else
+                                                       error = freq - current_freq;
                                        } else
                                                error = abs(current_freq - freq);
                                        vco_diff = abs(vco - best_vco);
 
                                        if ((best_vco == 0 && error < best_error) ||
                                            (best_vco != 0 &&
-                                            (error < best_error - 100 ||
+                                            ((best_error > 100 && error < best_error - 100) ||
                                              (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) {
                                                best_post_div = post_div;
                                                best_ref_div = ref_div;
@@ -803,7 +805,7 @@ done:
        *ref_div_p = ref_div;
        *post_div_p = post_div;
 
-       DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
+       DRM_DEBUG_KMS("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
 }
 
 void radeon_compute_pll(struct radeon_pll *pll,
@@ -919,6 +921,12 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
        { TV_STD_SECAM, "secam" },
 };
 
+static struct drm_prop_enum_list radeon_underscan_enum_list[] =
+{      { UNDERSCAN_OFF, "off" },
+       { UNDERSCAN_ON, "on" },
+       { UNDERSCAN_AUTO, "auto" },
+};
+
 static int radeon_modeset_create_props(struct radeon_device *rdev)
 {
        int i, sz;
@@ -972,6 +980,18 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
                                      radeon_tv_std_enum_list[i].name);
        }
 
+       sz = ARRAY_SIZE(radeon_underscan_enum_list);
+       rdev->mode_info.underscan_property =
+               drm_property_create(rdev->ddev,
+                                   DRM_MODE_PROP_ENUM,
+                                   "underscan", sz);
+       for (i = 0; i < sz; i++) {
+               drm_property_add_enum(rdev->mode_info.underscan_property,
+                                     i,
+                                     radeon_underscan_enum_list[i].type,
+                                     radeon_underscan_enum_list[i].name);
+       }
+
        return 0;
 }
 
@@ -1067,15 +1087,26 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
                                struct drm_display_mode *adjusted_mode)
 {
        struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *encoder;
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct radeon_encoder *radeon_encoder;
+       struct drm_connector *connector;
+       struct radeon_connector *radeon_connector;
        bool first = true;
+       u32 src_v = 1, dst_v = 1;
+       u32 src_h = 1, dst_h = 1;
+
+       radeon_crtc->h_border = 0;
+       radeon_crtc->v_border = 0;
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               radeon_encoder = to_radeon_encoder(encoder);
                if (encoder->crtc != crtc)
                        continue;
+               radeon_encoder = to_radeon_encoder(encoder);
+               connector = radeon_get_connector_for_encoder(encoder);
+               radeon_connector = to_radeon_connector(connector);
+
                if (first) {
                        /* set scaling */
                        if (radeon_encoder->rmx_type == RMX_OFF)
@@ -1085,31 +1116,49 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
                                radeon_crtc->rmx_type = radeon_encoder->rmx_type;
                        else
                                radeon_crtc->rmx_type = RMX_OFF;
+                       src_v = crtc->mode.vdisplay;
+                       dst_v = radeon_crtc->native_mode.vdisplay;
+                       src_h = crtc->mode.hdisplay;
+                       dst_h = radeon_crtc->native_mode.vdisplay;
                        /* copy native mode */
                        memcpy(&radeon_crtc->native_mode,
                               &radeon_encoder->native_mode,
                                sizeof(struct drm_display_mode));
+
+                       /* fix up for overscan on hdmi */
+                       if (ASIC_IS_AVIVO(rdev) &&
+                           ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
+                            ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
+                             drm_detect_hdmi_monitor(radeon_connector->edid)))) {
+                               radeon_crtc->h_border = (mode->hdisplay >> 5) + 16;
+                               radeon_crtc->v_border = (mode->vdisplay >> 5) + 16;
+                               radeon_crtc->rmx_type = RMX_FULL;
+                               src_v = crtc->mode.vdisplay;
+                               dst_v = crtc->mode.vdisplay - (radeon_crtc->v_border * 2);
+                               src_h = crtc->mode.hdisplay;
+                               dst_h = crtc->mode.hdisplay - (radeon_crtc->h_border * 2);
+                       }
                        first = false;
                } else {
                        if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
                                /* WARNING: Right now this can't happen but
                                 * in the future we need to check that scaling
-                                * are consistent accross different encoder
+                                * are consistent across different encoder
                                 * (ie all encoder can work with the same
                                 *  scaling).
                                 */
-                               DRM_ERROR("Scaling not consistent accross encoder.\n");
+                               DRM_ERROR("Scaling not consistent across encoder.\n");
                                return false;
                        }
                }
        }
        if (radeon_crtc->rmx_type != RMX_OFF) {
                fixed20_12 a, b;
-               a.full = dfixed_const(crtc->mode.vdisplay);
-               b.full = dfixed_const(radeon_crtc->native_mode.hdisplay);
+               a.full = dfixed_const(src_v);
+               b.full = dfixed_const(dst_v);
                radeon_crtc->vsc.full = dfixed_div(a, b);
-               a.full = dfixed_const(crtc->mode.hdisplay);
-               b.full = dfixed_const(radeon_crtc->native_mode.vdisplay);
+               a.full = dfixed_const(src_h);
+               b.full = dfixed_const(dst_h);
                radeon_crtc->hsc.full = dfixed_div(a, b);
        } else {
                radeon_crtc->vsc.full = dfixed_const(1);
index e166fe4d7c308f55ab451a710687a679dcf8720f..795403b0e2cda8ac392e8faac9cded15746fc500 100644 (file)
  * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs
  * - 2.4.0 - add crtc id query
  * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen
+ * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500)
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       5
+#define KMS_DRIVER_MINOR       6
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
@@ -238,7 +239,7 @@ static struct drm_driver kms_driver;
 static int __devinit
 radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &kms_driver);
+       return drm_get_pci_dev(pdev, ent, &kms_driver);
 }
 
 static void
index e0b30b264c2809997673f481bddec3a22b9d78a9..263c8098d7dd279447ebba20e408c25f791f0b7d 100644 (file)
@@ -205,14 +205,14 @@ void radeon_encoder_set_active_device(struct drm_encoder *encoder)
                if (connector->encoder == encoder) {
                        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
                        radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
-                       DRM_DEBUG("setting active device to %08x from %08x %08x for encoder %d\n",
+                       DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
                                  radeon_encoder->active_device, radeon_encoder->devices,
                                  radeon_connector->devices, encoder->encoder_type);
                }
        }
 }
 
-static struct drm_connector *
+struct drm_connector *
 radeon_get_connector_for_encoder(struct drm_encoder *encoder)
 {
        struct drm_device *dev = encoder->dev;
@@ -1021,7 +1021,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
 
        memset(&args, 0, sizeof(args));
 
-       DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
+       DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
                  radeon_encoder->encoder_id, mode, radeon_encoder->devices,
                  radeon_encoder->active_device);
        switch (radeon_encoder->encoder_id) {
@@ -1484,7 +1484,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
        uint32_t bios_0_scratch;
 
        if (!atombios_dac_load_detect(encoder, connector)) {
-               DRM_DEBUG("detect returned false \n");
+               DRM_DEBUG_KMS("detect returned false \n");
                return connector_status_unknown;
        }
 
@@ -1493,7 +1493,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
        else
                bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
 
-       DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
+       DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
        if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
                if (bios_0_scratch & ATOM_S0_CRT1_MASK)
                        return connector_status_connected;
@@ -1694,6 +1694,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
        radeon_encoder->encoder_id = encoder_id;
        radeon_encoder->devices = supported_device;
        radeon_encoder->rmx_type = RMX_OFF;
+       radeon_encoder->underscan_type = UNDERSCAN_OFF;
 
        switch (radeon_encoder->encoder_id) {
        case ENCODER_OBJECT_ID_INTERNAL_LVDS:
@@ -1707,6 +1708,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
                } else {
                        drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
                        radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
+                       if (ASIC_IS_AVIVO(rdev))
+                               radeon_encoder->underscan_type = UNDERSCAN_AUTO;
                }
                drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
                break;
@@ -1736,6 +1739,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
                } else {
                        drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
                        radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
+                       if (ASIC_IS_AVIVO(rdev))
+                               radeon_encoder->underscan_type = UNDERSCAN_AUTO;
                }
                drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
                break;
index ab389f89fa8df7fca6af0a3ca9197c0102dc39f4..ddcd3b13f15162cc9db280087b480a8171de8e30 100644 (file)
@@ -49,7 +49,7 @@ int radeon_driver_unload_kms(struct drm_device *dev)
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 {
        struct radeon_device *rdev;
-       int r;
+       int r, acpi_status;
 
        rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL);
        if (rdev == NULL) {
@@ -77,6 +77,12 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
                dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
                goto out;
        }
+
+       /* Call ACPI methods */
+       acpi_status = radeon_acpi_init(rdev);
+       if (acpi_status)
+               dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n");
+
        /* Again modeset_init should fail only on fatal error
         * otherwise it should provide enough functionalities
         * for shadowfb to run
@@ -135,15 +141,36 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                        }
                }
                if (!found) {
-                       DRM_DEBUG("unknown crtc id %d\n", value);
+                       DRM_DEBUG_KMS("unknown crtc id %d\n", value);
                        return -EINVAL;
                }
                break;
        case RADEON_INFO_ACCEL_WORKING2:
                value = rdev->accel_working;
                break;
+       case RADEON_INFO_TILING_CONFIG:
+               if (rdev->family >= CHIP_CEDAR)
+                       value = rdev->config.evergreen.tile_config;
+               else if (rdev->family >= CHIP_RV770)
+                       value = rdev->config.rv770.tile_config;
+               else if (rdev->family >= CHIP_R600)
+                       value = rdev->config.r600.tile_config;
+               else {
+                       DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
+                       return -EINVAL;
+               }
+       case RADEON_INFO_WANT_HYPERZ:
+               mutex_lock(&dev->struct_mutex);
+               if (rdev->hyperz_filp)
+                       value = 0;
+               else {
+                       rdev->hyperz_filp = filp;
+                       value = 1;
+               }
+               mutex_unlock(&dev->struct_mutex);
+               break;
        default:
-               DRM_DEBUG("Invalid request %d\n", info->request);
+               DRM_DEBUG_KMS("Invalid request %d\n", info->request);
                return -EINVAL;
        }
        if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
@@ -181,9 +208,11 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
 void radeon_driver_preclose_kms(struct drm_device *dev,
                                struct drm_file *file_priv)
 {
+       struct radeon_device *rdev = dev->dev_private;
+       if (rdev->hyperz_filp == file_priv)
+               rdev->hyperz_filp = NULL;
 }
 
-
 /*
  * VBlank related functions.
  */
index e1e5255396acc3a5c9c9e0a5d01d79adfff2e601..989df519a1e453b618e2599f0eeced23e637dc91 100644 (file)
@@ -362,10 +362,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
        uint32_t gen_cntl_reg, gen_cntl_val;
        int r;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
        /* no fb bound */
        if (!crtc->fb) {
-               DRM_DEBUG("No FB bound\n");
+               DRM_DEBUG_KMS("No FB bound\n");
                return 0;
        }
 
@@ -528,7 +528,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
        uint32_t crtc_v_sync_strt_wid;
        bool is_tv = false;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                if (encoder->crtc == crtc) {
                        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -757,7 +757,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                }
        }
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        if (!use_bios_divs) {
                radeon_compute_pll(pll, mode->clock,
@@ -772,7 +772,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                if (!post_div->divider)
                        post_div = &post_divs[0];
 
-               DRM_DEBUG("dc=%u, fd=%d, rd=%d, pd=%d\n",
+               DRM_DEBUG_KMS("dc=%u, fd=%d, rd=%d, pd=%d\n",
                          (unsigned)freq,
                          feedback_div,
                          reference_div,
@@ -841,12 +841,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                               | RADEON_P2PLL_SLEEP
                               | RADEON_P2PLL_ATOMIC_UPDATE_EN));
 
-               DRM_DEBUG("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+               DRM_DEBUG_KMS("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
                          (unsigned)pll_ref_div,
                          (unsigned)pll_fb_post_div,
                          (unsigned)htotal_cntl,
                          RREG32_PLL(RADEON_P2PLL_CNTL));
-               DRM_DEBUG("Wrote2: rd=%u, fd=%u, pd=%u\n",
+               DRM_DEBUG_KMS("Wrote2: rd=%u, fd=%u, pd=%u\n",
                          (unsigned)pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
                          (unsigned)pll_fb_post_div & RADEON_P2PLL_FB0_DIV_MASK,
                          (unsigned)((pll_fb_post_div &
@@ -947,12 +947,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                               | RADEON_PPLL_ATOMIC_UPDATE_EN
                               | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
 
-               DRM_DEBUG("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+               DRM_DEBUG_KMS("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
                          pll_ref_div,
                          pll_fb_post_div,
                          (unsigned)htotal_cntl,
                          RREG32_PLL(RADEON_PPLL_CNTL));
-               DRM_DEBUG("Wrote: rd=%d, fd=%d, pd=%d\n",
+               DRM_DEBUG_KMS("Wrote: rd=%d, fd=%d, pd=%d\n",
                          pll_ref_div & RADEON_PPLL_REF_DIV_MASK,
                          pll_fb_post_div & RADEON_PPLL_FB3_DIV_MASK,
                          (pll_fb_post_div & RADEON_PPLL_POST3_DIV_MASK) >> 16);
index 5688a0cf6bbecbea020edd8c96bcc9c70c0b28e5..b8149cbc0c70ca3511f748d13e05cb85c16073e9 100644 (file)
@@ -47,7 +47,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
        uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man;
        int panel_pwr_delay = 2000;
        bool is_mac = false;
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        if (radeon_encoder->enc_priv) {
                if (rdev->is_atom_bios) {
@@ -151,7 +151,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
        lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
@@ -167,7 +167,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
        } else {
                struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
                if (lvds) {
-                       DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl);
+                       DRM_DEBUG_KMS("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl);
                        lvds_gen_cntl = lvds->lvds_gen_cntl;
                        lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) |
                                              (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
@@ -250,7 +250,7 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
        uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL);
        uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL);
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        switch (mode) {
        case DRM_MODE_DPMS_ON:
@@ -315,7 +315,7 @@ static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder,
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        if (radeon_crtc->crtc_id == 0) {
                if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) {
@@ -446,7 +446,7 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL);
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        switch (mode) {
        case DRM_MODE_DPMS_ON:
@@ -502,7 +502,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
        uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl;
        int i;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL);
        tmp &= 0xfffff;
@@ -610,7 +610,7 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        switch (mode) {
        case DRM_MODE_DPMS_ON:
@@ -666,7 +666,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        uint32_t fp2_gen_cntl;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        if (rdev->is_atom_bios) {
                radeon_encoder->pixel_clock = adjusted_mode->clock;
@@ -760,7 +760,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
        uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0;
        uint32_t tv_master_cntl = 0;
        bool is_tv;
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false;
 
@@ -878,7 +878,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
        uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0;
        bool is_tv = false;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG_KMS("\n");
 
        is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false;
 
@@ -1075,10 +1075,10 @@ static bool r300_legacy_tv_detect(struct drm_encoder *encoder,
        tmp = RREG32(RADEON_TV_DAC_CNTL);
        if ((tmp & RADEON_TV_DAC_GDACDET) != 0) {
                found = true;
-               DRM_DEBUG("S-video TV connection detected\n");
+               DRM_DEBUG_KMS("S-video TV connection detected\n");
        } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) {
                found = true;
-               DRM_DEBUG("Composite TV connection detected\n");
+               DRM_DEBUG_KMS("Composite TV connection detected\n");
        }
 
        WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
@@ -1141,10 +1141,10 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder,
        tmp = RREG32(RADEON_TV_DAC_CNTL);
        if (tmp & RADEON_TV_DAC_GDACDET) {
                found = true;
-               DRM_DEBUG("S-video TV connection detected\n");
+               DRM_DEBUG_KMS("S-video TV connection detected\n");
        } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) {
                found = true;
-               DRM_DEBUG("Composite TV connection detected\n");
+               DRM_DEBUG_KMS("Composite TV connection detected\n");
        }
 
        WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
index 03204039774308bc01eefdd69616f310b50af739..c7b6cb428d096de2f0efdba0082357c9bae569f6 100644 (file)
@@ -496,7 +496,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)
 
        restart -= v_offset + h_offset;
 
-       DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n",
+       DRM_DEBUG_KMS("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n",
                  const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart);
 
        tv_dac->tv.hrestart = restart % h_total;
@@ -505,7 +505,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)
        restart /= v_total;
        tv_dac->tv.frestart = restart % f_total;
 
-       DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n",
+       DRM_DEBUG_KMS("compute_restart: F/H/V=%u,%u,%u\n",
                  (unsigned)tv_dac->tv.frestart,
                  (unsigned)tv_dac->tv.vrestart,
                  (unsigned)tv_dac->tv.hrestart);
@@ -523,7 +523,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)
        tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) |
                ((u32)h_inc << RADEON_H_INC_SHIFT);
 
-       DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc);
+       DRM_DEBUG_KMS("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc);
 
        return h_changed;
 }
index 95696aa57ac8c43048071ba93fd4254ec113ac92..71aea4037e90545f0d60a8ff9fda4a890ea854af 100644 (file)
@@ -66,6 +66,12 @@ enum radeon_tv_std {
        TV_STD_PAL_N,
 };
 
+enum radeon_underscan_type {
+       UNDERSCAN_OFF,
+       UNDERSCAN_ON,
+       UNDERSCAN_AUTO,
+};
+
 enum radeon_hpd_id {
        RADEON_HPD_1 = 0,
        RADEON_HPD_2,
@@ -226,10 +232,12 @@ struct radeon_mode_info {
        struct drm_property *coherent_mode_property;
        /* DAC enable load detect */
        struct drm_property *load_detect_property;
-       /* TV standard load detect */
+       /* TV standard */
        struct drm_property *tv_std_property;
        /* legacy TMDS PLL detect */
        struct drm_property *tmds_pll_property;
+       /* underscan */
+       struct drm_property *underscan_property;
        /* hardcoded DFP edid from BIOS */
        struct edid *bios_hardcoded_edid;
 
@@ -266,6 +274,8 @@ struct radeon_crtc {
        uint32_t legacy_display_base_addr;
        uint32_t legacy_cursor_offset;
        enum radeon_rmx_type rmx_type;
+       u8 h_border;
+       u8 v_border;
        fixed20_12 vsc;
        fixed20_12 hsc;
        struct drm_display_mode native_mode;
@@ -354,6 +364,7 @@ struct radeon_encoder {
        uint32_t flags;
        uint32_t pixel_clock;
        enum radeon_rmx_type rmx_type;
+       enum radeon_underscan_type underscan_type;
        struct drm_display_mode native_mode;
        void *enc_priv;
        int audio_polling_active;
@@ -392,7 +403,7 @@ struct radeon_connector {
        uint32_t connector_id;
        uint32_t devices;
        struct radeon_i2c_chan *ddc_bus;
-       /* some systems have a an hdmi and vga port with a shared ddc line */
+       /* some systems have an hdmi and vga port with a shared ddc line */
        bool shared_ddc;
        bool use_digital;
        /* we need to mind the EDID between detect
@@ -414,6 +425,9 @@ radeon_combios_get_tv_info(struct radeon_device *rdev);
 extern enum radeon_tv_std
 radeon_atombios_get_tv_info(struct radeon_device *rdev);
 
+extern struct drm_connector *
+radeon_get_connector_for_encoder(struct drm_encoder *encoder);
+
 extern void radeon_connector_hotplug(struct drm_connector *connector);
 extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
 extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
index d5b9373ce06c16b9be8ee81b9f27d70b20947a19..0afd1e62347dcfb9670d20e13a818d8d7a99b59c 100644 (file)
@@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
        bo->surface_reg = -1;
        INIT_LIST_HEAD(&bo->list);
 
+retry:
        radeon_ttm_placement_from_domain(bo, domain);
        /* Kernel allocation are uninterruptible */
        mutex_lock(&rdev->vram_mutex);
@@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
                        &radeon_ttm_bo_destroy);
        mutex_unlock(&rdev->vram_mutex);
        if (unlikely(r != 0)) {
-               if (r != -ERESTARTSYS)
+               if (r != -ERESTARTSYS) {
+                       if (domain == RADEON_GEM_DOMAIN_VRAM) {
+                               domain |= RADEON_GEM_DOMAIN_GTT;
+                               goto retry;
+                       }
                        dev_err(rdev->dev,
                                "object_init failed for (%lu, 0x%08X)\n",
                                size, domain);
+               }
                return r;
        }
        *bo_ptr = bo;
@@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_head *head)
 {
        struct radeon_bo_list *lobj;
        struct radeon_bo *bo;
+       u32 domain;
        int r;
 
        list_for_each_entry(lobj, head, list) {
@@ -333,17 +340,19 @@ int radeon_bo_list_validate(struct list_head *head)
        list_for_each_entry(lobj, head, list) {
                bo = lobj->bo;
                if (!bo->pin_count) {
-                       if (lobj->wdomain) {
-                               radeon_ttm_placement_from_domain(bo,
-                                                               lobj->wdomain);
-                       } else {
-                               radeon_ttm_placement_from_domain(bo,
-                                                               lobj->rdomain);
-                       }
+                       domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain;
+                       
+               retry:
+                       radeon_ttm_placement_from_domain(bo, domain);
                        r = ttm_bo_validate(&bo->tbo, &bo->placement,
                                                true, false, false);
-                       if (unlikely(r))
+                       if (unlikely(r)) {
+                               if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) {
+                                       domain |= RADEON_GEM_DOMAIN_GTT;
+                                       goto retry;
+                               }
                                return r;
+                       }
                }
                lobj->gpu_offset = radeon_bo_gpu_offset(bo);
                lobj->tiling_flags = bo->tiling_flags;
index 3fa6984d9896094c3b0318ff486186c6cdf7ebdd..95f8b3a3c43d993ee6eac9ea3a713b5aa35d3935 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/acpi.h>
 #endif
 #include <linux/power_supply.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
 
 #define RADEON_IDLE_LOOP_MS 100
 #define RADEON_RECLOCK_DELAY_MS 200
@@ -60,9 +62,9 @@ static int radeon_acpi_event(struct notifier_block *nb,
 
        if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
                if (power_supply_is_system_supplied() > 0)
-                       DRM_DEBUG("pm: AC\n");
+                       DRM_DEBUG_DRIVER("pm: AC\n");
                else
-                       DRM_DEBUG("pm: DC\n");
+                       DRM_DEBUG_DRIVER("pm: DC\n");
 
                if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
                        if (rdev->pm.profile == PM_PROFILE_AUTO) {
@@ -196,7 +198,7 @@ static void radeon_set_power_state(struct radeon_device *rdev)
                        radeon_set_engine_clock(rdev, sclk);
                        radeon_pm_debug_check_in_vbl(rdev, true);
                        rdev->pm.current_sclk = sclk;
-                       DRM_DEBUG("Setting: e: %d\n", sclk);
+                       DRM_DEBUG_DRIVER("Setting: e: %d\n", sclk);
                }
 
                /* set memory clock */
@@ -205,7 +207,7 @@ static void radeon_set_power_state(struct radeon_device *rdev)
                        radeon_set_memory_clock(rdev, mclk);
                        radeon_pm_debug_check_in_vbl(rdev, true);
                        rdev->pm.current_mclk = mclk;
-                       DRM_DEBUG("Setting: m: %d\n", mclk);
+                       DRM_DEBUG_DRIVER("Setting: m: %d\n", mclk);
                }
 
                if (misc_after)
@@ -217,7 +219,7 @@ static void radeon_set_power_state(struct radeon_device *rdev)
                rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
                rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
        } else
-               DRM_DEBUG("pm: GUI not idle!!!\n");
+               DRM_DEBUG_DRIVER("pm: GUI not idle!!!\n");
 }
 
 static void radeon_pm_set_clocks(struct radeon_device *rdev)
@@ -292,27 +294,27 @@ static void radeon_pm_print_states(struct radeon_device *rdev)
        struct radeon_power_state *power_state;
        struct radeon_pm_clock_info *clock_info;
 
-       DRM_DEBUG("%d Power State(s)\n", rdev->pm.num_power_states);
+       DRM_DEBUG_DRIVER("%d Power State(s)\n", rdev->pm.num_power_states);
        for (i = 0; i < rdev->pm.num_power_states; i++) {
                power_state = &rdev->pm.power_state[i];
-               DRM_DEBUG("State %d: %s\n", i,
+               DRM_DEBUG_DRIVER("State %d: %s\n", i,
                        radeon_pm_state_type_name[power_state->type]);
                if (i == rdev->pm.default_power_state_index)
-                       DRM_DEBUG("\tDefault");
+                       DRM_DEBUG_DRIVER("\tDefault");
                if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
-                       DRM_DEBUG("\t%d PCIE Lanes\n", power_state->pcie_lanes);
+                       DRM_DEBUG_DRIVER("\t%d PCIE Lanes\n", power_state->pcie_lanes);
                if (power_state->flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
-                       DRM_DEBUG("\tSingle display only\n");
-               DRM_DEBUG("\t%d Clock Mode(s)\n", power_state->num_clock_modes);
+                       DRM_DEBUG_DRIVER("\tSingle display only\n");
+               DRM_DEBUG_DRIVER("\t%d Clock Mode(s)\n", power_state->num_clock_modes);
                for (j = 0; j < power_state->num_clock_modes; j++) {
                        clock_info = &(power_state->clock_info[j]);
                        if (rdev->flags & RADEON_IS_IGP)
-                               DRM_DEBUG("\t\t%d e: %d%s\n",
+                               DRM_DEBUG_DRIVER("\t\t%d e: %d%s\n",
                                        j,
                                        clock_info->sclk * 10,
                                        clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : "");
                        else
-                               DRM_DEBUG("\t\t%d e: %d\tm: %d\tv: %d%s\n",
+                               DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d%s\n",
                                        j,
                                        clock_info->sclk * 10,
                                        clock_info->mclk * 10,
@@ -424,6 +426,82 @@ fail:
 static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile);
 static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method);
 
+static ssize_t radeon_hwmon_show_temp(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+       struct radeon_device *rdev = ddev->dev_private;
+       u32 temp;
+
+       switch (rdev->pm.int_thermal_type) {
+       case THERMAL_TYPE_RV6XX:
+               temp = rv6xx_get_temp(rdev);
+               break;
+       case THERMAL_TYPE_RV770:
+               temp = rv770_get_temp(rdev);
+               break;
+       case THERMAL_TYPE_EVERGREEN:
+               temp = evergreen_get_temp(rdev);
+               break;
+       default:
+               temp = 0;
+               break;
+       }
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", temp);
+}
+
+static ssize_t radeon_hwmon_show_name(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       return sprintf(buf, "radeon\n");
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0);
+
+static struct attribute *hwmon_attributes[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_name.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group hwmon_attrgroup = {
+       .attrs = hwmon_attributes,
+};
+
+static void radeon_hwmon_init(struct radeon_device *rdev)
+{
+       int err;
+
+       rdev->pm.int_hwmon_dev = NULL;
+
+       switch (rdev->pm.int_thermal_type) {
+       case THERMAL_TYPE_RV6XX:
+       case THERMAL_TYPE_RV770:
+       case THERMAL_TYPE_EVERGREEN:
+               rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
+               dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev);
+               err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj,
+                                        &hwmon_attrgroup);
+               if (err)
+                       DRM_ERROR("Unable to create hwmon sysfs file: %d\n", err);
+               break;
+       default:
+               break;
+       }
+}
+
+static void radeon_hwmon_fini(struct radeon_device *rdev)
+{
+       if (rdev->pm.int_hwmon_dev) {
+               sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup);
+               hwmon_device_unregister(rdev->pm.int_hwmon_dev);
+       }
+}
+
 void radeon_pm_suspend(struct radeon_device *rdev)
 {
        bool flush_wq = false;
@@ -471,6 +549,7 @@ int radeon_pm_init(struct radeon_device *rdev)
        rdev->pm.dynpm_can_downclock = true;
        rdev->pm.current_sclk = rdev->clock.default_sclk;
        rdev->pm.current_mclk = rdev->clock.default_mclk;
+       rdev->pm.int_thermal_type = THERMAL_TYPE_NONE;
 
        if (rdev->bios) {
                if (rdev->is_atom_bios)
@@ -481,6 +560,8 @@ int radeon_pm_init(struct radeon_device *rdev)
                radeon_pm_init_profile(rdev);
        }
 
+       /* set up the internal thermal sensor if applicable */
+       radeon_hwmon_init(rdev);
        if (rdev->pm.num_power_states > 1) {
                /* where's the best place to put these? */
                ret = device_create_file(rdev->dev, &dev_attr_power_profile);
@@ -536,6 +617,7 @@ void radeon_pm_fini(struct radeon_device *rdev)
 #endif
        }
 
+       radeon_hwmon_fini(rdev);
        if (rdev->pm.i2c_bus)
                radeon_i2c_destroy(rdev->pm.i2c_bus);
 }
@@ -576,7 +658,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
                                        radeon_pm_get_dynpm_state(rdev);
                                        radeon_pm_set_clocks(rdev);
 
-                                       DRM_DEBUG("radeon: dynamic power management deactivated\n");
+                                       DRM_DEBUG_DRIVER("radeon: dynamic power management deactivated\n");
                                }
                        } else if (rdev->pm.active_crtc_count == 1) {
                                /* TODO: Increase clocks if needed for current mode */
@@ -593,7 +675,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
                                        rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
                                        queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
                                                           msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
-                                       DRM_DEBUG("radeon: dynamic power management activated\n");
+                                       DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n");
                                }
                        } else { /* count == 0 */
                                if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) {
@@ -689,7 +771,7 @@ static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish
        bool in_vbl = radeon_pm_in_vbl(rdev);
 
        if (in_vbl == false)
-               DRM_DEBUG("not in vbl for pm change %08x at %s\n", stat_crtc,
+               DRM_DEBUG_DRIVER("not in vbl for pm change %08x at %s\n", stat_crtc,
                         finish ? "exit" : "entry");
        return in_vbl;
 }
index e9918d88f5b049675cfebe754d15ef83338bb91d..84c53e41a88fd783d6f7ba32c9155109eb3c95be 100644 (file)
@@ -59,28 +59,28 @@ static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
 /*
  * Global memory.
  */
-static int radeon_ttm_mem_global_init(struct ttm_global_reference *ref)
+static int radeon_ttm_mem_global_init(struct drm_global_reference *ref)
 {
        return ttm_mem_global_init(ref->object);
 }
 
-static void radeon_ttm_mem_global_release(struct ttm_global_reference *ref)
+static void radeon_ttm_mem_global_release(struct drm_global_reference *ref)
 {
        ttm_mem_global_release(ref->object);
 }
 
 static int radeon_ttm_global_init(struct radeon_device *rdev)
 {
-       struct ttm_global_reference *global_ref;
+       struct drm_global_reference *global_ref;
        int r;
 
        rdev->mman.mem_global_referenced = false;
        global_ref = &rdev->mman.mem_global_ref;
-       global_ref->global_type = TTM_GLOBAL_TTM_MEM;
+       global_ref->global_type = DRM_GLOBAL_TTM_MEM;
        global_ref->size = sizeof(struct ttm_mem_global);
        global_ref->init = &radeon_ttm_mem_global_init;
        global_ref->release = &radeon_ttm_mem_global_release;
-       r = ttm_global_item_ref(global_ref);
+       r = drm_global_item_ref(global_ref);
        if (r != 0) {
                DRM_ERROR("Failed setting up TTM memory accounting "
                          "subsystem.\n");
@@ -90,14 +90,14 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
        rdev->mman.bo_global_ref.mem_glob =
                rdev->mman.mem_global_ref.object;
        global_ref = &rdev->mman.bo_global_ref.ref;
-       global_ref->global_type = TTM_GLOBAL_TTM_BO;
+       global_ref->global_type = DRM_GLOBAL_TTM_BO;
        global_ref->size = sizeof(struct ttm_bo_global);
        global_ref->init = &ttm_bo_global_init;
        global_ref->release = &ttm_bo_global_release;
-       r = ttm_global_item_ref(global_ref);
+       r = drm_global_item_ref(global_ref);
        if (r != 0) {
                DRM_ERROR("Failed setting up TTM BO subsystem.\n");
-               ttm_global_item_unref(&rdev->mman.mem_global_ref);
+               drm_global_item_unref(&rdev->mman.mem_global_ref);
                return r;
        }
 
@@ -108,8 +108,8 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
 static void radeon_ttm_global_fini(struct radeon_device *rdev)
 {
        if (rdev->mman.mem_global_referenced) {
-               ttm_global_item_unref(&rdev->mman.bo_global_ref.ref);
-               ttm_global_item_unref(&rdev->mman.mem_global_ref);
+               drm_global_item_unref(&rdev->mman.bo_global_ref.ref);
+               drm_global_item_unref(&rdev->mman.mem_global_ref);
                rdev->mman.mem_global_referenced = false;
        }
 }
index 1e97b2d129fd90240056630cf60357ece84a7561..b506ec1cab4b330e298bb884f0645ca06a0d6244 100644 (file)
@@ -187,7 +187,6 @@ r300 0x4f60
 0x4364 RS_INST_13
 0x4368 RS_INST_14
 0x436C RS_INST_15
-0x43A4 SC_HYPERZ_EN
 0x43A8 SC_EDGERULE
 0x43B0 SC_CLIP_0_A
 0x43B4 SC_CLIP_0_B
@@ -716,16 +715,4 @@ r300 0x4f60
 0x4F08 ZB_STENCILREFMASK
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
-0x4F1C ZB_BW_CNTL
-0x4F28 ZB_DEPTHCLEARVALUE
-0x4F30 ZB_ZMASK_OFFSET
-0x4F34 ZB_ZMASK_PITCH
-0x4F38 ZB_ZMASK_WRINDEX
-0x4F3C ZB_ZMASK_DWORD
-0x4F40 ZB_ZMASK_RDINDEX
-0x4F44 ZB_HIZ_OFFSET
-0x4F48 ZB_HIZ_WRINDEX
-0x4F4C ZB_HIZ_DWORD
-0x4F50 ZB_HIZ_RDINDEX
-0x4F54 ZB_HIZ_PITCH
 0x4F58 ZB_ZPASS_DATA
index e958980d00f19d15b113bd8b95d186add903b246..8c1214c2390fdcc1d93682cb96af3208c1957134 100644 (file)
@@ -130,6 +130,7 @@ r420 0x4f60
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
+0x4028 GB_Z_PEQ_CONFIG
 0x4100 TX_INVALTAGS
 0x4200 GA_POINT_S0
 0x4204 GA_POINT_T0
@@ -187,7 +188,6 @@ r420 0x4f60
 0x4364 RS_INST_13
 0x4368 RS_INST_14
 0x436C RS_INST_15
-0x43A4 SC_HYPERZ_EN
 0x43A8 SC_EDGERULE
 0x43B0 SC_CLIP_0_A
 0x43B4 SC_CLIP_0_B
@@ -782,16 +782,4 @@ r420 0x4f60
 0x4F08 ZB_STENCILREFMASK
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
-0x4F1C ZB_BW_CNTL
-0x4F28 ZB_DEPTHCLEARVALUE
-0x4F30 ZB_ZMASK_OFFSET
-0x4F34 ZB_ZMASK_PITCH
-0x4F38 ZB_ZMASK_WRINDEX
-0x4F3C ZB_ZMASK_DWORD
-0x4F40 ZB_ZMASK_RDINDEX
-0x4F44 ZB_HIZ_OFFSET
-0x4F48 ZB_HIZ_WRINDEX
-0x4F4C ZB_HIZ_DWORD
-0x4F50 ZB_HIZ_RDINDEX
-0x4F54 ZB_HIZ_PITCH
 0x4F58 ZB_ZPASS_DATA
index 83e8bc0c2bb249d9fa11e90bea35b6716bcca236..0828d80396f29f9a994b51a1ec6526a1f9afff3f 100644 (file)
@@ -187,7 +187,6 @@ rs600 0x6d40
 0x4364 RS_INST_13
 0x4368 RS_INST_14
 0x436C RS_INST_15
-0x43A4 SC_HYPERZ_EN
 0x43A8 SC_EDGERULE
 0x43B0 SC_CLIP_0_A
 0x43B4 SC_CLIP_0_B
@@ -782,16 +781,4 @@ rs600 0x6d40
 0x4F08 ZB_STENCILREFMASK
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
-0x4F1C ZB_BW_CNTL
-0x4F28 ZB_DEPTHCLEARVALUE
-0x4F30 ZB_ZMASK_OFFSET
-0x4F34 ZB_ZMASK_PITCH
-0x4F38 ZB_ZMASK_WRINDEX
-0x4F3C ZB_ZMASK_DWORD
-0x4F40 ZB_ZMASK_RDINDEX
-0x4F44 ZB_HIZ_OFFSET
-0x4F48 ZB_HIZ_WRINDEX
-0x4F4C ZB_HIZ_DWORD
-0x4F50 ZB_HIZ_RDINDEX
-0x4F54 ZB_HIZ_PITCH
 0x4F58 ZB_ZPASS_DATA
index 1e46233985eb265106d5011d92402375632ea3f1..8293855f5f0d7d9aa1b24c4fb8c9660d5b9f7528 100644 (file)
@@ -235,7 +235,6 @@ rv515 0x6d40
 0x4354 RS_INST_13
 0x4358 RS_INST_14
 0x435C RS_INST_15
-0x43A4 SC_HYPERZ_EN
 0x43A8 SC_EDGERULE
 0x43B0 SC_CLIP_0_A
 0x43B4 SC_CLIP_0_B
@@ -479,17 +478,5 @@ rv515 0x6d40
 0x4F08 ZB_STENCILREFMASK
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
-0x4F1C ZB_BW_CNTL
-0x4F28 ZB_DEPTHCLEARVALUE
-0x4F30 ZB_ZMASK_OFFSET
-0x4F34 ZB_ZMASK_PITCH
-0x4F38 ZB_ZMASK_WRINDEX
-0x4F3C ZB_ZMASK_DWORD
-0x4F40 ZB_ZMASK_RDINDEX
-0x4F44 ZB_HIZ_OFFSET
-0x4F48 ZB_HIZ_WRINDEX
-0x4F4C ZB_HIZ_DWORD
-0x4F50 ZB_HIZ_RDINDEX
-0x4F54 ZB_HIZ_PITCH
 0x4F58 ZB_ZPASS_DATA
 0x4FD4 ZB_STENCILREFMASK_BF
index f454c9a5e7f22269a9ffe0618d87f1a74e05f276..ae2b76b9a388ae78da7e9d923a14de2d19c956e8 100644 (file)
@@ -55,14 +55,6 @@ void rs400_gart_adjust_size(struct radeon_device *rdev)
                rdev->mc.gtt_size = 32 * 1024 * 1024;
                return;
        }
-       if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
-               /* FIXME: RS400 & RS480 seems to have issue with GART size
-                * if 4G of system memory (needs more testing)
-                */
-               /* XXX is this still an issue with proper alignment? */
-               rdev->mc.gtt_size = 32 * 1024 * 1024;
-               DRM_ERROR("Forcing to 32M GART size (because of ASIC bug ?)\n");
-       }
 }
 
 void rs400_gart_tlb_flush(struct radeon_device *rdev)
@@ -483,6 +475,8 @@ int rs400_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index 6dc15ea8ba33ce088f273b17eea0f1fc42e537df..cc05b230d7effbbae88524da0d698dace6228ccf 100644 (file)
@@ -686,8 +686,8 @@ void rs600_mc_init(struct radeon_device *rdev)
 {
        u64 base;
 
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        rdev->mc.vram_is_ddr = true;
        rdev->mc.vram_width = 128;
        rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
@@ -696,7 +696,6 @@ void rs600_mc_init(struct radeon_device *rdev)
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        base = RREG32_MC(R_000004_MC_FB_LOCATION);
        base = G_000004_MC_FB_START(base) << 16;
-       rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        radeon_vram_location(rdev, &rdev->mc, base);
        rdev->mc.gtt_base_align = 0;
        radeon_gtt_location(rdev, &rdev->mc);
@@ -813,6 +812,13 @@ static int rs600_startup(struct radeon_device *rdev)
                dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
                return r;
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "failed initializing audio\n");
+               return r;
+       }
+
        return 0;
 }
 
@@ -839,6 +845,7 @@ int rs600_resume(struct radeon_device *rdev)
 
 int rs600_suspend(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_disable(rdev);
        r100_wb_disable(rdev);
        rs600_irq_disable(rdev);
@@ -848,6 +855,7 @@ int rs600_suspend(struct radeon_device *rdev)
 
 void rs600_fini(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
@@ -871,6 +879,8 @@ int rs600_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS */
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index ce4ecbe108163126c74fb14779eaf90dcf15ce41..3e3f75718be3e83ab156465dc80a11f604b58a64 100644 (file)
@@ -154,13 +154,13 @@ void rs690_mc_init(struct radeon_device *rdev)
        rdev->mc.vram_width = 128;
        rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
        rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
        base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
        base = G_000100_MC_FB_START(base) << 16;
-       rs690_pm_info(rdev);
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+       rs690_pm_info(rdev);
        radeon_vram_location(rdev, &rdev->mc, base);
        rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;
        radeon_gtt_location(rdev, &rdev->mc);
@@ -398,7 +398,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
        struct drm_display_mode *mode1 = NULL;
        struct rs690_watermark wm0;
        struct rs690_watermark wm1;
-       u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
+       u32 tmp;
+       u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
+       u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
        fixed20_12 priority_mark02, priority_mark12, fill_rate;
        fixed20_12 a, b;
 
@@ -495,10 +497,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
                        d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
                        d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
                }
-               WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        } else if (mode0) {
                if (dfixed_trunc(wm0.dbpp) > 64)
                        a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -528,13 +526,7 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
                d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
                if (rdev->disp_priority == 2)
                        d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
-               WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
-                       S_006D48_D2MODE_PRIORITY_A_OFF(1));
-               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
-                       S_006D4C_D2MODE_PRIORITY_B_OFF(1));
-       } else {
+       } else if (mode1) {
                if (dfixed_trunc(wm1.dbpp) > 64)
                        a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair);
                else
@@ -563,13 +555,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
                d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
                if (rdev->disp_priority == 2)
                        d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
-               WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
-                       S_006548_D1MODE_PRIORITY_A_OFF(1));
-               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
-                       S_00654C_D1MODE_PRIORITY_B_OFF(1));
-               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        }
+
+       WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+       WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+       WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+       WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 }
 
 uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -641,6 +632,13 @@ static int rs690_startup(struct radeon_device *rdev)
                dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
                return r;
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "failed initializing audio\n");
+               return r;
+       }
+
        return 0;
 }
 
@@ -667,6 +665,7 @@ int rs690_resume(struct radeon_device *rdev)
 
 int rs690_suspend(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_disable(rdev);
        r100_wb_disable(rdev);
        rs600_irq_disable(rdev);
@@ -676,6 +675,7 @@ int rs690_suspend(struct radeon_device *rdev)
 
 void rs690_fini(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
@@ -699,6 +699,8 @@ int rs690_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* TODO: disable VGA need to use VGA request */
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
index 0c9c169a6852f453c6703901cd64dc2fb84699e9..4d6e86041a9fde07f8caa56c4f90ba75c05a9f9e 100644 (file)
@@ -469,6 +469,8 @@ int rv515_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
@@ -925,7 +927,9 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
        struct drm_display_mode *mode1 = NULL;
        struct rv515_watermark wm0;
        struct rv515_watermark wm1;
-       u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
+       u32 tmp;
+       u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF;
+       u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF;
        fixed20_12 priority_mark02, priority_mark12, fill_rate;
        fixed20_12 a, b;
 
@@ -999,10 +1003,6 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
                        d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
                        d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
                }
-               WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-               WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-               WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-               WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        } else if (mode0) {
                if (dfixed_trunc(wm0.dbpp) > 64)
                        a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair);
@@ -1032,11 +1032,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
                d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
                if (rdev->disp_priority == 2)
                        d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
-               WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-               WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-               WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
-               WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
-       } else {
+       } else if (mode1) {
                if (dfixed_trunc(wm1.dbpp) > 64)
                        a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair);
                else
@@ -1065,11 +1061,12 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
                d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
                if (rdev->disp_priority == 2)
                        d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
-               WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
-               WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
-               WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-               WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        }
+
+       WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+       WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+       WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+       WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 }
 
 void rv515_bandwidth_update(struct radeon_device *rdev)
index b7fd82064922342d420cacb56a7ece8a00964393..f1c796810117fdb9dfb0b66aa5a89eee5e1da1e9 100644 (file)
 static void rv770_gpu_init(struct radeon_device *rdev);
 void rv770_fini(struct radeon_device *rdev);
 
+/* get temperature in millidegrees */
+u32 rv770_get_temp(struct radeon_device *rdev)
+{
+       u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
+               ASIC_T_SHIFT;
+       u32 actual_temp = 0;
+
+       if ((temp >> 9) & 1)
+               actual_temp = 0;
+       else
+               actual_temp = (temp >> 1) & 0xff;
+
+       return actual_temp * 1000;
+}
+
 void rv770_pm_misc(struct radeon_device *rdev)
 {
        int req_ps_idx = rdev->pm.requested_power_state_index;
@@ -189,7 +204,10 @@ static void rv770_mc_program(struct radeon_device *rdev)
                WREG32((0x2c20 + j), 0x00000000);
                WREG32((0x2c24 + j), 0x00000000);
        }
-       WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
+       /* r7xx hw bug.  Read from HDP_DEBUG1 rather
+        * than writing to HDP_REG_COHERENCY_FLUSH_CNTL
+        */
+       tmp = RREG32(HDP_DEBUG1);
 
        rv515_mc_stop(rdev, &save);
        if (r600_mc_wait_for_idle(rdev)) {
@@ -659,8 +677,9 @@ static void rv770_gpu_init(struct radeon_device *rdev)
                                                                 r600_count_pipe_bits((cc_rb_backend_disable &
                                                                                       R7XX_MAX_BACKENDS_MASK) >> 16)),
                                                                (cc_rb_backend_disable >> 16));
-       gb_tiling_config |= BACKEND_MAP(backend_map);
 
+       rdev->config.rv770.tile_config = gb_tiling_config;
+       gb_tiling_config |= BACKEND_MAP(backend_map);
 
        WREG32(GB_TILING_CONFIG, gb_tiling_config);
        WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
@@ -919,8 +938,8 @@ int rv770_mc_init(struct radeon_device *rdev)
        }
        rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        /* Setup GPU memory space */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
index 9506f8cb99e0552a295bef5bd60dfba49bfaaee0..b7a5a20e81dc444b1a85a5944e5e7fb87f07f2ce 100644 (file)
 #define                GUI_ACTIVE                                      (1<<31)
 #define        GRBM_STATUS2                                    0x8014
 
+#define        CG_MULT_THERMAL_STATUS                          0x740
+#define                ASIC_T(x)                               ((x) << 16)
+#define                ASIC_T_MASK                             0x3FF0000
+#define                ASIC_T_SHIFT                            16
+
 #define        HDP_HOST_PATH_CNTL                              0x2C00
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08
 #define        HDP_NONSURFACE_SIZE                             0x2C0C
 #define HDP_REG_COHERENCY_FLUSH_CNTL                   0x54A0
 #define        HDP_TILING_CONFIG                               0x2F3C
+#define HDP_DEBUG1                                      0x2F34
 
 #define MC_SHARED_CHMAP                                                0x2004
 #define                NOOFCHAN_SHIFT                                  12
index fa05cda8c98ff732103ef35d8f4c8513d238af42..976dc8d25280c749798f1c1f124219190c10ca84 100644 (file)
@@ -573,13 +573,13 @@ int savage_driver_firstopen(struct drm_device *dev)
        dev_priv->mtrr[2].handle = -1;
        if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
                fb_rsrc = 0;
-               fb_base = drm_get_resource_start(dev, 0);
+               fb_base = pci_resource_start(dev->pdev, 0);
                fb_size = SAVAGE_FB_SIZE_S3;
                mmio_base = fb_base + SAVAGE_FB_SIZE_S3;
                aper_rsrc = 0;
                aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
                /* this should always be true */
-               if (drm_get_resource_len(dev, 0) == 0x08000000) {
+               if (pci_resource_len(dev->pdev, 0) == 0x08000000) {
                        /* Don't make MMIO write-cobining! We need 3
                         * MTRRs. */
                        dev_priv->mtrr[0].base = fb_base;
@@ -599,18 +599,19 @@ int savage_driver_firstopen(struct drm_device *dev)
                                         dev_priv->mtrr[2].size, DRM_MTRR_WC);
                } else {
                        DRM_ERROR("strange pci_resource_len %08llx\n",
-                                 (unsigned long long)drm_get_resource_len(dev, 0));
+                                 (unsigned long long)
+                                 pci_resource_len(dev->pdev, 0));
                }
        } else if (dev_priv->chipset != S3_SUPERSAVAGE &&
                   dev_priv->chipset != S3_SAVAGE2000) {
-               mmio_base = drm_get_resource_start(dev, 0);
+               mmio_base = pci_resource_start(dev->pdev, 0);
                fb_rsrc = 1;
-               fb_base = drm_get_resource_start(dev, 1);
+               fb_base = pci_resource_start(dev->pdev, 1);
                fb_size = SAVAGE_FB_SIZE_S4;
                aper_rsrc = 1;
                aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
                /* this should always be true */
-               if (drm_get_resource_len(dev, 1) == 0x08000000) {
+               if (pci_resource_len(dev->pdev, 1) == 0x08000000) {
                        /* Can use one MTRR to cover both fb and
                         * aperture. */
                        dev_priv->mtrr[0].base = fb_base;
@@ -620,15 +621,16 @@ int savage_driver_firstopen(struct drm_device *dev)
                                         dev_priv->mtrr[0].size, DRM_MTRR_WC);
                } else {
                        DRM_ERROR("strange pci_resource_len %08llx\n",
-                                 (unsigned long long)drm_get_resource_len(dev, 1));
+                                 (unsigned long long)
+                                 pci_resource_len(dev->pdev, 1));
                }
        } else {
-               mmio_base = drm_get_resource_start(dev, 0);
+               mmio_base = pci_resource_start(dev->pdev, 0);
                fb_rsrc = 1;
-               fb_base = drm_get_resource_start(dev, 1);
-               fb_size = drm_get_resource_len(dev, 1);
+               fb_base = pci_resource_start(dev->pdev, 1);
+               fb_size = pci_resource_len(dev->pdev, 1);
                aper_rsrc = 2;
-               aperture_base = drm_get_resource_start(dev, 2);
+               aperture_base = pci_resource_start(dev->pdev, 2);
                /* Automatic MTRR setup will do the right thing. */
        }
 
index 4fd1f067d380779302c59e1f6bb4c5d574b202ae..776bf9e9ea1adfec718e6b5a4c7906eedaf72348 100644 (file)
@@ -47,9 +47,8 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
        dev->dev_private = (void *)dev_priv;
        dev_priv->chipset = chipset;
        ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
-       if (ret) {
+       if (ret)
                kfree(dev_priv);
-       }
 
        return ret;
 }
index af22111397d8cad6822cfa1b659c291ec885fa45..07d0f2979cac1158f4db86a90e28bf4184d2b1fa 100644 (file)
@@ -78,7 +78,7 @@ static unsigned long sis_sman_mm_offset(void *private, void *ref)
 #else /* CONFIG_FB_SIS[_MODULE] */
 
 #define SIS_MM_ALIGN_SHIFT 4
-#define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1)
+#define SIS_MM_ALIGN_MASK ((1 << SIS_MM_ALIGN_SHIFT) - 1)
 
 #endif /* CONFIG_FB_SIS[_MODULE] */
 
@@ -225,9 +225,8 @@ static drm_local_map_t *sis_reg_init(struct drm_device *dev)
                map = entry->map;
                if (!map)
                        continue;
-               if (map->type == _DRM_REGISTERS) {
+               if (map->type == _DRM_REGISTERS)
                        return map;
-               }
        }
        return NULL;
 }
@@ -264,10 +263,10 @@ int sis_idle(struct drm_device *dev)
 
        end = jiffies + (DRM_HZ * 3);
 
-       for (i=0; i<4; ++i) {
+       for (i = 0; i < 4; ++i) {
                do {
                        idle_reg = SIS_READ(0x85cc);
-               } while ( !time_after_eq(jiffies, end) &&
+               } while (!time_after_eq(jiffies, end) &&
                          ((idle_reg & 0x80000000) != 0x80000000));
        }
 
@@ -301,7 +300,7 @@ void sis_lastclose(struct drm_device *dev)
        mutex_unlock(&dev->struct_mutex);
 }
 
-void sis_reclaim_buffers_locked(struct drm_device * dev,
+void sis_reclaim_buffers_locked(struct drm_device *dev,
                                struct drm_file *file_priv)
 {
        drm_sis_private_t *dev_priv = dev->dev_private;
@@ -312,9 +311,8 @@ void sis_reclaim_buffers_locked(struct drm_device * dev,
                return;
        }
 
-       if (dev->driver->dma_quiescent) {
+       if (dev->driver->dma_quiescent)
                dev->driver->dma_quiescent(dev);
-       }
 
        drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
        mutex_unlock(&dev->struct_mutex);
index 4256e200647614b339f5d3110ff54732b29fa809..b256d4adfafe76710cf1dd6e3b03371e03f7fd46 100644 (file)
@@ -3,7 +3,7 @@
 
 ccflags-y := -Iinclude/drm
 ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \
-       ttm_bo_util.o ttm_bo_vm.o ttm_module.o ttm_global.o \
+       ttm_bo_util.o ttm_bo_vm.o ttm_module.o \
        ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o
 
 obj-$(CONFIG_DRM_TTM) += ttm.o
index 555ebb12ace83dae496fbf41e357bc29c954542d..cb4cf7ef4d1eee9bc726c4d4ee34f8962526b316 100644 (file)
@@ -476,7 +476,6 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
                        ++put_count;
                }
                if (bo->mem.mm_node) {
-                       bo->mem.mm_node->private = NULL;
                        drm_mm_put_block(bo->mem.mm_node);
                        bo->mem.mm_node = NULL;
                }
@@ -670,7 +669,6 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible,
                        printk(KERN_ERR TTM_PFX "Buffer eviction failed\n");
                spin_lock(&glob->lru_lock);
                if (evict_mem.mm_node) {
-                       evict_mem.mm_node->private = NULL;
                        drm_mm_put_block(evict_mem.mm_node);
                        evict_mem.mm_node = NULL;
                }
@@ -929,8 +927,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
                mem->mm_node = node;
                mem->mem_type = mem_type;
                mem->placement = cur_flags;
-               if (node)
-                       node->private = bo;
                return 0;
        }
 
@@ -973,7 +969,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
                                                interruptible, no_wait_reserve, no_wait_gpu);
                if (ret == 0 && mem->mm_node) {
                        mem->placement = cur_flags;
-                       mem->mm_node->private = bo;
                        return 0;
                }
                if (ret == -ERESTARTSYS)
@@ -1029,7 +1024,6 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
 out_unlock:
        if (ret && mem.mm_node) {
                spin_lock(&glob->lru_lock);
-               mem.mm_node->private = NULL;
                drm_mm_put_block(mem.mm_node);
                spin_unlock(&glob->lru_lock);
        }
@@ -1401,7 +1395,7 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj)
        kfree(glob);
 }
 
-void ttm_bo_global_release(struct ttm_global_reference *ref)
+void ttm_bo_global_release(struct drm_global_reference *ref)
 {
        struct ttm_bo_global *glob = ref->object;
 
@@ -1410,7 +1404,7 @@ void ttm_bo_global_release(struct ttm_global_reference *ref)
 }
 EXPORT_SYMBOL(ttm_bo_global_release);
 
-int ttm_bo_global_init(struct ttm_global_reference *ref)
+int ttm_bo_global_init(struct drm_global_reference *ref)
 {
        struct ttm_bo_global_ref *bo_ref =
                container_of(ref, struct ttm_bo_global_ref, ref);
index 13012a1f1486c1bf4cad58608068f27b667b2335..7cffb3e0423249ec4f78f7c7cbdc72b6df921e50 100644 (file)
@@ -353,8 +353,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
        fbo->vm_node = NULL;
 
        fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
-       if (fbo->mem.mm_node)
-               fbo->mem.mm_node->private = (void *)fbo;
        kref_init(&fbo->list_kref);
        kref_init(&fbo->kref);
        fbo->destroy = &ttm_transfered_destroy;
index 9a6edbfeaa9e49c7369623dbb542eb61204fe904..902d7cf9fb4eb5a59cc4bdb13518449344208a22 100644 (file)
@@ -70,8 +70,6 @@ static int __init ttm_init(void)
        if (unlikely(ret != 0))
                return ret;
 
-       ttm_global_init();
-
        atomic_set(&device_released, 0);
        ret = drm_class_device_register(&ttm_drm_class_device);
        if (unlikely(ret != 0))
@@ -81,7 +79,6 @@ static int __init ttm_init(void)
 out_no_dev_reg:
        atomic_set(&device_released, 1);
        wake_up_all(&exit_q);
-       ttm_global_release();
        return ret;
 }
 
@@ -95,7 +92,6 @@ static void __exit ttm_exit(void)
         */
 
        wait_event(exit_q, atomic_read(&device_released) == 1);
-       ttm_global_release();
 }
 
 module_init(ttm_init);
index bfb92d2832606945bbddc08a15047b1b09ae2881..68dda74a50ae54c8273eb0e076d7ff151f9f7231 100644 (file)
        *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1;  \
        *((uint32_t *)(vb) + 1) = (nData);                      \
        vb = ((uint32_t *)vb) + 2;                              \
-       dev_priv->dma_low +=8;                                  \
+       dev_priv->dma_low += 8;                                 \
 }
 
 #define via_flush_write_combine() DRM_MEMORYBARRIER()
 
-#define VIA_OUT_RING_QW(w1,w2)                 \
+#define VIA_OUT_RING_QW(w1, w2)        do {            \
        *vb++ = (w1);                           \
        *vb++ = (w2);                           \
-       dev_priv->dma_low += 8;
+       dev_priv->dma_low += 8;                 \
+} while (0)
 
-static void via_cmdbuf_start(drm_via_private_t * dev_priv);
-static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
-static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
-static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
-static int via_wait_idle(drm_via_private_t * dev_priv);
-static void via_pad_cache(drm_via_private_t * dev_priv, int qwords);
+static void via_cmdbuf_start(drm_via_private_t *dev_priv);
+static void via_cmdbuf_pause(drm_via_private_t *dev_priv);
+static void via_cmdbuf_reset(drm_via_private_t *dev_priv);
+static void via_cmdbuf_rewind(drm_via_private_t *dev_priv);
+static int via_wait_idle(drm_via_private_t *dev_priv);
+static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
 
 /*
  * Free space in command buffer.
  */
 
-static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv)
+static uint32_t via_cmdbuf_space(drm_via_private_t *dev_priv)
 {
        uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
        uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
@@ -93,7 +94,7 @@ static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv)
  * How much does the command regulator lag behind?
  */
 
-static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv)
+static uint32_t via_cmdbuf_lag(drm_via_private_t *dev_priv)
 {
        uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
        uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
@@ -108,7 +109,7 @@ static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv)
  */
 
 static inline int
-via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
+via_cmdbuf_wait(drm_via_private_t *dev_priv, unsigned int size)
 {
        uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
        uint32_t cur_addr, hw_addr, next_addr;
@@ -146,14 +147,13 @@ static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
            dev_priv->dma_high) {
                via_cmdbuf_rewind(dev_priv);
        }
-       if (via_cmdbuf_wait(dev_priv, size) != 0) {
+       if (via_cmdbuf_wait(dev_priv, size) != 0)
                return NULL;
-       }
 
        return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
 }
 
-int via_dma_cleanup(struct drm_device * dev)
+int via_dma_cleanup(struct drm_device *dev)
 {
        if (dev->dev_private) {
                drm_via_private_t *dev_priv =
@@ -171,9 +171,9 @@ int via_dma_cleanup(struct drm_device * dev)
        return 0;
 }
 
-static int via_initialize(struct drm_device * dev,
-                         drm_via_private_t * dev_priv,
-                         drm_via_dma_init_t * init)
+static int via_initialize(struct drm_device *dev,
+                         drm_via_private_t *dev_priv,
+                         drm_via_dma_init_t *init)
 {
        if (!dev_priv || !dev_priv->mmio) {
                DRM_ERROR("via_dma_init called before via_map_init\n");
@@ -258,7 +258,7 @@ static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *fil
        return retcode;
 }
 
-static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd)
+static int via_dispatch_cmdbuffer(struct drm_device *dev, drm_via_cmdbuffer_t *cmd)
 {
        drm_via_private_t *dev_priv;
        uint32_t *vb;
@@ -271,9 +271,8 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t *
                return -EFAULT;
        }
 
-       if (cmd->size > VIA_PCI_BUF_SIZE) {
+       if (cmd->size > VIA_PCI_BUF_SIZE)
                return -ENOMEM;
-       }
 
        if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
                return -EFAULT;
@@ -291,9 +290,8 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t *
        }
 
        vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
-       if (vb == NULL) {
+       if (vb == NULL)
                return -EAGAIN;
-       }
 
        memcpy(vb, dev_priv->pci_buf, cmd->size);
 
@@ -311,13 +309,12 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t *
        return 0;
 }
 
-int via_driver_dma_quiescent(struct drm_device * dev)
+int via_driver_dma_quiescent(struct drm_device *dev)
 {
        drm_via_private_t *dev_priv = dev->dev_private;
 
-       if (!via_wait_idle(dev_priv)) {
+       if (!via_wait_idle(dev_priv))
                return -EBUSY;
-       }
        return 0;
 }
 
@@ -339,22 +336,17 @@ static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *fi
        DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
 
        ret = via_dispatch_cmdbuffer(dev, cmdbuf);
-       if (ret) {
-               return ret;
-       }
-
-       return 0;
+       return ret;
 }
 
-static int via_dispatch_pci_cmdbuffer(struct drm_device * dev,
-                                     drm_via_cmdbuffer_t * cmd)
+static int via_dispatch_pci_cmdbuffer(struct drm_device *dev,
+                                     drm_via_cmdbuffer_t *cmd)
 {
        drm_via_private_t *dev_priv = dev->dev_private;
        int ret;
 
-       if (cmd->size > VIA_PCI_BUF_SIZE) {
+       if (cmd->size > VIA_PCI_BUF_SIZE)
                return -ENOMEM;
-       }
        if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
                return -EFAULT;
 
@@ -380,19 +372,14 @@ static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file
        DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
 
        ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf);
-       if (ret) {
-               return ret;
-       }
-
-       return 0;
+       return ret;
 }
 
-static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
+static inline uint32_t *via_align_buffer(drm_via_private_t *dev_priv,
                                         uint32_t * vb, int qw_count)
 {
-       for (; qw_count > 0; --qw_count) {
+       for (; qw_count > 0; --qw_count)
                VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
-       }
        return vb;
 }
 
@@ -401,7 +388,7 @@ static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
  *
  * Returns virtual pointer to ring buffer.
  */
-static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
+static inline uint32_t *via_get_dma(drm_via_private_t *dev_priv)
 {
        return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
 }
@@ -411,18 +398,18 @@ static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
  * modifying the pause address stored in the buffer itself. If
  * the regulator has already paused, restart it.
  */
-static int via_hook_segment(drm_via_private_t * dev_priv,
+static int via_hook_segment(drm_via_private_t *dev_priv,
                            uint32_t pause_addr_hi, uint32_t pause_addr_lo,
                            int no_pci_fire)
 {
        int paused, count;
        volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
-       uint32_t reader,ptr;
+       uint32_t reader, ptr;
        uint32_t diff;
 
        paused = 0;
        via_flush_write_combine();
-       (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1);
+       (void) *(volatile uint32_t *)(via_get_dma(dev_priv) - 1);
 
        *paused_at = pause_addr_lo;
        via_flush_write_combine();
@@ -435,7 +422,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
        dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
 
        /*
-        * If there is a possibility that the command reader will 
+        * If there is a possibility that the command reader will
         * miss the new pause address and pause on the old one,
         * In that case we need to program the new start address
         * using PCI.
@@ -443,9 +430,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
 
        diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
        count = 10000000;
-       while(diff == 0 && count--) {
+       while (diff == 0 && count--) {
                paused = (VIA_READ(0x41c) & 0x80000000);
-               if (paused) 
+               if (paused)
                        break;
                reader = *(dev_priv->hw_addr_ptr);
                diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
@@ -477,7 +464,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
        return paused;
 }
 
-static int via_wait_idle(drm_via_private_t * dev_priv)
+static int via_wait_idle(drm_via_private_t *dev_priv)
 {
        int count = 10000000;
 
@@ -491,9 +478,9 @@ static int via_wait_idle(drm_via_private_t * dev_priv)
        return count;
 }
 
-static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
-                              uint32_t addr, uint32_t * cmd_addr_hi,
-                              uint32_t * cmd_addr_lo, int skip_wait)
+static uint32_t *via_align_cmd(drm_via_private_t *dev_priv, uint32_t cmd_type,
+                              uint32_t addr, uint32_t *cmd_addr_hi,
+                              uint32_t *cmd_addr_lo, int skip_wait)
 {
        uint32_t agp_base;
        uint32_t cmd_addr, addr_lo, addr_hi;
@@ -521,7 +508,7 @@ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
        return vb;
 }
 
-static void via_cmdbuf_start(drm_via_private_t * dev_priv)
+static void via_cmdbuf_start(drm_via_private_t *dev_priv)
 {
        uint32_t pause_addr_lo, pause_addr_hi;
        uint32_t start_addr, start_addr_lo;
@@ -580,7 +567,7 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
        dev_priv->dma_diff = ptr - reader;
 }
 
-static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
+static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
 {
        uint32_t *vb;
 
@@ -590,7 +577,7 @@ static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
        via_align_buffer(dev_priv, vb, qwords);
 }
 
-static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
+static inline void via_dummy_bitblt(drm_via_private_t *dev_priv)
 {
        uint32_t *vb = via_get_dma(dev_priv);
        SetReg2DAGP(0x0C, (0 | (0 << 16)));
@@ -598,7 +585,7 @@ static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
        SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
 }
 
-static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
+static void via_cmdbuf_jump(drm_via_private_t *dev_priv)
 {
        uint32_t agp_base;
        uint32_t pause_addr_lo, pause_addr_hi;
@@ -617,9 +604,8 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
         */
 
        dev_priv->dma_low = 0;
-       if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) {
+       if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0)
                DRM_ERROR("via_cmdbuf_jump failed\n");
-       }
 
        via_dummy_bitblt(dev_priv);
        via_dummy_bitblt(dev_priv);
@@ -657,12 +643,12 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
 }
 
 
-static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
+static void via_cmdbuf_rewind(drm_via_private_t *dev_priv)
 {
        via_cmdbuf_jump(dev_priv);
 }
 
-static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
+static void via_cmdbuf_flush(drm_via_private_t *dev_priv, uint32_t cmd_type)
 {
        uint32_t pause_addr_lo, pause_addr_hi;
 
@@ -670,12 +656,12 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
        via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
 }
 
-static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
+static void via_cmdbuf_pause(drm_via_private_t *dev_priv)
 {
        via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
 }
 
-static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
+static void via_cmdbuf_reset(drm_via_private_t *dev_priv)
 {
        via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP);
        via_wait_idle(dev_priv);
@@ -708,9 +694,8 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *
        case VIA_CMDBUF_SPACE:
                while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size)
                       && --count) {
-                       if (!d_siz->wait) {
+                       if (!d_siz->wait)
                                break;
-                       }
                }
                if (!count) {
                        DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n");
@@ -720,9 +705,8 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *
        case VIA_CMDBUF_LAG:
                while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size)
                       && --count) {
-                       if (!d_siz->wait) {
+                       if (!d_siz->wait)
                                break;
-                       }
                }
                if (!count) {
                        DRM_ERROR("VIA_CMDBUF_LAG timed out.\n");
index 4c54f043068ed3195595863f563a6c19c01bf7fc..9b5b4d9dd62c9fceffe9c5fa0dd218ff7119d5a7 100644 (file)
@@ -70,7 +70,7 @@ via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
                descriptor_this_page;
        dma_addr_t next = vsg->chain_start;
 
-       while(num_desc--) {
+       while (num_desc--) {
                if (descriptor_this_page-- == 0) {
                        cur_descriptor_page--;
                        descriptor_this_page = vsg->descriptors_per_page - 1;
@@ -174,19 +174,19 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
        struct page *page;
        int i;
 
-       switch(vsg->state) {
+       switch (vsg->state) {
        case dr_via_device_mapped:
                via_unmap_blit_from_device(pdev, vsg);
        case dr_via_desc_pages_alloc:
-               for (i=0; i<vsg->num_desc_pages; ++i) {
+               for (i = 0; i < vsg->num_desc_pages; ++i) {
                        if (vsg->desc_pages[i] != NULL)
-                         free_page((unsigned long)vsg->desc_pages[i]);
+                               free_page((unsigned long)vsg->desc_pages[i]);
                }
                kfree(vsg->desc_pages);
        case dr_via_pages_locked:
-               for (i=0; i<vsg->num_pages; ++i) {
-                       if ( NULL != (page = vsg->pages[i])) {
-                               if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction))
+               for (i = 0; i < vsg->num_pages; ++i) {
+                       if (NULL != (page = vsg->pages[i])) {
+                               if (!PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction))
                                        SetPageDirty(page);
                                page_cache_release(page);
                        }
@@ -232,7 +232,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg,  drm_via_dmablit_t *xfer)
 {
        int ret;
        unsigned long first_pfn = VIA_PFN(xfer->mem_addr);
-       vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) -
+       vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) -
                first_pfn + 1;
 
        if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages)))
@@ -268,7 +268,7 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg)
 {
        int i;
 
-       vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t);
+       vsg->descriptors_per_page = PAGE_SIZE / sizeof(drm_via_descriptor_t);
        vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
                vsg->descriptors_per_page;
 
@@ -276,7 +276,7 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg)
                return -ENOMEM;
 
        vsg->state = dr_via_desc_pages_alloc;
-       for (i=0; i<vsg->num_desc_pages; ++i) {
+       for (i = 0; i < vsg->num_desc_pages; ++i) {
                if (NULL == (vsg->desc_pages[i] =
                             (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL)))
                        return -ENOMEM;
@@ -318,21 +318,20 @@ via_dmablit_handler(struct drm_device *dev, int engine, int from_irq)
        drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
        int cur;
        int done_transfer;
-       unsigned long irqsave=0;
+       unsigned long irqsave = 0;
        uint32_t status = 0;
 
        DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n",
                  engine, from_irq, (unsigned long) blitq);
 
-       if (from_irq) {
+       if (from_irq)
                spin_lock(&blitq->blit_lock);
-       } else {
+       else
                spin_lock_irqsave(&blitq->blit_lock, irqsave);
-       }
 
        done_transfer = blitq->is_active &&
-         (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD);
-       done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE));
+         ((status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD);
+       done_transfer = done_transfer || (blitq->aborting && !(status & VIA_DMA_CSR_DE));
 
        cur = blitq->cur;
        if (done_transfer) {
@@ -377,18 +376,16 @@ via_dmablit_handler(struct drm_device *dev, int engine, int from_irq)
                        if (!timer_pending(&blitq->poll_timer))
                                mod_timer(&blitq->poll_timer, jiffies + 1);
                } else {
-                       if (timer_pending(&blitq->poll_timer)) {
+                       if (timer_pending(&blitq->poll_timer))
                                del_timer(&blitq->poll_timer);
-                       }
                        via_dmablit_engine_off(dev, engine);
                }
        }
 
-       if (from_irq) {
+       if (from_irq)
                spin_unlock(&blitq->blit_lock);
-       } else {
+       else
                spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
-       }
 }
 
 
@@ -414,10 +411,9 @@ via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_que
                ((blitq->cur_blit_handle - handle) <= (1 << 23));
 
        if (queue && active) {
-               slot = handle - blitq->done_blit_handle + blitq->cur -1;
-               if (slot >= VIA_NUM_BLIT_SLOTS) {
+               slot = handle - blitq->done_blit_handle + blitq->cur - 1;
+               if (slot >= VIA_NUM_BLIT_SLOTS)
                        slot -= VIA_NUM_BLIT_SLOTS;
-               }
                *queue = blitq->blit_queue + slot;
        }
 
@@ -506,12 +502,12 @@ via_dmablit_workqueue(struct work_struct *work)
        int cur_released;
 
 
-       DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long)
+       DRM_DEBUG("Workqueue task called for blit engine %ld\n", (unsigned long)
                  (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues));
 
        spin_lock_irqsave(&blitq->blit_lock, irqsave);
 
-       while(blitq->serviced != blitq->cur) {
+       while (blitq->serviced != blitq->cur) {
 
                cur_released = blitq->serviced++;
 
@@ -545,13 +541,13 @@ via_dmablit_workqueue(struct work_struct *work)
 void
 via_init_dmablit(struct drm_device *dev)
 {
-       int i,j;
+       int i, j;
        drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
        drm_via_blitq_t *blitq;
 
        pci_set_master(dev->pdev);
 
-       for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) {
+       for (i = 0; i < VIA_NUM_BLIT_ENGINES; ++i) {
                blitq = dev_priv->blit_queues + i;
                blitq->dev = dev;
                blitq->cur_blit_handle = 0;
@@ -564,9 +560,8 @@ via_init_dmablit(struct drm_device *dev)
                blitq->is_active = 0;
                blitq->aborting = 0;
                spin_lock_init(&blitq->blit_lock);
-               for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) {
+               for (j = 0; j < VIA_NUM_BLIT_SLOTS; ++j)
                        DRM_INIT_WAITQUEUE(blitq->blit_queue + j);
-               }
                DRM_INIT_WAITQUEUE(&blitq->busy_queue);
                INIT_WORK(&blitq->wq, via_dmablit_workqueue);
                setup_timer(&blitq->poll_timer, via_dmablit_timer,
@@ -685,18 +680,17 @@ via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmabli
 static int
 via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine)
 {
-       int ret=0;
+       int ret = 0;
        unsigned long irqsave;
 
        DRM_DEBUG("Num free is %d\n", blitq->num_free);
        spin_lock_irqsave(&blitq->blit_lock, irqsave);
-       while(blitq->num_free == 0) {
+       while (blitq->num_free == 0) {
                spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
 
                DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0);
-               if (ret) {
+               if (ret)
                        return (-EINTR == ret) ? -EAGAIN : ret;
-               }
 
                spin_lock_irqsave(&blitq->blit_lock, irqsave);
        }
@@ -719,7 +713,7 @@ via_dmablit_release_slot(drm_via_blitq_t *blitq)
        spin_lock_irqsave(&blitq->blit_lock, irqsave);
        blitq->num_free++;
        spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
-       DRM_WAKEUP( &blitq->busy_queue );
+       DRM_WAKEUP(&blitq->busy_queue);
 }
 
 /*
@@ -744,9 +738,8 @@ via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer)
 
        engine = (xfer->to_fb) ? 0 : 1;
        blitq = dev_priv->blit_queues + engine;
-       if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) {
+       if (0 != (ret = via_dmablit_grab_slot(blitq, engine)))
                return ret;
-       }
        if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) {
                via_dmablit_release_slot(blitq);
                return -ENOMEM;
@@ -780,7 +773,7 @@ via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer)
  */
 
 int
-via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv )
+via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_via_blitsync_t *sync = data;
        int err;
@@ -804,7 +797,7 @@ via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_pri
  */
 
 int
-via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv )
+via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_via_dmablit_t *xfer = data;
        int err;
index 7408a547a036937af9bccc52ee77ab2e5a0e3fb2..9b662a327cef3e225765a6685b3893e73da1ec43 100644 (file)
@@ -45,12 +45,12 @@ typedef struct _drm_via_sg_info {
        int num_desc;
        enum dma_data_direction direction;
        unsigned char *bounce_buffer;
-        dma_addr_t chain_start;
+       dma_addr_t chain_start;
        uint32_t free_on_sequence;
-        unsigned int descriptors_per_page;
+       unsigned int descriptors_per_page;
        int aborted;
        enum {
-               dr_via_device_mapped,
+               dr_via_device_mapped,
                dr_via_desc_pages_alloc,
                dr_via_pages_locked,
                dr_via_pages_alloc,
@@ -68,7 +68,7 @@ typedef struct _drm_via_blitq {
        unsigned num_free;
        unsigned num_outstanding;
        unsigned long end;
-        int aborting;
+       int aborting;
        int is_active;
        drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS];
        spinlock_t blit_lock;
index cafcb844a2233879da8d8fb110658e963982b780..9cf87d9123252c49c00c79a396cbe9a1b836c0a0 100644 (file)
@@ -107,9 +107,9 @@ enum via_family {
 #define VIA_BASE ((dev_priv->mmio))
 
 #define VIA_READ(reg)          DRM_READ32(VIA_BASE, reg)
-#define VIA_WRITE(reg,val)     DRM_WRITE32(VIA_BASE, reg, val)
+#define VIA_WRITE(reg, val)    DRM_WRITE32(VIA_BASE, reg, val)
 #define VIA_READ8(reg)         DRM_READ8(VIA_BASE, reg)
-#define VIA_WRITE8(reg,val)    DRM_WRITE8(VIA_BASE, reg, val)
+#define VIA_WRITE8(reg, val)   DRM_WRITE8(VIA_BASE, reg, val)
 
 extern struct drm_ioctl_desc via_ioctls[];
 extern int via_max_ioctl;
@@ -121,28 +121,28 @@ extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *fil
 extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv );
-extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv );
+extern int via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv);
 
 extern int via_driver_load(struct drm_device *dev, unsigned long chipset);
 extern int via_driver_unload(struct drm_device *dev);
 
-extern int via_init_context(struct drm_device * dev, int context);
-extern int via_final_context(struct drm_device * dev, int context);
+extern int via_init_context(struct drm_device *dev, int context);
+extern int via_final_context(struct drm_device *dev, int context);
 
-extern int via_do_cleanup_map(struct drm_device * dev);
+extern int via_do_cleanup_map(struct drm_device *dev);
 extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
 extern int via_enable_vblank(struct drm_device *dev, int crtc);
 extern void via_disable_vblank(struct drm_device *dev, int crtc);
 
 extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
-extern void via_driver_irq_preinstall(struct drm_device * dev);
+extern void via_driver_irq_preinstall(struct drm_device *dev);
 extern int via_driver_irq_postinstall(struct drm_device *dev);
-extern void via_driver_irq_uninstall(struct drm_device * dev);
+extern void via_driver_irq_uninstall(struct drm_device *dev);
 
-extern int via_dma_cleanup(struct drm_device * dev);
+extern int via_dma_cleanup(struct drm_device *dev);
 extern void via_init_command_verifier(void);
-extern int via_driver_dma_quiescent(struct drm_device * dev);
+extern int via_driver_dma_quiescent(struct drm_device *dev);
 extern void via_init_futex(drm_via_private_t *dev_priv);
 extern void via_cleanup_futex(drm_via_private_t *dev_priv);
 extern void via_release_futex(drm_via_private_t *dev_priv, int context);
index 34079f251cd4d9c5960b19388c9dce9efd943e79..d391f48ef87ad586c0295b51233e7d01356de5c7 100644 (file)
@@ -141,11 +141,10 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
                        atomic_inc(&cur_irq->irq_received);
                        DRM_WAKEUP(&cur_irq->irq_queue);
                        handled = 1;
-                       if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) {
+                       if (dev_priv->irq_map[drm_via_irq_dma0_td] == i)
                                via_dmablit_handler(dev, 0, 1);
-                       } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) {
+                       else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i)
                                via_dmablit_handler(dev, 1, 1);
-                       }
                }
                cur_irq++;
        }
@@ -160,7 +159,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
                return IRQ_NONE;
 }
 
-static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
+static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t *dev_priv)
 {
        u32 status;
 
@@ -207,7 +206,7 @@ void via_disable_vblank(struct drm_device *dev, int crtc)
 }
 
 static int
-via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequence,
+via_driver_irq_wait(struct drm_device *dev, unsigned int irq, int force_sequence,
                    unsigned int *sequence)
 {
        drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
@@ -260,7 +259,7 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc
  * drm_dma.h hooks
  */
 
-void via_driver_irq_preinstall(struct drm_device * dev)
+void via_driver_irq_preinstall(struct drm_device *dev)
 {
        drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
        u32 status;
@@ -329,7 +328,7 @@ int via_driver_irq_postinstall(struct drm_device *dev)
        return 0;
 }
 
-void via_driver_irq_uninstall(struct drm_device * dev)
+void via_driver_irq_uninstall(struct drm_device *dev)
 {
        drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
        u32 status;
index 6e6f915916395fc6f47d82943d976ae3e796ead4..6cca9a709f7a25dfc3ba890f070023196450d7b1 100644 (file)
@@ -25,7 +25,7 @@
 #include "via_drm.h"
 #include "via_drv.h"
 
-static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
+static int via_do_init_map(struct drm_device *dev, drm_via_init_t *init)
 {
        drm_via_private_t *dev_priv = dev->dev_private;
 
@@ -68,7 +68,7 @@ static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
        return 0;
 }
 
-int via_do_cleanup_map(struct drm_device * dev)
+int via_do_cleanup_map(struct drm_device *dev)
 {
        via_dma_cleanup(dev);
 
index f694cb5ededca2ccfc74bd712b60a0cd06248bce..6cc2dadae3ef06acb3e94ff60da0d968470ac431 100644 (file)
@@ -31,7 +31,7 @@
 #include "drm_sman.h"
 
 #define VIA_MM_ALIGN_SHIFT 4
-#define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1)
+#define VIA_MM_ALIGN_MASK ((1 << VIA_MM_ALIGN_SHIFT) - 1)
 
 int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
@@ -172,7 +172,7 @@ int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
 }
 
 
-void via_reclaim_buffers_locked(struct drm_device * dev,
+void via_reclaim_buffers_locked(struct drm_device *dev,
                                struct drm_file *file_priv)
 {
        drm_via_private_t *dev_priv = dev->dev_private;
@@ -183,9 +183,8 @@ void via_reclaim_buffers_locked(struct drm_device * dev,
                return;
        }
 
-       if (dev->driver->dma_quiescent) {
+       if (dev->driver->dma_quiescent)
                dev->driver->dma_quiescent(dev);
-       }
 
        drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
        mutex_unlock(&dev->struct_mutex);
index 46a57919874797b3b41d694b1ab70159a6f3e13e..48957b856d41d89695a2e91158ae1a4e8ec1f6cb 100644 (file)
@@ -235,7 +235,7 @@ static hazard_t table2[256];
 static hazard_t table3[256];
 
 static __inline__ int
-eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
+eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words)
 {
        if ((buf_end - *buf) >= num_words) {
                *buf += num_words;
@@ -252,7 +252,7 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
 static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq,
                                                    unsigned long offset,
                                                    unsigned long size,
-                                                   struct drm_device * dev)
+                                                   struct drm_device *dev)
 {
        struct drm_map_list *r_list;
        drm_local_map_t *map = seq->map_cache;
@@ -344,7 +344,7 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
 }
 
 static __inline__ int
-investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
+investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
 {
        register uint32_t tmp, *tmp_addr;
 
@@ -518,7 +518,7 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
 
 static __inline__ int
 via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end,
-                   drm_via_state_t * cur_seq)
+                   drm_via_state_t *cur_seq)
 {
        drm_via_private_t *dev_priv =
            (drm_via_private_t *) cur_seq->dev->dev_private;
@@ -621,8 +621,8 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end,
 }
 
 static __inline__ verifier_state_t
-via_check_header2(uint32_t const **buffer, const uint32_t * buf_end,
-                 drm_via_state_t * hc_state)
+via_check_header2(uint32_t const **buffer, const uint32_t *buf_end,
+                 drm_via_state_t *hc_state)
 {
        uint32_t cmd;
        int hz_mode;
@@ -706,16 +706,15 @@ via_check_header2(uint32_t const **buffer, const uint32_t * buf_end,
                        return state_error;
                }
        }
-       if (hc_state->unfinished && finish_current_sequence(hc_state)) {
+       if (hc_state->unfinished && finish_current_sequence(hc_state))
                return state_error;
-       }
        *buffer = buf;
        return state_command;
 }
 
 static __inline__ verifier_state_t
-via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer,
-                 const uint32_t * buf_end, int *fire_count)
+via_parse_header2(drm_via_private_t *dev_priv, uint32_t const **buffer,
+                 const uint32_t *buf_end, int *fire_count)
 {
        uint32_t cmd;
        const uint32_t *buf = *buffer;
@@ -833,8 +832,8 @@ via_check_header1(uint32_t const **buffer, const uint32_t * buf_end)
 }
 
 static __inline__ verifier_state_t
-via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer,
-                 const uint32_t * buf_end)
+via_parse_header1(drm_via_private_t *dev_priv, uint32_t const **buffer,
+                 const uint32_t *buf_end)
 {
        register uint32_t cmd;
        const uint32_t *buf = *buffer;
@@ -851,7 +850,7 @@ via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer,
 }
 
 static __inline__ verifier_state_t
-via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end)
+via_check_vheader5(uint32_t const **buffer, const uint32_t *buf_end)
 {
        uint32_t data;
        const uint32_t *buf = *buffer;
@@ -884,8 +883,8 @@ via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end)
 }
 
 static __inline__ verifier_state_t
-via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer,
-                  const uint32_t * buf_end)
+via_parse_vheader5(drm_via_private_t *dev_priv, uint32_t const **buffer,
+                  const uint32_t *buf_end)
 {
        uint32_t addr, count, i;
        const uint32_t *buf = *buffer;
@@ -893,9 +892,8 @@ via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer,
        addr = *buf++ & ~VIA_VIDEOMASK;
        i = count = *buf;
        buf += 3;
-       while (i--) {
+       while (i--)
                VIA_WRITE(addr, *buf++);
-       }
        if (count & 3)
                buf += 4 - (count & 3);
        *buffer = buf;
@@ -940,8 +938,8 @@ via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end)
 }
 
 static __inline__ verifier_state_t
-via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer,
-                  const uint32_t * buf_end)
+via_parse_vheader6(drm_via_private_t *dev_priv, uint32_t const **buffer,
+                  const uint32_t *buf_end)
 {
 
        uint32_t addr, count, i;
@@ -1037,7 +1035,7 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size,
 }
 
 int
-via_parse_command_stream(struct drm_device * dev, const uint32_t * buf,
+via_parse_command_stream(struct drm_device *dev, const uint32_t *buf,
                         unsigned int size)
 {
 
@@ -1085,9 +1083,8 @@ via_parse_command_stream(struct drm_device * dev, const uint32_t * buf,
                        return -EINVAL;
                }
        }
-       if (state == state_error) {
+       if (state == state_error)
                return -EINVAL;
-       }
        return 0;
 }
 
@@ -1096,13 +1093,11 @@ setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
 {
        int i;
 
-       for (i = 0; i < 256; ++i) {
+       for (i = 0; i < 256; ++i)
                table[i] = forbidden_command;
-       }
 
-       for (i = 0; i < size; ++i) {
+       for (i = 0; i < size; ++i)
                table[init_table[i].code] = init_table[i].hz;
-       }
 }
 
 void via_init_command_verifier(void)
index d6f8214b69f59ab3e2934a810205b81e699a7956..26b6d361ab95bc9983fd4795a60c02143524aafb 100644 (file)
@@ -54,8 +54,8 @@ typedef struct {
        const uint32_t *buf_start;
 } drm_via_state_t;
 
-extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
-                                    struct drm_device * dev, int agp);
+extern int via_verify_command_stream(const uint32_t *buf, unsigned int size,
+                                    struct drm_device *dev, int agp);
 extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf,
                                    unsigned int size);
 
index 6efac8117c93c77a20eb7079bbdbb6c4440e58b3..675d311f038ff7fad036767c1ccdb880372c6ad9 100644 (file)
@@ -29,7 +29,7 @@
 #include "via_drm.h"
 #include "via_drv.h"
 
-void via_init_futex(drm_via_private_t * dev_priv)
+void via_init_futex(drm_via_private_t *dev_priv)
 {
        unsigned int i;
 
@@ -41,11 +41,11 @@ void via_init_futex(drm_via_private_t * dev_priv)
        }
 }
 
-void via_cleanup_futex(drm_via_private_t * dev_priv)
+void via_cleanup_futex(drm_via_private_t *dev_priv)
 {
 }
 
-void via_release_futex(drm_via_private_t * dev_priv, int context)
+void via_release_futex(drm_via_private_t *dev_priv, int context)
 {
        unsigned int i;
        volatile int *lock;
index b793c8c9acb3162049fabe03b7cf43cfab1939fb..9dd395b90216b17c54598c9309502785a2684220 100644 (file)
@@ -764,7 +764,7 @@ static struct drm_driver driver = {
 
 static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &driver);
+       return drm_get_pci_dev(pdev, ent, &driver);
 }
 
 static int __init vmwgfx_init(void)
index eaad520953393f5f5da3601627e0ec141c4c4a1f..429f917b60bf4b30ecdfd0946f9f1f0978bd5c58 100644 (file)
@@ -164,7 +164,7 @@ struct vmw_vga_topology_state {
 struct vmw_private {
        struct ttm_bo_device bdev;
        struct ttm_bo_global_ref bo_global_ref;
-       struct ttm_global_reference mem_global_ref;
+       struct drm_global_reference mem_global_ref;
 
        struct vmw_fifo_state fifo;
 
index b0866f04ec7613133a6e4ebc7ab3546906af8258..870967a97c15d52eb3f380323e6038d32ed6e76f 100644 (file)
@@ -528,7 +528,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
         * Dirty & Deferred IO
         */
        par->dirty.x1 = par->dirty.x2 = 0;
-       par->dirty.y1 = par->dirty.y1 = 0;
+       par->dirty.y1 = par->dirty.y2 = 0;
        par->dirty.active = true;
        spin_lock_init(&par->dirty.lock);
        info->fbdefio = &vmw_defio;
index e3df4adfb4d8ce4b89a0902bb6c24d9db2bc45a3..83123287c60c2d3f245fa3ab0a9696db2f694ede 100644 (file)
@@ -44,29 +44,29 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma)
        return ttm_bo_mmap(filp, vma, &dev_priv->bdev);
 }
 
-static int vmw_ttm_mem_global_init(struct ttm_global_reference *ref)
+static int vmw_ttm_mem_global_init(struct drm_global_reference *ref)
 {
        DRM_INFO("global init.\n");
        return ttm_mem_global_init(ref->object);
 }
 
-static void vmw_ttm_mem_global_release(struct ttm_global_reference *ref)
+static void vmw_ttm_mem_global_release(struct drm_global_reference *ref)
 {
        ttm_mem_global_release(ref->object);
 }
 
 int vmw_ttm_global_init(struct vmw_private *dev_priv)
 {
-       struct ttm_global_reference *global_ref;
+       struct drm_global_reference *global_ref;
        int ret;
 
        global_ref = &dev_priv->mem_global_ref;
-       global_ref->global_type = TTM_GLOBAL_TTM_MEM;
+       global_ref->global_type = DRM_GLOBAL_TTM_MEM;
        global_ref->size = sizeof(struct ttm_mem_global);
        global_ref->init = &vmw_ttm_mem_global_init;
        global_ref->release = &vmw_ttm_mem_global_release;
 
-       ret = ttm_global_item_ref(global_ref);
+       ret = drm_global_item_ref(global_ref);
        if (unlikely(ret != 0)) {
                DRM_ERROR("Failed setting up TTM memory accounting.\n");
                return ret;
@@ -75,11 +75,11 @@ int vmw_ttm_global_init(struct vmw_private *dev_priv)
        dev_priv->bo_global_ref.mem_glob =
                dev_priv->mem_global_ref.object;
        global_ref = &dev_priv->bo_global_ref.ref;
-       global_ref->global_type = TTM_GLOBAL_TTM_BO;
+       global_ref->global_type = DRM_GLOBAL_TTM_BO;
        global_ref->size = sizeof(struct ttm_bo_global);
        global_ref->init = &ttm_bo_global_init;
        global_ref->release = &ttm_bo_global_release;
-               ret = ttm_global_item_ref(global_ref);
+       ret = drm_global_item_ref(global_ref);
 
        if (unlikely(ret != 0)) {
                DRM_ERROR("Failed setting up TTM buffer objects.\n");
@@ -88,12 +88,12 @@ int vmw_ttm_global_init(struct vmw_private *dev_priv)
 
        return 0;
 out_no_bo:
-       ttm_global_item_unref(&dev_priv->mem_global_ref);
+       drm_global_item_unref(&dev_priv->mem_global_ref);
        return ret;
 }
 
 void vmw_ttm_global_release(struct vmw_private *dev_priv)
 {
-       ttm_global_item_unref(&dev_priv->bo_global_ref.ref);
-       ttm_global_item_unref(&dev_priv->mem_global_ref);
+       drm_global_item_unref(&dev_priv->bo_global_ref.ref);
+       drm_global_item_unref(&dev_priv->mem_global_ref);
 }
index c57e530d07c75d1bd8472f22370274e86d3022ff..4d382ae530923c5e0d90bbb4d043b3d7da5c4a26 100644 (file)
@@ -407,6 +407,13 @@ config SENSORS_CORETEMP
          sensor inside your CPU. Most of the family 6 CPUs
          are supported. Check documentation/driver for details.
 
+config SENSORS_PKGTEMP
+       tristate "Intel processor package temperature sensor"
+       depends on X86 && PCI && EXPERIMENTAL
+       help
+         If you say yes here you get support for the package level temperature
+         sensor inside your CPU. Check documentation/driver for details.
+
 config SENSORS_IBMAEM
        tristate "IBM Active Energy Manager temperature/power sensors and control"
        select IPMI_SI
index c5057745b068351932ba4fe01a462041c92cfee1..9103bd6ea73aa0755b9754467e0a4bd7b608bd7b 100644 (file)
@@ -39,6 +39,7 @@ obj-$(CONFIG_SENSORS_AMS)     += ams/
 obj-$(CONFIG_SENSORS_ASC7621)  += asc7621.o
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
+obj-$(CONFIG_SENSORS_PKGTEMP)  += pkgtemp.o
 obj-$(CONFIG_SENSORS_DME1737)  += dme1737.o
 obj-$(CONFIG_SENSORS_DS1621)   += ds1621.o
 obj-$(CONFIG_SENSORS_EMC1403)  += emc1403.o
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c
new file mode 100644 (file)
index 0000000..74157fc
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * pkgtemp.c - Linux kernel module for processor package hardware monitoring
+ *
+ * Copyright (C) 2010 Fenghua Yu <fenghua.yu@intel.com>
+ *
+ * Inspired from many hwmon drivers especially coretemp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/pci.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+
+#define DRVNAME        "pkgtemp"
+
+enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL, SHOW_NAME };
+
+/*
+ * Functions declaration
+ */
+
+static struct pkgtemp_data *pkgtemp_update_device(struct device *dev);
+
+struct pkgtemp_data {
+       struct device *hwmon_dev;
+       struct mutex update_lock;
+       const char *name;
+       u32 id;
+       u16 phys_proc_id;
+       char valid;             /* zero until following fields are valid */
+       unsigned long last_updated;     /* in jiffies */
+       int temp;
+       int tjmax;
+       int ttarget;
+       u8 alarm;
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+                         *devattr, char *buf)
+{
+       int ret;
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct pkgtemp_data *data = dev_get_drvdata(dev);
+
+       if (attr->index == SHOW_NAME)
+               ret = sprintf(buf, "%s\n", data->name);
+       else    /* show label */
+               ret = sprintf(buf, "physical id %d\n",
+                             data->phys_proc_id);
+       return ret;
+}
+
+static ssize_t show_alarm(struct device *dev, struct device_attribute
+                         *devattr, char *buf)
+{
+       struct pkgtemp_data *data = pkgtemp_update_device(dev);
+       /* read the Out-of-spec log, never clear */
+       return sprintf(buf, "%d\n", data->alarm);
+}
+
+static ssize_t show_temp(struct device *dev,
+                        struct device_attribute *devattr, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct pkgtemp_data *data = pkgtemp_update_device(dev);
+       int err = 0;
+
+       if (attr->index == SHOW_TEMP)
+               err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
+       else if (attr->index == SHOW_TJMAX)
+               err = sprintf(buf, "%d\n", data->tjmax);
+       else
+               err = sprintf(buf, "%d\n", data->ttarget);
+       return err;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, SHOW_TEMP);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, SHOW_TJMAX);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, SHOW_TTARGET);
+static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
+
+static struct attribute *pkgtemp_attributes[] = {
+       &sensor_dev_attr_name.dev_attr.attr,
+       &sensor_dev_attr_temp1_label.dev_attr.attr,
+       &dev_attr_temp1_crit_alarm.attr,
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group pkgtemp_group = {
+       .attrs = pkgtemp_attributes,
+};
+
+static struct pkgtemp_data *pkgtemp_update_device(struct device *dev)
+{
+       struct pkgtemp_data *data = dev_get_drvdata(dev);
+       unsigned int cpu;
+       int err;
+
+       mutex_lock(&data->update_lock);
+
+       if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
+               u32 eax, edx;
+
+               data->valid = 0;
+               cpu = data->id;
+               err = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_STATUS,
+                                  &eax, &edx);
+               if (!err) {
+                       data->alarm = (eax >> 5) & 1;
+                       data->temp = data->tjmax - (((eax >> 16)
+                                                       & 0x7f) * 1000);
+                       data->valid = 1;
+               } else
+                       dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
+
+               data->last_updated = jiffies;
+       }
+
+       mutex_unlock(&data->update_lock);
+       return data;
+}
+
+static int get_tjmax(int cpu, struct device *dev)
+{
+       int default_tjmax = 100000;
+       int err;
+       u32 eax, edx;
+       u32 val;
+
+       /* IA32_TEMPERATURE_TARGET contains the TjMax value */
+       err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
+       if (!err) {
+               val = (eax >> 16) & 0xff;
+               if ((val > 80) && (val < 120)) {
+                       dev_info(dev, "TjMax is %d C.\n", val);
+                       return val * 1000;
+               }
+       }
+       dev_warn(dev, "Unable to read TjMax from CPU.\n");
+       return default_tjmax;
+}
+
+static int __devinit pkgtemp_probe(struct platform_device *pdev)
+{
+       struct pkgtemp_data *data;
+       int err;
+       u32 eax, edx;
+#ifdef CONFIG_SMP
+       struct cpuinfo_x86 *c = &cpu_data(pdev->id);
+#endif
+
+       data = kzalloc(sizeof(struct pkgtemp_data), GFP_KERNEL);
+       if (!data) {
+               err = -ENOMEM;
+               dev_err(&pdev->dev, "Out of memory\n");
+               goto exit;
+       }
+
+       data->id = pdev->id;
+#ifdef CONFIG_SMP
+       data->phys_proc_id = c->phys_proc_id;
+#endif
+       data->name = "pkgtemp";
+       mutex_init(&data->update_lock);
+
+       /* test if we can access the THERM_STATUS MSR */
+       err = rdmsr_safe_on_cpu(data->id, MSR_IA32_PACKAGE_THERM_STATUS,
+                               &eax, &edx);
+       if (err) {
+               dev_err(&pdev->dev,
+                       "Unable to access THERM_STATUS MSR, giving up\n");
+               goto exit_free;
+       }
+
+       data->tjmax = get_tjmax(data->id, &pdev->dev);
+       platform_set_drvdata(pdev, data);
+
+       err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET,
+                               &eax, &edx);
+       if (err) {
+               dev_warn(&pdev->dev, "Unable to read"
+                               " IA32_TEMPERATURE_TARGET MSR\n");
+       } else {
+               data->ttarget = data->tjmax - (((eax >> 8) & 0xff) * 1000);
+               err = device_create_file(&pdev->dev,
+                               &sensor_dev_attr_temp1_max.dev_attr);
+               if (err)
+                       goto exit_free;
+       }
+
+       err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group);
+       if (err)
+               goto exit_free;
+
+       data->hwmon_dev = hwmon_device_register(&pdev->dev);
+       if (IS_ERR(data->hwmon_dev)) {
+               err = PTR_ERR(data->hwmon_dev);
+               dev_err(&pdev->dev, "Class registration failed (%d)\n",
+                       err);
+               goto exit_class;
+       }
+
+       return 0;
+
+exit_class:
+       sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
+exit_free:
+       kfree(data);
+exit:
+       return err;
+}
+
+static int __devexit pkgtemp_remove(struct platform_device *pdev)
+{
+       struct pkgtemp_data *data = platform_get_drvdata(pdev);
+
+       hwmon_device_unregister(data->hwmon_dev);
+       sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
+       platform_set_drvdata(pdev, NULL);
+       kfree(data);
+       return 0;
+}
+
+static struct platform_driver pkgtemp_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = DRVNAME,
+       },
+       .probe = pkgtemp_probe,
+       .remove = __devexit_p(pkgtemp_remove),
+};
+
+struct pdev_entry {
+       struct list_head list;
+       struct platform_device *pdev;
+       unsigned int cpu;
+#ifdef CONFIG_SMP
+       u16 phys_proc_id;
+#endif
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int __cpuinit pkgtemp_device_add(unsigned int cpu)
+{
+       int err;
+       struct platform_device *pdev;
+       struct pdev_entry *pdev_entry;
+#ifdef CONFIG_SMP
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
+#endif
+
+       mutex_lock(&pdev_list_mutex);
+
+#ifdef CONFIG_SMP
+       /* Only keep the first entry in each package */
+       list_for_each_entry(pdev_entry, &pdev_list, list) {
+               if (c->phys_proc_id == pdev_entry->phys_proc_id) {
+                       err = 0;        /* Not an error */
+                       goto exit;
+               }
+       }
+#endif
+
+       pdev = platform_device_alloc(DRVNAME, cpu);
+       if (!pdev) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+               goto exit;
+       }
+
+       pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+       if (!pdev_entry) {
+               err = -ENOMEM;
+               goto exit_device_put;
+       }
+
+       err = platform_device_add(pdev);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+                      err);
+               goto exit_device_free;
+       }
+
+#ifdef CONFIG_SMP
+       pdev_entry->phys_proc_id = c->phys_proc_id;
+#endif
+       pdev_entry->pdev = pdev;
+       pdev_entry->cpu = cpu;
+       list_add_tail(&pdev_entry->list, &pdev_list);
+       mutex_unlock(&pdev_list_mutex);
+
+       return 0;
+
+exit_device_free:
+       kfree(pdev_entry);
+exit_device_put:
+       platform_device_put(pdev);
+exit:
+       mutex_unlock(&pdev_list_mutex);
+       return err;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void pkgtemp_device_remove(unsigned int cpu)
+{
+       struct pdev_entry *p, *n;
+       unsigned int i;
+       int err;
+
+       mutex_lock(&pdev_list_mutex);
+       list_for_each_entry_safe(p, n, &pdev_list, list) {
+               if (p->cpu != cpu)
+                       continue;
+
+               platform_device_unregister(p->pdev);
+               list_del(&p->list);
+               kfree(p);
+               for_each_cpu(i, cpu_core_mask(cpu)) {
+                       if (i != cpu) {
+                               err = pkgtemp_device_add(i);
+                               if (!err)
+                                       break;
+                       }
+               }
+               break;
+       }
+       mutex_unlock(&pdev_list_mutex);
+}
+
+static int __cpuinit pkgtemp_cpu_callback(struct notifier_block *nfb,
+                                unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned long) hcpu;
+
+       switch (action) {
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+               pkgtemp_device_add(cpu);
+               break;
+       case CPU_DOWN_PREPARE:
+               pkgtemp_device_remove(cpu);
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block pkgtemp_cpu_notifier __refdata = {
+       .notifier_call = pkgtemp_cpu_callback,
+};
+#endif                         /* !CONFIG_HOTPLUG_CPU */
+
+static int __init pkgtemp_init(void)
+{
+       int i, err = -ENODEV;
+       struct pdev_entry *p, *n;
+
+       /* quick check if we run Intel */
+       if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
+               goto exit;
+
+       err = platform_driver_register(&pkgtemp_driver);
+       if (err)
+               goto exit;
+
+       for_each_online_cpu(i) {
+               struct cpuinfo_x86 *c = &cpu_data(i);
+
+               if (!cpu_has(c, X86_FEATURE_PTS))
+                       continue;
+
+               err = pkgtemp_device_add(i);
+               if (err)
+                       goto exit_devices_unreg;
+       }
+       if (list_empty(&pdev_list)) {
+               err = -ENODEV;
+               goto exit_driver_unreg;
+       }
+
+#ifdef CONFIG_HOTPLUG_CPU
+       register_hotcpu_notifier(&pkgtemp_cpu_notifier);
+#endif
+       return 0;
+
+exit_devices_unreg:
+       mutex_lock(&pdev_list_mutex);
+       list_for_each_entry_safe(p, n, &pdev_list, list) {
+               platform_device_unregister(p->pdev);
+               list_del(&p->list);
+               kfree(p);
+       }
+       mutex_unlock(&pdev_list_mutex);
+exit_driver_unreg:
+       platform_driver_unregister(&pkgtemp_driver);
+exit:
+       return err;
+}
+
+static void __exit pkgtemp_exit(void)
+{
+       struct pdev_entry *p, *n;
+#ifdef CONFIG_HOTPLUG_CPU
+       unregister_hotcpu_notifier(&pkgtemp_cpu_notifier);
+#endif
+       mutex_lock(&pdev_list_mutex);
+       list_for_each_entry_safe(p, n, &pdev_list, list) {
+               platform_device_unregister(p->pdev);
+               list_del(&p->list);
+               kfree(p);
+       }
+       mutex_unlock(&pdev_list_mutex);
+       platform_driver_unregister(&pkgtemp_driver);
+}
+
+MODULE_AUTHOR("Fenghua Yu <fenghua.yu@intel.com>");
+MODULE_DESCRIPTION("Intel processor package temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(pkgtemp_init)
+module_exit(pkgtemp_exit)
index 5da5942cf970763be13b716c5bd2a3c10d1af3ab..89643261ccdb93aecc42eb5d735bda668b64c0eb 100644 (file)
@@ -311,12 +311,12 @@ static struct of_platform_driver env_driver = {
 
 static int __init env_init(void)
 {
-       return of_register_driver(&env_driver, &of_bus_type);
+       return of_register_platform_driver(&env_driver);
 }
 
 static void __exit env_exit(void)
 {
-       of_unregister_driver(&env_driver);
+       of_unregister_platform_driver(&env_driver);
 }
 
 module_init(env_init);
index b02b4533651d8076f522e96923b09b3f3e8b289b..e591de1bc7044260f0735731cf6b6981e3f075bc 100644 (file)
@@ -652,6 +652,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
        cpm->adap = cpm_ops;
        i2c_set_adapdata(&cpm->adap, cpm);
        cpm->adap.dev.parent = &ofdev->dev;
+       cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node);
 
        result = cpm_i2c_setup(cpm);
        if (result) {
@@ -676,11 +677,6 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
        dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
                cpm->adap.name);
 
-       /*
-        * register OF I2C devices
-        */
-       of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node);
-
        return 0;
 out_shut:
        cpm_i2c_shutdown(cpm);
index bf344135647a8654a47c8b343c140e68453f40d5..1168d61418c95a86935729b007a03007dd28b371 100644 (file)
@@ -745,6 +745,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
        /* Register it with i2c layer */
        adap = &dev->adap;
        adap->dev.parent = &ofdev->dev;
+       adap->dev.of_node = of_node_get(np);
        strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
        i2c_set_adapdata(adap, dev);
        adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
@@ -760,9 +761,6 @@ static int __devinit iic_probe(struct of_device *ofdev,
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
-       /* Now register all the child nodes */
-       of_register_i2c_devices(adap, np);
-
        return 0;
 
 error_cleanup:
index 54247d475fc339b7994ccde36d5ba85af79a2f71..6545d1c99b61e157c3570a9adbb9b42ecc1cd440 100644 (file)
@@ -625,13 +625,13 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
        i2c->adap = mpc_ops;
        i2c_set_adapdata(&i2c->adap, i2c);
        i2c->adap.dev.parent = &op->dev;
+       i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
 
        result = i2c_add_adapter(&i2c->adap);
        if (result < 0) {
                dev_err(i2c->dev, "failed to add adapter\n");
                goto fail_add;
        }
-       of_register_i2c_devices(&i2c->adap, op->dev.of_node);
 
        return result;
 
index 0815e10da7c6da3b5ed4974cdb505fc848c43d87..df937df845ebf3b50b3941c9aea569ef3bb7f22b 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/of_i2c.h>
+#include <linux/of_device.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
 #include <linux/irqflags.h>
@@ -70,6 +72,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
        if (!client)
                return 0;
 
+       /* Attempt an OF style match */
+       if (of_driver_match_device(dev, drv))
+               return 1;
+
        driver = to_i2c_driver(drv);
        /* match on an id table if there is one */
        if (driver->id_table)
@@ -790,6 +796,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
        if (adap->nr < __i2c_first_dynamic_bus_num)
                i2c_scan_static_board_info(adap);
 
+       /* Register devices from the device tree */
+       of_i2c_register_devices(adap);
+
        /* Notify drivers */
        mutex_lock(&core_lock);
        dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
index 0b7815d2581c1456ee0452b726e4dd3e4ecff825..2a4cb9c18f01706ce7a3c6b17126882321185612 100644 (file)
@@ -43,7 +43,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -98,9 +97,8 @@ static int ide_probe(struct pcmcia_device *link)
     info->p_dev = link;
     link->priv = info;
 
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-    link->io.IOAddrLines = 3;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+    link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -229,24 +227,27 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev,
 
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+
                pdev->conf.ConfigIndex = cfg->index;
-               pdev->io.BasePort1 = io->win[0].base;
-               pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               pdev->resource[0]->start = io->win[0].base;
+               if (!(io->flags & CISTPL_IO_16BIT)) {
+                       pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+                       pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+               }
                if (io->nwin == 2) {
-                       pdev->io.NumPorts1 = 8;
-                       pdev->io.BasePort2 = io->win[1].base;
-                       pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
-                       if (pcmcia_request_io(pdev, &pdev->io) != 0)
+                       pdev->resource[0]->end = 8;
+                       pdev->resource[1]->start = io->win[1].base;
+                       pdev->resource[1]->end = (stk->is_kme) ? 2 : 1;
+                       if (pcmcia_request_io(pdev) != 0)
                                return -ENODEV;
-                       stk->ctl_base = pdev->io.BasePort2;
+                       stk->ctl_base = pdev->resource[1]->start;
                } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
-                       pdev->io.NumPorts1 = io->win[0].len;
-                       pdev->io.NumPorts2 = 0;
-                       if (pcmcia_request_io(pdev, &pdev->io) != 0)
+                       pdev->resource[0]->end = io->win[0].len;
+                       pdev->resource[1]->end = 0;
+                       if (pcmcia_request_io(pdev) != 0)
                                return -ENODEV;
-                       stk->ctl_base = pdev->io.BasePort1 + 0x0e;
+                       stk->ctl_base = pdev->resource[0]->start + 0x0e;
                } else
                        return -ENODEV;
                /* If we've got this far, we're done */
@@ -280,7 +281,7 @@ static int ide_config(struct pcmcia_device *link)
            if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
                    goto failed; /* No suitable config found */
     }
-    io_base = link->io.BasePort1;
+    io_base = link->resource[0]->start;
     ctl_base = stk->ctl_base;
 
     if (!link->irq)
@@ -297,7 +298,7 @@ static int ide_config(struct pcmcia_device *link)
        outb(0x81, ctl_base+1);
 
      host = idecs_register(io_base, ctl_base, link->irq, link);
-     if (host == NULL && link->io.NumPorts1 == 0x20) {
+     if (host == NULL && resource_size(link->resource[0]) == 0x20) {
            outb(0x02, ctl_base + 0x10);
            host = idecs_register(io_base + 0x10, ctl_base + 0x10,
                                  link->irq, link);
index 9946d73624b9188bc88bf3400a2f026b3828489b..9dfd6e5f786f6b04b9d35699333dbc6324414bc5 100644 (file)
@@ -115,7 +115,8 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
        input_dev->event = ixp4xx_spkr_event;
 
        err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
-                         IRQF_DISABLED | IRQF_TIMER, "ixp4xx-beeper", (void *) dev->id);
+                         IRQF_DISABLED | IRQF_NO_SUSPEND, "ixp4xx-beeper",
+                         (void *) dev->id);
        if (err)
                goto err_free_device;
 
index 1dacae4b43f0f32671e42934919526c5502a4dcf..f3bb92e9755fa1d7c9516a93b816006655710f93 100644 (file)
@@ -353,14 +353,12 @@ static struct of_platform_driver grover_beep_driver = {
 
 static int __init sparcspkr_init(void)
 {
-       int err = of_register_driver(&bbc_beep_driver,
-                                    &of_platform_bus_type);
+       int err = of_register_platform_driver(&bbc_beep_driver);
 
        if (!err) {
-               err = of_register_driver(&grover_beep_driver,
-                                        &of_platform_bus_type);
+               err = of_register_platform_driver(&grover_beep_driver);
                if (err)
-                       of_unregister_driver(&bbc_beep_driver);
+                       of_unregister_platform_driver(&bbc_beep_driver);
        }
 
        return err;
@@ -368,8 +366,8 @@ static int __init sparcspkr_init(void)
 
 static void __exit sparcspkr_exit(void)
 {
-       of_unregister_driver(&bbc_beep_driver);
-       of_unregister_driver(&grover_beep_driver);
+       of_unregister_platform_driver(&bbc_beep_driver);
+       of_unregister_platform_driver(&grover_beep_driver);
 }
 
 module_init(sparcspkr_init);
index 04e32f2d1241eacc9cfc6716fb22441d2dbd2a3e..cb2a24b947464bfb087a4cf43e6ab0ea939dd5ea 100644 (file)
@@ -58,9 +58,9 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
                if (!strcmp(dp->name, OBP_PS2KBD_NAME1) ||
                    !strcmp(dp->name, OBP_PS2KBD_NAME2)) {
                        struct of_device *kbd = of_find_device_by_node(dp);
-                       unsigned int irq = kbd->irqs[0];
+                       unsigned int irq = kbd->archdata.irqs[0];
                        if (irq == 0xffffffff)
-                               irq = op->irqs[0];
+                               irq = op->archdata.irqs[0];
                        i8042_kbd_irq = irq;
                        kbd_iobase = of_ioremap(&kbd->resource[0],
                                                0, 8, "kbd");
@@ -68,9 +68,9 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
                } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) ||
                           !strcmp(dp->name, OBP_PS2MS_NAME2)) {
                        struct of_device *ms = of_find_device_by_node(dp);
-                       unsigned int irq = ms->irqs[0];
+                       unsigned int irq = ms->archdata.irqs[0];
                        if (irq == 0xffffffff)
-                               irq = op->irqs[0];
+                               irq = op->archdata.irqs[0];
                        i8042_aux_irq = irq;
                }
 
@@ -116,8 +116,7 @@ static int __init i8042_platform_init(void)
                if (!kbd_iobase)
                        return -ENODEV;
        } else {
-               int err = of_register_driver(&sparc_i8042_driver,
-                                            &of_bus_type);
+               int err = of_register_platform_driver(&sparc_i8042_driver);
                if (err)
                        return err;
 
@@ -141,7 +140,7 @@ static inline void i8042_platform_exit(void)
        struct device_node *root = of_find_node_by_path("/");
 
        if (strcmp(root->name, "SUNW,JavaStation-1"))
-               of_unregister_driver(&sparc_i8042_driver);
+               of_unregister_platform_driver(&sparc_i8042_driver);
 }
 
 #else /* !CONFIG_PCI */
index e14081675bb2b5a8709570ad45e657a30381f3fb..ebb11907d402befd3a777e21e5bed63a0e66dfaf 100644 (file)
@@ -339,7 +339,7 @@ static struct xenbus_driver xenkbd_driver = {
 
 static int __init xenkbd_init(void)
 {
-       if (!xen_domain())
+       if (!xen_pv_domain())
                return -ENODEV;
 
        /* Nothing to do if running in dom0. */
index f410d0eb2fef0eaed55f6946e21dafec7aee67c8..09b1795516f4e95c4e49f0ce6e1e91c9eefa5bd1 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -76,9 +75,8 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
 {
 
     /* The io structure describes IO port mapping */
-    p_dev->io.NumPorts1 = 16;
-    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    p_dev->io.NumPorts2 = 0;
+    p_dev->resource[0]->end = 16;
+    p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
 
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -120,13 +118,9 @@ static int avmcs_configcheck(struct pcmcia_device *p_dev,
        if (cf->io.nwin <= 0)
                return -ENODEV;
 
-       p_dev->io.BasePort1 = cf->io.win[0].base;
-       p_dev->io.NumPorts1 = cf->io.win[0].len;
-       p_dev->io.NumPorts2 = 0;
-       printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
-              p_dev->io.BasePort1,
-              p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       p_dev->resource[0]->start = cf->io.win[0].base;
+       p_dev->resource[0]->end = cf->io.win[0].len;
+       return pcmcia_request_io(p_dev);
 }
 
 static int avmcs_config(struct pcmcia_device *link)
@@ -192,9 +186,10 @@ static int avmcs_config(struct pcmcia_device *link)
        default:
         case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
     }
-    if ((i = (*addcard)(link->io.BasePort1, link->irq)) < 0) {
-           dev_err(&link->dev, "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
-                   link->io.BasePort1, link->irq);
+    if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) {
+           dev_err(&link->dev,
+                   "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
+                   (unsigned int) link->resource[0]->start, link->irq);
            avmcs_release(link);
            return -ENODEV;
     }
@@ -212,7 +207,7 @@ static int avmcs_config(struct pcmcia_device *link)
 
 static void avmcs_release(struct pcmcia_device *link)
 {
-       b1pcmcia_delcard(link->io.BasePort1, link->irq);
+       b1pcmcia_delcard(link->resource[0]->start, link->irq);
        pcmcia_disable_device(link);
 } /* avmcs_release */
 
index a80a7617f16fb19ba72483983959c3ffe1fe96a1..94263c22b8746965109cc6b1654a8a30df2355fd 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -79,11 +78,10 @@ static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
     dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
 
     /* The io structure describes IO port mapping */
-    p_dev->io.NumPorts1 = 16;
-    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    p_dev->io.NumPorts2 = 16;
-    p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
-    p_dev->io.IOAddrLines = 5;
+    p_dev->resource[0]->end = 16;
+    p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+    p_dev->resource[1]->end = 16;
+    p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
 
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -127,13 +125,10 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev,
        if (cf->io.nwin <= 0)
                return -ENODEV;
 
-       p_dev->io.BasePort1 = cf->io.win[0].base;
-       p_dev->io.NumPorts1 = cf->io.win[0].len;
-       p_dev->io.NumPorts2 = 0;
-       printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
-              p_dev->io.BasePort1,
-              p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       p_dev->resource[0]->start = cf->io.win[0].base;
+       p_dev->resource[0]->end = cf->io.win[0].len;
+       p_dev->io_lines = 5;
+       return pcmcia_request_io(p_dev);
 }
 
 
@@ -181,16 +176,18 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
     }
 
     printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
-                               link->io.BasePort1, link->irq);
+               (unsigned int) link->resource[0]->start, link->irq);
 
     icard.para[0] = link->irq;
-    icard.para[1] = link->io.BasePort1;
+    icard.para[1] = link->resource[0]->start;
     icard.protocol = isdnprot;
     icard.typ = ISDN_CTYPE_A1_PCMCIA;
     
     i = hisax_init_pcmcia(link, &busy, &icard);
     if (i < 0) {
-       printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
+       printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 "
+                       "PCMCIA %d at i/o %#x\n", i,
+                       (unsigned int) link->resource[0]->start);
        avma1cs_release(link);
        return -ENODEV;
     }
index 218927e3a4ea1fce332ba56f81472a03fb856a61..b3c08aaf41c410e57c91aaa82fefddc4af6212a8 100644 (file)
@@ -46,7 +46,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -127,9 +126,8 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link)
       and attributes of IO windows) are fixed by the nature of the
       device, and can be hard-wired here.
     */
-    link->io.NumPorts1 = 8;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.IOAddrLines = 3;
+    link->resource[0]->end = 8;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
 
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -174,16 +172,18 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
 {
        int j;
 
+       p_dev->io_lines = 3;
+
        if ((cf->io.nwin > 0) && cf->io.win[0].base) {
                printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               p_dev->resource[0]->start = cf->io.win[0].base;
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        } else {
                printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
                for (j = 0x2f0; j > 0x100; j -= 0x10) {
-                       p_dev->io.BasePort1 = j;
-                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       p_dev->resource[0]->start = j;
+                       if (!pcmcia_request_io(p_dev))
                                return 0;
                }
        }
@@ -215,23 +215,21 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link)
            link->conf.ConfigIndex);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
        printk(", irq %d", link->irq);
-    if (link->io.NumPorts1)
-        printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-               link->io.BasePort1+link->io.NumPorts1-1);
-    if (link->io.NumPorts2)
-        printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-               link->io.BasePort2+link->io.NumPorts2-1);
+    if (link->resource[0])
+       printk(" & %pR", link->resource[0]);
+    if (link->resource[1])
+       printk(" & %pR", link->resource[1]);
     printk("\n");
 
     icard.para[0] = link->irq;
-    icard.para[1] = link->io.BasePort1;
+    icard.para[1] = link->resource[0]->start;
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_ELSA_PCMCIA;
     
     i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard);
     if (i < 0) {
-       printk(KERN_ERR "elsa_cs: failed to initialize Elsa PCMCIA %d at i/o %#x\n",
-               i, link->io.BasePort1);
+       printk(KERN_ERR "elsa_cs: failed to initialize Elsa "
+               "PCMCIA %d with %pR\n", i, link->resource[0]);
        elsa_cs_release(link);
     } else
        ((local_info_t*)link->priv)->cardnr = i;
index 1f4feaab21af28bd81721c42dfcdbbe7e962f5e5..a024192b672a3113c0e6663fc1778c5abe4ac6f2 100644 (file)
@@ -46,7 +46,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -130,9 +129,8 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link)
     /* from old sedl_cs 
     */
     /* The io structure describes IO port mapping */
-    link->io.NumPorts1 = 8;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.IOAddrLines = 3;
+    link->resource[0]->end = 8;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
 
     link->conf.Attributes = 0;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -173,8 +171,6 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
                                  unsigned int vcc,
                                  void *priv_data)
 {
-       win_req_t *req = priv_data;
-
        if (cfg->index == 0)
                return -ENODEV;
 
@@ -202,52 +198,25 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                                       pcmcia_io_cfg_data_width(io->flags);
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
                /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               p_dev->io_lines = 3;
+               if (pcmcia_request_io(p_dev) != 0)
                        return -ENODEV;
        }
 
-       /*
-         Now set up a common memory window, if needed.  There is room
-         in the struct pcmcia_device structure for one memory window handle,
-         but if the base addresses need to be saved, or if multiple
-         windows are needed, the info should go in the private data
-         structure for this device.
-
-         Note that the memory window base is a physical address, and
-         needs to be mapped to virtual space with ioremap() before it
-         is used.
-       */
-       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
-               cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
-               memreq_t map;
-               req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
-               req->Attributes |= WIN_ENABLE;
-               req->Base = mem->win[0].host_addr;
-               req->Size = mem->win[0].len;
-               req->AccessSpeed = 0;
-               if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
-                       return -ENODEV;
-               map.Page = 0;
-               map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
-                       return -ENODEV;
-       }
        return 0;
 }
 
@@ -255,16 +224,11 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
 
 static int __devinit sedlbauer_config(struct pcmcia_device *link)
 {
-    win_req_t *req;
     int ret;
     IsdnCard_t  icard;
 
     dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
 
-    req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
-    if (!req)
-           return -ENOMEM;
-
     /*
       In this loop, we scan the CIS for configuration table entries,
       each of which describes a valid card configuration, including
@@ -277,7 +241,7 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
       these things without consulting the CIS, and most client drivers
       will only use the CIS to fill in implementation-defined details.
     */
-    ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
+    ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL);
     if (ret)
            goto failed;
 
@@ -297,27 +261,22 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
        printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
        printk(", irq %d", link->irq);
-    if (link->io.NumPorts1)
-       printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-              link->io.BasePort1+link->io.NumPorts1-1);
-    if (link->io.NumPorts2)
-       printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-              link->io.BasePort2+link->io.NumPorts2-1);
-    if (link->win)
-       printk(", mem 0x%06lx-0x%06lx", req->Base,
-              req->Base+req->Size-1);
+    if (link->resource[0])
+       printk(" & %pR", link->resource[0]);
+    if (link->resource[1])
+       printk(" & %pR", link->resource[1]);
     printk("\n");
 
     icard.para[0] = link->irq;
-    icard.para[1] = link->io.BasePort1;
+    icard.para[1] = link->resource[0]->start;
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
     
     ret = hisax_init_pcmcia(link, 
                            &(((local_info_t *)link->priv)->stop), &icard);
     if (ret < 0) {
-       printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
-               ret, link->io.BasePort1);
+       printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d with %pR\n",
+               ret, link->resource[0]);
        sedlbauer_release(link);
        return -ENODEV;
     } else
index 5771955cc5326ef16897e4156a80abaef0b995dd..7296102ca255d89ef34bee0a1736d695629214d2 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -107,9 +106,8 @@ static int __devinit teles_probe(struct pcmcia_device *link)
       and attributes of IO windows) are fixed by the nature of the
       device, and can be hard-wired here.
     */
-    link->io.NumPorts1 = 96;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.IOAddrLines = 5;
+    link->resource[0]->end = 96;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
 
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -154,16 +152,18 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
 {
        int j;
 
+       p_dev->io_lines = 5;
+
        if ((cf->io.nwin > 0) && cf->io.win[0].base) {
                printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               p_dev->resource[0]->start = cf->io.win[0].base;
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        } else {
                printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
                for (j = 0x2f0; j > 0x100; j -= 0x10) {
-                       p_dev->io.BasePort1 = j;
-                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       p_dev->resource[0]->start = j;
+                       if (!pcmcia_request_io(p_dev))
                                return 0;
                }
        }
@@ -195,23 +195,21 @@ static int __devinit teles_cs_config(struct pcmcia_device *link)
            link->conf.ConfigIndex);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
            printk(", irq %d", link->irq);
-    if (link->io.NumPorts1)
-        printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-               link->io.BasePort1+link->io.NumPorts1-1);
-    if (link->io.NumPorts2)
-        printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-               link->io.BasePort2+link->io.NumPorts2-1);
+    if (link->resource[0])
+       printk(" & %pR", link->resource[0]);
+    if (link->resource[1])
+       printk(" & %pR", link->resource[1]);
     printk("\n");
 
     icard.para[0] = link->irq;
-    icard.para[1] = link->io.BasePort1;
+    icard.para[1] = link->resource[0]->start;
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_TELESPCMCIA;
     
     i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard);
     if (i < 0) {
        printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
-               i, link->io.BasePort1);
+                       i, (unsigned int) link->resource[0]->start);
        teles_cs_release(link);
        return -ENODEV;
     }
index 5dcdf9d69b3abae8d0370ccbe1a0d913c716e7d1..19dc4b61a1055220b0308434c30f7028bdcfb2df 100644 (file)
@@ -351,7 +351,7 @@ static ssize_t bd2802_store_reg##reg_addr(struct device *dev,               \
        return count;                                                   \
 }                                                                      \
 static struct device_attribute bd2802_reg##reg_addr##_attr = {         \
-       .attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE}, \
+       .attr = {.name = reg_name, .mode = 0644},                       \
        .store = bd2802_store_reg##reg_addr,                            \
 };
 
@@ -482,7 +482,6 @@ static struct device_attribute bd2802_adv_conf_attr = {
        .attr = {
                .name = "advanced_configuration",
                .mode = 0644,
-               .owner = THIS_MODULE
        },
        .show = bd2802_show_adv_conf,
        .store = bd2802_store_adv_conf,
@@ -519,7 +518,6 @@ static struct device_attribute bd2802_##attr_name##_attr = {                \
        .attr = {                                                       \
                .name = name_str,                                       \
                .mode = 0644,                                           \
-               .owner = THIS_MODULE                                    \
        },                                                              \
        .show = bd2802_show_##attr_name,                                \
        .store = bd2802_store_##attr_name,                              \
index 6999ce59fd1091ddd8e9b46f2ced859275deab1c..6024038a5b9dc9a450b6ff655205ea266b632f04 100644 (file)
@@ -41,10 +41,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
 static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
                              char *buf)
 {
-       struct of_device *ofdev = to_of_device(dev);
-       int len;
-
-       len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2);
+       int len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2);
 
        buf[len] = '\n';
        buf[len+1] = 0;
index 3d4fc0f7b00ba384d168214436c91103bb125419..35bc2737412fddaa3323e99ea34a3dd3de762355 100644 (file)
@@ -400,11 +400,12 @@ static int __init via_pmu_start(void)
                printk(KERN_ERR "via-pmu: can't map interrupt\n");
                return -ENODEV;
        }
-       /* We set IRQF_TIMER because we don't want the interrupt to be disabled
-        * between the 2 passes of driver suspend, we control our own disabling
-        * for that one
+       /* We set IRQF_NO_SUSPEND because we don't want the interrupt
+        * to be disabled between the 2 passes of driver suspend, we
+        * control our own disabling for that one
         */
-       if (request_irq(irq, via_pmu_interrupt, IRQF_TIMER, "VIA-PMU", (void *)0)) {
+       if (request_irq(irq, via_pmu_interrupt, IRQF_NO_SUSPEND,
+                       "VIA-PMU", (void *)0)) {
                printk(KERN_ERR "via-pmu: can't request irq %d\n", irq);
                return -ENODEV;
        }
index 90daa6e751d83dff10658368edb891ede0eaee81..07c5c18a25cbc619bff2e8bf3cd6951dc7dcf049 100644 (file)
@@ -705,6 +705,8 @@ done:
  */
 static int __devinit ivtv_init_struct1(struct ivtv *itv)
 {
+       struct sched_param param = { .sched_priority = 99 };
+
        itv->base_addr = pci_resource_start(itv->pdev, 0);
        itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
        itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
@@ -716,13 +718,17 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        spin_lock_init(&itv->lock);
        spin_lock_init(&itv->dma_reg_lock);
 
-       itv->irq_work_queues = create_singlethread_workqueue(itv->v4l2_dev.name);
-       if (itv->irq_work_queues == NULL) {
-               IVTV_ERR("Could not create ivtv workqueue\n");
+       init_kthread_worker(&itv->irq_worker);
+       itv->irq_worker_task = kthread_run(kthread_worker_fn, &itv->irq_worker,
+                                          itv->v4l2_dev.name);
+       if (IS_ERR(itv->irq_worker_task)) {
+               IVTV_ERR("Could not create ivtv task\n");
                return -1;
        }
+       /* must use the FIFO scheduler as it is realtime sensitive */
+       sched_setscheduler(itv->irq_worker_task, SCHED_FIFO, &param);
 
-       INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler);
+       init_kthread_work(&itv->irq_work, ivtv_irq_work_handler);
 
        /* start counting open_id at 1 */
        itv->open_id = 1;
@@ -1006,7 +1012,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
        /* PCI Device Setup */
        retval = ivtv_setup_pci(itv, pdev, pci_id);
        if (retval == -EIO)
-               goto free_workqueue;
+               goto free_worker;
        if (retval == -ENXIO)
                goto free_mem;
 
@@ -1218,8 +1224,8 @@ free_mem:
        release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
        if (itv->has_cx23415)
                release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
-free_workqueue:
-       destroy_workqueue(itv->irq_work_queues);
+free_worker:
+       kthread_stop(itv->irq_worker_task);
 err:
        if (retval == 0)
                retval = -ENODEV;
@@ -1363,9 +1369,9 @@ static void ivtv_remove(struct pci_dev *pdev)
        ivtv_set_irq_mask(itv, 0xffffffff);
        del_timer_sync(&itv->dma_timer);
 
-       /* Stop all Work Queues */
-       flush_workqueue(itv->irq_work_queues);
-       destroy_workqueue(itv->irq_work_queues);
+       /* Kill irq worker */
+       flush_kthread_worker(&itv->irq_worker);
+       kthread_stop(itv->irq_worker_task);
 
        ivtv_streams_cleanup(itv, 1);
        ivtv_udma_free(itv);
index bd084df4448ac0ccc81071373c0aeb48b9142762..102071246218db284eed240e4b173b1dc4eef417 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/unistd.h>
 #include <linux/pagemap.h>
 #include <linux/scatterlist.h>
-#include <linux/workqueue.h>
+#include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <asm/uaccess.h>
@@ -260,7 +260,6 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_DEC_PAUSED       20   /* the decoder is paused */
 #define IVTV_F_I_INITED                   21   /* set after first open */
 #define IVTV_F_I_FAILED                   22   /* set if first open failed */
-#define IVTV_F_I_WORK_INITED       23  /* worker thread was initialized */
 
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED           28   /* decoder stopped event */
@@ -666,8 +665,9 @@ struct ivtv {
        /* Interrupts & DMA */
        u32 irqmask;                    /* active interrupts */
        u32 irq_rr_idx;                 /* round-robin stream index */
-       struct workqueue_struct *irq_work_queues;       /* workqueue for PIO/YUV/VBI actions */
-       struct work_struct irq_work_queue;              /* work entry */
+       struct kthread_worker irq_worker;               /* kthread worker for PIO/YUV/VBI actions */
+       struct task_struct *irq_worker_task;            /* task for irq_worker */
+       struct kthread_work irq_work;   /* kthread work entry */
        spinlock_t dma_reg_lock;        /* lock access to DMA engine registers */
        int cur_dma_stream;             /* index of current stream doing DMA (-1 if none) */
        int cur_pio_stream;             /* index of current stream doing PIO (-1 if none) */
index fea1ec33b0df4c343a7220a95f092c59d6f38463..9b4faf009196afad6de8f4b3ffeebc0dbd2f05e6 100644 (file)
@@ -71,19 +71,10 @@ static void ivtv_pio_work_handler(struct ivtv *itv)
        write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
 }
 
-void ivtv_irq_work_handler(struct work_struct *work)
+void ivtv_irq_work_handler(struct kthread_work *work)
 {
-       struct ivtv *itv = container_of(work, struct ivtv, irq_work_queue);
+       struct ivtv *itv = container_of(work, struct ivtv, irq_work);
 
-       DEFINE_WAIT(wait);
-
-       if (test_and_clear_bit(IVTV_F_I_WORK_INITED, &itv->i_flags)) {
-               struct sched_param param = { .sched_priority = 99 };
-
-               /* This thread must use the FIFO scheduler as it
-                  is realtime sensitive. */
-               sched_setscheduler(current, SCHED_FIFO, &param);
-       }
        if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
                ivtv_pio_work_handler(itv);
 
@@ -975,7 +966,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
        }
 
        if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) {
-               queue_work(itv->irq_work_queues, &itv->irq_work_queue);
+               queue_kthread_work(&itv->irq_worker, &itv->irq_work);
        }
 
        spin_unlock(&itv->dma_reg_lock);
index f879a5822e7138ae8b374fa2f01ca86d40114951..1e84433737ccec20b39129222913beef73515c71 100644 (file)
@@ -46,7 +46,7 @@
 
 irqreturn_t ivtv_irq_handler(int irq, void *dev_id);
 
-void ivtv_irq_work_handler(struct work_struct *work);
+void ivtv_irq_work_handler(struct kthread_work *work);
 void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
 void ivtv_unfinished_dma(unsigned long arg);
 
index 9b089dfb173ef987f5220d38bce0336c66b92a0f..488f25472291feafbb12ca00e9ce3ecc4635281e 100644 (file)
@@ -72,7 +72,7 @@ config ATMEL_TCLIB
 
 config ATMEL_TCB_CLKSRC
        bool "TC Block Clocksource"
-       depends on ATMEL_TCLIB && GENERIC_TIME
+       depends on ATMEL_TCLIB
        default y
        help
          Select this to get a high precision clocksource based on a
@@ -240,7 +240,7 @@ config CS5535_MFGPT_DEFAULT_IRQ
 
 config CS5535_CLOCK_EVENT_SRC
        tristate "CS5535/CS5536 high-res timer (MFGPT) events"
-       depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
+       depends on GENERIC_CLOCKEVENTS && CS5535_MFGPT
        help
          This driver provides a clock event source based on the MFGPT
          timer(s) in the CS5535 and CS5536 companion chips.
index ad847a24a6756f8f88ec97f6ea8031b8a7169842..7b0f3ef50f9650241918a24cd50f330b2c9c8701 100644 (file)
@@ -1533,12 +1533,20 @@ static int __devexit mmc_spi_remove(struct spi_device *spi)
        return 0;
 }
 
+#if defined(CONFIG_OF)
+static struct of_device_id mmc_spi_of_match_table[] __devinitdata = {
+       { .compatible = "mmc-spi-slot", },
+};
+#endif
 
 static struct spi_driver mmc_spi_driver = {
        .driver = {
                .name =         "mmc_spi",
                .bus =          &spi_bus_type,
                .owner =        THIS_MODULE,
+#if defined(CONFIG_OF)
+               .of_match_table = mmc_spi_of_match_table,
+#endif
        },
        .probe =        mmc_spi_probe,
        .remove =       __devexit_p(mmc_spi_remove),
index e7507af3856e24c9cfef86443e6f5a2cc30ac47c..7aa65bb2af4a29cc03231589de9083e48589b66f 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/ioport.h>
 #include <linux/scatterlist.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index e699e6ac23df30123bee40c67babcad4c9b1c824..e9ca5ba7d9d2cfa1fe1671205f0a9db584d00e49 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -103,7 +102,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
 {
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        window_handle_t win = (window_handle_t)map->map_priv_2;
-       memreq_t mrq;
+       unsigned int offset;
        int ret;
 
        if (!pcmcia_dev_present(dev->p_dev)) {
@@ -111,15 +110,14 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
                return 0;
        }
 
-       mrq.CardOffset = to & ~(dev->win_size-1);
-       if(mrq.CardOffset != dev->offset) {
+       offset = to & ~(dev->win_size-1);
+       if (offset != dev->offset) {
                DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
-                     dev->offset, mrq.CardOffset);
-               mrq.Page = 0;
-               ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq);
+                     dev->offset, offset);
+               ret = pcmcia_map_mem_page(dev->p_dev, win, offset);
                if (ret != 0)
                        return NULL;
-               dev->offset = mrq.CardOffset;
+               dev->offset = offset;
        }
        return dev->win_base + (to & (dev->win_size-1));
 }
@@ -346,7 +344,6 @@ static void pcmciamtd_release(struct pcmcia_device *link)
                        iounmap(dev->win_base);
                        dev->win_base = NULL;
                }
-               pcmcia_release_window(link, link->win);
        }
        pcmcia_disable_device(link);
 }
index 0391c2527bd77ac075bf3a2fbc694b49cc5af939..8984236a8d0a5f93f4d31ba0d26d81abdcd9dea2 100644 (file)
@@ -160,12 +160,12 @@ static struct of_platform_driver uflash_driver = {
 
 static int __init uflash_init(void)
 {
-       return of_register_driver(&uflash_driver, &of_bus_type);
+       return of_register_platform_driver(&uflash_driver);
 }
 
 static void __exit uflash_exit(void)
 {
-       of_unregister_driver(&uflash_driver);
+       of_unregister_platform_driver(&uflash_driver);
 }
 
 module_init(uflash_init);
index 36d31a41632050f7e75d8f79a4ad16e79a02e59c..521c6ee1f32af75a0abb5950d10c941376d60116 100644 (file)
@@ -5825,11 +5825,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 
        e1000_print_device_info(adapter);
 
-       if (pci_dev_run_wake(pdev)) {
-               pm_runtime_set_active(&pdev->dev);
-               pm_runtime_enable(&pdev->dev);
-       }
-       pm_schedule_suspend(&pdev->dev, MSEC_PER_SEC);
+       if (pci_dev_run_wake(pdev))
+               pm_runtime_put_noidle(&pdev->dev);
 
        return 0;
 
@@ -5875,8 +5872,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
        struct e1000_adapter *adapter = netdev_priv(netdev);
        bool down = test_bit(__E1000_DOWN, &adapter->state);
 
-       pm_runtime_get_sync(&pdev->dev);
-
        /*
         * flush_scheduled work may reschedule our watchdog task, so
         * explicitly disable watchdog tasks from being rescheduled
@@ -5901,11 +5896,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
                clear_bit(__E1000_DOWN, &adapter->state);
        unregister_netdev(netdev);
 
-       if (pci_dev_run_wake(pdev)) {
-               pm_runtime_disable(&pdev->dev);
-               pm_runtime_set_suspended(&pdev->dev);
-       }
-       pm_runtime_put_noidle(&pdev->dev);
+       if (pci_dev_run_wake(pdev))
+               pm_runtime_get_noresume(&pdev->dev);
 
        /*
         * Release control of h/w to f/w.  If f/w is AMT enabled, this
index b4c41d72c423ef79e004bd901f23ef03f96e311f..f53f850b641888acb1080d6f08402caf2094eccb 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
index 0f1d4e96cf893884b3e6f0a09fe5c9a41ca75d6d..eeec7bc2ce74bf9c472c9179f621d2e43930ece3 100644 (file)
@@ -2339,11 +2339,11 @@ static int __devinit emac_wait_deps(struct emac_instance *dev)
                deps[EMAC_DEP_MDIO_IDX].phandle = dev->mdio_ph;
        if (dev->blist && dev->blist > emac_boot_list)
                deps[EMAC_DEP_PREV_IDX].phandle = 0xffffffffu;
-       bus_register_notifier(&of_platform_bus_type, &emac_of_bus_notifier);
+       bus_register_notifier(&platform_bus_type, &emac_of_bus_notifier);
        wait_event_timeout(emac_probe_wait,
                           emac_check_deps(dev, deps),
                           EMAC_PROBE_DEP_TIMEOUT);
-       bus_unregister_notifier(&of_platform_bus_type, &emac_of_bus_notifier);
+       bus_unregister_notifier(&platform_bus_type, &emac_of_bus_notifier);
        err = emac_check_deps(dev, deps) ? 0 : -ENODEV;
        for (i = 0; i < EMAC_DEP_COUNT; i++) {
                if (deps[i].node)
index 1a57c3da1f498bb5d21531879ae2d9df941324dd..04e552aa14ec40a756a4155cd787056ee86f5646 100644 (file)
@@ -1079,7 +1079,7 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
 
        mp->dev = dev;
        dev->watchdog_timeo = 5*HZ;
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
        dev->netdev_ops = &myri_ops;
 
        /* Register interrupt handler now. */
@@ -1172,12 +1172,12 @@ static struct of_platform_driver myri_sbus_driver = {
 
 static int __init myri_sbus_init(void)
 {
-       return of_register_driver(&myri_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&myri_sbus_driver);
 }
 
 static void __exit myri_sbus_exit(void)
 {
-       of_unregister_driver(&myri_sbus_driver);
+       of_unregister_platform_driver(&myri_sbus_driver);
 }
 
 module_init(myri_sbus_init);
index b9b950845b0e7d480a020f997f6707b89258f13e..404f2d552888c4b563472dacae939400de47d6b1 100644 (file)
 #include <linux/slab.h>
 
 #include <linux/io.h>
-
-#ifdef CONFIG_SPARC64
 #include <linux/of_device.h>
-#endif
 
 #include "niu.h"
 
@@ -9114,12 +9111,12 @@ static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map)
        if (!int_prop)
                return -ENODEV;
 
-       for (i = 0; i < op->num_irqs; i++) {
+       for (i = 0; i < op->archdata.num_irqs; i++) {
                ldg_num_map[i] = int_prop[i];
-               np->ldg[i].irq = op->irqs[i];
+               np->ldg[i].irq = op->archdata.irqs[i];
        }
 
-       np->num_ldg = op->num_irqs;
+       np->num_ldg = op->archdata.num_irqs;
 
        return 0;
 #else
@@ -10249,14 +10246,14 @@ static int __init niu_init(void)
        niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT);
 
 #ifdef CONFIG_SPARC64
-       err = of_register_driver(&niu_of_driver, &of_bus_type);
+       err = of_register_platform_driver(&niu_of_driver);
 #endif
 
        if (!err) {
                err = pci_register_driver(&niu_pci_driver);
 #ifdef CONFIG_SPARC64
                if (err)
-                       of_unregister_driver(&niu_of_driver);
+                       of_unregister_platform_driver(&niu_of_driver);
 #endif
        }
 
@@ -10267,7 +10264,7 @@ static void __exit niu_exit(void)
 {
        pci_unregister_driver(&niu_pci_driver);
 #ifdef CONFIG_SPARC64
-       of_unregister_driver(&niu_of_driver);
+       of_unregister_platform_driver(&niu_of_driver);
 #endif
 }
 
index d6715465f35d58137e5c78b26e4c3f653b7c6598..a41fa8ebe05fbfd8e909c61cd2e3862ff6e6f18d 100644 (file)
@@ -3236,7 +3236,7 @@ struct niu_phy_ops {
        int (*link_status)(struct niu *np, int *);
 };
 
-struct of_device;
+struct platform_device;
 struct niu {
        void __iomem                    *regs;
        struct net_device               *dev;
@@ -3297,7 +3297,7 @@ struct niu {
        struct niu_vpd                  vpd;
        u32                             eeprom_len;
 
-       struct of_device                *op;
+       struct platform_device          *op;
        void __iomem                    *vir_regs_1;
        void __iomem                    *vir_regs_2;
 };
index 10ee106a161778d6a510adc9c065123a6784964c..c683f77c6f424ebbc873d76f0e07cb386484ea70 100644 (file)
@@ -87,7 +87,6 @@ earlier 3Com products.
 #include <linux/bitops.h>
 #include <linux/mii.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -279,8 +278,8 @@ static int tc574_probe(struct pcmcia_device *link)
        lp->p_dev = link;
 
        spin_lock_init(&lp->window_lock);
-       link->io.NumPorts1 = 32;
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+       link->resource[0]->end = 32;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
@@ -338,10 +337,11 @@ static int tc574_config(struct pcmcia_device *link)
 
        dev_dbg(&link->dev, "3c574_config()\n");
 
-       link->io.IOAddrLines = 16;
+       link->io_lines = 16;
+
        for (i = j = 0; j < 0x400; j += 0x20) {
-               link->io.BasePort1 = j ^ 0x300;
-               i = pcmcia_request_io(link, &link->io);
+               link->resource[0]->start = j ^ 0x300;
+               i = pcmcia_request_io(link);
                if (i == 0)
                        break;
        }
@@ -357,7 +357,7 @@ static int tc574_config(struct pcmcia_device *link)
                goto failed;
 
        dev->irq = link->irq;
-       dev->base_addr = link->io.BasePort1;
+       dev->base_addr = link->resource[0]->start;
 
        ioaddr = dev->base_addr;
 
index ce63c3773b4c693a78642727fa2223b8c4587b58..61f9cf2100ffd8bfdff824ccfa2c3f3013a8eb1f 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -214,8 +213,8 @@ static int tc589_probe(struct pcmcia_device *link)
     lp->p_dev = link;
 
     spin_lock_init(&lp->lock);
-    link->io.NumPorts1 = 16;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+    link->resource[0]->end = 16;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
 
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -278,12 +277,13 @@ static int tc589_config(struct pcmcia_device *link)
                   "3Com card??\n");
     multi = (link->card_id == PRODID_3COM_3C562);
 
+    link->io_lines = 16;
+
     /* For the 3c562, the base address must be xx00-xx7f */
-    link->io.IOAddrLines = 16;
     for (i = j = 0; j < 0x400; j += 0x10) {
        if (multi && (j & 0x80)) continue;
-       link->io.BasePort1 = j ^ 0x300;
-       i = pcmcia_request_io(link, &link->io);
+       link->resource[0]->start = j ^ 0x300;
+       i = pcmcia_request_io(link);
        if (i == 0)
                break;
     }
@@ -299,7 +299,7 @@ static int tc589_config(struct pcmcia_device *link)
            goto failed;
 
     dev->irq = link->irq;
-    dev->base_addr = link->io.BasePort1;
+    dev->base_addr = link->resource[0]->start;
     ioaddr = dev->base_addr;
     EL3WINDOW(0);
 
index 33525bf2a3d3e87f6769ac24c65861441c375dd3..5f05ffb240cc899eb79537ffe8074ceb97d3da11 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/mii.h>
 #include "../8390.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -260,28 +259,30 @@ static int get_prom(struct pcmcia_device *link)
 static int try_io_port(struct pcmcia_device *link)
 {
     int j, ret;
-    if (link->io.NumPorts1 == 32) {
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+    link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+    link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+    if (link->resource[0]->end == 32) {
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
        /* for master/slave multifunction cards */
-       if (link->io.NumPorts2 > 0)
-           link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+       if (link->resource[1]->end > 0)
+           link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
     } else {
        /* This should be two 16-port windows */
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
     }
-    if (link->io.BasePort1 == 0) {
-       link->io.IOAddrLines = 16;
+    if (link->resource[0]->start == 0) {
        for (j = 0; j < 0x400; j += 0x20) {
-           link->io.BasePort1 = j ^ 0x300;
-           link->io.BasePort2 = (j ^ 0x300) + 0x10;
-           ret = pcmcia_request_io(link, &link->io);
+           link->resource[0]->start = j ^ 0x300;
+           link->resource[1]->start = (j ^ 0x300) + 0x10;
+           link->io_lines = 16;
+           ret = pcmcia_request_io(link);
            if (ret == 0)
                    return ret;
        }
        return ret;
     } else {
-       return pcmcia_request_io(link, &link->io);
+       return pcmcia_request_io(link);
     }
 }
 
@@ -302,15 +303,15 @@ static int axnet_configcheck(struct pcmcia_device *p_dev,
           network function with window 0, and serial with window 1 */
        if (io->nwin > 1) {
                i = (io->win[1].len > io->win[0].len);
-               p_dev->io.BasePort2 = io->win[1-i].base;
-               p_dev->io.NumPorts2 = io->win[1-i].len;
+               p_dev->resource[1]->start = io->win[1-i].base;
+               p_dev->resource[1]->end = io->win[1-i].len;
        } else {
-               i = p_dev->io.NumPorts2 = 0;
+               i = p_dev->resource[1]->end = 0;
        }
-       p_dev->io.BasePort1 = io->win[i].base;
-       p_dev->io.NumPorts1 = io->win[i].len;
-       p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-       if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+       p_dev->resource[0]->start = io->win[i].base;
+       p_dev->resource[0]->end = io->win[i].len;
+       p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+       if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
                return try_io_port(p_dev);
 
        return -ENODEV;
@@ -333,7 +334,7 @@ static int axnet_config(struct pcmcia_device *link)
     if (!link->irq)
            goto failed;
     
-    if (link->io.NumPorts2 == 8) {
+    if (resource_size(link->resource[1]) == 8) {
        link->conf.Attributes |= CONF_ENABLE_SPKR;
        link->conf.Status = CCSR_AUDIO_ENA;
     }
@@ -343,7 +344,7 @@ static int axnet_config(struct pcmcia_device *link)
            goto failed;
 
     dev->irq = link->irq;
-    dev->base_addr = link->io.BasePort1;
+    dev->base_addr = link->resource[0]->start;
 
     if (!get_prom(link)) {
        printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
@@ -379,8 +380,7 @@ static int axnet_config(struct pcmcia_device *link)
     /* Maybe PHY is in power down mode. (PPD_SET = 1) 
        Bit 2 of CCSR is active low. */ 
     if (i == 32) {
-       conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 };
-       pcmcia_access_configuration_register(link, &reg);
+       pcmcia_write_config_byte(link, CISREG_CCSR, 0x04);
        for (i = 0; i < 32; i++) {
            j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
            j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
index 5643f94541bc9ed07a14e67620655ca05a30f8bd..3c400cfa82ae2e88c0e67c3f0582f75491be925e 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/arcdevice.h>
 #include <linux/com20020.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -159,9 +158,8 @@ static int com20020_probe(struct pcmcia_device *p_dev)
     /* fill in our module parameters as defaults */
     dev->dev_addr[0] = node;
 
-    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    p_dev->io.NumPorts1 = 16;
-    p_dev->io.IOAddrLines = 16;
+    p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+    p_dev->resource[0]->end = 16;
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -246,20 +244,24 @@ static int com20020_config(struct pcmcia_device *link)
 
     dev_dbg(&link->dev, "com20020_config\n");
 
-    dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
+    dev_dbg(&link->dev, "baseport1 is %Xh\n",
+           (unsigned int) link->resource[0]->start);
+
     i = -ENODEV;
-    if (!link->io.BasePort1)
+    link->io_lines = 16;
+
+    if (!link->resource[0]->start)
     {
        for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
        {
-           link->io.BasePort1 = ioaddr;
-           i = pcmcia_request_io(link, &link->io);
+           link->resource[0]->start = ioaddr;
+           i = pcmcia_request_io(link);
            if (i == 0)
                break;
        }
     }
     else
-       i = pcmcia_request_io(link, &link->io);
+       i = pcmcia_request_io(link);
     
     if (i != 0)
     {
@@ -267,7 +269,7 @@ static int com20020_config(struct pcmcia_device *link)
        goto failed;
     }
        
-    ioaddr = dev->base_addr = link->io.BasePort1;
+    ioaddr = dev->base_addr = link->resource[0]->start;
     dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
 
     dev_dbg(&link->dev, "request IRQ %d\n",
index 7c27c50211a55448558f8f674160f20cf6aa1241..98fffb03ecd7f4714c068d7a47c5acf667423cac 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/ioport.h>
 #include <linux/crc32.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -249,9 +248,8 @@ static int fmvj18x_probe(struct pcmcia_device *link)
     lp->base = NULL;
 
     /* The io structure describes IO port mapping */
-    link->io.NumPorts1 = 32;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.IOAddrLines = 5;
+    link->resource[0]->end = 32;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
 
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -289,13 +287,13 @@ static int mfc_try_io_port(struct pcmcia_device *link)
        { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 
     for (i = 0; i < 5; i++) {
-       link->io.BasePort2 = serial_base[i];
-       link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-       if (link->io.BasePort2 == 0) {
-           link->io.NumPorts2 = 0;
+       link->resource[1]->start = serial_base[i];
+       link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+       if (link->resource[1]->start == 0) {
+           link->resource[1]->end = 0;
            printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
        }
-       ret = pcmcia_request_io(link, &link->io);
+       ret = pcmcia_request_io(link);
        if (ret == 0)
                return ret;
     }
@@ -311,12 +309,12 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
        0x380,0x3c0 only for ioport.
     */
     for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
-       link->io.BasePort1 = ioaddr;
-       ret = pcmcia_request_io(link, &link->io);
+       link->resource[0]->start = ioaddr;
+       ret = pcmcia_request_io(link);
        if (ret == 0) {
            /* calculate ConfigIndex value */
            link->conf.ConfigIndex = 
-               ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22;
+               ((link->resource[0]->start & 0x0f0) >> 3) | 0x22;
            return ret;
        }
     }
@@ -346,6 +344,8 @@ static int fmvj18x_config(struct pcmcia_device *link)
 
     dev_dbg(&link->dev, "fmvj18x_config\n");
 
+    link->io_lines = 5;
+
     len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
     kfree(buf);
 
@@ -364,20 +364,20 @@ static int fmvj18x_config(struct pcmcia_device *link)
                /* MultiFunction Card */
                link->conf.ConfigBase = 0x800;
                link->conf.ConfigIndex = 0x47;
-               link->io.NumPorts2 = 8;
+               link->resource[1]->end = 8;
            }
            break;
        case MANFID_NEC:
            cardtype = NEC; /* MultiFunction Card */
            link->conf.ConfigBase = 0x800;
            link->conf.ConfigIndex = 0x47;
-           link->io.NumPorts2 = 8;
+           link->resource[1]->end = 8;
            break;
        case MANFID_KME:
            cardtype = KME; /* MultiFunction Card */
            link->conf.ConfigBase = 0x800;
            link->conf.ConfigIndex = 0x47;
-           link->io.NumPorts2 = 8;
+           link->resource[1]->end = 8;
            break;
        case MANFID_CONTEC:
            cardtype = CONTEC;
@@ -418,14 +418,14 @@ static int fmvj18x_config(struct pcmcia_device *link)
        }
     }
 
-    if (link->io.NumPorts2 != 0) {
+    if (link->resource[1]->end != 0) {
        ret = mfc_try_io_port(link);
        if (ret != 0) goto failed;
     } else if (cardtype == UNGERMANN) {
        ret = ungermann_try_io_port(link);
        if (ret != 0) goto failed;
     } else { 
-           ret = pcmcia_request_io(link, &link->io);
+           ret = pcmcia_request_io(link);
            if (ret)
                    goto failed;
     }
@@ -437,9 +437,9 @@ static int fmvj18x_config(struct pcmcia_device *link)
            goto failed;
 
     dev->irq = link->irq;
-    dev->base_addr = link->io.BasePort1;
+    dev->base_addr = link->resource[0]->start;
 
-    if (link->io.BasePort2 != 0) {
+    if (resource_size(link->resource[1]) != 0) {
        ret = fmvj18x_setup_mfc(link);
        if (ret != 0) goto failed;
     }
@@ -545,7 +545,6 @@ failed:
 static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
 {
     win_req_t req;
-    memreq_t mem;
     u_char __iomem *base;
     int i, j;
 
@@ -558,9 +557,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
        return -1;
 
     base = ioremap(req.Base, req.Size);
-    mem.Page = 0;
-    mem.CardOffset = 0;
-    pcmcia_map_mem_page(link, link->win, &mem);
+    pcmcia_map_mem_page(link, link->win, 0);
 
     /*
      *  MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
@@ -594,7 +591,6 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
 static int fmvj18x_setup_mfc(struct pcmcia_device *link)
 {
     win_req_t req;
-    memreq_t mem;
     int i;
     struct net_device *dev = link->priv;
     unsigned int ioaddr;
@@ -614,9 +610,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
        return -1;
     }
 
-    mem.Page = 0;
-    mem.CardOffset = 0;
-    i = pcmcia_map_mem_page(link, link->win, &mem);
+    i = pcmcia_map_mem_page(link, link->win, 0);
     if (i != 0) {
        iounmap(lp->base);
        lp->base = NULL;
index 67ee9851a8ed5431f140e9c57435fe1574f90421..b0d06a3d962fc235fdc22c8f5af840272a5574d3 100644 (file)
@@ -57,7 +57,6 @@
 #include <linux/trdevice.h>
 #include <linux/ibmtr.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -152,9 +151,8 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
     link->priv = info;
     info->ti = netdev_priv(dev);
 
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.NumPorts1 = 4;
-    link->io.IOAddrLines = 16;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+    link->resource[0]->end = 4;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
@@ -213,26 +211,26 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     struct net_device *dev = info->dev;
     struct tok_info *ti = netdev_priv(dev);
     win_req_t req;
-    memreq_t mem;
     int i, ret;
 
     dev_dbg(&link->dev, "ibmtr_config\n");
 
     link->conf.ConfigIndex = 0x61;
+    link->io_lines = 16;
 
     /* Determine if this is PRIMARY or ALTERNATE. */
 
     /* Try PRIMARY card at 0xA20-0xA23 */
-    link->io.BasePort1 = 0xA20;
-    i = pcmcia_request_io(link, &link->io);
+    link->resource[0]->start = 0xA20;
+    i = pcmcia_request_io(link);
     if (i != 0) {
        /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
-       link->io.BasePort1 = 0xA24;
-       ret = pcmcia_request_io(link, &link->io);
+       link->resource[0]->start = 0xA24;
+       ret = pcmcia_request_io(link);
        if (ret)
                goto failed;
     }
-    dev->base_addr = link->io.BasePort1;
+    dev->base_addr = link->resource[0]->start;
 
     ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
     if (ret)
@@ -251,9 +249,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     if (ret)
            goto failed;
 
-    mem.CardOffset = mmiobase;
-    mem.Page = 0;
-    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    ret = pcmcia_map_mem_page(link, link->win, mmiobase);
     if (ret)
            goto failed;
     ti->mmio = ioremap(req.Base, req.Size);
@@ -268,13 +264,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     if (ret)
            goto failed;
 
-    mem.CardOffset = srambase;
-    mem.Page = 0;
-    ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
+    ret = pcmcia_map_mem_page(link, info->sram_win_handle, srambase);
     if (ret)
            goto failed;
 
-    ti->sram_base = mem.CardOffset >> 12;
+    ti->sram_base = srambase >> 12;
     ti->sram_virt = ioremap(req.Base, req.Size);
     ti->sram_phys = req.Base;
 
@@ -325,7 +319,6 @@ static void ibmtr_release(struct pcmcia_device *link)
        if (link->win) {
                struct tok_info *ti = netdev_priv(dev);
                iounmap(ti->mmio);
-               pcmcia_release_window(link, info->sram_win_handle);
        }
        pcmcia_disable_device(link);
 }
index 9b63dec549cbce4e453f0a996c3d45e7236b3850..68f2deeb3ade11722dc5333386f4afd56cc98eb3 100644 (file)
@@ -146,7 +146,6 @@ Include Files
 #include <linux/ioport.h>
 #include <linux/bitops.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/cistpl.h>
@@ -459,9 +458,8 @@ static int nmclan_probe(struct pcmcia_device *link)
     link->priv = dev;
     
     spin_lock_init(&lp->bank_lock);
-    link->io.NumPorts1 = 32;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.IOAddrLines = 5;
+    link->resource[0]->end = 32;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
@@ -645,7 +643,8 @@ static int nmclan_config(struct pcmcia_device *link)
 
   dev_dbg(&link->dev, "nmclan_config\n");
 
-  ret = pcmcia_request_io(link, &link->io);
+  link->io_lines = 5;
+  ret = pcmcia_request_io(link);
   if (ret)
          goto failed;
   ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
@@ -656,7 +655,7 @@ static int nmclan_config(struct pcmcia_device *link)
          goto failed;
 
   dev->irq = link->irq;
-  dev->base_addr = link->io.BasePort1;
+  dev->base_addr = link->resource[0]->start;
 
   ioaddr = dev->base_addr;
 
@@ -758,29 +757,20 @@ static void nmclan_reset(struct net_device *dev)
 
 #if RESET_XILINX
   struct pcmcia_device *link = &lp->link;
-  conf_reg_t reg;
-  u_long OrigCorValue; 
+  u8 OrigCorValue;
 
   /* Save original COR value */
-  reg.Function = 0;
-  reg.Action = CS_READ;
-  reg.Offset = CISREG_COR;
-  reg.Value = 0;
-  pcmcia_access_configuration_register(link, &reg);
-  OrigCorValue = reg.Value;
+  pcmcia_read_config_byte(link, CISREG_COR, &OrigCorValue);
 
   /* Reset Xilinx */
-  reg.Action = CS_WRITE;
-  reg.Offset = CISREG_COR;
-  dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
+  dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%x, resetting...\n",
        OrigCorValue);
-  reg.Value = COR_SOFT_RESET;
-  pcmcia_access_configuration_register(link, &reg);
+  pcmcia_write_config_byte(link, CISREG_COR, COR_SOFT_RESET);
   /* Need to wait for 20 ms for PCMCIA to finish reset. */
 
   /* Restore original COR configuration index */
-  reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK);
-  pcmcia_access_configuration_register(link, &reg);
+  pcmcia_write_config_byte(link, CISREG_COR,
+                         (COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK)));
   /* Xilinx is now completely reset along with the MACE chip. */
   lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
 
index bfdef72c5d5ea6371b2fc634c9e2a8476d13fa33..c3edfe4c26516fc14780ee19183fc6db95fbf273 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/mii.h>
 #include "../8390.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -113,8 +112,6 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg,
 
 static void pcnet_detach(struct pcmcia_device *p_dev);
 
-static dev_info_t dev_info = "pcnet_cs";
-
 /*====================================================================*/
 
 typedef struct hw_info_t {
@@ -304,7 +301,6 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     win_req_t req;
-    memreq_t mem;
     u_char __iomem *base, *virt;
     int i, j;
 
@@ -317,10 +313,8 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
        return NULL;
 
     virt = ioremap(req.Base, req.Size);
-    mem.Page = 0;
     for (i = 0; i < NR_INFO; i++) {
-       mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
-       pcmcia_map_mem_page(link, link->win, &mem);
+       pcmcia_map_mem_page(link, link->win, hw_info[i].offset & ~(req.Size-1));
        base = &virt[hw_info[i].offset & (req.Size-1)];
        if ((readb(base+0) == hw_info[i].a0) &&
            (readb(base+2) == hw_info[i].a1) &&
@@ -480,29 +474,31 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
 static int try_io_port(struct pcmcia_device *link)
 {
     int j, ret;
-    if (link->io.NumPorts1 == 32) {
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       if (link->io.NumPorts2 > 0) {
+    link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+    link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+    if (link->resource[0]->end == 32) {
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+       if (link->resource[1]->end > 0) {
            /* for master/slave multifunction cards */
-           link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+           link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
        }
     } else {
        /* This should be two 16-port windows */
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
     }
-    if (link->io.BasePort1 == 0) {
-       link->io.IOAddrLines = 16;
+    if (link->resource[0]->start == 0) {
        for (j = 0; j < 0x400; j += 0x20) {
-           link->io.BasePort1 = j ^ 0x300;
-           link->io.BasePort2 = (j ^ 0x300) + 0x10;
-           ret = pcmcia_request_io(link, &link->io);
+           link->resource[0]->start = j ^ 0x300;
+           link->resource[1]->start = (j ^ 0x300) + 0x10;
+           link->io_lines = 16;
+           ret = pcmcia_request_io(link);
            if (ret == 0)
                    return ret;
        }
        return ret;
     } else {
-       return pcmcia_request_io(link, &link->io);
+       return pcmcia_request_io(link);
     }
 }
 
@@ -523,18 +519,18 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
           network function with window 0, and serial with window 1 */
        if (io->nwin > 1) {
                i = (io->win[1].len > io->win[0].len);
-               p_dev->io.BasePort2 = io->win[1-i].base;
-               p_dev->io.NumPorts2 = io->win[1-i].len;
+               p_dev->resource[1]->start = io->win[1-i].base;
+               p_dev->resource[1]->end = io->win[1-i].len;
        } else {
-               i = p_dev->io.NumPorts2 = 0;
+               i = p_dev->resource[1]->end = 0;
        }
 
        *has_shmem = ((cfg->mem.nwin == 1) &&
                      (cfg->mem.win[0].len >= 0x4000));
-       p_dev->io.BasePort1 = io->win[i].base;
-       p_dev->io.NumPorts1 = io->win[i].len;
-       p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-       if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+       p_dev->resource[0]->start = io->win[i].base;
+       p_dev->resource[0]->end = io->win[i].len;
+       p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+       if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
                return try_io_port(p_dev);
 
        return 0;
@@ -557,7 +553,7 @@ static int pcnet_config(struct pcmcia_device *link)
     if (!link->irq)
            goto failed;
 
-    if (link->io.NumPorts2 == 8) {
+    if (resource_size(link->resource[1]) == 8) {
        link->conf.Attributes |= CONF_ENABLE_SPKR;
        link->conf.Status = CCSR_AUDIO_ENA;
     }
@@ -569,7 +565,7 @@ static int pcnet_config(struct pcmcia_device *link)
     if (ret)
            goto failed;
     dev->irq = link->irq;
-    dev->base_addr = link->io.BasePort1;
+    dev->base_addr = link->resource[0]->start;
     if (info->flags & HAS_MISC_REG) {
        if ((if_port == 1) || (if_port == 2))
            dev->if_port = if_port;
@@ -956,7 +952,7 @@ static int pcnet_open(struct net_device *dev)
     set_misc_reg(dev);
 
     outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
-    ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
+    ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev->name, dev);
     if (ret)
            return ret;
 
@@ -1464,7 +1460,6 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
     struct net_device *dev = link->priv;
     pcnet_dev_t *info = PRIV(dev);
     win_req_t req;
-    memreq_t mem;
     int i, window_size, offset, ret;
 
     window_size = (stop_pg - start_pg) << 8;
@@ -1483,11 +1478,9 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
     if (ret)
            goto failed;
 
-    mem.CardOffset = (start_pg << 8) + cm_offset;
-    offset = mem.CardOffset % window_size;
-    mem.CardOffset -= offset;
-    mem.Page = 0;
-    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    offset = (start_pg << 8) + cm_offset;
+    offset -= offset % window_size;
+    ret = pcmcia_map_mem_page(link, link->win, offset);
     if (ret)
            goto failed;
 
index 307cd1721e91271bb1b3762868f9dbcb6400d218..377367d03b419dd7907262bfaedaf3acc0d60aca 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/jiffies.h>
 #include <linux/firmware.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -325,9 +324,8 @@ static int smc91c92_probe(struct pcmcia_device *link)
     link->priv = dev;
 
     spin_lock_init(&smc->lock);
-    link->io.NumPorts1 = 16;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.IOAddrLines = 4;
+    link->resource[0]->end = 16;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -428,12 +426,13 @@ static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
                                void *priv_data)
 {
        int k;
-       p_dev->io.BasePort2 = cf->io.win[0].base;
+       p_dev->resource[1]->start = cf->io.win[0].base;
        for (k = 0; k < 0x400; k += 0x10) {
                if (k & 0x80)
                        continue;
-               p_dev->io.BasePort1 = k ^ 0x300;
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               p_dev->resource[0]->start = k ^ 0x300;
+               p_dev->io_lines = 16;
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        }
        return -ENODEV;
@@ -444,21 +443,20 @@ static int mhz_mfc_config(struct pcmcia_device *link)
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
     win_req_t req;
-    memreq_t mem;
+    unsigned int offset;
     int i;
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->io.IOAddrLines = 16;
-    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-    link->io.NumPorts2 = 8;
+    link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+    link->resource[1]->end = 8;
 
     /* The Megahertz combo cards have modem-like CIS entries, so
        we have to explicitly try a bunch of port combinations. */
     if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
            return -ENODEV;
 
-    dev->base_addr = link->io.BasePort1;
+    dev->base_addr = link->resource[0]->start;
 
     /* Allocate a memory window, for accessing the ISR */
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
@@ -469,11 +467,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
            return -ENODEV;
 
     smc->base = ioremap(req.Base, req.Size);
-    mem.CardOffset = mem.Page = 0;
-    if (smc->manfid == MANFID_MOTOROLA)
-       mem.CardOffset = link->conf.ConfigBase;
-    i = pcmcia_map_mem_page(link, link->win, &mem);
-
+    offset = (smc->manfid == MANFID_MOTOROLA) ? link->conf.ConfigBase : 0;
+    i = pcmcia_map_mem_page(link, link->win, offset);
     if ((i == 0) &&
        (smc->manfid == MANFID_MEGAHERTZ) &&
        (smc->cardid == PRODID_MEGAHERTZ_EM3288))
@@ -546,7 +541,7 @@ static void mot_config(struct pcmcia_device *link)
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
     unsigned int ioaddr = dev->base_addr;
-    unsigned int iouart = link->io.BasePort2;
+    unsigned int iouart = link->resource[1]->start;
 
     /* Set UART base address and force map with COR bit 1 */
     writeb(iouart & 0xff,        smc->base + MOT_UART + CISREG_IOBASE_0);
@@ -602,9 +597,9 @@ static int smc_configcheck(struct pcmcia_device *p_dev,
                           unsigned int vcc,
                           void *priv_data)
 {
-       p_dev->io.BasePort1 = cf->io.win[0].base;
-       p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       p_dev->resource[0]->start = cf->io.win[0].base;
+       p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
+       return pcmcia_request_io(p_dev);
 }
 
 static int smc_config(struct pcmcia_device *link)
@@ -612,10 +607,10 @@ static int smc_config(struct pcmcia_device *link)
     struct net_device *dev = link->priv;
     int i;
 
-    link->io.NumPorts1 = 16;
+    link->resource[0]->end = 16;
     i = pcmcia_loop_config(link, smc_configcheck, NULL);
     if (!i)
-           dev->base_addr = link->io.BasePort1;
+           dev->base_addr = link->resource[0]->start;
 
     return i;
 }
@@ -647,27 +642,27 @@ static int osi_config(struct pcmcia_device *link)
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->io.NumPorts1 = 64;
-    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-    link->io.NumPorts2 = 8;
-    link->io.IOAddrLines = 16;
+    link->resource[0]->end = 64;
+    link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+    link->resource[1]->end = 8;
 
     /* Enable Hard Decode, LAN, Modem */
     link->conf.ConfigIndex = 0x23;
+    link->io_lines = 16;
 
     for (i = j = 0; j < 4; j++) {
-       link->io.BasePort2 = com[j];
-       i = pcmcia_request_io(link, &link->io);
+       link->resource[1]->start = com[j];
+       i = pcmcia_request_io(link);
        if (i == 0)
                break;
     }
     if (i != 0) {
        /* Fallback: turn off hard decode */
        link->conf.ConfigIndex = 0x03;
-       link->io.NumPorts2 = 0;
-       i = pcmcia_request_io(link, &link->io);
+       link->resource[1]->end = 0;
+       i = pcmcia_request_io(link);
     }
-    dev->base_addr = link->io.BasePort1 + 0x10;
+    dev->base_addr = link->resource[0]->start + 0x10;
     return i;
 }
 
@@ -684,7 +679,7 @@ static int osi_load_firmware(struct pcmcia_device *link)
 
        /* Download the Seven of Diamonds firmware */
        for (i = 0; i < fw->size; i++) {
-           outb(fw->data[i], link->io.BasePort1 + 2);
+           outb(fw->data[i], link->resource[0]->start + 2);
            udelay(50);
        }
        release_firmware(fw);
@@ -726,12 +721,12 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
                return rc;
     } else if (manfid == MANFID_OSITECH) {
        /* Make sure both functions are powered up */
-       set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
+       set_bits(0x300, link->resource[0]->start + OSITECH_AUI_PWR);
        /* Now, turn on the interrupt for both card functions */
-       set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
+       set_bits(0x300, link->resource[0]->start + OSITECH_RESET_ISR);
        dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
-             inw(link->io.BasePort1 + OSITECH_AUI_PWR),
-             inw(link->io.BasePort1 + OSITECH_RESET_ISR));
+             inw(link->resource[0]->start + OSITECH_AUI_PWR),
+             inw(link->resource[0]->start + OSITECH_RESET_ISR));
     }
     return 0;
 }
@@ -804,7 +799,7 @@ static int check_sig(struct pcmcia_device *link)
     }
 
     /* Try setting bus width */
-    width = (link->io.Attributes1 == IO_DATA_PATH_WIDTH_AUTO);
+    width = (link->resource[0]->flags == IO_DATA_PATH_WIDTH_AUTO);
     s = inb(ioaddr + CONFIG);
     if (width)
        s |= CFG_16BIT;
index b6c3644888cd8e09077bb7f4f92872387b49b9ba..4eb6f986703bec69686b8def0677535a760aac61 100644 (file)
@@ -82,7 +82,6 @@
 #include <linux/bitops.h>
 #include <linux/mii.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -678,9 +677,9 @@ xirc2ps_config_modem(struct pcmcia_device *p_dev,
 
        if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8) {
                for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
-                       p_dev->io.BasePort2 = cf->io.win[0].base;
-                       p_dev->io.BasePort1 = ioaddr;
-                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       p_dev->resource[1]->start = cf->io.win[0].base;
+                       p_dev->resource[0]->start = ioaddr;
+                       if (!pcmcia_request_io(p_dev))
                                return 0;
                }
        }
@@ -697,11 +696,11 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
        int *pass = priv_data;
 
        if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
-               p_dev->io.BasePort2 = cf->io.win[0].base;
-               p_dev->io.BasePort1 = p_dev->io.BasePort2
+               p_dev->resource[1]->start = cf->io.win[0].base;
+               p_dev->resource[0]->start = p_dev->resource[1]->start
                        + (*pass ? (cf->index & 0x20 ? -24:8)
                           : (cf->index & 0x20 ?   8:-24));
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        }
        return -ENODEV;
@@ -808,8 +807,7 @@ xirc2ps_config(struct pcmcia_device * link)
        goto failure;
     }
 
-    link->io.IOAddrLines =10;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
     if (local->modem) {
        int pass;
 
@@ -817,16 +815,16 @@ xirc2ps_config(struct pcmcia_device * link)
            link->conf.Attributes |= CONF_ENABLE_SPKR;
            link->conf.Status |= CCSR_AUDIO_ENA;
        }
-       link->io.NumPorts2 = 8;
-       link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+       link->resource[1]->end = 8;
+       link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
        if (local->dingo) {
            /* Take the Modem IO port from the CIS and scan for a free
             * Ethernet port */
-           link->io.NumPorts1 = 16; /* no Mako stuff anymore */
+           link->resource[0]->end = 16; /* no Mako stuff anymore */
            if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
                    goto port_found;
        } else {
-           link->io.NumPorts1 = 18;
+           link->resource[0]->end = 18;
            /* We do 2 passes here: The first one uses the regular mapping and
             * the second tries again, thereby considering that the 32 ports are
             * mirrored every 32 bytes. Actually we use a mirrored port for
@@ -841,14 +839,15 @@ xirc2ps_config(struct pcmcia_device * link)
        }
        printk(KNOT_XIRC "no ports available\n");
     } else {
-       link->io.NumPorts1 = 16;
+       link->io_lines = 10;
+       link->resource[0]->end = 16;
        for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
-           link->io.BasePort1 = ioaddr;
-           if (!(err=pcmcia_request_io(link, &link->io)))
+           link->resource[0]->start = ioaddr;
+           if (!(err = pcmcia_request_io(link)))
                goto port_found;
        }
-       link->io.BasePort1 = 0; /* let CS decide */
-       if ((err=pcmcia_request_io(link, &link->io)))
+       link->resource[0]->start = 0; /* let CS decide */
+       if ((err = pcmcia_request_io(link)))
            goto config_error;
     }
   port_found:
@@ -870,24 +869,21 @@ xirc2ps_config(struct pcmcia_device * link)
        goto config_error;
 
     if (local->dingo) {
-       conf_reg_t reg;
        win_req_t req;
-       memreq_t mem;
 
        /* Reset the modem's BAR to the correct value
         * This is necessary because in the RequestConfiguration call,
         * the base address of the ethernet port (BasePort1) is written
         * to the BAR registers of the modem.
         */
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_IOBASE_0;
-       reg.Value = link->io.BasePort2 & 0xff;
-       if ((err = pcmcia_access_configuration_register(link, &reg)))
+       err = pcmcia_write_config_byte(link, CISREG_IOBASE_0, (u8)
+                               link->resource[1]->start & 0xff);
+       if (err)
            goto config_error;
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_IOBASE_1;
-       reg.Value = (link->io.BasePort2 >> 8) & 0xff;
-       if ((err = pcmcia_access_configuration_register(link, &reg)))
+
+       err = pcmcia_write_config_byte(link, CISREG_IOBASE_1,
+                               (link->resource[1]->start >> 8) & 0xff);
+       if (err)
            goto config_error;
 
        /* There is no config entry for the Ethernet part which
@@ -901,16 +897,14 @@ xirc2ps_config(struct pcmcia_device * link)
            goto config_error;
 
        local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
-       mem.CardOffset = 0x0;
-       mem.Page = 0;
-       if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
+       if ((err = pcmcia_map_mem_page(link, link->win, 0)))
            goto config_error;
 
        /* Setup the CCRs; there are no infos in the CIS about the Ethernet
         * part.
         */
        writeb(0x47, local->dingo_ccr + CISREG_COR);
-       ioaddr = link->io.BasePort1;
+       ioaddr = link->resource[0]->start;
        writeb(ioaddr & 0xff      , local->dingo_ccr + CISREG_IOBASE_0);
        writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1);
 
@@ -957,7 +951,7 @@ xirc2ps_config(struct pcmcia_device * link)
 
     /* we can now register the device with the net subsystem */
     dev->irq = link->irq;
-    dev->base_addr = link->io.BasePort1;
+    dev->base_addr = link->resource[0]->start;
 
     if (local->dingo)
        do_reset(dev, 1); /* a kludge to make the cem56 work */
index 35540411990d5867f1ed9d44164fc8b7e47a8a11..078bbf4e6f1933f3ee1e95e2c0dccfea92157088 100644 (file)
@@ -3219,11 +3219,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
 
-       if (pci_dev_run_wake(pdev)) {
-               pm_runtime_set_active(&pdev->dev);
-               pm_runtime_enable(&pdev->dev);
-       }
-       pm_runtime_idle(&pdev->dev);
+       if (pci_dev_run_wake(pdev))
+               pm_runtime_put_noidle(&pdev->dev);
 
 out:
        return rc;
@@ -3246,17 +3243,12 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 
-       pm_runtime_get_sync(&pdev->dev);
-
        flush_scheduled_work();
 
        unregister_netdev(dev);
 
-       if (pci_dev_run_wake(pdev)) {
-               pm_runtime_disable(&pdev->dev);
-               pm_runtime_set_suspended(&pdev->dev);
-       }
-       pm_runtime_put_noidle(&pdev->dev);
+       if (pci_dev_run_wake(pdev))
+               pm_runtime_get_noresume(&pdev->dev);
 
        /* restore original MAC address */
        rtl_rar_set(tp, dev->perm_addr);
index 367e96f317d4d4df298a59945a2d3e3ca7ea9e73..09c071bd6ad421cc5439d87b5727d1810089fe8b 100644 (file)
@@ -1201,7 +1201,7 @@ static int __devinit bigmac_ether_init(struct of_device *op,
        dev->watchdog_timeo = 5*HZ;
 
        /* Finish net device registration. */
-       dev->irq = bp->bigmac_op->irqs[0];
+       dev->irq = bp->bigmac_op->archdata.irqs[0];
        dev->dma = 0;
 
        if (register_netdev(dev)) {
@@ -1301,12 +1301,12 @@ static struct of_platform_driver bigmac_sbus_driver = {
 
 static int __init bigmac_init(void)
 {
-       return of_register_driver(&bigmac_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&bigmac_sbus_driver);
 }
 
 static void __exit bigmac_exit(void)
 {
-       of_unregister_driver(&bigmac_sbus_driver);
+       of_unregister_platform_driver(&bigmac_sbus_driver);
 }
 
 module_init(bigmac_init);
index 3d9650b8d38fab26fce127f52d7a09ad1170ff6d..eec443f640790ccde8def34cfd06bd6cf77a6700 100644 (file)
@@ -2561,7 +2561,7 @@ static int __init quattro_sbus_register_irqs(void)
                if (skip)
                        continue;
 
-               err = request_irq(op->irqs[0],
+               err = request_irq(op->archdata.irqs[0],
                                  quattro_sbus_interrupt,
                                  IRQF_SHARED, "Quattro",
                                  qp);
@@ -2590,7 +2590,7 @@ static void quattro_sbus_free_irqs(void)
                if (skip)
                        continue;
 
-               free_irq(op->irqs[0], qp);
+               free_irq(op->archdata.irqs[0], qp);
        }
 }
 #endif /* CONFIG_SBUS */
@@ -2790,7 +2790,7 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
        /* Happy Meal can do it all... */
        dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
        /* Hook up SBUS register/descriptor accessors. */
@@ -3304,7 +3304,7 @@ static int __init happy_meal_sbus_init(void)
 {
        int err;
 
-       err = of_register_driver(&hme_sbus_driver, &of_bus_type);
+       err = of_register_platform_driver(&hme_sbus_driver);
        if (!err)
                err = quattro_sbus_register_irqs();
 
@@ -3313,7 +3313,7 @@ static int __init happy_meal_sbus_init(void)
 
 static void happy_meal_sbus_exit(void)
 {
-       of_unregister_driver(&hme_sbus_driver);
+       of_unregister_platform_driver(&hme_sbus_driver);
        quattro_sbus_free_irqs();
 
        while (qfe_sbus_list) {
index 7d9c33dd9d1acf8efc6e9925787678f050a0b80c..ee364fa756342686d12618775790ea37a97f6e49 100644 (file)
@@ -1474,7 +1474,7 @@ no_link_test:
        dev->ethtool_ops = &sparc_lance_ethtool_ops;
        dev->netdev_ops = &sparc_lance_ops;
 
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
 
        /* We cannot sleep if the chip is busy during a
         * multicast list update event, because such events
@@ -1558,12 +1558,12 @@ static struct of_platform_driver sunlance_sbus_driver = {
 /* Find all the lance cards on the system and initialize them */
 static int __init sparc_lance_init(void)
 {
-       return of_register_driver(&sunlance_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&sunlance_sbus_driver);
 }
 
 static void __exit sparc_lance_exit(void)
 {
-       of_unregister_driver(&sunlance_sbus_driver);
+       of_unregister_platform_driver(&sunlance_sbus_driver);
 }
 
 module_init(sparc_lance_init);
index 72b579c8d8127d4d18c006c22ca631b2be06fe06..5f84a5dadeddd90feca5e72221506c001c416314 100644 (file)
@@ -803,7 +803,7 @@ static struct sunqec * __devinit get_qec(struct of_device *child)
 
                        qec_init_once(qecp, op);
 
-                       if (request_irq(op->irqs[0], qec_interrupt,
+                       if (request_irq(op->archdata.irqs[0], qec_interrupt,
                                        IRQF_SHARED, "qec", (void *) qecp)) {
                                printk(KERN_ERR "qec: Can't register irq.\n");
                                goto fail;
@@ -901,7 +901,7 @@ static int __devinit qec_ether_init(struct of_device *op)
        SET_NETDEV_DEV(dev, &op->dev);
 
        dev->watchdog_timeo = 5*HZ;
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
        dev->dma = 0;
        dev->ethtool_ops = &qe_ethtool_ops;
        dev->netdev_ops = &qec_ops;
@@ -988,18 +988,18 @@ static struct of_platform_driver qec_sbus_driver = {
 
 static int __init qec_init(void)
 {
-       return of_register_driver(&qec_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&qec_sbus_driver);
 }
 
 static void __exit qec_exit(void)
 {
-       of_unregister_driver(&qec_sbus_driver);
+       of_unregister_platform_driver(&qec_sbus_driver);
 
        while (root_qec_dev) {
                struct sunqec *next = root_qec_dev->next_module;
                struct of_device *op = root_qec_dev->op;
 
-               free_irq(op->irqs[0], (void *) root_qec_dev);
+               free_irq(op->archdata.irqs[0], (void *) root_qec_dev);
                of_iounmap(&op->resource[0], root_qec_dev->gregs,
                           GLOB_REG_SIZE);
                kfree(root_qec_dev);
index 33bdc6a84e816fae923e8980f52d7e427657d6d7..9a121a5b787cb2468005e914e81a15eee55e312f 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/timer.h>
 #include <linux/netdevice.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -155,8 +154,6 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
                                unsigned int vcc,
                                void *priv_data)
 {
-       win_req_t *req = priv_data;
-
        if (cfg->index == 0)
                return -ENODEV;
 
@@ -176,52 +173,25 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
        }
 
        /* This reserves IO space but doesn't actually enable it */
-       if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+       if (pcmcia_request_io(p_dev) != 0)
                return -ENODEV;
 
-       /*
-         Now set up a common memory window, if needed.  There is room
-         in the struct pcmcia_device structure for one memory window handle,
-         but if the base addresses need to be saved, or if multiple
-         windows are needed, the info should go in the private data
-         structure for this device.
-
-         Note that the memory window base is a physical address, and
-         needs to be mapped to virtual space with ioremap() before it
-         is used.
-       */
-       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
-               cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
-               memreq_t map;
-               req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
-               req->Base = mem->win[0].host_addr;
-               req->Size = mem->win[0].len;
-               req->AccessSpeed = 0;
-               if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
-                       return -ENODEV;
-               map.Page = 0;
-               map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
-                       return -ENODEV;
-       }
        /* If we got this far, we're cool! */
        return 0;
 }
@@ -230,17 +200,12 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
 static int airo_config(struct pcmcia_device *link)
 {
        local_info_t *dev;
-       win_req_t *req;
        int ret;
 
        dev = link->priv;
 
        dev_dbg(&link->dev, "airo_config\n");
 
-       req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
-       if (!req)
-               return -ENOMEM;
-
        /*
         * In this loop, we scan the CIS for configuration table
         * entries, each of which describes a valid card
@@ -255,7 +220,7 @@ static int airo_config(struct pcmcia_device *link)
         * and most client drivers will only use the CIS to fill in
         * implementation-defined details.
         */
-       ret = pcmcia_loop_config(link, airo_cs_config_check, req);
+       ret = pcmcia_loop_config(link, airo_cs_config_check, NULL);
        if (ret)
                goto failed;
 
@@ -272,7 +237,7 @@ static int airo_config(struct pcmcia_device *link)
                goto failed;
        ((local_info_t *)link->priv)->eth_dev =
                init_airo_card(link->irq,
-                              link->io.BasePort1, 1, &link->dev);
+                              link->resource[0]->start, 1, &link->dev);
        if (!((local_info_t *)link->priv)->eth_dev)
                goto failed;
 
@@ -282,22 +247,15 @@ static int airo_config(struct pcmcia_device *link)
        if (link->conf.Vpp)
                printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
        printk(", irq %d", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1+link->io.NumPorts1-1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2+link->io.NumPorts2-1);
-       if (link->win)
-               printk(", mem 0x%06lx-0x%06lx", req->Base,
-                      req->Base+req->Size-1);
+       if (link->resource[0])
+               printk(" & %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        printk("\n");
-       kfree(req);
        return 0;
 
  failed:
        airo_release(link);
-       kfree(req);
        return -ENODEV;
 } /* airo_config */
 
index c2746fc7f2beab159daf40e337b55ea878e26788..3b632161c10696ee7ae896db24c11d4886395486 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -191,25 +190,23 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
        }
 
        /* This reserves IO space but doesn't actually enable it */
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       return pcmcia_request_io(p_dev);
 }
 
 static int atmel_config(struct pcmcia_device *link)
@@ -254,7 +251,7 @@ static int atmel_config(struct pcmcia_device *link)
 
        ((local_info_t*)link->priv)->eth_dev =
                init_atmel_card(link->irq,
-                               link->io.BasePort1,
+                               link->resource[0]->start,
                                did ? did->driver_info : ATMEL_FW_TYPE_NONE,
                                &link->dev,
                                card_present,
index 0e99b634267c56b5077b058a7eaed3fce0edfe8e..dfbc41d431ffae744fca15a2a90506ee5e6abb01 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/ssb/ssb.h>
 #include <linux/slab.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -65,7 +64,6 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
 {
        struct ssb_bus *ssb;
        win_req_t win;
-       memreq_t mem;
        int err = -ENOMEM;
        int res = 0;
 
@@ -78,12 +76,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
        dev->conf.Attributes = CONF_ENABLE_IRQ;
        dev->conf.IntType = INT_MEMORY_AND_IO;
 
-       dev->io.BasePort2 = 0;
-       dev->io.NumPorts2 = 0;
-       dev->io.Attributes2 = 0;
-
-       win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
-                        WIN_ENABLE | WIN_DATA_WIDTH_16 |
+       win.Attributes =  WIN_ENABLE | WIN_DATA_WIDTH_16 |
                         WIN_USE_WAIT;
        win.Base = 0;
        win.Size = SSB_CORE_SIZE;
@@ -92,9 +85,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
        if (res != 0)
                goto err_kfree_ssb;
 
-       mem.CardOffset = 0;
-       mem.Page = 0;
-       res = pcmcia_map_mem_page(dev, dev->win, &mem);
+       res = pcmcia_map_mem_page(dev, dev->win, 0);
        if (res != 0)
                goto err_disable;
 
index 29b31a694b59cc2140cf7b044757f29c5dfd9701..ba54d1b04d22a7e50ae244bb2b905c84d44c1986 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -23,7 +22,7 @@
 #include "hostap_wlan.h"
 
 
-static dev_info_t dev_info = "hostap_cs";
+static char *dev_info = "hostap_cs";
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
@@ -225,27 +224,18 @@ static int prism2_pccard_card_present(local_info_t *local)
 static void sandisk_set_iobase(local_info_t *local)
 {
        int res;
-       conf_reg_t reg;
        struct hostap_cs_priv *hw_priv = local->hw_priv;
 
-       reg.Function = 0;
-       reg.Action = CS_WRITE;
-       reg.Offset = 0x10; /* 0x3f0 IO base 1 */
-       reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_write_config_byte(hw_priv->link, 0x10,
+                               hw_priv->link->resource[0]->start & 0x00ff);
        if (res != 0) {
                printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
                       " res=%d\n", res);
        }
        udelay(10);
 
-       reg.Function = 0;
-       reg.Action = CS_WRITE;
-       reg.Offset = 0x12; /* 0x3f2 IO base 2 */
-       reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_write_config_byte(hw_priv->link, 0x12,
+                               (hw_priv->link->resource[0]->start >> 8) & 0x00ff);
        if (res != 0) {
                printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
                       " res=%d\n", res);
@@ -271,12 +261,11 @@ static void sandisk_write_hcr(local_info_t *local, int hcr)
 static int sandisk_enable_wireless(struct net_device *dev)
 {
        int res, ret = 0;
-       conf_reg_t reg;
        struct hostap_interface *iface = netdev_priv(dev);
        local_info_t *local = iface->local;
        struct hostap_cs_priv *hw_priv = local->hw_priv;
 
-       if (hw_priv->link->io.NumPorts1 < 0x42) {
+       if (resource_size(hw_priv->link->resource[0]) < 0x42) {
                /* Not enough ports to be SanDisk multi-function card */
                ret = -ENODEV;
                goto done;
@@ -298,12 +287,8 @@ static int sandisk_enable_wireless(struct net_device *dev)
               " - using vendor-specific initialization\n", dev->name);
        hw_priv->sandisk_connectplus = 1;
 
-       reg.Function = 0;
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_COR;
-       reg.Value = COR_SOFT_RESET;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+                               COR_SOFT_RESET);
        if (res != 0) {
                printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
                       dev->name, res);
@@ -311,16 +296,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
        }
        mdelay(5);
 
-       reg.Function = 0;
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_COR;
        /*
         * Do not enable interrupts here to avoid some bogus events. Interrupts
         * will be enabled during the first cor_sreset call.
         */
-       reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+                               (COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE |
+                                       COR_FUNC_ENA));
        if (res != 0) {
                printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
                       dev->name, res);
@@ -343,30 +325,23 @@ done:
 static void prism2_pccard_cor_sreset(local_info_t *local)
 {
        int res;
-       conf_reg_t reg;
+       u8 val;
        struct hostap_cs_priv *hw_priv = local->hw_priv;
 
        if (!prism2_pccard_card_present(local))
               return;
 
-       reg.Function = 0;
-       reg.Action = CS_READ;
-       reg.Offset = CISREG_COR;
-       reg.Value = 0;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_read_config_byte(hw_priv->link, CISREG_COR, &val);
        if (res != 0) {
                printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
                       res);
                return;
        }
        printk(KERN_DEBUG "prism2_pccard_cor_sreset: original COR %02x\n",
-              reg.Value);
+               val);
 
-       reg.Action = CS_WRITE;
-       reg.Value |= COR_SOFT_RESET;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       val |= COR_SOFT_RESET;
+       res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR, val);
        if (res != 0) {
                printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
                       res);
@@ -375,11 +350,10 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
 
        mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
 
-       reg.Value &= ~COR_SOFT_RESET;
+       val &= ~COR_SOFT_RESET;
        if (hw_priv->sandisk_connectplus)
-               reg.Value |= COR_IREQ_ENA;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+               val |= COR_IREQ_ENA;
+       res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR, val);
        if (res != 0) {
                printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
                       res);
@@ -396,8 +370,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
 static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
 {
        int res;
-       conf_reg_t reg;
-       int old_cor;
+       u8 old_cor;
        struct hostap_cs_priv *hw_priv = local->hw_priv;
 
        if (!prism2_pccard_card_present(local))
@@ -408,25 +381,17 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
                return;
        }
 
-       reg.Function = 0;
-       reg.Action = CS_READ;
-       reg.Offset = CISREG_COR;
-       reg.Value = 0;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_read_config_byte(hw_priv->link, CISREG_COR, &old_cor);
        if (res != 0) {
                printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
                       "(%d)\n", res);
                return;
        }
        printk(KERN_DEBUG "prism2_pccard_genesis_sreset: original COR %02x\n",
-              reg.Value);
-       old_cor = reg.Value;
+               old_cor);
 
-       reg.Action = CS_WRITE;
-       reg.Value |= COR_SOFT_RESET;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+                               old_cor | COR_SOFT_RESET);
        if (res != 0) {
                printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
                       "(%d)\n", res);
@@ -436,11 +401,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
        mdelay(10);
 
        /* Setup Genesis mode */
-       reg.Action = CS_WRITE;
-       reg.Value = hcr;
-       reg.Offset = CISREG_CCSR;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_write_config_byte(hw_priv->link, CISREG_CCSR, hcr);
        if (res != 0) {
                printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
                       "(%d)\n", res);
@@ -448,11 +409,8 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
        }
        mdelay(10);
 
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_COR;
-       reg.Value = old_cor & ~COR_SOFT_RESET;
-       res = pcmcia_access_configuration_register(hw_priv->link,
-                                                  &reg);
+       res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+                               old_cor & ~COR_SOFT_RESET);
        if (res != 0) {
                printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
                       "(%d)\n", res);
@@ -561,30 +519,24 @@ static int prism2_config_check(struct pcmcia_device *p_dev,
        PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
               "dflt->io.nwin=%d\n",
               cfg->io.nwin, dflt->io.nwin);
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
-                      "io.base=0x%04x, len=%d\n", io->flags,
-                      io->win[0].base, io->win[0].len);
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags &
-                       CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
        }
 
        /* This reserves IO space but doesn't actually enable it */
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       return pcmcia_request_io(p_dev);
 }
 
 static int prism2_config(struct pcmcia_device *link)
@@ -646,7 +598,7 @@ static int prism2_config(struct pcmcia_device *link)
                goto failed_unlock;
 
        dev->irq = link->irq;
-       dev->base_addr = link->io.BasePort1;
+       dev->base_addr = link->resource[0]->start;
 
        spin_unlock_irqrestore(&local->irq_init_lock, flags);
 
@@ -658,12 +610,10 @@ static int prism2_config(struct pcmcia_device *link)
                       link->conf.Vpp % 10);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                printk(", irq %d", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1+link->io.NumPorts1-1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2+link->io.NumPorts2-1);
+       if (link->resource[0])
+               printk(" & %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        printk("\n");
 
        local->shutdown = 0;
index 08e4e3908003b2bfc5c9f007f2e29cca700346fb..9c298396be50b7fe5d0d6f8c6b102ecef441b3f7 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -802,9 +801,9 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev,
                         unsigned int vcc,
                         void *priv_data)
 {
-       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       p_dev->io.BasePort1 = cfg->io.win[0].base;
-       p_dev->io.NumPorts1 = cfg->io.win[0].len;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
 
        /* Do we need to allocate an interrupt? */
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
@@ -816,7 +815,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev,
        }
 
        /* This reserves IO space but doesn't actually enable it */
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       return pcmcia_request_io(p_dev);
 }
 
 static int if_cs_probe(struct pcmcia_device *p_dev)
@@ -854,7 +853,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
                goto out1;
 
        /* Initialize io access */
-       card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1);
+       card->iobase = ioport_map(p_dev->resource[0]->start,
+                               resource_size(p_dev->resource[0]));
        if (!card->iobase) {
                lbs_pr_err("error in ioport_map\n");
                ret = -EIO;
@@ -873,9 +873,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
        }
 
        /* Finally, report what we've done */
-       lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n",
-              p_dev->irq, p_dev->io.BasePort1,
-              p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
+       lbs_deb_cs("irq %d, io %pR", p_dev->irq, p_dev->resource[0]);
 
        /*
         * Most of the libertas cards can do unaligned register access, but some
index b16d5db52a4d96f858db37a79d066c873ac6014a..ef46a2d885392f49f1803fbb47bb2f6a6b2f7fdc 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -192,25 +191,23 @@ static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
 
                /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               if (pcmcia_request_io(p_dev) != 0)
                        goto next_entry;
        }
        return 0;
@@ -258,7 +255,8 @@ orinoco_cs_config(struct pcmcia_device *link)
        /* We initialize the hermes structure before completing PCMCIA
         * configuration just in case the interrupt handler gets
         * called. */
-       mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+       mem = ioport_map(link->resource[0]->start,
+                       resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
@@ -280,7 +278,7 @@ orinoco_cs_config(struct pcmcia_device *link)
        }
 
        /* Register an interface with the stack */
-       if (orinoco_if_add(priv, link->io.BasePort1,
+       if (orinoco_if_add(priv, link->resource[0]->start,
                           link->irq, NULL) != 0) {
                printk(KERN_ERR PFX "orinoco_if_add() failed\n");
                goto failed;
index b51a9adc80f6274648af92d4338cc37b5719b500..873877e17e1bf6bce4debd49b75f359a8d39b1ec 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -80,35 +79,27 @@ static int
 spectrum_reset(struct pcmcia_device *link, int idle)
 {
        int ret;
-       conf_reg_t reg;
-       u_int save_cor;
+       u8 save_cor;
+       u8 ccsr;
 
        /* Doing it if hardware is gone is guaranteed crash */
        if (!pcmcia_dev_present(link))
                return -ENODEV;
 
        /* Save original COR value */
-       reg.Function = 0;
-       reg.Action = CS_READ;
-       reg.Offset = CISREG_COR;
-       ret = pcmcia_access_configuration_register(link, &reg);
+       ret = pcmcia_read_config_byte(link, CISREG_COR, &save_cor);
        if (ret)
                goto failed;
-       save_cor = reg.Value;
 
        /* Soft-Reset card */
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_COR;
-       reg.Value = (save_cor | COR_SOFT_RESET);
-       ret = pcmcia_access_configuration_register(link, &reg);
+       ret = pcmcia_write_config_byte(link, CISREG_COR,
+                               (save_cor | COR_SOFT_RESET));
        if (ret)
                goto failed;
        udelay(1000);
 
        /* Read CCSR */
-       reg.Action = CS_READ;
-       reg.Offset = CISREG_CCSR;
-       ret = pcmcia_access_configuration_register(link, &reg);
+       ret = pcmcia_read_config_byte(link, CISREG_CCSR, &ccsr);
        if (ret)
                goto failed;
 
@@ -116,19 +107,15 @@ spectrum_reset(struct pcmcia_device *link, int idle)
         * Start or stop the firmware.  Memory width bit should be
         * preserved from the value we've just read.
         */
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_CCSR;
-       reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
-       ret = pcmcia_access_configuration_register(link, &reg);
+       ccsr = (idle ? HCR_IDLE : HCR_RUN) | (ccsr & HCR_MEM16);
+       ret = pcmcia_write_config_byte(link, CISREG_CCSR, ccsr);
        if (ret)
                goto failed;
        udelay(1000);
 
        /* Restore original COR configuration index */
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_COR;
-       reg.Value = (save_cor & ~COR_SOFT_RESET);
-       ret = pcmcia_access_configuration_register(link, &reg);
+       ret = pcmcia_write_config_byte(link, CISREG_COR,
+                               (save_cor & ~COR_SOFT_RESET));
        if (ret)
                goto failed;
        udelay(1000);
@@ -266,25 +253,23 @@ static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
 
                /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               if (pcmcia_request_io(p_dev) != 0)
                        goto next_entry;
        }
        return 0;
@@ -332,7 +317,8 @@ spectrum_cs_config(struct pcmcia_device *link)
        /* We initialize the hermes structure before completing PCMCIA
         * configuration just in case the interrupt handler gets
         * called. */
-       mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+       mem = ioport_map(link->resource[0]->start,
+                       resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
@@ -359,7 +345,7 @@ spectrum_cs_config(struct pcmcia_device *link)
        }
 
        /* Register an interface with the stack */
-       if (orinoco_if_add(priv, link->io.BasePort1,
+       if (orinoco_if_add(priv, link->resource[0]->start,
                           link->irq, NULL) != 0) {
                printk(KERN_ERR PFX "orinoco_if_add() failed\n");
                goto failed;
index 9c38fc331dca7966a6d643d37aaef20079cdd8b6..88560d0ae50a2457d1373103db85b98ebb61211e 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/ethtool.h>
 #include <linux/ieee80211.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -315,9 +314,8 @@ static int ray_probe(struct pcmcia_device *p_dev)
        local->finder = p_dev;
 
        /* The io structure describes IO port mapping. None used here */
-       p_dev->io.NumPorts1 = 0;
-       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       p_dev->io.IOAddrLines = 5;
+       p_dev->resource[0]->end = 0;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
 
        /* General socket configuration */
        p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -394,7 +392,6 @@ static int ray_config(struct pcmcia_device *link)
        int ret = 0;
        int i;
        win_req_t req;
-       memreq_t mem;
        struct net_device *dev = (struct net_device *)link->priv;
        ray_dev_t *local = netdev_priv(dev);
 
@@ -431,9 +428,7 @@ static int ray_config(struct pcmcia_device *link)
        ret = pcmcia_request_window(link, &req, &link->win);
        if (ret)
                goto failed;
-       mem.CardOffset = 0x0000;
-       mem.Page = 0;
-       ret = pcmcia_map_mem_page(link, link->win, &mem);
+       ret = pcmcia_map_mem_page(link, link->win, 0);
        if (ret)
                goto failed;
        local->sram = ioremap(req.Base, req.Size);
@@ -447,9 +442,7 @@ static int ray_config(struct pcmcia_device *link)
        ret = pcmcia_request_window(link, &req, &local->rmem_handle);
        if (ret)
                goto failed;
-       mem.CardOffset = 0x8000;
-       mem.Page = 0;
-       ret = pcmcia_map_mem_page(link, local->rmem_handle, &mem);
+       ret = pcmcia_map_mem_page(link, local->rmem_handle, 0x8000);
        if (ret)
                goto failed;
        local->rmem = ioremap(req.Base, req.Size);
@@ -463,9 +456,7 @@ static int ray_config(struct pcmcia_device *link)
        ret = pcmcia_request_window(link, &req, &local->amem_handle);
        if (ret)
                goto failed;
-       mem.CardOffset = 0x0000;
-       mem.Page = 0;
-       ret = pcmcia_map_mem_page(link, local->amem_handle, &mem);
+       ret = pcmcia_map_mem_page(link, local->amem_handle, 0);
        if (ret)
                goto failed;
        local->amem = ioremap(req.Base, req.Size);
@@ -793,7 +784,6 @@ static void ray_release(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
        ray_dev_t *local = netdev_priv(dev);
-       int i;
 
        dev_dbg(&link->dev, "ray_release\n");
 
@@ -802,13 +792,6 @@ static void ray_release(struct pcmcia_device *link)
        iounmap(local->sram);
        iounmap(local->rmem);
        iounmap(local->amem);
-       /* Do bother checking to see if these succeed or not */
-       i = pcmcia_release_window(link, local->amem_handle);
-       if (i != 0)
-               dev_dbg(&link->dev, "ReleaseWindow(local->amem) ret = %x\n", i);
-       i = pcmcia_release_window(link, local->rmem_handle);
-       if (i != 0)
-               dev_dbg(&link->dev, "ReleaseWindow(local->rmem) ret = %x\n", i);
        pcmcia_disable_device(link);
 
        dev_dbg(&link->dev, "ray_release ending\n");
index 376c6b964a9ce31f652fce6524f944d2ee2e3d55..a1cc2d498a1c01bd19b0174d1497d8bd0c0c8a8b 100644 (file)
@@ -48,7 +48,6 @@
 
 #include <net/iw_handler.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 static int wl3501_config(struct pcmcia_device *link);
 static void wl3501_release(struct pcmcia_device *link);
 
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card configuration
- * database.
- */
-static dev_info_t wl3501_dev_info = "wl3501_cs";
-
 static const struct {
        int reg_domain;
        int min, max, deflt;
@@ -1421,7 +1413,7 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
 
 static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       strlcpy(info->driver, wl3501_dev_info, sizeof(info->driver));
+       strlcpy(info->driver, "wl3501_cs", sizeof(info->driver));
 }
 
 static const struct ethtool_ops ops = {
@@ -1892,9 +1884,8 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
        struct wl3501_card *this;
 
        /* The io structure describes IO port mapping */
-       p_dev->io.NumPorts1     = 16;
-       p_dev->io.Attributes1   = IO_DATA_PATH_WIDTH_8;
-       p_dev->io.IOAddrLines   = 5;
+       p_dev->resource[0]->end = 16;
+       p_dev->resource[0]->flags       = IO_DATA_PATH_WIDTH_8;
 
        /* General socket configuration */
        p_dev->conf.Attributes  = CONF_ENABLE_IRQ;
@@ -1940,13 +1931,14 @@ static int wl3501_config(struct pcmcia_device *link)
        /* Try allocating IO ports.  This tries a few fixed addresses.  If you
         * want, you can also read the card's config table to pick addresses --
         * see the serial driver for an example. */
+       link->io_lines = 5;
 
        for (j = 0x280; j < 0x400; j += 0x20) {
                /* The '^0x300' is so that we probe 0x300-0x3ff first, then
                 * 0x200-0x2ff, and so on, because this seems safer */
-               link->io.BasePort1 = j;
-               link->io.BasePort2 = link->io.BasePort1 + 0x10;
-               i = pcmcia_request_io(link, &link->io);
+               link->resource[0]->start = j;
+               link->resource[1]->start = link->resource[0]->start + 0x10;
+               i = pcmcia_request_io(link);
                if (i == 0)
                        break;
        }
@@ -1968,7 +1960,7 @@ static int wl3501_config(struct pcmcia_device *link)
                goto failed;
 
        dev->irq = link->irq;
-       dev->base_addr = link->io.BasePort1;
+       dev->base_addr = link->resource[0]->start;
        SET_NETDEV_DEV(dev, &link->dev);
        if (register_netdev(dev)) {
                printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
index d04c5b262050a9aefef0f48cde2bfa2f700510a7..b2c2f391b29db5e025e94381e8d5f97438ff1fc8 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/skbuff.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-
+#include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #include <linux/of_mdio.h>
index 7cecc8fea9bd799ffd37e7361c7636cbe3bd69f1..6acbff389ab66c54e12f80a1831fedc41475de87 100644 (file)
@@ -1,35 +1,61 @@
-config OF_FLATTREE
+config DTC
+       bool
+
+config OF
        bool
+
+menu "Flattened Device Tree and Open Firmware support"
        depends on OF
 
+config PROC_DEVICETREE
+       bool "Support for device tree in /proc"
+       depends on PROC_FS && !SPARC
+       help
+         This option adds a device-tree directory under /proc which contains
+         an image of the device tree that the kernel copies from Open
+         Firmware or other boot firmware. If unsure, say Y here.
+
+config OF_FLATTREE
+       bool
+       select DTC
+
 config OF_DYNAMIC
        def_bool y
-       depends on OF && PPC_OF
+       depends on PPC_OF
+
+config OF_ADDRESS
+       def_bool y
+       depends on !SPARC
+
+config OF_IRQ
+       def_bool y
+       depends on !SPARC
 
 config OF_DEVICE
        def_bool y
-       depends on OF && (SPARC || PPC_OF || MICROBLAZE)
 
 config OF_GPIO
        def_bool y
-       depends on OF && (PPC_OF || MICROBLAZE) && GPIOLIB
+       depends on GPIOLIB && !SPARC
        help
          OpenFirmware GPIO accessors
 
 config OF_I2C
        def_tristate I2C
-       depends on (PPC_OF || MICROBLAZE) && I2C
+       depends on I2C && !SPARC
        help
          OpenFirmware I2C accessors
 
 config OF_SPI
        def_tristate SPI
-       depends on OF && (PPC_OF || MICROBLAZE) && SPI
+       depends on SPI && !SPARC
        help
          OpenFirmware SPI accessors
 
 config OF_MDIO
        def_tristate PHYLIB
-       depends on OF && PHYLIB
+       depends on PHYLIB
        help
          OpenFirmware MDIO bus (Ethernet PHY) accessors
+
+endmenu # OF
index f232cc98ce00904e9b655c0fd51b6dd5fa3028d4..0052c405463acfe1d692aaf4dadf22dc455fc771 100644 (file)
@@ -1,5 +1,7 @@
 obj-y = base.o
 obj-$(CONFIG_OF_FLATTREE) += fdt.o
+obj-$(CONFIG_OF_ADDRESS)  += address.o
+obj-$(CONFIG_OF_IRQ)    += irq.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
 obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)   += of_i2c.o
diff --git a/drivers/of/address.c b/drivers/of/address.c
new file mode 100644 (file)
index 0000000..fcadb72
--- /dev/null
@@ -0,0 +1,595 @@
+
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/pci_regs.h>
+#include <linux/string.h>
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS      4
+#define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
+                       (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+                                   u64 size, unsigned int flags,
+                                   struct resource *r);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const u32 *addr, int na)
+{
+       printk(KERN_DEBUG "%s", s);
+       while (na--)
+               printk(" %08x", be32_to_cpu(*(addr++)));
+       printk("\n");
+}
+#else
+static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+       const char      *name;
+       const char      *addresses;
+       int             (*match)(struct device_node *parent);
+       void            (*count_cells)(struct device_node *child,
+                                      int *addrc, int *sizec);
+       u64             (*map)(u32 *addr, const u32 *range,
+                               int na, int ns, int pna);
+       int             (*translate)(u32 *addr, u64 offset, int na);
+       unsigned int    (*get_flags)(const u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+                                      int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = of_n_addr_cells(dev);
+       if (sizec)
+               *sizec = of_n_size_cells(dev);
+}
+
+static u64 of_bus_default_map(u32 *addr, const u32 *range,
+               int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       cp = of_read_number(range, na);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr, na);
+
+       pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
+                (unsigned long long)cp, (unsigned long long)s,
+                (unsigned long long)da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+       u64 a = of_read_number(addr, na);
+       memset(addr, 0, na * 4);
+       a += offset;
+       if (na > 1)
+               addr[na - 2] = cpu_to_be32(a >> 32);
+       addr[na - 1] = cpu_to_be32(a & 0xffffffffu);
+
+       return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const u32 *addr)
+{
+       return IORESOURCE_MEM;
+}
+
+#ifdef CONFIG_PCI
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+       /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
+       return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 3;
+       if (sizec)
+               *sizec = 2;
+}
+
+static unsigned int of_bus_pci_get_flags(const u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       switch((w >> 24) & 0x03) {
+       case 0x01:
+               flags |= IORESOURCE_IO;
+               break;
+       case 0x02: /* 32 bits */
+       case 0x03: /* 64 bits */
+               flags |= IORESOURCE_MEM;
+               break;
+       }
+       if (w & 0x40000000)
+               flags |= IORESOURCE_PREFETCH;
+       return flags;
+}
+
+static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+       unsigned int af, rf;
+
+       af = of_bus_pci_get_flags(addr);
+       rf = of_bus_pci_get_flags(range);
+
+       /* Check address type match */
+       if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_number(range + 1, na - 1);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr + 1, na - 1);
+
+       pr_debug("OF: PCI map, cp=%llx, s=%llx, da=%llx\n",
+                (unsigned long long)cp, (unsigned long long)s,
+                (unsigned long long)da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+                       unsigned int *flags)
+{
+       const u32 *prop;
+       unsigned int psize;
+       struct device_node *parent;
+       struct of_bus *bus;
+       int onesize, i, na, ns;
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               return NULL;
+       bus = of_match_bus(parent);
+       if (strcmp(bus->name, "pci")) {
+               of_node_put(parent);
+               return NULL;
+       }
+       bus->count_cells(dev, &na, &ns);
+       of_node_put(parent);
+       if (!OF_CHECK_COUNTS(na, ns))
+               return NULL;
+
+       /* Get "reg" or "assigned-addresses" property */
+       prop = of_get_property(dev, bus->addresses, &psize);
+       if (prop == NULL)
+               return NULL;
+       psize /= 4;
+
+       onesize = na + ns;
+       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) {
+               u32 val = be32_to_cpu(prop[0]);
+               if ((val & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
+                       if (size)
+                               *size = of_read_number(prop + na, ns);
+                       if (flags)
+                               *flags = bus->get_flags(prop);
+                       return prop;
+               }
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_pci_address);
+
+int of_pci_address_to_resource(struct device_node *dev, int bar,
+                              struct resource *r)
+{
+       const u32       *addrp;
+       u64             size;
+       unsigned int    flags;
+
+       addrp = of_get_pci_address(dev, bar, &size, &flags);
+       if (addrp == NULL)
+               return -EINVAL;
+       return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+#endif /* CONFIG_PCI */
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+       return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 2;
+       if (sizec)
+               *sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       /* Check address type match */
+       if ((addr[0] ^ range[0]) & 0x00000001)
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_number(range + 1, na - 1);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr + 1, na - 1);
+
+       pr_debug("OF: ISA map, cp=%llx, s=%llx, da=%llx\n",
+                (unsigned long long)cp, (unsigned long long)s,
+                (unsigned long long)da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_isa_get_flags(const u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       if (w & 1)
+               flags |= IORESOURCE_IO;
+       else
+               flags |= IORESOURCE_MEM;
+       return flags;
+}
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+#ifdef CONFIG_PCI
+       /* PCI */
+       {
+               .name = "pci",
+               .addresses = "assigned-addresses",
+               .match = of_bus_pci_match,
+               .count_cells = of_bus_pci_count_cells,
+               .map = of_bus_pci_map,
+               .translate = of_bus_pci_translate,
+               .get_flags = of_bus_pci_get_flags,
+       },
+#endif /* CONFIG_PCI */
+       /* ISA */
+       {
+               .name = "isa",
+               .addresses = "reg",
+               .match = of_bus_isa_match,
+               .count_cells = of_bus_isa_count_cells,
+               .map = of_bus_isa_map,
+               .translate = of_bus_isa_translate,
+               .get_flags = of_bus_isa_get_flags,
+       },
+       /* Default */
+       {
+               .name = "default",
+               .addresses = "reg",
+               .match = NULL,
+               .count_cells = of_bus_default_count_cells,
+               .map = of_bus_default_map,
+               .translate = of_bus_default_translate,
+               .get_flags = of_bus_default_get_flags,
+       },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+               if (!of_busses[i].match || of_busses[i].match(np))
+                       return &of_busses[i];
+       BUG();
+       return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+                           struct of_bus *pbus, u32 *addr,
+                           int na, int ns, int pna, const char *rprop)
+{
+       const u32 *ranges;
+       unsigned int rlen;
+       int rone;
+       u64 offset = OF_BAD_ADDR;
+
+       /* Normally, an absence of a "ranges" property means we are
+        * crossing a non-translatable boundary, and thus the addresses
+        * below the current not cannot be converted to CPU physical ones.
+        * Unfortunately, while this is very clear in the spec, it's not
+        * what Apple understood, and they do have things like /uni-n or
+        * /ht nodes with no "ranges" property and a lot of perfectly
+        * useable mapped devices below them. Thus we treat the absence of
+        * "ranges" as equivalent to an empty "ranges" property which means
+        * a 1:1 translation at that level. It's up to the caller not to try
+        * to translate addresses that aren't supposed to be translated in
+        * the first place. --BenH.
+        *
+        * As far as we know, this damage only exists on Apple machines, so
+        * This code is only enabled on powerpc. --gcl
+        */
+       ranges = of_get_property(parent, rprop, &rlen);
+#if !defined(CONFIG_PPC)
+       if (ranges == NULL) {
+               pr_err("OF: no ranges; cannot translate\n");
+               return 1;
+       }
+#endif /* !defined(CONFIG_PPC) */
+       if (ranges == NULL || rlen == 0) {
+               offset = of_read_number(addr, na);
+               memset(addr, 0, pna * 4);
+               pr_debug("OF: empty ranges; 1:1 translation\n");
+               goto finish;
+       }
+
+       pr_debug("OF: walking ranges...\n");
+
+       /* Now walk through the ranges */
+       rlen /= 4;
+       rone = na + pna + ns;
+       for (; rlen >= rone; rlen -= rone, ranges += rone) {
+               offset = bus->map(addr, ranges, na, ns, pna);
+               if (offset != OF_BAD_ADDR)
+                       break;
+       }
+       if (offset == OF_BAD_ADDR) {
+               pr_debug("OF: not found !\n");
+               return 1;
+       }
+       memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+       of_dump_addr("OF: parent translation for:", addr, pna);
+       pr_debug("OF: with offset: %llx\n", (unsigned long long)offset);
+
+       /* Translate it into parent bus space */
+       return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
+                          const char *rprop)
+{
+       struct device_node *parent = NULL;
+       struct of_bus *bus, *pbus;
+       u32 addr[OF_MAX_ADDR_CELLS];
+       int na, ns, pna, pns;
+       u64 result = OF_BAD_ADDR;
+
+       pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+       /* Increase refcount at current level */
+       of_node_get(dev);
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               goto bail;
+       bus = of_match_bus(parent);
+
+       /* Cound address cells & copy address locally */
+       bus->count_cells(dev, &na, &ns);
+       if (!OF_CHECK_COUNTS(na, ns)) {
+               printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+                      dev->full_name);
+               goto bail;
+       }
+       memcpy(addr, in_addr, na * 4);
+
+       pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+           bus->name, na, ns, parent->full_name);
+       of_dump_addr("OF: translating address:", addr, na);
+
+       /* Translate */
+       for (;;) {
+               /* Switch to parent bus */
+               of_node_put(dev);
+               dev = parent;
+               parent = of_get_parent(dev);
+
+               /* If root, we have finished */
+               if (parent == NULL) {
+                       pr_debug("OF: reached root node\n");
+                       result = of_read_number(addr, na);
+                       break;
+               }
+
+               /* Get new parent bus and counts */
+               pbus = of_match_bus(parent);
+               pbus->count_cells(dev, &pna, &pns);
+               if (!OF_CHECK_COUNTS(pna, pns)) {
+                       printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+                              dev->full_name);
+                       break;
+               }
+
+               pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+                   pbus->name, pna, pns, parent->full_name);
+
+               /* Apply bus translation */
+               if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+                       break;
+
+               /* Complete the move up one level */
+               na = pna;
+               ns = pns;
+               bus = pbus;
+
+               of_dump_addr("OF: one level translation:", addr, na);
+       }
+ bail:
+       of_node_put(parent);
+       of_node_put(dev);
+
+       return result;
+}
+
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+{
+       return __of_translate_address(dev, in_addr, "ranges");
+}
+EXPORT_SYMBOL(of_translate_address);
+
+u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
+{
+       return __of_translate_address(dev, in_addr, "dma-ranges");
+}
+EXPORT_SYMBOL(of_translate_dma_address);
+
+const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+                   unsigned int *flags)
+{
+       const u32 *prop;
+       unsigned int psize;
+       struct device_node *parent;
+       struct of_bus *bus;
+       int onesize, i, na, ns;
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               return NULL;
+       bus = of_match_bus(parent);
+       bus->count_cells(dev, &na, &ns);
+       of_node_put(parent);
+       if (!OF_CHECK_COUNTS(na, ns))
+               return NULL;
+
+       /* Get "reg" or "assigned-addresses" property */
+       prop = of_get_property(dev, bus->addresses, &psize);
+       if (prop == NULL)
+               return NULL;
+       psize /= 4;
+
+       onesize = na + ns;
+       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+               if (i == index) {
+                       if (size)
+                               *size = of_read_number(prop + na, ns);
+                       if (flags)
+                               *flags = bus->get_flags(prop);
+                       return prop;
+               }
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+                                   u64 size, unsigned int flags,
+                                   struct resource *r)
+{
+       u64 taddr;
+
+       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+               return -EINVAL;
+       taddr = of_translate_address(dev, addrp);
+       if (taddr == OF_BAD_ADDR)
+               return -EINVAL;
+       memset(r, 0, sizeof(struct resource));
+       if (flags & IORESOURCE_IO) {
+               unsigned long port;
+               port = pci_address_to_pio(taddr);
+               if (port == (unsigned long)-1)
+                       return -EINVAL;
+               r->start = port;
+               r->end = port + size - 1;
+       } else {
+               r->start = taddr;
+               r->end = taddr + size - 1;
+       }
+       r->flags = flags;
+       r->name = dev->full_name;
+       return 0;
+}
+
+/**
+ * of_address_to_resource - Translate device tree address and return as resource
+ *
+ * Note that if your address is a PIO address, the conversion will fail if
+ * the physical address can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early or it
+ * can't be matched to any host bridge IO space
+ */
+int of_address_to_resource(struct device_node *dev, int index,
+                          struct resource *r)
+{
+       const u32       *addrp;
+       u64             size;
+       unsigned int    flags;
+
+       addrp = of_get_address(dev, index, &size, &flags);
+       if (addrp == NULL)
+               return -EINVAL;
+       return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device:    the device whose io range will be mapped
+ * @index:     index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+       struct resource res;
+
+       if (of_address_to_resource(np, index, &res))
+               return NULL;
+
+       return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
index b5ad9740d8b21a6eb6b3e3f3bd1586e8a5645426..aa805250de765e5e1c9531e0b9cbfbb6143683f2 100644 (file)
@@ -544,75 +544,29 @@ struct device_node *of_find_matching_node(struct device_node *from,
 }
 EXPORT_SYMBOL(of_find_matching_node);
 
-/**
- * of_modalias_table: Table of explicit compatible ==> modalias mappings
- *
- * This table allows particulare compatible property values to be mapped
- * to modalias strings.  This is useful for busses which do not directly
- * understand the OF device tree but are populated based on data contained
- * within the device tree.  SPI and I2C are the two current users of this
- * table.
- *
- * In most cases, devices do not need to be listed in this table because
- * the modalias value can be derived directly from the compatible table.
- * However, if for any reason a value cannot be derived, then this table
- * provides a method to override the implicit derivation.
- *
- * At the moment, a single table is used for all bus types because it is
- * assumed that the data size is small and that the compatible values
- * should already be distinct enough to differentiate between SPI, I2C
- * and other devices.
- */
-struct of_modalias_table {
-       char *of_device;
-       char *modalias;
-};
-static struct of_modalias_table of_modalias_table[] = {
-       { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
-       { "mmc-spi-slot", "mmc_spi" },
-};
-
 /**
  * of_modalias_node - Lookup appropriate modalias for a device node
  * @node:      pointer to a device tree node
  * @modalias:  Pointer to buffer that modalias value will be copied into
  * @len:       Length of modalias value
  *
- * Based on the value of the compatible property, this routine will determine
- * an appropriate modalias value for a particular device tree node.  Two
- * separate methods are attempted to derive a modalias value.
+ * Based on the value of the compatible property, this routine will attempt
+ * to choose an appropriate modalias value for a particular device tree node.
+ * It does this by stripping the manufacturer prefix (as delimited by a ',')
+ * from the first entry in the compatible list property.
  *
- * First method is to lookup the compatible value in of_modalias_table.
- * Second is to strip off the manufacturer prefix from the first
- * compatible entry and use the remainder as modalias
- *
- * This routine returns 0 on success
+ * This routine returns 0 on success, <0 on failure.
  */
 int of_modalias_node(struct device_node *node, char *modalias, int len)
 {
-       int i, cplen;
-       const char *compatible;
-       const char *p;
-
-       /* 1. search for exception list entry */
-       for (i = 0; i < ARRAY_SIZE(of_modalias_table); i++) {
-               compatible = of_modalias_table[i].of_device;
-               if (!of_device_is_compatible(node, compatible))
-                       continue;
-               strlcpy(modalias, of_modalias_table[i].modalias, len);
-               return 0;
-       }
+       const char *compatible, *p;
+       int cplen;
 
        compatible = of_get_property(node, "compatible", &cplen);
-       if (!compatible)
+       if (!compatible || strlen(compatible) > cplen)
                return -ENODEV;
-
-       /* 2. take first compatible entry and strip manufacturer */
        p = strchr(compatible, ',');
-       if (!p)
-               return -ENODEV;
-       p++;
-       strlcpy(modalias, p, len);
+       strlcpy(modalias, p ? p + 1 : compatible, len);
        return 0;
 }
 EXPORT_SYMBOL_GPL(of_modalias_node);
@@ -651,14 +605,14 @@ EXPORT_SYMBOL(of_find_node_by_phandle);
 struct device_node *
 of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
 {
-       const phandle *phandle;
+       const __be32 *phandle;
        int size;
 
        phandle = of_get_property(np, phandle_name, &size);
        if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
                return NULL;
 
-       return of_find_node_by_phandle(phandle[index]);
+       return of_find_node_by_phandle(be32_to_cpup(phandle + index));
 }
 EXPORT_SYMBOL(of_parse_phandle);
 
@@ -714,16 +668,16 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
 
        while (list < list_end) {
                const __be32 *cells;
-               const phandle *phandle;
+               phandle phandle;
 
-               phandle = list++;
+               phandle = be32_to_cpup(list++);
                args = list;
 
                /* one cell hole in the list = <>; */
-               if (!*phandle)
+               if (!phandle)
                        goto next;
 
-               node = of_find_node_by_phandle(*phandle);
+               node = of_find_node_by_phandle(phandle);
                if (!node) {
                        pr_debug("%s: could not find phandle\n",
                                 np->full_name);
index 7d18f8e0b013199c2e1bfd886b8dd6b93c639f7e..0d8a0644f54018810129479244c975be57f2c34c 100644 (file)
 const struct of_device_id *of_match_device(const struct of_device_id *matches,
                                           const struct device *dev)
 {
-       if (!dev->of_node)
+       if ((!matches) || (!dev->of_node))
                return NULL;
        return of_match_node(matches, dev->of_node);
 }
 EXPORT_SYMBOL(of_match_device);
 
-struct of_device *of_dev_get(struct of_device *dev)
+struct platform_device *of_dev_get(struct platform_device *dev)
 {
        struct device *tmp;
 
@@ -34,13 +34,13 @@ struct of_device *of_dev_get(struct of_device *dev)
                return NULL;
        tmp = get_device(&dev->dev);
        if (tmp)
-               return to_of_device(tmp);
+               return to_platform_device(tmp);
        else
                return NULL;
 }
 EXPORT_SYMBOL(of_dev_get);
 
-void of_dev_put(struct of_device *dev)
+void of_dev_put(struct platform_device *dev)
 {
        if (dev)
                put_device(&dev->dev);
@@ -50,28 +50,25 @@ EXPORT_SYMBOL(of_dev_put);
 static ssize_t devspec_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
-       struct of_device *ofdev;
+       struct platform_device *ofdev;
 
-       ofdev = to_of_device(dev);
+       ofdev = to_platform_device(dev);
        return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name);
 }
 
 static ssize_t name_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
-       struct of_device *ofdev;
+       struct platform_device *ofdev;
 
-       ofdev = to_of_device(dev);
+       ofdev = to_platform_device(dev);
        return sprintf(buf, "%s\n", ofdev->dev.of_node->name);
 }
 
 static ssize_t modalias_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
-       struct of_device *ofdev = to_of_device(dev);
-       ssize_t len = 0;
-
-       len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2);
+       ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2);
        buf[len] = '\n';
        buf[len+1] = 0;
        return len+1;
@@ -93,20 +90,25 @@ struct device_attribute of_platform_device_attrs[] = {
  */
 void of_release_dev(struct device *dev)
 {
-       struct of_device *ofdev;
+       struct platform_device *ofdev;
 
-       ofdev = to_of_device(dev);
+       ofdev = to_platform_device(dev);
        of_node_put(ofdev->dev.of_node);
        kfree(ofdev);
 }
 EXPORT_SYMBOL(of_release_dev);
 
-int of_device_register(struct of_device *ofdev)
+int of_device_register(struct platform_device *ofdev)
 {
        BUG_ON(ofdev->dev.of_node == NULL);
 
        device_initialize(&ofdev->dev);
 
+       /* name and id have to be set so that the platform bus doesn't get
+        * confused on matching */
+       ofdev->name = dev_name(&ofdev->dev);
+       ofdev->id = -1;
+
        /* device_add will assume that this device is on the same node as
         * the parent. If there is no parent defined, set the node
         * explicitly */
@@ -117,25 +119,24 @@ int of_device_register(struct of_device *ofdev)
 }
 EXPORT_SYMBOL(of_device_register);
 
-void of_device_unregister(struct of_device *ofdev)
+void of_device_unregister(struct platform_device *ofdev)
 {
        device_unregister(&ofdev->dev);
 }
 EXPORT_SYMBOL(of_device_unregister);
 
-ssize_t of_device_get_modalias(struct of_device *ofdev,
-                               char *str, ssize_t len)
+ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 {
        const char *compat;
        int cplen, i;
        ssize_t tsize, csize, repend;
 
        /* Name & Type */
-       csize = snprintf(str, len, "of:N%sT%s", ofdev->dev.of_node->name,
-                        ofdev->dev.of_node->type);
+       csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name,
+                        dev->of_node->type);
 
        /* Get compatible property if any */
-       compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
+       compat = of_get_property(dev->of_node, "compatible", &cplen);
        if (!compat)
                return csize;
 
@@ -170,3 +171,51 @@ ssize_t of_device_get_modalias(struct of_device *ofdev,
 
        return tsize;
 }
+
+/**
+ * of_device_uevent - Display OF related uevent information
+ */
+int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       const char *compat;
+       int seen = 0, cplen, sl;
+
+       if ((!dev) || (!dev->of_node))
+               return -ENODEV;
+
+       if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name))
+               return -ENOMEM;
+
+       if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type))
+               return -ENOMEM;
+
+       /* Since the compatible field can contain pretty much anything
+        * it's not really legal to split it out with commas. We split it
+        * up using a number of environment variables instead. */
+
+       compat = of_get_property(dev->of_node, "compatible", &cplen);
+       while (compat && *compat && cplen > 0) {
+               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
+                       return -ENOMEM;
+
+               sl = strlen(compat) + 1;
+               compat += sl;
+               cplen -= sl;
+               seen++;
+       }
+
+       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
+               return -ENOMEM;
+
+       /* modalias is trickier, we add it in 2 steps */
+       if (add_uevent_var(env, "MODALIAS="))
+               return -ENOMEM;
+
+       sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
+                                   sizeof(env->buf) - env->buflen);
+       if (sl >= (sizeof(env->buf) - env->buflen))
+               return -ENOMEM;
+       env->buflen += sl;
+
+       return 0;
+}
index b6987bba85566d6df8f3afdd8187599cb3618758..65da5aec7552c70162b6646ded99a32c72797b9d 100644 (file)
@@ -69,9 +69,9 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
                        u32 sz = be32_to_cpup((__be32 *)p);
                        p += 8;
                        if (be32_to_cpu(initial_boot_params->version) < 0x10)
-                               p = _ALIGN(p, sz >= 8 ? 8 : 4);
+                               p = ALIGN(p, sz >= 8 ? 8 : 4);
                        p += sz;
-                       p = _ALIGN(p, 4);
+                       p = ALIGN(p, 4);
                        continue;
                }
                if (tag != OF_DT_BEGIN_NODE) {
@@ -80,7 +80,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
                }
                depth++;
                pathp = (char *)p;
-               p = _ALIGN(p + strlen(pathp) + 1, 4);
+               p = ALIGN(p + strlen(pathp) + 1, 4);
                if ((*pathp) == '/') {
                        char *lp, *np;
                        for (lp = NULL, np = pathp; *np; np++)
@@ -109,7 +109,7 @@ unsigned long __init of_get_flat_dt_root(void)
                p += 4;
        BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
        p += 4;
-       return _ALIGN(p + strlen((char *)p) + 1, 4);
+       return ALIGN(p + strlen((char *)p) + 1, 4);
 }
 
 /**
@@ -138,7 +138,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
                noff = be32_to_cpup((__be32 *)(p + 4));
                p += 8;
                if (be32_to_cpu(initial_boot_params->version) < 0x10)
-                       p = _ALIGN(p, sz >= 8 ? 8 : 4);
+                       p = ALIGN(p, sz >= 8 ? 8 : 4);
 
                nstr = find_flat_dt_string(noff);
                if (nstr == NULL) {
@@ -151,7 +151,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
                        return (void *)p;
                }
                p += sz;
-               p = _ALIGN(p, 4);
+               p = ALIGN(p, 4);
        } while (1);
 }
 
@@ -169,7 +169,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
        if (cp == NULL)
                return 0;
        while (cplen > 0) {
-               if (strncasecmp(cp, compat, strlen(compat)) == 0)
+               if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
                        return 1;
                l = strlen(cp) + 1;
                cp += l;
@@ -184,7 +184,7 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 {
        void *res;
 
-       *mem = _ALIGN(*mem, align);
+       *mem = ALIGN(*mem, align);
        res = (void *)*mem;
        *mem += size;
 
@@ -220,7 +220,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
        *p += 4;
        pathp = (char *)*p;
        l = allocl = strlen(pathp) + 1;
-       *p = _ALIGN(*p + l, 4);
+       *p = ALIGN(*p + l, 4);
 
        /* version 0x10 has a more compact unit name here instead of the full
         * path. we accumulate the full path size using "fpsize", we'll rebuild
@@ -299,7 +299,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
                noff = be32_to_cpup((__be32 *)((*p) + 4));
                *p += 8;
                if (be32_to_cpu(initial_boot_params->version) < 0x10)
-                       *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+                       *p = ALIGN(*p, sz >= 8 ? 8 : 4);
 
                pname = find_flat_dt_string(noff);
                if (pname == NULL) {
@@ -320,20 +320,20 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
                        if ((strcmp(pname, "phandle") == 0) ||
                            (strcmp(pname, "linux,phandle") == 0)) {
                                if (np->phandle == 0)
-                                       np->phandle = *((u32 *)*p);
+                                       np->phandle = be32_to_cpup((__be32*)*p);
                        }
                        /* And we process the "ibm,phandle" property
                         * used in pSeries dynamic device tree
                         * stuff */
                        if (strcmp(pname, "ibm,phandle") == 0)
-                               np->phandle = *((u32 *)*p);
+                               np->phandle = be32_to_cpup((__be32 *)*p);
                        pp->name = pname;
                        pp->length = sz;
                        pp->value = (void *)*p;
                        *prev_pp = pp;
                        prev_pp = &pp->next;
                }
-               *p = _ALIGN((*p) + sz, 4);
+               *p = ALIGN((*p) + sz, 4);
        }
        /* with version 0x10 we may not have the name property, recreate
         * it here from the unit name if absent
index a1b31a4abae4479e647e3e1a5eacd314139fbad1..905960338fb21d905a21153b7e8bcc3832ab691a 100644 (file)
  * (at your option) any later version.
  */
 
-#include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <linux/slab.h>
+#include <linux/of_address.h>
 #include <linux/of_gpio.h>
-#include <asm/prom.h>
+#include <linux/slab.h>
 
 /**
  * of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API
@@ -33,32 +34,32 @@ int of_get_gpio_flags(struct device_node *np, int index,
                      enum of_gpio_flags *flags)
 {
        int ret;
-       struct device_node *gc;
-       struct of_gpio_chip *of_gc = NULL;
+       struct device_node *gpio_np;
+       struct gpio_chip *gc;
        int size;
        const void *gpio_spec;
        const __be32 *gpio_cells;
 
        ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
-                                         &gc, &gpio_spec);
+                                         &gpio_np, &gpio_spec);
        if (ret) {
                pr_debug("%s: can't parse gpios property\n", __func__);
                goto err0;
        }
 
-       of_gc = gc->data;
-       if (!of_gc) {
+       gc = of_node_to_gpiochip(gpio_np);
+       if (!gc) {
                pr_debug("%s: gpio controller %s isn't registered\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                ret = -ENODEV;
                goto err1;
        }
 
-       gpio_cells = of_get_property(gc, "#gpio-cells", &size);
+       gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size);
        if (!gpio_cells || size != sizeof(*gpio_cells) ||
-                       be32_to_cpup(gpio_cells) != of_gc->gpio_cells) {
+                       be32_to_cpup(gpio_cells) != gc->of_gpio_n_cells) {
                pr_debug("%s: wrong #gpio-cells for %s\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                ret = -EINVAL;
                goto err1;
        }
@@ -67,13 +68,13 @@ int of_get_gpio_flags(struct device_node *np, int index,
        if (flags)
                *flags = 0;
 
-       ret = of_gc->xlate(of_gc, np, gpio_spec, flags);
+       ret = gc->of_xlate(gc, np, gpio_spec, flags);
        if (ret < 0)
                goto err1;
 
-       ret += of_gc->gc.base;
+       ret += gc->base;
 err1:
-       of_node_put(gc);
+       of_node_put(gpio_np);
 err0:
        pr_debug("%s exited with status %d\n", __func__, ret);
        return ret;
@@ -116,7 +117,7 @@ EXPORT_SYMBOL(of_gpio_count);
 
 /**
  * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
- * @of_gc:     pointer to the of_gpio_chip structure
+ * @gc:                pointer to the gpio_chip structure
  * @np:                device node of the GPIO chip
  * @gpio_spec: gpio specifier as found in the device tree
  * @flags:     a flags pointer to fill in
@@ -125,8 +126,8 @@ EXPORT_SYMBOL(of_gpio_count);
  * gpio chips. This function performs only one sanity check: whether gpio
  * is less than ngpios (that is specified in the gpio_chip).
  */
-int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
-                        const void *gpio_spec, enum of_gpio_flags *flags)
+static int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np,
+                               const void *gpio_spec, u32 *flags)
 {
        const __be32 *gpio = gpio_spec;
        const u32 n = be32_to_cpup(gpio);
@@ -137,12 +138,12 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
         * number and the flags from a single gpio cell -- this is possible,
         * but not recommended).
         */
-       if (of_gc->gpio_cells < 2) {
+       if (gc->of_gpio_n_cells < 2) {
                WARN_ON(1);
                return -EINVAL;
        }
 
-       if (n > of_gc->gc.ngpio)
+       if (n > gc->ngpio)
                return -EINVAL;
 
        if (flags)
@@ -150,7 +151,6 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
 
        return n;
 }
-EXPORT_SYMBOL(of_gpio_simple_xlate);
 
 /**
  * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank)
@@ -161,10 +161,8 @@ EXPORT_SYMBOL(of_gpio_simple_xlate);
  *
  * 1) In the gpio_chip structure:
  *    - all the callbacks
- *
- * 2) In the of_gpio_chip structure:
- *    - gpio_cells
- *    - xlate callback (optional)
+ *    - of_gpio_n_cells
+ *    - of_xlate callback (optional)
  *
  * 3) In the of_mm_gpio_chip structure:
  *    - save_regs callback (optional)
@@ -177,8 +175,7 @@ int of_mm_gpiochip_add(struct device_node *np,
                       struct of_mm_gpio_chip *mm_gc)
 {
        int ret = -ENOMEM;
-       struct of_gpio_chip *of_gc = &mm_gc->of_gc;
-       struct gpio_chip *gc = &of_gc->gc;
+       struct gpio_chip *gc = &mm_gc->gc;
 
        gc->label = kstrdup(np->full_name, GFP_KERNEL);
        if (!gc->label)
@@ -190,26 +187,19 @@ int of_mm_gpiochip_add(struct device_node *np,
 
        gc->base = -1;
 
-       if (!of_gc->xlate)
-               of_gc->xlate = of_gpio_simple_xlate;
-
        if (mm_gc->save_regs)
                mm_gc->save_regs(mm_gc);
 
-       np->data = of_gc;
+       mm_gc->gc.of_node = np;
 
        ret = gpiochip_add(gc);
        if (ret)
                goto err2;
 
-       /* We don't want to lose the node and its ->data */
-       of_node_get(np);
-
        pr_debug("%s: registered as generic GPIO chip, base is %d\n",
                 np->full_name, gc->base);
        return 0;
 err2:
-       np->data = NULL;
        iounmap(mm_gc->regs);
 err1:
        kfree(gc->label);
@@ -219,3 +209,36 @@ err0:
        return ret;
 }
 EXPORT_SYMBOL(of_mm_gpiochip_add);
+
+void of_gpiochip_add(struct gpio_chip *chip)
+{
+       if ((!chip->of_node) && (chip->dev))
+               chip->of_node = chip->dev->of_node;
+
+       if (!chip->of_node)
+               return;
+
+       if (!chip->of_xlate) {
+               chip->of_gpio_n_cells = 2;
+               chip->of_xlate = of_gpio_simple_xlate;
+       }
+
+       of_node_get(chip->of_node);
+}
+
+void of_gpiochip_remove(struct gpio_chip *chip)
+{
+       if (chip->of_node)
+               of_node_put(chip->of_node);
+}
+
+/* Private function for resolving node pointer to gpio_chip */
+static int of_gpiochip_is_match(struct gpio_chip *chip, void *data)
+{
+       return chip->of_node == data;
+}
+
+struct gpio_chip *of_node_to_gpiochip(struct device_node *np)
+{
+       return gpiochip_find(np, of_gpiochip_is_match);
+}
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
new file mode 100644 (file)
index 0000000..6e595e5
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ *  Derived from arch/i386/kernel/irq.c
+ *    Copyright (C) 1992 Linus Torvalds
+ *  Adapted from arch/i386 by Gary Thomas
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
+ *    Copyright (C) 1996-2001 Cort Dougan
+ *  Adapted for Power Macintosh by Paul Mackerras
+ *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * This file contains the code used to make IRQ descriptions in the
+ * device tree to actual irq numbers on an interrupt controller
+ * driver.
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/string.h>
+
+/**
+ * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
+ * @device: Device node of the device whose interrupt is to be mapped
+ * @index: Index of the interrupt to map
+ *
+ * This function is a wrapper that chains of_irq_map_one() and
+ * irq_create_of_mapping() to make things easier to callers
+ */
+unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+{
+       struct of_irq oirq;
+
+       if (of_irq_map_one(dev, index, &oirq))
+               return NO_IRQ;
+
+       return irq_create_of_mapping(oirq.controller, oirq.specifier,
+                                    oirq.size);
+}
+EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+
+/**
+ * of_irq_find_parent - Given a device node, find its interrupt parent node
+ * @child: pointer to device node
+ *
+ * Returns a pointer to the interrupt parent node, or NULL if the interrupt
+ * parent could not be determined.
+ */
+static struct device_node *of_irq_find_parent(struct device_node *child)
+{
+       struct device_node *p;
+       const __be32 *parp;
+
+       if (!of_node_get(child))
+               return NULL;
+
+       do {
+               parp = of_get_property(child, "interrupt-parent", NULL);
+               if (parp == NULL)
+                       p = of_get_parent(child);
+               else {
+                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+                               p = of_node_get(of_irq_dflt_pic);
+                       else
+                               p = of_find_node_by_phandle(be32_to_cpup(parp));
+               }
+               of_node_put(child);
+               child = p;
+       } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+       return p;
+}
+
+/**
+ * of_irq_map_raw - Low level interrupt tree parsing
+ * @parent:    the device interrupt parent
+ * @intspec:   interrupt specifier ("interrupts" property of the device)
+ * @ointsize:   size of the passed in interrupt specifier
+ * @addr:      address specifier (start of "reg" property of the device)
+ * @out_irq:   structure of_irq filled by this function
+ *
+ * Returns 0 on success and a negative number on error
+ *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent.
+ */
+int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
+                  u32 ointsize, const __be32 *addr, struct of_irq *out_irq)
+{
+       struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+       const __be32 *tmp, *imap, *imask;
+       u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+       int imaplen, match, i;
+
+       pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+                parent->full_name, be32_to_cpup(intspec),
+                be32_to_cpup(intspec + 1), ointsize);
+
+       ipar = of_node_get(parent);
+
+       /* First get the #interrupt-cells property of the current cursor
+        * that tells us how to interpret the passed-in intspec. If there
+        * is none, we are nice and just walk up the tree
+        */
+       do {
+               tmp = of_get_property(ipar, "#interrupt-cells", NULL);
+               if (tmp != NULL) {
+                       intsize = be32_to_cpu(*tmp);
+                       break;
+               }
+               tnode = ipar;
+               ipar = of_irq_find_parent(ipar);
+               of_node_put(tnode);
+       } while (ipar);
+       if (ipar == NULL) {
+               pr_debug(" -> no parent found !\n");
+               goto fail;
+       }
+
+       pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
+
+       if (ointsize != intsize)
+               return -EINVAL;
+
+       /* Look for this #address-cells. We have to implement the old linux
+        * trick of looking for the parent here as some device-trees rely on it
+        */
+       old = of_node_get(ipar);
+       do {
+               tmp = of_get_property(old, "#address-cells", NULL);
+               tnode = of_get_parent(old);
+               of_node_put(old);
+               old = tnode;
+       } while (old && tmp == NULL);
+       of_node_put(old);
+       old = NULL;
+       addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);
+
+       pr_debug(" -> addrsize=%d\n", addrsize);
+
+       /* Now start the actual "proper" walk of the interrupt tree */
+       while (ipar != NULL) {
+               /* Now check if cursor is an interrupt-controller and if it is
+                * then we are done
+                */
+               if (of_get_property(ipar, "interrupt-controller", NULL) !=
+                               NULL) {
+                       pr_debug(" -> got it !\n");
+                       for (i = 0; i < intsize; i++)
+                               out_irq->specifier[i] =
+                                               of_read_number(intspec +i, 1);
+                       out_irq->size = intsize;
+                       out_irq->controller = ipar;
+                       of_node_put(old);
+                       return 0;
+               }
+
+               /* Now look for an interrupt-map */
+               imap = of_get_property(ipar, "interrupt-map", &imaplen);
+               /* No interrupt map, check for an interrupt parent */
+               if (imap == NULL) {
+                       pr_debug(" -> no map, getting parent\n");
+                       newpar = of_irq_find_parent(ipar);
+                       goto skiplevel;
+               }
+               imaplen /= sizeof(u32);
+
+               /* Look for a mask */
+               imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+
+               /* If we were passed no "reg" property and we attempt to parse
+                * an interrupt-map, then #address-cells must be 0.
+                * Fail if it's not.
+                */
+               if (addr == NULL && addrsize != 0) {
+                       pr_debug(" -> no reg passed in when needed !\n");
+                       goto fail;
+               }
+
+               /* Parse interrupt-map */
+               match = 0;
+               while (imaplen > (addrsize + intsize + 1) && !match) {
+                       /* Compare specifiers */
+                       match = 1;
+                       for (i = 0; i < addrsize && match; ++i) {
+                               u32 mask = imask ? imask[i] : 0xffffffffu;
+                               match = ((addr[i] ^ imap[i]) & mask) == 0;
+                       }
+                       for (; i < (addrsize + intsize) && match; ++i) {
+                               u32 mask = imask ? imask[i] : 0xffffffffu;
+                               match =
+                                  ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
+                       }
+                       imap += addrsize + intsize;
+                       imaplen -= addrsize + intsize;
+
+                       pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+
+                       /* Get the interrupt parent */
+                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+                               newpar = of_node_get(of_irq_dflt_pic);
+                       else
+                               newpar = of_find_node_by_phandle(be32_to_cpup(imap));
+                       imap++;
+                       --imaplen;
+
+                       /* Check if not found */
+                       if (newpar == NULL) {
+                               pr_debug(" -> imap parent not found !\n");
+                               goto fail;
+                       }
+
+                       /* Get #interrupt-cells and #address-cells of new
+                        * parent
+                        */
+                       tmp = of_get_property(newpar, "#interrupt-cells", NULL);
+                       if (tmp == NULL) {
+                               pr_debug(" -> parent lacks #interrupt-cells!\n");
+                               goto fail;
+                       }
+                       newintsize = be32_to_cpu(*tmp);
+                       tmp = of_get_property(newpar, "#address-cells", NULL);
+                       newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp);
+
+                       pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
+                           newintsize, newaddrsize);
+
+                       /* Check for malformed properties */
+                       if (imaplen < (newaddrsize + newintsize))
+                               goto fail;
+
+                       imap += newaddrsize + newintsize;
+                       imaplen -= newaddrsize + newintsize;
+
+                       pr_debug(" -> imaplen=%d\n", imaplen);
+               }
+               if (!match)
+                       goto fail;
+
+               of_node_put(old);
+               old = of_node_get(newpar);
+               addrsize = newaddrsize;
+               intsize = newintsize;
+               intspec = imap - intsize;
+               addr = intspec - addrsize;
+
+       skiplevel:
+               /* Iterate again with new parent */
+               pr_debug(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
+               of_node_put(ipar);
+               ipar = newpar;
+               newpar = NULL;
+       }
+ fail:
+       of_node_put(ipar);
+       of_node_put(old);
+       of_node_put(newpar);
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_raw);
+
+/**
+ * of_irq_map_one - Resolve an interrupt for a device
+ * @device: the device whose interrupt is to be resolved
+ * @index: index of the interrupt to resolve
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves an interrupt, walking the tree, for a given
+ * device-tree node. It's the high level pendant to of_irq_map_raw().
+ */
+int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
+{
+       struct device_node *p;
+       const __be32 *intspec, *tmp, *addr;
+       u32 intsize, intlen;
+       int res = -EINVAL;
+
+       pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
+
+       /* OldWorld mac stuff is "special", handle out of line */
+       if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
+               return of_irq_map_oldworld(device, index, out_irq);
+
+       /* Get the interrupts property */
+       intspec = of_get_property(device, "interrupts", &intlen);
+       if (intspec == NULL)
+               return -EINVAL;
+       intlen /= sizeof(*intspec);
+
+       pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
+
+       /* Get the reg property (if any) */
+       addr = of_get_property(device, "reg", NULL);
+
+       /* Look for the interrupt parent. */
+       p = of_irq_find_parent(device);
+       if (p == NULL)
+               return -EINVAL;
+
+       /* Get size of interrupt specifier */
+       tmp = of_get_property(p, "#interrupt-cells", NULL);
+       if (tmp == NULL)
+               goto out;
+       intsize = be32_to_cpu(*tmp);
+
+       pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
+
+       /* Check index */
+       if ((index + 1) * intsize > intlen)
+               goto out;
+
+       /* Get new specifier and map it */
+       res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+                            addr, out_irq);
+ out:
+       of_node_put(p);
+       return res;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_one);
+
+/**
+ * of_irq_to_resource - Decode a node's IRQ and return it as a resource
+ * @dev: pointer to device tree node
+ * @index: zero-based index of the irq
+ * @r: pointer to resource structure to return result into.
+ */
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+       int irq = irq_of_parse_and_map(dev, index);
+
+       /* Only dereference the resource if both the
+        * resource and the irq are valid. */
+       if (r && irq != NO_IRQ) {
+               r->start = r->end = irq;
+               r->flags = IORESOURCE_IRQ;
+               r->name = dev->full_name;
+       }
+
+       return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
index ab6522c8e4fe801fc5ae8fefb782fdc0869a77fa..0a694debd226b8dbc066789f198b2de0017c30d8 100644 (file)
 #include <linux/i2c.h>
 #include <linux/of.h>
 #include <linux/of_i2c.h>
+#include <linux/of_irq.h>
 #include <linux/module.h>
 
-void of_register_i2c_devices(struct i2c_adapter *adap,
-                            struct device_node *adap_node)
+void of_i2c_register_devices(struct i2c_adapter *adap)
 {
        void *result;
        struct device_node *node;
 
-       for_each_child_of_node(adap_node, node) {
+       /* Only register child devices if the adapter has a node pointer set */
+       if (!adap->dev.of_node)
+               return;
+
+       dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
+
+       for_each_child_of_node(adap->dev.of_node, node) {
                struct i2c_board_info info = {};
                struct dev_archdata dev_ad = {};
                const __be32 *addr;
                int len;
 
-               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0)
+               dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
+
+               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+                       dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
+                               node->full_name);
                        continue;
+               }
 
                addr = of_get_property(node, "reg", &len);
-               if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
-                       printk(KERN_ERR
-                              "of-i2c: invalid i2c device entry\n");
+               if (!addr || (len < sizeof(int))) {
+                       dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
+                               node->full_name);
                        continue;
                }
 
-               info.irq = irq_of_parse_and_map(node, 0);
-
                info.addr = be32_to_cpup(addr);
+               if (info.addr > (1 << 10) - 1) {
+                       dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
+                               info.addr, node->full_name);
+                       continue;
+               }
 
-               info.of_node = node;
+               info.irq = irq_of_parse_and_map(node, 0);
+               info.of_node = of_node_get(node);
                info.archdata = &dev_ad;
 
                request_module("%s", info.type);
 
                result = i2c_new_device(adap, &info);
                if (result == NULL) {
-                       printk(KERN_ERR
-                              "of-i2c: Failed to load driver for %s\n",
-                              info.type);
+                       dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
+                               node->full_name);
+                       of_node_put(node);
                        irq_dispose_mapping(info.irq);
                        continue;
                }
-
-               /*
-                * Get the node to not lose the dev_archdata->of_node.
-                * Currently there is no way to put it back, as well as no
-                * of_unregister_i2c_devices() call.
-                */
-               of_node_get(node);
        }
 }
-EXPORT_SYMBOL(of_register_i2c_devices);
+EXPORT_SYMBOL(of_i2c_register_devices);
 
 static int of_dev_node_match(struct device *dev, void *data)
 {
index 42a6715f8e84287ed2eef40382dc7bc89e181fbf..1fce00eb421bfc68ae531136a240680b66db4635 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/phy.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/of_mdio.h>
 #include <linux/module.h>
 
index 5fed7e3c7da341362a1c7bdf08f53b5e4b11c60a..1dbce58a58b01eecc8ebe48d7a9d802cfa90193f 100644 (file)
@@ -9,17 +9,17 @@
 #include <linux/of.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
+#include <linux/of_irq.h>
 #include <linux/of_spi.h>
 
 /**
  * of_register_spi_devices - Register child devices onto the SPI bus
  * @master:    Pointer to spi_master device
- * @np:                parent node of SPI device nodes
  *
- * Registers an spi_device for each child node of 'np' which has a 'reg'
+ * Registers an spi_device for each child node of master node which has a 'reg'
  * property.
  */
-void of_register_spi_devices(struct spi_master *master, struct device_node *np)
+void of_register_spi_devices(struct spi_master *master)
 {
        struct spi_device *spi;
        struct device_node *nc;
@@ -27,7 +27,10 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
        int rc;
        int len;
 
-       for_each_child_of_node(np, nc) {
+       if (!master->dev.of_node)
+               return;
+
+       for_each_child_of_node(master->dev.of_node, nc) {
                /* Alloc an spi_device */
                spi = spi_alloc_device(master);
                if (!spi) {
index 7dacc1ebe91e013cadbc77ca57cf729f34585ef5..bb72223c22ae233592b31549bd9417a1d3eb3c65 100644 (file)
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+       return dev->of_node == data;
+}
+
+/**
+ * of_find_device_by_node - Find the platform_device associated with a node
+ * @np: Pointer to device tree node
+ *
+ * Returns platform_device pointer, or NULL if not found
+ */
+struct platform_device *of_find_device_by_node(struct device_node *np)
+{
+       struct device *dev;
+
+       dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match);
+       return dev ? to_platform_device(dev) : NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+static int platform_driver_probe_shim(struct platform_device *pdev)
+{
+       struct platform_driver *pdrv;
+       struct of_platform_driver *ofpdrv;
+       const struct of_device_id *match;
+
+       pdrv = container_of(pdev->dev.driver, struct platform_driver, driver);
+       ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver);
+
+       /* There is an unlikely chance that an of_platform driver might match
+        * on a non-OF platform device.  If so, then of_match_device() will
+        * come up empty.  Return -EINVAL in this case so other drivers get
+        * the chance to bind. */
+       match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
+       return match ? ofpdrv->probe(pdev, match) : -EINVAL;
+}
+
+static void platform_driver_shutdown_shim(struct platform_device *pdev)
+{
+       struct platform_driver *pdrv;
+       struct of_platform_driver *ofpdrv;
+
+       pdrv = container_of(pdev->dev.driver, struct platform_driver, driver);
+       ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver);
+       ofpdrv->shutdown(pdev);
+}
+
+/**
+ * of_register_platform_driver
+ */
+int of_register_platform_driver(struct of_platform_driver *drv)
+{
+       char *of_name;
+
+       /* setup of_platform_driver to platform_driver adaptors */
+       drv->platform_driver.driver = drv->driver;
+
+       /* Prefix the driver name with 'of:' to avoid namespace collisions
+        * and bogus matches.  There are some drivers in the tree that
+        * register both an of_platform_driver and a platform_driver with
+        * the same name.  This is a temporary measure until they are all
+        * cleaned up --gcl July 29, 2010 */
+       of_name = kmalloc(strlen(drv->driver.name) + 5, GFP_KERNEL);
+       if (!of_name)
+               return -ENOMEM;
+       sprintf(of_name, "of:%s", drv->driver.name);
+       drv->platform_driver.driver.name = of_name;
+
+       if (drv->probe)
+               drv->platform_driver.probe = platform_driver_probe_shim;
+       drv->platform_driver.remove = drv->remove;
+       if (drv->shutdown)
+               drv->platform_driver.shutdown = platform_driver_shutdown_shim;
+       drv->platform_driver.suspend = drv->suspend;
+       drv->platform_driver.resume = drv->resume;
+
+       return platform_driver_register(&drv->platform_driver);
+}
+EXPORT_SYMBOL(of_register_platform_driver);
+
+void of_unregister_platform_driver(struct of_platform_driver *drv)
+{
+       platform_driver_unregister(&drv->platform_driver);
+       kfree(drv->platform_driver.driver.name);
+       drv->platform_driver.driver.name = NULL;
+}
+EXPORT_SYMBOL(of_unregister_platform_driver);
+
+#if defined(CONFIG_PPC_DCR)
+#include <asm/dcr.h>
+#endif
 
 extern struct device_attribute of_platform_device_attrs[];
 
@@ -33,11 +130,11 @@ static int of_platform_device_probe(struct device *dev)
 {
        int error = -ENODEV;
        struct of_platform_driver *drv;
-       struct of_device *of_dev;
+       struct platform_device *of_dev;
        const struct of_device_id *match;
 
        drv = to_of_platform_driver(dev->driver);
-       of_dev = to_of_device(dev);
+       of_dev = to_platform_device(dev);
 
        if (!drv->probe)
                return error;
@@ -55,7 +152,7 @@ static int of_platform_device_probe(struct device *dev)
 
 static int of_platform_device_remove(struct device *dev)
 {
-       struct of_device *of_dev = to_of_device(dev);
+       struct platform_device *of_dev = to_platform_device(dev);
        struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
 
        if (dev->driver && drv->remove)
@@ -65,7 +162,7 @@ static int of_platform_device_remove(struct device *dev)
 
 static void of_platform_device_shutdown(struct device *dev)
 {
-       struct of_device *of_dev = to_of_device(dev);
+       struct platform_device *of_dev = to_platform_device(dev);
        struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
 
        if (dev->driver && drv->shutdown)
@@ -76,7 +173,7 @@ static void of_platform_device_shutdown(struct device *dev)
 
 static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg)
 {
-       struct of_device *of_dev = to_of_device(dev);
+       struct platform_device *of_dev = to_platform_device(dev);
        struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
        int ret = 0;
 
@@ -87,7 +184,7 @@ static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg)
 
 static int of_platform_legacy_resume(struct device *dev)
 {
-       struct of_device *of_dev = to_of_device(dev);
+       struct platform_device *of_dev = to_platform_device(dev);
        struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
        int ret = 0;
 
@@ -384,15 +481,286 @@ int of_bus_type_init(struct bus_type *bus, const char *name)
 
 int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
 {
-       drv->driver.bus = bus;
+       /*
+        * Temporary: of_platform_bus used to be distinct from the platform
+        * bus.  It isn't anymore, and so drivers on the platform bus need
+        * to be registered in a special way.
+        *
+        * After all of_platform_bus_type drivers are converted to
+        * platform_drivers, this exception can be removed.
+        */
+       if (bus == &platform_bus_type)
+               return of_register_platform_driver(drv);
 
        /* register with core */
+       drv->driver.bus = bus;
        return driver_register(&drv->driver);
 }
 EXPORT_SYMBOL(of_register_driver);
 
 void of_unregister_driver(struct of_platform_driver *drv)
 {
-       driver_unregister(&drv->driver);
+       if (drv->driver.bus == &platform_bus_type)
+               of_unregister_platform_driver(drv);
+       else
+               driver_unregister(&drv->driver);
 }
 EXPORT_SYMBOL(of_unregister_driver);
+
+#if !defined(CONFIG_SPARC)
+/*
+ * The following routines scan a subtree and registers a device for
+ * each applicable node.
+ *
+ * Note: sparc doesn't use these routines because it has a different
+ * mechanism for creating devices from device tree nodes.
+ */
+
+/**
+ * of_device_make_bus_id - Use the device node data to assign a unique name
+ * @dev: pointer to device structure that is linked to a device tree node
+ *
+ * This routine will first try using either the dcr-reg or the reg property
+ * value to derive a unique name.  As a last resort it will use the node
+ * name followed by a unique number.
+ */
+void of_device_make_bus_id(struct device *dev)
+{
+       static atomic_t bus_no_reg_magic;
+       struct device_node *node = dev->of_node;
+       const u32 *reg;
+       u64 addr;
+       int magic;
+
+#ifdef CONFIG_PPC_DCR
+       /*
+        * If it's a DCR based device, use 'd' for native DCRs
+        * and 'D' for MMIO DCRs.
+        */
+       reg = of_get_property(node, "dcr-reg", NULL);
+       if (reg) {
+#ifdef CONFIG_PPC_DCR_NATIVE
+               dev_set_name(dev, "d%x.%s", *reg, node->name);
+#else /* CONFIG_PPC_DCR_NATIVE */
+               u64 addr = of_translate_dcr_address(node, *reg, NULL);
+               if (addr != OF_BAD_ADDR) {
+                       dev_set_name(dev, "D%llx.%s",
+                                    (unsigned long long)addr, node->name);
+                       return;
+               }
+#endif /* !CONFIG_PPC_DCR_NATIVE */
+       }
+#endif /* CONFIG_PPC_DCR */
+
+       /*
+        * For MMIO, get the physical address
+        */
+       reg = of_get_property(node, "reg", NULL);
+       if (reg) {
+               addr = of_translate_address(node, reg);
+               if (addr != OF_BAD_ADDR) {
+                       dev_set_name(dev, "%llx.%s",
+                                    (unsigned long long)addr, node->name);
+                       return;
+               }
+       }
+
+       /*
+        * No BusID, use the node name and add a globally incremented
+        * counter (and pray...)
+        */
+       magic = atomic_add_return(1, &bus_no_reg_magic);
+       dev_set_name(dev, "%s.%d", node->name, magic - 1);
+}
+
+/**
+ * of_device_alloc - Allocate and initialize an of_device
+ * @np: device node to assign to device
+ * @bus_id: Name to assign to the device.  May be null to use default name.
+ * @parent: Parent device.
+ */
+struct platform_device *of_device_alloc(struct device_node *np,
+                                 const char *bus_id,
+                                 struct device *parent)
+{
+       struct platform_device *dev;
+       int rc, i, num_reg = 0, num_irq = 0;
+       struct resource *res, temp_res;
+
+       /* First count how many resources are needed */
+       while (of_address_to_resource(np, num_reg, &temp_res) == 0)
+               num_reg++;
+       while (of_irq_to_resource(np, num_irq, &temp_res) != NO_IRQ)
+               num_irq++;
+
+       /* Allocate memory for both the struct device and the resource table */
+       dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)),
+                     GFP_KERNEL);
+       if (!dev)
+               return NULL;
+       res = (struct resource *) &dev[1];
+
+       /* Populate the resource table */
+       if (num_irq || num_reg) {
+               dev->num_resources = num_reg + num_irq;
+               dev->resource = res;
+               for (i = 0; i < num_reg; i++, res++) {
+                       rc = of_address_to_resource(np, i, res);
+                       WARN_ON(rc);
+               }
+               for (i = 0; i < num_irq; i++, res++) {
+                       rc = of_irq_to_resource(np, i, res);
+                       WARN_ON(rc == NO_IRQ);
+               }
+       }
+
+       dev->dev.of_node = of_node_get(np);
+#if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE)
+       dev->dev.dma_mask = &dev->archdata.dma_mask;
+#endif
+       dev->dev.parent = parent;
+       dev->dev.release = of_release_dev;
+
+       if (bus_id)
+               dev_set_name(&dev->dev, "%s", bus_id);
+       else
+               of_device_make_bus_id(&dev->dev);
+
+       return dev;
+}
+EXPORT_SYMBOL(of_device_alloc);
+
+/**
+ * of_platform_device_create - Alloc, initialize and register an of_device
+ * @np: pointer to node to create device for
+ * @bus_id: name to assign device
+ * @parent: Linux device model parent device.
+ */
+struct platform_device *of_platform_device_create(struct device_node *np,
+                                           const char *bus_id,
+                                           struct device *parent)
+{
+       struct platform_device *dev;
+
+       dev = of_device_alloc(np, bus_id, parent);
+       if (!dev)
+               return NULL;
+
+#if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE)
+       dev->archdata.dma_mask = 0xffffffffUL;
+#endif
+       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       dev->dev.bus = &platform_bus_type;
+
+       /* We do not fill the DMA ops for platform devices by default.
+        * This is currently the responsibility of the platform code
+        * to do such, possibly using a device notifier
+        */
+
+       if (of_device_register(dev) != 0) {
+               of_device_free(dev);
+               return NULL;
+       }
+
+       return dev;
+}
+EXPORT_SYMBOL(of_platform_device_create);
+
+/**
+ * of_platform_bus_create - Create an OF device for a bus node and all its
+ * children. Optionally recursively instantiate matching busses.
+ * @bus: device node of the bus to instantiate
+ * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
+ * disallow recursive creation of child busses
+ */
+static int of_platform_bus_create(const struct device_node *bus,
+                                 const struct of_device_id *matches,
+                                 struct device *parent)
+{
+       struct device_node *child;
+       struct platform_device *dev;
+       int rc = 0;
+
+       for_each_child_of_node(bus, child) {
+               pr_debug("   create child: %s\n", child->full_name);
+               dev = of_platform_device_create(child, NULL, parent);
+               if (dev == NULL)
+                       rc = -ENOMEM;
+               else if (!of_match_node(matches, child))
+                       continue;
+               if (rc == 0) {
+                       pr_debug("   and sub busses\n");
+                       rc = of_platform_bus_create(child, matches, &dev->dev);
+               }
+               if (rc) {
+                       of_node_put(child);
+                       break;
+               }
+       }
+       return rc;
+}
+
+/**
+ * of_platform_bus_probe - Probe the device-tree for platform busses
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Note that children of the provided root are not instantiated as devices
+ * unless the specified root itself matches the bus list and is not NULL.
+ */
+int of_platform_bus_probe(struct device_node *root,
+                         const struct of_device_id *matches,
+                         struct device *parent)
+{
+       struct device_node *child;
+       struct platform_device *dev;
+       int rc = 0;
+
+       if (WARN_ON(!matches || matches == OF_NO_DEEP_PROBE))
+               return -EINVAL;
+       if (root == NULL)
+               root = of_find_node_by_path("/");
+       else
+               of_node_get(root);
+       if (root == NULL)
+               return -EINVAL;
+
+       pr_debug("of_platform_bus_probe()\n");
+       pr_debug(" starting at: %s\n", root->full_name);
+
+       /* Do a self check of bus type, if there's a match, create
+        * children
+        */
+       if (of_match_node(matches, root)) {
+               pr_debug(" root match, create all sub devices\n");
+               dev = of_platform_device_create(root, NULL, parent);
+               if (dev == NULL) {
+                       rc = -ENOMEM;
+                       goto bail;
+               }
+               pr_debug(" create all sub busses\n");
+               rc = of_platform_bus_create(root, matches, &dev->dev);
+               goto bail;
+       }
+       for_each_child_of_node(root, child) {
+               if (!of_match_node(matches, child))
+                       continue;
+
+               pr_debug("  match: %s\n", child->full_name);
+               dev = of_platform_device_create(child, NULL, parent);
+               if (dev == NULL)
+                       rc = -ENOMEM;
+               else
+                       rc = of_platform_bus_create(child, matches, &dev->dev);
+               if (rc) {
+                       of_node_put(child);
+                       break;
+               }
+       }
+ bail:
+       of_node_put(root);
+       return rc;
+}
+EXPORT_SYMBOL(of_platform_bus_probe);
+#endif /* !CONFIG_SPARC */
index 5df60a6b67766adb402a30fee44d7b7782bc5e08..dd87e86048be7913e9cc0090c52a957712d0067c 100644 (file)
@@ -135,7 +135,7 @@ static int event_buffer_open(struct inode *inode, struct file *file)
         * echo 1 >/dev/oprofile/enable
         */
 
-       return 0;
+       return nonseekable_open(inode, file);
 
 fail:
        dcookie_unregister(file->private_data);
@@ -205,4 +205,5 @@ const struct file_operations event_buffer_fops = {
        .open           = event_buffer_open,
        .release        = event_buffer_release,
        .read           = event_buffer_read,
+       .llseek         = no_llseek,
 };
index fd8cfe95f0a3ab815902a4fd5043228ecd140703..23e50f4a27c5b8719ac745223b2455d39bea0ad6 100644 (file)
@@ -48,7 +48,6 @@
 #include <linux/parport.h>
 #include <linux/parport_pc.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -102,8 +101,8 @@ static int parport_probe(struct pcmcia_device *link)
     link->priv = info;
     info->p_dev = link;
 
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+    link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -144,16 +143,16 @@ static int parport_config_check(struct pcmcia_device *p_dev,
 {
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
                if (epp_mode)
                        p_dev->conf.ConfigIndex |= FORCE_EPP_MODE;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin == 2) {
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               if (pcmcia_request_io(p_dev) != 0)
                        return -ENODEV;
                return 0;
        }
@@ -178,12 +177,14 @@ static int parport_config(struct pcmcia_device *link)
     if (ret)
            goto failed;
 
-    p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
+    p = parport_pc_probe_port(link->resource[0]->start,
+                             link->resource[1]->start,
                              link->irq, PARPORT_DMA_NONE,
                              &link->dev, IRQF_SHARED);
     if (p == NULL) {
        printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
-              "0x%3x, irq %u failed\n", link->io.BasePort1,
+              "0x%3x, irq %u failed\n",
+              (unsigned int) link->resource[0]->start,
               link->irq);
        goto failed;
     }
index 9a5b4b89416146827467946e77e96c36ac391c68..210a6441a0662c08953b510d813ef15af8c865ac 100644 (file)
@@ -295,7 +295,7 @@ static int __devinit bpp_probe(struct of_device *op, const struct of_device_id *
        void __iomem *base;
        struct parport *p;
 
-       irq = op->irqs[0];
+       irq = op->archdata.irqs[0];
        base = of_ioremap(&op->resource[0], 0,
                          resource_size(&op->resource[0]),
                          "sunbpp");
@@ -393,12 +393,12 @@ static struct of_platform_driver bpp_sbus_driver = {
 
 static int __init parport_sunbpp_init(void)
 {
-       return of_register_driver(&bpp_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&bpp_sbus_driver);
 }
 
 static void __exit parport_sunbpp_exit(void)
 {
-       of_unregister_driver(&bpp_sbus_driver);
+       of_unregister_platform_driver(&bpp_sbus_driver);
 }
 
 MODULE_AUTHOR("Derrick J Brashear");
index 0b51857fbaf74842433d1eddef7b51cb54209ec3..dc1aa09228684b8881241c91fde01111df04bdb1 100644 (file)
@@ -55,6 +55,9 @@ obj-$(CONFIG_MICROBLAZE) += setup-bus.o
 #
 obj-$(CONFIG_ACPI)    += pci-acpi.o
 
+# SMBIOS provided firmware instance and labels
+obj-$(CONFIG_DMI)    += pci-label.o
+
 # Cardbus & CompactPCI use setup-bus
 obj-$(CONFIG_HOTPLUG) += setup-bus.o
 
index 628ea20a884190afbbffff2f80e0faf5cbaade1b..7f0af0e9b826dafa2e64d8302c130ea87e5af00b 100644 (file)
@@ -56,7 +56,7 @@ void pci_bus_remove_resources(struct pci_bus *bus)
        int i;
 
        for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
-               bus->resource[i] = 0;
+               bus->resource[i] = NULL;
 
        list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
                list_del(&bus_res->list);
@@ -240,6 +240,8 @@ void pci_enable_bridges(struct pci_bus *bus)
                if (dev->subordinate) {
                        if (!pci_is_enabled(dev)) {
                                retval = pci_enable_device(dev);
+                               if (retval)
+                                       dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", retval);
                                pci_set_master(dev);
                        }
                        pci_enable_bridges(dev->subordinate);
index 5317e4d7d96eab58ac6c24a450022ae82a5c13e5..17d10e2e8fb692f2f605fc6a63571df63ff46a14 100644 (file)
@@ -135,7 +135,7 @@ static int __init init_legacy(void)
        struct pci_dev *pdev = NULL;
 
        /* Add existing devices */
-       while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)))
+       for_each_pci_dev(pdev)
                legacy_add_slot(pdev);
 
        /* Be alerted of any new ones */
index 2fce726758d2f1bc0c5d24dff8ca3690707c4a56..a4031dfe938ecd037227896fac3fabe5ca24e56b 100644 (file)
@@ -137,7 +137,7 @@ int pciehp_unconfigure_device(struct slot *p_slot)
                                         "Cannot remove display device %s\n",
                                         pci_name(temp));
                                pci_dev_put(temp);
-                               rc = EINVAL;
+                               rc = -EINVAL;
                                break;
                        }
                }
index 5f5e8d2e35529a2ca9ec92be86eda94f28b4e86f..d3985e7deab7db44f8e2674f34da37a810c2d06d 100644 (file)
 #define CON_PFAULT_INTR_MASK   (1 << 28)
 #define MRL_CHANGE_SERR_MASK   (1 << 29)
 #define CON_PFAULT_SERR_MASK   (1 << 30)
-#define SLOT_REG_RSVDZ_MASK    (1 << 15) | (7 << 21)
+#define SLOT_REG_RSVDZ_MASK    ((1 << 15) | (7 << 21))
 
 /*
  * SHPC Command Code definitnions
index 8c3d3219f22777d709ed2eefc6fe1e3cb2b30b9e..a2ccfcd3c29840ea9bfa6384b79e813cba67e21e 100644 (file)
@@ -60,12 +60,6 @@ int __ref shpchp_configure_device(struct slot *p_slot)
                dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
                if (!dev)
                        continue;
-               if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
-                       ctrl_err(ctrl, "Cannot hot-add display device %s\n",
-                                pci_name(dev));
-                       pci_dev_put(dev);
-                       continue;
-               }
                if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
                                (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
                        /* Find an unused bus number for the new bridge */
@@ -114,17 +108,11 @@ int shpchp_unconfigure_device(struct slot *p_slot)
        ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n",
                 __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device);
 
-       for (j=0; j<8 ; j++) {
-               struct pci_devtemp = pci_get_slot(parent,
+       for (j = 0; j < 8 ; j++) {
+               struct pci_dev *temp = pci_get_slot(parent,
                                (p_slot->device << 3) | j);
                if (!temp)
                        continue;
-               if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
-                       ctrl_err(ctrl, "Cannot remove display device %s\n",
-                                pci_name(temp));
-                       pci_dev_put(temp);
-                       continue;
-               }
                if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
                        pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
                        if (bctl & PCI_BRIDGE_CTL_VGA) {
@@ -132,7 +120,8 @@ int shpchp_unconfigure_device(struct slot *p_slot)
                                         "Cannot remove display device %s\n",
                                         pci_name(temp));
                                pci_dev_put(temp);
-                               continue;
+                               rc = -EINVAL;
+                               break;
                        }
                }
                pci_remove_bus_device(temp);
index c9171be74564b684ba41108fd15a566187910023..6a5af18faf684e2ab6cecd1a9b9e9d8ad7e321b1 100644 (file)
@@ -3698,6 +3698,8 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
 
        if (cap == IOMMU_CAP_CACHE_COHERENCY)
                return dmar_domain->iommu_snooping;
+       if (cap == IOMMU_CAP_INTR_REMAP)
+               return intr_remapping_enabled;
 
        return 0;
 }
index 1315ac688aa267d9aa504f4d2874b9aa930b4bc8..1694a0e2845b1a4074c3c29e4332455a89a83676 100644 (file)
@@ -311,8 +311,8 @@ int modify_irte(int irq, struct irte *irte_modified)
        index = irq_iommu->irte_index + irq_iommu->sub_handle;
        irte = &iommu->ir_table->base[index];
 
-       set_64bit((unsigned long *)&irte->low, irte_modified->low);
-       set_64bit((unsigned long *)&irte->high, irte_modified->high);
+       set_64bit(&irte->low, irte_modified->low);
+       set_64bit(&irte->high, irte_modified->high);
        __iommu_flush_cache(iommu, irte, sizeof(*irte));
 
        rc = qi_flush_iec(iommu, index, 0);
@@ -393,8 +393,8 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
        end = start + (1 << irq_iommu->irte_mask);
 
        for (entry = start; entry < end; entry++) {
-               set_64bit((unsigned long *)&entry->low, 0);
-               set_64bit((unsigned long *)&entry->high, 0);
+               set_64bit(&entry->low, 0);
+               set_64bit(&entry->high, 0);
        }
 
        return qi_flush_iec(iommu, index, irq_iommu->irte_mask);
index 77b68eaf021e43152c4bbd257bd190a4a210473c..69b7be33b3a24768a460843a13c17a88c96a8024 100644 (file)
@@ -196,6 +196,9 @@ void unmask_msi_irq(unsigned int irq)
 void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
 {
        struct msi_desc *entry = get_irq_desc_msi(desc);
+
+       BUG_ON(entry->dev->current_state != PCI_D0);
+
        if (entry->msi_attrib.is_msix) {
                void __iomem *base = entry->mask_base +
                        entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
@@ -229,10 +232,32 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
        read_msi_msg_desc(desc, msg);
 }
 
+void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
+{
+       struct msi_desc *entry = get_irq_desc_msi(desc);
+
+       /* Assert that the cache is valid, assuming that
+        * valid messages are not all-zeroes. */
+       BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo |
+                entry->msg.data));
+
+       *msg = entry->msg;
+}
+
+void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+
+       get_cached_msi_msg_desc(desc, msg);
+}
+
 void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
 {
        struct msi_desc *entry = get_irq_desc_msi(desc);
-       if (entry->msi_attrib.is_msix) {
+
+       if (entry->dev->current_state != PCI_D0) {
+               /* Don't touch the hardware now */
+       } else if (entry->msi_attrib.is_msix) {
                void __iomem *base;
                base = entry->mask_base +
                        entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
@@ -435,7 +460,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos,
                                                        unsigned nr_entries)
 {
-       unsigned long phys_addr;
+       resource_size_t phys_addr;
        u32 table_offset;
        u8 bir;
 
index f9a0aec3abcf68c1594ee99d082dcab4a6560ff8..8a6f797de8e55af1b3d0380aefb2173b58ab9fa5 100644 (file)
@@ -289,8 +289,26 @@ struct drv_dev_and_id {
 static long local_pci_probe(void *_ddi)
 {
        struct drv_dev_and_id *ddi = _ddi;
-
-       return ddi->drv->probe(ddi->dev, ddi->id);
+       struct device *dev = &ddi->dev->dev;
+       int rc;
+
+       /* Unbound PCI devices are always set to disabled and suspended.
+        * During probe, the device is set to enabled and active and the
+        * usage count is incremented.  If the driver supports runtime PM,
+        * it should call pm_runtime_put_noidle() in its probe routine and
+        * pm_runtime_get_noresume() in its remove routine.
+        */
+       pm_runtime_get_noresume(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+
+       rc = ddi->drv->probe(ddi->dev, ddi->id);
+       if (rc) {
+               pm_runtime_disable(dev);
+               pm_runtime_set_suspended(dev);
+               pm_runtime_put_noidle(dev);
+       }
+       return rc;
 }
 
 static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
@@ -369,11 +387,19 @@ static int pci_device_remove(struct device * dev)
        struct pci_driver * drv = pci_dev->driver;
 
        if (drv) {
-               if (drv->remove)
+               if (drv->remove) {
+                       pm_runtime_get_sync(dev);
                        drv->remove(pci_dev);
+                       pm_runtime_put_noidle(dev);
+               }
                pci_dev->driver = NULL;
        }
 
+       /* Undo the runtime PM settings in local_pci_probe() */
+       pm_runtime_disable(dev);
+       pm_runtime_set_suspended(dev);
+       pm_runtime_put_noidle(dev);
+
        /*
         * If the device is still on, set the power state as "unknown",
         * since it might change by the next time we load the driver.
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
new file mode 100644 (file)
index 0000000..90c0a72
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Purpose: Export the firmware instance and label associated with
+ * a pci device to sysfs
+ * Copyright (C) 2010 Dell Inc.
+ * by Narendra K <Narendra_K@dell.com>,
+ * Jordan Hargrave <Jordan_Hargrave@dell.com>
+ *
+ * SMBIOS defines type 41 for onboard pci devices. This code retrieves
+ * the instance number and string from the type 41 record and exports
+ * it to sysfs.
+ *
+ * Please see http://linux.dell.com/wiki/index.php/Oss/libnetdevname for more
+ * information.
+ */
+
+#include <linux/dmi.h>
+#include <linux/sysfs.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include "pci.h"
+
+enum smbios_attr_enum {
+       SMBIOS_ATTR_NONE = 0,
+       SMBIOS_ATTR_LABEL_SHOW,
+       SMBIOS_ATTR_INSTANCE_SHOW,
+};
+
+static mode_t
+find_smbios_instance_string(struct pci_dev *pdev, char *buf,
+                           enum smbios_attr_enum attribute)
+{
+       const struct dmi_device *dmi;
+       struct dmi_dev_onboard *donboard;
+       int bus;
+       int devfn;
+
+       bus = pdev->bus->number;
+       devfn = pdev->devfn;
+
+       dmi = NULL;
+       while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD,
+                                     NULL, dmi)) != NULL) {
+               donboard = dmi->device_data;
+               if (donboard && donboard->bus == bus &&
+                                       donboard->devfn == devfn) {
+                       if (buf) {
+                               if (attribute == SMBIOS_ATTR_INSTANCE_SHOW)
+                                       return scnprintf(buf, PAGE_SIZE,
+                                                        "%d\n",
+                                                        donboard->instance);
+                               else if (attribute == SMBIOS_ATTR_LABEL_SHOW)
+                                       return scnprintf(buf, PAGE_SIZE,
+                                                        "%s\n",
+                                                        dmi->name);
+                       }
+                       return strlen(dmi->name);
+               }
+       }
+       return 0;
+}
+
+static mode_t
+smbios_instance_string_exist(struct kobject *kobj, struct attribute *attr,
+                            int n)
+{
+       struct device *dev;
+       struct pci_dev *pdev;
+
+       dev = container_of(kobj, struct device, kobj);
+       pdev = to_pci_dev(dev);
+
+       return find_smbios_instance_string(pdev, NULL, SMBIOS_ATTR_NONE) ?
+                                          S_IRUGO : 0;
+}
+
+static ssize_t
+smbioslabel_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct pci_dev *pdev;
+       pdev = to_pci_dev(dev);
+
+       return find_smbios_instance_string(pdev, buf,
+                                          SMBIOS_ATTR_LABEL_SHOW);
+}
+
+static ssize_t
+smbiosinstance_show(struct device *dev,
+                   struct device_attribute *attr, char *buf)
+{
+       struct pci_dev *pdev;
+       pdev = to_pci_dev(dev);
+
+       return find_smbios_instance_string(pdev, buf,
+                                          SMBIOS_ATTR_INSTANCE_SHOW);
+}
+
+static struct device_attribute smbios_attr_label = {
+       .attr = {.name = "label", .mode = 0444},
+       .show = smbioslabel_show,
+};
+
+static struct device_attribute smbios_attr_instance = {
+       .attr = {.name = "index", .mode = 0444},
+       .show = smbiosinstance_show,
+};
+
+static struct attribute *smbios_attributes[] = {
+       &smbios_attr_label.attr,
+       &smbios_attr_instance.attr,
+       NULL,
+};
+
+static struct attribute_group smbios_attr_group = {
+       .attrs = smbios_attributes,
+       .is_visible = smbios_instance_string_exist,
+};
+
+static int
+pci_create_smbiosname_file(struct pci_dev *pdev)
+{
+       if (!sysfs_create_group(&pdev->dev.kobj, &smbios_attr_group))
+               return 0;
+       return -ENODEV;
+}
+
+static void
+pci_remove_smbiosname_file(struct pci_dev *pdev)
+{
+       sysfs_remove_group(&pdev->dev.kobj, &smbios_attr_group);
+}
+
+void pci_create_firmware_label_files(struct pci_dev *pdev)
+{
+       if (!pci_create_smbiosname_file(pdev))
+               ;
+}
+
+void pci_remove_firmware_label_files(struct pci_dev *pdev)
+{
+       pci_remove_smbiosname_file(pdev);
+}
index c9957f68ac9bd574964271b363012aa62c8c8bc3..b5a7d9bfcb24a70523a33793e60d217475fc9a91 100644 (file)
@@ -734,7 +734,7 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 {
        struct pci_dev *pdev = to_pci_dev(container_of(kobj,
                                                       struct device, kobj));
-       struct resource *res = (struct resource *)attr->private;
+       struct resource *res = attr->private;
        enum pci_mmap_state mmap_type;
        resource_size_t start, end;
        int i;
@@ -778,6 +778,70 @@ pci_mmap_resource_wc(struct file *filp, struct kobject *kobj,
        return pci_mmap_resource(kobj, attr, vma, 1);
 }
 
+static ssize_t
+pci_resource_io(struct file *filp, struct kobject *kobj,
+               struct bin_attribute *attr, char *buf,
+               loff_t off, size_t count, bool write)
+{
+       struct pci_dev *pdev = to_pci_dev(container_of(kobj,
+                                                      struct device, kobj));
+       struct resource *res = attr->private;
+       unsigned long port = off;
+       int i;
+
+       for (i = 0; i < PCI_ROM_RESOURCE; i++)
+               if (res == &pdev->resource[i])
+                       break;
+       if (i >= PCI_ROM_RESOURCE)
+               return -ENODEV;
+
+       port += pci_resource_start(pdev, i);
+
+       if (port > pci_resource_end(pdev, i))
+               return 0;
+
+       if (port + count - 1 > pci_resource_end(pdev, i))
+               return -EINVAL;
+
+       switch (count) {
+       case 1:
+               if (write)
+                       outb(*(u8 *)buf, port);
+               else
+                       *(u8 *)buf = inb(port);
+               return 1;
+       case 2:
+               if (write)
+                       outw(*(u16 *)buf, port);
+               else
+                       *(u16 *)buf = inw(port);
+               return 2;
+       case 4:
+               if (write)
+                       outl(*(u32 *)buf, port);
+               else
+                       *(u32 *)buf = inl(port);
+               return 4;
+       }
+       return -EINVAL;
+}
+
+static ssize_t
+pci_read_resource_io(struct file *filp, struct kobject *kobj,
+                    struct bin_attribute *attr, char *buf,
+                    loff_t off, size_t count)
+{
+       return pci_resource_io(filp, kobj, attr, buf, off, count, false);
+}
+
+static ssize_t
+pci_write_resource_io(struct file *filp, struct kobject *kobj,
+                     struct bin_attribute *attr, char *buf,
+                     loff_t off, size_t count)
+{
+       return pci_resource_io(filp, kobj, attr, buf, off, count, true);
+}
+
 /**
  * pci_remove_resource_files - cleanup resource files
  * @pdev: dev to cleanup
@@ -828,6 +892,10 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
                        sprintf(res_attr_name, "resource%d", num);
                        res_attr->mmap = pci_mmap_resource_uc;
                }
+               if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
+                       res_attr->read = pci_read_resource_io;
+                       res_attr->write = pci_write_resource_io;
+               }
                res_attr->attr.name = res_attr_name;
                res_attr->attr.mode = S_IRUSR | S_IWUSR;
                res_attr->size = pci_resource_len(pdev, num);
@@ -1097,6 +1165,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
        if (retval)
                goto err_vga_file;
 
+       pci_create_firmware_label_files(pdev);
+
        return 0;
 
 err_vga_file:
@@ -1164,6 +1234,9 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
                sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
                kfree(pdev->rom_attr);
        }
+
+       pci_remove_firmware_label_files(pdev);
+
 }
 
 static int __init pci_sysfs_init(void)
index 130ed1daf0f8db10637649cd47d6c2c5a4673dd7..7fa3cbd742c53bd34a871355320cecc56906277f 100644 (file)
@@ -2312,21 +2312,17 @@ void pci_msi_off(struct pci_dev *dev)
 }
 EXPORT_SYMBOL_GPL(pci_msi_off);
 
-#ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE
 int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
 {
        return dma_set_max_seg_size(&dev->dev, size);
 }
 EXPORT_SYMBOL(pci_set_dma_max_seg_size);
-#endif
 
-#ifndef HAVE_ARCH_PCI_SET_DMA_SEGMENT_BOUNDARY
 int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
 {
        return dma_set_seg_boundary(&dev->dev, mask);
 }
 EXPORT_SYMBOL(pci_set_dma_seg_boundary);
-#endif
 
 static int pcie_flr(struct pci_dev *dev, int probe)
 {
index c8b7fd056ccdc3fbd53c798e02b0e89c90d13076..679c39de6a89124e96a36252f32e8ff45991b7aa 100644 (file)
 extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
 extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
 extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
+#ifndef CONFIG_DMI
+static inline void pci_create_firmware_label_files(struct pci_dev *pdev)
+{ return; }
+static inline void pci_remove_firmware_label_files(struct pci_dev *pdev)
+{ return; }
+#else
+extern void pci_create_firmware_label_files(struct pci_dev *pdev);
+extern void pci_remove_firmware_label_files(struct pci_dev *pdev);
+#endif
 extern void pci_cleanup_rom(struct pci_dev *dev);
 #ifdef HAVE_PCI_MMAP
 extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
index b8b494b3e0d058c0a1f42e51c81ee15e24ed82cb..dda70981b7a6f4ef3f4a29fc84f826111b1d0306 100644 (file)
@@ -31,14 +31,22 @@ source "drivers/pci/pcie/aer/Kconfig"
 # PCI Express ASPM
 #
 config PCIEASPM
-       bool "PCI Express ASPM support(Experimental)"
-       depends on PCI && EXPERIMENTAL && PCIEPORTBUS
-       default n
+       bool "PCI Express ASPM control" if EMBEDDED
+       depends on PCI && PCIEPORTBUS
+       default y
        help
-         This enables PCI Express ASPM (Active State Power Management) and
-         Clock Power Management. ASPM supports state L0/L0s/L1.
+         This enables OS control over PCI Express ASPM (Active State
+         Power Management) and Clock Power Management. ASPM supports
+         state L0/L0s/L1.
 
-         When in doubt, say N.
+         ASPM is initially set up the the firmware. With this option enabled,
+         Linux can modify this state in order to disable ASPM on known-bad
+         hardware or configurations and enable it when known-safe.
+
+         ASPM can be disabled or enabled at runtime via
+         /sys/module/pcie_aspm/parameters/policy
+
+         When in doubt, say Y.
 config PCIEASPM_DEBUG
        bool "Debug PCI Express ASPM"
        depends on PCIEASPM
index 8af4f619bba2ceb8871e4b34674ab0678c988c4b..fc0b5a93e1deaf3895ef671ae1f30892980c9352 100644 (file)
@@ -727,20 +727,21 @@ static void aer_isr_one_error(struct pcie_device *p_device,
 static int get_e_source(struct aer_rpc *rpc, struct aer_err_source *e_src)
 {
        unsigned long flags;
-       int ret = 0;
 
        /* Lock access to Root error producer/consumer index */
        spin_lock_irqsave(&rpc->e_lock, flags);
-       if (rpc->prod_idx != rpc->cons_idx) {
-               *e_src = rpc->e_sources[rpc->cons_idx];
-               rpc->cons_idx++;
-               if (rpc->cons_idx == AER_ERROR_SOURCES_MAX)
-                       rpc->cons_idx = 0;
-               ret = 1;
+       if (rpc->prod_idx == rpc->cons_idx) {
+               spin_unlock_irqrestore(&rpc->e_lock, flags);
+               return 0;
        }
+
+       *e_src = rpc->e_sources[rpc->cons_idx];
+       rpc->cons_idx++;
+       if (rpc->cons_idx == AER_ERROR_SOURCES_MAX)
+               rpc->cons_idx = 0;
        spin_unlock_irqrestore(&rpc->e_lock, flags);
 
-       return ret;
+       return 1;
 }
 
 /**
index be53d98fa38466992e762ca029d7c32007998d88..71222814c1ecf602880352d8cb3df7ff7930d5db 100644 (file)
@@ -588,11 +588,23 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
         * update through pcie_aspm_cap_init().
         */
        pcie_aspm_cap_init(link, blacklist);
-       pcie_config_aspm_path(link);
 
        /* Setup initial Clock PM state */
        pcie_clkpm_cap_init(link, blacklist);
-       pcie_set_clkpm(link, policy_to_clkpm_state(link));
+
+       /*
+        * At this stage drivers haven't had an opportunity to change the
+        * link policy setting. Enabling ASPM on broken hardware can cripple
+        * it even before the driver has had a chance to disable ASPM, so
+        * default to a safe level right now. If we're enabling ASPM beyond
+        * the BIOS's expectation, we'll do so once pci_enable_device() is
+        * called.
+        */
+       if (aspm_policy != POLICY_POWERSAVE) {
+               pcie_config_aspm_path(link);
+               pcie_set_clkpm(link, policy_to_clkpm_state(link));
+       }
+
 unlock:
        mutex_unlock(&aspm_lock);
 out:
index f4adba2d1dd3e6671b08c3a3ccb156a841829dfa..12625d90f8b573785f1a05a0a719fad46aa3155f 100644 (file)
@@ -163,9 +163,16 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                        struct resource *res, unsigned int pos)
 {
        u32 l, sz, mask;
+       u16 orig_cmd;
 
        mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
+       if (!dev->mmio_always_on) {
+               pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
+               pci_write_config_word(dev, PCI_COMMAND,
+                       orig_cmd & ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+       }
+
        res->name = pci_name(dev);
 
        pci_read_config_dword(dev, pos, &l);
@@ -173,6 +180,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
        pci_read_config_dword(dev, pos, &sz);
        pci_write_config_dword(dev, pos, l);
 
+       if (!dev->mmio_always_on)
+               pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
+
        /*
         * All bits set in sz means the device isn't working properly.
         * If the BAR isn't implemented, all bits must be 0.  If it's a
index 449e890267a2bae74de8a2b6b0bedf30023b7de0..01f0306525a504a7ed2a9f954f7376e06170c57e 100644 (file)
@@ -431,8 +431,6 @@ int pci_proc_detach_device(struct pci_dev *dev)
        struct proc_dir_entry *e;
 
        if ((e = dev->procent)) {
-               if (atomic_read(&e->count) > 1)
-                       return -EBUSY;
                remove_proc_entry(e->name, dev->bus->procdir);
                dev->procent = NULL;
        }
@@ -485,9 +483,9 @@ static int __init pci_proc_init(void)
        proc_create("devices", 0, proc_bus_pci_dir,
                    &proc_bus_pci_dev_operations);
        proc_initialized = 1;
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev)
                pci_proc_attach_device(dev);
-       }
+
        return 0;
 }
 
index 477345d416417c58662ea8386a0841ba65d0dd72..89ed181cd90cd9cd68506a212eb423ba60f9c8e2 100644 (file)
@@ -91,6 +91,19 @@ static void __devinit quirk_resource_alignment(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment);
 
+/*
+ * Decoding should be disabled for a PCI device during BAR sizing to avoid
+ * conflict. But doing so may cause problems on host bridge and perhaps other
+ * key system devices. For devices that need to have mmio decoding always-on,
+ * we need to set the dev->mmio_always_on bit.
+ */
+static void __devinit quirk_mmio_always_on(struct pci_dev *dev)
+{
+       if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+               dev->mmio_always_on = 1;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_mmio_always_on);
+
 /* The Mellanox Tavor device gives false positive parity errors
  * Mark this device with a broken_parity_status, to allow
  * PCI scanning code to "skip" this now blacklisted device.
@@ -1459,6 +1472,7 @@ static void quirk_jmicron_ata(struct pci_dev *pdev)
        switch (pdev->device) {
        case PCI_DEVICE_ID_JMICRON_JMB360: /* SATA single port */
        case PCI_DEVICE_ID_JMICRON_JMB362: /* SATA dual ports */
+       case PCI_DEVICE_ID_JMICRON_JMB364: /* SATA dual ports */
                /* The controller should be in single function ahci mode */
                conf1 |= 0x0002A100; /* Set 8, 13, 15, 17 */
                break;
@@ -1470,6 +1484,7 @@ static void quirk_jmicron_ata(struct pci_dev *pdev)
                /* Fall through */
        case PCI_DEVICE_ID_JMICRON_JMB361:
        case PCI_DEVICE_ID_JMICRON_JMB363:
+       case PCI_DEVICE_ID_JMICRON_JMB369:
                /* Enable dual function mode, AHCI on fn 0, IDE fn1 */
                /* Set the class codes correctly and then direct IDE 0 */
                conf1 |= 0x00C2A1B3; /* Set 0, 1, 4, 5, 7, 8, 13, 15, 17, 22, 23 */
@@ -1496,16 +1511,20 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, qui
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB364, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB369, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB364, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB369, quirk_jmicron_ata);
 
 #endif
 
@@ -2115,6 +2134,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disabl
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi);
 
 /* Disable MSI on chipsets that are known to not support it */
 static void __devinit quirk_disable_msi(struct pci_dev *dev)
@@ -2126,12 +2146,29 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi);
 
+/*
+ * The APC bridge device in AMD 780 family northbridges has some random
+ * OEM subsystem ID in its vendor ID register (erratum 18), so instead
+ * we use the possible vendor/device IDs of the host bridge for the
+ * declared quirk, and search for the APC bridge by slot number.
+ */
+static void __devinit quirk_amd_780_apc_msi(struct pci_dev *host_bridge)
+{
+       struct pci_dev *apc_bridge;
+
+       apc_bridge = pci_get_slot(host_bridge->bus, PCI_DEVFN(1, 0));
+       if (apc_bridge) {
+               if (apc_bridge->device == 0x9602)
+                       quirk_disable_msi(apc_bridge);
+               pci_dev_put(apc_bridge);
+       }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9600, quirk_amd_780_apc_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, quirk_amd_780_apc_msi);
+
 /* Go through the list of Hypertransport capabilities and
  * return 1 if a HT MSI capability is found and enabled */
 static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
@@ -2390,6 +2427,9 @@ static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
        int pos;
        int found;
 
+       if (!pci_msi_enabled())
+               return;
+
        /* check if there is HT MSI cap or enabled on this device */
        found = ht_check_msi_mapping(dev);
 
@@ -2742,7 +2782,7 @@ static int __init pci_apply_final_quirks(void)
                printk(KERN_DEBUG "PCI: CLS %u bytes\n",
                       pci_cache_line_size << 2);
 
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
                pci_fixup_device(pci_fixup_final, dev);
                /*
                 * If arch hasn't set it explicitly yet, use the CLS
index 20d03f7722890807b5a128a2032878180794435d..9d75dc8ca602995826b80c842e40edfea1a2d866 100644 (file)
@@ -169,7 +169,7 @@ struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
 {
        struct pci_dev *dev = NULL;
 
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
                if (pci_domain_nr(dev->bus) == domain &&
                    (dev->bus->number == bus && dev->devfn == devfn))
                        return dev;
index 19b111383f62fe63c9859dfd509de2cda3801d9e..66cb8f4cc5f4b37fbfc965fda9c63fc1fb1da913 100644 (file)
@@ -874,19 +874,16 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 again:
        pci_bus_size_bridges(parent);
        __pci_bridge_assign_resources(bridge, &head);
-       retval = pci_reenable_device(bridge);
-       pci_set_master(bridge);
-       pci_enable_bridges(parent);
 
        tried_times++;
 
        if (!head.next)
-               return;
+               goto enable_all;
 
        if (tried_times >= 2) {
                /* still fail, don't need to try more */
                free_failed_list(&head);
-               return;
+               goto enable_all;
        }
 
        printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
@@ -919,5 +916,10 @@ again:
        free_failed_list(&head);
 
        goto again;
+
+enable_all:
+       retval = pci_reenable_device(bridge);
+       pci_set_master(bridge);
+       pci_enable_bridges(parent);
 }
 EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
index aa795fd428ded07fd01d25755fe6680e6091041c..eec9738f34927c7a3b87c6f9d647a5c3b1207877 100644 (file)
@@ -59,7 +59,6 @@ pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
               int (*map_irq)(struct pci_dev *, u8, u8))
 {
        struct pci_dev *dev = NULL;
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev)
                pdev_fixup_irq(dev, swizzle, map_irq);
-       }
 }
index d006e8beab9c5eb60a8cbd580f720c42aa59ab4a..7a2b1604bf1c18c8117518333fe0d8f1b9b36e9c 100644 (file)
@@ -7,7 +7,6 @@ pcmcia_core-$(CONFIG_CARDBUS)                   += cardbus.o
 obj-$(CONFIG_PCCARD)                           += pcmcia_core.o
 
 pcmcia-y                                       += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o
-pcmcia-$(CONFIG_PCMCIA_IOCTL)                  += pcmcia_ioctl.o
 obj-$(CONFIG_PCMCIA)                           += pcmcia.o
 
 pcmcia_rsrc-y                                  += rsrc_mgr.o
index a324d329dea65e55a6183eed448aa68a29b52ac3..67530cefcf3c1bfd5d36ea1f93068a841e2d5642 100644 (file)
@@ -23,7 +23,6 @@
 
 /* include the world */
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
index 5a979cb8f3e66a54fc7e1ea98548e92f9018b43d..807f2d75dad3a84f7b98142af3e52e812cc601bd 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/types.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
-#include <pcmcia/bus_ops.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 8844bc3e3118bb5e3fc846a02ddab06b1ac46414..91414a0ddc442823faebfb1db8b5420ba407630a 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cisreg.h>
@@ -54,6 +53,9 @@ static const u_int exponent[] = {
 /* Upper limit on reasonable # of tuples */
 #define MAX_TUPLES             200
 
+/* Bits in IRQInfo1 field */
+#define IRQ_INFO2_VALID                0x10
+
 /* 16-bit CIS? */
 static int cis_width;
 module_param(cis_width, int, 0444);
@@ -210,7 +212,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
  * Probably only useful for writing one-byte registers. Must be called
  * with ops_mutex held.
  */
-void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
+int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
                   u_int len, void *ptr)
 {
        void __iomem *sys, *end;
@@ -232,7 +234,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
                                ((cis_width) ? MAP_16BIT : 0));
                if (!sys) {
                        dev_dbg(&s->dev, "could not map memory\n");
-                       return; /* FIXME: Error */
+                       return -EINVAL;
                }
 
                writeb(flags, sys+CISREG_ICTRL0);
@@ -257,7 +259,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
                        sys = set_cis_map(s, card_offset, flags);
                        if (!sys) {
                                dev_dbg(&s->dev, "could not map memory\n");
-                               return; /* FIXME: error */
+                               return -EINVAL;
                        }
 
                        end = sys + s->map_size;
@@ -271,6 +273,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
                        addr = 0;
                }
        }
+       return 0;
 }
 
 
index 976d80706eae7931c8bbf8329febe4ce791d4af2..2ec8ac97445c1491d73102808de25dcf8e2c26bc 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/system.h>
 #include <asm/irq.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -252,38 +251,6 @@ struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr)
 }
 EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
 
-/*
- * The central event handler.  Send_event() sends an event to the
- * 16-bit subsystem, which then calls the relevant device drivers.
- * Parse_events() interprets the event bits from
- * a card status change report.  Do_shutdown() handles the high
- * priority stuff associated with a card removal.
- */
-
-/* NOTE: send_event needs to be called with skt->sem held. */
-
-static int send_event(struct pcmcia_socket *s, event_t event, int priority)
-{
-       int ret;
-
-       if ((s->state & SOCKET_CARDBUS) && (event != CS_EVENT_CARD_REMOVAL))
-               return 0;
-
-       dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
-          event, priority, s->callback);
-
-       if (!s->callback)
-               return 0;
-       if (!try_module_get(s->callback->owner))
-               return 0;
-
-       ret = s->callback->event(s, event, priority);
-
-       module_put(s->callback->owner);
-
-       return ret;
-}
-
 static int socket_reset(struct pcmcia_socket *skt)
 {
        int status, i;
@@ -326,7 +293,8 @@ static void socket_shutdown(struct pcmcia_socket *s)
 
        dev_dbg(&s->dev, "shutdown\n");
 
-       send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
+       if (s->callback)
+               s->callback->remove(s);
 
        mutex_lock(&s->ops_mutex);
        s->state &= SOCKET_INUSE | SOCKET_PRESENT;
@@ -477,7 +445,8 @@ static int socket_insert(struct pcmcia_socket *skt)
                dev_dbg(&skt->dev, "insert done\n");
                mutex_unlock(&skt->ops_mutex);
 
-               send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+               if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
+                       skt->callback->add(skt);
        } else {
                mutex_unlock(&skt->ops_mutex);
                socket_shutdown(skt);
@@ -494,7 +463,6 @@ static int socket_suspend(struct pcmcia_socket *skt)
        mutex_lock(&skt->ops_mutex);
        skt->suspended_state = skt->state;
 
-       send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
        skt->socket = dead_socket;
        skt->ops->set_socket(skt, &skt->socket);
        if (skt->ops->suspend)
@@ -555,8 +523,8 @@ static int socket_late_resume(struct pcmcia_socket *skt)
                return 0;
        }
 #endif
-
-       send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
+       if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
+               skt->callback->early_resume(skt);
        return 0;
 }
 
@@ -654,16 +622,8 @@ static int pccardd(void *__skt)
                spin_unlock_irqrestore(&skt->thread_lock, flags);
 
                mutex_lock(&skt->skt_mutex);
-               if (events) {
-                       if (events & SS_DETECT)
-                               socket_detect_change(skt);
-                       if (events & SS_BATDEAD)
-                               send_event(skt, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW);
-                       if (events & SS_BATWARN)
-                               send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
-                       if (events & SS_READY)
-                               send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
-               }
+               if (events & SS_DETECT)
+                       socket_detect_change(skt);
 
                if (sysfs_events) {
                        if (sysfs_events & PCMCIA_UEVENT_EJECT)
@@ -783,7 +743,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
                s->callback = c;
 
                if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT)
-                       send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+                       s->callback->add(s);
        } else
                s->callback = NULL;
  err:
@@ -823,20 +783,13 @@ int pcmcia_reset_card(struct pcmcia_socket *skt)
                        break;
                }
 
-               ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
-               if (ret == 0) {
-                       send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
-                       if (skt->callback)
-                               skt->callback->suspend(skt);
-                       mutex_lock(&skt->ops_mutex);
-                       ret = socket_reset(skt);
-                       mutex_unlock(&skt->ops_mutex);
-                       if (ret == 0) {
-                               send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
-                               if (skt->callback)
-                                       skt->callback->resume(skt);
-                       }
-               }
+               if (skt->callback)
+                       skt->callback->suspend(skt);
+               mutex_lock(&skt->ops_mutex);
+               ret = socket_reset(skt);
+               mutex_unlock(&skt->ops_mutex);
+               if ((ret == 0) && (skt->callback))
+                       skt->callback->resume(skt);
 
                ret = 0;
        } while (0);
index 4126a75445eab528c2d072da319e553ba51e75fd..da055dc14d98a2933953e206d9544d33cc74cb17 100644 (file)
@@ -10,7 +10,7 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * (C) 1999            David A. Hinds
- * (C) 2003 - 2008     Dominik Brodowski
+ * (C) 2003 - 2010     Dominik Brodowski
  *
  *
  * This file contains definitions _only_ needed by the PCMCIA core modules.
@@ -26,6 +26,9 @@
 /* Flags in client state */
 #define CLIENT_WIN_REQ(i)      (0x1<<(i))
 
+/* Flag to access all functions */
+#define BIND_FN_ALL    0xff
+
 /* Each card function gets one of these guys */
 typedef struct config_t {
        struct kref     ref;
@@ -35,7 +38,10 @@ typedef struct config_t {
        unsigned int    ConfigBase;
        unsigned char   Status, Pin, Copy, Option, ExtStatus;
        unsigned int    CardValues;
-       io_req_t        io;
+
+       struct resource io[MAX_IO_WIN]; /* io ports */
+       struct resource mem[MAX_WIN];   /* mem areas */
+
        struct {
                u_int   Attributes;
        } irq;
@@ -56,18 +62,11 @@ struct pccard_resource_ops {
                                         unsigned int attr,
                                         unsigned int *base,
                                         unsigned int num,
-                                        unsigned int align);
+                                        unsigned int align,
+                                        struct resource **parent);
        struct resource* (*find_mem)    (unsigned long base, unsigned long num,
                                         unsigned long align, int low,
                                         struct pcmcia_socket *s);
-       int     (*add_io)               (struct pcmcia_socket *s,
-                                        unsigned int action,
-                                        unsigned long r_start,
-                                        unsigned long r_end);
-       int     (*add_mem)              (struct pcmcia_socket *s,
-                                        unsigned int action,
-                                        unsigned long r_start,
-                                        unsigned long r_end);
        int     (*init)                 (struct pcmcia_socket *s);
        void    (*exit)                 (struct pcmcia_socket *s);
 };
@@ -114,11 +113,12 @@ void cb_free(struct pcmcia_socket *s);
 
 struct pcmcia_callback{
        struct module   *owner;
-       int             (*event) (struct pcmcia_socket *s,
-                                 event_t event, int priority);
+       int             (*add) (struct pcmcia_socket *s);
+       int             (*remove) (struct pcmcia_socket *s);
        void            (*requery) (struct pcmcia_socket *s);
        int             (*validate) (struct pcmcia_socket *s, unsigned int *i);
        int             (*suspend) (struct pcmcia_socket *s);
+       int             (*early_resume) (struct pcmcia_socket *s);
        int             (*resume) (struct pcmcia_socket *s);
 };
 
@@ -146,6 +146,8 @@ void pcmcia_put_socket(struct pcmcia_socket *skt);
 /* ds.c */
 extern struct bus_type pcmcia_bus_type;
 
+struct pcmcia_device;
+
 /* pcmcia_resource.c */
 extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
 extern int pcmcia_validate_mem(struct pcmcia_socket *s);
@@ -163,8 +165,8 @@ extern struct bin_attribute pccard_cis_attr;
 
 int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
                        u_int addr, u_int len, void *ptr);
-void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
-                         u_int addr, u_int len, void *ptr);
+int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
+                       u_int addr, u_int len, void *ptr);
 void release_cis_mem(struct pcmcia_socket *s);
 void destroy_cis_cache(struct pcmcia_socket *s);
 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
@@ -188,34 +190,4 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
 
 int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
 
-
-#ifdef CONFIG_PCMCIA_IOCTL
-/* ds.c */
-extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
-extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
-
-struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
-                                       unsigned int function);
-
-/* pcmcia_ioctl.c */
-extern void __init pcmcia_setup_ioctl(void);
-extern void __exit pcmcia_cleanup_ioctl(void);
-extern void handle_event(struct pcmcia_socket *s, event_t event);
-extern int handle_request(struct pcmcia_socket *s, event_t event);
-
-#else /* CONFIG_PCMCIA_IOCTL */
-
-static inline void __init pcmcia_setup_ioctl(void) { return; }
-static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
-static inline void handle_event(struct pcmcia_socket *s, event_t event)
-{
-       return;
-}
-static inline int handle_request(struct pcmcia_socket *s, event_t event)
-{
-       return 0;
-}
-
-#endif /* CONFIG_PCMCIA_IOCTL */
-
 #endif /* _LINUX_CS_INTERNAL_H */
index 0f4cc3f00028ec8d96f4df730c7f2b6fa31f7428..27575e6378a1a6259410e3882004cbb68a716281 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 
 #include <asm/mach-au1x00/au1000.h>
index eac961463be2db5b4013e152e1ede2bccf85c1d2..55570d9e1e4cc0246fe9c9add4583ccad5e3dae7 100644 (file)
@@ -10,7 +10,7 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * (C) 1999            David A. Hinds
- * (C) 2003 - 2006     Dominik Brodowski
+ * (C) 2003 - 2010     Dominik Brodowski
  */
 
 #include <linux/kernel.h>
@@ -26,7 +26,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -213,7 +212,7 @@ EXPORT_SYMBOL(pcmcia_unregister_driver);
 
 /* pcmcia_device handling */
 
-struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev)
+static struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev)
 {
        struct device *tmp_dev;
        tmp_dev = get_device(&p_dev->dev);
@@ -222,7 +221,7 @@ struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev)
        return to_pcmcia_dev(tmp_dev);
 }
 
-void pcmcia_put_dev(struct pcmcia_device *p_dev)
+static void pcmcia_put_dev(struct pcmcia_device *p_dev)
 {
        if (p_dev)
                put_device(&p_dev->dev);
@@ -294,7 +293,7 @@ static int pcmcia_device_probe(struct device *dev)
        }
 
        mutex_lock(&s->ops_mutex);
-       if ((s->pcmcia_state.has_pfc) &&
+       if ((s->pcmcia_pfc) &&
            (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
                pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
        mutex_unlock(&s->ops_mutex);
@@ -359,7 +358,7 @@ static int pcmcia_device_remove(struct device *dev)
         * pseudo multi-function card, we need to unbind
         * all devices
         */
-       if ((p_dev->socket->pcmcia_state.has_pfc) &&
+       if ((p_dev->socket->pcmcia_pfc) &&
            (p_dev->socket->device_count > 0) &&
            (p_dev->device_no == 0))
                pcmcia_card_remove(p_dev->socket, p_dev);
@@ -477,7 +476,8 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
 }
 
 
-struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
+static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
+                                              unsigned int function)
 {
        struct pcmcia_device *p_dev, *tmp_dev;
        int i;
@@ -531,7 +531,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
        list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
                if (p_dev->func == tmp_dev->func) {
                        p_dev->function_config = tmp_dev->function_config;
-                       p_dev->io = tmp_dev->io;
                        p_dev->irq = tmp_dev->irq;
                        kref_get(&p_dev->function_config->ref);
                }
@@ -544,15 +543,29 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
                        "IRQ setup failed -- device might not work\n");
 
        if (!p_dev->function_config) {
+               config_t *c;
                dev_dbg(&p_dev->dev, "creating config_t\n");
-               p_dev->function_config = kzalloc(sizeof(struct config_t),
-                                                GFP_KERNEL);
-               if (!p_dev->function_config) {
+               c = kzalloc(sizeof(struct config_t), GFP_KERNEL);
+               if (!c) {
                        mutex_unlock(&s->ops_mutex);
                        goto err_unreg;
                }
-               kref_init(&p_dev->function_config->ref);
+               p_dev->function_config = c;
+               kref_init(&c->ref);
+               for (i = 0; i < MAX_IO_WIN; i++) {
+                       c->io[i].name = p_dev->devname;
+                       c->io[i].flags = IORESOURCE_IO;
+               }
+               for (i = 0; i< MAX_WIN; i++) {
+                       c->mem[i].name = p_dev->devname;
+                       c->mem[i].flags = IORESOURCE_MEM;
+               }
        }
+       for (i = 0; i < MAX_IO_WIN; i++)
+               p_dev->resource[i] = &p_dev->function_config->io[i];
+       for (; i < (MAX_IO_WIN + MAX_WIN); i++)
+               p_dev->resource[i] = &p_dev->function_config->mem[i-MAX_IO_WIN];
+
        mutex_unlock(&s->ops_mutex);
 
        dev_printk(KERN_NOTICE, &p_dev->dev,
@@ -680,7 +693,7 @@ static void pcmcia_requery(struct pcmcia_socket *s)
         * call pcmcia_device_add() -- which will fail if both
         * devices are already registered. */
        mutex_lock(&s->ops_mutex);
-       has_pfc = s->pcmcia_state.has_pfc;
+       has_pfc = s->pcmcia_pfc;
        mutex_unlock(&s->ops_mutex);
        if (has_pfc)
                pcmcia_device_add(s, 0);
@@ -812,7 +825,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
                dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");
                mutex_lock(&dev->socket->ops_mutex);
-               dev->socket->pcmcia_state.has_pfc = 1;
+               dev->socket->pcmcia_pfc = 1;
                mutex_unlock(&dev->socket->ops_mutex);
                if (dev->device_no != did->device_no)
                        return 0;
@@ -826,7 +839,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
 
                /* if this is a pseudo-multi-function device,
                 * we need explicit matches */
-               if (dev->socket->pcmcia_state.has_pfc)
+               if (dev->socket->pcmcia_pfc)
                        return 0;
                if (dev->device_no)
                        return 0;
@@ -885,14 +898,6 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv)
        }
        mutex_unlock(&p_drv->dynids.lock);
 
-#ifdef CONFIG_PCMCIA_IOCTL
-       /* matching by cardmgr */
-       if (p_dev->cardmgr == p_drv) {
-               dev_dbg(dev, "cardmgr matched to %s\n", drv->name);
-               return 1;
-       }
-#endif
-
        while (did && did->match_flags) {
                dev_dbg(dev, "trying to match to %s\n", drv->name);
                if (pcmcia_devmatch(p_dev, did)) {
@@ -1006,6 +1011,18 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]);
 pcmcia_device_stringattr(prod_id3, prod_id[2]);
 pcmcia_device_stringattr(prod_id4, prod_id[3]);
 
+static ssize_t pcmcia_show_resources(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+       char *str = buf;
+       int i;
+
+       for (i = 0; i < PCMCIA_NUM_RESOURCES; i++)
+               str += sprintf(str, "%pr\n", p_dev->resource[i]);
+
+       return str - buf;
+}
 
 static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1076,6 +1093,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
 static struct device_attribute pcmcia_dev_attrs[] = {
        __ATTR(function, 0444, func_show, NULL),
        __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state),
+       __ATTR(resources, 0444, pcmcia_show_resources, NULL),
        __ATTR_RO(func_id),
        __ATTR_RO(manf_id),
        __ATTR_RO(card_id),
@@ -1215,86 +1233,57 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
        return 0;
 }
 
+static int pcmcia_bus_remove(struct pcmcia_socket *skt)
+{
+       atomic_set(&skt->present, 0);
+       pcmcia_card_remove(skt, NULL);
 
-/*======================================================================
+       mutex_lock(&skt->ops_mutex);
+       destroy_cis_cache(skt);
+       pcmcia_cleanup_irq(skt);
+       mutex_unlock(&skt->ops_mutex);
 
-    The card status event handler.
+       return 0;
+}
 
-======================================================================*/
+static int pcmcia_bus_add(struct pcmcia_socket *skt)
+{
+       atomic_set(&skt->present, 1);
 
-/* Normally, the event is passed to individual drivers after
- * informing userspace. Only for CS_EVENT_CARD_REMOVAL this
- * is inversed to maintain historic compatibility.
- */
+       mutex_lock(&skt->ops_mutex);
+       skt->pcmcia_pfc = 0;
+       destroy_cis_cache(skt); /* to be on the safe side... */
+       mutex_unlock(&skt->ops_mutex);
 
-static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
-{
-       struct pcmcia_socket *s = pcmcia_get_socket(skt);
+       pcmcia_card_add(skt);
 
-       if (!s) {
-               dev_printk(KERN_ERR, &skt->dev,
-                          "PCMCIA obtaining reference to socket "      \
-                          "failed, event 0x%x lost!\n", event);
-               return -ENODEV;
-       }
+       return 0;
+}
 
-       dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
-                  event, priority, skt);
+static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
+{
+       if (!verify_cis_cache(skt)) {
+               pcmcia_put_socket(skt);
+               return 0;
+       }
 
-       switch (event) {
-       case CS_EVENT_CARD_REMOVAL:
-               atomic_set(&skt->present, 0);
-               pcmcia_card_remove(skt, NULL);
-               handle_event(skt, event);
-               mutex_lock(&s->ops_mutex);
-               destroy_cis_cache(s);
-               pcmcia_cleanup_irq(s);
-               mutex_unlock(&s->ops_mutex);
-               break;
+       dev_dbg(&skt->dev, "cis mismatch - different card\n");
 
-       case CS_EVENT_CARD_INSERTION:
-               atomic_set(&skt->present, 1);
-               mutex_lock(&s->ops_mutex);
-               s->pcmcia_state.has_pfc = 0;
-               destroy_cis_cache(s); /* to be on the safe side... */
-               mutex_unlock(&s->ops_mutex);
-               pcmcia_card_add(skt);
-               handle_event(skt, event);
-               break;
-
-       case CS_EVENT_EJECTION_REQUEST:
-               break;
-
-       case CS_EVENT_PM_RESUME:
-               if (verify_cis_cache(skt) != 0) {
-                       dev_dbg(&skt->dev, "cis mismatch - different card\n");
-                       /* first, remove the card */
-                       ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
-                       mutex_lock(&s->ops_mutex);
-                       destroy_cis_cache(skt);
-                       kfree(skt->fake_cis);
-                       skt->fake_cis = NULL;
-                       s->functions = 0;
-                       mutex_unlock(&s->ops_mutex);
-                       /* now, add the new card */
-                       ds_event(skt, CS_EVENT_CARD_INSERTION,
-                                CS_EVENT_PRI_LOW);
-               }
-               handle_event(skt, event);
-               break;
+       /* first, remove the card */
+       pcmcia_bus_remove(skt);
 
-       case CS_EVENT_PM_SUSPEND:
-       case CS_EVENT_RESET_PHYSICAL:
-       case CS_EVENT_CARD_RESET:
-       default:
-               handle_event(skt, event);
-               break;
-    }
+       mutex_lock(&skt->ops_mutex);
+       destroy_cis_cache(skt);
+       kfree(skt->fake_cis);
+       skt->fake_cis = NULL;
+       skt->functions = 0;
+       mutex_unlock(&skt->ops_mutex);
 
-    pcmcia_put_socket(s);
+       /* now, add the new card */
+       pcmcia_bus_add(skt);
+       return 0;
+}
 
-    return 0;
-} /* ds_event */
 
 /*
  * NOTE: This is racy. There's no guarantee the card will still be
@@ -1323,10 +1312,12 @@ EXPORT_SYMBOL(pcmcia_dev_present);
 
 static struct pcmcia_callback pcmcia_bus_callback = {
        .owner = THIS_MODULE,
-       .event = ds_event,
+       .add = pcmcia_bus_add,
+       .remove = pcmcia_bus_remove,
        .requery = pcmcia_requery,
        .validate = pccard_validate_cis,
        .suspend = pcmcia_bus_suspend,
+       .early_resume = pcmcia_bus_early_resume,
        .resume = pcmcia_bus_resume,
 };
 
@@ -1350,11 +1341,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
                return ret;
        }
 
-#ifdef CONFIG_PCMCIA_IOCTL
-       init_waitqueue_head(&socket->queue);
-#endif
        INIT_LIST_HEAD(&socket->devices_list);
-       memset(&socket->pcmcia_state, 0, sizeof(u8));
+       socket->pcmcia_pfc = 0;
        socket->device_count = 0;
        atomic_set(&socket->present, 0);
 
@@ -1429,8 +1417,6 @@ static int __init init_pcmcia_bus(void)
                return ret;
        }
 
-       pcmcia_setup_ioctl();
-
        return 0;
 }
 fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
@@ -1439,8 +1425,6 @@ fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
 
 static void __exit exit_pcmcia_bus(void)
 {
-       pcmcia_cleanup_ioctl();
-
        class_interface_unregister(&pcmcia_bus_interface);
 
        bus_unregister(&pcmcia_bus_type);
index 3003bb3dfcc0d08912897b2192e732ea26cccbf3..05d0879ce93568194f36f393cb951b43f3155bc8 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
index 9e2a15628de57af889115628a3c9e4aaca7e4a60..61746bd598b36a58d1ee5c5c5a87e48b740532cc 100644 (file)
@@ -50,7 +50,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
index 7e16ed8eb0a4e0b9ee3b425636fc2d52f0dd5ee1..24de499258630e2e6442ac0045134fa647fd0746 100644 (file)
@@ -26,7 +26,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
index 6c5c3f910d71435ff542c71eab7e6a0285abfc42..8e4723844ad3a2bb447de65e70ea236e2d22e3ef 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/system.h>
 #include <asm/addrspace.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
index 25e5e30a18afdd6bafaae72e1c06314f42c9efb0..f2f90a7d3e12279b0684dfc903a95ae2ed2c6893 100644 (file)
@@ -59,7 +59,6 @@
 #include <asm/irq.h>
 #include <asm/fs_pd.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 
index 4a65eaf96b0a19a8906605cc8cf06b09b88f9524..0ac54da158850352c766cebd9c5a502b5b7e65e0 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
deleted file mode 100644 (file)
index d007a2a..0000000
+++ /dev/null
@@ -1,1077 +0,0 @@
-/*
- * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
- *
- * (C) 1999            David A. Hinds
- * (C) 2003 - 2004     Dominik Brodowski
- */
-
-/*
- * This file will go away soon.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/ioctl.h>
-#include <linux/proc_fs.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
-#include <linux/workqueue.h>
-
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/ss.h>
-
-#include "cs_internal.h"
-
-static int major_dev = -1;
-
-
-/* Device user information */
-#define MAX_EVENTS     32
-#define USER_MAGIC     0x7ea4
-#define CHECK_USER(u) \
-    (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
-
-typedef struct user_info_t {
-       u_int                   user_magic;
-       int                     event_head, event_tail;
-       event_t                 event[MAX_EVENTS];
-       struct user_info_t      *next;
-       struct pcmcia_socket    *socket;
-} user_info_t;
-
-
-static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
-                                               unsigned int function)
-{
-       struct pcmcia_device *p_dev = NULL;
-
-       mutex_lock(&s->ops_mutex);
-       list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-               if (p_dev->func == function) {
-                       mutex_unlock(&s->ops_mutex);
-                       return pcmcia_get_dev(p_dev);
-               }
-       }
-       mutex_unlock(&s->ops_mutex);
-       return NULL;
-}
-
-/* backwards-compatible accessing of driver --- by name! */
-
-static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
-{
-       struct device_driver *drv;
-       struct pcmcia_driver *p_drv;
-
-       drv = driver_find((char *) dev_info, &pcmcia_bus_type);
-       if (!drv)
-               return NULL;
-
-       p_drv = container_of(drv, struct pcmcia_driver, drv);
-
-       return p_drv;
-}
-
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_pccard;
-
-static int proc_read_drivers_callback(struct device_driver *driver, void *_m)
-{
-       struct seq_file *m = _m;
-       struct pcmcia_driver *p_drv = container_of(driver,
-                                                  struct pcmcia_driver, drv);
-
-       seq_printf(m, "%-24.24s 1 %d\n", p_drv->drv.name,
-#ifdef CONFIG_MODULE_UNLOAD
-                     (p_drv->owner) ? module_refcount(p_drv->owner) : 1
-#else
-                     1
-#endif
-       );
-       return 0;
-}
-
-static int pccard_drivers_proc_show(struct seq_file *m, void *v)
-{
-       return bus_for_each_drv(&pcmcia_bus_type, NULL,
-                               m, proc_read_drivers_callback);
-}
-
-static int pccard_drivers_proc_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, pccard_drivers_proc_show, NULL);
-}
-
-static const struct file_operations pccard_drivers_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = pccard_drivers_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-#endif
-
-
-#ifdef CONFIG_PCMCIA_PROBE
-
-static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
-{
-       int irq;
-       u32 mask;
-
-       irq = adj->resource.irq.IRQ;
-       if ((irq < 0) || (irq > 15))
-               return -EINVAL;
-
-       if (adj->Action != REMOVE_MANAGED_RESOURCE)
-               return 0;
-
-       mask = 1 << irq;
-
-       if (!(s->irq_mask & mask))
-               return 0;
-
-       s->irq_mask &= ~mask;
-
-       return 0;
-}
-
-#else
-
-static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
-{
-       return 0;
-}
-
-#endif
-
-static int pcmcia_adjust_resource_info(adjust_t *adj)
-{
-       struct pcmcia_socket *s;
-       int ret = -ENOSYS;
-
-       down_read(&pcmcia_socket_list_rwsem);
-       list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
-
-               if (adj->Resource == RES_IRQ)
-                       ret = adjust_irq(s, adj);
-
-               else if (s->resource_ops->add_io) {
-                       unsigned long begin, end;
-
-                       /* you can't use the old interface if the new
-                        * one was used before */
-                       mutex_lock(&s->ops_mutex);
-                       if ((s->resource_setup_new) &&
-                           !(s->resource_setup_old)) {
-                               mutex_unlock(&s->ops_mutex);
-                               continue;
-                       } else if (!(s->resource_setup_old))
-                               s->resource_setup_old = 1;
-
-                       switch (adj->Resource) {
-                       case RES_MEMORY_RANGE:
-                               begin = adj->resource.memory.Base;
-                               end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
-                               if (s->resource_ops->add_mem)
-                                       ret = s->resource_ops->add_mem(s, adj->Action, begin, end);
-                       case RES_IO_RANGE:
-                               begin = adj->resource.io.BasePort;
-                               end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
-                               if (s->resource_ops->add_io)
-                                       ret = s->resource_ops->add_io(s, adj->Action, begin, end);
-                       }
-                       if (!ret) {
-                               /* as there's no way we know this is the
-                                * last call to adjust_resource_info, we
-                                * always need to assume this is the latest
-                                * one... */
-                               s->resource_setup_done = 1;
-                       }
-                       mutex_unlock(&s->ops_mutex);
-               }
-       }
-       up_read(&pcmcia_socket_list_rwsem);
-
-       return ret;
-}
-
-
-/** pcmcia_get_window
- */
-static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
-                       window_handle_t wh, win_req_t *req)
-{
-       pccard_mem_map *win;
-       window_handle_t w;
-
-       wh--;
-       if (!s || !(s->state & SOCKET_PRESENT))
-               return -ENODEV;
-       if (wh >= MAX_WIN)
-               return -EINVAL;
-       for (w = wh; w < MAX_WIN; w++)
-               if (s->state & SOCKET_WIN_REQ(w))
-                       break;
-       if (w == MAX_WIN)
-               return -EINVAL;
-       win = &s->win[w];
-       req->Base = win->res->start;
-       req->Size = win->res->end - win->res->start + 1;
-       req->AccessSpeed = win->speed;
-       req->Attributes = 0;
-       if (win->flags & MAP_ATTRIB)
-               req->Attributes |= WIN_MEMORY_TYPE_AM;
-       if (win->flags & MAP_ACTIVE)
-               req->Attributes |= WIN_ENABLE;
-       if (win->flags & MAP_16BIT)
-               req->Attributes |= WIN_DATA_WIDTH_16;
-       if (win->flags & MAP_USE_WAIT)
-               req->Attributes |= WIN_USE_WAIT;
-
-       *wh_out = w + 1;
-       return 0;
-} /* pcmcia_get_window */
-
-
-/** pcmcia_get_mem_page
- *
- * Change the card address of an already open memory window.
- */
-static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
-                       memreq_t *req)
-{
-       wh--;
-       if (wh >= MAX_WIN)
-               return -EINVAL;
-
-       req->Page = 0;
-       req->CardOffset = skt->win[wh].card_start;
-       return 0;
-} /* pcmcia_get_mem_page */
-
-
-/** pccard_get_status
- *
- * Get the current socket state bits.  We don't support the latched
- * SocketState yet: I haven't seen any point for it.
- */
-
-static int pccard_get_status(struct pcmcia_socket *s,
-                            struct pcmcia_device *p_dev,
-                            cs_status_t *status)
-{
-       config_t *c;
-       int val;
-
-       s->ops->get_status(s, &val);
-       status->CardState = status->SocketState = 0;
-       status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
-       status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
-       status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
-       status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
-       if (s->state & SOCKET_SUSPEND)
-               status->CardState |= CS_EVENT_PM_SUSPEND;
-       if (!(s->state & SOCKET_PRESENT))
-               return -ENODEV;
-
-       c = (p_dev) ? p_dev->function_config : NULL;
-
-       if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
-           (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
-               u_char reg;
-               if (c->CardValues & PRESENT_PIN_REPLACE) {
-                       mutex_lock(&s->ops_mutex);
-                       pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
-                       mutex_unlock(&s->ops_mutex);
-                       status->CardState |=
-                               (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
-                       status->CardState |=
-                               (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
-                       status->CardState |=
-                               (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
-                       status->CardState |=
-                               (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
-               } else {
-                       /* No PRR?  Then assume we're always ready */
-                       status->CardState |= CS_EVENT_READY_CHANGE;
-               }
-               if (c->CardValues & PRESENT_EXT_STATUS) {
-                       mutex_lock(&s->ops_mutex);
-                       pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
-                       mutex_unlock(&s->ops_mutex);
-                       status->CardState |=
-                               (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
-               }
-               return 0;
-       }
-       status->CardState |=
-               (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
-       status->CardState |=
-               (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
-       status->CardState |=
-               (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
-       status->CardState |=
-               (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
-       return 0;
-} /* pccard_get_status */
-
-static int pccard_get_configuration_info(struct pcmcia_socket *s,
-                                 struct pcmcia_device *p_dev,
-                                 config_info_t *config)
-{
-       config_t *c;
-
-       if (!(s->state & SOCKET_PRESENT))
-               return -ENODEV;
-
-
-#ifdef CONFIG_CARDBUS
-       if (s->state & SOCKET_CARDBUS) {
-               memset(config, 0, sizeof(config_info_t));
-               config->Vcc = s->socket.Vcc;
-               config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-               config->Option = s->cb_dev->subordinate->number;
-               if (s->state & SOCKET_CARDBUS_CONFIG) {
-                       config->Attributes = CONF_VALID_CLIENT;
-                       config->IntType = INT_CARDBUS;
-                       config->AssignedIRQ = s->pcmcia_irq;
-                       if (config->AssignedIRQ)
-                               config->Attributes |= CONF_ENABLE_IRQ;
-                       if (s->io[0].res) {
-                               config->BasePort1 = s->io[0].res->start;
-                               config->NumPorts1 = s->io[0].res->end -
-                                       config->BasePort1 + 1;
-                       }
-               }
-               return 0;
-       }
-#endif
-
-       if (p_dev) {
-               c = p_dev->function_config;
-               config->Function = p_dev->func;
-       } else {
-               c = NULL;
-               config->Function = 0;
-       }
-
-       if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
-               config->Attributes = 0;
-               config->Vcc = s->socket.Vcc;
-               config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-               return 0;
-       }
-
-       config->Attributes = c->Attributes | CONF_VALID_CLIENT;
-       config->Vcc = s->socket.Vcc;
-       config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-       config->IntType = c->IntType;
-       config->ConfigBase = c->ConfigBase;
-       config->Status = c->Status;
-       config->Pin = c->Pin;
-       config->Copy = c->Copy;
-       config->Option = c->Option;
-       config->ExtStatus = c->ExtStatus;
-       config->Present = config->CardValues = c->CardValues;
-       config->IRQAttributes = c->irq.Attributes;
-       config->AssignedIRQ = s->pcmcia_irq;
-       config->BasePort1 = c->io.BasePort1;
-       config->NumPorts1 = c->io.NumPorts1;
-       config->Attributes1 = c->io.Attributes1;
-       config->BasePort2 = c->io.BasePort2;
-       config->NumPorts2 = c->io.NumPorts2;
-       config->Attributes2 = c->io.Attributes2;
-       config->IOAddrLines = c->io.IOAddrLines;
-
-       return 0;
-} /* pccard_get_configuration_info */
-
-
-/*======================================================================
-
-    These manage a ring buffer of events pending for one user process
-
-======================================================================*/
-
-
-static int queue_empty(user_info_t *user)
-{
-    return (user->event_head == user->event_tail);
-}
-
-static event_t get_queued_event(user_info_t *user)
-{
-    user->event_tail = (user->event_tail+1) % MAX_EVENTS;
-    return user->event[user->event_tail];
-}
-
-static void queue_event(user_info_t *user, event_t event)
-{
-    user->event_head = (user->event_head+1) % MAX_EVENTS;
-    if (user->event_head == user->event_tail)
-       user->event_tail = (user->event_tail+1) % MAX_EVENTS;
-    user->event[user->event_head] = event;
-}
-
-void handle_event(struct pcmcia_socket *s, event_t event)
-{
-    user_info_t *user;
-    for (user = s->user; user; user = user->next)
-       queue_event(user, event);
-    wake_up_interruptible(&s->queue);
-}
-
-
-/*======================================================================
-
-    bind_request() and bind_device() are merged by now. Register_client()
-    is called right at the end of bind_request(), during the driver's
-    ->attach() call. Individual descriptions:
-
-    bind_request() connects a socket to a particular client driver.
-    It looks up the specified device ID in the list of registered
-    drivers, binds it to the socket, and tries to create an instance
-    of the device.  unbind_request() deletes a driver instance.
-
-    Bind_device() associates a device driver with a particular socket.
-    It is normally called by Driver Services after it has identified
-    a newly inserted card.  An instance of that driver will then be
-    eligible to register as a client of this socket.
-
-    Register_client() uses the dev_info_t handle to match the
-    caller with a socket.  The driver must have already been bound
-    to a socket with bind_device() -- in fact, bind_device()
-    allocates the client structure that will be used.
-
-======================================================================*/
-
-static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
-{
-       struct pcmcia_driver *p_drv;
-       struct pcmcia_device *p_dev;
-       int ret = 0;
-
-       s = pcmcia_get_socket(s);
-       if (!s)
-               return -EINVAL;
-
-       pr_debug("bind_request(%d, '%s')\n", s->sock,
-              (char *)bind_info->dev_info);
-
-       p_drv = get_pcmcia_driver(&bind_info->dev_info);
-       if (!p_drv) {
-               ret = -EINVAL;
-               goto err_put;
-       }
-
-       if (!try_module_get(p_drv->owner)) {
-               ret = -EINVAL;
-               goto err_put_driver;
-       }
-
-       mutex_lock(&s->ops_mutex);
-       list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-               if (p_dev->func == bind_info->function) {
-                       if ((p_dev->dev.driver == &p_drv->drv)) {
-                               if (p_dev->cardmgr) {
-                                       /* if there's already a device
-                                        * registered, and it was registered
-                                        * by userspace before, we need to
-                                        * return the "instance". */
-                                       mutex_unlock(&s->ops_mutex);
-                                       bind_info->instance = p_dev;
-                                       ret = -EBUSY;
-                                       goto err_put_module;
-                               } else {
-                                       /* the correct driver managed to bind
-                                        * itself magically to the correct
-                                        * device. */
-                                       mutex_unlock(&s->ops_mutex);
-                                       p_dev->cardmgr = p_drv;
-                                       ret = 0;
-                                       goto err_put_module;
-                               }
-                       } else if (!p_dev->dev.driver) {
-                               /* there's already a device available where
-                                * no device has been bound to yet. So we don't
-                                * need to register a device! */
-                               mutex_unlock(&s->ops_mutex);
-                               goto rescan;
-                       }
-               }
-       }
-       mutex_unlock(&s->ops_mutex);
-
-       p_dev = pcmcia_device_add(s, bind_info->function);
-       if (!p_dev) {
-               ret = -EIO;
-               goto err_put_module;
-       }
-
-rescan:
-       p_dev->cardmgr = p_drv;
-
-       /* if a driver is already running, we can abort */
-       if (p_dev->dev.driver)
-               goto err_put_module;
-
-       /*
-        * Prevent this racing with a card insertion.
-        */
-       mutex_lock(&s->skt_mutex);
-       ret = bus_rescan_devices(&pcmcia_bus_type);
-       mutex_unlock(&s->skt_mutex);
-       if (ret)
-               goto err_put_module;
-
-       /* check whether the driver indeed matched. I don't care if this
-        * is racy or not, because it can only happen on cardmgr access
-        * paths...
-        */
-       if (!(p_dev->dev.driver == &p_drv->drv))
-               p_dev->cardmgr = NULL;
-
- err_put_module:
-       module_put(p_drv->owner);
- err_put_driver:
-       put_driver(&p_drv->drv);
- err_put:
-       pcmcia_put_socket(s);
-
-       return ret;
-} /* bind_request */
-
-#ifdef CONFIG_CARDBUS
-
-static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
-{
-       if (!s || !(s->state & SOCKET_CARDBUS))
-               return NULL;
-
-       return s->cb_dev->subordinate;
-}
-#endif
-
-static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
-{
-       struct pcmcia_device *p_dev;
-       struct pcmcia_driver *p_drv;
-       int ret = 0;
-
-#ifdef CONFIG_CARDBUS
-       /*
-        * Some unbelievably ugly code to associate the PCI cardbus
-        * device and its driver with the PCMCIA "bind" information.
-        */
-       {
-               struct pci_bus *bus;
-
-               bus = pcmcia_lookup_bus(s);
-               if (bus) {
-                       struct list_head *list;
-                       struct pci_dev *dev = NULL;
-
-                       list = bus->devices.next;
-                       while (list != &bus->devices) {
-                               struct pci_dev *pdev = pci_dev_b(list);
-                               list = list->next;
-
-                               if (first) {
-                                       dev = pdev;
-                                       break;
-                               }
-
-                               /* Try to handle "next" here some way? */
-                       }
-                       if (dev && dev->driver) {
-                               strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
-                               bind_info->major = 0;
-                               bind_info->minor = 0;
-                               bind_info->next = NULL;
-                               return 0;
-                       }
-               }
-       }
-#endif
-
-       mutex_lock(&s->ops_mutex);
-       list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-               if (p_dev->func == bind_info->function) {
-                       p_dev = pcmcia_get_dev(p_dev);
-                       if (!p_dev)
-                               continue;
-                       goto found;
-               }
-       }
-       mutex_unlock(&s->ops_mutex);
-       return -ENODEV;
-
- found:
-       mutex_unlock(&s->ops_mutex);
-
-       p_drv = to_pcmcia_drv(p_dev->dev.driver);
-       if (p_drv && !p_dev->_locked) {
-               ret = -EAGAIN;
-               goto err_put;
-       }
-
-       if (!first) {
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       strlcpy(bind_info->name, dev_name(&p_dev->dev), DEV_NAME_LEN);
-       bind_info->next = NULL;
-
- err_put:
-       pcmcia_put_dev(p_dev);
-       return ret;
-} /* get_device_info */
-
-
-static int ds_open(struct inode *inode, struct file *file)
-{
-    socket_t i = iminor(inode);
-    struct pcmcia_socket *s;
-    user_info_t *user;
-    static int warning_printed;
-    int ret = 0;
-
-    pr_debug("ds_open(socket %d)\n", i);
-
-    lock_kernel();
-    s = pcmcia_get_socket_by_nr(i);
-    if (!s) {
-           ret = -ENODEV;
-           goto out;
-    }
-    s = pcmcia_get_socket(s);
-    if (!s) {
-           ret = -ENODEV;
-           goto out;
-    }
-
-    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
-           if (s->pcmcia_state.busy) {
-                   pcmcia_put_socket(s);
-                   ret = -EBUSY;
-                   goto out;
-           }
-       else
-           s->pcmcia_state.busy = 1;
-    }
-
-    user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
-    if (!user) {
-           pcmcia_put_socket(s);
-           ret = -ENOMEM;
-           goto out;
-    }
-    user->event_tail = user->event_head = 0;
-    user->next = s->user;
-    user->user_magic = USER_MAGIC;
-    user->socket = s;
-    s->user = user;
-    file->private_data = user;
-
-    if (!warning_printed) {
-           printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
-                       "usage from process: %s.\n", current->comm);
-           printk(KERN_INFO "pcmcia: This interface will soon be removed from "
-                       "the kernel; please expect breakage unless you upgrade "
-                       "to new tools.\n");
-           printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
-                       "utils/kernel/pcmcia/pcmcia.html for details.\n");
-           warning_printed = 1;
-    }
-
-    if (atomic_read(&s->present))
-       queue_event(user, CS_EVENT_CARD_INSERTION);
-out:
-    unlock_kernel();
-    return ret;
-} /* ds_open */
-
-/*====================================================================*/
-
-static int ds_release(struct inode *inode, struct file *file)
-{
-    struct pcmcia_socket *s;
-    user_info_t *user, **link;
-
-    pr_debug("ds_release(socket %d)\n", iminor(inode));
-
-    user = file->private_data;
-    if (CHECK_USER(user))
-       goto out;
-
-    s = user->socket;
-
-    /* Unlink user data structure */
-    if ((file->f_flags & O_ACCMODE) != O_RDONLY)
-       s->pcmcia_state.busy = 0;
-
-    file->private_data = NULL;
-    for (link = &s->user; *link; link = &(*link)->next)
-       if (*link == user)
-               break;
-    if (link == NULL)
-       goto out;
-    *link = user->next;
-    user->user_magic = 0;
-    kfree(user);
-    pcmcia_put_socket(s);
-out:
-    return 0;
-} /* ds_release */
-
-/*====================================================================*/
-
-static ssize_t ds_read(struct file *file, char __user *buf,
-                      size_t count, loff_t *ppos)
-{
-    struct pcmcia_socket *s;
-    user_info_t *user;
-    int ret;
-
-    pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
-
-    if (count < 4)
-       return -EINVAL;
-
-    user = file->private_data;
-    if (CHECK_USER(user))
-       return -EIO;
-
-    s = user->socket;
-    ret = wait_event_interruptible(s->queue, !queue_empty(user));
-    if (ret == 0)
-       ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
-
-    return ret;
-} /* ds_read */
-
-/*====================================================================*/
-
-static ssize_t ds_write(struct file *file, const char __user *buf,
-                       size_t count, loff_t *ppos)
-{
-    pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
-
-    if (count != 4)
-       return -EINVAL;
-    if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-       return -EBADF;
-
-    return -EIO;
-} /* ds_write */
-
-/*====================================================================*/
-
-/* No kernel lock - fine */
-static u_int ds_poll(struct file *file, poll_table *wait)
-{
-    struct pcmcia_socket *s;
-    user_info_t *user;
-
-    pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
-
-    user = file->private_data;
-    if (CHECK_USER(user))
-       return POLLERR;
-    s = user->socket;
-    /*
-     * We don't check for a dead socket here since that
-     * will send cardmgr into an endless spin.
-     */
-    poll_wait(file, &s->queue, wait);
-    if (!queue_empty(user))
-       return POLLIN | POLLRDNORM;
-    return 0;
-} /* ds_poll */
-
-/*====================================================================*/
-
-static int ds_ioctl(struct file *file, u_int cmd, u_long arg)
-{
-    struct pcmcia_socket *s;
-    void __user *uarg = (char __user *)arg;
-    u_int size;
-    int ret, err;
-    ds_ioctl_arg_t *buf;
-    user_info_t *user;
-
-    pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
-
-    user = file->private_data;
-    if (CHECK_USER(user))
-       return -EIO;
-
-    s = user->socket;
-
-    size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
-    if (size > sizeof(ds_ioctl_arg_t))
-       return -EINVAL;
-
-    /* Permission check */
-    if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
-       return -EPERM;
-
-    if (cmd & IOC_IN) {
-       if (!access_ok(VERIFY_READ, uarg, size)) {
-           pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
-           return -EFAULT;
-       }
-    }
-    if (cmd & IOC_OUT) {
-       if (!access_ok(VERIFY_WRITE, uarg, size)) {
-           pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
-           return -EFAULT;
-       }
-    }
-    buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
-    if (!buf)
-       return -ENOMEM;
-
-    err = ret = 0;
-
-    if (cmd & IOC_IN) {
-       if (__copy_from_user((char *)buf, uarg, size)) {
-           err = -EFAULT;
-           goto free_out;
-       }
-    }
-
-    switch (cmd) {
-    case DS_ADJUST_RESOURCE_INFO:
-       ret = pcmcia_adjust_resource_info(&buf->adjust);
-       break;
-    case DS_GET_CONFIGURATION_INFO:
-       if (buf->config.Function &&
-          (buf->config.Function >= s->functions))
-           ret = -EINVAL;
-       else {
-           struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
-           ret = pccard_get_configuration_info(s, p_dev, &buf->config);
-           pcmcia_put_dev(p_dev);
-       }
-       break;
-    case DS_GET_FIRST_TUPLE:
-       mutex_lock(&s->skt_mutex);
-       pcmcia_validate_mem(s);
-       mutex_unlock(&s->skt_mutex);
-       ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
-       break;
-    case DS_GET_NEXT_TUPLE:
-       ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
-       break;
-    case DS_GET_TUPLE_DATA:
-       buf->tuple.TupleData = buf->tuple_parse.data;
-       buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
-       ret = pccard_get_tuple_data(s, &buf->tuple);
-       break;
-    case DS_PARSE_TUPLE:
-       buf->tuple.TupleData = buf->tuple_parse.data;
-       ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
-       break;
-    case DS_RESET_CARD:
-       ret = pcmcia_reset_card(s);
-       break;
-    case DS_GET_STATUS:
-           if (buf->status.Function &&
-               (buf->status.Function >= s->functions))
-                   ret = -EINVAL;
-           else {
-                   struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
-                   ret = pccard_get_status(s, p_dev, &buf->status);
-                   pcmcia_put_dev(p_dev);
-           }
-           break;
-    case DS_VALIDATE_CIS:
-       mutex_lock(&s->skt_mutex);
-       pcmcia_validate_mem(s);
-       mutex_unlock(&s->skt_mutex);
-       ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
-       break;
-    case DS_SUSPEND_CARD:
-       pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
-       break;
-    case DS_RESUME_CARD:
-       pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
-       break;
-    case DS_EJECT_CARD:
-       pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
-       break;
-    case DS_INSERT_CARD:
-       pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
-       break;
-    case DS_ACCESS_CONFIGURATION_REGISTER:
-       if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
-           err = -EPERM;
-           goto free_out;
-       }
-
-       ret = -EINVAL;
-
-       if (!(buf->conf_reg.Function &&
-            (buf->conf_reg.Function >= s->functions))) {
-               struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
-               if (p_dev) {
-                       ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
-                       pcmcia_put_dev(p_dev);
-               }
-       }
-       break;
-    case DS_GET_FIRST_REGION:
-    case DS_GET_NEXT_REGION:
-    case DS_BIND_MTD:
-       if (!capable(CAP_SYS_ADMIN)) {
-               err = -EPERM;
-               goto free_out;
-       } else {
-                       printk_once(KERN_WARNING
-                               "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
-                       printk_once(KERN_WARNING "MTD handling any more.\n");
-       }
-       err = -EINVAL;
-       goto free_out;
-       break;
-    case DS_GET_FIRST_WINDOW:
-       ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
-                       &buf->win_info.window);
-       break;
-    case DS_GET_NEXT_WINDOW:
-       ret = pcmcia_get_window(s, &buf->win_info.handle,
-                       buf->win_info.handle + 1, &buf->win_info.window);
-       break;
-    case DS_GET_MEM_PAGE:
-       ret = pcmcia_get_mem_page(s, buf->win_info.handle,
-                          &buf->win_info.map);
-       break;
-    case DS_REPLACE_CIS:
-       ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
-       break;
-    case DS_BIND_REQUEST:
-       if (!capable(CAP_SYS_ADMIN)) {
-               err = -EPERM;
-               goto free_out;
-       }
-       err = bind_request(s, &buf->bind_info);
-       break;
-    case DS_GET_DEVICE_INFO:
-       err = get_device_info(s, &buf->bind_info, 1);
-       break;
-    case DS_GET_NEXT_DEVICE:
-       err = get_device_info(s, &buf->bind_info, 0);
-       break;
-    case DS_UNBIND_REQUEST:
-       err = 0;
-       break;
-    default:
-       err = -EINVAL;
-    }
-
-    if ((err == 0) && (ret != 0)) {
-       pr_debug("ds_ioctl: ret = %d\n", ret);
-       switch (ret) {
-       case -ENODEV:
-       case -EINVAL:
-       case -EBUSY:
-       case -ENOSYS:
-           err = ret;
-           break;
-       case -ENOMEM:
-           err = -ENOSPC; break;
-       case -ENOSPC:
-           err = -ENODATA; break;
-       default:
-           err = -EIO; break;
-       }
-    }
-
-    if (cmd & IOC_OUT) {
-       if (__copy_to_user(uarg, (char *)buf, size))
-               err = -EFAULT;
-    }
-
-free_out:
-    kfree(buf);
-    return err;
-} /* ds_ioctl */
-
-static long ds_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       int ret;
-
-       lock_kernel();
-       ret = ds_ioctl(file, cmd, arg);
-       unlock_kernel();
-
-       return ret;
-}
-
-
-/*====================================================================*/
-
-static const struct file_operations ds_fops = {
-       .owner          = THIS_MODULE,
-       .open           = ds_open,
-       .release        = ds_release,
-       .unlocked_ioctl = ds_unlocked_ioctl,
-       .read           = ds_read,
-       .write          = ds_write,
-       .poll           = ds_poll,
-};
-
-void __init pcmcia_setup_ioctl(void)
-{
-       int i;
-
-       /* Set up character device for user mode clients */
-       i = register_chrdev(0, "pcmcia", &ds_fops);
-       if (i < 0)
-               printk(KERN_NOTICE "unable to find a free device # for "
-                      "Driver Services (error=%d)\n", i);
-       else
-               major_dev = i;
-
-#ifdef CONFIG_PROC_FS
-       proc_pccard = proc_mkdir("bus/pccard", NULL);
-       if (proc_pccard)
-               proc_create("drivers", 0, proc_pccard, &pccard_drivers_proc_fops);
-#endif
-}
-
-
-void __exit pcmcia_cleanup_ioctl(void)
-{
-#ifdef CONFIG_PROC_FS
-       if (proc_pccard) {
-               remove_proc_entry("drivers", proc_pccard);
-               remove_proc_entry("bus/pccard", NULL);
-       }
-#endif
-       if (major_dev != -1)
-               unregister_chrdev(major_dev, "pcmcia");
-}
index a4cd9adfcbc0a543462158b76a796a7f96aa811a..54aa1c238cb34a5966a1d8ff6621835846514d87 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <asm/irq.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -57,77 +56,107 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
 }
 
 
+static void release_io_space(struct pcmcia_socket *s, struct resource *res)
+{
+       resource_size_t num = resource_size(res);
+       int i;
+
+       dev_dbg(&s->dev, "release_io_space for %pR\n", res);
+
+       for (i = 0; i < MAX_IO_WIN; i++) {
+               if (!s->io[i].res)
+                       continue;
+               if ((s->io[i].res->start <= res->start) &&
+                   (s->io[i].res->end >= res->end)) {
+                       s->io[i].InUse -= num;
+                       if (res->parent)
+                               release_resource(res);
+                       res->start = res->end = 0;
+                       res->flags = IORESOURCE_IO;
+                       /* Free the window if no one else is using it */
+                       if (s->io[i].InUse == 0) {
+                               release_resource(s->io[i].res);
+                               kfree(s->io[i].res);
+                               s->io[i].res = NULL;
+                       }
+               }
+       }
+} /* release_io_space */
+
 /** alloc_io_space
  *
  * Special stuff for managing IO windows, because they are scarce
  */
-
-static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
-                         unsigned int *base, unsigned int num, u_int lines)
+static int alloc_io_space(struct pcmcia_socket *s, struct resource *res,
+                       unsigned int lines)
 {
        unsigned int align;
+       unsigned int base = res->start;
+       unsigned int num = res->end;
+       int ret;
 
-       align = (*base) ? (lines ? 1<<lines : 0) : 1;
+       res->flags |= IORESOURCE_IO;
+
+       dev_dbg(&s->dev, "alloc_io_space request for %pR, %d lines\n",
+               res, lines);
+
+       align = base ? (lines ? 1<<lines : 0) : 1;
        if (align && (align < num)) {
-               if (*base) {
-                       dev_dbg(&s->dev, "odd IO request: num %#x align %#x\n",
-                              num, align);
+               if (base) {
+                       dev_dbg(&s->dev, "odd IO request\n");
                        align = 0;
                } else
                        while (align && (align < num))
                                align <<= 1;
        }
-       if (*base & ~(align-1)) {
-               dev_dbg(&s->dev, "odd IO request: base %#x align %#x\n",
-                      *base, align);
+       if (base & ~(align-1)) {
+               dev_dbg(&s->dev, "odd IO request\n");
                align = 0;
        }
 
-       return s->resource_ops->find_io(s, attr, base, num, align);
-} /* alloc_io_space */
-
+       ret = s->resource_ops->find_io(s, res->flags, &base, num, align,
+                               &res->parent);
+       if (ret) {
+               dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret);
+               return -EINVAL;
+       }
 
-static void release_io_space(struct pcmcia_socket *s, unsigned int base,
-                            unsigned int num)
-{
-       int i;
+       res->start = base;
+       res->end = res->start + num - 1;
 
-       for (i = 0; i < MAX_IO_WIN; i++) {
-               if (!s->io[i].res)
-                       continue;
-               if ((s->io[i].res->start <= base) &&
-                   (s->io[i].res->end >= base+num-1)) {
-                       s->io[i].InUse -= num;
-                       /* Free the window if no one else is using it */
-                       if (s->io[i].InUse == 0) {
-                               release_resource(s->io[i].res);
-                               kfree(s->io[i].res);
-                               s->io[i].res = NULL;
-                       }
+       if (res->parent) {
+               ret = request_resource(res->parent, res);
+               if (ret) {
+                       dev_warn(&s->dev,
+                               "request_resource %pR failed: %d\n", res, ret);
+                       res->parent = NULL;
+                       release_io_space(s, res);
                }
        }
-} /* release_io_space */
+       dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
+       return ret;
+} /* alloc_io_space */
 
 
-/** pccard_access_configuration_register
+/**
+ * pcmcia_access_config() - read or write card configuration registers
  *
- * Access_configuration_register() reads and writes configuration
- * registers in attribute memory.  Memory window 0 is reserved for
- * this and the tuple reading services.
+ * pcmcia_access_config() reads and writes configuration registers in
+ * attribute memory.  Memory window 0 is reserved for this and the tuple
+ * reading services. Drivers must use pcmcia_read_config_byte() or
+ * pcmcia_write_config_byte().
  */
-
-int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
-                                        conf_reg_t *reg)
+static int pcmcia_access_config(struct pcmcia_device *p_dev,
+                               off_t where, u8 *val,
+                               int (*accessf) (struct pcmcia_socket *s,
+                                               int attr, unsigned int addr,
+                                               unsigned int len, void *ptr))
 {
        struct pcmcia_socket *s;
        config_t *c;
        int addr;
-       u_char val;
        int ret = 0;
 
-       if (!p_dev || !p_dev->function_config)
-               return -EINVAL;
-
        s = p_dev->socket;
 
        mutex_lock(&s->ops_mutex);
@@ -139,44 +168,57 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
                return -EACCES;
        }
 
-       addr = (c->ConfigBase + reg->Offset) >> 1;
+       addr = (c->ConfigBase + where) >> 1;
+
+       ret = accessf(s, 1, addr, 1, val);
 
-       switch (reg->Action) {
-       case CS_READ:
-               ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val);
-               reg->Value = val;
-               break;
-       case CS_WRITE:
-               val = reg->Value;
-               pcmcia_write_cis_mem(s, 1, addr, 1, &val);
-               break;
-       default:
-               dev_dbg(&s->dev, "Invalid conf register request\n");
-               ret = -EINVAL;
-               break;
-       }
        mutex_unlock(&s->ops_mutex);
+
        return ret;
-} /* pcmcia_access_configuration_register */
-EXPORT_SYMBOL(pcmcia_access_configuration_register);
+} /* pcmcia_access_config */
+
+
+/**
+ * pcmcia_read_config_byte() - read a byte from a card configuration register
+ *
+ * pcmcia_read_config_byte() reads a byte from a configuration register in
+ * attribute memory.
+ */
+int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val)
+{
+       return pcmcia_access_config(p_dev, where, val, pcmcia_read_cis_mem);
+}
+EXPORT_SYMBOL(pcmcia_read_config_byte);
+
+
+/**
+ * pcmcia_write_config_byte() - write a byte to a card configuration register
+ *
+ * pcmcia_write_config_byte() writes a byte to a configuration register in
+ * attribute memory.
+ */
+int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val)
+{
+       return pcmcia_access_config(p_dev, where, &val, pcmcia_write_cis_mem);
+}
+EXPORT_SYMBOL(pcmcia_write_config_byte);
 
 
 int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
-                       memreq_t *req)
+                       unsigned int offset)
 {
        struct pcmcia_socket *s = p_dev->socket;
+       struct resource *res = wh;
+       unsigned int w;
        int ret;
 
-       wh--;
-       if (wh >= MAX_WIN)
+       w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
+       if (w >= MAX_WIN)
                return -EINVAL;
-       if (req->Page != 0) {
-               dev_dbg(&s->dev, "failure: requested page is zero\n");
-               return -EINVAL;
-       }
+
        mutex_lock(&s->ops_mutex);
-       s->win[wh].card_start = req->CardOffset;
-       ret = s->ops->set_mem_map(s, &s->win[wh]);
+       s->win[w].card_start = offset;
+       ret = s->ops->set_mem_map(s, &s->win[w]);
        if (ret)
                dev_warn(&s->dev, "failed to set_mem_map\n");
        mutex_unlock(&s->ops_mutex);
@@ -316,31 +358,25 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
  * don't bother checking the port ranges against the current socket
  * values.
  */
-static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
+static int pcmcia_release_io(struct pcmcia_device *p_dev)
 {
        struct pcmcia_socket *s = p_dev->socket;
        int ret = -EINVAL;
        config_t *c;
 
        mutex_lock(&s->ops_mutex);
-       c = p_dev->function_config;
-
        if (!p_dev->_io)
                goto out;
 
-       p_dev->_io = 0;
+       c = p_dev->function_config;
 
-       if ((c->io.BasePort1 != req->BasePort1) ||
-           (c->io.NumPorts1 != req->NumPorts1) ||
-           (c->io.BasePort2 != req->BasePort2) ||
-           (c->io.NumPorts2 != req->NumPorts2))
-               goto out;
+       release_io_space(s, &c->io[0]);
 
-       c->state &= ~CONFIG_IO_REQ;
+       if (c->io[1].end)
+               release_io_space(s, &c->io[1]);
 
-       release_io_space(s, req->BasePort1, req->NumPorts1);
-       if (req->NumPorts2)
-               release_io_space(s, req->BasePort2, req->NumPorts2);
+       p_dev->_io = 0;
+       c->state &= ~CONFIG_IO_REQ;
 
 out:
        mutex_unlock(&s->ops_mutex);
@@ -349,19 +385,22 @@ out:
 } /* pcmcia_release_io */
 
 
-int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
+int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
 {
        struct pcmcia_socket *s = p_dev->socket;
        pccard_mem_map *win;
+       unsigned int w;
+
+       dev_dbg(&p_dev->dev, "releasing window %pR\n", res);
 
-       wh--;
-       if (wh >= MAX_WIN)
+       w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
+       if (w >= MAX_WIN)
                return -EINVAL;
 
        mutex_lock(&s->ops_mutex);
-       win = &s->win[wh];
+       win = &s->win[w];
 
-       if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
+       if (!(p_dev->_win & CLIENT_WIN_REQ(w))) {
                dev_dbg(&s->dev, "not releasing unknown window\n");
                mutex_unlock(&s->ops_mutex);
                return -EINVAL;
@@ -370,15 +409,16 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
        /* Shut down memory window */
        win->flags &= ~MAP_ACTIVE;
        s->ops->set_mem_map(s, win);
-       s->state &= ~SOCKET_WIN_REQ(wh);
+       s->state &= ~SOCKET_WIN_REQ(w);
 
        /* Release system memory */
        if (win->res) {
+               release_resource(res);
                release_resource(win->res);
                kfree(win->res);
                win->res = NULL;
        }
-       p_dev->_win &= ~CLIENT_WIN_REQ(wh);
+       p_dev->_win &= ~CLIENT_WIN_REQ(w);
        mutex_unlock(&s->ops_mutex);
 
        return 0;
@@ -473,13 +513,13 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
                pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);
        }
        if (req->Present & PRESENT_IOBASE_0) {
-               u_char b = c->io.BasePort1 & 0xff;
+               u8 b = c->io[0].start & 0xff;
                pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
-               b = (c->io.BasePort1 >> 8) & 0xff;
+               b = (c->io[0].start >> 8) & 0xff;
                pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
        }
        if (req->Present & PRESENT_IOSIZE) {
-               u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;
+               u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1;
                pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
        }
 
@@ -513,28 +553,29 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
 EXPORT_SYMBOL(pcmcia_request_configuration);
 
 
-/** pcmcia_request_io
+/**
+ * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices
  *
- * Request_io() reserves ranges of port addresses for a socket.
- * I have not implemented range sharing or alias addressing.
+ * pcmcia_request_io() attepts to reserve the IO port ranges specified in
+ * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The
+ * "start" value is the requested start of the IO port resource; "end"
+ * reflects the number of ports requested. The number of IO lines requested
+ * is specified in &struct pcmcia_device @p_dev->io_lines.
  */
-int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
+int pcmcia_request_io(struct pcmcia_device *p_dev)
 {
        struct pcmcia_socket *s = p_dev->socket;
-       config_t *c;
+       config_t *c = p_dev->function_config;
        int ret = -EINVAL;
 
        mutex_lock(&s->ops_mutex);
+       dev_dbg(&s->dev, "pcmcia_request_io: %pR , %pR", &c->io[0], &c->io[1]);
 
        if (!(s->state & SOCKET_PRESENT)) {
-               dev_dbg(&s->dev, "No card present\n");
+               dev_dbg(&s->dev, "pcmcia_request_io: No card present\n");
                goto out;
        }
 
-       if (!req)
-               goto out;
-
-       c = p_dev->function_config;
        if (c->state & CONFIG_LOCKED) {
                dev_dbg(&s->dev, "Configuration is locked\n");
                goto out;
@@ -543,40 +584,25 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
                dev_dbg(&s->dev, "IO already configured\n");
                goto out;
        }
-       if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
-               dev_dbg(&s->dev, "bad attribute setting for IO region 1\n");
-               goto out;
-       }
-       if ((req->NumPorts2 > 0) &&
-           (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
-               dev_dbg(&s->dev, "bad attribute setting for IO region 2\n");
-               goto out;
-       }
 
-       dev_dbg(&s->dev, "trying to allocate resource 1\n");
-       ret = alloc_io_space(s, req->Attributes1, &req->BasePort1,
-                            req->NumPorts1, req->IOAddrLines);
-       if (ret) {
-               dev_dbg(&s->dev, "allocation of resource 1 failed\n");
+       ret = alloc_io_space(s, &c->io[0], p_dev->io_lines);
+       if (ret)
                goto out;
-       }
 
-       if (req->NumPorts2) {
-               dev_dbg(&s->dev, "trying to allocate resource 2\n");
-               ret = alloc_io_space(s, req->Attributes2, &req->BasePort2,
-                                    req->NumPorts2, req->IOAddrLines);
+       if (c->io[1].end) {
+               ret = alloc_io_space(s, &c->io[1], p_dev->io_lines);
                if (ret) {
-                       dev_dbg(&s->dev, "allocation of resource 2 failed\n");
-                       release_io_space(s, req->BasePort1, req->NumPorts1);
+                       release_io_space(s, &c->io[0]);
                        goto out;
                }
-       }
+       } else
+               c->io[1].start = 0;
 
-       c->io = *req;
        c->state |= CONFIG_IO_REQ;
        p_dev->_io = 1;
-       dev_dbg(&s->dev, "allocating resources succeeded: %d\n", ret);
 
+       dev_dbg(&s->dev, "pcmcia_request_io succeeded: %pR , %pR",
+               &c->io[0], &c->io[1]);
 out:
        mutex_unlock(&s->ops_mutex);
 
@@ -651,7 +677,7 @@ EXPORT_SYMBOL(__pcmcia_request_exclusive_irq);
 #ifdef CONFIG_PCMCIA_PROBE
 
 /* mask of IRQs already reserved by other cards, we should avoid using them */
-static u8 pcmcia_used_irq[NR_IRQS];
+static u8 pcmcia_used_irq[32];
 
 static irqreturn_t test_action(int cpl, void *dev_id)
 {
@@ -674,6 +700,9 @@ static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
        for (try = 0; try < 64; try++) {
                irq = try % 32;
 
+               if (irq > NR_IRQS)
+                       continue;
+
                /* marked as available by driver, not blocked by userspace? */
                if (!((mask >> irq) & 1))
                        continue;
@@ -767,23 +796,18 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
        struct pcmcia_socket *s = p_dev->socket;
        pccard_mem_map *win;
        u_long align;
+       struct resource *res;
        int w;
 
        if (!(s->state & SOCKET_PRESENT)) {
                dev_dbg(&s->dev, "No card present\n");
                return -ENODEV;
        }
-       if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
-               dev_dbg(&s->dev, "bad attribute setting for iomem region\n");
-               return -EINVAL;
-       }
 
        /* Window size defaults to smallest available */
        if (req->Size == 0)
                req->Size = s->map_size;
-       align = (((s->features & SS_CAP_MEM_ALIGN) ||
-                 (req->Attributes & WIN_STRICT_ALIGN)) ?
-                req->Size : s->map_size);
+       align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size;
        if (req->Size & (s->map_size-1)) {
                dev_dbg(&s->dev, "invalid map size\n");
                return -EINVAL;
@@ -797,20 +821,21 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
                align = 0;
 
        /* Allocate system memory window */
+       mutex_lock(&s->ops_mutex);
        for (w = 0; w < MAX_WIN; w++)
                if (!(s->state & SOCKET_WIN_REQ(w)))
                        break;
        if (w == MAX_WIN) {
                dev_dbg(&s->dev, "all windows are used already\n");
+               mutex_unlock(&s->ops_mutex);
                return -EINVAL;
        }
 
-       mutex_lock(&s->ops_mutex);
        win = &s->win[w];
 
        if (!(s->features & SS_CAP_STATIC_MAP)) {
                win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
-                                                     (req->Attributes & WIN_MAP_BELOW_1MB), s);
+                                               0, s);
                if (!win->res) {
                        dev_dbg(&s->dev, "allocating mem region failed\n");
                        mutex_unlock(&s->ops_mutex);
@@ -821,16 +846,8 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
 
        /* Configure the socket controller */
        win->map = w+1;
-       win->flags = 0;
+       win->flags = req->Attributes;
        win->speed = req->AccessSpeed;
-       if (req->Attributes & WIN_MEMORY_TYPE)
-               win->flags |= MAP_ATTRIB;
-       if (req->Attributes & WIN_ENABLE)
-               win->flags |= MAP_ACTIVE;
-       if (req->Attributes & WIN_DATA_WIDTH_16)
-               win->flags |= MAP_16BIT;
-       if (req->Attributes & WIN_USE_WAIT)
-               win->flags |= MAP_USE_WAIT;
        win->card_start = 0;
 
        if (s->ops->set_mem_map(s, win) != 0) {
@@ -846,8 +863,21 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
        else
                req->Base = win->res->start;
 
+       /* convert to new-style resources */
+       res = p_dev->resource[w + MAX_IO_WIN];
+       res->start = req->Base;
+       res->end = req->Base + req->Size - 1;
+       res->flags &= ~IORESOURCE_BITS;
+       res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2);
+       res->flags |= IORESOURCE_MEM;
+       res->parent = win->res;
+       if (win->res)
+               request_resource(&iomem_resource, res);
+
+       dev_dbg(&s->dev, "request_window results in %pR\n", res);
+
        mutex_unlock(&s->ops_mutex);
-       *wh = w + 1;
+       *wh = res;
 
        return 0;
 } /* pcmcia_request_window */
@@ -855,13 +885,18 @@ EXPORT_SYMBOL(pcmcia_request_window);
 
 void pcmcia_disable_device(struct pcmcia_device *p_dev)
 {
+       int i;
+       for (i = 0; i < MAX_WIN; i++) {
+               struct resource *res = p_dev->resource[MAX_IO_WIN + i];
+               if (res->flags & WIN_FLAGS_REQ)
+                       pcmcia_release_window(p_dev, res);
+       }
+
        pcmcia_release_configuration(p_dev);
-       pcmcia_release_io(p_dev, &p_dev->io);
+       pcmcia_release_io(p_dev);
        if (p_dev->_irq) {
                free_irq(p_dev->irq, p_dev->priv);
                p_dev->_irq = 0;
        }
-       if (p_dev->win)
-               pcmcia_release_window(p_dev, p_dev->win);
 }
 EXPORT_SYMBOL(pcmcia_disable_device);
index b61a13663a0a79babf86a0d86722b76d8c02ad40..b8a869af0f4410dd25a3cb0b4b5ace093ea5d6a5 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/device.h>
 #include <linux/io.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
index f370476d5417d49b48540e49432c5f82b97cf53c..ae07b4db8a6ec00def420e5af77bbcede2b90730 100644 (file)
@@ -32,7 +32,6 @@
 #include <mach/pxa2xx-regs.h>
 #include <asm/mach-types.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
 
index d0bf350210659f15885e2a6d23bbb12ce9a27c4b..8510c35d2952e5a264877632f22954c0de85c77f 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -88,7 +87,7 @@ static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s,
 
 static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                        unsigned int *base, unsigned int num,
-                       unsigned int align)
+                       unsigned int align, struct resource **parent)
 {
        int i, ret = 0;
 
@@ -129,6 +128,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                                ((res->flags & ~IORESOURCE_BITS) |
                                        (attr & IORESOURCE_BITS));
                        s->io[i].InUse = num;
+                       *parent = res;
                        return 0;
                }
 
@@ -140,6 +140,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                                continue;
                        *base = try;
                        s->io[i].InUse += num;
+                       *parent = res;
                        return 0;
                }
 
@@ -152,6 +153,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                                continue;
                        *base = try;
                        s->io[i].InUse += num;
+                       *parent = res;
                        return 0;
                }
        }
@@ -164,8 +166,6 @@ struct pccard_resource_ops pccard_iodyn_ops = {
        .validate_mem = NULL,
        .find_io = iodyn_find_io,
        .find_mem = NULL,
-       .add_io = NULL,
-       .add_mem = NULL,
        .init = static_init,
        .exit = NULL,
 };
index 142efac3c387bbe5fa05bdf5cb3ddc3a8c0edb8b..4e80421fd9084d02433aea7f1c0561edcd2c6192 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -48,11 +47,12 @@ struct resource *pcmcia_make_resource(unsigned long start, unsigned long end,
 
 static int static_find_io(struct pcmcia_socket *s, unsigned int attr,
                        unsigned int *base, unsigned int num,
-                       unsigned int align)
+                       unsigned int align, struct resource **parent)
 {
        if (!s->io_offset)
                return -EINVAL;
        *base = s->io_offset | (*base & 0x0fff);
+       *parent = NULL;
 
        return 0;
 }
@@ -62,8 +62,6 @@ struct pccard_resource_ops pccard_static_ops = {
        .validate_mem = NULL,
        .find_io = static_find_io,
        .find_mem = NULL,
-       .add_io = NULL,
-       .add_mem = NULL,
        .init = static_init,
        .exit = NULL,
 };
index dcd1a4ad3d631b42dc93114e686231e733ff5718..96f348b35fdea356daabb8b1836d438b163ca117 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <asm/irq.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -64,6 +63,9 @@ struct socket_data {
 #define MEM_PROBE_LOW  (1 << 0)
 #define MEM_PROBE_HIGH (1 << 1)
 
+/* Action field */
+#define REMOVE_MANAGED_RESOURCE                1
+#define ADD_MANAGED_RESOURCE           2
 
 /*======================================================================
 
@@ -716,7 +718,7 @@ static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
 
 static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                        unsigned int *base, unsigned int num,
-                       unsigned int align)
+                       unsigned int align, struct resource **parent)
 {
        int i, ret = 0;
 
@@ -758,6 +760,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                                ((res->flags & ~IORESOURCE_BITS) |
                                        (attr & IORESOURCE_BITS));
                        s->io[i].InUse = num;
+                       *parent = res;
                        return 0;
                }
 
@@ -773,6 +776,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                                        continue;
                                *base = try;
                                s->io[i].InUse += num;
+                               *parent = res;
                                return 0;
                        }
                }
@@ -791,6 +795,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                                        continue;
                                *base = try;
                                s->io[i].InUse += num;
+                               *parent = res;
                                return 0;
                        }
                }
@@ -1055,8 +1060,6 @@ struct pccard_resource_ops pccard_nonstatic_ops = {
        .validate_mem = pcmcia_nonstatic_validate_mem,
        .find_io = nonstatic_find_io,
        .find_mem = nonstatic_find_mem_region,
-       .add_io = adjust_io,
-       .add_mem = adjust_memory,
        .init = nonstatic_init,
        .exit = nonstatic_release_resource_db,
 };
@@ -1115,8 +1118,6 @@ static ssize_t store_io_db(struct device *dev,
 
        mutex_lock(&s->ops_mutex);
        ret = adjust_io(s, add, start_addr, end_addr);
-       if (!ret)
-               s->resource_setup_new = 1;
        mutex_unlock(&s->ops_mutex);
 
        return ret ? ret : count;
@@ -1183,8 +1184,6 @@ static ssize_t store_mem_db(struct device *dev,
 
        mutex_lock(&s->ops_mutex);
        ret = adjust_memory(s, add, start_addr, end_addr);
-       if (!ret)
-               s->resource_setup_new = 1;
        mutex_unlock(&s->ops_mutex);
 
        return ret ? ret : count;
index edbd8c472628fd8312334803ba21b2c7175d5236..e09851480295dd22260cea8c7609acc9bf6d0b56 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 
index e40824ce6b0b2f0960be487acb8cedb3e01cb9fb..3fba3a679128b10547714cd672461c0ba9e563b0 100644 (file)
@@ -11,7 +11,6 @@
 
 /* include the world */
 #include <linux/cpufreq.h>
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
index 80e36bc407dac811ab1b6e9e54c1b8bc36f79e77..cb0d3ace18bd5b6113512e12a9c42c1142393468 100644 (file)
@@ -26,7 +26,6 @@
 #include <asm/system.h>
 #include <asm/irq.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
index 56004a1b5bbaefa4683a584a57fbf86d46525ed1..be0d841c7ebd9d9e2bb1407a4165ee92623105ec 100644 (file)
@@ -49,7 +49,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 #include "tcic.h"
index 201ccfa1e97b59a383e2fe05fd12082e3c63f6d5..fa88c360c37a21f1875ba05e3fea58c3194d95ab 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
index f1d41374eea7a32426e8acfeadc903b1901bee22..414d9a6f9a32c04f3908373d93c6e361b34b4ed2 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
index 2248087b9be2456bc2430ddcbda3f4f0e6085d4f..422a709d271d51d593899db82b0b930cf93f2847 100644 (file)
@@ -1025,7 +1025,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                if (regulator->dev_attr.attr.name == NULL)
                        goto attr_name_err;
 
-               regulator->dev_attr.attr.owner = THIS_MODULE;
                regulator->dev_attr.attr.mode = 0444;
                regulator->dev_attr.show = device_requested_uA_show;
                err = device_create_file(dev, &regulator->dev_attr);
index 8bfdd63a1fcbc085c33fbbab85c61e8675347138..3e89c313e98dddeab4b405a70007eb98aee4be31 100644 (file)
@@ -317,7 +317,7 @@ static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int inde
 
        bp->waiting = 0;
        init_waitqueue_head(&bp->wq);
-       if (request_irq(op->irqs[0], bbc_i2c_interrupt,
+       if (request_irq(op->archdata.irqs[0], bbc_i2c_interrupt,
                        IRQF_SHARED, "bbc_i2c", bp))
                goto fail;
 
@@ -373,7 +373,7 @@ static int __devinit bbc_i2c_probe(struct of_device *op,
 
        err = bbc_envctrl_init(bp);
        if (err) {
-               free_irq(op->irqs[0], bp);
+               free_irq(op->archdata.irqs[0], bp);
                if (bp->i2c_bussel_reg)
                        of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1);
                if (bp->i2c_control_regs)
@@ -392,7 +392,7 @@ static int __devexit bbc_i2c_remove(struct of_device *op)
 
        bbc_envctrl_cleanup(bp);
 
-       free_irq(op->irqs[0], bp);
+       free_irq(op->archdata.irqs[0], bp);
 
        if (bp->i2c_bussel_reg)
                of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1);
@@ -425,12 +425,12 @@ static struct of_platform_driver bbc_i2c_driver = {
 
 static int __init bbc_i2c_init(void)
 {
-       return of_register_driver(&bbc_i2c_driver, &of_bus_type);
+       return of_register_platform_driver(&bbc_i2c_driver);
 }
 
 static void __exit bbc_i2c_exit(void)
 {
-       of_unregister_driver(&bbc_i2c_driver);
+       of_unregister_platform_driver(&bbc_i2c_driver);
 }
 
 module_init(bbc_i2c_init);
index 4ad4d2c91075f1e335cc7f6ea8fb1e5ddef757f8..47db97583ea7085ff1c74b6774eaa7a3be174c69 100644 (file)
@@ -277,12 +277,12 @@ static struct of_platform_driver d7s_driver = {
 
 static int __init d7s_init(void)
 {
-       return of_register_driver(&d7s_driver, &of_bus_type);
+       return of_register_platform_driver(&d7s_driver);
 }
 
 static void __exit d7s_exit(void)
 {
-       of_unregister_driver(&d7s_driver);
+       of_unregister_platform_driver(&d7s_driver);
 }
 
 module_init(d7s_init);
index bd0bbc621351db63966af1558a1d7bb8ab14bfce..3c27f45e2b6dd281fca4334cd1a11929ac7d7555 100644 (file)
@@ -1140,12 +1140,12 @@ static struct of_platform_driver envctrl_driver = {
 
 static int __init envctrl_init(void)
 {
-       return of_register_driver(&envctrl_driver, &of_bus_type);
+       return of_register_platform_driver(&envctrl_driver);
 }
 
 static void __exit envctrl_exit(void)
 {
-       of_unregister_driver(&envctrl_driver);
+       of_unregister_platform_driver(&envctrl_driver);
 }
 
 module_init(envctrl_init);
index ed9494e1885995568c478e28fdbc50e9cb6c71b4..8bb31c584b64f4bd2dd82a365ebe882cf4404bee 100644 (file)
@@ -219,12 +219,12 @@ static struct of_platform_driver flash_driver = {
 
 static int __init flash_init(void)
 {
-       return of_register_driver(&flash_driver, &of_bus_type);
+       return of_register_platform_driver(&flash_driver);
 }
 
 static void __exit flash_cleanup(void)
 {
-       of_unregister_driver(&flash_driver);
+       of_unregister_platform_driver(&flash_driver);
 }
 
 module_init(flash_init);
index 079da4cb45a5d951e719475893226df4cc08cf15..41eb6725ff5f21395829ebebebcece995fc92d1c 100644 (file)
@@ -368,7 +368,7 @@ static int __devinit uctrl_probe(struct of_device *op,
                goto out_free;
        }
 
-       p->irq = op->irqs[0];
+       p->irq = op->archdata.irqs[0];
        err = request_irq(p->irq, uctrl_interrupt, 0, "uctrl", p);
        if (err) {
                printk(KERN_ERR "uctrl: Unable to register irq.\n");
@@ -438,12 +438,12 @@ static struct of_platform_driver uctrl_driver = {
 
 static int __init uctrl_init(void)
 {
-       return of_register_driver(&uctrl_driver, &of_bus_type);
+       return of_register_platform_driver(&uctrl_driver);
 }
 
 static void __exit uctrl_exit(void)
 {
-       of_unregister_driver(&uctrl_driver);
+       of_unregister_platform_driver(&uctrl_driver);
 }
 
 module_init(uctrl_init);
index 07fdfe57e38e07eaf501ddc83a8aba77ed3ca39c..a4e04c50c436c9624031ad8272a877432b18fd12 100644 (file)
@@ -192,7 +192,6 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = {
        .attr = {
                .name = "mu_read",
                .mode = S_IRUSR ,
-               .owner = THIS_MODULE,
        },
        .size = 1032,
        .read = arcmsr_sysfs_iop_message_read,
@@ -202,7 +201,6 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = {
        .attr = {
                .name = "mu_write",
                .mode = S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 1032,
        .write = arcmsr_sysfs_iop_message_write,
@@ -212,7 +210,6 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = {
        .attr = {
                .name = "mu_clear",
                .mode = S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 1,
        .write = arcmsr_sysfs_iop_message_clear,
index 868874c28f99a6c0bf3ab89d0419f0698eff032d..162704cf6a96eb805ca1f6d6bba008fe317c602c 100644 (file)
@@ -2778,7 +2778,6 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = {
        .attr = {
                .name = "lpfc_drvr_stat_data",
                .mode = S_IRUSR,
-               .owner = THIS_MODULE,
        },
        .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
        .read = sysfs_drvr_stat_data_read,
index 9d70aef9922707d75c109b7d871918f5e9669e9b..61f49bdcc0c2815cc3b28f805c711cc3e4163ff8 100644 (file)
@@ -49,7 +49,6 @@
 #include <scsi/scsi_host.h>
 #include "aha152x.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -101,9 +100,8 @@ static int aha152x_probe(struct pcmcia_device *link)
     info->p_dev = link;
     link->priv = info;
 
-    link->io.NumPorts1 = 0x20;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.IOAddrLines = 10;
+    link->resource[0]->end = 0x20;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
@@ -131,15 +129,16 @@ static int aha152x_config_check(struct pcmcia_device *p_dev,
                                unsigned int vcc,
                                void *priv_data)
 {
+       p_dev->io_lines = 10;
        /* For New Media T&J, look for a SCSI window */
        if (cfg->io.win[0].len >= 0x20)
-               p_dev->io.BasePort1 = cfg->io.win[0].base;
+               p_dev->resource[0]->start = cfg->io.win[0].base;
        else if ((cfg->io.nwin > 1) &&
                 (cfg->io.win[1].len >= 0x20))
-               p_dev->io.BasePort1 = cfg->io.win[1].base;
+               p_dev->resource[0]->start = cfg->io.win[1].base;
        if ((cfg->io.nwin > 0) &&
-           (p_dev->io.BasePort1 < 0xffff)) {
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+           (p_dev->resource[0]->start < 0xffff)) {
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        }
        return -EINVAL;
@@ -168,7 +167,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
     /* Set configuration options for the aha152x driver */
     memset(&s, 0, sizeof(s));
     s.conf        = "PCMCIA setup";
-    s.io_port     = link->io.BasePort1;
+    s.io_port     = link->resource[0]->start;
     s.irq         = link->irq;
     s.scsiid      = host_id;
     s.reconnect   = reconnect;
index 21b141151dfcbc211dee3a608082319563ef8fda..13dbe5c48492e720c2691e24ad17930d3ee41f36 100644 (file)
@@ -46,7 +46,6 @@
 #include <scsi/scsi_host.h>
 #include "fdomain.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -84,9 +83,8 @@ static int fdomain_probe(struct pcmcia_device *link)
 
        info->p_dev = link;
        link->priv = info;
-       link->io.NumPorts1 = 0x10;
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       link->io.IOAddrLines = 10;
+       link->resource[0]->end = 0x10;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.Present = PRESENT_OPTION;
@@ -113,8 +111,9 @@ static int fdomain_config_check(struct pcmcia_device *p_dev,
                                unsigned int vcc,
                                void *priv_data)
 {
-       p_dev->io.BasePort1 = cfg->io.win[0].base;
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       p_dev->io_lines = 10;
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       return pcmcia_request_io(p_dev);
 }
 
 
@@ -138,10 +137,10 @@ static int fdomain_config(struct pcmcia_device *link)
            goto failed;
 
     /* A bad hack... */
-    release_region(link->io.BasePort1, link->io.NumPorts1);
+    release_region(link->resource[0]->start, resource_size(link->resource[0]));
 
     /* Set configuration options for the fdomain driver */
-    sprintf(str, "%d,%d", link->io.BasePort1, link->irq);
+    sprintf(str, "%d,%d", (unsigned int) link->resource[0]->start, link->irq);
     fdomain_setup(str);
 
     host = __fdomain_16x0_detect(&fdomain_driver_template);
index 0f0e112c3f8e23fbaa2093ca5a87cb18b5892c2c..dd9b40306f3d28f0d355a2ed72903b5fa148530f 100644 (file)
@@ -47,7 +47,6 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -1559,9 +1558,8 @@ static int nsp_cs_probe(struct pcmcia_device *link)
        nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
 
        /* The io structure describes IO port mapping */
-       link->io.NumPorts1       = 0x10;
-       link->io.Attributes1     = IO_DATA_PATH_WIDTH_AUTO;
-       link->io.IOAddrLines     = 10;  /* not used */
+       link->resource[0]->end   = 0x10;
+       link->resource[0]->flags = IO_DATA_PATH_WIDTH_AUTO;
 
        /* General socket configuration */
        link->conf.Attributes    = CONF_ENABLE_IRQ;
@@ -1642,29 +1640,27 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
                p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
                /* IO window settings */
-               p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+               p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
                if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                        cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       p_dev->io.BasePort1 = io->win[0].base;
-                       p_dev->io.NumPorts1 = io->win[0].len;
+                       p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+                       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+                       p_dev->resource[0]->flags |=
+                               pcmcia_io_cfg_data_width(io->flags);
+                       p_dev->resource[0]->start = io->win[0].base;
+                       p_dev->resource[0]->end = io->win[0].len;
                        if (io->nwin > 1) {
-                               p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                               p_dev->io.BasePort2 = io->win[1].base;
-                               p_dev->io.NumPorts2 = io->win[1].len;
+                               p_dev->resource[1]->flags =
+                                       p_dev->resource[0]->flags;
+                               p_dev->resource[1]->start = io->win[1].base;
+                               p_dev->resource[1]->end = io->win[1].len;
                        }
                        /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+                       if (pcmcia_request_io(p_dev) != 0)
                                goto next_entry;
                }
 
                if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
-                       memreq_t        map;
                        cistpl_mem_t    *mem =
                                (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
                        cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
@@ -1676,8 +1672,8 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
                        cfg_mem->req.AccessSpeed = 0;
                        if (pcmcia_request_window(p_dev, &cfg_mem->req, &p_dev->win) != 0)
                                goto next_entry;
-                       map.Page = 0; map.CardOffset = mem->win[0].card_addr;
-                       if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
+                       if (pcmcia_map_mem_page(p_dev, p_dev->win,
+                                       mem->win[0].card_addr) != 0)
                                goto next_entry;
 
                        cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
@@ -1720,17 +1716,19 @@ static int nsp_cs_config(struct pcmcia_device *link)
                goto cs_failed;
 
        if (free_ports) {
-               if (link->io.BasePort1) {
-                       release_region(link->io.BasePort1, link->io.NumPorts1);
+               if (link->resource[0]) {
+                       release_region(link->resource[0]->start,
+                                       resource_size(link->resource[0]));
                }
-               if (link->io.BasePort2) {
-                       release_region(link->io.BasePort2, link->io.NumPorts2);
+               if (link->resource[1]) {
+                       release_region(link->resource[1]->start,
+                                       resource_size(link->resource[1]));
                }
        }
 
        /* Set port and IRQ */
-       data->BaseAddress = link->io.BasePort1;
-       data->NumAddress  = link->io.NumPorts1;
+       data->BaseAddress = link->resource[0]->start;
+       data->NumAddress  = resource_size(link->resource[0]);
        data->IrqNumber   = link->irq;
 
        nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
@@ -1765,13 +1763,10 @@ static int nsp_cs_config(struct pcmcia_device *link)
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
                printk(", irq %d", link->irq);
        }
-       if (link->io.NumPorts1) {
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1+link->io.NumPorts1-1);
-       }
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2+link->io.NumPorts2-1);
+       if (link->resource[0])
+               printk(", io %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        if (link->win)
                printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base,
                       cfg_mem->req.Base+cfg_mem->req.Size-1);
index f0fc6baed9fc8f6ff1f9d5f106b0c4c9a49fba1d..eb775f1a523cef364b0666db7baa01609a9d833d 100644 (file)
@@ -48,7 +48,6 @@
 #include <scsi/scsi_host.h>
 #include "../qlogicfas408.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -157,9 +156,8 @@ static int qlogic_probe(struct pcmcia_device *link)
                return -ENOMEM;
        info->p_dev = link;
        link->priv = info;
-       link->io.NumPorts1 = 16;
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       link->io.IOAddrLines = 10;
+       link->resource[0]->end = 16;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.Present = PRESENT_OPTION;
@@ -186,13 +184,14 @@ static int qlogic_config_check(struct pcmcia_device *p_dev,
                               unsigned int vcc,
                               void *priv_data)
 {
-       p_dev->io.BasePort1 = cfg->io.win[0].base;
-       p_dev->io.NumPorts1 = cfg->io.win[0].len;
+       p_dev->io_lines = 10;
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
 
-       if (p_dev->io.BasePort1 == 0)
+       if (p_dev->resource[0]->start == 0)
                return -ENODEV;
 
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       return pcmcia_request_io(p_dev);
 }
 
 static int qlogic_config(struct pcmcia_device * link)
@@ -216,18 +215,18 @@ static int qlogic_config(struct pcmcia_device * link)
 
        if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
                /* set ATAcmd */
-               outb(0xb4, link->io.BasePort1 + 0xd);
-               outb(0x24, link->io.BasePort1 + 0x9);
-               outb(0x04, link->io.BasePort1 + 0xd);
+               outb(0xb4, link->resource[0]->start + 0xd);
+               outb(0x24, link->resource[0]->start + 0x9);
+               outb(0x04, link->resource[0]->start + 0xd);
        }
 
        /* The KXL-810AN has a bigger IO port window */
-       if (link->io.NumPorts1 == 32)
+       if (resource_size(link->resource[0]) == 32)
                host = qlogic_detect(&qlogicfas_driver_template, link,
-                       link->io.BasePort1 + 16, link->irq);
+                       link->resource[0]->start + 16, link->irq);
        else
                host = qlogic_detect(&qlogicfas_driver_template, link,
-                       link->io.BasePort1, link->irq);
+                       link->resource[0]->start, link->irq);
        
        if (!host) {
                printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
@@ -269,9 +268,9 @@ static int qlogic_resume(struct pcmcia_device *link)
        if ((info->manf_id == MANFID_MACNICA) ||
            (info->manf_id == MANFID_PIONEER) ||
            (info->manf_id == 0x0098)) {
-               outb(0x80, link->io.BasePort1 + 0xd);
-               outb(0x24, link->io.BasePort1 + 0x9);
-               outb(0x04, link->io.BasePort1 + 0xd);
+               outb(0x80, link->resource[0]->start + 0xd);
+               outb(0x24, link->resource[0]->start + 0x9);
+               outb(0x04, link->resource[0]->start + 0xd);
        }
        /* Ugggglllyyyy!!! */
        qlogicfas408_bus_reset(NULL);
index a5116417117906827e653eb4a89230f36be9bd76..321e390c9120631f07b81434e2dfe853bf78f05c 100644 (file)
@@ -71,7 +71,6 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -691,13 +690,14 @@ static int SYM53C500_config_check(struct pcmcia_device *p_dev,
                                  unsigned int vcc,
                                  void *priv_data)
 {
-       p_dev->io.BasePort1 = cfg->io.win[0].base;
-       p_dev->io.NumPorts1 = cfg->io.win[0].len;
+       p_dev->io_lines = 10;
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
 
-       if (p_dev->io.BasePort1 == 0)
+       if (p_dev->resource[0]->start == 0)
                return -ENODEV;
 
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       return pcmcia_request_io(p_dev);
 }
 
 static int
@@ -734,9 +734,9 @@ SYM53C500_config(struct pcmcia_device *link)
            (info->manf_id == MANFID_PIONEER) ||
            (info->manf_id == 0x0098)) {
                /* set ATAcmd */
-               outb(0xb4, link->io.BasePort1 + 0xd);
-               outb(0x24, link->io.BasePort1 + 0x9);
-               outb(0x04, link->io.BasePort1 + 0xd);
+               outb(0xb4, link->resource[0]->start + 0xd);
+               outb(0x24, link->resource[0]->start + 0x9);
+               outb(0x04, link->resource[0]->start + 0xd);
        }
 
        /*
@@ -749,7 +749,7 @@ SYM53C500_config(struct pcmcia_device *link)
        *       0x130, 0x230, 0x280, 0x290,
        *       0x320, 0x330, 0x340, 0x350
        */
-       port_base = link->io.BasePort1;
+       port_base = link->resource[0]->start;
        irq_level = link->irq;
 
        DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n",
@@ -822,15 +822,15 @@ static int sym53c500_resume(struct pcmcia_device *link)
        if ((info->manf_id == MANFID_MACNICA) ||
            (info->manf_id == MANFID_PIONEER) ||
            (info->manf_id == 0x0098)) {
-               outb(0x80, link->io.BasePort1 + 0xd);
-               outb(0x24, link->io.BasePort1 + 0x9);
-               outb(0x04, link->io.BasePort1 + 0xd);
+               outb(0x80, link->resource[0]->start + 0xd);
+               outb(0x24, link->resource[0]->start + 0x9);
+               outb(0x04, link->resource[0]->start + 0xd);
        }
        /*
         *  If things don't work after a "resume",
         *  this is a good place to start looking.
         */
-       SYM53C500_int_host_reset(link->io.BasePort1);
+       SYM53C500_int_host_reset(link->resource[0]->start);
 
        return 0;
 }
@@ -859,9 +859,8 @@ SYM53C500_probe(struct pcmcia_device *link)
                return -ENOMEM;
        info->p_dev = link;
        link->priv = info;
-       link->io.NumPorts1 = 16;
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       link->io.IOAddrLines = 10;
+       link->resource[0]->end = 16;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
index ca5c15c779cfc5a4d26659818545414b12682052..53d7ed0dc169b24c8e4350418817fc7c61819c55 100644 (file)
@@ -729,7 +729,7 @@ static int __devinit qpti_register_irq(struct qlogicpti *qpti)
 {
        struct of_device *op = qpti->op;
 
-       qpti->qhost->irq = qpti->irq = op->irqs[0];
+       qpti->qhost->irq = qpti->irq = op->archdata.irqs[0];
 
        /* We used to try various overly-clever things to
         * reduce the interrupt processing overhead on
@@ -1302,7 +1302,7 @@ static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_devic
        /* Sometimes Antares cards come up not completely
         * setup, and we get a report of a zero IRQ.
         */
-       if (op->irqs[0] == 0)
+       if (op->archdata.irqs[0] == 0)
                return -ENODEV;
 
        host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
@@ -1467,12 +1467,12 @@ static struct of_platform_driver qpti_sbus_driver = {
 
 static int __init qpti_init(void)
 {
-       return of_register_driver(&qpti_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&qpti_sbus_driver);
 }
 
 static void __exit qpti_exit(void)
 {
-       of_unregister_driver(&qpti_sbus_driver);
+       of_unregister_platform_driver(&qpti_sbus_driver);
 }
 
 MODULE_DESCRIPTION("QlogicISP SBUS driver");
index 026295e2c53959adcb6fb1abbbb047b9dc75095a..b4056d14f812d7ecc4e8affc0c234bf6e4837424 100644 (file)
@@ -148,8 +148,6 @@ static inline void scsi_netlink_exit(void) {}
 /* scsi_pm.c */
 #ifdef CONFIG_PM_OPS
 extern const struct dev_pm_ops scsi_bus_pm_ops;
-#else /* CONFIG_PM_OPS */
-#define scsi_bus_pm_ops                (*NULL)
 #endif
 #ifdef CONFIG_PM_RUNTIME
 extern void scsi_autopm_get_target(struct scsi_target *);
index 562fb3bce2611b2366603c723a2ae7192d0ad9f4..c3f67373a4f8f2193505603e24b019dca1d051d9 100644 (file)
@@ -381,7 +381,9 @@ struct bus_type scsi_bus_type = {
         .name          = "scsi",
         .match         = scsi_bus_match,
        .uevent         = scsi_bus_uevent,
+#ifdef CONFIG_PM_OPS
        .pm             = &scsi_bus_pm_ops,
+#endif
 };
 EXPORT_SYMBOL_GPL(scsi_bus_type);
 
index 386dd9d602b6e32ce4d262375caa4738ff9b1b5e..89ba6fe02f80e3e7f9c249ec10f7155b5e13ac4a 100644 (file)
@@ -116,7 +116,7 @@ static int __devinit esp_sbus_register_irq(struct esp *esp)
        struct Scsi_Host *host = esp->host;
        struct of_device *op = esp->dev;
 
-       host->irq = op->irqs[0];
+       host->irq = op->archdata.irqs[0];
        return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
 }
 
@@ -644,12 +644,12 @@ static struct of_platform_driver esp_sbus_driver = {
 
 static int __init sunesp_init(void)
 {
-       return of_register_driver(&esp_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&esp_sbus_driver);
 }
 
 static void __exit sunesp_exit(void)
 {
-       of_unregister_driver(&esp_sbus_driver);
+       of_unregister_platform_driver(&esp_sbus_driver);
 }
 
 MODULE_DESCRIPTION("Sun ESP SCSI driver");
index a9a94ae7234951f3b30b25829c67d1ee13a3a8f2..39f9a1adaa756b408a18ce02e6dfe662350f2246 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kdb.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/vt_kern.h>
 
 #define MAX_CONFIG_LEN         40
 
@@ -31,6 +32,7 @@ static struct kparam_string kps = {
        .maxlen                 = MAX_CONFIG_LEN,
 };
 
+static int kgdboc_use_kms;  /* 1 if we use kernel mode switching */
 static struct tty_driver       *kgdb_tty_driver;
 static int                     kgdb_tty_line;
 
@@ -104,6 +106,12 @@ static int configure_kgdboc(void)
        kgdboc_io_ops.is_console = 0;
        kgdb_tty_driver = NULL;
 
+       kgdboc_use_kms = 0;
+       if (strncmp(cptr, "kms,", 4) == 0) {
+               cptr += 4;
+               kgdboc_use_kms = 1;
+       }
+
        if (kgdboc_register_kbd(&cptr))
                goto do_register;
 
@@ -201,8 +209,14 @@ static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
        return configure_kgdboc();
 }
 
+static int dbg_restore_graphics;
+
 static void kgdboc_pre_exp_handler(void)
 {
+       if (!dbg_restore_graphics && kgdboc_use_kms) {
+               dbg_restore_graphics = 1;
+               con_debug_enter(vc_cons[fg_console].d);
+       }
        /* Increment the module count when the debugger is active */
        if (!kgdb_connected)
                try_module_get(THIS_MODULE);
@@ -213,6 +227,10 @@ static void kgdboc_post_exp_handler(void)
        /* decrement the module count when the debugger detaches */
        if (!kgdb_connected)
                module_put(THIS_MODULE);
+       if (kgdboc_use_kms && dbg_restore_graphics) {
+               dbg_restore_graphics = 0;
+               con_debug_leave();
+       }
 }
 
 static struct kgdb_io kgdboc_io_ops = {
index ab17c08ddc03cac3fcc6674dba53bd2a4e9960a9..141c69554bd481d27863b852bbd79b364417643e 100644 (file)
@@ -45,7 +45,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -115,16 +114,14 @@ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_
 
 static int quirk_post_ibm(struct pcmcia_device *link)
 {
-       conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
+       u8 val;
        int ret;
 
-       ret = pcmcia_access_configuration_register(link, &reg);
+       ret = pcmcia_read_config_byte(link, 0x800, &val);
        if (ret)
                goto failed;
 
-       reg.Action = CS_WRITE;
-       reg.Value = reg.Value | 1;
-       ret = pcmcia_access_configuration_register(link, &reg);
+       ret = pcmcia_write_config_byte(link, 0x800, val | 1);
        if (ret)
                goto failed;
        return 0;
@@ -338,8 +335,8 @@ static int serial_probe(struct pcmcia_device *link)
        info->p_dev = link;
        link->priv = info;
 
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.NumPorts1 = 8;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[0]->end = 8;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        if (do_sound) {
                link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -427,12 +424,13 @@ static int simple_config_check(struct pcmcia_device *p_dev,
                p_dev->conf.Vpp =
                        cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
 
+       p_dev->io_lines = ((*try & 0x1) == 0) ?
+                       16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+
        if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)])
            && (cf->io.win[0].base != 0)) {
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ?
-                       16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               p_dev->resource[0]->start = cf->io.win[0].base;
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        }
        return -EINVAL;
@@ -449,9 +447,9 @@ static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
 
        if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
                for (j = 0; j < 5; j++) {
-                       p_dev->io.BasePort1 = base[j];
-                       p_dev->io.IOAddrLines = base[j] ? 16 : 3;
-                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       p_dev->resource[0]->start = base[j];
+                       p_dev->io_lines = base[j] ? 16 : 3;
+                       if (!pcmcia_request_io(p_dev))
                                return 0;
                }
        }
@@ -466,13 +464,13 @@ static int simple_config(struct pcmcia_device *link)
        /* If the card is already configured, look up the port and irq */
        if (link->function_config) {
                unsigned int port = 0;
-               if ((link->io.BasePort2 != 0) &&
-                   (link->io.NumPorts2 == 8)) {
-                       port = link->io.BasePort2;
+               if ((link->resource[1]->end != 0) &&
+                       (resource_size(link->resource[1]) == 8)) {
+                       port = link->resource[1]->end;
                        info->slave = 1;
                } else if ((info->manfid == MANFID_OSITECH) &&
-                          (link->io.NumPorts1 == 0x40)) {
-                       port = link->io.BasePort1 + 0x28;
+                       (resource_size(link->resource[0]) == 0x40)) {
+                       port = link->resource[0]->start + 0x28;
                        info->slave = 1;
                }
                if (info->slave) {
@@ -510,7 +508,7 @@ found_port:
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0)
                return -1;
-       return setup_serial(link, info, link->io.BasePort1, link->irq);
+       return setup_serial(link, info, link->resource[0]->start, link->irq);
 }
 
 static int multi_config_check(struct pcmcia_device *p_dev,
@@ -524,10 +522,10 @@ static int multi_config_check(struct pcmcia_device *p_dev,
        /* The quad port cards have bad CIS's, so just look for a
           window larger than 8 ports and assume it will be right */
        if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev, &p_dev->io)) {
-                       *base2 = p_dev->io.BasePort1 + 8;
+               p_dev->resource[0]->start = cf->io.win[0].base;
+               p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
+               if (!pcmcia_request_io(p_dev)) {
+                       *base2 = p_dev->resource[0]->start + 8;
                        return 0;
                }
        }
@@ -543,11 +541,11 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
        int *base2 = priv_data;
 
        if (cf->io.nwin == 2) {
-               p_dev->io.BasePort1 = cf->io.win[0].base;
-               p_dev->io.BasePort2 = cf->io.win[1].base;
-               p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev, &p_dev->io)) {
-                       *base2 = p_dev->io.BasePort2;
+               p_dev->resource[0]->start = cf->io.win[0].base;
+               p_dev->resource[1]->start = cf->io.win[1].base;
+               p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
+               if (!pcmcia_request_io(p_dev)) {
+                       *base2 = p_dev->resource[1]->start;
                        return 0;
                }
        }
@@ -560,10 +558,10 @@ static int multi_config(struct pcmcia_device *link)
        int i, base2 = 0;
 
        /* First, look for a generic full-sized window */
-       link->io.NumPorts1 = info->multi * 8;
+       link->resource[0]->end = info->multi * 8;
        if (pcmcia_loop_config(link, multi_config_check, &base2)) {
                /* If that didn't work, look for two windows */
-               link->io.NumPorts1 = link->io.NumPorts2 = 8;
+               link->resource[0]->end = link->resource[1]->end = 8;
                info->multi = 2;
                if (pcmcia_loop_config(link, multi_config_check_notpicky,
                                       &base2)) {
@@ -599,9 +597,9 @@ static int multi_config(struct pcmcia_device *link)
                    link->conf.ConfigIndex == 3) {
                        err = setup_serial(link, info, base2,
                                        link->irq);
-                       base2 = link->io.BasePort1;
+                       base2 = link->resource[0]->start;;
                } else {
-                       err = setup_serial(link, info, link->io.BasePort1,
+                       err = setup_serial(link, info, link->resource[0]->start,
                                        link->irq);
                }
                info->c950ctrl = base2;
@@ -616,7 +614,7 @@ static int multi_config(struct pcmcia_device *link)
                return 0;
        }
 
-       setup_serial(link, info, link->io.BasePort1, link->irq);
+       setup_serial(link, info, link->resource[0]->start, link->irq);
        for (i = 0; i < info->multi - 1; i++)
                setup_serial(link, info, base2 + (8 * i),
                                link->irq);
index 890f91742962433e8b710d060ede982070e09391..a779e22d213ee3abd9f5c1cfa6f267a4fdba96c8 100644 (file)
@@ -525,7 +525,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
        unsigned long minor;
        int err;
 
-       if (op->irqs[0] == 0xffffffff)
+       if (op->archdata.irqs[0] == 0xffffffff)
                return -ENODEV;
 
        port = kzalloc(sizeof(struct uart_port), GFP_KERNEL);
@@ -557,7 +557,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
 
        port->membase = (unsigned char __iomem *) __pa(port);
 
-       port->irq = op->irqs[0];
+       port->irq = op->archdata.irqs[0];
 
        port->dev = &op->dev;
 
@@ -644,12 +644,12 @@ static int __init sunhv_init(void)
        if (tlb_type != hypervisor)
                return -ENODEV;
 
-       return of_register_driver(&hv_driver, &of_bus_type);
+       return of_register_platform_driver(&hv_driver);
 }
 
 static void __exit sunhv_exit(void)
 {
-       of_unregister_driver(&hv_driver);
+       of_unregister_platform_driver(&hv_driver);
 }
 
 module_init(sunhv_init);
index 5e81bc6b48b0738ad307b9be94149da299f6063f..9845fb1cfb1ffea3438681f8c36f2c42fa58556d 100644 (file)
@@ -969,7 +969,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
                return -ENOMEM;
        up->regs = (union sab82532_async_regs __iomem *) up->port.membase;
 
-       up->port.irq = op->irqs[0];
+       up->port.irq = op->archdata.irqs[0];
 
        up->port.fifosize = SAB82532_XMIT_FIFO_SIZE;
        up->port.iotype = UPIO_MEM;
@@ -1130,12 +1130,12 @@ static int __init sunsab_init(void)
                }
        }
 
-       return of_register_driver(&sab_driver, &of_bus_type);
+       return of_register_platform_driver(&sab_driver);
 }
 
 static void __exit sunsab_exit(void)
 {
-       of_unregister_driver(&sab_driver);
+       of_unregister_platform_driver(&sab_driver);
        if (sunsab_reg.nr) {
                sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr);
        }
index ffbf4553f6651966269b1be1bc57b43b37b34b98..3cdf74822db51336f98f955efcbebf95090b47cc 100644 (file)
@@ -1443,7 +1443,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
                return -ENOMEM;
        }
 
-       up->port.irq = op->irqs[0];
+       up->port.irq = op->archdata.irqs[0];
 
        up->port.dev = &op->dev;
 
@@ -1586,7 +1586,7 @@ static int __init sunsu_init(void)
                        return err;
        }
 
-       err = of_register_driver(&su_driver, &of_bus_type);
+       err = of_register_platform_driver(&su_driver);
        if (err && num_uart)
                sunserial_unregister_minors(&sunsu_reg, num_uart);
 
index f9a24f4ebb3479626073c23ffa906320dcf025a5..d1e6bcb59546b993128edacac119182b834a01e3 100644 (file)
@@ -1426,7 +1426,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
        rp = sunzilog_chip_regs[inst];
 
        if (zilog_irq == -1)
-               zilog_irq = op->irqs[0];
+               zilog_irq = op->archdata.irqs[0];
 
        up = &sunzilog_port_table[inst * 2];
 
@@ -1434,7 +1434,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
        up[0].port.mapbase = op->resource[0].start + 0x00;
        up[0].port.membase = (void __iomem *) &rp->channelA;
        up[0].port.iotype = UPIO_MEM;
-       up[0].port.irq = op->irqs[0];
+       up[0].port.irq = op->archdata.irqs[0];
        up[0].port.uartclk = ZS_CLOCK;
        up[0].port.fifosize = 1;
        up[0].port.ops = &sunzilog_pops;
@@ -1451,7 +1451,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
        up[1].port.mapbase = op->resource[0].start + 0x04;
        up[1].port.membase = (void __iomem *) &rp->channelB;
        up[1].port.iotype = UPIO_MEM;
-       up[1].port.irq = op->irqs[0];
+       up[1].port.irq = op->archdata.irqs[0];
        up[1].port.uartclk = ZS_CLOCK;
        up[1].port.fifosize = 1;
        up[1].port.ops = &sunzilog_pops;
@@ -1492,12 +1492,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
                       "is a %s\n",
                       dev_name(&op->dev),
                       (unsigned long long) up[0].port.mapbase,
-                      op->irqs[0], sunzilog_type(&up[0].port));
+                      op->archdata.irqs[0], sunzilog_type(&up[0].port));
                printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) "
                       "is a %s\n",
                       dev_name(&op->dev),
                       (unsigned long long) up[1].port.mapbase,
-                      op->irqs[0], sunzilog_type(&up[1].port));
+                      op->archdata.irqs[0], sunzilog_type(&up[1].port));
                kbm_inst++;
        }
 
@@ -1576,7 +1576,7 @@ static int __init sunzilog_init(void)
                        goto out_free_tables;
        }
 
-       err = of_register_driver(&zs_driver, &of_bus_type);
+       err = of_register_platform_driver(&zs_driver);
        if (err)
                goto out_unregister_uart;
 
@@ -1604,7 +1604,7 @@ out:
        return err;
 
 out_unregister_driver:
-       of_unregister_driver(&zs_driver);
+       of_unregister_platform_driver(&zs_driver);
 
 out_unregister_uart:
        if (num_sunzilog) {
@@ -1619,7 +1619,7 @@ out_free_tables:
 
 static void __exit sunzilog_exit(void)
 {
-       of_unregister_driver(&zs_driver);
+       of_unregister_platform_driver(&zs_driver);
 
        if (zilog_irq != -1) {
                struct uart_sunzilog_port *up = sunzilog_irq_chain;
index 8acccd564378aaa405f2fb04cf1958b532499993..caf085d3a76abdc18c8e2cca06e7304a503342d4 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/io.h>
 #if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 
index 2534b1ec3eddc5b39485c8fa71fff21dcbef07d3..10baac3f8ea53d1ed3a8cafe6b9d90dd561eb771 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/workqueue.h>
 #include <linux/completion.h>
@@ -440,6 +441,7 @@ static int __init mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
        master->setup = mpc512x_psc_spi_setup;
        master->transfer = mpc512x_psc_spi_transfer;
        master->cleanup = mpc512x_psc_spi_cleanup;
+       master->dev.of_node = dev->of_node;
 
        tempp = ioremap(regaddr, size);
        if (!tempp) {
index 7104cb739da7eceab4af5a2bcf644c0aaa239d26..66d170147dccabc9cbb22d5c8e1d50af39225415 100644 (file)
@@ -16,8 +16,8 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
-#include <linux/of_spi.h>
 #include <linux/workqueue.h>
 #include <linux/completion.h>
 #include <linux/io.h>
@@ -398,6 +398,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
        master->setup = mpc52xx_psc_spi_setup;
        master->transfer = mpc52xx_psc_spi_transfer;
        master->cleanup = mpc52xx_psc_spi_cleanup;
+       master->dev.of_node = dev->of_node;
 
        mps->psc = ioremap(regaddr, size);
        if (!mps->psc) {
@@ -470,7 +471,6 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
        const u32 *regaddr_p;
        u64 regaddr64, size64;
        s16 id = -1;
-       int rc;
 
        regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
        if (!regaddr_p) {
@@ -491,13 +491,8 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
                id = *psc_nump + 1;
        }
 
-       rc = mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
+       return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
                                irq_of_parse_and_map(op->dev.of_node, 0), id);
-       if (rc == 0)
-               of_register_spi_devices(dev_get_drvdata(&op->dev),
-                                       op->dev.of_node);
-
-       return rc;
 }
 
 static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op)
index b1a76bff775f8f2c11e0c1d35efc41039fa95acf..56136ff00e01643dbfe46754e0f3aefce01d11dc 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/spi/spi.h>
-#include <linux/of_spi.h>
 #include <linux/io.h>
 #include <linux/of_gpio.h>
 #include <linux/slab.h>
@@ -439,6 +438,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
        master->setup = mpc52xx_spi_setup;
        master->transfer = mpc52xx_spi_transfer;
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
+       master->dev.of_node = op->dev.of_node;
 
        dev_set_drvdata(&op->dev, master);
 
@@ -512,7 +512,6 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
        if (rc)
                goto err_register;
 
-       of_register_spi_devices(master, op->dev.of_node);
        dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n");
 
        return rc;
index b3a1f9259b62539d6f2b3bd4c2a501f93c337cee..1bb1b88780cefc4cd69e88e15d4e1f5413c55d1e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
+#include <linux/of_spi.h>
 
 
 /* SPI bustype and spi_master class are registered after board init code
@@ -540,6 +541,9 @@ int spi_register_master(struct spi_master *master)
        /* populate children from any spi device tables */
        scan_boardinfo(master);
        status = 0;
+
+       /* Register devices from the device tree */
+       of_register_spi_devices(master);
 done:
        return status;
 }
index 97ab0a81338adf036bea9e706dbcbe552b6d607c..aad9ae1b9c69093b829aa09c942b7a8a8b53dd78 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/of_platform.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
-#include <linux/of_spi.h>
 #include <linux/slab.h>
 
 #include <sysdev/fsl_soc.h>
@@ -1009,6 +1008,7 @@ mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
        master->setup = mpc8xxx_spi_setup;
        master->transfer = mpc8xxx_spi_transfer;
        master->cleanup = mpc8xxx_spi_cleanup;
+       master->dev.of_node = dev->of_node;
 
        mpc8xxx_spi = spi_master_get_devdata(master);
        mpc8xxx_spi->dev = dev;
@@ -1299,8 +1299,6 @@ static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev,
                goto err;
        }
 
-       of_register_spi_devices(master, np);
-
        return 0;
 
 err:
index d53466a249d9700bb9108478a5b08ffcf1955b6a..0f5fa7e2a55041f6f4695bcd4f54f2f2167ff6d7 100644 (file)
@@ -407,6 +407,7 @@ static int __init spi_ppc4xx_of_probe(struct of_device *op,
        master = spi_alloc_master(dev, sizeof *hw);
        if (master == NULL)
                return -ENOMEM;
+       master->dev.of_node = np;
        dev_set_drvdata(dev, master);
        hw = spi_master_get_devdata(master);
        hw->master = spi_master_get(master);
@@ -545,7 +546,6 @@ static int __init spi_ppc4xx_of_probe(struct of_device *op,
        }
 
        dev_info(dev, "driver initialized\n");
-       of_register_spi_devices(master, np);
 
        return 0;
 
index 1b47363cb73f6d8c624b0af5bc44d2047e6ae8a7..80f2db5bcfd6e669bdd136c25f2d04ebb51d4595 100644 (file)
@@ -390,6 +390,9 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
 
        master->bus_num = bus_num;
        master->num_chipselect = pdata->num_chipselect;
+#ifdef CONFIG_OF
+       master->dev.of_node = dev->of_node;
+#endif
 
        xspi->mem = *mem;
        xspi->irq = irq;
index 4654805b08d887f8b44460ef174941040effc0b6..f53d3f6b9f611671ccc31d6bf5afb847882a9153 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
 #include <linux/of_spi.h>
@@ -80,9 +81,6 @@ static int __devinit xilinx_spi_of_probe(struct of_device *ofdev,
 
        dev_set_drvdata(&ofdev->dev, master);
 
-       /* Add any subnodes on the SPI bus */
-       of_register_spi_devices(master, ofdev->dev.of_node);
-
        return 0;
 }
 
index 7cee7f4eb60b8f761fe2552e483c59f1f6e3efac..7892ac163522cd0e62f568fbc7cefcea173f298e 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/mmc/sdio_func.h>
 #include <linux/slab.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index e72f4046a5e0ee1cccb46a7bd11362261f9f3e0b..526682d68de8b67247c65703ea1bcff83c1988a7 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/io.h>
 #include <linux/etherdevice.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
 /* Write to a PCMCIA configuration register. */
 static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
 {
-       conf_reg_t reg;
        int res;
 
-       memset(&reg, 0, sizeof(reg));
-       reg.Offset = offset;
-       reg.Action = CS_WRITE;
-       reg.Value = value;
-       res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
+       res = pcmcia_write_config_byte(bus->host_pcmcia, offset, value);
        if (unlikely(res != 0))
                return -EBUSY;
 
@@ -89,16 +83,11 @@ static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
 /* Read from a PCMCIA configuration register. */
 static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
 {
-       conf_reg_t reg;
        int res;
 
-       memset(&reg, 0, sizeof(reg));
-       reg.Offset = offset;
-       reg.Action = CS_READ;
-       res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
+       res = pcmcia_read_config_byte(bus->host_pcmcia, offset, value);
        if (unlikely(res != 0))
                return -EBUSY;
-       *value = reg.Value;
 
        return 0;
 }
index 0d6c0280eb34cf6d2e20db19faf51107b9bfa89b..9738cad4ba13fb9f269bfa37a451fe307fc3e276 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/pci.h>
 #include <linux/io.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index 0e4122ed1b363fd8581d71268b24d1720c664562..4a7a7a7f11b67b6efd6b559023824dadeefdff07 100644 (file)
@@ -97,6 +97,8 @@ source "drivers/staging/octeon/Kconfig"
 
 source "drivers/staging/serqt_usb2/Kconfig"
 
+source "drivers/staging/spectra/Kconfig"
+
 source "drivers/staging/quatech_usb2/Kconfig"
 
 source "drivers/staging/vt6655/Kconfig"
@@ -115,7 +117,7 @@ source "drivers/staging/sep/Kconfig"
 
 source "drivers/staging/iio/Kconfig"
 
-source "drivers/staging/ramzswap/Kconfig"
+source "drivers/staging/zram/Kconfig"
 
 source "drivers/staging/wlags49_h2/Kconfig"
 
@@ -127,8 +129,6 @@ source "drivers/staging/samsung-laptop/Kconfig"
 
 source "drivers/staging/sm7xx/Kconfig"
 
-source "drivers/staging/dt3155/Kconfig"
-
 source "drivers/staging/dt3155v4l/Kconfig"
 
 source "drivers/staging/crystalhd/Kconfig"
@@ -147,5 +147,13 @@ source "drivers/staging/msm/Kconfig"
 
 source "drivers/staging/lirc/Kconfig"
 
+source "drivers/staging/easycap/Kconfig"
+
+source "drivers/staging/solo6x10/Kconfig"
+
+source "drivers/staging/tidspbridge/Kconfig"
+
+source "drivers/staging/quickstart/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING
index ecfb0bb990b6222d1cc7fcbee550bf6ec1c8856c..ca5c03eb3ce36e233280f7f4bb00ceae5697e4e9 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_R8187SE)         += rtl8187se/
 obj-$(CONFIG_RTL8192SU)                += rtl8192su/
 obj-$(CONFIG_RTL8192U)         += rtl8192u/
 obj-$(CONFIG_RTL8192E)         += rtl8192e/
+obj-$(CONFIG_SPECTRA)          += spectra/
 obj-$(CONFIG_TRANZPORT)                += frontier/
 obj-$(CONFIG_DREAM)            += dream/
 obj-$(CONFIG_POHMELFS)         += pohmelfs/
@@ -39,13 +40,12 @@ obj-$(CONFIG_VME_BUS)               += vme/
 obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
 obj-$(CONFIG_DX_SEP)           += sep/
 obj-$(CONFIG_IIO)              += iio/
-obj-$(CONFIG_RAMZSWAP)         += ramzswap/
+obj-$(CONFIG_ZRAM)             += zram/
 obj-$(CONFIG_WLAGS49_H2)       += wlags49_h2/
 obj-$(CONFIG_WLAGS49_H25)      += wlags49_h25/
 obj-$(CONFIG_BATMAN_ADV)       += batman-adv/
 obj-$(CONFIG_SAMSUNG_LAPTOP)   += samsung-laptop/
 obj-$(CONFIG_FB_SM7XX)         += sm7xx/
-obj-$(CONFIG_DT3155)           += dt3155/
 obj-$(CONFIG_VIDEO_DT3155)     += dt3155v4l/
 obj-$(CONFIG_CRYSTALHD)                += crystalhd/
 obj-$(CONFIG_CXT1E1)           += cxt1e1/
@@ -54,3 +54,7 @@ obj-$(CONFIG_ADIS16255)               += adis16255/
 obj-$(CONFIG_FB_XGI)           += xgifb/
 obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH)     += mrst-touchscreen/
 obj-$(CONFIG_MSM_STAGING)      += msm/
+obj-$(CONFIG_EASYCAP)          += easycap/
+obj-$(CONFIG_SOLO6X10)         += solo6x10/
+obj-$(CONFIG_TIDSPBRIDGE)      += tidspbridge/
+obj-$(CONFIG_ACPI_QUICKSTART)  += quickstart/
index 55d66e290f7d1d80eb0e1603c12b4b7224031c0e..c3e6a4d5f33429ff76cdc001192259fe60a6fc59 100644 (file)
@@ -303,7 +303,7 @@ static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
        if (status != 0)
                goto err;
        if (value != 0x0800) {
-               dev_warn(&spiadis->spi->dev, "Scale factor is none default"
+               dev_warn(&spiadis->spi->dev, "Scale factor is none default "
                                "value (%.4x)\n", value);
        }
 
@@ -338,7 +338,7 @@ static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
                        status = -ENODEV;
                        goto err;
                } else if (value & 0x3) {
-                       dev_warn(&spiadis->spi->dev, "Sensor voltage"
+                       dev_warn(&spiadis->spi->dev, "Sensor voltage "
                                                "out of range.\n");
                        status = -ENODEV;
                        goto err;
index c8f9d9e06bb475b91a61e0334f8a890d4a6e42bd..86450b4f7d763ad2bf27963a852e4f0a1c652afa 100644 (file)
@@ -1,3 +1,15 @@
+batman-adv 2010.0.0:
+
+* support latest kernels (2.6.21 - 2.6.35)
+* further code refactoring and cleaning for coding style
+* move from procfs based configuration to sysfs
+* reorganized sequence number handling
+* limit queue lengths for batman and broadcast packets
+* many bugs (endless loop and rogue packets on shutdown, wrong tcpdump output,
+  missing frees in error situations, sleeps in atomic contexts) squashed
+
+ -- Fri, 18 Jun 2010 21:34:26 +0200
+
 batman-adv 0.2.1:
 
 * support latest kernels (2.6.20 - 2.6.33)
index 1e7e0a8dbc8ba8ae612f311e2a9db70b9b91ef3a..8553f35174541a346d5bcf1ad6b327ed81d888d0 100644 (file)
@@ -4,7 +4,7 @@
 
 config BATMAN_ADV
        tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
-       depends on PROC_FS && NET
+       depends on NET
         default n
        ---help---
 
index f25068c0fae669ccdbad16d84b2580182a3ac019..e9817b5a614c90cffa961ed075054baff343680b 100644 (file)
@@ -18,5 +18,5 @@
 # 02110-1301, USA
 #
 
-obj-m += batman-adv.o
-batman-adv-objs := main.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 bat_sysfs.o
+obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
+batman-adv-objs := main.o bat_debugfs.o bat_sysfs.o send.o routing.o soft-interface.o icmp_socket.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o
index 14244a2c4e4f3dd2d1ce842d2827923c88fc5691..7192b7fa218301d5e65ccd8a415ee134b34628b2 100644 (file)
@@ -1,4 +1,4 @@
-[state: 03-05-2010]
+[state: 12-06-2010]
 
 BATMAN-ADV
 ----------
index 518db7fd41b15a9936120769935f30216b8e2289..9c5aea20be153d24de2e25ac5dac81a64ed4645b 100644 (file)
@@ -1,6 +1,9 @@
-Request a review.
-Process the comments from the review.
-Move into mainline proper.
+ * Use hweight* for hamming weight calculation
+ * Save/cache packets direktly as skb instead of using a normal memory region
+   and copying it in a skb using send_raw_packet and similar functions
+ * Request a new review
+ * Process the comments from the review
+ * Move into mainline proper
 
 Please send all patches to:
        Marek Lindner <lindner_marek@yahoo.de>
index ce8b8a6e5ae6462d8336236a1a46ad0cef8d2126..9862d16bbdc88e977914f8d13986e09ac6720fd6 100644 (file)
@@ -106,11 +106,14 @@ static void new_aggregated_packet(unsigned char *packet_buff,
 {
        struct forw_packet *forw_packet_aggr;
        unsigned long flags;
+       /* FIXME: each batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
 
        /* own packet should always be scheduled */
        if (!own_packet) {
                if (!atomic_dec_not_zero(&batman_queue_left)) {
-                       bat_dbg(DBG_BATMAN, "batman packet queue full\n");
+                       bat_dbg(DBG_BATMAN, bat_priv,
+                               "batman packet queue full\n");
                        return;
                }
        }
@@ -252,9 +255,9 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
        while (aggregated_packet(buff_pos, packet_len,
                                 batman_packet->num_hna)) {
 
-               /* network to host order for our 16bit seqno, and the
+               /* network to host order for our 32bit seqno, and the
                   orig_interval. */
-               batman_packet->seqno = ntohs(batman_packet->seqno);
+               batman_packet->seqno = ntohl(batman_packet->seqno);
 
                hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
                receive_bat_packet(ethhdr, batman_packet,
index 84401ca24c35c97ca473647f5efb4db48bf6e794..71a91b3da913aa1438a44edb9d1295e8d6679e9d 100644 (file)
@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_AGGREGATION_H_
+#define _NET_BATMAN_ADV_AGGREGATION_H_
+
 #include "main.h"
 
 /* is there another aggregated packet here? */
@@ -36,3 +39,5 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
                            unsigned long send_time);
 void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
                             int packet_len, struct batman_if *if_incoming);
+
+#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
diff --git a/drivers/staging/batman-adv/bat_debugfs.c b/drivers/staging/batman-adv/bat_debugfs.c
new file mode 100644 (file)
index 0000000..507da68
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+
+#include <linux/debugfs.h>
+
+#include "bat_debugfs.h"
+#include "translation-table.h"
+#include "originator.h"
+#include "hard-interface.h"
+#include "vis.h"
+#include "icmp_socket.h"
+
+static struct dentry *bat_debugfs;
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+#define LOG_BUFF_MASK (log_buff_len-1)
+#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK])
+
+static int log_buff_len = LOG_BUF_LEN;
+
+static void emit_log_char(struct debug_log *debug_log, char c)
+{
+       LOG_BUFF(debug_log->log_end) = c;
+       debug_log->log_end++;
+
+       if (debug_log->log_end - debug_log->log_start > log_buff_len)
+               debug_log->log_start = debug_log->log_end - log_buff_len;
+}
+
+static int fdebug_log(struct debug_log *debug_log, char *fmt, ...)
+{
+       int printed_len;
+       va_list args;
+       static char debug_log_buf[256];
+       char *p;
+       unsigned long flags;
+
+       if (!debug_log)
+               return 0;
+
+       spin_lock_irqsave(&debug_log->lock, flags);
+       va_start(args, fmt);
+       printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf),
+                                fmt, args);
+       va_end(args);
+
+       for (p = debug_log_buf; *p != 0; p++)
+               emit_log_char(debug_log, *p);
+
+       spin_unlock_irqrestore(&debug_log->lock, flags);
+
+       wake_up(&debug_log->queue_wait);
+
+       return 0;
+}
+
+int debug_log(struct bat_priv *bat_priv, char *fmt, ...)
+{
+       va_list args;
+       char tmp_log_buf[256];
+
+       va_start(args, fmt);
+       vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
+       fdebug_log(bat_priv->debug_log, "[%10u] %s",
+                  (jiffies / HZ), tmp_log_buf);
+       va_end(args);
+
+       return 0;
+}
+
+static int log_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       inc_module_count();
+       return 0;
+}
+
+static int log_release(struct inode *inode, struct file *file)
+{
+       dec_module_count();
+       return 0;
+}
+
+static ssize_t log_read(struct file *file, char __user *buf,
+                       size_t count, loff_t *ppos)
+{
+       struct bat_priv *bat_priv = file->private_data;
+       struct debug_log *debug_log = bat_priv->debug_log;
+       int error, i = 0;
+       char c;
+       unsigned long flags;
+
+       if ((file->f_flags & O_NONBLOCK) &&
+           !(debug_log->log_end - debug_log->log_start))
+               return -EAGAIN;
+
+       if ((!buf) || (count < 0))
+               return -EINVAL;
+
+       if (count == 0)
+               return 0;
+
+       if (!access_ok(VERIFY_WRITE, buf, count))
+               return -EFAULT;
+
+       error = wait_event_interruptible(debug_log->queue_wait,
+                               (debug_log->log_start - debug_log->log_end));
+
+       if (error)
+               return error;
+
+       spin_lock_irqsave(&debug_log->lock, flags);
+
+       while ((!error) && (i < count) &&
+              (debug_log->log_start != debug_log->log_end)) {
+               c = LOG_BUFF(debug_log->log_start);
+
+               debug_log->log_start++;
+
+               spin_unlock_irqrestore(&debug_log->lock, flags);
+
+               error = __put_user(c, buf);
+
+               spin_lock_irqsave(&debug_log->lock, flags);
+
+               buf++;
+               i++;
+
+       }
+
+       spin_unlock_irqrestore(&debug_log->lock, flags);
+
+       if (!error)
+               return i;
+
+       return error;
+}
+
+static unsigned int log_poll(struct file *file, poll_table *wait)
+{
+       struct bat_priv *bat_priv = file->private_data;
+       struct debug_log *debug_log = bat_priv->debug_log;
+
+       poll_wait(file, &debug_log->queue_wait, wait);
+
+       if (debug_log->log_end - debug_log->log_start)
+               return POLLIN | POLLRDNORM;
+
+       return 0;
+}
+
+static const struct file_operations log_fops = {
+       .open           = log_open,
+       .release        = log_release,
+       .read           = log_read,
+       .poll           = log_poll,
+};
+
+static int debug_log_setup(struct bat_priv *bat_priv)
+{
+       struct dentry *d;
+
+       if (!bat_priv->debug_dir)
+               goto err;
+
+       bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC);
+       if (!bat_priv->debug_log)
+               goto err;
+
+       spin_lock_init(&bat_priv->debug_log->lock);
+       init_waitqueue_head(&bat_priv->debug_log->queue_wait);
+
+       d = debugfs_create_file("log", S_IFREG | S_IRUSR,
+                               bat_priv->debug_dir, bat_priv, &log_fops);
+       if (d)
+               goto err;
+
+       return 0;
+
+err:
+       return 1;
+}
+
+static void debug_log_cleanup(struct bat_priv *bat_priv)
+{
+       kfree(bat_priv->debug_log);
+       bat_priv->debug_log = NULL;
+}
+#else /* CONFIG_BATMAN_ADV_DEBUG */
+static int debug_log_setup(struct bat_priv *bat_priv)
+{
+       bat_priv->debug_log = NULL;
+       return 0;
+}
+
+static void debug_log_cleanup(struct bat_priv *bat_priv)
+{
+       return;
+}
+#endif
+
+static int originators_open(struct inode *inode, struct file *file)
+{
+       struct net_device *net_dev = (struct net_device *)inode->i_private;
+       return single_open(file, orig_seq_print_text, net_dev);
+}
+
+static int transtable_global_open(struct inode *inode, struct file *file)
+{
+       struct net_device *net_dev = (struct net_device *)inode->i_private;
+       return single_open(file, hna_global_seq_print_text, net_dev);
+}
+
+static int transtable_local_open(struct inode *inode, struct file *file)
+{
+       struct net_device *net_dev = (struct net_device *)inode->i_private;
+       return single_open(file, hna_local_seq_print_text, net_dev);
+}
+
+static int vis_data_open(struct inode *inode, struct file *file)
+{
+       struct net_device *net_dev = (struct net_device *)inode->i_private;
+       return single_open(file, vis_seq_print_text, net_dev);
+}
+
+struct bat_debuginfo {
+       struct attribute attr;
+       const struct file_operations fops;
+};
+
+#define BAT_DEBUGINFO(_name, _mode, _open)     \
+struct bat_debuginfo bat_debuginfo_##_name = { \
+       .attr = { .name = __stringify(_name),   \
+                 .mode = _mode, },             \
+       .fops = { .owner = THIS_MODULE,         \
+                 .open = _open,                \
+                 .read = seq_read,             \
+                 .llseek = seq_lseek,          \
+                 .release = single_release,    \
+               }                               \
+};
+
+static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
+static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
+static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
+static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
+
+static struct bat_debuginfo *mesh_debuginfos[] = {
+       &bat_debuginfo_originators,
+       &bat_debuginfo_transtable_global,
+       &bat_debuginfo_transtable_local,
+       &bat_debuginfo_vis_data,
+       NULL,
+};
+
+void debugfs_init(void)
+{
+       bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
+       if (bat_debugfs == ERR_PTR(-ENODEV))
+               bat_debugfs = NULL;
+}
+
+void debugfs_destroy(void)
+{
+       if (bat_debugfs) {
+               debugfs_remove_recursive(bat_debugfs);
+               bat_debugfs = NULL;
+       }
+}
+
+int debugfs_add_meshif(struct net_device *dev)
+{
+       struct bat_priv *bat_priv = netdev_priv(dev);
+       struct bat_debuginfo **bat_debug;
+       struct dentry *file;
+
+       if (!bat_debugfs)
+               goto out;
+
+       bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs);
+       if (!bat_priv->debug_dir)
+               goto out;
+
+       bat_socket_setup(bat_priv);
+       debug_log_setup(bat_priv);
+
+       for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) {
+               file = debugfs_create_file(((*bat_debug)->attr).name,
+                                         S_IFREG | ((*bat_debug)->attr).mode,
+                                         bat_priv->debug_dir,
+                                         dev, &(*bat_debug)->fops);
+               if (!file) {
+                       bat_err(dev, "Can't add debugfs file: %s/%s\n",
+                               dev->name, ((*bat_debug)->attr).name);
+                       goto rem_attr;
+               }
+       }
+
+       return 0;
+rem_attr:
+       debugfs_remove_recursive(bat_priv->debug_dir);
+       bat_priv->debug_dir = NULL;
+out:
+#ifdef CONFIG_DEBUG_FS
+       return -ENOMEM;
+#else
+       return 0;
+#endif /* CONFIG_DEBUG_FS */
+}
+
+void debugfs_del_meshif(struct net_device *dev)
+{
+       struct bat_priv *bat_priv = netdev_priv(dev);
+
+       debug_log_cleanup(bat_priv);
+
+       if (bat_debugfs) {
+               debugfs_remove_recursive(bat_priv->debug_dir);
+               bat_priv->debug_dir = NULL;
+       }
+}
diff --git a/drivers/staging/batman-adv/bat_debugfs.h b/drivers/staging/batman-adv/bat_debugfs.h
new file mode 100644 (file)
index 0000000..72df532
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+
+#ifndef _NET_BATMAN_ADV_DEBUGFS_H_
+#define _NET_BATMAN_ADV_DEBUGFS_H_
+
+#define DEBUGFS_BAT_SUBDIR "batman_adv"
+
+void debugfs_init(void);
+void debugfs_destroy(void);
+int debugfs_add_meshif(struct net_device *dev);
+void debugfs_del_meshif(struct net_device *dev);
+
+#endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */
index 212bc21e6d682f7b3e822856be86c1af6f916102..b4a8d5eb64fabc4879bd11e27577c2ed12f5b00a 100644 (file)
 
 #define to_dev(obj)     container_of(obj, struct device, kobj)
 
-struct bat_attribute {
-       struct attribute attr;
-       ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
-                       char *buf);
-       ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
-                        char *buf, size_t count);
-};
-
-struct hardif_attribute {
-       struct attribute attr;
-       ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
-                       char *buf);
-       ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
-                        char *buf, size_t count);
-};
-
 #define BAT_ATTR(_name, _mode, _show, _store)  \
 struct bat_attribute bat_attr_##_name = {      \
        .attr = {.name = __stringify(_name),    \
@@ -52,34 +36,18 @@ struct bat_attribute bat_attr_##_name = {   \
        .store  = _store,                       \
 };
 
-#define BAT_BIN_ATTR(_name, _mode, _read, _write)      \
-struct bin_attribute bat_attr_##_name = {              \
-       .attr = { .name = __stringify(_name),           \
-                 .mode = _mode, },                     \
-       .read = _read,                                  \
-       .write = _write,                                \
-};
-
-#define HARDIF_ATTR(_name, _mode, _show, _store)       \
-struct hardif_attribute hardif_attr_##_name = {                \
-       .attr = {.name = __stringify(_name),            \
-                .mode = _mode },                       \
-       .show   = _show,                                \
-       .store  = _store,                               \
-};
-
-static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr,
+static ssize_t show_aggr_ogms(struct kobject *kobj, struct attribute *attr,
                             char *buff)
 {
        struct device *dev = to_dev(kobj->parent);
        struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
        int aggr_status = atomic_read(&bat_priv->aggregation_enabled);
 
-       return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1\n",
+       return sprintf(buff, "%s\n",
                       aggr_status == 0 ? "disabled" : "enabled");
 }
 
-static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr,
+static ssize_t store_aggr_ogms(struct kobject *kobj, struct attribute *attr,
                              char *buff, size_t count)
 {
        struct device *dev = to_dev(kobj->parent);
@@ -99,23 +67,73 @@ static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr,
                if (buff[count - 1] == '\n')
                        buff[count - 1] = '\0';
 
-               printk(KERN_INFO "batman-adv:Invalid parameter for 'aggregate OGM' setting on mesh %s received: %s\n",
-                      net_dev->name, buff);
+               bat_info(net_dev,
+                        "Invalid parameter for 'aggregate OGM' setting"
+                        "received: %s\n", buff);
                return -EINVAL;
        }
 
        if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp)
                return count;
 
-       printk(KERN_INFO "batman-adv:Changing aggregation from: %s to: %s on mesh: %s\n",
-              atomic_read(&bat_priv->aggregation_enabled) == 1 ?
-              "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled",
-              net_dev->name);
+       bat_info(net_dev, "Changing aggregation from: %s to: %s\n",
+                atomic_read(&bat_priv->aggregation_enabled) == 1 ?
+                "enabled" : "disabled", aggr_tmp == 1 ? "enabled" :
+                "disabled");
 
        atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp);
        return count;
 }
 
+static ssize_t show_bond(struct kobject *kobj, struct attribute *attr,
+                            char *buff)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+       int bond_status = atomic_read(&bat_priv->bonding_enabled);
+
+       return sprintf(buff, "%s\n",
+                      bond_status == 0 ? "disabled" : "enabled");
+}
+
+static ssize_t store_bond(struct kobject *kobj, struct attribute *attr,
+                         char *buff, size_t count)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct net_device *net_dev = to_net_dev(dev);
+       struct bat_priv *bat_priv = netdev_priv(net_dev);
+       int bonding_enabled_tmp = -1;
+
+       if (((count == 2) && (buff[0] == '1')) ||
+           (strncmp(buff, "enable", 6) == 0))
+               bonding_enabled_tmp = 1;
+
+       if (((count == 2) && (buff[0] == '0')) ||
+           (strncmp(buff, "disable", 7) == 0))
+               bonding_enabled_tmp = 0;
+
+       if (bonding_enabled_tmp < 0) {
+               if (buff[count - 1] == '\n')
+                       buff[count - 1] = '\0';
+
+               bat_err(net_dev,
+                       "Invalid parameter for 'bonding' setting received: "
+                       "%s\n", buff);
+               return -EINVAL;
+       }
+
+       if (atomic_read(&bat_priv->bonding_enabled) == bonding_enabled_tmp)
+               return count;
+
+       bat_info(net_dev, "Changing bonding from: %s to: %s\n",
+                atomic_read(&bat_priv->bonding_enabled) == 1 ?
+                "enabled" : "disabled",
+                bonding_enabled_tmp == 1 ? "enabled" : "disabled");
+
+       atomic_set(&bat_priv->bonding_enabled, (unsigned)bonding_enabled_tmp);
+       return count;
+}
+
 static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
                             char *buff)
 {
@@ -123,10 +141,9 @@ static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
        struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
        int vis_mode = atomic_read(&bat_priv->vis_mode);
 
-       return sprintf(buff, "status: %s\ncommands: client, server, %d, %d\n",
+       return sprintf(buff, "%s\n",
                       vis_mode == VIS_TYPE_CLIENT_UPDATE ?
-                                                       "client" : "server",
-                      VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE);
+                                                       "client" : "server");
 }
 
 static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
@@ -141,7 +158,8 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
        ret = strict_strtoul(buff, 10, &val);
 
        if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
-           (strncmp(buff, "client", 6) == 0))
+           (strncmp(buff, "client", 6) == 0) ||
+           (strncmp(buff, "off", 3) == 0))
                vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE;
 
        if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) ||
@@ -152,18 +170,19 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
                if (buff[count - 1] == '\n')
                        buff[count - 1] = '\0';
 
-               printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n",
-                      net_dev->name, buff);
+               bat_info(net_dev,
+                        "Invalid parameter for 'vis mode' setting received: "
+                        "%s\n", buff);
                return -EINVAL;
        }
 
        if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
                return count;
 
-       printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n",
-              atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
-              "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
-              "client" : "server", net_dev->name);
+       bat_info(net_dev, "Changing vis mode from: %s to: %s\n",
+                atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
+                "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
+                "client" : "server");
 
        atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp);
        return count;
@@ -175,7 +194,7 @@ static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr,
        struct device *dev = to_dev(kobj->parent);
        struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
 
-       return sprintf(buff, "status: %i\n",
+       return sprintf(buff, "%i\n",
                       atomic_read(&bat_priv->orig_interval));
 }
 
@@ -190,91 +209,87 @@ static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr,
 
        ret = strict_strtoul(buff, 10, &orig_interval_tmp);
        if (ret) {
-               printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n",
-                      net_dev->name, buff);
+               bat_info(net_dev, "Invalid parameter for 'orig_interval' "
+                        "setting received: %s\n", buff);
                return -EINVAL;
        }
 
-       if (orig_interval_tmp <= JITTER * 2) {
-               printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n",
-                      orig_interval_tmp, JITTER * 2);
+       if (orig_interval_tmp < JITTER * 2) {
+               bat_info(net_dev, "New originator interval too small: %li "
+                        "(min: %i)\n", orig_interval_tmp, JITTER * 2);
                return -EINVAL;
        }
 
        if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp)
                return count;
 
-       printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n",
-              atomic_read(&bat_priv->orig_interval),
-              orig_interval_tmp, net_dev->name);
+       bat_info(net_dev, "Changing originator interval from: %i to: %li\n",
+                atomic_read(&bat_priv->orig_interval),
+                orig_interval_tmp);
 
        atomic_set(&bat_priv->orig_interval, orig_interval_tmp);
        return count;
 }
 
-static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR,
-               show_aggr_ogm, store_aggr_ogm);
-static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
-static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
-               show_orig_interval, store_orig_interval);
-
-static struct bat_attribute *mesh_attrs[] = {
-       &bat_attr_aggregate_ogm,
-       &bat_attr_vis_mode,
-       &bat_attr_orig_interval,
-       NULL,
-};
-
-static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj,
-                                 struct bin_attribute *bin_attr,
-                                 char *buff, loff_t off, size_t count)
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+static ssize_t show_log_level(struct kobject *kobj, struct attribute *attr,
+                            char *buff)
 {
        struct device *dev = to_dev(kobj->parent);
-       struct net_device *net_dev = to_net_dev(dev);
+       struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+       int log_level = atomic_read(&bat_priv->log_level);
 
-       return hna_local_fill_buffer_text(net_dev, buff, count, off);
+       return sprintf(buff, "%d\n", log_level);
 }
 
-static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj,
-                                 struct bin_attribute *bin_attr,
-                                 char *buff, loff_t off, size_t count)
+static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr,
+                             char *buff, size_t count)
 {
        struct device *dev = to_dev(kobj->parent);
        struct net_device *net_dev = to_net_dev(dev);
+       struct bat_priv *bat_priv = netdev_priv(net_dev);
+       unsigned long log_level_tmp;
+       int ret;
 
-       return hna_global_fill_buffer_text(net_dev, buff, count, off);
-}
-
-static ssize_t originators_read(struct file *filp, struct kobject *kobj,
-                                 struct bin_attribute *bin_attr,
-                                 char *buff, loff_t off, size_t count)
-{
-       struct device *dev = to_dev(kobj->parent);
-       struct net_device *net_dev = to_net_dev(dev);
+       ret = strict_strtoul(buff, 10, &log_level_tmp);
+       if (ret) {
+               bat_info(net_dev, "Invalid parameter for 'log_level' "
+                        "setting received: %s\n", buff);
+               return -EINVAL;
+       }
 
-       return orig_fill_buffer_text(net_dev, buff, count, off);
-}
+       if (log_level_tmp > 3) {
+               bat_info(net_dev, "New log level too big: %li "
+                        "(max: %i)\n", log_level_tmp, 3);
+               return -EINVAL;
+       }
 
-static ssize_t vis_data_read(struct file *filp, struct kobject *kobj,
-                                 struct bin_attribute *bin_attr,
-                                 char *buff, loff_t off, size_t count)
-{
-       struct device *dev = to_dev(kobj->parent);
-       struct net_device *net_dev = to_net_dev(dev);
+       if (atomic_read(&bat_priv->log_level) == log_level_tmp)
+               return count;
 
-       return vis_fill_buffer_text(net_dev, buff, count, off);
+       atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp);
+       return count;
 }
+#endif
 
-static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL);
-static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL);
-static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL);
-static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
+static BAT_ATTR(aggregated_ogms, S_IRUGO | S_IWUSR,
+               show_aggr_ogms, store_aggr_ogms);
+static BAT_ATTR(bonding, S_IRUGO | S_IWUSR, show_bond, store_bond);
+static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
+static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
+               show_orig_interval, store_orig_interval);
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+static BAT_ATTR(log_level, S_IRUGO | S_IWUSR, show_log_level, store_log_level);
+#endif
 
-static struct bin_attribute *mesh_bin_attrs[] = {
-       &bat_attr_transtable_local,
-       &bat_attr_transtable_global,
-       &bat_attr_originators,
-       &bat_attr_vis_data,
+static struct bat_attribute *mesh_attrs[] = {
+       &bat_attr_aggregated_ogms,
+       &bat_attr_bonding,
+       &bat_attr_vis_mode,
+       &bat_attr_orig_interval,
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+       &bat_attr_log_level,
+#endif
        NULL,
 };
 
@@ -283,22 +298,24 @@ int sysfs_add_meshif(struct net_device *dev)
        struct kobject *batif_kobject = &dev->dev.kobj;
        struct bat_priv *bat_priv = netdev_priv(dev);
        struct bat_attribute **bat_attr;
-       struct bin_attribute **bin_attr;
        int err;
 
        /* FIXME: should be done in the general mesh setup
                  routine as soon as we have it */
        atomic_set(&bat_priv->aggregation_enabled, 1);
+       atomic_set(&bat_priv->bonding_enabled, 0);
        atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
        atomic_set(&bat_priv->orig_interval, 1000);
+       atomic_set(&bat_priv->log_level, 0);
+
        bat_priv->primary_if = NULL;
        bat_priv->num_ifaces = 0;
 
        bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
                                                    batif_kobject);
        if (!bat_priv->mesh_obj) {
-               printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
-                      dev->name, SYSFS_IF_MESH_SUBDIR);
+               bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
+                       SYSFS_IF_MESH_SUBDIR);
                goto out;
        }
 
@@ -306,28 +323,15 @@ int sysfs_add_meshif(struct net_device *dev)
                err = sysfs_create_file(bat_priv->mesh_obj,
                                        &((*bat_attr)->attr));
                if (err) {
-                       printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
-                              dev->name, SYSFS_IF_MESH_SUBDIR,
-                              ((*bat_attr)->attr).name);
+                       bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
+                               dev->name, SYSFS_IF_MESH_SUBDIR,
+                               ((*bat_attr)->attr).name);
                        goto rem_attr;
                }
        }
 
-       for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) {
-               err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr));
-               if (err) {
-                       printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
-                              dev->name, SYSFS_IF_MESH_SUBDIR,
-                              ((*bin_attr)->attr).name);
-                       goto rem_bin_attr;
-               }
-       }
-
        return 0;
 
-rem_bin_attr:
-       for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
-               sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
 rem_attr:
        for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
                sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
@@ -342,10 +346,6 @@ void sysfs_del_meshif(struct net_device *dev)
 {
        struct bat_priv *bat_priv = netdev_priv(dev);
        struct bat_attribute **bat_attr;
-       struct bin_attribute **bin_attr;
-
-       for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
-               sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
 
        for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
                sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
@@ -364,7 +364,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr,
        if (!batman_if)
                return 0;
 
-       return sprintf(buff, "status: %s\ncommands: none, bat0\n",
+       return sprintf(buff, "%s\n",
                       batman_if->if_status == IF_NOT_IN_USE ?
                                                        "none" : "bat0");
 }
@@ -390,8 +390,8 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
                if (buff[count - 1] == '\n')
                        buff[count - 1] = '\0';
 
-               printk(KERN_ERR "batman-adv:Invalid parameter for 'mesh_iface' setting received: %s\n",
-                      buff);
+               pr_err("Invalid parameter for 'mesh_iface' setting received: "
+                      "%s\n", buff);
                return -EINVAL;
        }
 
@@ -433,37 +433,37 @@ static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr,
        }
 }
 
-static HARDIF_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
-                  show_mesh_iface, store_mesh_iface);
-static HARDIF_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
+static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
+               show_mesh_iface, store_mesh_iface);
+static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
 
-static struct hardif_attribute *batman_attrs[] = {
-       &hardif_attr_mesh_iface,
-       &hardif_attr_iface_status,
+static struct bat_attribute *batman_attrs[] = {
+       &bat_attr_mesh_iface,
+       &bat_attr_iface_status,
        NULL,
 };
 
 int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
 {
        struct kobject *hardif_kobject = &dev->dev.kobj;
-       struct hardif_attribute **hardif_attr;
+       struct bat_attribute **bat_attr;
        int err;
 
        *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR,
                                                    hardif_kobject);
 
        if (!*hardif_obj) {
-               printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
-                      dev->name, SYSFS_IF_BAT_SUBDIR);
+               bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
+                       SYSFS_IF_BAT_SUBDIR);
                goto out;
        }
 
-       for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) {
-               err = sysfs_create_file(*hardif_obj, &((*hardif_attr)->attr));
+       for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) {
+               err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
                if (err) {
-                       printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
-                              dev->name, SYSFS_IF_BAT_SUBDIR,
-                              ((*hardif_attr)->attr).name);
+                       bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
+                               dev->name, SYSFS_IF_BAT_SUBDIR,
+                               ((*bat_attr)->attr).name);
                        goto rem_attr;
                }
        }
@@ -471,8 +471,8 @@ int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
        return 0;
 
 rem_attr:
-       for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr)
-               sysfs_remove_file(*hardif_obj, &((*hardif_attr)->attr));
+       for (bat_attr = batman_attrs; *bat_attr; ++bat_attr)
+               sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
 out:
        return -ENOMEM;
 }
index e1893411871ebf38b5b8ec4955137c2f7d8e27f3..7f186c007b4fc63e910479c334966cf1f901306d 100644 (file)
  */
 
 
+#ifndef _NET_BATMAN_ADV_SYSFS_H_
+#define _NET_BATMAN_ADV_SYSFS_H_
+
 #define SYSFS_IF_MESH_SUBDIR "mesh"
 #define SYSFS_IF_BAT_SUBDIR "batman_adv"
 
+struct bat_attribute {
+       struct attribute attr;
+       ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
+                       char *buf);
+       ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
+                        char *buf, size_t count);
+};
+
 int sysfs_add_meshif(struct net_device *dev);
 void sysfs_del_meshif(struct net_device *dev);
 int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev);
 void sysfs_del_hardif(struct kobject **hardif_obj);
+
+#endif /* _NET_BATMAN_ADV_SYSFS_H_ */
index 2fef6e35f8c38ef23a461d1afc7033d3f9e8b256..dd4193c99d4ec3fc81a1e9ea7cffda247dd11a6c 100644 (file)
 
 /* returns true if the corresponding bit in the given seq_bits indicates true
  * and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
-                      uint16_t curr_seqno)
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
+                      uint32_t curr_seqno)
 {
-       int16_t diff, word_offset, word_num;
+       int32_t diff, word_offset, word_num;
 
        diff = last_seqno - curr_seqno;
        if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) {
@@ -63,7 +63,7 @@ void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n)
 }
 
 /* shift the packet array by n places. */
-void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
+static void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
 {
        int32_t word_offset, word_num;
        int32_t i;
@@ -125,9 +125,12 @@ static void bit_reset_window(TYPE_OF_WORD *seq_bits)
  *  1 if the window was moved (either new or very old)
  *  0 if the window was not moved/shifted.
  */
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
                    int8_t set_mark)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
+
        /* sequence number is slightly older. We already got a sequence number
         * higher than this one, so we just mark it. */
 
@@ -152,7 +155,7 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
 
        if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE)
                || (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "We missed a lot of packets (%i) !\n",
                        seq_num_diff - 1);
                bit_reset_window(seq_bits);
@@ -169,7 +172,7 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
        if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
                || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
 
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Other host probably restarted!\n");
 
                bit_reset_window(seq_bits);
index 76ad24c9f3de6fae91b1ef256c70fbbb64aa8a04..01897d6962d03655813e978f32ee5764e9b873f9 100644 (file)
@@ -19,6 +19,8 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_BITARRAY_H_
+#define _NET_BATMAN_ADV_BITARRAY_H_
 
 /* you should choose something big, if you don't want to waste cpu */
 #define TYPE_OF_WORD unsigned long
 
 /* returns true if the corresponding bit in the given seq_bits indicates true
  * and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
-                                          uint16_t curr_seqno);
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
+                                          uint32_t curr_seqno);
 
 /* turn corresponding bit on, so we can remember that we got the packet */
 void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n);
 
-/* shift the packet array by n places. */
-void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n);
-
 
 /* receive and process one packet, returns 1 if received seq_num is considered
  * new, 0 if old  */
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
                                        int8_t set_mark);
 
 /* count the hamming weight, how many good packets did we receive? */
 int  bit_packet_count(TYPE_OF_WORD *seq_bits);
+
+#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c
deleted file mode 100644 (file)
index 32204b5..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#include <linux/device.h>
-#include <linux/slab.h>
-#include "main.h"
-#include "device.h"
-#include "send.h"
-#include "types.h"
-#include "hash.h"
-#include "hard-interface.h"
-
-static struct class *batman_class;
-
-static int Major;      /* Major number assigned to our device driver */
-
-static const struct file_operations fops = {
-       .open = bat_device_open,
-       .release = bat_device_release,
-       .read = bat_device_read,
-       .write = bat_device_write,
-       .poll = bat_device_poll,
-};
-
-static struct device_client *device_client_hash[256];
-
-void bat_device_init(void)
-{
-       memset(device_client_hash, 0, sizeof(device_client_hash));
-}
-
-int bat_device_setup(void)
-{
-       int tmp_major;
-
-       if (Major)
-               return 1;
-
-       /* register our device - kernel assigns a free major number */
-       tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
-       if (tmp_major < 0) {
-               printk(KERN_ERR "batman-adv:"
-                      "Registering the character device failed with %d\n",
-                         tmp_major);
-               return 0;
-       }
-
-       batman_class = class_create(THIS_MODULE, "batman-adv");
-
-       if (IS_ERR(batman_class)) {
-               printk(KERN_ERR "batman-adv:"
-                      "Could not register class 'batman-adv'\n");
-               return 0;
-       }
-
-       device_create(batman_class, NULL, MKDEV(tmp_major, 0), NULL,
-                     "batman-adv");
-
-       Major = tmp_major;
-       return 1;
-}
-
-void bat_device_destroy(void)
-{
-       if (!Major)
-               return;
-
-       device_destroy(batman_class, MKDEV(Major, 0));
-       class_destroy(batman_class);
-
-       /* Unregister the device */
-       unregister_chrdev(Major, DRIVER_DEVICE);
-
-       Major = 0;
-}
-
-int bat_device_open(struct inode *inode, struct file *file)
-{
-       unsigned int i;
-       struct device_client *device_client;
-
-       device_client = kmalloc(sizeof(struct device_client), GFP_KERNEL);
-
-       if (!device_client)
-               return -ENOMEM;
-
-       for (i = 0; i < ARRAY_SIZE(device_client_hash); i++) {
-               if (!device_client_hash[i]) {
-                       device_client_hash[i] = device_client;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(device_client_hash)) {
-               printk(KERN_ERR "batman-adv:"
-                      "Error - can't add another packet client: "
-                      "maximum number of clients reached\n");
-               kfree(device_client);
-               return -EXFULL;
-       }
-
-       INIT_LIST_HEAD(&device_client->queue_list);
-       device_client->queue_len = 0;
-       device_client->index = i;
-       spin_lock_init(&device_client->lock);
-       init_waitqueue_head(&device_client->queue_wait);
-
-       file->private_data = device_client;
-
-       inc_module_count();
-       return 0;
-}
-
-int bat_device_release(struct inode *inode, struct file *file)
-{
-       struct device_client *device_client =
-               (struct device_client *)file->private_data;
-       struct device_packet *device_packet;
-       struct list_head *list_pos, *list_pos_tmp;
-       unsigned long flags;
-
-       spin_lock_irqsave(&device_client->lock, flags);
-
-       /* for all packets in the queue ... */
-       list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) {
-               device_packet = list_entry(list_pos,
-                                          struct device_packet, list);
-
-               list_del(list_pos);
-               kfree(device_packet);
-       }
-
-       device_client_hash[device_client->index] = NULL;
-       spin_unlock_irqrestore(&device_client->lock, flags);
-
-       kfree(device_client);
-       dec_module_count();
-
-       return 0;
-}
-
-ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
-                       loff_t *ppos)
-{
-       struct device_client *device_client =
-               (struct device_client *)file->private_data;
-       struct device_packet *device_packet;
-       int error;
-       unsigned long flags;
-
-       if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0))
-               return -EAGAIN;
-
-       if ((!buf) || (count < sizeof(struct icmp_packet)))
-               return -EINVAL;
-
-       if (!access_ok(VERIFY_WRITE, buf, count))
-               return -EFAULT;
-
-       error = wait_event_interruptible(device_client->queue_wait,
-                                        device_client->queue_len);
-
-       if (error)
-               return error;
-
-       spin_lock_irqsave(&device_client->lock, flags);
-
-       device_packet = list_first_entry(&device_client->queue_list,
-                                        struct device_packet, list);
-       list_del(&device_packet->list);
-       device_client->queue_len--;
-
-       spin_unlock_irqrestore(&device_client->lock, flags);
-
-       error = __copy_to_user(buf, &device_packet->icmp_packet,
-                              sizeof(struct icmp_packet));
-
-       kfree(device_packet);
-
-       if (error)
-               return -EFAULT;
-
-       return sizeof(struct icmp_packet);
-}
-
-ssize_t bat_device_write(struct file *file, const char __user *buff,
-                        size_t len, loff_t *off)
-{
-       struct device_client *device_client =
-               (struct device_client *)file->private_data;
-       struct icmp_packet icmp_packet;
-       struct orig_node *orig_node;
-       struct batman_if *batman_if;
-       uint8_t dstaddr[ETH_ALEN];
-       unsigned long flags;
-
-       if (len < sizeof(struct icmp_packet)) {
-               bat_dbg(DBG_BATMAN, "batman-adv:"
-                       "Error - can't send packet from char device: "
-                       "invalid packet size\n");
-               return -EINVAL;
-       }
-
-       if (!access_ok(VERIFY_READ, buff, sizeof(struct icmp_packet)))
-               return -EFAULT;
-
-       if (__copy_from_user(&icmp_packet, buff, sizeof(icmp_packet)))
-               return -EFAULT;
-
-       if (icmp_packet.packet_type != BAT_ICMP) {
-               bat_dbg(DBG_BATMAN, "batman-adv:"
-                       "Error - can't send packet from char device: "
-                       "got bogus packet type (expected: BAT_ICMP)\n");
-               return -EINVAL;
-       }
-
-       if (icmp_packet.msg_type != ECHO_REQUEST) {
-               bat_dbg(DBG_BATMAN, "batman-adv:"
-                       "Error - can't send packet from char device: "
-                       "got bogus message type (expected: ECHO_REQUEST)\n");
-               return -EINVAL;
-       }
-
-       icmp_packet.uid = device_client->index;
-
-       if (icmp_packet.version != COMPAT_VERSION) {
-               icmp_packet.msg_type = PARAMETER_PROBLEM;
-               icmp_packet.ttl = COMPAT_VERSION;
-               bat_device_add_packet(device_client, &icmp_packet);
-               goto out;
-       }
-
-       if (atomic_read(&module_state) != MODULE_ACTIVE)
-               goto dst_unreach;
-
-       spin_lock_irqsave(&orig_hash_lock, flags);
-       orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
-
-       if (!orig_node)
-               goto unlock;
-
-       if (!orig_node->router)
-               goto unlock;
-
-       batman_if = orig_node->router->if_incoming;
-       memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
-
-       spin_unlock_irqrestore(&orig_hash_lock, flags);
-
-       if (!batman_if)
-               goto dst_unreach;
-
-       if (batman_if->if_status != IF_ACTIVE)
-               goto dst_unreach;
-
-       memcpy(icmp_packet.orig,
-              batman_if->net_dev->dev_addr,
-              ETH_ALEN);
-
-       send_raw_packet((unsigned char *)&icmp_packet,
-                       sizeof(struct icmp_packet),
-                       batman_if, dstaddr);
-
-       goto out;
-
-unlock:
-       spin_unlock_irqrestore(&orig_hash_lock, flags);
-dst_unreach:
-       icmp_packet.msg_type = DESTINATION_UNREACHABLE;
-       bat_device_add_packet(device_client, &icmp_packet);
-out:
-       return len;
-}
-
-unsigned int bat_device_poll(struct file *file, poll_table *wait)
-{
-       struct device_client *device_client =
-               (struct device_client *)file->private_data;
-
-       poll_wait(file, &device_client->queue_wait, wait);
-
-       if (device_client->queue_len > 0)
-               return POLLIN | POLLRDNORM;
-
-       return 0;
-}
-
-void bat_device_add_packet(struct device_client *device_client,
-                          struct icmp_packet *icmp_packet)
-{
-       struct device_packet *device_packet;
-       unsigned long flags;
-
-       device_packet = kmalloc(sizeof(struct device_packet), GFP_ATOMIC);
-
-       if (!device_packet)
-               return;
-
-       INIT_LIST_HEAD(&device_packet->list);
-       memcpy(&device_packet->icmp_packet, icmp_packet,
-              sizeof(struct icmp_packet));
-
-       spin_lock_irqsave(&device_client->lock, flags);
-
-       /* while waiting for the lock the device_client could have been
-        * deleted */
-       if (!device_client_hash[icmp_packet->uid]) {
-               spin_unlock_irqrestore(&device_client->lock, flags);
-               kfree(device_packet);
-               return;
-       }
-
-       list_add_tail(&device_packet->list, &device_client->queue_list);
-       device_client->queue_len++;
-
-       if (device_client->queue_len > 100) {
-               device_packet = list_first_entry(&device_client->queue_list,
-                                                struct device_packet, list);
-
-               list_del(&device_packet->list);
-               kfree(device_packet);
-               device_client->queue_len--;
-       }
-
-       spin_unlock_irqrestore(&device_client->lock, flags);
-
-       wake_up(&device_client->queue_wait);
-}
-
-void bat_device_receive_packet(struct icmp_packet *icmp_packet)
-{
-       struct device_client *hash = device_client_hash[icmp_packet->uid];
-
-       if (hash)
-               bat_device_add_packet(hash, icmp_packet);
-}
index 96c86c873011a428c832aafc39a589408f76aa6b..92c216a568856b4592e6a38427163bcec386aab3 100644 (file)
@@ -30,6 +30,7 @@
 #include "hash.h"
 
 #include <linux/if_arp.h>
+#include <linux/netfilter_bridge.h>
 
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 
@@ -108,7 +109,7 @@ static void set_primary_if(struct bat_priv *bat_priv,
        set_main_if_addr(batman_if->net_dev->dev_addr);
 
        batman_packet = (struct batman_packet *)(batman_if->packet_buff);
-       batman_packet->flags = 0;
+       batman_packet->flags = PRIMARIES_FIRST_HOP;
        batman_packet->ttl = TTL;
 
        /***
@@ -149,12 +150,10 @@ static void check_known_mac_addr(uint8_t *addr)
                if (!compare_orig(batman_if->net_dev->dev_addr, addr))
                        continue;
 
-               printk(KERN_WARNING "batman-adv:"
-                   "The newly added mac address (%pM) already exists on: %s\n",
-                   addr, batman_if->dev);
-               printk(KERN_WARNING "batman-adv:"
-                   "It is strongly recommended to keep mac addresses unique"
-                   "to avoid problems!\n");
+               pr_warning("The newly added mac address (%pM) already exists "
+                          "on: %s\n", addr, batman_if->dev);
+               pr_warning("It is strongly recommended to keep mac addresses "
+                          "unique to avoid problems!\n");
        }
        rcu_read_unlock();
 }
@@ -188,7 +187,8 @@ void update_min_mtu(void)
                soft_device->mtu = min_mtu;
 }
 
-static void hardif_activate_interface(struct bat_priv *bat_priv,
+static void hardif_activate_interface(struct net_device *net_dev,
+                                     struct bat_priv *bat_priv,
                                      struct batman_if *batman_if)
 {
        if (batman_if->if_status != IF_INACTIVE)
@@ -206,8 +206,7 @@ static void hardif_activate_interface(struct bat_priv *bat_priv,
        if (!bat_priv->primary_if)
                set_primary_if(bat_priv, batman_if);
 
-       printk(KERN_INFO "batman-adv:Interface activated: %s\n",
-              batman_if->dev);
+       bat_info(net_dev, "Interface activated: %s\n", batman_if->dev);
 
        if (atomic_read(&module_state) == MODULE_INACTIVE)
                activate_module();
@@ -216,7 +215,8 @@ static void hardif_activate_interface(struct bat_priv *bat_priv,
        return;
 }
 
-static void hardif_deactivate_interface(struct batman_if *batman_if)
+static void hardif_deactivate_interface(struct net_device *net_dev,
+                                       struct batman_if *batman_if)
 {
        if ((batman_if->if_status != IF_ACTIVE) &&
           (batman_if->if_status != IF_TO_BE_ACTIVATED))
@@ -226,8 +226,7 @@ static void hardif_deactivate_interface(struct batman_if *batman_if)
 
        batman_if->if_status = IF_INACTIVE;
 
-       printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
-              batman_if->dev);
+       bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
 
        update_min_mtu();
 }
@@ -245,9 +244,8 @@ int hardif_enable_interface(struct batman_if *batman_if)
        batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
 
        if (!batman_if->packet_buff) {
-               printk(KERN_ERR "batman-adv:"
-                      "Can't add interface packet (%s): out of memory\n",
-                      batman_if->dev);
+               bat_err(soft_device, "Can't add interface packet (%s): "
+                       "out of memory\n", batman_if->dev);
                goto err;
        }
 
@@ -265,15 +263,14 @@ int hardif_enable_interface(struct batman_if *batman_if)
        orig_hash_add_if(batman_if, bat_priv->num_ifaces);
 
        atomic_set(&batman_if->seqno, 1);
-       printk(KERN_INFO "batman-adv:Adding interface: %s\n", batman_if->dev);
+       bat_info(soft_device, "Adding interface: %s\n", batman_if->dev);
 
        if (hardif_is_iface_up(batman_if))
-               hardif_activate_interface(bat_priv, batman_if);
+               hardif_activate_interface(soft_device, bat_priv, batman_if);
        else
-               printk(KERN_ERR "batman-adv:"
-                      "Not using interface %s "
-                      "(retrying later): interface not active\n",
-                      batman_if->dev);
+               bat_err(soft_device, "Not using interface %s "
+                       "(retrying later): interface not active\n",
+                       batman_if->dev);
 
        /* begin scheduling originator messages on that interface */
        schedule_own_packet(batman_if);
@@ -291,12 +288,12 @@ void hardif_disable_interface(struct batman_if *batman_if)
        struct bat_priv *bat_priv = netdev_priv(soft_device);
 
        if (batman_if->if_status == IF_ACTIVE)
-               hardif_deactivate_interface(batman_if);
+               hardif_deactivate_interface(soft_device, batman_if);
 
        if (batman_if->if_status != IF_INACTIVE)
                return;
 
-       printk(KERN_INFO "batman-adv:Removing interface: %s\n", batman_if->dev);
+       bat_info(soft_device, "Removing interface: %s\n", batman_if->dev);
        bat_priv->num_ifaces--;
        orig_hash_del_if(batman_if, bat_priv->num_ifaces);
 
@@ -323,8 +320,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
 
        batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
        if (!batman_if) {
-               printk(KERN_ERR "batman-adv:"
-                      "Can't add interface (%s): out of memory\n",
+               pr_err("Can't add interface (%s): out of memory\n",
                       net_dev->name);
                goto out;
        }
@@ -407,11 +403,11 @@ static int hard_if_event(struct notifier_block *this,
        case NETDEV_REGISTER:
                break;
        case NETDEV_UP:
-               hardif_activate_interface(bat_priv, batman_if);
+               hardif_activate_interface(soft_device, bat_priv, batman_if);
                break;
        case NETDEV_GOING_DOWN:
        case NETDEV_DOWN:
-               hardif_deactivate_interface(batman_if);
+               hardif_deactivate_interface(soft_device, batman_if);
                break;
        case NETDEV_UNREGISTER:
                hardif_remove_interface(batman_if);
@@ -432,11 +428,18 @@ out:
        return NOTIFY_DONE;
 }
 
+static int batman_skb_recv_finish(struct sk_buff *skb)
+{
+       return NF_ACCEPT;
+}
+
 /* receive a packet with the batman ethertype coming on a hard
  * interface */
 int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
        struct packet_type *ptype, struct net_device *orig_dev)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct batman_packet *batman_packet;
        struct batman_if *batman_if;
        struct net_device_stats *stats;
@@ -452,6 +455,13 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
        if (atomic_read(&module_state) != MODULE_ACTIVE)
                goto err_free;
 
+       /* if netfilter/ebtables wants to block incoming batman
+        * packets then give them a chance to do so here */
+       ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL,
+                     batman_skb_recv_finish);
+       if (ret != 1)
+               goto err_out;
+
        /* packet should hold at least type and version */
        if (unlikely(skb_headlen(skb) < 2))
                goto err_free;
@@ -478,7 +488,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
        batman_packet = (struct batman_packet *)skb->data;
 
        if (batman_packet->version != COMPAT_VERSION) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: incompatible batman version (%i)\n",
                        batman_packet->version);
                goto err_free;
@@ -500,7 +510,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 
                /* unicast packet */
        case BAT_UNICAST:
-               ret = recv_unicast_packet(skb);
+               ret = recv_unicast_packet(skb, batman_if);
                break;
 
                /* broadcast packet */
@@ -531,7 +541,6 @@ err_out:
        return NET_RX_DROP;
 }
 
-
 struct notifier_block hard_if_notifier = {
        .notifier_call = hard_if_event,
 };
index 1e5fc3e720f4b2263a37aacfb618030aa11533b4..d5640b045cb3cded11531b00401026a076a1fb9b 100644 (file)
@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_
+#define _NET_BATMAN_ADV_HARD_INTERFACE_H_
+
 #define IF_NOT_IN_USE 0
 #define IF_TO_BE_REMOVED 1
 #define IF_INACTIVE 2
@@ -38,3 +41,5 @@ int batman_skb_recv(struct sk_buff *skb,
                                struct net_device *orig_dev);
 int hardif_min_mtu(void);
 void update_min_mtu(void);
+
+#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
index d4a4adc57042c4590cfa12a9db6ddfd9ae2a05e8..1286f8ff44f40e46a94b8db98c22c4ac23b1c9ff 100644 (file)
@@ -23,7 +23,7 @@
 #include "hash.h"
 
 /* clears the hash */
-void hash_init(struct hashtable_t *hash)
+static void hash_init(struct hashtable_t *hash)
 {
        int i;
 
index ea6d21e0125186c798e95620fdd8cb36f4dc61e9..c483e1129fc03778584d6f801fde03ccac5afc22 100644 (file)
@@ -19,8 +19,9 @@
  *
  */
 
-#ifndef _BATMAN_HASH_H
-#define _BATMAN_HASH_H
+#ifndef _NET_BATMAN_ADV_HASH_H_
+#define _NET_BATMAN_ADV_HASH_H_
+
 #define HASHIT(name) struct hash_it_t name = { \
                .index = -1, .bucket = NULL, \
                .prev_bucket = NULL, \
@@ -56,9 +57,6 @@ struct hashtable_t {
                                     * argument and the size the second */
 };
 
-/* clears the hash */
-void hash_init(struct hashtable_t *hash);
-
 /* allocates and clears the hash */
 struct hashtable_t *hash_new(int size, hashdata_compare_cb compare,
                             hashdata_choose_cb choose);
@@ -99,6 +97,4 @@ struct hashtable_t *hash_resize(struct hashtable_t *hash, int size);
 struct hash_it_t *hash_iterate(struct hashtable_t *hash,
                               struct hash_it_t *iter_in);
 
-/* print the hash table for debugging */
-void hash_debug(struct hashtable_t *hash);
-#endif
+#endif /* _NET_BATMAN_ADV_HASH_H_ */
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c
new file mode 100644 (file)
index 0000000..fc3d32c
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include "icmp_socket.h"
+#include "send.h"
+#include "types.h"
+#include "hash.h"
+#include "hard-interface.h"
+
+
+static struct socket_client *socket_client_hash[256];
+
+static void bat_socket_add_packet(struct socket_client *socket_client,
+                                 struct icmp_packet_rr *icmp_packet,
+                                 size_t icmp_len);
+
+void bat_socket_init(void)
+{
+       memset(socket_client_hash, 0, sizeof(socket_client_hash));
+}
+
+static int bat_socket_open(struct inode *inode, struct file *file)
+{
+       unsigned int i;
+       struct socket_client *socket_client;
+
+       socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL);
+
+       if (!socket_client)
+               return -ENOMEM;
+
+       for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) {
+               if (!socket_client_hash[i]) {
+                       socket_client_hash[i] = socket_client;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(socket_client_hash)) {
+               pr_err("Error - can't add another packet client: "
+                      "maximum number of clients reached\n");
+               kfree(socket_client);
+               return -EXFULL;
+       }
+
+       INIT_LIST_HEAD(&socket_client->queue_list);
+       socket_client->queue_len = 0;
+       socket_client->index = i;
+       spin_lock_init(&socket_client->lock);
+       init_waitqueue_head(&socket_client->queue_wait);
+
+       file->private_data = socket_client;
+
+       inc_module_count();
+       return 0;
+}
+
+static int bat_socket_release(struct inode *inode, struct file *file)
+{
+       struct socket_client *socket_client = file->private_data;
+       struct socket_packet *socket_packet;
+       struct list_head *list_pos, *list_pos_tmp;
+       unsigned long flags;
+
+       spin_lock_irqsave(&socket_client->lock, flags);
+
+       /* for all packets in the queue ... */
+       list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) {
+               socket_packet = list_entry(list_pos,
+                                          struct socket_packet, list);
+
+               list_del(list_pos);
+               kfree(socket_packet);
+       }
+
+       socket_client_hash[socket_client->index] = NULL;
+       spin_unlock_irqrestore(&socket_client->lock, flags);
+
+       kfree(socket_client);
+       dec_module_count();
+
+       return 0;
+}
+
+static ssize_t bat_socket_read(struct file *file, char __user *buf,
+                              size_t count, loff_t *ppos)
+{
+       struct socket_client *socket_client = file->private_data;
+       struct socket_packet *socket_packet;
+       size_t packet_len;
+       int error;
+       unsigned long flags;
+
+       if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0))
+               return -EAGAIN;
+
+       if ((!buf) || (count < sizeof(struct icmp_packet)))
+               return -EINVAL;
+
+       if (!access_ok(VERIFY_WRITE, buf, count))
+               return -EFAULT;
+
+       error = wait_event_interruptible(socket_client->queue_wait,
+                                        socket_client->queue_len);
+
+       if (error)
+               return error;
+
+       spin_lock_irqsave(&socket_client->lock, flags);
+
+       socket_packet = list_first_entry(&socket_client->queue_list,
+                                        struct socket_packet, list);
+       list_del(&socket_packet->list);
+       socket_client->queue_len--;
+
+       spin_unlock_irqrestore(&socket_client->lock, flags);
+
+       error = __copy_to_user(buf, &socket_packet->icmp_packet,
+                              socket_packet->icmp_len);
+
+       packet_len = socket_packet->icmp_len;
+       kfree(socket_packet);
+
+       if (error)
+               return -EFAULT;
+
+       return packet_len;
+}
+
+static ssize_t bat_socket_write(struct file *file, const char __user *buff,
+                               size_t len, loff_t *off)
+{
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
+       struct socket_client *socket_client = file->private_data;
+       struct icmp_packet_rr icmp_packet;
+       struct orig_node *orig_node;
+       struct batman_if *batman_if;
+       size_t packet_len = sizeof(struct icmp_packet);
+       uint8_t dstaddr[ETH_ALEN];
+       unsigned long flags;
+
+       if (len < sizeof(struct icmp_packet)) {
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "Error - can't send packet from char device: "
+                       "invalid packet size\n");
+               return -EINVAL;
+       }
+
+       if (len >= sizeof(struct icmp_packet_rr))
+               packet_len = sizeof(struct icmp_packet_rr);
+
+       if (!access_ok(VERIFY_READ, buff, packet_len))
+               return -EFAULT;
+
+       if (__copy_from_user(&icmp_packet, buff, packet_len))
+               return -EFAULT;
+
+       if (icmp_packet.packet_type != BAT_ICMP) {
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "Error - can't send packet from char device: "
+                       "got bogus packet type (expected: BAT_ICMP)\n");
+               return -EINVAL;
+       }
+
+       if (icmp_packet.msg_type != ECHO_REQUEST) {
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "Error - can't send packet from char device: "
+                       "got bogus message type (expected: ECHO_REQUEST)\n");
+               return -EINVAL;
+       }
+
+       icmp_packet.uid = socket_client->index;
+
+       if (icmp_packet.version != COMPAT_VERSION) {
+               icmp_packet.msg_type = PARAMETER_PROBLEM;
+               icmp_packet.ttl = COMPAT_VERSION;
+               bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
+               goto out;
+       }
+
+       if (atomic_read(&module_state) != MODULE_ACTIVE)
+               goto dst_unreach;
+
+       spin_lock_irqsave(&orig_hash_lock, flags);
+       orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
+
+       if (!orig_node)
+               goto unlock;
+
+       if (!orig_node->router)
+               goto unlock;
+
+       batman_if = orig_node->router->if_incoming;
+       memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+
+       spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+       if (!batman_if)
+               goto dst_unreach;
+
+       if (batman_if->if_status != IF_ACTIVE)
+               goto dst_unreach;
+
+       memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN);
+
+       if (packet_len == sizeof(struct icmp_packet_rr))
+               memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
+
+       send_raw_packet((unsigned char *)&icmp_packet,
+                       packet_len, batman_if, dstaddr);
+
+       goto out;
+
+unlock:
+       spin_unlock_irqrestore(&orig_hash_lock, flags);
+dst_unreach:
+       icmp_packet.msg_type = DESTINATION_UNREACHABLE;
+       bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
+out:
+       return len;
+}
+
+static unsigned int bat_socket_poll(struct file *file, poll_table *wait)
+{
+       struct socket_client *socket_client = file->private_data;
+
+       poll_wait(file, &socket_client->queue_wait, wait);
+
+       if (socket_client->queue_len > 0)
+               return POLLIN | POLLRDNORM;
+
+       return 0;
+}
+
+static const struct file_operations fops = {
+       .owner = THIS_MODULE,
+       .open = bat_socket_open,
+       .release = bat_socket_release,
+       .read = bat_socket_read,
+       .write = bat_socket_write,
+       .poll = bat_socket_poll,
+};
+
+int bat_socket_setup(struct bat_priv *bat_priv)
+{
+       struct dentry *d;
+
+       if (!bat_priv->debug_dir)
+               goto err;
+
+       d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
+                               bat_priv->debug_dir, NULL, &fops);
+       if (d)
+               goto err;
+
+       return 0;
+
+err:
+       return 1;
+}
+
+static void bat_socket_add_packet(struct socket_client *socket_client,
+                                 struct icmp_packet_rr *icmp_packet,
+                                 size_t icmp_len)
+{
+       struct socket_packet *socket_packet;
+       unsigned long flags;
+
+       socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC);
+
+       if (!socket_packet)
+               return;
+
+       INIT_LIST_HEAD(&socket_packet->list);
+       memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len);
+       socket_packet->icmp_len = icmp_len;
+
+       spin_lock_irqsave(&socket_client->lock, flags);
+
+       /* while waiting for the lock the socket_client could have been
+        * deleted */
+       if (!socket_client_hash[icmp_packet->uid]) {
+               spin_unlock_irqrestore(&socket_client->lock, flags);
+               kfree(socket_packet);
+               return;
+       }
+
+       list_add_tail(&socket_packet->list, &socket_client->queue_list);
+       socket_client->queue_len++;
+
+       if (socket_client->queue_len > 100) {
+               socket_packet = list_first_entry(&socket_client->queue_list,
+                                                struct socket_packet, list);
+
+               list_del(&socket_packet->list);
+               kfree(socket_packet);
+               socket_client->queue_len--;
+       }
+
+       spin_unlock_irqrestore(&socket_client->lock, flags);
+
+       wake_up(&socket_client->queue_wait);
+}
+
+void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
+                              size_t icmp_len)
+{
+       struct socket_client *hash = socket_client_hash[icmp_packet->uid];
+
+       if (hash)
+               bat_socket_add_packet(hash, icmp_packet, icmp_len);
+}
similarity index 54%
rename from drivers/staging/batman-adv/device.h
rename to drivers/staging/batman-adv/icmp_socket.h
index eb14b371cea95155c23b4cc73ce629cce052b357..bf9b348cde2786cf4469105f2c1979fbf318e293 100644 (file)
  *
  */
 
+#ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_
+#define _NET_BATMAN_ADV_ICMP_SOCKET_H_
+
 #include "types.h"
 
-void bat_device_init(void);
-int bat_device_setup(void);
-void bat_device_destroy(void);
-int bat_device_open(struct inode *inode, struct file *file);
-int bat_device_release(struct inode *inode, struct file *file);
-ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
-                       loff_t *ppos);
-ssize_t bat_device_write(struct file *file, const char __user *buff,
-                        size_t len, loff_t *off);
-unsigned int bat_device_poll(struct file *file, poll_table *wait);
-void bat_device_add_packet(struct device_client *device_client,
-                          struct icmp_packet *icmp_packet);
-void bat_device_receive_packet(struct icmp_packet *icmp_packet);
+#define ICMP_SOCKET "socket"
+
+void bat_socket_init(void);
+int bat_socket_setup(struct bat_priv *bat_priv);
+void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
+                              size_t icmp_len);
+
+#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
index 74c70d589a932d1d42ed249d3b9b04c0558d276b..2686019fe4e133f60e445cf2f2b5eddcf211cd73 100644 (file)
 
 #include "main.h"
 #include "bat_sysfs.h"
+#include "bat_debugfs.h"
 #include "routing.h"
 #include "send.h"
 #include "originator.h"
 #include "soft-interface.h"
-#include "device.h"
+#include "icmp_socket.h"
 #include "translation-table.h"
 #include "hard-interface.h"
 #include "types.h"
@@ -41,7 +42,6 @@ DEFINE_SPINLOCK(orig_hash_lock);
 DEFINE_SPINLOCK(forw_bat_list_lock);
 DEFINE_SPINLOCK(forw_bcast_list_lock);
 
-atomic_t vis_interval;
 atomic_t bcast_queue_left;
 atomic_t batman_queue_left;
 
@@ -49,7 +49,7 @@ int16_t num_hna;
 
 struct net_device *soft_device;
 
-unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 atomic_t module_state;
 
 static struct packet_type batman_adv_packet_type __read_mostly = {
@@ -59,18 +59,7 @@ static struct packet_type batman_adv_packet_type __read_mostly = {
 
 struct workqueue_struct *bat_event_workqueue;
 
-#ifdef CONFIG_BATMAN_ADV_DEBUG
-int debug;
-
-module_param(debug, int, 0644);
-
-int bat_debug_type(int type)
-{
-       return debug & type;
-}
-#endif
-
-int init_module(void)
+static int __init batman_init(void)
 {
        int retval;
 
@@ -80,8 +69,6 @@ int init_module(void)
 
        atomic_set(&module_state, MODULE_INACTIVE);
 
-       atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
-                                        * for debugging now. */
        atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN);
        atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN);
 
@@ -92,23 +79,22 @@ int init_module(void)
        if (!bat_event_workqueue)
                return -ENOMEM;
 
-       bat_device_init();
+       bat_socket_init();
+       debugfs_init();
 
        /* initialize layer 2 interface */
        soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d",
                                   interface_setup);
 
        if (!soft_device) {
-               printk(KERN_ERR "batman-adv:"
-                      "Unable to allocate the batman interface\n");
+               pr_err("Unable to allocate the batman interface\n");
                goto end;
        }
 
        retval = register_netdev(soft_device);
 
        if (retval < 0) {
-               printk(KERN_ERR "batman-adv:"
-                      "Unable to register the batman interface: %i\n", retval);
+               pr_err("Unable to register the batman interface: %i\n", retval);
                goto free_soft_device;
        }
 
@@ -117,15 +103,22 @@ int init_module(void)
        if (retval < 0)
                goto unreg_soft_device;
 
+       retval = debugfs_add_meshif(soft_device);
+
+       if (retval < 0)
+               goto unreg_sysfs;
+
        register_netdevice_notifier(&hard_if_notifier);
        dev_add_pack(&batman_adv_packet_type);
 
-       printk(KERN_INFO "batman-adv:"
-              "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n",
-              SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
+       pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) "
+               "loaded\n", SOURCE_VERSION, REVISION_VERSION_STR,
+               COMPAT_VERSION);
 
        return 0;
 
+unreg_sysfs:
+       sysfs_del_meshif(soft_device);
 unreg_soft_device:
        unregister_netdev(soft_device);
        soft_device = NULL;
@@ -138,14 +131,16 @@ end:
        return -ENOMEM;
 }
 
-void cleanup_module(void)
+static void __exit batman_exit(void)
 {
        deactivate_module();
 
+       debugfs_destroy();
        unregister_netdevice_notifier(&hard_if_notifier);
        hardif_remove_interfaces();
 
        if (soft_device) {
+               debugfs_del_meshif(soft_device);
                sysfs_del_meshif(soft_device);
                unregister_netdev(soft_device);
                soft_device = NULL;
@@ -157,7 +152,7 @@ void cleanup_module(void)
        bat_event_workqueue = NULL;
 }
 
-/* activates the module, creates bat device, starts timer ... */
+/* activates the module, starts timer ... */
 void activate_module(void)
 {
        if (originator_init() < 1)
@@ -171,9 +166,6 @@ void activate_module(void)
 
        hna_local_add(soft_device->dev_addr);
 
-       if (bat_device_setup() < 1)
-               goto end;
-
        if (vis_init() < 1)
                goto err;
 
@@ -182,8 +174,7 @@ void activate_module(void)
        goto end;
 
 err:
-       printk(KERN_ERR "batman-adv:"
-              "Unable to allocate memory for mesh information structures: "
+       pr_err("Unable to allocate memory for mesh information structures: "
               "out of mem ?\n");
        deactivate_module();
 end:
@@ -208,7 +199,6 @@ void deactivate_module(void)
        hna_global_free();
 
        synchronize_net();
-       bat_device_destroy();
 
        synchronize_rcu();
        atomic_set(&module_state, MODULE_INACTIVE);
@@ -226,8 +216,7 @@ void dec_module_count(void)
 
 int addr_to_string(char *buff, uint8_t *addr)
 {
-       return sprintf(buff, MAC_FMT,
-                      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+       return sprintf(buff, "%pM", addr);
 }
 
 /* returns 1 if they are the same originator */
@@ -284,6 +273,9 @@ int is_mcast(uint8_t *addr)
        return *addr & 0x01;
 }
 
+module_init(batman_init);
+module_exit(batman_exit);
+
 MODULE_LICENSE("GPL");
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
index 5f8343d360f67e99ae5d3f2738d0f77ab47f652f..8513261b8a7728264de229a0b152a1ad3fcbf931 100644 (file)
@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_MAIN_H_
+#define _NET_BATMAN_ADV_MAIN_H_
+
 /* Kernel Programming */
 #define LINUX
 
@@ -27,7 +30,7 @@
 #define DRIVER_DESC   "B.A.T.M.A.N. advanced"
 #define DRIVER_DEVICE "batman-adv"
 
-#define SOURCE_VERSION "0.2.2-beta"
+#define SOURCE_VERSION "maint"
 
 
 /* B.A.T.M.A.N. parameters */
 #define JITTER 20
 #define TTL 50                   /* Time To Live of broadcast messages */
 
-#define PURGE_TIMEOUT 200000     /* purge originators after time in ms if no
+#define PURGE_TIMEOUT 200      /* purge originators after time in seconds if no
                                   * valid packet comes in -> TODO: check
                                   * influence on TQ_LOCAL_WINDOW_SIZE */
-#define LOCAL_HNA_TIMEOUT 3600000
+#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
 
 #define TQ_LOCAL_WINDOW_SIZE 64          /* sliding packet range of received originator
                                   * messages in squence numbers (should be a
 #define LOG_BUF_LEN 8192         /* has to be a power of 2 */
 #define ETH_STR_LEN 20
 
+#define VIS_INTERVAL 5000      /* 5 seconds */
+
+/* how much worse secondary interfaces may be to
+ * to be considered as bonding candidates */
+
+#define BONDING_TQ_THRESHOLD   50
+
 #define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
                                   * change the size of
                                   * forw_packet->direct_link_flags */
 #define MAX_AGGREGATION_MS 100
 
 #define RESET_PROTECTION_MS 30000
-#define EXPECTED_SEQNO_RANGE   4096
+#define EXPECTED_SEQNO_RANGE   65536
 /* don't reset again within 30 seconds */
 
 #define MODULE_INACTIVE 0
 #define MODULE_ACTIVE 1
 #define MODULE_DEACTIVATING 2
 
-#define BCAST_QUEUE_LEN 256
+#define BCAST_QUEUE_LEN                256
 #define BATMAN_QUEUE_LEN       256
 
 /*
  * Debug Messages
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before
+                                            * kernel messages */
 
 #define DBG_BATMAN 1   /* all messages related to routing / flooding /
                         * broadcasting / etc */
 #define DBG_ROUTES 2   /* route or hna added / changed / deleted */
+#define DBG_ALL 3
 
-#ifdef CONFIG_BATMAN_ADV_DEBUG
-extern int debug;
+#define LOG_BUF_LEN 8192          /* has to be a power of 2 */
 
-extern int bat_debug_type(int type);
-#define bat_dbg(type, fmt, arg...) do {                                        \
-               if (bat_debug_type(type))                               \
-                       printk(KERN_DEBUG "batman-adv:" fmt, ## arg);   \
-       }                                                               \
-       while (0)
-#else /* !CONFIG_BATMAN_ADV_DEBUG */
-#define bat_dbg(type, fmt, arg...) do {                \
-       }                                       \
-       while (0)
-#endif
 
 /*
  *  Vis
@@ -117,6 +118,7 @@ extern int bat_debug_type(int type);
 #include <linux/slab.h>
 #include <net/sock.h>          /* struct sock */
 #include <linux/jiffies.h>
+#include <linux/seq_file.h>
 #include "types.h"
 
 #ifndef REVISION_VERSION
@@ -134,14 +136,13 @@ extern spinlock_t orig_hash_lock;
 extern spinlock_t forw_bat_list_lock;
 extern spinlock_t forw_bcast_list_lock;
 
-extern atomic_t vis_interval;
 extern atomic_t bcast_queue_left;
 extern atomic_t batman_queue_left;
 extern int16_t num_hna;
 
 extern struct net_device *soft_device;
 
-extern unsigned char broadcastAddr[];
+extern unsigned char broadcast_addr[];
 extern atomic_t module_state;
 extern struct workqueue_struct *bat_event_workqueue;
 
@@ -155,3 +156,44 @@ int choose_orig(void *data, int32_t size);
 int is_my_mac(uint8_t *addr);
 int is_bcast(uint8_t *addr);
 int is_mcast(uint8_t *addr);
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+extern int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
+
+#define bat_dbg(type, bat_priv, fmt, arg...)                   \
+       do {                                                    \
+               if (atomic_read(&bat_priv->log_level) & type)   \
+                       debug_log(bat_priv, fmt, ## arg);       \
+       }                                                       \
+       while (0)
+#else /* !CONFIG_BATMAN_ADV_DEBUG */
+static inline void bat_dbg(char type __attribute__((unused)),
+                          struct bat_priv *bat_priv __attribute__((unused)),
+                          char *fmt __attribute__((unused)), ...)
+{
+}
+#endif
+
+#define bat_warning(net_dev, fmt, arg...)                              \
+       do {                                                            \
+               struct net_device *_netdev = (net_dev);                 \
+               struct bat_priv *_batpriv = netdev_priv(_netdev);       \
+               bat_dbg(DBG_ALL, _batpriv, fmt, ## arg);                \
+               pr_warning("%s: " fmt, _netdev->name, ## arg);          \
+       } while (0)
+#define bat_info(net_dev, fmt, arg...)                                 \
+       do {                                                            \
+               struct net_device *_netdev = (net_dev);                 \
+               struct bat_priv *_batpriv = netdev_priv(_netdev);       \
+               bat_dbg(DBG_ALL, _batpriv, fmt, ## arg);                \
+               pr_info("%s: " fmt, _netdev->name, ## arg);             \
+       } while (0)
+#define bat_err(net_dev, fmt, arg...)                                  \
+       do {                                                            \
+               struct net_device *_netdev = (net_dev);                 \
+               struct bat_priv *_batpriv = netdev_priv(_netdev);       \
+               bat_dbg(DBG_ALL, _batpriv, fmt, ## arg);                \
+               pr_err("%s: " fmt, _netdev->name, ## arg);              \
+       } while (0)
+
+#endif /* _NET_BATMAN_ADV_MAIN_H_ */
index 568aef8371beed108798473a12e1728c0dc13993..28bb627ffa135ceb9022621d33362e8611887b46 100644 (file)
@@ -56,28 +56,16 @@ err:
        return 0;
 }
 
-void originator_free(void)
-{
-       unsigned long flags;
-
-       if (!orig_hash)
-               return;
-
-       cancel_delayed_work_sync(&purge_orig_wq);
-
-       spin_lock_irqsave(&orig_hash_lock, flags);
-       hash_delete(orig_hash, free_orig_node);
-       orig_hash = NULL;
-       spin_unlock_irqrestore(&orig_hash_lock, flags);
-}
-
 struct neigh_node *
 create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
                uint8_t *neigh, struct batman_if *if_incoming)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct neigh_node *neigh_node;
 
-       bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
+       bat_dbg(DBG_BATMAN, bat_priv,
+               "Creating new last-hop neighbor of originator\n");
 
        neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
        if (!neigh_node)
@@ -93,7 +81,7 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
        return neigh_node;
 }
 
-void free_orig_node(void *data)
+static void free_orig_node(void *data)
 {
        struct list_head *list_pos, *list_pos_tmp;
        struct neigh_node *neigh_node;
@@ -114,6 +102,21 @@ void free_orig_node(void *data)
        kfree(orig_node);
 }
 
+void originator_free(void)
+{
+       unsigned long flags;
+
+       if (!orig_hash)
+               return;
+
+       cancel_delayed_work_sync(&purge_orig_wq);
+
+       spin_lock_irqsave(&orig_hash_lock, flags);
+       hash_delete(orig_hash, free_orig_node);
+       orig_hash = NULL;
+       spin_unlock_irqrestore(&orig_hash_lock, flags);
+}
+
 /* this function finds or creates an originator entry for the given
  * address if it does not exits */
 struct orig_node *get_orig_node(uint8_t *addr)
@@ -129,7 +132,8 @@ struct orig_node *get_orig_node(uint8_t *addr)
        if (orig_node != NULL)
                return orig_node;
 
-       bat_dbg(DBG_BATMAN, "Creating new originator: %pM\n", addr);
+       bat_dbg(DBG_BATMAN, bat_priv,
+               "Creating new originator: %pM\n", addr);
 
        orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
        if (!orig_node)
@@ -163,8 +167,8 @@ struct orig_node *get_orig_node(uint8_t *addr)
                swaphash = hash_resize(orig_hash, orig_hash->size * 2);
 
                if (swaphash == NULL)
-                       printk(KERN_ERR
-                              "batman-adv:Couldn't resize orig hash table\n");
+                       bat_err(soft_device,
+                               "Couldn't resize orig hash table\n");
                else
                        orig_hash = swaphash;
        }
@@ -182,6 +186,8 @@ free_orig_node:
 static bool purge_orig_neighbors(struct orig_node *orig_node,
                                 struct neigh_node **best_neigh_node)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct list_head *list_pos, *list_pos_tmp;
        struct neigh_node *neigh_node;
        bool neigh_purged = false;
@@ -193,20 +199,19 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
                neigh_node = list_entry(list_pos, struct neigh_node, list);
 
                if ((time_after(jiffies,
-                              (neigh_node->last_valid +
-                               ((PURGE_TIMEOUT * HZ) / 1000)))) ||
+                       neigh_node->last_valid + PURGE_TIMEOUT * HZ)) ||
                    (neigh_node->if_incoming->if_status ==
                                                IF_TO_BE_REMOVED)) {
 
                        if (neigh_node->if_incoming->if_status ==
                                                        IF_TO_BE_REMOVED)
-                               bat_dbg(DBG_BATMAN,
+                               bat_dbg(DBG_BATMAN, bat_priv,
                                        "neighbor purge: originator %pM, "
                                        "neighbor: %pM, iface: %s\n",
                                        orig_node->orig, neigh_node->addr,
                                        neigh_node->if_incoming->dev);
                        else
-                               bat_dbg(DBG_BATMAN,
+                               bat_dbg(DBG_BATMAN, bat_priv,
                                        "neighbor timeout: originator %pM, "
                                        "neighbor: %pM, last_valid: %lu\n",
                                        orig_node->orig, neigh_node->addr,
@@ -226,21 +231,26 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
 
 static bool purge_orig_node(struct orig_node *orig_node)
 {
+       /* FIXME: each batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct neigh_node *best_neigh_node;
 
        if (time_after(jiffies,
-                      (orig_node->last_valid +
-                       ((2 * PURGE_TIMEOUT * HZ) / 1000)))) {
+               orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) {
 
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Originator timeout: originator %pM, last_valid %lu\n",
                        orig_node->orig, (orig_node->last_valid / HZ));
                return true;
        } else {
-               if (purge_orig_neighbors(orig_node, &best_neigh_node))
+               if (purge_orig_neighbors(orig_node, &best_neigh_node)) {
                        update_routes(orig_node, best_neigh_node,
                                      orig_node->hna_buff,
                                      orig_node->hna_buff_len);
+                       /* update bonding candidates, we could have lost
+                        * some candidates. */
+                       update_bonding_candidates(bat_priv, orig_node);
+               }
        }
 
        return false;
@@ -271,49 +281,41 @@ void purge_orig(struct work_struct *work)
                start_purge_timer();
 }
 
-ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
-                             size_t count, loff_t off)
+int orig_seq_print_text(struct seq_file *seq, void *offset)
 {
        HASHIT(hashit);
+       struct net_device *net_dev = (struct net_device *)seq->private;
        struct bat_priv *bat_priv = netdev_priv(net_dev);
        struct orig_node *orig_node;
        struct neigh_node *neigh_node;
-       size_t hdr_len, tmp_len;
-       int batman_count = 0, bytes_written = 0;
+       int batman_count = 0;
+       int last_seen_secs;
+       int last_seen_msecs;
        unsigned long flags;
        char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
 
-       if (!bat_priv->primary_if) {
-               if (off == 0)
-                       return sprintf(buff,
-                                    "BATMAN mesh %s disabled - "
+       if ((!bat_priv->primary_if) ||
+           (bat_priv->primary_if->if_status != IF_ACTIVE)) {
+               if (!bat_priv->primary_if)
+                       return seq_printf(seq, "BATMAN mesh %s disabled - "
                                     "please specify interfaces to enable it\n",
                                     net_dev->name);
 
-               return 0;
+               return seq_printf(seq, "BATMAN mesh %s "
+                                 "disabled - primary interface not active\n",
+                                 net_dev->name);
        }
 
-       if (bat_priv->primary_if->if_status != IF_ACTIVE && off == 0)
-               return sprintf(buff,
-                              "BATMAN mesh %s "
-                              "disabled - primary interface not active\n",
-                              net_dev->name);
-       else if (bat_priv->primary_if->if_status != IF_ACTIVE)
-               return 0;
-
        rcu_read_lock();
-       hdr_len = sprintf(buff,
-                  "  %-14s (%s/%i) %17s [%10s]: %20s "
-                  "... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
-                  "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
-                  "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
+       seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
+                  SOURCE_VERSION, REVISION_VERSION_STR,
                   bat_priv->primary_if->dev, bat_priv->primary_if->addr_str,
                   net_dev->name);
+       seq_printf(seq, "  %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
+                  "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
+                  "outgoingIF", "Potential nexthops");
        rcu_read_unlock();
 
-       if (off < hdr_len)
-               bytes_written = hdr_len;
-
        spin_lock_irqsave(&orig_hash_lock, flags);
 
        while (hash_iterate(orig_hash, &hashit)) {
@@ -326,44 +328,34 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
                if (orig_node->router->tq_avg == 0)
                        continue;
 
-               /* estimated line length */
-               if (count < bytes_written + 200)
-                       break;
-
                addr_to_string(orig_str, orig_node->orig);
                addr_to_string(router_str, orig_node->router->addr);
+               last_seen_secs = jiffies_to_msecs(jiffies -
+                                               orig_node->last_valid) / 1000;
+               last_seen_msecs = jiffies_to_msecs(jiffies -
+                                               orig_node->last_valid) % 1000;
 
-               tmp_len = sprintf(buff + bytes_written,
-                                 "%-17s  (%3i) %17s [%10s]:",
-                                  orig_str, orig_node->router->tq_avg,
-                                  router_str,
-                                  orig_node->router->if_incoming->dev);
+               seq_printf(seq, "%-17s %4i.%03is   (%3i) %17s [%10s]:",
+                          orig_str, last_seen_secs, last_seen_msecs,
+                          orig_node->router->tq_avg, router_str,
+                          orig_node->router->if_incoming->dev);
 
                list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
                        addr_to_string(orig_str, neigh_node->addr);
-                       tmp_len += sprintf(buff + bytes_written + tmp_len,
-                                          " %17s (%3i)", orig_str,
+                       seq_printf(seq, " %17s (%3i)", orig_str,
                                           neigh_node->tq_avg);
                }
 
-               tmp_len += sprintf(buff + bytes_written + tmp_len, "\n");
-
+               seq_printf(seq, "\n");
                batman_count++;
-               hdr_len += tmp_len;
-
-               if (off >= hdr_len)
-                       continue;
-
-               bytes_written += tmp_len;
        }
 
        spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-       if ((batman_count == 0) && (off == 0))
-               bytes_written += sprintf(buff + bytes_written,
-                                       "No batman nodes in range ...\n");
+       if ((batman_count == 0))
+               seq_printf(seq, "No batman nodes in range ...\n");
 
-       return bytes_written;
+       return 0;
 }
 
 static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
@@ -373,8 +365,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
        data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS,
                           GFP_ATOMIC);
        if (!data_ptr) {
-               printk(KERN_ERR
-                      "batman-adv:Can't resize orig: out of memory\n");
+               pr_err("Can't resize orig: out of memory\n");
                return -1;
        }
 
@@ -385,8 +376,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
 
        data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
        if (!data_ptr) {
-               printk(KERN_ERR
-                      "batman-adv:Can't resize orig: out of memory\n");
+               pr_err("Can't resize orig: out of memory\n");
                return -1;
        }
 
@@ -435,8 +425,7 @@ static int orig_node_del_if(struct orig_node *orig_node,
        chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS;
        data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
        if (!data_ptr) {
-               printk(KERN_ERR
-                      "batman-adv:Can't resize orig: out of memory\n");
+               pr_err("Can't resize orig: out of memory\n");
                return -1;
        }
 
@@ -457,8 +446,7 @@ free_bcast_own:
 
        data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
        if (!data_ptr) {
-               printk(KERN_ERR
-                      "batman-adv:Can't resize orig: out of memory\n");
+               pr_err("Can't resize orig: out of memory\n");
                return -1;
        }
 
index afbc7c0e8aa399e4ae841c1476f17b0cd5d7a922..e88411d9db71278bf3a795fbac05efeca64346cb 100644 (file)
  *
  */
 
+#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_
+#define _NET_BATMAN_ADV_ORIGINATOR_H_
+
 int originator_init(void);
-void free_orig_node(void *data);
 void originator_free(void);
 void purge_orig(struct work_struct *work);
-struct orig_node *orig_find(char *mac);
 struct orig_node *get_orig_node(uint8_t *addr);
 struct neigh_node *
 create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
                uint8_t *neigh, struct batman_if *if_incoming);
-ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
-                             size_t count, loff_t off);
+int orig_seq_print_text(struct seq_file *seq, void *offset);
 int orig_hash_add_if(struct batman_if *batman_if, int max_if_num);
 int orig_hash_del_if(struct batman_if *batman_if, int max_if_num);
+
+#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */
index 152f57b1c6c50f35454d2bd481d26b207aaa9d5f..abb5e460f23e488f4233abe205269b47b10bcb16 100644 (file)
@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_PACKET_H_
+#define _NET_BATMAN_ADV_PACKET_H_
+
 #define ETH_P_BATMAN  0x4305   /* unofficial/not registered Ethertype */
 
 #define BAT_PACKET    0x01
 #define BAT_VIS       0x05
 
 /* this file is included by batctl which needs these defines */
-#define COMPAT_VERSION 8
+#define COMPAT_VERSION 11
 #define DIRECTLINK 0x40
 #define VIS_SERVER 0x20
+#define PRIMARIES_FIRST_HOP 0x10
 
 /* ICMP message types */
 #define ECHO_REPLY 0
@@ -48,7 +52,7 @@ struct batman_packet {
        uint8_t  version;  /* batman version field */
        uint8_t  flags;    /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
        uint8_t  tq;
-       uint16_t seqno;
+       uint32_t seqno;
        uint8_t  orig[6];
        uint8_t  prev_sender[6];
        uint8_t  ttl;
@@ -68,6 +72,23 @@ struct icmp_packet {
        uint8_t  uid;
 } __attribute__((packed));
 
+#define BAT_RR_LEN 16
+
+/* icmp_packet_rr must start with all fields from imcp_packet
+   as this is assumed by code that handles ICMP packets */
+struct icmp_packet_rr {
+       uint8_t  packet_type;
+       uint8_t  version;  /* batman version field */
+       uint8_t  msg_type; /* see ICMP message types above */
+       uint8_t  ttl;
+       uint8_t  dst[6];
+       uint8_t  orig[6];
+       uint16_t seqno;
+       uint8_t  uid;
+       uint8_t  rr_cur;
+       uint8_t  rr[BAT_RR_LEN][ETH_ALEN];
+} __attribute__((packed));
+
 struct unicast_packet {
        uint8_t  packet_type;
        uint8_t  version;  /* batman version field */
@@ -79,18 +100,21 @@ struct bcast_packet {
        uint8_t  packet_type;
        uint8_t  version;  /* batman version field */
        uint8_t  orig[6];
-       uint16_t seqno;
+       uint8_t  ttl;
+       uint32_t seqno;
 } __attribute__((packed));
 
 struct vis_packet {
        uint8_t  packet_type;
        uint8_t  version;        /* batman version field */
        uint8_t  vis_type;       /* which type of vis-participant sent this? */
-       uint8_t  seqno;          /* sequence number */
        uint8_t  entries;        /* number of entries behind this struct */
+       uint32_t seqno;          /* sequence number */
        uint8_t  ttl;            /* TTL */
        uint8_t  vis_orig[6];    /* originator that informs about its
                                  * neighbors */
        uint8_t  target_orig[6]; /* who should receive this packet */
        uint8_t  sender_orig[6]; /* who sent or rebroadcasted this packet */
 } __attribute__((packed));
+
+#endif /* _NET_BATMAN_ADV_PACKET_H_ */
index b8c9456558bcb366bb7371f11fdcf9452278f43d..6b0cb9aaeba56edf3a282d34163309dff672c5dd 100644 (file)
  *
  */
 
+#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_
+#define _NET_BATMAN_ADV_RING_BUFFER_H_
+
 void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value);
 uint8_t ring_buffer_avg(uint8_t lq_recv[]);
+
+#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
index 066dc8b388177c6fea09d0fb0bd4b8ba91d9e5ab..066cc9149bf1be3c38cb1984ea39c8a3201f1a68 100644 (file)
@@ -25,7 +25,7 @@
 #include "hash.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
-#include "device.h"
+#include "icmp_socket.h"
 #include "translation-table.h"
 #include "originator.h"
 #include "types.h"
@@ -33,7 +33,7 @@
 #include "vis.h"
 #include "aggregation.h"
 
-DECLARE_WAIT_QUEUE_HEAD(thread_wait);
+static DECLARE_WAIT_QUEUE_HEAD(thread_wait);
 
 void slide_own_bcast_window(struct batman_if *batman_if)
 {
@@ -77,24 +77,27 @@ static void update_route(struct orig_node *orig_node,
                         struct neigh_node *neigh_node,
                         unsigned char *hna_buff, int hna_buff_len)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
+
        /* route deleted */
        if ((orig_node->router != NULL) && (neigh_node == NULL)) {
 
-               bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n",
+               bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
                        orig_node->orig);
                hna_global_del_orig(orig_node, "originator timed out");
 
                /* route added */
        } else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
 
-               bat_dbg(DBG_ROUTES,
+               bat_dbg(DBG_ROUTES, bat_priv,
                        "Adding route towards: %pM (via %pM)\n",
                        orig_node->orig, neigh_node->addr);
                hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
 
                /* route changed */
        } else {
-               bat_dbg(DBG_ROUTES,
+               bat_dbg(DBG_ROUTES, bat_priv,
                        "Changing route towards: %pM "
                        "(now via %pM - was via %pM)\n",
                        orig_node->orig, neigh_node->addr,
@@ -120,11 +123,13 @@ void update_routes(struct orig_node *orig_node,
                update_HNA(orig_node, hna_buff, hna_buff_len);
 }
 
-static int isBidirectionalNeigh(struct orig_node *orig_node,
+static int is_bidirectional_neigh(struct orig_node *orig_node,
                                struct orig_node *orig_neigh_node,
                                struct batman_packet *batman_packet,
                                struct batman_if *if_incoming)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
        unsigned char total_count;
 
@@ -211,7 +216,7 @@ static int isBidirectionalNeigh(struct orig_node *orig_node,
                              orig_neigh_node->tq_asym_penalty) /
                             (TQ_MAX_VALUE * TQ_MAX_VALUE));
 
-       bat_dbg(DBG_BATMAN,
+       bat_dbg(DBG_BATMAN, bat_priv,
                "bidirectional: "
                "orig = %-15pM neigh = %-15pM => own_bcast = %2i, "
                "real recv = %2i, local tq: %3i, asym_penalty: %3i, "
@@ -234,10 +239,12 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
                        unsigned char *hna_buff, int hna_buff_len,
                        char is_duplicate)
 {
+       /* FIXME: get bat_priv */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
        int tmp_hna_buff_len;
 
-       bat_dbg(DBG_BATMAN, "update_originator(): "
+       bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
                "Searching and updating originator entry of received packet\n");
 
        list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
@@ -269,7 +276,7 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
                if (!neigh_node)
                        return;
        } else
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Updating existing last-hop neighbor of originator\n");
 
        orig_node->flags = batman_packet->flags;
@@ -318,16 +325,19 @@ update_hna:
  *  0 if the packet is to be accepted
  *  1 if the packet is to be ignored.
  */
-static int window_protected(int16_t seq_num_diff,
+static int window_protected(int32_t seq_num_diff,
                                unsigned long *last_reset)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
+
        if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
                || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
                if (time_after(jiffies, *last_reset +
                        msecs_to_jiffies(RESET_PROTECTION_MS))) {
 
                        *last_reset = jiffies;
-                       bat_dbg(DBG_BATMAN,
+                       bat_dbg(DBG_BATMAN, bat_priv,
                                "old packet received, start protection\n");
 
                        return 0;
@@ -349,10 +359,12 @@ static char count_real_packets(struct ethhdr *ethhdr,
                               struct batman_packet *batman_packet,
                               struct batman_if *if_incoming)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct orig_node *orig_node;
        struct neigh_node *tmp_neigh_node;
        char is_duplicate = 0;
-       int16_t seq_diff;
+       int32_t seq_diff;
        int need_update = 0;
        int set_mark;
 
@@ -387,7 +399,8 @@ static char count_real_packets(struct ethhdr *ethhdr,
        }
 
        if (need_update) {
-               bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n",
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "updating last_seqno: old %d, new %d\n",
                        orig_node->last_real_seqno, batman_packet->seqno);
                orig_node->last_real_seqno = batman_packet->seqno;
        }
@@ -395,18 +408,127 @@ static char count_real_packets(struct ethhdr *ethhdr,
        return is_duplicate;
 }
 
+/* copy primary address for bonding */
+static void mark_bonding_address(struct bat_priv *bat_priv,
+                                struct orig_node *orig_node,
+                                struct orig_node *orig_neigh_node,
+                                struct batman_packet *batman_packet)
+
+{
+       if (batman_packet->flags & PRIMARIES_FIRST_HOP)
+               memcpy(orig_neigh_node->primary_addr,
+                      orig_node->orig, ETH_ALEN);
+
+       return;
+}
+
+/* mark possible bond.candidates in the neighbor list */
+void update_bonding_candidates(struct bat_priv *bat_priv,
+                              struct orig_node *orig_node)
+{
+       int candidates;
+       int interference_candidate;
+       int best_tq;
+       struct neigh_node *tmp_neigh_node, *tmp_neigh_node2;
+       struct neigh_node *first_candidate, *last_candidate;
+
+       /* update the candidates for this originator */
+       if (!orig_node->router) {
+               orig_node->bond.candidates = 0;
+               return;
+       }
+
+       best_tq = orig_node->router->tq_avg;
+
+       /* update bond.candidates */
+
+       candidates = 0;
+
+       /* mark other nodes which also received "PRIMARIES FIRST HOP" packets
+        * as "bonding partner" */
+
+       /* first, zero the list */
+       list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+               tmp_neigh_node->next_bond_candidate = NULL;
+       }
+
+       first_candidate = NULL;
+       last_candidate = NULL;
+       list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+
+               /* only consider if it has the same primary address ...  */
+               if (memcmp(orig_node->orig,
+                               tmp_neigh_node->orig_node->primary_addr,
+                               ETH_ALEN) != 0)
+                       continue;
+
+               /* ... and is good enough to be considered */
+               if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD)
+                       continue;
+
+               /* check if we have another candidate with the same
+                * mac address or interface. If we do, we won't
+                * select this candidate because of possible interference. */
+
+               interference_candidate = 0;
+               list_for_each_entry(tmp_neigh_node2,
+                               &orig_node->neigh_list, list) {
+
+                       if (tmp_neigh_node2 == tmp_neigh_node)
+                               continue;
+
+                       /* we only care if the other candidate is even
+                        * considered as candidate. */
+                       if (tmp_neigh_node2->next_bond_candidate == NULL)
+                               continue;
+
+
+                       if ((tmp_neigh_node->if_incoming ==
+                               tmp_neigh_node2->if_incoming)
+                               || (memcmp(tmp_neigh_node->addr,
+                               tmp_neigh_node2->addr, ETH_ALEN) == 0)) {
+
+                               interference_candidate = 1;
+                               break;
+                       }
+               }
+               /* don't care further if it is an interference candidate */
+               if (interference_candidate)
+                       continue;
+
+               if (first_candidate == NULL) {
+                       first_candidate = tmp_neigh_node;
+                       tmp_neigh_node->next_bond_candidate = first_candidate;
+               } else
+                       tmp_neigh_node->next_bond_candidate = last_candidate;
+
+               last_candidate = tmp_neigh_node;
+
+               candidates++;
+       }
+
+       if (candidates > 0) {
+               first_candidate->next_bond_candidate = last_candidate;
+               orig_node->bond.selected = first_candidate;
+       }
+
+       orig_node->bond.candidates = candidates;
+}
+
 void receive_bat_packet(struct ethhdr *ethhdr,
                                struct batman_packet *batman_packet,
                                unsigned char *hna_buff, int hna_buff_len,
                                struct batman_if *if_incoming)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct batman_if *batman_if;
        struct orig_node *orig_neigh_node, *orig_node;
        char has_directlink_flag;
        char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
        char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
        char is_duplicate;
-       unsigned short if_incoming_seqno;
+       uint32_t if_incoming_seqno;
 
        /* Silently drop when the batman packet is actually not a
         * correct packet.
@@ -431,7 +553,8 @@ void receive_bat_packet(struct ethhdr *ethhdr,
        is_single_hop_neigh = (compare_orig(ethhdr->h_source,
                                            batman_packet->orig) ? 1 : 0);
 
-       bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] "
+       bat_dbg(DBG_BATMAN, bat_priv,
+               "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",
                ethhdr->h_source, if_incoming->dev, if_incoming->addr_str,
@@ -455,19 +578,19 @@ void receive_bat_packet(struct ethhdr *ethhdr,
                                 batman_if->net_dev->dev_addr))
                        is_my_oldorig = 1;
 
-               if (compare_orig(ethhdr->h_source, broadcastAddr))
+               if (compare_orig(ethhdr->h_source, broadcast_addr))
                        is_broadcast = 1;
        }
 
        if (batman_packet->version != COMPAT_VERSION) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: incompatible batman version (%i)\n",
                        batman_packet->version);
                return;
        }
 
        if (is_my_addr) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: received my own broadcast (sender: %pM"
                        ")\n",
                        ethhdr->h_source);
@@ -475,7 +598,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
        }
 
        if (is_broadcast) {
-               bat_dbg(DBG_BATMAN, "Drop packet: "
+               bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
                "ignoring all packets with broadcast source addr (sender: %pM"
                ")\n", ethhdr->h_source);
                return;
@@ -505,13 +628,13 @@ void receive_bat_packet(struct ethhdr *ethhdr,
                                bit_packet_count(word);
                }
 
-               bat_dbg(DBG_BATMAN, "Drop packet: "
+               bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
                        "originator packet from myself (via neighbor)\n");
                return;
        }
 
        if (is_my_oldorig) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: ignoring all rebroadcast echos (sender: "
                        "%pM)\n", ethhdr->h_source);
                return;
@@ -524,14 +647,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
        is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
 
        if (is_duplicate == -1) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: packet within seqno protection time "
                        "(sender: %pM)\n", ethhdr->h_source);
                return;
        }
 
        if (batman_packet->tq == 0) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: originator packet with tq equal 0\n");
                return;
        }
@@ -544,7 +667,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
            !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
            (compare_orig(orig_node->router->addr,
                          orig_node->router->orig_node->router->addr))) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: ignoring all rebroadcast packets that "
                        "may make me loop (sender: %pM)\n", ethhdr->h_source);
                return;
@@ -561,11 +684,12 @@ void receive_bat_packet(struct ethhdr *ethhdr,
         * don't route towards it */
        if (!is_single_hop_neigh &&
            (orig_neigh_node->router == NULL)) {
-               bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n");
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "Drop packet: OGM via unknown neighbor!\n");
                return;
        }
 
-       is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node,
+       is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node,
                                                batman_packet, if_incoming);
 
        /* update ranking if it is not a duplicate or has the same
@@ -577,6 +701,10 @@ void receive_bat_packet(struct ethhdr *ethhdr,
                update_orig(orig_node, ethhdr, batman_packet,
                            if_incoming, hna_buff, hna_buff_len, is_duplicate);
 
+       mark_bonding_address(bat_priv, orig_node,
+                            orig_neigh_node, batman_packet);
+       update_bonding_candidates(bat_priv, orig_node);
+
        /* is single hop (direct) neighbor */
        if (is_single_hop_neigh) {
 
@@ -584,24 +712,25 @@ void receive_bat_packet(struct ethhdr *ethhdr,
                schedule_forward_packet(orig_node, ethhdr, batman_packet,
                                        1, hna_buff_len, if_incoming);
 
-               bat_dbg(DBG_BATMAN, "Forwarding packet: "
+               bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
                        "rebroadcast neighbor packet with direct link flag\n");
                return;
        }
 
        /* multihop originator */
        if (!is_bidirectional) {
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "Drop packet: not received via bidirectional link\n");
                return;
        }
 
        if (is_duplicate) {
-               bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n");
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "Drop packet: duplicate packet received\n");
                return;
        }
 
-       bat_dbg(DBG_BATMAN,
+       bat_dbg(DBG_BATMAN, bat_priv,
                "Forwarding packet: rebroadcast originator packet\n");
        schedule_forward_packet(orig_node, ethhdr, batman_packet,
                                0, hna_buff_len, if_incoming);
@@ -652,10 +781,10 @@ int recv_bat_packet(struct sk_buff *skb,
        return NET_RX_SUCCESS;
 }
 
-static int recv_my_icmp_packet(struct sk_buff *skb)
+static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
 {
        struct orig_node *orig_node;
-       struct icmp_packet *icmp_packet;
+       struct icmp_packet_rr *icmp_packet;
        struct ethhdr *ethhdr;
        struct sk_buff *skb_old;
        struct batman_if *batman_if;
@@ -663,12 +792,12 @@ static int recv_my_icmp_packet(struct sk_buff *skb)
        unsigned long flags;
        uint8_t dstaddr[ETH_ALEN];
 
-       icmp_packet = (struct icmp_packet *)skb->data;
+       icmp_packet = (struct icmp_packet_rr *)skb->data;
        ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
        /* add data to device queue */
        if (icmp_packet->msg_type != ECHO_REQUEST) {
-               bat_device_receive_packet(icmp_packet);
+               bat_socket_receive_packet(icmp_packet, icmp_len);
                return NET_RX_DROP;
        }
 
@@ -690,13 +819,12 @@ static int recv_my_icmp_packet(struct sk_buff *skb)
 
                /* create a copy of the skb, if needed, to modify it. */
                skb_old = NULL;
-               if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+               if (!skb_clone_writable(skb, icmp_len)) {
                        skb_old = skb;
                        skb = skb_copy(skb, GFP_ATOMIC);
                        if (!skb)
                                return NET_RX_DROP;
-
-                       icmp_packet = (struct icmp_packet *)skb->data;
+                       icmp_packet = (struct icmp_packet_rr *)skb->data;
                        ethhdr = (struct ethhdr *)skb_mac_header(skb);
                        kfree_skb(skb_old);
                }
@@ -715,7 +843,7 @@ static int recv_my_icmp_packet(struct sk_buff *skb)
        return ret;
 }
 
-static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
+static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
 {
        struct orig_node *orig_node;
        struct icmp_packet *icmp_packet;
@@ -731,10 +859,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
 
        /* send TTL exceeded if packet is an echo request (traceroute) */
        if (icmp_packet->msg_type != ECHO_REQUEST) {
-               printk(KERN_WARNING "batman-adv:"
-                      "Warning - can't forward icmp packet from %pM to %pM: "
-                      "ttl exceeded\n",
-                      icmp_packet->orig, icmp_packet->dst);
+               pr_warning("Warning - can't forward icmp packet from %pM to "
+                          "%pM: ttl exceeded\n", icmp_packet->orig,
+                          icmp_packet->dst);
                return NET_RX_DROP;
        }
 
@@ -754,7 +881,7 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
                spin_unlock_irqrestore(&orig_hash_lock, flags);
 
                /* create a copy of the skb, if needed, to modify it. */
-               if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+               if (!skb_clone_writable(skb, icmp_len)) {
                        skb_old = skb;
                        skb = skb_copy(skb, GFP_ATOMIC);
                        if (!skb)
@@ -781,7 +908,7 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
 
 int recv_icmp_packet(struct sk_buff *skb)
 {
-       struct icmp_packet *icmp_packet;
+       struct icmp_packet_rr *icmp_packet;
        struct ethhdr *ethhdr;
        struct orig_node *orig_node;
        struct sk_buff *skb_old;
@@ -791,6 +918,12 @@ int recv_icmp_packet(struct sk_buff *skb)
        unsigned long flags;
        uint8_t dstaddr[ETH_ALEN];
 
+       /**
+        * we truncate all incoming icmp packets if they don't match our size
+        */
+       if (skb_headlen(skb) >= sizeof(struct icmp_packet_rr))
+               hdr_size = sizeof(struct icmp_packet_rr);
+
        /* drop packet if it has not necessary minimum size */
        if (skb_headlen(skb) < hdr_size)
                return NET_RX_DROP;
@@ -809,15 +942,23 @@ int recv_icmp_packet(struct sk_buff *skb)
        if (!is_my_mac(ethhdr->h_dest))
                return NET_RX_DROP;
 
-       icmp_packet = (struct icmp_packet *)skb->data;
+       icmp_packet = (struct icmp_packet_rr *)skb->data;
+
+       /* add record route information if not full */
+       if ((hdr_size == sizeof(struct icmp_packet_rr)) &&
+           (icmp_packet->rr_cur < BAT_RR_LEN)) {
+               memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
+                       ethhdr->h_dest, ETH_ALEN);
+               icmp_packet->rr_cur++;
+       }
 
        /* packet for me */
        if (is_my_mac(icmp_packet->dst))
-               return recv_my_icmp_packet(skb);
+               return recv_my_icmp_packet(skb, hdr_size);
 
        /* TTL exceeded */
        if (icmp_packet->ttl < 2)
-               return recv_icmp_ttl_exceeded(skb);
+               return recv_icmp_ttl_exceeded(skb, hdr_size);
 
        ret = NET_RX_DROP;
 
@@ -836,12 +977,12 @@ int recv_icmp_packet(struct sk_buff *skb)
                spin_unlock_irqrestore(&orig_hash_lock, flags);
 
                /* create a copy of the skb, if needed, to modify it. */
-               if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+               if (!skb_clone_writable(skb, hdr_size)) {
                        skb_old = skb;
                        skb = skb_copy(skb, GFP_ATOMIC);
                        if (!skb)
                                return NET_RX_DROP;
-                       icmp_packet = (struct icmp_packet *)skb->data;
+                       icmp_packet = (struct icmp_packet_rr *)skb->data;
                        ethhdr = (struct ethhdr *)skb_mac_header(skb);
                        kfree_skb(skb_old);
                }
@@ -859,16 +1000,109 @@ int recv_icmp_packet(struct sk_buff *skb)
        return ret;
 }
 
-int recv_unicast_packet(struct sk_buff *skb)
+/* find a suitable router for this originator, and use
+ * bonding if possible. */
+struct neigh_node *find_router(struct orig_node *orig_node,
+               struct batman_if *recv_if)
+{
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
+       struct orig_node *primary_orig_node;
+       struct orig_node *router_orig;
+       struct neigh_node *router, *first_candidate, *best_router;
+       static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
+       int bonding_enabled;
+
+       if (!orig_node)
+               return NULL;
+
+       if (!orig_node->router)
+               return NULL;
+
+       /* without bonding, the first node should
+        * always choose the default router. */
+
+       bonding_enabled = atomic_read(&bat_priv->bonding_enabled);
+       if (!bonding_enabled && (recv_if == NULL))
+                       return orig_node->router;
+
+       router_orig = orig_node->router->orig_node;
+
+       /* if we have something in the primary_addr, we can search
+        * for a potential bonding candidate. */
+       if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0)
+               return orig_node->router;
+
+       /* find the orig_node which has the primary interface. might
+        * even be the same as our router_orig in many cases */
+
+       if (memcmp(router_orig->primary_addr,
+                               router_orig->orig, ETH_ALEN) == 0) {
+               primary_orig_node = router_orig;
+       } else {
+               primary_orig_node = hash_find(orig_hash,
+                                               router_orig->primary_addr);
+               if (!primary_orig_node)
+                       return orig_node->router;
+       }
+
+       /* with less than 2 candidates, we can't do any
+        * bonding and prefer the original router. */
+
+       if (primary_orig_node->bond.candidates < 2)
+               return orig_node->router;
+
+
+       /* all nodes between should choose a candidate which
+        * is is not on the interface where the packet came
+        * in. */
+       first_candidate = primary_orig_node->bond.selected;
+       router = first_candidate;
+
+       if (bonding_enabled) {
+               /* in the bonding case, send the packets in a round
+                * robin fashion over the remaining interfaces. */
+               do {
+                       /* recv_if == NULL on the first node. */
+                       if (router->if_incoming != recv_if)
+                               break;
+
+                       router = router->next_bond_candidate;
+               } while (router != first_candidate);
+
+               primary_orig_node->bond.selected = router->next_bond_candidate;
+
+       } else {
+               /* if bonding is disabled, use the best of the
+                * remaining candidates which are not using
+                * this interface. */
+               best_router = first_candidate;
+
+               do {
+                       /* recv_if == NULL on the first node. */
+                       if ((router->if_incoming != recv_if) &&
+                               (router->tq_avg > best_router->tq_avg))
+                                       best_router = router;
+
+                       router = router->next_bond_candidate;
+               } while (router != first_candidate);
+
+               router = best_router;
+       }
+
+       return router;
+}
+
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
 {
        struct unicast_packet *unicast_packet;
        struct orig_node *orig_node;
+       struct neigh_node *router;
        struct ethhdr *ethhdr;
        struct batman_if *batman_if;
        struct sk_buff *skb_old;
        uint8_t dstaddr[ETH_ALEN];
        int hdr_size = sizeof(struct unicast_packet);
-       int ret;
        unsigned long flags;
 
        /* drop packet if it has not necessary minimum size */
@@ -899,49 +1133,50 @@ int recv_unicast_packet(struct sk_buff *skb)
 
        /* TTL exceeded */
        if (unicast_packet->ttl < 2) {
-               printk(KERN_WARNING "batman-adv:Warning - "
-                      "can't forward unicast packet from %pM to %pM: "
-                      "ttl exceeded\n",
-                      ethhdr->h_source, unicast_packet->dest);
+               pr_warning("Warning - can't forward unicast packet from %pM to "
+                          "%pM: ttl exceeded\n", ethhdr->h_source,
+                          unicast_packet->dest);
                return NET_RX_DROP;
        }
 
-       ret = NET_RX_DROP;
        /* get routing information */
        spin_lock_irqsave(&orig_hash_lock, flags);
        orig_node = ((struct orig_node *)
                     hash_find(orig_hash, unicast_packet->dest));
 
-       if ((orig_node != NULL) &&
-           (orig_node->router != NULL)) {
+       router = find_router(orig_node, recv_if);
 
-               /* don't lock while sending the packets ... we therefore
-                * copy the required data before sending */
-               batman_if = orig_node->router->if_incoming;
-               memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+       if (!router) {
                spin_unlock_irqrestore(&orig_hash_lock, flags);
+               return NET_RX_DROP;
+       }
 
-               /* create a copy of the skb, if needed, to modify it. */
-               if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
-                       skb_old = skb;
-                       skb = skb_copy(skb, GFP_ATOMIC);
-                       if (!skb)
-                               return NET_RX_DROP;
-                       unicast_packet = (struct unicast_packet *)skb->data;
-                       ethhdr = (struct ethhdr *)skb_mac_header(skb);
-                       kfree_skb(skb_old);
-               }
-               /* decrement ttl */
-               unicast_packet->ttl--;
+       /* don't lock while sending the packets ... we therefore
+        * copy the required data before sending */
 
-               /* route it */
-               send_skb_packet(skb, batman_if, dstaddr);
-               ret = NET_RX_SUCCESS;
+       batman_if = router->if_incoming;
+       memcpy(dstaddr, router->addr, ETH_ALEN);
 
-       } else
-               spin_unlock_irqrestore(&orig_hash_lock, flags);
+       spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-       return ret;
+       /* create a copy of the skb, if needed, to modify it. */
+       if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
+               skb_old = skb;
+               skb = skb_copy(skb, GFP_ATOMIC);
+               if (!skb)
+                       return NET_RX_DROP;
+               unicast_packet = (struct unicast_packet *) skb->data;
+               ethhdr = (struct ethhdr *)skb_mac_header(skb);
+               kfree_skb(skb_old);
+       }
+
+       /* decrement ttl */
+       unicast_packet->ttl--;
+
+       /* route it */
+       send_skb_packet(skb, batman_if, dstaddr);
+
+       return NET_RX_SUCCESS;
 }
 
 int recv_bcast_packet(struct sk_buff *skb)
@@ -950,7 +1185,7 @@ int recv_bcast_packet(struct sk_buff *skb)
        struct bcast_packet *bcast_packet;
        struct ethhdr *ethhdr;
        int hdr_size = sizeof(struct bcast_packet);
-       int16_t seq_diff;
+       int32_t seq_diff;
        unsigned long flags;
 
        /* drop packet if it has not necessary minimum size */
@@ -977,6 +1212,9 @@ int recv_bcast_packet(struct sk_buff *skb)
        if (is_my_mac(bcast_packet->orig))
                return NET_RX_DROP;
 
+       if (bcast_packet->ttl < 2)
+               return NET_RX_DROP;
+
        spin_lock_irqsave(&orig_hash_lock, flags);
        orig_node = ((struct orig_node *)
                     hash_find(orig_hash, bcast_packet->orig));
@@ -989,12 +1227,12 @@ int recv_bcast_packet(struct sk_buff *skb)
        /* check whether the packet is a duplicate */
        if (get_bit_status(orig_node->bcast_bits,
                           orig_node->last_bcast_seqno,
-                          ntohs(bcast_packet->seqno))) {
+                          ntohl(bcast_packet->seqno))) {
                spin_unlock_irqrestore(&orig_hash_lock, flags);
                return NET_RX_DROP;
        }
 
-       seq_diff = ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno;
+       seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
 
        /* check whether the packet is old and the host just restarted. */
        if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) {
@@ -1005,7 +1243,7 @@ int recv_bcast_packet(struct sk_buff *skb)
        /* mark broadcast in flood history, update window position
         * if required. */
        if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1))
-               orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
+               orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
 
        spin_unlock_irqrestore(&orig_hash_lock, flags);
        /* rebroadcast packet */
index 8288decea370f06547e9c8ff9415c26c51ba1478..3eac64e3cf9b258ce916cecd8f5a5578fc8c2d9f 100644 (file)
  *
  */
 
-#include "types.h"
+#ifndef _NET_BATMAN_ADV_ROUTING_H_
+#define _NET_BATMAN_ADV_ROUTING_H_
 
-extern wait_queue_head_t thread_wait;
+#include "types.h"
 
 void slide_own_bcast_window(struct batman_if *batman_if);
 void receive_bat_packet(struct ethhdr *ethhdr,
@@ -32,8 +33,14 @@ void update_routes(struct orig_node *orig_node,
                                struct neigh_node *neigh_node,
                                unsigned char *hna_buff, int hna_buff_len);
 int recv_icmp_packet(struct sk_buff *skb);
-int recv_unicast_packet(struct sk_buff *skb);
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if);
 int recv_bcast_packet(struct sk_buff *skb);
 int recv_vis_packet(struct sk_buff *skb);
 int recv_bat_packet(struct sk_buff *skb,
                                struct batman_if *batman_if);
+struct neigh_node *find_router(struct orig_node *orig_node,
+               struct batman_if *recv_if);
+void update_bonding_candidates(struct bat_priv *bat_priv,
+                              struct orig_node *orig_node);
+
+#endif /* _NET_BATMAN_ADV_ROUTING_H_ */
index ac69ed871a7614c36b8bfc1d2bda10cb1792b14b..055edee7b4e401be0f9142d222fab9a52631c150 100644 (file)
 #include "vis.h"
 #include "aggregation.h"
 
+#include <linux/netfilter_bridge.h>
+
+static void send_outstanding_bcast_packet(struct work_struct *work);
+
 /* apply hop penalty for a normal link */
 static uint8_t hop_penalty(const uint8_t tq)
 {
@@ -38,15 +42,15 @@ static uint8_t hop_penalty(const uint8_t tq)
 /* when do we schedule our own packet to be sent */
 static unsigned long own_send_time(struct bat_priv *bat_priv)
 {
-       return jiffies +
-               (((atomic_read(&bat_priv->orig_interval) - JITTER +
-                  (random32() % 2*JITTER)) * HZ) / 1000);
+       return jiffies + msecs_to_jiffies(
+                  atomic_read(&bat_priv->orig_interval) -
+                  JITTER + (random32() % 2*JITTER));
 }
 
 /* when do we schedule a forwarded packet to be sent */
 static unsigned long forward_send_time(struct bat_priv *bat_priv)
 {
-       return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000);
+       return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
 }
 
 /* send out an already prepared packet to the given address via the
@@ -64,10 +68,8 @@ int send_skb_packet(struct sk_buff *skb,
                goto send_skb_err;
 
        if (!(batman_if->net_dev->flags & IFF_UP)) {
-               printk(KERN_WARNING
-                      "batman-adv:Interface %s "
-                      "is not up - can't send packet via that interface!\n",
-                      batman_if->dev);
+               pr_warning("Interface %s is not up - can't send packet via "
+                          "that interface!\n", batman_if->dev);
                goto send_skb_err;
        }
 
@@ -90,9 +92,12 @@ int send_skb_packet(struct sk_buff *skb,
 
        /* dev_queue_xmit() returns a negative result on error.  However on
         * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
-        * (which is > 0). This will not be treated as an error. */
+        * (which is > 0). This will not be treated as an error.
+        * Also, if netfilter/ebtables wants to block outgoing batman
+        * packets then giving them a chance to do so here */
 
-       return dev_queue_xmit(skb);
+       return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+                      dev_queue_xmit);
 send_skb_err:
        kfree_skb(skb);
        return NET_XMIT_DROP;
@@ -119,6 +124,8 @@ void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
 static void send_packet_to_if(struct forw_packet *forw_packet,
                              struct batman_if *batman_if)
 {
+       /* FIXME: each batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        char *fwd_str;
        uint8_t packet_num;
        int16_t buff_pos;
@@ -148,11 +155,11 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
                fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
                                                            "Sending own" :
                                                            "Forwarding"));
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
                        " IDF %s) on interface %s [%s]\n",
                        fwd_str, (packet_num > 0 ? "aggregated " : ""),
-                       batman_packet->orig, ntohs(batman_packet->seqno),
+                       batman_packet->orig, ntohl(batman_packet->seqno),
                        batman_packet->tq, batman_packet->ttl,
                        (batman_packet->flags & DIRECTLINK ?
                         "on" : "off"),
@@ -167,20 +174,22 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
 
        send_raw_packet(forw_packet->packet_buff,
                        forw_packet->packet_len,
-                       batman_if, broadcastAddr);
+                       batman_if, broadcast_addr);
 }
 
 /* send a batman packet */
 static void send_packet(struct forw_packet *forw_packet)
 {
+       /* FIXME: each batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct batman_if *batman_if;
        struct batman_packet *batman_packet =
                (struct batman_packet *)(forw_packet->packet_buff);
        unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
 
        if (!forw_packet->if_incoming) {
-               printk(KERN_ERR "batman-adv: Error - can't forward packet: "
-                      "incoming iface not specified\n");
+               pr_err("Error - can't forward packet: incoming iface not "
+                      "specified\n");
                return;
        }
 
@@ -193,18 +202,18 @@ static void send_packet(struct forw_packet *forw_packet)
            (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
 
                /* FIXME: what about aggregated packets ? */
-               bat_dbg(DBG_BATMAN,
+               bat_dbg(DBG_BATMAN, bat_priv,
                        "%s packet (originator %pM, seqno %d, TTL %d) "
                        "on interface %s [%s]\n",
                        (forw_packet->own ? "Sending own" : "Forwarding"),
-                       batman_packet->orig, ntohs(batman_packet->seqno),
+                       batman_packet->orig, ntohl(batman_packet->seqno),
                        batman_packet->ttl, forw_packet->if_incoming->dev,
                        forw_packet->if_incoming->addr_str);
 
                send_raw_packet(forw_packet->packet_buff,
                                forw_packet->packet_len,
                                forw_packet->if_incoming,
-                               broadcastAddr);
+                               broadcast_addr);
                return;
        }
 
@@ -276,14 +285,14 @@ void schedule_own_packet(struct batman_if *batman_if)
        batman_packet = (struct batman_packet *)batman_if->packet_buff;
 
        /* change sequence number to network order */
-       batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
+       batman_packet->seqno =
+               htonl((uint32_t)atomic_read(&batman_if->seqno));
 
        if (vis_server == VIS_TYPE_SERVER_SYNC)
-               batman_packet->flags = VIS_SERVER;
+               batman_packet->flags |= VIS_SERVER;
        else
                batman_packet->flags &= ~VIS_SERVER;
 
-       /* could be read by receive_bat_packet() */
        atomic_inc(&batman_if->seqno);
 
        slide_own_bcast_window(batman_if);
@@ -306,7 +315,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
        unsigned long send_time;
 
        if (batman_packet->ttl <= 1) {
-               bat_dbg(DBG_BATMAN, "ttl exceeded\n");
+               bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
                return;
        }
 
@@ -335,13 +344,16 @@ void schedule_forward_packet(struct orig_node *orig_node,
        /* apply hop penalty */
        batman_packet->tq = hop_penalty(batman_packet->tq);
 
-       bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, "
+       bat_dbg(DBG_BATMAN, bat_priv,
+               "Forwarding packet: tq_orig: %i, tq_avg: %i, "
                "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
                in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
                batman_packet->ttl);
 
-       batman_packet->seqno = htons(batman_packet->seqno);
+       batman_packet->seqno = htonl(batman_packet->seqno);
 
+       /* switch of primaries first hop flag when forwarding */
+       batman_packet->flags &= ~PRIMARIES_FIRST_HOP;
        if (directlink)
                batman_packet->flags |= DIRECTLINK;
        else
@@ -392,9 +404,12 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
 int add_bcast_packet_to_list(struct sk_buff *skb)
 {
        struct forw_packet *forw_packet;
+       struct bcast_packet *bcast_packet;
+       /* FIXME: each batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
 
        if (!atomic_dec_not_zero(&bcast_queue_left)) {
-               bat_dbg(DBG_BATMAN, "bcast packet queue full\n");
+               bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
                goto out;
        }
 
@@ -407,6 +422,10 @@ int add_bcast_packet_to_list(struct sk_buff *skb)
        if (!skb)
                goto packet_free;
 
+       /* as we have a copy now, it is safe to decrease the TTL */
+       bcast_packet = (struct bcast_packet *)skb->data;
+       bcast_packet->ttl--;
+
        skb_reset_mac_header(skb);
 
        forw_packet->skb = skb;
@@ -426,7 +445,7 @@ out:
        return NETDEV_TX_BUSY;
 }
 
-void send_outstanding_bcast_packet(struct work_struct *work)
+static void send_outstanding_bcast_packet(struct work_struct *work)
 {
        struct batman_if *batman_if;
        struct delayed_work *delayed_work =
@@ -450,7 +469,7 @@ void send_outstanding_bcast_packet(struct work_struct *work)
                skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
                if (skb1)
                        send_skb_packet(skb1,
-                               batman_if, broadcastAddr);
+                               batman_if, broadcast_addr);
        }
        rcu_read_unlock();
 
@@ -502,15 +521,19 @@ out:
 
 void purge_outstanding_packets(struct batman_if *batman_if)
 {
+       /* FIXME: each batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct forw_packet *forw_packet;
        struct hlist_node *tmp_node, *safe_tmp_node;
        unsigned long flags;
 
        if (batman_if)
-               bat_dbg(DBG_BATMAN, "purge_outstanding_packets(): %s\n",
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "purge_outstanding_packets(): %s\n",
                        batman_if->dev);
        else
-               bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
+               bat_dbg(DBG_BATMAN, bat_priv,
+                       "purge_outstanding_packets()\n");
 
        /* free bcast list */
        spin_lock_irqsave(&forw_bcast_list_lock, flags);
index feaa2fc7f9a18e3f0bc6fc8551b4e297d670c36b..b64c62783fecd13ddbe60ccd968dc2c6b650801a 100644 (file)
  *
  */
 
+#ifndef _NET_BATMAN_ADV_SEND_H_
+#define _NET_BATMAN_ADV_SEND_H_
+
 #include "types.h"
 
-void send_own_packet_work(struct work_struct *work);
 int send_skb_packet(struct sk_buff *skb,
                                struct batman_if *batman_if,
                                uint8_t *dst_addr);
@@ -34,6 +36,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
                             uint8_t directlink, int hna_buff_len,
                             struct batman_if *if_outgoing);
 int  add_bcast_packet_to_list(struct sk_buff *skb);
-void send_outstanding_bcast_packet(struct work_struct *work);
 void send_outstanding_bat_packet(struct work_struct *work);
 void purge_outstanding_packets(struct batman_if *batman_if);
+
+#endif /* _NET_BATMAN_ADV_SEND_H_ */
index 51c40b77c8d73d2246b3e15882a1c7429b50e889..2ea97de435ceab80b9c4838d66474bc064dbcb54 100644 (file)
@@ -22,6 +22,7 @@
 #include "main.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
+#include "routing.h"
 #include "send.h"
 #include "translation-table.h"
 #include "types.h"
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 
-static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
+static uint32_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
                                  * broadcast storms */
 static int32_t skb_packets;
 static int32_t skb_bad_packets;
 
-unsigned char mainIfAddr[ETH_ALEN];
-static unsigned char mainIfAddr_default[ETH_ALEN];
+unsigned char main_if_addr[ETH_ALEN];
 static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
 static void bat_get_drvinfo(struct net_device *dev,
                            struct ethtool_drvinfo *info);
@@ -58,12 +58,7 @@ static const struct ethtool_ops bat_ethtool_ops = {
 
 void set_main_if_addr(uint8_t *addr)
 {
-       memcpy(mainIfAddr, addr, ETH_ALEN);
-}
-
-int main_if_was_up(void)
-{
-       return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
+       memcpy(main_if_addr, addr, ETH_ALEN);
 }
 
 int my_skb_push(struct sk_buff *skb, unsigned int len)
@@ -83,69 +78,25 @@ int my_skb_push(struct sk_buff *skb, unsigned int len)
        return 0;
 }
 
-#ifdef HAVE_NET_DEVICE_OPS
-static const struct net_device_ops bat_netdev_ops = {
-       .ndo_open = interface_open,
-       .ndo_stop = interface_release,
-       .ndo_get_stats = interface_stats,
-       .ndo_set_mac_address = interface_set_mac_addr,
-       .ndo_change_mtu = interface_change_mtu,
-       .ndo_start_xmit = interface_tx,
-       .ndo_validate_addr = eth_validate_addr
-};
-#endif
-
-void interface_setup(struct net_device *dev)
-{
-       struct bat_priv *priv = netdev_priv(dev);
-       char dev_addr[ETH_ALEN];
-
-       ether_setup(dev);
-
-#ifdef HAVE_NET_DEVICE_OPS
-       dev->netdev_ops = &bat_netdev_ops;
-#else
-       dev->open = interface_open;
-       dev->stop = interface_release;
-       dev->get_stats = interface_stats;
-       dev->set_mac_address = interface_set_mac_addr;
-       dev->change_mtu = interface_change_mtu;
-       dev->hard_start_xmit = interface_tx;
-#endif
-       dev->destructor = free_netdev;
-
-       dev->mtu = hardif_min_mtu();
-       dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
-                                               * skbuff for our header */
-
-       /* generate random address */
-       random_ether_addr(dev_addr);
-       memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
-
-       SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
-
-       memset(priv, 0, sizeof(struct bat_priv));
-}
-
-int interface_open(struct net_device *dev)
+static int interface_open(struct net_device *dev)
 {
        netif_start_queue(dev);
        return 0;
 }
 
-int interface_release(struct net_device *dev)
+static int interface_release(struct net_device *dev)
 {
        netif_stop_queue(dev);
        return 0;
 }
 
-struct net_device_stats *interface_stats(struct net_device *dev)
+static struct net_device_stats *interface_stats(struct net_device *dev)
 {
        struct bat_priv *priv = netdev_priv(dev);
        return &priv->stats;
 }
 
-int interface_set_mac_addr(struct net_device *dev, void *p)
+static int interface_set_mac_addr(struct net_device *dev, void *p)
 {
        struct sockaddr *addr = p;
 
@@ -163,7 +114,7 @@ int interface_set_mac_addr(struct net_device *dev, void *p)
        return 0;
 }
 
-int interface_change_mtu(struct net_device *dev, int new_mtu)
+static int interface_change_mtu(struct net_device *dev, int new_mtu)
 {
        /* check ranges */
        if ((new_mtu < 68) || (new_mtu > hardif_min_mtu()))
@@ -179,6 +130,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
        struct unicast_packet *unicast_packet;
        struct bcast_packet *bcast_packet;
        struct orig_node *orig_node;
+       struct neigh_node *router;
        struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
        struct bat_priv *priv = netdev_priv(dev);
        struct batman_if *batman_if;
@@ -205,16 +157,17 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 
                bcast_packet = (struct bcast_packet *)skb->data;
                bcast_packet->version = COMPAT_VERSION;
+               bcast_packet->ttl = TTL;
 
                /* batman packet type: broadcast */
                bcast_packet->packet_type = BAT_BCAST;
 
                /* hw address of first interface is the orig mac because only
                 * this mac is known throughout the mesh */
-               memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
+               memcpy(bcast_packet->orig, main_if_addr, ETH_ALEN);
 
                /* set broadcast sequence number */
-               bcast_packet->seqno = htons(bcast_seqno);
+               bcast_packet->seqno = htonl(bcast_seqno);
 
                /* broadcast packet. on success, increase seqno. */
                if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
@@ -235,38 +188,36 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
                if (!orig_node)
                        orig_node = transtable_search(ethhdr->h_dest);
 
-               if ((orig_node) &&
-                   (orig_node->router)) {
-                       struct neigh_node *router = orig_node->router;
+               router = find_router(orig_node, NULL);
 
-                       if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
-                               goto unlock;
+               if (!router)
+                       goto unlock;
 
-                       unicast_packet = (struct unicast_packet *)skb->data;
+               /* don't lock while sending the packets ... we therefore
+                * copy the required data before sending */
 
-                       unicast_packet->version = COMPAT_VERSION;
-                       /* batman packet type: unicast */
-                       unicast_packet->packet_type = BAT_UNICAST;
-                       /* set unicast ttl */
-                       unicast_packet->ttl = TTL;
-                       /* copy the destination for faster routing */
-                       memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+               batman_if = router->if_incoming;
+               memcpy(dstaddr, router->addr, ETH_ALEN);
 
-                       /* net_dev won't be available when not active */
-                       if (router->if_incoming->if_status != IF_ACTIVE)
-                               goto unlock;
+               spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-                       /* don't lock while sending the packets ... we therefore
-                        * copy the required data before sending */
+               if (batman_if->if_status != IF_ACTIVE)
+                       goto dropped;
 
-                       batman_if = router->if_incoming;
-                       memcpy(dstaddr, router->addr, ETH_ALEN);
-                       spin_unlock_irqrestore(&orig_hash_lock, flags);
+               if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
+                       goto dropped;
 
-                       send_skb_packet(skb, batman_if, dstaddr);
-               } else {
-                       goto unlock;
-               }
+               unicast_packet = (struct unicast_packet *)skb->data;
+
+               unicast_packet->version = COMPAT_VERSION;
+               /* batman packet type: unicast */
+               unicast_packet->packet_type = BAT_UNICAST;
+               /* set unicast ttl */
+               unicast_packet->ttl = TTL;
+               /* copy the destination for faster routing */
+               memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+
+               send_skb_packet(skb, batman_if, dstaddr);
        }
 
        priv->stats.tx_packets++;
@@ -315,6 +266,50 @@ void interface_rx(struct sk_buff *skb, int hdr_size)
        netif_rx(skb);
 }
 
+#ifdef HAVE_NET_DEVICE_OPS
+static const struct net_device_ops bat_netdev_ops = {
+       .ndo_open = interface_open,
+       .ndo_stop = interface_release,
+       .ndo_get_stats = interface_stats,
+       .ndo_set_mac_address = interface_set_mac_addr,
+       .ndo_change_mtu = interface_change_mtu,
+       .ndo_start_xmit = interface_tx,
+       .ndo_validate_addr = eth_validate_addr
+};
+#endif
+
+void interface_setup(struct net_device *dev)
+{
+       struct bat_priv *priv = netdev_priv(dev);
+       char dev_addr[ETH_ALEN];
+
+       ether_setup(dev);
+
+#ifdef HAVE_NET_DEVICE_OPS
+       dev->netdev_ops = &bat_netdev_ops;
+#else
+       dev->open = interface_open;
+       dev->stop = interface_release;
+       dev->get_stats = interface_stats;
+       dev->set_mac_address = interface_set_mac_addr;
+       dev->change_mtu = interface_change_mtu;
+       dev->hard_start_xmit = interface_tx;
+#endif
+       dev->destructor = free_netdev;
+
+       dev->mtu = hardif_min_mtu();
+       dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
+                                               * skbuff for our header */
+
+       /* generate random address */
+       random_ether_addr(dev_addr);
+       memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
+
+       SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
+
+       memset(priv, 0, sizeof(struct bat_priv));
+}
+
 /* ethtool */
 static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
index e7f59af7df33177fd18b6acf3baf31d0928a30ad..6364854390092a6e1c851f2cc0888da31f4ef2d6 100644 (file)
  *
  */
 
+#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_
+#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
+
 void set_main_if_addr(uint8_t *addr);
-int main_if_was_up(void);
 void interface_setup(struct net_device *dev);
-int interface_open(struct net_device *dev);
-int interface_release(struct net_device *dev);
-struct net_device_stats *interface_stats(struct net_device *dev);
-int interface_set_mac_addr(struct net_device *dev, void *addr);
-int interface_change_mtu(struct net_device *dev, int new_mtu);
 int interface_tx(struct sk_buff *skb, struct net_device *dev);
 void interface_rx(struct sk_buff *skb, int hdr_size);
 int my_skb_push(struct sk_buff *skb, unsigned int len);
 
-extern unsigned char mainIfAddr[];
+extern unsigned char main_if_addr[];
+
+#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
diff --git a/drivers/staging/batman-adv/sysfs-class-net-batman-adv b/drivers/staging/batman-adv/sysfs-class-net-batman-adv
new file mode 100644 (file)
index 0000000..38dd762
--- /dev/null
@@ -0,0 +1,14 @@
+
+What:           /sys/class/net/<iface>/batman-adv/mesh_iface
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                The /sys/class/net/<iface>/batman-adv/mesh_iface file
+                displays the batman mesh interface this <iface>
+                currently is associated with.
+
+What:           /sys/class/net/<iface>/batman-adv/iface_status
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Indicates the status of <iface> as it is seen by batman.
diff --git a/drivers/staging/batman-adv/sysfs-class-net-mesh b/drivers/staging/batman-adv/sysfs-class-net-mesh
new file mode 100644 (file)
index 0000000..5aa1912
--- /dev/null
@@ -0,0 +1,33 @@
+
+What:           /sys/class/net/<mesh_iface>/mesh/aggregated_ogms
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Indicates whether the batman protocol messages of the
+                mesh <mesh_iface> shall be aggregated or not.
+
+What:           /sys/class/net/<mesh_iface>/mesh/bonding
+Date:           June 2010
+Contact:        Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Description:
+                Indicates whether the data traffic going through the
+                mesh will be sent using multiple interfaces at the
+                same time (if available).
+
+What:           /sys/class/net/<mesh_iface>/mesh/orig_interval
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Defines the interval in milliseconds in which batman
+                sends its protocol messages.
+
+What:           /sys/class/net/<mesh_iface>/mesh/vis_mode
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Each batman node only maintains information about its
+                own local neighborhood, therefore generating graphs
+                showing the topology of the entire mesh is not easily
+                feasible without having a central instance to collect
+                the local topologies from all nodes. This file allows
+                to activate the collecting (server) mode.
index e01ff2151f76453395c2e03292657b12c5af08d7..b233377d756808bf15398ad13ff7560b2589d51d 100644 (file)
@@ -32,7 +32,10 @@ atomic_t hna_local_changed;
 DEFINE_SPINLOCK(hna_local_hash_lock);
 static DEFINE_SPINLOCK(hna_global_hash_lock);
 
+static void hna_local_purge(struct work_struct *work);
 static DECLARE_DELAYED_WORK(hna_local_purge_wq, hna_local_purge);
+static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+                                char *message);
 
 static void hna_local_start_timer(void)
 {
@@ -57,6 +60,8 @@ int hna_local_init(void)
 
 void hna_local_add(uint8_t *addr)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct hna_local_entry *hna_local_entry;
        struct hna_global_entry *hna_global_entry;
        struct hashtable_t *swaphash;
@@ -77,15 +82,15 @@ void hna_local_add(uint8_t *addr)
           MAC-flooding. */
        if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
            (num_hna + 1 > 255)) {
-               bat_dbg(DBG_ROUTES,
+               bat_dbg(DBG_ROUTES, bat_priv,
                        "Can't add new local hna entry (%pM): "
                        "number of local hna entries exceeds packet size\n",
                        addr);
                return;
        }
 
-       bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM\n",
-               addr);
+       bat_dbg(DBG_ROUTES, bat_priv,
+               "Creating new local hna entry: %pM\n", addr);
 
        hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
        if (!hna_local_entry)
@@ -111,8 +116,7 @@ void hna_local_add(uint8_t *addr)
                                       hna_local_hash->size * 2);
 
                if (swaphash == NULL)
-                       printk(KERN_ERR "batman-adv:"
-                              "Couldn't resize local hna hash table\n");
+                       pr_err("Couldn't resize local hna hash table\n");
                else
                        hna_local_hash = swaphash;
        }
@@ -160,59 +164,54 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
        return i;
 }
 
-int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
-                              size_t count, loff_t off)
+int hna_local_seq_print_text(struct seq_file *seq, void *offset)
 {
+       struct net_device *net_dev = (struct net_device *)seq->private;
        struct bat_priv *bat_priv = netdev_priv(net_dev);
        struct hna_local_entry *hna_local_entry;
        HASHIT(hashit);
-       int bytes_written = 0;
+       HASHIT(hashit_count);
        unsigned long flags;
-       size_t hdr_len;
+       size_t buf_size, pos;
+       char *buff;
 
        if (!bat_priv->primary_if) {
-               if (off == 0)
-                       return sprintf(buff,
-                                    "BATMAN mesh %s disabled - "
-                                    "please specify interfaces to enable it\n",
-                                    net_dev->name);
-
-               return 0;
+               return seq_printf(seq, "BATMAN mesh %s disabled - "
+                              "please specify interfaces to enable it\n",
+                              net_dev->name);
        }
 
-       hdr_len = sprintf(buff,
-                         "Locally retrieved addresses (from %s) "
-                         "announced via HNA:\n",
-                         net_dev->name);
-
-       if (off < hdr_len)
-               bytes_written = hdr_len;
+       seq_printf(seq, "Locally retrieved addresses (from %s) "
+                  "announced via HNA:\n",
+                  net_dev->name);
 
        spin_lock_irqsave(&hna_local_hash_lock, flags);
 
-       while (hash_iterate(hna_local_hash, &hashit)) {
-               hdr_len += 21;
-
-               if (count < bytes_written + 22)
-                       break;
+       buf_size = 1;
+       /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
+       while (hash_iterate(hna_local_hash, &hashit_count))
+               buf_size += 21;
 
-               if (off >= hdr_len)
-                       continue;
+       buff = kmalloc(buf_size, GFP_ATOMIC);
+       if (!buff) {
+               spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+               return -ENOMEM;
+       }
+       buff[0] = '\0';
+       pos = 0;
 
+       while (hash_iterate(hna_local_hash, &hashit)) {
                hna_local_entry = hashit.bucket->data;
 
-               bytes_written += snprintf(buff + bytes_written, 22,
-                                         " * " MAC_FMT "\n",
-                                         hna_local_entry->addr[0],
-                                         hna_local_entry->addr[1],
-                                         hna_local_entry->addr[2],
-                                         hna_local_entry->addr[3],
-                                         hna_local_entry->addr[4],
-                                         hna_local_entry->addr[5]);
+               pos += snprintf(buff + pos, 22, " * %pM\n",
+                               hna_local_entry->addr);
        }
 
        spin_unlock_irqrestore(&hna_local_hash_lock, flags);
-       return bytes_written;
+
+       seq_printf(seq, "%s", buff);
+       kfree(buff);
+       return 0;
 }
 
 static void _hna_local_del(void *data)
@@ -225,7 +224,9 @@ static void _hna_local_del(void *data)
 static void hna_local_del(struct hna_local_entry *hna_local_entry,
                          char *message)
 {
-       bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s\n",
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
+       bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
                hna_local_entry->addr, message);
 
        hash_remove(hna_local_hash, hna_local_entry->addr);
@@ -247,7 +248,7 @@ void hna_local_remove(uint8_t *addr, char *message)
        spin_unlock_irqrestore(&hna_local_hash_lock, flags);
 }
 
-void hna_local_purge(struct work_struct *work)
+static void hna_local_purge(struct work_struct *work)
 {
        struct hna_local_entry *hna_local_entry;
        HASHIT(hashit);
@@ -259,8 +260,7 @@ void hna_local_purge(struct work_struct *work)
        while (hash_iterate(hna_local_hash, &hashit)) {
                hna_local_entry = hashit.bucket->data;
 
-               timeout = hna_local_entry->last_seen +
-                       ((LOCAL_HNA_TIMEOUT / 1000) * HZ);
+               timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ;
                if ((!hna_local_entry->never_purge) &&
                    time_after(jiffies, timeout))
                        hna_local_del(hna_local_entry, "address timed out");
@@ -296,6 +296,8 @@ int hna_global_init(void)
 void hna_global_add_orig(struct orig_node *orig_node,
                         unsigned char *hna_buff, int hna_buff_len)
 {
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct hna_global_entry *hna_global_entry;
        struct hna_local_entry *hna_local_entry;
        struct hashtable_t *swaphash;
@@ -322,7 +324,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
 
                        memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
 
-                       bat_dbg(DBG_ROUTES,
+                       bat_dbg(DBG_ROUTES, bat_priv,
                                "Creating new global hna entry: "
                                "%pM (via %pM)\n",
                                hna_global_entry->addr, orig_node->orig);
@@ -369,8 +371,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
                                       hna_global_hash->size * 2);
 
                if (swaphash == NULL)
-                       printk(KERN_ERR "batman-adv:"
-                              "Couldn't resize global hna hash table\n");
+                       pr_err("Couldn't resize global hna hash table\n");
                else
                        hna_global_hash = swaphash;
        }
@@ -378,71 +379,63 @@ void hna_global_add_orig(struct orig_node *orig_node,
        spin_unlock_irqrestore(&hna_global_hash_lock, flags);
 }
 
-int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
-                               size_t count, loff_t off)
+int hna_global_seq_print_text(struct seq_file *seq, void *offset)
 {
+       struct net_device *net_dev = (struct net_device *)seq->private;
        struct bat_priv *bat_priv = netdev_priv(net_dev);
        struct hna_global_entry *hna_global_entry;
        HASHIT(hashit);
-       int bytes_written = 0;
+       HASHIT(hashit_count);
        unsigned long flags;
-       size_t hdr_len;
+       size_t buf_size, pos;
+       char *buff;
 
        if (!bat_priv->primary_if) {
-               if (off == 0)
-                       return sprintf(buff,
-                                    "BATMAN mesh %s disabled - "
-                                    "please specify interfaces to enable it\n",
-                                    net_dev->name);
-
-               return 0;
+               return seq_printf(seq, "BATMAN mesh %s disabled - "
+                                 "please specify interfaces to enable it\n",
+                                 net_dev->name);
        }
 
-       hdr_len = sprintf(buff,
-                         "Globally announced HNAs received via the mesh %s "
-                         "(translation table):\n",
-                         net_dev->name);
-
-       if (off < hdr_len)
-               bytes_written = hdr_len;
+       seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
+                  net_dev->name);
 
        spin_lock_irqsave(&hna_global_hash_lock, flags);
 
-       while (hash_iterate(hna_global_hash, &hashit)) {
-               hdr_len += 43;
-
-               if (count < bytes_written + 44)
-                       break;
+       buf_size = 1;
+       /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
+       while (hash_iterate(hna_global_hash, &hashit_count))
+               buf_size += 43;
 
-               if (off >= hdr_len)
-                       continue;
+       buff = kmalloc(buf_size, GFP_ATOMIC);
+       if (!buff) {
+               spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+               return -ENOMEM;
+       }
+       buff[0] = '\0';
+       pos = 0;
 
+       while (hash_iterate(hna_global_hash, &hashit)) {
                hna_global_entry = hashit.bucket->data;
 
-               bytes_written += snprintf(buff + bytes_written, 44,
-                                         " * " MAC_FMT " via " MAC_FMT "\n",
-                                         hna_global_entry->addr[0],
-                                         hna_global_entry->addr[1],
-                                         hna_global_entry->addr[2],
-                                         hna_global_entry->addr[3],
-                                         hna_global_entry->addr[4],
-                                         hna_global_entry->addr[5],
-                                         hna_global_entry->orig_node->orig[0],
-                                         hna_global_entry->orig_node->orig[1],
-                                         hna_global_entry->orig_node->orig[2],
-                                         hna_global_entry->orig_node->orig[3],
-                                         hna_global_entry->orig_node->orig[4],
-                                         hna_global_entry->orig_node->orig[5]);
+               pos += snprintf(buff + pos, 44,
+                               " * %pM via %pM\n", hna_global_entry->addr,
+                               hna_global_entry->orig_node->orig);
        }
 
        spin_unlock_irqrestore(&hna_global_hash_lock, flags);
-       return bytes_written;
+
+       seq_printf(seq, "%s", buff);
+       kfree(buff);
+       return 0;
 }
 
-void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
-                         char *message)
+static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+                                char *message)
 {
-       bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s\n",
+       /* FIXME: each orig_node->batman_if will be attached to a softif */
+       struct bat_priv *bat_priv = netdev_priv(soft_device);
+       bat_dbg(DBG_ROUTES, bat_priv,
+               "Deleting global hna entry %pM (via %pM): %s\n",
                hna_global_entry->addr, hna_global_entry->orig_node->orig,
                message);
 
index 8f412fca87f1678065c6420caeaf0530d6ce28b7..fa93e37d095109ca676decb9315ab71e968b4b50 100644 (file)
  *
  */
 
+#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
+#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
+
 #include "types.h"
 
 int hna_local_init(void);
 void hna_local_add(uint8_t *addr);
 void hna_local_remove(uint8_t *addr, char *message);
 int hna_local_fill_buffer(unsigned char *buff, int buff_len);
-int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
-                              size_t count, loff_t off);
-void hna_local_purge(struct work_struct *work);
+int hna_local_seq_print_text(struct seq_file *seq, void *offset);
 void hna_local_free(void);
 int hna_global_init(void);
 void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff,
                         int hna_buff_len);
-int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
-                               size_t count, loff_t off);
-void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
-                         char *orig_str);
+int hna_global_seq_print_text(struct seq_file *seq, void *offset);
 void hna_global_del_orig(struct orig_node *orig_node, char *message);
 void hna_global_free(void);
 struct orig_node *transtable_search(uint8_t *addr);
@@ -43,3 +41,5 @@ struct orig_node *transtable_search(uint8_t *addr);
 extern spinlock_t hna_local_hash_lock;
 extern struct hashtable_t *hna_local_hash;
 extern atomic_t hna_local_changed;
+
+#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
index 86007c7eb443713b0d70a270925def9caa9372cd..21d0717afb09ef7d7f4c6d066a6218c3085392bf 100644 (file)
 
 
 
-
-
-#ifndef TYPES_H
-#define TYPES_H
+#ifndef _NET_BATMAN_ADV_TYPES_H_
+#define _NET_BATMAN_ADV_TYPES_H_
 
 #include "packet.h"
 #include "bitarray.h"
@@ -52,6 +50,7 @@ struct batman_if {
 
 /**
   *    orig_node - structure for orig_list maintaining nodes of mesh
+  *    @primary_addr: hosts primary interface address
   *    @last_valid: when last packet from this node was received
   *    @bcast_seqno_reset: time when the broadcast seqno window was reset
   *    @batman_seqno_reset: time when the batman seqno window was reset
@@ -59,9 +58,13 @@ struct batman_if {
   *    @last_real_seqno: last and best known squence number
   *    @last_ttl: ttl of last received packet
   *    @last_bcast_seqno: last broadcast sequence number received by this host
+  *
+  *    @candidates: how many candidates are available
+  *    @selected: next bonding candidate
  */
 struct orig_node {
        uint8_t orig[ETH_ALEN];
+       uint8_t primary_addr[ETH_ALEN];
        struct neigh_node *router;
        TYPE_OF_WORD *bcast_own;
        uint8_t *bcast_own_sum;
@@ -72,12 +75,16 @@ struct orig_node {
        unsigned long batman_seqno_reset;
        uint8_t  flags;
        unsigned char *hna_buff;
-       int16_t  hna_buff_len;
-       uint16_t last_real_seqno;
+       int16_t hna_buff_len;
+       uint32_t last_real_seqno;
        uint8_t last_ttl;
        TYPE_OF_WORD bcast_bits[NUM_WORDS];
-       uint16_t last_bcast_seqno;
+       uint32_t last_bcast_seqno;
        struct list_head neigh_list;
+       struct {
+               uint8_t candidates;
+               struct neigh_node *selected;
+       } bond;
 };
 
 /**
@@ -92,6 +99,7 @@ struct neigh_node {
        uint8_t tq_index;
        uint8_t tq_avg;
        uint8_t last_ttl;
+       struct neigh_node *next_bond_candidate;
        unsigned long last_valid;
        TYPE_OF_WORD real_bits[NUM_WORDS];
        struct orig_node *orig_node;
@@ -101,14 +109,18 @@ struct neigh_node {
 struct bat_priv {
        struct net_device_stats stats;
        atomic_t aggregation_enabled;
+       atomic_t bonding_enabled;
        atomic_t vis_mode;
        atomic_t orig_interval;
+       atomic_t log_level;
        char num_ifaces;
+       struct debug_log *debug_log;
        struct batman_if *primary_if;
        struct kobject *mesh_obj;
+       struct dentry *debug_dir;
 };
 
-struct device_client {
+struct socket_client {
        struct list_head queue_list;
        unsigned int queue_len;
        unsigned char index;
@@ -116,9 +128,10 @@ struct device_client {
        wait_queue_head_t queue_wait;
 };
 
-struct device_packet {
+struct socket_packet {
        struct list_head list;
-       struct icmp_packet icmp_packet;
+       size_t icmp_len;
+       struct icmp_packet_rr icmp_packet;
 };
 
 struct hna_local_entry {
@@ -159,4 +172,12 @@ struct if_list_entry {
        struct hlist_node list;
 };
 
-#endif
+struct debug_log {
+       char log_buff[LOG_BUF_LEN];
+       unsigned long log_start;
+       unsigned long log_end;
+       spinlock_t lock;
+       wait_queue_head_t queue_wait;
+};
+
+#endif /* _NET_BATMAN_ADV_TYPES_H_ */
index 1d3d954847fdaa4dc18c7fce12ea6d27ba23e2e0..4b6a5045f057dbda9e9d2556aa0404efe79bd803 100644 (file)
@@ -43,8 +43,8 @@
                        _dummy > smallest_signed_int(_dummy); })
 #define seq_after(x, y) seq_before(y, x)
 
-struct hashtable_t *vis_hash;
-DEFINE_SPINLOCK(vis_hash_lock);
+static struct hashtable_t *vis_hash;
+static DEFINE_SPINLOCK(vis_hash_lock);
 static DEFINE_SPINLOCK(recv_list_lock);
 static struct vis_info *my_vis_info;
 static struct list_head send_list;     /* always locked with vis_hash_lock */
@@ -115,7 +115,7 @@ static void vis_data_insert_interface(const uint8_t *interface,
        }
 
        /* its a new address, add it to the list */
-       entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
        if (!entry)
                return;
        memcpy(entry->addr, interface, ETH_ALEN);
@@ -142,12 +142,29 @@ static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
        return len;
 }
 
+static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
+{
+       struct if_list_entry *entry;
+       struct hlist_node *pos;
+       size_t count = 0;
+
+       hlist_for_each_entry(entry, pos, if_list, list) {
+               if (entry->primary)
+                       count += 9;
+               else
+                       count += 23;
+       }
+
+       return count;
+}
+
 /* read an entry  */
 static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
                                   uint8_t *src, bool primary)
 {
-       char to[40];
+       char to[18];
 
+       /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
        addr_to_string(to, entry->dest);
        if (primary && entry->quality == 0)
                return sprintf(buff, "HNA %s, ", to);
@@ -157,38 +174,74 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
        return 0;
 }
 
-ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
-                             size_t count, loff_t off)
+int vis_seq_print_text(struct seq_file *seq, void *offset)
 {
        HASHIT(hashit);
+       HASHIT(hashit_count);
        struct vis_info *info;
        struct vis_info_entry *entries;
+       struct net_device *net_dev = (struct net_device *)seq->private;
        struct bat_priv *bat_priv = netdev_priv(net_dev);
        HLIST_HEAD(vis_if_list);
        struct if_list_entry *entry;
        struct hlist_node *pos, *n;
-       size_t hdr_len, tmp_len;
-       int i, bytes_written = 0;
+       int i;
        char tmp_addr_str[ETH_STR_LEN];
        unsigned long flags;
        int vis_server = atomic_read(&bat_priv->vis_mode);
+       size_t buff_pos, buf_size;
+       char *buff;
 
        if ((!bat_priv->primary_if) ||
            (vis_server == VIS_TYPE_CLIENT_UPDATE))
                return 0;
 
-       hdr_len = 0;
-
+       buf_size = 1;
+       /* Estimate length */
        spin_lock_irqsave(&vis_hash_lock, flags);
+       while (hash_iterate(vis_hash, &hashit_count)) {
+               info = hashit_count.bucket->data;
+               entries = (struct vis_info_entry *)
+                       ((char *)info + sizeof(struct vis_info));
+
+               for (i = 0; i < info->packet.entries; i++) {
+                       if (entries[i].quality == 0)
+                               continue;
+                       vis_data_insert_interface(entries[i].src, &vis_if_list,
+                               compare_orig(entries[i].src,
+                                               info->packet.vis_orig));
+               }
+
+               hlist_for_each_entry(entry, pos, &vis_if_list, list) {
+                       buf_size += 18 + 26 * info->packet.entries;
+
+                       /* add primary/secondary records */
+                       if (compare_orig(entry->addr, info->packet.vis_orig))
+                               buf_size +=
+                                       vis_data_count_prim_sec(&vis_if_list);
+
+                       buf_size += 1;
+               }
+
+               hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
+                       hlist_del(&entry->list);
+                       kfree(entry);
+               }
+       }
+
+       buff = kmalloc(buf_size, GFP_ATOMIC);
+       if (!buff) {
+               spin_unlock_irqrestore(&vis_hash_lock, flags);
+               return -ENOMEM;
+       }
+       buff[0] = '\0';
+       buff_pos = 0;
+
        while (hash_iterate(vis_hash, &hashit)) {
                info = hashit.bucket->data;
                entries = (struct vis_info_entry *)
                        ((char *)info + sizeof(struct vis_info));
 
-               /* estimated line length */
-               if (count < bytes_written + 200)
-                       break;
-
                for (i = 0; i < info->packet.entries; i++) {
                        if (entries[i].quality == 0)
                                continue;
@@ -199,30 +252,22 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
 
                hlist_for_each_entry(entry, pos, &vis_if_list, list) {
                        addr_to_string(tmp_addr_str, entry->addr);
-                       tmp_len = sprintf(buff + bytes_written,
-                                         "%s,", tmp_addr_str);
+                       buff_pos += sprintf(buff + buff_pos, "%s,",
+                                           tmp_addr_str);
 
                        for (i = 0; i < info->packet.entries; i++)
-                               tmp_len += vis_data_read_entry(
-                                               buff + bytes_written + tmp_len,
-                                               &entries[i], entry->addr,
-                                               entry->primary);
+                               buff_pos += vis_data_read_entry(buff + buff_pos,
+                                                               &entries[i],
+                                                               entry->addr,
+                                                               entry->primary);
 
                        /* add primary/secondary records */
                        if (compare_orig(entry->addr, info->packet.vis_orig))
-                               tmp_len += vis_data_read_prim_sec(
-                                               buff + bytes_written + tmp_len,
-                                               &vis_if_list);
-
-                       tmp_len += sprintf(buff + bytes_written + tmp_len,
-                                         "\n");
-
-                       hdr_len += tmp_len;
+                               buff_pos +=
+                                       vis_data_read_prim_sec(buff + buff_pos,
+                                                              &vis_if_list);
 
-                       if (off >= hdr_len)
-                               continue;
-
-                       bytes_written += tmp_len;
+                       buff_pos += sprintf(buff + buff_pos, "\n");
                }
 
                hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
@@ -230,9 +275,13 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
                        kfree(entry);
                }
        }
+
        spin_unlock_irqrestore(&vis_hash_lock, flags);
 
-       return bytes_written;
+       seq_printf(seq, "%s", buff);
+       kfree(buff);
+
+       return 0;
 }
 
 /* add the info packet to the send list, if it was not
@@ -308,7 +357,8 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
        old_info = hash_find(vis_hash, &search_elem);
 
        if (old_info != NULL) {
-               if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) {
+               if (!seq_after(ntohl(vis_packet->seqno),
+                               ntohl(old_info->packet.seqno))) {
                        if (old_info->packet.seqno == vis_packet->seqno) {
                                recv_list_add(&old_info->recv_list,
                                              vis_packet->sender_orig);
@@ -340,7 +390,7 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
 
        /* Make it a broadcast packet, if required */
        if (make_broadcast)
-               memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+               memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
 
        /* repair if entries is longer than packet. */
        if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
@@ -474,9 +524,9 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
        info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
 
        spin_lock_irqsave(&orig_hash_lock, flags);
-       memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+       memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
        info->packet.ttl = TTL;
-       info->packet.seqno++;
+       info->packet.seqno = htonl(ntohl(info->packet.seqno) + 1);
        info->packet.entries = 0;
 
        if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
@@ -547,7 +597,7 @@ static void purge_vis_packets(void)
                if (info == my_vis_info)        /* never purge own data. */
                        continue;
                if (time_after(jiffies,
-                              info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
+                              info->first_seen + VIS_TIMEOUT * HZ)) {
                        hash_remove_bucket(vis_hash, &hashit);
                        send_list_del(info);
                        kref_put(&info->refcount, free_info);
@@ -591,7 +641,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
 
        }
        spin_unlock_irqrestore(&orig_hash_lock, flags);
-       memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+       memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
 }
 
 static void unicast_vis_packet(struct vis_info *info, int packet_length)
@@ -628,11 +678,11 @@ static void send_vis_packet(struct vis_info *info)
        int packet_length;
 
        if (info->packet.ttl < 2) {
-               printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
+               pr_warning("Error - can't send vis packet: ttl exceeded\n");
                return;
        }
 
-       memcpy(info->packet.sender_orig, mainIfAddr, ETH_ALEN);
+       memcpy(info->packet.sender_orig, main_if_addr, ETH_ALEN);
        info->packet.ttl--;
 
        packet_length = sizeof(struct vis_packet) +
@@ -690,18 +740,18 @@ int vis_init(void)
 
        vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
        if (!vis_hash) {
-               printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n");
+               pr_err("Can't initialize vis_hash\n");
                goto err;
        }
 
        my_vis_info = kmalloc(1000, GFP_ATOMIC);
        if (!my_vis_info) {
-               printk(KERN_ERR "batman-adv:Can't initialize vis packet\n");
+               pr_err("Can't initialize vis packet\n");
                goto err;
        }
 
        /* prefill the vis info */
-       my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
+       my_vis_info->first_seen = jiffies - msecs_to_jiffies(VIS_INTERVAL);
        INIT_LIST_HEAD(&my_vis_info->recv_list);
        INIT_LIST_HEAD(&my_vis_info->send_list);
        kref_init(&my_vis_info->refcount);
@@ -713,12 +763,11 @@ int vis_init(void)
 
        INIT_LIST_HEAD(&send_list);
 
-       memcpy(my_vis_info->packet.vis_orig, mainIfAddr, ETH_ALEN);
-       memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
+       memcpy(my_vis_info->packet.vis_orig, main_if_addr, ETH_ALEN);
+       memcpy(my_vis_info->packet.sender_orig, main_if_addr, ETH_ALEN);
 
        if (hash_add(vis_hash, my_vis_info) < 0) {
-               printk(KERN_ERR
-                      "batman-adv:Can't add own vis packet into hash\n");
+               pr_err("Can't add own vis packet into hash\n");
                /* not in hash, need to remove it manually. */
                kref_put(&my_vis_info->refcount, free_info);
                goto err;
@@ -764,5 +813,5 @@ void vis_quit(void)
 static void start_vis_timer(void)
 {
        queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
-                          (atomic_read(&vis_interval) * HZ) / 1000);
+                          (VIS_INTERVAL * HZ) / 1000);
 }
index 9c1fd771cbaeee7cff0ad5e5e946015e2d1d7d80..bb13bf1a3f49841eded9f9e9e991837bf4657947 100644 (file)
  *
  */
 
-#define VIS_TIMEOUT            200000
+#ifndef _NET_BATMAN_ADV_VIS_H_
+#define _NET_BATMAN_ADV_VIS_H_
+
+#define VIS_TIMEOUT            200     /* timeout of vis packets in seconds */
 
 struct vis_info {
        unsigned long       first_seen;
@@ -44,11 +47,7 @@ struct recvlist_node {
        uint8_t mac[ETH_ALEN];
 };
 
-extern struct hashtable_t *vis_hash;
-extern spinlock_t vis_hash_lock;
-
-ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
-                             size_t count, loff_t off);
+int vis_seq_print_text(struct seq_file *seq, void *offset);
 void receive_server_sync_packet(struct bat_priv *bat_priv,
                                struct vis_packet *vis_packet,
                                int vis_info_len);
@@ -57,3 +56,5 @@ void receive_client_update_packet(struct bat_priv *bat_priv,
                                  int vis_info_len);
 int vis_init(void);
 void vis_quit(void);
+
+#endif /* _NET_BATMAN_ADV_VIS_H_ */
index 15c9348fb93872705ef95b404b8f658eed5131fa..b10f739b7e3e1fcbe16acaf7d66705b59e534441 100644 (file)
@@ -2,7 +2,6 @@ TODO:
        - checkpatch.pl cleanups
        - Lindent
        - remove all wrappers
-       - remove typedefs
        - audit userspace interface
        - reserve major number
        - cleanup the individual comedi drivers as well
index aeb2c00875cd2110117afae796edb95748134e39..14091313cebbe66c419b73453ccd0b158d89c1da 100644 (file)
@@ -1845,8 +1845,15 @@ ok:
                }
        }
 
-       if (dev->attached && dev->use_count == 0 && dev->open)
-               dev->open(dev);
+       if (dev->attached && dev->use_count == 0 && dev->open) {
+               int rc = dev->open(dev);
+               if (rc < 0) {
+                       module_put(dev->driver->module);
+                       module_put(THIS_MODULE);
+                       mutex_unlock(&dev->mutex);
+                       return rc;
+               }
+       }
 
        dev->use_count++;
 
index 4eb2b77f56dc55ef9442e00935094a630742318b..68aa9176d2490c821d4e94ccec459df53390f964 100644 (file)
        COMEDI_MINORVERSION, COMEDI_MICROVERSION)
 #define COMEDI_RELEASE VERSION
 
-#define COMEDI_INITCLEANUP_NOMODULE(x)                                 \
-       static int __init x ## _init_module(void)                       \
-               {return comedi_driver_register(&(x)); }                 \
-       static void __exit x ## _cleanup_module(void)                   \
-               {comedi_driver_unregister(&(x)); }                      \
-       module_init(x ## _init_module);                                 \
-       module_exit(x ## _cleanup_module);
-
-#define COMEDI_MODULE_MACROS                                           \
-       MODULE_AUTHOR("Comedi http://www.comedi.org");          \
-       MODULE_DESCRIPTION("Comedi low-level driver");                  \
-       MODULE_LICENSE("GPL");
-
-#define COMEDI_INITCLEANUP(x)                                          \
-       COMEDI_MODULE_MACROS            \
-       COMEDI_INITCLEANUP_NOMODULE(x)
-
-#define COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) \
-       static int __devinit comedi_driver ## _pci_probe(struct pci_dev *dev, \
-               const struct pci_device_id *ent) \
-       { \
-               return comedi_pci_auto_config(dev, comedi_driver.driver_name); \
-       } \
-       static void __devexit comedi_driver ## _pci_remove(\
-               struct pci_dev *dev) \
-       { \
-               comedi_pci_auto_unconfig(dev); \
-       } \
-       static struct pci_driver comedi_driver ## _pci_driver = \
-       { \
-               .id_table = pci_id_table, \
-               .probe = &comedi_driver ## _pci_probe, \
-               .remove = __devexit_p(&comedi_driver ## _pci_remove) \
-       }; \
-       static int __init comedi_driver ## _init_module(void) \
-       { \
-               int retval; \
-               retval = comedi_driver_register(&comedi_driver); \
-               if (retval < 0) \
-                       return retval; \
-                       comedi_driver ## _pci_driver.name = \
-                               (char *)comedi_driver.driver_name; \
-               return pci_register_driver(&comedi_driver ## _pci_driver); \
-       } \
-       static void __exit comedi_driver ## _cleanup_module(void) \
-       { \
-               pci_unregister_driver(&comedi_driver ## _pci_driver); \
-               comedi_driver_unregister(&comedi_driver); \
-       } \
-       module_init(comedi_driver ## _init_module); \
-       module_exit(comedi_driver ## _cleanup_module);
-
-#define COMEDI_PCI_INITCLEANUP(comedi_driver, pci_id_table) \
-       COMEDI_MODULE_MACROS \
-       COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table)
-
 #define PCI_VENDOR_ID_ADLINK           0x144a
 #define PCI_VENDOR_ID_ICP              0x104c
 #define PCI_VENDOR_ID_CONTEC           0x1221
@@ -285,7 +229,7 @@ struct comedi_device {
 
        struct fasync_struct *async_queue;
 
-       void (*open) (struct comedi_device *dev);
+       int (*open) (struct comedi_device *dev);
        void (*close) (struct comedi_device *dev);
 };
 
index fe63830bd850bf6711c4ddcdaf834966ff6667c4..95049a8d3b38721e0bb6d71f56188c1a01593e69 100644 (file)
@@ -117,7 +117,18 @@ static struct comedi_driver driver_8255 = {
        .detach = dev_8255_detach,
 };
 
-COMEDI_INITCLEANUP(driver_8255);
+static int __init driver_8255_init_module(void)
+{
+       return comedi_driver_register(&driver_8255);
+}
+
+static void __exit driver_8255_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_8255);
+}
+
+module_init(driver_8255_init_module);
+module_exit(driver_8255_cleanup_module);
 
 static void do_config(struct comedi_device *dev, struct comedi_subdevice *s);
 
@@ -457,3 +468,7 @@ static int dev_8255_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index e20c3542c069d2a9333af9dcf7e58d23c46ccc43..9def2250bb8002ab84460649bc854069f23ce3f0 100644 (file)
@@ -49,7 +49,18 @@ static struct comedi_driver driver_acl7225b = {
        .offset = sizeof(struct boardtype),
 };
 
-COMEDI_INITCLEANUP(driver_acl7225b);
+static int __init driver_acl7225b_init_module(void)
+{
+       return comedi_driver_register(&driver_acl7225b);
+}
+
+static void __exit driver_acl7225b_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_acl7225b);
+}
+
+module_init(driver_acl7225b_init_module);
+module_exit(driver_acl7225b_cleanup_module);
 
 static int acl7225b_do_insn(struct comedi_device *dev,
                            struct comedi_subdevice *s,
@@ -150,3 +161,7 @@ static int acl7225b_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index c3284eb0f0ac4447dcc53b8234263df27021a133..8ed19bcbf35252173ff3093b61038c3881713929 100644 (file)
@@ -247,16 +247,14 @@ int i_pci_card_data(struct pcilst_struct *amcc,
 /* build list of amcc cards in this system */
 void v_pci_card_list_init(unsigned short pci_vendor, char display)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct pcilst_struct *amcc, *last;
        int i;
        int i_Count = 0;
        amcc_devices = NULL;
        last = NULL;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                for (i_Count = 0; i_Count < 2; i_Count++) {
                        pci_vendor = i_ADDIDATADeviceID[i_Count];
                        if (pcidev->vendor == pci_vendor) {
index b18e81d8cf8a5187fc4bc41afc974b5eb91ccbae..5ed4b9451f2873f77777f4cd7d96882ec8aa156d 100644 (file)
@@ -2541,7 +2541,43 @@ static struct comedi_driver driver_addi = {
        .offset = sizeof(struct addi_board),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_addi, addi_apci_tbl);
+static int __devinit driver_addi_pci_probe(struct pci_dev *dev,
+                                          const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_addi.driver_name);
+}
+
+static void __devexit driver_addi_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_addi_pci_driver = {
+       .id_table = addi_apci_tbl,
+       .probe = &driver_addi_pci_probe,
+       .remove = __devexit_p(&driver_addi_pci_remove)
+};
+
+static int __init driver_addi_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_addi);
+       if (retval < 0)
+               return retval;
+
+       driver_addi_pci_driver.name = (char *)driver_addi.driver_name;
+       return pci_register_driver(&driver_addi_pci_driver);
+}
+
+static void __exit driver_addi_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_addi_pci_driver);
+       comedi_driver_unregister(&driver_addi);
+}
+
+module_init(driver_addi_init_module);
+module_exit(driver_addi_cleanup_module);
 
 /*
 +----------------------------------------------------------------------------+
index bea329f44d80974bcd589b5bbbb6b221cfccbf83..e0213a903af1e7518bf834720da8d5d07a88423b 100644 (file)
@@ -101,10 +101,10 @@ struct str_TimerMainHeader {
 };
 
 
-typedef struct {
+struct str_AnalogOutputHeader {
        unsigned short w_Nchannel;
        unsigned char b_Resolution;
-} str_AnalogOutputHeader;
+};
 
 struct str_AnalogInputHeader {
        unsigned short w_Nchannel;
@@ -136,7 +136,7 @@ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
 
 int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
        char *pc_PCIChipInformation, unsigned short w_Address,
-       str_AnalogOutputHeader *s_Header);
+       struct str_AnalogOutputHeader *s_Header);
 
 int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
        char *pc_PCIChipInformation, unsigned short w_Address,
@@ -635,7 +635,7 @@ void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromComman
 
 | Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
 
-|                    unsigned short    w_offset : Offset of the adress to read             |
+|                    unsigned short    w_offset : Offset of the address to read             |
 
 |                    unsigned short *   pw_Value : PCI eeprom 16 bit read value.            |
 
@@ -811,7 +811,7 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
        struct str_DigitalInputHeader s_DigitalInputHeader;
        struct str_DigitalOutputHeader s_DigitalOutputHeader;
        /* struct str_TimerMainHeader     s_TimerMainHeader,s_WatchdogMainHeader; */
-       str_AnalogOutputHeader s_AnalogOutputHeader;
+       struct str_AnalogOutputHeader s_AnalogOutputHeader;
        struct str_AnalogInputHeader s_AnalogInputHeader;
 
        /* Read size */
@@ -1081,7 +1081,7 @@ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
 
 int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
        char *pc_PCIChipInformation, unsigned short w_Address,
-       str_AnalogOutputHeader *s_Header)
+       struct str_AnalogOutputHeader *s_Header)
 {
        unsigned short w_Temp;
        /*  No of channels for 1st hard component */
index f93ddd4eb06c260c5b64ae991eed82f01e5c9cfe..851f71bbf1bff69ef1f8ec322ee8c76ca3aa03f5 100644 (file)
@@ -1090,13 +1090,13 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
  * and put into into an array array used may be for differnet pages
  */
 
-               /*  DMA Start Adress Low */
+               /*  DMA Start Address Low */
                outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
                outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF),
                        devpriv->i_IobaseAddon + 2);
 
                /*************************/
-               /* DMA Start Adress High */
+               /* DMA Start Address High */
                /*************************/
                outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
                outw((devpriv->ul_DmaBufferHw[0] / 65536),
@@ -1733,11 +1733,11 @@ void v_APCI3120_InterruptDma(int irq, void *d)
                var = devpriv->ul_DmaBufferHw[next_dma_buf];
                high_word = var / 65536;
 
-               /* DMA Start Adress Low */
+               /* DMA Start Address Low */
                outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
                outw(low_word, devpriv->i_IobaseAddon + 2);
 
-               /* DMA Start Adress High */
+               /* DMA Start Address High */
                outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
                outw(high_word, devpriv->i_IobaseAddon + 2);
 
index 6dfcbe803f2dcd18aeec42f93e7ea13861eb7fcd..4c00df4bc15311986714ef884fd629cf5eee8898 100644 (file)
@@ -5,3 +5,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_035"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 4722ec834f7bfd796b42da0c1a2883c4dc4b5993..7831ce33b02e2f632abeabe4e45cb6bb2a3ddcbf 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_1032"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index db3dafdcf691728bb46bb4a653ea51eb54be6d4d..bfd84f66d9c0b17728f6f448eb8f7ef2ac8c5cad 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_1500"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index f591baff6a0b192606dfc810d5574bb401162618..a12e2f42137035b3d6afd166e3797e64ef418a4c 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_1516"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 6f5c923ac22604750486fb291f64f8cfffb493a1..1b9d598fb6ca1bb5312c0d7f8a56d9ee90303f7b 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_1564"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 1d926add9e6d9606e57e70befcfa0188b1d6ccd6..d54218d59c58a349a23914388be192cc75da9dbb 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_16xx"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 7266e412f0a6373109db9b1835be9276d5d4aff8..fa50c7bb7ade2b77e0f7549f9e27f6c824ff7364 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_2016"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index f67da94119e8c5ff1c027d801b07f05eb834b43d..073a8a56dbe41abf2db606860b6d051b6c454dbb 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_2032"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index bc7f7d6535034902dd37d198b6828968c93e833d..adfbb5d410ef0e58054fe13c805b7f2a8ff174cc 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_2200"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index d86c4209cb90afd168f36e496b5aad875bcba445..00ac762965c12422ec12dadf6617914b41671032 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_3001"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 0b22cf10415d3c9a8cc5d8291deb81fbee2902d1..c35515845cf3ac338739b08b13f865722aa0d30e 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_3120"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index d8a01b154e3585372fdd3fc103cccb25ea32030a..dd2c1d3bc18be6dd2d168cd0daefb89b89937607 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_3501"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 942bc9e259a8bdf3f8df7546350618455eaa66eb..03161c88eac2ae5a6f7a53bdec3d8b2448770fd7 100644 (file)
@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME   "addi_apci_3xxx"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 712b9e0788b671b9dd58b38805175d8185b6ee85..073d0242c28e72835b2a62659bf6fa7f2382795b 100644 (file)
@@ -119,7 +119,43 @@ static struct comedi_driver driver_pci6208 = {
        .detach = pci6208_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(driver_pci6208, pci6208_pci_table);
+static int __devinit driver_pci6208_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_pci6208.driver_name);
+}
+
+static void __devexit driver_pci6208_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci6208_pci_driver = {
+       .id_table = pci6208_pci_table,
+       .probe = &driver_pci6208_pci_probe,
+       .remove = __devexit_p(&driver_pci6208_pci_remove)
+};
+
+static int __init driver_pci6208_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_pci6208);
+       if (retval < 0)
+               return retval;
+
+       driver_pci6208_pci_driver.name = (char *)driver_pci6208.driver_name;
+       return pci_register_driver(&driver_pci6208_pci_driver);
+}
+
+static void __exit driver_pci6208_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_pci6208_pci_driver);
+       comedi_driver_unregister(&driver_pci6208);
+}
+
+module_init(driver_pci6208_init_module);
+module_exit(driver_pci6208_cleanup_module);
 
 static int pci6208_find_device(struct comedi_device *dev, int bus, int slot);
 static int
@@ -315,12 +351,10 @@ static int pci6208_ao_rinsn(struct comedi_device *dev,
 
 static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
 {
-       struct pci_dev *pci_dev;
+       struct pci_dev *pci_dev = NULL;
        int i;
 
-       for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pci_dev != NULL;
-            pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+       for_each_pci_dev(pci_dev) {
                if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) {
                        for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) {
                                if (pci6208_boards[i].dev_id ==
@@ -408,3 +442,7 @@ pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 24a82eb9d15373ef89d35c45da7b3b108041c152..72a7258b5b9279c8eef9eed8f8d0e64aed742bc5 100644 (file)
@@ -90,7 +90,7 @@ static int adl_pci7230_do_insn_bits(struct comedi_device *dev,
 static int adl_pci7230_attach(struct comedi_device *dev,
        struct comedi_devconfig *it)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct comedi_subdevice *s;
        int bus, slot;
 
@@ -106,10 +106,7 @@ static int adl_pci7230_attach(struct comedi_device *dev,
        if (alloc_subdevices(dev, 2) < 0)
                return -ENOMEM;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-               pcidev != NULL;
-               pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
                        pcidev->device == PCI_DEVICE_ID_PCI7230) {
                        if (bus || slot) {
@@ -203,4 +200,46 @@ static int adl_pci7230_di_insn_bits(struct comedi_device *dev,
        return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci7230, adl_pci7230_pci_table);
+static int __devinit driver_adl_pci7230_pci_probe(struct pci_dev *dev,
+                                                 const struct pci_device_id
+                                                 *ent)
+{
+       return comedi_pci_auto_config(dev, driver_adl_pci7230.driver_name);
+}
+
+static void __devexit driver_adl_pci7230_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci7230_pci_driver = {
+       .id_table = adl_pci7230_pci_table,
+       .probe = &driver_adl_pci7230_pci_probe,
+       .remove = __devexit_p(&driver_adl_pci7230_pci_remove)
+};
+
+static int __init driver_adl_pci7230_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_adl_pci7230);
+       if (retval < 0)
+               return retval;
+
+       driver_adl_pci7230_pci_driver.name =
+           (char *)driver_adl_pci7230.driver_name;
+       return pci_register_driver(&driver_adl_pci7230_pci_driver);
+}
+
+static void __exit driver_adl_pci7230_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_adl_pci7230_pci_driver);
+       comedi_driver_unregister(&driver_adl_pci7230);
+}
+
+module_init(driver_adl_pci7230_init_module);
+module_exit(driver_adl_pci7230_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 8602865ae6b7a7885cd3cf2efab4f6aa063b6700..f28fe6bec050948985143f1d1a1720687cd27d20 100644 (file)
@@ -77,7 +77,7 @@ static struct comedi_driver driver_adl_pci7296 = {
 static int adl_pci7296_attach(struct comedi_device *dev,
                              struct comedi_devconfig *it)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct comedi_subdevice *s;
        int bus, slot;
        int ret;
@@ -94,10 +94,7 @@ static int adl_pci7296_attach(struct comedi_device *dev,
        if (alloc_subdevices(dev, 4) < 0)
                return -ENOMEM;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
                    pcidev->device == PCI_DEVICE_ID_PCI7296) {
                        if (bus || slot) {
@@ -177,4 +174,46 @@ static int adl_pci7296_detach(struct comedi_device *dev)
        return 0;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci7296, adl_pci7296_pci_table);
+static int __devinit driver_adl_pci7296_pci_probe(struct pci_dev *dev,
+                                                 const struct pci_device_id
+                                                 *ent)
+{
+       return comedi_pci_auto_config(dev, driver_adl_pci7296.driver_name);
+}
+
+static void __devexit driver_adl_pci7296_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci7296_pci_driver = {
+       .id_table = adl_pci7296_pci_table,
+       .probe = &driver_adl_pci7296_pci_probe,
+       .remove = __devexit_p(&driver_adl_pci7296_pci_remove)
+};
+
+static int __init driver_adl_pci7296_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_adl_pci7296);
+       if (retval < 0)
+               return retval;
+
+       driver_adl_pci7296_pci_driver.name =
+           (char *)driver_adl_pci7296.driver_name;
+       return pci_register_driver(&driver_adl_pci7296_pci_driver);
+}
+
+static void __exit driver_adl_pci7296_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_adl_pci7296_pci_driver);
+       comedi_driver_unregister(&driver_adl_pci7296);
+}
+
+module_init(driver_adl_pci7296_init_module);
+module_exit(driver_adl_pci7296_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index b5a9499e438c0e09ce99a46f8ef049d631b2a193..262da7b29b281bb86a44480b53a3fb0927cc5749 100644 (file)
@@ -86,7 +86,7 @@ static int adl_pci7432_do_insn_bits(struct comedi_device *dev,
 static int adl_pci7432_attach(struct comedi_device *dev,
                              struct comedi_devconfig *it)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct comedi_subdevice *s;
        int bus, slot;
 
@@ -102,10 +102,7 @@ static int adl_pci7432_attach(struct comedi_device *dev,
        if (alloc_subdevices(dev, 2) < 0)
                return -ENOMEM;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
                    pcidev->device == PCI_DEVICE_ID_PCI7432) {
                        if (bus || slot) {
@@ -210,4 +207,46 @@ static int adl_pci7432_di_insn_bits(struct comedi_device *dev,
        return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci7432, adl_pci7432_pci_table);
+static int __devinit driver_adl_pci7432_pci_probe(struct pci_dev *dev,
+                                                 const struct pci_device_id
+                                                 *ent)
+{
+       return comedi_pci_auto_config(dev, driver_adl_pci7432.driver_name);
+}
+
+static void __devexit driver_adl_pci7432_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci7432_pci_driver = {
+       .id_table = adl_pci7432_pci_table,
+       .probe = &driver_adl_pci7432_pci_probe,
+       .remove = __devexit_p(&driver_adl_pci7432_pci_remove)
+};
+
+static int __init driver_adl_pci7432_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_adl_pci7432);
+       if (retval < 0)
+               return retval;
+
+       driver_adl_pci7432_pci_driver.name =
+           (char *)driver_adl_pci7432.driver_name;
+       return pci_register_driver(&driver_adl_pci7432_pci_driver);
+}
+
+static void __exit driver_adl_pci7432_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_adl_pci7432_pci_driver);
+       comedi_driver_unregister(&driver_adl_pci7432);
+}
+
+module_init(driver_adl_pci7432_init_module);
+module_exit(driver_adl_pci7432_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index da256a1e0b4dae23fe771f15046512b4e54212b4..767a594935c713d512940e2ac2eaf6437ceb06d7 100644 (file)
@@ -125,7 +125,7 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
 static int adl_pci8164_attach(struct comedi_device *dev,
                              struct comedi_devconfig *it)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct comedi_subdevice *s;
        int bus, slot;
 
@@ -142,10 +142,7 @@ static int adl_pci8164_attach(struct comedi_device *dev,
        if (alloc_subdevices(dev, 4) < 0)
                return -ENOMEM;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
                    pcidev->device == PCI_DEVICE_ID_PCI8164) {
                        if (bus || slot) {
@@ -389,4 +386,46 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
        return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci8164, adl_pci8164_pci_table);
+static int __devinit driver_adl_pci8164_pci_probe(struct pci_dev *dev,
+                                                 const struct pci_device_id
+                                                 *ent)
+{
+       return comedi_pci_auto_config(dev, driver_adl_pci8164.driver_name);
+}
+
+static void __devexit driver_adl_pci8164_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci8164_pci_driver = {
+       .id_table = adl_pci8164_pci_table,
+       .probe = &driver_adl_pci8164_pci_probe,
+       .remove = __devexit_p(&driver_adl_pci8164_pci_remove)
+};
+
+static int __init driver_adl_pci8164_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_adl_pci8164);
+       if (retval < 0)
+               return retval;
+
+       driver_adl_pci8164_pci_driver.name =
+           (char *)driver_adl_pci8164.driver_name;
+       return pci_register_driver(&driver_adl_pci8164_pci_driver);
+}
+
+static void __exit driver_adl_pci8164_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_adl_pci8164_pci_driver);
+       comedi_driver_unregister(&driver_adl_pci8164);
+}
+
+module_init(driver_adl_pci8164_init_module);
+module_exit(driver_adl_pci8164_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 39d112b708e3711c6bf78b7ad966ceafcce810fb..b2a02b0f569ac5199e93fba20711243c6e548157 100644 (file)
@@ -38,8 +38,8 @@ Supports:
   - do_insn read/write
   - ai_do_cmd mode with the following sources:
 
-    - start_src                TRIG_NOW
-    - scan_begin_src           TRIG_FOLLOW     TRIG_TIMER      TRIG_EXT
+    - start_src                        TRIG_NOW
+    - scan_begin_src           TRIG_FOLLOW     TRIG_TIMER      TRIG_EXT
     - convert_src                              TRIG_TIMER      TRIG_EXT
     - scan_end_src             TRIG_COUNT
     - stop_src                 TRIG_COUNT      TRIG_NONE
@@ -68,8 +68,9 @@ CHANGELOG:
 TODO:
 
   - Really test implemented functionality.
-  - Add support for the PCI-9111DG with a probe routine to identify the card type
-    (perhaps with the help of the channel number readback of the A/D Data register).
+  - Add support for the PCI-9111DG with a probe routine to identify the card
+    type (perhaps with the help of the channel number readback of the A/D Data
+    register).
   - Add external multiplexer support.
 
 */
@@ -83,12 +84,12 @@ TODO:
 #include "comedi_pci.h"
 #include "comedi_fc.h"
 
-#define PCI9111_DRIVER_NAME    "adl_pci9111"
-#define PCI9111_HR_DEVICE_ID   0x9111
+#define PCI9111_DRIVER_NAME    "adl_pci9111"
+#define PCI9111_HR_DEVICE_ID   0x9111
 
 /*  TODO: Add other pci9111 board id */
 
-#define PCI9111_IO_RANGE       0x0100
+#define PCI9111_IO_RANGE       0x0100
 
 #define PCI9111_FIFO_HALF_SIZE 512
 
@@ -134,27 +135,29 @@ TODO:
 
 /* IO address map */
 
-#define PCI9111_REGISTER_AD_FIFO_VALUE                         0x00    /*  AD Data stored in FIFO */
-#define PCI9111_REGISTER_DA_OUTPUT                     0x00
-#define PCI9111_REGISTER_DIGITAL_IO                    0x02
-#define PCI9111_REGISTER_EXTENDED_IO_PORTS             0x04
-#define PCI9111_REGISTER_AD_CHANNEL_CONTROL            0x06    /*  Channel selection */
-#define PCI9111_REGISTER_AD_CHANNEL_READBACK           0x06
-#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE            0x08
-#define PCI9111_REGISTER_RANGE_STATUS_READBACK                 0x08
-#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL          0x0A
-#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK    0x0A
-#define PCI9111_REGISTER_SOFTWARE_TRIGGER              0x0E
-#define PCI9111_REGISTER_INTERRUPT_CONTROL             0x0C
+#define PCI9111_REGISTER_AD_FIFO_VALUE                 0x00 /* AD Data stored
+                                                               in FIFO */
+#define PCI9111_REGISTER_DA_OUTPUT                     0x00
+#define PCI9111_REGISTER_DIGITAL_IO                    0x02
+#define PCI9111_REGISTER_EXTENDED_IO_PORTS             0x04
+#define PCI9111_REGISTER_AD_CHANNEL_CONTROL            0x06 /* Channel
+                                                               selection */
+#define PCI9111_REGISTER_AD_CHANNEL_READBACK           0x06
+#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE            0x08
+#define PCI9111_REGISTER_RANGE_STATUS_READBACK         0x08
+#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL          0x0A
+#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK    0x0A
+#define PCI9111_REGISTER_SOFTWARE_TRIGGER              0x0E
+#define PCI9111_REGISTER_INTERRUPT_CONTROL             0x0C
 #define PCI9111_REGISTER_8254_COUNTER_0                        0x40
 #define PCI9111_REGISTER_8254_COUNTER_1                        0x42
-#define PCI9111_REGISTER_8254_COUNTER_2                0X44
+#define PCI9111_REGISTER_8254_COUNTER_2                        0X44
 #define PCI9111_REGISTER_8254_CONTROL                  0x46
-#define PCI9111_REGISTER_INTERRUPT_CLEAR               0x48
+#define PCI9111_REGISTER_INTERRUPT_CLEAR               0x48
 
-#define PCI9111_TRIGGER_MASK                           0x0F
-#define PCI9111_PTRG_OFF                               (0 << 3)
-#define PCI9111_PTRG_ON                                (1 << 3)
+#define PCI9111_TRIGGER_MASK                           0x0F
+#define PCI9111_PTRG_OFF                               (0 << 3)
+#define PCI9111_PTRG_ON                                        (1 << 3)
 #define PCI9111_EITS_EXTERNAL                          (1 << 2)
 #define PCI9111_EITS_INTERNAL                          (0 << 2)
 #define PCI9111_TPST_SOFTWARE_TRIGGER                  (0 << 1)
@@ -164,9 +167,9 @@ TODO:
 
 #define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0)
 #define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL         (1 << 0)
-#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK             (0 << 1)
-#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG                (1 << 1)
-#define PCI9111_FFEN_SET_FIFO_ENABLE                   (0 << 2)
+#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK             (0 << 1)
+#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG                        (1 << 1)
+#define PCI9111_FFEN_SET_FIFO_ENABLE                   (0 << 2)
 #define PCI9111_FFEN_SET_FIFO_DISABLE                  (1 << 2)
 
 #define PCI9111_CHANNEL_MASK                           0x0F
@@ -177,7 +180,7 @@ TODO:
 #define PCI9111_FIFO_FULL_MASK                         0x40
 #define PCI9111_AD_BUSY_MASK                           0x80
 
-#define PCI9111_IO_BASE dev->iobase
+#define PCI9111_IO_BASE (dev->iobase)
 
 /*
  * Define inlined function
@@ -189,8 +192,9 @@ TODO:
 #define pci9111_trigger_and_autoscan_set(flags) \
   outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
 
-#define pci9111_interrupt_and_fifo_get() \
-  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) &0x03)
+#define pci9111_interrupt_and_fifo_get()                                  \
+  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) \
+   &0x03)
 
 #define pci9111_interrupt_and_fifo_set(flags) \
   outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
@@ -201,45 +205,56 @@ TODO:
 #define pci9111_software_trigger() \
   outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
 
-#define pci9111_fifo_reset() \
-  outb(PCI9111_FFEN_SET_FIFO_ENABLE, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
-  outb(PCI9111_FFEN_SET_FIFO_DISABLE, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
-  outb(PCI9111_FFEN_SET_FIFO_ENABLE, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+#define pci9111_fifo_reset() do {                                      \
+  outb(PCI9111_FFEN_SET_FIFO_ENABLE,                                   \
+       PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL);            \
+  outb(PCI9111_FFEN_SET_FIFO_DISABLE,                                  \
+       PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL);            \
+  outb(PCI9111_FFEN_SET_FIFO_ENABLE,                                   \
+       PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL);            \
+  } while (0)
 
 #define pci9111_is_fifo_full() \
   ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
-    PCI9111_FIFO_FULL_MASK)==0)
+    PCI9111_FIFO_FULL_MASK) == 0)
 
 #define pci9111_is_fifo_half_full() \
   ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
-    PCI9111_FIFO_HALF_FULL_MASK)==0)
+    PCI9111_FIFO_HALF_FULL_MASK) == 0)
 
 #define pci9111_is_fifo_empty() \
   ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
-    PCI9111_FIFO_EMPTY_MASK)==0)
+    PCI9111_FIFO_EMPTY_MASK) == 0)
 
-#define pci9111_ai_channel_set(channel) \
-  outb((channel)&PCI9111_CHANNEL_MASK, PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
+#define pci9111_ai_channel_set(channel)                                        \
+  outb((channel)&PCI9111_CHANNEL_MASK,                                 \
+       PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
 
-#define pci9111_ai_channel_get() \
-  inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)&PCI9111_CHANNEL_MASK
+#define pci9111_ai_channel_get()                                       \
+  (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)           \
+   &PCI9111_CHANNEL_MASK)
 
-#define pci9111_ai_range_set(range) \
-  outb((range)&PCI9111_RANGE_MASK, PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
+#define pci9111_ai_range_set(range)                                    \
+  outb((range)&PCI9111_RANGE_MASK,                                     \
+       PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
 
-#define pci9111_ai_range_get() \
-  inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)&PCI9111_RANGE_MASK
+#define pci9111_ai_range_get()                                         \
+  (inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)         \
+   &PCI9111_RANGE_MASK)
 
-#define pci9111_ai_get_data() \
-  ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)&PCI9111_AI_RESOLUTION_MASK) \
-  ^ PCI9111_AI_RESOLUTION_2_CMP_BIT
+#define pci9111_ai_get_data()                                          \
+  (((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)           \
+    &PCI9111_AI_RESOLUTION_MASK)                                       \
+   ^ PCI9111_AI_RESOLUTION_2_CMP_BIT)
 
-#define pci9111_hr_ai_get_data() \
-  (inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \
-  ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT
+#define pci9111_hr_ai_get_data()                                       \
+  ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)                        \
+    & PCI9111_HR_AI_RESOLUTION_MASK)                                   \
+   ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT)
 
-#define pci9111_ao_set_data(data) \
-  outw(data&PCI9111_AO_RESOLUTION_MASK, PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
+#define pci9111_ao_set_data(data)                                      \
+  outw(data&PCI9111_AO_RESOLUTION_MASK,                                        \
+       PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
 
 #define pci9111_di_get_bits() \
   inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
@@ -284,12 +299,11 @@ static const struct comedi_lrange pci9111_hr_ai_range = {
 };
 
 static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
-       {
-       PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID,
-                   PCI_ANY_ID, 0, 0, 0},
-           /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
-       {
-       0}
+       { PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
+         0, 0, 0 },
+       /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
+        *   0, 0, 0 }, */
+       { 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
@@ -337,7 +351,43 @@ static struct comedi_driver pci9111_driver = {
        .detach = pci9111_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(pci9111_driver, pci9111_pci_table);
+static int __devinit pci9111_driver_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, pci9111_driver.driver_name);
+}
+
+static void __devexit pci9111_driver_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver pci9111_driver_pci_driver = {
+       .id_table = pci9111_pci_table,
+       .probe = &pci9111_driver_pci_probe,
+       .remove = __devexit_p(&pci9111_driver_pci_remove)
+};
+
+static int __init pci9111_driver_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&pci9111_driver);
+       if (retval < 0)
+               return retval;
+
+       pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name;
+       return pci_register_driver(&pci9111_driver_pci_driver);
+}
+
+static void __exit pci9111_driver_cleanup_module(void)
+{
+       pci_unregister_driver(&pci9111_driver_pci_driver);
+       comedi_driver_unregister(&pci9111_driver);
+}
+
+module_init(pci9111_driver_init_module);
+module_exit(pci9111_driver_cleanup_module);
 
 /*  Private data structure */
 
@@ -345,7 +395,8 @@ struct pci9111_private_data {
        struct pci_dev *pci_device;
        unsigned long io_range; /*  PCI6503 io range */
 
-       unsigned long lcr_io_base;      /*  Local configuration register base address */
+       unsigned long lcr_io_base; /* Local configuration register base
+                                   * address */
        unsigned long lcr_io_range;
 
        int stop_counter;
@@ -358,7 +409,8 @@ struct pci9111_private_data {
 
        int ao_readback;        /*  Last written analog output data */
 
-       unsigned int timer_divisor_1;   /*  Divisor values for the 8254 timer pacer */
+       unsigned int timer_divisor_1; /* Divisor values for the 8254 timer
+                                      * pacer */
        unsigned int timer_divisor_2;
 
        int is_valid;           /*  Is device valid */
@@ -366,7 +418,7 @@ struct pci9111_private_data {
        short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
 };
 
-#define dev_private    ((struct pci9111_private_data *)dev->private)
+#define dev_private    ((struct pci9111_private_data *)dev->private)
 
 /*  ------------------------------------------------------------------ */
 /*  PLX9050 SECTION */
@@ -548,10 +600,12 @@ static int pci9111_ai_cancel(struct comedi_device *dev,
 
 /*  Test analog input command */
 
-#define pci9111_check_trigger_src(src, flags) \
-  tmp = src; \
-  src &= flags; \
-  if (!src || tmp != src) error++
+#define pci9111_check_trigger_src(src, flags)  do {                    \
+               tmp = src;                                              \
+               src &= flags;                                           \
+               if (!src || tmp != src)                                 \
+                       error++;                                        \
+       } while (false);
 
 static int
 pci9111_ai_do_cmd_test(struct comedi_device *dev,
@@ -575,7 +629,8 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
        if (error)
                return 1;
 
-       /*  step 2 : make sure trigger sources are unique and mutually compatible */
+       /*  step 2 : make sure trigger sources are unique and mutually
+        *  compatible */
 
        if (cmd->start_src != TRIG_NOW)
                error++;
@@ -637,7 +692,8 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
                cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
                error++;
        }
-       if ((cmd->scan_begin_src == TRIG_FOLLOW) && (cmd->scan_begin_arg != 0)) {
+       if ((cmd->scan_begin_src == TRIG_FOLLOW)
+           && (cmd->scan_begin_arg != 0)) {
                cmd->scan_begin_arg = 0;
                error++;
        }
@@ -1216,7 +1272,7 @@ static int pci9111_attach(struct comedi_device *dev,
 {
        struct comedi_subdevice *subdevice;
        unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
-       struct pci_dev *pci_device;
+       struct pci_dev *pci_device = NULL;
        int error, i;
        const struct pci9111_board *board;
 
@@ -1226,17 +1282,17 @@ static int pci9111_attach(struct comedi_device *dev,
 
        printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor);
 
-       for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pci_device != NULL;
-            pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+       for_each_pci_dev(pci_device) {
                if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) {
                        for (i = 0; i < pci9111_board_nbr; i++) {
                                if (pci9111_boards[i].device_id ==
                                    pci_device->device) {
-                                       /*  was a particular bus/slot requested? */
+                                       /* was a particular bus/slot
+                                        * requested? */
                                        if ((it->options[0] != 0)
                                            || (it->options[1] != 0)) {
-                                               /*  are we on the wrong bus/slot? */
+                                               /* are we on the wrong
+                                                * bus/slot? */
                                                if (pci_device->bus->number !=
                                                    it->options[0]
                                                    ||
@@ -1272,7 +1328,8 @@ found:
 
        /*  TODO: Warn about non-tested boards. */
 
-       /*  Read local configuration register base address [PCI_BASE_ADDRESS #1]. */
+       /*  Read local configuration register base address
+        *  [PCI_BASE_ADDRESS #1]. */
 
        lcr_io_base = pci_resource_start(pci_device, 1);
        lcr_io_range = pci_resource_len(pci_device, 1);
@@ -1399,3 +1456,7 @@ static int pci9111_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index ccef549778e409c7eb3249f1e69cb7b7728c4d58..b0e39cb7477482418b46eec89030daeee59ca429 100644 (file)
@@ -289,7 +289,43 @@ static struct comedi_driver driver_pci9118 = {
        .offset = sizeof(struct boardtype),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
+static int __devinit driver_pci9118_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_pci9118.driver_name);
+}
+
+static void __devexit driver_pci9118_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci9118_pci_driver = {
+       .id_table = pci9118_pci_table,
+       .probe = &driver_pci9118_pci_probe,
+       .remove = __devexit_p(&driver_pci9118_pci_remove)
+};
+
+static int __init driver_pci9118_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_pci9118);
+       if (retval < 0)
+               return retval;
+
+       driver_pci9118_pci_driver.name = (char *)driver_pci9118.driver_name;
+       return pci_register_driver(&driver_pci9118_pci_driver);
+}
+
+static void __exit driver_pci9118_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_pci9118_pci_driver);
+       comedi_driver_unregister(&driver_pci9118);
+}
+
+module_init(driver_pci9118_init_module);
+module_exit(driver_pci9118_cleanup_module);
 
 struct pci9118_private {
        unsigned long iobase_a; /* base+size for AMCC chip */
@@ -2432,3 +2468,7 @@ static int pci9118_detach(struct comedi_device *dev)
 /*
 ==============================================================================
 */
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index f3ba645bf63b248a762f4b460bc5840088f594cc..4b470000b69c755eab0f03c2faa1fbd1d92e43fd 100644 (file)
@@ -402,4 +402,19 @@ static int adq12b_do_insn_bits(struct comedi_device *dev,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver_adq12b);
+static int __init driver_adq12b_init_module(void)
+{
+       return comedi_driver_register(&driver_adq12b);
+}
+
+static void __exit driver_adq12b_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_adq12b);
+}
+
+module_init(driver_adq12b_init_module);
+module_exit(driver_adq12b_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 67c4f11a36ab261eb045b26925e1fe131f0dbb64..bdd6954cad96f5b863d1cf22cf3a189aa43e120e 100644 (file)
@@ -19,7 +19,7 @@
 /*
 Driver: adv_pci1710
 Description: Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713,
-             Advantech PCI-1720, PCI-1731
+            Advantech PCI-1720, PCI-1731
 Author: Michal Dobes <dobes@tesnet.cz>
 Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG (pci1710hg),
   PCI-1711 (adv_pci1710), PCI-1713, PCI-1720,
@@ -37,8 +37,8 @@ PCI driver.
 Configuration options:
   [0] - PCI bus of device (optional)
   [1] - PCI slot of device (optional)
-          If bus/slot is not specified, the first available PCI
-          device will be used.
+       If bus/slot is not specified, the first available PCI
+       device will be used.
 */
 
 #include <linux/interrupt.h>
@@ -50,7 +50,9 @@ Configuration options:
 #include "8253.h"
 #include "amcc_s5933.h"
 
-#define PCI171x_PARANOIDCHECK  /* if defined, then is used code which control correct channel number on every 12 bit sample */
+#define PCI171x_PARANOIDCHECK  /* if defined, then is used code which control
+                                * correct channel number on every 12 bit
+                                * sample */
 
 #undef PCI171X_EXTDEBUG
 
@@ -70,8 +72,8 @@ Configuration options:
 #define TYPE_PCI1713   2
 #define TYPE_PCI1720   3
 
-#define IORANGE_171x   32
-#define IORANGE_1720   16
+#define IORANGE_171x   32
+#define IORANGE_1720   16
 
 #define PCI171x_AD_DATA         0      /* R:   A/D data */
 #define PCI171x_SOFTTRG         0      /* W:   soft trigger for A/D */
@@ -91,13 +93,15 @@ Configuration options:
 #define PCI171x_CNT2   28      /* R/W: 8254 counter 2 */
 #define PCI171x_CNTCTRL        30      /* W:   8254 counter control */
 
-/* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */
+/* upper bits from status register (PCI171x_STATUS) (lower is same with control
+ * reg) */
 #define        Status_FE       0x0100  /* 1=FIFO is empty */
 #define Status_FH      0x0200  /* 1=FIFO is half full */
 #define Status_FF      0x0400  /* 1=FIFO is full, fatal error */
 #define Status_IRQ     0x0800  /* 1=IRQ occured */
 /* bits from control register (PCI171x_CONTROL) */
-#define Control_CNT0   0x0040  /* 1=CNT0 have external source, 0=have internal 100kHz source */
+#define Control_CNT0   0x0040  /* 1=CNT0 have external source,
+                                * 0=have internal 100kHz source */
 #define Control_ONEFH  0x0020  /* 1=IRQ on FIFO is half full, 0=every sample */
 #define Control_IRQEN  0x0010  /* 1=enable IRQ */
 #define Control_GATE   0x0008  /* 1=enable external trigger GATE (8254?) */
@@ -112,7 +116,8 @@ Configuration options:
 #define Counter_RW0     0x0010 /* RW0/RW1 select read/write mode */
 #define Counter_RW1     0x0020
 #define Counter_SC0     0x0040 /* Select Counter. Only 00 or 11 may */
-#define Counter_SC1     0x0080 /* be used, 00 for CNT0, 11 for read-back command */
+#define Counter_SC1     0x0080 /* be used, 00 for CNT0,
+                                * 11 for read-back command */
 
 #define PCI1720_DA0     0      /* W:   D/A register 0 */
 #define PCI1720_DA1     2      /* W:   D/A register 1 */
@@ -138,8 +143,8 @@ static const struct comedi_lrange range_pci1710_3 = { 9, {
                                                          }
 };
 
-static const char range_codes_pci1710_3[] =
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };
+static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
+                                             0x10, 0x11, 0x12, 0x13 };
 
 static const struct comedi_lrange range_pci1710hg = { 12, {
                                                           BIP_RANGE(5),
@@ -157,10 +162,9 @@ static const struct comedi_lrange range_pci1710hg = { 12, {
                                                           }
 };
 
-static const char range_codes_pci1710hg[] =
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
-       0x13
-};
+static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
+                                             0x05, 0x06, 0x07, 0x10, 0x11,
+                                             0x12, 0x13 };
 
 static const struct comedi_lrange range_pci17x1 = { 5, {
                                                        BIP_RANGE(10),
@@ -301,7 +305,8 @@ struct pci1710_private {
        unsigned int ai_timer1; /*  timers */
        unsigned int ai_timer2;
        short ao_data[4];       /*  data output buffer */
-       unsigned int cnt0_write_wait;   /*  after a write, wait for update of the internal state */
+       unsigned int cnt0_write_wait;   /* after a write, wait for update of the
+                                        * internal state */
 };
 
 #define devpriv ((struct pci1710_private *)dev->private)
@@ -324,7 +329,9 @@ static int pci1710_reset(struct comedi_device *dev);
 static int pci171x_ai_cancel(struct comedi_device *dev,
                             struct comedi_subdevice *s);
 
-static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,     /*  used for gain list programming */
+/*  used for gain list programming */
+static const unsigned int muxonechan[] = {
+       0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
        0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
        0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
        0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
@@ -774,7 +781,8 @@ static void interrupt_pci1710_half_fifo(void *d)
        }
 
        if (!devpriv->neverending_ai)
-               if (devpriv->ai_act_scan >= devpriv->ai_scans) {        /* all data sampled */
+               if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data
+                                                                   sampled */
                        pci171x_ai_cancel(dev, s);
                        s->async->events |= COMEDI_CB_EOA;
                        comedi_event(dev, s);
@@ -1559,7 +1567,8 @@ static int pci1710_attach(struct comedi_device *dev,
                s->maxdata = 1;
                s->len_chanlist = this_board->n_dochan;
                s->range_table = &range_digital;
-               s->io_bits = (1 << this_board->n_dochan) - 1;   /* all bits output */
+               /* all bits output */
+               s->io_bits = (1 << this_board->n_dochan) - 1;
                s->state = 0;
                s->insn_bits = pci171x_insn_bits_do;
                subdev++;
@@ -1609,7 +1618,47 @@ static int pci1710_detach(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-COMEDI_PCI_INITCLEANUP(driver_pci1710, pci1710_pci_table);
+static int __devinit driver_pci1710_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_pci1710.driver_name);
+}
+
+static void __devexit driver_pci1710_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci1710_pci_driver = {
+       .id_table = pci1710_pci_table,
+       .probe = &driver_pci1710_pci_probe,
+       .remove = __devexit_p(&driver_pci1710_pci_remove)
+};
+
+static int __init driver_pci1710_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_pci1710);
+       if (retval < 0)
+               return retval;
+
+       driver_pci1710_pci_driver.name = (char *)driver_pci1710.driver_name;
+       return pci_register_driver(&driver_pci1710_pci_driver);
+}
+
+static void __exit driver_pci1710_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_pci1710_pci_driver);
+       comedi_driver_unregister(&driver_pci1710);
+}
+
+module_init(driver_pci1710_init_module);
+module_exit(driver_pci1710_cleanup_module);
 /*
 ==============================================================================
 */
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 9fe8fcc7f1d602e0018a10750df8559a8c4fdc6e..b133bb84c4fe4255bf8b93059674a169399c985d 100644 (file)
@@ -496,4 +496,44 @@ static int pci1723_detach(struct comedi_device *dev)
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_pci1723, pci1723_pci_table);
+static int __devinit driver_pci1723_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_pci1723.driver_name);
+}
+
+static void __devexit driver_pci1723_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci1723_pci_driver = {
+       .id_table = pci1723_pci_table,
+       .probe = &driver_pci1723_pci_probe,
+       .remove = __devexit_p(&driver_pci1723_pci_remove)
+};
+
+static int __init driver_pci1723_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_pci1723);
+       if (retval < 0)
+               return retval;
+
+       driver_pci1723_pci_driver.name = (char *)driver_pci1723.driver_name;
+       return pci_register_driver(&driver_pci1723_pci_driver);
+}
+
+static void __exit driver_pci1723_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_pci1723_pci_driver);
+       comedi_driver_unregister(&driver_pci1723);
+}
+
+module_init(driver_pci1723_init_module);
+module_exit(driver_pci1723_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index e424a0c7d34fdfbb4ca8a26fa42f1cc4e5f2b600..d018bb4e2890619000196343748585c25c755744 100644 (file)
@@ -8,8 +8,8 @@
 /*
 Driver: adv_pci_dio
 Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
-             PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
-             PCI-1754, PCI-1756, PCI-1762
+       PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
+       PCI-1754, PCI-1756, PCI-1762
 Author: Michal Dobes <dobes@tesnet.cz>
 Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
   PCI-1734, PCI-1735U, PCI-1736UP, PCI-1750,
@@ -24,8 +24,8 @@ This driver supports now only insn interface for DI/DO/DIO.
 Configuration options:
   [0] - PCI bus of device (optional)
   [1] - PCI slot of device (optional)
-          If bus/slot is not specified, the first available PCI
-          device will be used.
+       If bus/slot is not specified, the first available PCI
+       device will be used.
 
 */
 
@@ -67,9 +67,12 @@ enum hw_io_access {
 
 #define MAX_DI_SUBDEVS 2       /* max number of DI subdevices per card */
 #define MAX_DO_SUBDEVS 2       /* max number of DO subdevices per card */
-#define MAX_DIO_SUBDEVG        2       /* max number of DIO subdevices group per card */
-#define MAX_8254_SUBDEVS   1   /* max number of 8254 counter subdevs per card */
-                               /* (could be more than one 8254 per subdevice) */
+#define MAX_DIO_SUBDEVG        2       /* max number of DIO subdevices group per
+                                * card */
+#define MAX_8254_SUBDEVS   1   /* max number of 8254 counter subdevs per
+                                * card */
+                               /* (could be more than one 8254 per
+                                * subdevice) */
 
 #define SIZE_8254         4    /* 8254 IO space length */
 #define SIZE_8255         4    /* 8255 IO space length */
@@ -84,7 +87,8 @@ enum hw_io_access {
 #define PCI1730_DO        2    /* W:   Digital output 0-15 */
 #define PCI1733_IDI       0    /* R:   Isolated digital input  0-31 */
 #define        PCI1730_3_INT_EN        0x08    /* R/W: enable/disable interrupts */
-#define        PCI1730_3_INT_RF        0x0c    /* R/W: set falling/raising edge for interrupts */
+#define        PCI1730_3_INT_RF        0x0c    /* R/W: set falling/raising edge for
+                                        * interrupts */
 #define        PCI1730_3_INT_CLR       0x10    /* R/W: clear interrupts */
 #define PCI1734_IDO       0    /* W:   Isolated digital output 0-31 */
 #define PCI173x_BOARDID           4    /* R:   Board I/D switch for 1730/3/4 */
@@ -99,7 +103,8 @@ enum hw_io_access {
 #define PCI1736_IDI        0   /* R:   Isolated digital input  0-15 */
 #define PCI1736_IDO        0   /* W:   Isolated digital output 0-15 */
 #define PCI1736_3_INT_EN        0x08   /* R/W: enable/disable interrupts */
-#define PCI1736_3_INT_RF        0x0c   /* R/W: set falling/raising edge for interrupts */
+#define PCI1736_3_INT_RF        0x0c   /* R/W: set falling/raising edge for
+                                        * interrupts */
 #define PCI1736_3_INT_CLR       0x10   /* R/W: clear interrupts */
 #define PCI1736_BOARDID    4   /* R:   Board I/D switch for 1736UP */
 #define PCI1736_MAINREG    0   /* Normal register (2) doesn't work */
@@ -161,37 +166,66 @@ enum hw_io_access {
 #define INTCSR3                0x3b
 
 /*  PCI-1760 mailbox commands */
-#define CMD_ClearIMB2          0x00    /* Clear IMB2 status and return actaul DI status in IMB3 */
+#define CMD_ClearIMB2          0x00    /* Clear IMB2 status and return actual
+                                        * DI status in IMB3 */
 #define CMD_SetRelaysOutput    0x01    /* Set relay output from OMB0 */
 #define CMD_GetRelaysStatus    0x02    /* Get relay status to IMB0 */
-#define CMD_ReadCurrentStatus  0x07    /* Read the current status of the register in OMB0, result in IMB0 */
-#define CMD_ReadFirmwareVersion        0x0e    /* Read the firmware ver., result in IMB1.IMB0 */
-#define CMD_ReadHardwareVersion        0x0f    /* Read the hardware ver., result in IMB1.IMB0 */
-#define CMD_EnableIDIFilters   0x20    /* Enable IDI filters based on bits in OMB0 */
-#define CMD_EnableIDIPatternMatch 0x21 /* Enable IDI pattern match based on bits in OMB0 */
-#define CMD_SetIDIPatternMatch 0x22    /* Enable IDI pattern match based on bits in OMB0 */
-#define CMD_EnableIDICounters  0x28    /* Enable IDI counters based on bits in OMB0 */
-#define CMD_ResetIDICounters   0x29    /* Reset IDI counters based on bits in OMB0 to its reset values */
-#define CMD_OverflowIDICounters        0x2a    /* Enable IDI counters overflow interrupts  based on bits in OMB0 */
-#define CMD_MatchIntIDICounters        0x2b    /* Enable IDI counters match value interrupts  based on bits in OMB0 */
-#define CMD_EdgeIDICounters    0x2c    /* Set IDI up counters count edge (bit=0 - rising, =1 - falling) */
-#define CMD_GetIDICntCurValue  0x2f    /* Read IDI{OMB0} up counter current value */
-#define CMD_SetIDI0CntResetValue 0x40  /* Set IDI0 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntResetValue 0x41  /* Set IDI1 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntResetValue 0x42  /* Set IDI2 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntResetValue 0x43  /* Set IDI3 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntResetValue 0x44  /* Set IDI4 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntResetValue 0x45  /* Set IDI5 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntResetValue 0x46  /* Set IDI6 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntResetValue 0x47  /* Set IDI7 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI0CntMatchValue 0x48  /* Set IDI0 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntMatchValue 0x49  /* Set IDI1 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntMatchValue 0x4a  /* Set IDI2 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntMatchValue 0x4b  /* Set IDI3 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntMatchValue 0x4c  /* Set IDI4 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntMatchValue 0x4d  /* Set IDI5 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntMatchValue 0x4e  /* Set IDI6 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntMatchValue 0x4f  /* Set IDI7 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_ReadCurrentStatus  0x07    /* Read the current status of the
+                                        * register in OMB0, result in IMB0 */
+#define CMD_ReadFirmwareVersion        0x0e    /* Read the firmware ver., result in
+                                        * IMB1.IMB0 */
+#define CMD_ReadHardwareVersion        0x0f    /* Read the hardware ver., result in
+                                        * IMB1.IMB0 */
+#define CMD_EnableIDIFilters   0x20    /* Enable IDI filters based on bits in
+                                        * OMB0 */
+#define CMD_EnableIDIPatternMatch 0x21 /* Enable IDI pattern match based on
+                                        * bits in OMB0 */
+#define CMD_SetIDIPatternMatch 0x22    /* Enable IDI pattern match based on
+                                        * bits in OMB0 */
+#define CMD_EnableIDICounters  0x28    /* Enable IDI counters based on bits in
+                                        * OMB0 */
+#define CMD_ResetIDICounters   0x29    /* Reset IDI counters based on bits in
+                                        * OMB0 to its reset values */
+#define CMD_OverflowIDICounters        0x2a    /* Enable IDI counters overflow
+                                        * interrupts  based on bits in OMB0 */
+#define CMD_MatchIntIDICounters        0x2b    /* Enable IDI counters match value
+                                        * interrupts  based on bits in OMB0 */
+#define CMD_EdgeIDICounters    0x2c    /* Set IDI up counters count edge (bit=0
+                                        * - rising, =1 - falling) */
+#define CMD_GetIDICntCurValue  0x2f    /* Read IDI{OMB0} up counter current
+                                        * value */
+#define CMD_SetIDI0CntResetValue 0x40  /* Set IDI0 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntResetValue 0x41  /* Set IDI1 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntResetValue 0x42  /* Set IDI2 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntResetValue 0x43  /* Set IDI3 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntResetValue 0x44  /* Set IDI4 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntResetValue 0x45  /* Set IDI5 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntResetValue 0x46  /* Set IDI6 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntResetValue 0x47  /* Set IDI7 Counter Reset Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI0CntMatchValue 0x48  /* Set IDI0 Counter Match Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntMatchValue 0x49  /* Set IDI1 Counter Match Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntMatchValue 0x4a  /* Set IDI2 Counter Match Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntMatchValue 0x4b  /* Set IDI3 Counter Match Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntMatchValue 0x4c  /* Set IDI4 Counter Match Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntMatchValue 0x4d  /* Set IDI5 Counter Match Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntMatchValue 0x4e  /* Set IDI6 Counter Match Value
+                                        * 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntMatchValue 0x4f  /* Set IDI7 Counter Match Value
+                                        * 256*OMB1+OMB0 */
 
 #define OMBCMD_RETRY   0x03    /* 3 times try request before error */
 
@@ -244,115 +278,115 @@ MODULE_DEVICE_TABLE(pci, pci_dio_pci_table);
 static const struct dio_boardtype boardtypes[] = {
        {"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG,
         TYPE_PCI1730,
-        {{16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0}},
-        {{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0} },
+        { {16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
         TYPE_PCI1733,
-        {{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
         TYPE_PCI1734,
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1735", PCI_VENDOR_ID_ADVANTECH, 0x1735, PCIDIO_MAINREG,
         TYPE_PCI1735,
-        {{32, PCI1735_DI, 4, 0}, {0, 0, 0, 0}},
-        {{32, PCI1735_DO, 4, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {32, PCI1735_DI, 4, 0}, {0, 0, 0, 0} },
+        { {32, PCI1735_DO, 4, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         { 4, PCI1735_BOARDID, 1, SDF_INTERNAL},
-        {{3, PCI1735_C8254, 1, 0}},
+        { {3, PCI1735_C8254, 1, 0} },
         IO_8b},
        {"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
         TYPE_PCI1736,
-        {{0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0}},
-        {{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0} },
+        { {0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI1736_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
         TYPE_PCI1750,
-        {{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
-        {{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0} },
+        { {0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {0, 0, 0, 0},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
         TYPE_PCI1751,
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0} },
         {0, 0, 0, 0},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
         TYPE_PCI1752,
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_16b},
        {"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
         TYPE_PCI1753,
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0} },
         {0, 0, 0, 0},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
         TYPE_PCI1753E,
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0} },
         {0, 0, 0, 0},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
         TYPE_PCI1754,
-        {{32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_16b},
        {"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
         TYPE_PCI1756,
-        {{0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0}},
-        {{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0} },
+        { {0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_16b},
        {"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
         TYPE_PCI1760,
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},  /*  This card have own setup work */
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {0, 0, 0, 0} }, /* This card have own setup work */
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {0, 0, 0, 0},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_8b},
        {"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
         TYPE_PCI1762,
-        {{0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0}},
-        {{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
-        {{0, 0, 0, 0}, {0, 0, 0, 0}},
+        { {0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0} },
+        { {0, 0, 0, 0}, {16, PCI1762_RO, 1, 0} },
+        { {0, 0, 0, 0}, {0, 0, 0, 0} },
         {4, PCI1762_BOARDID, 1, SDF_INTERNAL},
-        {{0, 0, 0, 0}},
+        { {0, 0, 0, 0} },
         IO_16b}
 };
 
@@ -372,13 +406,16 @@ struct pci_dio_private {
        char valid;             /*  card is usable */
        char GlobalIrqEnabled;  /*  1= any IRQ source is enabled */
        /*  PCI-1760 specific data */
-       unsigned char IDICntEnable;     /*  counter's counting enable status */
-       unsigned char IDICntOverEnable; /*  counter's overflow interrupts enable status */
-       unsigned char IDICntMatchEnable;        /*  counter's match interrupts enable status */
-       unsigned char IDICntEdge;       /*  counter's count edge value (bit=0 - rising, =1 - falling) */
+       unsigned char IDICntEnable;     /* counter's counting enable status */
+       unsigned char IDICntOverEnable; /* counter's overflow interrupts enable
+                                        * status */
+       unsigned char IDICntMatchEnable;        /* counter's match interrupts
+                                                * enable status */
+       unsigned char IDICntEdge;       /* counter's count edge value
+                                        * (bit=0 - rising, =1 - falling) */
        unsigned short CntResValue[8];  /*  counters' reset value */
-       unsigned short CntMatchValue[8];        /*  counters' match interrupt value */
-       unsigned char IDIFiltersEn;     /*  IDI's digital filters enable status */
+       unsigned short CntMatchValue[8]; /*  counters' match interrupt value */
+       unsigned char IDIFiltersEn; /*  IDI's digital filters enable status */
        unsigned char IDIPatMatchEn;    /*  IDI's pattern match enable status */
        unsigned char IDIPatMatchValue; /*  IDI's pattern match value */
        unsigned short IDIFiltrLow[8];  /*  IDI's filter value low signal */
@@ -691,7 +728,8 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev,
        };
        unsigned char imb[4];
 
-       if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) { /*  Set reset value if different */
+       /* Set reset value if different */
+       if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) {
                ret = pci1760_mbxrequest(dev, omb, imb);
                if (!ret)
                        return ret;
@@ -704,7 +742,8 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev,
        if (!ret)
                return ret;
 
-       if (!(bitmask & devpriv->IDICntEnable)) {       /*  start counter if it don't run */
+       /*  start counter if it don't run */
+       if (!(bitmask & devpriv->IDICntEnable)) {
                omb[0] = bitmask;
                omb[2] = CMD_EnableIDICounters;
                ret = pci1760_mbxrequest(dev, omb, imb);
@@ -740,12 +779,14 @@ static int pci1760_reset(struct comedi_device *dev)
        devpriv->IDICntEnable = 0;
 
        omb[0] = 0x00;
-       omb[2] = CMD_OverflowIDICounters;       /*  disable counters overflow interrupts */
+       omb[2] = CMD_OverflowIDICounters; /* disable counters overflow
+                                          * interrupts */
        pci1760_mbxrequest(dev, omb, imb);
        devpriv->IDICntOverEnable = 0;
 
        omb[0] = 0x00;
-       omb[2] = CMD_MatchIntIDICounters;       /*  disable counters match value interrupts */
+       omb[2] = CMD_MatchIntIDICounters; /* disable counters match value
+                                          * interrupts */
        pci1760_mbxrequest(dev, omb, imb);
        devpriv->IDICntMatchEnable = 0;
 
@@ -766,7 +807,8 @@ static int pci1760_reset(struct comedi_device *dev)
        }
 
        omb[0] = 0xff;
-       omb[2] = CMD_ResetIDICounters;  /*  reset IDI up counters to reset values */
+       omb[2] = CMD_ResetIDICounters; /* reset IDI up counters to reset
+                                       * values */
        pci1760_mbxrequest(dev, omb, imb);
 
        omb[0] = 0x00;
@@ -807,9 +849,12 @@ static int pci_dio_reset(struct comedi_device *dev)
                outb(0, dev->iobase + PCI1730_IDO + 1);
                /* NO break there! */
        case TYPE_PCI1733:
-               outb(0, dev->iobase + PCI1730_3_INT_EN);        /*  disable interrupts */
-               outb(0x0f, dev->iobase + PCI1730_3_INT_CLR);    /*  clear interrupts */
-               outb(0, dev->iobase + PCI1730_3_INT_RF);        /*  set rising edge trigger */
+               /* disable interrupts */
+               outb(0, dev->iobase + PCI1730_3_INT_EN);
+               /* clear interrupts */
+               outb(0x0f, dev->iobase + PCI1730_3_INT_CLR);
+               /* set rising edge trigger */
+               outb(0, dev->iobase + PCI1730_3_INT_RF);
                break;
        case TYPE_PCI1734:
                outb(0, dev->iobase + PCI1734_IDO);     /*  clear outputs */
@@ -830,43 +875,53 @@ static int pci_dio_reset(struct comedi_device *dev)
        case TYPE_PCI1736:
                outb(0, dev->iobase + PCI1736_IDO);
                outb(0, dev->iobase + PCI1736_IDO + 1);
-               outb(0, dev->iobase + PCI1736_3_INT_EN);        /*  disable interrupts */
-               outb(0x0f, dev->iobase + PCI1736_3_INT_CLR);    /*  clear interrupts */
-               outb(0, dev->iobase + PCI1736_3_INT_RF);        /*  set rising edge trigger */
+               /* disable interrupts */
+               outb(0, dev->iobase + PCI1736_3_INT_EN);
+               /* clear interrupts */
+               outb(0x0f, dev->iobase + PCI1736_3_INT_CLR);
+               /* set rising edge trigger */
+               outb(0, dev->iobase + PCI1736_3_INT_RF);
                break;
 
        case TYPE_PCI1750:
        case TYPE_PCI1751:
-               outb(0x88, dev->iobase + PCI1750_ICR);  /*  disable & clear interrupts */
+               /* disable & clear interrupts */
+               outb(0x88, dev->iobase + PCI1750_ICR);
                break;
        case TYPE_PCI1752:
-               outw(0, dev->iobase + PCI1752_6_CFC);   /*  disable channel freeze function */
+               outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
+                                                      * function */
                outw(0, dev->iobase + PCI1752_IDO);     /*  clear outputs */
                outw(0, dev->iobase + PCI1752_IDO + 2);
                outw(0, dev->iobase + PCI1752_IDO2);
                outw(0, dev->iobase + PCI1752_IDO2 + 2);
                break;
        case TYPE_PCI1753E:
-               outb(0x88, dev->iobase + PCI1753E_ICR0);        /*  disable & clear interrupts */
+               outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear
+                                                         * interrupts */
                outb(0x80, dev->iobase + PCI1753E_ICR1);
                outb(0x80, dev->iobase + PCI1753E_ICR2);
                outb(0x80, dev->iobase + PCI1753E_ICR3);
                /* NO break there! */
        case TYPE_PCI1753:
-               outb(0x88, dev->iobase + PCI1753_ICR0); /*  disable & clear interrupts */
+               outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear
+                                                        * interrupts */
                outb(0x80, dev->iobase + PCI1753_ICR1);
                outb(0x80, dev->iobase + PCI1753_ICR2);
                outb(0x80, dev->iobase + PCI1753_ICR3);
                break;
        case TYPE_PCI1754:
-               outw(0x08, dev->iobase + PCI1754_6_ICR0);       /*  disable and clear interrupts */
+               outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
+                                                          * interrupts */
                outw(0x08, dev->iobase + PCI1754_6_ICR1);
                outw(0x08, dev->iobase + PCI1754_ICR2);
                outw(0x08, dev->iobase + PCI1754_ICR3);
                break;
        case TYPE_PCI1756:
-               outw(0, dev->iobase + PCI1752_6_CFC);   /*  disable channel freeze function */
-               outw(0x08, dev->iobase + PCI1754_6_ICR0);       /*  disable and clear interrupts */
+               outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
+                                                      * function */
+               outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
+                                                          * interrupts */
                outw(0x08, dev->iobase + PCI1754_6_ICR1);
                outw(0, dev->iobase + PCI1756_IDO);     /*  clear outputs */
                outw(0, dev->iobase + PCI1756_IDO + 2);
@@ -875,7 +930,8 @@ static int pci_dio_reset(struct comedi_device *dev)
                pci1760_reset(dev);
                break;
        case TYPE_PCI1762:
-               outw(0x0101, dev->iobase + PCI1762_ICR);        /*  disable & clear interrupts */
+               outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear
+                                                         * interrupts */
                break;
        }
 
@@ -996,7 +1052,7 @@ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
 ==============================================================================
 */
 static int pci_dio_add_8254(struct comedi_device *dev,
-                           struct comedi_subdevice * s,
+                           struct comedi_subdevice *s,
                            const struct diosubd_data *d, int subdev)
 {
        s->type = COMEDI_SUBD_COUNTER;
@@ -1023,7 +1079,7 @@ static int CheckAndAllocCard(struct comedi_device *dev,
 
        for (pr = pci_priv, prev = NULL; pr != NULL; prev = pr, pr = pr->next) {
                if (pr->pcidev == pcidev)
-                       return 0;       /*  this card is used, look for another */
+                       return 0; /* this card is used, look for another */
 
        }
 
@@ -1048,7 +1104,7 @@ static int pci_dio_attach(struct comedi_device *dev,
        struct comedi_subdevice *s;
        int ret, subdev, n_subdevices, i, j;
        unsigned long iobase;
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
 
        printk("comedi%d: adv_pci_dio: ", dev->minor);
 
@@ -1058,9 +1114,7 @@ static int pci_dio_attach(struct comedi_device *dev,
                return -ENOMEM;
        }
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                /*  loop through cards supported by this driver */
                for (i = 0; i < n_boardtypes; ++i) {
                        if (boardtypes[i].vendor_id != pcidev->vendor)
@@ -1215,15 +1269,12 @@ static int pci_dio_detach(struct comedi_device *dev)
                        }
                }
 
-               if (this_board->boardid.chans) {
+               if (this_board->boardid.chans)
                        subdev++;
-               }
 
-               for (i = 0; i < MAX_8254_SUBDEVS; i++) {
-                       if (this_board->s8254[i].chans) {
+               for (i = 0; i < MAX_8254_SUBDEVS; i++)
+                       if (this_board->s8254[i].chans)
                                subdev++;
-                       }
-               }
 
                for (i = 0; i < dev->n_subdevices; i++) {
                        s = dev->subdevices + i;
@@ -1253,7 +1304,47 @@ static int pci_dio_detach(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-COMEDI_PCI_INITCLEANUP(driver_pci_dio, pci_dio_pci_table);
+static int __devinit driver_pci_dio_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_pci_dio.driver_name);
+}
+
+static void __devexit driver_pci_dio_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci_dio_pci_driver = {
+       .id_table = pci_dio_pci_table,
+       .probe = &driver_pci_dio_pci_probe,
+       .remove = __devexit_p(&driver_pci_dio_pci_remove)
+};
+
+static int __init driver_pci_dio_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_pci_dio);
+       if (retval < 0)
+               return retval;
+
+       driver_pci_dio_pci_driver.name = (char *)driver_pci_dio.driver_name;
+       return pci_register_driver(&driver_pci_dio_pci_driver);
+}
+
+static void __exit driver_pci_dio_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_pci_dio_pci_driver);
+       comedi_driver_unregister(&driver_pci_dio);
+}
+
+module_init(driver_pci_dio_init_module);
+module_exit(driver_pci_dio_cleanup_module);
 /*
 ==============================================================================
 */
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 7a1c636df5be11720c765503f320a5e8f5c907c8..1728cc013d16ef602188814339b310a1b8024cb0 100644 (file)
@@ -227,4 +227,19 @@ static struct comedi_driver driver_aio_aio12_8 = {
        .offset = sizeof(struct aio12_8_boardtype),
 };
 
-COMEDI_INITCLEANUP(driver_aio_aio12_8);
+static int __init driver_aio_aio12_8_init_module(void)
+{
+       return comedi_driver_register(&driver_aio_aio12_8);
+}
+
+static void __exit driver_aio_aio12_8_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_aio_aio12_8);
+}
+
+module_init(driver_aio_aio12_8_init_module);
+module_exit(driver_aio_aio12_8_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 4baef9ff932a7111c788013663a58301b52e5828..487599531fed7d1f4cd9dd09fdb7d7bc82d15087 100644 (file)
@@ -184,4 +184,19 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
        return 2;
 }
 
-COMEDI_INITCLEANUP(driver_aio_iiro_16);
+static int __init driver_aio_iiro_16_init_module(void)
+{
+       return comedi_driver_register(&driver_aio_iiro_16);
+}
+
+static void __exit driver_aio_iiro_16_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_aio_iiro_16);
+}
+
+module_init(driver_aio_iiro_16_init_module);
+module_exit(driver_aio_iiro_16_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 73367d6afffe0c1d9ca754cf51bff1e5c79f3032..0bb839e514935c0821372f4e3816dc0b5b9d79f0 100644 (file)
 #ifdef Am9513_8BITBUS
 
 #define Am9513_write_register(reg, val)                                \
-       do                                                    \
+       do {                                                    \
                Am9513_output_control(reg);                     \
                Am9513_output_data(val>>8);                     \
                Am9513_output_data(val&0xff);                   \
-       }while (0)
+       } while (0)
 
 #define Am9513_read_register(reg, val)                         \
-       do                                                    \
+       do {                                                    \
                Am9513_output_control(reg);                     \
-               val=Am9513_input_data()<<8;                     \
-               val|=Am9513_input_data();                       \
-       }while (0)
+               val = Am9513_input_data()<<8;                   \
+               val |= Am9513_input_data();                     \
+       } while (0)
 
 #else /* Am9513_16BITBUS */
 
 #define Am9513_write_register(reg, val)                                \
-       do                                                    \
+       do {                                                    \
                Am9513_output_control(reg);                     \
                Am9513_output_data(val);                        \
-       }while (0)
+       } while (0)
 
 #define Am9513_read_register(reg, val)                         \
-       do                                                    \
+       do {                                                    \
                Am9513_output_control(reg);                     \
-               val=Am9513_input_data();                        \
-       }while (0)
+               val = Am9513_input_data();                      \
+       } while (0)
 
 #endif
 
index bf27617aa62d426e15cdb93b7436613633ff138e..93bbe4ec318da86e54a89ed72ed408e30c85e493 100644 (file)
@@ -494,9 +494,58 @@ static struct comedi_driver driver_amplc_dio200 = {
 };
 
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
+static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev,
+                                                  const struct pci_device_id
+                                                  *ent)
+{
+       return comedi_pci_auto_config(dev, driver_amplc_dio200.driver_name);
+}
+
+static void __devexit driver_amplc_dio200_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_dio200_pci_driver = {
+       .id_table = dio200_pci_table,
+       .probe = &driver_amplc_dio200_pci_probe,
+       .remove = __devexit_p(&driver_amplc_dio200_pci_remove)
+};
+
+static int __init driver_amplc_dio200_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_amplc_dio200);
+       if (retval < 0)
+               return retval;
+
+       driver_amplc_dio200_pci_driver.name =
+           (char *)driver_amplc_dio200.driver_name;
+       return pci_register_driver(&driver_amplc_dio200_pci_driver);
+}
+
+static void __exit driver_amplc_dio200_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_amplc_dio200_pci_driver);
+       comedi_driver_unregister(&driver_amplc_dio200);
+}
+
+module_init(driver_amplc_dio200_init_module);
+module_exit(driver_amplc_dio200_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_amplc_dio200);
+static int __init driver_amplc_dio200_init_module(void)
+{
+       return comedi_driver_register(&driver_amplc_dio200);
+}
+
+static void __exit driver_amplc_dio200_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_amplc_dio200);
+}
+
+module_init(driver_amplc_dio200_init_module);
+module_exit(driver_amplc_dio200_cleanup_module);
 #endif
 
 /*
@@ -1501,3 +1550,7 @@ static int dio200_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index a307d68d79c692e8a491f982d825ea4fc7cfb489..48246cd50d470fa499eca602b553e90c272158bc 100644 (file)
@@ -182,9 +182,58 @@ static struct comedi_driver driver_amplc_pc236 = {
 };
 
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_amplc_pc236, pc236_pci_table);
+static int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev,
+                                                 const struct pci_device_id
+                                                 *ent)
+{
+       return comedi_pci_auto_config(dev, driver_amplc_pc236.driver_name);
+}
+
+static void __devexit driver_amplc_pc236_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pc236_pci_driver = {
+       .id_table = pc236_pci_table,
+       .probe = &driver_amplc_pc236_pci_probe,
+       .remove = __devexit_p(&driver_amplc_pc236_pci_remove)
+};
+
+static int __init driver_amplc_pc236_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_amplc_pc236);
+       if (retval < 0)
+               return retval;
+
+       driver_amplc_pc236_pci_driver.name =
+           (char *)driver_amplc_pc236.driver_name;
+       return pci_register_driver(&driver_amplc_pc236_pci_driver);
+}
+
+static void __exit driver_amplc_pc236_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_amplc_pc236_pci_driver);
+       comedi_driver_unregister(&driver_amplc_pc236);
+}
+
+module_init(driver_amplc_pc236_init_module);
+module_exit(driver_amplc_pc236_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_amplc_pc236);
+static int __init driver_amplc_pc236_init_module(void)
+{
+       return comedi_driver_register(&driver_amplc_pc236);
+}
+
+static void __exit driver_amplc_pc236_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_amplc_pc236);
+}
+
+module_init(driver_amplc_pc236_init_module);
+module_exit(driver_amplc_pc236_cleanup_module);
 #endif
 
 static int pc236_request_region(unsigned minor, unsigned long from,
@@ -664,3 +713,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d)
        }
        return IRQ_RETVAL(handled);
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 15808e95ceabc0714dd5e0576950950e4170d23c..8a3388079094a6b4f9e5e5ae090ad7cca7810e86 100644 (file)
@@ -432,7 +432,60 @@ static int pc263_dio_insn_config(struct comedi_device *dev,
  * as necessary.
  */
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_amplc_pc263, pc263_pci_table);
+static int __devinit driver_amplc_pc263_pci_probe(struct pci_dev *dev,
+                                                 const struct pci_device_id
+                                                 *ent)
+{
+       return comedi_pci_auto_config(dev, driver_amplc_pc263.driver_name);
+}
+
+static void __devexit driver_amplc_pc263_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pc263_pci_driver = {
+       .id_table = pc263_pci_table,
+       .probe = &driver_amplc_pc263_pci_probe,
+       .remove = __devexit_p(&driver_amplc_pc263_pci_remove)
+};
+
+static int __init driver_amplc_pc263_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_amplc_pc263);
+       if (retval < 0)
+               return retval;
+
+       driver_amplc_pc263_pci_driver.name =
+           (char *)driver_amplc_pc263.driver_name;
+       return pci_register_driver(&driver_amplc_pc263_pci_driver);
+}
+
+static void __exit driver_amplc_pc263_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_amplc_pc263_pci_driver);
+       comedi_driver_unregister(&driver_amplc_pc263);
+}
+
+module_init(driver_amplc_pc263_init_module);
+module_exit(driver_amplc_pc263_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_amplc_pc263);
+static int __init driver_amplc_pc263_init_module(void)
+{
+       return comedi_driver_register(&driver_amplc_pc263);
+}
+
+static void __exit driver_amplc_pc263_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_amplc_pc263);
+}
+
+module_init(driver_amplc_pc263_init_module);
+module_exit(driver_amplc_pc263_cleanup_module);
 #endif
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index c486a878e180330e7058da08654cecf43d28cdd4..1b5ba1c2725929e3cd50c7692b9b6b50f1ecedbd 100644 (file)
@@ -443,7 +443,45 @@ static struct comedi_driver driver_amplc_pci224 = {
        .num_names = ARRAY_SIZE(pci224_boards),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_amplc_pci224, pci224_pci_table);
+static int __devinit driver_amplc_pci224_pci_probe(struct pci_dev *dev,
+                                                  const struct pci_device_id
+                                                  *ent)
+{
+       return comedi_pci_auto_config(dev, driver_amplc_pci224.driver_name);
+}
+
+static void __devexit driver_amplc_pci224_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pci224_pci_driver = {
+       .id_table = pci224_pci_table,
+       .probe = &driver_amplc_pci224_pci_probe,
+       .remove = __devexit_p(&driver_amplc_pci224_pci_remove)
+};
+
+static int __init driver_amplc_pci224_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_amplc_pci224);
+       if (retval < 0)
+               return retval;
+
+       driver_amplc_pci224_pci_driver.name =
+           (char *)driver_amplc_pci224.driver_name;
+       return pci_register_driver(&driver_amplc_pci224_pci_driver);
+}
+
+static void __exit driver_amplc_pci224_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_amplc_pci224_pci_driver);
+       comedi_driver_unregister(&driver_amplc_pci224);
+}
+
+module_init(driver_amplc_pci224_init_module);
+module_exit(driver_amplc_pci224_cleanup_module);
 
 /*
  * Called from the 'insn_write' function to perform a single write.
@@ -1557,3 +1595,7 @@ static int pci224_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 7fffd967d47e9b70e0bfd86304dd38adc3490311..5d064577b2f1872eedad442cd9a5f5e82281f58d 100644 (file)
@@ -617,7 +617,45 @@ static struct comedi_driver driver_amplc_pci230 = {
        .num_names = ARRAY_SIZE(pci230_boards),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_amplc_pci230, pci230_pci_table);
+static int __devinit driver_amplc_pci230_pci_probe(struct pci_dev *dev,
+                                                  const struct pci_device_id
+                                                  *ent)
+{
+       return comedi_pci_auto_config(dev, driver_amplc_pci230.driver_name);
+}
+
+static void __devexit driver_amplc_pci230_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pci230_pci_driver = {
+       .id_table = pci230_pci_table,
+       .probe = &driver_amplc_pci230_pci_probe,
+       .remove = __devexit_p(&driver_amplc_pci230_pci_remove)
+};
+
+static int __init driver_amplc_pci230_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_amplc_pci230);
+       if (retval < 0)
+               return retval;
+
+       driver_amplc_pci230_pci_driver.name =
+           (char *)driver_amplc_pci230.driver_name;
+       return pci_register_driver(&driver_amplc_pci230_pci_driver);
+}
+
+static void __exit driver_amplc_pci230_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_amplc_pci230_pci_driver);
+       comedi_driver_unregister(&driver_amplc_pci230);
+}
+
+module_init(driver_amplc_pci230_init_module);
+module_exit(driver_amplc_pci230_cleanup_module);
 
 static int pci230_ai_rinsn(struct comedi_device *dev,
                           struct comedi_subdevice *s, struct comedi_insn *insn,
@@ -726,7 +764,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        struct comedi_subdevice *s;
        unsigned long iobase1, iobase2;
        /* PCI230's I/O spaces 1 and 2 respectively. */
-       struct pci_dev *pci_dev;
+       struct pci_dev *pci_dev = NULL;
        int i = 0, irq_hdl, rc;
 
        printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor,
@@ -742,9 +780,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        spin_lock_init(&devpriv->ai_stop_spinlock);
        spin_lock_init(&devpriv->ao_stop_spinlock);
        /* Find card */
-       for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pci_dev != NULL;
-            pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+       for_each_pci_dev(pci_dev) {
                if (it->options[0] || it->options[1]) {
                        /* Match against bus/slot options. */
                        if (it->options[0] != pci_dev->bus->number ||
@@ -3014,3 +3050,7 @@ static int pci230_ai_cancel(struct comedi_device *dev,
        pci230_ai_stop(dev, s);
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index fb0d5fa71765e0c214528830565b3795d84b52ac..e0ac825ea58aa032e568ed024ef989e050cb4c92 100644 (file)
@@ -517,4 +517,19 @@ static int c6xdigio_detach(struct comedi_device *dev)
        return 0;
 }
 
-COMEDI_INITCLEANUP(driver_c6xdigio);
+static int __init driver_c6xdigio_init_module(void)
+{
+       return comedi_driver_register(&driver_c6xdigio);
+}
+
+static void __exit driver_c6xdigio_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_c6xdigio);
+}
+
+module_init(driver_c6xdigio_init_module);
+module_exit(driver_c6xdigio_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index cfeb11f443e340a322ad22759790540cab23e0fd..f8ede1182ccc5113b657a997b3df20460bf729fa 100644 (file)
@@ -37,7 +37,6 @@ Status: experimental
 #include <linux/delay.h>
 #include <linux/pci.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -171,7 +170,7 @@ static int das16cs_attach(struct comedi_device *dev,
        if (!link)
                return -EIO;
 
-       dev->iobase = link->io.BasePort1;
+       dev->iobase = link->resource[0]->start;;
        printk("I/O base=0x%04lx ", dev->iobase);
 
        printk("fingerprint:\n");
@@ -662,14 +661,6 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *);
    less on other parts of the kernel.
 */
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "cb_das16_cs";
-
 struct local_info_t {
        struct pcmcia_device *link;
        int stop;
@@ -719,8 +710,7 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
        ((struct local_info_t *)link->priv)->stop = 1;
        das16cs_pcmcia_release(link);
        /* This points to the parent struct local_info_t struct */
-       if (link->priv)
-               kfree(link->priv);
+       kfree(link->priv);
 }                              /* das16cs_pcmcia_detach */
 
 
@@ -737,24 +727,22 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
                /* This reserves IO space but doesn't actually enable it */
-               return pcmcia_request_io(p_dev, &p_dev->io);
+               return pcmcia_request_io(p_dev);
        }
 
        return 0;
@@ -788,12 +776,10 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
        dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                printk(", irq %u", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1 + link->io.NumPorts1 - 1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2 + link->io.NumPorts2 - 1);
+       if (link->resource[0])
+               printk(", io %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(", io %pR", link->resource[1]);
        printk("\n");
 
        return;
@@ -847,7 +833,7 @@ struct pcmcia_driver das16cs_driver = {
        .id_table = das16cs_id_table,
        .owner = THIS_MODULE,
        .drv = {
-               .name = dev_info,
+               .name = "cb_das16_cs",
                },
 };
 
@@ -881,5 +867,16 @@ void __exit cleanup_module(void)
 }
 
 #else
-COMEDI_INITCLEANUP(driver_das16cs);
+static int __init driver_das16cs_init_module(void)
+{
+       return comedi_driver_register(&driver_das16cs);
+}
+
+static void __exit driver_das16cs_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_das16cs);
+}
+
+module_init(driver_das16cs_init_module);
+module_exit(driver_das16cs_cleanup_module);
 #endif /* CONFIG_PCMCIA */
index 434591de37c535d75f0a4693574bb04f0587d8d2..6530b6c9d98b98b0fdd14210ba90637c5b9cfb15 100644 (file)
@@ -533,7 +533,7 @@ static int cb_pcidas_attach(struct comedi_device *dev,
                            struct comedi_devconfig *it)
 {
        struct comedi_subdevice *s;
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        int index;
        int i;
 
@@ -550,9 +550,7 @@ static int cb_pcidas_attach(struct comedi_device *dev,
  */
        printk("\n");
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                /*  is it not a computer boards card? */
                if (pcidev->vendor != PCI_VENDOR_ID_CB)
                        continue;
@@ -1871,4 +1869,44 @@ static int nvram_read(struct comedi_device *dev, unsigned int address,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table);
+static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev,
+                                               const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name);
+}
+
+static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidas_pci_driver = {
+       .id_table = cb_pcidas_pci_table,
+       .probe = &driver_cb_pcidas_pci_probe,
+       .remove = __devexit_p(&driver_cb_pcidas_pci_remove)
+};
+
+static int __init driver_cb_pcidas_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_cb_pcidas);
+       if (retval < 0)
+               return retval;
+
+       driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name;
+       return pci_register_driver(&driver_cb_pcidas_pci_driver);
+}
+
+static void __exit driver_cb_pcidas_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_cb_pcidas_pci_driver);
+       comedi_driver_unregister(&driver_cb_pcidas);
+}
+
+module_init(driver_cb_pcidas_init_module);
+module_exit(driver_cb_pcidas_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 79aa286e9bb4a796d19d31f715c19e36b85f5c4b..53e7015869fc1332d355214fe2663ab80618169b 100644 (file)
@@ -1237,7 +1237,43 @@ static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags);
 static void load_ao_dma(struct comedi_device *dev,
                        const struct comedi_cmd *cmd);
 
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, pcidas64_pci_table);
+static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev,
+                                               const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name);
+}
+
+static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidas_pci_driver = {
+       .id_table = pcidas64_pci_table,
+       .probe = &driver_cb_pcidas_pci_probe,
+       .remove = __devexit_p(&driver_cb_pcidas_pci_remove)
+};
+
+static int __init driver_cb_pcidas_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_cb_pcidas);
+       if (retval < 0)
+               return retval;
+
+       driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name;
+       return pci_register_driver(&driver_cb_pcidas_pci_driver);
+}
+
+static void __exit driver_cb_pcidas_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_cb_pcidas_pci_driver);
+       comedi_driver_unregister(&driver_cb_pcidas);
+}
+
+module_init(driver_cb_pcidas_init_module);
+module_exit(driver_cb_pcidas_cleanup_module);
 
 static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
                                       unsigned int range_index)
@@ -1718,7 +1754,7 @@ static inline void warn_external_queue(struct comedi_device *dev)
  */
 static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        int index;
        uint32_t local_range, local_decode;
        int retval;
@@ -1735,9 +1771,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
  * Probe the device to determine what device in the series it is.
  */
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                /*  is it not a computer boards card? */
                if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
                        continue;
@@ -4303,3 +4337,7 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
        }
        i2c_stop(dev);
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index c374bee250687597a8c196e8a8823b44f2ea3aaa..2d35143b8e525b5c7d6e19e624e76ce9dee28772 100644 (file)
@@ -280,7 +280,7 @@ static int cb_pcidda_attach(struct comedi_device *dev,
                            struct comedi_devconfig *it)
 {
        struct comedi_subdevice *s;
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        int index;
 
        printk("comedi%d: cb_pcidda: ", dev->minor);
@@ -296,9 +296,7 @@ static int cb_pcidda_attach(struct comedi_device *dev,
  */
        printk("\n");
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == PCI_VENDOR_ID_CB) {
                        if (it->options[0] || it->options[1]) {
                                if (pcidev->bus->number != it->options[0] ||
@@ -856,4 +854,44 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidda, cb_pcidda_pci_table);
+static int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev,
+                                               const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name);
+}
+
+static void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidda_pci_driver = {
+       .id_table = cb_pcidda_pci_table,
+       .probe = &driver_cb_pcidda_pci_probe,
+       .remove = __devexit_p(&driver_cb_pcidda_pci_remove)
+};
+
+static int __init driver_cb_pcidda_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_cb_pcidda);
+       if (retval < 0)
+               return retval;
+
+       driver_cb_pcidda_pci_driver.name = (char *)driver_cb_pcidda.driver_name;
+       return pci_register_driver(&driver_cb_pcidda_pci_driver);
+}
+
+static void __exit driver_cb_pcidda_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_cb_pcidda_pci_driver);
+       comedi_driver_unregister(&driver_cb_pcidda);
+}
+
+module_init(driver_cb_pcidda_init_module);
+module_exit(driver_cb_pcidda_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 38ccd105fa350a307331376abeb71d29a34afe61..c1693c91a6d08d84f4558a236d4f14d36a499a02 100644 (file)
@@ -202,9 +202,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
  * Probe the device to determine what device in the series it is.
  */
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                /*  is it not a computer boards card? */
                if (pcidev->vendor != PCI_VENDOR_ID_CB)
                        continue;
@@ -300,4 +298,44 @@ static int pcidio_detach(struct comedi_device *dev)
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidio, pcidio_pci_table);
+static int __devinit driver_cb_pcidio_pci_probe(struct pci_dev *dev,
+                                               const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_cb_pcidio.driver_name);
+}
+
+static void __devexit driver_cb_pcidio_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidio_pci_driver = {
+       .id_table = pcidio_pci_table,
+       .probe = &driver_cb_pcidio_pci_probe,
+       .remove = __devexit_p(&driver_cb_pcidio_pci_remove)
+};
+
+static int __init driver_cb_pcidio_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_cb_pcidio);
+       if (retval < 0)
+               return retval;
+
+       driver_cb_pcidio_pci_driver.name = (char *)driver_cb_pcidio.driver_name;
+       return pci_register_driver(&driver_cb_pcidio_pci_driver);
+}
+
+static void __exit driver_cb_pcidio_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_cb_pcidio_pci_driver);
+       comedi_driver_unregister(&driver_cb_pcidio);
+}
+
+module_init(driver_cb_pcidio_init_module);
+module_exit(driver_cb_pcidio_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 49dccbbd713fd67e362feb5c8a871111597ee3c7..ced346a7cae36550bc93311e7cf4e62142233078 100644 (file)
@@ -210,7 +210,7 @@ static int cb_pcimdas_attach(struct comedi_device *dev,
                             struct comedi_devconfig *it)
 {
        struct comedi_subdevice *s;
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        int index;
        /* int i; */
 
@@ -227,9 +227,7 @@ static int cb_pcimdas_attach(struct comedi_device *dev,
  */
        printk("\n");
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                /*  is it not a computer boards card? */
                if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
                        continue;
@@ -491,4 +489,46 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcimdas, cb_pcimdas_pci_table);
+static int __devinit driver_cb_pcimdas_pci_probe(struct pci_dev *dev,
+                                                const struct pci_device_id
+                                                *ent)
+{
+       return comedi_pci_auto_config(dev, driver_cb_pcimdas.driver_name);
+}
+
+static void __devexit driver_cb_pcimdas_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcimdas_pci_driver = {
+       .id_table = cb_pcimdas_pci_table,
+       .probe = &driver_cb_pcimdas_pci_probe,
+       .remove = __devexit_p(&driver_cb_pcimdas_pci_remove)
+};
+
+static int __init driver_cb_pcimdas_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_cb_pcimdas);
+       if (retval < 0)
+               return retval;
+
+       driver_cb_pcimdas_pci_driver.name =
+           (char *)driver_cb_pcimdas.driver_name;
+       return pci_register_driver(&driver_cb_pcimdas_pci_driver);
+}
+
+static void __exit driver_cb_pcimdas_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_cb_pcimdas_pci_driver);
+       comedi_driver_unregister(&driver_cb_pcimdas);
+}
+
+module_init(driver_cb_pcimdas_init_module);
+module_exit(driver_cb_pcimdas_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index f404ec7723e52cb1c3a8481e730c58ad0b8af6db..8c981a89ab63cad9f459c0937c8a9e65ec4d8a2f 100644 (file)
@@ -195,7 +195,45 @@ MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA "
                   "series.  Currently only supports PCIM-DDA06-16 (which "
                   "also happens to be the only board in this series. :) ) ");
 MODULE_LICENSE("GPL");
-COMEDI_PCI_INITCLEANUP_NOMODULE(cb_pcimdda_driver, pci_table);
+static int __devinit cb_pcimdda_driver_pci_probe(struct pci_dev *dev,
+                                                const struct pci_device_id
+                                                *ent)
+{
+       return comedi_pci_auto_config(dev, cb_pcimdda_driver.driver_name);
+}
+
+static void __devexit cb_pcimdda_driver_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver cb_pcimdda_driver_pci_driver = {
+       .id_table = pci_table,
+       .probe = &cb_pcimdda_driver_pci_probe,
+       .remove = __devexit_p(&cb_pcimdda_driver_pci_remove)
+};
+
+static int __init cb_pcimdda_driver_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&cb_pcimdda_driver);
+       if (retval < 0)
+               return retval;
+
+       cb_pcimdda_driver_pci_driver.name =
+           (char *)cb_pcimdda_driver.driver_name;
+       return pci_register_driver(&cb_pcimdda_driver_pci_driver);
+}
+
+static void __exit cb_pcimdda_driver_cleanup_module(void)
+{
+       pci_unregister_driver(&cb_pcimdda_driver_pci_driver);
+       comedi_driver_unregister(&cb_pcimdda_driver);
+}
+
+module_init(cb_pcimdda_driver_init_module);
+module_exit(cb_pcimdda_driver_cleanup_module);
 
 static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
                    struct comedi_insn *insn, unsigned int *data);
@@ -426,13 +464,11 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  */
 static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        int index;
        unsigned long registers;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                /*  is it not a computer boards card? */
                if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
                        continue;
index 701622280ff475d1e13c409d54e45b3f13ddc970..cfcbd9b8f39376bc9de300a86104c198db2a4d2c 100644 (file)
@@ -50,43 +50,6 @@ Configuration Options:
   within each minor will be concatenated together in the order given here.
 */
 
-/*
- * The previous block comment is used to automatically generate
- * documentation in Comedi and Comedilib.  The fields:
- *
- * Driver: the name of the driver
- * Description: a short phrase describing the driver.  Don't list boards.
- * Devices: a full list of the boards that attempt to be supported by
- *   the driver.  Format is "(manufacturer) board name [comedi name]",
- *   where comedi_name is the name that is used to configure the board.
- *   See the comment near board_name: in the struct comedi_driver structure
- *   below.  If (manufacturer) or [comedi name] is missing, the previous
- *   value is used.
- * Author: you
- * Updated: date when the _documentation_ was last updated.  Use 'date -R'
- *   to get a value for this.
- * Status: a one-word description of the status.  Valid values are:
- *   works - driver works correctly on most boards supported, and
- *     passes comedi_test.
- *   unknown - unknown.  Usually put there by ds.
- *   experimental - may not work in any particular release.  Author
- *     probably wants assistance testing it.
- *   bitrotten - driver has not been update in a long time, probably
- *     doesn't work, and probably is missing support for significant
- *     Comedi interface features.
- *   untested - author probably wrote it "blind", and is believed to
- *     work, but no confirmation.
- *
- * These headers should be followed by a blank line, and any comments
- * you wish to say about the driver.  The comment area is the place
- * to put any known bugs, limitations, unsupported features, supported
- * command triggers, whether or not commands are supported on particular
- * subdevices, etc.
- *
- * Somewhere in the comment should be information about configuration
- * options that are used with comedi_config.
- */
-
 #include <linux/string.h>
 #include <linux/slab.h>
 #include "../comedi.h"
index fcd7721c553769e6b434c3dfaf008d60a341c240..21d834dd92b6408a948f5f419f3c3823539ce088 100644 (file)
@@ -101,7 +101,18 @@ static struct comedi_driver driver_parport = {
        .detach = parport_detach,
 };
 
-COMEDI_INITCLEANUP(driver_parport);
+static int __init driver_parport_init_module(void)
+{
+       return comedi_driver_register(&driver_parport);
+}
+
+static void __exit driver_parport_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_parport);
+}
+
+module_init(driver_parport_init_module);
+module_exit(driver_parport_cleanup_module);
 
 struct parport_private {
        unsigned int a_data;
@@ -396,3 +407,7 @@ static int parport_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index ef83a1a445bad3edbcb1dd5789860a31fbe67592..b220b30554120028c6e4f4500061e9ca9e7e618a 100644 (file)
@@ -107,7 +107,18 @@ static struct comedi_driver driver_waveform = {
        .num_names = ARRAY_SIZE(waveform_boards),
 };
 
-COMEDI_INITCLEANUP(driver_waveform);
+static int __init driver_waveform_init_module(void)
+{
+       return comedi_driver_register(&driver_waveform);
+}
+
+static void __exit driver_waveform_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_waveform);
+}
+
+module_init(driver_waveform_init_module);
+module_exit(driver_waveform_cleanup_module);
 
 static int waveform_ai_cmdtest(struct comedi_device *dev,
                               struct comedi_subdevice *s,
@@ -549,3 +560,7 @@ static int waveform_ao_insn_write(struct comedi_device *dev,
 
        return insn->n;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 9511814e6413a01b284aa20f64fca6247a032c98..871f109bcfa31093e12a555b432eb0064647935c 100644 (file)
@@ -103,7 +103,7 @@ static int contec_ns_to_timer(unsigned int *ns, int round);
 
 static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct comedi_subdevice *s;
 
        printk("comedi%d: contec: ", dev->minor);
@@ -116,10 +116,7 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        if (alloc_subdevices(dev, 2) < 0)
                return -ENOMEM;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == PCI_VENDOR_ID_CONTEC &&
                    pcidev->device == PCI_DEVICE_ID_PIO1616L) {
                        if (it->options[0] || it->options[1]) {
@@ -232,4 +229,44 @@ static int contec_di_insn_bits(struct comedi_device *dev,
        return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_contec, contec_pci_table);
+static int __devinit driver_contec_pci_probe(struct pci_dev *dev,
+                                            const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_contec.driver_name);
+}
+
+static void __devexit driver_contec_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_contec_pci_driver = {
+       .id_table = contec_pci_table,
+       .probe = &driver_contec_pci_probe,
+       .remove = __devexit_p(&driver_contec_pci_remove)
+};
+
+static int __init driver_contec_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_contec);
+       if (retval < 0)
+               return retval;
+
+       driver_contec_pci_driver.name = (char *)driver_contec.driver_name;
+       return pci_register_driver(&driver_contec_pci_driver);
+}
+
+static void __exit driver_contec_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_contec_pci_driver);
+       comedi_driver_unregister(&driver_contec);
+}
+
+module_init(driver_contec_init_module);
+module_exit(driver_contec_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 078ec273b277006761b1d5e8d1fe25e23f72cd01..6af6c8323d56642c2a441a31906ad4eed68b1762 100644 (file)
@@ -887,4 +887,46 @@ static int daqboard2000_detach(struct comedi_device *dev)
        return 0;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_daqboard2000, daqboard2000_pci_table);
+static int __devinit driver_daqboard2000_pci_probe(struct pci_dev *dev,
+                                                  const struct pci_device_id
+                                                  *ent)
+{
+       return comedi_pci_auto_config(dev, driver_daqboard2000.driver_name);
+}
+
+static void __devexit driver_daqboard2000_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_daqboard2000_pci_driver = {
+       .id_table = daqboard2000_pci_table,
+       .probe = &driver_daqboard2000_pci_probe,
+       .remove = __devexit_p(&driver_daqboard2000_pci_remove)
+};
+
+static int __init driver_daqboard2000_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_daqboard2000);
+       if (retval < 0)
+               return retval;
+
+       driver_daqboard2000_pci_driver.name =
+           (char *)driver_daqboard2000.driver_name;
+       return pci_register_driver(&driver_daqboard2000_pci_driver);
+}
+
+static void __exit driver_daqboard2000_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_daqboard2000_pci_driver);
+       comedi_driver_unregister(&driver_daqboard2000);
+}
+
+module_init(driver_daqboard2000_init_module);
+module_exit(driver_daqboard2000_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 9cb144f7e70c29f6b7af2bdd9e54463322f17063..3141dc80fe743d4ec5e916581d4a74f471447b34 100644 (file)
  * Description: DAS-08 compatible boards
  * Author: Warren Jasper, ds, Frank Hess
  * Devices: [Keithley Metrabyte] DAS08 (isa-das08),
- * [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm),
- * DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
- * DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
- * DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08),
- * PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16)
+ *   [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm),
+ *   DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
+ *   DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
+ *   DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08),
+ *   PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16)
  * Status: works
  *
  * This is a rewrite of the das08 and das08jr drivers.
@@ -980,7 +980,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        unsigned long iobase;
 #ifdef CONFIG_COMEDI_PCI
        unsigned long pci_iobase = 0;
-       struct pci_dev *pdev;
+       struct pci_dev *pdev = NULL;
 #endif
 
        ret = alloc_private(dev, sizeof(struct das08_private_struct));
@@ -997,9 +997,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                }
                printk("\n");
                /*  find card */
-               for (pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-                    pdev != NULL;
-                    pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
+               for_each_pci_dev(pdev) {
                        if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS
                            && pdev->device == PCI_DEVICE_ID_PCIDAS08) {
                                if (it->options[0] || it->options[1]) {
@@ -1082,11 +1080,62 @@ int das08_common_detach(struct comedi_device *dev)
 EXPORT_SYMBOL_GPL(das08_common_detach);
 
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_das08, das08_pci_table);
+static int __devinit driver_das08_pci_probe(struct pci_dev *dev,
+                                           const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_das08.driver_name);
+}
+
+static void __devexit driver_das08_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_das08_pci_driver = {
+       .id_table = das08_pci_table,
+       .probe = &driver_das08_pci_probe,
+       .remove = __devexit_p(&driver_das08_pci_remove)
+};
+
+static int __init driver_das08_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_das08);
+       if (retval < 0)
+               return retval;
+
+       driver_das08_pci_driver.name = (char *)driver_das08.driver_name;
+       return pci_register_driver(&driver_das08_pci_driver);
+}
+
+static void __exit driver_das08_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_das08_pci_driver);
+       comedi_driver_unregister(&driver_das08);
+}
+
+module_init(driver_das08_init_module);
+module_exit(driver_das08_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_das08);
+static int __init driver_das08_init_module(void)
+{
+       return comedi_driver_register(&driver_das08);
+}
+
+static void __exit driver_das08_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_das08);
+}
+
+module_init(driver_das08_init_module);
+module_exit(driver_das08_cleanup_module);
 #endif
 
 #ifdef CONFIG_COMEDI_PCMCIA
 EXPORT_SYMBOL_GPL(das08_cs_boards);
 #endif
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 8761a6d285dc0ff8f618b0afefc99461371cce1a..c6aa52f8dcee3c5f97ea3df1a3f9374cf9a04f04 100644 (file)
@@ -48,7 +48,6 @@ Command support does not exist, but could be added for this board.
 #include "das08.h"
 
 /* pcmcia includes */
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -89,7 +88,7 @@ static int das08_cs_attach(struct comedi_device *dev,
                        printk(" no pcmcia cards found\n");
                        return -EIO;
                }
-               iobase = link->io.BasePort1;
+               iobase = link->resource[0]->start;
        } else {
                printk(" bug! board does not have PCMCIA bustype\n");
                return -EINVAL;
@@ -132,14 +131,6 @@ static void das08_pcmcia_detach(struct pcmcia_device *);
    less on other parts of the kernel.
 */
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static const dev_info_t dev_info = "pcm-das08";
-
 struct local_info_t {
        struct pcmcia_device *link;
        int stop;
@@ -206,8 +197,7 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
        das08_pcmcia_release(link);
 
        /* This points to the parent struct local_info_t struct */
-       if (link->priv)
-               kfree(link->priv);
+       kfree(link->priv);
 
 }                              /* das08_pcmcia_detach */
 
@@ -225,24 +215,23 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
                p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
                /* This reserves IO space but doesn't actually enable it */
-               return pcmcia_request_io(p_dev, &p_dev->io);
+               return pcmcia_request_io(p_dev);
        }
        return 0;
 }
@@ -284,12 +273,10 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
        dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                printk(", irq %u", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1 + link->io.NumPorts1 - 1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2 + link->io.NumPorts2 - 1);
+       if (link->resource[0])
+               printk(", io %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        printk("\n");
 
        return;
@@ -363,7 +350,7 @@ struct pcmcia_driver das08_cs_driver = {
        .id_table = das08_cs_id_table,
        .owner = THIS_MODULE,
        .drv = {
-               .name = dev_info,
+               .name = "pcm-das08",
                },
 };
 
index ccee4f1802d69b5bc19843c51a84cc09794192ec..0af1b465908829013eb498c5371195011ae5b3d8 100644 (file)
@@ -1717,7 +1717,18 @@ static int das16_detach(struct comedi_device *dev)
        return 0;
 }
 
-COMEDI_INITCLEANUP(driver_das16);
+static int __init driver_das16_init_module(void)
+{
+       return comedi_driver_register(&driver_das16);
+}
+
+static void __exit driver_das16_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_das16);
+}
+
+module_init(driver_das16_init_module);
+module_exit(driver_das16_cleanup_module);
 
 /* utility function that suggests a dma transfer size in bytes */
 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
@@ -1776,3 +1787,7 @@ static void das16_ai_munge(struct comedi_device *dev,
 
        }
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index c403d88274347a3a583bddaf83fa6d3e73e7526b..a5ce3b2abe4a7c0486cabe830d3c51ba81b28bb9 100644 (file)
@@ -198,7 +198,18 @@ struct das16m1_private_struct {
 #define devpriv ((struct das16m1_private_struct *)(dev->private))
 #define thisboard ((const struct das16m1_board *)(dev->board_ptr))
 
-COMEDI_INITCLEANUP(driver_das16m1);
+static int __init driver_das16m1_init_module(void)
+{
+       return comedi_driver_register(&driver_das16m1);
+}
+
+static void __exit driver_das16m1_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_das16m1);
+}
+
+module_init(driver_das16m1_init_module);
+module_exit(driver_das16m1_cleanup_module);
 
 static inline short munge_sample(short data)
 {
@@ -777,3 +788,7 @@ static int das16m1_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index de5e82fec8781dd5d43416d6a58fdf63839fe2d2..6ea93f9c0b483a4ff1042a1c26812fad869b507c 100644 (file)
@@ -531,7 +531,18 @@ static struct comedi_driver driver_das1800 = {
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver_das1800);
+static int __init driver_das1800_init_module(void)
+{
+       return comedi_driver_register(&driver_das1800);
+}
+
+static void __exit driver_das1800_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_das1800);
+}
+
+module_init(driver_das1800_init_module);
+module_exit(driver_das1800_cleanup_module);
 
 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
                            unsigned int dma1)
@@ -1800,3 +1811,7 @@ static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
 
        return size;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index a404a183191109320ec4b297ff869861d2be8c37..6328f5280b6602755705d467b40f55064cd8f65c 100644 (file)
@@ -109,7 +109,18 @@ static struct comedi_driver driver_das6402 = {
        .detach = das6402_detach,
 };
 
-COMEDI_INITCLEANUP(driver_das6402);
+static int __init driver_das6402_init_module(void)
+{
+       return comedi_driver_register(&driver_das6402);
+}
+
+static void __exit driver_das6402_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_das6402);
+}
+
+module_init(driver_das6402_init_module);
+module_exit(driver_das6402_cleanup_module);
 
 struct das6402_private {
        int ai_bytes_to_read;
@@ -360,3 +371,7 @@ static int das6402_attach(struct comedi_device *dev,
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index aadc4971c909aa0819684708252f0fe3c65d0442..aecaedc5027e71e338abaac43ee4e455a8543dc8 100644 (file)
@@ -347,7 +347,18 @@ static int das800_probe(struct comedi_device *dev)
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver_das800);
+static int __init driver_das800_init_module(void)
+{
+       return comedi_driver_register(&driver_das800);
+}
+
+static void __exit driver_das800_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_das800);
+}
+
+module_init(driver_das800_init_module);
+module_exit(driver_das800_cleanup_module);
 
 /* interrupt service routine */
 static irqreturn_t das800_interrupt(int irq, void *d)
@@ -905,3 +916,7 @@ static int das800_set_frequency(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index d5cbd515c370ac3f0e2f6013a300c39f66589dbf..693728e14bdb0145d469bc771df7095f11bf5a6b 100644 (file)
@@ -37,43 +37,6 @@ Configuration Options:
   comedi_config /dev/comedi0 dmm32at baseaddr,irq
 */
 
-/*
- * The previous block comment is used to automatically generate
- * documentation in Comedi and Comedilib.  The fields:
- *
- * Driver: the name of the driver
- * Description: a short phrase describing the driver.  Don't list boards.
- * Devices: a full list of the boards that attempt to be supported by
- *   the driver.  Format is "(manufacturer) board name [comedi name]",
- *   where comedi_name is the name that is used to configure the board.
- *   See the comment near board_name: in the struct comedi_driver structure
- *   below.  If (manufacturer) or [comedi name] is missing, the previous
- *   value is used.
- * Author: you
- * Updated: date when the _documentation_ was last updated.  Use 'date -R'
- *   to get a value for this.
- * Status: a one-word description of the status.  Valid values are:
- *   works - driver works correctly on most boards supported, and
- *     passes comedi_test.
- *   unknown - unknown.  Usually put there by ds.
- *   experimental - may not work in any particular release.  Author
- *     probably wants assistance testing it.
- *   bitrotten - driver has not been update in a long time, probably
- *     doesn't work, and probably is missing support for significant
- *     Comedi interface features.
- *   untested - author probably wrote it "blind", and is believed to
- *     work, but no confirmation.
- *
- * These headers should be followed by a blank line, and any comments
- * you wish to say about the driver.  The comment area is the place
- * to put any known bugs, limitations, unsupported features, supported
- * command triggers, whether or not commands are supported on particular
- * subdevices, etc.
- *
- * Somewhere in the comment should be information about configuration
- * options that are used with comedi_config.
- */
-
 #include <linux/interrupt.h>
 #include "../comedidev.h"
 #include <linux/ioport.h>
@@ -336,12 +299,14 @@ static int dmm32at_attach(struct comedi_device *dev,
        iobase = it->options[0];
        irq = it->options[1];
 
-       printk("comedi%d: dmm32at: attaching\n", dev->minor);
-       printk("dmm32at: probing at address 0x%04lx, irq %u\n", iobase, irq);
+       printk(KERN_INFO "comedi%d: dmm32at: attaching\n", dev->minor);
+       printk(KERN_DEBUG "dmm32at: probing at address 0x%04lx, irq %u\n",
+              iobase, irq);
 
        /* register address space */
        if (!request_region(iobase, DMM32AT_MEMSIZE, thisboard->name)) {
-               printk("I/O port conflict\n");
+               printk(KERN_ERR "comedi%d: dmm32at: I/O port conflict\n",
+                      dev->minor);
                return -EIO;
        }
        dev->iobase = iobase;
@@ -379,14 +344,15 @@ static int dmm32at_attach(struct comedi_device *dev,
        intstat = dmm_inb(dev, DMM32AT_INTCLOCK);
        airback = dmm_inb(dev, DMM32AT_AIRBACK);
 
-       printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
+       printk(KERN_DEBUG "dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
               ailo, aihi, fifostat);
-       printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
+       printk(KERN_DEBUG
+              "dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
               aistat, intstat, airback);
 
        if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
            (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
-               printk("dmmat32: board detection failed\n");
+               printk(KERN_ERR "dmmat32: board detection failed\n");
                return -EIO;
        }
 
@@ -394,7 +360,7 @@ static int dmm32at_attach(struct comedi_device *dev,
        if (irq) {
                ret = request_irq(irq, dmm32at_isr, 0, thisboard->name, dev);
                if (ret < 0) {
-                       printk("irq conflict\n");
+                       printk(KERN_ERR "dmm32at: irq conflict\n");
                        return ret;
                }
                dev->irq = irq;
@@ -478,7 +444,7 @@ static int dmm32at_attach(struct comedi_device *dev,
        }
 
        /* success */
-       printk("comedi%d: dmm32at: attached\n", dev->minor);
+       printk(KERN_INFO "comedi%d: dmm32at: attached\n", dev->minor);
 
        return 1;
 
@@ -494,7 +460,7 @@ static int dmm32at_attach(struct comedi_device *dev,
  */
 static int dmm32at_detach(struct comedi_device *dev)
 {
-       printk("comedi%d: dmm32at: remove\n", dev->minor);
+       printk(KERN_INFO "comedi%d: dmm32at: remove\n", dev->minor);
        if (dev->irq)
                free_irq(dev->irq, dev);
        if (dev->iobase)
@@ -542,7 +508,7 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev,
                        break;
        }
        if (i == 40000) {
-               printk("timeout\n");
+               printk(KERN_WARNING "dmm32at: timeout\n");
                return -ETIMEDOUT;
        }
 
@@ -557,7 +523,7 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev,
                                break;
                }
                if (i == 40000) {
-                       printk("timeout\n");
+                       printk(KERN_WARNING "dmm32at: timeout\n");
                        return -ETIMEDOUT;
                }
 
@@ -627,7 +593,8 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
        if (err)
                return 1;
 
-       /* step 2: make sure trigger sources are unique and mutually compatible */
+       /* step 2: make sure trigger sources are unique and mutually
+        * compatible */
 
        /* note that mutual compatibility is not an issue here */
        if (cmd->scan_begin_src != TRIG_TIMER &&
@@ -800,7 +767,8 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        if (cmd->stop_src == TRIG_COUNT)
                devpriv->ai_scans_left = cmd->stop_arg;
        else {                  /* TRIG_NONE */
-               devpriv->ai_scans_left = 0xffffffff;    /* indicates TRIG_NONE to isr */
+               devpriv->ai_scans_left = 0xffffffff; /* indicates TRIG_NONE to
+                                                     * isr */
        }
 
        /* wait for circuit to settle */
@@ -810,7 +778,7 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                        break;
        }
        if (i == 40000) {
-               printk("timeout\n");
+               printk(KERN_WARNING "dmm32at: timeout\n");
                return -ETIMEDOUT;
        }
 
@@ -823,13 +791,13 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                dmm_outb(dev, DMM32AT_CONV, 0xff);
        }
 
-/*     printk("dmmat32 in command\n"); */
+/*     printk("dmmat32 in command\n"); */
 
-/*     for(i=0;i<cmd->chanlist_len;i++) */
-/*             comedi_buf_put(s->async,i*100); */
+/*     for(i=0;i<cmd->chanlist_len;i++) */
+/*             comedi_buf_put(s->async,i*100); */
 
-/*     s->async->events |= COMEDI_CB_EOA; */
-/*     comedi_event(dev, s); */
+/*     s->async->events |= COMEDI_CB_EOA; */
+/*     comedi_event(dev, s); */
 
        return 0;
 
@@ -937,7 +905,7 @@ static int dmm32at_ao_winsn(struct comedi_device *dev,
                                break;
                }
                if (i == 40000) {
-                       printk("timeout\n");
+                       printk(KERN_WARNING "dmm32at: timeout\n");
                        return -ETIMEDOUT;
                }
                /* dummy read to update trigger the output */
@@ -1095,4 +1063,19 @@ void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver_dmm32at);
+static int __init driver_dmm32at_init_module(void)
+{
+       return comedi_driver_register(&driver_dmm32at);
+}
+
+static void __exit driver_dmm32at_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dmm32at);
+}
+
+module_init(driver_dmm32at_init_module);
+module_exit(driver_dmm32at_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 83fb6e56c3e9cb25ffb1bca209efa18887ace644..5cce1b5f448479a780143127df79a79874adb623 100644 (file)
@@ -98,7 +98,18 @@ static struct comedi_driver driver_dt2801 = {
        .detach = dt2801_detach,
 };
 
-COMEDI_INITCLEANUP(driver_dt2801);
+static int __init driver_dt2801_init_module(void)
+{
+       return comedi_driver_register(&driver_dt2801);
+}
+
+static void __exit driver_dt2801_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dt2801);
+}
+
+module_init(driver_dt2801_init_module);
+module_exit(driver_dt2801_cleanup_module);
 
 #if 0
 /* ignore 'defined but not used' warning */
@@ -720,3 +731,7 @@ static int dt2801_dio_insn_config(struct comedi_device *dev,
 
        return 1;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index ea9bfb7fd88e859343f278632e57e2334deb2b56..a1664caa1d961fd89cf637f6c1a66efa0da093b3 100644 (file)
@@ -239,7 +239,18 @@ static struct comedi_driver driver_dt2811 = {
        .offset = sizeof(struct dt2811_board),
 };
 
-COMEDI_INITCLEANUP(driver_dt2811);
+static int __init driver_dt2811_init_module(void)
+{
+       return comedi_driver_register(&driver_dt2811);
+}
+
+static void __exit driver_dt2811_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dt2811);
+}
+
+module_init(driver_dt2811_init_module);
+module_exit(driver_dt2811_cleanup_module);
 
 static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
                          struct comedi_insn *insn, unsigned int *data);
@@ -625,3 +636,7 @@ static int dt2811_do_insn_bits(struct comedi_device *dev,
 
        return 2;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 16fde066d26609197081ed6f09d9282d1907c27b..1c6248cf5928144f7cf9d97ef5220d3d048f07ce 100644 (file)
@@ -70,7 +70,18 @@ static struct comedi_driver driver_dt2814 = {
        .detach = dt2814_detach,
 };
 
-COMEDI_INITCLEANUP(driver_dt2814);
+static int __init driver_dt2814_init_module(void)
+{
+       return comedi_driver_register(&driver_dt2814);
+}
+
+static void __exit driver_dt2814_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dt2814);
+}
+
+module_init(driver_dt2814_init_module);
+module_exit(driver_dt2814_cleanup_module);
 
 static irqreturn_t dt2814_interrupt(int irq, void *dev);
 
@@ -387,3 +398,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d)
        comedi_event(dev, s);
        return IRQ_HANDLED;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index d1a4f7822433e5cbad438aa8953f317658c6aa1e..4155da43fd517c6f4e36209967a6a7f57cf4b27f 100644 (file)
@@ -82,7 +82,18 @@ static struct comedi_driver driver_dt2815 = {
        .detach = dt2815_detach,
 };
 
-COMEDI_INITCLEANUP(driver_dt2815);
+static int __init driver_dt2815_init_module(void)
+{
+       return comedi_driver_register(&driver_dt2815);
+}
+
+static void __exit driver_dt2815_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dt2815);
+}
+
+module_init(driver_dt2815_init_module);
+module_exit(driver_dt2815_cleanup_module);
 
 static void dt2815_free_resources(struct comedi_device *dev);
 
@@ -255,3 +266,7 @@ static int dt2815_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 54e0dea0fc59d9910c2741b84b8e70449c442e20..651fe050d0299818a08182b04e3f527c3d138906 100644 (file)
@@ -57,7 +57,18 @@ static struct comedi_driver driver_dt2817 = {
        .detach = dt2817_detach,
 };
 
-COMEDI_INITCLEANUP(driver_dt2817);
+static int __init driver_dt2817_init_module(void)
+{
+       return comedi_driver_register(&driver_dt2817);
+}
+
+static void __exit driver_dt2817_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dt2817);
+}
+
+module_init(driver_dt2817_init_module);
+module_exit(driver_dt2817_cleanup_module);
 
 static int dt2817_dio_insn_config(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
@@ -180,3 +191,7 @@ static int dt2817_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index fd8728c83669aade16eeb3f28dd9d4ece630a4eb..8cea9dca3d7e64fcf098dee5277e41be9e7b9bf8 100644 (file)
@@ -423,7 +423,18 @@ static struct comedi_driver driver_dt282x = {
        .offset = sizeof(struct dt282x_board),
 };
 
-COMEDI_INITCLEANUP(driver_dt282x);
+static int __init driver_dt282x_init_module(void)
+{
+       return comedi_driver_register(&driver_dt282x);
+}
+
+static void __exit driver_dt282x_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dt282x);
+}
+
+module_init(driver_dt282x_init_module);
+module_exit(driver_dt282x_cleanup_module);
 
 static void free_resources(struct comedi_device *dev);
 static int prep_ai_dma(struct comedi_device *dev, int chan, int size);
@@ -1502,3 +1513,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index ca687890fc12bccc1c2397d0a18524cb01d71cad..656e7bbf2fcbad7f05412c6aa3ad255ca4ed6002 100644 (file)
@@ -287,7 +287,43 @@ static struct comedi_driver driver_dt3000 = {
        .detach = dt3000_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(driver_dt3000, dt3k_pci_table);
+static int __devinit driver_dt3000_pci_probe(struct pci_dev *dev,
+                                            const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_dt3000.driver_name);
+}
+
+static void __devexit driver_dt3000_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_dt3000_pci_driver = {
+       .id_table = dt3k_pci_table,
+       .probe = &driver_dt3000_pci_probe,
+       .remove = __devexit_p(&driver_dt3000_pci_remove)
+};
+
+static int __init driver_dt3000_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_dt3000);
+       if (retval < 0)
+               return retval;
+
+       driver_dt3000_pci_driver.name = (char *)driver_dt3000.driver_name;
+       return pci_register_driver(&driver_dt3000_pci_driver);
+}
+
+static void __exit driver_dt3000_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_dt3000_pci_driver);
+       comedi_driver_unregister(&driver_dt3000);
+}
+
+module_init(driver_dt3000_init_module);
+module_exit(driver_dt3000_cleanup_module);
 
 static void dt3k_ai_empty_fifo(struct comedi_device *dev,
                               struct comedi_subdevice *s);
@@ -991,3 +1027,7 @@ static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board)
        *board = -1;
        return from;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 96caae36279c6a642441b47a0a3aa7bf3310d877..d01d2dc79112b8c47dac6216e29446eb775c3f89 100644 (file)
@@ -890,8 +890,10 @@ static struct usb_driver dt9812_usb_driver = {
  * Comedi functions
  */
 
-static void dt9812_comedi_open(struct comedi_device *dev)
+static int dt9812_comedi_open(struct comedi_device *dev)
 {
+       int result = -ENODEV;
+
        down(&devpriv->slot->mutex);
        if (devpriv->slot->usb) {
                /* We have an attached device, fill in current range info */
@@ -934,8 +936,10 @@ static void dt9812_comedi_open(struct comedi_device *dev)
                        }
                        break;
                }
+               result = 0;
        }
        up(&devpriv->slot->mutex);
+       return result;
 }
 
 static int dt9812_di_rinsn(struct comedi_device *dev,
index a10a2b070a24669ecc5cdc70122ec02683ab7a54..7f49add60b2137f345d05f6324c92c03cff0f568 100644 (file)
@@ -52,7 +52,18 @@ static struct comedi_driver driver_fl512 = {
        .detach = fl512_detach,
 };
 
-COMEDI_INITCLEANUP(driver_fl512);
+static int __init driver_fl512_init_module(void)
+{
+       return comedi_driver_register(&driver_fl512);
+}
+
+static void __exit driver_fl512_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_fl512);
+}
+
+module_init(driver_fl512_init_module);
+module_exit(driver_fl512_cleanup_module);
 
 static int fl512_ai_insn(struct comedi_device *dev,
                         struct comedi_subdevice *s, struct comedi_insn *insn,
@@ -205,3 +216,7 @@ static int fl512_detach(struct comedi_device *dev)
        printk(KERN_INFO "comedi%d: fl512: dummy i detach\n", dev->minor);
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 51f12bf45cf1514fe7c0f838a319e36e48d8fbd2..1661b57ca2adf90bef66ba0bc66af2d30cda530e 100644 (file)
@@ -311,17 +311,25 @@ struct hpdi_private {
        void *plx9080_iobase;
        void *hpdi_iobase;
        uint32_t *dio_buffer[NUM_DMA_BUFFERS];  /*  dma buffers */
-       dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];       /*  physical addresses of dma buffers */
-       struct plx_dma_desc *dma_desc;  /*  array of dma descriptors read by plx9080, allocated to get proper alignment */
-       dma_addr_t dma_desc_phys_addr;  /*  physical address of dma descriptor array */
+       /* physical addresses of dma buffers */
+       dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];
+       /* array of dma descriptors read by plx9080, allocated to get proper
+        * alignment */
+       struct plx_dma_desc *dma_desc;
+       /* physical address of dma descriptor array */
+       dma_addr_t dma_desc_phys_addr;
        unsigned int num_dma_descriptors;
-       uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS]; /*  pointer to start of buffers indexed by descriptor */
-       volatile unsigned int dma_desc_index;   /*  index of the dma descriptor that is currently being used */
+       /* pointer to start of buffers indexed by descriptor */
+       uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS];
+       /* index of the dma descriptor that is currently being used */
+       volatile unsigned int dma_desc_index;
        unsigned int tx_fifo_size;
        unsigned int rx_fifo_size;
        volatile unsigned long dio_count;
-       volatile uint32_t bits[24];     /*  software copies of values written to hpdi registers */
-       volatile unsigned int block_size;       /*  number of bytes at which to generate COMEDI_CB_BLOCK events */
+       /* software copies of values written to hpdi registers */
+       volatile uint32_t bits[24];
+       /* number of bytes at which to generate COMEDI_CB_BLOCK events */
+       volatile unsigned int block_size;
        unsigned dio_config_output:1;
 };
 
@@ -337,7 +345,43 @@ static struct comedi_driver driver_hpdi = {
        .detach = hpdi_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(driver_hpdi, hpdi_pci_table);
+static int __devinit driver_hpdi_pci_probe(struct pci_dev *dev,
+                                          const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_hpdi.driver_name);
+}
+
+static void __devexit driver_hpdi_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_hpdi_pci_driver = {
+       .id_table = hpdi_pci_table,
+       .probe = &driver_hpdi_pci_probe,
+       .remove = __devexit_p(&driver_hpdi_pci_remove)
+};
+
+static int __init driver_hpdi_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_hpdi);
+       if (retval < 0)
+               return retval;
+
+       driver_hpdi_pci_driver.name = (char *)driver_hpdi.driver_name;
+       return pci_register_driver(&driver_hpdi_pci_driver);
+}
+
+static void __exit driver_hpdi_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_hpdi_pci_driver);
+       comedi_driver_unregister(&driver_hpdi);
+}
+
+module_init(driver_hpdi_init_module);
+module_exit(driver_hpdi_cleanup_module);
 
 static int dio_config_insn(struct comedi_device *dev,
                           struct comedi_subdevice *s, struct comedi_insn *insn,
@@ -570,7 +614,8 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                return -ENOMEM;
 
        pcidev = NULL;
-       for (i = 0; i < ARRAY_SIZE(hpdi_boards) && dev->board_ptr == NULL; i++) {
+       for (i = 0; i < ARRAY_SIZE(hpdi_boards) &&
+                   dev->board_ptr == NULL; i++) {
                do {
                        pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
                                                hpdi_boards[i].device_id,
@@ -618,7 +663,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        /*  remap, won't work with 2.0 kernels but who cares */
        priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
                                            pci_resource_len(pcidev,
-                                                            PLX9080_BADDRINDEX));
+                                           PLX9080_BADDRINDEX));
        priv(dev)->hpdi_iobase =
            ioremap(priv(dev)->hpdi_phys_iobase,
                    pci_resource_len(pcidev, HPDI_BADDRINDEX));
@@ -769,7 +814,8 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
        if (err)
                return 1;
 
-       /* step 2: make sure trigger sources are unique and mutually compatible */
+       /* step 2: make sure trigger sources are unique and mutually
+        * compatible */
 
        /*  uniqueness check */
        if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
@@ -1066,3 +1112,7 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index fa0e48173bd4479968f3eb027ef6ee60583954c2..809d17efd5b35eeded7a220e590d997b1c81014e 100644 (file)
@@ -185,7 +185,18 @@ board_name : &boardtypes[0].name,
 offset : sizeof(struct boardtype),
 };
 
-COMEDI_INITCLEANUP(driver_icp_multi);
+static int __init driver_icp_multi_init_module(void)
+{
+       return comedi_driver_register(&driver_icp_multi);
+}
+
+static void __exit driver_icp_multi_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_icp_multi);
+}
+
+module_init(driver_icp_multi_init_module);
+module_exit(driver_icp_multi_cleanup_module);
 
 struct icp_multi_private {
        struct pcilst_struct *card;     /*  pointer to card */
@@ -1125,3 +1136,7 @@ static int icp_multi_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 2bb96b1d21e78c650d9a82519190ca87cc203e02..68acefe16888bef038ef8f5df2c2ba43256d2557 100644 (file)
@@ -62,16 +62,14 @@ static int pci_card_data(struct pcilst_struct *amcc,
 /* build list of Inova cards in this system */
 static void pci_card_list_init(unsigned short pci_vendor, char display)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct pcilst_struct *inova, *last;
        int i;
 
        inova_devices = NULL;
        last = NULL;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == pci_vendor) {
                        inova = kzalloc(sizeof(*inova), GFP_KERNEL);
                        if (!inova) {
index e26c1b88ebeb0908b5cf4f0248c32f2788d5cdd4..39a6a850d63c3287974eeea5c9a3fa874990af60 100644 (file)
@@ -640,4 +640,19 @@ static unsigned int pci20xxx_di(struct comedi_device *dev,
 }
 #endif
 
-COMEDI_INITCLEANUP(driver_pci20xxx);
+static int __init driver_pci20xxx_init_module(void)
+{
+       return comedi_driver_register(&driver_pci20xxx);
+}
+
+static void __exit driver_pci20xxx_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pci20xxx);
+}
+
+module_init(driver_pci20xxx_init_module);
+module_exit(driver_pci20xxx_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index d330b1886846f866103ba746d2fb93653619258b..8b383ee959b28199d377a5739d76459037089688 100644 (file)
@@ -48,6 +48,7 @@ Devices: [JR3] PCI force sensor board (jr3_pci)
 #include <linux/jiffies.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
+#include <linux/kernel.h>
 #include "comedi_pci.h"
 #include "jr3_pci.h"
 
@@ -123,12 +124,9 @@ struct jr3_pci_subdev_private {
 };
 
 /* Hotplug firmware loading stuff */
-
-typedef int comedi_firmware_callback(struct comedi_device *dev,
-                                    const u8 * data, size_t size);
-
 static int comedi_load_firmware(struct comedi_device *dev, char *name,
-                               comedi_firmware_callback cb)
+                               int (*cb)(struct comedi_device *dev,
+                                       const u8 *data, size_t size))
 {
        int result = 0;
        const struct firmware *fw;
@@ -373,7 +371,7 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev,
        return result;
 }
 
-static void jr3_pci_open(struct comedi_device *dev)
+static int jr3_pci_open(struct comedi_device *dev)
 {
        int i;
        struct jr3_pci_dev_private *devpriv = dev->private;
@@ -388,6 +386,7 @@ static void jr3_pci_open(struct comedi_device *dev)
                               p->channel_no);
                }
        }
+       return 0;
 }
 
 int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
@@ -399,14 +398,14 @@ int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
                }
                /*  Collect value */
                *val = 0;
-               for (; *pos < size && isxdigit(data[*pos]); (*pos)++) {
-                       char ch = tolower(data[*pos]);
-                       result = 1;
-                       if ('0' <= ch && ch <= '9') {
-                               *val = (*val << 4) + (ch - '0');
-                       } else if ('a' <= ch && ch <= 'f') {
-                               *val = (*val << 4) + (ch - 'a' + 10);
-                       }
+               for (; *pos < size; (*pos)++) {
+                       int value;
+                       value = hex_to_bin(data[*pos]);
+                       if (value >= 0) {
+                               result = 1;
+                               *val = (*val << 4) + value;
+                       } else
+                               break;
                }
        }
        return result;
@@ -986,4 +985,44 @@ static int jr3_pci_detach(struct comedi_device *dev)
        return 0;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_jr3_pci, jr3_pci_pci_table);
+static int __devinit driver_jr3_pci_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_jr3_pci.driver_name);
+}
+
+static void __devexit driver_jr3_pci_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_jr3_pci_pci_driver = {
+       .id_table = jr3_pci_pci_table,
+       .probe = &driver_jr3_pci_pci_probe,
+       .remove = __devexit_p(&driver_jr3_pci_pci_remove)
+};
+
+static int __init driver_jr3_pci_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_jr3_pci);
+       if (retval < 0)
+               return retval;
+
+       driver_jr3_pci_pci_driver.name = (char *)driver_jr3_pci.driver_name;
+       return pci_register_driver(&driver_jr3_pci_pci_driver);
+}
+
+static void __exit driver_jr3_pci_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_jr3_pci_pci_driver);
+       comedi_driver_unregister(&driver_jr3_pci);
+}
+
+module_init(driver_jr3_pci_init_module);
+module_exit(driver_jr3_pci_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 73b0445e310faf125d956c8b5c9b163bcc0a466b..286093bca3fba6eed4f0c3b2ef775270785090f0 100644 (file)
@@ -96,7 +96,43 @@ static struct comedi_driver cnt_driver = {
        .detach = cnt_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table);
+static int __devinit cnt_driver_pci_probe(struct pci_dev *dev,
+                                         const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, cnt_driver.driver_name);
+}
+
+static void __devexit cnt_driver_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver cnt_driver_pci_driver = {
+       .id_table = cnt_pci_table,
+       .probe = &cnt_driver_pci_probe,
+       .remove = __devexit_p(&cnt_driver_pci_remove)
+};
+
+static int __init cnt_driver_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&cnt_driver);
+       if (retval < 0)
+               return retval;
+
+       cnt_driver_pci_driver.name = (char *)cnt_driver.driver_name;
+       return pci_register_driver(&cnt_driver_pci_driver);
+}
+
+static void __exit cnt_driver_cleanup_module(void)
+{
+       pci_unregister_driver(&cnt_driver_pci_driver);
+       comedi_driver_unregister(&cnt_driver);
+}
+
+module_init(cnt_driver_init_module);
+module_exit(cnt_driver_cleanup_module);
 
 /*-- counter write ----------------------------------------------------------*/
 
@@ -152,7 +188,7 @@ static int cnt_rinsn(struct comedi_device *dev,
 static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
        struct comedi_subdevice *subdevice;
-       struct pci_dev *pci_device;
+       struct pci_dev *pci_device = NULL;
        struct cnt_board_struct *board;
        unsigned long io_base;
        int error, i;
@@ -163,9 +199,7 @@ static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                return error;
 
        /* Probe the device to determine what device in the series it is. */
-       for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pci_device != NULL;
-            pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+       for_each_pci_dev(pci_device) {
                if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) {
                        for (i = 0; i < cnt_board_nbr; i++) {
                                if (cnt_boards[i].device_id ==
@@ -259,3 +293,7 @@ static int cnt_detach(struct comedi_device *dev)
               dev->minor);
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 8b9fa0f9f1f62606eb0d8e618ae0c0f5e0862ba0..14713849564d9f29db923f65bf83309089842d8a 100644 (file)
@@ -91,22 +91,22 @@ static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
 
 static const struct me4000_board me4000_boards[] = {
-       {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
+       {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} },
 
-       {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
-       {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
-       {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
-       {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
+       {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
+       {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
+       {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
+       {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
 
-       {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
-       {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
-       {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
-       {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
+       {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
+       {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
+       {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
+       {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
 
-       {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
-       {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
-       {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
-       {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
+       {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
+       {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
+       {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
+       {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
 
        {0},
 };
@@ -120,10 +120,10 @@ static int me4000_attach(struct comedi_device *dev,
                         struct comedi_devconfig *it);
 static int me4000_detach(struct comedi_device *dev);
 static struct comedi_driver driver_me4000 = {
-driver_name:"me4000",
-module:THIS_MODULE,
-attach:me4000_attach,
-detach:me4000_detach,
+driver_name: "me4000",
+module : THIS_MODULE,
+attach : me4000_attach,
+detach : me4000_detach,
 };
 
 /*-----------------------------------------------------------------------------
@@ -302,8 +302,8 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                        if (request_irq(info->irq, me4000_ai_isr,
                                        IRQF_SHARED, "ME-4000", dev)) {
                                printk
-                                   ("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n",
-                                    dev->minor);
+                                   ("comedi%d: me4000: me4000_attach(): "
+                                    "Unable to allocate irq\n", dev->minor);
                        } else {
                                dev->read_subdev = s;
                                s->subdev_flags |= SDF_CMD_READ;
@@ -313,8 +313,8 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                        }
                } else {
                        printk(KERN_WARNING
-                              "comedi%d: me4000: me4000_attach(): No interrupt available\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_attach(): "
+                              "No interrupt available\n", dev->minor);
                }
        } else {
                s->type = COMEDI_SUBD_UNUSED;
@@ -389,7 +389,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-       struct pci_dev *pci_device;
+       struct pci_dev *pci_device = NULL;
        int result, i;
        struct me4000_board *board;
 
@@ -402,17 +402,21 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
        /*
         * Probe the device to determine what device in the series it is.
         */
-       for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pci_device != NULL;
-            pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+       for_each_pci_dev(pci_device) {
                if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
                        for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
                                if (me4000_boards[i].device_id ==
                                    pci_device->device) {
-                                       /* Was a particular bus/slot requested? */
+                                       /*
+                                        * Was a particular
+                                        * bus/slot requested?
+                                        */
                                        if ((it->options[0] != 0)
                                            || (it->options[1] != 0)) {
-                                               /* Are we on the wrong bus/slot? */
+                                               /*
+                                                * Are we on the wrong
+                                                * bus/slot?
+                                                */
                                                if (pci_device->bus->number !=
                                                    it->options[0]
                                                    ||
@@ -433,14 +437,16 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
        }
 
        printk(KERN_ERR
-              "comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
+              "comedi%d: me4000: me4000_probe(): "
+              "No supported board found (req. bus/slot : %d/%d)\n",
               dev->minor, it->options[0], it->options[1]);
        return -ENODEV;
 
 found:
 
        printk(KERN_INFO
-              "comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
+              "comedi%d: me4000: me4000_probe(): "
+              "Found %s at PCI bus %d, slot %d\n",
               dev->minor, me4000_boards[i].name, pci_device->bus->number,
               PCI_SLOT(pci_device->devfn));
 
@@ -451,8 +457,8 @@ found:
        result = comedi_pci_enable(pci_device, dev->board_name);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Cannot enable PCI device and request I/O regions\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): Cannot enable PCI "
+                      "device and request I/O regions\n", dev->minor);
                return result;
        }
 
@@ -460,16 +466,16 @@ found:
        result = get_registers(dev, pci_device);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Cannot get registers\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): "
+                      "Cannot get registers\n", dev->minor);
                return result;
        }
        /* Initialize board info */
        result = init_board_info(dev, pci_device);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Cannot init baord info\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): "
+                      "Cannot init baord info\n", dev->minor);
                return result;
        }
 
@@ -477,8 +483,8 @@ found:
        result = init_ao_context(dev);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Cannot init ao context\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): "
+                      "Cannot init ao context\n", dev->minor);
                return result;
        }
 
@@ -486,8 +492,8 @@ found:
        result = init_ai_context(dev);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Cannot init ai context\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): "
+                      "Cannot init ai context\n", dev->minor);
                return result;
        }
 
@@ -495,8 +501,8 @@ found:
        result = init_dio_context(dev);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Cannot init dio context\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): "
+                      "Cannot init dio context\n", dev->minor);
                return result;
        }
 
@@ -504,8 +510,8 @@ found:
        result = init_cnt_context(dev);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Cannot init cnt context\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): "
+                      "Cannot init cnt context\n", dev->minor);
                return result;
        }
 
@@ -513,8 +519,8 @@ found:
        result = xilinx_download(dev);
        if (result) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_probe(): Can't download firmware\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_probe(): "
+                      "Can't download firmware\n", dev->minor);
                return result;
        }
 
@@ -535,24 +541,24 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
 
        CALL_PDEBUG("In get_registers()\n");
 
-    /*--------------------------- plx regbase ---------------------------------*/
+    /*--------------------------- plx regbase -------------------------------*/
 
        info->plx_regbase = pci_resource_start(pci_dev_p, 1);
        if (info->plx_regbase == 0) {
                printk(KERN_ERR
-                      "comedi%d: me4000: get_registers(): PCI base address 1 is not available\n",
-                      dev->minor);
+                      "comedi%d: me4000: get_registers(): "
+                      "PCI base address 1 is not available\n", dev->minor);
                return -ENODEV;
        }
        info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
 
-    /*--------------------------- me4000 regbase ------------------------------*/
+    /*--------------------------- me4000 regbase ----------------------------*/
 
        info->me4000_regbase = pci_resource_start(pci_dev_p, 2);
        if (info->me4000_regbase == 0) {
                printk(KERN_ERR
-                      "comedi%d: me4000: get_registers(): PCI base address 2 is not available\n",
-                      dev->minor);
+                      "comedi%d: me4000: get_registers(): "
+                      "PCI base address 2 is not available\n", dev->minor);
                return -ENODEV;
        }
        info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
@@ -562,19 +568,19 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
        info->timer_regbase = pci_resource_start(pci_dev_p, 3);
        if (info->timer_regbase == 0) {
                printk(KERN_ERR
-                      "comedi%d: me4000: get_registers(): PCI base address 3 is not available\n",
-                      dev->minor);
+                      "comedi%d: me4000: get_registers(): "
+                      "PCI base address 3 is not available\n", dev->minor);
                return -ENODEV;
        }
        info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
 
-    /*--------------------------- program regbase ------------------------------*/
+    /*--------------------------- program regbase ----------------------------*/
 
        info->program_regbase = pci_resource_start(pci_dev_p, 5);
        if (info->program_regbase == 0) {
                printk(KERN_ERR
-                      "comedi%d: me4000: get_registers(): PCI base address 5 is not available\n",
-                      dev->minor);
+                      "comedi%d: me4000: get_registers(): "
+                      "PCI base address 5 is not available\n", dev->minor);
                return -ENODEV;
        }
        info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
@@ -800,8 +806,8 @@ static int xilinx_download(struct comedi_device *dev)
        udelay(20);
        if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
                printk(KERN_ERR
-                      "comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
-                      dev->minor);
+                      "comedi%d: me4000: xilinx_download(): "
+                      "Can't init Xilinx\n", dev->minor);
                return -EIO;
        }
 
@@ -810,8 +816,8 @@ static int xilinx_download(struct comedi_device *dev)
        value &= ~0x100;
        outl(value, info->plx_regbase + PLX_ICR);
        if (FIRMWARE_NOT_AVAILABLE) {
-               comedi_error(dev,
-                            "xilinx firmware unavailable due to licensing, aborting");
+               comedi_error(dev, "xilinx firmware unavailable "
+                            "due to licensing, aborting");
                return -EIO;
        } else {
                /* Download Xilinx firmware */
@@ -826,7 +832,8 @@ static int xilinx_download(struct comedi_device *dev)
                        /* Check if BUSY flag is low */
                        if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
                                printk(KERN_ERR
-                                      "comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n",
+                                      "comedi%d: me4000: xilinx_download(): "
+                                      "Xilinx is still busy (idx = %d)\n",
                                       dev->minor, idx);
                                return -EIO;
                        }
@@ -837,11 +844,11 @@ static int xilinx_download(struct comedi_device *dev)
        if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
        } else {
                printk(KERN_ERR
-                      "comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
-                      dev->minor);
+                      "comedi%d: me4000: xilinx_download(): "
+                      "DONE flag is not set\n", dev->minor);
                printk(KERN_ERR
-                      "comedi%d: me4000: xilinx_download(): Download not successful\n",
-                      dev->minor);
+                      "comedi%d: me4000: xilinx_download(): "
+                      "Download not successful\n", dev->minor);
                return -EIO;
        }
 
@@ -902,7 +909,10 @@ static int reset_board(struct comedi_device *dev)
        me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE,
                    info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
 
-       /* Set digital I/O direction for port 0 to output on isolated versions */
+       /*
+        * Set digital I/O direction for port 0
+        * to output on isolated versions
+        */
        if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
                me4000_outl(dev, 0x1,
                            info->me4000_regbase + ME4000_DIO_CTRL_REG);
@@ -950,8 +960,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
                return 0;
        } else if (insn->n > 1) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
-                      dev->minor, insn->n);
+                      "comedi%d: me4000: me4000_ai_insn_read(): "
+                      "Invalid instruction length %d\n", dev->minor, insn->n);
                return -EINVAL;
        }
 
@@ -970,8 +980,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_insn_read(): "
+                      "Invalid range specified\n", dev->minor);
                return -EINVAL;
        }
 
@@ -980,8 +990,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
        case AREF_COMMON:
                if (chan >= thisboard->ai.count) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_insn_read(): "
+                              "Analog input is not available\n", dev->minor);
                        return -EINVAL;
                }
                entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
@@ -990,23 +1000,24 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
        case AREF_DIFF:
                if (rang == 0 || rang == 1) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
+                              "comedi%d: me4000: me4000_ai_insn_read(): "
+                              "Range must be bipolar when aref = diff\n",
                               dev->minor);
                        return -EINVAL;
                }
 
                if (chan >= thisboard->ai.diff_count) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_insn_read(): "
+                              "Analog input is not available\n", dev->minor);
                        return -EINVAL;
                }
                entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_insn_read(): "
+                      "Invalid aref specified\n", dev->minor);
                return -EINVAL;
        }
 
@@ -1045,8 +1056,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
            (me4000_inl(dev, info->ai_context.status_reg) &
             ME4000_AI_STATUS_BIT_EF_DATA)) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_insn_read(): "
+                      "Value not available after wait\n", dev->minor);
                return -EIO;
        }
 
@@ -1086,24 +1097,24 @@ static int ai_check_chanlist(struct comedi_device *dev,
        /* Check whether a channel list is available */
        if (!cmd->chanlist_len) {
                printk(KERN_ERR
-                      "comedi%d: me4000: ai_check_chanlist(): No channel list available\n",
-                      dev->minor);
+                      "comedi%d: me4000: ai_check_chanlist(): "
+                      "No channel list available\n", dev->minor);
                return -EINVAL;
        }
 
        /* Check the channel list size */
        if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
                printk(KERN_ERR
-                      "comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n",
-                      dev->minor);
+                      "comedi%d: me4000: ai_check_chanlist(): "
+                      "Channel list is to large\n", dev->minor);
                return -EINVAL;
        }
 
        /* Check the pointer */
        if (!cmd->chanlist) {
                printk(KERN_ERR
-                      "comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n",
-                      dev->minor);
+                      "comedi%d: me4000: ai_check_chanlist(): "
+                      "NULL pointer to channel list\n", dev->minor);
                return -EFAULT;
        }
 
@@ -1112,7 +1123,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
        for (i = 0; i < cmd->chanlist_len; i++) {
                if (CR_AREF(cmd->chanlist[i]) != aref) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n",
+                              "comedi%d: me4000: ai_check_chanlist(): "
+                              "Mode is not equal for all entries\n",
                               dev->minor);
                        return -EINVAL;
                }
@@ -1124,8 +1136,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
                        if (CR_CHAN(cmd->chanlist[i]) >=
                            thisboard->ai.diff_count) {
                                printk(KERN_ERR
-                                      "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
-                                      dev->minor);
+                                      "comedi%d: me4000: ai_check_chanlist():"
+                                      " Channel number to high\n", dev->minor);
                                return -EINVAL;
                        }
                }
@@ -1133,8 +1145,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
                for (i = 0; i < cmd->chanlist_len; i++) {
                        if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
                                printk(KERN_ERR
-                                      "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
-                                      dev->minor);
+                                      "comedi%d: me4000: ai_check_chanlist(): "
+                                      "Channel number to high\n", dev->minor);
                                return -EINVAL;
                        }
                }
@@ -1146,7 +1158,9 @@ static int ai_check_chanlist(struct comedi_device *dev,
                        if (CR_RANGE(cmd->chanlist[i]) != 1 &&
                            CR_RANGE(cmd->chanlist[i]) != 2) {
                                printk(KERN_ERR
-                                      "comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
+                                      "comedi%d: me4000: ai_check_chanlist(): "
+                                      "Bipolar is not selected in "
+                                      "differential mode\n",
                                       dev->minor);
                                return -EINVAL;
                        }
@@ -1330,21 +1344,19 @@ static int ai_write_chanlist(struct comedi_device *dev,
 
                entry = chan;
 
-               if (rang == 0) {
+               if (rang == 0)
                        entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
-               } else if (rang == 1) {
+               else if (rang == 1)
                        entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
-               } else if (rang == 2) {
+               else if (rang == 2)
                        entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
-               } else {
+               else
                        entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
-               }
 
-               if (aref == SDF_DIFF) {
+               if (aref == SDF_DIFF)
                        entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
-               } else {
+               else
                        entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
-               }
 
                me4000_outl(dev, entry, info->ai_context.channel_list_reg);
        }
@@ -1454,8 +1466,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Invalid start source\n", dev->minor);
                cmd->start_src = TRIG_NOW;
                err++;
        }
@@ -1470,8 +1482,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Invalid scan begin source\n", dev->minor);
                cmd->scan_begin_src = TRIG_FOLLOW;
                err++;
        }
@@ -1485,8 +1497,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Invalid convert source\n", dev->minor);
                cmd->convert_src = TRIG_TIMER;
                err++;
        }
@@ -1500,8 +1512,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Invalid scan end source\n", dev->minor);
                cmd->scan_end_src = TRIG_NONE;
                err++;
        }
@@ -1515,8 +1527,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Invalid stop source\n", dev->minor);
                cmd->stop_src = TRIG_NONE;
                err++;
        }
@@ -1546,8 +1558,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                   cmd->convert_src == TRIG_EXT) {
        } else {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Invalid start trigger combination\n", dev->minor);
                cmd->start_src = TRIG_NOW;
                cmd->scan_begin_src = TRIG_FOLLOW;
                cmd->convert_src = TRIG_TIMER;
@@ -1563,8 +1575,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                   cmd->scan_end_src == TRIG_COUNT) {
        } else {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Invalid stop trigger combination\n", dev->minor);
                cmd->stop_src = TRIG_NONE;
                cmd->scan_end_src = TRIG_NONE;
                err++;
@@ -1577,29 +1589,29 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
         */
        if (cmd->chanlist_len < 1) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "No channel list\n", dev->minor);
                cmd->chanlist_len = 1;
                err++;
        }
        if (init_ticks < 66) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Start arg to low\n", dev->minor);
                cmd->start_arg = 2000;
                err++;
        }
        if (scan_ticks && scan_ticks < 67) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Scan begin arg to low\n", dev->minor);
                cmd->scan_begin_arg = 2031;
                err++;
        }
        if (chan_ticks < 66) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                      "Convert arg to low\n", dev->minor);
                cmd->convert_arg = 2000;
                err++;
        }
@@ -1617,23 +1629,25 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                /* Check timer arguments */
                if (init_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid start arg\n", dev->minor);
                        cmd->start_arg = 2000;  /*  66 ticks at least */
                        err++;
                }
                if (chan_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid convert arg\n", dev->minor);
                        cmd->convert_arg = 2000;        /*  66 ticks at least */
                        err++;
                }
                if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
-                              dev->minor);
-                       cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;      /*  At least one tick more */
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid scan end arg\n", dev->minor);
+
+                       /*  At least one tick more */
+                       cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
                        err++;
                }
        } else if (cmd->start_src == TRIG_NOW &&
@@ -1643,15 +1657,15 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                /* Check timer arguments */
                if (init_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid start arg\n", dev->minor);
                        cmd->start_arg = 2000;  /*  66 ticks at least */
                        err++;
                }
                if (chan_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid convert arg\n", dev->minor);
                        cmd->convert_arg = 2000;        /*  66 ticks at least */
                        err++;
                }
@@ -1662,23 +1676,25 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                /* Check timer arguments */
                if (init_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid start arg\n", dev->minor);
                        cmd->start_arg = 2000;  /*  66 ticks at least */
                        err++;
                }
                if (chan_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid convert arg\n", dev->minor);
                        cmd->convert_arg = 2000;        /*  66 ticks at least */
                        err++;
                }
                if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
-                              dev->minor);
-                       cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;      /*  At least one tick more */
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid scan end arg\n", dev->minor);
+
+                       /*  At least one tick more */
+                       cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
                        err++;
                }
        } else if (cmd->start_src == TRIG_EXT &&
@@ -1688,15 +1704,15 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                /* Check timer arguments */
                if (init_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid start arg\n", dev->minor);
                        cmd->start_arg = 2000;  /*  66 ticks at least */
                        err++;
                }
                if (chan_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid convert arg\n", dev->minor);
                        cmd->convert_arg = 2000;        /*  66 ticks at least */
                        err++;
                }
@@ -1707,15 +1723,15 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                /* Check timer arguments */
                if (init_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid start arg\n", dev->minor);
                        cmd->start_arg = 2000;  /*  66 ticks at least */
                        err++;
                }
                if (chan_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid convert arg\n", dev->minor);
                        cmd->convert_arg = 2000;        /*  66 ticks at least */
                        err++;
                }
@@ -1726,8 +1742,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
                /* Check timer arguments */
                if (init_ticks < ME4000_AI_MIN_TICKS) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid start arg\n", dev->minor);
                        cmd->start_arg = 2000;  /*  66 ticks at least */
                        err++;
                }
@@ -1735,8 +1751,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
        if (cmd->stop_src == TRIG_COUNT) {
                if (cmd->stop_arg == 0) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid stop arg\n", dev->minor);
                        cmd->stop_arg = 1;
                        err++;
                }
@@ -1744,8 +1760,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
        if (cmd->scan_end_src == TRIG_COUNT) {
                if (cmd->scan_end_arg == 0) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_do_cmd_test(): "
+                              "Invalid scan end arg\n", dev->minor);
                        cmd->scan_end_arg = 1;
                        err++;
                }
@@ -1786,8 +1802,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
        /* Check if irq number is right */
        if (irq != ai_context->irq) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n",
-                      dev->minor, irq);
+                      "comedi%d: me4000: me4000_ai_isr(): "
+                      "Incorrect interrupt num: %d\n", dev->minor, irq);
                return IRQ_HANDLED;
        }
 
@@ -1806,7 +1822,10 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
                        ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
                        c = ME4000_AI_FIFO_COUNT;
 
-                       /* FIFO overflow, so stop conversion and disable all interrupts */
+                       /*
+                        * FIFO overflow, so stop conversion
+                        * and disable all interrupts
+                        */
                        tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
                        tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
                                 ME4000_AI_CTRL_BIT_SC_IRQ);
@@ -1815,8 +1834,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
                        s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_isr(): "
+                              "FIFO overflow\n", dev->minor);
                } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
                           && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
                           && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
@@ -1827,11 +1846,14 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
                        c = ME4000_AI_FIFO_COUNT / 2;
                } else {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_isr(): "
+                              "Can't determine state of fifo\n", dev->minor);
                        c = 0;
 
-                       /* Undefined state, so stop conversion and disable all interrupts */
+                       /*
+                        * Undefined state, so stop conversion
+                        * and disable all interrupts
+                        */
                        tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
                        tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
                                 ME4000_AI_CTRL_BIT_SC_IRQ);
@@ -1840,8 +1862,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
                        s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n",
-                              dev->minor);
+                              "comedi%d: me4000: me4000_ai_isr(): "
+                              "Undefined FIFO state\n", dev->minor);
                }
 
                ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
@@ -1852,7 +1874,10 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
                        lval ^= 0x8000;
 
                        if (!comedi_buf_put(s->async, lval)) {
-                               /* Buffer overflow, so stop conversion and disable all interrupts */
+                               /*
+                                * Buffer overflow, so stop conversion
+                                * and disable all interrupts
+                                */
                                tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
                                tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
                                         ME4000_AI_CTRL_BIT_SC_IRQ);
@@ -1861,8 +1886,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
                                s->async->events |= COMEDI_CB_OVERFLOW;
 
                                printk(KERN_ERR
-                                      "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
-                                      dev->minor);
+                                      "comedi%d: me4000: me4000_ai_isr(): "
+                                      "Buffer overflow\n", dev->minor);
 
                                break;
                        }
@@ -1883,7 +1908,10 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 
                s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
 
-               /* Acquisition is complete, so stop conversion and disable all interrupts */
+               /*
+                * Acquisition is complete, so stop
+                * conversion and disable all interrupts
+                */
                tmp = me4000_inl(dev, ai_context->ctrl_reg);
                tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
                tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
@@ -1897,8 +1925,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 
                        if (!comedi_buf_put(s->async, lval)) {
                                printk(KERN_ERR
-                                      "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
-                                      dev->minor);
+                                      "comedi%d: me4000: me4000_ai_isr(): "
+                                      "Buffer overflow\n", dev->minor);
                                s->async->events |= COMEDI_CB_OVERFLOW;
                                break;
                        }
@@ -1941,29 +1969,29 @@ static int me4000_ao_insn_write(struct comedi_device *dev,
                return 0;
        } else if (insn->n > 1) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
-                      dev->minor, insn->n);
+                      "comedi%d: me4000: me4000_ao_insn_write(): "
+                      "Invalid instruction length %d\n", dev->minor, insn->n);
                return -EINVAL;
        }
 
        if (chan >= thisboard->ao.count) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
-                      dev->minor, insn->n);
+                      "comedi%d: me4000: me4000_ao_insn_write(): "
+                      "Invalid channel %d\n", dev->minor, insn->n);
                return -EINVAL;
        }
 
        if (rang != 0) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
-                      dev->minor, insn->n);
+                      "comedi%d: me4000: me4000_ao_insn_write(): "
+                      "Invalid range %d\n", dev->minor, insn->n);
                return -EINVAL;
        }
 
        if (aref != AREF_GROUND && aref != AREF_COMMON) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
-                      dev->minor, insn->n);
+                      "comedi%d: me4000: me4000_ao_insn_write(): "
+                      "Invalid aref %d\n", dev->minor, insn->n);
                return -EINVAL;
        }
 
@@ -1994,8 +2022,8 @@ static int me4000_ao_insn_read(struct comedi_device *dev,
                return 0;
        } else if (insn->n > 1) {
                printk
-                   ("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n",
-                    dev->minor);
+                   ("comedi%d: me4000: me4000_ao_insn_read(): "
+                    "Invalid instruction length\n", dev->minor);
                return -EINVAL;
        }
 
@@ -2021,8 +2049,8 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
 
        if (insn->n != 2) {
                printk
-                   ("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n",
-                    dev->minor);
+                   ("comedi%d: me4000: me4000_dio_insn_bits(): "
+                    "Invalid instruction length\n", dev->minor);
                return -EINVAL;
        }
 
@@ -2095,8 +2123,9 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
                        tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
                } else if (chan < 16) {
                        /*
-                        * Chech for optoisolated ME-4000 version. If one the first
-                        * port is a fixed output port and the second is a fixed input port.
+                        * Chech for optoisolated ME-4000 version.
+                        * If one the first port is a fixed output
+                        * port and the second is a fixed input port.
                         */
                        if (!me4000_inl(dev, info->dio_context.dir_reg))
                                return -ENODEV;
@@ -2121,8 +2150,9 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
        } else {
                if (chan < 8) {
                        /*
-                        * Chech for optoisolated ME-4000 version. If one the first
-                        * port is a fixed output port and the second is a fixed input port.
+                        * Chech for optoisolated ME-4000 version.
+                        * If one the first port is a fixed output
+                        * port and the second is a fixed input port.
                         */
                        if (!me4000_inl(dev, info->dio_context.dir_reg))
                                return -ENODEV;
@@ -2257,7 +2287,8 @@ static int me4000_cnt_insn_config(struct comedi_device *dev,
        case GPCT_RESET:
                if (insn->n != 1) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
+                              "comedi%d: me4000: me4000_cnt_insn_config(): "
+                              "Invalid instruction length%d\n",
                               dev->minor, insn->n);
                        return -EINVAL;
                }
@@ -2269,7 +2300,8 @@ static int me4000_cnt_insn_config(struct comedi_device *dev,
        case GPCT_SET_OPERATION:
                if (insn->n != 2) {
                        printk(KERN_ERR
-                              "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
+                              "comedi%d: me4000: me4000_cnt_insn_config(): "
+                              "Invalid instruction length%d\n",
                               dev->minor, insn->n);
                        return -EINVAL;
                }
@@ -2280,8 +2312,8 @@ static int me4000_cnt_insn_config(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
-                      dev->minor);
+                      "comedi%d: me4000: me4000_cnt_insn_config(): "
+                      "Invalid instruction\n", dev->minor);
                return -EINVAL;
        }
 
@@ -2302,7 +2334,8 @@ static int me4000_cnt_insn_read(struct comedi_device *dev,
 
        if (insn->n > 1) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
+                      "comedi%d: me4000: me4000_cnt_insn_read(): "
+                      "Invalid instruction length %d\n",
                       dev->minor, insn->n);
                return -EINVAL;
        }
@@ -2328,7 +2361,8 @@ static int me4000_cnt_insn_read(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
+                      "comedi%d: me4000: me4000_cnt_insn_read(): "
+                      "Invalid channel %d\n",
                       dev->minor, insn->chanspec);
                return -EINVAL;
        }
@@ -2349,7 +2383,8 @@ static int me4000_cnt_insn_write(struct comedi_device *dev,
                return 0;
        } else if (insn->n > 1) {
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
+                      "comedi%d: me4000: me4000_cnt_insn_write(): "
+                      "Invalid instruction length %d\n",
                       dev->minor, insn->n);
                return -EINVAL;
        }
@@ -2375,7 +2410,8 @@ static int me4000_cnt_insn_write(struct comedi_device *dev,
                break;
        default:
                printk(KERN_ERR
-                      "comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
+                      "comedi%d: me4000: me4000_cnt_insn_write(): "
+                      "Invalid channel %d\n",
                       dev->minor, insn->chanspec);
                return -EINVAL;
        }
@@ -2383,4 +2419,44 @@ static int me4000_cnt_insn_write(struct comedi_device *dev,
        return 1;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_me4000, me4000_pci_table);
+static int __devinit driver_me4000_pci_probe(struct pci_dev *dev,
+                                            const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_me4000.driver_name);
+}
+
+static void __devexit driver_me4000_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_me4000_pci_driver = {
+       .id_table = me4000_pci_table,
+       .probe = &driver_me4000_pci_probe,
+       .remove = __devexit_p(&driver_me4000_pci_remove)
+};
+
+static int __init driver_me4000_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_me4000);
+       if (retval < 0)
+               return retval;
+
+       driver_me4000_pci_driver.name = (char *)driver_me4000.driver_name;
+       return pci_register_driver(&driver_me4000_pci_driver);
+}
+
+static void __exit driver_me4000_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_me4000_pci_driver);
+       comedi_driver_unregister(&driver_me4000);
+}
+
+module_init(driver_me4000_init_module);
+module_exit(driver_me4000_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index c8484aec657db8b2491bcb1b23bfa78be524c034..cda4b224b30fb933571d46fd66b528a437718165 100644 (file)
@@ -257,7 +257,43 @@ static struct comedi_driver me_driver = {
        .detach = me_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(me_driver, me_pci_table);
+static int __devinit me_driver_pci_probe(struct pci_dev *dev,
+                                        const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, me_driver.driver_name);
+}
+
+static void __devexit me_driver_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver me_driver_pci_driver = {
+       .id_table = me_pci_table,
+       .probe = &me_driver_pci_probe,
+       .remove = __devexit_p(&me_driver_pci_remove)
+};
+
+static int __init me_driver_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&me_driver);
+       if (retval < 0)
+               return retval;
+
+       me_driver_pci_driver.name = (char *)me_driver.driver_name;
+       return pci_register_driver(&me_driver_pci_driver);
+}
+
+static void __exit me_driver_cleanup_module(void)
+{
+       pci_unregister_driver(&me_driver_pci_driver);
+       comedi_driver_unregister(&me_driver);
+}
+
+module_init(me_driver_init_module);
+module_exit(me_driver_cleanup_module);
 
 /* Private data structure */
 struct me_private_data {
@@ -644,7 +680,7 @@ static int me_reset(struct comedi_device *dev)
  */
 static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-       struct pci_dev *pci_device;
+       struct pci_dev *pci_device = NULL;
        struct comedi_subdevice *subdevice;
        struct me_board *board;
        resource_size_t plx_regbase_tmp;
@@ -661,9 +697,7 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                return -ENOMEM;
 
        /* Probe the device to determine what device in the series it is. */
-       for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pci_device != NULL;
-            pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+       for_each_pci_dev(pci_device) {
                if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
                        for (i = 0; i < me_board_nbr; i++) {
                                if (me_boards[i].device_id ==
@@ -857,3 +891,7 @@ static int me_detach(struct comedi_device *dev)
        }
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 99d9985c5b371aeba859e4d8bc270eec6719dc96..cd25b241cc1f4e131925abcce8ec40dd067e8fa9 100644 (file)
@@ -70,12 +70,10 @@ EXPORT_SYMBOL(mite_devices);
 
 void mite_init(void)
 {
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = NULL;
        struct mite_struct *mite;
 
-       for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-            pcidev != NULL;
-            pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+       for_each_pci_dev(pcidev) {
                if (pcidev->vendor == PCI_VENDOR_ID_NI) {
                        unsigned i;
 
@@ -829,3 +827,7 @@ void __exit cleanup_module(void)
        mite_cleanup();
 }
 #endif
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 9874ac3749c3bcd3bbe7a731f713d528e68e4847..a89eebd23f654ad68c6141455a2790127a7011f7 100644 (file)
@@ -406,4 +406,19 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
        return n;
 }
 
-COMEDI_INITCLEANUP(driver_mpc624);
+static int __init driver_mpc624_init_module(void)
+{
+       return comedi_driver_register(&driver_mpc624);
+}
+
+static void __exit driver_mpc624_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_mpc624);
+}
+
+module_init(driver_mpc624_init_module);
+module_exit(driver_mpc624_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 440a144a037ea791d3d0cce27611a235f2f5bdc0..5f6816a3fe8ca9b6b74f054c09ca8fbbee3f09f8 100644 (file)
@@ -56,7 +56,18 @@ static struct comedi_driver driver_mpc8260cpm = {
        .detach = mpc8260cpm_detach,
 };
 
-COMEDI_INITCLEANUP(driver_mpc8260cpm);
+static int __init driver_mpc8260cpm_init_module(void)
+{
+       return comedi_driver_register(&driver_mpc8260cpm);
+}
+
+static void __exit driver_mpc8260cpm_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_mpc8260cpm);
+}
+
+module_init(driver_mpc8260cpm_init_module);
+module_exit(driver_mpc8260cpm_cleanup_module);
 
 static int mpc8260cpm_dio_config(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
index 6b22f0f8f06a3dce026937195c6503d927878bae..dace902d3bceb35ea2e778443f5a61787b5f59d7 100644 (file)
@@ -93,7 +93,18 @@ static struct comedi_driver driver_multiq3 = {
        .detach = multiq3_detach,
 };
 
-COMEDI_INITCLEANUP(driver_multiq3);
+static int __init driver_multiq3_init_module(void)
+{
+       return comedi_driver_register(&driver_multiq3);
+}
+
+static void __exit driver_multiq3_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_multiq3);
+}
+
+module_init(driver_multiq3_init_module);
+module_exit(driver_multiq3_cleanup_module);
 
 struct multiq3_private {
        unsigned int ao_readback[2];
@@ -338,3 +349,7 @@ static int multiq3_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 1fc76cc6a28eb0d33b1b64fcd26357818502aafe..14e716e99a5ca0f0168f694e76db2644f9af6cbe 100644 (file)
@@ -490,4 +490,40 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot)
        return -EIO;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_ni6527, ni6527_pci_table);
+static int __devinit driver_ni6527_pci_probe(struct pci_dev *dev,
+                                            const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_ni6527.driver_name);
+}
+
+static void __devexit driver_ni6527_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_ni6527_pci_driver = {
+       .id_table = ni6527_pci_table,
+       .probe = &driver_ni6527_pci_probe,
+       .remove = __devexit_p(&driver_ni6527_pci_remove)
+};
+
+static int __init driver_ni6527_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_ni6527);
+       if (retval < 0)
+               return retval;
+
+       driver_ni6527_pci_driver.name = (char *)driver_ni6527.driver_name;
+       return pci_register_driver(&driver_ni6527_pci_driver);
+}
+
+static void __exit driver_ni6527_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_ni6527_pci_driver);
+       comedi_driver_unregister(&driver_ni6527);
+}
+
+module_init(driver_ni6527_init_module);
+module_exit(driver_ni6527_cleanup_module);
index d793f5a4ac988c69a23ecedebcd041941a8c08ba..8b8e2aaf77fb49a8233f23c01ed14fca6a9cd69c 100644 (file)
@@ -834,4 +834,40 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot)
        return -EIO;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_ni_65xx, ni_65xx_pci_table);
+static int __devinit driver_ni_65xx_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_ni_65xx.driver_name);
+}
+
+static void __devexit driver_ni_65xx_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_ni_65xx_pci_driver = {
+       .id_table = ni_65xx_pci_table,
+       .probe = &driver_ni_65xx_pci_probe,
+       .remove = __devexit_p(&driver_ni_65xx_pci_remove)
+};
+
+static int __init driver_ni_65xx_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_ni_65xx);
+       if (retval < 0)
+               return retval;
+
+       driver_ni_65xx_pci_driver.name = (char *)driver_ni_65xx.driver_name;
+       return pci_register_driver(&driver_ni_65xx_pci_driver);
+}
+
+static void __exit driver_ni_65xx_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_ni_65xx_pci_driver);
+       comedi_driver_unregister(&driver_ni_65xx);
+}
+
+module_init(driver_ni_65xx_init_module);
+module_exit(driver_ni_65xx_cleanup_module);
index 6a6fae53ea0b39fcc8d693b2246bddb431258b6b..6612b085c4ef5c82ae82569b32114b27bd5fe355 100644 (file)
@@ -382,7 +382,7 @@ enum global_interrupt_config_register_bits {
        Global_Int_Enable_Bit = 0x80000000
 };
 
-/* Offset of the GPCT chips from the base-adress of the card */
+/* Offset of the GPCT chips from the base-address of the card */
 /* First chip is at base-address + 0x00, etc. */
 static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
 
@@ -471,7 +471,43 @@ static struct comedi_driver driver_ni_660x = {
        .detach = ni_660x_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table);
+static int __devinit driver_ni_660x_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_ni_660x.driver_name);
+}
+
+static void __devexit driver_ni_660x_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_ni_660x_pci_driver = {
+       .id_table = ni_660x_pci_table,
+       .probe = &driver_ni_660x_pci_probe,
+       .remove = __devexit_p(&driver_ni_660x_pci_remove)
+};
+
+static int __init driver_ni_660x_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_ni_660x);
+       if (retval < 0)
+               return retval;
+
+       driver_ni_660x_pci_driver.name = (char *)driver_ni_660x.driver_name;
+       return pci_register_driver(&driver_ni_660x_pci_driver);
+}
+
+static void __exit driver_ni_660x_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_ni_660x_pci_driver);
+       comedi_driver_unregister(&driver_ni_660x);
+}
+
+module_init(driver_ni_660x_init_module);
+module_exit(driver_ni_660x_cleanup_module);
 
 static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot);
 static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
index 44ae8368454defbd728fac76146661a8259eefb1..e9f034efdc6fc81ec2b1ace34b09ef21e3cc835d 100644 (file)
@@ -120,7 +120,43 @@ static struct comedi_driver driver_ni_670x = {
        .detach = ni_670x_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(driver_ni_670x, ni_670x_pci_table);
+static int __devinit driver_ni_670x_pci_probe(struct pci_dev *dev,
+                                             const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_ni_670x.driver_name);
+}
+
+static void __devexit driver_ni_670x_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_ni_670x_pci_driver = {
+       .id_table = ni_670x_pci_table,
+       .probe = &driver_ni_670x_pci_probe,
+       .remove = __devexit_p(&driver_ni_670x_pci_remove)
+};
+
+static int __init driver_ni_670x_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_ni_670x);
+       if (retval < 0)
+               return retval;
+
+       driver_ni_670x_pci_driver.name = (char *)driver_ni_670x.driver_name;
+       return pci_register_driver(&driver_ni_670x_pci_driver);
+}
+
+static void __exit driver_ni_670x_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_ni_670x_pci_driver);
+       comedi_driver_unregister(&driver_ni_670x);
+}
+
+module_init(driver_ni_670x_init_module);
+module_exit(driver_ni_670x_cleanup_module);
 
 static struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
 
index 9bff34cf06d1a709199c5e41cecf05710a4f6ea5..e46d62b75fc0a63d9484e63e0716a5f463140593 100644 (file)
@@ -197,7 +197,18 @@ static int a2150_set_chanlist(struct comedi_device *dev,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver_a2150);
+static int __init driver_a2150_init_module(void)
+{
+       return comedi_driver_register(&driver_a2150);
+}
+
+static void __exit driver_a2150_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_a2150);
+}
+
+module_init(driver_a2150_init_module);
+module_exit(driver_a2150_cleanup_module);
 
 #ifdef A2150_DEBUG
 
@@ -910,3 +921,7 @@ static int a2150_set_chanlist(struct comedi_device *dev,
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index ce60224bb7bf9466bd02d165b88f32fd153e3f29..138dcc2275ab5c9af27f25c2c833352fc20204bb 100644 (file)
@@ -194,7 +194,18 @@ static struct comedi_driver driver_atao = {
        .num_names = ARRAY_SIZE(atao_boards),
 };
 
-COMEDI_INITCLEANUP(driver_atao);
+static int __init driver_atao_init_module(void)
+{
+       return comedi_driver_register(&driver_atao);
+}
+
+static void __exit driver_atao_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_atao);
+}
+
+module_init(driver_atao_init_module);
+module_exit(driver_atao_cleanup_module);
 
 static void atao_reset(struct comedi_device *dev);
 
@@ -459,3 +470,7 @@ static int atao_calib_insn_write(struct comedi_device *dev,
 
        return insn->n;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 003d00b595b08316498fc18e48809bd30eed245d..3330b3d53e8d4e8966074d72036ff38fe93d4ad1 100644 (file)
@@ -349,7 +349,18 @@ static struct comedi_driver driver_atmio = {
        .detach = ni_atmio_detach,
 };
 
-COMEDI_INITCLEANUP(driver_atmio);
+static int __init driver_atmio_init_module(void)
+{
+       return comedi_driver_register(&driver_atmio);
+}
+
+static void __exit driver_atmio_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_atmio);
+}
+
+module_init(driver_atmio_init_module);
+module_exit(driver_atmio_cleanup_module);
 
 #include "ni_mio_common.c"
 
index cf4f241f210a69109257cdd242563c36cf258d0b..285b933551abddb03ca8cbc152659841e0cf0535 100644 (file)
@@ -151,7 +151,18 @@ static struct comedi_driver driver_atmio16d = {
        .offset = sizeof(struct atmio16_board_t),
 };
 
-COMEDI_INITCLEANUP(driver_atmio16d);
+static int __init driver_atmio16d_init_module(void)
+{
+       return comedi_driver_register(&driver_atmio16d);
+}
+
+static void __exit driver_atmio16d_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_atmio16d);
+}
+
+module_init(driver_atmio16d_init_module);
+module_exit(driver_atmio16d_cleanup_module);
 
 /* range structs */
 static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { 4, {
@@ -887,3 +898,7 @@ static int atmio16d_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 6ec77bf88c635961c55d0e6028b5eeab318bcf60..cc15666e5cc195391d5fd5093dc90f4c30169943 100644 (file)
@@ -47,7 +47,6 @@ IRQ is assigned but not used.
 
 #include <linux/ioport.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -377,7 +376,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                link = pcmcia_cur_dev;  /* XXX hack */
                if (!link)
                        return -EIO;
-               iobase = link->io.BasePort1;
+               iobase = link->resource[0]->start;
 #ifdef incomplete
                irq = link->irq;
 #endif
@@ -459,14 +458,6 @@ static void dio700_cs_detach(struct pcmcia_device *);
    less on other parts of the kernel.
 */
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static const dev_info_t dev_info = "ni_daq_700";
-
 struct local_info_t {
        struct pcmcia_device *link;
        int stop;
@@ -537,8 +528,7 @@ static void dio700_cs_detach(struct pcmcia_device *link)
        dio700_release(link);
 
        /* This points to the parent struct local_info_t struct */
-       if (link->priv)
-               kfree(link->priv);
+       kfree(link->priv);
 
 }                              /* dio700_cs_detach */
 
@@ -556,9 +546,6 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
                                unsigned int vcc,
                                void *priv_data)
 {
-       win_req_t *req = priv_data;
-       memreq_t map;
-
        if (cfg->index == 0)
                return -ENODEV;
 
@@ -572,44 +559,25 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
                /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               if (pcmcia_request_io(p_dev) != 0)
                        return -ENODEV;
        }
 
-       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
-               cistpl_mem_t *mem =
-                       (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
-               req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
-               req->Attributes |= WIN_ENABLE;
-               req->Base = mem->win[0].host_addr;
-               req->Size = mem->win[0].len;
-               if (req->Size < 0x1000)
-                       req->Size = 0x1000;
-               req->AccessSpeed = 0;
-               if (pcmcia_request_window(p_dev, req, &p_dev->win))
-                       return -ENODEV;
-               map.Page = 0;
-               map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
-                       return -ENODEV;
-       }
        /* If we got this far, we're cool! */
        return 0;
 }
@@ -623,7 +591,7 @@ static void dio700_config(struct pcmcia_device *link)
 
        dev_dbg(&link->dev, "dio700_config\n");
 
-       ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, &req);
+       ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL);
        if (ret) {
                dev_warn(&link->dev, "no configuration found\n");
                goto failed;
@@ -645,15 +613,10 @@ static void dio700_config(struct pcmcia_device *link)
        dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                printk(", irq %d", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1 + link->io.NumPorts1 - 1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2 + link->io.NumPorts2 - 1);
-       if (link->win)
-               printk(", mem 0x%06lx-0x%06lx", req.Base,
-                      req.Base + req.Size - 1);
+       if (link->resource[0])
+               printk(", io %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        printk("\n");
 
        return;
@@ -723,7 +686,7 @@ struct pcmcia_driver dio700_cs_driver = {
        .id_table = dio700_cs_ids,
        .owner = THIS_MODULE,
        .drv = {
-               .name = dev_info,
+               .name = "ni_daq_700",
                },
 };
 
index e4865b1c23103563846656e729ea4d250b5ebbed..773ae2044e0ee8a52435f14879563dd37597d6f4 100644 (file)
@@ -48,7 +48,6 @@ the PCMCIA interface.
 
 #include "8255.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -129,7 +128,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                link = pcmcia_cur_dev;  /* XXX hack */
                if (!link)
                        return -EIO;
-               iobase = link->io.BasePort1;
+               iobase = link->resource[0]->start;
 #ifdef incomplete
                irq = link->irq;
 #endif
@@ -211,14 +210,6 @@ static void dio24_cs_detach(struct pcmcia_device *);
    less on other parts of the kernel.
 */
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static const dev_info_t dev_info = "ni_daq_dio24";
-
 struct local_info_t {
        struct pcmcia_device *link;
        int stop;
@@ -289,8 +280,7 @@ static void dio24_cs_detach(struct pcmcia_device *link)
        dio24_release(link);
 
        /* This points to the parent local_info_t struct */
-       if (link->priv)
-               kfree(link->priv);
+       kfree(link->priv);
 
 }                              /* dio24_cs_detach */
 
@@ -308,9 +298,6 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
                                unsigned int vcc,
                                void *priv_data)
 {
-       win_req_t *req = priv_data;
-       memreq_t map;
-
        if (cfg->index == 0)
                return -ENODEV;
 
@@ -324,44 +311,25 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
                /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               if (pcmcia_request_io(p_dev) != 0)
                        return -ENODEV;
        }
 
-       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
-               cistpl_mem_t *mem =
-                       (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
-               req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
-               req->Attributes |= WIN_ENABLE;
-               req->Base = mem->win[0].host_addr;
-               req->Size = mem->win[0].len;
-               if (req->Size < 0x1000)
-                       req->Size = 0x1000;
-               req->AccessSpeed = 0;
-               if (pcmcia_request_window(p_dev, req, &p_dev->win))
-                       return -ENODEV;
-               map.Page = 0;
-               map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
-                       return -ENODEV;
-       }
        /* If we got this far, we're cool! */
        return 0;
 }
@@ -369,13 +337,12 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
 static void dio24_config(struct pcmcia_device *link)
 {
        int ret;
-       win_req_t req;
 
        printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
 
        dev_dbg(&link->dev, "dio24_config\n");
 
-       ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req);
+       ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL);
        if (ret) {
                dev_warn(&link->dev, "no configuration found\n");
                goto failed;
@@ -397,15 +364,10 @@ static void dio24_config(struct pcmcia_device *link)
        dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                printk(", irq %d", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1 + link->io.NumPorts1 - 1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2 + link->io.NumPorts2 - 1);
-       if (link->win)
-               printk(", mem 0x%06lx-0x%06lx", req.Base,
-                      req.Base + req.Size - 1);
+       if (link->resource[0])
+               printk(" & %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        printk("\n");
 
        return;
@@ -474,7 +436,7 @@ struct pcmcia_driver dio24_cs_driver = {
        .id_table = dio24_cs_ids,
        .owner = THIS_MODULE,
        .drv = {
-               .name = dev_info,
+               .name = "ni_daq_dio24",
                },
 };
 
index 67c8a538802c715bc85926b8d35c752d7caa4f0b..3acf7e62bec47c56a1d40fc2ecffd409f6f3d27a 100644 (file)
@@ -526,7 +526,8 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
        unsigned long dma_flags, isr_flags;
        short lsb, msb;
 
-       printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
+       printk(KERN_ERR "comedi%d: ni_labpc: %s, io 0x%lx", dev->minor,
+                                                               thisboard->name,
               iobase);
        if (irq)
                printk(", irq %u", irq);
@@ -543,7 +544,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
                /* check if io addresses are available */
                if (!request_region(iobase, LABPC_SIZE,
                                    driver_labpc.driver_name)) {
-                       printk("I/O port conflict\n");
+                       printk(KERN_ERR "I/O port conflict\n");
                        return -EIO;
                }
        }
@@ -575,7 +576,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
                        isr_flags |= IRQF_SHARED;
                if (request_irq(irq, labpc_interrupt, isr_flags,
                                driver_labpc.driver_name, dev)) {
-                       printk("unable to allocate irq %u\n", irq);
+                       printk(KERN_ERR "unable to allocate irq %u\n", irq);
                        return -EINVAL;
                }
        }
@@ -583,18 +584,18 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
 
        /* grab dma channel */
        if (dma_chan > 3) {
-               printk(" invalid dma channel %u\n", dma_chan);
+               printk(KERN_ERR " invalid dma channel %u\n", dma_chan);
                return -EINVAL;
        } else if (dma_chan) {
                /* allocate dma buffer */
                devpriv->dma_buffer =
                    kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
                if (devpriv->dma_buffer == NULL) {
-                       printk(" failed to allocate dma buffer\n");
+                       printk(KERN_ERR " failed to allocate dma buffer\n");
                        return -ENOMEM;
                }
                if (request_dma(dma_chan, driver_labpc.driver_name)) {
-                       printk(" failed to allocate dma channel %u\n",
+                       printk(KERN_ERR " failed to allocate dma channel %u\n",
                               dma_chan);
                        return -EINVAL;
                }
@@ -690,7 +691,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
                for (i = 0; i < EEPROM_SIZE; i++)
                        devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
 #ifdef LABPC_DEBUG
-               printk(" eeprom:");
+               printk(KERN_ERR " eeprom:");
                for (i = 0; i < EEPROM_SIZE; i++)
                        printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
                printk("\n");
@@ -732,7 +733,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                iobase = (unsigned long)devpriv->mite->daq_io_addr;
                irq = mite_irq(devpriv->mite);
 #else
-               printk(" this driver has not been built with PCI support.\n");
+               printk(KERN_ERR " this driver has not been built with PCI "
+                                                               "support.\n");
                return -EINVAL;
 #endif
                break;
@@ -742,7 +744,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                return -EINVAL;
                break;
        default:
-               printk("bug! couldn't determine board type\n");
+               printk(KERN_ERR "bug! couldn't determine board type\n");
                return -EINVAL;
                break;
        }
@@ -776,7 +778,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
                        }
                }
        }
-       printk("no device found\n");
+       printk(KERN_ERR "no device found\n");
        mite_list_devices();
        return -EIO;
 }
@@ -784,7 +786,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
 
 int labpc_common_detach(struct comedi_device *dev)
 {
-       printk("comedi%d: ni_labpc: detach\n", dev->minor);
+       printk(KERN_ERR "comedi%d: ni_labpc: detach\n", dev->minor);
 
        if (dev->subdevices)
                subdev_8255_cleanup(dev, dev->subdevices + 2);
@@ -846,7 +848,7 @@ static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
        if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
                return MODE_MULT_CHAN_DOWN;
 
-       printk("ni_labpc: bug! this should never happen\n");
+       printk(KERN_ERR "ni_labpc: bug! this should never happen\n");
 
        return 0;
 }
@@ -902,7 +904,7 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
                        }
                        break;
                default:
-                       printk("ni_labpc: bug! in chanlist check\n");
+                       printk(KERN_ERR "ni_labpc: bug! in chanlist check\n");
                        return 1;
                        break;
                }
@@ -1096,7 +1098,10 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
                        err++;
                }
                break;
-               /*  TRIG_EXT doesn't care since it doesn't trigger off a numbered channel */
+               /*
+                * TRIG_EXT doesn't care since it doesn't
+                * trigger off a numbered channel
+                */
        default:
                break;
        }
@@ -1154,25 +1159,35 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
        /*  setup hardware conversion counter */
        if (cmd->stop_src == TRIG_EXT) {
-               /*  load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0 */
+               /*
+                * load counter a1 with count of 3
+                * (pc+ manual says this is minimum allowed) using mode 0
+                */
                ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
                                         1, 3, 0);
                if (ret < 0) {
                        comedi_error(dev, "error loading counter a1");
                        return -1;
                }
-       } else                  /*  otherwise, just put a1 in mode 0 with no count to set its output low */
+       } else                  /*
+                                * otherwise, just put a1 in mode 0
+                                * with no count to set its output low
+                                */
                devpriv->write_byte(INIT_A1_BITS,
                                    dev->iobase + COUNTER_A_CONTROL_REG);
 
        /*  figure out what method we will use to transfer data */
        if (devpriv->dma_chan &&        /*  need a dma channel allocated */
-           /*  dma unsafe at RT priority, and too much setup time for TRIG_WAKE_EOS for */
+               /*
+                * dma unsafe at RT priority,
+                * and too much setup time for TRIG_WAKE_EOS for
+                */
            (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) == 0 &&
            /*  only available on the isa boards */
            thisboard->bustype == isa_bustype) {
                xfer = isa_dma_transfer;
-       } else if (thisboard->register_layout == labpc_1200_layout &&   /*  pc-plus has no fifo-half full interrupt */
+               /* pc-plus has no fifo-half full interrupt */
+       } else if (thisboard->register_layout == labpc_1200_layout &&
                   /*  wake-end-of-scan should interrupt on fifo not empty */
                   (cmd->flags & TRIG_WAKE_EOS) == 0 &&
                   /*  make sure we are taking more than just a few points */
@@ -1619,7 +1634,10 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                devpriv->command4_bits |= ADC_DIFF_BIT;
        devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
 
-       /* initialize pacer counter output to make sure it doesn't cause any problems */
+       /*
+        * initialize pacer counter output to make sure it doesn't
+        * cause any problems
+        */
        devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
 
        labpc_clear_adc_fifo(dev);
@@ -1844,7 +1862,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
                unsigned int scan_period;
 
                scan_period = labpc_ai_scan_period(cmd);
-               /* calculate cascaded counter values that give desired scan timing */
+               /*
+                * calculate cascaded counter values
+                * that give desired scan timing
+                */
                i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
                                               &(devpriv->divisor_b1),
                                               &(devpriv->divisor_b0),
@@ -1855,7 +1876,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
                unsigned int convert_period;
 
                convert_period = labpc_ai_convert_period(cmd);
-               /* calculate cascaded counter values that give desired conversion timing */
+               /*
+                * calculate cascaded counter values
+                * that give desired conversion timing
+                */
                i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
                                               &(devpriv->divisor_a0),
                                               &(devpriv->divisor_b0),
@@ -2076,9 +2100,56 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
 }
 
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_labpc, labpc_pci_table);
+static int __devinit driver_labpc_pci_probe(struct pci_dev *dev,
+                                           const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_labpc.driver_name);
+}
+
+static void __devexit driver_labpc_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_labpc_pci_driver = {
+       .id_table = labpc_pci_table,
+       .probe = &driver_labpc_pci_probe,
+       .remove = __devexit_p(&driver_labpc_pci_remove)
+};
+
+static int __init driver_labpc_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_labpc);
+       if (retval < 0)
+               return retval;
+
+       driver_labpc_pci_driver.name = (char *)driver_labpc.driver_name;
+       return pci_register_driver(&driver_labpc_pci_driver);
+}
+
+static void __exit driver_labpc_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_labpc_pci_driver);
+       comedi_driver_unregister(&driver_labpc);
+}
+
+module_init(driver_labpc_init_module);
+module_exit(driver_labpc_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_labpc);
+static int __init driver_labpc_init_module(void)
+{
+       return comedi_driver_register(&driver_labpc);
+}
+
+static void __exit driver_labpc_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_labpc);
+}
+
+module_init(driver_labpc_init_module);
+module_exit(driver_labpc_cleanup_module);
 #endif
 
 EXPORT_SYMBOL_GPL(labpc_common_attach);
@@ -2086,3 +2157,7 @@ EXPORT_SYMBOL_GPL(labpc_common_detach);
 EXPORT_SYMBOL_GPL(range_labpc_1200_ai);
 EXPORT_SYMBOL_GPL(labpc_1200_ai_gain_bits);
 EXPORT_SYMBOL_GPL(labpc_1200_is_unipolar);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 163245ebb3115c26c82f32d1205a5b2b6bdf1dae..68c4ecbd93ae83728c422f00da13e273a13d63a1 100644 (file)
@@ -71,7 +71,6 @@ NI manuals:
 #include "comedi_fc.h"
 #include "ni_labpc.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -143,7 +142,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                link = pcmcia_cur_dev;  /* XXX hack */
                if (!link)
                        return -EIO;
-               iobase = link->io.BasePort1;
+               iobase = link->resource[0]->start;
                irq = link->irq;
                break;
        default:
@@ -189,14 +188,6 @@ static void labpc_cs_detach(struct pcmcia_device *);
    less on other parts of the kernel.
 */
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static const dev_info_t dev_info = "daqcard-1200";
-
 struct local_info_t {
        struct pcmcia_device *link;
        int stop;
@@ -286,9 +277,6 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
                                unsigned int vcc,
                                void *priv_data)
 {
-       win_req_t *req = priv_data;
-       memreq_t map;
-
        if (cfg->index == 0)
                return -ENODEV;
 
@@ -302,44 +290,25 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
                /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               if (pcmcia_request_io(p_dev) != 0)
                        return -ENODEV;
        }
 
-       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
-               cistpl_mem_t *mem =
-                       (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
-               req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
-               req->Attributes |= WIN_ENABLE;
-               req->Base = mem->win[0].host_addr;
-               req->Size = mem->win[0].len;
-               if (req->Size < 0x1000)
-                       req->Size = 0x1000;
-               req->AccessSpeed = 0;
-               if (pcmcia_request_window(p_dev, req, &p_dev->win))
-                       return -ENODEV;
-               map.Page = 0;
-               map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
-                       return -ENODEV;
-       }
        /* If we got this far, we're cool! */
        return 0;
 }
@@ -348,11 +317,10 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
 static void labpc_config(struct pcmcia_device *link)
 {
        int ret;
-       win_req_t req;
 
        dev_dbg(&link->dev, "labpc_config\n");
 
-       ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, &req);
+       ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL);
        if (ret) {
                dev_warn(&link->dev, "no configuration found\n");
                goto failed;
@@ -374,15 +342,10 @@ static void labpc_config(struct pcmcia_device *link)
        dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                printk(", irq %d", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1 + link->io.NumPorts1 - 1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2 + link->io.NumPorts2 - 1);
-       if (link->win)
-               printk(", mem 0x%06lx-0x%06lx", req.Base,
-                      req.Base + req.Size - 1);
+       if (link->resource[0])
+               printk(" & %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        printk("\n");
 
        return;
@@ -449,7 +412,7 @@ struct pcmcia_driver labpc_cs_driver = {
        .id_table = labpc_cs_ids,
        .owner = THIS_MODULE,
        .drv = {
-               .name = dev_info,
+               .name = "daqcard-1200",
                },
 };
 
index 3a46f0c0bff905e7df83c80e8a794d67a7a24f53..1f2426352eb57d82cc0c18ba98d738d224fe31cf 100644 (file)
@@ -48,7 +48,6 @@ See the notes in the ni_atmio.o driver.
 #include "ni_stc.h"
 #include "8255.h"
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -261,12 +260,11 @@ static void cs_release(struct pcmcia_device *link);
 static void cs_detach(struct pcmcia_device *);
 
 static struct pcmcia_device *cur_dev = NULL;
-static const dev_info_t dev_info = "ni_mio_cs";
 
 static int cs_attach(struct pcmcia_device *link)
 {
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-       link->io.NumPorts1 = 16;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
+       link->resource[0]->end = 16;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -311,13 +309,12 @@ static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev,
 {
        int base, ret;
 
-       p_dev->io.NumPorts1 = cfg->io.win[0].len;
-       p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
-       p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
+       p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
 
        for (base = 0x000; base < 0x400; base += 0x20) {
-               p_dev->io.BasePort1 = base;
-               ret = pcmcia_request_io(p_dev, &p_dev->io);
+               p_dev->resource[0]->start = base;
+               ret = pcmcia_request_io(p_dev);
                if (!ret)
                        return 0;
        }
@@ -356,7 +353,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                return -EIO;
 
        dev->driver = &driver_ni_mio_cs;
-       dev->iobase = link->io.BasePort1;
+       dev->iobase = link->resource[0]->start;
 
        irq = link->irq;
 
@@ -450,7 +447,7 @@ struct pcmcia_driver ni_mio_cs_driver = {
        .id_table = ni_mio_cs_ids,
        .owner = THIS_MODULE,
        .drv = {
-               .name = dev_info,
+               .name = "ni_mio_cs",
                },
 };
 
index b126638d33b22d57c082fe5c3019083f57a78cac..84a15c34e48449743e8c6efc697fa5cb368ed684 100644 (file)
@@ -1317,4 +1317,40 @@ static int nidio_find_device(struct comedi_device *dev, int bus, int slot)
        return -EIO;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_pcidio, ni_pcidio_pci_table);
+static int __devinit driver_pcidio_pci_probe(struct pci_dev *dev,
+                                            const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_pcidio.driver_name);
+}
+
+static void __devexit driver_pcidio_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pcidio_pci_driver = {
+       .id_table = ni_pcidio_pci_table,
+       .probe = &driver_pcidio_pci_probe,
+       .remove = __devexit_p(&driver_pcidio_pci_remove)
+};
+
+static int __init driver_pcidio_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_pcidio);
+       if (retval < 0)
+               return retval;
+
+       driver_pcidio_pci_driver.name = (char *)driver_pcidio.driver_name;
+       return pci_register_driver(&driver_pcidio_pci_driver);
+}
+
+static void __exit driver_pcidio_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_pcidio_pci_driver);
+       comedi_driver_unregister(&driver_pcidio);
+}
+
+module_init(driver_pcidio_init_module);
+module_exit(driver_pcidio_cleanup_module);
index 577fda84190d858f7c254f20c5d2faed8d5b375c..23a381247285f020afcfd0477529379541fce054 100644 (file)
@@ -1239,7 +1239,43 @@ static struct comedi_driver driver_pcimio = {
        .detach = pcimio_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(driver_pcimio, ni_pci_table)
+static int __devinit driver_pcimio_pci_probe(struct pci_dev *dev,
+                                            const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_pcimio.driver_name);
+}
+
+static void __devexit driver_pcimio_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pcimio_pci_driver = {
+       .id_table = ni_pci_table,
+       .probe = &driver_pcimio_pci_probe,
+       .remove = __devexit_p(&driver_pcimio_pci_remove)
+};
+
+static int __init driver_pcimio_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_pcimio);
+       if (retval < 0)
+               return retval;
+
+       driver_pcimio_pci_driver.name = (char *)driver_pcimio.driver_name;
+       return pci_register_driver(&driver_pcimio_pci_driver);
+}
+
+static void __exit driver_pcimio_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_pcimio_pci_driver);
+       comedi_driver_unregister(&driver_pcimio);
+}
+
+module_init(driver_pcimio_init_module);
+module_exit(driver_pcimio_cleanup_module);
 
 struct ni_private {
 NI_PRIVATE_COMMON};
index 13e5b264ff0d6196a9a2d6a982c8999fcaedaeb8..a9bb6b13dfc46d9deebe35298a7e5dc0a627d873 100644 (file)
@@ -302,7 +302,7 @@ struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device *dev,
                                                                        ni_gpct_register
                                                                        reg),
                                                unsigned (*read_register)
-                                               (struct ni_gpct * counter,
+                                               (struct ni_gpct *counter,
                                                 enum ni_gpct_register reg),
                                                enum ni_gpct_variant variant,
                                                unsigned num_counters)
@@ -332,6 +332,7 @@ struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device *dev,
        counter_dev->num_counters = num_counters;
        return counter_dev;
 }
+EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
 
 void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
 {
@@ -340,6 +341,7 @@ void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
        kfree(counter_dev->counters);
        kfree(counter_dev);
 }
+EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
 
 static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
                                                *counter_dev)
@@ -418,6 +420,7 @@ void ni_tio_init_counter(struct ni_gpct *counter)
                        NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
                        ~0, 0x0);
 }
+EXPORT_SYMBOL_GPL(ni_tio_init_counter);
 
 static unsigned int ni_tio_counter_status(struct ni_gpct *counter)
 {
@@ -446,9 +449,7 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
        if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
                return;
 
-       switch (ni_tio_get_soft_copy(counter,
-                                    counting_mode_reg) & Gi_Counting_Mode_Mask)
-       {
+       switch (ni_tio_get_soft_copy(counter, counting_mode_reg) & Gi_Counting_Mode_Mask) {
        case Gi_Counting_Mode_QuadratureX1_Bits:
        case Gi_Counting_Mode_QuadratureX2_Bits:
        case Gi_Counting_Mode_QuadratureX4_Bits:
@@ -513,9 +514,8 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
                counting_mode_bits |=
                    ((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) <<
                     Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask;
-               if (mode & NI_GPCT_INDEX_ENABLE_BIT) {
+               if (mode & NI_GPCT_INDEX_ENABLE_BIT)
                        counting_mode_bits |= Gi_Index_Mode_Bit;
-               }
                ni_tio_set_bits(counter,
                                NITIO_Gi_Counting_Mode_Reg(counter->
                                                           counter_index),
@@ -529,12 +529,10 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
                        (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) <<
                        Gi_Up_Down_Shift);
 
-       if (mode & NI_GPCT_OR_GATE_BIT) {
+       if (mode & NI_GPCT_OR_GATE_BIT)
                input_select_bits |= Gi_Or_Gate_Bit;
-       }
-       if (mode & NI_GPCT_INVERT_OUTPUT_BIT) {
+       if (mode & NI_GPCT_INVERT_OUTPUT_BIT)
                input_select_bits |= Gi_Output_Polarity_Bit;
-       }
        ni_tio_set_bits(counter,
                        NITIO_Gi_Input_Select_Reg(counter->counter_index),
                        Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit |
@@ -600,6 +598,7 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
                                  0, 0, command_transient_bits);
        return 0;
 }
+EXPORT_SYMBOL_GPL(ni_tio_arm);
 
 static unsigned ni_660x_source_select_bits(unsigned int clock_source)
 {
@@ -706,7 +705,7 @@ static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
                }
                if (i <= ni_m_series_max_pfi_channel)
                        break;
-               printk("invalid clock source 0x%lx\n",
+               printk(KERN_ERR "invalid clock source 0x%lx\n",
                       (unsigned long)clock_source);
                BUG();
                ni_m_series_clock = 0;
@@ -1026,14 +1025,12 @@ static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
        const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask;
        unsigned mode_values = 0;
 
-       if (gate_source & CR_INVERT) {
+       if (gate_source & CR_INVERT)
                mode_values |= Gi_Gate_Polarity_Bit;
-       }
-       if (gate_source & CR_EDGE) {
+       if (gate_source & CR_EDGE)
                mode_values |= Gi_Rising_Edge_Gating_Bits;
-       } else {
+       else
                mode_values |= Gi_Level_Gating_Bits;
-       }
        ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
                        mode_mask, mode_values);
 }
@@ -1290,6 +1287,7 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
        }
        return 0;
 }
+EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);
 
 static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
                                unsigned int source)
@@ -1531,12 +1529,10 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
                        BUG();
                        break;
                }
-               if (mode_bits & Gi_Gate_Polarity_Bit) {
+               if (mode_bits & Gi_Gate_Polarity_Bit)
                        *gate_source |= CR_INVERT;
-               }
-               if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+               if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits)
                        *gate_source |= CR_EDGE;
-               }
                break;
        case 1:
                if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits
@@ -1572,9 +1568,8 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
                        *gate_source |= CR_INVERT;
                }
                /* second gate can't have edge/level mode set independently */
-               if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+               if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits)
                        *gate_source |= CR_EDGE;
-               }
                break;
        default:
                return -EINVAL;
@@ -1627,6 +1622,7 @@ int ni_tio_insn_config(struct ni_gpct *counter,
        }
        return -EINVAL;
 }
+EXPORT_SYMBOL_GPL(ni_tio_insn_config);
 
 int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn *insn,
                 unsigned int *data)
@@ -1681,6 +1677,7 @@ int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn *insn,
        };
        return 0;
 }
+EXPORT_SYMBOL_GPL(ni_tio_rinsn);
 
 static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
 {
@@ -1688,11 +1685,10 @@ static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
                                            NITIO_Gxx_Status_Reg(counter->
                                                                 counter_index));
 
-       if (bits & Gi_Next_Load_Source_Bit(counter->counter_index)) {
+       if (bits & Gi_Next_Load_Source_Bit(counter->counter_index))
                return NITIO_Gi_LoadB_Reg(counter->counter_index);
-       } else {
+       else
                return NITIO_Gi_LoadA_Reg(counter->counter_index);
-       }
 }
 
 int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn *insn,
@@ -1735,12 +1731,4 @@ int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn *insn,
        }
        return 0;
 }
-
-EXPORT_SYMBOL_GPL(ni_tio_rinsn);
 EXPORT_SYMBOL_GPL(ni_tio_winsn);
-EXPORT_SYMBOL_GPL(ni_tio_insn_config);
-EXPORT_SYMBOL_GPL(ni_tio_init_counter);
-EXPORT_SYMBOL_GPL(ni_tio_arm);
-EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);
-EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
-EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
index a499f7070f7201bfc5313f8087ae0e804e974e8b..b44386a6b63620451b2f307aac64e48beec2a58f 100644 (file)
@@ -171,7 +171,18 @@ static struct comedi_driver driver_pcl711 = {
        .offset = sizeof(struct pcl711_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcl711);
+static int __init driver_pcl711_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl711);
+}
+
+static void __exit driver_pcl711_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl711);
+}
+
+module_init(driver_pcl711_init_module);
+module_exit(driver_pcl711_cleanup_module);
 
 struct pcl711_private {
 
@@ -270,7 +281,7 @@ static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
                                goto ok;
                        udelay(1);
                }
-               printk("comedi%d: pcl711: A/D timeout\n", dev->minor);
+               printk(KERN_ERR "comedi%d: pcl711: A/D timeout\n", dev->minor);
                return -ETIME;
 
 ok:
@@ -505,7 +516,7 @@ static int pcl711_do_insn_bits(struct comedi_device *dev,
 /*  Free any resources that we have claimed  */
 static int pcl711_detach(struct comedi_device *dev)
 {
-       printk("comedi%d: pcl711: remove\n", dev->minor);
+       printk(KERN_INFO "comedi%d: pcl711: remove\n", dev->minor);
 
        if (dev->irq)
                free_irq(dev->irq, dev);
@@ -527,7 +538,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        /* claim our I/O space */
 
        iobase = it->options[0];
-       printk("comedi%d: pcl711: 0x%04lx ", dev->minor, iobase);
+       printk(KERN_INFO "comedi%d: pcl711: 0x%04lx ", dev->minor, iobase);
        if (!request_region(iobase, PCL711_SIZE, "pcl711")) {
                printk("I/O port conflict\n");
                return -EIO;
@@ -542,15 +553,15 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        /* grab our IRQ */
        irq = it->options[1];
        if (irq > this_board->maxirq) {
-               printk("irq out of range\n");
+               printk(KERN_ERR "irq out of range\n");
                return -EINVAL;
        }
        if (irq) {
                if (request_irq(irq, pcl711_interrupt, 0, "pcl711", dev)) {
-                       printk("unable to allocate irq %u\n", irq);
+                       printk(KERN_ERR "unable to allocate irq %u\n", irq);
                        return -EINVAL;
                } else {
-                       printk("( irq = %u )\n", irq);
+                       printk(KERN_INFO "( irq = %u )\n", irq);
                }
        }
        dev->irq = irq;
@@ -624,7 +635,11 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        outb(0, dev->iobase + PCL711_DA1_LO);
        outb(0, dev->iobase + PCL711_DA1_HI);
 
-       printk("\n");
+       printk(KERN_INFO "\n");
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 0f103c328064e964262b5812d6857454c15b6393..396a058bb67dc242721408498dd2734370e145a6 100644 (file)
@@ -93,7 +93,18 @@ static struct comedi_driver driver_pcl724 = {
        .offset = sizeof(struct pcl724_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcl724);
+static int __init driver_pcl724_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl724);
+}
+
+static void __exit driver_pcl724_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl724);
+}
+
+module_init(driver_pcl724_init_module);
+module_exit(driver_pcl724_cleanup_module);
 
 static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
 {
@@ -221,3 +232,7 @@ static int pcl724_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 60261f4ba5b40a3100e3322f36aac8b9cce2aabd..24b223ca43993cee11266800457bd71b83d37e8c 100644 (file)
@@ -30,7 +30,18 @@ static struct comedi_driver driver_pcl725 = {
        .detach = pcl725_detach,
 };
 
-COMEDI_INITCLEANUP(driver_pcl725);
+static int __init driver_pcl725_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl725);
+}
+
+static void __exit driver_pcl725_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl725);
+}
+
+module_init(driver_pcl725_init_module);
+module_exit(driver_pcl725_cleanup_module);
 
 static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
                          struct comedi_insn *insn, unsigned int *data)
@@ -110,3 +121,7 @@ static int pcl725_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 6a1a9790a9072109168b009a6e56ddf98ce21abe..897cd808eeb77f16a6ebf64701458c870fd5fbb0 100644 (file)
@@ -162,7 +162,18 @@ static struct comedi_driver driver_pcl726 = {
        .offset = sizeof(struct pcl726_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcl726);
+static int __init driver_pcl726_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl726);
+}
+
+static void __exit driver_pcl726_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl726);
+}
+
+module_init(driver_pcl726_init_module);
+module_exit(driver_pcl726_cleanup_module);
 
 struct pcl726_private {
 
@@ -381,3 +392,7 @@ static int pcl726_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index e5e7bed21de050cca644276d8930b4c3e5175ad0..c9682d614e0e3daa688c51a67c1965fdc9e9f817 100644 (file)
@@ -55,7 +55,18 @@ static struct comedi_driver driver_pcl730 = {
        .offset = sizeof(struct pcl730_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcl730);
+static int __init driver_pcl730_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl730);
+}
+
+static void __exit driver_pcl730_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl730);
+}
+
+module_init(driver_pcl730_init_module);
+module_exit(driver_pcl730_cleanup_module);
 
 static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
                          struct comedi_insn *insn, unsigned int *data)
@@ -166,3 +177,7 @@ static int pcl730_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 1ddc19c705a6b186f9aab5fb59f8be06bdee1a8a..c6dce4a1425e1d7ed7880429feb308b9ef0636b0 100644 (file)
  *  card:   A-823PGH, A-823PGL, A-826PG
  * driver:  a823pgh,  a823pgl,  a826pg
  */
+
 /*
-Driver: pcl812
-Description: Advantech PCL-812/PG, PCL-813/B,
            ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216,
            ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG,
            ICP DAS ISO-813
-Author: Michal Dobes <dobes@tesnet.cz>
-Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg),
-  PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg),
-  ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216),
-  [ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl),
-  A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl),
-  A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg)
-Updated: Mon, 06 Aug 2007 12:03:15 +0100
-Status: works (I hope. My board fire up under my hands
              and I cann't test all features.)
-
-This driver supports insn and cmd interfaces. Some boards support only insn
-becouse their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813).
-Data transfer over DMA is supported only when you measure only one
-channel, this is too hardware limitation of these boards.
-
-Options for PCL-812:
-  [0] - IO Base
-  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
-  [2] - DMA  (0=disable, 1, 3)
-  [3] - 0=trigger source is internal 8253 with 2MHz clock
-        1=trigger source is external
-  [4] - 0=A/D input range is +/-10V
-        1=A/D input range is +/-5V
-        2=A/D input range is +/-2.5V
-        3=A/D input range is +/-1.25V
-        4=A/D input range is +/-0.625V
-        5=A/D input range is +/-0.3125V
-  [5] - 0=D/A outputs 0-5V  (internal reference -5V)
-        1=D/A outputs 0-10V (internal reference -10V)
-        2=D/A outputs unknown (external reference)
-
-Options for PCL-812PG, ACL-8112PG:
-  [0] - IO Base
-  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
-  [2] - DMA  (0=disable, 1, 3)
-  [3] - 0=trigger source is internal 8253 with 2MHz clock
-        1=trigger source is external
-  [4] - 0=A/D have max +/-5V input
-        1=A/D have max +/-10V input
-  [5] - 0=D/A outputs 0-5V  (internal reference -5V)
-        1=D/A outputs 0-10V (internal reference -10V)
-        2=D/A outputs unknown (external reference)
-
-Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
-  [0] - IO Base
-  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
-  [2] - DMA  (0=disable, 1, 3)
-  [3] - 0=trigger source is internal 8253 with 2MHz clock
-        1=trigger source is external
-  [4] - 0=A/D channels are S.E.
-        1=A/D channels are DIFF
-  [5] - 0=D/A outputs 0-5V  (internal reference -5V)
-        1=D/A outputs 0-10V (internal reference -10V)
-        2=D/A outputs unknown (external reference)
-
-Options for A-821PGL/PGH:
-  [0] - IO Base
-  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
-  [2] - 0=A/D channels are S.E.
-        1=A/D channels are DIFF
-  [3] - 0=D/A output 0-5V  (internal reference -5V)
-        1=D/A output 0-10V (internal reference -10V)
-
-Options for A-821PGL-NDA:
-  [0] - IO Base
-  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
-  [2] - 0=A/D channels are S.E.
-        1=A/D channels are DIFF
-
-Options for PCL-813:
-  [0] - IO Base
-
-Options for PCL-813B:
-  [0] - IO Base
-  [1] - 0= bipolar inputs
-        1= unipolar inputs
-
-Options for ACL-8113, ISO-813:
-  [0] - IO Base
-  [1] - 0= 10V bipolar inputs
-        1= 10V unipolar inputs
-        2= 20V bipolar inputs
-        3= 20V unipolar inputs
-*/
+ * Driver: pcl812
+ * Description: Advantech PCL-812/PG, PCL-813/B,
*          ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216,
*          ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG,
*          ICP DAS ISO-813
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ * Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg),
*     PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg),
*     ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216),
*     [ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl),
*     A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl),
*     A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg)
+ * Updated: Mon, 06 Aug 2007 12:03:15 +0100
+ * Status: works (I hope. My board fire up under my hands
*            and I cann't test all features.)
+ *
+ * This driver supports insn and cmd interfaces. Some boards support only insn
+ * becouse their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813).
+ * Data transfer over DMA is supported only when you measure only one
+ * channel, this is too hardware limitation of these boards.
+ *
+ * Options for PCL-812:
*   [0] - IO Base
*   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
*   [2] - DMA  (0=disable, 1, 3)
*   [3] - 0=trigger source is internal 8253 with 2MHz clock
*         1=trigger source is external
*   [4] - 0=A/D input range is +/-10V
       1=A/D input range is +/-5V
       2=A/D input range is +/-2.5V
       3=A/D input range is +/-1.25V
       4=A/D input range is +/-0.625V
       5=A/D input range is +/-0.3125V
*   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
       1=D/A outputs 0-10V (internal reference -10V)
       2=D/A outputs unknown (external reference)
+ *
+ * Options for PCL-812PG, ACL-8112PG:
*   [0] - IO Base
*   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
*   [2] - DMA  (0=disable, 1, 3)
*   [3] - 0=trigger source is internal 8253 with 2MHz clock
       1=trigger source is external
*   [4] - 0=A/D have max +/-5V input
       1=A/D have max +/-10V input
*   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
       1=D/A outputs 0-10V (internal reference -10V)
       2=D/A outputs unknown (external reference)
+ *
+ * Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
*   [0] - IO Base
*   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
*   [2] - DMA  (0=disable, 1, 3)
*   [3] - 0=trigger source is internal 8253 with 2MHz clock
       1=trigger source is external
*   [4] - 0=A/D channels are S.E.
       1=A/D channels are DIFF
*   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
       1=D/A outputs 0-10V (internal reference -10V)
       2=D/A outputs unknown (external reference)
+ *
+ * Options for A-821PGL/PGH:
*   [0] - IO Base
*   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
*   [2] - 0=A/D channels are S.E.
       1=A/D channels are DIFF
*   [3] - 0=D/A output 0-5V  (internal reference -5V)
       1=D/A output 0-10V (internal reference -10V)
+ *
+ * Options for A-821PGL-NDA:
*   [0] - IO Base
*   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
*   [2] - 0=A/D channels are S.E.
       1=A/D channels are DIFF
+ *
+ * Options for PCL-813:
*   [0] - IO Base
+ *
+ * Options for PCL-813B:
*   [0] - IO Base
*   [1] - 0= bipolar inputs
       1= unipolar inputs
+ *
+ * Options for ACL-8113, ISO-813:
*   [0] - IO Base
*   [1] - 0= 10V bipolar inputs
       1= 10V unipolar inputs
       2= 20V bipolar inputs
       3= 20V unipolar inputs
+ */
 
 #include <linux/interrupt.h>
 #include <linux/gfp.h>
@@ -117,49 +118,50 @@ Options for ACL-8113, ISO-813:
 
 #include "8253.h"
 
-#undef PCL812_EXTDEBUG         /* if this is defined then a lot of messages is printed */
+/* if this is defined then a lot of messages is printed */
+#undef PCL812_EXTDEBUG
 
 /* hardware types of the cards */
-#define boardPCL812PG           0      /* and ACL-8112PG */
-#define boardPCL813B            1
-#define boardPCL812             2
-#define boardPCL813             3
-#define boardISO813             5
-#define boardACL8113            6
-#define boardACL8112            7      /* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */
-#define boardACL8216            8      /* and ICP DAS A-826PG */
-#define boardA821               9      /* PGH, PGL, PGL/NDA versions */
-
-#define PCLx1x_IORANGE                 16
-
-#define PCL812_CTR0             0
-#define PCL812_CTR1             1
-#define PCL812_CTR2             2
-#define PCL812_CTRCTL           3
-#define PCL812_AD_LO            4
-#define PCL812_DA1_LO           4
-#define PCL812_AD_HI            5
-#define PCL812_DA1_HI           5
-#define PCL812_DA2_LO           6
-#define PCL812_DI_LO            6
-#define PCL812_DA2_HI           7
-#define PCL812_DI_HI            7
-#define PCL812_CLRINT           8
-#define PCL812_GAIN             9
-#define PCL812_MUX             10
-#define PCL812_MODE            11
-#define PCL812_CNTENABLE       10
-#define PCL812_SOFTTRIG        12
-#define PCL812_DO_LO           13
-#define PCL812_DO_HI           14
-
-#define PCL812_DRDY            0x10    /* =0 data ready */
-
-#define ACL8216_STATUS                  8      /* 5. bit signalize data ready */
-
-#define ACL8216_DRDY           0x20    /* =0 data ready */
-
-#define MAX_CHANLIST_LEN       256     /* length of scan list */
+#define boardPCL812PG        0 /* and ACL-8112PG */
+#define boardPCL813B         1
+#define boardPCL812          2
+#define boardPCL813          3
+#define boardISO813          5
+#define boardACL8113         6
+#define boardACL8112         7 /* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */
+#define boardACL8216         8 /* and ICP DAS A-826PG */
+#define boardA821            9 /* PGH, PGL, PGL/NDA versions */
+
+#define PCLx1x_IORANGE      16
+
+#define PCL812_CTR0          0
+#define PCL812_CTR1          1
+#define PCL812_CTR2          2
+#define PCL812_CTRCTL        3
+#define PCL812_AD_LO         4
+#define PCL812_DA1_LO        4
+#define PCL812_AD_HI         5
+#define PCL812_DA1_HI        5
+#define PCL812_DA2_LO        6
+#define PCL812_DI_LO         6
+#define PCL812_DA2_HI        7
+#define PCL812_DI_HI         7
+#define PCL812_CLRINT        8
+#define PCL812_GAIN          9
+#define PCL812_MUX          10
+#define PCL812_MODE         11
+#define PCL812_CNTENABLE     10
+#define PCL812_SOFTTRIG             12
+#define PCL812_DO_LO        13
+#define PCL812_DO_HI        14
+
+#define PCL812_DRDY       0x10 /* =0 data ready */
+
+#define ACL8216_STATUS       8 /* 5. bit signalize data ready */
+
+#define ACL8216_DRDY      0x20 /* =0 data ready */
+
+#define MAX_CHANLIST_LEN    256        /* length of scan list */
 
 static const struct comedi_lrange range_pcl812pg_ai = { 5, {
                                                            BIP_RANGE(5),
@@ -407,7 +409,18 @@ static struct comedi_driver driver_pcl812 = {
        .offset = sizeof(struct pcl812_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcl812);
+static int __init driver_pcl812_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl812);
+}
+
+static void __exit driver_pcl812_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl812);
+}
+
+module_init(driver_pcl812_init_module);
+module_exit(driver_pcl812_cleanup_module);
 
 struct pcl812_private {
 
@@ -466,10 +479,13 @@ static int pcl812_ai_insn_read(struct comedi_device *dev,
        int n;
        int timeout, hi;
 
-       outb(devpriv->mode_reg_int | 1, dev->iobase + PCL812_MODE);     /* select software trigger */
-       setup_range_channel(dev, s, insn->chanspec, 1); /*  select channel and renge */
+       /* select software trigger */
+       outb(devpriv->mode_reg_int | 1, dev->iobase + PCL812_MODE);
+       /*  select channel and renge */
+       setup_range_channel(dev, s, insn->chanspec, 1);
        for (n = 0; n < insn->n; n++) {
-               outb(255, dev->iobase + PCL812_SOFTTRIG);       /* start conversion */
+               /* start conversion */
+               outb(255, dev->iobase + PCL812_SOFTTRIG);
                udelay(5);
                timeout = 50;   /* wait max 50us, it must finish under 33us */
                while (timeout--) {
@@ -501,10 +517,13 @@ static int acl8216_ai_insn_read(struct comedi_device *dev,
        int n;
        int timeout;
 
-       outb(1, dev->iobase + PCL812_MODE);     /* select software trigger */
-       setup_range_channel(dev, s, insn->chanspec, 1); /*  select channel and renge */
+       /* select software trigger */
+       outb(1, dev->iobase + PCL812_MODE);
+       /*  select channel and renge */
+       setup_range_channel(dev, s, insn->chanspec, 1);
        for (n = 0; n < insn->n; n++) {
-               outb(255, dev->iobase + PCL812_SOFTTRIG);       /* start conversion */
+               /* start conversion */
+               outb(255, dev->iobase + PCL812_SOFTTRIG);
                udelay(5);
                timeout = 50;   /* wait max 50us, it must finish under 33us */
                while (timeout--) {
@@ -558,9 +577,8 @@ static int pcl812_ao_insn_read(struct comedi_device *dev,
        int chan = CR_CHAN(insn->chanspec);
        int i;
 
-       for (i = 0; i < insn->n; i++) {
+       for (i = 0; i < insn->n; i++)
                data[i] = devpriv->ao_readback[chan];
-       }
 
        return i;
 }
@@ -608,14 +626,15 @@ static int pcl812_do_insn_bits(struct comedi_device *dev,
 */
 static void pcl812_cmdtest_out(int e, struct comedi_cmd *cmd)
 {
-       printk("pcl812 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+       printk(KERN_INFO "pcl812 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
               cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
-       printk("pcl812 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+       printk(KERN_INFO "pcl812 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
               cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
-       printk("pcl812 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
-              cmd->scan_end_src);
-       printk("pcl812 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
-              cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+       printk(KERN_INFO "pcl812 e=%d stopsrc=%x scanend=%x\n", e,
+              cmd->stop_src, cmd->scan_end_src);
+       printk(KERN_INFO "pcl812 e=%d stoparg=%d scanendarg=%d "
+              "chanlistlen=%d\n", e, cmd->stop_arg, cmd->scan_end_arg,
+              cmd->chanlist_len);
 }
 #endif
 
@@ -645,11 +664,11 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
                err++;
 
        tmp = cmd->convert_src;
-       if (devpriv->use_ext_trg) {
+       if (devpriv->use_ext_trg)
                cmd->convert_src &= TRIG_EXT;
-       } else {
+       else
                cmd->convert_src &= TRIG_TIMER;
-       }
+
        if (!cmd->convert_src || tmp != cmd->convert_src)
                err++;
 
@@ -673,7 +692,10 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
                return 1;
        }
 
-       /* step 2: make sure trigger sources are unique and mutually compatible */
+       /*
+        * step 2: make sure trigger sources are
+        * unique and mutually compatible
+        */
 
        if (cmd->start_src != TRIG_NOW) {
                cmd->start_src = TRIG_NOW;
@@ -807,7 +829,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        struct comedi_cmd *cmd = &s->async->cmd;
 
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: BGN: pcl812_ai_cmd(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: BGN: pcl812_ai_cmd(...)\n");
 #endif
 
        if (cmd->start_src != TRIG_NOW)
@@ -842,13 +864,15 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_n_chan = cmd->chanlist_len;
        memcpy(devpriv->ai_chanlist, cmd->chanlist,
               sizeof(unsigned int) * cmd->scan_end_arg);
-       setup_range_channel(dev, s, devpriv->ai_chanlist[0], 1);        /*  select first channel and range */
+       /*  select first channel and range */
+       setup_range_channel(dev, s, devpriv->ai_chanlist[0], 1);
 
        if (devpriv->dma) {     /*  check if we can use DMA transfer */
                devpriv->ai_dma = 1;
                for (i = 1; i < devpriv->ai_n_chan; i++)
                        if (devpriv->ai_chanlist[0] != devpriv->ai_chanlist[i]) {
-                               devpriv->ai_dma = 0;    /*  we cann't use DMA :-( */
+                               /*  we cann't use DMA :-( */
+                               devpriv->ai_dma = 0;
                                break;
                        }
        } else
@@ -869,14 +893,18 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_poll_ptr = 0;
        s->async->cur_chan = 0;
 
-       if ((devpriv->ai_flags & TRIG_WAKE_EOS)) {      /*  don't we want wake up every scan? */
+       /*  don't we want wake up every scan? */
+       if ((devpriv->ai_flags & TRIG_WAKE_EOS)) {
                devpriv->ai_eos = 1;
+
+               /*  DMA is useless for this situation */
                if (devpriv->ai_n_chan == 1)
-                       devpriv->ai_dma = 0;    /*  DMA is useless for this situation */
+                       devpriv->ai_dma = 0;
        }
 
        if (devpriv->ai_dma) {
-               if (devpriv->ai_eos) {  /*  we use EOS, so adapt DMA buffer to one scan */
+               /*  we use EOS, so adapt DMA buffer to one scan */
+               if (devpriv->ai_eos) {
                        devpriv->dmabytestomove[0] =
                            devpriv->ai_n_chan * sizeof(short);
                        devpriv->dmabytestomove[1] =
@@ -894,9 +922,17 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                        if (devpriv->ai_neverending) {
                                devpriv->dma_runs_to_end = 1;
                        } else {
-                               bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short); /*  how many samples we must transfer? */
-                               devpriv->dma_runs_to_end = bytes / devpriv->dmabytestomove[0];  /*  how many DMA pages we must fill */
-                               devpriv->last_dma_run = bytes % devpriv->dmabytestomove[0];     /* on last dma transfer must be moved */
+                               /*  how many samples we must transfer? */
+                               bytes = devpriv->ai_n_chan *
+                                       devpriv->ai_scans * sizeof(short);
+
+                               /*  how many DMA pages we must fill */
+                               devpriv->dma_runs_to_end =
+                                       bytes / devpriv->dmabytestomove[0];
+
+                               /* on last dma transfer must be moved */
+                               devpriv->last_dma_run =
+                                       bytes % devpriv->dmabytestomove[0];
                                if (devpriv->dma_runs_to_end == 0)
                                        devpriv->dmabytestomove[0] =
                                            devpriv->last_dma_run;
@@ -934,14 +970,13 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                break;
        }
 
-       if (devpriv->ai_dma) {
-               outb(devpriv->mode_reg_int | 2, dev->iobase + PCL812_MODE);     /*  let's go! */
-       } else {
-               outb(devpriv->mode_reg_int | 6, dev->iobase + PCL812_MODE);     /*  let's go! */
-       }
+       if (devpriv->ai_dma)                                    /*  let's go! */
+               outb(devpriv->mode_reg_int | 2, dev->iobase + PCL812_MODE);
+       else                                                    /*  let's go! */
+               outb(devpriv->mode_reg_int | 6, dev->iobase + PCL812_MODE);
 
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: END: pcl812_ai_cmd(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: END: pcl812_ai_cmd(...)\n");
 #endif
 
        return 0;
@@ -983,7 +1018,8 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
 
        if (err) {
                printk
-                   ("comedi%d: pcl812: (%s at 0x%lx) A/D cmd IRQ without DRDY!\n",
+                   ("comedi%d: pcl812: (%s at 0x%lx) "
+                    "A/D cmd IRQ without DRDY!\n",
                     dev->minor, dev->board_name, dev->iobase);
                pcl812_ai_cancel(dev, s);
                s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
@@ -1009,7 +1045,8 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
        if (next_chan == 0) {   /* one scan done */
                devpriv->ai_act_scan++;
                if (!(devpriv->ai_neverending))
-                       if (devpriv->ai_act_scan >= devpriv->ai_scans) {        /* all data sampled */
+                                                       /* all data sampled */
+                       if (devpriv->ai_act_scan >= devpriv->ai_scans) {
                                pcl812_ai_cancel(dev, s);
                                s->async->events |= COMEDI_CB_EOA;
                        }
@@ -1030,14 +1067,16 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
 
        s->async->events = 0;
        for (i = len; i; i--) {
-               comedi_buf_put(s->async, ptr[bufptr++]);        /*  get one sample */
+                                                       /*  get one sample */
+               comedi_buf_put(s->async, ptr[bufptr++]);
 
                s->async->cur_chan++;
                if (s->async->cur_chan >= devpriv->ai_n_chan) {
                        s->async->cur_chan = 0;
                        devpriv->ai_act_scan++;
                        if (!devpriv->ai_neverending)
-                               if (devpriv->ai_act_scan >= devpriv->ai_scans) {        /* all data sampled */
+                                                       /* all data sampled */
+                               if (devpriv->ai_act_scan >= devpriv->ai_scans) {
                                        pcl812_ai_cancel(dev, s);
                                        s->async->events |= COMEDI_CB_EOA;
                                        break;
@@ -1060,7 +1099,7 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
        short *ptr;
 
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: BGN: interrupt_pcl812_ai_dma(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: BGN: interrupt_pcl812_ai_dma(...)\n");
 #endif
        ptr = (short *)devpriv->dmabuf[devpriv->next_dma_buf];
        len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
@@ -1095,7 +1134,7 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
        transfer_from_dma_buf(dev, s, ptr, bufptr, len);
 
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: END: interrupt_pcl812_ai_dma(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: END: interrupt_pcl812_ai_dma(...)\n");
 #endif
        return IRQ_HANDLED;
 }
@@ -1111,11 +1150,10 @@ static irqreturn_t interrupt_pcl812(int irq, void *d)
                comedi_error(dev, "spurious interrupt");
                return IRQ_HANDLED;
        }
-       if (devpriv->ai_dma) {
+       if (devpriv->ai_dma)
                return interrupt_pcl812_ai_dma(irq, d);
-       } else {
+       else
                return interrupt_pcl812_ai_int(irq, d);
-       };
 }
 
 /*
@@ -1132,7 +1170,8 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
        spin_lock_irqsave(&dev->spinlock, flags);
 
        for (i = 0; i < 10; i++) {
-               top1 = get_dma_residue(devpriv->ai_dma);        /*  where is now DMA */
+               /*  where is now DMA */
+               top1 = get_dma_residue(devpriv->ai_dma);
                top2 = get_dma_residue(devpriv->ai_dma);
                if (top1 == top2)
                        break;
@@ -1142,8 +1181,8 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
                spin_unlock_irqrestore(&dev->spinlock, flags);
                return 0;
        }
-
-       top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1;       /*  where is now DMA in buffer */
+       /*  where is now DMA in buffer */
+       top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1;
        top1 >>= 1;             /*  sample position */
        top2 = top1 - devpriv->ai_poll_ptr;
        if (top2 < 1) {         /*  no new samples */
@@ -1171,7 +1210,9 @@ static void setup_range_channel(struct comedi_device *dev,
                                unsigned int rangechan, char wait)
 {
        unsigned char chan_reg = CR_CHAN(rangechan);    /*  normal board */
-       unsigned char gain_reg = CR_RANGE(rangechan) + devpriv->range_correction;       /*  gain index */
+                                                       /*  gain index */
+       unsigned char gain_reg = CR_RANGE(rangechan) +
+                                devpriv->range_correction;
 
        if ((chan_reg == devpriv->old_chan_reg)
            && (gain_reg == devpriv->old_gain_reg))
@@ -1184,20 +1225,25 @@ static void setup_range_channel(struct comedi_device *dev,
                if (devpriv->use_diff) {
                        chan_reg = chan_reg | 0x30;     /*  DIFF inputs */
                } else {
-                       if (chan_reg & 0x80) {
-                               chan_reg = chan_reg | 0x20;     /*  SE inputs 8-15 */
-                       } else {
-                               chan_reg = chan_reg | 0x10;     /*  SE inputs 0-7 */
-                       }
+                       if (chan_reg & 0x80)
+                                                       /*  SE inputs 8-15 */
+                               chan_reg = chan_reg | 0x20;
+                       else
+                                                       /*  SE inputs 0-7 */
+                               chan_reg = chan_reg | 0x10;
                }
        }
 
        outb(chan_reg, dev->iobase + PCL812_MUX);       /* select channel */
        outb(gain_reg, dev->iobase + PCL812_GAIN);      /* select gain */
 
-       if (wait) {
-               udelay(devpriv->max_812_ai_mode0_rangewait);    /*  XXX this depends on selected range and can be very long for some high gain ranges! */
-       }
+
+       if (wait)
+               /*
+                * XXX this depends on selected range and can be very long for
+                * some high gain ranges!
+                */
+               udelay(devpriv->max_812_ai_mode0_rangewait);
 }
 
 /*
@@ -1207,8 +1253,8 @@ static void start_pacer(struct comedi_device *dev, int mode,
                        unsigned int divisor1, unsigned int divisor2)
 {
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode, divisor1,
-              divisor2);
+       printk(KERN_DEBUG "pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode,
+              divisor1, divisor2);
 #endif
        outb(0xb4, dev->iobase + PCL812_CTRCTL);
        outb(0x74, dev->iobase + PCL812_CTRCTL);
@@ -1221,7 +1267,7 @@ static void start_pacer(struct comedi_device *dev, int mode,
                outb((divisor1 >> 8) & 0xff, dev->iobase + PCL812_CTR1);
        }
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: END: start_pacer(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: END: start_pacer(...)\n");
 #endif
 }
 
@@ -1252,16 +1298,17 @@ static int pcl812_ai_cancel(struct comedi_device *dev,
                            struct comedi_subdevice *s)
 {
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: BGN: pcl812_ai_cancel(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: BGN: pcl812_ai_cancel(...)\n");
 #endif
        if (devpriv->ai_dma)
                disable_dma(devpriv->dma);
        outb(0, dev->iobase + PCL812_CLRINT);   /* clear INT request */
-       outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);     /* Stop A/D */
+                                                       /* Stop A/D */
+       outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
        start_pacer(dev, -1, 0, 0);     /*  stop 8254 */
        outb(0, dev->iobase + PCL812_CLRINT);   /* clear INT request */
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: END: pcl812_ai_cancel(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: END: pcl812_ai_cancel(...)\n");
 #endif
        return 0;
 }
@@ -1272,7 +1319,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev,
 static void pcl812_reset(struct comedi_device *dev)
 {
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: BGN: pcl812_reset(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: BGN: pcl812_reset(...)\n");
 #endif
        outb(0, dev->iobase + PCL812_MUX);
        outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN);
@@ -1304,7 +1351,7 @@ static void pcl812_reset(struct comedi_device *dev)
        }
        udelay(5);
 #ifdef PCL812_EXTDEBUG
-       printk("pcl812 EDBG: END: pcl812_reset(...)\n");
+       printk(KERN_DEBUG "pcl812 EDBG: END: pcl812_reset(...)\n");
 #endif
 }
 
@@ -1322,8 +1369,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        int n_subdevices;
 
        iobase = it->options[0];
-       printk("comedi%d: pcl812:  board=%s, ioport=0x%03lx", dev->minor,
-              this_board->name, iobase);
+       printk(KERN_INFO "comedi%d: pcl812:  board=%s, ioport=0x%03lx",
+              dev->minor, this_board->name, iobase);
 
        if (!request_region(iobase, this_board->io_range, "pcl812")) {
                printk("I/O port conflict\n");
@@ -1345,18 +1392,18 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                if (irq) {      /* we want to use IRQ */
                        if (((1 << irq) & this_board->IRQbits) == 0) {
                                printk
-                                   (", IRQ %u is out of allowed range, DISABLING IT",
-                                    irq);
+                                   (", IRQ %u is out of allowed range, "
+                                    "DISABLING IT", irq);
                                irq = 0;        /* Bad IRQ */
                        } else {
                                if (request_irq
                                    (irq, interrupt_pcl812, 0, "pcl812", dev)) {
                                        printk
-                                           (", unable to allocate IRQ %u, DISABLING IT",
-                                            irq);
+                                           (", unable to allocate IRQ %u, "
+                                            "DISABLING IT", irq);
                                        irq = 0;        /* Can't use IRQ */
                                } else {
-                                       printk(", irq=%u", irq);
+                                       printk(KERN_INFO ", irq=%u", irq);
                                }
                        }
                }
@@ -1376,16 +1423,20 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                }
                ret = request_dma(dma, "pcl812");
                if (ret) {
-                       printk(", unable to allocate DMA %u, FAIL!\n", dma);
+                       printk(KERN_ERR ", unable to allocate DMA %u, FAIL!\n",
+                              dma);
                        return -EBUSY;  /* DMA isn't free */
                }
                devpriv->dma = dma;
-               printk(", dma=%u", dma);
+               printk(KERN_INFO ", dma=%u", dma);
                pages = 1;      /* we want 8KB */
                devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
                if (!devpriv->dmabuf[0]) {
                        printk(", unable to allocate DMA buffer, FAIL!\n");
-                       /* maybe experiment with try_to_free_pages() will help .... */
+                       /*
+                        * maybe experiment with try_to_free_pages()
+                        * will help ....
+                        */
                        free_resources(dev);
                        return -EBUSY;  /* no buffer :-( */
                }
@@ -1394,7 +1445,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                devpriv->hwdmasize[0] = PAGE_SIZE * (1 << pages);
                devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
                if (!devpriv->dmabuf[1]) {
-                       printk(", unable to allocate DMA buffer, FAIL!\n");
+                       printk(KERN_ERR ", unable to allocate DMA buffer, FAIL!\n");
                        free_resources(dev);
                        return -EBUSY;
                }
@@ -1457,11 +1508,11 @@ no_dma:
                s->maxdata = this_board->ai_maxdata;
                s->len_chanlist = MAX_CHANLIST_LEN;
                s->range_table = this_board->rangelist_ai;
-               if (this_board->board_type == boardACL8216) {
+               if (this_board->board_type == boardACL8216)
                        s->insn_read = acl8216_ai_insn_read;
-               } else {
+               else
                        s->insn_read = pcl812_ai_insn_read;
-               }
+
                devpriv->use_MPC = this_board->haveMPC508;
                s->cancel = pcl812_ai_cancel;
                if (dev->irq) {
@@ -1500,8 +1551,8 @@ no_dma:
                                s->range_table = &range_bipolar10;
                                break;
                                printk
-                                   (", incorrect range number %d, changing to 0 (+/-10V)",
-                                    it->options[4]);
+                                   (", incorrect range number %d, changing "
+                                    "to 0 (+/-10V)", it->options[4]);
                                break;
                        }
                        break;
@@ -1530,8 +1581,8 @@ no_dma:
                                s->range_table = &range_iso813_1_ai;
                                break;
                                printk
-                                   (", incorrect range number %d, changing to 0 ",
-                                    it->options[1]);
+                                   (", incorrect range number %d, "
+                                    "changing to 0 ", it->options[1]);
                                break;
                        }
                        break;
@@ -1555,8 +1606,8 @@ no_dma:
                                s->range_table = &range_acl8113_1_ai;
                                break;
                                printk
-                                   (", incorrect range number %d, changing to 0 ",
-                                    it->options[1]);
+                                   (", incorrect range number %d, "
+                                    "changing to 0 ", it->options[1]);
                                break;
                        }
                        break;
@@ -1627,7 +1678,8 @@ no_dma:
        case boardACL8112:
                devpriv->max_812_ai_mode0_rangewait = 1;
                if (it->options[3] > 0)
-                       devpriv->use_ext_trg = 1;       /*  we use external trigger */
+                                               /*  we use external trigger */
+                       devpriv->use_ext_trg = 1;
        case boardA821:
                devpriv->max_812_ai_mode0_rangewait = 1;
                devpriv->mode_reg_int = (irq << 4) & 0xf0;
@@ -1636,11 +1688,12 @@ no_dma:
        case boardPCL813:
        case boardISO813:
        case boardACL8113:
-               devpriv->max_812_ai_mode0_rangewait = 5;        /* maybe there must by greatest timeout */
+               /* maybe there must by greatest timeout */
+               devpriv->max_812_ai_mode0_rangewait = 5;
                break;
        }
 
-       printk("\n");
+       printk(KERN_INFO "\n");
        devpriv->valid = 1;
 
        pcl812_reset(dev);
@@ -1655,8 +1708,12 @@ static int pcl812_detach(struct comedi_device *dev)
 {
 
 #ifdef PCL812_EXTDEBUG
-       printk("comedi%d: pcl812: remove\n", dev->minor);
+       printk(KERN_DEBUG "comedi%d: pcl812: remove\n", dev->minor);
 #endif
        free_resources(dev);
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 71c2a3aa379e419e477b3973e90db17b95b8f501..3d0f018faa6b1c2de6a6b5a4db66ad7089597bce 100644 (file)
@@ -2,7 +2,7 @@
    comedi/drivers/pcl816.c
 
    Author:  Juan Grigera <juan@grigera.com.ar>
-            based on pcl818 by Michal Dobes <dobes@tesnet.cz> and bits of pcl812
+           based on pcl818 by Michal Dobes <dobes@tesnet.cz> and bits of pcl812
 
    hardware driver for Advantech cards:
     card:   PCL-816, PCL814B
@@ -28,7 +28,7 @@ Configuration Options:
   [1] - IRQ    (0=disable, 2, 3, 4, 5, 6, 7)
   [2] - DMA    (0=disable, 1, 3)
   [3] - 0, 10=10MHz clock for 8254
-            1= 1MHz clock for 8254
+           1= 1MHz clock for 8254
 
 */
 
@@ -85,7 +85,7 @@ Configuration Options:
 #define INT_TYPE_AI3_DMA_RTC 10
 
 /* RTC stuff... */
-#define RTC_IRQ        8
+#define RTC_IRQ                8
 #define RTC_IO_EXTENT  0x10
 #endif
 
@@ -168,7 +168,18 @@ static struct comedi_driver driver_pcl816 = {
        .offset = sizeof(struct pcl816_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcl816);
+static int __init driver_pcl816_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl816);
+}
+
+static void __exit driver_pcl816_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl816);
+}
+
+module_init(driver_pcl816_init_module);
+module_exit(driver_pcl816_cleanup_module);
 
 struct pcl816_private {
 
@@ -253,7 +264,8 @@ static int pcl816_ai_insn_read(struct comedi_device *dev,
 
        /*  Set the input channel */
        outb(CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX);
-       outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE);     /* select gain */
+       /* select gain */
+       outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE);
 
        for (n = 0; n < insn->n; n++) {
 
@@ -268,8 +280,8 @@ static int pcl816_ai_insn_read(struct comedi_device *dev,
                                    ((inb(dev->iobase +
                                          PCL816_AD_HI) << 8) |
                                     (inb(dev->iobase + PCL816_AD_LO)));
-
-                               outb(0, dev->iobase + PCL816_CLRINT);   /* clear INT (conversion end) flag */
+                               /* clear INT (conversion end) flag */
+                               outb(0, dev->iobase + PCL816_CLRINT);
                                break;
                        }
                        udelay(1);
@@ -278,7 +290,8 @@ static int pcl816_ai_insn_read(struct comedi_device *dev,
                if (!timeout) {
                        comedi_error(dev, "A/D insn timeout\n");
                        data[0] = 0;
-                       outb(0, dev->iobase + PCL816_CLRINT);   /* clear INT (conversion end) flag */
+                       /* clear INT (conversion end) flag */
+                       outb(0, dev->iobase + PCL816_CLRINT);
                        return -EIO;
                }
 
@@ -332,7 +345,8 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
        }
 
        if (!devpriv->ai_neverending)
-               if (devpriv->ai_act_scan >= devpriv->ai_scans) {        /* all data sampled */
+                                       /* all data sampled */
+               if (devpriv->ai_act_scan >= devpriv->ai_scans) {
                        /* all data sampled */
                        pcl816_ai_cancel(dev, s);
                        s->async->events |= COMEDI_CB_EOA;
@@ -369,7 +383,8 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
                }
 
                if (!devpriv->ai_neverending)
-                       if (devpriv->ai_act_scan >= devpriv->ai_scans) {        /*  all data sampled */
+                                               /*  all data sampled */
+                       if (devpriv->ai_act_scan >= devpriv->ai_scans) {
                                pcl816_ai_cancel(dev, s);
                                s->async->events |= COMEDI_CB_EOA;
                                s->async->events |= COMEDI_CB_BLOCK;
@@ -391,7 +406,8 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
        disable_dma(devpriv->dma);
        this_dma_buf = devpriv->next_dma_buf;
 
-       if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) {       /*  switch dma bufs */
+       /*  switch dma bufs */
+       if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) {
 
                devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
                set_dma_mode(devpriv->dma, DMA_MODE_READ);
@@ -467,14 +483,14 @@ static irqreturn_t interrupt_pcl816(int irq, void *d)
 */
 static void pcl816_cmdtest_out(int e, struct comedi_cmd *cmd)
 {
-       printk("pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+       printk(KERN_INFO "pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
               cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
-       printk("pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+       printk(KERN_INFO "pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
               cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
-       printk("pcl816 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
-              cmd->scan_end_src);
-       printk("pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
-              cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+       printk(KERN_INFO "pcl816 e=%d stopsrc=%x scanend=%x\n", e,
+              cmd->stop_src, cmd->scan_end_src);
+       printk(KERN_INFO "pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
+              e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
 }
 
 /*
@@ -486,8 +502,9 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
        int err = 0;
        int tmp, divisor1 = 0, divisor2 = 0;
 
-       DEBUG(printk("pcl816 pcl812_ai_cmdtest\n"); pcl816_cmdtest_out(-1, cmd);
-           );
+       DEBUG(printk(KERN_INFO "pcl816 pcl812_ai_cmdtest\n");
+             pcl816_cmdtest_out(-1, cmd);
+            );
 
        /* step 1: make sure trigger sources are trivially valid */
        tmp = cmd->start_src;
@@ -515,11 +532,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
        if (!cmd->stop_src || tmp != cmd->stop_src)
                err++;
 
-       if (err) {
+       if (err)
                return 1;
-       }
 
-       /* step 2: make sure trigger sources are unique and mutually compatible */
+
+       /*
+        * step 2: make sure trigger sources
+        * are unique and mutually compatible
+        */
 
        if (cmd->start_src != TRIG_NOW) {
                cmd->start_src = TRIG_NOW;
@@ -544,9 +564,9 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
        if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
                err++;
 
-       if (err) {
+       if (err)
                return 2;
-       }
+
 
        /* step 3: make sure arguments are trivially compatible */
        if (cmd->start_arg != 0) {
@@ -586,9 +606,9 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
                }
        }
 
-       if (err) {
+       if (err)
                return 3;
-       }
+
 
        /* step 4: fix up any arguments */
        if (cmd->convert_src == TRIG_TIMER) {
@@ -603,9 +623,9 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
                        err++;
        }
 
-       if (err) {
+       if (err)
                return 4;
-       }
+
 
        /* step 5: complain about special chanlist considerations */
 
@@ -643,7 +663,9 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
                                          &divisor2, &cmd->convert_arg,
                                          cmd->flags & TRIG_ROUND_MASK);
-               if (divisor1 == 1) {    /*  PCL816 crash if any divisor is set to 1 */
+
+               /*  PCL816 crash if any divisor is set to 1 */
+               if (divisor1 == 1) {
                        divisor1 = 2;
                        divisor2 /= 2;
                }
@@ -676,8 +698,10 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                devpriv->ai_neverending = 1;
        }
 
-       if ((cmd->flags & TRIG_WAKE_EOS)) {     /*  don't we want wake up every scan? */
-               printk("pl816: You wankt WAKE_EOS but I dont want handle it");
+       /*  don't we want wake up every scan? */
+       if ((cmd->flags & TRIG_WAKE_EOS)) {
+               printk(KERN_INFO
+                      "pl816: You wankt WAKE_EOS but I dont want handle it");
                /*               devpriv->ai_eos=1; */
                /* if (devpriv->ai_n_chan==1) */
                /*       devpriv->dma=0; // DMA is useless for this situation */
@@ -686,9 +710,17 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        if (devpriv->dma) {
                bytes = devpriv->hwdmasize[0];
                if (!devpriv->ai_neverending) {
-                       bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short);        /*  how many */
-                       devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0];       /*  how many DMA pages we must fill */
-                       devpriv->last_dma_run = bytes % devpriv->hwdmasize[0];  /* on last dma transfer must be moved */
+                       /*  how many */
+                       bytes = s->async->cmd.chanlist_len *
+                       s->async->cmd.chanlist_len *
+                       sizeof(short);
+
+                       /*  how many DMA pages we must fill */
+                       devpriv->dma_runs_to_end = bytes /
+                       devpriv->hwdmasize[0];
+
+                       /* on last dma transfer must be moved */
+                       devpriv->last_dma_run = bytes % devpriv->hwdmasize[0];
                        devpriv->dma_runs_to_end--;
                        if (devpriv->dma_runs_to_end >= 0)
                                bytes = devpriv->hwdmasize[0];
@@ -711,14 +743,22 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        switch (cmd->convert_src) {
        case TRIG_TIMER:
                devpriv->int816_mode = INT_TYPE_AI1_DMA;
-               outb(0x32, dev->iobase + PCL816_CONTROL);       /*  Pacer+IRQ+DMA */
-               outb(dmairq, dev->iobase + PCL816_STATUS);      /*  write irq and DMA to card */
+
+               /*  Pacer+IRQ+DMA */
+               outb(0x32, dev->iobase + PCL816_CONTROL);
+
+               /*  write irq and DMA to card */
+               outb(dmairq, dev->iobase + PCL816_STATUS);
                break;
 
        default:
                devpriv->int816_mode = INT_TYPE_AI3_DMA;
-               outb(0x34, dev->iobase + PCL816_CONTROL);       /*  Ext trig+IRQ+DMA */
-               outb(dmairq, dev->iobase + PCL816_STATUS);      /*  write irq to card */
+
+               /*  Ext trig+IRQ+DMA */
+               outb(0x34, dev->iobase + PCL816_CONTROL);
+
+               /*  write irq to card */
+               outb(dmairq, dev->iobase + PCL816_STATUS);
                break;
        }
 
@@ -747,7 +787,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
                return 0;
        }
 
-       top1 = devpriv->hwdmasize[0] - top1;    /*  where is now DMA in buffer */
+       /*  where is now DMA in buffer */
+       top1 = devpriv->hwdmasize[0] - top1;
        top1 >>= 1;             /*  sample position */
        top2 = top1 - devpriv->ai_poll_ptr;
        if (top2 < 1) {         /*  no new samples */
@@ -787,16 +828,23 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
                        disable_dma(devpriv->dma);
                case INT_TYPE_AI1_INT:
                case INT_TYPE_AI3_INT:
-                       outb(inb(dev->iobase + PCL816_CONTROL) & 0x73, dev->iobase + PCL816_CONTROL);   /* Stop A/D */
+                       outb(inb(dev->iobase + PCL816_CONTROL) & 0x73,
+                            dev->iobase + PCL816_CONTROL);     /* Stop A/D */
                        udelay(1);
                        outb(0, dev->iobase + PCL816_CONTROL);  /* Stop A/D */
-                       outb(0xb0, dev->iobase + PCL816_CTRCTL);        /* Stop pacer */
+
+                       /* Stop pacer */
+                       outb(0xb0, dev->iobase + PCL816_CTRCTL);
                        outb(0x70, dev->iobase + PCL816_CTRCTL);
                        outb(0, dev->iobase + PCL816_AD_LO);
                        inb(dev->iobase + PCL816_AD_LO);
                        inb(dev->iobase + PCL816_AD_HI);
-                       outb(0, dev->iobase + PCL816_CLRINT);   /* clear INT request */
-                       outb(0, dev->iobase + PCL816_CONTROL);  /* Stop A/D */
+
+                       /* clear INT request */
+                       outb(0, dev->iobase + PCL816_CLRINT);
+
+                       /* Stop A/D */
+                       outb(0, dev->iobase + PCL816_CONTROL);
                        devpriv->irq_blocked = 0;
                        devpriv->irq_was_now_closed = devpriv->int816_mode;
                        devpriv->int816_mode = 0;
@@ -866,8 +914,11 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
        outb(0xff, dev->iobase + PCL816_CTR0);
        outb(0x00, dev->iobase + PCL816_CTR0);
        udelay(1);
-       outb(0xb4, dev->iobase + PCL816_CTRCTL);        /*  set counter 2 as mode 3 */
-       outb(0x74, dev->iobase + PCL816_CTRCTL);        /*  set counter 1 as mode 3 */
+
+       /*  set counter 2 as mode 3 */
+       outb(0xb4, dev->iobase + PCL816_CTRCTL);
+       /*  set counter 1 as mode 3 */
+       outb(0x74, dev->iobase + PCL816_CTRCTL);
        udelay(1);
 
        if (mode == 1) {
@@ -903,41 +954,51 @@ check_channel_list(struct comedi_device *dev,
        }
 
        if (chanlen > 1) {
-               chansegment[0] = chanlist[0];   /*  first channel is everytime ok */
+               /*  first channel is everytime ok */
+               chansegment[0] = chanlist[0];
                for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
                        /*  build part of chanlist */
-                       DEBUG(printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]),
+                       DEBUG(printk(KERN_INFO "%d. %d %d\n", i,
+                                    CR_CHAN(chanlist[i]),
                                     CR_RANGE(chanlist[i]));)
+
+                       /*  we detect loop, this must by finish */
                            if (chanlist[0] == chanlist[i])
-                               break;  /*  we detect loop, this must by finish */
+                               break;
                        nowmustbechan =
                            (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
                        if (nowmustbechan != CR_CHAN(chanlist[i])) {
                                /*  channel list isn't continous :-( */
-                               printk
-                                   ("comedi%d: pcl816: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
-                                    dev->minor, i, CR_CHAN(chanlist[i]),
-                                    nowmustbechan, CR_CHAN(chanlist[0]));
+                               printk(KERN_WARNING
+                                      "comedi%d: pcl816: channel list must "
+                                      "be continous! chanlist[%i]=%d but "
+                                      "must be %d or %d!\n", dev->minor,
+                                      i, CR_CHAN(chanlist[i]), nowmustbechan,
+                                      CR_CHAN(chanlist[0]));
                                return 0;
                        }
-                       chansegment[i] = chanlist[i];   /*  well, this is next correct channel in list */
+                       /*  well, this is next correct channel in list */
+                       chansegment[i] = chanlist[i];
                }
 
-               for (i = 0, segpos = 0; i < chanlen; i++) {     /*  check whole chanlist */
+               /*  check whole chanlist */
+               for (i = 0, segpos = 0; i < chanlen; i++) {
                        DEBUG(printk("%d %d=%d %d\n",
                                     CR_CHAN(chansegment[i % seglen]),
                                     CR_RANGE(chansegment[i % seglen]),
                                     CR_CHAN(chanlist[i]),
                                     CR_RANGE(chanlist[i]));)
                            if (chanlist[i] != chansegment[i % seglen]) {
-                               printk
-                                   ("comedi%d: pcl816: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
-                                    dev->minor, i, CR_CHAN(chansegment[i]),
-                                    CR_RANGE(chansegment[i]),
-                                    CR_AREF(chansegment[i]),
-                                    CR_CHAN(chanlist[i % seglen]),
-                                    CR_RANGE(chanlist[i % seglen]),
-                                    CR_AREF(chansegment[i % seglen]));
+                               printk(KERN_WARNING
+                                      "comedi%d: pcl816: bad channel or range"
+                                      " number! chanlist[%i]=%d,%d,%d and not"
+                                      " %d,%d,%d!\n", dev->minor, i,
+                                      CR_CHAN(chansegment[i]),
+                                      CR_RANGE(chansegment[i]),
+                                      CR_AREF(chansegment[i]),
+                                      CR_CHAN(chanlist[i % seglen]),
+                                      CR_RANGE(chanlist[i % seglen]),
+                                      CR_AREF(chansegment[i % seglen]));
                                return 0;       /*  chan/gain list is strange */
                        }
                }
@@ -965,12 +1026,15 @@ setup_channel_list(struct comedi_device *dev,
        for (i = 0; i < seglen; i++) {  /*  store range list to card */
                devpriv->ai_act_chanlist[i] = CR_CHAN(chanlist[i]);
                outb(CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX);
-               outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE);        /* select gain */
+               /* select gain */
+               outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE);
        }
 
        udelay(1);
-
-       outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX);      /* select channel interval to scan */
+       /* select channel interval to scan */
+       outb(devpriv->ai_act_chanlist[0] |
+            (devpriv->ai_act_chanlist[seglen - 1] << 4),
+            dev->iobase + PCL816_MUX);
 }
 
 #ifdef unused
@@ -998,11 +1062,11 @@ static int set_rtc_irq_bit(unsigned char bit)
        save_flags(flags);
        cli();
        val = CMOS_READ(RTC_CONTROL);
-       if (bit) {
+       if (bit)
                val |= RTC_PIE;
-       } else {
+       else
                val &= ~RTC_PIE;
-       }
+
        CMOS_WRITE(val, RTC_CONTROL);
        CMOS_READ(RTC_INTR_FLAGS);
        restore_flags(flags);
@@ -1072,7 +1136,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        dev->iobase = iobase;
 
        if (pcl816_check(iobase)) {
-               printk(", I cann't detect board. FAIL!\n");
+               printk(KERN_ERR ", I cann't detect board. FAIL!\n");
                return -EIO;
        }
 
@@ -1090,30 +1154,29 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                if (irq) {      /* we want to use IRQ */
                        if (((1 << irq) & this_board->IRQbits) == 0) {
                                printk
-                                   (", IRQ %u is out of allowed range, DISABLING IT",
-                                    irq);
+                                   (", IRQ %u is out of allowed range, "
+                                    "DISABLING IT", irq);
                                irq = 0;        /* Bad IRQ */
                        } else {
                                if (request_irq
                                    (irq, interrupt_pcl816, 0, "pcl816", dev)) {
                                        printk
-                                           (", unable to allocate IRQ %u, DISABLING IT",
-                                            irq);
+                                           (", unable to allocate IRQ %u, "
+                                            "DISABLING IT", irq);
                                        irq = 0;        /* Can't use IRQ */
                                } else {
-                                       printk(", irq=%u", irq);
+                                       printk(KERN_INFO ", irq=%u", irq);
                                }
                        }
                }
        }
 
        dev->irq = irq;
-       if (irq) {
+       if (irq)        /* 1=we have allocated irq */
                devpriv->irq_free = 1;
-       } /* 1=we have allocated irq */
-       else {
+       else
                devpriv->irq_free = 0;
-       }
+
        devpriv->irq_blocked = 0;       /* number of subdevice which use IRQ */
        devpriv->int816_mode = 0;       /* mode of irq */
 
@@ -1170,18 +1233,22 @@ no_rtc:
                }
                ret = request_dma(dma, "pcl816");
                if (ret) {
-                       printk(", unable to allocate DMA %u, FAIL!\n", dma);
+                       printk(KERN_ERR
+                              ", unable to allocate DMA %u, FAIL!\n", dma);
                        return -EBUSY;  /* DMA isn't free */
                }
 
                devpriv->dma = dma;
-               printk(", dma=%u", dma);
+               printk(KERN_INFO ", dma=%u", dma);
                pages = 2;      /* we need 16KB */
                devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
 
                if (!devpriv->dmabuf[0]) {
                        printk(", unable to allocate DMA buffer, FAIL!\n");
-                       /* maybe experiment with try_to_free_pages() will help .... */
+                       /*
+                        * maybe experiment with try_to_free_pages()
+                        * will help ....
+                        */
                        return -EBUSY;  /* no buffer :-( */
                }
                devpriv->dmapages[0] = pages;
@@ -1192,8 +1259,9 @@ no_rtc:
                if (devpriv->dma_rtc == 0) {    /*  we must do duble buff :-( */
                        devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
                        if (!devpriv->dmabuf[1]) {
-                               printk
-                                   (", unable to allocate DMA buffer, FAIL!\n");
+                               printk(KERN_ERR
+                                      ", unable to allocate DMA buffer, "
+                                      "FAIL!\n");
                                return -EBUSY;
                        }
                        devpriv->dmapages[1] = pages;
@@ -1277,7 +1345,7 @@ case COMEDI_SUBD_DO:
  */
 static int pcl816_detach(struct comedi_device *dev)
 {
-       DEBUG(printk("comedi%d: pcl816: remove\n", dev->minor);)
+       DEBUG(printk(KERN_INFO "comedi%d: pcl816: remove\n", dev->minor);)
            free_resources(dev);
 #ifdef unused
        if (devpriv->dma_rtc)
@@ -1285,3 +1353,7 @@ static int pcl816_detach(struct comedi_device *dev)
 #endif
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 9d6aa393ef13b83785efff2bee825662714c64fd..d2bd6f82b830b3b3a5f6c45946c658a9f40a418c 100644 (file)
@@ -313,7 +313,18 @@ static struct comedi_driver driver_pcl818 = {
        .offset = sizeof(struct pcl818_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcl818);
+static int __init driver_pcl818_init_module(void)
+{
+       return comedi_driver_register(&driver_pcl818);
+}
+
+static void __exit driver_pcl818_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcl818);
+}
+
+module_init(driver_pcl818_init_module);
+module_exit(driver_pcl818_cleanup_module);
 
 struct pcl818_private {
 
@@ -2036,3 +2047,7 @@ static int pcl818_detach(struct comedi_device *dev)
        free_resources(dev);
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index ed6103079232928edd60a97995138f5eb6743cbe..7fb3c27e5979ce1b42eaf7e1a166aa95ed4b0a48 100644 (file)
@@ -97,7 +97,18 @@ static struct comedi_driver driver_pcm3724 = {
        .offset = sizeof(struct pcm3724_board),
 };
 
-COMEDI_INITCLEANUP(driver_pcm3724);
+static int __init driver_pcm3724_init_module(void)
+{
+       return comedi_driver_register(&driver_pcm3724);
+}
+
+static void __exit driver_pcm3724_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcm3724);
+}
+
+module_init(driver_pcm3724_init_module);
+module_exit(driver_pcm3724_cleanup_module);
 
 /* (setq c-basic-offset 8) */
 
@@ -184,7 +195,7 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s,
        struct priv_pcm3724 *priv;
 
        gatecfg = 0;
-       priv = (struct priv_pcm3724 *)(dev->private);
+       priv = dev->private;
 
        mask = 1 << CR_CHAN(chanspec);
        if (s == dev->subdevices)       /*  subdev 0 */
@@ -307,3 +318,7 @@ static int pcm3724_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 22b7aae63addf666be5823b7f2961402b1765ab7..bada6b236ff13a4d66612dfd39a761bef81a88f4 100644 (file)
@@ -38,7 +38,18 @@ static struct comedi_driver driver_pcm3730 = {
        .detach = pcm3730_detach,
 };
 
-COMEDI_INITCLEANUP(driver_pcm3730);
+static int __init driver_pcm3730_init_module(void)
+{
+       return comedi_driver_register(&driver_pcm3730);
+}
+
+static void __exit driver_pcm3730_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcm3730);
+}
+
+module_init(driver_pcm3730_init_module);
+module_exit(driver_pcm3730_cleanup_module);
 
 static int pcm3730_do_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
@@ -154,3 +165,7 @@ static int pcm3730_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 52c2a6698214277393d00490c412ffdc5a60591a..474af7bc6c8bfe6f593533b33ca202bada8a7d50 100644 (file)
@@ -109,3 +109,7 @@ int comedi_pcm_cmdtest(struct comedi_device *dev,
        return 0;
 }
 EXPORT_SYMBOL(comedi_pcm_cmdtest);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index fab8092bd7aa7600e62139ce16db426a104f5614..23b3d777340ca5eb9c1471c67e7401716ab58ee5 100644 (file)
@@ -89,7 +89,18 @@ static struct comedi_driver driver_pcmad = {
        .offset = sizeof(pcmad_boards[0]),
 };
 
-COMEDI_INITCLEANUP(driver_pcmad);
+static int __init driver_pcmad_init_module(void)
+{
+       return comedi_driver_register(&driver_pcmad);
+}
+
+static void __exit driver_pcmad_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_pcmad);
+}
+
+module_init(driver_pcmad_init_module);
+module_exit(driver_pcmad_cleanup_module);
 
 #define TIMEOUT        100
 
@@ -176,3 +187,7 @@ static int pcmad_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 7133eb0352bc815f040aa23dc0db92eb5b1c58a1..0e9ffa28d745d98e5d8b717946f8b528fa12ed3f 100644 (file)
@@ -157,7 +157,8 @@ static int pcmda12_attach(struct comedi_device *dev,
        unsigned long iobase;
 
        iobase = it->options[0];
-       printk("comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name,
+       printk(KERN_INFO
+              "comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name,
               iobase, it->options[1] ? "simultaneous xfer mode enabled" : "");
 
        if (!request_region(iobase, IOSIZE, driver.driver_name)) {
@@ -177,7 +178,7 @@ static int pcmda12_attach(struct comedi_device *dev,
  * convenient macro defined in comedidev.h.
  */
        if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) {
-               printk("cannot allocate private data structure\n");
+               printk(KERN_ERR "cannot allocate private data structure\n");
                return -ENOMEM;
        }
 
@@ -191,7 +192,7 @@ static int pcmda12_attach(struct comedi_device *dev,
         * 96-channel version of the board.
         */
        if (alloc_subdevices(dev, 1) < 0) {
-               printk("cannot allocate subdevice data structures\n");
+               printk(KERN_ERR "cannot allocate subdevice data structures\n");
                return -ENOMEM;
        }
 
@@ -207,7 +208,7 @@ static int pcmda12_attach(struct comedi_device *dev,
 
        zero_chans(dev);        /* clear out all the registers, basically */
 
-       printk("attached\n");
+       printk(KERN_INFO "attached\n");
 
        return 1;
 }
@@ -222,7 +223,8 @@ static int pcmda12_attach(struct comedi_device *dev,
  */
 static int pcmda12_detach(struct comedi_device *dev)
 {
-       printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+       printk(KERN_INFO
+              "comedi%d: %s: remove\n", dev->minor, driver.driver_name);
        if (dev->iobase)
                release_region(dev->iobase, IOSIZE);
        return 0;
@@ -303,4 +305,19 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver);
+static int __init driver_init_module(void)
+{
+       return comedi_driver_register(&driver);
+}
+
+static void __exit driver_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver);
+}
+
+module_init(driver_init_module);
+module_exit(driver_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 025a52e8981d1868d68497359b4a165d96bfc24a..5c832d7ed45dc3ead22d0aff528f53e5bd7d7f04 100644 (file)
@@ -145,10 +145,6 @@ Configuration Options:
 #define PAGE_ENAB 2
 #define PAGE_INT_ID 3
 
-typedef int (*comedi_insn_fn_t) (struct comedi_device *,
-                                struct comedi_subdevice *,
-                                struct comedi_insn *, unsigned int *);
-
 static int ai_rinsn(struct comedi_device *, struct comedi_subdevice *,
                    struct comedi_insn *, unsigned int *);
 static int ao_rinsn(struct comedi_device *, struct comedi_subdevice *,
@@ -171,7 +167,18 @@ struct pcmmio_board {
        const int n_ai_chans;
        const int n_ao_chans;
        const struct comedi_lrange *ai_range_table, *ao_range_table;
-       comedi_insn_fn_t ai_rinsn, ao_rinsn, ao_winsn;
+       int (*ai_rinsn) (struct comedi_device *dev,
+                       struct comedi_subdevice *s,
+                       struct comedi_insn *insn,
+                       unsigned int *data);
+       int (*ao_rinsn) (struct comedi_device *dev,
+                       struct comedi_subdevice *s,
+                       struct comedi_insn *insn,
+                       unsigned int *data);
+       int (*ao_winsn) (struct comedi_device *dev,
+                       struct comedi_subdevice *s,
+                       struct comedi_insn *insn,
+                       unsigned int *data);
 };
 
 static const struct comedi_lrange ranges_ai = {
@@ -1333,4 +1340,19 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver);
+static int __init driver_init_module(void)
+{
+       return comedi_driver_register(&driver);
+}
+
+static void __exit driver_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver);
+}
+
+module_init(driver_init_module);
+module_exit(driver_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 5af4c8448a3a6ab1a670c2a72ce350bbd0dfac51..7a9287433b2e69c494b3a0f52a32a09db95a71aa 100644 (file)
@@ -1018,4 +1018,19 @@ pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver);
+static int __init driver_init_module(void)
+{
+       return comedi_driver_register(&driver);
+}
+
+static void __exit driver_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver);
+}
+
+module_init(driver_init_module);
+module_exit(driver_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 1ebc356ce40e76bee6d0ebd3adf06ac96d8fe4ec..831a576c24aaa2fdd23e65e09a5c45d9d9575f60 100644 (file)
@@ -248,4 +248,19 @@ static int pcl734_insn_bits(struct comedi_device *dev,
        return 2;
 }
 
-COMEDI_INITCLEANUP(driver_poc);
+static int __init driver_poc_init_module(void)
+{
+       return comedi_driver_register(&driver_poc);
+}
+
+static void __exit driver_poc_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_poc);
+}
+
+module_init(driver_poc_init_module);
+module_exit(driver_poc_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index a91db6c420283426f2194b248daf13a5e09bc806..bf489d7f49909ce75bc9e9b2c3990b1b840218f6 100644 (file)
@@ -14,7 +14,7 @@
 
     Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
 
-                ftp://ftp.quatech.com/Manuals/daqp-208.pdf
+               ftp://ftp.quatech.com/Manuals/daqp-208.pdf
 
     This manual is for both the DAQP-208 and the DAQP-308.
 
@@ -50,7 +50,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
 #include "../comedidev.h"
 #include <linux/semaphore.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -195,7 +194,7 @@ static struct comedi_driver driver_daqp = {
 
 static void daqp_dump(struct comedi_device *dev)
 {
-       printk("DAQP: status %02x; aux status %02x\n",
+       printk(KERN_INFO "DAQP: status %02x; aux status %02x\n",
               inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
 }
 
@@ -207,9 +206,9 @@ static void hex_dump(char *str, void *ptr, int len)
        printk(str);
 
        for (i = 0; i < len; i++) {
-               if (i % 16 == 0) {
-                       printk("\n0x%08x:", (unsigned int)cptr);
-               }
+               if (i % 16 == 0)
+                       printk("\n%p:", cptr);
+
                printk(" %02x", *(cptr++));
        }
        printk("\n");
@@ -223,9 +222,9 @@ static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct local_info_t *local = (struct local_info_t *)s->private;
 
-       if (local->stop) {
+       if (local->stop)
                return -EIO;
-       }
+
 
        outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
 
@@ -355,9 +354,9 @@ static int daqp_ai_insn_read(struct comedi_device *dev,
        int v;
        int counter = 10000;
 
-       if (local->stop) {
+       if (local->stop)
                return -EIO;
-       }
+
 
        /* Stop any running conversion */
        daqp_ai_cancel(dev, s);
@@ -372,9 +371,9 @@ static int daqp_ai_insn_read(struct comedi_device *dev,
        v = DAQP_SCANLIST_CHANNEL(CR_CHAN(insn->chanspec))
            | DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec));
 
-       if (CR_AREF(insn->chanspec) == AREF_DIFF) {
+       if (CR_AREF(insn->chanspec) == AREF_DIFF)
                v |= DAQP_SCANLIST_DIFFERENTIAL;
-       }
+
 
        v |= DAQP_SCANLIST_START;
 
@@ -488,7 +487,10 @@ static int daqp_ai_cmdtest(struct comedi_device *dev,
        if (err)
                return 1;
 
-       /* step 2: make sure trigger sources are unique and mutually compatible */
+       /*
+        * step 2: make sure trigger sources
+        * are unique and mutually compatible
+        */
 
        /* note that mutual compatibility is not an issue here */
        if (cmd->scan_begin_src != TRIG_TIMER &&
@@ -588,9 +590,9 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        int i;
        int v;
 
-       if (local->stop) {
+       if (local->stop)
                return -EIO;
-       }
+
 
        /* Stop any running conversion */
        daqp_ai_cancel(dev, s);
@@ -640,13 +642,11 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                v = DAQP_SCANLIST_CHANNEL(CR_CHAN(chanspec))
                    | DAQP_SCANLIST_GAIN(CR_RANGE(chanspec));
 
-               if (CR_AREF(chanspec) == AREF_DIFF) {
+               if (CR_AREF(chanspec) == AREF_DIFF)
                        v |= DAQP_SCANLIST_DIFFERENTIAL;
-               }
 
-               if (i == 0 || scanlist_start_on_every_entry) {
+               if (i == 0 || scanlist_start_on_every_entry)
                        v |= DAQP_SCANLIST_START;
-               }
 
                outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
                outb(v >> 8, dev->iobase + DAQP_SCANLIST);
@@ -760,7 +760,8 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        while (--counter
               && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
        if (!counter) {
-               printk("daqp: couldn't clear interrupts in status register\n");
+               printk(KERN_ERR
+                      "daqp: couldn't clear interrupts in status register\n");
                return -1;
        }
 
@@ -785,9 +786,8 @@ static int daqp_ao_insn_write(struct comedi_device *dev,
        int d;
        unsigned int chan;
 
-       if (local->stop) {
+       if (local->stop)
                return -EIO;
-       }
 
        chan = CR_CHAN(insn->chanspec);
        d = data[0];
@@ -811,9 +811,8 @@ static int daqp_di_insn_read(struct comedi_device *dev,
 {
        struct local_info_t *local = (struct local_info_t *)s->private;
 
-       if (local->stop) {
+       if (local->stop)
                return -EIO;
-       }
 
        data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
 
@@ -828,9 +827,8 @@ static int daqp_do_insn_write(struct comedi_device *dev,
 {
        struct local_info_t *local = (struct local_info_t *)s->private;
 
-       if (local->stop) {
+       if (local->stop)
                return -EIO;
-       }
 
        outw(data[0] & 0xf, dev->iobase + DAQP_DIGITAL_IO);
 
@@ -872,13 +870,13 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                }
        }
 
-       dev->iobase = local->link->io.BasePort1;
+       dev->iobase = local->link->resource[0]->start;
 
        ret = alloc_subdevices(dev, 4);
        if (ret < 0)
                return ret;
 
-       printk("comedi%d: attaching daqp%d (io 0x%04lx)\n",
+       printk(KERN_INFO "comedi%d: attaching daqp%d (io 0x%04lx)\n",
               dev->minor, it->options[0], dev->iobase);
 
        s = dev->subdevices + 0;
@@ -931,7 +929,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 static int daqp_detach(struct comedi_device *dev)
 {
-       printk("comedi%d: detaching daqp\n", dev->minor);
+       printk(KERN_INFO "comedi%d: detaching daqp\n", dev->minor);
 
        return 0;
 }
@@ -996,14 +994,6 @@ static int daqp_cs_resume(struct pcmcia_device *p_dev);
 static int daqp_cs_attach(struct pcmcia_device *);
 static void daqp_cs_detach(struct pcmcia_device *);
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static const dev_info_t dev_info = "quatech_daqp_cs";
-
 /*======================================================================
 
     daqp_cs_attach() creates an "instance" of the driver, allocating
@@ -1076,8 +1066,7 @@ static void daqp_cs_detach(struct pcmcia_device *link)
 
        /* Unlink device structure, and free it */
        dev_table[dev->table_index] = NULL;
-       if (dev)
-               kfree(dev);
+       kfree(dev);
 
 }                              /* daqp_cs_detach */
 
@@ -1103,26 +1092,24 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                       pcmcia_io_cfg_data_width(io->flags);
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
                if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
        }
 
        /* This reserves IO space but doesn't actually enable it */
-       return pcmcia_request_io(p_dev, &p_dev->io);
+       return pcmcia_request_io(p_dev);
 }
 
 static void daqp_cs_config(struct pcmcia_device *link)
@@ -1154,12 +1141,10 @@ static void daqp_cs_config(struct pcmcia_device *link)
        dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                printk(", irq %u", link->irq);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1 + link->io.NumPorts1 - 1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2 + link->io.NumPorts2 - 1);
+       if (link->resource[0])
+               printk(" & %pR", link->resource[0]);
+       if (link->resource[1])
+               printk(" & %pR", link->resource[1]);
        printk("\n");
 
        return;
@@ -1228,7 +1213,7 @@ static struct pcmcia_driver daqp_cs_driver = {
        .id_table = daqp_cs_id_table,
        .owner = THIS_MODULE,
        .drv = {
-               .name = dev_info,
+               .name = "quatech_daqp_cs",
                },
 };
 
index 8626658e778c118ffa5b7d6589aba4be4ee7d02b..0367d2b9e2fac324e6ea5567cd9f24cfad3c43c0 100644 (file)
@@ -2356,4 +2356,44 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(rtd520Driver, rtd520_pci_table);
+static int __devinit rtd520Driver_pci_probe(struct pci_dev *dev,
+                                           const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, rtd520Driver.driver_name);
+}
+
+static void __devexit rtd520Driver_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver rtd520Driver_pci_driver = {
+       .id_table = rtd520_pci_table,
+       .probe = &rtd520Driver_pci_probe,
+       .remove = __devexit_p(&rtd520Driver_pci_remove)
+};
+
+static int __init rtd520Driver_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&rtd520Driver);
+       if (retval < 0)
+               return retval;
+
+       rtd520Driver_pci_driver.name = (char *)rtd520Driver.driver_name;
+       return pci_register_driver(&rtd520Driver_pci_driver);
+}
+
+static void __exit rtd520Driver_cleanup_module(void)
+{
+       pci_unregister_driver(&rtd520Driver_pci_driver);
+       comedi_driver_unregister(&rtd520Driver);
+}
+
+module_init(rtd520Driver_init_module);
+module_exit(rtd520Driver_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 028ed6f89c4cce37c3068f57fdc5b8fa55c1e158..72042b818310418d24809e6340b7dcad1a25a78c 100644 (file)
@@ -158,7 +158,18 @@ static struct comedi_driver driver_rti800 = {
        .offset = sizeof(struct rti800_board),
 };
 
-COMEDI_INITCLEANUP(driver_rti800);
+static int __init driver_rti800_init_module(void)
+{
+       return comedi_driver_register(&driver_rti800);
+}
+
+static void __exit driver_rti800_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_rti800);
+}
+
+module_init(driver_rti800_init_module);
+module_exit(driver_rti800_cleanup_module);
 
 static irqreturn_t rti800_interrupt(int irq, void *dev);
 
@@ -475,3 +486,7 @@ static int rti800_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 2157edcf7997e96ebd11ea654007b325d366140f..f59cb11590f68e0c05d5b86c07987e89e8a8e53c 100644 (file)
@@ -57,7 +57,18 @@ static struct comedi_driver driver_rti802 = {
        .detach = rti802_detach,
 };
 
-COMEDI_INITCLEANUP(driver_rti802);
+static int __init driver_rti802_init_module(void)
+{
+       return comedi_driver_register(&driver_rti802);
+}
+
+static void __exit driver_rti802_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_rti802);
+}
+
+module_init(driver_rti802_init_module);
+module_exit(driver_rti802_cleanup_module);
 
 struct rti802_private {
        enum {
@@ -150,3 +161,7 @@ static int rti802_detach(struct comedi_device *dev)
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 07c21e686f270b69a92baa5689ce52a230347e5a..3607aaee4af62a1b5b5954809219d2974331e2c6 100644 (file)
@@ -1002,4 +1002,19 @@ static int s526_dio_insn_config(struct comedi_device *dev,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver_s526);
+static int __init driver_s526_init_module(void)
+{
+       return comedi_driver_register(&driver_s526);
+}
+
+static void __exit driver_s526_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_s526);
+}
+
+module_init(driver_s526_init_module);
+module_exit(driver_s526_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index a3cc93362ec245381f8500c4c58000632f4c9777..d5ba3ab357a3839540c01614fb47bd9843f70418 100644 (file)
@@ -60,10 +60,10 @@ INSN_CONFIG instructions:
    insn.insn=INSN_CONFIG;   //configuration instruction
    insn.n=1;                //number of operation (must be 1)
    insn.data=&initialvalue; //initial value loaded into encoder
-                            //during configuration
+                               //during configuration
    insn.subdev=5;           //encoder subdevice
    insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
-                                                        //to configure
+                                                       //to configure
 
    comedi_do_insn(cf,&insn); //executing configuration
 */
@@ -224,7 +224,43 @@ static struct dio_private *dio_private_word[]={
 #define devpriv ((struct s626_private *)dev->private)
 #define diopriv ((struct dio_private *)s->private)
 
-COMEDI_PCI_INITCLEANUP_NOMODULE(driver_s626, s626_pci_table);
+static int __devinit driver_s626_pci_probe(struct pci_dev *dev,
+                                          const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_s626.driver_name);
+}
+
+static void __devexit driver_s626_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_s626_pci_driver = {
+       .id_table = s626_pci_table,
+       .probe = &driver_s626_pci_probe,
+       .remove = __devexit_p(&driver_s626_pci_remove)
+};
+
+static int __init driver_s626_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_s626);
+       if (retval < 0)
+               return retval;
+
+       driver_s626_pci_driver.name = (char *)driver_s626.driver_name;
+       return pci_register_driver(&driver_s626_pci_driver);
+}
+
+static void __exit driver_s626_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_s626_pci_driver);
+       comedi_driver_unregister(&driver_s626);
+}
+
+module_init(driver_s626_init_module);
+module_exit(driver_s626_cleanup_module);
 
 /* ioctl routines */
 static int s626_ai_insn_config(struct comedi_device *dev,
@@ -263,7 +299,7 @@ static int s626_enc_insn_write(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               struct comedi_insn *insn, unsigned int *data);
 static int s626_ns_to_timer(int *nanosec, int round_mode);
-static int s626_ai_load_polllist(uint8_t * ppl, struct comedi_cmd *cmd);
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd);
 static int s626_ai_inttrig(struct comedi_device *dev,
                           struct comedi_subdevice *s, unsigned int trignum);
 static irqreturn_t s626_irq_handler(int irq, void *d);
@@ -294,16 +330,16 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
 /*  COUNTER OBJECT ------------------------------------------------ */
 struct enc_private {
        /*  Pointers to functions that differ for A and B counters: */
-       uint16_t(*GetEnable) (struct comedi_device * dev, struct enc_private *);        /* Return clock enable. */
-       uint16_t(*GetIntSrc) (struct comedi_device * dev, struct enc_private *);        /* Return interrupt source. */
-       uint16_t(*GetLoadTrig) (struct comedi_device * dev, struct enc_private *);      /* Return preload trigger source. */
-       uint16_t(*GetMode) (struct comedi_device * dev, struct enc_private *);  /* Return standardized operating mode. */
-       void (*PulseIndex) (struct comedi_device * dev, struct enc_private *);  /* Generate soft index strobe. */
-       void (*SetEnable) (struct comedi_device * dev, struct enc_private *, uint16_t enab);    /* Program clock enable. */
-       void (*SetIntSrc) (struct comedi_device * dev, struct enc_private *, uint16_t IntSource);       /* Program interrupt source. */
-       void (*SetLoadTrig) (struct comedi_device * dev, struct enc_private *, uint16_t Trig);  /* Program preload trigger source. */
-       void (*SetMode) (struct comedi_device * dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc);     /* Program standardized operating mode. */
-       void (*ResetCapFlags) (struct comedi_device * dev, struct enc_private *);       /* Reset event capture flags. */
+       uint16_t(*GetEnable) (struct comedi_device *dev, struct enc_private *); /* Return clock enable. */
+       uint16_t(*GetIntSrc) (struct comedi_device *dev, struct enc_private *); /* Return interrupt source. */
+       uint16_t(*GetLoadTrig) (struct comedi_device *dev, struct enc_private *);       /* Return preload trigger source. */
+       uint16_t(*GetMode) (struct comedi_device *dev, struct enc_private *);   /* Return standardized operating mode. */
+       void (*PulseIndex) (struct comedi_device *dev, struct enc_private *);   /* Generate soft index strobe. */
+       void (*SetEnable) (struct comedi_device *dev, struct enc_private *, uint16_t enab);     /* Program clock enable. */
+       void (*SetIntSrc) (struct comedi_device *dev, struct enc_private *, uint16_t IntSource);        /* Program interrupt source. */
+       void (*SetLoadTrig) (struct comedi_device *dev, struct enc_private *, uint16_t Trig);   /* Program preload trigger source. */
+       void (*SetMode) (struct comedi_device *dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc);      /* Program standardized operating mode. */
+       void (*ResetCapFlags) (struct comedi_device *dev, struct enc_private *);        /* Reset event capture flags. */
 
        uint16_t MyCRA;         /*    Address of CRA register. */
        uint16_t MyCRB;         /*    Address of CRB register. */
@@ -543,13 +579,13 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        devpriv->pdev = pdev;
 
        if (pdev == NULL) {
-               printk("s626_attach: Board not present!!!\n");
+               printk(KERN_ERR "s626_attach: Board not present!!!\n");
                return -ENODEV;
        }
 
        result = comedi_pci_enable(pdev, "s626");
        if (result < 0) {
-               printk("s626_attach: comedi_pci_enable fails\n");
+               printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n");
                return -ENODEV;
        }
        devpriv->got_regions = 1;
@@ -558,7 +594,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        devpriv->base_addr = ioremap(resourceStart, SIZEOF_ADDRESS_SPACE);
        if (devpriv->base_addr == NULL) {
-               printk("s626_attach: IOREMAP failed\n");
+               printk(KERN_ERR "s626_attach: IOREMAP failed\n");
                return -ENODEV;
        }
 
@@ -579,7 +615,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                    pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
 
                if (devpriv->ANABuf.LogicalBase == NULL) {
-                       printk("s626_attach: DMA Memory mapping error\n");
+                       printk(KERN_ERR "s626_attach: DMA Memory mapping error\n");
                        return -ENOMEM;
                }
 
@@ -596,7 +632,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                    pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
 
                if (devpriv->RPSBuf.LogicalBase == NULL) {
-                       printk("s626_attach: DMA Memory mapping error\n");
+                       printk(KERN_ERR "s626_attach: DMA Memory mapping error\n");
                        return -ENOMEM;
                }
 
@@ -622,18 +658,18 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        /* set up interrupt handler */
        if (dev->irq == 0) {
-               printk(" unknown irq (bad)\n");
+               printk(KERN_ERR " unknown irq (bad)\n");
        } else {
                ret = request_irq(dev->irq, s626_irq_handler, IRQF_SHARED,
                                  "s626", dev);
 
                if (ret < 0) {
-                       printk(" irq not available\n");
+                       printk(KERN_ERR " irq not available\n");
                        dev->irq = 0;
                }
        }
 
-       DEBUG("s626_attach: -- it opts  %d,%d -- \n",
+       DEBUG("s626_attach: -- it opts  %d,%d --\n",
              it->options[0], it->options[1]);
 
        s = dev->subdevices + 0;
@@ -779,7 +815,8 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                /*  Write I2C control: abort any I2C activity. */
                MC_ENABLE(P_MC2, MC2_UPLD_IIC);
                /*  Invoke command  upload */
-               while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) ;
+               while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0)
+                       ;
                /*  and wait for upload to complete. */
 
                /* Per SAA7146 data sheet, write to STATUS reg twice to
@@ -788,7 +825,8 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                        WR7146(P_I2CSTAT, I2C_CLKSEL);
                        /*  Write I2C control: reset  error flags. */
                        MC_ENABLE(P_MC2, MC2_UPLD_IIC); /*  Invoke command upload */
-                       while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
+                       while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+                               ;
                        /* and wait for upload to complete. */
                }
 
@@ -828,14 +866,14 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                 * not start up in a defined state after a PCI reset.
                 */
 
-/*     PollList = EOPL;                        // Create a simple polling */
-/*                                     // list for analog input */
-/*                                     // channel 0. */
+/*     PollList = EOPL;                // Create a simple polling */
+/*                             // list for analog input */
+/*                             // channel 0. */
 /*     ResetADC( dev, &PollList ); */
 
 /*     s626_ai_rinsn(dev,dev->subdevices,NULL,data); //( &AdcData ); // */
-/*                                               //Get initial ADC */
-/*                                               //value. */
+/*                                                     //Get initial ADC */
+/*                                                     //value. */
 
 /*     StartVal = data[0]; */
 
@@ -848,10 +886,10 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 /*     for ( index = 0; index < 500; index++ ) */
 /*       { */
-/*     s626_ai_rinsn(dev,dev->subdevices,NULL,data); */
-/*     AdcData = data[0];      //ReadADC(  &AdcData ); */
-/*     if ( AdcData != StartVal ) */
-/*       break; */
+/*     s626_ai_rinsn(dev,dev->subdevices,NULL,data); */
+/*     AdcData = data[0];      //ReadADC(  &AdcData ); */
+/*     if ( AdcData != StartVal ) */
+/*             break; */
 /*       } */
 
                /*  end initADC */
@@ -1513,7 +1551,7 @@ void ResetADC(struct comedi_device *dev, uint8_t * ppl)
                        break;  /*  Exit poll list processing loop. */
                }
        }
-       DEBUG("ResetADC: ADC items %d \n", devpriv->AdcItems);
+       DEBUG("ResetADC: ADC items %d\n", devpriv->AdcItems);
 
        /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
         * ADC to stabilize for 2 microseconds before starting the final
@@ -1574,7 +1612,7 @@ static int s626_ai_insn_config(struct comedi_device *dev,
 /*   register uint8_t  i; */
 /*   register int32_t  *readaddr; */
 
-/*   DEBUG("as626_ai_rinsn: ai_rinsn enter \n");  */
+/*   DEBUG("as626_ai_rinsn: ai_rinsn enter\n");  */
 
 /*   Trigger ADC scan loop start by setting RPS Signal 0. */
 /*   MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
@@ -1591,11 +1629,11 @@ static int s626_ai_insn_config(struct comedi_device *dev,
 /*  Convert ADC data to 16-bit integer values and copy to application buffer. */
 /*   for ( i = 0; i < devpriv->AdcItems; i++ ) { */
 /*     *data = s626_ai_reg_to_uint( *readaddr++ ); */
-/*     DEBUG("s626_ai_rinsn: data %d \n",*data); */
+/*     DEBUG("s626_ai_rinsn: data %d\n",*data); */
 /*     data++; */
 /*   } */
 
-/*   DEBUG("s626_ai_rinsn: ai_rinsn escape \n"); */
+/*   DEBUG("s626_ai_rinsn: ai_rinsn escape\n"); */
 /*   return i; */
 /* } */
 
@@ -1651,7 +1689,8 @@ static int s626_ai_insn_read(struct comedi_device *dev,
                /*  shift into FB BUFFER 1 register. */
 
                /*  Wait for ADC done. */
-               while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+               while (!(RR7146(P_PSR) & PSR_GPIO2))
+                       ;
 
                /*  Fetch ADC data. */
                if (n != 0)
@@ -1683,7 +1722,8 @@ static int s626_ai_insn_read(struct comedi_device *dev,
        /*  Wait for the data to arrive in FB BUFFER 1 register. */
 
        /*  Wait for ADC done. */
-       while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+       while (!(RR7146(P_PSR) & PSR_GPIO2))
+               ;
 
        /*  Fetch ADC data from audio interface's input shift register. */
 
@@ -1696,7 +1736,7 @@ static int s626_ai_insn_read(struct comedi_device *dev,
        return n;
 }
 
-static int s626_ai_load_polllist(uint8_t * ppl, struct comedi_cmd *cmd)
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
 {
 
        int n;
@@ -1743,7 +1783,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        DEBUG("s626_ai_cmd: entering command function\n");
 
        if (devpriv->ai_cmd_running) {
-               printk("s626_ai_cmd: Another ai_cmd is running %d\n",
+               printk(KERN_ERR "s626_ai_cmd: Another ai_cmd is running %d\n",
                       dev->minor);
                return -EBUSY;
        }
@@ -2147,7 +2187,7 @@ static void s626_dio_init(struct comedi_device *dev)
                DEBIwrite(dev, diopriv->WRDOut, 0);     /*  Program all outputs */
                /*  to inactive state. */
        }
-       DEBUG("s626_dio_init: DIO initialized \n");
+       DEBUG("s626_dio_init: DIO initialized\n");
 }
 
 /* DIO devices are slightly special.  Although it is possible to
@@ -2346,7 +2386,7 @@ static int s626_enc_insn_read(struct comedi_device *dev,
        int n;
        struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
 
-       DEBUG("s626_enc_insn_read: encoder read channel %d \n",
+       DEBUG("s626_enc_insn_read: encoder read channel %d\n",
              CR_CHAN(insn->chanspec));
 
        for (n = 0; n < insn->n; n++)
@@ -2364,7 +2404,7 @@ static int s626_enc_insn_write(struct comedi_device *dev,
 
        struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
 
-       DEBUG("s626_enc_insn_write: encoder write channel %d \n",
+       DEBUG("s626_enc_insn_write: encoder write channel %d\n",
              CR_CHAN(insn->chanspec));
 
        /*  Set the preload register */
@@ -2425,8 +2465,7 @@ static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
 static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
 
 /*  TrimDac LogicalChan-to-EepromAdrs mapping table. */
-static uint8_t trimadrs[] =
-    { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
+static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
 
 static void LoadTrimDACs(struct comedi_device *dev)
 {
@@ -2524,10 +2563,12 @@ static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
        /*  upload confirmation. */
 
        MC_ENABLE(P_MC2, MC2_UPLD_IIC);
-       while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
+       while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+               ;
 
        /*  Wait until I2C bus transfer is finished or an error occurs. */
-       while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) ;
+       while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY)
+               ;
 
        /*  Return non-zero if I2C error occured. */
        return RR7146(P_I2CCTRL) & I2C_ERR;
@@ -2641,7 +2682,8 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         * Done by polling the DMAC enable flag; this flag is automatically
         * cleared when the transfer has finished.
         */
-       while ((RR7146(P_MC1) & MC1_A2OUT) != 0) ;
+       while ((RR7146(P_MC1) & MC1_A2OUT) != 0)
+               ;
 
        /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
 
@@ -2658,7 +2700,8 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         * finished transferring the DAC's data DWORD from the output FIFO
         * to the output buffer register.
         */
-       while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) ;
+       while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0)
+               ;
 
        /* Set up to trap execution at slot 0 when the TSL sequencer cycles
         * back to slot 0 after executing the EOS in slot 5.  Also,
@@ -2694,7 +2737,8 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
                 * from 0xFF to 0x00, which slot 0 causes to happen by shifting
                 * out/in on SD2 the 0x00 that is always referenced by slot 5.
                 */
-               while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) ;
+               while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0)
+                       ;
        }
        /* Either (1) we were too late setting the slot 0 trap; the TSL
         * sequencer restarted slot 0 before we could set the EOS trap flag,
@@ -2710,7 +2754,8 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         * the next DAC write.  This is detected when FB_BUFFER2 MSB changes
         * from 0x00 to 0xFF.
         */
-       while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) ;
+       while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0)
+               ;
 }
 
 static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
@@ -2749,10 +2794,12 @@ static void DEBItransfer(struct comedi_device *dev)
 
        /*  Wait for completion of upload from shadow RAM to DEBI control */
        /*  register. */
-       while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) ;
+       while (!MC_TEST(P_MC2, MC2_UPLD_DEBI))
+               ;
 
        /*  Wait until DEBI transfer is done. */
-       while (RR7146(P_PSR) & PSR_DEBI_S) ;
+       while (RR7146(P_PSR) & PSR_DEBI_S)
+               ;
 }
 
 /*  Write a value to a gate array register. */
@@ -3099,18 +3146,18 @@ static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
 static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
                           uint16_t value)
 {
-       DEBUG("SetLatchSource: SetLatchSource enter 3550 \n");
+       DEBUG("SetLatchSource: SetLatchSource enter 3550\n");
        DEBIreplace(dev, k->MyCRB,
                    (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)),
                    (uint16_t) (value << CRBBIT_LATCHSRC));
 
-       DEBUG("SetLatchSource: SetLatchSource exit \n");
+       DEBUG("SetLatchSource: SetLatchSource exit\n");
 }
 
 /*
  * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k )
  * {
- *     return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
+ *     return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
  * }
  */
 
@@ -3317,6 +3364,6 @@ static void CountersInit(struct comedi_device *dev)
                k->ResetCapFlags(dev, k);
                k->SetEnable(dev, k, CLKENAB_ALWAYS);
        }
-       DEBUG("CountersInit: counters initialized \n");
+       DEBUG("CountersInit: counters initialized\n");
 
 }
index d02742a95294a3fddf85bbede6fe505a451a65ff..2d1afecbbb60f6ae8f9b062b76363c88686480b6 100644 (file)
 #define STDMSK_CLKMULT         ((uint16_t)(3 << STDBIT_CLKMULT))
 #define STDMSK_CLKENAB         ((uint16_t)(1 << STDBIT_CLKENAB))
 
-/* typedef struct indexCounter */
-/* { */
-/*   unsigned int ao; */
-/*   unsigned int ai; */
-/*   unsigned int digout; */
-/*   unsigned int digin; */
-/*   unsigned int enc; */
-/* }CallCounter; */
-
 struct bufferDMA {
        dma_addr_t PhysicalBase;
        void *LogicalBase;
index 0792617ebc3557c327d5c05f36389c6af1d1ae7d..c9be9e05f0286680798b6900b3b85d3c03b4385b 100644 (file)
@@ -393,15 +393,16 @@ static void serial_write(struct file *f, struct serial_data data)
        }
 }
 
-static void serial_2002_open(struct comedi_device *dev)
+static int serial_2002_open(struct comedi_device *dev)
 {
+       int result;
        char port[20];
 
        sprintf(port, "/dev/ttyS%d", devpriv->port);
        devpriv->tty = filp_open(port, O_RDWR, 0);
        if (IS_ERR(devpriv->tty)) {
-               printk("serial_2002: file open error = %ld\n",
-                      PTR_ERR(devpriv->tty));
+               result = (int)PTR_ERR(devpriv->tty);
+               printk("serial_2002: file open error = %d\n", result);
        } else {
                struct config_t {
 
@@ -411,29 +412,25 @@ static void serial_2002_open(struct comedi_device *dev)
                        int max;
                };
 
-               struct config_t dig_in_config[32];
-               struct config_t dig_out_config[32];
-               struct config_t chan_in_config[32];
-               struct config_t chan_out_config[32];
+               struct config_t *dig_in_config;
+               struct config_t *dig_out_config;
+               struct config_t *chan_in_config;
+               struct config_t *chan_out_config;
                int i;
 
-               for (i = 0; i < 32; i++) {
-                       dig_in_config[i].kind = 0;
-                       dig_in_config[i].bits = 0;
-                       dig_in_config[i].min = 0;
-                       dig_in_config[i].max = 0;
-                       dig_out_config[i].kind = 0;
-                       dig_out_config[i].bits = 0;
-                       dig_out_config[i].min = 0;
-                       dig_out_config[i].max = 0;
-                       chan_in_config[i].kind = 0;
-                       chan_in_config[i].bits = 0;
-                       chan_in_config[i].min = 0;
-                       chan_in_config[i].max = 0;
-                       chan_out_config[i].kind = 0;
-                       chan_out_config[i].bits = 0;
-                       chan_out_config[i].min = 0;
-                       chan_out_config[i].max = 0;
+               result = 0;
+               dig_in_config = kcalloc(32, sizeof(struct config_t),
+                               GFP_KERNEL);
+               dig_out_config = kcalloc(32, sizeof(struct config_t),
+                               GFP_KERNEL);
+               chan_in_config = kcalloc(32, sizeof(struct config_t),
+                               GFP_KERNEL);
+               chan_out_config = kcalloc(32, sizeof(struct config_t),
+                               GFP_KERNEL);
+               if (!dig_in_config || !dig_out_config
+                   || !chan_in_config || !chan_out_config) {
+                       result = -ENOMEM;
+                       goto err_alloc_configs;
                }
 
                tty_setspeed(devpriv->tty, devpriv->speed);
@@ -447,7 +444,7 @@ static void serial_2002_open(struct comedi_device *dev)
                                break;
                        } else {
                                int command, channel, kind;
-                               struct config_t *cur_config = 0;
+                               struct config_t *cur_config = NULL;
 
                                channel = data.value & 0x1f;
                                kind = (data.value >> 5) & 0x7;
@@ -574,8 +571,8 @@ static void serial_2002_open(struct comedi_device *dev)
                for (i = 0; i <= 4; i++) {
                        /*  Fill in subdev data */
                        struct config_t *c;
-                       unsigned char *mapping = 0;
-                       struct serial2002_range_table_t *range = 0;
+                       unsigned char *mapping = NULL;
+                       struct serial2002_range_table_t *range = NULL;
                        int kind = 0;
 
                        switch (i) {
@@ -613,7 +610,7 @@ static void serial_2002_open(struct comedi_device *dev)
                                }
                                break;
                        default:{
-                                       c = 0;
+                                       c = NULL;
                                }
                                break;
                        }
@@ -632,22 +629,23 @@ static void serial_2002_open(struct comedi_device *dev)
                                s = &dev->subdevices[i];
                                s->n_chan = chan;
                                s->maxdata = 0;
-                               if (s->maxdata_list) {
-                                       kfree(s->maxdata_list);
-                               }
+                               kfree(s->maxdata_list);
                                s->maxdata_list = maxdata_list =
                                    kmalloc(sizeof(unsigned int) * s->n_chan,
                                            GFP_KERNEL);
-                               if (s->range_table_list) {
-                                       kfree(s->range_table_list);
-                               }
+                               if (!s->maxdata_list)
+                                       break;  /* error handled below */
+                               kfree(s->range_table_list);
+                               s->range_table = NULL;
+                               s->range_table_list = NULL;
                                if (range) {
-                                       s->range_table = 0;
                                        s->range_table_list = range_table_list =
                                            kmalloc(sizeof
                                                    (struct
                                                     serial2002_range_table_t) *
                                                    s->n_chan, GFP_KERNEL);
+                                       if (!s->range_table_list)
+                                               break;  /* err handled below */
                                }
                                for (chan = 0, j = 0; j < 32; j++) {
                                        if (c[j].kind == kind) {
@@ -673,7 +671,35 @@ static void serial_2002_open(struct comedi_device *dev)
                                }
                        }
                }
+               if (i <= 4) {
+                       /* Failed to allocate maxdata_list or range_table_list
+                        * for a subdevice that needed it.  */
+                       result = -ENOMEM;
+                       for (i = 0; i <= 4; i++) {
+                               struct comedi_subdevice *s;
+
+                               s = &dev->subdevices[i];
+                               kfree(s->maxdata_list);
+                               s->maxdata_list = NULL;
+                               kfree(s->range_table_list);
+                               s->range_table_list = NULL;
+                       }
+               }
+
+err_alloc_configs:
+               kfree(dig_in_config);
+               kfree(dig_out_config);
+               kfree(chan_in_config);
+               kfree(chan_out_config);
+
+               if (result) {
+                       if (devpriv->tty) {
+                               filp_close(devpriv->tty, 0);
+                               devpriv->tty = NULL;
+                       }
+               }
        }
+       return result;
 }
 
 static void serial_2002_close(struct comedi_device *dev)
@@ -879,7 +905,7 @@ static int serial2002_detach(struct comedi_device *dev)
        int i;
 
        printk("comedi%d: serial2002: remove\n", dev->minor);
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < 5; i++) {
                s = &dev->subdevices[i];
                if (s->maxdata_list) {
                        kfree(s->maxdata_list);
@@ -891,4 +917,19 @@ static int serial2002_detach(struct comedi_device *dev)
        return 0;
 }
 
-COMEDI_INITCLEANUP(driver_serial2002);
+static int __init driver_serial2002_init_module(void)
+{
+       return comedi_driver_register(&driver_serial2002);
+}
+
+static void __exit driver_serial2002_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_serial2002);
+}
+
+module_init(driver_serial2002_init_module);
+module_exit(driver_serial2002_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 490753b3d90439ea97fb0a9bcdbd1fe3b66e096f..0b9ecb19511e71deaabc4a0024722c673b93c2c8 100644 (file)
@@ -39,28 +39,28 @@ Configuration Options:
  * The previous block comment is used to automatically generate
  * documentation in Comedi and Comedilib.  The fields:
  *
- * Driver: the name of the driver
- * Description: a short phrase describing the driver.  Don't list boards.
- * Devices: a full list of the boards that attempt to be supported by
- *   the driver.  Format is "(manufacturer) board name [comedi name]",
- *   where comedi_name is the name that is used to configure the board.
- *   See the comment near board_name: in the struct comedi_driver structure
- *   below.  If (manufacturer) or [comedi name] is missing, the previous
- *   value is used.
- * Author: you
- * Updated: date when the _documentation_ was last updated.  Use 'date -R'
- *   to get a value for this.
- * Status: a one-word description of the status.  Valid values are:
- *   works - driver works correctly on most boards supported, and
- *     passes comedi_test.
- *   unknown - unknown.  Usually put there by ds.
- *   experimental - may not work in any particular release.  Author
- *     probably wants assistance testing it.
- *   bitrotten - driver has not been update in a long time, probably
- *     doesn't work, and probably is missing support for significant
- *     Comedi interface features.
- *   untested - author probably wrote it "blind", and is believed to
- *     work, but no confirmation.
+ *  Driver: the name of the driver
+ *  Description: a short phrase describing the driver.  Don't list boards.
+ *  Devices: a full list of the boards that attempt to be supported by
+ *    the driver.  Format is "(manufacturer) board name [comedi name]",
+ *    where comedi_name is the name that is used to configure the board.
+ *    See the comment near board_name: in the struct comedi_driver structure
+ *    below.  If (manufacturer) or [comedi name] is missing, the previous
+ *    value is used.
+ *  Author: you
+ *  Updated: date when the _documentation_ was last updated.  Use 'date -R'
+ *    to get a value for this.
+ *  Status: a one-word description of the status.  Valid values are:
+ *    works - driver works correctly on most boards supported, and
+ *      passes comedi_test.
+ *    unknown - unknown.  Usually put there by ds.
+ *    experimental - may not work in any particular release.  Author
+ *      probably wants assistance testing it.
+ *    bitrotten - driver has not been update in a long time, probably
+ *      doesn't work, and probably is missing support for significant
+ *      Comedi interface features.
+ *    untested - author probably wrote it "blind", and is believed to
+ *      work, but no confirmation.
  *
  * These headers should be followed by a blank line, and any comments
  * you wish to say about the driver.  The comment area is the place
@@ -620,12 +620,59 @@ static int skel_dio_insn_config(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
- * A convenient macro that defines init_module() and cleanup_module(),
- * as necessary.
- */
-COMEDI_INITCLEANUP(driver_skel);
-/* If you are writing a PCI driver you should use COMEDI_PCI_INITCLEANUP
- * instead.
- */
-/* COMEDI_PCI_INITCLEANUP(driver_skel, skel_pci_table) */
+#ifdef CONFIG_COMEDI_PCI
+static int __devinit driver_skel_pci_probe(struct pci_dev *dev,
+                                          const struct pci_device_id *ent)
+{
+       return comedi_pci_auto_config(dev, driver_skel.driver_name);
+}
+
+static void __devexit driver_skel_pci_remove(struct pci_dev *dev)
+{
+       comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_skel_pci_driver = {
+       .id_table = skel_pci_table,
+       .probe = &driver_skel_pci_probe,
+       .remove = __devexit_p(&driver_skel_pci_remove)
+};
+
+static int __init driver_skel_init_module(void)
+{
+       int retval;
+
+       retval = comedi_driver_register(&driver_skel);
+       if (retval < 0)
+               return retval;
+
+       driver_skel_pci_driver.name = (char *)driver_skel.driver_name;
+       return pci_register_driver(&driver_skel_pci_driver);
+}
+
+static void __exit driver_skel_cleanup_module(void)
+{
+       pci_unregister_driver(&driver_skel_pci_driver);
+       comedi_driver_unregister(&driver_skel);
+}
+
+module_init(driver_skel_init_module);
+module_exit(driver_skel_cleanup_module);
+#else
+static int __init driver_skel_init_module(void)
+{
+       return comedi_driver_register(&driver_skel);
+}
+
+static void __exit driver_skel_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_skel);
+}
+
+module_init(driver_skel_init_module);
+module_exit(driver_skel_cleanup_module);
+#endif
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 18b0a83c4bbc7f698afd8215c59d0123872223a9..526de2efa125ebe09f07ab0ec628d7a8b1880b49 100644 (file)
@@ -102,7 +102,18 @@ static struct comedi_driver driver_dnp = {
        .num_names = ARRAY_SIZE(dnp_boards),
 };
 
-COMEDI_INITCLEANUP(driver_dnp);
+static int __init driver_dnp_init_module(void)
+{
+       return comedi_driver_register(&driver_dnp);
+}
+
+static void __exit driver_dnp_cleanup_module(void)
+{
+       comedi_driver_unregister(&driver_dnp);
+}
+
+module_init(driver_dnp_init_module);
+module_exit(driver_dnp_cleanup_module);
 
 static int dnp_dio_insn_bits(struct comedi_device *dev,
                             struct comedi_subdevice *s,
@@ -314,3 +325,7 @@ static int dnp_dio_insn_config(struct comedi_device *dev,
        return 1;
 
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 16d4c9f69165726867007d6f43e3e11c2859d6be..598884ec3ede576afcf3b49cd35e4d2a375d4222 100644 (file)
@@ -114,7 +114,18 @@ static struct comedi_driver unioxx5_driver = {
        .detach = unioxx5_detach
 };
 
-COMEDI_INITCLEANUP(unioxx5_driver);
+static int __init unioxx5_driver_init_module(void)
+{
+       return comedi_driver_register(&unioxx5_driver);
+}
+
+static void __exit unioxx5_driver_cleanup_module(void)
+{
+       comedi_driver_unregister(&unioxx5_driver);
+}
+
+module_init(unioxx5_driver_init_module);
+module_exit(unioxx5_driver_cleanup_module);
 
 static int unioxx5_attach(struct comedi_device *dev,
                          struct comedi_devconfig *it)
@@ -302,7 +313,8 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev,
                __unioxx5_analog_config(usp, i * 2);
                outb(i + 1, subdev_iobase + 5); /* sends channel number to card */
                outb('H', subdev_iobase + 6);   /* requests EEPROM world */
-               while (!(inb(subdev_iobase + 0) & TxBE)) ;      /* waits while writting will be allowed */
+               while (!(inb(subdev_iobase + 0) & TxBE))
+                       ;       /* waits while writting will be allowed */
                outb(0, subdev_iobase + 6);
 
                /* waits while reading of two bytes will be allowed */
@@ -437,7 +449,8 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp,
 
        /* sending for bytes to module(one byte per cycle iteration) */
        for (i = 0; i < 4; i++) {
-               while (!((inb(usp->usp_iobase + 0)) & TxBE)) ;  /* waits while writting will be allowed */
+               while (!((inb(usp->usp_iobase + 0)) & TxBE))
+                       ;       /* waits while writting will be allowed */
                outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6);
        }
 
@@ -467,7 +480,8 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp,
        control = inb(usp->usp_iobase); /* get control register byte */
 
        /* waits while reading four bytes will be allowed */
-       while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA)) ;
+       while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA))
+               ;
 
        /* if four bytes readding error occurs - return 0(false) */
        if ((control & Rx4CA_ERR_MASK)) {
@@ -526,3 +540,7 @@ static int __unioxx5_define_chan_offset(int chan_num)
 
        return (chan_num >> 3) + 1;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 27b4cb2e2ec2924928b44089c92dc61ee9bab87a..4b320b1ff8237e068345d998fde8563190e4b937 100644 (file)
@@ -111,7 +111,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
 #define VENDOR_DIR_IN  0xC0
 #define VENDOR_DIR_OUT 0x40
 
-/* internal adresses of the 8051 processor */
+/* internal addresses of the 8051 processor */
 #define USBDUXSUB_CPUCS 0xE600
 
 /*
@@ -2085,7 +2085,7 @@ static int usbdux_pwm_start(struct comedi_device *dev,
        if (ret < 0)
                return ret;
 
-       /* initalise the buffer */
+       /* initialise the buffer */
        for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
                ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
 
index 29c3c016b93a6458f625397f098458a58e37208d..0a164a9a66c3b0024890b61a76e0178abf576023 100644 (file)
@@ -67,7 +67,7 @@
 #define VENDOR_DIR_OUT         0x40
 
 /*
- * internal adresses of the 8051 processor
+ * internal addresses of the 8051 processor
  */
 #define USBDUXFASTSUB_CPUCS    0xE600
 
index 863aae40edeb55f7a089a36502fc610a1875859f..0252b4408851b17cf973617bcd9018237ade1f85 100644 (file)
@@ -93,7 +93,7 @@ static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn)
        s = dev->subdevices + insn->subdev;
 
        if (s->type == COMEDI_SUBD_UNUSED) {
-               printk("%d not useable subdevice\n", insn->subdev);
+               printk(KERN_ERR "%d not useable subdevice\n", insn->subdev);
                ret = -EIO;
                goto error;
        }
@@ -102,7 +102,7 @@ static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn)
 
        ret = comedi_check_chanlist(s, 1, &insn->chanspec);
        if (ret < 0) {
-               printk("bad chanspec\n");
+               printk(KERN_ERR "bad chanspec\n");
                ret = -EINVAL;
                goto error;
        }
index a4ec891328cd586adf34222abbe5dad7f772e61e..fbb80f09a3d9213f85b8091c965a2c2e5642886d 100644 (file)
   along with this driver.  If not, see <http://www.gnu.org/licenses/>.
 ***************************************************************************/
 
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
 #include <linux/slab.h>
 
 #include "crystalhd_lnx.h"
 
+static DEFINE_MUTEX(chd_dec_mutex);
 static struct class *crystalhd_class;
 
 static struct crystalhd_adp *g_adp_info;
@@ -152,10 +153,8 @@ static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, struct crystalhd_ioctl
        if (rc) {
                BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
                           io->add_cdata_sz, (unsigned int)ua_off);
-               if (io->add_cdata) {
-                       kfree(io->add_cdata);
-                       io->add_cdata = NULL;
-               }
+               kfree(io->add_cdata);
+               io->add_cdata = NULL;
                return -ENODATA;
        }
 
@@ -273,22 +272,22 @@ static long chd_dec_ioctl(struct file *fd, unsigned int cmd, unsigned long ua)
                return -EINVAL;
        }
 
-       uc = (struct crystalhd_user *)fd->private_data;
+       uc = fd->private_data;
        if (!uc) {
                BCMLOG_ERR("Failed to get uc\n");
                return -ENODATA;
        }
 
-       lock_kernel();
+       mutex_lock(&chd_dec_mutex);
        cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc);
        if (!cproc) {
                BCMLOG_ERR("Unhandled command: %d\n", cmd);
-               unlock_kernel();
+               mutex_unlock(&chd_dec_mutex);
                return -EINVAL;
        }
 
        ret = chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc);
-       unlock_kernel();
+       mutex_unlock(&chd_dec_mutex);
        return ret;
 }
 
@@ -334,7 +333,7 @@ static int chd_dec_close(struct inode *in, struct file *fd)
                return -EINVAL;
        }
 
-       uc = (struct crystalhd_user *)fd->private_data;
+       uc = fd->private_data;
        if (!uc) {
                BCMLOG_ERR("Failed to get uc\n");
                return -ENODATA;
@@ -435,8 +434,7 @@ static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
        /* Clear iodata pool.. */
        do {
                temp = chd_dec_alloc_iodata(adp, 0);
-               if (temp)
-                       kfree(temp);
+               kfree(temp);
        } while (temp);
 
        crystalhd_delete_elem_pool(adp);
index a43b18816fa51b372f76704cec75c9e185fc6c50..bbe36437ac16e02d3d5e00c3f6693838d341996a 100644 (file)
@@ -698,7 +698,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
 
        /* Card "creation" */
        card->private_free = snd_cx25821_dev_free;
-       chip = (struct cx25821_audio_dev *) card->private_data;
+       chip = card->private_data;
        spin_lock_init(&chip->reg_lock);
 
        chip->dev = dev;
index 86b4980902654d8c0e47081ef077774ca5cb2578..23ea101d7a894c54fb75ca6026d4bf06bd1b46d7 100644 (file)
@@ -122,19 +122,7 @@ watchdog_func (unsigned long arg)
             pr_warning("%s: drvr not available (%x)\n", __func__, drvr_state);
         return;
     }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    /* Initialize the tq entry only the first time */
-    if (wd->init_tq)
-    {
-        wd->init_tq = 0;
-        wd->tq.routine = wd->func;
-        wd->tq.sync = 0;
-        wd->tq.data = wd->softc;
-    }
-    schedule_task (&wd->tq);
-#else
     schedule_work (&wd->work);
-#endif
     mod_timer (&wd->h, jiffies + wd->ticks);
 }
 
index 4c8610293fcc3d4c9567e0781f1f635e76c560bd..89200e7af26c99e6c67e472662fe97cd53b4722b 100644 (file)
@@ -305,15 +305,9 @@ c4hw_attach_all (void)
     error_flag = 0;
     prep_hdw_info ();
     /*** scan PCI bus for all possible boards */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     while ((pdev = pci_get_device (PCI_VENDOR_ID_CONEXANT,
-                                   PCI_DEVICE_ID_CN8474,
-                                   pdev)))
-#else
-    while ((pdev = pci_find_device (PCI_VENDOR_ID_CONEXANT,
                                     PCI_DEVICE_ID_CN8474,
                                     pdev)))
-#endif
     {
         if (c4_hdw_init (pdev, found))
             found++;
index 134e7568024b86b97ac1b0e3088d8bd96f3e608d..eb0f4bdf6273474d64d3e0f6307d87b56d715fe6 100644 (file)
@@ -142,10 +142,6 @@ getuserbychan (int channum)
 }
 
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#define DEV_TO_PRIV(dev) ( * (struct c4_priv **) ((hdlc_device*)(dev)+1))
-#else
-
 char       *
 get_hdlc_name (hdlc_device * hdlc)
 {
@@ -154,7 +150,6 @@ get_hdlc_name (hdlc_device * hdlc)
 
     return dev->name;
 }
-#endif
 
 
 static      status_t
@@ -167,7 +162,6 @@ mkret (int bsd)
 }
 
 /***************************************************************************/
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
 #include <linux/workqueue.h>
 
 /***
@@ -259,7 +253,6 @@ c4_wq_port_cleanup (mpi_t * pi)
         pi->wq_port = 0;
     }
 }
-#endif
 
 /***************************************************************************/
 
@@ -291,48 +284,6 @@ void_open (struct net_device * ndev)
 }
 
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
-
-/** Linux 2.4.18-19 **/
-STATIC int
-chan_open (hdlc_device * hdlc)
-{
-    status_t    ret;
-
-    if ((ret = c4_chan_up (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum)))
-        return -ret;
-    MOD_INC_USE_COUNT;
-    netif_start_queue (hdlc_to_dev (hdlc));
-    return 0;                       /* no error = success */
-}
-
-#else
-
-/** Linux 2.4.20 and higher **/
-STATIC int
-chan_open (struct net_device * ndev)
-{
-    hdlc_device *hdlc = dev_to_hdlc (ndev);
-    status_t    ret;
-
-    hdlc->proto = IF_PROTO_HDLC;
-    if ((ret = hdlc_open (hdlc)))
-    {
-        pr_info("hdlc_open failure, err %d.\n", ret);
-        return ret;
-    }
-    if ((ret = c4_chan_up (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum)))
-        return -ret;
-    MOD_INC_USE_COUNT;
-    netif_start_queue (hdlc_to_dev (hdlc));
-    return 0;                       /* no error = success */
-}
-#endif
-
-#else
-
-/** Linux 2.6 **/
 STATIC int
 chan_open (struct net_device * ndev)
 {
@@ -351,39 +302,8 @@ chan_open (struct net_device * ndev)
     netif_start_queue (ndev);
     return 0;                       /* no error = success */
 }
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
-
-/** Linux 2.4.18-19 **/
-STATIC void
-chan_close (hdlc_device * hdlc)
-{
-    netif_stop_queue (hdlc_to_dev (hdlc));
-    musycc_chan_down ((ci_t *) 0, DEV_TO_PRIV (hdlc)->channum);
-    MOD_DEC_USE_COUNT;
-}
-#else
-
-/** Linux 2.4.20 and higher **/
-STATIC int
-chan_close (struct net_device * ndev)
-{
-    hdlc_device *hdlc = dev_to_hdlc (ndev);
-
-    netif_stop_queue (hdlc_to_dev (hdlc));
-    musycc_chan_down ((ci_t *) 0, DEV_TO_PRIV (hdlc)->channum);
-    hdlc_close (hdlc);
-    MOD_DEC_USE_COUNT;
-    return 0;
-}
-#endif
 
-#else
 
-/** Linux 2.6 **/
 STATIC int
 chan_close (struct net_device * ndev)
 {
@@ -396,37 +316,8 @@ chan_close (struct net_device * ndev)
     module_put (THIS_MODULE);
     return 0;
 }
-#endif
-
-
-#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
-
-/** Linux 2.4.18-19 **/
-STATIC int
-chan_ioctl (hdlc_device * hdlc, struct ifreq * ifr, int cmd)
-{
-    if (cmd == HDLCSCLOCK)
-    {
-        ifr->ifr_ifru.ifru_ivalue = LINE_DEFAULT;
-        return 0;
-    }
-    return -EINVAL;
-}
-#endif
 
 
-#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
-STATIC int
-chan_dev_ioctl (struct net_device * hdlc, struct ifreq * ifr, int cmd)
-{
-    if (cmd == HDLCSCLOCK)
-    {
-        ifr->ifr_ifru.ifru_ivalue = LINE_DEFAULT;
-        return 0;
-    }
-    return -EINVAL;
-}
-#else
 STATIC int
 chan_dev_ioctl (struct net_device * dev, struct ifreq * ifr, int cmd)
 {
@@ -435,16 +326,11 @@ chan_dev_ioctl (struct net_device * dev, struct ifreq * ifr, int cmd)
 
 
 STATIC int
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-chan_attach_noop (hdlc_device * hdlc, unsigned short foo_1, unsigned short foo_2)
-#else
 chan_attach_noop (struct net_device * ndev, unsigned short foo_1, unsigned short foo_2)
-#endif
 {
     return 0;                   /* our driver has nothing to do here, show's
                                  * over, go home */
 }
-#endif
 
 
 STATIC struct net_device_stats *
@@ -455,16 +341,12 @@ chan_get_stats (struct net_device * ndev)
     struct sbecom_chan_stats *stats;
     int         channum;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    channum = DEV_TO_PRIV (ndev)->channum;
-#else
     {
         struct c4_priv *priv;
 
         priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
         channum = priv->channum;
     }
-#endif
 
     ch = c4_find_chan (channum);
     if (ch == NULL)
@@ -511,34 +393,19 @@ get_ci_by_dev (struct net_device * ndev)
 }
 
 
-#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
-STATIC int
-c4_linux_xmit (hdlc_device * hdlc, struct sk_buff * skb)
-{
-    int         rval;
-
-    rval = musycc_start_xmit (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum, skb);
-    return -rval;
-}
-#else                           /* new */
 STATIC int
 c4_linux_xmit (struct sk_buff * skb, struct net_device * ndev)
 {
     const struct c4_priv *priv;
     int         rval;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    priv = DEV_TO_PRIV (ndev);
-#else
     hdlc_device *hdlc = dev_to_hdlc (ndev);
 
     priv = hdlc->priv;
-#endif
 
     rval = musycc_start_xmit (priv->ci, priv->channum, skb);
     return -rval;
 }
-#endif                          /* GENERIC_HDLC_VERSION */
 
 static const struct net_device_ops chan_ops = {
        .ndo_open       = chan_open,
@@ -823,18 +690,10 @@ do_create_chan (struct net_device * ndev, void *data)
     ret = mkret (c4_new_chan (ci, cp.port, cp.channum, dev));
     if (ret)
     {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-        rtnl_unlock ();             /* needed due to Ioctl calling sequence */
-        V7 (unregister_hdlc_device) (dev_to_hdlc (dev));
-        rtnl_lock ();               /* needed due to Ioctl calling sequence */
-        OS_kfree (DEV_TO_PRIV (dev));
-        OS_kfree (dev);
-#else
         rtnl_unlock ();             /* needed due to Ioctl calling sequence */
         unregister_hdlc_device (dev);
         rtnl_lock ();               /* needed due to Ioctl calling sequence */
         free_netdev (dev);
-#endif
     }
     return ret;
 }
@@ -883,11 +742,7 @@ do_deluser (struct net_device * ndev, int lockit)
         const struct c4_priv *priv;
         int         channum;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-        priv = DEV_TO_PRIV (ndev);
-#else
         priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
-#endif
         ci = priv->ci;
         channum = priv->channum;
 
@@ -897,22 +752,12 @@ do_deluser (struct net_device * ndev, int lockit)
         ch->user = 0;               /* will be freed, below */
     }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    if (lockit)
-        rtnl_unlock ();             /* needed if Ioctl calling sequence */
-    V7 (unregister_hdlc_device) (dev_to_hdlc (ndev));
-    if (lockit)
-        rtnl_lock ();               /* needed if Ioctl calling sequence */
-    OS_kfree (DEV_TO_PRIV (ndev));
-    OS_kfree (ndev);
-#else
     if (lockit)
         rtnl_unlock ();             /* needed if Ioctl calling sequence */
     unregister_hdlc_device (ndev);
     if (lockit)
         rtnl_lock ();               /* needed if Ioctl calling sequence */
     free_netdev (ndev);
-#endif
     return 0;
 }
 
@@ -1339,14 +1184,6 @@ c4_mod_remove (void)
 module_init (c4_mod_init);
 module_exit (c4_mod_remove);
 
-#ifndef SBE_INCLUDE_SYMBOLS
-#ifndef CONFIG_SBE_WANC24_NCOMM
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-EXPORT_NO_SYMBOLS;
-#endif
-#endif
-#endif
-
 MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>");
 MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
 #ifdef MODULE_LICENSE
index d3f5a5b52dc36d1dcd17a4751786beaee201df47..12c76a553e0fc87fcb96e54d0b76e4b8ae314ef4 100644 (file)
@@ -405,7 +405,6 @@ musycc_update_tx_thp (mch_t * ch)
 }
 
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
 /*
  * This is the workq task executed by the OS when our queue_work() is
  * scheduled and run.  It can fire off either RX or TX ACTIVATION depending
@@ -515,7 +514,6 @@ musycc_wq_chan_restart (void *arg)      /* channel private structure */
 #endif
     }
 }
-#endif
 
 
  /*
@@ -531,7 +529,6 @@ musycc_chan_restart (mch_t * ch)
             ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status);
 #endif
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
     /* 2.6 - find next unprocessed message, then set TX thp to it */
 #ifdef RLD_RESTART_DEBUG
     pr_info(">> musycc_chan_restart: scheduling Chan %x workQ @ %p\n", ch->channum, &ch->ch_work);
@@ -539,51 +536,9 @@ musycc_chan_restart (mch_t * ch)
     c4_wk_chan_restart (ch);        /* work queue mechanism fires off: Ref:
                                      * musycc_wq_chan_restart () */
 
-#else
-
-
-    /* 2.4 - find next unprocessed message, then set TX thp to it */
-#ifdef RLD_RESTART_DEBUG
-    pr_info(">> musycc_chan_restart: scheduling Chan %x start_tx %x\n", ch->channum, ch->ch_start_tx);
-#endif
-    /* restart transmission from background loop */
-    ch->up->up->wd_notify = WD_NOTIFY_1TX;
-#endif
 }
 
 
-#if 0
-void
-musycc_cleanup (ci_t * ci)
-{
-    mpi_t      *pi;
-    int         i, j;
-
-    /* free up driver resources */
-    ci->state = C_INIT;             /* mark as hardware not available */
-
-    for (i = 0; i < ci->max_ports; i++)
-    {
-        pi = &ci->port[i];
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
-        c4_wq_port_cleanup (pi);
-#endif
-        for (j = 0; j < MUSYCC_NCHANS; j++)
-        {
-            if (pi->chan[j])
-                OS_kfree (pi->chan[j]); /* free mch_t struct */
-        }
-        OS_kfree (pi->regram_saved);
-    }
-#if 0
-    /* obsolete - watchdog is now static w/in ci_t */
-    OS_free_watchdog (ci->wd);
-#endif
-    OS_kfree (ci->iqd_p_saved);
-    OS_kfree (ci);
-}
-#endif
-
 void
 rld_put_led (mpi_t * pi, u_int32_t ledval)
 {
@@ -2008,37 +1963,13 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
     atomic_add (len, &ci->tx_pending);
     ch->s.tx_packets++;
     ch->s.tx_bytes += len;
-#if 0
-    spin_unlock_irqrestore (&ch->ch_txlock, flags);   /* allow pending
-                                                       * interrupt to sneak
-                                                       * thru */
-#endif
-
     /*
      * If an ONR was seen, then channel requires poking to restart
      * transmission.
      */
     if (ch->ch_start_tx)
     {
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,41)
-        SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_");  /* only 1 thru here, per
-                                                 * board */
-        if ((ch->ch_start_tx == CH_START_TX_ONR) && (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
-        {
-            /* ONR restart transmission from background loop */
-            ci->wd_notify = WD_NOTIFY_ONR;      /* enabled global watchdog
-                                                 * scan-thru  */
-        } else
-        {
-            /* start first transmission from background loop */
-            ci->wd_notify = WD_NOTIFY_1TX;      /* enabled global watchdog
-                                                 * scan-thru  */
-        }
         musycc_chan_restart (ch);
-        SD_SEM_GIVE (&ci->sem_wdbusy);
-#else
-        musycc_chan_restart (ch);
-#endif
     }
 #ifdef SBE_WAN256T3_ENABLE
     wan256t3_led (ci, LED_TX, LEDV_G);
@@ -2047,139 +1978,4 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
 }
 
 
-#if 0
-int
-musycc_set_chan (ci_t * ci, int channum, struct sbecom_chan_param * p)
-{
-    mch_t      *ch;
-    int         rok = 0;
-    int         n = 0;
-
-    if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS))      /* sanity chk param */
-        return ECHRNG;
-    if (!(ch = sd_find_chan (ci, channum)))
-        return ENOENT;
-    if (ch->channum != p->channum)
-        return EINVAL;
-    if (sd_line_is_ok (ch->user))
-    {
-        rok = 1;
-        sd_line_is_down (ch->user);
-    }
-    if (ch->state == UP &&          /* bring down in current configuration */
-        (ch->p.status != p->status ||
-         ch->p.chan_mode != p->chan_mode ||
-         ch->p.intr_mask != p->intr_mask ||
-         ch->txd_free < ch->txd_num))
-    {
-        if ((n = musycc_chan_down (ci, channum)))
-            return n;
-        if (ch->p.mode_56k != p->mode_56k)
-        {
-            ch->p = *p;             /* copy in new parameters */
-            musycc_update_timeslots (&ci->port[ch->channum / MUSYCC_NCHANS]);
-        } else
-            ch->p = *p;             /* copy in new parameters */
-        if ((n = musycc_chan_up (ci, channum)))
-            return n;
-        sd_enable_xmit (ch->user);  /* re-enable to catch flow controlled
-                                     * channel */
-    } else
-    {
-        if (ch->p.mode_56k != p->mode_56k)
-        {
-            ch->p = *p;             /* copy in new parameters */
-            musycc_update_timeslots (&ci->port[ch->channum / MUSYCC_NCHANS]);
-        } else
-            ch->p = *p;             /* copy in new parameters */
-    }
-
-    if (rok)
-        sd_line_is_up (ch->user);
-    return 0;
-}
-#endif
-
-
-int
-musycc_get_chan (ci_t * ci, int channum, struct sbecom_chan_param * p)
-{
-    mch_t      *ch;
-
-#if 0
-    if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS))      /* sanity chk param */
-        return ECHRNG;
-#endif
-    if (!(ch = sd_find_chan (ci, channum)))
-        return ENOENT;
-    *p = ch->p;
-    return 0;
-}
-
-
-int
-musycc_get_chan_stats (ci_t * ci, int channum, struct sbecom_chan_stats * p)
-{
-    mch_t      *ch;
-
-    if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS))      /* sanity chk param */
-        return ECHRNG;
-    if (!(ch = sd_find_chan (ci, channum)))
-        return ENOENT;
-    *p = ch->s;
-    p->tx_pending = atomic_read (&ch->tx_pending);
-    return 0;
-}
-
-
-
-#ifdef SBE_WAN256T3_ENABLE
-int
-musycc_chan_down (ci_t * ci, int channum)
-{
-    mch_t      *ch;
-    mpi_t      *pi;
-    int         i, gchan;
-
-    if (!(ch = sd_find_chan (ci, channum)))
-        return EINVAL;
-    pi = ch->up;
-    gchan = ch->gchan;
-
-    /* Deactivate the channel */
-    musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan);
-    ch->ch_start_rx = 0;
-    musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan);
-    ch->ch_start_tx = 0;
-
-    if (ch->state == DOWN)
-        return 0;
-    ch->state = DOWN;
-
-    pi->regram->thp[gchan] = 0;
-    pi->regram->tmp[gchan] = 0;
-    pi->regram->rhp[gchan] = 0;
-    pi->regram->rmp[gchan] = 0;
-    FLUSH_MEM_WRITE ();
-    for (i = 0; i < ch->txd_num; i++)
-    {
-        if (ch->mdt[i].mem_token != 0)
-            OS_mem_token_free (ch->mdt[i].mem_token);
-    }
-
-    for (i = 0; i < ch->rxd_num; i++)
-    {
-        if (ch->mdr[i].mem_token != 0)
-            OS_mem_token_free (ch->mdr[i].mem_token);
-    }
-
-    OS_kfree (ch->mdt);
-    ch->mdt = 0;
-    OS_kfree (ch->mdr);
-    ch->mdr = 0;
-
-    return 0;
-}
-#endif
-
 /*** End-of-File ***/
index 1c8dfb80e7d7f4659c89573c9319a8c670758c1d..62b12fb45fcc786204a10ecb1fea49effeb3aa9e 100644 (file)
@@ -500,11 +500,7 @@ pmc_init_seeprom (u_int32_t addr, u_int32_t serialNum)
     time_t      createTime;
     int         i;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    createTime = CURRENT_TIME;
-#else
     createTime = get_seconds ();
-#endif
 
     /* use template data */
     for (i = 0; i < sizeof (FLD_TYPE2); ++i)
index 26c1f0ea72e96dbde77cadbf9c20291c66da47d2..ef6ac7fe7ddd54755682121cd244a9856670875f 100644 (file)
@@ -117,12 +117,8 @@ extern      "C"
 
 #include "pmcc4_private.h"
 
-#if !(LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 char       *get_hdlc_name (hdlc_device *);
 
-#endif
-
-
 /*
  * external interface
  */
index 333cf2687dd16a3c4a55be13d867fac04e22b230..9f730e68526c3810546486ea2d4e0e327c5babf2 100644 (file)
@@ -119,12 +119,10 @@ char        OSSIid_pmcc4_drvc[] =
 #define KERN_WARN KERN_WARNING
 
 /* forward references */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
 status_t    c4_wk_chan_init (mpi_t *, mch_t *);
 void        c4_wq_port_cleanup (mpi_t *);
 status_t    c4_wq_port_init (mpi_t *);
 
-#endif
 int         c4_loop_port (ci_t *, int, u_int8_t);
 status_t    c4_set_port (ci_t *, int);
 status_t    musycc_chan_down (ci_t *, int);
@@ -533,145 +531,15 @@ checkPorts (ci_t * ci)
 STATIC void
 c4_watchdog (ci_t * ci)
 {
-#if 0
-    //unsigned long flags;
-#endif
-
     if (drvr_state != SBE_DRVR_AVAILABLE)
     {
         if (log_level >= LOG_MONITOR)
             pr_info("drvr not available (%x)\n", drvr_state);
         return;
     }
-#if 0
-    SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_");    /* only 1 thru here, per
-                                               * board */
-#endif
-
     ci->wdcount++;
     checkPorts (ci);
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,41)
-    if (ci->wd_notify)
-    {                               /* is there a state change to search for */
-        int         port, gchan;
-
-        ci->wd_notify = 0;          /* reset notification */
-        for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
-        {
-            for (port = 0; port < ci->max_port; port++)
-            {
-                mch_t      *ch = ci->port[port].chan[gchan];
-
-                if (!ch || ci->state != C_RUNNING)      /* state changed while
-                                                         * acquiring semaphore */
-                    break;
-                if (ch->state == UP)/* channel must be set up */
-                {
-#if 0
-#ifdef RLD_TRANS_DEBUG
-                    if (1 || log_level >= LOG_MONITOR)
-#else
-                    if (log_level >= LOG_MONITOR)
-#endif
-                        pr_info("%s: watchdog reviving Port %d Channel %d [%d] sts %x/%x, start_TX %x free %x start_RX %x\n",
-                         ci->devname, ch->channum, port, gchan, ch->channum,
-                                ch->p.status, ch->status,
-                            ch->ch_start_tx, ch->txd_free, ch->ch_start_rx);
-#endif
-
-                    /**********************************/
-                    /** check for RX restart request **/
-                    /**********************************/
-
-                    if (ch->ch_start_rx &&
-                        (ch->status & RX_ENABLED))      /* requires start on
-                                                         * enabled RX */
-                    {
-                        ch->ch_start_rx = 0;    /* we are restarting RX... */
-#ifdef RLD_TRANS_DEBUG
-                        pr_info("++ c4_watchdog() CHAN RX ACTIVATE: chan %d\n",
-                                ch->channum);
-#endif
-#ifdef RLD_RXACT_DEBUG
-                        {
-                            struct mdesc *md;
-                            static int  hereb4 = 7;
-
-                            if (hereb4)
-                            {
-                                hereb4--;
-                                md = &ch->mdr[ch->rxix_irq_srv];
-                                pr_info("++ c4_watchdog[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
-                                        ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), ch->s.rx_packets);
-                                musycc_dump_rxbuffer_ring (ch, 1);      /* RLD DEBUG */
-                            }
-                        }
-#endif
-                        musycc_serv_req (ch->up, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan);
-                    }
-                    /**********************************/
-                    /** check for TX restart request **/
-                    /**********************************/
-
-                    if (ch->ch_start_tx &&
-                        (ch->status & TX_ENABLED))      /* requires start on
-                                                         * enabled TX */
-                    {
-                        struct mdesc *md;
-
-                        /*
-                         * find next unprocessed message, then set TX thp to
-                         * it
-                         */
-                        musycc_update_tx_thp (ch);
-
-#if 0
-                        spin_lock_irqsave (&ch->ch_txlock, flags);
-#endif
-                        md = ch->txd_irq_srv;
-                        if (!md)
-                        {
-                            pr_info("-- c4_watchdog[%d]: WARNING, starting NULL md\n",
-                                    ch->channum);
-                            pr_info("--   chan %d txd_irq_srv %p sts %x usr_add %p sts %x, txpkt %lu\n",
-                                    ch->channum, ch->txd_irq_srv, le32_to_cpu ((struct mdesc *) (ch->txd_irq_srv)->status),
-                                    ch->txd_usr_add, le32_to_cpu ((struct mdesc *) (ch->txd_usr_add)->status),
-                                    ch->s.tx_packets);
-#if 0
-                            spin_unlock_irqrestore (&ch->ch_txlock, flags);
-#endif
-                        } else if (md->data && ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED))
-                        {
-#ifdef RLD_TRANS_DEBUG
-                            pr_info("++ c4_watchdog[%d] CHAN TX ACTIVATE: start_tx %x\n",
-                                    ch->channum, ch->ch_start_tx);
-#endif
-                            ch->ch_start_tx = 0;        /* we are restarting
-                                                         * TX... */
-#if 0
-                            spin_unlock_irqrestore (&ch->ch_txlock, flags);   /* allow interrupts for
-                                                                               * service request */
-#endif
-                            musycc_serv_req (ch->up, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | gchan);
-#ifdef RLD_TRANS_DEBUG
-                            if (1 || log_level >= LOG_MONITOR)
-#else
-                            if (log_level >= LOG_MONITOR)
-#endif
-                                pr_info("++ SACK[P%d/C%d] ack'd, continuing...\n",
-                                        ch->up->portnum, ch->channum);
-                        }
-                    }
-                }
-            }
-        }
-    }
-#else
     ci->wd_notify = 0;
-#endif
-#if 0
-    SD_SEM_GIVE (&ci->sem_wdbusy);/* release per-board hold */
-#endif
 }
 
 
@@ -690,9 +558,7 @@ c4_cleanup (void)
         for (portnum = 0; portnum < ci->max_port; portnum++)
         {
             pi = &ci->port[portnum];
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
             c4_wq_port_cleanup (pi);
-#endif
             for (j = 0; j < MUSYCC_NCHANS; j++)
             {
                 if (pi->chan[j])
@@ -700,10 +566,6 @@ c4_cleanup (void)
             }
             OS_kfree (pi->regram_saved);
         }
-#if 0
-        /* obsolete - watchdog is now static w/in ci_t */
-        OS_free_watchdog (ci->wd);
-#endif
         OS_kfree (ci->iqd_p_saved);
         OS_kfree (ci);
         ci = next;                  /* cleanup next board, if any */
@@ -1145,7 +1007,6 @@ c4_set_port (ci_t * ci, int portnum)
         return EBUSY;               /* group needs initialization only for
                                      * first channel of a group */
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
     {
         status_t    ret;
 
@@ -1153,7 +1014,6 @@ c4_set_port (ci_t * ci, int portnum)
                                                  * workqueue_struct */
             return (ret);
     }
-#endif
 
     init_comet (ci, pi->cometbase, pp->port_mode, 1 /* clockmaster == true */ , pp->portP);
     clck = pci_read_32 ((u_int32_t *) &ci->cpldbase->mclk) & PMCC4_CPLD_MCLK_MASK;
@@ -1269,14 +1129,12 @@ c4_new_chan (ci_t * ci, int portnum, int channum, void *user)
     spin_lock_init (&ch->ch_rxlock);
     spin_lock_init (&ch->ch_txlock);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
     {
         status_t    ret;
 
         if ((ret = c4_wk_chan_init (pi, ch)))
             return ret;
     }
-#endif
 
     /* save off interface assignments which bound a board */
     if (ci->first_if == 0)          /* first channel registered is assumed to
@@ -1705,31 +1563,23 @@ sbecom_get_brdinfo (ci_t * ci, struct sbe_brd_info * bip, u_int8_t *bsn)
 
     if (ci->first_if)
     {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-        np = (char *) hdlc_to_name (ci->first_if);
-#else
         {
             struct net_device *dev;
 
             dev = (struct net_device *) ci->first_if;
             np = (char *) dev->name;
         }
-#endif
         strncpy (bip->first_iname, np, CHNM_STRLEN - 1);
     } else
         strcpy (bip->first_iname, "<NULL>");
     if (ci->last_if)
     {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-        np = (char *) hdlc_to_name (ci->last_if);
-#else
         {
             struct net_device *dev;
 
             dev = (struct net_device *) ci->last_if;
             np = (char *) dev->name;
         }
-#endif
         strncpy (bip->last_iname, np, CHNM_STRLEN - 1);
     } else
         strcpy (bip->last_iname, "<NULL>");
@@ -1763,11 +1613,7 @@ c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip)
     if (!(dev = getuserbychan (iip->channum)))
         return ENOENT;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    np = (char *) hdlc_to_name (dev_to_hdlc (dev));
-#else
     np = dev->name;
-#endif
     strncpy (iip->iname, np, CHNM_STRLEN - 1);
     return 0;
 }
@@ -1826,11 +1672,7 @@ c4_ebus_intr_th_handler (void *devp)
     pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
 #endif
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,20)
-    return;
-#else
     return IRQ_RETVAL (handled);
-#endif
 }
 
 
index c65172db2ad89e75a21ef3208f84bb6208cd4d3f..5a72cb5cff422db42455efa98459a078245495e0 100644 (file)
@@ -48,9 +48,6 @@
 #else
 #include <linux/types.h>
 #include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
-#include <linux/config.h>
-#endif
 #if defined(CONFIG_SMP) && ! defined(__SMP__)
 #define __SMP__
 #endif
 
 #ifdef MODULE
 #ifdef MODVERSIONS
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/modversions.h>
-#else
 #include <config/modversions.h>
 #endif
-#endif
 #include <linux/module.h>
 #endif
 #endif
@@ -260,11 +253,7 @@ OS_sem_free (void *sem)
 struct watchdog
 {
     struct timer_list h;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    struct tq_struct tq;
-#else
     struct work_struct work;
-#endif
     void       *softc;
     void        (*func) (void *softc);
     int         ticks;
index e61fdba6283867ac56cda2a2c21c557418378936..d87d56f914de832cd3e398abd84f707cd7795729 100644 (file)
@@ -644,17 +644,10 @@ static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
                if (!axid)
                        return -EFAULT;
 
-               axio =
-                       kmalloc(sizeof(struct vfe_cmd_axi_output_config),
-                               GFP_ATOMIC);
-               if (!axio)
-                       return -ENOMEM;
-
-               if (copy_from_user(axio, (void __user *)(vfecmd.value),
-                       sizeof(struct vfe_cmd_axi_output_config))) {
-                       kfree(axio);
-                       return -EFAULT;
-               }
+               axio = memdup_user((void __user *)(vfecmd.value),
+                                  sizeof(struct vfe_cmd_axi_output_config));
+               if (IS_ERR(axio))
+                       return PTR_ERR(axio);
 
                vfe_config_axi(OUTPUT_1, axid, axio);
                vfe_axi_output_config(axio);
@@ -669,17 +662,10 @@ static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
                if (!axid)
                        return -EFAULT;
 
-               axio =
-                       kmalloc(sizeof(struct vfe_cmd_axi_output_config),
-                               GFP_ATOMIC);
-               if (!axio)
-                       return -ENOMEM;
-
-               if (copy_from_user(axio, (void __user *)(vfecmd.value),
-                               sizeof(struct vfe_cmd_axi_output_config))) {
-                       kfree(axio);
-                       return -EFAULT;
-               }
+               axio = memdup_user((void __user *)(vfecmd.value),
+                                  sizeof(struct vfe_cmd_axi_output_config));
+               if (IS_ERR(axio))
+                       return PTR_ERR(axio);
 
                vfe_config_axi(OUTPUT_2, axid, axio);
 
@@ -694,17 +680,10 @@ static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
                if (!axid)
                        return -EFAULT;
 
-               axio =
-                       kmalloc(sizeof(struct vfe_cmd_axi_output_config),
-                               GFP_ATOMIC);
-               if (!axio)
-                       return -ENOMEM;
-
-               if (copy_from_user(axio, (void __user *)(vfecmd.value),
-                       sizeof(struct vfe_cmd_axi_output_config))) {
-                       kfree(axio);
-                       return -EFAULT;
-               }
+               axio = memdup_user((void __user *)(vfecmd.value),
+                                  sizeof(struct vfe_cmd_axi_output_config));
+               if (IS_ERR(axio))
+                       return PTR_ERR(axio);
 
                vfe_config_axi(OUTPUT_1_AND_2,
                        axid, axio);
index 6387365a833d36f51277f13af68f31d7724c3e16..7d6bbadd7fc72164d3d879dd3a4a147b614287fe 100644 (file)
@@ -24,8 +24,8 @@
 #include <linux/mempolicy.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 #include <asm/cacheflush.h>
 
 #define PMEM_MAX_DEVICES 10
@@ -175,7 +175,7 @@ static int pmem_mmap(struct file *, struct vm_area_struct *);
 static int pmem_open(struct inode *, struct file *);
 static long pmem_ioctl(struct file *, unsigned int, unsigned long);
 
-struct file_operations pmem_fops = {
+const struct file_operations pmem_fops = {
        .release = pmem_release,
        .mmap = pmem_mmap,
        .open = pmem_open,
@@ -209,7 +209,7 @@ static int has_allocation(struct file *file)
 
        if (unlikely(!file->private_data))
                return 0;
-       data = (struct pmem_data *)file->private_data;
+       data = file->private_data;
        if (unlikely(data->index < 0))
                return 0;
        return 1;
@@ -223,7 +223,7 @@ static int is_master_owner(struct file *file)
 
        if (!is_pmem_file(file) || !has_allocation(file))
                return 0;
-       data = (struct pmem_data *)file->private_data;
+       data = file->private_data;
        if (PMEM_FLAGS_MASTERMAP & data->flags)
                return 1;
        master_file = fget_light(data->master_fd, &put_needed);
@@ -268,7 +268,7 @@ static void pmem_revoke(struct file *file, struct pmem_data *data);
 
 static int pmem_release(struct inode *inode, struct file *file)
 {
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
+       struct pmem_data *data = file->private_data;
        struct pmem_region_node *region_node;
        struct list_head *elt, *elt2;
        int id = get_id(file), ret = 0;
@@ -399,8 +399,8 @@ static int pmem_allocate(int id, unsigned long len)
        DLOG("order %lx\n", order);
 
        /* look through the bitmap:
-        *      if you find a free slot of the correct order use it
-        *      otherwise, use the best fit (smallest with size > order) slot
+        *      if you find a free slot of the correct order use it
+        *      otherwise, use the best fit (smallest with size > order) slot
         */
        while (curr < end) {
                if (PMEM_IS_FREE(id, curr)) {
@@ -426,8 +426,8 @@ static int pmem_allocate(int id, unsigned long len)
        }
 
        /* now partition the best fit:
-        *      split the slot into 2 buddies of order - 1
-        *      repeat until the slot is of the correct order
+        *      split the slot into 2 buddies of order - 1
+        *      repeat until the slot is of the correct order
         */
        while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
                int buddy;
@@ -591,7 +591,7 @@ static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
                return -EINVAL;
        }
 
-       data = (struct pmem_data *)file->private_data;
+       data = file->private_data;
        down_write(&data->sem);
        /* check this file isn't already mmaped, for submaps check this file
         * has never been mmaped */
@@ -690,7 +690,7 @@ int get_pmem_user_addr(struct file *file, unsigned long *start,
 #endif
                return -1;
        }
-       data = (struct pmem_data *)file->private_data;
+       data = file->private_data;
        down_read(&data->sem);
        if (data->vma) {
                *start = data->vma->vm_start;
@@ -712,7 +712,7 @@ int get_pmem_addr(struct file *file, unsigned long *start,
        if (!is_pmem_file(file) || !has_allocation(file))
                return -1;
 
-       data = (struct pmem_data *)file->private_data;
+       data = file->private_data;
        if (data->index == -1) {
 #if PMEM_DEBUG
                printk(KERN_INFO "pmem: requested pmem data from file with no "
@@ -766,7 +766,7 @@ void put_pmem_file(struct file *file)
        if (!is_pmem_file(file))
                return;
        id = get_id(file);
-       data = (struct pmem_data *)file->private_data;
+       data = file->private_data;
 #if PMEM_DEBUG
        down_write(&data->sem);
        if (data->ref == 0) {
@@ -793,7 +793,7 @@ void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
                return;
 
        id = get_id(file);
-       data = (struct pmem_data *)file->private_data;
+       data = file->private_data;
        if (!pmem[id].cached)
                return;
 
@@ -822,7 +822,7 @@ end:
 
 static int pmem_connect(unsigned long connect, struct file *file)
 {
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
+       struct pmem_data *data = file->private_data;
        struct pmem_data *src_data;
        struct file *src_file;
        int ret = 0, put_needed;
@@ -842,7 +842,7 @@ static int pmem_connect(unsigned long connect, struct file *file)
                ret = -EINVAL;
                goto err_bad_file;
        }
-       src_data = (struct pmem_data *)src_file->private_data;
+       src_data = src_file->private_data;
 
        if (has_allocation(file) && (data->index != src_data->index)) {
                printk(KERN_INFO "pmem: file is already mapped but doesn't "
@@ -929,7 +929,7 @@ int pmem_remap(struct pmem_region *region, struct file *file,
        struct mm_struct *mm = NULL;
        struct list_head *elt, *elt2;
        int id = get_id(file);
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
+       struct pmem_data *data = file->private_data;
 
        /* pmem region must be aligned on a page boundry */
        if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
@@ -1053,7 +1053,7 @@ static void pmem_revoke(struct file *file, struct pmem_data *data)
 
 static void pmem_get_size(struct pmem_region *region, struct file *file)
 {
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
+       struct pmem_data *data = file->private_data;
        int id = get_id(file);
 
        if (!has_allocation(file)) {
@@ -1082,7 +1082,7 @@ static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                region.offset = 0;
                                region.len = 0;
                        } else {
-                               data = (struct pmem_data *)file->private_data;
+                               data = file->private_data;
                                region.offset = pmem_start_addr(id, data);
                                region.len = pmem_len(id, data);
                        }
@@ -1099,7 +1099,7 @@ static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        if (copy_from_user(&region, (void __user *)arg,
                                                sizeof(struct pmem_region)))
                                return -EFAULT;
-                       data = (struct pmem_data *)file->private_data;
+                       data = file->private_data;
                        return pmem_remap(&region, file, PMEM_MAP);
                }
                break;
@@ -1109,7 +1109,7 @@ static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        if (copy_from_user(&region, (void __user *)arg,
                                                sizeof(struct pmem_region)))
                                return -EFAULT;
-                       data = (struct pmem_data *)file->private_data;
+                       data = file->private_data;
                        return pmem_remap(&region, file, PMEM_UNMAP);
                        break;
                }
@@ -1139,7 +1139,7 @@ static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                {
                        if (has_allocation(file))
                                return -EINVAL;
-                       data = (struct pmem_data *)file->private_data;
+                       data = file->private_data;
                        data->index = pmem_allocate(id, arg);
                        break;
                }
diff --git a/drivers/staging/dt3155/Kconfig b/drivers/staging/dt3155/Kconfig
deleted file mode 100644 (file)
index 4a3293c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-config DT3155
-       tristate "DT3155 Digitizer support"
-       depends on PCI
-
diff --git a/drivers/staging/dt3155/Makefile b/drivers/staging/dt3155/Makefile
deleted file mode 100644 (file)
index 136f21f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_DT3155)   += dt3155.o
-dt3155-objs := \
-               dt3155_drv.o    \
-               dt3155_isr.o    \
-               dt3155_io.o     \
-               allocator.o
diff --git a/drivers/staging/dt3155/TODO b/drivers/staging/dt3155/TODO
deleted file mode 100644 (file)
index 3baa3b6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-TODO:
-       - fix checkpatch.pl issues
-       - remove old kernel support, it is not needed
-       - convert to proper PCI device API
-       - fix sparse warnings
-       - audit for correct subsystem interaction
-       - review review review!
-
-Please send patches to Greg Kroah-Hartman <greg@kroah.com>
-and Scott Smedley <ss@aao.gov.au>
diff --git a/drivers/staging/dt3155/allocator.README b/drivers/staging/dt3155/allocator.README
deleted file mode 100644 (file)
index 05700b6..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-
-The allocator shown here  exploits high memory. This document explains
-how  a user can  deal   with drivers uses   this  allocator and how  a
-programmer can link in the module.
-
-The module is being used by my pxc and pxdrv device drivers (as well as
-other ones), available from ftp.systemy.it/pub/develop and
-ftp.linux.it/pub/People/Rubini
-
-       User's manual
-       =============
-
-
-One of the most compelling problems with any DMA-capable device is the
-allocation  of a suitable  memory buffer. The "allocator" module tries
-to deal with  the problem in  a clean way.  The module is  able to use
-high   memory  (above the  one   used in  normal   operation)  for DMA
-allocation.
-
-To prevent  the  kernel for using   high memory,  so  that it  remains
-available for  DMA, you should  pass a  command  line argument to  the
-kernel.  Command line arguments  can be passed to  Lilo, to Loadlin or
-to whichever loader  you are using  (unless it's very poor in design).
-For Lilo, either use  "append=" in  /etc/lilo.conf or add  commandline
-arguments to the  interactive prompt. For  example, I have a 32MB  box
-and reserve two megs for DMA:
-
-In lilo.conf:
-       image = /zImage
-       label = linux
-       append = "mem=30M"
-
-Or, interactively:
-       LILO: linux mem=30M
-
-Once  the kernel is booted  with the  right command-line argument, any
-driver  linked   with  the  allocator   module  will  be able   to get
-DMA-capable memory without  much  trouble (unless the  various drivers
-need more memory than available).
-
-The module implements an alloc/free  mechanism,  so that it can  serve
-multiple drivers  at the  same time. Note  however that  the allocator
-uses all of  high memory and assumes to  be the only piece of software
-using such memory.
-
-
-       Programmer's manual
-       ===================
-
-The allocator,  as  released, is designed  to  be linked  to  a device
-driver.  In this  case, the driver  must call allocator_init()  before
-using   the  allocator   and  must  call   allocator_cleanup()  before
-unloading.  This is  usually  done   from within  init_module()    and
-cleanup_module(). If the allocator is linked to  a driver, it won't be
-possible for several drivers to allocate high DMA memory, as explained
-above.
-
-It is possible, on the other hand, to compile the module as a standalone
-module, so that several modules can rely on the allocator for they DMA
-buffers. To compile the allocator as a standalone module, do the
-following in this directory (or provide a suitable Makefile, or edit
-the source code):
-
-       make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h"
-
-The previous commandline  tells   to include <linux/module.h>  in  the
-first place,  and to rename the init  and cleanup function to the ones
-needed for  module loading and  unloading.  Drivers using a standalone
-allocator won't need to call allocator_init() nor allocator_cleanup().
-
-The allocator exports the following functions (declared in allocator.h):
-
-   unsigned long allocator_allocate_dma (unsigned long kilobytes,
-                                        int priority);
-
-       This function returns a physical address, over high_memory,
-       which corresponds to an area of at least "kilobytes" kilobytes.
-       The area will be owned by the module calling the function.
-       The returned address can be passed to device boards, to instruct
-       their DMA controllers, via phys_to_bus(). The address can be used
-       by C code after vremap()/ioremap(). The "priority" argument should
-       be GFP_KERNEL or GFP_ATOMIC, according to the context of the
-       caller; it is used to call kmalloc(), as the allocator must keep
-       track of any region it gives away. In case of error the function
-       returns 0, and the caller is expected to issue a -ENOMEM error.
-
-
-   void allocator_free_dma (unsigned long address);
-
-       This function is the reverse of the previous one. If a driver
-       doesn't free the DMA memory it allocated, the allocator will
-       consider such memory as busy. Note, however, that
-       allocator_cleanup() calls kfree() on every region it reclaimed,
-       so that a driver with the allocator linked in can avoid calling
-       allocator_free_dma() at unload time.
-
-
-
diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c
deleted file mode 100644 (file)
index d33947b..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * allocator.c -- allocate after high_memory, if available
- *
- * NOTE: this is different from my previous allocator, the one that
- *       assembles pages, which revealed itself both slow and unreliable.
- *
- * Copyright (C) 1998   rubini@linux.it (Alessandro Rubini)
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-
--- Changes --
-
-  Date       Programmer  Description of changes made
-  -------------------------------------------------------------------
-  02-Aug-2002 NJC         allocator now steps in 1MB increments, rather
-                         than doubling its size each time.
-                         Also, allocator_init(u32 *) now returns
-                         (in the first arg) the size of the free
-                         space.  This is no longer consistent with
-                         using the allocator as a module, and some changes
-                         may be necessary for that purpose.  This was
-                         designed to work with the DT3155 driver, in
-                         stand alone mode only!!!
-  26-Oct-2009 SS         Port to 2.6.30 kernel.
- */
-
-
-#ifndef __KERNEL__
-#  define __KERNEL__
-#endif
-#ifndef MODULE
-#  define MODULE
-#endif
-
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/proc_fs.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/mm.h>  /* PAGE_ALIGN() */
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <asm/page.h>
-
-#include "allocator.h"
-
-/*#define ALL_DEBUG*/
-#define ALL_MSG "allocator: "
-
-#undef PDEBUG             /* undef it, just in case */
-#ifdef ALL_DEBUG
-#  define __static
-#  define DUMP_LIST() dump_list()
-#  ifdef __KERNEL__
-     /* This one if debugging is on, and kernel space */
-#    define PDEBUG(fmt, args...) printk(KERN_DEBUG ALL_MSG fmt, ## args)
-#  else
-     /* This one for user space */
-#    define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
-#  endif
-#else
-#  define PDEBUG(fmt, args...) /* not debugging: nothing */
-#  define DUMP_LIST()
-#  define __static static
-#endif
-
-#undef PDEBUGG
-#define PDEBUGG(fmt, args...)
-/*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/
-
-
-static int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable   */
-static int allocator_step = 1;  /* This is the step size in MB              */
-static int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */
-
-static unsigned long allocator_buffer;         /* physical address */
-static unsigned long allocator_buffer_size;    /* kilobytes */
-
-/*
- * The allocator keeps a list of DMA areas, so multiple devices
- * can coexist. The list is kept sorted by address
- */
-
-struct allocator_struct {
-       unsigned long address;
-       unsigned long size;
-       struct allocator_struct *next;
-};
-
-static struct allocator_struct *allocator_list;
-
-#ifdef ALL_DEBUG
-static int dump_list(void)
-{
-       struct allocator_struct *ptr;
-
-       PDEBUG("Current list:\n");
-       for (ptr = allocator_list; ptr; ptr = ptr->next)
-               PDEBUG("0x%08lx (size %likB)\n", ptr->address, ptr->size>>10);
-       return 0;
-}
-#endif
-
-/* ========================================================================
- * This function is the actual allocator.
- *
- * If space is available in high memory (as detected at load time), that
- * one is returned. The return value is a physical address (i.e., it can
- * be used straight ahead for DMA, but needs remapping for program use).
- */
-
-unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags)
-{
-       struct allocator_struct *ptr = allocator_list, *newptr;
-       unsigned long bytes = kilobytes << 10;
-
-       /* check if high memory is available */
-       if (!allocator_buffer)
-               return 0;
-
-       /* Round it to a multiple of the pagesize */
-       bytes = PAGE_ALIGN(bytes);
-       PDEBUG("request for %li bytes\n", bytes);
-
-       while (ptr && ptr->next) {
-               if (ptr->next->address - (ptr->address + ptr->size) >= bytes)
-                       break; /* enough space */
-               ptr = ptr->next;
-       }
-       if (!ptr->next) {
-               DUMP_LIST();
-               PDEBUG("alloc failed\n");
-               return 0; /* end of list */
-       }
-       newptr = kmalloc(sizeof(struct allocator_struct), flags);
-       if (!newptr)
-               return 0;
-
-       /* ok, now stick it after ptr */
-       newptr->address = ptr->address + ptr->size;
-       newptr->size = bytes;
-       newptr->next = ptr->next;
-       ptr->next = newptr;
-
-       DUMP_LIST();
-       PDEBUG("returning 0x%08lx\n", newptr->address);
-       return newptr->address;
-}
-
-int allocator_free_dma(unsigned long address)
-{
-       struct allocator_struct *ptr = allocator_list, *prev;
-
-       while (ptr && ptr->next) {
-               if (ptr->next->address == address)
-                       break;
-               ptr = ptr->next;
-       }
-       /* the one being freed is ptr->next */
-       prev = ptr; ptr = ptr->next;
-
-       if (!ptr) {
-               pr_err(ALL_MSG "free_dma but add. not allocated\n");
-               return -EINVAL;
-       }
-       PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size,
-               ptr->next->address);
-       prev->next = ptr->next;
-       kfree(ptr);
-
-       /* dump_list(); */
-       return 0;
-}
-
-/* ========================================================================
- * Init and cleanup
- *
- * On cleanup everything is released. If the list is not empty, that a
- * problem of our clients
- */
-int allocator_init(u32 *allocator_max)
-{
-       /* check how much free memory is there */
-       void *remapped;
-       unsigned long max;
-       unsigned long trial_size = allocator_himem<<20;
-       unsigned long last_trial = 0;
-       unsigned long step = allocator_step<<20;
-       unsigned long i = 0;
-       struct allocator_struct *head, *tail;
-       char test_string[] = "0123456789abcde"; /* 16 bytes */
-
-       PDEBUGG("himem = %i\n", allocator_himem);
-       if (allocator_himem < 0) /* don't even try */
-               return -EINVAL;
-
-       if (!trial_size)
-               trial_size = 1<<20; /* not specified: try one meg */
-
-       while (1) {
-               remapped = ioremap(__pa(high_memory), trial_size);
-               if (!remapped) {
-                       PDEBUGG("%li megs failed!\n", trial_size>>20);
-                       break;
-               }
-               PDEBUGG("Trying %li megs (at %p, %p)\n", trial_size>>20,
-                       (void *)__pa(high_memory), remapped);
-               for (i = last_trial; i < trial_size; i += 16) {
-                       strcpy((char *)(remapped)+i, test_string);
-                       if (strcmp((char *)(remapped)+i, test_string))
-                               break;
-                       }
-               iounmap((void *)remapped);
-               schedule();
-               last_trial = trial_size;
-               if (i == trial_size)
-                       trial_size += step; /* increment, if all went well */
-               else {
-                       PDEBUGG("%li megs copy test failed!\n", trial_size>>20);
-                       break;
-               }
-               if (!allocator_probe)
-                       break;
-       }
-       PDEBUG("%li megs (%li k, %li b)\n", i>>20, i>>10, i);
-       allocator_buffer_size = i>>10; /* kilobytes */
-       allocator_buffer = __pa(high_memory);
-       if (!allocator_buffer_size) {
-               printk(KERN_WARNING ALL_MSG "no free high memory to use\n");
-               return -ENOMEM;
-       }
-
-       /*
-       * to simplify things, always have two cells in the list:
-       * the first and the last. This avoids some conditionals and
-       * extra code when allocating and deallocating: we only play
-       * in the middle of the list
-       */
-       head = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
-       if (!head)
-               return -ENOMEM;
-       tail = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
-       if (!tail) {
-               kfree(head);
-               return -ENOMEM;
-       }
-
-       max = allocator_buffer_size<<10;
-
-       head->size = tail->size = 0;
-       head->address = allocator_buffer;
-       tail->address = allocator_buffer + max;
-       head->next = tail;
-       tail->next = NULL;
-       allocator_list = head;
-
-       /* Back to the user code, in KB */
-       *allocator_max = allocator_buffer_size;
-
-       return 0; /* ok, ready */
-}
-
-void allocator_cleanup(void)
-{
-       struct allocator_struct *ptr, *next;
-
-       for (ptr = allocator_list; ptr; ptr = next) {
-               next = ptr->next;
-               PDEBUG("freeing list: 0x%08lx\n", ptr->address);
-               kfree(ptr);
-       }
-
-       allocator_buffer      = 0;
-       allocator_buffer_size = 0;
-       allocator_list = NULL;
-}
-
-
diff --git a/drivers/staging/dt3155/allocator.h b/drivers/staging/dt3155/allocator.h
deleted file mode 100644 (file)
index 425b70f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * allocator.h -- prototypes for allocating high memory
- *
- * NOTE: this is different from my previous allocator, the one that
- *       assembles pages, which revealed itself both slow and unreliable.
- *
- * Copyright (C) 1998   rubini@linux.it (Alessandro Rubini)
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-int allocator_free_dma(unsigned long address);
-unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags);
-int allocator_init(u32 *);
-void allocator_cleanup(void);
diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h
deleted file mode 100644 (file)
index 793e2fc..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-
-Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
-                        Jason Lapenta, Scott Smedley
-
-This file is part of the DT3155 Device Driver.
-
-The DT3155 Device Driver is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The DT3155 Device Driver is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with the DT3155 Device Driver; if not, write to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307 USA
-
--- Changes --
-
-  Date     Programmer  Description of changes made
-  -------------------------------------------------------------------
-  03-Jul-2000 JML     n/a
-  10-Oct-2001 SS      port to 2.4 kernel.
-  24-Jul-2002 SS      remove unused code & added GPL licence.
-  05-Aug-2005 SS      port to 2.6 kernel; make CCIR mode default.
-
-*/
-
-#ifndef _DT3155_INC
-#define _DT3155_INC
-
-#include <linux/types.h>
-#include <linux/time.h>                /* struct timeval */
-
-
-/* Uncomment this for 50Hz CCIR */
-#define CCIR 1
-
-/* Can be 1 or 2 */
-#define MAXBOARDS 1
-
-#define BOARD_MAX_BUFFS        3
-#define MAXBUFFERS     (BOARD_MAX_BUFFS*MAXBOARDS)
-
-#define PCI_PAGE_SIZE  (1 << 12)
-
-#ifdef CCIR
-#define DT3155_MAX_ROWS        576
-#define DT3155_MAX_COLS        768
-#define FORMAT50HZ     1
-#else
-#define DT3155_MAX_ROWS        480
-#define DT3155_MAX_COLS        640
-#define FORMAT50HZ     0
-#endif
-
-/* Configuration structure */
-struct dt3155_config {
-       u32 acq_mode;
-       u32 cols, rows;
-       u32 continuous;
-};
-
-
-/* hold data for each frame */
-struct frame_info {
-       u32 addr;               /* address of the buffer with the frame */
-       u32 tag;                /* unique number for the frame */
-       struct timeval time;    /* time that capture took place */
-};
-
-/*
- * Structure for interrupt and buffer handling.
- * This is the setup for 1 card
- */
-struct dt3155_fbuffer {
-       int    nbuffers;
-
-       struct frame_info frame_info[BOARD_MAX_BUFFS];
-
-       int empty_buffers[BOARD_MAX_BUFFS];     /* indexes empty frames */
-       int empty_len;                          /* Number of empty buffers */
-                                               /* Zero means empty */
-
-       int active_buf;                 /* Where data is currently dma'ing */
-       int locked_buf;                 /* Buffers used by user */
-
-       int ready_que[BOARD_MAX_BUFFS];
-       u32 ready_head; /* The most recent buffer located here */
-       u32 ready_len;  /* The number of ready buffers */
-
-       int even_happened;
-       int even_stopped;
-
-       int stop_acquire;       /* Flag to stop interrupts */
-       u32 frame_count;        /* Counter for frames acquired by this card */
-};
-
-
-
-#define DT3155_MODE_FRAME      1
-#define DT3155_MODE_FIELD      2
-
-#define DT3155_SNAP            1
-#define DT3155_ACQ             2
-
-/* There is one status structure for each card. */
-struct dt3155_status {
-       int fixed_mode;         /* if 1, we are in fixed frame mode */
-       u32 reg_addr;   /* Register address for a single card */
-       u32 mem_addr;   /* Buffer start addr for this card */
-       u32 mem_size;   /* This is the amount of mem available  */
-       u32 irq;                /* this card's irq */
-       struct dt3155_config config;            /* configuration struct */
-       struct dt3155_fbuffer fbuffer;  /* frame buffer state struct */
-       u32 state;              /* this card's state */
-       u32 device_installed;   /* Flag if installed. 1=installed */
-};
-
-/* Reference to global status structure */
-extern struct dt3155_status dt3155_status[MAXBOARDS];
-
-#define DT3155_STATE_IDLE      0x00
-#define DT3155_STATE_FRAME     0x01
-#define DT3155_STATE_FLD       0x02
-#define DT3155_STATE_STOP      0x100
-#define DT3155_STATE_ERROR     0x200
-#define DT3155_STATE_MODE      0x0ff
-
-#define DT3155_IOC_MAGIC       '!'
-
-#define DT3155_SET_CONFIG      _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config)
-#define DT3155_GET_CONFIG      _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status)
-#define DT3155_STOP            _IO(DT3155_IOC_MAGIC, 3)
-#define DT3155_START           _IO(DT3155_IOC_MAGIC, 4)
-#define DT3155_FLUSH           _IO(DT3155_IOC_MAGIC, 5)
-#define DT3155_IOC_MAXNR       5
-
-/* Error codes */
-
-#define DT_ERR_NO_BUFFERS      0x10000 /* not used but it might be one day */
-#define DT_ERR_CORRUPT         0x20000
-#define DT_ERR_OVERRUN         0x30000
-#define DT_ERR_I2C_TIMEOUT     0x40000
-#define DT_ERR_MASK            0xff0000/* not used but it might be one day */
-
-/* User code will probably want to declare one of these for each card */
-struct dt3155_read {
-       u32 offset;
-       u32 frame_seq;
-       u32 state;
-
-       struct frame_info frame_info;
-};
-
-#endif /* _DT3155_inc */
diff --git a/drivers/staging/dt3155/dt3155.sysvinit b/drivers/staging/dt3155/dt3155.sysvinit
deleted file mode 100644 (file)
index 92ec093..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#! /bin/sh
-#
-# Module load/unload script for use with SysV-style /etc/init.d/ systems.
-# On a Debian system, copy this to /etc/init.d/dt3155 and then run
-#      /usr/sbin/update-rc.d dt3155 defaults 55
-# to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links.
-# (The "55" is arbitrary but is what I use to load this rather late.)
-#
-#    Andy Dougherty   Feb 22 2000      doughera@lafayette.edu
-#    Dept. of Physics
-#    Lafayette College, Easton PA 18042
-#
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-
-# Edit to point to your local copy.
-FILE=/usr/local/lib/modules/dt3155/dt3155.o
-NAME="dt3155"
-DESC="dt3155 Frame Grabber module"
-DEV="dt3155"
-
-if test ! -f $FILE; then
-    echo "Unable to locate $FILE"
-    exit 0
-fi
-
-set -e
-
-case "$1" in
-  start)
-    echo -n "Loading $DESC "
-    if /sbin/insmod -v -f $FILE; then
-       major=`grep $DEV /proc/devices | awk "{print \\$1}"`
-       rm -f /dev/dt3155?
-       mknod /dev/dt3155a c $major 0
-       mknod /dev/dt3155b c $major 1
-       chmod go+rw /dev/dt3155?
-       echo
-    else
-       echo "$FILE not loaded."
-    fi
-    ;;
-  stop)
-    echo -n "Unloading $DESC: "
-    if /sbin/rmmod $NAME ; then
-       echo
-    else
-       echo "$DEV not removed"
-       exit 0
-    fi
-    rm -f /dev/dt3155?
-    ;;
-  *)
-    echo "Usage: /etc/init.d/$NAME {start|stop}"
-    exit 1
-    ;;
-esac
-
-exit 0
-
diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c
deleted file mode 100644 (file)
index 40ef97f..0000000
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
-
-Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
-                         Jason Lapenta, Scott Smedley, Greg Sharp
-
-This file is part of the DT3155 Device Driver.
-
-The DT3155 Device Driver is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The DT3155 Device Driver is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with the DT3155 Device Driver; if not, write to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307 USA
-
--- Changes --
-
-  Date     Programmer  Description of changes made
-  -------------------------------------------------------------------
-  03-Jul-2000 JML       n/a
-  10-Oct-2001 SS        port to 2.4 kernel
-  02-Apr-2002 SS        Mods to use allocator as a standalone module;
-                        Merged John Roll's changes (john@cfa.harvard.edu)
-                        to make work with multiple boards.
-  02-Jul-2002 SS        Merged James Rose's chages (rosejr@purdue.edu) to:
-                         * fix successive interrupt-driven captures
-                         * add select/poll support.
-  10-Jul-2002 GCS       Add error check when ndevices > MAXBOARDS.
-  02-Aug-2002 GCS       Fix field mode so that odd (lower) field is stored
-                        in lower half of buffer.
-  05-Aug-2005 SS        port to 2.6 kernel.
-  26-Oct-2009 SS       port to 2.6.30 kernel.
-
--- Notes --
-
-** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system.
- * using allocator.c and allocator.h from o'reilly book (alessandro rubini)
-    ftp://ftp.systemy.it/pub/develop (see README.allocator)
-
- + might want to get rid of MAXboards for allocating initial buffer.
-    confusing and not necessary
-
- + in cleanup_module the MOD_IN_USE looks like it is check after it should
-
- * GFP_DMA should not be set with a PCI system (pg 291)
-
- - NJC why are only two buffers allowed? (see isr, approx line 358)
-
-*/
-
-extern void printques(int);
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <linux/poll.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include "dt3155.h"
-#include "dt3155_drv.h"
-#include "dt3155_isr.h"
-#include "dt3155_io.h"
-#include "allocator.h"
-
-
-MODULE_LICENSE("GPL");
-
-/* Error variable.  Zero means no error. */
-int dt3155_errno = 0;
-
-#ifndef PCI_DEVICE_ID_INTEL_7116
-#define PCI_DEVICE_ID_INTEL_7116 0x1223
-#endif
-
-#define DT3155_VENDORID    PCI_VENDOR_ID_INTEL
-#define DT3155_DEVICEID    PCI_DEVICE_ID_INTEL_7116
-#define MAXPCI    16
-
-#ifdef DT_DEBUG
-#define DT_3155_DEBUG_MSG(x,y) printk(x,y)
-#else
-#define DT_3155_DEBUG_MSG(x,y)
-#endif
-
-/* wait queue for interrupts */
-wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS];
-
-#define DT_3155_SUCCESS 0
-#define DT_3155_FAILURE -EIO
-
-/* set to dynamicaly allocate, but it is tunable: */
-/* insmod DT_3155 dt3155 dt3155_major=XX */
-int dt3155_major = 0;
-
-/* The minor numbers are 0 and 1 ... they are not tunable.
- * They are used as the indices for the structure vectors,
- * and register address vectors
- */
-
-/* Global structures and variables */
-
-/* Status of each device */
-struct dt3155_status dt3155_status[MAXBOARDS];
-
-/* kernel logical address of the board */
-u8 *dt3155_lbase[MAXBOARDS] = { NULL
-#if MAXBOARDS == 2
-                                     , NULL
-#endif
-};
-/* DT3155 registers              */
-u8 *dt3155_bbase = NULL;                 /* kernel logical address of the *
-                                          * buffer region                 */
-u32  dt3155_dev_open[MAXBOARDS] = {0
-#if MAXBOARDS == 2
-                                      , 0
-#endif
-};
-
-u32  ndevices = 0;
-u32 unique_tag = 0;;
-
-
-/*
- * Stops interrupt generation right away and resets the status
- * to idle.  I don't know why this works and the other way doesn't.
- * (James Rose)
- */
-static void quick_stop (int minor)
-{
-  // TODO: scott was here
-#if 1
-  ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
-  /* disable interrupts */
-  int_csr_r.fld.FLD_END_EVE_EN = 0;
-  int_csr_r.fld.FLD_END_ODD_EN = 0;
-  WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
-
-  dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff);
-  /* mark the system stopped: */
-  dt3155_status[minor].state |= DT3155_STATE_IDLE;
-  dt3155_fbuffer[minor]->stop_acquire = 0;
-  dt3155_fbuffer[minor]->even_stopped = 0;
-#else
-  dt3155_status[minor].state |= DT3155_STATE_STOP;
-  dt3155_status[minor].fbuffer.stop_acquire = 1;
-#endif
-
-}
-
-
-/*****************************************************
- *  dt3155_isr() Interrupt service routien
- *
- * - looks like this isr supports IRQ sharing (or could) JML
- * - Assumes irq's are disabled, via SA_INTERRUPT flag
- * being set in request_irq() call from init_module()
- *****************************************************/
-static void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs)
-{
-  int    minor = -1;
-  int    index;
-  unsigned long flags;
-  u32 buffer_addr;
-
-  /* find out who issued the interrupt */
-  for (index = 0; index < ndevices; index++) {
-    if(dev_id == (void*) &dt3155_status[index])
-      {
-       minor = index;
-       break;
-      }
-  }
-
-  /* hopefully we should not get here */
-  if (minor < 0 || minor >= MAXBOARDS) {
-    printk(KERN_ERR "dt3155_isr called with invalid dev_id\n");
-    return;
-  }
-
-  /* Check for corruption and set a flag if so */
-  ReadMReg((dt3155_lbase[minor] + CSR1), csr1_r.reg);
-
-  if ((csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD))
-    {
-      /* TODO: this should probably stop acquisition */
-      /* and set some flags so that dt3155_read      */
-      /* returns an error next time it is called     */
-      dt3155_errno = DT_ERR_CORRUPT;
-      printk("dt3155:  corrupt field\n");
-      return;
-    }
-
-  ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
-
-  /* Handle the even field ... */
-  if (int_csr_r.fld.FLD_END_EVE)
-    {
-      if ((dt3155_status[minor].state & DT3155_STATE_MODE) ==
-          DT3155_STATE_FLD)
-       {
-         dt3155_fbuffer[minor]->frame_count++;
-       }
-
-      ReadI2C(dt3155_lbase[minor], EVEN_CSR, &i2c_even_csr.reg);
-
-      /* Clear the interrupt? */
-      int_csr_r.fld.FLD_END_EVE = 1;
-
-      /* disable the interrupt if last field */
-      if (dt3155_fbuffer[minor]->stop_acquire)
-       {
-         printk("dt3155:  even stopped.\n");
-         dt3155_fbuffer[minor]->even_stopped = 1;
-         if (i2c_even_csr.fld.SNGL_EVE)
-           {
-             int_csr_r.fld.FLD_END_EVE_EN = 0;
-           }
-         else
-           {
-             i2c_even_csr.fld.SNGL_EVE  = 1;
-           }
-       }
-
-      WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
-
-      /* Set up next DMA if we are doing FIELDS */
-      if ((dt3155_status[minor].state & DT3155_STATE_MODE) ==
-          DT3155_STATE_FLD)
-       {
-         /* GCS (Aug 2, 2002) -- In field mode, dma the odd field
-            into the lower half of the buffer */
-         const u32 stride =  dt3155_status[minor].config.cols;
-         buffer_addr = dt3155_fbuffer[minor]->
-           frame_info[dt3155_fbuffer[minor]->active_buf].addr
-           + (DT3155_MAX_ROWS / 2) * stride;
-         local_save_flags(flags);
-         local_irq_disable();
-         wake_up_interruptible(&dt3155_read_wait_queue[minor]);
-
-         /* Set up the DMA address for the next field */
-         local_irq_restore(flags);
-         WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr);
-       }
-
-      /* Check for errors. */
-      i2c_even_csr.fld.DONE_EVE = 1;
-      if (i2c_even_csr.fld.ERROR_EVE)
-       dt3155_errno = DT_ERR_OVERRUN;
-
-      WriteI2C(dt3155_lbase[minor], EVEN_CSR, i2c_even_csr.reg);
-
-      /* Note that we actually saw an even field meaning  */
-      /* that subsequent odd field complete the frame     */
-      dt3155_fbuffer[minor]->even_happened = 1;
-
-      /* recording the time that the even field finished, this should be */
-      /* about time in the middle of the frame */
-      do_gettimeofday(&(dt3155_fbuffer[minor]->
-                        frame_info[dt3155_fbuffer[minor]->
-                                    active_buf].time));
-      return;
-    }
-
-  /* ... now handle the odd field */
-  if (int_csr_r.fld.FLD_END_ODD)
-    {
-      ReadI2C(dt3155_lbase[minor], ODD_CSR, &i2c_odd_csr.reg);
-
-      /* Clear the interrupt? */
-      int_csr_r.fld.FLD_END_ODD = 1;
-
-      if (dt3155_fbuffer[minor]->even_happened ||
-         (dt3155_status[minor].state & DT3155_STATE_MODE) ==
-         DT3155_STATE_FLD)
-       {
-         dt3155_fbuffer[minor]->frame_count++;
-       }
-
-      if (dt3155_fbuffer[minor]->stop_acquire &&
-          dt3155_fbuffer[minor]->even_stopped)
-       {
-         printk(KERN_DEBUG "dt3155:  stopping odd..\n");
-         if (i2c_odd_csr.fld.SNGL_ODD)
-           {
-             /* disable interrupts */
-             int_csr_r.fld.FLD_END_ODD_EN = 0;
-             dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff);
-
-             /* mark the system stopped: */
-             dt3155_status[minor].state |= DT3155_STATE_IDLE;
-             dt3155_fbuffer[minor]->stop_acquire = 0;
-             dt3155_fbuffer[minor]->even_stopped = 0;
-
-             printk(KERN_DEBUG "dt3155:  state is now %x\n",
-                    dt3155_status[minor].state);
-           }
-         else
-           {
-             i2c_odd_csr.fld.SNGL_ODD  = 1;
-           }
-       }
-
-      WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
-
-      /* if the odd field has been acquired, then     */
-      /* change the next dma location for both fields */
-      /* and wake up the process if sleeping          */
-      if (dt3155_fbuffer[minor]->even_happened ||
-          (dt3155_status[minor].state & DT3155_STATE_MODE) ==
-          DT3155_STATE_FLD)
-       {
-
-         local_save_flags(flags);
-         local_irq_disable();
-
-#ifdef DEBUG_QUES_B
-         printques(minor);
-#endif
-         if (dt3155_fbuffer[minor]->nbuffers > 2)
-           {
-             if (!are_empty_buffers(minor))
-               {
-                 /* The number of active + locked buffers is
-                  * at most 2, and since there are none empty, there
-                  * must be at least nbuffers-2 ready buffers.
-                  * This is where we 'drop frames', oldest first. */
-                 push_empty(pop_ready(minor),  minor);
-               }
-
-             /* The ready_que can't be full, since we know
-              * there is one active buffer right now, so it's safe
-              * to push the active buf on the ready_que. */
-             push_ready(minor, dt3155_fbuffer[minor]->active_buf);
-             /* There's at least 1 empty -- make it active */
-             dt3155_fbuffer[minor]->active_buf = pop_empty(minor);
-             dt3155_fbuffer[minor]->
-               frame_info[dt3155_fbuffer[minor]->
-                           active_buf].tag = ++unique_tag;
-           }
-         else /* nbuffers == 2, special case */
-           { /* There is 1 active buffer.
-              * If there is a locked buffer, keep the active buffer
-              * the same -- that means we drop a frame.
-              */
-             if (dt3155_fbuffer[minor]->locked_buf < 0)
-               {
-                 push_ready(minor,
-                             dt3155_fbuffer[minor]->active_buf);
-                 if (are_empty_buffers(minor))
-                   {
-                     dt3155_fbuffer[minor]->active_buf =
-                       pop_empty(minor);
-                   }
-                 else
-                   { /* no empty or locked buffers, so use a readybuf */
-                     dt3155_fbuffer[minor]->active_buf =
-                       pop_ready(minor);
-                   }
-               }
-           }
-
-#ifdef DEBUG_QUES_B
-         printques(minor);
-#endif
-
-         dt3155_fbuffer[minor]->even_happened = 0;
-
-         wake_up_interruptible(&dt3155_read_wait_queue[minor]);
-
-         local_irq_restore(flags);
-       }
-
-
-      /* Set up the DMA address for the next frame/field */
-      buffer_addr = dt3155_fbuffer[minor]->
-       frame_info[dt3155_fbuffer[minor]->active_buf].addr;
-      if ((dt3155_status[minor].state & DT3155_STATE_MODE) ==
-          DT3155_STATE_FLD)
-       {
-         WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr);
-       }
-      else
-       {
-         WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr);
-
-         WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr
-                   + dt3155_status[minor].config.cols);
-       }
-
-      /* Do error checking */
-      i2c_odd_csr.fld.DONE_ODD = 1;
-      if (i2c_odd_csr.fld.ERROR_ODD)
-       dt3155_errno = DT_ERR_OVERRUN;
-
-      WriteI2C(dt3155_lbase[minor], ODD_CSR, i2c_odd_csr.reg);
-
-      return;
-    }
-  /* If we get here, the Odd Field wasn't it either... */
-  printk("neither even nor odd.  shared perhaps?\n");
-}
-
-/*****************************************************
- * init_isr(int minor)
- *   turns on interupt generation for the card
- *   designated by "minor".
- *   It is called *only* from inside ioctl().
- *****************************************************/
-static void dt3155_init_isr(int minor)
-{
-  const u32 stride =  dt3155_status[minor].config.cols;
-
-  switch (dt3155_status[minor].state & DT3155_STATE_MODE)
-    {
-    case DT3155_STATE_FLD:
-      {
-       even_dma_start_r  = dt3155_status[minor].
-         fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr;
-       even_dma_stride_r = 0;
-       odd_dma_stride_r  = 0;
-
-       WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START),
-                 even_dma_start_r);
-       WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE),
-                 even_dma_stride_r);
-       WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE),
-                 odd_dma_stride_r);
-       break;
-      }
-
-    case DT3155_STATE_FRAME:
-    default:
-      {
-       even_dma_start_r  = dt3155_status[minor].
-         fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr;
-       odd_dma_start_r   =  even_dma_start_r + stride;
-       even_dma_stride_r =  stride;
-       odd_dma_stride_r  =  stride;
-
-       WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START),
-                 even_dma_start_r);
-       WriteMReg((dt3155_lbase[minor] + ODD_DMA_START),
-                 odd_dma_start_r);
-       WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE),
-                 even_dma_stride_r);
-       WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE),
-                 odd_dma_stride_r);
-       break;
-      }
-    }
-
-  /* 50/60 Hz should be set before this point but let's make sure it is */
-  /* right anyway */
-
-  ReadI2C(dt3155_lbase[minor], CSR2, &i2c_csr2.reg);
-  i2c_csr2.fld.HZ50 = FORMAT50HZ;
-  WriteI2C(dt3155_lbase[minor], CSR2, i2c_csr2.reg);
-
-  /* enable busmaster chip, clear flags */
-
-  /*
-   * TODO:
-   * shouldn't we be concered with continuous values of
-   * DT3155_SNAP & DT3155_ACQ here? (SS)
-   */
-
-  csr1_r.reg                = 0;
-  csr1_r.fld.CAP_CONT_EVE   = 1; /* use continuous capture bits to */
-  csr1_r.fld.CAP_CONT_ODD   = 1; /* enable */
-  csr1_r.fld.FLD_DN_EVE     = 1; /* writing a 1 clears flags */
-  csr1_r.fld.FLD_DN_ODD     = 1;
-  csr1_r.fld.SRST           = 1; /* reset        - must be 1 */
-  csr1_r.fld.FIFO_EN        = 1; /* fifo control - must be 1 */
-  csr1_r.fld.FLD_CRPT_EVE   = 1; /* writing a 1 clears flags */
-  csr1_r.fld.FLD_CRPT_ODD   = 1;
-
-  WriteMReg((dt3155_lbase[minor] + CSR1),csr1_r.reg);
-
-  /* Enable interrupts at the end of each field */
-
-  int_csr_r.reg = 0;
-  int_csr_r.fld.FLD_END_EVE_EN = 1;
-  int_csr_r.fld.FLD_END_ODD_EN = 1;
-  int_csr_r.fld.FLD_START_EN = 0;
-
-  WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
-
-  /* start internal BUSY bits */
-
-  ReadI2C(dt3155_lbase[minor], CSR2, &i2c_csr2.reg);
-  i2c_csr2.fld.BUSY_ODD  = 1;
-  i2c_csr2.fld.BUSY_EVE  = 1;
-  WriteI2C(dt3155_lbase[minor], CSR2, i2c_csr2.reg);
-
-  /* Now its up to the interrupt routine!! */
-
-  return;
-}
-
-
-/*****************************************************
- * ioctl()
- *
- *****************************************************/
-static int dt3155_ioctl(struct inode *inode,
-                       struct file *file,
-                       unsigned int cmd,
-                       unsigned long arg)
-{
-  int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */
-
-  if (minor >= MAXBOARDS || minor < 0)
-    return -ENODEV;
-
-  /* make sure it is valid command */
-  if (_IOC_NR(cmd) > DT3155_IOC_MAXNR)
-    {
-      printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
-      printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
-            (unsigned int)DT3155_GET_CONFIG,
-            (unsigned int)DT3155_SET_CONFIG,
-            (unsigned int)DT3155_START,
-            (unsigned int)DT3155_STOP,
-            (unsigned int)DT3155_FLUSH);
-      return -EINVAL;
-    }
-
-  switch (cmd)
-    {
-    case DT3155_SET_CONFIG:
-      {
-       if (dt3155_status[minor].state != DT3155_STATE_IDLE)
-         return -EBUSY;
-
-       {
-         struct dt3155_config tmp;
-         if (copy_from_user((void *)&tmp, (void *) arg, sizeof(tmp)))
-             return -EFAULT;
-         /* check for valid settings */
-         if (tmp.rows > DT3155_MAX_ROWS ||
-             tmp.cols > DT3155_MAX_COLS ||
-             (tmp.acq_mode != DT3155_MODE_FRAME &&
-              tmp.acq_mode != DT3155_MODE_FIELD) ||
-             (tmp.continuous != DT3155_SNAP &&
-              tmp.continuous != DT3155_ACQ))
-           {
-             return -EINVAL;
-           }
-         dt3155_status[minor].config = tmp;
-       }
-       return 0;
-      }
-    case DT3155_GET_CONFIG:
-      {
-       if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
-                    sizeof(struct dt3155_status)))
-           return -EFAULT;
-       return 0;
-      }
-    case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */
-      {
-       if (dt3155_status[minor].state != DT3155_STATE_IDLE)
-         return -EBUSY;
-       return dt3155_flush(minor);
-      }
-    case DT3155_STOP:
-      {
-       if (dt3155_status[minor].state & DT3155_STATE_STOP ||
-           dt3155_status[minor].fbuffer.stop_acquire)
-         return -EBUSY;
-
-       if (dt3155_status[minor].state == DT3155_STATE_IDLE)
-         return 0;
-
-       quick_stop(minor);
-       if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
-                    sizeof(struct dt3155_status)))
-           return -EFAULT;
-       return 0;
-      }
-    case DT3155_START:
-      {
-       if (dt3155_status[minor].state != DT3155_STATE_IDLE)
-         return -EBUSY;
-
-       dt3155_status[minor].fbuffer.stop_acquire = 0;
-       dt3155_status[minor].fbuffer.frame_count = 0;
-
-       /* Set the MODE in the status -- we default to FRAME */
-       if (dt3155_status[minor].config.acq_mode == DT3155_MODE_FIELD)
-         {
-           dt3155_status[minor].state = DT3155_STATE_FLD;
-         }
-       else
-         {
-           dt3155_status[minor].state = DT3155_STATE_FRAME;
-         }
-
-       dt3155_init_isr(minor);
-       if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
-                     sizeof(struct dt3155_status)))
-           return -EFAULT;
-       return 0;
-      }
-    default:
-      {
-       printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
-      printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
-            (unsigned int)DT3155_GET_CONFIG,
-            (unsigned int)DT3155_SET_CONFIG,
-            DT3155_START, DT3155_STOP, DT3155_FLUSH);
-       return -ENOSYS;
-      }
-    }
-  return -ENOSYS;
-}
-
-/*****************************************************
- * mmap()
- *
- * only allow the user to mmap the registers and buffer
- * It is quite possible that this is broken, since the
- * addition of of the capacity for two cards!!!!!!!!
- * It *looks* like it should work but since I'm not
- * sure how to use it, I'm not actually sure. (NJC? ditto by SS)
- *****************************************************/
-static int dt3155_mmap (struct file * file, struct vm_area_struct * vma)
-{
-  /* which device are we mmapping? */
-  int                          minor = MINOR(file->f_dentry->d_inode->i_rdev);
-  unsigned long        offset;
-  offset = vma->vm_pgoff << PAGE_SHIFT;
-
-  if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
-    vma->vm_flags |= VM_IO;
-
-  /* Don't try to swap out physical pages.. */
-  vma->vm_flags |= VM_RESERVED;
-
-  /* they are mapping the registers or the buffer */
-  if ((offset == dt3155_status[minor].reg_addr &&
-       vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) ||
-      (offset == dt3155_status[minor].mem_addr &&
-       vma->vm_end - vma->vm_start == dt3155_status[minor].mem_size))
-    {
-      if (remap_pfn_range(vma,
-                       vma->vm_start,
-                       offset >> PAGE_SHIFT,
-                       vma->vm_end - vma->vm_start,
-                       vma->vm_page_prot)) {
-         printk("DT3155: remap_page_range() failed.\n");
-         return -EAGAIN;
-       }
-    }
-  else
-    {
-      printk("DT3155: dt3155_mmap() bad call.\n");
-      return -ENXIO;
-    }
-
-  return 0;
-}
-
-
-/*****************************************************
- * open()
- *
- * Our special open code.
- * MOD_INC_USE_COUNT make sure that the driver memory is not freed
- * while the device is in use.
- *****************************************************/
-static int dt3155_open(struct inode* inode, struct file* filep)
-{
-  int minor = MINOR(inode->i_rdev); /* what device are we opening? */
-  if (dt3155_dev_open[minor]) {
-    printk ("DT3155:  Already opened by another process.\n");
-    return -EBUSY;
-  }
-
-  if (dt3155_status[minor].device_installed==0)
-    {
-      printk("DT3155 Open Error: No such device dt3155 minor number %d\n",
-            minor);
-      return -EIO;
-    }
-
-  if (dt3155_status[minor].state != DT3155_STATE_IDLE) {
-    printk ("DT3155:  Not in idle state (state = %x)\n",
-           dt3155_status[minor].state);
-    return -EBUSY;
-  }
-
-  printk("DT3155: Device opened.\n");
-
-  dt3155_dev_open[minor] = 1 ;
-
-  dt3155_flush(minor);
-
-  /* Disable ALL interrupts */
-  int_csr_r.reg = 0;
-  WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
-
-  init_waitqueue_head(&(dt3155_read_wait_queue[minor]));
-
-  return 0;
-}
-
-
-/*****************************************************
- * close()
- *
- * Now decrement the use count.
- *
- *****************************************************/
-static int dt3155_close(struct inode *inode, struct file *filep)
-{
-  int minor;
-
-  minor = MINOR(inode->i_rdev); /* which device are we closing */
-  if (!dt3155_dev_open[minor])
-    {
-      printk("DT3155: attempt to CLOSE a not OPEN device\n");
-    }
-  else
-    {
-      dt3155_dev_open[minor] = 0;
-
-      if (dt3155_status[minor].state != DT3155_STATE_IDLE)
-       {
-         quick_stop(minor);
-       }
-    }
-  return 0;
-}
-
-/*****************************************************
- * read()
- *
- *****************************************************/
-static ssize_t dt3155_read(struct file *filep, char __user *buf,
-                          size_t count, loff_t *ppos)
-{
-  /* which device are we reading from? */
-  int          minor = MINOR(filep->f_dentry->d_inode->i_rdev);
-  u32          offset;
-  int          frame_index;
-  struct frame_info    *frame_info;
-
-  /* TODO: this should check the error flag and */
-  /*   return an error on hardware failures */
-  if (count != sizeof(struct dt3155_read))
-    {
-      printk("DT3155 ERROR (NJC): count is not right\n");
-      return -EINVAL;
-    }
-
-
-  /* Hack here -- I'm going to allow reading even when idle.
-   * this is so that the frames can be read after STOP has
-   * been called.  Leaving it here, commented out, as a reminder
-   * for a short while to make sure there are no problems.
-   * Note that if the driver is not opened in non_blocking mode,
-   * and the device is idle, then it could sit here forever! */
-
-  /*  if (dt3155_status[minor].state == DT3155_STATE_IDLE)*/
-  /*    return -EBUSY;*/
-
-  /* non-blocking reads should return if no data */
-  if (filep->f_flags & O_NDELAY)
-    {
-      if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) {
-       /*printk("dt3155:  no buffers available (?)\n");*/
-       /*              printques(minor); */
-       return -EAGAIN;
-      }
-    }
-  else
-    {
-      /*
-       * sleep till data arrives , or we get interrupted.
-       * Note that wait_event_interruptible() does not actually
-       * sleep/wait if it's condition evaluates to true upon entry.
-       */
-      wait_event_interruptible(dt3155_read_wait_queue[minor],
-                              (frame_index = dt3155_get_ready_buffer(minor))
-                              >= 0);
-
-      if (frame_index < 0)
-       {
-         printk ("DT3155: read: interrupted\n");
-         quick_stop (minor);
-         printques(minor);
-         return -EINTR;
-       }
-    }
-
-  frame_info = &dt3155_status[minor].fbuffer.frame_info[frame_index];
-
-  /* make this an offset */
-  offset = frame_info->addr - dt3155_status[minor].mem_addr;
-
-  put_user(offset, (unsigned int *) buf);
-  buf += sizeof(u32);
-  put_user(dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf);
-  buf += sizeof(u32);
-  put_user(dt3155_status[minor].state, (unsigned int *) buf);
-  buf += sizeof(u32);
-  if (copy_to_user(buf, frame_info, sizeof(*frame_info)))
-      return -EFAULT;
-
-  return sizeof(struct dt3155_read);
-}
-
-static unsigned int dt3155_poll (struct file * filp, poll_table *wait)
-{
-  int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
-
-  if (!is_ready_buf_empty(minor))
-    return POLLIN | POLLRDNORM;
-
-  poll_wait (filp, &dt3155_read_wait_queue[minor], wait);
-
-  return 0;
-}
-
-static long
-dt3155_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       int ret;
-
-       lock_kernel();
-       ret = dt3155_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
-       unlock_kernel();
-
-       return ret;
-}
-
-/*****************************************************
- * file operations supported by DT3155 driver
- *  needed by init_module
- *  register_chrdev
- *****************************************************/
-static struct file_operations dt3155_fops = {
-       .read           = dt3155_read,
-       .unlocked_ioctl = dt3155_unlocked_ioctl,
-       .mmap           = dt3155_mmap,
-       .poll           = dt3155_poll,
-       .open           = dt3155_open,
-       .release        = dt3155_close
-};
-
-
-/*****************************************************
- * find_PCI();
- *
- * PCI has been totally reworked in 2.1..
- *****************************************************/
-static int find_PCI (void)
-{
-  struct pci_dev *pci_dev = NULL;
-  int error, pci_index = 0;
-  unsigned short rev_device;
-  unsigned long base;
-  unsigned char irq;
-
-  while ((pci_dev = pci_get_device
-         (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL)
-    {
-      pci_index ++;
-
-      /* Is it really there? */
-      if ((error =
-          pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device)))
-       continue;
-
-      /* Found a board */
-      DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index);
-
-      /* Make sure the driver was compiled with enough buffers to handle
-        this many boards */
-      if (pci_index > MAXBOARDS) {
-       printk("DT3155: ERROR - found %d devices, but driver only configured "
-              "for %d devices\n"
-              "DT3155: Please change MAXBOARDS in dt3155.h\n",
-              pci_index, MAXBOARDS);
-       goto err;
-      }
-
-      /* Now, just go out and make sure that this/these device(s) is/are
-        actually mapped into the kernel address space */
-      if ((error = pci_read_config_dword(pci_dev, PCI_BASE_ADDRESS_0,
-                                         (u32 *) &base)))
-       {
-         printk("DT3155: Was not able to find device \n");
-         goto err;
-       }
-
-      DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base);
-      dt3155_status[pci_index-1].reg_addr = base;
-
-      /* Remap the base address to a logical address through which we
-       * can access it. */
-      dt3155_lbase[pci_index - 1] = ioremap(base,PCI_PAGE_SIZE);
-      dt3155_status[pci_index - 1].reg_addr = base;
-      DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n",
-                       dt3155_lbase[pci_index-1]);
-      if (!dt3155_lbase[pci_index-1])
-       {
-         printk("DT3155: Unable to remap control registers\n");
-         goto err;
-       }
-
-      if ((error = pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &irq)))
-       {
-         printk("DT3155: Was not able to find device \n");
-         goto err;
-       }
-
-      DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq);
-      dt3155_status[pci_index-1].irq = irq;
-      /* Set flag: kth device found! */
-      dt3155_status[pci_index-1].device_installed = 1;
-      printk("DT3155: Installing device %d w/irq %d and address %p\n",
-            pci_index,
-            dt3155_status[pci_index-1].irq,
-            dt3155_lbase[pci_index-1]);
-
-    }
-  ndevices = pci_index;
-
-  return DT_3155_SUCCESS;
-
-err:
-  pci_dev_put(pci_dev);
-  return DT_3155_FAILURE;
-}
-
-u32 allocatorAddr = 0;
-
-/*****************************************************
- * init_module()
- *****************************************************/
-int init_module(void)
-{
-  int index;
-  int rcode = 0;
-  char *devname[MAXBOARDS];
-
-  devname[0] = "dt3155a";
-#if MAXBOARDS == 2
-  devname[1] = "dt3155b";
-#endif
-
-  printk("DT3155: Loading module...\n");
-
-  /* Register the device driver */
-  rcode = register_chrdev(dt3155_major, "dt3155", &dt3155_fops);
-  if(rcode < 0)
-    {
-      printk(KERN_INFO "DT3155: register_chrdev failed \n");
-      return rcode;
-    }
-
-  if(dt3155_major == 0)
-    dt3155_major = rcode; /* dynamic */
-
-
-  /* init the status variables.                     */
-  /* DMA memory is taken care of in setup_buffers() */
-  for (index = 0; index < MAXBOARDS; index++)
-    {
-      dt3155_status[index].config.acq_mode   = DT3155_MODE_FRAME;
-      dt3155_status[index].config.continuous = DT3155_ACQ;
-      dt3155_status[index].config.cols       = DT3155_MAX_COLS;
-      dt3155_status[index].config.rows       = DT3155_MAX_ROWS;
-      dt3155_status[index].state = DT3155_STATE_IDLE;
-
-      /* find_PCI() will check if devices are installed; */
-      /* first assume they're not:                       */
-      dt3155_status[index].mem_addr          = 0;
-      dt3155_status[index].mem_size          = 0;
-      dt3155_status[index].state             = DT3155_STATE_IDLE;
-      dt3155_status[index].device_installed  = 0;
-    }
-
-  /* Now let's find the hardware.  find_PCI() will set ndevices to the
-   * number of cards found in this machine. */
-    {
-      if ((rcode = find_PCI()) !=  DT_3155_SUCCESS)
-       {
-         printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n");
-         unregister_chrdev(dt3155_major, "dt3155");
-         return rcode;
-       }
-    }
-
-  /* Ok, time to setup the frame buffers */
-  if((rcode = dt3155_setup_buffers(&allocatorAddr)) < 0)
-    {
-      printk("DT3155: Error: setting up buffer not large enough.");
-      unregister_chrdev(dt3155_major, "dt3155");
-      return rcode;
-    }
-
-  /* If we are this far, then there is enough RAM */
-  /* for the buffers: Print the configuration.    */
-  for( index = 0;  index < ndevices;  index++)
-    {
-      printk("DT3155: Device = %d; acq_mode = %d; "
-            "continuous = %d; cols = %d; rows = %d;\n",
-            index ,
-            dt3155_status[index].config.acq_mode,
-            dt3155_status[index].config.continuous,
-            dt3155_status[index].config.cols,
-            dt3155_status[index].config.rows);
-      printk("DT3155: m_addr = 0x%x; m_size = %ld; "
-            "state = %d; device_installed = %d\n",
-            dt3155_status[index].mem_addr,
-            (long int)dt3155_status[index].mem_size,
-            dt3155_status[index].state,
-            dt3155_status[index].device_installed);
-    }
-
-  /* Disable ALL interrupts */
-  int_csr_r.reg = 0;
-  for( index = 0;  index < ndevices;  index++)
-    {
-      WriteMReg((dt3155_lbase[index] + INT_CSR), int_csr_r.reg);
-      if(dt3155_status[index].device_installed)
-       {
-         /*
-          * This driver *looks* like it can handle sharing interrupts,
-          * but I can't actually test myself. I've had reports that it
-          * DOES work so I'll enable it for now. This comment will remain
-          * as a reminder in case any problems arise. (SS)
-          */
-         /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */
-         rcode = request_irq(dt3155_status[index].irq, (void *)dt3155_isr,
-                              IRQF_SHARED | IRQF_DISABLED, devname[index],
-                              (void*) &dt3155_status[index]);
-         if(rcode < 0)
-           {
-             printk("DT3155: minor %d request_irq failed for IRQ %d\n",
-                    index, dt3155_status[index].irq);
-             unregister_chrdev(dt3155_major, "dt3155");
-             return rcode;
-           }
-       }
-    }
-
-  printk("DT3155: finished loading\n");
-
-  return 0;
-}
-
-/*****************************************************
- * cleanup_module(void)
- *
- *****************************************************/
-void cleanup_module(void)
-{
-  int index;
-
-  printk("DT3155:  cleanup_module called\n");
-
-  /* removed DMA allocated with the allocator */
-#ifdef STANDALONE_ALLOCATOR
-  if (allocatorAddr != 0)
-    allocator_free_dma(allocatorAddr);
-#else
-  allocator_cleanup();
-#endif
-
-  unregister_chrdev(dt3155_major, "dt3155");
-
-  for(index = 0; index < ndevices; index++)
-    {
-      if(dt3155_status[index].device_installed == 1)
-       {
-         printk("DT3155: Freeing irq %d for device %d\n",
-                 dt3155_status[index].irq, index);
-         free_irq(dt3155_status[index].irq, (void*)&dt3155_status[index]);
-       }
-    }
-}
-
diff --git a/drivers/staging/dt3155/dt3155_drv.h b/drivers/staging/dt3155/dt3155_drv.h
deleted file mode 100644 (file)
index 95e68c3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-
-Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
-                   Scott Smedley
-
-This file is part of the DT3155 Device Driver.
-
-The DT3155 Device Driver is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The DT3155 Device Driver is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with the DT3155 Device Driver; if not, write to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307 USA
-*/
-
-#ifndef DT3155_DRV_INC
-#define DT3155_DRV_INC
-
-/* kernel logical address of the frame grabbers */
-extern u8 *dt3155_lbase[MAXBOARDS];
-
-/* kernel logical address of ram buffer */
-extern u8 *dt3155_bbase;
-
-#ifdef __KERNEL__
-#include <linux/wait.h>
-
-/* wait queue for reads */
-extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS];
-#endif
-
-/* number of devices */
-extern u32 ndevices;
-
-extern int dt3155_errno;
-
-#endif
diff --git a/drivers/staging/dt3155/dt3155_io.c b/drivers/staging/dt3155/dt3155_io.c
deleted file mode 100644 (file)
index 7792e71..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
- *                         Jason Lapenta, Scott Smedley
- *
- * This file is part of the DT3155 Device Driver.
- *
- * The DT3155 Device Driver is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * The DT3155 Device Driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
- * Public License for more details.
- */
-
-/*
- * This file provides some basic register io routines.  It is modified from
- * demo code provided by Data Translations.
- */
-
-#include <linux/delay.h>
-#include "dt3155.h"
-#include "dt3155_io.h"
-#include "dt3155_drv.h"
-
-
-/****** local copies of board's 32 bit registers ******/
-u32 even_dma_start_r;  /*  bit 0 should always be 0 */
-u32 odd_dma_start_r;   /*               .. */
-u32 even_dma_stride_r; /*  bits 0&1 should always be 0 */
-u32 odd_dma_stride_r;  /*               .. */
-u32 even_pixel_fmt_r;
-u32 odd_pixel_fmt_r;
-
-FIFO_TRIGGER_R         fifo_trigger_r;
-XFER_MODE_R            xfer_mode_r;
-CSR1_R                 csr1_r;
-RETRY_WAIT_CNT_R       retry_wait_cnt_r;
-INT_CSR_R              int_csr_r;
-
-u32 even_fld_mask_r;
-u32 odd_fld_mask_r;
-
-MASK_LENGTH_R          mask_length_r;
-FIFO_FLAG_CNT_R                fifo_flag_cnt_r;
-IIC_CLK_DUR_R          iic_clk_dur_r;
-IIC_CSR1_R             iic_csr1_r;
-IIC_CSR2_R             iic_csr2_r;
-DMA_UPPER_LMT_R                even_dma_upper_lmt_r;
-DMA_UPPER_LMT_R                odd_dma_upper_lmt_r;
-
-
-
-/******** local copies of board's 8 bit I2C registers ******/
-I2C_CSR2 i2c_csr2;
-I2C_EVEN_CSR i2c_even_csr;
-I2C_ODD_CSR i2c_odd_csr;
-I2C_CONFIG i2c_config;
-u8 i2c_dt_id;
-u8 i2c_x_clip_start;
-u8 i2c_y_clip_start;
-u8 i2c_x_clip_end;
-u8 i2c_y_clip_end;
-u8 i2c_ad_addr;
-u8 i2c_ad_lut;
-I2C_AD_CMD i2c_ad_cmd;
-u8 i2c_dig_out;
-u8 i2c_pm_lut_addr;
-u8 i2c_pm_lut_data;
-
-/*
- * wait_ibsyclr()
- *
- * This function handles read/write timing and r/w timeout error
- */
-static int wait_ibsyclr(u8 *lpReg)
-{
-       /* wait 100 microseconds */
-       udelay(100L);
-       /* __delay(loops_per_sec/10000); */
-
-       ReadMReg(lpReg + IIC_CSR2, iic_csr2_r.reg);
-       if (iic_csr2_r.fld.NEW_CYCLE) {
-               /* if NEW_CYCLE didn't clear */
-               /* TIMEOUT ERROR */
-               dt3155_errno = DT_ERR_I2C_TIMEOUT;
-               return -ETIMEDOUT;
-       }
-
-       return 0;       /* no error */
-}
-
-/*
- * WriteI2C()
- *
- * This function handles writing to 8-bit DT3155 registers
- *
- * 1st parameter is pointer to 32-bit register base address
- * 2nd parameter is reg. index;
- * 3rd is value to be written
- */
-int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal)
-{
-       /* read 32 bit IIC_CSR2 register data into union */
-
-       ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
-
-       /* for write operation */
-       iic_csr2_r.fld.DIR_RD      = 0;
-       /* I2C address of I2C register: */
-       iic_csr2_r.fld.DIR_ADDR    = wIregIndex;
-       /* 8 bit data to be written to I2C reg */
-       iic_csr2_r.fld.DIR_WR_DATA = byVal;
-       /* will start a direct I2C cycle: */
-       iic_csr2_r.fld.NEW_CYCLE   = 1;
-
-       /* xfer union data into 32 bit IIC_CSR2 register */
-       WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
-
-       /* wait for IIC cycle to finish */
-       return wait_ibsyclr(lpReg);
-}
-
-/*
- * ReadI2C()
- *
- * This function handles reading from 8-bit DT3155 registers
- *
- * 1st parameter is pointer to 32-bit register base address
- * 2nd parameter is reg. index;
- * 3rd is adrs of value to be read
- */
-int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal)
-{
-       int writestat;  /* status for return */
-
-       /*  read 32 bit IIC_CSR2 register data into union */
-       ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
-
-       /*  for read operation */
-       iic_csr2_r.fld.DIR_RD     = 1;
-
-       /*  I2C address of I2C register: */
-       iic_csr2_r.fld.DIR_ADDR   = wIregIndex;
-
-       /*  will start a direct I2C cycle: */
-       iic_csr2_r.fld.NEW_CYCLE  = 1;
-
-       /*  xfer union's data into 32 bit IIC_CSR2 register */
-       WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
-
-       /* wait for IIC cycle to finish */
-       writestat = wait_ibsyclr(lpReg);
-
-       /* Next 2 commands read 32 bit IIC_CSR1 register's data into union */
-       /* first read data is in IIC_CSR1 */
-       ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg);
-
-       /* now get data u8 out of register */
-       *byVal = (u8) iic_csr1_r.fld.RD_DATA;
-
-       return writestat;
-}
diff --git a/drivers/staging/dt3155/dt3155_io.h b/drivers/staging/dt3155/dt3155_io.h
deleted file mode 100644 (file)
index d1a2510..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
-
-Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
-                   Jason Lapenta, Scott Smedley
-
-This file is part of the DT3155 Device Driver.
-
-The DT3155 Device Driver is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The DT3155 Device Driver is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with the DT3155 Device Driver; if not, write to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307 USA
-
-
--- Changes --
-
-  Date     Programmer  Description of changes made
-  -------------------------------------------------------------------
-  24-Jul-2002 SS       GPL licence.
-
-*/
-
-/* This code is a modified version of examples provided by Data Translations.*/
-
-#ifndef DT3155_IO_INC
-#define DT3155_IO_INC
-
-/* macros to access registers */
-
-#define WriteMReg(Address, Data)       (*((u32 *)(Address)) = Data)
-#define ReadMReg(Address, Data)                (Data = *((u32 *)(Address)))
-
-/***************** 32 bit register globals  **************/
-
-/*  offsets for 32-bit memory mapped registers */
-
-#define EVEN_DMA_START         0x000
-#define ODD_DMA_START          0x00C
-#define EVEN_DMA_STRIDE                0x018
-#define ODD_DMA_STRIDE         0x024
-#define EVEN_PIXEL_FMT         0x030
-#define ODD_PIXEL_FMT          0x034
-#define FIFO_TRIGGER           0x038
-#define XFER_MODE              0x03C
-#define CSR1                   0x040
-#define RETRY_WAIT_CNT         0x044
-#define INT_CSR                        0x048
-#define EVEN_FLD_MASK          0x04C
-#define ODD_FLD_MASK           0x050
-#define MASK_LENGTH            0x054
-#define FIFO_FLAG_CNT          0x058
-#define IIC_CLK_DUR            0x05C
-#define IIC_CSR1               0x060
-#define IIC_CSR2               0x064
-#define EVEN_DMA_UPPR_LMT      0x08C
-#define ODD_DMA_UPPR_LMT       0x090
-
-#define CLK_DUR_VAL            0x01010101
-
-
-
-/******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/
-
-typedef union fifo_trigger_tag {
-       u32   reg;
-       struct {
-               u32 PACKED:6;
-               u32       :9;
-               u32 PLANER:7;
-               u32       :9;
-       } fld;
-} FIFO_TRIGGER_R;
-
-typedef union xfer_mode_tag {
-       u32   reg;
-       struct {
-               u32             :2;
-               u32 FIELD_TOGGLE:1;
-               u32             :5;
-               u32             :2;
-               u32             :22;
-       } fld;
-} XFER_MODE_R;
-
-typedef union csr1_tag {
-       u32   reg;
-       struct {
-               u32 CAP_CONT_EVE:1;
-               u32 CAP_CONT_ODD:1;
-               u32 CAP_SNGL_EVE:1;
-               u32 CAP_SNGL_ODD:1;
-               u32 FLD_DN_EVE  :1;
-               u32 FLD_DN_ODD  :1;
-               u32 SRST        :1;
-               u32 FIFO_EN     :1;
-               u32 FLD_CRPT_EVE:1;
-               u32 FLD_CRPT_ODD:1;
-               u32 ADDR_ERR_EVE:1;
-               u32 ADDR_ERR_ODD:1;
-               u32 CRPT_DIS    :1;
-               u32 RANGE_EN    :1;
-               u32             :16;
-       } fld;
-} CSR1_R;
-
-typedef union retry_wait_cnt_tag {
-       u32   reg;
-       struct {
-               u32 RTRY_WAIT_CNT:8;
-               u32              :24;
-       } fld;
-} RETRY_WAIT_CNT_R;
-
-typedef union int_csr_tag {
-       u32   reg;
-       struct {
-               u32 FLD_END_EVE   :1;
-               u32 FLD_END_ODD   :1;
-               u32 FLD_START     :1;
-               u32               :5;
-               u32 FLD_END_EVE_EN:1;
-               u32 FLD_END_ODD_EN:1;
-               u32 FLD_START_EN  :1;
-               u32               :21;
-       } fld;
-} INT_CSR_R;
-
-typedef union mask_length_tag {
-       u32   reg;
-       struct {
-               u32 MASK_LEN_EVE:5;
-               u32             :11;
-               u32 MASK_LEN_ODD:5;
-               u32             :11;
-       } fld;
-} MASK_LENGTH_R;
-
-typedef union fifo_flag_cnt_tag {
-       u32   reg;
-       struct {
-               u32 AF_COUNT:7;
-               u32         :9;
-               u32 AE_COUNT:7;
-               u32         :9;
-       } fld;
-} FIFO_FLAG_CNT_R;
-
-typedef union iic_clk_dur {
-       u32   reg;
-       struct {
-               u32 PHASE_1:8;
-               u32 PHASE_2:8;
-               u32 PHASE_3:8;
-               u32 PHASE_4:8;
-       } fld;
-} IIC_CLK_DUR_R;
-
-typedef union iic_csr1_tag {
-       u32   reg;
-       struct {
-               u32 AUTO_EN     :1;
-               u32 BYPASS      :1;
-               u32 SDA_OUT     :1;
-               u32 SCL_OUT     :1;
-               u32             :4;
-               u32 AUTO_ABORT  :1;
-               u32 DIRECT_ABORT:1;
-               u32 SDA_IN      :1;
-               u32 SCL_IN      :1;
-               u32             :4;
-               u32 AUTO_ADDR   :8;
-               u32 RD_DATA     :8;
-       } fld;
-} IIC_CSR1_R;
-
-/**********************************
- * iic_csr2_tag
- */
-typedef union iic_csr2_tag {
-       u32   reg;
-       struct {
-               u32 DIR_WR_DATA :8;
-               u32 DIR_SUB_ADDR:8;
-               u32 DIR_RD      :1;
-               u32 DIR_ADDR    :7;
-               u32 NEW_CYCLE   :1;
-               u32             :7;
-       } fld;
-}  IIC_CSR2_R;
-
-/* use for both EVEN and ODD DMA UPPER LIMITS */
-
-/*
- * dma_upper_lmt_tag
- */
-typedef union dma_upper_lmt_tag   {
-       u32 reg;
-       struct {
-               u32 DMA_UPPER_LMT_VAL:24;
-               u32                  :8;
-       } fld;
-} DMA_UPPER_LMT_R;
-
-
-/*
- * Global declarations of local copies of boards' 32 bit registers
- */
-extern u32 even_dma_start_r;           /*  bit 0 should always be 0 */
-extern u32 odd_dma_start_r;            /*               ..          */
-extern u32 even_dma_stride_r;  /*  bits 0&1 should always be 0 */
-extern u32 odd_dma_stride_r;           /*               ..             */
-extern u32 even_pixel_fmt_r;
-extern u32 odd_pixel_fmt_r;
-
-extern FIFO_TRIGGER_R          fifo_trigger_r;
-extern XFER_MODE_R             xfer_mode_r;
-extern CSR1_R                  csr1_r;
-extern RETRY_WAIT_CNT_R                retry_wait_cnt_r;
-extern INT_CSR_R               int_csr_r;
-
-extern u32 even_fld_mask_r;
-extern u32 odd_fld_mask_r;
-
-extern MASK_LENGTH_R           mask_length_r;
-extern FIFO_FLAG_CNT_R         fifo_flag_cnt_r;
-extern IIC_CLK_DUR_R           iic_clk_dur_r;
-extern IIC_CSR1_R              iic_csr1_r;
-extern IIC_CSR2_R              iic_csr2_r;
-extern DMA_UPPER_LMT_R         even_dma_upper_lmt_r;
-extern DMA_UPPER_LMT_R         odd_dma_upper_lmt_r;
-
-
-
-/***************** 8 bit I2C register globals  ***********/
-#define CSR2           0x010   /* indices of 8-bit I2C mapped reg's*/
-#define EVEN_CSR       0x011
-#define ODD_CSR                0x012
-#define CONFIG         0x013
-#define DT_ID          0x01F
-#define X_CLIP_START   0x020
-#define Y_CLIP_START   0x022
-#define X_CLIP_END     0x024
-#define Y_CLIP_END     0x026
-#define AD_ADDR                0x030
-#define AD_LUT         0x031
-#define AD_CMD         0x032
-#define DIG_OUT                0x040
-#define PM_LUT_ADDR    0x050
-#define PM_LUT_DATA    0x051
-
-
-/******** Assignments and Typedefs for 8 bit I2C Registers********************/
-
-typedef union i2c_csr2_tag {
-       u8 reg;
-       struct {
-               u8 CHROM_FIL:1;
-               u8 SYNC_SNTL:1;
-               u8 HZ50:1;
-               u8 SYNC_PRESENT:1;
-               u8 BUSY_EVE:1;
-               u8 BUSY_ODD:1;
-               u8 DISP_PASS:1;
-       } fld;
-} I2C_CSR2;
-
-typedef union i2c_even_csr_tag {
-       u8    reg;
-       struct {
-               u8 DONE_EVE :1;
-               u8 SNGL_EVE :1;
-               u8 ERROR_EVE:1;
-               u8          :5;
-       } fld;
-} I2C_EVEN_CSR;
-
-typedef union i2c_odd_csr_tag {
-       u8 reg;
-       struct {
-               u8 DONE_ODD:1;
-               u8 SNGL_ODD:1;
-               u8 ERROR_ODD:1;
-               u8 :5;
-       } fld;
-} I2C_ODD_CSR;
-
-typedef union i2c_config_tag {
-       u8 reg;
-       struct {
-               u8 ACQ_MODE:2;
-               u8 EXT_TRIG_EN:1;
-               u8 EXT_TRIG_POL:1;
-               u8 H_SCALE:1;
-               u8 CLIP:1;
-               u8 PM_LUT_SEL:1;
-               u8 PM_LUT_PGM:1;
-       } fld;
-} I2C_CONFIG;
-
-
-typedef union i2c_ad_cmd_tag {
-       /* bits can have 3 different meanings depending on value of AD_ADDR */
-       u8 reg;
-       /* Bt252 Command Register if AD_ADDR = 00h */
-       struct {
-               u8             :2;
-               u8 SYNC_LVL_SEL:2;
-               u8 SYNC_CNL_SEL:2;
-               u8 DIGITIZE_CNL_SEL1:2;
-               } bt252_command;
-
-       /* Bt252 IOUT0 register if AD_ADDR = 01h */
-       struct {
-               u8 IOUT_DATA:8;
-       } bt252_iout0;
-
-       /* BT252 IOUT1 register if AD_ADDR = 02h */
-       struct {
-               u8 IOUT_DATA:8;
-       } bt252_iout1;
-} I2C_AD_CMD;
-
-
-/***** Global declarations of local copies of boards' 8 bit I2C registers ***/
-
-extern I2C_CSR2                        i2c_csr2;
-extern I2C_EVEN_CSR            i2c_even_csr;
-extern I2C_ODD_CSR             i2c_odd_csr;
-extern I2C_CONFIG              i2c_config;
-extern u8                      i2c_dt_id;
-extern u8                      i2c_x_clip_start;
-extern u8                      i2c_y_clip_start;
-extern u8                      i2c_x_clip_end;
-extern u8                      i2c_y_clip_end;
-extern u8                      i2c_ad_addr;
-extern u8                      i2c_ad_lut;
-extern I2C_AD_CMD              i2c_ad_cmd;
-extern u8                      i2c_dig_out;
-extern u8                      i2c_pm_lut_addr;
-extern u8                      i2c_pm_lut_data;
-
-/* Functions for Global use */
-
-/* access 8-bit IIC registers */
-
-extern int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal);
-extern int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal);
-
-#endif
diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c
deleted file mode 100644 (file)
index 33ddc9c..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
-
-Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
-                               Jason Lapenta, Scott Smedley, Greg Sharp
-
-This file is part of the DT3155 Device Driver.
-
-The DT3155 Device Driver is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The DT3155 Device Driver is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with the DT3155 Device Driver; if not, write to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307 USA
-
-   File: dt3155_isr.c
-Purpose: Buffer management routines, and other routines for the ISR
-               (the actual isr is in dt3155_drv.c)
-
--- Changes --
-
-  Date       Programmer  Description of changes made
-  -------------------------------------------------------------------
-  03-Jul-2000 JML       n/a
-  02-Apr-2002 SS        Mods to make work with separate allocator
-                       module; Merged John Roll's mods to make work with
-                       multiple boards.
-  10-Jul-2002 GCS       Complete rewrite of setup_buffers to disallow
-                       buffers which span a 4MB boundary.
-  24-Jul-2002 SS        GPL licence.
-  30-Jul-2002 NJC       Added support for buffer loop.
-  31-Jul-2002 NJC       Complete rewrite of buffer management
-  02-Aug-2002 NJC       Including slab.h instead of malloc.h (no warning).
-                       Also, allocator_init() now returns allocator_max
-                       so cleaned up allocate_buffers() accordingly.
-  08-Aug-2005 SS        port to 2.6 kernel.
-
-*/
-
-#include <asm/system.h>
-#include <linux/gfp.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-
-#include "dt3155.h"
-#include "dt3155_drv.h"
-#include "dt3155_io.h"
-#include "dt3155_isr.h"
-#include "allocator.h"
-
-#define FOUR_MB         (0x0400000)  /* Can't DMA accross a 4MB boundary!*/
-#define UPPER_10_BITS   (0x3FF<<22)  /* Can't DMA accross a 4MB boundary!*/
-
-
-/* Pointer into global structure for handling buffers */
-struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS] = {NULL
-#if MAXBOARDS == 2
-                                                     , NULL
-#endif
-};
-
-/******************************************************************************
- * Simple array based que struct
- *
- * Some handy functions using the buffering structure.
- *****************************************************************************/
-
-
-/***************************
- * are_empty_buffers
- * m is minor # of device
- ***************************/
-bool are_empty_buffers(int m)
-{
-  return dt3155_fbuffer[m]->empty_len;
-}
-
-/**************************
- * push_empty
- * m is minor # of device
- *
- * This is slightly confusing.  The number empty_len is the literal #
- * of empty buffers.  After calling, empty_len-1 is the index into the
- * empty buffer stack.  So, if empty_len == 1, there is one empty buffer,
- * given by dt3155_fbuffer[m]->empty_buffers[0].
- * empty_buffers should never fill up, though this is not checked.
- **************************/
-void push_empty(int index, int m)
-{
-  dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len] = index;
-  dt3155_fbuffer[m]->empty_len++;
-}
-
-/**************************
- * pop_empty(m)
- * m is minor # of device
- **************************/
-int pop_empty(int m)
-{
-  dt3155_fbuffer[m]->empty_len--;
-  return dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len];
-}
-
-/*************************
- * is_ready_buf_empty(m)
- * m is minor # of device
- *************************/
-bool is_ready_buf_empty(int m)
-{
-  return ((dt3155_fbuffer[m]->ready_len) == 0);
-}
-
-/*************************
- * is_ready_buf_full(m)
- * m is minor # of device
- * this should *never* be true if there are any active, locked or empty
- * buffers, since it corresponds to nbuffers ready buffers!!
- * 7/31/02: total rewrite. --NJC
- *************************/
-bool is_ready_buf_full(int m)
-{
-  return dt3155_fbuffer[m]->ready_len == dt3155_fbuffer[m]->nbuffers;
-}
-
-/*****************************************************
- * push_ready(m, buffer)
- * m is minor # of device
- *
- *****************************************************/
-void push_ready(int m, int index)
-{
-  int head = dt3155_fbuffer[m]->ready_head;
-
-  dt3155_fbuffer[m]->ready_que[head] = index;
-  dt3155_fbuffer[m]->ready_head = ((head + 1) %
-                                     (dt3155_fbuffer[m]->nbuffers));
-  dt3155_fbuffer[m]->ready_len++;
-
-}
-
-/*****************************************************
- * get_tail()
- * m is minor # of device
- *
- * Simply comptutes the tail given the head and the length.
- *****************************************************/
-static int get_tail(int m)
-{
-  return (dt3155_fbuffer[m]->ready_head -
-          dt3155_fbuffer[m]->ready_len +
-          dt3155_fbuffer[m]->nbuffers)%
-         (dt3155_fbuffer[m]->nbuffers);
-}
-
-
-
-/*****************************************************
- * pop_ready()
- * m is minor # of device
- *
- * This assumes that there is a ready buffer ready... should
- * be checked (e.g. with is_ready_buf_empty()  prior to call.
- *****************************************************/
-int pop_ready(int m)
-{
-  int tail;
-  tail = get_tail(m);
-  dt3155_fbuffer[m]->ready_len--;
-  return dt3155_fbuffer[m]->ready_que[tail];
-}
-
-
-/*****************************************************
- * printques
- * m is minor # of device
- *****************************************************/
-void printques(int m)
-{
-  int head = dt3155_fbuffer[m]->ready_head;
-  int tail;
-  int num = dt3155_fbuffer[m]->nbuffers;
-  int frame_index;
-  int index;
-
-  tail = get_tail(m);
-
-  printk("\n R:");
-    for (index = tail; index != head; index++, index = index % (num)) {
-       frame_index = dt3155_fbuffer[m]->ready_que[index];
-       printk(" %d ", frame_index);
-    }
-
-  printk("\n E:");
-    for (index = 0; index < dt3155_fbuffer[m]->empty_len; index++) {
-       frame_index = dt3155_fbuffer[m]->empty_buffers[index];
-       printk(" %d ", frame_index);
-    }
-
-  frame_index = dt3155_fbuffer[m]->active_buf;
-  printk("\n A: %d", frame_index);
-
-  frame_index = dt3155_fbuffer[m]->locked_buf;
-  printk("\n L: %d\n", frame_index);
-
-}
-
-/*****************************************************
- * adjust_4MB
- *
- *  If a buffer intersects the 4MB boundary, push
- *  the start address up to the beginning of the
- *  next 4MB chunk (assuming bufsize < 4MB).
- *****************************************************/
-u32 adjust_4MB(u32 buf_addr, u32 bufsize)
-{
-    if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS))
-       return (buf_addr+bufsize) & UPPER_10_BITS;
-    else
-       return buf_addr;
-}
-
-
-/*****************************************************
- * allocate_buffers
- *
- *  Try to allocate enough memory for all requested
- *  buffers.  If there is not enough free space
- *  try for less memory.
- *****************************************************/
-void allocate_buffers(u32 *buf_addr, u32* total_size_kbs,
-                      u32 bufsize)
-{
-  /* Compute the minimum amount of memory guaranteed to hold all
-     MAXBUFFERS such that no buffer crosses the 4MB boundary.
-     Store this value in the variable "full_size" */
-
-  u32 allocator_max;
-  u32 bufs_per_chunk = (FOUR_MB / bufsize);
-  u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk;
-  u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk;
-
-  u32 full_size = bufsize      /* possibly unusable part of 1st chunk */
-    + filled_chunks * FOUR_MB   /* max # of completely filled 4mb chunks */
-    + leftover_bufs * bufsize;  /* these buffs will be in a partly filled
-                                  chunk at beginning or end */
-
-  u32 full_size_kbs = 1 + (full_size-1) / 1024;
-  u32 min_size_kbs = 2*ndevices*bufsize / 1024;
-  u32 size_kbs;
-
-  /* Now, try to allocate full_size.  If this fails, keep trying for
-     less & less memory until it succeeds. */
-#ifndef STANDALONE_ALLOCATOR
-  /* initialize the allocator            */
-  allocator_init(&allocator_max);
-#endif
-  size_kbs = full_size_kbs;
-  *buf_addr = 0;
-  printk("DT3155: We would like to get: %d KB\n", full_size_kbs);
-  printk("DT3155: ...but need at least: %d KB\n", min_size_kbs);
-  printk("DT3155: ...the allocator has: %d KB\n", allocator_max);
-  size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max);
-    if (size_kbs > min_size_kbs) {
-       if ((*buf_addr = allocator_allocate_dma(size_kbs, GFP_KERNEL)) != 0) {
-               printk("DT3155:  Managed to allocate: %d KB\n", size_kbs);
-               *total_size_kbs = size_kbs;
-               return;
-       }
-    }
-  /* If we got here, the allocation failed */
-  printk("DT3155: Allocator failed!\n");
-  *buf_addr = 0;
-  *total_size_kbs = 0;
-  return;
-
-}
-
-
-/*****************************************************
- * dt3155_setup_buffers
- *
- *  setup_buffers just puts the buffering system into
- *  a consistent state before the start of interrupts
- *
- * JML : it looks like all the buffers need to be
- * continuous. So I'm going to try and allocate one
- * continuous buffer.
- *
- * GCS : Fix DMA problems when buffer spans
- * 4MB boundary.  Also, add error checking.  This
- * function will return -ENOMEM when not enough memory.
- *****************************************************/
-u32 dt3155_setup_buffers(u32 *allocatorAddr)
-
-{
-  u32 index;
-  u32 rambuff_addr; /* start of allocation */
-  u32 rambuff_size; /* total size allocated to driver */
-  u32 rambuff_acm;  /* accumlator, keep track of how much
-                         is left after being split up*/
-  u32 rambuff_end;  /* end of rambuff */
-  u32 numbufs;      /* number of useful buffers allocated (per device) */
-  u32 bufsize      = DT3155_MAX_ROWS * DT3155_MAX_COLS;
-  int m;               /* minor # of device, looped for all devs */
-
-  /* zero the fbuffer status and address structure */
-    for (m = 0; m < ndevices; m++) {
-       dt3155_fbuffer[m] = &(dt3155_status[m].fbuffer);
-
-      /* Make sure the buffering variables are consistent */
-      {
-       u8 *ptr = (u8 *) dt3155_fbuffer[m];
-               for (index = 0; index < sizeof(struct dt3155_fbuffer); index++)
-                       *(ptr++) = 0;
-      }
-    }
-
-  /* allocate a large contiguous chunk of RAM */
-  allocate_buffers(&rambuff_addr, &rambuff_size, bufsize);
-  printk("DT3155: mem info\n");
-  printk("  - rambuf_addr = 0x%x\n", rambuff_addr);
-  printk("  - length (kb) = %u\n", rambuff_size);
-    if (rambuff_addr == 0) {
-       printk(KERN_INFO
-           "DT3155: Error setup_buffers() allocator dma failed\n");
-       return -ENOMEM;
-    }
-  *allocatorAddr = rambuff_addr;
-  rambuff_end = rambuff_addr + 1024 * rambuff_size;
-
-  /* after allocation, we need to count how many useful buffers there
-     are so we can give an equal number to each device */
-  rambuff_acm = rambuff_addr;
-    for (index = 0; index < MAXBUFFERS; index++) {
-       rambuff_acm = adjust_4MB(rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/
-       if (rambuff_acm + bufsize > rambuff_end)
-               break;
-       rambuff_acm += bufsize;
-    }
-  /* Following line is OK, will waste buffers if index
-   * not evenly divisible by ndevices -NJC*/
-  numbufs = index / ndevices;
-  printk("  - numbufs = %u\n", numbufs);
-    if (numbufs < 2) {
-       printk(KERN_INFO
-       "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n");
-       return -ENOMEM;
-    }
-
-  /* now that we have board memory we spit it up */
-  /* between the boards and the buffers          */
-    rambuff_acm = rambuff_addr;
-    for (m = 0; m < ndevices; m++) {
-       rambuff_acm = adjust_4MB(rambuff_acm, bufsize);
-
-       /* Save the start of this boards buffer space (for mmap).  */
-       dt3155_status[m].mem_addr = rambuff_acm;
-
-       for (index = 0; index < numbufs; index++) {
-               rambuff_acm = adjust_4MB(rambuff_acm, bufsize);
-               if (rambuff_acm + bufsize > rambuff_end) {
-                       /* Should never happen */
-                       printk("DT3155 PROGRAM ERROR (GCS)\n"
-                       "Error distributing allocated buffers\n");
-                       return -ENOMEM;
-               }
-
-               dt3155_fbuffer[m]->frame_info[index].addr = rambuff_acm;
-               push_empty(index, m);
-               /* printk("  - Buffer : %lx\n",
-               * dt3155_fbuffer[m]->frame_info[index].addr);
-               */
-               dt3155_fbuffer[m]->nbuffers += 1;
-               rambuff_acm += bufsize;
-       }
-
-       /* Make sure there is an active buffer there. */
-       dt3155_fbuffer[m]->active_buf    = pop_empty(m);
-       dt3155_fbuffer[m]->even_happened = 0;
-       dt3155_fbuffer[m]->even_stopped  = 0;
-
-       /* make sure there is no locked_buf JML 2/28/00 */
-       dt3155_fbuffer[m]->locked_buf = -1;
-
-       dt3155_status[m].mem_size =
-       rambuff_acm - dt3155_status[m].mem_addr;
-
-       /* setup the ready queue */
-       dt3155_fbuffer[m]->ready_head = 0;
-       dt3155_fbuffer[m]->ready_len = 0;
-       printk("Available buffers for device %d: %d\n",
-           m, dt3155_fbuffer[m]->nbuffers);
-    }
-
-    return 1;
-}
-
-/*****************************************************
- * internal_release_locked_buffer
- *
- * The internal function for releasing a locked buffer.
- * It assumes interrupts are turned off.
- *
- * m is minor number of device
- *****************************************************/
-static void internal_release_locked_buffer(int m)
-{
-  /* Pointer into global structure for handling buffers */
-    if (dt3155_fbuffer[m]->locked_buf >= 0) {
-       push_empty(dt3155_fbuffer[m]->locked_buf, m);
-       dt3155_fbuffer[m]->locked_buf = -1;
-    }
-}
-
-
-/*****************************************************
- * dt3155_release_locked_buffer()
- * m is minor # of device
- *
- * The user function of the above.
- *
- *****************************************************/
-void dt3155_release_locked_buffer(int m)
-{
-       unsigned long int flags;
-       local_save_flags(flags);
-       local_irq_disable();
-       internal_release_locked_buffer(m);
-       local_irq_restore(flags);
-}
-
-
-/*****************************************************
- * dt3155_flush()
- * m is minor # of device
- *
- *****************************************************/
-int dt3155_flush(int m)
-{
-  int index;
-  unsigned long int flags;
-  local_save_flags(flags);
-  local_irq_disable();
-
-  internal_release_locked_buffer(m);
-  dt3155_fbuffer[m]->empty_len = 0;
-
-    for (index = 0; index < dt3155_fbuffer[m]->nbuffers; index++)
-       push_empty(index,  m);
-
-  /* Make sure there is an active buffer there. */
-  dt3155_fbuffer[m]->active_buf = pop_empty(m);
-
-  dt3155_fbuffer[m]->even_happened = 0;
-  dt3155_fbuffer[m]->even_stopped  = 0;
-
-  /* setup the ready queue  */
-  dt3155_fbuffer[m]->ready_head = 0;
-  dt3155_fbuffer[m]->ready_len = 0;
-
-  local_irq_restore(flags);
-
-  return 0;
-}
-
-/*****************************************************
- * dt3155_get_ready_buffer()
- * m is minor # of device
- *
- * get_ready_buffer will grab the next chunk of data
- * if it is already there, otherwise it returns 0.
- * If the user has a buffer locked it will unlock
- * that buffer before returning the new one.
- *****************************************************/
-int dt3155_get_ready_buffer(int m)
-{
-  int frame_index;
-  unsigned long int flags;
-  local_save_flags(flags);
-  local_irq_disable();
-
-#ifdef DEBUG_QUES_A
-  printques(m);
-#endif
-
-  internal_release_locked_buffer(m);
-
-    if (is_ready_buf_empty(m))
-       frame_index = -1;
-    else {
-       frame_index = pop_ready(m);
-       dt3155_fbuffer[m]->locked_buf = frame_index;
-    }
-
-#ifdef DEBUG_QUES_B
-  printques(m);
-#endif
-
-  local_irq_restore(flags);
-
-  return frame_index;
-}
diff --git a/drivers/staging/dt3155/dt3155_isr.h b/drivers/staging/dt3155/dt3155_isr.h
deleted file mode 100644 (file)
index 7d474cf..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-
-Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
-                   Jason Lapenta, Scott Smedley
-
-This file is part of the DT3155 Device Driver.
-
-The DT3155 Device Driver is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The DT3155 Device Driver is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with the DT3155 Device Driver; if not, write to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307 USA
-
-
--- Changes --
-
-  Date     Programmer   Description of changes made
-  -------------------------------------------------------------------
-  03-Jul-2000 JML       n/a
-  24-Jul-2002 SS        GPL licence.
-  26-Oct-2009 SS       Porting to 2.6.30 kernel.
-
--- notes --
-
-*/
-
-#ifndef DT3155_ISR_H
-#define DT3155_ISR_H
-
-extern struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS];
-
-/* User functions for buffering */
-/* Initialize the buffering system.  This should */
-/* be called prior to enabling interrupts */
-
-u32 dt3155_setup_buffers(u32 *allocatorAddr);
-
-/* Get the next frame of data if it is ready.  Returns */
-/* zero if no data is ready.  If there is data but */
-/* the user has a locked buffer, it will unlock that */
-/* buffer and return it to the free list. */
-
-int dt3155_get_ready_buffer(int minor);
-
-/* Return a locked buffer to the free list */
-
-void dt3155_release_locked_buffer(int minor);
-
-/* Flush the buffer system */
-int dt3155_flush(int minor);
-
-/**********************************
- * Simple array based que struct
- **********************************/
-
-bool are_empty_buffers(int minor);
-void push_empty(int index, int minor);
-
-int  pop_empty(int minor);
-
-bool is_ready_buf_empty(int minor);
-bool is_ready_buf_full(int minor);
-
-void push_ready(int minor, int index);
-int  pop_ready(int minor);
-
-
-#endif
index 6dc3af622848c8e0f56d6e7e4958363e5dc75164..fd48b38e797c7c76965f3dc21695e84b6c56db55 100644 (file)
@@ -1008,6 +1008,8 @@ struct dma_coherent_mem {
 static int __devinit
 dt3155_alloc_coherent(struct device *dev, size_t size, int flags)
 {
+       struct dma_coherent_mem *mem;
+       dma_addr_t dev_base;
        int pages = size >> PAGE_SHIFT;
        int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
 
@@ -1018,25 +1020,28 @@ dt3155_alloc_coherent(struct device *dev, size_t size, int flags)
        if (dev->dma_mem)
                goto out;
 
-       dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
-       if (!dev->dma_mem)
+       mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+       if (!mem)
                goto out;
-       dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-       if (!dev->dma_mem->bitmap)
+       mem->virt_base = dma_alloc_coherent(dev, size, &dev_base,
+                                                       DT3155_COH_FLAGS);
+       if (!mem->virt_base)
+               goto err_alloc_coherent;
+       mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+       if (!mem->bitmap)
                goto err_bitmap;
 
-       dev->dma_mem->virt_base = dma_alloc_coherent(dev, size,
-                               &dev->dma_mem->device_base, DT3155_COH_FLAGS);
-       if (!dev->dma_mem->virt_base)
-               goto err_coherent;
-       dev->dma_mem->size = pages;
-       dev->dma_mem->flags = flags;
+       /* coherent_dma_mask is already set to 32 bits */
+       mem->device_base = dev_base;
+       mem->size = pages;
+       mem->flags = flags;
+       dev->dma_mem = mem;
        return DMA_MEMORY_MAP;
 
-err_coherent:
-       kfree(dev->dma_mem->bitmap);
 err_bitmap:
-       kfree(dev->dma_mem);
+       dma_free_coherent(dev, size, mem->virt_base, dev_base);
+err_alloc_coherent:
+       kfree(mem);
 out:
        return 0;
 }
diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig
new file mode 100644 (file)
index 0000000..bd96f39
--- /dev/null
@@ -0,0 +1,17 @@
+config EASYCAP
+       tristate "EasyCAP USB ID 05e1:0408 support"
+       depends on USB && VIDEO_DEV
+
+       ---help---
+         This is an integrated audio/video driver for EasyCAP cards with
+         USB ID 05e1:0408.  It supports two hardware variants:
+
+         *  EasyCAP USB 2.0 Video Adapter with Audio, Model DC60,
+            having input cables labelled CVBS, S-VIDEO, AUDIO(L), AUDIO(R)
+
+         *  EasyCAP002 4-Channel USB 2.0 DVR, having input cables labelled
+            1, 2, 3, 4 and an unlabelled input cable for a microphone.
+
+         To compile this driver as a module, choose M here: the
+         module will be called easycap
+
diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile
new file mode 100644 (file)
index 0000000..d93bd6b
--- /dev/null
@@ -0,0 +1,13 @@
+
+obj-$(CONFIG_EASYCAP)  += easycap.o
+
+easycap-objs   := easycap_main.o easycap_low.o easycap_sound.o
+easycap-objs   += easycap_ioctl.o easycap_settings.o
+easycap-objs   += easycap_testcard.o
+
+EXTRA_CFLAGS += -Wall
+# Impose all or none of the following:
+EXTRA_CFLAGS += -DEASYCAP_IS_VIDEODEV_CLIENT
+EXTRA_CFLAGS += -DEASYCAP_NEEDS_V4L2_DEVICE_H
+EXTRA_CFLAGS += -DEASYCAP_NEEDS_V4L2_FOPS
+
diff --git a/drivers/staging/easycap/README b/drivers/staging/easycap/README
new file mode 100644 (file)
index 0000000..3775481
--- /dev/null
@@ -0,0 +1,130 @@
+
+        ***********************************************************
+        *   EasyCAP USB 2.0 Video Adapter with Audio, Model DC60  *
+        *                            and                          *
+        *             EasyCAP002 4-Channel USB 2.0 DVR            *
+        ***********************************************************
+                     Mike Thomas  <rmthomas@sciolus.org>
+
+
+
+SUPPORTED HARDWARE
+------------------
+
+This driver is intended for use with hardware having USB ID 05e1:0408.
+Two kinds of EasyCAP have this USB ID, namely:
+
+    *  EasyCAP USB 2.0 Video Adapter with Audio, Model DC60,
+       having input cables labelled CVBS, S-VIDEO, AUDIO(L), AUDIO(R)
+
+    *  EasyCAP002 4-Channel USB 2.0 DVR, having input cables labelled
+       1, 2, 3, 4 and an unlabelled input cable for a microphone.
+
+
+BUILD OPTIONS AND DEPENDENCIES
+------------------------------
+
+If the parameter EASYCAP_IS_VIDEODEV_CLIENT is undefined during compilation
+the built module is entirely independent of the videodev module, and when
+the EasyCAP is physically plugged into a USB port the special files
+/dev/easycap0 and /dev/easysnd1 are created as video and sound sources
+respectively.
+
+If the parameter EASYCAP_IS_VIDEODEV_CLIENT is defined during compilation
+the built easycap module is configured to register with the videodev module,
+in which case the special files created when the EasyCAP is plugged in are
+/dev/video0 and /dev/easysnd0.  Use of the easycap module as a client of
+the videodev module has received very little testing as of June 2010.
+
+
+KNOWN BUILD PROBLEMS
+--------------------
+
+(1) Recent gcc versions may generate the message:
+
+     warning: the frame size of .... bytes is larger than 1024 bytes
+
+This warning can be suppressed by specifying in the Makefile:
+
+     EXTRA_CFLAGS += -Wframe-larger-than=8192
+
+but it would be preferable to remove the cause of the warning.
+
+
+KNOWN RUNTIME ISSUES
+--------------------
+
+(1) Randomly (maybe 5 to 10% of occasions) the driver fails to produce any
+output at start-up.  Closing mplayer (or whatever the user program is) and
+restarting it restores normal performance without any other remedial action
+being necessary.  The reason for this is not known.
+
+(2) Intentionally, this driver will not stream material which is unambiguously
+identified by the hardware as copy-protected.  The video output will freeze
+within about a minute when this situation arises.
+
+(3) The controls for luminance, contrast, saturation, hue and volume may not
+always work properly.
+
+(4) Reduced-resolution S-Video seems to suffer from moire artefacts.  No
+attempt has yet been made to rememdy this.
+
+
+SUPPORTED TV STANDARDS AND RESOLUTIONS
+--------------------------------------
+
+The following TV standards are natively supported by the hardware and are
+usable as (for example) the "norm=" parameter in the mplayer command:
+
+    PAL_BGHIN,    NTSC_N_443,
+    PAL_Nc,       NTSC_N,
+    SECAM,        NTSC_M,        NTSC_M_JP,
+    PAL_60,       NTSC_443,
+    PAL_M.
+
+The available picture sizes are:
+
+     at 25 frames per second:   720x576, 704x576, 640x480, 360x288, 320x240;
+     at 30 frames per second:   720x480, 640x480, 360x240, 320x240;
+
+
+WHAT'S TESTED AND WHAT'S NOT
+----------------------------
+
+This driver is known to work with mplayer, mencoder, tvtime and sufficiently
+recent versions of vlc.  An interface to ffmpeg is implemented, but serious
+audio-video synchronization problems remain.
+
+The driver is designed to support all the TV standards accepted by the
+hardware, but as yet it has actually been tested on only a few of these.
+
+I have been unable to test and calibrate the S-video input myself because I
+do not possess any equipment with S-video output.
+
+This driver does not understand the V4L1 IOCTL commands, so programs such
+as camorama are not compatible.  There are reports that the driver does
+work with sufficiently recent (V4L2) versions of zoneminder, but I have not
+attempted to confirm this myself.
+
+
+UDEV RULES
+----------
+
+In order that the special files /dev/easycap0 and /dev/easysnd1 are created
+with conveniently relaxed permissions when the EasyCAP is plugged in, a file
+is preferably to be provided in directory /etc/udev/rules.d with content:
+
+ACTION!="add|change", GOTO="easycap_rules_end"
+ATTRS{idVendor}=="05e1", ATTRS{idProduct}=="0408", \
+       MODE="0666", OWNER="root", GROUP="root"
+LABEL="easycap_rules_end"
+
+
+ACKNOWLEGEMENTS AND REFERENCES
+------------------------------
+This driver makes use of information contained in the Syntek Semicon DC-1125
+Driver, presently maintained at http://sourceforge.net/projects/syntekdriver/
+by Nicolas Vivien.  Particularly useful has been a patch to the latter driver
+provided by Ivor Hewitt in January 2009.  The NTSC implementation is taken
+from the work of Ben Trask.
+
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h
new file mode 100644 (file)
index 0000000..ad836d2
--- /dev/null
@@ -0,0 +1,642 @@
+/*****************************************************************************
+*                                                                            *
+*  easycap.h                                                                 *
+*                                                                            *
+*****************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE FOLLOWING PARAMETERS ARE UNDEFINED:
+ *
+ *                EASYCAP_DEBUG
+ *                EASYCAP_IS_VIDEODEV_CLIENT
+ *                EASYCAP_NEEDS_USBVIDEO_H
+ *                EASYCAP_NEEDS_V4L2_DEVICE_H
+ *                EASYCAP_NEEDS_V4L2_FOPS
+ *
+ *  IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
+ *  OPTIONS.
+ */
+/*---------------------------------------------------------------------------*/
+
+#if (!defined(EASYCAP_H))
+#define EASYCAP_H
+
+#if defined(EASYCAP_DEBUG)
+#if (9 < EASYCAP_DEBUG)
+#error Debug levels 0 to 9 are okay.\
+  To achieve higher levels, remove this trap manually from easycap.h
+#endif
+#endif /*EASYCAP_DEBUG*/
+/*---------------------------------------------------------------------------*/
+/*
+ *  THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED:
+ */
+/*---------------------------------------------------------------------------*/
+#undef  PREFER_NTSC
+#undef  EASYCAP_TESTCARD
+#undef  EASYCAP_TESTTONE
+#undef  LOCKFRAME
+#undef  NOREADBACK
+#undef  AUDIOTIME
+/*---------------------------------------------------------------------------*/
+/*
+ *
+ *  DEFINE   BRIDGER   TO ACTIVATE THE ROUTINE FOR BRIDGING VIDEOTAPE DROPOUTS.
+ *
+ *             *** UNDER DEVELOPMENT/TESTING - NOT READY YET!***
+ *
+ */
+/*---------------------------------------------------------------------------*/
+#undef  BRIDGER
+/*---------------------------------------------------------------------------*/
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/smp_lock.h>
+#include <linux/usb.h>
+#include <linux/uaccess.h>
+
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+#include <linux/poll.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+#if (!defined(__OLD_VIDIOC_))
+#define __OLD_VIDIOC_
+#endif /* !defined(__OLD_VIDIOC_) */
+
+#include <media/v4l2-dev.h>
+
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+#include <media/v4l2-device.h>
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+
+#if (!defined(__OLD_VIDIOC_))
+#define __OLD_VIDIOC_
+#endif /* !defined(__OLD_VIDIOC_) */
+#include <linux/videodev2.h>
+
+#include <linux/soundcard.h>
+
+#if defined(EASYCAP_NEEDS_USBVIDEO_H)
+#include <config/video/usbvideo.h>
+#endif /*EASYCAP_NEEDS_USBVIDEO_H*/
+
+#if (!defined(PAGE_SIZE))
+#error "PAGE_SIZE not defined"
+#endif
+
+#define STRINGIZE_AGAIN(x) #x
+#define STRINGIZE(x) STRINGIZE_AGAIN(x)
+
+/*---------------------------------------------------------------------------*/
+/*  VENDOR, PRODUCT:  Syntek Semiconductor Co., Ltd
+ *
+ *      EITHER        EasyCAP USB 2.0 Video Adapter with Audio, Model No. DC60
+ *               with input cabling:  AUDIO(L), AUDIO(R), CVBS, S-VIDEO.
+ *
+ *          OR        EasyCAP 4CHANNEL USB 2.0 DVR, Model No. EasyCAP002
+ *               with input cabling:  MICROPHONE, CVBS1, CVBS2, CVBS3, CVBS4.
+ */
+/*---------------------------------------------------------------------------*/
+#define USB_EASYCAP_VENDOR_ID  0x05e1
+#define USB_EASYCAP_PRODUCT_ID 0x0408
+
+#define EASYCAP_DRIVER_VERSION "0.8.21"
+#define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
+
+#define USB_SKEL_MINOR_BASE     192
+#define VIDEO_DEVICE_MANY 8
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  DEFAULT LUMINANCE, CONTRAST, SATURATION AND HUE
+ */
+/*---------------------------------------------------------------------------*/
+#define SAA_0A_DEFAULT 0x7F
+#define SAA_0B_DEFAULT 0x3F
+#define SAA_0C_DEFAULT 0x2F
+#define SAA_0D_DEFAULT 0x00
+/*---------------------------------------------------------------------------*/
+/*
+ *  VIDEO STREAMING PARAMETERS:
+ *  USB 2.0 PROVIDES FOR HIGH-BANDWIDTH ENDPOINTS WITH AN UPPER LIMIT
+ *  OF 3072 BYTES PER MICROFRAME for wMaxPacketSize.
+ */
+/*---------------------------------------------------------------------------*/
+#define VIDEO_ISOC_BUFFER_MANY 16
+#define VIDEO_ISOC_ORDER 3
+#define VIDEO_ISOC_FRAMESPERDESC ((unsigned int) 1 << VIDEO_ISOC_ORDER)
+#define USB_2_0_MAXPACKETSIZE 3072
+#if (USB_2_0_MAXPACKETSIZE > PAGE_SIZE)
+#error video_isoc_buffer[.] will not be big enough
+#endif
+/*---------------------------------------------------------------------------*/
+/*
+ *  VIDEO BUFFERS
+ */
+/*---------------------------------------------------------------------------*/
+#define FIELD_BUFFER_SIZE (203 * PAGE_SIZE)
+#define FRAME_BUFFER_SIZE (405 * PAGE_SIZE)
+#define FIELD_BUFFER_MANY 4
+#define FRAME_BUFFER_MANY 6
+/*---------------------------------------------------------------------------*/
+/*
+ *  AUDIO STREAMING PARAMETERS
+ */
+/*---------------------------------------------------------------------------*/
+#define AUDIO_ISOC_BUFFER_MANY 16
+#define AUDIO_ISOC_ORDER 3
+#define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER)
+/*---------------------------------------------------------------------------*/
+/*
+ *  AUDIO BUFFERS
+ */
+/*---------------------------------------------------------------------------*/
+#define AUDIO_FRAGMENT_MANY 32
+/*---------------------------------------------------------------------------*/
+/*
+ *  IT IS ESSENTIAL THAT EVEN-NUMBERED STANDARDS ARE 25 FRAMES PER SECOND,
+ *                        ODD-NUMBERED STANDARDS ARE 30 FRAMES PER SECOND.
+ *  THE NUMBERING OF STANDARDS MUST NOT BE CHANGED WITHOUT DUE CARE.  NOT
+ *  ONLY MUST THE PARAMETER
+ *                             STANDARD_MANY
+ *  BE CHANGED TO CORRESPOND TO THE NEW NUMBER OF STANDARDS, BUT ALSO THE
+ *  NUMBERING MUST REMAIN AN UNBROKEN ASCENDING SEQUENCE:  DUMMY STANDARDS
+ *  MAY NEED TO BE ADDED.   APPROPRIATE CHANGES WILL ALWAYS BE REQUIRED IN
+ *  ROUTINE fillin_formats() AND POSSIBLY ELSEWHERE.  BEWARE.
+ */
+/*---------------------------------------------------------------------------*/
+#define  PAL_BGHIN      0
+#define  PAL_Nc         2
+#define  SECAM          4
+#define  NTSC_N         6
+#define  NTSC_N_443     8
+#define  NTSC_M         1
+#define  NTSC_443       3
+#define  NTSC_M_JP      5
+#define  PAL_60         7
+#define  PAL_M          9
+#define  STANDARD_MANY 10
+/*---------------------------------------------------------------------------*/
+/*
+ *  ENUMS
+ */
+/*---------------------------------------------------------------------------*/
+enum {
+AT_720x576,
+AT_704x576,
+AT_640x480,
+AT_720x480,
+AT_360x288,
+AT_320x240,
+AT_360x240,
+RESOLUTION_MANY
+};
+enum {
+FMT_UYVY,
+FMT_YUY2,
+FMT_RGB24,
+FMT_RGB32,
+FMT_BGR24,
+FMT_BGR32,
+PIXELFORMAT_MANY
+};
+enum {
+FIELD_NONE,
+FIELD_INTERLACED,
+FIELD_ALTERNATE,
+INTERLACE_MANY
+};
+#define SETTINGS_MANY  (STANDARD_MANY * \
+                       RESOLUTION_MANY * \
+                       2 * \
+                       PIXELFORMAT_MANY * \
+                       INTERLACE_MANY)
+/*---------------------------------------------------------------------------*/
+/*
+ *  STRUCTURE DEFINITIONS
+ */
+/*---------------------------------------------------------------------------*/
+struct data_buffer {
+struct list_head list_head;
+void *pgo;
+void *pto;
+__u16 kount;
+};
+/*---------------------------------------------------------------------------*/
+struct data_urb {
+struct list_head list_head;
+struct urb *purb;
+int isbuf;
+int length;
+};
+/*---------------------------------------------------------------------------*/
+struct easycap_standard {
+__u16 mask;
+struct v4l2_standard v4l2_standard;
+};
+struct easycap_format {
+__u16 mask;
+char name[128];
+struct v4l2_format v4l2_format;
+};
+/*---------------------------------------------------------------------------*/
+/*
+ *   easycap.ilk == 0   =>  CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=256
+ *   easycap.ilk == 2   =>  CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=9
+ *   easycap.ilk == 3   =>     FOUR-CVBS HARDWARE, AUDIO wMaxPacketSize=9
+ */
+/*---------------------------------------------------------------------------*/
+struct easycap {
+unsigned int audio_pages_per_fragment;
+unsigned int audio_bytes_per_fragment;
+unsigned int audio_buffer_page_many;
+
+#define UPSAMPLE
+#if defined(UPSAMPLE)
+__s16 oldaudio;
+#endif /*UPSAMPLE*/
+
+struct easycap_format easycap_format[1 + SETTINGS_MANY];
+
+int ilk;
+bool microphone;
+
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+struct video_device *pvideo_device;
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+
+struct usb_device *pusb_device;
+struct usb_interface *pusb_interface;
+
+struct kref kref;
+
+struct mutex mutex_mmap_video[FRAME_BUFFER_MANY];
+struct mutex mutex_timeval0;
+struct mutex mutex_timeval1;
+
+int queued[FRAME_BUFFER_MANY];
+int done[FRAME_BUFFER_MANY];
+
+wait_queue_head_t wq_video;
+wait_queue_head_t wq_audio;
+
+int input;
+int polled;
+int standard_offset;
+int format_offset;
+
+int fps;
+int usec;
+int tolerate;
+int merit[180];
+
+struct timeval timeval0;
+struct timeval timeval1;
+struct timeval timeval2;
+struct timeval timeval7;
+long long int dnbydt;
+
+int    video_interface;
+int    video_altsetting_on;
+int    video_altsetting_off;
+int    video_endpointnumber;
+int    video_isoc_maxframesize;
+int    video_isoc_buffer_size;
+int    video_isoc_framesperdesc;
+
+int    video_isoc_streaming;
+int    video_isoc_sequence;
+int    video_idle;
+int    video_eof;
+int    video_junk;
+
+int    fudge;
+
+struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY];
+struct data_buffer \
+            field_buffer[FIELD_BUFFER_MANY][(FIELD_BUFFER_SIZE/PAGE_SIZE)];
+struct data_buffer \
+            frame_buffer[FRAME_BUFFER_MANY][(FRAME_BUFFER_SIZE/PAGE_SIZE)];
+
+struct list_head urb_video_head;
+struct list_head *purb_video_head;
+
+int vma_many;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  BUFFER INDICATORS
+ */
+/*---------------------------------------------------------------------------*/
+int field_fill;                /* Field buffer being filled by easycap_complete().  */
+                       /*   Bumped only by easycap_complete().              */
+int field_page;                /* Page of field buffer page being filled by         */
+                       /*   easycap_complete().                             */
+int field_read;                /* Field buffer to be read by field2frame().         */
+                       /*   Bumped only by easycap_complete().              */
+int frame_fill;                /* Frame buffer being filled by field2frame().       */
+                       /*   Bumped only by easycap_dqbuf() when             */
+                       /*   field2frame() has created a complete frame.     */
+int frame_read;                /* Frame buffer offered to user by DQBUF.            */
+                       /*   Set only by easycap_dqbuf() to trail frame_fill.*/
+int frame_lock;                /* Flag set to 1 by DQBUF and cleared by QBUF        */
+/*---------------------------------------------------------------------------*/
+/*
+ *  IMAGE PROPERTIES
+ */
+/*---------------------------------------------------------------------------*/
+__u32                   pixelformat;
+__u32                   field;
+int                     width;
+int                     height;
+int                     bytesperpixel;
+bool                    byteswaporder;
+bool                    decimatepixel;
+bool                    offerfields;
+int                     frame_buffer_used;
+int                     frame_buffer_many;
+int                     videofieldamount;
+
+int                     brightness;
+int                     contrast;
+int                     saturation;
+int                     hue;
+
+int allocation_video_urb;
+int allocation_video_page;
+int allocation_video_struct;
+int registered_video;
+/*---------------------------------------------------------------------------*/
+/*
+ *  SOUND PROPERTIES
+ */
+/*---------------------------------------------------------------------------*/
+int audio_interface;
+int audio_altsetting_on;
+int audio_altsetting_off;
+int audio_endpointnumber;
+int audio_isoc_maxframesize;
+int audio_isoc_buffer_size;
+int audio_isoc_framesperdesc;
+
+int audio_isoc_streaming;
+int audio_idle;
+int audio_eof;
+int volume;
+int mute;
+
+struct data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY];
+
+struct list_head urb_audio_head;
+struct list_head *purb_audio_head;
+/*---------------------------------------------------------------------------*/
+/*
+ *  BUFFER INDICATORS
+ */
+/*---------------------------------------------------------------------------*/
+int audio_fill;                /* Audio buffer being filled by easysnd_complete().  */
+                       /*   Bumped only by easysnd_complete().              */
+int audio_read;                /* Audio buffer page being read by easysnd_read().   */
+                       /*   Set by easysnd_read() to trail audio_fill by    */
+                       /*   one fragment.                                   */
+/*---------------------------------------------------------------------------*/
+/*
+ *  SOUND PROPERTIES
+ */
+/*---------------------------------------------------------------------------*/
+
+int audio_buffer_many;
+
+int allocation_audio_urb;
+int allocation_audio_page;
+int allocation_audio_struct;
+int registered_audio;
+
+long long int audio_sample;
+long long int audio_niveau;
+long long int audio_square;
+
+struct data_buffer audio_buffer[];
+};
+/*---------------------------------------------------------------------------*/
+/*
+ *  VIDEO FUNCTION PROTOTYPES
+ */
+/*---------------------------------------------------------------------------*/
+void             easycap_complete(struct urb *);
+int              easycap_open(struct inode *, struct file *);
+int              easycap_release(struct inode *, struct file *);
+int              easycap_ioctl(struct inode *, struct file *, \
+                                               unsigned int,  unsigned long);
+
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+int              easycap_open_noinode(struct file *);
+int              easycap_release_noinode(struct file *);
+long             easycap_ioctl_noinode(struct file *, \
+                                               unsigned int,  unsigned long);
+int              videodev_release(struct video_device *);
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+
+unsigned int     easycap_poll(struct file *, poll_table *);
+int              easycap_mmap(struct file *, struct vm_area_struct *);
+int              easycap_usb_probe(struct usb_interface *, \
+                                               const struct usb_device_id *);
+void             easycap_usb_disconnect(struct usb_interface *);
+void             easycap_delete(struct kref *);
+
+void             easycap_vma_open(struct vm_area_struct *);
+void             easycap_vma_close(struct vm_area_struct *);
+int              easycap_vma_fault(struct vm_area_struct *, struct vm_fault *);
+int              easycap_dqbuf(struct easycap *, int);
+int              submit_video_urbs(struct easycap *);
+int              kill_video_urbs(struct easycap *);
+int              field2frame(struct easycap *);
+int              redaub(struct easycap *, void *, void *, \
+                                               int, int, __u8, __u8, bool);
+void             debrief(struct easycap *);
+void             sayreadonly(struct easycap *);
+void             easycap_testcard(struct easycap *, int);
+int              explain_ioctl(__u32);
+int              explain_cid(__u32);
+int              fillin_formats(void);
+int              adjust_standard(struct easycap *, v4l2_std_id);
+int              adjust_format(struct easycap *, __u32, __u32, __u32, \
+                                                               int, bool);
+int              adjust_brightness(struct easycap *, int);
+int              adjust_contrast(struct easycap *, int);
+int              adjust_saturation(struct easycap *, int);
+int              adjust_hue(struct easycap *, int);
+int              adjust_volume(struct easycap *, int);
+/*---------------------------------------------------------------------------*/
+/*
+ *  AUDIO FUNCTION PROTOTYPES
+ */
+/*---------------------------------------------------------------------------*/
+void             easysnd_complete(struct urb *);
+ssize_t          easysnd_read(struct file *, char __user *, size_t, loff_t *);
+int              easysnd_open(struct inode *, struct file *);
+int              easysnd_release(struct inode *, struct file *);
+int              easysnd_ioctl(struct inode *, struct file *, \
+                                               unsigned int,  unsigned long);
+unsigned int     easysnd_poll(struct file *, poll_table *);
+void             easysnd_delete(struct kref *);
+int              submit_audio_urbs(struct easycap *);
+int              kill_audio_urbs(struct easycap *);
+void             easysnd_testtone(struct easycap *, int);
+int              audio_setup(struct easycap *);
+/*---------------------------------------------------------------------------*/
+/*
+ *  LOW-LEVEL FUNCTION PROTOTYPES
+ */
+/*---------------------------------------------------------------------------*/
+int              audio_gainget(struct usb_device *);
+int              audio_gainset(struct usb_device *, __s8);
+
+int              set_interface(struct usb_device *, __u16);
+int              wakeup_device(struct usb_device *);
+int              confirm_resolution(struct usb_device *);
+int              confirm_stream(struct usb_device *);
+
+int              setup_stk(struct usb_device *);
+int              setup_saa(struct usb_device *);
+int              setup_vt(struct usb_device *);
+int              check_stk(struct usb_device *);
+int              check_saa(struct usb_device *);
+int              ready_saa(struct usb_device *);
+int              merit_saa(struct usb_device *);
+int              check_vt(struct usb_device *);
+int              select_input(struct usb_device *, int, int);
+int              set_resolution(struct usb_device *, \
+                                               __u16, __u16, __u16, __u16);
+
+int              read_saa(struct usb_device *, __u16);
+int              read_stk(struct usb_device *, __u32);
+int              write_saa(struct usb_device *, __u16, __u16);
+int              wait_i2c(struct usb_device *);
+int              write_000(struct usb_device *, __u16, __u16);
+int              start_100(struct usb_device *);
+int              stop_100(struct usb_device *);
+int              write_300(struct usb_device *);
+int              read_vt(struct usb_device *, __u16);
+int              write_vt(struct usb_device *, __u16, __u16);
+
+int              set2to78(struct usb_device *);
+int              set2to93(struct usb_device *);
+
+int              regset(struct usb_device *, __u16, __u16);
+int              regget(struct usb_device *, __u16, void *);
+/*---------------------------------------------------------------------------*/
+struct signed_div_result {
+long long int quotient;
+unsigned long long int remainder;
+} signed_div(long long int, long long int);
+/*---------------------------------------------------------------------------*/
+/*
+ *  MACROS
+ */
+/*---------------------------------------------------------------------------*/
+#define GET(X, Y, Z) do { \
+       int rc; \
+       *(Z) = (__u16)0; \
+       rc = regget(X, Y, Z); \
+       if (0 > rc) { \
+               JOT(8, ":-(%i\n", __LINE__);  return(rc); \
+       } \
+} while (0)
+
+#define SET(X, Y, Z) do { \
+       int rc; \
+       rc = regset(X, Y, Z); \
+       if (0 > rc) { \
+               JOT(8, ":-(%i\n", __LINE__);  return(rc); \
+       } \
+} while (0)
+/*---------------------------------------------------------------------------*/
+
+#define SAY(format, args...) do { \
+       printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \
+} while (0)
+
+
+#if defined(EASYCAP_DEBUG)
+#define JOT(n, format, args...) do { \
+       if (n <= easycap_debug) { \
+               printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \
+       } \
+} while (0)
+#else
+#define JOT(n, format, args...) do {} while (0)
+#endif /*EASYCAP_DEBUG*/
+
+#define POUT JOT(8, ":-(in file %s line %4i\n", __FILE__, __LINE__)
+
+#define MICROSECONDS(X, Y) \
+                       ((1000000*((long long int)(X.tv_sec - Y.tv_sec))) + \
+                                       (long long int)(X.tv_usec - Y.tv_usec))
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  (unsigned char *)P           pointer to next byte pair
+ *       (long int *)X           pointer to accumulating count
+ *       (long int *)Y           pointer to accumulating sum
+ *  (long long int *)Z           pointer to accumulating sum of squares
+ */
+/*---------------------------------------------------------------------------*/
+#define SUMMER(P, X, Y, Z) do {                                 \
+       unsigned char *p;                                    \
+       unsigned int u0, u1, u2;                             \
+       long int s;                                          \
+       p = (unsigned char *)(P);                            \
+       u0 = (unsigned int) (*p);                            \
+       u1 = (unsigned int) (*(p + 1));                      \
+       u2 = (unsigned int) ((u1 << 8) | u0);                \
+       if (0x8000 & u2)                                     \
+               s = -(long int)(0x7FFF & (~u2));             \
+       else                                                 \
+               s =  (long int)(0x7FFF & u2);                \
+       *((X)) += (long int) 1;                              \
+       *((Y)) += (long int) s;                              \
+       *((Z)) += ((long long int)(s) * (long long int)(s)); \
+} while (0)
+/*---------------------------------------------------------------------------*/
+
+#endif /*EASYCAP_H*/
diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h
new file mode 100644 (file)
index 0000000..1d10d7e
--- /dev/null
@@ -0,0 +1,27 @@
+/*****************************************************************************
+*                                                                            *
+*  easycap_debug.h                                                           *
+*                                                                            *
+*****************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+extern int easycap_debug;
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c
new file mode 100644 (file)
index 0000000..276b63d
--- /dev/null
@@ -0,0 +1,2687 @@
+/******************************************************************************
+*                                                                             *
+*  easycap_ioctl.c                                                            *
+*                                                                             *
+******************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+
+#include "easycap.h"
+#include "easycap_debug.h"
+#include "easycap_standard.h"
+#include "easycap_ioctl.h"
+
+/*--------------------------------------------------------------------------*/
+/*
+ *  UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
+ *  FOLLOWING:
+ *          peasycap->standard_offset
+ *          peasycap->fps
+ *          peasycap->usec
+ *          peasycap->tolerate
+ */
+/*---------------------------------------------------------------------------*/
+int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
+{
+struct easycap_standard const *peasycap_standard;
+__u16 reg, set;
+int ir, rc, need;
+unsigned int itwas, isnow;
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+peasycap_standard = &easycap_standard[0];
+while (0xFFFF != peasycap_standard->mask) {
+       if (std_id & peasycap_standard->v4l2_standard.id)
+               break;
+       peasycap_standard++;
+}
+if (0xFFFF == peasycap_standard->mask) {
+       SAY("ERROR: 0x%08X=std_id: standard not found\n", \
+                                                       (unsigned int)std_id);
+       return -EINVAL;
+}
+SAY("user requests standard: %s\n", \
+                       &(peasycap_standard->v4l2_standard.name[0]));
+if (peasycap->standard_offset == \
+                       (int)(peasycap_standard - &easycap_standard[0])) {
+       SAY("requested standard already in effect\n");
+       return 0;
+}
+peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]);
+peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \
+               peasycap_standard->v4l2_standard.frameperiod.numerator;
+if (!peasycap->fps) {
+       SAY("MISTAKE: frames-per-second is zero\n");
+       return -EFAULT;
+}
+JOT(8, "%i frames-per-second\n", peasycap->fps);
+peasycap->usec = 1000000 / (2 * peasycap->fps);
+peasycap->tolerate = 1000 * (25 / peasycap->fps);
+
+kill_video_urbs(peasycap);
+
+/*--------------------------------------------------------------------------*/
+/*
+ *  SAA7113H DATASHEET PAGE 44, TABLE 42
+ */
+/*--------------------------------------------------------------------------*/
+need = 0;  itwas = 0;  reg = 0x00;  set = 0x00;
+switch (peasycap_standard->mask & 0x000F) {
+case NTSC_M_JP: {
+       reg = 0x0A;  set = 0x95;
+       ir = read_saa(peasycap->pusb_device, reg);
+       if (0 > ir)
+               SAY("ERROR: cannot read SAA register 0x%02X\n", reg);
+       else
+               itwas = (unsigned int)ir;
+
+
+       set2to78(peasycap->pusb_device);
+
+
+       rc = write_saa(peasycap->pusb_device, reg, set);
+       if (0 != rc)
+               SAY("ERROR: failed to set SAA register " \
+                       "0x%02X to 0x%02X for JP standard\n", reg, set);
+       else {
+               isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+               if (0 > ir)
+                       JOT(8, "SAA register 0x%02X changed " \
+                               "to 0x%02X\n", reg, isnow);
+               else
+                       JOT(8, "SAA register 0x%02X changed " \
+                               "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+
+               set2to78(peasycap->pusb_device);
+
+       }
+
+       reg = 0x0B;  set = 0x48;
+       ir = read_saa(peasycap->pusb_device, reg);
+       if (0 > ir)
+               SAY("ERROR: cannot read SAA register 0x%02X\n", reg);
+       else
+               itwas = (unsigned int)ir;
+
+       set2to78(peasycap->pusb_device);
+
+       rc = write_saa(peasycap->pusb_device, reg, set);
+       if (0 != rc)
+               SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X " \
+                                               "for JP standard\n", reg, set);
+       else {
+               isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+               if (0 > ir)
+                       JOT(8, "SAA register 0x%02X changed " \
+                               "to 0x%02X\n", reg, isnow);
+               else
+                       JOT(8, "SAA register 0x%02X changed " \
+                               "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+
+               set2to78(peasycap->pusb_device);
+
+       }
+/*--------------------------------------------------------------------------*/
+/*
+ *  NOTE:  NO break HERE:  RUN ON TO NEXT CASE
+ */
+/*--------------------------------------------------------------------------*/
+}
+case NTSC_M:
+case PAL_BGHIN: {
+       reg = 0x0E;  set = 0x01;  need = 1;  break;
+}
+case NTSC_N_443:
+case PAL_60: {
+       reg = 0x0E;  set = 0x11;  need = 1;  break;
+}
+case NTSC_443:
+case PAL_Nc: {
+       reg = 0x0E;  set = 0x21;  need = 1;  break;
+}
+case NTSC_N:
+case PAL_M: {
+       reg = 0x0E;  set = 0x31;  need = 1;  break;
+}
+case SECAM: {
+       reg = 0x0E;  set = 0x51;  need = 1;  break;
+}
+default:
+       break;
+}
+/*--------------------------------------------------------------------------*/
+if (need) {
+       ir = read_saa(peasycap->pusb_device, reg);
+       if (0 > ir)
+               SAY("ERROR: failed to read SAA register 0x%02X\n", reg);
+       else
+               itwas = (unsigned int)ir;
+
+       set2to78(peasycap->pusb_device);
+
+       rc = write_saa(peasycap->pusb_device, reg, set);
+       if (0 != write_saa(peasycap->pusb_device, reg, set)) {
+               SAY("ERROR: failed to set SAA register " \
+                       "0x%02X to 0x%02X for table 42\n", reg, set);
+       } else {
+               isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+               if (0 > ir)
+                       JOT(8, "SAA register 0x%02X changed " \
+                               "to 0x%02X\n", reg, isnow);
+               else
+                       JOT(8, "SAA register 0x%02X changed " \
+                               "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+       }
+}
+/*--------------------------------------------------------------------------*/
+/*
+ *  SAA7113H DATASHEET PAGE 41
+ */
+/*--------------------------------------------------------------------------*/
+reg = 0x08;
+ir = read_saa(peasycap->pusb_device, reg);
+if (0 > ir)
+       SAY("ERROR: failed to read SAA register 0x%02X " \
+                                               "so cannot reset\n", reg);
+else {
+       itwas = (unsigned int)ir;
+       if (peasycap_standard->mask & 0x0001)
+               set = itwas | 0x40 ;
+       else
+               set = itwas & ~0x40 ;
+
+set2to78(peasycap->pusb_device);
+
+rc  = write_saa(peasycap->pusb_device, reg, set);
+if (0 != rc)
+       SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set);
+else {
+       isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+       if (0 > ir)
+               JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow);
+       else
+               JOT(8, "SAA register 0x%02X changed " \
+                       "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+       }
+}
+/*--------------------------------------------------------------------------*/
+/*
+ *  SAA7113H DATASHEET PAGE 51, TABLE 57
+ */
+/*---------------------------------------------------------------------------*/
+reg = 0x40;
+ir = read_saa(peasycap->pusb_device, reg);
+if (0 > ir)
+       SAY("ERROR: failed to read SAA register 0x%02X " \
+                                               "so cannot reset\n", reg);
+else {
+       itwas = (unsigned int)ir;
+       if (peasycap_standard->mask & 0x0001)
+               set = itwas | 0x80 ;
+       else
+               set = itwas & ~0x80 ;
+
+set2to78(peasycap->pusb_device);
+
+rc = write_saa(peasycap->pusb_device, reg, set);
+if (0 != rc)
+       SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set);
+else {
+       isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+       if (0 > ir)
+               JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow);
+       else
+               JOT(8, "SAA register 0x%02X changed " \
+                       "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+       }
+}
+/*--------------------------------------------------------------------------*/
+/*
+ *  SAA7113H DATASHEET PAGE 53, TABLE 66
+ */
+/*--------------------------------------------------------------------------*/
+reg = 0x5A;
+ir = read_saa(peasycap->pusb_device, reg);
+if (0 > ir)
+       SAY("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
+       itwas = (unsigned int)ir;
+       if (peasycap_standard->mask & 0x0001)
+               set = 0x0A ;
+       else
+               set = 0x07 ;
+
+       set2to78(peasycap->pusb_device);
+
+       if (0 != write_saa(peasycap->pusb_device, reg, set))
+               SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
+                                                               reg, set);
+       else {
+               isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+               if (0 > ir)
+                       JOT(8, "SAA register 0x%02X changed "
+                               "to 0x%02X\n", reg, isnow);
+               else
+                       JOT(8, "SAA register 0x%02X changed "
+                               "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+       }
+       if (0 != check_saa(peasycap->pusb_device))
+               SAY("ERROR: check_saa() failed\n");
+return 0;
+}
+/*****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL DEPENDS ON THE
+ *  CURRENT VALUE OF peasycap->standard_offset.
+ *  PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN
+ *  THIS ROUTINE UPDATES THE FOLLOWING:
+ *          peasycap->format_offset
+ *          peasycap->pixelformat
+ *          peasycap->field
+ *          peasycap->height
+ *          peasycap->width
+ *          peasycap->bytesperpixel
+ *          peasycap->byteswaporder
+ *          peasycap->decimatepixel
+ *          peasycap->frame_buffer_used
+ *          peasycap->videofieldamount
+ *          peasycap->offerfields
+ *
+ *  IF SUCCESSFUL THE FUNCTION RETURNS THE OFFSET IN easycap_format[]
+ *  IDENTIFYING THE FORMAT WHICH IS TO RETURNED TO THE USER.
+ *  ERRORS RETURN A NEGATIVE NUMBER.
+ */
+/*--------------------------------------------------------------------------*/
+int adjust_format(struct easycap *peasycap, \
+       __u32 width, __u32 height, __u32 pixelformat, int field, bool try)
+{
+struct easycap_format *peasycap_format, *peasycap_best_format;
+__u16 mask;
+struct usb_device *p;
+int miss, multiplier, best;
+char bf[5], *pc;
+__u32 uc;
+
+if ((struct easycap *)NULL == peasycap) {
+       SAY("ERROR: peasycap is NULL\n");
+       return -EFAULT;
+}
+p = peasycap->pusb_device;
+if ((struct usb_device *)NULL == p) {
+       SAY("ERROR: peaycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+pc = &bf[0];
+uc = pixelformat;  memcpy((void *)pc, (void *)(&uc), 4);  bf[4] = 0;
+mask = easycap_standard[peasycap->standard_offset].mask;
+SAY("sought:    %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \
+                               width, height, pc, pixelformat, field, mask);
+if (V4L2_FIELD_ANY == field) {
+       field = V4L2_FIELD_INTERLACED;
+       SAY("prefer:    V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n");
+}
+peasycap_best_format = (struct easycap_format *)NULL;
+peasycap_format = &easycap_format[0];
+while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
+       JOT(16, ".> %i %i 0x%08X %ix%i\n", \
+               peasycap_format->mask & 0x01,
+               peasycap_format->v4l2_format.fmt.pix.field,
+               peasycap_format->v4l2_format.fmt.pix.pixelformat,
+               peasycap_format->v4l2_format.fmt.pix.width,
+               peasycap_format->v4l2_format.fmt.pix.height);
+
+       if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
+               (peasycap_format->v4l2_format.fmt.pix.field == field) && \
+               (peasycap_format->v4l2_format.fmt.pix.pixelformat == \
+                                                       pixelformat) && \
+               (peasycap_format->v4l2_format.fmt.pix.width  == width) && \
+               (peasycap_format->v4l2_format.fmt.pix.height == height)) {
+                       peasycap_best_format = peasycap_format;
+                       break;
+               }
+       peasycap_format++;
+}
+if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
+       SAY("cannot do: %ix%i with standard mask 0x%02X\n", \
+                                                       width, height, mask);
+       peasycap_format = &easycap_format[0];  best = -1;
+       while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
+               if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
+                                (peasycap_format->v4l2_format.fmt.pix\
+                                               .field == field) && \
+                                (peasycap_format->v4l2_format.fmt.pix\
+                                               .pixelformat == pixelformat)) {
+                       miss = abs(peasycap_format->\
+                                       v4l2_format.fmt.pix.width  - width);
+                       if ((best > miss) || (best < 0)) {
+                               best = miss;
+                               peasycap_best_format = peasycap_format;
+                               if (!miss)
+                                       break;
+                       }
+               }
+               peasycap_format++;
+       }
+       if (-1 == best) {
+               SAY("cannot do %ix... with standard mask 0x%02X\n", \
+                                                               width, mask);
+               SAY("cannot do ...x%i with standard mask 0x%02X\n", \
+                                                               height, mask);
+               SAY("           %ix%i unmatched\n", width, height);
+               return peasycap->format_offset;
+       }
+}
+if ((struct easycap_format *)NULL == peasycap_best_format) {
+       SAY("MISTAKE: peasycap_best_format is NULL");
+       return -EINVAL;
+}
+peasycap_format = peasycap_best_format;
+
+/*...........................................................................*/
+if (true == try)
+       return (int)(peasycap_best_format - &easycap_format[0]);
+/*...........................................................................*/
+
+if (false != try) {
+       SAY("MISTAKE: true==try where is should be false\n");
+       return -EINVAL;
+}
+SAY("actioning: %ix%i %s\n", \
+                       peasycap_format->v4l2_format.fmt.pix.width, \
+                       peasycap_format->v4l2_format.fmt.pix.height,
+                       &peasycap_format->name[0]);
+peasycap->height        = peasycap_format->v4l2_format.fmt.pix.height;
+peasycap->width         = peasycap_format->v4l2_format.fmt.pix.width;
+peasycap->pixelformat   = peasycap_format->v4l2_format.fmt.pix.pixelformat;
+peasycap->field         = peasycap_format->v4l2_format.fmt.pix.field;
+peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]);
+peasycap->bytesperpixel = (0x00F0 & peasycap_format->mask) >> 4 ;
+if (0x0100 & peasycap_format->mask)
+       peasycap->byteswaporder = true;
+else
+       peasycap->byteswaporder = false;
+if (0x0800 & peasycap_format->mask)
+       peasycap->decimatepixel = true;
+else
+       peasycap->decimatepixel = false;
+if (0x1000 & peasycap_format->mask)
+       peasycap->offerfields = true;
+else
+       peasycap->offerfields = false;
+if (true == peasycap->decimatepixel)
+       multiplier = 2;
+else
+       multiplier = 1;
+peasycap->videofieldamount = multiplier * peasycap->width * \
+                                       multiplier * peasycap->height;
+peasycap->frame_buffer_used = peasycap->bytesperpixel * \
+                                       peasycap->width * peasycap->height;
+
+if (true == peasycap->offerfields) {
+       SAY("WARNING: %i=peasycap->field is untested: " \
+                               "please report problems\n", peasycap->field);
+
+
+/*
+ *    FIXME ---- THIS IS UNTESTED, MAY BE (AND PROBABLY IS) INCORRECT:
+ *
+ *    peasycap->frame_buffer_used = peasycap->frame_buffer_used / 2;
+ *
+ *    SO DO NOT RISK IT YET.
+ *
+ */
+
+
+
+}
+
+kill_video_urbs(peasycap);
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  PAL
+ */
+/*---------------------------------------------------------------------------*/
+if (0 == (0x01 & peasycap_format->mask)) {
+       if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (576 == \
+                       peasycap_format->v4l2_format.fmt.pix.height)) || \
+                       ((360 == \
+                       peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (288 == \
+                       peasycap_format->v4l2_format.fmt.pix.height))) {
+               if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
+                       SAY("ERROR: set_resolution() failed\n");
+                       return -EINVAL;
+               }
+       } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (576 == peasycap_format->v4l2_format.fmt.pix.height)) {
+               if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
+                       SAY("ERROR: set_resolution() failed\n");
+                       return -EINVAL;
+               }
+       } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (480 == \
+                       peasycap_format->v4l2_format.fmt.pix.height)) || \
+                       ((320 == \
+                       peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (240 == \
+                       peasycap_format->v4l2_format.fmt.pix.height))) {
+               if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
+                       SAY("ERROR: set_resolution() failed\n");
+                       return -EINVAL;
+               }
+       } else {
+               SAY("MISTAKE: bad format, cannot set resolution\n");
+               return -EINVAL;
+       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  NTSC
+ */
+/*---------------------------------------------------------------------------*/
+} else {
+       if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (480 == \
+                       peasycap_format->v4l2_format.fmt.pix.height)) || \
+                       ((360 == \
+                       peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (240 == \
+                       peasycap_format->v4l2_format.fmt.pix.height))) {
+               if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
+                       SAY("ERROR: set_resolution() failed\n");
+                       return -EINVAL;
+               }
+       } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (480 == \
+                       peasycap_format->v4l2_format.fmt.pix.height)) || \
+                       ((320 == \
+                       peasycap_format->v4l2_format.fmt.pix.width) && \
+                       (240 == \
+                       peasycap_format->v4l2_format.fmt.pix.height))) {
+               if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
+                       SAY("ERROR: set_resolution() failed\n");
+                       return -EINVAL;
+               }
+       } else {
+               SAY("MISTAKE: bad format, cannot set resolution\n");
+               return -EINVAL;
+       }
+}
+/*---------------------------------------------------------------------------*/
+
+check_stk(peasycap->pusb_device);
+
+return (int)(peasycap_best_format - &easycap_format[0]);
+}
+/*****************************************************************************/
+int adjust_brightness(struct easycap *peasycap, int value)
+{
+unsigned int mood;
+int i1;
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+i1 = 0;
+while (0xFFFFFFFF != easycap_control[i1].id) {
+       if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) {
+               if ((easycap_control[i1].minimum > value) || \
+                                       (easycap_control[i1].maximum < value))
+                       value = easycap_control[i1].default_value;
+               peasycap->brightness = value;
+               mood = 0x00FF & (unsigned int)peasycap->brightness;
+
+               set2to78(peasycap->pusb_device);
+
+               if (!write_saa(peasycap->pusb_device, 0x0A, mood)) {
+                       SAY("adjusting brightness to  0x%02X\n", mood);
+                       return 0;
+               } else {
+                       SAY("WARNING: failed to adjust brightness " \
+                                                       "to 0x%02X\n", mood);
+                       return -ENOENT;
+               }
+
+               set2to78(peasycap->pusb_device);
+
+               break;
+       }
+       i1++;
+}
+SAY("WARNING: failed to adjust brightness: control not found\n");
+return -ENOENT;
+}
+/*****************************************************************************/
+int adjust_contrast(struct easycap *peasycap, int value)
+{
+unsigned int mood;
+int i1;
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+i1 = 0;
+while (0xFFFFFFFF != easycap_control[i1].id) {
+       if (V4L2_CID_CONTRAST == easycap_control[i1].id) {
+               if ((easycap_control[i1].minimum > value) || \
+                                       (easycap_control[i1].maximum < value))
+                       value = easycap_control[i1].default_value;
+               peasycap->contrast = value;
+               mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
+
+               set2to78(peasycap->pusb_device);
+
+               if (!write_saa(peasycap->pusb_device, 0x0B, mood)) {
+                       SAY("adjusting contrast to  0x%02X\n", mood);
+                       return 0;
+               } else {
+                       SAY("WARNING: failed to adjust contrast to " \
+                                                       "0x%02X\n", mood);
+                       return -ENOENT;
+               }
+
+               set2to78(peasycap->pusb_device);
+
+               break;
+       }
+       i1++;
+}
+SAY("WARNING: failed to adjust contrast: control not found\n");
+return -ENOENT;
+}
+/*****************************************************************************/
+int adjust_saturation(struct easycap *peasycap, int value)
+{
+unsigned int mood;
+int i1;
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+i1 = 0;
+while (0xFFFFFFFF != easycap_control[i1].id) {
+       if (V4L2_CID_SATURATION == easycap_control[i1].id) {
+               if ((easycap_control[i1].minimum > value) || \
+                                       (easycap_control[i1].maximum < value))
+                       value = easycap_control[i1].default_value;
+               peasycap->saturation = value;
+               mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
+
+               set2to78(peasycap->pusb_device);
+
+               if (!write_saa(peasycap->pusb_device, 0x0C, mood)) {
+                       SAY("adjusting saturation to  0x%02X\n", mood);
+                       return 0;
+               } else {
+                       SAY("WARNING: failed to adjust saturation to " \
+                                                       "0x%02X\n", mood);
+                       return -ENOENT;
+               }
+               break;
+
+               set2to78(peasycap->pusb_device);
+
+       }
+       i1++;
+}
+SAY("WARNING: failed to adjust saturation: control not found\n");
+return -ENOENT;
+}
+/*****************************************************************************/
+int adjust_hue(struct easycap *peasycap, int value)
+{
+unsigned int mood;
+int i1, i2;
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+i1 = 0;
+while (0xFFFFFFFF != easycap_control[i1].id) {
+       if (V4L2_CID_HUE == easycap_control[i1].id) {
+               if ((easycap_control[i1].minimum > value) || \
+                                       (easycap_control[i1].maximum < value))
+                       value = easycap_control[i1].default_value;
+               peasycap->hue = value;
+               i2 = peasycap->hue - 128;
+               mood = 0x00FF & ((int) i2);
+
+               set2to78(peasycap->pusb_device);
+
+               if (!write_saa(peasycap->pusb_device, 0x0D, mood)) {
+                       SAY("adjusting hue to  0x%02X\n", mood);
+                       return 0;
+               } else {
+                       SAY("WARNING: failed to adjust hue to 0x%02X\n", mood);
+                       return -ENOENT;
+               }
+
+               set2to78(peasycap->pusb_device);
+
+               break;
+       }
+       i1++;
+}
+SAY("WARNING: failed to adjust hue: control not found\n");
+return -ENOENT;
+}
+/*****************************************************************************/
+int adjust_volume(struct easycap *peasycap, int value)
+{
+__s8 mood;
+int i1;
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+i1 = 0;
+while (0xFFFFFFFF != easycap_control[i1].id) {
+       if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
+               if ((easycap_control[i1].minimum > value) || \
+                       (easycap_control[i1].maximum < value))
+                       value = easycap_control[i1].default_value;
+               peasycap->volume = value;
+               mood = (16 > peasycap->volume) ? 16 : \
+                       ((31 < peasycap->volume) ? 31 : \
+                       (__s8) peasycap->volume);
+               if (!audio_gainset(peasycap->pusb_device, mood)) {
+                       SAY("adjusting volume to 0x%01X\n", mood);
+                       return 0;
+               } else {
+                       SAY("WARNING: failed to adjust volume to " \
+                                                       "0x%1X\n", mood);
+                       return -ENOENT;
+               }
+               break;
+       }
+i1++;
+}
+SAY("WARNING: failed to adjust volume: control not found\n");
+return -ENOENT;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE:
+ *            usb_set_interface(peasycap->pusb_device, \
+ *                              peasycap->audio_interface, \
+ *                              peasycap->audio_altsetting_off);
+ *  HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
+ *  -ESHUTDOWN.  THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT
+ *  THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY.  BEWARE.
+ */
+/*---------------------------------------------------------------------------*/
+int adjust_mute(struct easycap *peasycap, int value)
+{
+int i1;
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+i1 = 0;
+while (0xFFFFFFFF != easycap_control[i1].id) {
+       if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) {
+               peasycap->mute = value;
+               switch (peasycap->mute) {
+               case 1: {
+                       peasycap->audio_idle = 1;
+                       peasycap->timeval0.tv_sec = 0;
+                       SAY("adjusting mute: %i=peasycap->audio_idle\n", \
+                                                       peasycap->audio_idle);
+                       return 0;
+               }
+               default: {
+                       peasycap->audio_idle = 0;
+                       SAY("adjusting mute: %i=peasycap->audio_idle\n", \
+                                                       peasycap->audio_idle);
+                       return 0;
+               }
+               }
+               break;
+       }
+       i1++;
+}
+SAY("WARNING: failed to adjust mute: control not found\n");
+return -ENOENT;
+}
+/****************************************************************************/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+long
+easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg)\
+                                                                       {
+       return easycap_ioctl((struct inode *)NULL, file, cmd, arg);
+}
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*--------------------------------------------------------------------------*/
+int easycap_ioctl(struct inode *inode, struct file *file, \
+                                       unsigned int cmd, unsigned long arg)
+{
+static struct easycap *peasycap;
+static struct usb_device *p;
+static __u32 isequence;
+
+peasycap = file->private_data;
+if (NULL == peasycap) {
+       SAY("ERROR:  peasycap is NULL\n");
+       return -1;
+}
+p = peasycap->pusb_device;
+if ((struct usb_device *)NULL == p) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  MOST OF THE VARIABLES DECLARED static IN THE case{} BLOCKS BELOW ARE SO
+ *  DECLARED SIMPLY TO AVOID A COMPILER WARNING OF THE KIND:
+ *  easycap_ioctl.c: warning:
+ *                       the frame size of ... bytes is larger than 1024 bytes
+ */
+/*---------------------------------------------------------------------------*/
+switch (cmd) {
+case VIDIOC_QUERYCAP: {
+       static struct v4l2_capability v4l2_capability;
+       static char version[16], *p1, *p2;
+       static int i, rc, k[3];
+       static long lng;
+
+       JOT(8, "VIDIOC_QUERYCAP\n");
+
+       if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
+               SAY("ERROR: bad driver version string\n"); return -EINVAL;
+       }
+       strcpy(&version[0], EASYCAP_DRIVER_VERSION);
+       for (i = 0; i < 3; i++)
+               k[i] = 0;
+       p2 = &version[0];  i = 0;
+       while (*p2) {
+               p1 = p2;
+               while (*p2 && ('.' != *p2))
+                       p2++;
+               if (*p2)
+                       *p2++ = 0;
+               if (3 > i) {
+                       rc = (int) strict_strtol(p1, 10, &lng);
+                       if (0 != rc) {
+                               SAY("ERROR: %i=strict_strtol(%s,.,,)\n", \
+                                                               rc, p1);
+                               return -EINVAL;
+                       }
+                       k[i] = (int)lng;
+               }
+               i++;
+       }
+
+       memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
+       strlcpy(&v4l2_capability.driver[0], "easycap", \
+                                       sizeof(v4l2_capability.driver));
+
+       v4l2_capability.capabilities = \
+                               V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
+                               V4L2_CAP_AUDIO         | V4L2_CAP_READWRITE;
+
+       v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
+       JOT(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
+
+       strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \
+               sizeof(v4l2_capability.card));
+
+       if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\
+                               sizeof(v4l2_capability.bus_info)) < 0) {
+               strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \
+                                       sizeof(v4l2_capability.bus_info));
+               JOT(8, "%s=v4l2_capability.bus_info\n", \
+                                       &v4l2_capability.bus_info[0]);
+       }
+       if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
+                                       sizeof(struct v4l2_capability))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_ENUMINPUT: {
+       static struct v4l2_input v4l2_input;
+       static __u32 index;
+
+       JOT(8, "VIDIOC_ENUMINPUT\n");
+
+       if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
+                                       sizeof(struct v4l2_input))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       index = v4l2_input.index;
+       memset(&v4l2_input, 0, sizeof(struct v4l2_input));
+
+       switch (index) {
+       case 0: {
+               v4l2_input.index = index;
+               strcpy(&v4l2_input.name[0], "CVBS0");
+               v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
+               v4l2_input.audioset = 0x01;
+               v4l2_input.tuner = 0;
+               v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
+                               V4L2_STD_NTSC ;
+               v4l2_input.status = 0;
+               JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+               break;
+       }
+       case 1: {
+               v4l2_input.index = index;
+               strcpy(&v4l2_input.name[0], "CVBS1");
+               v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
+               v4l2_input.audioset = 0x01;
+               v4l2_input.tuner = 0;
+               v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
+                               V4L2_STD_NTSC ;
+               v4l2_input.status = 0;
+               JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+               break;
+       }
+       case 2: {
+               v4l2_input.index = index;
+               strcpy(&v4l2_input.name[0], "CVBS2");
+               v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
+               v4l2_input.audioset = 0x01;
+               v4l2_input.tuner = 0;
+               v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
+                               V4L2_STD_NTSC ;
+               v4l2_input.status = 0;
+               JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+               break;
+       }
+       case 3: {
+               v4l2_input.index = index;
+               strcpy(&v4l2_input.name[0], "CVBS3");
+               v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
+               v4l2_input.audioset = 0x01;
+               v4l2_input.tuner = 0;
+               v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
+                               V4L2_STD_NTSC ;
+               v4l2_input.status = 0;
+               JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+               break;
+       }
+       case 4: {
+               v4l2_input.index = index;
+               strcpy(&v4l2_input.name[0], "CVBS4");
+               v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
+               v4l2_input.audioset = 0x01;
+               v4l2_input.tuner = 0;
+               v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
+                               V4L2_STD_NTSC ;
+               v4l2_input.status = 0;
+               JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+               break;
+       }
+       case 5: {
+               v4l2_input.index = index;
+               strcpy(&v4l2_input.name[0], "S-VIDEO");
+               v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
+               v4l2_input.audioset = 0x01;
+               v4l2_input.tuner = 0;
+               v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
+                               V4L2_STD_NTSC ;
+               v4l2_input.status = 0;
+               JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+               break;
+       }
+       default: {
+               JOT(8, "%i=index: exhausts inputs\n", index);
+               return -EINVAL;
+       }
+       }
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
+                                               sizeof(struct v4l2_input))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_INPUT: {
+       static __u32 index;
+
+       JOT(8, "VIDIOC_G_INPUT\n");
+       index = (__u32)peasycap->input;
+       JOT(8, "user is told: %i\n", index);
+       if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_S_INPUT:
+       {
+       static __u32 index;
+
+       JOT(8, "VIDIOC_S_INPUT\n");
+
+       if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       JOT(8, "user requests input %i\n", index);
+
+       if ((int)index == peasycap->input) {
+               SAY("requested input already in effect\n");
+               break;
+       }
+
+       if ((0 > index) || (5 < index)) {
+               JOT(8, "ERROR:  bad requested input: %i\n", index);
+               return -EINVAL;
+       }
+       peasycap->input = (int)index;
+
+       select_input(peasycap->pusb_device, peasycap->input, 9);
+
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_ENUMAUDIO: {
+       JOT(8, "VIDIOC_ENUMAUDIO\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_ENUMAUDOUT: {
+       static struct v4l2_audioout v4l2_audioout;
+
+       JOT(8, "VIDIOC_ENUMAUDOUT\n");
+
+       if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
+                                       sizeof(struct v4l2_audioout))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (0 != v4l2_audioout.index)
+               return -EINVAL;
+       memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
+       v4l2_audioout.index = 0;
+       strcpy(&v4l2_audioout.name[0], "Soundtrack");
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
+                                       sizeof(struct v4l2_audioout))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_QUERYCTRL: {
+       static int i1;
+       static struct v4l2_queryctrl v4l2_queryctrl;
+
+       JOT(8, "VIDIOC_QUERYCTRL\n");
+
+       if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
+                                       sizeof(struct v4l2_queryctrl))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       i1 = 0;
+       while (0xFFFFFFFF != easycap_control[i1].id) {
+               if (easycap_control[i1].id == v4l2_queryctrl.id) {
+                       JOT(8, "VIDIOC_QUERYCTRL  %s=easycap_control[%i]" \
+                               ".name\n", &easycap_control[i1].name[0], i1);
+                       memcpy(&v4l2_queryctrl, &easycap_control[i1], \
+                                               sizeof(struct v4l2_queryctrl));
+                       break;
+               }
+               i1++;
+       }
+       if (0xFFFFFFFF == easycap_control[i1].id) {
+               JOT(8, "%i=index: exhausts controls\n", i1);
+               return -EINVAL;
+       }
+       if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
+                                       sizeof(struct v4l2_queryctrl))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_QUERYMENU: {
+       JOT(8, "VIDIOC_QUERYMENU unsupported\n");
+       return -EINVAL;
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_CTRL: {
+       static struct v4l2_control v4l2_control;
+
+       JOT(8, "VIDIOC_G_CTRL\n");
+
+       if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
+                                       sizeof(struct v4l2_control))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       switch (v4l2_control.id) {
+       case V4L2_CID_BRIGHTNESS: {
+               v4l2_control.value = peasycap->brightness;
+               JOT(8, "user enquires brightness: %i\n", v4l2_control.value);
+               break;
+       }
+       case V4L2_CID_CONTRAST: {
+               v4l2_control.value = peasycap->contrast;
+               JOT(8, "user enquires contrast: %i\n", v4l2_control.value);
+               break;
+       }
+       case V4L2_CID_SATURATION: {
+               v4l2_control.value = peasycap->saturation;
+               JOT(8, "user enquires saturation: %i\n", v4l2_control.value);
+               break;
+       }
+       case V4L2_CID_HUE: {
+               v4l2_control.value = peasycap->hue;
+               JOT(8, "user enquires hue: %i\n", v4l2_control.value);
+               break;
+       }
+       case V4L2_CID_AUDIO_VOLUME: {
+               v4l2_control.value = peasycap->volume;
+               JOT(8, "user enquires volume: %i\n", v4l2_control.value);
+               break;
+       }
+       case V4L2_CID_AUDIO_MUTE: {
+               if (1 == peasycap->mute)
+                       v4l2_control.value = true;
+               else
+                       v4l2_control.value = false;
+               JOT(8, "user enquires mute: %i\n", v4l2_control.value);
+               break;
+       }
+       default: {
+               SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
+                                                       v4l2_control.id);
+               explain_cid(v4l2_control.id);
+               return -EINVAL;
+       }
+       }
+       if (0 != copy_to_user((void __user *)arg, &v4l2_control, \
+                                       sizeof(struct v4l2_control))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#if defined(VIDIOC_S_CTRL_OLD)
+case VIDIOC_S_CTRL_OLD: {
+       JOT(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
+}
+#endif /*VIDIOC_S_CTRL_OLD*/
+case VIDIOC_S_CTRL:
+       {
+       static struct v4l2_control v4l2_control;
+
+       JOT(8, "VIDIOC_S_CTRL\n");
+
+       if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
+                                       sizeof(struct v4l2_control))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       switch (v4l2_control.id) {
+       case V4L2_CID_BRIGHTNESS: {
+               JOT(8, "user requests brightness %i\n", v4l2_control.value);
+               if (0 != adjust_brightness(peasycap, v4l2_control.value))
+                       ;
+               break;
+       }
+       case V4L2_CID_CONTRAST: {
+               JOT(8, "user requests contrast %i\n", v4l2_control.value);
+               if (0 != adjust_contrast(peasycap, v4l2_control.value))
+                       ;
+               break;
+       }
+       case V4L2_CID_SATURATION: {
+               JOT(8, "user requests saturation %i\n", v4l2_control.value);
+               if (0 != adjust_saturation(peasycap, v4l2_control.value))
+                       ;
+               break;
+       }
+       case V4L2_CID_HUE: {
+               JOT(8, "user requests hue %i\n", v4l2_control.value);
+               if (0 != adjust_hue(peasycap, v4l2_control.value))
+                       ;
+               break;
+       }
+       case V4L2_CID_AUDIO_VOLUME: {
+               JOT(8, "user requests volume %i\n", v4l2_control.value);
+               if (0 != adjust_volume(peasycap, v4l2_control.value))
+                       ;
+               break;
+       }
+       case V4L2_CID_AUDIO_MUTE: {
+               int mute;
+
+               JOT(8, "user requests mute %i\n", v4l2_control.value);
+               if (true == v4l2_control.value)
+                       mute = 1;
+               else
+                       mute = 0;
+
+               if (0 != adjust_mute(peasycap, mute))
+                       SAY("WARNING: failed to adjust mute to %i\n", mute);
+               break;
+       }
+       default: {
+               SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
+                                                       v4l2_control.id);
+               explain_cid(v4l2_control.id);
+       return -EINVAL;
+                       }
+               }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_S_EXT_CTRLS: {
+       JOT(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_ENUM_FMT: {
+       static __u32 index;
+       static struct v4l2_fmtdesc v4l2_fmtdesc;
+
+       JOT(8, "VIDIOC_ENUM_FMT\n");
+
+       if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
+                                       sizeof(struct v4l2_fmtdesc))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       index = v4l2_fmtdesc.index;
+       memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
+
+       v4l2_fmtdesc.index = index;
+       v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+       switch (index) {
+       case 0: {
+               v4l2_fmtdesc.flags = 0;
+               strcpy(&v4l2_fmtdesc.description[0], "uyvy");
+               v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
+               JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+               break;
+       }
+       case 1: {
+               v4l2_fmtdesc.flags = 0;
+               strcpy(&v4l2_fmtdesc.description[0], "yuy2");
+               v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
+               JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+               break;
+       }
+       case 2: {
+               v4l2_fmtdesc.flags = 0;
+               strcpy(&v4l2_fmtdesc.description[0], "rgb24");
+               v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
+               JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+               break;
+       }
+       case 3: {
+               v4l2_fmtdesc.flags = 0;
+               strcpy(&v4l2_fmtdesc.description[0], "rgb32");
+               v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
+               JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+               break;
+       }
+       case 4: {
+               v4l2_fmtdesc.flags = 0;
+               strcpy(&v4l2_fmtdesc.description[0], "bgr24");
+               v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
+               JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+               break;
+       }
+       case 5: {
+               v4l2_fmtdesc.flags = 0;
+               strcpy(&v4l2_fmtdesc.description[0], "bgr32");
+               v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
+               JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+               break;
+       }
+       default: {
+               JOT(8, "%i=index: exhausts formats\n", index);
+               return -EINVAL;
+       }
+       }
+       if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
+                                       sizeof(struct v4l2_fmtdesc))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_ENUM_FRAMESIZES: {
+       JOT(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n");
+       return -EINVAL;
+}
+case VIDIOC_ENUM_FRAMEINTERVALS: {
+       JOT(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_FMT: {
+       static struct v4l2_format v4l2_format;
+       static struct v4l2_pix_format v4l2_pix_format;
+
+       JOT(8, "VIDIOC_G_FMT\n");
+
+       if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
+                                       sizeof(struct v4l2_format))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+               POUT;
+               return -EINVAL;
+       }
+
+       memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
+       v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       memcpy(&(v4l2_format.fmt.pix), \
+                        &(easycap_format[peasycap->format_offset]\
+                       .v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
+       JOT(8, "user is told: %s\n", \
+                       &easycap_format[peasycap->format_offset].name[0]);
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
+                                       sizeof(struct v4l2_format))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_TRY_FMT:
+case VIDIOC_S_FMT: {
+       static struct v4l2_format v4l2_format;
+       static struct v4l2_pix_format v4l2_pix_format;
+       static bool try;
+       static int best_format;
+
+       if (VIDIOC_TRY_FMT == cmd) {
+               JOT(8, "VIDIOC_TRY_FMT\n");
+               try = true;
+       } else {
+               JOT(8, "VIDIOC_S_FMT\n");
+               try = false;
+       }
+
+       if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
+                                       sizeof(struct v4l2_format))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       best_format = adjust_format(peasycap, \
+                                       v4l2_format.fmt.pix.width, \
+                                       v4l2_format.fmt.pix.height, \
+                                       v4l2_format.fmt.pix.pixelformat, \
+                                       v4l2_format.fmt.pix.field, \
+                                       try);
+       if (0 > best_format) {
+               JOT(8, "WARNING: adjust_format() returned %i\n", best_format);
+               return -ENOENT;
+       }
+/*...........................................................................*/
+       memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
+       v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+       memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\
+                       .v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
+       JOT(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
+                                       sizeof(struct v4l2_format))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_CROPCAP: {
+       static struct v4l2_cropcap v4l2_cropcap;
+
+       JOT(8, "VIDIOC_CROPCAP\n");
+
+       if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
+                                       sizeof(struct v4l2_cropcap))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+
+       memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
+       v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       v4l2_cropcap.bounds.left      = 0;
+       v4l2_cropcap.bounds.top       = 0;
+       v4l2_cropcap.bounds.width     = peasycap->width;
+       v4l2_cropcap.bounds.height    = peasycap->height;
+       v4l2_cropcap.defrect.left     = 0;
+       v4l2_cropcap.defrect.top      = 0;
+       v4l2_cropcap.defrect.width    = peasycap->width;
+       v4l2_cropcap.defrect.height   = peasycap->height;
+       v4l2_cropcap.pixelaspect.numerator = 1;
+       v4l2_cropcap.pixelaspect.denominator = 1;
+
+       JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
+                                       sizeof(struct v4l2_cropcap))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_CROP:
+case VIDIOC_S_CROP: {
+       JOT(8, "VIDIOC_G_CROP|VIDIOC_S_CROP  unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_QUERYSTD: {
+       JOT(8, "VIDIOC_QUERYSTD: " \
+                       "EasyCAP is incapable of detecting standard\n");
+       return -EINVAL;
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE MANIPULATIONS INVOLVING last0,last1,last2,last3 CONSTITUTE A WORKAROUND
+ *  FOR WHAT APPEARS TO BE A BUG IN 64-BIT mplayer.
+ *  NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer.
+ */
+/*---------------------------------------------------------------------------*/
+case VIDIOC_ENUMSTD: {
+       static int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
+       static struct v4l2_standard v4l2_standard;
+       static __u32 index;
+       static struct easycap_standard const *peasycap_standard;
+
+       JOT(8, "VIDIOC_ENUMSTD\n");
+
+       if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
+                                       sizeof(struct v4l2_standard))) {
+               POUT;
+               return -EFAULT;
+       }
+       index = v4l2_standard.index;
+
+       last3 = last2; last2 = last1; last1 = last0; last0 = index;
+       if ((index == last3) && (index == last2) && \
+                       (index == last1) && (index == last0)) {
+               index++;
+               last3 = last2; last2 = last1; last1 = last0; last0 = index;
+       }
+
+       memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
+
+       peasycap_standard = &easycap_standard[0];
+       while (0xFFFF != peasycap_standard->mask) {
+               if ((int)(peasycap_standard - &easycap_standard[0]) == index)
+                       break;
+               peasycap_standard++;
+       }
+       if (0xFFFF == peasycap_standard->mask) {
+               JOT(8, "%i=index: exhausts standards\n", index);
+               return -EINVAL;
+       }
+       JOT(8, "%i=index: %s\n", index, \
+                               &(peasycap_standard->v4l2_standard.name[0]));
+       memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \
+                                       sizeof(struct v4l2_standard));
+
+       v4l2_standard.index = index;
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
+                                       sizeof(struct v4l2_standard))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_STD: {
+       static v4l2_std_id std_id;
+       static struct easycap_standard const *peasycap_standard;
+
+       JOT(8, "VIDIOC_G_STD\n");
+
+       if (0 != copy_from_user(&std_id, (void __user *)arg, \
+                                               sizeof(v4l2_std_id))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       peasycap_standard = &easycap_standard[peasycap->standard_offset];
+       std_id = peasycap_standard->v4l2_standard.id;
+
+       JOT(8, "user is told: %s\n", \
+                               &peasycap_standard->v4l2_standard.name[0]);
+
+       if (0 != copy_to_user((void __user *)arg, &std_id, \
+                                               sizeof(v4l2_std_id))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_S_STD: {
+       static v4l2_std_id std_id;
+       static int rc;
+
+       JOT(8, "VIDIOC_S_STD\n");
+
+       if (0 != copy_from_user(&std_id, (void __user *)arg, \
+                                               sizeof(v4l2_std_id))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       rc = adjust_standard(peasycap, std_id);
+       if (0 > rc) {
+               JOT(8, "WARNING: adjust_standard() returned %i\n", rc);
+               return -ENOENT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_REQBUFS: {
+       static int nbuffers;
+       static struct v4l2_requestbuffers v4l2_requestbuffers;
+
+       JOT(8, "VIDIOC_REQBUFS\n");
+
+       if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
+                               sizeof(struct v4l2_requestbuffers))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+       if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
+               POUT;
+               return -EINVAL;
+       }
+       nbuffers = v4l2_requestbuffers.count;
+       JOT(8, "                   User requests %i buffers ...\n", nbuffers);
+       if (nbuffers < 2)
+               nbuffers = 2;
+       if (nbuffers > FRAME_BUFFER_MANY)
+               nbuffers = FRAME_BUFFER_MANY;
+       if (v4l2_requestbuffers.count == nbuffers) {
+               JOT(8, "                   ... agree to  %i buffers\n", \
+                                                               nbuffers);
+       } else {
+               JOT(8, "                  ... insist on  %i buffers\n", \
+                                                               nbuffers);
+               v4l2_requestbuffers.count = nbuffers;
+       }
+       peasycap->frame_buffer_many = nbuffers;
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
+                               sizeof(struct v4l2_requestbuffers))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_QUERYBUF: {
+       static __u32 index;
+       static struct v4l2_buffer v4l2_buffer;
+
+       JOT(8, "VIDIOC_QUERYBUF\n");
+
+       if (peasycap->video_eof) {
+               JOT(8, "returning -1 because  %i=video_eof\n", \
+                                                       peasycap->video_eof);
+               return -1;
+       }
+
+       if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
+                                       sizeof(struct v4l2_buffer))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+       index = v4l2_buffer.index;
+       if (index < 0 || index >= peasycap->frame_buffer_many)
+               return -EINVAL;
+       memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
+       v4l2_buffer.index = index;
+       v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       v4l2_buffer.bytesused = peasycap->frame_buffer_used;
+       v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \
+                                               peasycap->done[index] | \
+                                               peasycap->queued[index];
+       v4l2_buffer.field = peasycap->field;
+       v4l2_buffer.memory = V4L2_MEMORY_MMAP;
+       v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
+       v4l2_buffer.length = FRAME_BUFFER_SIZE;
+
+       JOT(16, "  %10i=index\n", v4l2_buffer.index);
+       JOT(16, "  0x%08X=type\n", v4l2_buffer.type);
+       JOT(16, "  %10i=bytesused\n", v4l2_buffer.bytesused);
+       JOT(16, "  0x%08X=flags\n", v4l2_buffer.flags);
+       JOT(16, "  %10i=field\n", v4l2_buffer.field);
+       JOT(16, "  %10li=timestamp.tv_usec\n", \
+                                        (long)v4l2_buffer.timestamp.tv_usec);
+       JOT(16, "  %10i=sequence\n", v4l2_buffer.sequence);
+       JOT(16, "  0x%08X=memory\n", v4l2_buffer.memory);
+       JOT(16, "  %10i=m.offset\n", v4l2_buffer.m.offset);
+       JOT(16, "  %10i=length\n", v4l2_buffer.length);
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
+                                       sizeof(struct v4l2_buffer))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_QBUF: {
+       static struct v4l2_buffer v4l2_buffer;
+
+       JOT(8, "VIDIOC_QBUF\n");
+
+       if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
+                                       sizeof(struct v4l2_buffer))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+       if (v4l2_buffer.memory != V4L2_MEMORY_MMAP)
+               return -EINVAL;
+       if (v4l2_buffer.index < 0 || \
+                (v4l2_buffer.index >= peasycap->frame_buffer_many))
+               return -EINVAL;
+       v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
+
+       peasycap->done[v4l2_buffer.index]   = 0;
+       peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
+                                       sizeof(struct v4l2_buffer))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       JOT(8, ".....   user queueing frame buffer %i\n", \
+                                               (int)v4l2_buffer.index);
+
+       peasycap->frame_lock = 0;
+
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_DQBUF:
+       {
+#if defined(AUDIOTIME)
+       static struct signed_div_result sdr;
+       static long long int above, below, dnbydt, fudge, sll;
+       static unsigned long long int ull;
+       static struct timeval timeval0;
+       struct timeval timeval1;
+#endif /*AUDIOTIME*/
+       static struct timeval timeval, timeval2;
+       static int i, j;
+       static struct v4l2_buffer v4l2_buffer;
+
+       JOT(8, "VIDIOC_DQBUF\n");
+
+       if ((peasycap->video_idle) || (peasycap->video_eof)) {
+               JOT(8, "returning -EIO because  " \
+                               "%i=video_idle  %i=video_eof\n", \
+                               peasycap->video_idle, peasycap->video_eof);
+               return -EIO;
+       }
+
+       if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
+                                       sizeof(struct v4l2_buffer))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (!peasycap->video_isoc_streaming) {
+               JOT(16, "returning -EIO because video urbs not streaming\n");
+               return -EIO;
+       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING
+ *  THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE.  IN THIS
+ *  CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
+ */
+/*---------------------------------------------------------------------------*/
+
+       if (!peasycap->polled) {
+               if (-EIO == easycap_dqbuf(peasycap, 0))
+                       return -EIO;
+       } else {
+               if (peasycap->video_eof)
+                       return -EIO;
+       }
+       if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
+               SAY("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
+                                       peasycap->done[peasycap->frame_read]);
+       }
+       peasycap->polled = 0;
+
+       if (!(isequence % 10)) {
+               for (i = 0; i < 179; i++)
+                       peasycap->merit[i] = peasycap->merit[i+1];
+               peasycap->merit[179] = merit_saa(peasycap->pusb_device);
+               j = 0;
+               for (i = 0; i < 180; i++)
+                       j += peasycap->merit[i];
+               if (90 < j) {
+                       SAY("easycap driver shutting down " \
+                                                       "on condition blue\n");
+                       peasycap->video_eof = 1; peasycap->audio_eof = 1;
+               }
+       }
+
+       v4l2_buffer.index = peasycap->frame_read;
+       v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       v4l2_buffer.bytesused = peasycap->frame_buffer_used;
+       v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
+       v4l2_buffer.field =  peasycap->field;
+       if (V4L2_FIELD_ALTERNATE == v4l2_buffer.field)
+               v4l2_buffer.field = \
+                               0x000F & (peasycap->\
+                               frame_buffer[peasycap->frame_read][0].kount);
+       do_gettimeofday(&timeval);
+       timeval2 = timeval;
+
+#if defined(AUDIOTIME)
+       if (!peasycap->timeval0.tv_sec) {
+               timeval0 = timeval;
+               timeval1 = timeval;
+               timeval2 = timeval;
+               dnbydt = 192000;
+
+               if (mutex_lock_interruptible(&(peasycap->mutex_timeval0)))
+                       return -ERESTARTSYS;
+               peasycap->timeval0 = timeval0;
+               mutex_unlock(&(peasycap->mutex_timeval0));
+       } else {
+               if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
+                       return -ERESTARTSYS;
+               dnbydt = peasycap->dnbydt;
+               timeval1 = peasycap->timeval1;
+               mutex_unlock(&(peasycap->mutex_timeval1));
+               above = dnbydt * MICROSECONDS(timeval, timeval1);
+               below = 192000;
+               sdr = signed_div(above, below);
+
+               above = sdr.quotient + timeval1.tv_usec - 350000;
+
+               below = 1000000;
+               sdr = signed_div(above, below);
+               timeval2.tv_usec = sdr.remainder;
+               timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
+       }
+       if (!(isequence % 500)) {
+               fudge = ((long long int)(1000000)) * \
+                               ((long long int)(timeval.tv_sec - \
+                                               timeval2.tv_sec)) + \
+                               (long long int)(timeval.tv_usec - \
+                               timeval2.tv_usec);
+               sdr = signed_div(fudge, 1000);
+               sll = sdr.quotient;
+               ull = sdr.remainder;
+
+               SAY("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
+       }
+#endif /*AUDIOTIME*/
+
+       v4l2_buffer.timestamp = timeval2;
+       v4l2_buffer.sequence = isequence++;
+       v4l2_buffer.memory = V4L2_MEMORY_MMAP;
+       v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
+       v4l2_buffer.length = FRAME_BUFFER_SIZE;
+
+       JOT(16, "  %10i=index\n", v4l2_buffer.index);
+       JOT(16, "  0x%08X=type\n", v4l2_buffer.type);
+       JOT(16, "  %10i=bytesused\n", v4l2_buffer.bytesused);
+       JOT(16, "  0x%08X=flags\n", v4l2_buffer.flags);
+       JOT(16, "  %10i=field\n", v4l2_buffer.field);
+       JOT(16, "  %10li=timestamp.tv_usec\n", \
+                                       (long)v4l2_buffer.timestamp.tv_usec);
+       JOT(16, "  %10i=sequence\n", v4l2_buffer.sequence);
+       JOT(16, "  0x%08X=memory\n", v4l2_buffer.memory);
+       JOT(16, "  %10i=m.offset\n", v4l2_buffer.m.offset);
+       JOT(16, "  %10i=length\n", v4l2_buffer.length);
+
+       if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
+                                               sizeof(struct v4l2_buffer))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       JOT(8, "..... user is offered frame buffer %i\n", \
+                                                       peasycap->frame_read);
+       peasycap->frame_lock = 1;
+       if (peasycap->frame_read == peasycap->frame_fill) {
+               if (peasycap->frame_lock) {
+                       JOT(8, "ERROR:  filling frame buffer " \
+                                               "while offered to user\n");
+               }
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/*---------------------------------------------------------------------------*/
+/*
+ *  AUDIO URBS HAVE ALREADY BEEN SUBMITTED WHEN THIS COMMAND IS RECEIVED;
+ *  VIDEO URBS HAVE NOT.
+ */
+/*---------------------------------------------------------------------------*/
+case VIDIOC_STREAMON: {
+       static int i;
+
+       JOT(8, "VIDIOC_STREAMON\n");
+
+       isequence = 0;
+       for (i = 0; i < 180; i++)
+               peasycap->merit[i] = 0;
+       if ((struct usb_device *)NULL == peasycap->pusb_device) {
+               SAY("ERROR: peasycap->pusb_device is NULL\n");
+               return -EFAULT;
+       }
+       submit_video_urbs(peasycap);
+       peasycap->video_idle = 0;
+       peasycap->audio_idle = 0;
+       peasycap->video_eof = 0;
+       peasycap->audio_eof = 0;
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_STREAMOFF: {
+       JOT(8, "VIDIOC_STREAMOFF\n");
+
+       if ((struct usb_device *)NULL == peasycap->pusb_device) {
+               SAY("ERROR: peasycap->pusb_device is NULL\n");
+               return -EFAULT;
+       }
+
+       peasycap->video_idle = 1;
+       peasycap->audio_idle = 1;  peasycap->timeval0.tv_sec = 0;
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
+ *  THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT.   BEWARE.
+ */
+/*---------------------------------------------------------------------------*/
+       JOT(8, "calling wake_up on wq_video and wq_audio\n");
+       wake_up_interruptible(&(peasycap->wq_video));
+       wake_up_interruptible(&(peasycap->wq_audio));
+/*---------------------------------------------------------------------------*/
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_PARM: {
+       static struct v4l2_streamparm v4l2_streamparm;
+
+       JOT(8, "VIDIOC_G_PARM\n");
+
+       if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \
+                                       sizeof(struct v4l2_streamparm))) {
+               POUT;
+               return -EFAULT;
+       }
+
+       if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+               POUT;
+               return -EINVAL;
+       }
+       v4l2_streamparm.parm.capture.capability = 0;
+       v4l2_streamparm.parm.capture.capturemode = 0;
+       v4l2_streamparm.parm.capture.timeperframe.numerator = 1;
+       v4l2_streamparm.parm.capture.timeperframe.denominator = 30;
+       v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many;
+       v4l2_streamparm.parm.capture.extendedmode = 0;
+       if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \
+                                       sizeof(struct v4l2_streamparm))) {
+               POUT;
+               return -EFAULT;
+       }
+       break;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_S_PARM: {
+       JOT(8, "VIDIOC_S_PARM unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_AUDIO: {
+       JOT(8, "VIDIOC_G_AUDIO unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_S_AUDIO: {
+       JOT(8, "VIDIOC_S_AUDIO unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_S_TUNER: {
+       JOT(8, "VIDIOC_S_TUNER unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_FBUF:
+case VIDIOC_S_FBUF:
+case VIDIOC_OVERLAY: {
+       JOT(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+case VIDIOC_G_TUNER: {
+       JOT(8, "VIDIOC_G_TUNER unsupported\n");
+       return -EINVAL;
+}
+case VIDIOC_G_FREQUENCY:
+case VIDIOC_S_FREQUENCY: {
+       JOT(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
+       return -EINVAL;
+}
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+default: {
+       JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
+       explain_ioctl(cmd);
+       POUT;
+       return -ENOIOCTLCMD;
+}
+}
+return 0;
+}
+/****************************************************************************/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+long
+easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       return easysnd_ioctl((struct inode *)NULL, file, cmd, arg);
+}
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*--------------------------------------------------------------------------*/
+int easysnd_ioctl(struct inode *inode, struct file *file, \
+                                       unsigned int cmd, unsigned long arg)
+{
+struct easycap *peasycap;
+struct usb_device *p;
+
+peasycap = file->private_data;
+if (NULL == peasycap) {
+       SAY("ERROR:  peasycap is NULL.\n");
+       return -1;
+}
+p = peasycap->pusb_device;
+/*---------------------------------------------------------------------------*/
+switch (cmd) {
+case SNDCTL_DSP_GETCAPS: {
+       int caps;
+       JOT(8, "SNDCTL_DSP_GETCAPS\n");
+
+#if defined(UPSAMPLE)
+       if (true == peasycap->microphone)
+               caps = 0x04400000;
+       else
+               caps = 0x04400000;
+#else
+       if (true == peasycap->microphone)
+               caps = 0x02400000;
+       else
+               caps = 0x04400000;
+#endif /*UPSAMPLE*/
+
+       if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int)))
+               return -EFAULT;
+       break;
+}
+case SNDCTL_DSP_GETFMTS: {
+       int incoming;
+       JOT(8, "SNDCTL_DSP_GETFMTS\n");
+
+#if defined(UPSAMPLE)
+       if (true == peasycap->microphone)
+               incoming = AFMT_S16_LE;
+       else
+               incoming = AFMT_S16_LE;
+#else
+       if (true == peasycap->microphone)
+               incoming = AFMT_S16_LE;
+       else
+               incoming = AFMT_S16_LE;
+#endif /*UPSAMPLE*/
+
+       if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+               return -EFAULT;
+       break;
+}
+case SNDCTL_DSP_SETFMT: {
+       int incoming, outgoing;
+       JOT(8, "SNDCTL_DSP_SETFMT\n");
+       if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+               return -EFAULT;
+       JOT(8, "........... %i=incoming\n", incoming);
+
+#if defined(UPSAMPLE)
+       if (true == peasycap->microphone)
+               outgoing = AFMT_S16_LE;
+       else
+               outgoing = AFMT_S16_LE;
+#else
+       if (true == peasycap->microphone)
+               outgoing = AFMT_S16_LE;
+       else
+               outgoing = AFMT_S16_LE;
+#endif /*UPSAMPLE*/
+
+       if (incoming != outgoing) {
+               JOT(8, "........... %i=outgoing\n", outgoing);
+               JOT(8, "        cf. %i=AFMT_S16_LE\n", AFMT_S16_LE);
+               JOT(8, "        cf. %i=AFMT_U8\n", AFMT_U8);
+               if (0 != copy_to_user((void __user *)arg, &outgoing, \
+                                                               sizeof(int)))
+                       return -EFAULT;
+               return -EINVAL ;
+       }
+       break;
+}
+case SNDCTL_DSP_STEREO: {
+       int incoming;
+       JOT(8, "SNDCTL_DSP_STEREO\n");
+       if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+               return -EFAULT;
+       JOT(8, "........... %i=incoming\n", incoming);
+
+#if defined(UPSAMPLE)
+       if (true == peasycap->microphone)
+               incoming = 1;
+       else
+               incoming = 1;
+#else
+       if (true == peasycap->microphone)
+               incoming = 0;
+       else
+               incoming = 1;
+#endif /*UPSAMPLE*/
+
+       if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+               return -EFAULT;
+       break;
+}
+case SNDCTL_DSP_SPEED: {
+       int incoming;
+       JOT(8, "SNDCTL_DSP_SPEED\n");
+       if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+               return -EFAULT;
+       JOT(8, "........... %i=incoming\n", incoming);
+
+#if defined(UPSAMPLE)
+       if (true == peasycap->microphone)
+               incoming = 32000;
+       else
+               incoming = 48000;
+#else
+       if (true == peasycap->microphone)
+               incoming = 8000;
+       else
+               incoming = 48000;
+#endif /*UPSAMPLE*/
+
+       if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+               return -EFAULT;
+       break;
+}
+case SNDCTL_DSP_GETTRIGGER: {
+       int incoming;
+       JOT(8, "SNDCTL_DSP_GETTRIGGER\n");
+       if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+               return -EFAULT;
+       JOT(8, "........... %i=incoming\n", incoming);
+
+       incoming = PCM_ENABLE_INPUT;
+       if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+               return -EFAULT;
+       break;
+}
+case SNDCTL_DSP_SETTRIGGER: {
+       int incoming;
+       JOT(8, "SNDCTL_DSP_SETTRIGGER\n");
+       if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+               return -EFAULT;
+       JOT(8, "........... %i=incoming\n", incoming);
+       JOT(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \
+                               "0x%x=PCM_ENABLE_OUTPUT\n", \
+                                       PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT);
+       ;
+       ;
+       ;
+       ;
+       break;
+}
+case SNDCTL_DSP_GETBLKSIZE: {
+       int incoming;
+       JOT(8, "SNDCTL_DSP_GETBLKSIZE\n");
+       if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+               return -EFAULT;
+       JOT(8, "........... %i=incoming\n", incoming);
+       incoming = peasycap->audio_bytes_per_fragment;
+       if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+               return -EFAULT;
+       break;
+}
+case SNDCTL_DSP_GETISPACE: {
+       struct audio_buf_info audio_buf_info;
+
+       JOT(8, "SNDCTL_DSP_GETISPACE\n");
+
+       audio_buf_info.bytes      = peasycap->audio_bytes_per_fragment;
+       audio_buf_info.fragments  = 1;
+       audio_buf_info.fragsize   = 0;
+       audio_buf_info.fragstotal = 0;
+
+       if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \
+                                                               sizeof(int)))
+               return -EFAULT;
+       break;
+}
+default: {
+       JOT(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
+       POUT;
+       return -ENOIOCTLCMD;
+}
+}
+return 0;
+}
+/*****************************************************************************/
+int explain_ioctl(__u32 wot)
+{
+int k;
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
+ *  SHELL SCRIPT:
+ *  #
+ *  cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \
+ *     grep "^#define VIDIOC_" - | grep -v "_OLD" - | \
+ *     sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \
+ *     sed -e "s/^#define /  {/;s/#define /, \"/;s/$/\"},/" | \
+ *     sed -e "s,      ,,g;s, ,,g" >ioctl.tmp
+ *  echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp
+ *  exit 0
+ *  #
+ * AND REINSTATING THE EXCISED "_OLD" CASES WERE LATER MANUALLY.
+ *
+ * THE DATA FOR THE ARRAY mess1 BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
+ * SHELL SCRIPT:
+ *  cat /usr/src/linux-headers-`uname -r`/include/linux/videodev.h | \
+ *     grep "^#define VIDIOC" - | grep -v "_OLD" - | \
+ *     sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \
+ *     sed -e "s/^#define /  {/;s/#define /, \"/;s/$/\"},/" | \
+ *     sed -e "s,   ,,g;s, ,,g" >ioctl.tmp
+ *  echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp
+ *  exit 0
+ *  #
+ */
+/*---------------------------------------------------------------------------*/
+static struct mess {
+       __u32 command;
+       char  name[64];
+} mess[] = {
+#if defined(VIDIOC_QUERYCAP)
+{VIDIOC_QUERYCAP, "VIDIOC_QUERYCAP"},
+#endif
+#if defined(VIDIOC_RESERVED)
+{VIDIOC_RESERVED, "VIDIOC_RESERVED"},
+#endif
+#if defined(VIDIOC_ENUM_FMT)
+{VIDIOC_ENUM_FMT, "VIDIOC_ENUM_FMT"},
+#endif
+#if defined(VIDIOC_G_FMT)
+{VIDIOC_G_FMT, "VIDIOC_G_FMT"},
+#endif
+#if defined(VIDIOC_S_FMT)
+{VIDIOC_S_FMT, "VIDIOC_S_FMT"},
+#endif
+#if defined(VIDIOC_REQBUFS)
+{VIDIOC_REQBUFS, "VIDIOC_REQBUFS"},
+#endif
+#if defined(VIDIOC_QUERYBUF)
+{VIDIOC_QUERYBUF, "VIDIOC_QUERYBUF"},
+#endif
+#if defined(VIDIOC_G_FBUF)
+{VIDIOC_G_FBUF, "VIDIOC_G_FBUF"},
+#endif
+#if defined(VIDIOC_S_FBUF)
+{VIDIOC_S_FBUF, "VIDIOC_S_FBUF"},
+#endif
+#if defined(VIDIOC_OVERLAY)
+{VIDIOC_OVERLAY, "VIDIOC_OVERLAY"},
+#endif
+#if defined(VIDIOC_QBUF)
+{VIDIOC_QBUF, "VIDIOC_QBUF"},
+#endif
+#if defined(VIDIOC_DQBUF)
+{VIDIOC_DQBUF, "VIDIOC_DQBUF"},
+#endif
+#if defined(VIDIOC_STREAMON)
+{VIDIOC_STREAMON, "VIDIOC_STREAMON"},
+#endif
+#if defined(VIDIOC_STREAMOFF)
+{VIDIOC_STREAMOFF, "VIDIOC_STREAMOFF"},
+#endif
+#if defined(VIDIOC_G_PARM)
+{VIDIOC_G_PARM, "VIDIOC_G_PARM"},
+#endif
+#if defined(VIDIOC_S_PARM)
+{VIDIOC_S_PARM, "VIDIOC_S_PARM"},
+#endif
+#if defined(VIDIOC_G_STD)
+{VIDIOC_G_STD, "VIDIOC_G_STD"},
+#endif
+#if defined(VIDIOC_S_STD)
+{VIDIOC_S_STD, "VIDIOC_S_STD"},
+#endif
+#if defined(VIDIOC_ENUMSTD)
+{VIDIOC_ENUMSTD, "VIDIOC_ENUMSTD"},
+#endif
+#if defined(VIDIOC_ENUMINPUT)
+{VIDIOC_ENUMINPUT, "VIDIOC_ENUMINPUT"},
+#endif
+#if defined(VIDIOC_G_CTRL)
+{VIDIOC_G_CTRL, "VIDIOC_G_CTRL"},
+#endif
+#if defined(VIDIOC_S_CTRL)
+{VIDIOC_S_CTRL, "VIDIOC_S_CTRL"},
+#endif
+#if defined(VIDIOC_G_TUNER)
+{VIDIOC_G_TUNER, "VIDIOC_G_TUNER"},
+#endif
+#if defined(VIDIOC_S_TUNER)
+{VIDIOC_S_TUNER, "VIDIOC_S_TUNER"},
+#endif
+#if defined(VIDIOC_G_AUDIO)
+{VIDIOC_G_AUDIO, "VIDIOC_G_AUDIO"},
+#endif
+#if defined(VIDIOC_S_AUDIO)
+{VIDIOC_S_AUDIO, "VIDIOC_S_AUDIO"},
+#endif
+#if defined(VIDIOC_QUERYCTRL)
+{VIDIOC_QUERYCTRL, "VIDIOC_QUERYCTRL"},
+#endif
+#if defined(VIDIOC_QUERYMENU)
+{VIDIOC_QUERYMENU, "VIDIOC_QUERYMENU"},
+#endif
+#if defined(VIDIOC_G_INPUT)
+{VIDIOC_G_INPUT, "VIDIOC_G_INPUT"},
+#endif
+#if defined(VIDIOC_S_INPUT)
+{VIDIOC_S_INPUT, "VIDIOC_S_INPUT"},
+#endif
+#if defined(VIDIOC_G_OUTPUT)
+{VIDIOC_G_OUTPUT, "VIDIOC_G_OUTPUT"},
+#endif
+#if defined(VIDIOC_S_OUTPUT)
+{VIDIOC_S_OUTPUT, "VIDIOC_S_OUTPUT"},
+#endif
+#if defined(VIDIOC_ENUMOUTPUT)
+{VIDIOC_ENUMOUTPUT, "VIDIOC_ENUMOUTPUT"},
+#endif
+#if defined(VIDIOC_G_AUDOUT)
+{VIDIOC_G_AUDOUT, "VIDIOC_G_AUDOUT"},
+#endif
+#if defined(VIDIOC_S_AUDOUT)
+{VIDIOC_S_AUDOUT, "VIDIOC_S_AUDOUT"},
+#endif
+#if defined(VIDIOC_G_MODULATOR)
+{VIDIOC_G_MODULATOR, "VIDIOC_G_MODULATOR"},
+#endif
+#if defined(VIDIOC_S_MODULATOR)
+{VIDIOC_S_MODULATOR, "VIDIOC_S_MODULATOR"},
+#endif
+#if defined(VIDIOC_G_FREQUENCY)
+{VIDIOC_G_FREQUENCY, "VIDIOC_G_FREQUENCY"},
+#endif
+#if defined(VIDIOC_S_FREQUENCY)
+{VIDIOC_S_FREQUENCY, "VIDIOC_S_FREQUENCY"},
+#endif
+#if defined(VIDIOC_CROPCAP)
+{VIDIOC_CROPCAP, "VIDIOC_CROPCAP"},
+#endif
+#if defined(VIDIOC_G_CROP)
+{VIDIOC_G_CROP, "VIDIOC_G_CROP"},
+#endif
+#if defined(VIDIOC_S_CROP)
+{VIDIOC_S_CROP, "VIDIOC_S_CROP"},
+#endif
+#if defined(VIDIOC_G_JPEGCOMP)
+{VIDIOC_G_JPEGCOMP, "VIDIOC_G_JPEGCOMP"},
+#endif
+#if defined(VIDIOC_S_JPEGCOMP)
+{VIDIOC_S_JPEGCOMP, "VIDIOC_S_JPEGCOMP"},
+#endif
+#if defined(VIDIOC_QUERYSTD)
+{VIDIOC_QUERYSTD, "VIDIOC_QUERYSTD"},
+#endif
+#if defined(VIDIOC_TRY_FMT)
+{VIDIOC_TRY_FMT, "VIDIOC_TRY_FMT"},
+#endif
+#if defined(VIDIOC_ENUMAUDIO)
+{VIDIOC_ENUMAUDIO, "VIDIOC_ENUMAUDIO"},
+#endif
+#if defined(VIDIOC_ENUMAUDOUT)
+{VIDIOC_ENUMAUDOUT, "VIDIOC_ENUMAUDOUT"},
+#endif
+#if defined(VIDIOC_G_PRIORITY)
+{VIDIOC_G_PRIORITY, "VIDIOC_G_PRIORITY"},
+#endif
+#if defined(VIDIOC_S_PRIORITY)
+{VIDIOC_S_PRIORITY, "VIDIOC_S_PRIORITY"},
+#endif
+#if defined(VIDIOC_G_SLICED_VBI_CAP)
+{VIDIOC_G_SLICED_VBI_CAP, "VIDIOC_G_SLICED_VBI_CAP"},
+#endif
+#if defined(VIDIOC_LOG_STATUS)
+{VIDIOC_LOG_STATUS, "VIDIOC_LOG_STATUS"},
+#endif
+#if defined(VIDIOC_G_EXT_CTRLS)
+{VIDIOC_G_EXT_CTRLS, "VIDIOC_G_EXT_CTRLS"},
+#endif
+#if defined(VIDIOC_S_EXT_CTRLS)
+{VIDIOC_S_EXT_CTRLS, "VIDIOC_S_EXT_CTRLS"},
+#endif
+#if defined(VIDIOC_TRY_EXT_CTRLS)
+{VIDIOC_TRY_EXT_CTRLS, "VIDIOC_TRY_EXT_CTRLS"},
+#endif
+#if defined(VIDIOC_ENUM_FRAMESIZES)
+{VIDIOC_ENUM_FRAMESIZES, "VIDIOC_ENUM_FRAMESIZES"},
+#endif
+#if defined(VIDIOC_ENUM_FRAMEINTERVALS)
+{VIDIOC_ENUM_FRAMEINTERVALS, "VIDIOC_ENUM_FRAMEINTERVALS"},
+#endif
+#if defined(VIDIOC_G_ENC_INDEX)
+{VIDIOC_G_ENC_INDEX, "VIDIOC_G_ENC_INDEX"},
+#endif
+#if defined(VIDIOC_ENCODER_CMD)
+{VIDIOC_ENCODER_CMD, "VIDIOC_ENCODER_CMD"},
+#endif
+#if defined(VIDIOC_TRY_ENCODER_CMD)
+{VIDIOC_TRY_ENCODER_CMD, "VIDIOC_TRY_ENCODER_CMD"},
+#endif
+#if defined(VIDIOC_G_CHIP_IDENT)
+{VIDIOC_G_CHIP_IDENT, "VIDIOC_G_CHIP_IDENT"},
+#endif
+
+#if defined(VIDIOC_OVERLAY_OLD)
+{VIDIOC_OVERLAY_OLD, "VIDIOC_OVERLAY_OLD"},
+#endif
+#if defined(VIDIOC_S_PARM_OLD)
+{VIDIOC_S_PARM_OLD, "VIDIOC_S_PARM_OLD"},
+#endif
+#if defined(VIDIOC_S_CTRL_OLD)
+{VIDIOC_S_CTRL_OLD, "VIDIOC_S_CTRL_OLD"},
+#endif
+#if defined(VIDIOC_G_AUDIO_OLD)
+{VIDIOC_G_AUDIO_OLD, "VIDIOC_G_AUDIO_OLD"},
+#endif
+#if defined(VIDIOC_G_AUDOUT_OLD)
+{VIDIOC_G_AUDOUT_OLD, "VIDIOC_G_AUDOUT_OLD"},
+#endif
+#if defined(VIDIOC_CROPCAP_OLD)
+{VIDIOC_CROPCAP_OLD, "VIDIOC_CROPCAP_OLD"},
+#endif
+{0xFFFFFFFF, ""}
+};
+
+static struct mess mess1[] = \
+{
+#if defined(VIDIOCGCAP)
+{VIDIOCGCAP, "VIDIOCGCAP"},
+#endif
+#if defined(VIDIOCGCHAN)
+{VIDIOCGCHAN, "VIDIOCGCHAN"},
+#endif
+#if defined(VIDIOCSCHAN)
+{VIDIOCSCHAN, "VIDIOCSCHAN"},
+#endif
+#if defined(VIDIOCGTUNER)
+{VIDIOCGTUNER, "VIDIOCGTUNER"},
+#endif
+#if defined(VIDIOCSTUNER)
+{VIDIOCSTUNER, "VIDIOCSTUNER"},
+#endif
+#if defined(VIDIOCGPICT)
+{VIDIOCGPICT, "VIDIOCGPICT"},
+#endif
+#if defined(VIDIOCSPICT)
+{VIDIOCSPICT, "VIDIOCSPICT"},
+#endif
+#if defined(VIDIOCCAPTURE)
+{VIDIOCCAPTURE, "VIDIOCCAPTURE"},
+#endif
+#if defined(VIDIOCGWIN)
+{VIDIOCGWIN, "VIDIOCGWIN"},
+#endif
+#if defined(VIDIOCSWIN)
+{VIDIOCSWIN, "VIDIOCSWIN"},
+#endif
+#if defined(VIDIOCGFBUF)
+{VIDIOCGFBUF, "VIDIOCGFBUF"},
+#endif
+#if defined(VIDIOCSFBUF)
+{VIDIOCSFBUF, "VIDIOCSFBUF"},
+#endif
+#if defined(VIDIOCKEY)
+{VIDIOCKEY, "VIDIOCKEY"},
+#endif
+#if defined(VIDIOCGFREQ)
+{VIDIOCGFREQ, "VIDIOCGFREQ"},
+#endif
+#if defined(VIDIOCSFREQ)
+{VIDIOCSFREQ, "VIDIOCSFREQ"},
+#endif
+#if defined(VIDIOCGAUDIO)
+{VIDIOCGAUDIO, "VIDIOCGAUDIO"},
+#endif
+#if defined(VIDIOCSAUDIO)
+{VIDIOCSAUDIO, "VIDIOCSAUDIO"},
+#endif
+#if defined(VIDIOCSYNC)
+{VIDIOCSYNC, "VIDIOCSYNC"},
+#endif
+#if defined(VIDIOCMCAPTURE)
+{VIDIOCMCAPTURE, "VIDIOCMCAPTURE"},
+#endif
+#if defined(VIDIOCGMBUF)
+{VIDIOCGMBUF, "VIDIOCGMBUF"},
+#endif
+#if defined(VIDIOCGUNIT)
+{VIDIOCGUNIT, "VIDIOCGUNIT"},
+#endif
+#if defined(VIDIOCGCAPTURE)
+{VIDIOCGCAPTURE, "VIDIOCGCAPTURE"},
+#endif
+#if defined(VIDIOCSCAPTURE)
+{VIDIOCSCAPTURE, "VIDIOCSCAPTURE"},
+#endif
+#if defined(VIDIOCSPLAYMODE)
+{VIDIOCSPLAYMODE, "VIDIOCSPLAYMODE"},
+#endif
+#if defined(VIDIOCSWRITEMODE)
+{VIDIOCSWRITEMODE, "VIDIOCSWRITEMODE"},
+#endif
+#if defined(VIDIOCGPLAYINFO)
+{VIDIOCGPLAYINFO, "VIDIOCGPLAYINFO"},
+#endif
+#if defined(VIDIOCSMICROCODE)
+{VIDIOCSMICROCODE, "VIDIOCSMICROCODE"},
+#endif
+{0xFFFFFFFF, ""}
+};
+
+k = 0;
+while (mess[k].name[0]) {
+       if (wot == mess[k].command) {
+               JOT(8, "ioctl 0x%08X is %s\n", \
+                                       mess[k].command, &mess[k].name[0]);
+               return 0;
+       }
+       k++;
+}
+JOT(8, "ioctl 0x%08X is not in videodev2.h\n", wot);
+
+k = 0;
+while (mess1[k].name[0]) {
+       if (wot == mess1[k].command) {
+               JOT(8, "ioctl 0x%08X is %s (V4L1)\n", \
+                                       mess1[k].command, &mess1[k].name[0]);
+               return 0;
+       }
+       k++;
+}
+JOT(8, "ioctl 0x%08X is not in videodev.h\n", wot);
+return -1;
+}
+/*****************************************************************************/
+int explain_cid(__u32 wot)
+{
+int k;
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
+ *  SHELL SCRIPT:
+ *  #
+ *  cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \
+ *     grep "^#define V4L2_CID_" |  \
+ *     sed -e "s,(.*$,,;p" | sed -e "N;s,\n,, " | \
+ *     sed -e "s/^#define /  {/;s/#define /, \"/;s/$/\"},/" | \
+ *     sed -e "s,      ,,g;s, ,,g" | grep -v "_BASE" | grep -v "MPEG" >cid.tmp
+ *  echo "{0xFFFFFFFF,\"\"}" >>cid.tmp
+ *  exit 0
+ *  #
+ */
+/*---------------------------------------------------------------------------*/
+static struct mess
+{
+__u32 command;
+char  name[64];
+} mess[] = {
+#if defined(V4L2_CID_USER_CLASS)
+{V4L2_CID_USER_CLASS, "V4L2_CID_USER_CLASS"},
+#endif
+#if defined(V4L2_CID_BRIGHTNESS)
+{V4L2_CID_BRIGHTNESS, "V4L2_CID_BRIGHTNESS"},
+#endif
+#if defined(V4L2_CID_CONTRAST)
+{V4L2_CID_CONTRAST, "V4L2_CID_CONTRAST"},
+#endif
+#if defined(V4L2_CID_SATURATION)
+{V4L2_CID_SATURATION, "V4L2_CID_SATURATION"},
+#endif
+#if defined(V4L2_CID_HUE)
+{V4L2_CID_HUE, "V4L2_CID_HUE"},
+#endif
+#if defined(V4L2_CID_AUDIO_VOLUME)
+{V4L2_CID_AUDIO_VOLUME, "V4L2_CID_AUDIO_VOLUME"},
+#endif
+#if defined(V4L2_CID_AUDIO_BALANCE)
+{V4L2_CID_AUDIO_BALANCE, "V4L2_CID_AUDIO_BALANCE"},
+#endif
+#if defined(V4L2_CID_AUDIO_BASS)
+{V4L2_CID_AUDIO_BASS, "V4L2_CID_AUDIO_BASS"},
+#endif
+#if defined(V4L2_CID_AUDIO_TREBLE)
+{V4L2_CID_AUDIO_TREBLE, "V4L2_CID_AUDIO_TREBLE"},
+#endif
+#if defined(V4L2_CID_AUDIO_MUTE)
+{V4L2_CID_AUDIO_MUTE, "V4L2_CID_AUDIO_MUTE"},
+#endif
+#if defined(V4L2_CID_AUDIO_LOUDNESS)
+{V4L2_CID_AUDIO_LOUDNESS, "V4L2_CID_AUDIO_LOUDNESS"},
+#endif
+#if defined(V4L2_CID_BLACK_LEVEL)
+{V4L2_CID_BLACK_LEVEL, "V4L2_CID_BLACK_LEVEL"},
+#endif
+#if defined(V4L2_CID_AUTO_WHITE_BALANCE)
+{V4L2_CID_AUTO_WHITE_BALANCE, "V4L2_CID_AUTO_WHITE_BALANCE"},
+#endif
+#if defined(V4L2_CID_DO_WHITE_BALANCE)
+{V4L2_CID_DO_WHITE_BALANCE, "V4L2_CID_DO_WHITE_BALANCE"},
+#endif
+#if defined(V4L2_CID_RED_BALANCE)
+{V4L2_CID_RED_BALANCE, "V4L2_CID_RED_BALANCE"},
+#endif
+#if defined(V4L2_CID_BLUE_BALANCE)
+{V4L2_CID_BLUE_BALANCE, "V4L2_CID_BLUE_BALANCE"},
+#endif
+#if defined(V4L2_CID_GAMMA)
+{V4L2_CID_GAMMA, "V4L2_CID_GAMMA"},
+#endif
+#if defined(V4L2_CID_WHITENESS)
+{V4L2_CID_WHITENESS, "V4L2_CID_WHITENESS"},
+#endif
+#if defined(V4L2_CID_EXPOSURE)
+{V4L2_CID_EXPOSURE, "V4L2_CID_EXPOSURE"},
+#endif
+#if defined(V4L2_CID_AUTOGAIN)
+{V4L2_CID_AUTOGAIN, "V4L2_CID_AUTOGAIN"},
+#endif
+#if defined(V4L2_CID_GAIN)
+{V4L2_CID_GAIN, "V4L2_CID_GAIN"},
+#endif
+#if defined(V4L2_CID_HFLIP)
+{V4L2_CID_HFLIP, "V4L2_CID_HFLIP"},
+#endif
+#if defined(V4L2_CID_VFLIP)
+{V4L2_CID_VFLIP, "V4L2_CID_VFLIP"},
+#endif
+#if defined(V4L2_CID_HCENTER)
+{V4L2_CID_HCENTER, "V4L2_CID_HCENTER"},
+#endif
+#if defined(V4L2_CID_VCENTER)
+{V4L2_CID_VCENTER, "V4L2_CID_VCENTER"},
+#endif
+#if defined(V4L2_CID_POWER_LINE_FREQUENCY)
+{V4L2_CID_POWER_LINE_FREQUENCY, "V4L2_CID_POWER_LINE_FREQUENCY"},
+#endif
+#if defined(V4L2_CID_HUE_AUTO)
+{V4L2_CID_HUE_AUTO, "V4L2_CID_HUE_AUTO"},
+#endif
+#if defined(V4L2_CID_WHITE_BALANCE_TEMPERATURE)
+{V4L2_CID_WHITE_BALANCE_TEMPERATURE, "V4L2_CID_WHITE_BALANCE_TEMPERATURE"},
+#endif
+#if defined(V4L2_CID_SHARPNESS)
+{V4L2_CID_SHARPNESS, "V4L2_CID_SHARPNESS"},
+#endif
+#if defined(V4L2_CID_BACKLIGHT_COMPENSATION)
+{V4L2_CID_BACKLIGHT_COMPENSATION, "V4L2_CID_BACKLIGHT_COMPENSATION"},
+#endif
+#if defined(V4L2_CID_CHROMA_AGC)
+{V4L2_CID_CHROMA_AGC, "V4L2_CID_CHROMA_AGC"},
+#endif
+#if defined(V4L2_CID_COLOR_KILLER)
+{V4L2_CID_COLOR_KILLER, "V4L2_CID_COLOR_KILLER"},
+#endif
+#if defined(V4L2_CID_LASTP1)
+{V4L2_CID_LASTP1, "V4L2_CID_LASTP1"},
+#endif
+#if defined(V4L2_CID_CAMERA_CLASS)
+{V4L2_CID_CAMERA_CLASS, "V4L2_CID_CAMERA_CLASS"},
+#endif
+#if defined(V4L2_CID_EXPOSURE_AUTO)
+{V4L2_CID_EXPOSURE_AUTO, "V4L2_CID_EXPOSURE_AUTO"},
+#endif
+#if defined(V4L2_CID_EXPOSURE_ABSOLUTE)
+{V4L2_CID_EXPOSURE_ABSOLUTE, "V4L2_CID_EXPOSURE_ABSOLUTE"},
+#endif
+#if defined(V4L2_CID_EXPOSURE_AUTO_PRIORITY)
+{V4L2_CID_EXPOSURE_AUTO_PRIORITY, "V4L2_CID_EXPOSURE_AUTO_PRIORITY"},
+#endif
+#if defined(V4L2_CID_PAN_RELATIVE)
+{V4L2_CID_PAN_RELATIVE, "V4L2_CID_PAN_RELATIVE"},
+#endif
+#if defined(V4L2_CID_TILT_RELATIVE)
+{V4L2_CID_TILT_RELATIVE, "V4L2_CID_TILT_RELATIVE"},
+#endif
+#if defined(V4L2_CID_PAN_RESET)
+{V4L2_CID_PAN_RESET, "V4L2_CID_PAN_RESET"},
+#endif
+#if defined(V4L2_CID_TILT_RESET)
+{V4L2_CID_TILT_RESET, "V4L2_CID_TILT_RESET"},
+#endif
+#if defined(V4L2_CID_PAN_ABSOLUTE)
+{V4L2_CID_PAN_ABSOLUTE, "V4L2_CID_PAN_ABSOLUTE"},
+#endif
+#if defined(V4L2_CID_TILT_ABSOLUTE)
+{V4L2_CID_TILT_ABSOLUTE, "V4L2_CID_TILT_ABSOLUTE"},
+#endif
+#if defined(V4L2_CID_FOCUS_ABSOLUTE)
+{V4L2_CID_FOCUS_ABSOLUTE, "V4L2_CID_FOCUS_ABSOLUTE"},
+#endif
+#if defined(V4L2_CID_FOCUS_RELATIVE)
+{V4L2_CID_FOCUS_RELATIVE, "V4L2_CID_FOCUS_RELATIVE"},
+#endif
+#if defined(V4L2_CID_FOCUS_AUTO)
+{V4L2_CID_FOCUS_AUTO, "V4L2_CID_FOCUS_AUTO"},
+#endif
+{0xFFFFFFFF, ""}
+};
+
+k = 0;
+while (mess[k].name[0]) {
+       if (wot == mess[k].command) {
+               JOT(8, "ioctl 0x%08X is %s\n", \
+                                       mess[k].command, &mess[k].name[0]);
+               return 0;
+       }
+       k++;
+}
+JOT(8, "cid 0x%08X is not in videodev2.h\n", wot);
+return -1;
+}
+/*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_ioctl.h b/drivers/staging/easycap/easycap_ioctl.h
new file mode 100644 (file)
index 0000000..210cd62
--- /dev/null
@@ -0,0 +1,28 @@
+/*****************************************************************************
+*                                                                            *
+*  easycap_ioctl.h                                                           *
+*                                                                            *
+*****************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+extern struct easycap_format easycap_format[];
+extern struct v4l2_queryctrl easycap_control[];
diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c
new file mode 100644 (file)
index 0000000..ad1fc4c
--- /dev/null
@@ -0,0 +1,1041 @@
+/*****************************************************************************
+*                                                                            *
+*                                                                            *
+*  easycap_low.c                                                             *
+*                                                                            *
+*                                                                            *
+*****************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+/*
+ *  ACKNOWLEGEMENTS AND REFERENCES
+ *  ------------------------------
+ *  This driver makes use of register information contained in the Syntek
+ *  Semicon DC-1125 driver hosted at
+ *               http://sourceforge.net/projects/syntekdriver/.
+ *  Particularly useful has been a patch to the latter driver provided by
+ *  Ivor Hewitt in January 2009.  The NTSC implementation is taken from the
+ *  work of Ben Trask.
+*/
+/****************************************************************************/
+
+#include "easycap_debug.h"
+#include "easycap.h"
+
+/*--------------------------------------------------------------------------*/
+const struct stk1160config { int reg; int set; } stk1160config[256] = {
+       {0x000, 0x0098},
+       {0x002, 0x0093},
+
+       {0x001, 0x0003},
+       {0x003, 0x0080},
+       {0x00D, 0x0000},
+       {0x00F, 0x0002},
+       {0x018, 0x0010},
+       {0x019, 0x0000},
+       {0x01A, 0x0014},
+       {0x01B, 0x000E},
+       {0x01C, 0x0046},
+
+       {0x100, 0x0033},
+       {0x103, 0x0000},
+       {0x104, 0x0000},
+       {0x105, 0x0000},
+       {0x106, 0x0000},
+
+#if defined(PREFER_NTSC)
+
+#undef  OLDMARGIN
+#if defined(OLDMARGIN)
+       {0x110, 0x0008},
+#else
+       {0x110, 0x0014},
+#endif /*OLDMARGIN*/
+
+       {0x111, 0x0000},
+       {0x112, 0x0003},
+       {0x113, 0x0000},
+
+#if defined(OLDMARGIN)
+       {0x114, 0x0508},
+#else
+       {0x114, 0x0514},
+#endif /*OLDMARGIN*/
+
+       {0x115, 0x0005},
+       {0x116, 0x00F3},
+       {0x117, 0x0000},
+
+#else /* ! PREFER_NTSC*/
+
+#if defined(OLDMARGIN)
+       {0x110, 0x0008},
+#else
+       {0x110, 0x0014},
+#endif /*OLDMARGIN*/
+
+       {0x111, 0x0000},
+       {0x112, 0x0020},
+       {0x113, 0x0000},
+
+#if defined(OLDMARGIN)
+       {0x114, 0x0508},
+#else
+       {0x114, 0x0514},
+#endif /*OLDMARGIN*/
+
+       {0x115, 0x0005},
+       {0x116, 0x0110},
+       {0x117, 0x0001},
+
+#endif /* ! PREFER_NTSC*/
+
+       {0x202, 0x000F},
+       {0x203, 0x004A},
+       {0x2FF, 0x0000},
+/*---------------------------------------------------------------------------*/
+       {0xFFF, 0xFFFF}
+       };
+/*--------------------------------------------------------------------------*/
+const struct saa7113config { int reg; int set; } saa7113config[256] = {
+       {0x01, 0x08},
+       {0x02, 0x80},
+       {0x03, 0x33},
+       {0x04, 0x00},
+       {0x05, 0x00},
+       {0x06, 0xE9},
+       {0x07, 0x0D},
+#if defined(PREFER_NTSC)
+       {0x08, 0x78},
+#else
+       {0x08, 0x38},
+#endif /* ! PREFER_NTSC*/
+       {0x09, 0x00},
+       {0x0A, SAA_0A_DEFAULT},
+       {0x0B, SAA_0B_DEFAULT},
+       {0x0C, SAA_0C_DEFAULT},
+       {0x0D, SAA_0D_DEFAULT},
+       {0x0E, 0x01},
+       {0x0F, 0x36},
+       {0x10, 0x00},
+       {0x11, 0x0C},
+       {0x12, 0xE7},
+       {0x13, 0x00},
+       {0x15, 0x00},
+       {0x16, 0x00},
+#if defined(PREFER_NTSC)
+       {0x40, 0x82},
+#else
+       {0x40, 0x02},
+#endif /* ! PREFER_NTSC*/
+       {0x41, 0xFF},
+       {0x42, 0xFF},
+       {0x43, 0xFF},
+       {0x44, 0xFF},
+       {0x45, 0xFF},
+       {0x46, 0xFF},
+       {0x47, 0xFF},
+       {0x48, 0xFF},
+       {0x49, 0xFF},
+       {0x4A, 0xFF},
+       {0x4B, 0xFF},
+       {0x4C, 0xFF},
+       {0x4D, 0xFF},
+       {0x4E, 0xFF},
+       {0x4F, 0xFF},
+       {0x50, 0xFF},
+       {0x51, 0xFF},
+       {0x52, 0xFF},
+       {0x53, 0xFF},
+       {0x54, 0xFF},
+       {0x55, 0xFF},
+       {0x56, 0xFF},
+       {0x57, 0xFF},
+       {0x58, 0x40},
+       {0x59, 0x54},
+#if defined(PREFER_NTSC)
+       {0x5A, 0x0A},
+#else
+       {0x5A, 0x07},
+#endif /* ! PREFER_NTSC*/
+       {0x5B, 0x83},
+       {0xFF, 0xFF}
+       };
+/*--------------------------------------------------------------------------*/
+
+/****************************************************************************/
+int
+confirm_resolution(struct usb_device *p)
+{
+__u8 get0, get1, get2, get3, get4, get5, get6, get7;
+GET(p, 0x0110, &get0);
+GET(p, 0x0111, &get1);
+GET(p, 0x0112, &get2);
+GET(p, 0x0113, &get3);
+GET(p, 0x0114, &get4);
+GET(p, 0x0115, &get5);
+GET(p, 0x0116, &get6);
+GET(p, 0x0117, &get7);
+JOT(8,  "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X\n", \
+       get0, get1, get2, get3, get4, get5, get6, get7);
+JOT(8,  "....cf PAL_720x526: " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X\n", \
+       0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001);
+JOT(8,  "....cf PAL_704x526: " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X\n", \
+       0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001);
+JOT(8,  "....cf VGA_640x480: " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X, " \
+       "0x%03X, 0x%03X\n", \
+       0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001);
+return 0;
+}
+/****************************************************************************/
+int
+confirm_stream(struct usb_device *p)
+{
+__u16 get2;
+__u8 igot;
+
+GET(p, 0x0100, &igot);  get2 = 0x80 & igot;
+if (0x80 == get2)
+       JOT(8, "confirm_stream:  OK\n");
+else
+       JOT(8, "confirm_stream:  STUCK\n");
+return 0;
+}
+/****************************************************************************/
+int
+setup_stk(struct usb_device *p)
+{
+int i0;
+
+i0 = 0;
+while (0xFFF != stk1160config[i0].reg) {
+       SET(p, stk1160config[i0].reg, stk1160config[i0].set);
+       i0++;
+       }
+
+write_300(p);
+
+return 0;
+}
+/****************************************************************************/
+int
+setup_saa(struct usb_device *p)
+{
+int i0, ir;
+
+
+set2to78(p);
+
+
+i0 = 0;
+while (0xFF != saa7113config[i0].reg) {
+       ir = write_saa(p, saa7113config[i0].reg, saa7113config[i0].set);
+       i0++;
+       }
+return 0;
+}
+/****************************************************************************/
+int
+write_000(struct usb_device *p, __u16 set2, __u16 set0)
+{
+__u8 igot0, igot2;
+
+GET(p, 0x0002, &igot2);
+GET(p, 0x0000, &igot0);
+SET(p, 0x0002, set2);
+SET(p, 0x0000, set0);
+return 0;
+}
+/****************************************************************************/
+int
+write_saa(struct usb_device *p, __u16 reg0, __u16 set0)
+{
+SET(p, 0x200, 0x00);
+SET(p, 0x204, reg0);
+SET(p, 0x205, set0);
+SET(p, 0x200, 0x01);
+return wait_i2c(p);
+}
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
+ *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
+ *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO SET
+ *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO SET
+ *  REGISTER 504:  TARGET ADDRESS ON VT1612A
+ */
+/*--------------------------------------------------------------------------*/
+int
+write_vt(struct usb_device *p, __u16 reg0, __u16 set0)
+{
+__u8 igot;
+__u16 got502, got503;
+__u16 set502, set503;
+
+SET(p, 0x0504, reg0);
+SET(p, 0x0500, 0x008B);
+
+GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
+GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
+
+JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", \
+                                       reg0, set0, ((got503 << 8) | got502));
+
+set502 =  (0x00FF & set0);
+set503 = ((0xFF00 & set0) >> 8);
+
+SET(p, 0x0504, reg0);
+SET(p, 0x0502, set502);
+SET(p, 0x0503, set503);
+SET(p, 0x0500, 0x008C);
+
+return 0;
+}
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  REGISTER 500:  SETTING VALUE TO 0x008B READS FROM VT1612A (?)
+ *  REGISTER 500:  SETTING VALUE TO 0x008C WRITES TO  VT1612A
+ *  REGISTER 502:  LEAST SIGNIFICANT BYTE OF VALUE TO GET
+ *  REGISTER 503:  MOST SIGNIFICANT BYTE OF VALUE TO GET
+ *  REGISTER 504:  TARGET ADDRESS ON VT1612A
+ */
+/*--------------------------------------------------------------------------*/
+int
+read_vt(struct usb_device *p, __u16 reg0)
+{
+__u8 igot;
+__u16 got502, got503;
+
+SET(p, 0x0504, reg0);
+SET(p, 0x0500, 0x008B);
+
+GET(p, 0x0502, &igot);  got502 = (0xFF & igot);
+GET(p, 0x0503, &igot);  got503 = (0xFF & igot);
+
+JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", reg0, ((got503 << 8) | got502));
+
+return (got503 << 8) | got502;
+}
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
+ */
+/*--------------------------------------------------------------------------*/
+int
+write_300(struct usb_device *p)
+{
+SET(p, 0x300, 0x0012);
+SET(p, 0x350, 0x002D);
+SET(p, 0x351, 0x0001);
+SET(p, 0x352, 0x0000);
+SET(p, 0x353, 0x0000);
+SET(p, 0x300, 0x0080);
+return 0;
+}
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  NOTE: THE FOLLOWING IS NOT CHECKED:
+ *  REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
+ */
+/*--------------------------------------------------------------------------*/
+int
+check_saa(struct usb_device *p)
+{
+int i0, ir, rc;
+i0 = 0;
+
+rc = 0;
+while (0xFF != saa7113config[i0].reg) {
+       if (0x0F == saa7113config[i0].reg) {
+               i0++; continue;
+       }
+
+       ir = read_saa(p, saa7113config[i0].reg);
+       if (ir != saa7113config[i0].set) {
+               SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n", \
+                       saa7113config[i0].reg, ir, saa7113config[i0].set);
+               rc--;
+       }
+       i0++;
+}
+if (-8 > rc)
+       return rc;
+else
+       return 0;
+}
+/****************************************************************************/
+int
+merit_saa(struct usb_device *p)
+{
+int rc;
+
+rc = read_saa(p, 0x1F);
+if ((0 > rc) || (0x02 & rc))
+       return 1 ;
+else
+       return 0;
+}
+/****************************************************************************/
+int
+ready_saa(struct usb_device *p)
+{
+int j, rc;
+static int max = 10;
+
+j = 0;
+while (max > j) {
+       rc = read_saa(p, 0x1F);
+       if (0 <= rc) {
+               if ((1 == (0x01 & rc))&&(0 == (0x40 & rc)))
+                       break;
+       }
+       msleep(100);  j++;
+}
+if (max == j)
+       return -1;
+else {
+       if (0x20 & rc)
+               JOT(8, "hardware detects 60 Hz\n");
+       else
+               JOT(8, "hardware detects 50 Hz\n");
+       if (0x80 & rc)
+               JOT(8, "hardware detects interlacing\n");
+       else
+               JOT(8, "hardware detects no interlacing\n");
+}
+return 0;
+}
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  NOTE: THE FOLLOWING ARE NOT CHECKED:
+ *  REGISTERS 0x000, 0x002:  FUNCTIONALITY IS NOT KNOWN
+ *  REGISTER  0x100:  ACCEPT ALSO (0x80 | stk1160config[.].set)
+ */
+/*--------------------------------------------------------------------------*/
+int
+check_stk(struct usb_device *p)
+{
+int i0, ir;
+i0 = 0;
+while (0xFFF != stk1160config[i0].reg) {
+       if (0x000 == stk1160config[i0].reg) {
+               i0++; continue;
+       }
+       if (0x002 == stk1160config[i0].reg) {
+               i0++; continue;
+       }
+
+       ir = read_stk(p, stk1160config[i0].reg);
+
+       if (0x100 == stk1160config[i0].reg) {
+               if ((ir != (0xFF & stk1160config[i0].set)) && \
+                       (ir != (0x80 | (0xFF & stk1160config[i0].set))) && \
+                               (0xFFFF != stk1160config[i0].set)) {
+                       SAY("STK register 0x%03X has 0x%02X, " \
+                                       "expected 0x%02X\n", \
+                                       stk1160config[i0].reg, ir, \
+                                       stk1160config[i0].set);
+                       }
+               i0++; continue;
+               }
+
+       if ((ir != (0xFF & stk1160config[i0].set)) && \
+                       (0xFFFF != stk1160config[i0].set)) {
+               SAY("STK register 0x%03X has 0x%02X, " \
+                                       "expected 0x%02X\n", \
+                                       stk1160config[i0].reg, ir, \
+                                       stk1160config[i0].set);
+               }
+       i0++;
+       }
+return 0;
+}
+/****************************************************************************/
+int
+read_saa(struct usb_device *p, __u16 reg0)
+{
+__u8 igot;
+
+SET(p, 0x208, reg0);
+SET(p, 0x200, 0x20);
+if (0 != wait_i2c(p))
+       return -1;
+igot = 0;
+GET(p, 0x0209, &igot);
+return igot;
+}
+/****************************************************************************/
+int
+read_stk(struct usb_device *p, __u32 reg0)
+{
+__u8 igot;
+
+igot = 0;
+GET(p, reg0, &igot);
+return igot;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *    HARDWARE    USERSPACE INPUT NUMBER   PHYSICAL INPUT   DRIVER input VALUE
+ *
+ *  CVBS+S-VIDEO           0 or 1              CVBS                 1
+ *   FOUR-CVBS             0 or 1              CVBS1                1
+ *   FOUR-CVBS                2                CVBS2                2
+ *   FOUR-CVBS                3                CVBS3                3
+ *   FOUR-CVBS                4                CVBS4                4
+ *  CVBS+S-VIDEO              5               S-VIDEO               5
+ *
+ *  WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
+ *
+ *     mode  7   => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
+ *     mode  9   => USE AUTOMATIC GAIN CONTROL (DEFAULT)
+ *
+*/
+/*---------------------------------------------------------------------------*/
+int
+select_input(struct usb_device *p, int input, int mode)
+{
+
+stop_100(p);
+
+msleep(20);
+switch (input) {
+case 0:
+case 1: {
+       SET(p, 0x0000, 0x0098); break;
+}
+case 2: {
+       SET(p, 0x0000, 0x0090); break;
+}
+case 3: {
+       SET(p, 0x0000, 0x0088); break;
+}
+case 4: {
+       SET(p, 0x0000, 0x0080); break;
+}
+case 5: {
+       if (9 != mode)
+               mode = 7;
+       switch (mode) {
+       case 7:
+               {
+               if (0 != write_saa(p, 0x02, 0x87)) {
+                       SAY("ERROR: failed to set SAA " \
+                               "register 0x02 for input " \
+                               "%i\n", input);
+               }
+               if (0 != write_saa(p, 0x05, 0xFF)) {
+                       SAY("ERROR: failed to set SAA " \
+                               "register 0x05 for input " \
+                               "%i\n", input);
+               }
+               break;
+       }
+       case 9:
+               {
+               if (0 != write_saa(p, 0x02, 0x89)) {
+                       SAY("ERROR: failed to set SAA " \
+                               "register 0x02 for input " \
+                               "%i\n", input);
+               }
+               if (0 != write_saa(p, 0x05, 0x00)) {
+                       SAY("ERROR: failed to set SAA " \
+                               "register 0x05 for input " \
+                               "%i\n", input);
+               }
+               break;
+       }
+       default:
+               {
+               SAY("MISTAKE:  bad mode: %i\n", mode);
+               return -1;
+               }
+       }
+       if (0 != write_saa(p, 0x04, 0x00)) {
+               SAY("ERROR: failed to set SAA register 0x04 " \
+                                       "for input %i\n", input);
+       }
+       if (0 != write_saa(p, 0x09, 0x80)) {
+               SAY("ERROR: failed to set SAA register 0x09 " \
+                                       "for input %i\n", input);
+       }
+       break;
+}
+default:
+       {
+       SAY("ERROR:  bad input: %i\n", input);
+       return -1;
+}
+}
+msleep(20);
+SET(p, 0x0002, 0x0093);
+msleep(20);
+
+start_100(p);
+
+return 0;
+}
+/****************************************************************************/
+int
+set_resolution(struct usb_device *p, \
+                               __u16 set0, __u16 set1, __u16 set2, __u16 set3)
+{
+__u16 u0x0111, u0x0113, u0x0115, u0x0117;
+
+u0x0111 = ((0xFF00 & set0) >> 8);
+u0x0113 = ((0xFF00 & set1) >> 8);
+u0x0115 = ((0xFF00 & set2) >> 8);
+u0x0117 = ((0xFF00 & set3) >> 8);
+
+SET(p, 0x0110, (0x00FF & set0));
+SET(p, 0x0111, u0x0111);
+SET(p, 0x0112, (0x00FF & set1));
+SET(p, 0x0113, u0x0113);
+SET(p, 0x0114, (0x00FF & set2));
+SET(p, 0x0115, u0x0115);
+SET(p, 0x0116, (0x00FF & set3));
+SET(p, 0x0117, u0x0117);
+
+return 0;
+}
+/****************************************************************************/
+int
+start_100(struct usb_device *p)
+{
+__u16 get0;
+__u8 igot;
+
+GET(p, 0x0100, &igot);  get0 = igot;
+msleep(0x1f4);
+SET(p, 0x0100, (0x80 | get0));
+msleep(0x1f4);
+return 0;
+}
+/****************************************************************************/
+int
+stop_100(struct usb_device *p)
+{
+__u16 get0;
+__u8 igot;
+
+GET(p, 0x0100, &igot);  get0 = igot;
+msleep(0x1f4);
+SET(p, 0x0100, (0x7F & get0));
+msleep(0x1f4);
+return 0;
+}
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
+*/
+/*--------------------------------------------------------------------------*/
+int
+wait_i2c(struct usb_device *p)
+{
+__u16 get0;
+__u8 igot;
+const int max = 4;
+int k;
+
+for (k = 0;  k < max;  k++) {
+       GET(p, 0x0201, &igot);  get0 = igot;
+       switch (get0) {
+       case 0x04:
+       case 0x01: {
+               return 0;
+       }
+       case 0x00: {
+               msleep(10);
+               continue;
+       }
+       default: {
+               return get0 - 1;
+       }
+       }
+}
+return -1;
+}
+/****************************************************************************/
+int
+regset(struct usb_device *pusb_device, __u16 index, __u16 value)
+{
+__u16 igot;
+int rc0, rc1;
+
+if (!pusb_device)
+       return -EFAULT;
+
+rc1 = 0;  igot = 0;
+rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
+               (__u8)0x01, \
+               (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
+               (__u16)value, \
+               (__u16)index, \
+               (void *)NULL, \
+               (__u16)0, \
+               (int)500);
+
+#if defined(NOREADBACK)
+#
+#else
+rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \
+               (__u8)0x00, \
+               (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
+               (__u16)0x00, \
+               (__u16)index, \
+               (void *)&igot, \
+               (__u16)sizeof(__u16), \
+               (int)50000);
+igot = 0xFF & igot;
+switch (index) {
+case 0x000:
+case 0x500:
+case 0x502:
+case 0x503:
+case 0x504:
+case 0x506:
+case 0x507: {
+       break;
+}
+case 0x204:
+case 0x205:
+case 0x350:
+case 0x351: {
+       if (0 != igot) {
+               JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", \
+                                                               igot, index);
+       }
+break;
+}
+case 0x114:
+case 0x116: {
+       if ((0xFF & value) != igot) {
+               JOT(8, "unexpected 0x%02X != 0x%02X " \
+                                               "for STK register 0x%03X\n", \
+                                               igot, value, index);
+       }
+break;
+}
+case 0x200: {
+       if (0 == igot)
+               break;
+}
+default: {
+       if (value != igot) {
+               JOT(8, "unexpected 0x%02X != 0x%02X " \
+                                       "for STK register 0x%03X\n", \
+                                       igot, value, index);
+       }
+break;
+}
+}
+#endif /* ! NOREADBACK*/
+
+return (0 > rc0) ? rc0 : rc1;
+}
+/*****************************************************************************/
+int
+regget(struct usb_device *pusb_device, __u16 index, void *pvoid)
+{
+int ir;
+
+if (!pusb_device)
+       return -EFAULT;
+
+ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \
+               (__u8)0x00, \
+               (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
+               (__u16)0x00, \
+               (__u16)index, \
+               (void *)pvoid, \
+               sizeof(__u8), \
+               (int)50000);
+return 0xFF & ir;
+}
+/*****************************************************************************/
+int
+wakeup_device(struct usb_device *pusb_device)
+{
+return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
+               (__u8)USB_REQ_SET_FEATURE, \
+               (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), \
+               USB_DEVICE_REMOTE_WAKEUP, \
+               (__u16)0, \
+               (void *) NULL, \
+               (__u16)0, \
+               (int)50000);
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *                                IMPORTANT:
+ *  THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
+ *  CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
+ *  TO ENABLE AUDIO  THE VALUE 0x0200 MUST BE SENT.
+ */
+/*---------------------------------------------------------------------------*/
+int
+audio_setup(struct easycap *peasycap)
+{
+struct usb_device *pusb_device;
+static __u8 request = 0x01;
+static __u8 requesttype = \
+               (__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
+
+static __u16 value_unmute = 0x0200;
+static __u16 index = 0x0301;
+
+static unsigned char buffer[1];
+static __u16 length = 1;
+int rc, id1, id2;
+
+if (NULL == peasycap)
+       return -EFAULT;
+
+pusb_device = peasycap->pusb_device;
+if (NULL == pusb_device)
+       return -EFAULT;
+
+JOT(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",    \
+                       requesttype, request,           \
+                       (0x00FF & value_unmute),        \
+                       (0xFF00 & value_unmute) >> 8,   \
+                       (0x00FF & index),               \
+                       (0xFF00 & index) >> 8,          \
+                       (0x00FF & length),              \
+                       (0xFF00 & length) >> 8);
+
+buffer[0] = 0x01;
+
+rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),     \
+                       (__u8)request,                                  \
+                       (__u8)requesttype,                              \
+                       (__u16)value_unmute,                            \
+                       (__u16)index,                                   \
+                       (void *)&buffer[0],                             \
+                       (__u16)length,                                  \
+                       (int)50000);
+
+JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0]));
+if (rc != (int)length)
+       SAY("ERROR: usb_control_msg returned %i\n", rc);
+
+/*--------------------------------------------------------------------------*/
+/*
+ *  REGISTER 500:  SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
+ *  REGISTER 506:  ANALOGUE AUDIO ATTENTUATOR ???
+ *                 FOR THE CVBS+S-VIDEO HARDWARE:
+ *                    SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
+ *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
+ *                 FOR THE FOUR-CVBS HARDWARE:
+ *                    SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
+ *  REGISTER 507:  ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
+ *                 FOR THE CVBS-S-VIDEO HARDWARE:
+ *                    SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
+ *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
+ */
+/*--------------------------------------------------------------------------*/
+
+SET(pusb_device, 0x0500, 0x0094);
+
+SET(pusb_device, 0x0500, 0x008C);
+
+SET(pusb_device, 0x0506, 0x0001);
+SET(pusb_device, 0x0507, 0x0000);
+
+id1 = read_vt(pusb_device, 0x007C);
+id2 = read_vt(pusb_device, 0x007E);
+SAY("0x%04X:0x%04X is audio vendor id\n", id1, id2);
+
+/*---------------------------------------------------------------------------*/
+/*
+*   SELECT AUDIO SOURCE "LINE IN" AND SET DEFAULT GAIN TO 0 dB.
+*
+*   THESE COMMANDS SEEM TO BE ACCEPTED (THOUGH POSSIBLY IGNORED) EVEN WHEN
+*   THERE IS NO SEPARATE AUDIO CHIP PRESENT.
+*/
+/*---------------------------------------------------------------------------*/
+
+write_vt(pusb_device, 0x0002, 0x8000);
+write_vt(pusb_device, 0x001C, 0x8000);
+
+write_vt(pusb_device, 0x000E, 0x0000);
+write_vt(pusb_device, 0x0010, 0x0000);
+write_vt(pusb_device, 0x0012, 0x8000);
+write_vt(pusb_device, 0x0016, 0x0000);
+
+write_vt(pusb_device, 0x001A, 0x0404);
+write_vt(pusb_device, 0x0002, 0x0000);
+write_vt(pusb_device, 0x001C, 0x0000);
+
+check_vt(pusb_device);
+
+return 0;
+}
+/*****************************************************************************/
+int
+check_vt(struct usb_device *pusb_device)
+{
+int igot;
+
+igot = read_vt(pusb_device, 0x0002);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x02\n");
+if (0x8000 & igot)
+       SAY("register 0x%02X muted\n", 0x02);
+
+igot = read_vt(pusb_device, 0x000E);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x0E\n");
+if (0x8000 & igot)
+       SAY("register 0x%02X muted\n", 0x0E);
+
+igot = read_vt(pusb_device, 0x0010);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x10\n");
+if (0x8000 & igot)
+       SAY("register 0x%02X muted\n", 0x10);
+
+igot = read_vt(pusb_device, 0x0012);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x12\n");
+if (0x8000 & igot)
+       SAY("register 0x%02X muted\n", 0x12);
+
+igot = read_vt(pusb_device, 0x0016);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x16\n");
+if (0x8000 & igot)
+       SAY("register 0x%02X muted\n", 0x16);
+
+igot = read_vt(pusb_device, 0x001A);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x1A\n");
+if (0x8000 & igot)
+       SAY("register 0x%02X muted\n", 0x1A);
+
+igot = read_vt(pusb_device, 0x001C);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x1C\n");
+if (0x8000 & igot)
+       SAY("register 0x%02X muted\n", 0x1C);
+
+return 0;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  NOTE:  THIS DOES INCREASE THE VOLUME DRAMATICALLY:
+ *         audio_gainset(pusb_device, 0x000F);
+ *
+ *  IF 16<loud<31 VT1621A REGISTER 0x1C IS SET FOR POSITIVE GAIN.
+ *  IF loud<=16 VT1621A REGISTER 0x1C IS SET FOR ZERO GAIN.
+ *  THERE IS NEVER ANY (ADDITIONAL) ATTENUATION.
+ */
+/*---------------------------------------------------------------------------*/
+int
+audio_gainset(struct usb_device *pusb_device, __s8 loud)
+{
+int igot;
+__u8 u8;
+__u16 mute;
+
+if (16 > loud)
+       loud = 16;
+u8 = 0x000F & (__u8)(loud - 16);
+
+write_vt(pusb_device, 0x0002, 0x8000);
+
+igot = read_vt(pusb_device, 0x001C);
+if (0 > igot) {
+       SAY("ERROR: failed to read VT1612A register 0x1C\n");
+       mute = 0x0000;
+} else
+       mute = 0x8000 & ((unsigned int)igot);
+
+JOT(8, "0x%04X=(mute|u8|(u8<<8))\n", mute | u8 | (u8 << 8));
+
+write_vt(pusb_device, 0x001C, 0x8000);
+write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8)));
+write_vt(pusb_device, 0x0002, 0x0000);
+
+return 0;
+}
+/*****************************************************************************/
+int
+audio_gainget(struct usb_device *pusb_device)
+{
+int igot;
+
+igot = read_vt(pusb_device, 0x001C);
+if (0 > igot)
+       SAY("ERROR: failed to read VT1612A register 0x1C\n");
+return igot;
+}
+/*****************************************************************************/
+int
+set2to78(struct usb_device *p)
+{
+int ir;
+
+msleep(20);
+ir = regset(p, 0x0002, 0x0078);
+if (0 > ir)
+       SAY("ERROR: failed to set register 0x0002 to 0x0078\n");
+msleep(20);
+return ir;
+}
+/*****************************************************************************/
+int
+set2to93(struct usb_device *p)
+{
+int ir;
+
+msleep(20);
+ir = regset(p, 0x0002, 0x0093);
+if (0 > ir)
+       SAY("ERROR: failed to set register 0x0002 to 0x0078\n");
+msleep(20);
+return ir;
+}
+/*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c
new file mode 100644 (file)
index 0000000..09c194c
--- /dev/null
@@ -0,0 +1,4354 @@
+/******************************************************************************
+*                                                                             *
+*  easycap_main.c                                                             *
+*                                                                             *
+*  Video driver for EasyCAP USB2.0 Video Capture Device DC60                  *
+*                                                                             *
+*                                                                             *
+******************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+
+#include "easycap.h"
+#include "easycap_standard.h"
+
+int easycap_debug;
+module_param(easycap_debug, int, S_IRUGO | S_IWUSR);
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
+ */
+/*---------------------------------------------------------------------------*/
+struct usb_device_id easycap_usb_device_id_table[] = {
+{ USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) },
+{ }
+};
+MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
+struct usb_driver easycap_usb_driver = {
+.name = "easycap",
+.id_table = easycap_usb_device_id_table,
+.probe = easycap_usb_probe,
+.disconnect = easycap_usb_disconnect,
+};
+/*---------------------------------------------------------------------------*/
+/*
+ *  PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
+ *
+ *  NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
+ *        CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
+ *        THIS IS THE CASE FOR OpenSUSE.
+ */
+/*---------------------------------------------------------------------------*/
+const struct file_operations easycap_fops = {
+.owner =   THIS_MODULE,
+.open =    easycap_open,
+.release = easycap_release,
+.ioctl =   easycap_ioctl,
+.poll =    easycap_poll,
+.mmap =    easycap_mmap,
+.llseek =  no_llseek,
+};
+struct vm_operations_struct easycap_vm_ops = {
+.open  = easycap_vma_open,
+.close = easycap_vma_close,
+.fault = easycap_vma_fault,
+};
+struct usb_class_driver easycap_class = {
+.name = "usb/easycap%d",
+.fops = &easycap_fops,
+.minor_base = USB_SKEL_MINOR_BASE,
+};
+
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+#if defined(EASYCAP_NEEDS_V4L2_FOPS)
+const struct v4l2_file_operations v4l2_fops = {
+.owner =   THIS_MODULE,
+.open =    easycap_open_noinode,
+.release = easycap_release_noinode,
+.ioctl =   easycap_ioctl_noinode,
+.poll =    easycap_poll,
+.mmap =    easycap_mmap,
+};
+#endif /*EASYCAP_NEEDS_V4L2_FOPS*/
+int video_device_many /*=0*/;
+struct video_device *pvideo_array[VIDEO_DEVICE_MANY], *pvideo_device;
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+
+/*--------------------------------------------------------------------------*/
+/*
+ *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
+ */
+/*--------------------------------------------------------------------------*/
+const struct file_operations easysnd_fops = {
+.owner =   THIS_MODULE,
+.open =    easysnd_open,
+.release = easysnd_release,
+.ioctl =   easysnd_ioctl,
+.read =    easysnd_read,
+.llseek =  no_llseek,
+};
+struct usb_class_driver easysnd_class = {
+.name = "usb/easysnd%d",
+.fops = &easysnd_fops,
+.minor_base = USB_SKEL_MINOR_BASE,
+};
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  IT IS NOT APPROPRIATE FOR easycap_open() TO SUBMIT THE VIDEO URBS HERE,
+ *  BECAUSE THERE WILL ALWAYS BE SUBSEQUENT NEGOTIATION OF TV STANDARD AND
+ *  FORMAT BY IOCTL AND IT IS INADVISABLE TO HAVE THE URBS RUNNING WHILE
+ *  REGISTERS OF THE SA7113H ARE BEING MANIPULATED.
+ *
+ *  THE SUBMISSION OF VIDEO URBS IS THEREFORE DELAYED UNTIL THE IOCTL COMMAND
+ *  STREAMON IS RECEIVED.
+ */
+/*--------------------------------------------------------------------------*/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+int
+easycap_open_noinode(struct file *file)
+{
+return easycap_open((struct inode *)NULL, file);
+}
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+int
+easycap_open(struct inode *inode, struct file *file)
+{
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+struct usb_interface *pusb_interface;
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+struct usb_device *p;
+struct easycap *peasycap;
+int i, k, m, rc;
+
+JOT(4, "\n");
+SAY("==========OPEN=========\n");
+
+peasycap = (struct easycap *)NULL;
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+if ((struct inode *)NULL == inode) {
+       SAY("ERROR: inode is NULL.\n");
+       return -EFAULT;
+}
+pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode));
+if (!pusb_interface) {
+       SAY("ERROR: pusb_interface is NULL.\n");
+       return -EFAULT;
+}
+peasycap = usb_get_intfdata(pusb_interface);
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#else
+for (i = 0;  i < video_device_many;  i++) {
+       pvideo_device = pvideo_array[i];
+       if ((struct video_device *)NULL != pvideo_device) {
+               peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
+               break;
+       }
+}
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+if ((struct easycap *)NULL == peasycap) {
+       SAY("MISTAKE: peasycap is NULL\n");
+       return -EFAULT;
+}
+file->private_data = peasycap;
+/*---------------------------------------------------------------------------*/
+/*
+ *  INITIALIZATION
+ */
+/*---------------------------------------------------------------------------*/
+JOT(4, "starting initialization\n");
+
+for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
+       for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++)
+               memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
+}
+p = peasycap->pusb_device;
+if ((struct usb_device *)NULL == p) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+} else {
+       JOT(16, "0x%08lX=peasycap->pusb_device\n", \
+                                       (long int)peasycap->pusb_device);
+}
+rc = wakeup_device(peasycap->pusb_device);
+if (0 == rc)
+       JOT(8, "wakeup_device() OK\n");
+else {
+       SAY("ERROR: wakeup_device() returned %i\n", rc);
+       return -EFAULT;
+}
+rc = setup_stk(p);  peasycap->input = 0;
+if (0 == rc)
+       JOT(8, "setup_stk() OK\n");
+else {
+       SAY("ERROR: setup_stk() returned %i\n", rc);
+       return -EFAULT;
+}
+rc = setup_saa(p);
+if (0 == rc)
+       JOT(8, "setup_saa() OK\n");
+else {
+       SAY("ERROR: setup_saa() returned %i\n", rc);
+       return -EFAULT;
+}
+rc = check_saa(p);
+if (0 == rc)
+       JOT(8, "check_saa() OK\n");
+else if (-8 < rc)
+       SAY("check_saa() returned %i\n", rc);
+else {
+       SAY("ERROR: check_saa() returned %i\n", rc);
+       return -EFAULT;
+}
+peasycap->standard_offset = -1;
+/*---------------------------------------------------------------------------*/
+#if defined(PREFER_NTSC)
+
+rc = adjust_standard(peasycap, V4L2_STD_NTSC_M);
+if (0 == rc)
+       JOT(8, "adjust_standard(.,NTSC_M) OK\n");
+else {
+       SAY("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc);
+       return -EFAULT;
+}
+rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
+                                                                       false);
+if (0 <= rc)
+       JOT(8, "adjust_format(.,640,480,UYVY) OK\n");
+else {
+       SAY("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc);
+       return -EFAULT;
+}
+
+#else
+
+rc = adjust_standard(peasycap, \
+               (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
+               V4L2_STD_PAL_I | V4L2_STD_PAL_N));
+if (0 == rc)
+       JOT(8, "adjust_standard(.,PAL_BGHIN) OK\n");
+else {
+       SAY("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc);
+       return -EFAULT;
+}
+rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
+                                                                       false);
+if (0 <= rc)
+       JOT(8, "adjust_format(.,640,480,uyvy,false) OK\n");
+else {
+       SAY("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc);
+       return -EFAULT;
+}
+
+#endif /* !PREFER_NTSC*/
+/*---------------------------------------------------------------------------*/
+rc = adjust_brightness(peasycap, -8192);
+if (0 != rc) {
+       SAY("ERROR: adjust_brightness(default) returned %i\n", rc);
+       return -EFAULT;
+}
+rc = adjust_contrast(peasycap, -8192);
+if (0 != rc) {
+       SAY("ERROR: adjust_contrast(default) returned %i\n", rc);
+       return -EFAULT;
+}
+rc = adjust_saturation(peasycap, -8192);
+if (0 != rc) {
+       SAY("ERROR: adjust_saturation(default) returned %i\n", rc);
+       return -EFAULT;
+}
+rc = adjust_hue(peasycap, -8192);
+if (0 != rc) {
+       SAY("ERROR: adjust_hue(default) returned %i\n", rc);
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, \
+                                               peasycap->video_altsetting_on);
+if (0 == rc)
+       JOT(8, "usb_set_interface(.,%i,%i) OK\n", peasycap->video_interface, \
+                                               peasycap->video_altsetting_on);
+else {
+       SAY("ERROR: usb_set_interface() returned %i\n", rc);
+       return -EFAULT;
+}
+rc = start_100(p);
+if (0 == rc)
+       JOT(8, "start_100() OK\n");
+else {
+       SAY("ERROR: start_100() returned %i\n", rc);
+       return -EFAULT;
+}
+peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
+peasycap->video_idle = 0;
+peasycap->video_junk = 0;
+for (i = 0; i < 180; i++)
+       peasycap->merit[i] = 0;
+peasycap->video_eof = 0;
+peasycap->audio_eof = 0;
+
+do_gettimeofday(&peasycap->timeval7);
+
+peasycap->fudge = 0;
+
+JOT(4, "finished initialization\n");
+return 0;
+}
+/*****************************************************************************/
+int
+submit_video_urbs(struct easycap *peasycap)
+{
+struct data_urb *pdata_urb;
+struct urb *purb;
+struct list_head *plist_head;
+int j, isbad, m, rc;
+int isbuf;
+
+if ((struct list_head *)NULL == peasycap->purb_video_head) {
+       SAY("ERROR: peasycap->urb_video_head uninitialized\n");
+       return -EFAULT;
+}
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+if (!peasycap->video_isoc_streaming) {
+
+
+
+
+
+
+
+
+       JOT(4, "submission of all video urbs\n");
+       if (0 != ready_saa(peasycap->pusb_device)) {
+               SAY("ERROR: not ready to capture after waiting " \
+                                                       "one second\n");
+               SAY(".....  continuing anyway\n");
+       }
+       isbad = 0;  m = 0;
+       list_for_each(plist_head, (peasycap->purb_video_head)) {
+               pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+               if (NULL != pdata_urb) {
+                       purb = pdata_urb->purb;
+                       if (NULL != purb) {
+                               isbuf = pdata_urb->isbuf;
+                               purb->interval = 1;
+                               purb->dev = peasycap->pusb_device;
+                               purb->pipe = \
+                                       usb_rcvisocpipe(peasycap->pusb_device,\
+                                       peasycap->video_endpointnumber);
+                               purb->transfer_flags = URB_ISO_ASAP;
+                               purb->transfer_buffer = \
+                                       peasycap->video_isoc_buffer[isbuf].pgo;
+                               purb->transfer_buffer_length = \
+                                       peasycap->video_isoc_buffer_size;
+                               purb->complete = easycap_complete;
+                               purb->context = peasycap;
+                               purb->start_frame = 0;
+                               purb->number_of_packets = \
+                                       peasycap->video_isoc_framesperdesc;
+
+                               for (j = 0;  j < peasycap->\
+                                       video_isoc_framesperdesc; j++) {
+                                               purb->iso_frame_desc[j].\
+                                               offset = j * \
+                                               peasycap->\
+                                               video_isoc_maxframesize;
+                                               purb->iso_frame_desc[j].\
+                                               length = peasycap->\
+                                               video_isoc_maxframesize;
+                                       }
+
+                               rc = usb_submit_urb(purb, GFP_KERNEL);
+                               if (0 != rc) {
+                                       isbad++;
+                                       SAY("ERROR: usb_submit_urb() failed " \
+                                                       "for urb with rc:\n");
+                                       switch (rc) {
+                                       case -ENOMEM: {
+                                               SAY("ENOMEM\n");
+                                               break;
+                                       }
+                                       case -ENODEV: {
+                                               SAY("ENODEV\n");
+                                               break;
+                                       }
+                                       case -ENXIO: {
+                                               SAY("ENXIO\n");
+                                               break;
+                                       }
+                                       case -EINVAL: {
+                                               SAY("EINVAL\n");
+                                               break;
+                                       }
+                                       case -EAGAIN: {
+                                               SAY("EAGAIN\n");
+                                               break;
+                                       }
+                                       case -EFBIG: {
+                                               SAY("EFBIG\n");
+                                               break;
+                                       }
+                                       case -EPIPE: {
+                                               SAY("EPIPE\n");
+                                               break;
+                                       }
+                                       case -EMSGSIZE: {
+                                               SAY("EMSGSIZE\n");
+                                               break;
+                                       }
+                                       default: {
+                                               SAY("unknown error code %i\n",\
+                                                                        rc);
+                                               break;
+                                       }
+                                       }
+                               } else {
+                                       m++;
+                               }
+                               } else {
+                                       isbad++;
+                               }
+                       } else {
+                                isbad++;
+                       }
+               }
+       if (isbad) {
+               JOT(4, "attempting cleanup instead of submitting\n");
+               list_for_each(plist_head, (peasycap->purb_video_head)) {
+                       pdata_urb = list_entry(plist_head, struct data_urb, \
+                                                               list_head);
+                       if (NULL != pdata_urb) {
+                               purb = pdata_urb->purb;
+                               if (NULL != purb)
+                                       usb_kill_urb(purb);
+                       }
+               }
+               peasycap->video_isoc_streaming = 0;
+       } else {
+               peasycap->video_isoc_streaming = 1;
+               JOT(4, "submitted %i video urbs\n", m);
+       }
+
+
+
+
+
+
+} else {
+       JOT(4, "already streaming video urbs\n");
+}
+return 0;
+}
+/*****************************************************************************/
+int
+kill_video_urbs(struct easycap *peasycap)
+{
+int m;
+struct list_head *plist_head;
+struct data_urb *pdata_urb;
+
+if ((struct easycap *)NULL == peasycap) {
+       SAY("ERROR: peasycap is NULL\n");
+       return -EFAULT;
+}
+if (peasycap->video_isoc_streaming) {
+
+
+
+       if ((struct list_head *)NULL != peasycap->purb_video_head) {
+               peasycap->video_isoc_streaming = 0;
+               JOT(4, "killing video urbs\n");
+               m = 0;
+               list_for_each(plist_head, (peasycap->purb_video_head)) {
+                       pdata_urb = list_entry(plist_head, struct data_urb, \
+                                                               list_head);
+                       if ((struct data_urb *)NULL != pdata_urb) {
+                               if ((struct urb *)NULL != pdata_urb->purb) {
+                                       usb_kill_urb(pdata_urb->purb);
+                                       m++;
+                               }
+                       }
+               }
+               JOT(4, "%i video urbs killed\n", m);
+       } else {
+               SAY("ERROR: peasycap->purb_video_head is NULL\n");
+               return -EFAULT;
+       }
+} else {
+       JOT(8, "%i=video_isoc_streaming, no video urbs killed\n", \
+                                       peasycap->video_isoc_streaming);
+}
+return 0;
+}
+/****************************************************************************/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+int
+easycap_release_noinode(struct file *file)
+{
+return easycap_release((struct inode *)NULL, file);
+}
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*--------------------------------------------------------------------------*/
+int
+easycap_release(struct inode *inode, struct file *file)
+{
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+struct easycap *peasycap;
+
+JOT(4, "\n");
+
+peasycap = file->private_data;
+if (NULL == peasycap) {
+       SAY("ERROR:  peasycap is NULL.\n");
+       SAY("ending unsuccessfully\n");
+       return -EFAULT;
+}
+if (0 != kill_video_urbs(peasycap)) {
+       SAY("ERROR: kill_video_urbs() failed\n");
+       return -EFAULT;
+}
+JOT(4, "ending successfully\n");
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#else
+#
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+
+return 0;
+}
+/****************************************************************************/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+int
+videodev_release(struct video_device *pvd)
+{
+struct easycap *peasycap;
+int i, j, k;
+
+JOT(4, "\n");
+
+k = 0;
+for (i = 0;  i < video_device_many;  i++) {
+       pvideo_device = pvideo_array[i];
+       if ((struct video_device *)NULL != pvideo_device) {
+               if (pvd->minor == pvideo_device->minor) {
+                       peasycap = (struct easycap *)\
+                                       video_get_drvdata(pvideo_device);
+                       if ((struct easycap *)NULL == peasycap) {
+                               SAY("ERROR:  peasycap is NULL\n");
+                               SAY("ending unsuccessfully\n");
+                               return -EFAULT;
+                       }
+                       if (0 != kill_video_urbs(peasycap)) {
+                               SAY("ERROR: kill_video_urbs() failed\n");
+                               return -EFAULT;
+                       }
+                       JOT(4, "freeing video_device structure: " \
+                                                       "/dev/video%i\n", i);
+                       kfree((void *)pvideo_device);
+                       for (j = i;  j < (VIDEO_DEVICE_MANY - 1);  j++)
+                               pvideo_array[j] = pvideo_array[j + 1];
+                       video_device_many--;  k++;
+                       break;
+               }
+       }
+}
+if (!k) {
+       SAY("ERROR: lost video_device structure for %i=minor\n", pvd->minor);
+       SAY("cannot free: may cause memory leak\n");
+       SAY("ending unsuccessfully\n");
+       return -EFAULT;
+}
+
+JOT(4, "ending successfully\n");
+return 0;
+}
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect().
+ *  BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED.
+ *  peasycap->pusb_device IS NO LONGER VALID AND SHOULD HAVE BEEN SET TO NULL.
+ */
+/*---------------------------------------------------------------------------*/
+void
+easycap_delete(struct kref *pkref)
+{
+int k, m, lost;
+int allocation_video_urb, allocation_video_page, allocation_video_struct;
+int allocation_audio_urb, allocation_audio_page, allocation_audio_struct;
+int registered_video, registered_audio;
+struct easycap *peasycap;
+struct data_urb *pdata_urb;
+struct list_head *plist_head, *plist_next;
+
+JOT(4, "\n");
+
+peasycap = container_of(pkref, struct easycap, kref);
+if ((struct easycap *)NULL == peasycap) {
+       SAY("ERROR: peasycap is NULL: cannot perform deletions\n");
+       return;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  FREE VIDEO.
+ */
+/*---------------------------------------------------------------------------*/
+if ((struct list_head *)NULL != peasycap->purb_video_head) {
+       JOT(4, "freeing video urbs\n");
+       m = 0;
+       list_for_each(plist_head, (peasycap->purb_video_head)) {
+               pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+               if (NULL == pdata_urb)
+                       JOT(4, "ERROR: pdata_urb is NULL\n");
+               else {
+                       if ((struct urb *)NULL != pdata_urb->purb) {
+                               usb_free_urb(pdata_urb->purb);
+                               pdata_urb->purb = (struct urb *)NULL;
+                               peasycap->allocation_video_urb -= 1;
+                               m++;
+                       }
+               }
+       }
+
+       JOT(4, "%i video urbs freed\n", m);
+/*---------------------------------------------------------------------------*/
+       JOT(4, "freeing video data_urb structures.\n");
+       m = 0;
+       list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) {
+               pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+               if ((struct data_urb *)NULL != pdata_urb) {
+                       kfree(pdata_urb);  pdata_urb = (struct data_urb *)NULL;
+                       peasycap->allocation_video_struct -= \
+                                               sizeof(struct data_urb);
+                       m++;
+               }
+       }
+       JOT(4, "%i video data_urb structures freed\n", m);
+       JOT(4, "setting peasycap->purb_video_head=NULL\n");
+       peasycap->purb_video_head = (struct list_head *)NULL;
+       } else {
+JOT(4, "peasycap->purb_video_head is NULL\n");
+}
+/*---------------------------------------------------------------------------*/
+JOT(4, "freeing video isoc buffers.\n");
+m = 0;
+for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY;  k++) {
+       if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) {
+               free_pages((unsigned long)\
+                               (peasycap->video_isoc_buffer[k].pgo), \
+                               VIDEO_ISOC_ORDER);
+               peasycap->video_isoc_buffer[k].pgo = (void *)NULL;
+               peasycap->allocation_video_page -= \
+                               ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
+               m++;
+       }
+}
+JOT(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER));
+/*---------------------------------------------------------------------------*/
+JOT(4, "freeing video field buffers.\n");
+lost = 0;
+for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
+       for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
+               if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
+                       free_page((unsigned long)\
+                                       (peasycap->field_buffer[k][m].pgo));
+                       peasycap->field_buffer[k][m].pgo = (void *)NULL;
+                       peasycap->allocation_video_page -= 1;
+                       lost++;
+               }
+       }
+}
+JOT(4, "video field buffers freed: %i pages\n", lost);
+/*---------------------------------------------------------------------------*/
+JOT(4, "freeing video frame buffers.\n");
+lost = 0;
+for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
+       for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
+               if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) {
+                       free_page((unsigned long)\
+                                       (peasycap->frame_buffer[k][m].pgo));
+                       peasycap->frame_buffer[k][m].pgo = (void *)NULL;
+                       peasycap->allocation_video_page -= 1;
+                       lost++;
+               }
+       }
+}
+JOT(4, "video frame buffers freed: %i pages\n", lost);
+/*---------------------------------------------------------------------------*/
+/*
+ *  FREE AUDIO.
+ */
+/*---------------------------------------------------------------------------*/
+if ((struct list_head *)NULL != peasycap->purb_audio_head) {
+       JOT(4, "freeing audio urbs\n");
+       m = 0;
+       list_for_each(plist_head, (peasycap->purb_audio_head)) {
+               pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+               if (NULL == pdata_urb)
+                       JOT(4, "ERROR: pdata_urb is NULL\n");
+               else {
+                       if ((struct urb *)NULL != pdata_urb->purb) {
+                               usb_free_urb(pdata_urb->purb);
+                               pdata_urb->purb = (struct urb *)NULL;
+                               peasycap->allocation_audio_urb -= 1;
+                               m++;
+                       }
+               }
+       }
+       JOT(4, "%i audio urbs freed\n", m);
+/*---------------------------------------------------------------------------*/
+       JOT(4, "freeing audio data_urb structures.\n");
+       m = 0;
+       list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) {
+               pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+               if ((struct data_urb *)NULL != pdata_urb) {
+                       kfree(pdata_urb);  pdata_urb = (struct data_urb *)NULL;
+                       peasycap->allocation_audio_struct -= \
+                                               sizeof(struct data_urb);
+                       m++;
+               }
+       }
+JOT(4, "%i audio data_urb structures freed\n", m);
+JOT(4, "setting peasycap->purb_audio_head=NULL\n");
+peasycap->purb_audio_head = (struct list_head *)NULL;
+} else {
+JOT(4, "peasycap->purb_audio_head is NULL\n");
+}
+/*---------------------------------------------------------------------------*/
+JOT(4, "freeing audio isoc buffers.\n");
+m = 0;
+for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
+       if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) {
+               free_pages((unsigned long)\
+                               (peasycap->audio_isoc_buffer[k].pgo), \
+                               AUDIO_ISOC_ORDER);
+               peasycap->audio_isoc_buffer[k].pgo = (void *)NULL;
+               peasycap->allocation_audio_page -= \
+                               ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
+               m++;
+       }
+}
+JOT(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
+                                       m * (0x01 << AUDIO_ISOC_ORDER));
+/*---------------------------------------------------------------------------*/
+JOT(4, "freeing audio buffers.\n");
+lost = 0;
+for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
+       if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
+               free_page((unsigned long)(peasycap->audio_buffer[k].pgo));
+               peasycap->audio_buffer[k].pgo = (void *)NULL;
+               peasycap->allocation_audio_page -= 1;
+               lost++;
+       }
+}
+JOT(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost);
+/*---------------------------------------------------------------------------*/
+JOT(4, "freeing easycap structure.\n");
+allocation_video_urb    = peasycap->allocation_video_urb;
+allocation_video_page   = peasycap->allocation_video_page;
+allocation_video_struct = peasycap->allocation_video_struct;
+registered_video        = peasycap->registered_video;
+allocation_audio_urb    = peasycap->allocation_audio_urb;
+allocation_audio_page   = peasycap->allocation_audio_page;
+allocation_audio_struct = peasycap->allocation_audio_struct;
+registered_audio        = peasycap->registered_audio;
+m = 0;
+if ((struct easycap *)NULL != peasycap) {
+       kfree(peasycap);  peasycap = (struct easycap *)NULL;
+       allocation_video_struct -= sizeof(struct easycap);
+       m++;
+}
+JOT(4, "%i easycap structure freed\n", m);
+/*---------------------------------------------------------------------------*/
+
+SAY("%8i= video urbs     after all deletions\n", allocation_video_urb);
+SAY("%8i= video pages    after all deletions\n", allocation_video_page);
+SAY("%8i= video structs  after all deletions\n", allocation_video_struct);
+SAY("%8i= video devices  after all deletions\n", registered_video);
+SAY("%8i= audio urbs     after all deletions\n", allocation_audio_urb);
+SAY("%8i= audio pages    after all deletions\n", allocation_audio_page);
+SAY("%8i= audio structs  after all deletions\n", allocation_audio_struct);
+SAY("%8i= audio devices  after all deletions\n", registered_audio);
+
+JOT(4, "ending.\n");
+return;
+}
+/*****************************************************************************/
+unsigned int easycap_poll(struct file *file, poll_table *wait)
+{
+struct easycap *peasycap;
+
+JOT(8, "\n");
+
+if (NULL == ((poll_table *)wait))
+       JOT(8, "WARNING:  poll table pointer is NULL ... continuing\n");
+if (NULL == ((struct file *)file)) {
+       SAY("ERROR:  file pointer is NULL\n");
+       return -EFAULT;
+}
+peasycap = file->private_data;
+if (NULL == peasycap) {
+       SAY("ERROR:  peasycap is NULL\n");
+       return -EFAULT;
+}
+peasycap->polled = 1;
+
+if (0 == easycap_dqbuf(peasycap, 0))
+       return POLLIN | POLLRDNORM;
+else
+       return POLLERR;
+
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
+ */
+/*---------------------------------------------------------------------------*/
+int
+easycap_dqbuf(struct easycap *peasycap, int mode)
+{
+int miss, rc;
+
+JOT(8, "\n");
+
+if (NULL == peasycap) {
+       SAY("ERROR:  peasycap is NULL\n");
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  WAIT FOR FIELD 0
+ */
+/*---------------------------------------------------------------------------*/
+miss = 0;
+if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
+       return -ERESTARTSYS;
+while ((peasycap->field_read == peasycap->field_fill) || \
+                               (0 != (0xFF00 & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount)) || \
+                               (0 != (0x00FF & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount))) {
+       mutex_unlock(&(peasycap->mutex_mmap_video[0]));
+
+       if (mode)
+               return -EAGAIN;
+
+       JOT(8, "first wait  on wq_video, " \
+                               "%i=field_read  %i=field_fill\n", \
+                               peasycap->field_read, peasycap->field_fill);
+
+       msleep(1);
+       if (0 != (wait_event_interruptible(peasycap->wq_video, \
+                       (peasycap->video_idle || peasycap->video_eof  || \
+                       ((peasycap->field_read != peasycap->field_fill) && \
+                               (0 == (0xFF00 & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount)) && \
+                               (0 == (0x00FF & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount))))))){
+               SAY("aborted by signal\n");
+               return -EIO;
+               }
+       if (peasycap->video_idle) {
+               JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
+               return -EIO;
+       }
+       if (peasycap->video_eof) {
+               JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
+               debrief(peasycap);
+               kill_video_urbs(peasycap);
+               return -EIO;
+       }
+miss++;
+if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
+       return -ERESTARTSYS;
+}
+mutex_unlock(&(peasycap->mutex_mmap_video[0]));
+JOT(8, "first awakening on wq_video after %i waits\n", miss);
+
+rc = field2frame(peasycap);
+if (0 != rc)
+       SAY("ERROR: field2frame() returned %i\n", rc);
+
+if (true == peasycap->offerfields) {
+       peasycap->frame_read = peasycap->frame_fill;
+       (peasycap->frame_fill)++;
+       if (peasycap->frame_buffer_many <= peasycap->frame_fill)
+               peasycap->frame_fill = 0;
+
+       if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
+               peasycap->frame_buffer[peasycap->frame_read][0].kount = \
+                                                       V4L2_FIELD_BOTTOM;
+       } else {
+               peasycap->frame_buffer[peasycap->frame_read][0].kount = \
+                                                       V4L2_FIELD_TOP;
+       }
+JOT(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
+JOT(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  WAIT FOR FIELD 1
+ */
+/*---------------------------------------------------------------------------*/
+miss = 0;
+if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
+       return -ERESTARTSYS;
+while ((peasycap->field_read == peasycap->field_fill) || \
+                               (0 != (0xFF00 & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount)) || \
+                               (0 == (0x00FF & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount))) {
+       mutex_unlock(&(peasycap->mutex_mmap_video[0]));
+
+       if (mode)
+               return -EAGAIN;
+
+       JOT(8, "second wait on wq_video, " \
+                               "%i=field_read  %i=field_fill\n", \
+                               peasycap->field_read, peasycap->field_fill);
+       msleep(1);
+       if (0 != (wait_event_interruptible(peasycap->wq_video, \
+                       (peasycap->video_idle || peasycap->video_eof  || \
+                       ((peasycap->field_read != peasycap->field_fill) && \
+                               (0 == (0xFF00 & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount)) && \
+                               (0 != (0x00FF & peasycap->field_buffer\
+                                       [peasycap->field_read][0].kount))))))){
+               SAY("aborted by signal\n");
+               return -EIO;
+       }
+       if (peasycap->video_idle) {
+               JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
+               return -EIO;
+       }
+       if (peasycap->video_eof) {
+               JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
+               debrief(peasycap);
+               kill_video_urbs(peasycap);
+               return -EIO;
+       }
+miss++;
+if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
+       return -ERESTARTSYS;
+}
+mutex_unlock(&(peasycap->mutex_mmap_video[0]));
+JOT(8, "second awakening on wq_video after %i waits\n", miss);
+
+rc = field2frame(peasycap);
+if (0 != rc)
+       SAY("ERROR: field2frame() returned %i\n", rc);
+
+peasycap->frame_read = peasycap->frame_fill;
+peasycap->queued[peasycap->frame_read] = 0;
+peasycap->done[peasycap->frame_read]   = V4L2_BUF_FLAG_DONE;
+
+(peasycap->frame_fill)++;
+if (peasycap->frame_buffer_many <= peasycap->frame_fill)
+       peasycap->frame_fill = 0;
+
+if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
+       peasycap->frame_buffer[peasycap->frame_read][0].kount = \
+                                                       V4L2_FIELD_TOP;
+} else {
+       peasycap->frame_buffer[peasycap->frame_read][0].kount = \
+                                                       V4L2_FIELD_BOTTOM;
+}
+
+JOT(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
+JOT(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
+
+return 0;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  BY DEFINITION, odd IS true  FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
+ *                 odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
+ *
+ *  WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
+ *  odd==false IS TRANSFERRED TO THE FRAME BUFFER.
+ *
+ *  THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
+ *  CHOOSES THE OPTION V4L2_FIELD_ALTERNATE.  NO USERSPACE PROGRAM TESTED
+ *  TO DATE HAS DONE THIS.  BUGS ARE LIKELY.
+ */
+/*---------------------------------------------------------------------------*/
+int
+field2frame(struct easycap *peasycap)
+{
+static struct timeval timeval0;
+struct timeval timeval;
+long long int above, below;
+__u32 remainder;
+struct signed_div_result sdr;
+
+void *pex, *pad;
+int kex, kad, mex, mad, rex, rad, rad2;
+int c2, c3, w2, w3, cz, wz;
+int rc, bytesperpixel, multiplier, much, more, over, rump, caches;
+__u8 mask, margin;
+bool odd, isuy, decimatepixel, offerfields;
+
+JOT(8, "=====  parity %i, field buffer %i --> frame buffer %i\n", \
+                       peasycap->field_buffer[peasycap->field_read][0].kount,\
+                       peasycap->field_read, peasycap->frame_fill);
+JOT(8, "=====  %i=bytesperpixel\n", peasycap->bytesperpixel);
+if (true == peasycap->offerfields)
+       JOT(8, "===== offerfields\n");
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  REJECT OR CLEAN BAD FIELDS
+ */
+/*---------------------------------------------------------------------------*/
+if (peasycap->field_read == peasycap->field_fill) {
+       SAY("ERROR: on entry, still filling field buffer %i\n", \
+                                                       peasycap->field_read);
+       return 0;
+}
+#if defined(EASYCAP_TESTCARD)
+easycap_testcard(peasycap, peasycap->field_read);
+#else
+if (0 != (0x0400 & peasycap->field_buffer[peasycap->field_read][0].kount))
+       easycap_testcard(peasycap, peasycap->field_read);
+#endif /*EASYCAP_TESTCARD*/
+/*---------------------------------------------------------------------------*/
+
+offerfields = peasycap->offerfields;
+bytesperpixel = peasycap->bytesperpixel;
+decimatepixel = peasycap->decimatepixel;
+
+if ((2 != bytesperpixel) && \
+                       (3 != bytesperpixel) && \
+                       (4 != bytesperpixel)) {
+       SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
+       return -EFAULT;
+}
+if (true == decimatepixel)
+       multiplier = 2;
+else
+       multiplier = 1;
+
+w2 = 2 * multiplier * (peasycap->width);
+w3 = bytesperpixel * \
+               multiplier * \
+               (peasycap->width);
+wz = multiplier * \
+               (peasycap->height) * \
+               multiplier * \
+               (peasycap->width);
+
+kex = peasycap->field_read;  mex = 0;
+kad = peasycap->frame_fill;  mad = 0;
+
+pex = peasycap->field_buffer[kex][0].pgo;  rex = PAGE_SIZE;
+pad = peasycap->frame_buffer[kad][0].pgo;  rad = PAGE_SIZE;
+if (peasycap->field_buffer[kex][0].kount)
+       odd = true;
+else
+       odd = false;
+
+if ((true == odd) && (false == offerfields) &&(false == decimatepixel)) {
+       JOT(8, "  initial skipping    %4i          bytes p.%4i\n", \
+                                                       w3/multiplier, mad);
+       pad += (w3 / multiplier);  rad -= (w3 / multiplier);
+}
+isuy = true;
+mask = 0;  rump = 0;  caches = 0;
+
+cz = 0;
+while (cz < wz) {
+       /*-------------------------------------------------------------------*/
+       /*
+       **  PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
+       **  READ   w2   BYTES FROM FIELD BUFFER,
+       **  WRITE  w3   BYTES TO FRAME BUFFER
+       **/
+       /*-------------------------------------------------------------------*/
+       if (false == decimatepixel) {
+               over = w2;
+               do {
+                       much = over;  more = 0;  margin = 0;  mask = 0x00;
+                       if (rex < much)
+                               much = rex;
+                       rump = 0;
+
+                       if (much % 2) {
+                               SAY("MISTAKE: much is odd\n");
+                               return -EFAULT;
+                       }
+
+                       more = (bytesperpixel * \
+                                       much) / 2;
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+                       if (1 < bytesperpixel) {
+                               if ((rad * \
+                                       2) < (much * \
+                                               bytesperpixel)) {
+                                       /*
+                                       **   INJUDICIOUS ALTERATION OF THIS
+                                       **   BLOCK WILL CAUSE BREAKAGE.
+                                       **   BEWARE.
+                                       **/
+                                       rad2 = rad + bytesperpixel - 1;
+                                       much = ((((2 * \
+                                               rad2)/bytesperpixel)/2) * 2);
+                                       rump = ((bytesperpixel * \
+                                                       much) / 2) - rad;
+                                       more = rad;
+                                       }
+                               mask = (__u8)rump;
+                               margin = 0;
+                               if (much == rex) {
+                                       mask |= 0x04;
+                                       if ((mex + 1) < FIELD_BUFFER_SIZE/ \
+                                                               PAGE_SIZE) {
+                                               margin = *((__u8 *)(peasycap->\
+                                                       field_buffer\
+                                                       [kex][mex + 1].pgo));
+                                       } else
+                                               mask |= 0x08;
+                               }
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+                       } else {
+                               SAY("MISTAKE: %i=bytesperpixel\n", \
+                                               bytesperpixel);
+                               return -EFAULT;
+                       }
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+                       if (rump)
+                               caches++;
+
+                       rc = redaub(peasycap, pad, pex, much, more, \
+                                                       mask, margin, isuy);
+                       if (0 > rc) {
+                               SAY("ERROR: redaub() failed\n");
+                               return -EFAULT;
+                       }
+                       if (much % 4) {
+                               if (isuy)
+                                       isuy = false;
+                               else
+                                       isuy = true;
+                       }
+                       over -= much;   cz += much;
+                       pex  += much;  rex -= much;
+                       if (!rex) {
+                               mex++;
+                               pex = peasycap->field_buffer[kex][mex].pgo;
+                               rex = PAGE_SIZE;
+                       }
+                       pad  += more;
+                       rad -= more;
+                       if (!rad) {
+                               mad++;
+                               pad = peasycap->frame_buffer[kad][mad].pgo;
+                               rad = PAGE_SIZE;
+                               if (rump) {
+                                       pad += rump;
+                                       rad -= rump;
+                               }
+                       }
+               } while (over);
+/*---------------------------------------------------------------------------*/
+/*
+ *  SKIP  w3 BYTES IN TARGET FRAME BUFFER,
+ *  UNLESS IT IS THE LAST LINE OF AN ODD FRAME
+ */
+/*---------------------------------------------------------------------------*/
+               if (((false == odd) || (cz != wz))&&(false == offerfields)) {
+                       over = w3;
+                       do {
+                               if (!rad) {
+                                       mad++;
+                                       pad = peasycap->frame_buffer\
+                                               [kad][mad].pgo;
+                                       rad = PAGE_SIZE;
+                               }
+                               more = over;
+                               if (rad < more)
+                                       more = rad;
+                               over -= more;
+                               pad  += more;
+                               rad  -= more;
+                       } while (over);
+               }
+/*---------------------------------------------------------------------------*/
+/*
+ *  PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
+ *  ONLY IF false==odd,
+ *  READ   w2   BYTES FROM FIELD BUFFER,
+ *  WRITE  w3 / 2  BYTES TO FRAME BUFFER
+ */
+/*---------------------------------------------------------------------------*/
+       } else if (false == odd) {
+               over = w2;
+               do {
+                       much = over;  more = 0;  margin = 0;  mask = 0x00;
+                       if (rex < much)
+                               much = rex;
+                       rump = 0;
+
+                       if (much % 2) {
+                               SAY("MISTAKE: much is odd\n");
+                               return -EFAULT;
+                       }
+
+                       more = (bytesperpixel * \
+                                       much) / 4;
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+                       if (1 < bytesperpixel) {
+                               if ((rad * 4) < (much * \
+                                               bytesperpixel)) {
+                                       /*
+                                       **   INJUDICIOUS ALTERATION OF THIS
+                                       **   BLOCK WILL CAUSE BREAKAGE.
+                                       **   BEWARE.
+                                       **/
+                                       rad2 = rad + bytesperpixel - 1;
+                                       much = ((((2 * rad2)/bytesperpixel)/2)\
+                                                                       * 4);
+                                       rump = ((bytesperpixel * \
+                                                       much) / 4) - rad;
+                                       more = rad;
+                                       }
+                               mask = (__u8)rump;
+                               margin = 0;
+                               if (much == rex) {
+                                       mask |= 0x04;
+                                       if ((mex + 1) < FIELD_BUFFER_SIZE/ \
+                                                               PAGE_SIZE) {
+                                               margin = *((__u8 *)(peasycap->\
+                                                       field_buffer\
+                                                       [kex][mex + 1].pgo));
+                                               }
+                                       else
+                                               mask |= 0x08;
+                                       }
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+                               } else {
+                                       SAY("MISTAKE: %i=bytesperpixel\n", \
+                                               bytesperpixel);
+                                       return -EFAULT;
+                               }
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+                       if (rump)
+                               caches++;
+
+                       rc = redaub(peasycap, pad, pex, much, more, \
+                                                       mask, margin, isuy);
+                       if (0 > rc) {
+                               SAY("ERROR: redaub() failed\n");
+                               return -EFAULT;
+                       }
+                       over -= much;   cz += much;
+                       pex  += much;  rex -= much;
+                       if (!rex) {
+                               mex++;
+                               pex = peasycap->field_buffer[kex][mex].pgo;
+                               rex = PAGE_SIZE;
+                       }
+                       pad  += more;
+                       rad -= more;
+                       if (!rad) {
+                               mad++;
+                               pad = peasycap->frame_buffer[kad][mad].pgo;
+                               rad = PAGE_SIZE;
+                               if (rump) {
+                                       pad += rump;
+                                       rad -= rump;
+                               }
+                       }
+               } while (over);
+/*---------------------------------------------------------------------------*/
+/*
+ *  OTHERWISE JUST
+ *  READ   w2   BYTES FROM FIELD BUFFER AND DISCARD THEM
+ */
+/*---------------------------------------------------------------------------*/
+       } else {
+               over = w2;
+               do {
+                       if (!rex) {
+                               mex++;
+                               pex = peasycap->field_buffer[kex][mex].pgo;
+                               rex = PAGE_SIZE;
+                       }
+                       much = over;
+                       if (rex < much)
+                               much = rex;
+                       over -= much;
+                       cz += much;
+                       pex  += much;
+                       rex -= much;
+               } while (over);
+       }
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  SANITY CHECKS
+ */
+/*---------------------------------------------------------------------------*/
+c2 = (mex + 1)*PAGE_SIZE - rex;
+if (cz != c2)
+       SAY("ERROR: discrepancy %i in bytes read\n", c2 - cz);
+c3 = (mad + 1)*PAGE_SIZE - rad;
+
+if (false == decimatepixel) {
+       if (bytesperpixel * \
+               cz != c3) \
+               SAY("ERROR: discrepancy %i in bytes written\n", \
+                                               c3 - (bytesperpixel * \
+                                                                       cz));
+} else {
+       if (false == odd) {
+               if (bytesperpixel * \
+                       cz != (4 * c3))
+                       SAY("ERROR: discrepancy %i in bytes written\n", \
+                                               (2*c3)-(bytesperpixel * \
+                                                                       cz));
+               } else {
+                       if (0 != c3)
+                               SAY("ERROR: discrepancy %i " \
+                                               "in bytes written\n", c3);
+               }
+}
+if (rump)
+       SAY("ERROR: undischarged cache at end of line in frame buffer\n");
+
+JOT(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
+JOT(8, "===== field2frame(): %i=mad  %i=rad\n", mad, rad);
+
+if (true == odd)
+       JOT(8, "+++++ field2frame():  frame buffer %i is full\n", kad);
+
+if (peasycap->field_read == peasycap->field_fill)
+       SAY("WARNING: on exit, filling field buffer %i\n", \
+                                                       peasycap->field_read);
+/*---------------------------------------------------------------------------*/
+/*
+ *  CALCULATE VIDEO STREAMING RATE
+ */
+/*---------------------------------------------------------------------------*/
+do_gettimeofday(&timeval);
+if (timeval0.tv_sec) {
+       below = ((long long int)(1000000)) * \
+               ((long long int)(timeval.tv_sec  - timeval0.tv_sec)) + \
+                        (long long int)(timeval.tv_usec - timeval0.tv_usec);
+       above = (long long int)1000000;
+
+       sdr = signed_div(above, below);
+       above = sdr.quotient;
+       remainder = (__u32)sdr.remainder;
+
+       JOT(8, "video streaming at %3lli.%03i fields per second\n", above, \
+                                                       (remainder/1000));
+}
+timeval0 = timeval;
+
+if (caches)
+       JOT(8, "%i=caches\n", caches);
+return 0;
+}
+/*****************************************************************************/
+struct signed_div_result
+signed_div(long long int above, long long int below)
+{
+struct signed_div_result sdr;
+
+if (((0 <= above) && (0 <= below)) || ((0  > above) && (0  > below))) {
+       sdr.remainder = (unsigned long long int) do_div(above, below);
+       sdr.quotient  = (long long int) above;
+} else {
+       if (0 > above)
+               above = -above;
+       if (0 > below)
+               below = -below;
+       sdr.remainder = (unsigned long long int) do_div(above, below);
+       sdr.quotient  = -((long long int) above);
+}
+return sdr;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  DECIMATION AND COLOURSPACE CONVERSION.
+ *
+ *  THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
+ *  AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
+ *  THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
+ *  ALSO ENSURE THAT much IS EVEN.
+ *
+ *  much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
+ *  IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
+ *
+ *  mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
+ *     0x03 & mask =  number of bytes to be written to cache instead of to
+ *                    frame buffer
+ *     0x04 & mask => use argument margin to set the chrominance for last pixel
+ *     0x08 & mask => do not set the chrominance for last pixel
+ *
+ *  YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
+ *
+ *  THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
+ *  INEFFICIENT SWITCHING INSIDE INNER LOOPS.  REARRANGING THE LOGIC TO
+ *  REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE.  BEWARE.
+ */
+/*---------------------------------------------------------------------------*/
+int
+redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, \
+                                       __u8 mask, __u8 margin, bool isuy)
+{
+static __s32 ay[256], bu[256], rv[256], gu[256], gv[256];
+static __u8 cache[8], *pcache;
+__u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
+int  bytesperpixel;
+bool byteswaporder, decimatepixel, last;
+int j, rump;
+__s32 s32;
+
+if (much % 2) {
+       SAY("MISTAKE: much is odd\n");
+       return -EFAULT;
+}
+bytesperpixel = peasycap->bytesperpixel;
+byteswaporder = peasycap->byteswaporder;
+decimatepixel = peasycap->decimatepixel;
+
+/*---------------------------------------------------------------------------*/
+if (!bu[255]) {
+       for (j = 0; j < 112; j++) {
+               s32 = (0xFF00 & (453 * j)) >> 8;
+               bu[j + 128] =  s32; bu[127 - j] = -s32;
+               s32 = (0xFF00 & (359 * j)) >> 8;
+               rv[j + 128] =  s32; rv[127 - j] = -s32;
+               s32 = (0xFF00 & (88 * j)) >> 8;
+               gu[j + 128] =  s32; gu[127 - j] = -s32;
+               s32 = (0xFF00 & (183 * j)) >> 8;
+               gv[j + 128] =  s32; gv[127 - j] = -s32;
+       }
+       for (j = 0; j < 16; j++) {
+               bu[j] = bu[16]; rv[j] = rv[16];
+               gu[j] = gu[16]; gv[j] = gv[16];
+       }
+       for (j = 240; j < 256; j++) {
+               bu[j] = bu[239]; rv[j] = rv[239];
+               gu[j] = gu[239]; gv[j] = gv[239];
+       }
+       for (j =  16; j < 236; j++)
+               ay[j] = j;
+       for (j =   0; j <  16; j++)
+               ay[j] = ay[16];
+       for (j = 236; j < 256; j++)
+               ay[j] = ay[235];
+       JOT(8, "lookup tables are prepared\n");
+}
+if ((__u8 *)NULL == pcache)
+       pcache = &cache[0];
+/*---------------------------------------------------------------------------*/
+/*
+ *  TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
+ */
+/*---------------------------------------------------------------------------*/
+if (!pcache) {
+       SAY("MISTAKE: pcache is NULL\n");
+       return -EFAULT;
+}
+
+if (pcache != &cache[0])
+       JOT(16, "cache has %i bytes\n", (int)(pcache - &cache[0]));
+p2 = &cache[0];
+p3 = (__u8 *)pad - (int)(pcache - &cache[0]);
+while (p2 < pcache) {
+       *p3++ = *p2;  p2++;
+}
+pcache = &cache[0];
+if (p3 != pad) {
+       SAY("MISTAKE: pointer misalignment\n");
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+rump = (int)(0x03 & mask);
+u = 0; v = 0;
+p2 = (__u8 *)pex;  pz = p2 + much;  pr = p3 + more;  last = false;
+p2++;
+
+if (true == isuy)
+       u = *(p2 - 1);
+else
+       v = *(p2 - 1);
+
+if (rump)
+       JOT(16, "%4i=much  %4i=more  %i=rump\n", much, more, rump);
+
+/*---------------------------------------------------------------------------*/
+switch (bytesperpixel) {
+case 2: {
+       if (false == decimatepixel) {
+               memcpy(pad, pex, (size_t)much);
+               if (false == byteswaporder)
+                       /*---------------------------------------------------*/
+                       /*
+                       **  UYVY
+                       */
+                       /*---------------------------------------------------*/
+                       return 0;
+               else {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  YUYV
+                       */
+                       /*---------------------------------------------------*/
+                       p3 = (__u8 *)pad;  pz = p3 + much;
+                       while  (pz > p3) {
+                               c = *p3;
+                               *p3 = *(p3 + 1);
+                               *(p3 + 1) = c;
+                               p3 += 2;
+                       }
+                       return 0;
+               }
+       } else {
+               if (false == byteswaporder) {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  UYVY DECIMATED
+                       */
+                       /*---------------------------------------------------*/
+                       p2 = (__u8 *)pex;  p3 = (__u8 *)pad;  pz = p2 + much;
+                       while (pz > p2) {
+                               *p3 = *p2;
+                               *(p3 + 1) = *(p2 + 1);
+                               *(p3 + 2) = *(p2 + 2);
+                               *(p3 + 3) = *(p2 + 3);
+                               p3 += 4;  p2 += 8;
+                       }
+                       return 0;
+               } else {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  YUYV DECIMATED
+                       **/
+                       /*---------------------------------------------------*/
+                       p2 = (__u8 *)pex;  p3 = (__u8 *)pad;  pz = p2 + much;
+                       while (pz > p2) {
+                               *p3 = *(p2 + 1);
+                               *(p3 + 1) = *p2;
+                               *(p3 + 2) = *(p2 + 3);
+                               *(p3 + 3) = *(p2 + 2);
+                               p3 += 4;  p2 += 8;
+                       }
+                       return 0;
+               }
+       }
+       break;
+       }
+case 3:
+       {
+       if (false == decimatepixel) {
+               if (false == byteswaporder) {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  RGB
+                       **/
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       } else
+                                               if (0x08 & mask)
+                                                       ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               s32 = ay[(int)y] + rv[(int)v];
+                               r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                       0 : (__u8)s32);
+                               s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
+                               g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                       0 : (__u8)s32);
+                               s32 = ay[(int)y] + bu[(int)u];
+                               b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                       0 : (__u8)s32);
+
+                               if ((true == last) && rump) {
+                                       pcache = &cache[0];
+                                       switch (bytesperpixel - rump) {
+                                       case 1: {
+                                               *p3 = r;
+                                               *pcache++ = g;
+                                               *pcache++ = b;
+                                               break;
+                                       }
+                                       case 2: {
+                                               *p3 = r;
+                                               *(p3 + 1) = g;
+                                               *pcache++ = b;
+                                               break;
+                                       }
+                                       default: {
+                                               SAY("MISTAKE: %i=rump\n", \
+                                                       bytesperpixel - rump);
+                                               return -EFAULT;
+                                       }
+                                       }
+                               } else {
+                                       *p3 = r;
+                                       *(p3 + 1) = g;
+                                       *(p3 + 2) = b;
+                               }
+                               p2 += 2;
+                               if (true == isuy)
+                                       isuy = false;
+                               else
+                                       isuy = true;
+                               p3 += bytesperpixel;
+                       }
+                       return 0;
+               } else {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  BGR
+                       */
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       }
+                               else
+                                       if (0x08 & mask)
+                                               ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               s32 = ay[(int)y] + rv[(int)v];
+                               r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                               s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
+                               g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                               s32 = ay[(int)y] + bu[(int)u];
+                               b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+
+                               if ((true == last) && rump) {
+                                       pcache = &cache[0];
+                                       switch (bytesperpixel - rump) {
+                                       case 1: {
+                                               *p3 = b;
+                                               *pcache++ = g;
+                                               *pcache++ = r;
+                                               break;
+                                       }
+                                       case 2: {
+                                               *p3 = b;
+                                               *(p3 + 1) = g;
+                                               *pcache++ = r;
+                                               break;
+                                       }
+                                       default: {
+                                               SAY("MISTAKE: %i=rump\n", \
+                                                       bytesperpixel - rump);
+                                               return -EFAULT;
+                                       }
+                                       }
+                               } else {
+                                       *p3 = b;
+                                       *(p3 + 1) = g;
+                                       *(p3 + 2) = r;
+                                       }
+                               p2 += 2;
+                               if (true == isuy)
+                                       isuy = false;
+                               else
+                                       isuy = true;
+                               p3 += bytesperpixel;
+                               }
+                       }
+               return 0;
+       } else {
+               if (false == byteswaporder) {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  RGB DECIMATED
+                       */
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       } else
+                                               if (0x08 & mask)
+                                                       ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               if (true == isuy) {
+                                       s32 = ay[(int)y] + rv[(int)v];
+                                       r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] - gu[(int)u] - \
+                                                               gv[(int)v];
+                                       g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] + bu[(int)u];
+                                       b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+
+                                       if ((true == last) && rump) {
+                                               pcache = &cache[0];
+                                               switch (bytesperpixel - rump) {
+                                               case 1: {
+                                                       *p3 = r;
+                                                       *pcache++ = g;
+                                                       *pcache++ = b;
+                                                       break;
+                                               }
+                                               case 2: {
+                                                       *p3 = r;
+                                                       *(p3 + 1) = g;
+                                                       *pcache++ = b;
+                                                       break;
+                                               }
+                                               default: {
+                                                       SAY("MISTAKE: " \
+                                                       "%i=rump\n", \
+                                                       bytesperpixel - rump);
+                                                       return -EFAULT;
+                                               }
+                                               }
+                                       } else {
+                                               *p3 = r;
+                                               *(p3 + 1) = g;
+                                               *(p3 + 2) = b;
+                                       }
+                                       isuy = false;
+                                       p3 += bytesperpixel;
+                               } else {
+                                       isuy = true;
+                               }
+                               p2 += 2;
+                       }
+                       return 0;
+               } else {
+                       /*---------------------------------------------------*/
+                       /*
+                        *  BGR DECIMATED
+                        */
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       } else
+                                               if (0x08 & mask)
+                                                       ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               if (true == isuy) {
+
+                                       s32 = ay[(int)y] + rv[(int)v];
+                                       r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] - gu[(int)u] - \
+                                                               gv[(int)v];
+                                       g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] + bu[(int)u];
+                                       b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+
+                                       if ((true == last) && rump) {
+                                               pcache = &cache[0];
+                                               switch (bytesperpixel - rump) {
+                                               case 1: {
+                                                       *p3 = b;
+                                                       *pcache++ = g;
+                                                       *pcache++ = r;
+                                                       break;
+                                               }
+                                               case 2: {
+                                                       *p3 = b;
+                                                       *(p3 + 1) = g;
+                                                       *pcache++ = r;
+                                                       break;
+                                               }
+                                               default: {
+                                                       SAY("MISTAKE: " \
+                                                       "%i=rump\n", \
+                                                       bytesperpixel - rump);
+                                                       return -EFAULT;
+                                               }
+                                               }
+                                       } else {
+                                               *p3 = b;
+                                               *(p3 + 1) = g;
+                                               *(p3 + 2) = r;
+                                               }
+                                       isuy = false;
+                                       p3 += bytesperpixel;
+                                       }
+                               else
+                                       isuy = true;
+                               p2 += 2;
+                               }
+                       return 0;
+                       }
+               }
+       break;
+       }
+case 4:
+       {
+       if (false == decimatepixel) {
+               if (false == byteswaporder) {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  RGBA
+                       */
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       } else
+                                                if (0x08 & mask)
+                                                       ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               s32 = ay[(int)y] + rv[(int)v];
+                               r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                               s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
+                               g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                               s32 = ay[(int)y] + bu[(int)u];
+                               b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+
+                               if ((true == last) && rump) {
+                                       pcache = &cache[0];
+                                       switch (bytesperpixel - rump) {
+                                       case 1: {
+                                               *p3 = r;
+                                               *pcache++ = g;
+                                               *pcache++ = b;
+                                               *pcache++ = 0;
+                                               break;
+                                       }
+                                       case 2: {
+                                               *p3 = r;
+                                               *(p3 + 1) = g;
+                                               *pcache++ = b;
+                                               *pcache++ = 0;
+                                               break;
+                                       }
+                                       case 3: {
+                                               *p3 = r;
+                                               *(p3 + 1) = g;
+                                               *(p3 + 2) = b;
+                                               *pcache++ = 0;
+                                               break;
+                                       }
+                                       default: {
+                                               SAY("MISTAKE: %i=rump\n", \
+                                                       bytesperpixel - rump);
+                                               return -EFAULT;
+                                       }
+                                       }
+                               } else {
+                                       *p3 = r;
+                                       *(p3 + 1) = g;
+                                       *(p3 + 2) = b;
+                                       *(p3 + 3) = 0;
+                               }
+                               p2 += 2;
+                               if (true == isuy)
+                                       isuy = false;
+                               else
+                                       isuy = true;
+                               p3 += bytesperpixel;
+                       }
+                       return 0;
+               } else {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  BGRA
+                       */
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       } else
+                                                if (0x08 & mask)
+                                                       ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               s32 = ay[(int)y] + rv[(int)v];
+                               r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                               s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
+                               g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                               s32 = ay[(int)y] + bu[(int)u];
+                               b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+
+                               if ((true == last) && rump) {
+                                       pcache = &cache[0];
+                                       switch (bytesperpixel - rump) {
+                                       case 1: {
+                                               *p3 = b;
+                                               *pcache++ = g;
+                                               *pcache++ = r;
+                                               *pcache++ = 0;
+                                               break;
+                                       }
+                                       case 2: {
+                                               *p3 = b;
+                                               *(p3 + 1) = g;
+                                               *pcache++ = r;
+                                               *pcache++ = 0;
+                                               break;
+                                       }
+                                       case 3: {
+                                               *p3 = b;
+                                               *(p3 + 1) = g;
+                                               *(p3 + 2) = r;
+                                               *pcache++ = 0;
+                                               break;
+                                       }
+                                       default: {
+                                               SAY("MISTAKE: %i=rump\n", \
+                                                       bytesperpixel - rump);
+                                               return -EFAULT;
+                                       }
+                                       }
+                               } else {
+                                       *p3 = b;
+                                       *(p3 + 1) = g;
+                                       *(p3 + 2) = r;
+                                       *(p3 + 3) = 0;
+                               }
+                               p2 += 2;
+                               if (true == isuy)
+                                       isuy = false;
+                               else
+                                       isuy = true;
+                               p3 += bytesperpixel;
+                       }
+               }
+               return 0;
+       } else {
+               if (false == byteswaporder) {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  RGBA DECIMATED
+                       */
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       } else
+                                               if (0x08 & mask)
+                                                       ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               if (true == isuy) {
+
+                                       s32 = ay[(int)y] + rv[(int)v];
+                                       r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] - gu[(int)u] - \
+                                                               gv[(int)v];
+                                       g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] + bu[(int)u];
+                                       b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+
+                                       if ((true == last) && rump) {
+                                               pcache = &cache[0];
+                                               switch (bytesperpixel - rump) {
+                                               case 1: {
+                                                       *p3 = r;
+                                                       *pcache++ = g;
+                                                       *pcache++ = b;
+                                                       *pcache++ = 0;
+                                                       break;
+                                               }
+                                               case 2: {
+                                                       *p3 = r;
+                                                       *(p3 + 1) = g;
+                                                       *pcache++ = b;
+                                                       *pcache++ = 0;
+                                                       break;
+                                               }
+                                               case 3: {
+                                                       *p3 = r;
+                                                       *(p3 + 1) = g;
+                                                       *(p3 + 2) = b;
+                                                       *pcache++ = 0;
+                                                       break;
+                                               }
+                                               default: {
+                                                       SAY("MISTAKE: " \
+                                                       "%i=rump\n", \
+                                                       bytesperpixel - \
+                                                       rump);
+                                                       return -EFAULT;
+                                                       }
+                                               }
+                                       } else {
+                                               *p3 = r;
+                                               *(p3 + 1) = g;
+                                               *(p3 + 2) = b;
+                                               *(p3 + 3) = 0;
+                                               }
+                                       isuy = false;
+                                       p3 += bytesperpixel;
+                               } else
+                                       isuy = true;
+                               p2 += 2;
+                       }
+                       return 0;
+               } else {
+                       /*---------------------------------------------------*/
+                       /*
+                       **  BGRA DECIMATED
+                       */
+                       /*---------------------------------------------------*/
+                       while (pz > p2) {
+                               if (pr <= (p3 + bytesperpixel))
+                                       last = true;
+                               else
+                                       last = false;
+                               y = *p2;
+                               if ((true == last) && (0x0C & mask)) {
+                                       if (0x04 & mask) {
+                                               if (true == isuy)
+                                                       v = margin;
+                                               else
+                                                       u = margin;
+                                       } else
+                                               if (0x08 & mask)
+                                                       ;
+                               } else {
+                                       if (true == isuy)
+                                               v = *(p2 + 1);
+                                       else
+                                               u = *(p2 + 1);
+                               }
+
+                               if (true == isuy) {
+                                       s32 = ay[(int)y] + rv[(int)v];
+                                       r = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] - gu[(int)u] - \
+                                                               gv[(int)v];
+                                       g = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+                                       s32 = ay[(int)y] + bu[(int)u];
+                                       b = (255 < s32) ? 255 : ((0 > s32) ? \
+                                                               0 : (__u8)s32);
+
+                                       if ((true == last) && rump) {
+                                               pcache = &cache[0];
+                                               switch (bytesperpixel - rump) {
+                                               case 1: {
+                                                       *p3 = b;
+                                                       *pcache++ = g;
+                                                       *pcache++ = r;
+                                                       *pcache++ = 0;
+                                                       break;
+                                               }
+                                               case 2: {
+                                                       *p3 = b;
+                                                       *(p3 + 1) = g;
+                                                       *pcache++ = r;
+                                                       *pcache++ = 0;
+                                                       break;
+                                               }
+                                               case 3: {
+                                                       *p3 = b;
+                                                       *(p3 + 1) = g;
+                                                       *(p3 + 2) = r;
+                                                       *pcache++ = 0;
+                                                       break;
+                                               }
+                                               default: {
+                                                       SAY("MISTAKE: " \
+                                                       "%i=rump\n", \
+                                                       bytesperpixel - rump);
+                                                       return -EFAULT;
+                                               }
+                                               }
+                                       } else {
+                                               *p3 = b;
+                                               *(p3 + 1) = g;
+                                               *(p3 + 2) = r;
+                                               *(p3 + 3) = 0;
+                                       }
+                                       isuy = false;
+                                       p3 += bytesperpixel;
+                               } else
+                                       isuy = true;
+                                       p2 += 2;
+                               }
+                               return 0;
+                       }
+               }
+       break;
+       }
+default: {
+       SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
+       return -EFAULT;
+       }
+}
+return 0;
+}
+/*****************************************************************************/
+void
+debrief(struct easycap *peasycap)
+{
+if ((struct usb_device *)NULL != peasycap->pusb_device) {
+       check_stk(peasycap->pusb_device);
+       check_saa(peasycap->pusb_device);
+       sayreadonly(peasycap);
+       SAY("%i=peasycap->field_fill\n", peasycap->field_fill);
+       SAY("%i=peasycap->field_read\n", peasycap->field_read);
+       SAY("%i=peasycap->frame_fill\n", peasycap->frame_fill);
+       SAY("%i=peasycap->frame_read\n", peasycap->frame_read);
+}
+return;
+}
+/*****************************************************************************/
+void
+sayreadonly(struct easycap *peasycap)
+{
+static int done;
+int got00, got1F, got60, got61, got62;
+
+if ((!done) && ((struct usb_device *)NULL != peasycap->pusb_device)) {
+       done = 1;
+       got00 = read_saa(peasycap->pusb_device, 0x00);
+       got1F = read_saa(peasycap->pusb_device, 0x1F);
+       got60 = read_saa(peasycap->pusb_device, 0x60);
+       got61 = read_saa(peasycap->pusb_device, 0x61);
+       got62 = read_saa(peasycap->pusb_device, 0x62);
+       SAY("0x%02X=reg0x00  0x%02X=reg0x1F\n", got00, got1F);
+       SAY("0x%02X=reg0x60  0x%02X=reg0x61  0x%02X=reg0x62\n", \
+                                                       got60, got61, got62);
+}
+return;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
+ */
+/*---------------------------------------------------------------------------*/
+int easycap_mmap(struct file *file, struct vm_area_struct *pvma)
+{
+
+JOT(8, "\n");
+
+pvma->vm_ops = &easycap_vm_ops;
+pvma->vm_flags |= VM_RESERVED;
+if (NULL != file)
+       pvma->vm_private_data = file->private_data;
+easycap_vma_open(pvma);
+return 0;
+}
+/*****************************************************************************/
+void
+easycap_vma_open(struct vm_area_struct *pvma)
+{
+struct easycap *peasycap;
+
+peasycap = pvma->vm_private_data;
+if (NULL != peasycap)
+       peasycap->vma_many++;
+
+JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
+
+return;
+}
+/*****************************************************************************/
+void
+easycap_vma_close(struct vm_area_struct *pvma)
+{
+struct easycap *peasycap;
+
+peasycap = pvma->vm_private_data;
+if (NULL != peasycap) {
+       peasycap->vma_many--;
+       JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
+}
+return;
+}
+/*****************************************************************************/
+int
+easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf)
+{
+int k, m, retcode;
+void *pbuf;
+struct page *page;
+struct easycap *peasycap;
+
+retcode = VM_FAULT_NOPAGE;
+pbuf = (void *)NULL;
+page = (struct page *)NULL;
+
+if (NULL == pvma) {
+       SAY("pvma is NULL\n");
+       return retcode;
+}
+if (NULL == pvmf) {
+       SAY("pvmf is NULL\n");
+       return retcode;
+}
+
+k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE);
+m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE);
+
+if (!m)
+       JOT(4, "%4i=k, %4i=m\n", k, m);
+else
+       JOT(16, "%4i=k, %4i=m\n", k, m);
+
+if ((0 > k) || (FRAME_BUFFER_MANY <= k)) {
+       SAY("ERROR: buffer index %i out of range\n", k);
+       return retcode;
+}
+if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) {
+       SAY("ERROR: page number  %i out of range\n", m);
+       return retcode;
+}
+peasycap = pvma->vm_private_data;
+if (NULL == peasycap) {
+       SAY("ERROR: peasycap is NULL\n");
+       return retcode;
+}
+mutex_lock(&(peasycap->mutex_mmap_video[0]));
+/*---------------------------------------------------------------------------*/
+pbuf = peasycap->frame_buffer[k][m].pgo;
+if (NULL == pbuf) {
+       SAY("ERROR:  pbuf is NULL\n");
+       goto finish;
+}
+page = virt_to_page(pbuf);
+if (NULL == page) {
+       SAY("ERROR:  page is NULL\n");
+       goto finish;
+}
+get_page(page);
+/*---------------------------------------------------------------------------*/
+finish:
+mutex_unlock(&(peasycap->mutex_mmap_video[0]));
+if (NULL == page) {
+       SAY("ERROR:  page is NULL after get_page(page)\n");
+} else {
+       pvmf->page = page;
+       retcode = VM_FAULT_MINOR;
+}
+return retcode;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
+ *  PROVIDED peasycap->video_idle IS ZER0.  REGARDLESS OF THIS BEING TRUE,
+ *  IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
+ *
+ *  THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
+ *
+ *  INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
+ *  STORED IN THE TWO-BYTE STATUS PARAMETER
+ *        peasycap->field_buffer[peasycap->field_fill][0].kount
+ *  NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
+ *
+ *  THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
+ *  CHIP.
+ *
+ *  THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
+ *      0 != (kount & 0x8000)   => AT LEAST ONE URB COMPLETED WITH ERRORS
+ *      0 != (kount & 0x4000)   => BUFFER HAS TOO MUCH DATA
+ *      0 != (kount & 0x2000)   => BUFFER HAS NOT ENOUGH DATA
+ *      0 != (kount & 0x0400)   => FIELD WAS SUBMITTED BY BRIDGER ROUTINE
+ *      0 != (kount & 0x0200)   => FIELD BUFFER NOT YET CHECKED
+ *      0 != (kount & 0x0100)   => BUFFER HAS TWO EXTRA BYTES - WHY?
+ */
+/*---------------------------------------------------------------------------*/
+void
+easycap_complete(struct urb *purb)
+{
+static int mt;
+struct easycap *peasycap;
+struct data_buffer *pfield_buffer;
+char errbuf[16];
+int i, more, much, leap, rc, last;
+int videofieldamount;
+unsigned int override;
+int framestatus, framelength, frameactual, frameoffset;
+__u8 *pu;
+#if defined(BRIDGER)
+struct timeval timeval;
+long long usec;
+#endif /*BRIDGER*/
+
+if (NULL == purb) {
+       SAY("ERROR: easycap_complete(): purb is NULL\n");
+       return;
+}
+peasycap = purb->context;
+if (NULL == peasycap) {
+       SAY("ERROR: easycap_complete(): peasycap is NULL\n");
+       return;
+}
+
+if (peasycap->video_eof)
+       return;
+
+for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
+       if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
+               break;
+JOT(16, "%2i=urb\n", i);
+last = peasycap->video_isoc_sequence;
+if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \
+                                               (0 != i)) || \
+       (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \
+                                               ((last + 1) != i))) {
+       SAY("ERROR: out-of-order urbs %i,%i ... continuing\n", last, i);
+}
+peasycap->video_isoc_sequence = i;
+
+if (peasycap->video_idle) {
+       JOT(16, "%i=video_idle  %i=video_isoc_streaming\n", \
+                       peasycap->video_idle, peasycap->video_isoc_streaming);
+       if (peasycap->video_isoc_streaming) {
+               rc = usb_submit_urb(purb, GFP_ATOMIC);
+               if (0 != rc) {
+                       SAY("ERROR: while %i=video_idle, " \
+                                       "usb_submit_urb() failed with rc:\n", \
+                                                       peasycap->video_idle);
+                       switch (rc) {
+                       case -ENOMEM: {
+                               SAY("ENOMEM\n");
+                               break;
+                       }
+                       case -ENODEV: {
+                               SAY("ENODEV\n");
+                               break;
+                       }
+                       case -ENXIO: {
+                               SAY("ENXIO\n");
+                               break;
+                       }
+                       case -EINVAL: {
+                               SAY("EINVAL\n");
+                               break;
+                       }
+                       case -EAGAIN: {
+                               SAY("EAGAIN\n");
+                               break;
+                       }
+                       case -EFBIG: {
+                               SAY("EFBIG\n");
+                               break;
+                       }
+                       case -EPIPE: {
+                               SAY("EPIPE\n");
+                               break;
+                       }
+                       case -EMSGSIZE: {
+                               SAY("EMSGSIZE\n");
+                               break;
+                       }
+                       case -ENOSPC: {
+                               SAY("ENOSPC\n");
+                               break;
+                       }
+                       default: {
+                               SAY("0x%08X\n", rc);
+                               break;
+                       }
+                       }
+               }
+       }
+return;
+}
+override = 0;
+/*---------------------------------------------------------------------------*/
+if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
+       SAY("ERROR: bad peasycap->field_fill\n");
+       return;
+}
+if (purb->status) {
+       if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
+               JOT(8, "urb status -ESHUTDOWN or -ENOENT\n");
+               return;
+       }
+
+       (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
+       SAY("ERROR: bad urb status:\n");
+       switch (purb->status) {
+       case -EINPROGRESS: {
+               SAY("-EINPROGRESS\n"); break;
+       }
+       case -ENOSR: {
+               SAY("-ENOSR\n"); break;
+       }
+       case -EPIPE: {
+               SAY("-EPIPE\n"); break;
+       }
+       case -EOVERFLOW: {
+               SAY("-EOVERFLOW\n"); break;
+       }
+       case -EPROTO: {
+               SAY("-EPROTO\n"); break;
+       }
+       case -EILSEQ: {
+               SAY("-EILSEQ\n"); break;
+       }
+       case -ETIMEDOUT: {
+               SAY("-ETIMEDOUT\n"); break;
+       }
+       case -EMSGSIZE: {
+               SAY("-EMSGSIZE\n"); break;
+       }
+       case -EOPNOTSUPP: {
+               SAY("-EOPNOTSUPP\n"); break;
+       }
+       case -EPFNOSUPPORT: {
+               SAY("-EPFNOSUPPORT\n"); break;
+       }
+       case -EAFNOSUPPORT: {
+               SAY("-EAFNOSUPPORT\n"); break;
+       }
+       case -EADDRINUSE: {
+               SAY("-EADDRINUSE\n"); break;
+       }
+       case -EADDRNOTAVAIL: {
+               SAY("-EADDRNOTAVAIL\n"); break;
+       }
+       case -ENOBUFS: {
+               SAY("-ENOBUFS\n"); break;
+       }
+       case -EISCONN: {
+               SAY("-EISCONN\n"); break;
+       }
+       case -ENOTCONN: {
+               SAY("-ENOTCONN\n"); break;
+       }
+       case -ESHUTDOWN: {
+               SAY("-ESHUTDOWN\n"); break;
+       }
+       case -ENOENT: {
+               SAY("-ENOENT\n"); break;
+       }
+       case -ECONNRESET: {
+               SAY("-ECONNRESET\n"); break;
+       }
+       case -ENOSPC: {
+               SAY("ENOSPC\n"); break;
+       }
+       default: {
+               SAY("unknown error code 0x%08X\n", purb->status); break;
+       }
+       }
+/*---------------------------------------------------------------------------*/
+} else {
+       for (i = 0;  i < purb->number_of_packets; i++) {
+               if (0 != purb->iso_frame_desc[i].status) {
+                       (peasycap->field_buffer\
+                               [peasycap->field_fill][0].kount) |= 0x8000 ;
+                       switch (purb->iso_frame_desc[i].status) {
+                       case  0: {
+                               strcpy(&errbuf[0], "OK"); break;
+                       }
+                       case -ENOENT: {
+                               strcpy(&errbuf[0], "-ENOENT"); break;
+                       }
+                       case -EINPROGRESS: {
+                               strcpy(&errbuf[0], "-EINPROGRESS"); break;
+                       }
+                       case -EPROTO: {
+                               strcpy(&errbuf[0], "-EPROTO"); break;
+                       }
+                       case -EILSEQ: {
+                               strcpy(&errbuf[0], "-EILSEQ"); break;
+                       }
+                       case -ETIME: {
+                               strcpy(&errbuf[0], "-ETIME"); break;
+                       }
+                       case -ETIMEDOUT: {
+                               strcpy(&errbuf[0], "-ETIMEDOUT"); break;
+                       }
+                       case -EPIPE: {
+                               strcpy(&errbuf[0], "-EPIPE"); break;
+                       }
+                       case -ECOMM: {
+                               strcpy(&errbuf[0], "-ECOMM"); break;
+                       }
+                       case -ENOSR: {
+                               strcpy(&errbuf[0], "-ENOSR"); break;
+                       }
+                       case -EOVERFLOW: {
+                               strcpy(&errbuf[0], "-EOVERFLOW"); break;
+                       }
+                       case -EREMOTEIO: {
+                               strcpy(&errbuf[0], "-EREMOTEIO"); break;
+                       }
+                       case -ENODEV: {
+                               strcpy(&errbuf[0], "-ENODEV"); break;
+                       }
+                       case -EXDEV: {
+                               strcpy(&errbuf[0], "-EXDEV"); break;
+                       }
+                       case -EINVAL: {
+                               strcpy(&errbuf[0], "-EINVAL"); break;
+                       }
+                       case -ECONNRESET: {
+                               strcpy(&errbuf[0], "-ECONNRESET"); break;
+                       }
+                       case -ENOSPC: {
+                               SAY("ENOSPC\n"); break;
+                       }
+                       case -ESHUTDOWN: {
+                               strcpy(&errbuf[0], "-ESHUTDOWN"); break;
+                       }
+                       default: {
+                               strcpy(&errbuf[0], "unknown error"); break;
+                       }
+                       }
+               }
+               framestatus = purb->iso_frame_desc[i].status;
+               framelength = purb->iso_frame_desc[i].length;
+               frameactual = purb->iso_frame_desc[i].actual_length;
+               frameoffset = purb->iso_frame_desc[i].offset;
+
+               JOT(16, "frame[%2i]:" \
+                               "%4i=status "  \
+                               "%4i=actual "  \
+                               "%4i=length "  \
+                               "%5i=offset\n", \
+                       i, framestatus, frameactual, framelength, frameoffset);
+               if (!purb->iso_frame_desc[i].status) {
+                       more = purb->iso_frame_desc[i].actual_length;
+                       pfield_buffer = &peasycap->field_buffer\
+                                 [peasycap->field_fill][peasycap->field_page];
+                       videofieldamount = (peasycap->field_page * \
+                               PAGE_SIZE) + \
+                               (int)(pfield_buffer->pto - pfield_buffer->pgo);
+               if (4 == more)
+                       mt++;
+               if (4 < more) {
+                       if (mt) {
+                               JOT(8, "%4i empty video urb frames\n", mt);
+                               mt = 0;
+                       }
+                       if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
+                               SAY("ERROR: bad peasycap->field_fill\n");
+                               return;
+                       }
+                       if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
+                                                       peasycap->field_page) {
+                               SAY("ERROR: bad peasycap->field_page\n");
+                               return;
+                       }
+                       pfield_buffer = &peasycap->field_buffer\
+                               [peasycap->field_fill][peasycap->field_page];
+                       pu = (__u8 *)(purb->transfer_buffer + \
+                                       purb->iso_frame_desc[i].offset);
+                       if (0x80 & *pu)
+                               leap = 8;
+                       else
+                               leap = 4;
+/*--------------------------------------------------------------------------*/
+/*
+ *  EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
+ *  NOTE:  A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
+ *         CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
+ *
+ *  PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
+ *  BYTE OF
+ *        peasycap->field_buffer[peasycap->field_fill][0].kount
+ *  THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
+ *  UPDATED AND field_fill IS BUMPED.  IF THE FIELD BUFFER CONTAINS BAD DATA
+ *  NOTHING IS OFFERED TO dqbuf().
+ *
+ *  THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
+ *  RESTS WITH dqbuf().
+ */
+/*---------------------------------------------------------------------------*/
+                       if ((8 == more) || override) {
+                               if (videofieldamount > \
+                                               peasycap->videofieldamount) {
+                                       if (2 == videofieldamount - \
+                                                       peasycap->\
+                                                       videofieldamount)
+                                               (peasycap->field_buffer\
+                                               [peasycap->field_fill]\
+                                                       [0].kount) |= 0x0100;
+                                       else
+                                               (peasycap->field_buffer\
+                                               [peasycap->field_fill]\
+                                                       [0].kount) |= 0x4000;
+                                       } else if (videofieldamount < \
+                                                       peasycap->\
+                                                       videofieldamount) {
+                                               (peasycap->field_buffer\
+                                               [peasycap->field_fill]\
+                                                       [0].kount) |= 0x2000;
+                                       }
+                               if (!(0xFF00 & peasycap->field_buffer\
+                                               [peasycap->field_fill]\
+                                               [0].kount)) {
+                                       (peasycap->video_junk)--;
+                                       if (-16 > peasycap->video_junk)
+                                               peasycap->video_junk = -16;
+                                       peasycap->field_read = \
+                                                       (peasycap->\
+                                                               field_fill)++;
+
+                                       if (FIELD_BUFFER_MANY <= \
+                                               peasycap->field_fill)
+                                               peasycap->field_fill = 0;
+                                       peasycap->field_page = 0;
+                                       pfield_buffer = &peasycap->\
+                                               field_buffer\
+                                               [peasycap->field_fill]\
+                                               [peasycap->field_page];
+                                       pfield_buffer->pto = \
+                                                       pfield_buffer->pgo;
+
+                                       JOT(8, "bumped to: %i=peasycap->" \
+                                               "field_fill  %i=parity\n", \
+                                               peasycap->field_fill, \
+                                               0x00FF & pfield_buffer->kount);
+                                       JOT(8, "field buffer %i has %i " \
+                                               "bytes fit to be read\n", \
+                                               peasycap->field_read, \
+                                               videofieldamount);
+                                       JOT(8, "wakeup call to wq_video, " \
+                                               "%i=field_read %i=field_fill "\
+                                               "%i=parity\n", \
+                                               peasycap->field_read, \
+                                               peasycap->field_fill, \
+                                               0x00FF & peasycap->\
+                                               field_buffer[peasycap->\
+                                               field_read][0].kount);
+                                       wake_up_interruptible(&(peasycap->\
+                                                               wq_video));
+                                       do_gettimeofday(&peasycap->timeval7);
+                                       } else {
+                                       peasycap->video_junk++;
+                                       JOT(8, "field buffer %i had %i " \
+                                               "bytes, now discarded\n", \
+                                               peasycap->field_fill, \
+                                               videofieldamount);
+
+                                       (peasycap->field_fill)++;
+
+                                       if (FIELD_BUFFER_MANY <= \
+                                                       peasycap->field_fill)
+                                               peasycap->field_fill = 0;
+                                       peasycap->field_page = 0;
+                                       pfield_buffer = \
+                                               &peasycap->field_buffer\
+                                               [peasycap->field_fill]\
+                                               [peasycap->field_page];
+                                       pfield_buffer->pto = \
+                                                       pfield_buffer->pgo;
+
+                                       JOT(8, "bumped to: %i=peasycap->" \
+                                               "field_fill  %i=parity\n", \
+                                               peasycap->field_fill, \
+                                               0x00FF & pfield_buffer->kount);
+                               }
+                               if (8 == more) {
+                                       JOT(8, "end-of-field: received " \
+                                               "parity byte 0x%02X\n", \
+                                               (0xFF & *pu));
+                                       if (0x40 & *pu)
+                                               pfield_buffer->kount = 0x0000;
+                                       else
+                                               pfield_buffer->kount = 0x0001;
+                                       JOT(8, "end-of-field: 0x%02X=kount\n",\
+                                               0xFF & pfield_buffer->kount);
+                               }
+                       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
+ */
+/*---------------------------------------------------------------------------*/
+                       pu += leap;
+                       more -= leap;
+
+                       if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
+                               SAY("ERROR: bad peasycap->field_fill\n");
+                               return;
+                       }
+                       if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
+                                                       peasycap->field_page) {
+                               SAY("ERROR: bad peasycap->field_page\n");
+                               return;
+                       }
+                       pfield_buffer = &peasycap->field_buffer\
+                               [peasycap->field_fill][peasycap->field_page];
+                       while (more) {
+                               pfield_buffer = &peasycap->field_buffer\
+                                               [peasycap->field_fill]\
+                                               [peasycap->field_page];
+                               if (PAGE_SIZE < (pfield_buffer->pto - \
+                                                       pfield_buffer->pgo)) {
+                                       SAY("ERROR: bad pfield_buffer->pto\n");
+                                       return;
+                               }
+                               if (PAGE_SIZE == (pfield_buffer->pto - \
+                                                       pfield_buffer->pgo)) {
+                                       (peasycap->field_page)++;
+                                       if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
+                                                       peasycap->field_page) {
+                                               JOT(16, "wrapping peasycap->" \
+                                                       "field_page\n");
+                                               peasycap->field_page = 0;
+                                       }
+                                       pfield_buffer = &peasycap->\
+                                                       field_buffer\
+                                                       [peasycap->field_fill]\
+                                                       [peasycap->field_page];
+                                       pfield_buffer->pto = \
+                                                       pfield_buffer->pgo;
+                               }
+
+                               much = PAGE_SIZE - (int)(pfield_buffer->pto - \
+                                                       pfield_buffer->pgo);
+
+                               if (much > more)
+                                       much = more;
+                               memcpy(pfield_buffer->pto, pu, much);
+                               pu += much;
+                               (pfield_buffer->pto) += much;
+                               more -= much;
+                               }
+                       }
+               }
+       }
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *
+ *
+ *             *** UNDER DEVELOPMENT/TESTING - NOT READY YET! ***
+ *
+ *
+ *
+ *  VIDEOTAPES MAY HAVE BEEN MANUALLY PAUSED AND RESTARTED DURING RECORDING.
+ *  THIS CAUSES LOSS OF SYNC, CONFUSING DOWNSTREAM USERSPACE PROGRAMS WHICH
+ *  MAY INTERPRET THE INTERRUPTION AS A SYMPTOM OF LATENCY.  TO OVERCOME THIS
+ *  THE DRIVER BRIDGES THE HIATUS BY SENDING DUMMY VIDEO FRAMES AT ROUGHLY
+ *  THE RIGHT TIME INTERVALS IN THE HOPE OF PERSUADING THE DOWNSTREAM USERSPACE
+ *  PROGRAM TO RESUME NORMAL SERVICE WHEN THE INTERRUPTION IS OVER.
+ */
+/*---------------------------------------------------------------------------*/
+#if defined(BRIDGER)
+do_gettimeofday(&timeval);
+if (peasycap->timeval7.tv_sec) {
+       usec = 1000000*(timeval.tv_sec  - peasycap->timeval7.tv_sec) + \
+                       (timeval.tv_usec - peasycap->timeval7.tv_usec);
+       if (usec > (peasycap->usec + peasycap->tolerate)) {
+               JOT(8, "bridging hiatus\n");
+               peasycap->video_junk = 0;
+               peasycap->field_buffer[peasycap->field_fill][0].kount |= 0x0400;
+
+               peasycap->field_read = (peasycap->field_fill)++;
+
+               if (FIELD_BUFFER_MANY <= peasycap->field_fill) \
+                                               peasycap->field_fill = 0;
+               peasycap->field_page = 0;
+               pfield_buffer = &peasycap->field_buffer\
+                               [peasycap->field_fill][peasycap->field_page];
+               pfield_buffer->pto = pfield_buffer->pgo;
+
+               JOT(8, "bumped to: %i=peasycap->field_fill  %i=parity\n", \
+                       peasycap->field_fill, 0x00FF & pfield_buffer->kount);
+               JOT(8, "field buffer %i has %i bytes to be overwritten\n", \
+                       peasycap->field_read, videofieldamount);
+               JOT(8, "wakeup call to wq_video, " \
+                       "%i=field_read %i=field_fill %i=parity\n", \
+                       peasycap->field_read, peasycap->field_fill, \
+                       0x00FF & \
+                       peasycap->field_buffer[peasycap->field_read][0].kount);
+               wake_up_interruptible(&(peasycap->wq_video));
+               do_gettimeofday(&peasycap->timeval7);
+       }
+}
+#endif /*BRIDGER*/
+/*---------------------------------------------------------------------------*/
+/*
+ *  RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
+ *
+ *  IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
+ *  THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT.   BEWARE.
+ */
+/*---------------------------------------------------------------------------*/
+if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
+       SAY("easycap driver shutting down on condition green\n");
+       peasycap->video_eof = 1;
+       peasycap->audio_eof = 1;
+       peasycap->video_junk = -VIDEO_ISOC_BUFFER_MANY;
+       wake_up_interruptible(&(peasycap->wq_video));
+       wake_up_interruptible(&(peasycap->wq_audio));
+       return;
+}
+if (peasycap->video_isoc_streaming) {
+       rc = usb_submit_urb(purb, GFP_ATOMIC);
+       if (0 != rc) {
+               SAY("ERROR: while %i=video_idle, usb_submit_urb() failed " \
+                                       "with rc:\n", peasycap->video_idle);
+               switch (rc) {
+               case -ENOMEM: {
+                       SAY("ENOMEM\n"); break;
+               }
+               case -ENODEV: {
+                       SAY("ENODEV\n"); break;
+               }
+               case -ENXIO: {
+                       SAY("ENXIO\n"); break;
+               }
+               case -EINVAL: {
+                       SAY("EINVAL\n"); break;
+               }
+               case -EAGAIN: {
+                       SAY("EAGAIN\n"); break;
+               }
+               case -EFBIG: {
+                       SAY("EFBIG\n"); break;
+               }
+               case -EPIPE: {
+                       SAY("EPIPE\n"); break;
+               }
+               case -EMSGSIZE: {
+                       SAY("EMSGSIZE\n");  break;
+               }
+               case -ENOSPC: {
+                       SAY("ENOSPC\n"); break;
+               }
+               default: {
+                       SAY("0x%08X\n", rc); break;
+               }
+               }
+       }
+}
+return;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *
+ *                                  FIXME
+ *
+ *
+ *  THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE DEVICE IS
+ *  PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
+ *  IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops.
+ *
+ *  THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE.
+ */
+/*---------------------------------------------------------------------------*/
+int
+easycap_usb_probe(struct usb_interface *pusb_interface, \
+                                               const struct usb_device_id *id)
+{
+struct usb_device *pusb_device, *pusb_device1;
+struct usb_host_interface *pusb_host_interface;
+struct usb_endpoint_descriptor *pepd;
+struct usb_interface_descriptor *pusb_interface_descriptor;
+struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor;
+struct urb *purb;
+static struct easycap *peasycap /*=NULL*/;
+struct data_urb *pdata_urb;
+size_t wMaxPacketSize;
+int ISOCwMaxPacketSize;
+int BULKwMaxPacketSize;
+int INTwMaxPacketSize;
+int CTRLwMaxPacketSize;
+__u8 bEndpointAddress;
+__u8 ISOCbEndpointAddress;
+__u8 INTbEndpointAddress;
+int isin, i, j, k, m;
+__u8 bInterfaceNumber;
+__u8 bInterfaceClass;
+__u8 bInterfaceSubClass;
+void *pbuf;
+int okalt[8], isokalt;
+int okepn[8], isokepn;
+int okmps[8], isokmps;
+int maxpacketsize;
+int rc;
+
+JOT(4, "\n");
+
+if ((struct usb_interface *)NULL == pusb_interface) {
+       SAY("ERROR: pusb_interface is NULL\n");
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  GET POINTER TO STRUCTURE usb_device
+ */
+/*---------------------------------------------------------------------------*/
+pusb_device1 = container_of(pusb_interface->dev.parent, \
+                                               struct usb_device, dev);
+if ((struct usb_device *)NULL == pusb_device1) {
+       SAY("ERROR: pusb_device1 is NULL\n");
+       return -EFAULT;
+}
+pusb_device = usb_get_dev(pusb_device1);
+if ((struct usb_device *)NULL == pusb_device) {
+       SAY("ERROR: pusb_device is NULL\n");
+       return -EFAULT;
+}
+if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) {
+       JOT(4, "ERROR: pusb_device1 != pusb_device\n");
+       return -EFAULT;
+}
+
+JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations);
+
+/*---------------------------------------------------------------------------*/
+pusb_host_interface = pusb_interface->cur_altsetting;
+if (NULL == pusb_host_interface) {
+       SAY("ERROR: pusb_host_interface is NULL\n");
+       return -EFAULT;
+}
+pusb_interface_descriptor = &(pusb_host_interface->desc);
+if (NULL == pusb_interface_descriptor) {
+       SAY("ERROR: pusb_interface_descriptor is NULL\n");
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  GET PROPERTIES OF PROBED INTERFACE
+ */
+/*---------------------------------------------------------------------------*/
+bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
+bInterfaceClass = pusb_interface_descriptor->bInterfaceClass;
+bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass;
+
+JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \
+                       bInterfaceNumber, pusb_interface->num_altsetting);
+JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \
+                       "pusb_interface->altsetting=%li\n", bInterfaceNumber, \
+                       (long int)(pusb_interface->cur_altsetting - \
+                                               pusb_interface->altsetting));
+switch (bInterfaceClass) {
+case USB_CLASS_AUDIO: {
+       JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \
+                               bInterfaceNumber, bInterfaceClass); break;
+       }
+case USB_CLASS_VIDEO: {
+       JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \
+                               bInterfaceNumber, bInterfaceClass); break;
+       }
+case USB_CLASS_VENDOR_SPEC: {
+       JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \
+                               bInterfaceNumber, bInterfaceClass); break;
+       }
+default:
+       break;
+}
+switch (bInterfaceSubClass) {
+case 0x01: {
+       JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \
+                       bInterfaceNumber, bInterfaceSubClass); break;
+}
+case 0x02: {
+       JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \
+                       bInterfaceNumber, bInterfaceSubClass); break;
+}
+case 0x03: {
+       JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \
+                       bInterfaceNumber, bInterfaceSubClass); break;
+}
+default:
+       break;
+}
+/*---------------------------------------------------------------------------*/
+pusb_interface_assoc_descriptor = pusb_interface->intf_assoc;
+if (NULL != pusb_interface_assoc_descriptor) {
+       JOT(4, "intf[%i]: bFirstInterface=0x%02X  bInterfaceCount=0x%02X\n", \
+                       bInterfaceNumber, \
+                       pusb_interface_assoc_descriptor->bFirstInterface, \
+                       pusb_interface_assoc_descriptor->bInterfaceCount);
+} else {
+JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \
+                                                       bInterfaceNumber);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
+ *  IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap.  THIS
+ *  SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE DEVICE WAS PHYSICALLY
+ *  UNPLUGGED.
+ */
+/*---------------------------------------------------------------------------*/
+if (0 == bInterfaceNumber) {
+       peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
+       if (NULL == peasycap) {
+               SAY("ERROR: Could not allocate peasycap\n");
+               return -ENOMEM;
+       } else {
+               peasycap->allocation_video_struct = sizeof(struct easycap);
+               peasycap->allocation_video_page = 0;
+               peasycap->allocation_video_urb = 0;
+               peasycap->allocation_audio_struct = 0;
+               peasycap->allocation_audio_page = 0;
+               peasycap->allocation_audio_urb = 0;
+       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  INITIALIZE THE NEW easycap STRUCTURE.
+ *  NO PARAMETERS ARE SPECIFIED HERE REQUIRING THE SETTING OF REGISTERS.
+ *  THAT IS DONE FIRST BY easycap_open() AND LATER BY easycap_ioctl().
+ */
+/*---------------------------------------------------------------------------*/
+       peasycap->pusb_device = pusb_device;
+       peasycap->pusb_interface = pusb_interface;
+
+       kref_init(&peasycap->kref);
+       JOT(8, "intf[%i]: after kref_init(..._video) " \
+                       "%i=peasycap->kref.refcount.counter\n", \
+                       bInterfaceNumber, peasycap->kref.refcount.counter);
+
+       init_waitqueue_head(&(peasycap->wq_video));
+       init_waitqueue_head(&(peasycap->wq_audio));
+
+       mutex_init(&(peasycap->mutex_timeval0));
+       mutex_init(&(peasycap->mutex_timeval1));
+
+       for (k = 0; k < FRAME_BUFFER_MANY; k++)
+               mutex_init(&(peasycap->mutex_mmap_video[k]));
+
+       peasycap->ilk = 0;
+       peasycap->microphone = false;
+
+       peasycap->video_interface = -1;
+       peasycap->video_altsetting_on = -1;
+       peasycap->video_altsetting_off = -1;
+       peasycap->video_endpointnumber = -1;
+       peasycap->video_isoc_maxframesize = -1;
+       peasycap->video_isoc_buffer_size = -1;
+
+       peasycap->audio_interface = -1;
+       peasycap->audio_altsetting_on = -1;
+       peasycap->audio_altsetting_off = -1;
+       peasycap->audio_endpointnumber = -1;
+       peasycap->audio_isoc_maxframesize = -1;
+       peasycap->audio_isoc_buffer_size = -1;
+
+       peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
+
+       if ((struct mutex *)NULL == &(peasycap->mutex_mmap_video[0])) {
+               SAY("ERROR: &(peasycap->mutex_mmap_video[%i]) is NULL\n", 0);
+               return -EFAULT;
+       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  DYNAMICALLY FILL IN THE AVAILABLE FORMATS.
+ */
+/*---------------------------------------------------------------------------*/
+       rc = fillin_formats();
+       if (0 > rc) {
+               SAY("ERROR: fillin_formats() returned %i\n", rc);
+               return -EFAULT;
+       }
+       JOT(4, "%i formats available\n", rc);
+       } else {
+/*---------------------------------------------------------------------------*/
+               if ((struct easycap *)NULL == peasycap) {
+                       SAY("ERROR: peasycap is NULL " \
+                                       "when probing interface %i\n", \
+                                                       bInterfaceNumber);
+                       return -EFAULT;
+               }
+
+       JOT(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", \
+                                       (int)peasycap->kref.refcount.counter);
+       kref_get(&peasycap->kref);
+}
+/*---------------------------------------------------------------------------*/
+if ((USB_CLASS_VIDEO == bInterfaceClass) || \
+       (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
+       if (-1 == peasycap->video_interface) {
+               peasycap->video_interface = bInterfaceNumber;
+               JOT(4, "setting peasycap->video_interface=%i\n", \
+                                               peasycap->video_interface);
+       } else {
+               if (peasycap->video_interface != bInterfaceNumber) {
+                       SAY("ERROR: attempting to reset " \
+                                       "peasycap->video_interface\n");
+                       SAY("...... continuing with " \
+                                       "%i=peasycap->video_interface\n", \
+                                       peasycap->video_interface);
+               }
+       }
+} else if ((USB_CLASS_AUDIO == bInterfaceClass) && \
+                                               (0x02 == bInterfaceSubClass)) {
+       if (-1 == peasycap->audio_interface) {
+               peasycap->audio_interface = bInterfaceNumber;
+               JOT(4, "setting peasycap->audio_interface=%i\n", \
+                                                peasycap->audio_interface);
+       } else {
+               if (peasycap->audio_interface != bInterfaceNumber) {
+                       SAY("ERROR: attempting to reset " \
+                                       "peasycap->audio_interface\n");
+                       SAY("...... continuing with " \
+                                       "%i=peasycap->audio_interface\n", \
+                                       peasycap->audio_interface);
+               }
+       }
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  INVESTIGATE ALL ALTSETTINGS.
+ *  DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
+ */
+/*---------------------------------------------------------------------------*/
+isokalt = 0;
+isokepn = 0;
+isokmps = 0;
+
+for (i = 0; i < pusb_interface->num_altsetting; i++) {
+       pusb_host_interface = &(pusb_interface->altsetting[i]);
+       if ((struct usb_host_interface *)NULL == pusb_host_interface) {
+               SAY("ERROR: pusb_host_interface is NULL\n");
+               return -EFAULT;
+       }
+       pusb_interface_descriptor = &(pusb_host_interface->desc);
+       if ((struct usb_interface_descriptor *)NULL == \
+                                               pusb_interface_descriptor) {
+               SAY("ERROR: pusb_interface_descriptor is NULL\n");
+               return -EFAULT;
+       }
+
+       JOT(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType);
+       JOT(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber);
+       JOT(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting);
+       JOT(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints);
+       JOT(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass);
+       JOT(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass);
+       JOT(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol);
+       JOT(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
+       bInterfaceNumber, i, pusb_interface_descriptor->iInterface);
+
+       ISOCwMaxPacketSize = -1;
+       BULKwMaxPacketSize = -1;
+       INTwMaxPacketSize = -1;
+       CTRLwMaxPacketSize = -1;
+       ISOCbEndpointAddress = 0;
+       INTbEndpointAddress = 0;
+
+       if (0 == pusb_interface_descriptor->bNumEndpoints)
+                               JOT(4, "intf[%i]alt[%i] has no endpoints\n", \
+                                                       bInterfaceNumber, i);
+/*---------------------------------------------------------------------------*/
+       for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) {
+               pepd = &(pusb_host_interface->endpoint[j].desc);
+               if ((struct usb_endpoint_descriptor *)NULL == pepd) {
+                       SAY("ERROR:  pepd is NULL.\n");
+                       SAY("...... skipping\n");
+                       continue;
+               }
+               wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize);
+               bEndpointAddress = pepd->bEndpointAddress;
+
+               JOT(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
+                               bInterfaceNumber, i, j, \
+                               pepd->bEndpointAddress);
+               JOT(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
+                               bInterfaceNumber, i, j, \
+                               pepd->bmAttributes);
+               JOT(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
+                               bInterfaceNumber, i, j, \
+                               pepd->wMaxPacketSize);
+               JOT(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
+                               bInterfaceNumber, i, j, \
+                               pepd->bInterval);
+
+               if (pepd->bEndpointAddress & USB_DIR_IN) {
+                       JOT(4, "intf[%i]alt[%i]end[%i] is an  IN  endpoint\n",\
+                                               bInterfaceNumber, i, j);
+                       isin = 1;
+               } else {
+                       JOT(4, "intf[%i]alt[%i]end[%i] is an  OUT endpoint\n",\
+                                               bInterfaceNumber, i, j);
+                       SAY("ERROR: OUT endpoint unexpected\n");
+                       SAY("...... continuing\n");
+                       isin = 0;
+               }
+               if ((pepd->bmAttributes & \
+                               USB_ENDPOINT_XFERTYPE_MASK) == \
+                               USB_ENDPOINT_XFER_ISOC) {
+                       JOT(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
+                                               bInterfaceNumber, i, j);
+                       if (isin) {
+                               switch (bInterfaceClass) {
+                               case USB_CLASS_VIDEO:
+                               case USB_CLASS_VENDOR_SPEC: {
+                                       if (!peasycap) {
+                                               SAY("MISTAKE: " \
+                                                       "peasycap is NULL\n");
+                                               return -EFAULT;
+                                       }
+                                       if (pepd->wMaxPacketSize) {
+                                               if (8 > isokalt) {
+                                                       okalt[isokalt] = i;
+                                                       JOT(4,\
+                                                       "%i=okalt[%i]\n", \
+                                                       okalt[isokalt], \
+                                                       isokalt);
+                                                       isokalt++;
+                                               }
+                                               if (8 > isokepn) {
+                                                       okepn[isokepn] = \
+                                                       pepd->\
+                                                       bEndpointAddress & \
+                                                       0x0F;
+                                                       JOT(4,\
+                                                       "%i=okepn[%i]\n", \
+                                                       okepn[isokepn], \
+                                                       isokepn);
+                                                       isokepn++;
+                                               }
+                                               if (8 > isokmps) {
+                                                       okmps[isokmps] = \
+                                                       le16_to_cpu(pepd->\
+                                                       wMaxPacketSize);
+                                                       JOT(4,\
+                                                       "%i=okmps[%i]\n", \
+                                                       okmps[isokmps], \
+                                                       isokmps);
+                                                       isokmps++;
+                                               }
+                                       } else {
+                                               if (-1 == peasycap->\
+                                                       video_altsetting_off) {
+                                                       peasycap->\
+                                                       video_altsetting_off =\
+                                                                        i;
+                                                       JOT(4, "%i=video_" \
+                                                       "altsetting_off " \
+                                                               "<====\n", \
+                                                       peasycap->\
+                                                       video_altsetting_off);
+                                               } else {
+                                                       SAY("ERROR: peasycap" \
+                                                       "->video_altsetting_" \
+                                                       "off already set\n");
+                                                       SAY("...... " \
+                                                       "continuing with " \
+                                                       "%i=peasycap->video_" \
+                                                       "altsetting_off\n", \
+                                                       peasycap->\
+                                                       video_altsetting_off);
+                                               }
+                                       }
+                                       break;
+                               }
+                               case USB_CLASS_AUDIO: {
+                                       if (0x02 != bInterfaceSubClass)
+                                               break;
+                                       if (!peasycap) {
+                                               SAY("MISTAKE: " \
+                                               "peasycap is NULL\n");
+                                               return -EFAULT;
+                                       }
+                                       if (pepd->wMaxPacketSize) {
+                                               if (8 > isokalt) {
+                                                       okalt[isokalt] = i ;
+                                                       JOT(4,\
+                                                       "%i=okalt[%i]\n", \
+                                                       okalt[isokalt], \
+                                                       isokalt);
+                                                       isokalt++;
+                                               }
+                                               if (8 > isokepn) {
+                                                       okepn[isokepn] = \
+                                                       pepd->\
+                                                       bEndpointAddress & \
+                                                       0x0F;
+                                                       JOT(4,\
+                                                       "%i=okepn[%i]\n", \
+                                                       okepn[isokepn], \
+                                                       isokepn);
+                                                       isokepn++;
+                                               }
+                                               if (8 > isokmps) {
+                                                       okmps[isokmps] = \
+                                                       le16_to_cpu(pepd->\
+                                                       wMaxPacketSize);
+                                                       JOT(4,\
+                                                       "%i=okmps[%i]\n",\
+                                                       okmps[isokmps], \
+                                                       isokmps);
+                                                       isokmps++;
+                                               }
+                                       } else {
+                                               if (-1 == peasycap->\
+                                                       audio_altsetting_off) {
+                                                       peasycap->\
+                                                       audio_altsetting_off =\
+                                                                        i;
+                                                       JOT(4, "%i=audio_" \
+                                                       "altsetting_off " \
+                                                       "<====\n", \
+                                                       peasycap->\
+                                                       audio_altsetting_off);
+                                               } else {
+                                                       SAY("ERROR: peasycap" \
+                                                       "->audio_altsetting_" \
+                                                       "off already set\n");
+                                                       SAY("...... " \
+                                                       "continuing with " \
+                                                       "%i=peasycap->\
+                                                       audio_altsetting_" \
+                                                       "off\n",
+                                                       peasycap->\
+                                                       audio_altsetting_off);
+                                               }
+                                       }
+                               break;
+                               }
+                               default:
+                                       break;
+                               }
+                       }
+               } else if ((pepd->bmAttributes & \
+                                               USB_ENDPOINT_XFERTYPE_MASK) ==\
+                                               USB_ENDPOINT_XFER_BULK) {
+                       JOT(4, "intf[%i]alt[%i]end[%i] is a  BULK endpoint\n",\
+                                               bInterfaceNumber, i, j);
+               } else if ((pepd->bmAttributes & \
+                                               USB_ENDPOINT_XFERTYPE_MASK) ==\
+                                               USB_ENDPOINT_XFER_INT) {
+                       JOT(4, "intf[%i]alt[%i]end[%i] is an  INT endpoint\n",\
+                                               bInterfaceNumber, i, j);
+               } else {
+                       JOT(4, "intf[%i]alt[%i]end[%i] is a  CTRL endpoint\n",\
+                                               bInterfaceNumber, i, j);
+               }
+               if (0 == pepd->wMaxPacketSize) {
+                       JOT(4, "intf[%i]alt[%i]end[%i] " \
+                                               "has zero packet size\n", \
+                                               bInterfaceNumber, i, j);
+               }
+       }
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  PERFORM INITIALIZATION OF THE PROBED INTERFACE
+ */
+/*---------------------------------------------------------------------------*/
+JOT(4, "initialization begins for interface %i\n", \
+                               pusb_interface_descriptor->bInterfaceNumber);
+switch (bInterfaceNumber) {
+/*---------------------------------------------------------------------------*/
+/*
+ *  INTERFACE 0 IS THE VIDEO INTERFACE
+ */
+/*---------------------------------------------------------------------------*/
+case 0: {
+       if (!peasycap) {
+               SAY("MISTAKE: peasycap is NULL\n");
+               return -EFAULT;
+       }
+       if (!isokalt) {
+               SAY("ERROR:  no viable video_altsetting_on\n");
+               return -ENOENT;
+       } else {
+               peasycap->video_altsetting_on = okalt[isokalt - 1];
+               JOT(4, "%i=video_altsetting_on <====\n", \
+                                       peasycap->video_altsetting_on);
+       }
+       if (!isokepn) {
+               SAY("ERROR:  no viable video_endpointnumber\n");
+               return -ENOENT;
+       } else {
+               peasycap->video_endpointnumber = okepn[isokepn - 1];
+               JOT(4, "%i=video_endpointnumber\n", \
+                                       peasycap->video_endpointnumber);
+               }
+       if (!isokmps) {
+               SAY("ERROR:  no viable video_maxpacketsize\n");
+               return -ENOENT;
+/*---------------------------------------------------------------------------*/
+/*
+ *  DECIDE THE VIDEO STREAMING PARAMETERS
+ */
+/*---------------------------------------------------------------------------*/
+       } else {
+               maxpacketsize = okmps[isokmps - 1] - 1024;
+               if (USB_2_0_MAXPACKETSIZE > maxpacketsize) {
+                       peasycap->video_isoc_maxframesize = maxpacketsize;
+               } else {
+                       peasycap->video_isoc_maxframesize = \
+                                                       USB_2_0_MAXPACKETSIZE;
+               }
+               JOT(4, "%i=video_isoc_maxframesize\n", \
+                                       peasycap->video_isoc_maxframesize);
+               if (0 >= peasycap->video_isoc_maxframesize) {
+                       SAY("ERROR:  bad video_isoc_maxframesize\n");
+                       return -ENOENT;
+               }
+               peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
+               JOT(4, "%i=video_isoc_framesperdesc\n", \
+                                       peasycap->video_isoc_framesperdesc);
+               if (0 >= peasycap->video_isoc_framesperdesc) {
+                       SAY("ERROR:  bad video_isoc_framesperdesc\n");
+                       return -ENOENT;
+               }
+               peasycap->video_isoc_buffer_size = \
+                                       peasycap->video_isoc_maxframesize * \
+                                       peasycap->video_isoc_framesperdesc;
+               JOT(4, "%i=video_isoc_buffer_size\n", \
+                                       peasycap->video_isoc_buffer_size);
+               if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \
+                                       peasycap->video_isoc_buffer_size) {
+                       SAY("MISTAKE: " \
+                               "peasycap->video_isoc_buffer_size too big\n");
+                       return -EFAULT;
+               }
+       }
+/*---------------------------------------------------------------------------*/
+       if (-1 == peasycap->video_interface) {
+               SAY("MISTAKE:  video_interface is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->video_altsetting_on) {
+               SAY("MISTAKE:  video_altsetting_on is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->video_altsetting_off) {
+               SAY("MISTAKE:  video_interface_off is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->video_endpointnumber) {
+               SAY("MISTAKE:  video_endpointnumber is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->video_isoc_maxframesize) {
+               SAY("MISTAKE:  video_isoc_maxframesize is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->video_isoc_buffer_size) {
+               SAY("MISTAKE:  video_isoc_buffer_size is unset\n");
+               return -EFAULT;
+       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  ALLOCATE MEMORY FOR VIDEO BUFFERS.  LISTS MUST BE INITIALIZED FIRST.
+ */
+/*---------------------------------------------------------------------------*/
+       INIT_LIST_HEAD(&(peasycap->urb_video_head));
+       peasycap->purb_video_head = &(peasycap->urb_video_head);
+/*---------------------------------------------------------------------------*/
+       JOT(4, "allocating %i frame buffers of size %li\n",  \
+                       FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
+       JOT(4, ".... each scattered over %li pages\n", \
+                                               FRAME_BUFFER_SIZE/PAGE_SIZE);
+
+       for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
+               for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
+                       if ((void *)NULL != peasycap->frame_buffer[k][m].pgo)
+                               SAY("attempting to reallocate frame " \
+                                                               " buffers\n");
+                       else {
+                               pbuf = (void *)__get_free_page(GFP_KERNEL);
+                               if ((void *)NULL == pbuf) {
+                                       SAY("ERROR: Could not allocate frame "\
+                                               "buffer %i page %i\n", k, m);
+                                       return -ENOMEM;
+                               } else
+                                       peasycap->allocation_video_page += 1;
+                               peasycap->frame_buffer[k][m].pgo = pbuf;
+                       }
+                       peasycap->frame_buffer[k][m].pto = \
+                                       peasycap->frame_buffer[k][m].pgo;
+               }
+       }
+
+       peasycap->frame_fill = 0;
+       peasycap->frame_read = 0;
+       JOT(4, "allocation of frame buffers done:  %i pages\n", k * \
+                                                               m);
+/*---------------------------------------------------------------------------*/
+       JOT(4, "allocating %i field buffers of size %li\n",  \
+                       FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
+       JOT(4, ".... each scattered over %li pages\n", \
+                                       FIELD_BUFFER_SIZE/PAGE_SIZE);
+
+       for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
+               for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
+                       if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
+                               SAY("ERROR: attempting to reallocate " \
+                                                       "field buffers\n");
+                       } else {
+                               pbuf = (void *) __get_free_page(GFP_KERNEL);
+                               if ((void *)NULL == pbuf) {
+                                       SAY("ERROR: Could not allocate field" \
+                                               " buffer %i page %i\n", k, m);
+                                       return -ENOMEM;
+                                       }
+                               else
+                                       peasycap->allocation_video_page += 1;
+                               peasycap->field_buffer[k][m].pgo = pbuf;
+                               }
+                       peasycap->field_buffer[k][m].pto = \
+                                       peasycap->field_buffer[k][m].pgo;
+               }
+               peasycap->field_buffer[k][0].kount = 0x0200;
+       }
+       peasycap->field_fill = 0;
+       peasycap->field_page = 0;
+       peasycap->field_read = 0;
+       JOT(4, "allocation of field buffers done:  %i pages\n", k * \
+                                                               m);
+/*---------------------------------------------------------------------------*/
+       JOT(4, "allocating %i isoc video buffers of size %i\n",  \
+                                       VIDEO_ISOC_BUFFER_MANY, \
+                                       peasycap->video_isoc_buffer_size);
+       JOT(4, ".... each occupying contiguous memory pages\n");
+
+       for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
+               pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER);
+               if (NULL == pbuf) {
+                       SAY("ERROR: Could not allocate isoc video buffer " \
+                                                               "%i\n", k);
+                       return -ENOMEM;
+               } else
+                       peasycap->allocation_video_page += \
+                               ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
+
+               peasycap->video_isoc_buffer[k].pgo = pbuf;
+               peasycap->video_isoc_buffer[k].pto = pbuf + \
+                                       peasycap->video_isoc_buffer_size;
+               peasycap->video_isoc_buffer[k].kount = k;
+       }
+       JOT(4, "allocation of isoc video buffers done: %i pages\n", \
+                                       k * (0x01 << VIDEO_ISOC_ORDER));
+/*---------------------------------------------------------------------------*/
+/*
+ *  ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
+ */
+/*---------------------------------------------------------------------------*/
+       JOT(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
+       JOT(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
+                                       peasycap->video_isoc_framesperdesc);
+       JOT(4, "using %i=peasycap->video_isoc_maxframesize\n", \
+                                       peasycap->video_isoc_maxframesize);
+       JOT(4, "using %i=peasycap->video_isoc_buffer_sizen", \
+                                       peasycap->video_isoc_buffer_size);
+
+       for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
+               purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \
+                                                               GFP_KERNEL);
+               if (NULL == purb) {
+                       SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
+                                                               "%i\n", k);
+                       return -ENOMEM;
+               } else
+                       peasycap->allocation_video_urb += 1;
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+               pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
+               if (NULL == pdata_urb) {
+                       SAY("ERROR: Could not allocate struct data_urb.\n");
+                       return -ENOMEM;
+               } else
+                       peasycap->allocation_video_struct += \
+                                               sizeof(struct data_urb);
+
+               pdata_urb->purb = purb;
+               pdata_urb->isbuf = k;
+               pdata_urb->length = 0;
+               list_add_tail(&(pdata_urb->list_head), \
+                                               peasycap->purb_video_head);
+/*---------------------------------------------------------------------------*/
+/*
+ *  ... AND INITIALIZE THEM
+ */
+/*---------------------------------------------------------------------------*/
+               if (!k) {
+                       JOT(4, "initializing video urbs thus:\n");
+                       JOT(4, "  purb->interval = 1;\n");
+                       JOT(4, "  purb->dev = peasycap->pusb_device;\n");
+                       JOT(4, "  purb->pipe = usb_rcvisocpipe" \
+                                       "(peasycap->pusb_device,%i);\n", \
+                                       peasycap->video_endpointnumber);
+                       JOT(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
+                       JOT(4, "  purb->transfer_buffer = peasycap->" \
+                                       "video_isoc_buffer[.].pgo;\n");
+                       JOT(4, "  purb->transfer_buffer_length = %i;\n", \
+                                       peasycap->video_isoc_buffer_size);
+                       JOT(4, "  purb->complete = easycap_complete;\n");
+                       JOT(4, "  purb->context = peasycap;\n");
+                       JOT(4, "  purb->start_frame = 0;\n");
+                       JOT(4, "  purb->number_of_packets = %i;\n", \
+                                       peasycap->video_isoc_framesperdesc);
+                       JOT(4, "  for (j = 0; j < %i; j++)\n", \
+                                       peasycap->video_isoc_framesperdesc);
+                       JOT(4, "    {\n");
+                       JOT(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
+                                       peasycap->video_isoc_maxframesize);
+                       JOT(4, "    purb->iso_frame_desc[j].length = %i;\n", \
+                                       peasycap->video_isoc_maxframesize);
+                       JOT(4, "    }\n");
+               }
+
+               purb->interval = 1;
+               purb->dev = peasycap->pusb_device;
+               purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
+                                       peasycap->video_endpointnumber);
+               purb->transfer_flags = URB_ISO_ASAP;
+               purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
+               purb->transfer_buffer_length = \
+                                       peasycap->video_isoc_buffer_size;
+               purb->complete = easycap_complete;
+               purb->context = peasycap;
+               purb->start_frame = 0;
+               purb->number_of_packets = peasycap->video_isoc_framesperdesc;
+               for (j = 0;  j < peasycap->video_isoc_framesperdesc; j++) {
+                       purb->iso_frame_desc[j].offset = j * \
+                                       peasycap->video_isoc_maxframesize;
+                       purb->iso_frame_desc[j].length = \
+                                       peasycap->video_isoc_maxframesize;
+               }
+       }
+       JOT(4, "allocation of %i struct urb done.\n", k);
+/*--------------------------------------------------------------------------*/
+/*
+ *  SAVE POINTER peasycap IN THIS INTERFACE.
+ */
+/*--------------------------------------------------------------------------*/
+       usb_set_intfdata(pusb_interface, peasycap);
+/*--------------------------------------------------------------------------*/
+/*
+ *  THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
+ */
+/*--------------------------------------------------------------------------*/
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+       if (0 != (usb_register_dev(pusb_interface, &easycap_class))) {
+               err("Not able to get a minor for this device");
+               usb_set_intfdata(pusb_interface, NULL);
+               return -ENODEV;
+       } else
+               (peasycap->registered_video)++;
+       SAY("easycap attached to minor #%d\n", pusb_interface->minor);
+       break;
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#else
+       pvideo_device = (struct video_device *)\
+                       kzalloc(sizeof(struct video_device), GFP_KERNEL);
+       if ((struct video_device *)NULL == pvideo_device) {
+               SAY("ERROR: Could not allocate structure video_device\n");
+               return -ENOMEM;
+       }
+       if (VIDEO_DEVICE_MANY <= video_device_many) {
+               SAY("ERROR: Too many /dev/videos\n");
+               return -ENOMEM;
+       }
+       pvideo_array[video_device_many] = pvideo_device;  video_device_many++;
+
+       strcpy(&pvideo_device->name[0], "easycapdc60");
+#if defined(EASYCAP_NEEDS_V4L2_FOPS)
+       pvideo_device->fops = &v4l2_fops;
+#else
+       pvideo_device->fops = &easycap_fops;
+#endif /*EASYCAP_NEEDS_V4L2_FOPS*/
+       pvideo_device->minor = -1;
+       pvideo_device->release = (void *)(&videodev_release);
+
+       video_set_drvdata(pvideo_device, (void *)peasycap);
+
+       rc = video_register_device(pvideo_device, VFL_TYPE_GRABBER, -1);
+       if (0 != rc) {
+               err("Not able to register with videodev");
+               videodev_release(pvideo_device);
+               return -ENODEV;
+       } else {
+               peasycap->pvideo_device = pvideo_device;
+               (peasycap->registered_video)++;
+               JOT(4, "registered with videodev: %i=minor\n", \
+                                                       pvideo_device->minor);
+       }
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+       break;
+}
+/*--------------------------------------------------------------------------*/
+/*
+ *  INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
+ *  INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
+ */
+/*--------------------------------------------------------------------------*/
+case 1: {
+/*--------------------------------------------------------------------------*/
+/*
+ *  SAVE POINTER peasycap IN INTERFACE 1
+ */
+/*--------------------------------------------------------------------------*/
+       usb_set_intfdata(pusb_interface, peasycap);
+       JOT(4, "no initialization required for interface %i\n", \
+                               pusb_interface_descriptor->bInterfaceNumber);
+       break;
+}
+/*--------------------------------------------------------------------------*/
+case 2: {
+       if (!peasycap) {
+               SAY("MISTAKE: peasycap is NULL\n");
+               return -EFAULT;
+       }
+       if (!isokalt) {
+               SAY("ERROR:  no viable audio_altsetting_on\n");
+               return -ENOENT;
+       } else {
+               peasycap->audio_altsetting_on = okalt[isokalt - 1];
+               JOT(4, "%i=audio_altsetting_on <====\n", \
+                                               peasycap->audio_altsetting_on);
+       }
+       if (!isokepn) {
+               SAY("ERROR:  no viable audio_endpointnumber\n");
+               return -ENOENT;
+       } else {
+               peasycap->audio_endpointnumber = okepn[isokepn - 1];
+               JOT(4, "%i=audio_endpointnumber\n", \
+                                       peasycap->audio_endpointnumber);
+       }
+       if (!isokmps) {
+               SAY("ERROR:  no viable audio_maxpacketsize\n");
+               return -ENOENT;
+       } else {
+               peasycap->audio_isoc_maxframesize = okmps[isokmps - 1];
+               JOT(4, "%i=audio_isoc_maxframesize\n", \
+                                       peasycap->audio_isoc_maxframesize);
+               if (0 >= peasycap->audio_isoc_maxframesize) {
+                       SAY("ERROR:  bad audio_isoc_maxframesize\n");
+                       return -ENOENT;
+               }
+               if (9 == peasycap->audio_isoc_maxframesize) {
+                       peasycap->ilk |= 0x02;
+                       SAY("hardware is FOUR-CVBS\n");
+                       peasycap->microphone = true;
+                       peasycap->audio_pages_per_fragment = 4;
+               } else if (256 == peasycap->audio_isoc_maxframesize) {
+                       peasycap->ilk &= ~0x02;
+                       SAY("hardware is CVBS+S-VIDEO\n");
+                       peasycap->microphone = false;
+                       peasycap->audio_pages_per_fragment = 4;
+               } else {
+                       SAY("hardware is unidentified:\n");
+                       SAY("%i=audio_isoc_maxframesize\n", \
+                                       peasycap->audio_isoc_maxframesize);
+                       return -ENOENT;
+               }
+
+               peasycap->audio_bytes_per_fragment = \
+                                       peasycap->audio_pages_per_fragment * \
+                                                               PAGE_SIZE ;
+               peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \
+                                       peasycap->audio_pages_per_fragment);
+
+               JOT(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
+               JOT(4, "%6i=audio_pages_per_fragment\n", \
+                                       peasycap->audio_pages_per_fragment);
+               JOT(4, "%6i=audio_bytes_per_fragment\n", \
+                                       peasycap->audio_bytes_per_fragment);
+               JOT(4, "%6i=audio_buffer_page_many\n", \
+                                       peasycap->audio_buffer_page_many);
+
+               peasycap->audio_isoc_framesperdesc = 128;
+
+               JOT(4, "%i=audio_isoc_framesperdesc\n", \
+                                       peasycap->audio_isoc_framesperdesc);
+               if (0 >= peasycap->audio_isoc_framesperdesc) {
+                       SAY("ERROR:  bad audio_isoc_framesperdesc\n");
+                       return -ENOENT;
+               }
+
+               peasycap->audio_isoc_buffer_size = \
+                               peasycap->audio_isoc_maxframesize * \
+                               peasycap->audio_isoc_framesperdesc;
+               JOT(4, "%i=audio_isoc_buffer_size\n", \
+                                       peasycap->audio_isoc_buffer_size);
+               if (AUDIO_ISOC_BUFFER_SIZE < \
+                                       peasycap->audio_isoc_buffer_size) {
+                       SAY("MISTAKE:  audio_isoc_buffer_size bigger "
+                       "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
+                                               AUDIO_ISOC_BUFFER_SIZE);
+                       return -EFAULT;
+               }
+       }
+
+       if (-1 == peasycap->audio_interface) {
+               SAY("MISTAKE:  audio_interface is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->audio_altsetting_on) {
+               SAY("MISTAKE:  audio_altsetting_on is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->audio_altsetting_off) {
+               SAY("MISTAKE:  audio_interface_off is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->audio_endpointnumber) {
+               SAY("MISTAKE:  audio_endpointnumber is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->audio_isoc_maxframesize) {
+               SAY("MISTAKE:  audio_isoc_maxframesize is unset\n");
+               return -EFAULT;
+       }
+       if (-1 == peasycap->audio_isoc_buffer_size) {
+               SAY("MISTAKE:  audio_isoc_buffer_size is unset\n");
+               return -EFAULT;
+       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  ALLOCATE MEMORY FOR AUDIO BUFFERS.  LISTS MUST BE INITIALIZED FIRST.
+ */
+/*---------------------------------------------------------------------------*/
+       INIT_LIST_HEAD(&(peasycap->urb_audio_head));
+       peasycap->purb_audio_head = &(peasycap->urb_audio_head);
+
+       JOT(4, "allocating an audio buffer\n");
+       JOT(4, ".... scattered over %i pages\n", \
+                                       peasycap->audio_buffer_page_many);
+
+       for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
+               if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
+                       SAY("ERROR: attempting to reallocate audio buffers\n");
+               } else {
+                       pbuf = (void *) __get_free_page(GFP_KERNEL);
+                       if ((void *)NULL == pbuf) {
+                               SAY("ERROR: Could not allocate audio " \
+                                                       "buffer page %i\n", k);
+                               return -ENOMEM;
+                       } else
+                               peasycap->allocation_audio_page += 1;
+
+                       peasycap->audio_buffer[k].pgo = pbuf;
+               }
+               peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo;
+       }
+
+       peasycap->audio_fill = 0;
+       peasycap->audio_read = 0;
+       JOT(4, "allocation of audio buffer done:  %i pages\n", k);
+/*---------------------------------------------------------------------------*/
+       JOT(4, "allocating %i isoc audio buffers of size %i\n",  \
+               AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
+       JOT(4, ".... each occupying contiguous memory pages\n");
+
+       for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
+               pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
+               if (NULL == pbuf) {
+                       SAY("ERROR: Could not allocate isoc audio buffer " \
+                                                       "%i\n", k);
+                       return -ENOMEM;
+               } else
+                       peasycap->allocation_audio_page += \
+                               ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
+
+               peasycap->audio_isoc_buffer[k].pgo = pbuf;
+               peasycap->audio_isoc_buffer[k].pto = pbuf + \
+               peasycap->audio_isoc_buffer_size;
+               peasycap->audio_isoc_buffer[k].kount = k;
+       }
+       JOT(4, "allocation of isoc audio buffers done.\n");
+/*---------------------------------------------------------------------------*/
+/*
+ *  ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
+ */
+/*---------------------------------------------------------------------------*/
+       JOT(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
+       JOT(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
+                                       peasycap->audio_isoc_framesperdesc);
+       JOT(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
+                                       peasycap->audio_isoc_maxframesize);
+       JOT(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
+                                       peasycap->audio_isoc_buffer_size);
+
+       for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY; k++) {
+               purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \
+                                                               GFP_KERNEL);
+               if (NULL == purb) {
+                       SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
+                                                       "%i\n", k);
+                       return -ENOMEM;
+               } else
+                       peasycap->allocation_audio_urb += 1 ;
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+               pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
+               if (NULL == pdata_urb) {
+                       SAY("ERROR: Could not allocate struct data_urb.\n");
+                       return -ENOMEM;
+               } else
+                       peasycap->allocation_audio_struct += \
+                                               sizeof(struct data_urb);
+
+               pdata_urb->purb = purb;
+               pdata_urb->isbuf = k;
+               pdata_urb->length = 0;
+               list_add_tail(&(pdata_urb->list_head), \
+                                               peasycap->purb_audio_head);
+/*---------------------------------------------------------------------------*/
+/*
+ *  ... AND INITIALIZE THEM
+ */
+/*---------------------------------------------------------------------------*/
+               if (!k) {
+                       JOT(4, "initializing audio urbs thus:\n");
+                       JOT(4, "  purb->interval = 1;\n");
+                       JOT(4, "  purb->dev = peasycap->pusb_device;\n");
+                       JOT(4, "  purb->pipe = usb_rcvisocpipe(peasycap->" \
+                                       "pusb_device,%i);\n", \
+                                       peasycap->audio_endpointnumber);
+                       JOT(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
+                       JOT(4, "  purb->transfer_buffer = " \
+                               "peasycap->audio_isoc_buffer[.].pgo;\n");
+                       JOT(4, "  purb->transfer_buffer_length = %i;\n", \
+                                       peasycap->audio_isoc_buffer_size);
+                       JOT(4, "  purb->complete = easysnd_complete;\n");
+                       JOT(4, "  purb->context = peasycap;\n");
+                       JOT(4, "  purb->start_frame = 0;\n");
+                       JOT(4, "  purb->number_of_packets = %i;\n", \
+                                       peasycap->audio_isoc_framesperdesc);
+                       JOT(4, "  for (j = 0; j < %i; j++)\n", \
+                                       peasycap->audio_isoc_framesperdesc);
+                       JOT(4, "    {\n");
+                       JOT(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
+                                       peasycap->audio_isoc_maxframesize);
+                       JOT(4, "    purb->iso_frame_desc[j].length = %i;\n", \
+                                       peasycap->audio_isoc_maxframesize);
+                       JOT(4, "    }\n");
+                       }
+
+               purb->interval = 1;
+               purb->dev = peasycap->pusb_device;
+               purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
+                                       peasycap->audio_endpointnumber);
+               purb->transfer_flags = URB_ISO_ASAP;
+               purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
+               purb->transfer_buffer_length = \
+                                       peasycap->audio_isoc_buffer_size;
+               purb->complete = easysnd_complete;
+               purb->context = peasycap;
+               purb->start_frame = 0;
+               purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
+               for (j = 0;  j < peasycap->audio_isoc_framesperdesc; j++) {
+                       purb->iso_frame_desc[j].offset = j * \
+                                       peasycap->audio_isoc_maxframesize;
+                       purb->iso_frame_desc[j].length = \
+                                       peasycap->audio_isoc_maxframesize;
+               }
+       }
+       JOT(4, "allocation of %i struct urb done.\n", k);
+/*---------------------------------------------------------------------------*/
+/*
+ *  SAVE POINTER peasycap IN THIS INTERFACE.
+ */
+/*---------------------------------------------------------------------------*/
+       usb_set_intfdata(pusb_interface, peasycap);
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
+ */
+/*---------------------------------------------------------------------------*/
+       rc = usb_register_dev(pusb_interface, &easysnd_class);
+       if (0 != rc) {
+               err("Not able to get a minor for this device.");
+               usb_set_intfdata(pusb_interface, NULL);
+               return -ENODEV;
+       } else
+               (peasycap->registered_audio)++;
+/*---------------------------------------------------------------------------*/
+/*
+ *  LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
+ */
+/*---------------------------------------------------------------------------*/
+       SAY("easysnd attached to minor #%d\n", pusb_interface->minor);
+       break;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
+ */
+/*---------------------------------------------------------------------------*/
+default: {
+       JOT(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
+       return -EINVAL;
+}
+}
+JOT(4, "ends successfully for interface %i\n", \
+                               pusb_interface_descriptor->bInterfaceNumber);
+return 0;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY
+ *  UNPLUGGED.
+ *  HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL.
+ */
+/*---------------------------------------------------------------------------*/
+void
+easycap_usb_disconnect(struct usb_interface *pusb_interface)
+{
+struct usb_host_interface *pusb_host_interface;
+struct usb_interface_descriptor *pusb_interface_descriptor;
+__u8 bInterfaceNumber;
+struct easycap *peasycap;
+
+struct list_head *plist_head;
+struct data_urb *pdata_urb;
+int minor, m;
+
+JOT(4, "\n");
+
+if ((struct usb_interface *)NULL == pusb_interface) {
+       JOT(4, "ERROR: pusb_interface is NULL\n");
+       return;
+}
+pusb_host_interface = pusb_interface->cur_altsetting;
+if ((struct usb_host_interface *)NULL == pusb_host_interface) {
+       JOT(4, "ERROR: pusb_host_interface is NULL\n");
+       return;
+}
+pusb_interface_descriptor = &(pusb_host_interface->desc);
+if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) {
+       JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
+       return;
+}
+bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
+minor = pusb_interface->minor;
+JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
+
+peasycap = usb_get_intfdata(pusb_interface);
+if ((struct easycap *)NULL == peasycap)
+       SAY("ERROR: peasycap is NULL\n");
+else {
+       peasycap->pusb_device = (struct usb_device *)NULL;
+       switch (bInterfaceNumber) {
+/*---------------------------------------------------------------------------*/
+       case 0: {
+               if ((struct list_head *)NULL != peasycap->purb_video_head) {
+                       JOT(4, "killing video urbs\n");
+                       m = 0;
+                       list_for_each(plist_head, (peasycap->purb_video_head))
+                               {
+                               pdata_urb = list_entry(plist_head, \
+                                               struct data_urb, list_head);
+                               if ((struct data_urb *)NULL != pdata_urb) {
+                                       if ((struct urb *)NULL != \
+                                                       pdata_urb->purb) {
+                                               usb_kill_urb(pdata_urb->purb);
+                                               m++;
+                                       }
+                               }
+                       }
+                       JOT(4, "%i video urbs killed\n", m);
+               } else
+                       SAY("ERROR: peasycap->purb_video_head is NULL\n");
+               break;
+       }
+/*---------------------------------------------------------------------------*/
+       case 2: {
+               if ((struct list_head *)NULL != peasycap->purb_audio_head) {
+                       JOT(4, "killing audio urbs\n");
+                       m = 0;
+                       list_for_each(plist_head, \
+                                               (peasycap->purb_audio_head)) {
+                               pdata_urb = list_entry(plist_head, \
+                                               struct data_urb, list_head);
+                               if ((struct data_urb *)NULL != pdata_urb) {
+                                       if ((struct urb *)NULL != \
+                                                       pdata_urb->purb) {
+                                               usb_kill_urb(pdata_urb->purb);
+                                               m++;
+                                       }
+                               }
+                       }
+                       JOT(4, "%i audio urbs killed\n", m);
+               } else
+                       SAY("ERROR: peasycap->purb_audio_head is NULL\n");
+               break;
+       }
+/*---------------------------------------------------------------------------*/
+       default:
+               break;
+       }
+}
+/*--------------------------------------------------------------------------*/
+/*
+ *  DEREGISTER
+ */
+/*--------------------------------------------------------------------------*/
+switch (bInterfaceNumber) {
+case 0: {
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+       if ((struct easycap *)NULL == peasycap) {
+               SAY("ERROR: peasycap has become NULL\n");
+       } else {
+               lock_kernel();
+               usb_deregister_dev(pusb_interface, &easycap_class);
+               (peasycap->registered_video)--;
+
+               JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
+               unlock_kernel();
+               SAY("easycap detached from minor #%d\n", minor);
+       }
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#else
+       if ((struct easycap *)NULL == peasycap)
+               SAY("ERROR: peasycap has become NULL\n");
+       else {
+               lock_kernel();
+               video_unregister_device(peasycap->pvideo_device);
+               (peasycap->registered_video)--;
+               unlock_kernel();
+               JOT(4, "unregistered with videodev: %i=minor\n", \
+                                                       pvideo_device->minor);
+       }
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+       break;
+}
+case 2: {
+       lock_kernel();
+
+       usb_deregister_dev(pusb_interface, &easysnd_class);
+       if ((struct easycap *)NULL != peasycap)
+               (peasycap->registered_audio)--;
+
+       JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
+       unlock_kernel();
+
+       SAY("easysnd detached from minor #%d\n", minor);
+       break;
+}
+default:
+       break;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
+ */
+/*---------------------------------------------------------------------------*/
+if ((struct easycap *)NULL == peasycap) {
+       SAY("ERROR: peasycap has become NULL\n");
+       SAY("cannot call kref_put()\n");
+       SAY("ending unsuccessfully: may cause memory leak\n");
+       return;
+}
+if (!peasycap->kref.refcount.counter) {
+       SAY("ERROR: peasycap->kref.refcount.counter is zero " \
+                                               "so cannot call kref_put()\n");
+       SAY("ending unsuccessfully: may cause memory leak\n");
+       return;
+}
+JOT(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \
+               bInterfaceNumber, (int)peasycap->kref.refcount.counter);
+kref_put(&peasycap->kref, easycap_delete);
+JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
+/*---------------------------------------------------------------------------*/
+
+JOT(4, "ends\n");
+return;
+}
+/*****************************************************************************/
+int __init
+easycap_module_init(void)
+{
+int result;
+
+SAY("========easycap=======\n");
+JOT(4, "begins.  %i=debug\n", easycap_debug);
+SAY("version: " EASYCAP_DRIVER_VERSION "\n");
+/*---------------------------------------------------------------------------*/
+/*
+ *  REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
+ */
+/*---------------------------------------------------------------------------*/
+JOT(4, "registering driver easycap\n");
+
+result = usb_register(&easycap_usb_driver);
+if (0 != result)
+       SAY("ERROR:  usb_register returned %i\n", result);
+
+JOT(4, "ends\n");
+return result;
+}
+/*****************************************************************************/
+void __exit
+easycap_module_exit(void)
+{
+JOT(4, "begins\n");
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM.
+ */
+/*---------------------------------------------------------------------------*/
+usb_deregister(&easycap_usb_driver);
+
+JOT(4, "ends\n");
+}
+/*****************************************************************************/
+
+module_init(easycap_module_init);
+module_exit(easycap_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
+MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
+MODULE_VERSION(EASYCAP_DRIVER_VERSION);
+#if defined(EASYCAP_DEBUG)
+MODULE_PARM_DESC(easycap_debug, "debug: 0 (default), 1, 2,...");
+#endif /*EASYCAP_DEBUG*/
+/*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c
new file mode 100644 (file)
index 0000000..38d9405
--- /dev/null
@@ -0,0 +1,489 @@
+/******************************************************************************
+*                                                                             *
+*  easycap_settings.c                                                         *
+*                                                                             *
+******************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+
+#include "easycap.h"
+#include "easycap_debug.h"
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE LEAST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
+ *                         0 => 25 fps
+ *                         1 => 30 fps
+ */
+/*---------------------------------------------------------------------------*/
+const struct easycap_standard easycap_standard[] = {
+{
+.mask = 0x000F & PAL_BGHIN ,
+.v4l2_standard = {
+       .index = PAL_BGHIN,
+       .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
+                                       V4L2_STD_PAL_I | V4L2_STD_PAL_N),
+       .name = "PAL_BGHIN",
+       .frameperiod = {1, 25},
+       .framelines = 625,
+       .reserved = {0, 0, 0, 0}
+       }
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & NTSC_N_443 ,
+.v4l2_standard = {
+       .index = NTSC_N_443,
+       .id = V4L2_STD_UNKNOWN,
+       .name = "NTSC_N_443",
+       .frameperiod = {1, 25},
+       .framelines = 480,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & PAL_Nc ,
+.v4l2_standard = {
+       .index = PAL_Nc,
+       .id = V4L2_STD_PAL_Nc,
+       .name = "PAL_Nc",
+       .frameperiod = {1, 25},
+       .framelines = 625,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & NTSC_N ,
+.v4l2_standard = {
+       .index = NTSC_N,
+       .id = V4L2_STD_UNKNOWN,
+       .name = "NTSC_N",
+       .frameperiod = {1, 25},
+       .framelines = 525,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & SECAM ,
+.v4l2_standard = {
+       .index = SECAM,
+       .id = V4L2_STD_SECAM,
+       .name = "SECAM",
+       .frameperiod = {1, 25},
+       .framelines = 625,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & NTSC_M ,
+.v4l2_standard = {
+       .index = NTSC_M,
+       .id = V4L2_STD_NTSC_M,
+       .name = "NTSC_M",
+       .frameperiod = {1, 30},
+       .framelines = 525,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & NTSC_M_JP ,
+.v4l2_standard = {
+       .index = NTSC_M_JP,
+       .id = V4L2_STD_NTSC_M_JP,
+       .name = "NTSC_M_JP",
+       .frameperiod = {1, 30},
+       .framelines = 525,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & PAL_60 ,
+.v4l2_standard = {
+       .index = PAL_60,
+       .id = V4L2_STD_PAL_60,
+       .name = "PAL_60",
+       .frameperiod = {1, 30},
+       .framelines = 525,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & NTSC_443 ,
+.v4l2_standard = {
+       .index = NTSC_443,
+       .id = V4L2_STD_NTSC_443,
+       .name = "NTSC_443",
+       .frameperiod = {1, 30},
+       .framelines = 525,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x000F & PAL_M ,
+.v4l2_standard = {
+       .index = PAL_M,
+       .id = V4L2_STD_PAL_M,
+       .name = "PAL_M",
+       .frameperiod = {1, 30},
+       .framelines = 525,
+       .reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0xFFFF
+}
+};
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE 16-BIT easycap_format.mask HAS MEANING:
+ *    (least significant) BIT  0:     0 => PAL, 25 FPS;   1 => NTSC, 30 FPS
+ *                        BITS 1-3:   RESERVED FOR DIFFERENTIATING STANDARDS
+ *                        BITS 4-7:   NUMBER OF BYTES PER PIXEL
+ *                        BIT  8:     0 => NATIVE BYTE ORDER;  1 => SWAPPED
+ *                        BITS 9-10:  RESERVED FOR OTHER BYTE PERMUTATIONS
+ *                        BIT 11:     0 => UNDECIMATED;  1 => DECIMATED
+ *                        BIT 12:     0 => OFFER FRAMES; 1 => OFFER FIELDS
+ *     (most significant) BITS 13-15: RESERVED FOR OTHER FIELD ORDER OPTIONS
+ *  IT FOLLOWS THAT:
+ *     bytesperpixel IS         ((0x00F0 & easycap_format.mask) >> 4)
+ *     byteswaporder IS true IF (0 != (0x0100 & easycap_format.mask))
+ *
+ *     decimatepixel IS true IF (0 != (0x0800 & easycap_format.mask))
+ *
+ *       offerfields IS true IF (0 != (0x1000 & easycap_format.mask))
+ */
+/*---------------------------------------------------------------------------*/
+
+struct easycap_format easycap_format[1 + SETTINGS_MANY];
+
+int
+fillin_formats(void)
+{
+int i, j, k, m, n;
+__u32 width, height, pixelformat, bytesperline, sizeimage;
+__u32 field, colorspace;
+__u16 mask1, mask2, mask3, mask4;
+char name1[32], name2[32], name3[32], name4[32];
+
+for (i = 0, n = 0; i < STANDARD_MANY; i++) {
+       mask1 = 0x0000;
+       switch (i) {
+       case PAL_BGHIN: {
+               mask1 = PAL_BGHIN;
+               strcpy(&name1[0], "PAL_BGHIN");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+               break;
+       }
+       case SECAM: {
+               mask1 = SECAM;
+               strcpy(&name1[0], "SECAM");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+               break;
+       }
+       case PAL_Nc: {
+               mask1 = PAL_Nc;
+               strcpy(&name1[0], "PAL_Nc");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+               break;
+       }
+       case PAL_60: {
+               mask1 = PAL_60;
+               strcpy(&name1[0], "PAL_60");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+               break;
+       }
+       case PAL_M: {
+               mask1 = PAL_M;
+               strcpy(&name1[0], "PAL_M");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+               break;
+       }
+       case NTSC_M: {
+               mask1 = NTSC_M;
+               strcpy(&name1[0], "NTSC_M");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+               break;
+       }
+       case NTSC_443: {
+               mask1 = NTSC_443;
+               strcpy(&name1[0], "NTSC_443");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+               break;
+       }
+       case NTSC_M_JP: {
+               mask1 = NTSC_M_JP;
+               strcpy(&name1[0], "NTSC_M_JP");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+               break;
+       }
+       case NTSC_N: {
+               mask1 = NTSC_M;
+               strcpy(&name1[0], "NTSC_N");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+               break;
+       }
+       case NTSC_N_443: {
+               mask1 = NTSC_N_443;
+               strcpy(&name1[0], "NTSC_N_443");
+               colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+               break;
+       }
+       default:
+               return -1;
+       }
+
+       for (j = 0; j < RESOLUTION_MANY; j++) {
+               mask2 = 0x0000;
+               switch (j) {
+               case AT_720x576: {
+                       if (0x1 & mask1)
+                               continue;
+                       strcpy(&name2[0], "_AT_720x576");
+                       width = 720; height = 576; break;
+               }
+               case AT_704x576: {
+                       if (0x1 & mask1)
+                               continue;
+                       strcpy(&name2[0], "_AT_704x576");
+                       width = 704; height = 576; break;
+               }
+               case AT_640x480: {
+                       strcpy(&name2[0], "_AT_640x480");
+                       width = 640; height = 480; break;
+               }
+               case AT_720x480: {
+                       if (!(0x1 & mask1))
+                               continue;
+                       strcpy(&name2[0], "_AT_720x480");
+                       width = 720; height = 480; break;
+               }
+               case AT_360x288: {
+                       if (0x1 & mask1)
+                               continue;
+                       strcpy(&name2[0], "_AT_360x288");
+                       width = 360; height = 288; mask2 = 0x0800; break;
+               }
+               case AT_320x240: {
+                       strcpy(&name2[0], "_AT_320x240");
+                       width = 320; height = 240; mask2 = 0x0800; break;
+               }
+               case AT_360x240: {
+                       if (!(0x1 & mask1))
+                               continue;
+                       strcpy(&name2[0], "_AT_360x240");
+                       width = 360; height = 240; mask2 = 0x0800; break;
+               }
+               default:
+                       return -2;
+               }
+
+               for (k = 0; k < PIXELFORMAT_MANY; k++) {
+                       mask3 = 0x0000;
+                       switch (k) {
+                       case FMT_UYVY: {
+                               strcpy(&name3[0], "_" STRINGIZE(FMT_UYVY));
+                               pixelformat = V4L2_PIX_FMT_UYVY;
+                               mask3 |= (0x02 << 4);
+                               break;
+                       }
+                       case FMT_YUY2: {
+                               strcpy(&name3[0], "_" STRINGIZE(FMT_YUY2));
+                               pixelformat = V4L2_PIX_FMT_YUYV;
+                               mask3 |= (0x02 << 4);
+                               mask3 |= 0x0100;
+                               break;
+                       }
+                       case FMT_RGB24: {
+                               strcpy(&name3[0], "_" STRINGIZE(FMT_RGB24));
+                               pixelformat = V4L2_PIX_FMT_RGB24;
+                               mask3 |= (0x03 << 4);
+                               break;
+                       }
+                       case FMT_RGB32: {
+                               strcpy(&name3[0], "_" STRINGIZE(FMT_RGB32));
+                               pixelformat = V4L2_PIX_FMT_RGB32;
+                               mask3 |= (0x04 << 4);
+                               break;
+                       }
+                       case FMT_BGR24: {
+                               strcpy(&name3[0], "_" STRINGIZE(FMT_BGR24));
+                               pixelformat = V4L2_PIX_FMT_BGR24;
+                               mask3 |= (0x03 << 4);
+                               mask3 |= 0x0100;
+                               break;
+                       }
+                       case FMT_BGR32: {
+                               strcpy(&name3[0], "_" STRINGIZE(FMT_BGR32));
+                               pixelformat = V4L2_PIX_FMT_BGR32;
+                               mask3 |= (0x04 << 4);
+                               mask3 |= 0x0100;
+                               break;
+                       }
+                       default:
+                               return -3;
+                       }
+                       bytesperline = width * ((mask3 & 0x00F0) >> 4);
+                       sizeimage =  bytesperline * height;
+
+                       for (m = 0; m < INTERLACE_MANY; m++) {
+                               mask4 = 0x0000;
+                               switch (m) {
+                               case FIELD_NONE: {
+                                       strcpy(&name4[0], "-n");
+                                       field = V4L2_FIELD_NONE;
+                                       break;
+                               }
+                               case FIELD_INTERLACED: {
+                                       strcpy(&name4[0], "-i");
+                                       field = V4L2_FIELD_INTERLACED;
+                                       break;
+                               }
+                               case FIELD_ALTERNATE: {
+                                       strcpy(&name4[0], "-a");
+                                       mask4 |= 0x1000;
+                                       field = V4L2_FIELD_ALTERNATE;
+                                       break;
+                               }
+                               default:
+                                       return -4;
+                               }
+                               if (SETTINGS_MANY <= n)
+                                       return -5;
+                               strcpy(&easycap_format[n].name[0], &name1[0]);
+                               strcat(&easycap_format[n].name[0], &name2[0]);
+                               strcat(&easycap_format[n].name[0], &name3[0]);
+                               strcat(&easycap_format[n].name[0], &name4[0]);
+                               easycap_format[n].mask = \
+                                               mask1 | mask2 | mask3 | mask4;
+                               easycap_format[n].v4l2_format\
+                                       .type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.width = width;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.height = height;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.pixelformat = pixelformat;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.field = field;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.bytesperline = bytesperline;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.sizeimage = sizeimage;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.colorspace = colorspace;
+                               easycap_format[n].v4l2_format\
+                                       .fmt.pix.priv = 0;
+                               n++;
+                       }
+               }
+       }
+}
+if ((1 + SETTINGS_MANY) <= n)
+       return -6;
+easycap_format[n].mask = 0xFFFF;
+return n;
+}
+/*---------------------------------------------------------------------------*/
+struct v4l2_queryctrl easycap_control[] = \
+ {{
+.id       = V4L2_CID_BRIGHTNESS,
+.type     = V4L2_CTRL_TYPE_INTEGER,
+.name     = "Brightness",
+.minimum  = 0,
+.maximum  = 255,
+.step     =  1,
+.default_value = SAA_0A_DEFAULT,
+.flags    = 0,
+.reserved = {0, 0}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.id       = V4L2_CID_CONTRAST,
+.type     = V4L2_CTRL_TYPE_INTEGER,
+.name     = "Contrast",
+.minimum  = 0,
+.maximum  = 255,
+.step     =   1,
+.default_value = SAA_0B_DEFAULT + 128,
+.flags    = 0,
+.reserved = {0, 0}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.id       = V4L2_CID_SATURATION,
+.type     = V4L2_CTRL_TYPE_INTEGER,
+.name     = "Saturation",
+.minimum  = 0,
+.maximum  = 255,
+.step     =   1,
+.default_value = SAA_0C_DEFAULT + 128,
+.flags    = 0,
+.reserved = {0, 0}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.id       = V4L2_CID_HUE,
+.type     = V4L2_CTRL_TYPE_INTEGER,
+.name     = "Hue",
+.minimum  = 0,
+.maximum  = 255,
+.step     =   1,
+.default_value = SAA_0D_DEFAULT + 128,
+.flags    = 0,
+.reserved = {0, 0}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.id       = V4L2_CID_AUDIO_VOLUME,
+.type     = V4L2_CTRL_TYPE_INTEGER,
+.name     = "Volume",
+.minimum  = 0,
+.maximum  = 31,
+.step     =   1,
+.default_value = 16,
+.flags    = 0,
+.reserved = {0, 0}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.id       = V4L2_CID_AUDIO_MUTE,
+.type     = V4L2_CTRL_TYPE_BOOLEAN,
+.name     = "Mute",
+.default_value = true,
+.flags    = 0,
+.reserved = {0, 0}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.id = 0xFFFFFFFF
+}
+ };
+/*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c
new file mode 100644 (file)
index 0000000..63562bd
--- /dev/null
@@ -0,0 +1,1046 @@
+/******************************************************************************
+*                                                                             *
+*  easycap_sound.c                                                            *
+*                                                                             *
+*  Audio driver for EasyCAP USB2.0 Video Capture Device DC60                  *
+*                                                                             *
+*                                                                             *
+******************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+
+#include "easycap.h"
+#include "easycap_debug.h"
+#include "easycap_sound.h"
+
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
+ *  PROVIDED peasycap->audio_idle IS ZER0.  REGARDLESS OF THIS BEING TRUE,
+ *  IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
+ */
+/*---------------------------------------------------------------------------*/
+void
+easysnd_complete(struct urb *purb)
+{
+static int mt;
+struct easycap *peasycap;
+struct data_buffer *paudio_buffer;
+char errbuf[16];
+__u8 *p1, *p2;
+__s16 s16;
+int i, j, more, much, leap, rc;
+#if defined(UPSAMPLE)
+int k;
+__s16 oldaudio, newaudio, delta;
+#endif /*UPSAMPLE*/
+
+JOT(16, "\n");
+
+if (NULL == purb) {
+       SAY("ERROR: purb is NULL\n");
+       return;
+}
+peasycap = purb->context;
+if (NULL == peasycap) {
+       SAY("ERROR: peasycap is NULL\n");
+       return;
+}
+much = 0;
+
+
+if (peasycap->audio_idle) {
+       JOT(16, "%i=audio_idle  %i=audio_isoc_streaming\n", \
+                       peasycap->audio_idle, peasycap->audio_isoc_streaming);
+       if (peasycap->audio_isoc_streaming) {
+               rc = usb_submit_urb(purb, GFP_ATOMIC);
+               if (0 != rc) {
+                       SAY("ERROR: while %i=audio_idle, " \
+                                       "usb_submit_urb() failed with rc:\n", \
+                                                       peasycap->audio_idle);
+                       switch (rc) {
+                       case -ENOMEM: {
+                               SAY("ENOMEM\n");    break;
+                       }
+                       case -ENODEV: {
+                               SAY("ENODEV\n");    break;
+                       }
+                       case -ENXIO: {
+                               SAY("ENXIO\n");     break;
+                       }
+                       case -EINVAL: {
+                               SAY("EINVAL\n");    break;
+                       }
+                       case -EAGAIN: {
+                               SAY("EAGAIN\n");    break;
+                       }
+                       case -EFBIG: {
+                               SAY("EFBIG\n");     break;
+                       }
+                       case -EPIPE: {
+                               SAY("EPIPE\n");     break;
+                       }
+                       case -EMSGSIZE: {
+                               SAY("EMSGSIZE\n");  break;
+                       }
+                       case -ENOSPC: {
+                               SAY("ENOSPC\n");  break;
+                       }
+                       default: {
+                               SAY("0x%08X\n", rc); break;
+                       }
+                       }
+               }
+       }
+return;
+}
+/*---------------------------------------------------------------------------*/
+if (purb->status) {
+       if (-ESHUTDOWN == purb->status) {
+               JOT(16, "immediate return because -ESHUTDOWN=purb->status\n");
+               return;
+       }
+       SAY("ERROR: non-zero urb status:\n");
+       switch (purb->status) {
+       case -EINPROGRESS: {
+               SAY("-EINPROGRESS\n"); break;
+       }
+       case -ENOSR: {
+               SAY("-ENOSR\n"); break;
+       }
+       case -EPIPE: {
+               SAY("-EPIPE\n"); break;
+       }
+       case -EOVERFLOW: {
+               SAY("-EOVERFLOW\n"); break;
+       }
+       case -EPROTO: {
+               SAY("-EPROTO\n"); break;
+       }
+       case -EILSEQ: {
+               SAY("-EILSEQ\n"); break;
+       }
+       case -ETIMEDOUT: {
+               SAY("-ETIMEDOUT\n"); break;
+       }
+       case -EMSGSIZE: {
+               SAY("-EMSGSIZE\n"); break;
+       }
+       case -EOPNOTSUPP: {
+               SAY("-EOPNOTSUPP\n"); break;
+       }
+       case -EPFNOSUPPORT: {
+               SAY("-EPFNOSUPPORT\n"); break;
+       }
+       case -EAFNOSUPPORT: {
+               SAY("-EAFNOSUPPORT\n"); break;
+       }
+       case -EADDRINUSE: {
+               SAY("-EADDRINUSE\n"); break;
+       }
+       case -EADDRNOTAVAIL: {
+               SAY("-EADDRNOTAVAIL\n"); break;
+       }
+       case -ENOBUFS: {
+               SAY("-ENOBUFS\n"); break;
+       }
+       case -EISCONN: {
+               SAY("-EISCONN\n"); break;
+       }
+       case -ENOTCONN: {
+               SAY("-ENOTCONN\n"); break;
+       }
+       case -ESHUTDOWN: {
+               SAY("-ESHUTDOWN\n"); break;
+       }
+       case -ENOENT: {
+               SAY("-ENOENT\n"); break;
+       }
+       case -ECONNRESET: {
+               SAY("-ECONNRESET\n"); break;
+       }
+       case -ENOSPC: {
+               SAY("ENOSPC\n");  break;
+       }
+       default: {
+               SAY("unknown error code 0x%08X\n", purb->status); break;
+       }
+       }
+/*---------------------------------------------------------------------------*/
+/*
+ *  RESUBMIT THIS URB AFTER AN ERROR
+ *
+ *  (THIS IS DUPLICATE CODE TO REDUCE INDENTATION OF THE NO-ERROR PATH)
+ */
+/*---------------------------------------------------------------------------*/
+       if (peasycap->audio_isoc_streaming) {
+               rc = usb_submit_urb(purb, GFP_ATOMIC);
+               if (0 != rc) {
+                       SAY("ERROR: while %i=audio_idle, usb_submit_urb() "
+                               "failed with rc:\n", peasycap->audio_idle);
+                       switch (rc) {
+                       case -ENOMEM: {
+                               SAY("ENOMEM\n");    break;
+                       }
+                       case -ENODEV: {
+                               SAY("ENODEV\n");    break;
+                       }
+                       case -ENXIO: {
+                               SAY("ENXIO\n");     break;
+                       }
+                       case -EINVAL: {
+                               SAY("EINVAL\n");    break;
+                       }
+                       case -EAGAIN: {
+                               SAY("EAGAIN\n");    break;
+                       }
+                       case -EFBIG: {
+                               SAY("EFBIG\n");     break;
+                       }
+                       case -EPIPE: {
+                               SAY("EPIPE\n");     break;
+                       }
+                       case -EMSGSIZE: {
+                               SAY("EMSGSIZE\n");  break;
+                       }
+                       default: {
+                               SAY("0x%08X\n", rc); break;
+                       }
+                       }
+               }
+       }
+       return;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  PROCEED HERE WHEN NO ERROR
+ */
+/*---------------------------------------------------------------------------*/
+#if defined(UPSAMPLE)
+oldaudio = peasycap->oldaudio;
+#endif /*UPSAMPLE*/
+
+for (i = 0;  i < purb->number_of_packets; i++) {
+       switch (purb->iso_frame_desc[i].status) {
+       case  0: {
+               strcpy(&errbuf[0], "OK"); break;
+       }
+       case -ENOENT: {
+               strcpy(&errbuf[0], "-ENOENT"); break;
+       }
+       case -EINPROGRESS: {
+               strcpy(&errbuf[0], "-EINPROGRESS"); break;
+       }
+       case -EPROTO: {
+               strcpy(&errbuf[0], "-EPROTO"); break;
+       }
+       case -EILSEQ: {
+               strcpy(&errbuf[0], "-EILSEQ"); break;
+       }
+       case -ETIME: {
+               strcpy(&errbuf[0], "-ETIME"); break;
+       }
+       case -ETIMEDOUT: {
+               strcpy(&errbuf[0], "-ETIMEDOUT"); break;
+       }
+       case -EPIPE: {
+               strcpy(&errbuf[0], "-EPIPE"); break;
+       }
+       case -ECOMM: {
+               strcpy(&errbuf[0], "-ECOMM"); break;
+       }
+       case -ENOSR: {
+               strcpy(&errbuf[0], "-ENOSR"); break;
+       }
+       case -EOVERFLOW: {
+               strcpy(&errbuf[0], "-EOVERFLOW"); break;
+       }
+       case -EREMOTEIO: {
+               strcpy(&errbuf[0], "-EREMOTEIO"); break;
+       }
+       case -ENODEV: {
+               strcpy(&errbuf[0], "-ENODEV"); break;
+       }
+       case -EXDEV: {
+               strcpy(&errbuf[0], "-EXDEV"); break;
+       }
+       case -EINVAL: {
+               strcpy(&errbuf[0], "-EINVAL"); break;
+       }
+       case -ECONNRESET: {
+               strcpy(&errbuf[0], "-ECONNRESET"); break;
+       }
+       case -ENOSPC: {
+               strcpy(&errbuf[0], "-ENOSPC"); break;
+       }
+       case -ESHUTDOWN: {
+               strcpy(&errbuf[0], "-ESHUTDOWN"); break;
+       }
+       default: {
+               strcpy(&errbuf[0], "UNKNOWN"); break;
+       }
+       }
+       if ((!purb->iso_frame_desc[i].status) && 0) {
+               JOT(16, "frame[%2i]: %i=status{=%16s}  "  \
+                                               "%5i=actual  "  \
+                                               "%5i=length  "  \
+                                               "%3i=offset\n", \
+                               i, purb->iso_frame_desc[i].status, &errbuf[0],
+                               purb->iso_frame_desc[i].actual_length,
+                               purb->iso_frame_desc[i].length,
+                               purb->iso_frame_desc[i].offset);
+       }
+       if (!purb->iso_frame_desc[i].status) {
+               more = purb->iso_frame_desc[i].actual_length;
+
+#if defined(TESTTONE)
+               if (!more)
+                       more = purb->iso_frame_desc[i].length;
+#endif
+
+               if (!more)
+                       mt++;
+               else {
+                       if (mt) {
+                               JOT(16, "%4i empty audio urb frames\n", mt);
+                               mt = 0;
+                       }
+
+                       p1 = (__u8 *)(purb->transfer_buffer + \
+                                       purb->iso_frame_desc[i].offset);
+
+                       leap = 0;
+                       p1 += leap;
+                       more -= leap;
+/*---------------------------------------------------------------------------*/
+/*
+ *  COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
+ *  CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
+ */
+/*---------------------------------------------------------------------------*/
+                       while (more) {
+                               if (0 > more) {
+                                       SAY("easysnd_complete: MISTAKE: " \
+                                                       "more is negative\n");
+                                       return;
+                               }
+                               if (peasycap->audio_buffer_page_many <= \
+                                                       peasycap->audio_fill) {
+                                       SAY("ERROR: bad " \
+                                               "peasycap->audio_fill\n");
+                                       return;
+                               }
+
+                               paudio_buffer = &peasycap->audio_buffer\
+                                                       [peasycap->audio_fill];
+                               if (PAGE_SIZE < (paudio_buffer->pto - \
+                                               paudio_buffer->pgo)) {
+                                       SAY("ERROR: bad paudio_buffer->pto\n");
+                                       return;
+                               }
+                               if (PAGE_SIZE == (paudio_buffer->pto - \
+                                                       paudio_buffer->pgo)) {
+
+#if defined(TESTTONE)
+                                       easysnd_testtone(peasycap, \
+                                                       peasycap->audio_fill);
+#endif /*TESTTONE*/
+
+                                       paudio_buffer->pto = \
+                                                       paudio_buffer->pgo;
+                                       (peasycap->audio_fill)++;
+                                       if (peasycap->\
+                                               audio_buffer_page_many <= \
+                                                       peasycap->audio_fill)
+                                               peasycap->audio_fill = 0;
+
+                                       JOT(12, "bumped peasycap->" \
+                                                       "audio_fill to %i\n", \
+                                                       peasycap->audio_fill);
+
+                                       paudio_buffer = &peasycap->\
+                                                       audio_buffer\
+                                                       [peasycap->audio_fill];
+                                       paudio_buffer->pto = \
+                                                       paudio_buffer->pgo;
+
+                                       if (!(peasycap->audio_fill % \
+                                               peasycap->\
+                                               audio_pages_per_fragment)) {
+                                               JOT(12, "wakeup call on wq_" \
+                                               "audio, %i=frag reading  %i" \
+                                               "=fragment fill\n", \
+                                               (peasycap->audio_read / \
+                                               peasycap->\
+                                               audio_pages_per_fragment), \
+                                               (peasycap->audio_fill / \
+                                               peasycap->\
+                                               audio_pages_per_fragment));
+                                               wake_up_interruptible\
+                                               (&(peasycap->wq_audio));
+                                       }
+                               }
+
+                               much = PAGE_SIZE - (int)(paudio_buffer->pto -\
+                                                        paudio_buffer->pgo);
+
+                               if (false == peasycap->microphone) {
+                                       if (much > more)
+                                               much = more;
+
+                                       memcpy(paudio_buffer->pto, p1, much);
+                                       p1 += much;
+                                       more -= much;
+                               } else {
+#if defined(UPSAMPLE)
+                                       if (much % 16)
+                                               JOT(8, "MISTAKE? much" \
+                                               " is not divisible by 16\n");
+                                       if (much > (16 * \
+                                                       more))
+                                               much = 16 * \
+                                                       more;
+                                       p2 = (__u8 *)paudio_buffer->pto;
+
+                                       for (j = 0;  j < (much/16);  j++) {
+                                               newaudio =  ((int) *p1) - 128;
+                                               newaudio = 128 * \
+                                                               newaudio;
+
+                                               delta = (newaudio - oldaudio) \
+                                                                       / 4;
+                                               s16 = oldaudio + delta;
+
+                                               for (k = 0;  k < 4;  k++) {
+                                                       *p2 = (0x00FF & s16);
+                                                       *(p2 + 1) = (0xFF00 & \
+                                                               s16) >> 8;
+                                                       p2 += 2;
+                                                       *p2 = (0x00FF & s16);
+                                                       *(p2 + 1) = (0xFF00 & \
+                                                               s16) >> 8;
+                                                       p2 += 2;
+
+                                                       s16 += delta;
+                                               }
+                                               p1++;
+                                               more--;
+                                               oldaudio = s16;
+                                       }
+#else
+                                       if (much > (2 * more))
+                                               much = 2 * more;
+                                       p2 = (__u8 *)paudio_buffer->pto;
+
+                                       for (j = 0;  j < (much / 2);  j++) {
+                                               s16 =  ((int) *p1) - 128;
+                                               s16 = 128 * \
+                                                               s16;
+                                               *p2 = (0x00FF & s16);
+                                               *(p2 + 1) = (0xFF00 & s16) >> \
+                                                                       8;
+                                               p1++;  p2 += 2;
+                                               more--;
+                                       }
+#endif /*UPSAMPLE*/
+                               }
+                               (paudio_buffer->pto) += much;
+                       }
+               }
+       } else {
+               JOT(12, "discarding audio samples because " \
+                       "%i=purb->iso_frame_desc[i].status\n", \
+                               purb->iso_frame_desc[i].status);
+       }
+
+#if defined(UPSAMPLE)
+peasycap->oldaudio = oldaudio;
+#endif /*UPSAMPLE*/
+
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  RESUBMIT THIS URB AFTER NO ERROR
+ */
+/*---------------------------------------------------------------------------*/
+if (peasycap->audio_isoc_streaming) {
+       rc = usb_submit_urb(purb, GFP_ATOMIC);
+       if (0 != rc) {
+               SAY("ERROR: while %i=audio_idle, usb_submit_urb() failed " \
+                                       "with rc:\n", peasycap->audio_idle);
+               switch (rc) {
+               case -ENOMEM: {
+                       SAY("ENOMEM\n");    break;
+               }
+               case -ENODEV: {
+                       SAY("ENODEV\n");    break;
+               }
+               case -ENXIO: {
+                       SAY("ENXIO\n");     break;
+               }
+               case -EINVAL: {
+                       SAY("EINVAL\n");    break;
+               }
+               case -EAGAIN: {
+                       SAY("EAGAIN\n");    break;
+               }
+               case -EFBIG: {
+                       SAY("EFBIG\n");     break;
+               }
+               case -EPIPE: {
+                       SAY("EPIPE\n");     break;
+               }
+               case -EMSGSIZE: {
+                       SAY("EMSGSIZE\n");  break;
+               }
+               case -ENOSPC: {
+                       SAY("ENOSPC\n");  break;
+               }
+               default: {
+                       SAY("0x%08X\n", rc); break;
+               }
+               }
+       }
+}
+return;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
+ *  STREAM FROM /dev/easysnd1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
+ *  HAVE AN IOCTL INTERFACE.  THE VIDEO URBS, BY CONTRAST, MUST BE SUBMITTED
+ *  MUCH LATER: SEE COMMENTS IN FILE easycap_main.c.
+ */
+/*---------------------------------------------------------------------------*/
+int
+easysnd_open(struct inode *inode, struct file *file)
+{
+struct usb_interface *pusb_interface;
+struct easycap *peasycap;
+int subminor, rc;
+
+JOT(4, "begins.\n");
+
+subminor = iminor(inode);
+
+pusb_interface = usb_find_interface(&easycap_usb_driver, subminor);
+if (NULL == pusb_interface) {
+       SAY("ERROR: pusb_interface is NULL\n");
+       SAY("ending unsuccessfully\n");
+       return -1;
+}
+peasycap = usb_get_intfdata(pusb_interface);
+if (NULL == peasycap) {
+       SAY("ERROR: peasycap is NULL\n");
+       SAY("ending unsuccessfully\n");
+       return -1;
+}
+
+file->private_data = peasycap;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  INITIALIZATION.
+ */
+/*---------------------------------------------------------------------------*/
+JOT(4, "starting initialization\n");
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+} else {
+       JOT(16, "0x%08lX=peasycap->pusb_device\n", \
+                                       (long int)peasycap->pusb_device);
+}
+
+rc = audio_setup(peasycap);
+if (0 <= rc)
+       JOT(8, "audio_setup() returned %i\n", rc);
+else
+       JOT(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc);
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device has become NULL\n");
+       return -EFAULT;
+}
+rc = adjust_volume(peasycap, -8192);
+if (0 != rc) {
+       SAY("ERROR: adjust_volume(default) returned %i\n", rc);
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device has become NULL\n");
+       return -EFAULT;
+}
+rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \
+                                       peasycap->audio_altsetting_on);
+JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \
+                                       peasycap->audio_altsetting_on, rc);
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device has become NULL\n");
+       return -EFAULT;
+}
+rc = wakeup_device(peasycap->pusb_device);
+if (0 == rc)
+       JOT(8, "wakeup_device() returned %i\n", rc);
+else
+       JOT(8, "easysnd open(): ERROR: wakeup_device() returned %i\n", rc);
+
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device has become NULL\n");
+       return -EFAULT;
+}
+submit_audio_urbs(peasycap);
+peasycap->audio_idle = 0;
+
+peasycap->timeval1.tv_sec  = 0;
+peasycap->timeval1.tv_usec = 0;
+
+JOT(4, "finished initialization\n");
+return 0;
+}
+/*****************************************************************************/
+int
+easysnd_release(struct inode *inode, struct file *file)
+{
+struct easycap *peasycap;
+
+JOT(4, "begins\n");
+
+peasycap = file->private_data;
+if (NULL == peasycap) {
+       SAY("ERROR:  peasycap is NULL.\n");
+       return -EFAULT;
+}
+if (0 != kill_audio_urbs(peasycap)) {
+       SAY("ERROR: kill_audio_urbs() failed\n");
+       return -EFAULT;
+}
+JOT(4, "ending successfully\n");
+return 0;
+}
+/*****************************************************************************/
+ssize_t
+easysnd_read(struct file *file, char __user *puserspacebuffer, \
+                                               size_t kount, loff_t *poff)
+{
+struct timeval timeval;
+static struct timeval timeval1;
+static long long int audio_bytes, above, below, mean;
+struct signed_div_result sdr;
+unsigned char *p0;
+long int kount1, more, rc, l0, lm;
+int fragment;
+struct easycap *peasycap;
+struct data_buffer *pdata_buffer;
+size_t szret;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
+ *
+ ******************************************************************************
+ *****  N.B.  IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
+ *****        THIS CONDITION SIGNIFIES END-OF-FILE.                      ******
+ ******************************************************************************
+ */
+/*---------------------------------------------------------------------------*/
+
+JOT(8, "===== easysnd_read(): kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
+
+peasycap = (struct easycap *)(file->private_data);
+if (NULL == peasycap) {
+       SAY("ERROR in easysnd_read(): peasycap is NULL\n");
+       return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+if ((0 > peasycap->audio_read) || \
+               (peasycap->audio_buffer_page_many <= peasycap->audio_read)) {
+       SAY("ERROR: peasycap->audio_read out of range\n");
+       return -EFAULT;
+}
+pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
+if ((struct data_buffer *)NULL == pdata_buffer) {
+       SAY("ERROR: pdata_buffer is NULL\n");
+       return -EFAULT;
+}
+JOT(12, "before wait, %i=frag read  %i=frag fill\n", \
+               (peasycap->audio_read / peasycap->audio_pages_per_fragment), \
+               (peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
+while ((fragment == (peasycap->audio_fill / \
+                               peasycap->audio_pages_per_fragment)) || \
+               (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) {
+       if (file->f_flags & O_NONBLOCK) {
+               JOT(16, "returning -EAGAIN as instructed\n");
+               return -EAGAIN;
+       }
+       rc = wait_event_interruptible(peasycap->wq_audio, \
+               (peasycap->audio_idle  || peasycap->audio_eof   || \
+               ((fragment != (peasycap->audio_fill / \
+                               peasycap->audio_pages_per_fragment)) && \
+               (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo))))));
+       if (0 != rc) {
+               SAY("aborted by signal\n");
+               return -ERESTARTSYS;
+       }
+       if (peasycap->audio_eof) {
+               JOT(8, "returning 0 because  %i=audio_eof\n", \
+                                                       peasycap->audio_eof);
+               kill_audio_urbs(peasycap);
+               msleep(500);
+               return 0;
+       }
+       if (peasycap->audio_idle) {
+               JOT(16, "returning 0 because  %i=audio_idle\n", \
+                                                       peasycap->audio_idle);
+               return 0;
+       }
+       if (!peasycap->audio_isoc_streaming) {
+               JOT(16, "returning 0 because audio urbs not streaming\n");
+               return 0;
+       }
+}
+JOT(12, "after  wait, %i=frag read  %i=frag fill\n", \
+               (peasycap->audio_read / peasycap->audio_pages_per_fragment), \
+               (peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+szret = (size_t)0;
+while (fragment == (peasycap->audio_read / \
+                               peasycap->audio_pages_per_fragment)) {
+       if (NULL == pdata_buffer->pgo) {
+               SAY("ERROR: pdata_buffer->pgo is NULL\n");
+               return -EFAULT;
+       }
+       if (NULL == pdata_buffer->pto) {
+               SAY("ERROR: pdata_buffer->pto is NULL\n");
+               return -EFAULT;
+       }
+       kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
+       if (0 > kount1) {
+               SAY("easysnd_read: MISTAKE: kount1 is negative\n");
+               return -ERESTARTSYS;
+       }
+       if (!kount1) {
+               (peasycap->audio_read)++;
+               if (peasycap->audio_buffer_page_many <= peasycap->audio_read)
+                       peasycap->audio_read = 0;
+               JOT(12, "bumped peasycap->audio_read to %i\n", \
+                                               peasycap->audio_read);
+
+               if (fragment != (peasycap->audio_read / \
+                                       peasycap->audio_pages_per_fragment))
+                       break;
+
+               if ((0 > peasycap->audio_read) || \
+                       (peasycap->audio_buffer_page_many <= \
+                                       peasycap->audio_read)) {
+                       SAY("ERROR: peasycap->audio_read out of range\n");
+                       return -EFAULT;
+               }
+               pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
+               if ((struct data_buffer *)NULL == pdata_buffer) {
+                       SAY("ERROR: pdata_buffer is NULL\n");
+                       return -EFAULT;
+               }
+               if (NULL == pdata_buffer->pgo) {
+                       SAY("ERROR: pdata_buffer->pgo is NULL\n");
+                       return -EFAULT;
+               }
+               if (NULL == pdata_buffer->pto) {
+                       SAY("ERROR: pdata_buffer->pto is NULL\n");
+                       return -EFAULT;
+               }
+               kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
+       }
+       JOT(12, "ready  to send %li bytes\n", (long int) kount1);
+       JOT(12, "still  to send %li bytes\n", (long int) kount);
+       more = kount1;
+       if (more > kount)
+               more = kount;
+       JOT(12, "agreed to send %li bytes from page %i\n", \
+                                               more, peasycap->audio_read);
+       if (!more)
+               break;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  ACCUMULATE DYNAMIC-RANGE INFORMATION
+ */
+/*---------------------------------------------------------------------------*/
+       p0 = (unsigned char *)pdata_buffer->pgo;  l0 = 0;  lm = more/2;
+       while (l0 < lm) {
+               SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, \
+                               &peasycap->audio_square);  l0++;  p0 += 2;
+       }
+/*---------------------------------------------------------------------------*/
+       rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more);
+       if (0 != rc) {
+               SAY("ERROR: copy_to_user() returned %li\n", rc);
+               return -EFAULT;
+       }
+       *poff += (loff_t)more;
+       szret += (size_t)more;
+       pdata_buffer->pto += more;
+       puserspacebuffer += more;
+       kount -= (size_t)more;
+}
+JOT(12, "after  read, %i=frag read  %i=frag fill\n", \
+               (peasycap->audio_read / peasycap->audio_pages_per_fragment), \
+               (peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+if (kount < 0) {
+       SAY("MISTAKE:  %li=kount  %li=szret\n", \
+                                       (long int)kount, (long int)szret);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
+ */
+/*---------------------------------------------------------------------------*/
+if (peasycap->audio_sample) {
+       below = peasycap->audio_sample;
+       above = peasycap->audio_square;
+       sdr = signed_div(above, below);
+       above = sdr.quotient;
+       mean = peasycap->audio_niveau;
+       sdr = signed_div(mean, peasycap->audio_sample);
+
+       JOT(8, "%8lli=mean  %8lli=meansquare after %lli samples, =>\n", \
+                               sdr.quotient, above, peasycap->audio_sample);
+
+       sdr = signed_div(above, 32768);
+       JOT(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  UPDATE THE AUDIO CLOCK
+ */
+/*---------------------------------------------------------------------------*/
+do_gettimeofday(&timeval);
+if (!peasycap->timeval1.tv_sec) {
+       audio_bytes = 0;
+       timeval1 = timeval;
+
+       if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
+               return -ERESTARTSYS;
+       peasycap->timeval1 = timeval1;
+       mutex_unlock(&(peasycap->mutex_timeval1));
+       sdr.quotient = 192000;
+} else {
+       audio_bytes += (long long int) szret;
+       below = ((long long int)(1000000)) * \
+               ((long long int)(timeval.tv_sec  - timeval1.tv_sec)) + \
+               (long long int)(timeval.tv_usec - timeval1.tv_usec);
+       above = 1000000 * ((long long int) audio_bytes);
+
+       if (below)
+               sdr = signed_div(above, below);
+       else
+               sdr.quotient = 192000;
+}
+JOT(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
+if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
+       return -ERESTARTSYS;
+peasycap->dnbydt = sdr.quotient;
+mutex_unlock(&(peasycap->mutex_timeval1));
+
+JOT(8, "returning %li\n", (long int)szret);
+return szret;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  SUBMIT ALL AUDIO URBS.
+ */
+/*---------------------------------------------------------------------------*/
+int
+submit_audio_urbs(struct easycap *peasycap)
+{
+struct data_urb *pdata_urb;
+struct urb *purb;
+struct list_head *plist_head;
+int j, isbad, m, rc;
+int isbuf;
+
+if ((struct list_head *)NULL == peasycap->purb_audio_head) {
+       SAY("ERROR: peasycap->urb_audio_head uninitialized\n");
+       return -EFAULT;
+}
+if ((struct usb_device *)NULL == peasycap->pusb_device) {
+       SAY("ERROR: peasycap->pusb_device is NULL\n");
+       return -EFAULT;
+}
+if (!peasycap->audio_isoc_streaming) {
+       JOT(4, "initial submission of all audio urbs\n");
+       rc = usb_set_interface(peasycap->pusb_device,
+                                       peasycap->audio_interface, \
+                                       peasycap->audio_altsetting_on);
+       JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", \
+                                       peasycap->audio_interface, \
+                                       peasycap->audio_altsetting_on, rc);
+
+       isbad = 0;  m = 0;
+       list_for_each(plist_head, (peasycap->purb_audio_head)) {
+               pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+               if (NULL != pdata_urb) {
+                       purb = pdata_urb->purb;
+                       if (NULL != purb) {
+                               isbuf = pdata_urb->isbuf;
+
+                               purb->interval = 1;
+                               purb->dev = peasycap->pusb_device;
+                               purb->pipe = \
+                                       usb_rcvisocpipe(peasycap->pusb_device,\
+                                       peasycap->audio_endpointnumber);
+                               purb->transfer_flags = URB_ISO_ASAP;
+                               purb->transfer_buffer = \
+                                       peasycap->audio_isoc_buffer[isbuf].pgo;
+                               purb->transfer_buffer_length = \
+                                       peasycap->audio_isoc_buffer_size;
+                               purb->complete = easysnd_complete;
+                               purb->context = peasycap;
+                               purb->start_frame = 0;
+                               purb->number_of_packets = \
+                                       peasycap->audio_isoc_framesperdesc;
+                               for (j = 0;  j < peasycap->\
+                                               audio_isoc_framesperdesc; \
+                                                                       j++) {
+                                       purb->iso_frame_desc[j].offset = j * \
+                                               peasycap->\
+                                               audio_isoc_maxframesize;
+                                       purb->iso_frame_desc[j].length = \
+                                               peasycap->\
+                                               audio_isoc_maxframesize;
+                               }
+
+                               rc = usb_submit_urb(purb, GFP_KERNEL);
+                               if (0 != rc) {
+                                       isbad++;
+                                       SAY("ERROR: usb_submit_urb() failed" \
+                                                       " for urb with rc:\n");
+                                       switch (rc) {
+                                       case -ENOMEM: {
+                                               SAY("ENOMEM\n"); break;
+                                       }
+                                       case -ENODEV: {
+                                               SAY("ENODEV\n"); break;
+                                       }
+                                       case -ENXIO: {
+                                               SAY("ENXIO\n"); break;
+                                       }
+                                       case -EINVAL: {
+                                               SAY("EINVAL\n"); break;
+                                       }
+                                       case -EAGAIN: {
+                                               SAY("EAGAIN\n"); break;
+                                       }
+                                       case -EFBIG: {
+                                               SAY("EFBIG\n"); break;
+                                       }
+                                       case -EPIPE: {
+                                               SAY("EPIPE\n"); break;
+                                       }
+                                       case -EMSGSIZE: {
+                                               SAY("EMSGSIZE\n"); break;
+                                       }
+                                       case -ENOSPC: {
+                                               SAY("ENOSPC\n"); break;
+                                       }
+                                       default: {
+                                               SAY("unknown error code %i\n",\
+                                                                rc); break;
+                                       }
+                                       }
+                               } else {
+                                        m++;
+                               }
+                       } else {
+                               isbad++;
+                       }
+               } else {
+                       isbad++;
+               }
+       }
+       if (isbad) {
+               JOT(4, "attempting cleanup instead of submitting\n");
+               list_for_each(plist_head, (peasycap->purb_audio_head)) {
+                       pdata_urb = list_entry(plist_head, struct data_urb, \
+                                                               list_head);
+                       if (NULL != pdata_urb) {
+                               purb = pdata_urb->purb;
+                               if (NULL != purb)
+                                       usb_kill_urb(purb);
+                       }
+               }
+               peasycap->audio_isoc_streaming = 0;
+       } else {
+               peasycap->audio_isoc_streaming = 1;
+               JOT(4, "submitted %i audio urbs\n", m);
+       }
+} else
+       JOT(4, "already streaming audio urbs\n");
+
+return 0;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  KILL ALL AUDIO URBS.
+ */
+/*---------------------------------------------------------------------------*/
+int
+kill_audio_urbs(struct easycap *peasycap)
+{
+int m;
+struct list_head *plist_head;
+struct data_urb *pdata_urb;
+
+if (peasycap->audio_isoc_streaming) {
+       if ((struct list_head *)NULL != peasycap->purb_audio_head) {
+               peasycap->audio_isoc_streaming = 0;
+               JOT(4, "killing audio urbs\n");
+               m = 0;
+               list_for_each(plist_head, (peasycap->purb_audio_head)) {
+                       pdata_urb = list_entry(plist_head, struct data_urb,
+                                                               list_head);
+                       if ((struct data_urb *)NULL != pdata_urb) {
+                               if ((struct urb *)NULL != pdata_urb->purb) {
+                                       usb_kill_urb(pdata_urb->purb);
+                                       m++;
+                               }
+                       }
+               }
+               JOT(4, "%i audio urbs killed\n", m);
+       } else {
+               SAY("ERROR: peasycap->purb_audio_head is NULL\n");
+               return -EFAULT;
+       }
+} else {
+       JOT(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \
+                                       peasycap->audio_isoc_streaming);
+}
+return 0;
+}
+/*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_sound.h b/drivers/staging/easycap/easycap_sound.h
new file mode 100644 (file)
index 0000000..4912739
--- /dev/null
@@ -0,0 +1,28 @@
+/*****************************************************************************
+*                                                                            *
+*  easycap_sound.h                                                           *
+*                                                                            *
+*****************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+extern struct easycap *peasycap;
+extern struct usb_driver easycap_usb_driver;
diff --git a/drivers/staging/easycap/easycap_standard.h b/drivers/staging/easycap/easycap_standard.h
new file mode 100644 (file)
index 0000000..cadc8d2
--- /dev/null
@@ -0,0 +1,27 @@
+/*****************************************************************************
+*                                                                            *
+*  easycap_standard.h                                                        *
+*                                                                            *
+*****************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+extern struct easycap_standard easycap_standard[];
diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c
new file mode 100644 (file)
index 0000000..3c2ce28
--- /dev/null
@@ -0,0 +1,392 @@
+/******************************************************************************
+*                                                                             *
+*  easycap_testcard.c                                                         *
+*                                                                             *
+******************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
+ *
+ *
+ *  This is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+
+#include "easycap.h"
+#include "easycap_debug.h"
+
+/*****************************************************************************/
+#define TESTCARD_BYTESPERLINE (2 * 1440)
+void
+easycap_testcard(struct easycap *peasycap, int field_fill)
+{
+int total;
+int y, u, v, r, g, b;
+unsigned char uyvy[4];
+
+int i1, line, k, m, n, more, much, barwidth;
+unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2;
+struct data_buffer *pfield_buffer;
+
+JOT(8, "%i=field_fill\n", field_fill);
+
+if ((TESTCARD_BYTESPERLINE / 2) < peasycap->width) {
+       SAY("ERROR: image is too wide\n");
+       return;
+}
+if (peasycap->width % 16) {
+       SAY("ERROR: indivisible image width\n");
+       return;
+}
+
+total = 0;
+barwidth = (2 * peasycap->width) / 8;
+
+k = field_fill;
+m = 0;
+n = 0;
+
+for (line = 0;  line < (peasycap->height / 2);  line++) {
+       for (i1 = 0;  i1 < 8;  i1++) {
+               r = (i1 * 256)/8;
+               g = (i1 * 256)/8;
+               b = (i1 * 256)/8;
+
+               y =  299*r/1000 + 587*g/1000 + 114*b/1000 ;
+               u = -147*r/1000 - 289*g/1000 + 436*b/1000 ;  u = u + 128;
+               v =  615*r/1000 - 515*g/1000 - 100*b/1000 ;  v = v + 128;
+
+               uyvy[0] =  0xFF & u ;
+               uyvy[1] =  0xFF & y ;
+               uyvy[2] =  0xFF & v ;
+               uyvy[3] =  0xFF & y ;
+
+               p1 = &bfbar[0];
+               while (p1 < &bfbar[barwidth]) {
+                       *p1++ = uyvy[0] ;
+                       *p1++ = uyvy[1] ;
+                       *p1++ = uyvy[2] ;
+                       *p1++ = uyvy[3] ;
+                       total += 4;
+                       }
+
+               p1 = &bfbar[0];
+               more = barwidth;
+
+               while (more) {
+                       if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) {
+                               SAY("ERROR:  bad m reached\n");
+                               return;
+                       }
+               if (PAGE_SIZE < n) {
+                       SAY("ERROR:  bad n reached\n"); return;
+               }
+
+               if (0 > more) {
+                       SAY("ERROR:  internal fault\n");
+                       return;
+               }
+
+               much = PAGE_SIZE - n;
+               if (much > more)
+                       much = more;
+               pfield_buffer = &peasycap->field_buffer[k][m];
+               p2 = pfield_buffer->pgo + n;
+               memcpy(p2, p1, much);
+
+               p1 += much;
+               n += much;
+               more -= much;
+               if (PAGE_SIZE == n) {
+                       m++;
+                       n = 0;
+                       }
+               }
+       }
+}
+
+JOT(8, "%i=total\n", total);
+if (total != peasycap->width * peasycap->height)
+       SAY("ERROR: wrong number of bytes written:  %i\n", total);
+return;
+}
+/*****************************************************************************/
+#if defined(EASYCAP_TESTTONE)
+/*-----------------------------------------------------------------------------
+THE tones[] ARRAY BELOW IS THE OUTPUT OF THIS PROGRAM,
+COMPILED gcc -o prog -lm prog.c
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#include <stdio.h>
+#include <math.h>
+
+int main(void);
+int
+main(void)
+{
+int i1, i2, last;
+double d1, d2;
+
+last = 1024 - 1;
+d1 = 10.0*3.14159265/1024.0;
+printf("int tones[2048] =\n{\n");
+for (i1 = 0;  i1 <= last;  i1++)
+       {
+       d2 = ((double)i1) * d1;
+       i2 = (int)(16384.0*sin(d2));
+
+       if (last != i1)
+               {
+               printf("%6i, ", i2);  printf("%6i, ", i2);
+               if (!((i1 + 1)%5)) printf("\n");
+               }
+       else
+               {
+               printf("%6i, ", i2);  printf("%6i\n};\n", i2);
+               }
+       }
+return(0);
+}
+-----------------------------------------------------------------------------*/
+int tones[2048] = {
+     0,     0,   502,   502,  1004,  1004,  1505,  1505,  2005,  2005,
+  2503,  2503,  2998,  2998,  3491,  3491,  3980,  3980,  4466,  4466,
+  4948,  4948,  5424,  5424,  5896,  5896,  6362,  6362,  6822,  6822,
+  7276,  7276,  7723,  7723,  8162,  8162,  8594,  8594,  9018,  9018,
+  9434,  9434,  9840,  9840, 10237, 10237, 10625, 10625, 11002, 11002,
+ 11370, 11370, 11726, 11726, 12072, 12072, 12406, 12406, 12728, 12728,
+ 13038, 13038, 13337, 13337, 13622, 13622, 13895, 13895, 14155, 14155,
+ 14401, 14401, 14634, 14634, 14853, 14853, 15058, 15058, 15249, 15249,
+ 15426, 15426, 15588, 15588, 15735, 15735, 15868, 15868, 15985, 15985,
+ 16088, 16088, 16175, 16175, 16248, 16248, 16305, 16305, 16346, 16346,
+ 16372, 16372, 16383, 16383, 16379, 16379, 16359, 16359, 16323, 16323,
+ 16272, 16272, 16206, 16206, 16125, 16125, 16028, 16028, 15917, 15917,
+ 15790, 15790, 15649, 15649, 15492, 15492, 15322, 15322, 15136, 15136,
+ 14937, 14937, 14723, 14723, 14496, 14496, 14255, 14255, 14001, 14001,
+ 13733, 13733, 13452, 13452, 13159, 13159, 12854, 12854, 12536, 12536,
+ 12207, 12207, 11866, 11866, 11513, 11513, 11150, 11150, 10777, 10777,
+ 10393, 10393, 10000, 10000,  9597,  9597,  9185,  9185,  8765,  8765,
+  8336,  8336,  7900,  7900,  7456,  7456,  7005,  7005,  6547,  6547,
+  6083,  6083,  5614,  5614,  5139,  5139,  4659,  4659,  4175,  4175,
+  3687,  3687,  3196,  3196,  2701,  2701,  2204,  2204,  1705,  1705,
+  1205,  1205,   703,   703,   201,   201,  -301,  -301,  -803,  -803,
+ -1305, -1305, -1805, -1805, -2304, -2304, -2801, -2801, -3294, -3294,
+ -3785, -3785, -4272, -4272, -4756, -4756, -5234, -5234, -5708, -5708,
+ -6176, -6176, -6639, -6639, -7095, -7095, -7545, -7545, -7988, -7988,
+ -8423, -8423, -8850, -8850, -9268, -9268, -9679, -9679, -10079, -10079,
+-10471, -10471, -10853, -10853, -11224, -11224, -11585, -11585, -11935, -11935,
+-12273, -12273, -12600, -12600, -12916, -12916, -13219, -13219, -13510, -13510,
+-13788, -13788, -14053, -14053, -14304, -14304, -14543, -14543, -14767, -14767,
+-14978, -14978, -15175, -15175, -15357, -15357, -15525, -15525, -15678, -15678,
+-15817, -15817, -15940, -15940, -16049, -16049, -16142, -16142, -16221, -16221,
+-16284, -16284, -16331, -16331, -16364, -16364, -16381, -16381, -16382, -16382,
+-16368, -16368, -16339, -16339, -16294, -16294, -16234, -16234, -16159, -16159,
+-16069, -16069, -15963, -15963, -15842, -15842, -15707, -15707, -15557, -15557,
+-15392, -15392, -15212, -15212, -15018, -15018, -14810, -14810, -14589, -14589,
+-14353, -14353, -14104, -14104, -13842, -13842, -13566, -13566, -13278, -13278,
+-12977, -12977, -12665, -12665, -12340, -12340, -12003, -12003, -11656, -11656,
+-11297, -11297, -10928, -10928, -10548, -10548, -10159, -10159, -9759, -9759,
+ -9351, -9351, -8934, -8934, -8509, -8509, -8075, -8075, -7634, -7634,
+ -7186, -7186, -6731, -6731, -6269, -6269, -5802, -5802, -5329, -5329,
+ -4852, -4852, -4369, -4369, -3883, -3883, -3393, -3393, -2900, -2900,
+ -2404, -2404, -1905, -1905, -1405, -1405,  -904,  -904,  -402,  -402,
+   100,   100,   603,   603,  1105,  1105,  1605,  1605,  2105,  2105,
+  2602,  2602,  3097,  3097,  3589,  3589,  4078,  4078,  4563,  4563,
+  5043,  5043,  5519,  5519,  5990,  5990,  6455,  6455,  6914,  6914,
+  7366,  7366,  7811,  7811,  8249,  8249,  8680,  8680,  9102,  9102,
+  9516,  9516,  9920,  9920, 10315, 10315, 10701, 10701, 11077, 11077,
+ 11442, 11442, 11796, 11796, 12139, 12139, 12471, 12471, 12791, 12791,
+ 13099, 13099, 13395, 13395, 13678, 13678, 13948, 13948, 14205, 14205,
+ 14449, 14449, 14679, 14679, 14895, 14895, 15098, 15098, 15286, 15286,
+ 15459, 15459, 15618, 15618, 15763, 15763, 15892, 15892, 16007, 16007,
+ 16107, 16107, 16191, 16191, 16260, 16260, 16314, 16314, 16353, 16353,
+ 16376, 16376, 16384, 16384, 16376, 16376, 16353, 16353, 16314, 16314,
+ 16260, 16260, 16191, 16191, 16107, 16107, 16007, 16007, 15892, 15892,
+ 15763, 15763, 15618, 15618, 15459, 15459, 15286, 15286, 15098, 15098,
+ 14895, 14895, 14679, 14679, 14449, 14449, 14205, 14205, 13948, 13948,
+ 13678, 13678, 13395, 13395, 13099, 13099, 12791, 12791, 12471, 12471,
+ 12139, 12139, 11796, 11796, 11442, 11442, 11077, 11077, 10701, 10701,
+ 10315, 10315,  9920,  9920,  9516,  9516,  9102,  9102,  8680,  8680,
+  8249,  8249,  7811,  7811,  7366,  7366,  6914,  6914,  6455,  6455,
+  5990,  5990,  5519,  5519,  5043,  5043,  4563,  4563,  4078,  4078,
+  3589,  3589,  3097,  3097,  2602,  2602,  2105,  2105,  1605,  1605,
+  1105,  1105,   603,   603,   100,   100,  -402,  -402,  -904,  -904,
+ -1405, -1405, -1905, -1905, -2404, -2404, -2900, -2900, -3393, -3393,
+ -3883, -3883, -4369, -4369, -4852, -4852, -5329, -5329, -5802, -5802,
+ -6269, -6269, -6731, -6731, -7186, -7186, -7634, -7634, -8075, -8075,
+ -8509, -8509, -8934, -8934, -9351, -9351, -9759, -9759, -10159, -10159,
+-10548, -10548, -10928, -10928, -11297, -11297, -11656, -11656, -12003, -12003,
+-12340, -12340, -12665, -12665, -12977, -12977, -13278, -13278, -13566, -13566,
+-13842, -13842, -14104, -14104, -14353, -14353, -14589, -14589, -14810, -14810,
+-15018, -15018, -15212, -15212, -15392, -15392, -15557, -15557, -15707, -15707,
+-15842, -15842, -15963, -15963, -16069, -16069, -16159, -16159, -16234, -16234,
+-16294, -16294, -16339, -16339, -16368, -16368, -16382, -16382, -16381, -16381,
+-16364, -16364, -16331, -16331, -16284, -16284, -16221, -16221, -16142, -16142,
+-16049, -16049, -15940, -15940, -15817, -15817, -15678, -15678, -15525, -15525,
+-15357, -15357, -15175, -15175, -14978, -14978, -14767, -14767, -14543, -14543,
+-14304, -14304, -14053, -14053, -13788, -13788, -13510, -13510, -13219, -13219,
+-12916, -12916, -12600, -12600, -12273, -12273, -11935, -11935, -11585, -11585,
+-11224, -11224, -10853, -10853, -10471, -10471, -10079, -10079, -9679, -9679,
+ -9268, -9268, -8850, -8850, -8423, -8423, -7988, -7988, -7545, -7545,
+ -7095, -7095, -6639, -6639, -6176, -6176, -5708, -5708, -5234, -5234,
+ -4756, -4756, -4272, -4272, -3785, -3785, -3294, -3294, -2801, -2801,
+ -2304, -2304, -1805, -1805, -1305, -1305,  -803,  -803,  -301,  -301,
+   201,   201,   703,   703,  1205,  1205,  1705,  1705,  2204,  2204,
+  2701,  2701,  3196,  3196,  3687,  3687,  4175,  4175,  4659,  4659,
+  5139,  5139,  5614,  5614,  6083,  6083,  6547,  6547,  7005,  7005,
+  7456,  7456,  7900,  7900,  8336,  8336,  8765,  8765,  9185,  9185,
+  9597,  9597, 10000, 10000, 10393, 10393, 10777, 10777, 11150, 11150,
+ 11513, 11513, 11866, 11866, 12207, 12207, 12536, 12536, 12854, 12854,
+ 13159, 13159, 13452, 13452, 13733, 13733, 14001, 14001, 14255, 14255,
+ 14496, 14496, 14723, 14723, 14937, 14937, 15136, 15136, 15322, 15322,
+ 15492, 15492, 15649, 15649, 15790, 15790, 15917, 15917, 16028, 16028,
+ 16125, 16125, 16206, 16206, 16272, 16272, 16323, 16323, 16359, 16359,
+ 16379, 16379, 16383, 16383, 16372, 16372, 16346, 16346, 16305, 16305,
+ 16248, 16248, 16175, 16175, 16088, 16088, 15985, 15985, 15868, 15868,
+ 15735, 15735, 15588, 15588, 15426, 15426, 15249, 15249, 15058, 15058,
+ 14853, 14853, 14634, 14634, 14401, 14401, 14155, 14155, 13895, 13895,
+ 13622, 13622, 13337, 13337, 13038, 13038, 12728, 12728, 12406, 12406,
+ 12072, 12072, 11726, 11726, 11370, 11370, 11002, 11002, 10625, 10625,
+ 10237, 10237,  9840,  9840,  9434,  9434,  9018,  9018,  8594,  8594,
+  8162,  8162,  7723,  7723,  7276,  7276,  6822,  6822,  6362,  6362,
+  5896,  5896,  5424,  5424,  4948,  4948,  4466,  4466,  3980,  3980,
+  3491,  3491,  2998,  2998,  2503,  2503,  2005,  2005,  1505,  1505,
+  1004,  1004,   502,   502,     0,     0,  -502,  -502, -1004, -1004,
+ -1505, -1505, -2005, -2005, -2503, -2503, -2998, -2998, -3491, -3491,
+ -3980, -3980, -4466, -4466, -4948, -4948, -5424, -5424, -5896, -5896,
+ -6362, -6362, -6822, -6822, -7276, -7276, -7723, -7723, -8162, -8162,
+ -8594, -8594, -9018, -9018, -9434, -9434, -9840, -9840, -10237, -10237,
+-10625, -10625, -11002, -11002, -11370, -11370, -11726, -11726, -12072, -12072,
+-12406, -12406, -12728, -12728, -13038, -13038, -13337, -13337, -13622, -13622,
+-13895, -13895, -14155, -14155, -14401, -14401, -14634, -14634, -14853, -14853,
+-15058, -15058, -15249, -15249, -15426, -15426, -15588, -15588, -15735, -15735,
+-15868, -15868, -15985, -15985, -16088, -16088, -16175, -16175, -16248, -16248,
+-16305, -16305, -16346, -16346, -16372, -16372, -16383, -16383, -16379, -16379,
+-16359, -16359, -16323, -16323, -16272, -16272, -16206, -16206, -16125, -16125,
+-16028, -16028, -15917, -15917, -15790, -15790, -15649, -15649, -15492, -15492,
+-15322, -15322, -15136, -15136, -14937, -14937, -14723, -14723, -14496, -14496,
+-14255, -14255, -14001, -14001, -13733, -13733, -13452, -13452, -13159, -13159,
+-12854, -12854, -12536, -12536, -12207, -12207, -11866, -11866, -11513, -11513,
+-11150, -11150, -10777, -10777, -10393, -10393, -10000, -10000, -9597, -9597,
+ -9185, -9185, -8765, -8765, -8336, -8336, -7900, -7900, -7456, -7456,
+ -7005, -7005, -6547, -6547, -6083, -6083, -5614, -5614, -5139, -5139,
+ -4659, -4659, -4175, -4175, -3687, -3687, -3196, -3196, -2701, -2701,
+ -2204, -2204, -1705, -1705, -1205, -1205,  -703,  -703,  -201,  -201,
+   301,   301,   803,   803,  1305,  1305,  1805,  1805,  2304,  2304,
+  2801,  2801,  3294,  3294,  3785,  3785,  4272,  4272,  4756,  4756,
+  5234,  5234,  5708,  5708,  6176,  6176,  6639,  6639,  7095,  7095,
+  7545,  7545,  7988,  7988,  8423,  8423,  8850,  8850,  9268,  9268,
+  9679,  9679, 10079, 10079, 10471, 10471, 10853, 10853, 11224, 11224,
+ 11585, 11585, 11935, 11935, 12273, 12273, 12600, 12600, 12916, 12916,
+ 13219, 13219, 13510, 13510, 13788, 13788, 14053, 14053, 14304, 14304,
+ 14543, 14543, 14767, 14767, 14978, 14978, 15175, 15175, 15357, 15357,
+ 15525, 15525, 15678, 15678, 15817, 15817, 15940, 15940, 16049, 16049,
+ 16142, 16142, 16221, 16221, 16284, 16284, 16331, 16331, 16364, 16364,
+ 16381, 16381, 16382, 16382, 16368, 16368, 16339, 16339, 16294, 16294,
+ 16234, 16234, 16159, 16159, 16069, 16069, 15963, 15963, 15842, 15842,
+ 15707, 15707, 15557, 15557, 15392, 15392, 15212, 15212, 15018, 15018,
+ 14810, 14810, 14589, 14589, 14353, 14353, 14104, 14104, 13842, 13842,
+ 13566, 13566, 13278, 13278, 12977, 12977, 12665, 12665, 12340, 12340,
+ 12003, 12003, 11656, 11656, 11297, 11297, 10928, 10928, 10548, 10548,
+ 10159, 10159,  9759,  9759,  9351,  9351,  8934,  8934,  8509,  8509,
+  8075,  8075,  7634,  7634,  7186,  7186,  6731,  6731,  6269,  6269,
+  5802,  5802,  5329,  5329,  4852,  4852,  4369,  4369,  3883,  3883,
+  3393,  3393,  2900,  2900,  2404,  2404,  1905,  1905,  1405,  1405,
+   904,   904,   402,   402,  -100,  -100,  -603,  -603, -1105, -1105,
+ -1605, -1605, -2105, -2105, -2602, -2602, -3097, -3097, -3589, -3589,
+ -4078, -4078, -4563, -4563, -5043, -5043, -5519, -5519, -5990, -5990,
+ -6455, -6455, -6914, -6914, -7366, -7366, -7811, -7811, -8249, -8249,
+ -8680, -8680, -9102, -9102, -9516, -9516, -9920, -9920, -10315, -10315,
+-10701, -10701, -11077, -11077, -11442, -11442, -11796, -11796, -12139, -12139,
+-12471, -12471, -12791, -12791, -13099, -13099, -13395, -13395, -13678, -13678,
+-13948, -13948, -14205, -14205, -14449, -14449, -14679, -14679, -14895, -14895,
+-15098, -15098, -15286, -15286, -15459, -15459, -15618, -15618, -15763, -15763,
+-15892, -15892, -16007, -16007, -16107, -16107, -16191, -16191, -16260, -16260,
+-16314, -16314, -16353, -16353, -16376, -16376, -16383, -16383, -16376, -16376,
+-16353, -16353, -16314, -16314, -16260, -16260, -16191, -16191, -16107, -16107,
+-16007, -16007, -15892, -15892, -15763, -15763, -15618, -15618, -15459, -15459,
+-15286, -15286, -15098, -15098, -14895, -14895, -14679, -14679, -14449, -14449,
+-14205, -14205, -13948, -13948, -13678, -13678, -13395, -13395, -13099, -13099,
+-12791, -12791, -12471, -12471, -12139, -12139, -11796, -11796, -11442, -11442,
+-11077, -11077, -10701, -10701, -10315, -10315, -9920, -9920, -9516, -9516,
+ -9102, -9102, -8680, -8680, -8249, -8249, -7811, -7811, -7366, -7366,
+ -6914, -6914, -6455, -6455, -5990, -5990, -5519, -5519, -5043, -5043,
+ -4563, -4563, -4078, -4078, -3589, -3589, -3097, -3097, -2602, -2602,
+ -2105, -2105, -1605, -1605, -1105, -1105,  -603,  -603,  -100,  -100,
+   402,   402,   904,   904,  1405,  1405,  1905,  1905,  2404,  2404,
+  2900,  2900,  3393,  3393,  3883,  3883,  4369,  4369,  4852,  4852,
+  5329,  5329,  5802,  5802,  6269,  6269,  6731,  6731,  7186,  7186,
+  7634,  7634,  8075,  8075,  8509,  8509,  8934,  8934,  9351,  9351,
+  9759,  9759, 10159, 10159, 10548, 10548, 10928, 10928, 11297, 11297,
+ 11656, 11656, 12003, 12003, 12340, 12340, 12665, 12665, 12977, 12977,
+ 13278, 13278, 13566, 13566, 13842, 13842, 14104, 14104, 14353, 14353,
+ 14589, 14589, 14810, 14810, 15018, 15018, 15212, 15212, 15392, 15392,
+ 15557, 15557, 15707, 15707, 15842, 15842, 15963, 15963, 16069, 16069,
+ 16159, 16159, 16234, 16234, 16294, 16294, 16339, 16339, 16368, 16368,
+ 16382, 16382, 16381, 16381, 16364, 16364, 16331, 16331, 16284, 16284,
+ 16221, 16221, 16142, 16142, 16049, 16049, 15940, 15940, 15817, 15817,
+ 15678, 15678, 15525, 15525, 15357, 15357, 15175, 15175, 14978, 14978,
+ 14767, 14767, 14543, 14543, 14304, 14304, 14053, 14053, 13788, 13788,
+ 13510, 13510, 13219, 13219, 12916, 12916, 12600, 12600, 12273, 12273,
+ 11935, 11935, 11585, 11585, 11224, 11224, 10853, 10853, 10471, 10471,
+ 10079, 10079,  9679,  9679,  9268,  9268,  8850,  8850,  8423,  8423,
+  7988,  7988,  7545,  7545,  7095,  7095,  6639,  6639,  6176,  6176,
+  5708,  5708,  5234,  5234,  4756,  4756,  4272,  4272,  3785,  3785,
+  3294,  3294,  2801,  2801,  2304,  2304,  1805,  1805,  1305,  1305,
+   803,   803,   301,   301,  -201,  -201,  -703,  -703, -1205, -1205,
+ -1705, -1705, -2204, -2204, -2701, -2701, -3196, -3196, -3687, -3687,
+ -4175, -4175, -4659, -4659, -5139, -5139, -5614, -5614, -6083, -6083,
+ -6547, -6547, -7005, -7005, -7456, -7456, -7900, -7900, -8336, -8336,
+ -8765, -8765, -9185, -9185, -9597, -9597, -10000, -10000, -10393, -10393,
+-10777, -10777, -11150, -11150, -11513, -11513, -11866, -11866, -12207, -12207,
+-12536, -12536, -12854, -12854, -13159, -13159, -13452, -13452, -13733, -13733,
+-14001, -14001, -14255, -14255, -14496, -14496, -14723, -14723, -14937, -14937,
+-15136, -15136, -15322, -15322, -15492, -15492, -15649, -15649, -15790, -15790,
+-15917, -15917, -16028, -16028, -16125, -16125, -16206, -16206, -16272, -16272,
+-16323, -16323, -16359, -16359, -16379, -16379, -16383, -16383, -16372, -16372,
+-16346, -16346, -16305, -16305, -16248, -16248, -16175, -16175, -16088, -16088,
+-15985, -15985, -15868, -15868, -15735, -15735, -15588, -15588, -15426, -15426,
+-15249, -15249, -15058, -15058, -14853, -14853, -14634, -14634, -14401, -14401,
+-14155, -14155, -13895, -13895, -13622, -13622, -13337, -13337, -13038, -13038,
+-12728, -12728, -12406, -12406, -12072, -12072, -11726, -11726, -11370, -11370,
+-11002, -11002, -10625, -10625, -10237, -10237, -9840, -9840, -9434, -9434,
+ -9018, -9018, -8594, -8594, -8162, -8162, -7723, -7723, -7276, -7276,
+ -6822, -6822, -6362, -6362, -5896, -5896, -5424, -5424, -4948, -4948,
+ -4466, -4466, -3980, -3980, -3491, -3491, -2998, -2998, -2503, -2503,
+ -2005, -2005, -1505, -1505, -1004, -1004,  -502,  -502
+};
+/*****************************************************************************/
+void
+easysnd_testtone(struct easycap *peasycap, int audio_fill)
+{
+int i1;
+unsigned char *p2;
+struct data_buffer *paudio_buffer;
+
+JOT(8, "%i=audio_fill\n", audio_fill);
+
+paudio_buffer = &peasycap->audio_buffer[audio_fill];
+
+p2 = (unsigned char *)(paudio_buffer->pgo);
+for (i1 = 0;  i1 < PAGE_SIZE;  i1 += 4, p2 += 4) {
+       *p2       = (unsigned char) (0x00FF & tones[i1/2]);
+       *(p2 + 1) = (unsigned char)((0xFF00 & tones[i1/2]) >> 8);
+       *(p2 + 2) = (unsigned char) (0x00FF & tones[i1/2 + 1]);
+       *(p2 + 3) = (unsigned char)((0xFF00 & tones[i1/2 + 1]) >> 8);
+       }
+return;
+}
+#endif /*EASYCAP_TESTTONE*/
+/*****************************************************************************/
index a6d9f29ff49cd0d97ecb7a4064ac1d4e9cf6d437..21c5eeec62ddf237705539f45dc3607d457327e6 100644 (file)
@@ -760,7 +760,8 @@ void et131x_Mii_check(struct et131x_adapter *etdev,
                        if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) {
                                /* NOTE - Is there a way to query this without
                                 * TruePHY?
-                                * && TRU_QueryCoreType(etdev->hTruePhy, 0) == EMI_TRUEPHY_A13O) {
+                                * && TRU_QueryCoreType(etdev->hTruePhy, 0) ==
+                                * EMI_TRUEPHY_A13O) {
                                 */
                                u16 Register18;
 
@@ -778,7 +779,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev,
                         * in the LinkDetectionDPC).
                         */
                        if (!(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) ||
-                         (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) {
+                        (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) {
                                spin_lock_irqsave(&etdev->Lock, flags);
                                etdev->MediaState =
                                    NETIF_STATUS_MEDIA_DISCONNECT;
@@ -836,7 +837,8 @@ void et131x_Mii_check(struct et131x_adapter *etdev,
                                /*
                                 * NOTE - Is there a way to query this without
                                 * TruePHY?
-                                * && TRU_QueryCoreType(etdev->hTruePhy, 0)== EMI_TRUEPHY_A13O) {
+                                * && TRU_QueryCoreType(etdev->hTruePhy, 0)==
+                                * EMI_TRUEPHY_A13O) {
                                 */
                                u16 Register18;
 
index 97480f5c659939c2cd359b3705b330d09d91156e..7455c804962ae181cb0910a8608112e823e49250 100644 (file)
@@ -17,7 +17,7 @@ config HYPERV_STORAGE
 
 config HYPERV_BLOCK
        tristate "Microsoft Hyper-V virtual block driver"
-       depends on BLOCK && SCSI && LBDAF
+       depends on BLOCK && SCSI && (LBDAF || 64BIT)
        default HYPERV
        help
          Select this option to enable the Hyper-V virtual block driver.
index 1866f80a45d32ceb03f8b7dc37fb1c5c06586aea..b63515c20f5f9fc79dc6f95fbff07735d87bd75e 100644 (file)
@@ -1,4 +1,4 @@
-obj-$(CONFIG_HYPERV)           += hv_vmbus.o
+obj-$(CONFIG_HYPERV)           += hv_vmbus.o hv_timesource.o
 obj-$(CONFIG_HYPERV_STORAGE)   += hv_storvsc.o
 obj-$(CONFIG_HYPERV_BLOCK)     += hv_blkvsc.o
 obj-$(CONFIG_HYPERV_NET)       += hv_netvsc.o
index 0daebc472e63b189f95f245ddba413b25ea05fcd..929238a6ce80b88151c471ea4c6f2a1f5d6ad24d 100644 (file)
@@ -40,15 +40,11 @@ static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
        struct storvsc_device_info *deviceInfo;
        int ret = 0;
 
-       DPRINT_ENTER(BLKVSC);
-
        deviceInfo = (struct storvsc_device_info *)AdditionalInfo;
 
        ret = StorVscOnDeviceAdd(Device, AdditionalInfo);
-       if (ret != 0) {
-               DPRINT_EXIT(BLKVSC);
+       if (ret != 0)
                return ret;
-       }
 
        /*
         * We need to use the device instance guid to set the path and target
@@ -63,8 +59,6 @@ static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
        deviceInfo->TargetId = Device->deviceInstance.data[5] << 8 |
                               Device->deviceInstance.data[4];
 
-       DPRINT_EXIT(BLKVSC);
-
        return ret;
 }
 
@@ -73,8 +67,6 @@ int BlkVscInitialize(struct hv_driver *Driver)
        struct storvsc_driver_object *storDriver;
        int ret = 0;
 
-       DPRINT_ENTER(BLKVSC);
-
        storDriver = (struct storvsc_driver_object *)Driver;
 
        /* Make sure we are at least 2 pages since 1 page is used for control */
@@ -106,7 +98,5 @@ int BlkVscInitialize(struct hv_driver *Driver)
        storDriver->Base.OnCleanup = StorVscOnCleanup;
        storDriver->OnIORequest = StorVscOnIORequest;
 
-       DPRINT_EXIT(BLKVSC);
-
        return ret;
 }
index 61bd0be5fb189391823ad255bd9ebcdbbe1a448f..f7ea2a3efed75c0f6565670889d3c895ed9e1c26 100644 (file)
@@ -175,8 +175,6 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
        struct driver_context *drv_ctx = &g_blkvsc_drv.drv_ctx;
        int ret;
 
-       DPRINT_ENTER(BLKVSC_DRV);
-
        vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface);
 
        storvsc_drv_obj->RingBufferSize = blkvsc_ringbuffer_size;
@@ -195,8 +193,6 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
        /* The driver belongs to vmbus */
        ret = vmbus_child_driver_register(drv_ctx);
 
-       DPRINT_EXIT(BLKVSC_DRV);
-
        return ret;
 }
 
@@ -214,8 +210,6 @@ static void blkvsc_drv_exit(void)
        struct device *current_dev;
        int ret;
 
-       DPRINT_ENTER(BLKVSC_DRV);
-
        while (1) {
                current_dev = NULL;
 
@@ -241,8 +235,6 @@ static void blkvsc_drv_exit(void)
 
        vmbus_child_driver_unregister(drv_ctx);
 
-       DPRINT_EXIT(BLKVSC_DRV);
-
        return;
 }
 
@@ -268,8 +260,6 @@ static int blkvsc_probe(struct device *device)
        static int ide0_registered;
        static int ide1_registered;
 
-       DPRINT_ENTER(BLKVSC_DRV);
-
        DPRINT_DBG(BLKVSC_DRV, "blkvsc_probe - enter");
 
        if (!storvsc_drv_obj->Base.OnDeviceAdd) {
@@ -413,8 +403,6 @@ Cleanup:
                blkdev = NULL;
        }
 
-       DPRINT_EXIT(BLKVSC_DRV);
-
        return ret;
 }
 
@@ -751,14 +739,10 @@ static int blkvsc_remove(struct device *device)
        unsigned long flags;
        int ret;
 
-       DPRINT_ENTER(BLKVSC_DRV);
-
        DPRINT_DBG(BLKVSC_DRV, "blkvsc_remove()\n");
 
-       if (!storvsc_drv_obj->Base.OnDeviceRemove) {
-               DPRINT_EXIT(BLKVSC_DRV);
+       if (!storvsc_drv_obj->Base.OnDeviceRemove)
                return -1;
-       }
 
        /*
         * Call to the vsc driver to let it know that the device is being
@@ -802,8 +786,6 @@ static int blkvsc_remove(struct device *device)
 
        kfree(blkdev);
 
-       DPRINT_EXIT(BLKVSC_DRV);
-
        return ret;
 }
 
@@ -1492,22 +1474,16 @@ static int __init blkvsc_init(void)
 
        BUILD_BUG_ON(sizeof(sector_t) != 8);
 
-       DPRINT_ENTER(BLKVSC_DRV);
-
        DPRINT_INFO(BLKVSC_DRV, "Blkvsc initializing....");
 
        ret = blkvsc_drv_init(BlkVscInitialize);
 
-       DPRINT_EXIT(BLKVSC_DRV);
-
        return ret;
 }
 
 static void __exit blkvsc_exit(void)
 {
-       DPRINT_ENTER(BLKVSC_DRV);
        blkvsc_drv_exit();
-       DPRINT_ENTER(BLKVSC_DRV);
 }
 
 MODULE_LICENSE("GPL");
index f047c5a7f64c1c35e7eed64b9818906e6f95885d..fece30c303a54aeae1a5b9c326f4a1f1fad3a957 100644 (file)
@@ -74,8 +74,6 @@ static void VmbusChannelSetEvent(struct vmbus_channel *Channel)
 {
        struct hv_monitor_page *monitorPage;
 
-       DPRINT_ENTER(VMBUS);
-
        if (Channel->OfferMsg.MonitorAllocated) {
                /* Each u32 represents 32 channels */
                set_bit(Channel->OfferMsg.ChildRelId & 31,
@@ -92,8 +90,6 @@ static void VmbusChannelSetEvent(struct vmbus_channel *Channel)
        } else {
                VmbusSetEvent(Channel->OfferMsg.ChildRelId);
        }
-
-       DPRINT_EXIT(VMBUS);
 }
 
 #if 0
@@ -101,8 +97,6 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel)
 {
        struct hv_monitor_page *monitorPage;
 
-       DPRINT_ENTER(VMBUS);
-
        if (Channel->OfferMsg.MonitorAllocated) {
                /* Each u32 represents 32 channels */
                clear_bit(Channel->OfferMsg.ChildRelId & 31,
@@ -117,8 +111,6 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel)
                          (unsigned long *)&monitorPage->TriggerGroup
                                        [Channel->MonitorGroup].Pending);
        }
-
-       DPRINT_EXIT(VMBUS);
 }
 
 #endif
@@ -180,8 +172,6 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize,
        unsigned long flags;
        int ret, err = 0;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Aligned to page size */
        /* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */
        /* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */
@@ -305,9 +295,6 @@ Cleanup:
 
        kfree(openInfo->WaitEvent);
        kfree(openInfo);
-
-       DPRINT_EXIT(VMBUS);
-
        return 0;
 
 errorout:
@@ -465,6 +452,8 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size,
                          sizeof(struct vmbus_channel_gpadl_header) +
                          sizeof(struct gpa_range) + pageCount * sizeof(u64);
                msgHeader = kzalloc(msgSize, GFP_KERNEL);
+               if (msgHeader == NULL)
+                       goto nomem;
                msgHeader->MessageSize = msgSize;
 
                gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg;
@@ -509,8 +498,6 @@ int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer,
        unsigned long flags;
        int ret = 0;
 
-       DPRINT_ENTER(VMBUS);
-
        nextGpadlHandle = atomic_read(&gVmbusConnection.NextGpadlHandle);
        atomic_inc(&gVmbusConnection.NextGpadlHandle);
 
@@ -592,9 +579,6 @@ Cleanup:
 
        kfree(msgInfo->WaitEvent);
        kfree(msgInfo);
-
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -608,8 +592,6 @@ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle)
        unsigned long flags;
        int ret;
 
-       DPRINT_ENTER(VMBUS);
-
        /* ASSERT(GpadlHandle != 0); */
 
        info = kmalloc(sizeof(*info) +
@@ -650,9 +632,6 @@ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle)
 
        kfree(info->WaitEvent);
        kfree(info);
-
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -666,8 +645,6 @@ void VmbusChannelClose(struct vmbus_channel *Channel)
        unsigned long flags;
        int ret;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Stop callback and cancel the timer asap */
        Channel->OnChannelCallback = NULL;
        del_timer_sync(&Channel->poll_timer);
@@ -720,8 +697,6 @@ void VmbusChannelClose(struct vmbus_channel *Channel)
 
                FreeVmbusChannel(Channel);
        }
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /**
@@ -749,7 +724,6 @@ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer,
        u64 alignedData = 0;
        int ret;
 
-       DPRINT_ENTER(VMBUS);
        DPRINT_DBG(VMBUS, "channel %p buffer %p len %d",
                   Channel, Buffer, BufferLen);
 
@@ -776,8 +750,6 @@ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer,
        if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
                VmbusChannelSetEvent(Channel);
 
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 EXPORT_SYMBOL(VmbusChannelSendPacket);
@@ -800,8 +772,6 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel,
        struct scatterlist bufferList[3];
        u64 alignedData = 0;
 
-       DPRINT_ENTER(VMBUS);
-
        if (PageCount > MAX_PAGE_BUFFER_COUNT)
                return -EINVAL;
 
@@ -844,8 +814,6 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel,
        if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
                VmbusChannelSetEvent(Channel);
 
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -867,8 +835,6 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel,
        u32 PfnCount = NUM_PAGES_SPANNED(MultiPageBuffer->Offset,
                                         MultiPageBuffer->Length);
 
-       DPRINT_ENTER(VMBUS);
-
        DumpVmbusChannel(Channel);
 
        DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u",
@@ -914,8 +880,6 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel,
        if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
                VmbusChannelSetEvent(Channel);
 
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -942,8 +906,6 @@ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer,
        int ret;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        *BufferActualLen = 0;
        *RequestId = 0;
 
@@ -955,7 +917,6 @@ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer,
                spin_unlock_irqrestore(&Channel->inbound_lock, flags);
 
                /* DPRINT_DBG(VMBUS, "nothing to read!!"); */
-               DPRINT_EXIT(VMBUS);
                return 0;
        }
 
@@ -977,8 +938,6 @@ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer,
 
                DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d",
                           BufferLen, userLen);
-               DPRINT_EXIT(VMBUS);
-
                return -1;
        }
 
@@ -990,8 +949,6 @@ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer,
 
        spin_unlock_irqrestore(&Channel->inbound_lock, flags);
 
-       DPRINT_EXIT(VMBUS);
-
        return 0;
 }
 EXPORT_SYMBOL(VmbusChannelRecvPacket);
@@ -1009,8 +966,6 @@ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer,
        int ret;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        *BufferActualLen = 0;
        *RequestId = 0;
 
@@ -1022,7 +977,6 @@ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer,
                spin_unlock_irqrestore(&Channel->inbound_lock, flags);
 
                /* DPRINT_DBG(VMBUS, "nothing to read!!"); */
-               DPRINT_EXIT(VMBUS);
                return 0;
        }
 
@@ -1043,7 +997,6 @@ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer,
 
                DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but "
                           "got space for only %d bytes", packetLen, BufferLen);
-               DPRINT_EXIT(VMBUS);
                return -2;
        }
 
@@ -1053,9 +1006,6 @@ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer,
        ret = RingBufferRead(&Channel->Inbound, Buffer, packetLen, 0);
 
        spin_unlock_irqrestore(&Channel->inbound_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
-
        return 0;
 }
 
index 12db555a3a5d59b1348c4f3616e246991f7c3246..6ccf505e802d6f8d5b063b12112fab3e459d1a2b 100644 (file)
@@ -267,15 +267,11 @@ static inline void ReleaseVmbusChannel(void *context)
 {
        struct vmbus_channel *channel = context;
 
-       DPRINT_ENTER(VMBUS);
-
        DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
        destroy_workqueue(channel->ControlWQ);
        DPRINT_DBG(VMBUS, "channel released (%p)", channel);
 
        kfree(channel);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -326,8 +322,6 @@ static void VmbusChannelProcessOffer(void *context)
        int cnt;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Make sure this is a new offer */
        spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
 
@@ -353,7 +347,6 @@ static void VmbusChannelProcessOffer(void *context)
                DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)",
                           newChannel->OfferMsg.ChildRelId);
                FreeVmbusChannel(newChannel);
-               DPRINT_EXIT(VMBUS);
                return;
        }
 
@@ -410,7 +403,6 @@ static void VmbusChannelProcessOffer(void *context)
                        }
                }
        }
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -420,9 +412,7 @@ static void VmbusChannelProcessRescindOffer(void *context)
 {
        struct vmbus_channel *channel = context;
 
-       DPRINT_ENTER(VMBUS);
        VmbusChildDeviceRemove(channel->DeviceObject);
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -441,8 +431,6 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
        int i;
        int fSupported = 0;
 
-       DPRINT_ENTER(VMBUS);
-
        offer = (struct vmbus_channel_offer_channel *)hdr;
        for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
                if (memcmp(&offer->Offer.InterfaceType,
@@ -455,7 +443,6 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
        if (!fSupported) {
                DPRINT_DBG(VMBUS, "Ignoring channel offer notification for "
                           "child relid %d", offer->ChildRelId);
-               DPRINT_EXIT(VMBUS);
                return;
        }
 
@@ -504,8 +491,6 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
        /* TODO: Make sure the offer comes from our parent partition */
        osd_schedule_callback(newChannel->ControlWQ, VmbusChannelProcessOffer,
                              newChannel);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -518,8 +503,6 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
        struct vmbus_channel_rescind_offer *rescind;
        struct vmbus_channel *channel;
 
-       DPRINT_ENTER(VMBUS);
-
        rescind = (struct vmbus_channel_rescind_offer *)hdr;
        channel = GetChannelFromRelId(rescind->ChildRelId);
        if (channel == NULL) {
@@ -531,8 +514,6 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
        osd_schedule_callback(channel->ControlWQ,
                              VmbusChannelProcessRescindOffer,
                              channel);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -543,8 +524,6 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
 static void VmbusChannelOnOffersDelivered(
                        struct vmbus_channel_message_header *hdr)
 {
-       DPRINT_ENTER(VMBUS);
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -563,8 +542,6 @@ static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr)
        struct vmbus_channel_open_channel *openMsg;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        result = (struct vmbus_channel_open_result *)hdr;
        DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status);
 
@@ -591,8 +568,6 @@ static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr)
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -611,8 +586,6 @@ static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr)
        struct vmbus_channel_gpadl_header *gpadlHeader;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        gpadlCreated = (struct vmbus_channel_gpadl_created *)hdr;
        DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d",
                   gpadlCreated->CreationStatus);
@@ -643,8 +616,6 @@ static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr)
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -664,8 +635,6 @@ static void VmbusChannelOnGpadlTorndown(
        struct vmbus_channel_gpadl_teardown *gpadlTeardown;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        gpadlTorndown = (struct vmbus_channel_gpadl_torndown *)hdr;
 
        /*
@@ -691,8 +660,6 @@ static void VmbusChannelOnGpadlTorndown(
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -712,8 +679,6 @@ static void VmbusChannelOnVersionResponse(
        struct vmbus_channel_version_response *versionResponse;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        versionResponse = (struct vmbus_channel_version_response *)hdr;
        spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
 
@@ -732,8 +697,6 @@ static void VmbusChannelOnVersionResponse(
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /* Channel message dispatch table */
@@ -769,8 +732,6 @@ void VmbusOnChannelMessage(void *Context)
        struct vmbus_channel_message_header *hdr;
        int size;
 
-       DPRINT_ENTER(VMBUS);
-
        hdr = (struct vmbus_channel_message_header *)msg->u.Payload;
        size = msg->Header.PayloadSize;
 
@@ -794,7 +755,6 @@ void VmbusOnChannelMessage(void *Context)
 
        /* Free the msg that was allocated in VmbusOnMsgDPC() */
        kfree(msg);
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -806,8 +766,6 @@ int VmbusChannelRequestOffers(void)
        struct vmbus_channel_msginfo *msgInfo;
        int ret;
 
-       DPRINT_ENTER(VMBUS);
-
        msgInfo = kmalloc(sizeof(*msgInfo) +
                          sizeof(struct vmbus_channel_message_header),
                          GFP_KERNEL);
@@ -853,7 +811,6 @@ Cleanup:
                kfree(msgInfo);
        }
 
-       DPRINT_EXIT(VMBUS);
        return ret;
 }
 
index 5908b81d3e9c044ac1d35583e8355016a00f8516..f969267895be6d20ecee417840b3a35a03d24497 100644 (file)
@@ -247,8 +247,8 @@ struct vmbus_channel {
        /* Allocated memory for ring buffer */
        void *RingBufferPages;
        u32 RingBufferPageCount;
-       RING_BUFFER_INFO Outbound;      /* send to parent */
-       RING_BUFFER_INFO Inbound;       /* receive from parent */
+       struct hv_ring_buffer_info Outbound;    /* send to parent */
+       struct hv_ring_buffer_info Inbound;     /* receive from parent */
        spinlock_t inbound_lock;
        struct workqueue_struct *ControlWQ;
 
@@ -272,8 +272,8 @@ struct vmbus_channel_debug_info {
        u32 ClientMonitorLatency;
        u32 ClientMonitorConnectionId;
 
-       RING_BUFFER_DEBUG_INFO Inbound;
-       RING_BUFFER_DEBUG_INFO Outbound;
+       struct hv_ring_buffer_debug_info Inbound;
+       struct hv_ring_buffer_debug_info Outbound;
 };
 
 /*
index e8824dadffc31786f32ac5494ad1b32f46c911b4..1f4d6683aaa7e15bd716c25ac26c1eee0e30c092 100644 (file)
@@ -44,8 +44,6 @@ int VmbusConnect(void)
        struct vmbus_channel_initiate_contact *msg;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Make sure we are not connecting or connected */
        if (gVmbusConnection.ConnectState != Disconnected)
                return -1;
@@ -155,8 +153,6 @@ int VmbusConnect(void)
 
        kfree(msgInfo->WaitEvent);
        kfree(msgInfo);
-       DPRINT_EXIT(VMBUS);
-
        return 0;
 
 Cleanup:
@@ -180,8 +176,6 @@ Cleanup:
                kfree(msgInfo);
        }
 
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -193,8 +187,6 @@ int VmbusDisconnect(void)
        int ret = 0;
        struct vmbus_channel_message_header *msg;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Make sure we are connected */
        if (gVmbusConnection.ConnectState != Connected)
                return -1;
@@ -221,7 +213,6 @@ int VmbusDisconnect(void)
 
 Cleanup:
        kfree(msg);
-       DPRINT_EXIT(VMBUS);
        return ret;
 }
 
@@ -285,8 +276,6 @@ void VmbusOnEvents(void)
        int relid;
        u32 *recvInterruptPage = gVmbusConnection.RecvInterruptPage;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Check events */
        if (recvInterruptPage) {
                for (dword = 0; dword < maxdword; dword++) {
@@ -310,8 +299,6 @@ void VmbusOnEvents(void)
                        }
                 }
        }
-       DPRINT_EXIT(VMBUS);
-
        return;
 }
 
@@ -332,18 +319,10 @@ int VmbusPostMessage(void *buffer, size_t bufferLen)
  */
 int VmbusSetEvent(u32 childRelId)
 {
-       int ret = 0;
-
-       DPRINT_ENTER(VMBUS);
-
        /* Each u32 represents 32 channels */
        set_bit(childRelId & 31,
                (unsigned long *)gVmbusConnection.SendInterruptPage +
                (childRelId >> 5));
 
-       ret = HvSignalEvent();
-
-       DPRINT_EXIT(VMBUS);
-
-       return ret;
+       return HvSignalEvent();
 }
index 6c77e64027f0eb801d1336ffeb93bcebf9ee033c..86b1ddd9040411e019fc2c45c5f125445aa7e486 100644 (file)
@@ -192,8 +192,6 @@ int HvInit(void)
        union hv_x64_msr_hypercall_contents hypercallMsr;
        void *virtAddr = NULL;
 
-       DPRINT_ENTER(VMBUS);
-
        memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS);
        memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS);
 
@@ -275,8 +273,6 @@ int HvInit(void)
        gHvContext.SignalEventParam->FlagNumber = 0;
        gHvContext.SignalEventParam->RsvdZ = 0;
 
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 
 Cleanup:
@@ -289,8 +285,6 @@ Cleanup:
                vfree(virtAddr);
        }
        ret = -1;
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -303,8 +297,6 @@ void HvCleanup(void)
 {
        union hv_x64_msr_hypercall_contents hypercallMsr;
 
-       DPRINT_ENTER(VMBUS);
-
        kfree(gHvContext.SignalEventBuffer);
        gHvContext.SignalEventBuffer = NULL;
        gHvContext.SignalEventParam = NULL;
@@ -315,8 +307,6 @@ void HvCleanup(void)
                vfree(gHvContext.HypercallPage);
                gHvContext.HypercallPage = NULL;
        }
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -392,12 +382,8 @@ void HvSynicInit(void *irqarg)
        u32 irqVector = *((u32 *)(irqarg));
        int cpu = smp_processor_id();
 
-       DPRINT_ENTER(VMBUS);
-
-       if (!gHvContext.HypercallPage) {
-               DPRINT_EXIT(VMBUS);
+       if (!gHvContext.HypercallPage)
                return;
-       }
 
        /* Check the version */
        rdmsrl(HV_X64_MSR_SVERSION, version);
@@ -464,9 +450,6 @@ void HvSynicInit(void *irqarg)
        wrmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
 
        gHvContext.SynICInitialized = true;
-
-       DPRINT_EXIT(VMBUS);
-
        return;
 
 Cleanup:
@@ -475,8 +458,6 @@ Cleanup:
 
        if (gHvContext.synICMessagePage[cpu])
                osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
-
-       DPRINT_EXIT(VMBUS);
        return;
 }
 
@@ -490,12 +471,8 @@ void HvSynicCleanup(void *arg)
        union hv_synic_siefp siefp;
        int cpu = smp_processor_id();
 
-       DPRINT_ENTER(VMBUS);
-
-       if (!gHvContext.SynICInitialized) {
-               DPRINT_EXIT(VMBUS);
+       if (!gHvContext.SynICInitialized)
                return;
-       }
 
        rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
 
@@ -519,6 +496,4 @@ void HvSynicCleanup(void *arg)
 
        osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
        osd_PageFree(gHvContext.synICEventPage[cpu], 1);
-
-       DPRINT_EXIT(VMBUS);
 }
diff --git a/drivers/staging/hv/hv_timesource.c b/drivers/staging/hv/hv_timesource.c
new file mode 100644 (file)
index 0000000..a7ee533
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * A clocksource for Linux running on HyperV.
+ *
+ *
+ * Copyright (C) 2010, Novell, Inc.
+ * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dmi.h>
+#include <asm/hyperv.h>
+#include <asm/mshyperv.h>
+#include <asm/hypervisor.h>
+
+#define HV_CLOCK_SHIFT 22
+
+static cycle_t read_hv_clock(struct clocksource *arg)
+{
+       cycle_t current_tick;
+       /*
+        * Read the partition counter to get the current tick count. This count
+        * is set to 0 when the partition is created and is incremented in
+        * 100 nanosecond units.
+        */
+       rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
+       return current_tick;
+}
+
+static struct clocksource hyperv_cs = {
+       .name           = "hyperv_clocksource",
+       .rating         = 400, /* use this when running on Hyperv*/
+       .read           = read_hv_clock,
+       .mask           = CLOCKSOURCE_MASK(64),
+       /*
+        * The time ref counter in HyperV is in 100ns units.
+        * The definition of mult is:
+        * mult/2^shift = ns/cyc = 100
+        * mult = (100 << shift)
+        */
+       .mult           = (100 << HV_CLOCK_SHIFT),
+       .shift          = HV_CLOCK_SHIFT,
+};
+
+static const struct dmi_system_id __initconst
+hv_timesource_dmi_table[] __maybe_unused  = {
+       {
+               .ident = "Hyper-V",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
+               },
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(dmi, hv_timesource_dmi_table);
+
+static const struct pci_device_id __initconst
+hv_timesource_pci_table[] __maybe_unused = {
+       { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, hv_timesource_pci_table);
+
+
+static int __init init_hv_clocksource(void)
+{
+       if ((x86_hyper != &x86_hyper_ms_hyperv) ||
+               !(ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE))
+               return -ENODEV;
+
+       if (!dmi_check_system(hv_timesource_dmi_table))
+               return -ENODEV;
+
+       printk(KERN_INFO "Registering HyperV clock source\n");
+       return clocksource_register(&hyperv_cs);
+}
+
+module_init(init_hv_clocksource);
+MODULE_DESCRIPTION("HyperV based clocksource");
+MODULE_AUTHOR("K. Y. Srinivasan <ksrinivasan@novell.com>");
+MODULE_LICENSE("GPL");
index 2adc9b48ca9cf5aea96de4cc672f62327945af83..6eb79febef9b345c631576f840f6d63378a3e78a 100644 (file)
@@ -52,8 +52,6 @@ static void shutdown_onchannelcallback(void *context)
        struct icmsg_hdr *icmsghdrp;
        struct icmsg_negotiate *negop = NULL;
 
-       DPRINT_ENTER(VMBUS);
-
        buflen = PAGE_SIZE;
        buf = kmalloc(buflen, GFP_ATOMIC);
 
@@ -102,8 +100,6 @@ static void shutdown_onchannelcallback(void *context)
 
        kfree(buf);
 
-       DPRINT_EXIT(VMBUS);
-
        if (execute_shutdown == true)
                orderly_poweroff(false);
 }
@@ -160,8 +156,6 @@ static void timesync_onchannelcallback(void *context)
        struct icmsg_hdr *icmsghdrp;
        struct ictimesync_data *timedatap;
 
-       DPRINT_ENTER(VMBUS);
-
        buflen = PAGE_SIZE;
        buf = kmalloc(buflen, GFP_ATOMIC);
 
@@ -192,8 +186,6 @@ static void timesync_onchannelcallback(void *context)
        }
 
        kfree(buf);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -210,8 +202,6 @@ static void heartbeat_onchannelcallback(void *context)
        struct icmsg_hdr *icmsghdrp;
        struct heartbeat_msg_data *heartbeat_msg;
 
-       DPRINT_ENTER(VMBUS);
-
        buflen = PAGE_SIZE;
        buf = kmalloc(buflen, GFP_ATOMIC);
 
@@ -249,8 +239,6 @@ static void heartbeat_onchannelcallback(void *context)
        }
 
        kfree(buf);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 static const struct pci_device_id __initconst
index ad4cfcfb7b112189778e3112a857dc02f1397d87..20d4d12023deb571ff2daf7a9e54aa0836729dfb 100644 (file)
@@ -92,21 +92,4 @@ extern unsigned int vmbus_loglevel;
                       __func__, ## args);\
        } while (0)
 
-#ifdef DEBUG
-#define DPRINT_ENTER(mod) do {\
-       if ((mod & (HIWORD(vmbus_loglevel))) && \
-           (DEBUG_LVL_ENTEREXIT <= LOWORD(vmbus_loglevel)))    \
-               printk(KERN_DEBUG "["#mod"]: %s() enter\n", __func__);\
-       } while (0)
-
-#define DPRINT_EXIT(mod) do {\
-       if ((mod & (HIWORD(vmbus_loglevel))) && \
-           (DEBUG_LVL_ENTEREXIT <= LOWORD(vmbus_loglevel)))    \
-               printk(KERN_DEBUG "["#mod"]: %s() exit\n", __func__);\
-       } while (0)
-#else
-#define DPRINT_ENTER(mod)
-#define DPRINT_EXIT(mod)
-#endif
-
 #endif /* _LOGGING_H_ */
index ba15059c45b2c46313e1b22a517834f7c460ff44..1d2ebbe17e2cb8d1e917f8fe28a6b51de0d7236e 100644 (file)
@@ -174,8 +174,6 @@ int NetVscInitialize(struct hv_driver *drv)
 {
        struct netvsc_driver *driver = (struct netvsc_driver *)drv;
 
-       DPRINT_ENTER(NETVSC);
-
        DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, "
                   "sizeof(struct nvsp_message)=%zd, "
                   "sizeof(struct vmtransfer_page_packet_header)=%zd",
@@ -202,9 +200,6 @@ int NetVscInitialize(struct hv_driver *drv)
        driver->OnSend                  = NetVscOnSend;
 
        RndisFilterInit(driver);
-
-       DPRINT_EXIT(NETVSC);
-
        return 0;
 }
 
@@ -214,13 +209,10 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device)
        struct netvsc_device *netDevice;
        struct nvsp_message *initPacket;
 
-       DPRINT_ENTER(NETVSC);
-
        netDevice = GetOutboundNetDevice(Device);
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "unable to get net device..."
                           "device being destroyed?");
-               DPRINT_EXIT(NETVSC);
                return -1;
        }
        /* ASSERT(netDevice->ReceiveBufferSize > 0); */
@@ -335,7 +327,6 @@ Cleanup:
 
 Exit:
        PutNetDevice(Device);
-       DPRINT_EXIT(NETVSC);
        return ret;
 }
 
@@ -345,13 +336,10 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device)
        struct netvsc_device *netDevice;
        struct nvsp_message *initPacket;
 
-       DPRINT_ENTER(NETVSC);
-
        netDevice = GetOutboundNetDevice(Device);
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "unable to get net device..."
                           "device being destroyed?");
-               DPRINT_EXIT(NETVSC);
                return -1;
        }
        if (netDevice->SendBufferSize <= 0) {
@@ -434,7 +422,6 @@ Cleanup:
 
 Exit:
        PutNetDevice(Device);
-       DPRINT_EXIT(NETVSC);
        return ret;
 }
 
@@ -443,8 +430,6 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice)
        struct nvsp_message *revokePacket;
        int ret = 0;
 
-       DPRINT_ENTER(NETVSC);
-
        /*
         * If we got a section count, it means we received a
         * SendReceiveBufferComplete msg (ie sent
@@ -475,7 +460,6 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice)
                if (ret != 0) {
                        DPRINT_ERR(NETVSC, "unable to send revoke receive "
                                   "buffer to netvsp");
-                       DPRINT_EXIT(NETVSC);
                        return -1;
                }
        }
@@ -492,7 +476,6 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice)
                if (ret != 0) {
                        DPRINT_ERR(NETVSC,
                                   "unable to teardown receive buffer's gpadl");
-                       DPRINT_EXIT(NETVSC);
                        return -1;
                }
                NetDevice->ReceiveBufferGpadlHandle = 0;
@@ -513,8 +496,6 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice)
                NetDevice->ReceiveSections = NULL;
        }
 
-       DPRINT_EXIT(NETVSC);
-
        return ret;
 }
 
@@ -523,8 +504,6 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice)
        struct nvsp_message *revokePacket;
        int ret = 0;
 
-       DPRINT_ENTER(NETVSC);
-
        /*
         * If we got a section count, it means we received a
         *  SendReceiveBufferComplete msg (ie sent
@@ -554,7 +533,6 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice)
                if (ret != 0) {
                        DPRINT_ERR(NETVSC, "unable to send revoke send buffer "
                                   "to netvsp");
-                       DPRINT_EXIT(NETVSC);
                        return -1;
                }
        }
@@ -572,7 +550,6 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice)
                if (ret != 0) {
                        DPRINT_ERR(NETVSC, "unable to teardown send buffer's "
                                   "gpadl");
-                       DPRINT_EXIT(NETVSC);
                        return -1;
                }
                NetDevice->SendBufferGpadlHandle = 0;
@@ -587,8 +564,6 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice)
                NetDevice->SendBuffer = NULL;
        }
 
-       DPRINT_EXIT(NETVSC);
-
        return ret;
 }
 
@@ -600,13 +575,10 @@ static int NetVscConnectToVsp(struct hv_device *Device)
        struct nvsp_message *initPacket;
        int ndisVersion;
 
-       DPRINT_ENTER(NETVSC);
-
        netDevice = GetOutboundNetDevice(Device);
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "unable to get net device..."
                           "device being destroyed?");
-               DPRINT_EXIT(NETVSC);
                return -1;
        }
 
@@ -696,18 +668,13 @@ static int NetVscConnectToVsp(struct hv_device *Device)
 
 Cleanup:
        PutNetDevice(Device);
-       DPRINT_EXIT(NETVSC);
        return ret;
 }
 
 static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice)
 {
-       DPRINT_ENTER(NETVSC);
-
        NetVscDestroyReceiveBuffer(NetDevice);
        NetVscDestroySendBuffer(NetDevice);
-
-       DPRINT_EXIT(NETVSC);
 }
 
 /*
@@ -722,8 +689,6 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
        struct netvsc_driver *netDriver =
                                (struct netvsc_driver *)Device->Driver;
 
-       DPRINT_ENTER(NETVSC);
-
        netDevice = AllocNetDevice(Device);
        if (!netDevice) {
                ret = -1;
@@ -787,7 +752,6 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
        DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***",
                    ret);
 
-       DPRINT_EXIT(NETVSC);
        return ret;
 
 Close:
@@ -812,7 +776,6 @@ Cleanup:
                FreeNetDevice(netDevice);
        }
 
-       DPRINT_EXIT(NETVSC);
        return ret;
 }
 
@@ -824,8 +787,6 @@ static int NetVscOnDeviceRemove(struct hv_device *Device)
        struct netvsc_device *netDevice;
        struct hv_netvsc_packet *netvscPacket, *pos;
 
-       DPRINT_ENTER(NETVSC);
-
        DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...",
                    Device->Extension);
 
@@ -868,8 +829,6 @@ static int NetVscOnDeviceRemove(struct hv_device *Device)
 
        kfree(netDevice->ChannelInitEvent);
        FreeNetDevice(netDevice);
-
-       DPRINT_EXIT(NETVSC);
        return 0;
 }
 
@@ -878,8 +837,6 @@ static int NetVscOnDeviceRemove(struct hv_device *Device)
  */
 static void NetVscOnCleanup(struct hv_driver *drv)
 {
-       DPRINT_ENTER(NETVSC);
-       DPRINT_EXIT(NETVSC);
 }
 
 static void NetVscOnSendCompletion(struct hv_device *Device,
@@ -889,13 +846,10 @@ static void NetVscOnSendCompletion(struct hv_device *Device,
        struct nvsp_message *nvspPacket;
        struct hv_netvsc_packet *nvscPacket;
 
-       DPRINT_ENTER(NETVSC);
-
        netDevice = GetInboundNetDevice(Device);
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "unable to get net device..."
                           "device being destroyed?");
-               DPRINT_EXIT(NETVSC);
                return;
        }
 
@@ -929,7 +883,6 @@ static void NetVscOnSendCompletion(struct hv_device *Device,
        }
 
        PutNetDevice(Device);
-       DPRINT_EXIT(NETVSC);
 }
 
 static int NetVscOnSend(struct hv_device *Device,
@@ -940,13 +893,10 @@ static int NetVscOnSend(struct hv_device *Device,
 
        struct nvsp_message sendMessage;
 
-       DPRINT_ENTER(NETVSC);
-
        netDevice = GetOutboundNetDevice(Device);
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
                           "ignoring outbound packets", netDevice);
-               DPRINT_EXIT(NETVSC);
                return -2;
        }
 
@@ -986,8 +936,6 @@ static int NetVscOnSend(struct hv_device *Device,
 
        atomic_inc(&netDevice->NumOutstandingSends);
        PutNetDevice(Device);
-
-       DPRINT_EXIT(NETVSC);
        return ret;
 }
 
@@ -1007,13 +955,10 @@ static void NetVscOnReceive(struct hv_device *Device,
        unsigned long flags;
        LIST_HEAD(listHead);
 
-       DPRINT_ENTER(NETVSC);
-
        netDevice = GetInboundNetDevice(Device);
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "unable to get net device..."
                           "device being destroyed?");
-               DPRINT_EXIT(NETVSC);
                return;
        }
 
@@ -1189,7 +1134,6 @@ static void NetVscOnReceive(struct hv_device *Device,
        /* ASSERT(list_empty(&listHead)); */
 
        PutNetDevice(Device);
-       DPRINT_EXIT(NETVSC);
 }
 
 static void NetVscSendReceiveCompletion(struct hv_device *Device,
@@ -1248,8 +1192,6 @@ static void NetVscOnReceiveCompletion(void *Context)
        bool fSendReceiveComp = false;
        unsigned long flags;
 
-       DPRINT_ENTER(NETVSC);
-
        /* ASSERT(packet->XferPagePacket); */
 
        /*
@@ -1261,7 +1203,6 @@ static void NetVscOnReceiveCompletion(void *Context)
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "unable to get net device..."
                           "device being destroyed?");
-               DPRINT_EXIT(NETVSC);
                return;
        }
 
@@ -1292,7 +1233,6 @@ static void NetVscOnReceiveCompletion(void *Context)
                NetVscSendReceiveCompletion(device, transactionId);
 
        PutNetDevice(device);
-       DPRINT_EXIT(NETVSC);
 }
 
 static void NetVscOnChannelCallback(void *Context)
@@ -1307,9 +1247,6 @@ static void NetVscOnChannelCallback(void *Context)
        unsigned char *buffer;
        int bufferlen = NETVSC_PACKET_SIZE;
 
-
-       DPRINT_ENTER(NETVSC);
-
        /* ASSERT(device); */
 
        packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char),
@@ -1322,7 +1259,6 @@ static void NetVscOnChannelCallback(void *Context)
        if (!netDevice) {
                DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
                           "ignoring inbound packets", netDevice);
-               DPRINT_EXIT(NETVSC);
                goto out;
        }
 
@@ -1386,7 +1322,6 @@ static void NetVscOnChannelCallback(void *Context)
        } while (1);
 
        PutNetDevice(device);
-       DPRINT_EXIT(NETVSC);
 out:
        kfree(buffer);
        return;
index 55b993298ff4f34a021c6a5eb952665f9666d40e..56e11575c97763f1747a35ae67db81b49cdd6325 100644 (file)
@@ -76,8 +76,6 @@ static int netvsc_open(struct net_device *net)
        struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
        int ret = 0;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        if (netif_carrier_ok(net)) {
                /* Open up the device */
                ret = RndisFilterOnOpen(device_obj);
@@ -92,7 +90,6 @@ static int netvsc_open(struct net_device *net)
                DPRINT_ERR(NETVSC_DRV, "unable to open device...link is down.");
        }
 
-       DPRINT_EXIT(NETVSC_DRV);
        return ret;
 }
 
@@ -102,16 +99,12 @@ static int netvsc_close(struct net_device *net)
        struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
        int ret;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        netif_stop_queue(net);
 
        ret = RndisFilterOnClose(device_obj);
        if (ret != 0)
                DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret);
 
-       DPRINT_EXIT(NETVSC_DRV);
-
        return ret;
 }
 
@@ -121,8 +114,6 @@ static void netvsc_xmit_completion(void *context)
        struct sk_buff *skb = (struct sk_buff *)
                (unsigned long)packet->Completion.Send.SendCompletionTid;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        kfree(packet);
 
        if (skb) {
@@ -135,8 +126,6 @@ static void netvsc_xmit_completion(void *context)
                if ((net_device_ctx->avail += num_pages) >= PACKET_PAGES_HIWATER)
                        netif_wake_queue(net);
        }
-
-       DPRINT_EXIT(NETVSC_DRV);
 }
 
 static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
@@ -151,8 +140,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
        int ret;
        unsigned int i, num_pages;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        DPRINT_DBG(NETVSC_DRV, "xmit packet - len %d data_len %d",
                   skb->len, skb->data_len);
 
@@ -225,7 +212,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
                netvsc_xmit_completion(packet);
        }
 
-       DPRINT_EXIT(NETVSC_DRV);
        return NETDEV_TX_OK;
 }
 
@@ -238,8 +224,6 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj,
        struct vm_device *device_ctx = to_vm_device(device_obj);
        struct net_device *net = dev_get_drvdata(&device_ctx->device);
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        if (!net) {
                DPRINT_ERR(NETVSC_DRV, "got link status but net device "
                                "not initialized yet");
@@ -253,7 +237,6 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj,
                netif_carrier_off(net);
                netif_stop_queue(net);
        }
-       DPRINT_EXIT(NETVSC_DRV);
 }
 
 /*
@@ -270,8 +253,6 @@ static int netvsc_recv_callback(struct hv_device *device_obj,
        int i;
        unsigned long flags;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        if (!net) {
                DPRINT_ERR(NETVSC_DRV, "got receive callback but net device "
                                "not initialized yet");
@@ -323,8 +304,6 @@ static int netvsc_recv_callback(struct hv_device *device_obj,
        DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu",
                   net->stats.rx_packets, net->stats.rx_bytes);
 
-       DPRINT_EXIT(NETVSC_DRV);
-
        return 0;
 }
 
@@ -364,8 +343,6 @@ static int netvsc_probe(struct device *device)
        struct netvsc_device_info device_info;
        int ret;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        if (!net_drv_obj->Base.OnDeviceAdd)
                return -1;
 
@@ -422,7 +399,6 @@ static int netvsc_probe(struct device *device)
                free_netdev(net);
        }
 
-       DPRINT_EXIT(NETVSC_DRV);
        return ret;
 }
 
@@ -438,18 +414,13 @@ static int netvsc_remove(struct device *device)
        struct hv_device *device_obj = &device_ctx->device_obj;
        int ret;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        if (net == NULL) {
                DPRINT_INFO(NETVSC, "no net device to remove");
-               DPRINT_EXIT(NETVSC_DRV);
                return 0;
        }
 
-       if (!net_drv_obj->Base.OnDeviceRemove) {
-               DPRINT_EXIT(NETVSC_DRV);
+       if (!net_drv_obj->Base.OnDeviceRemove)
                return -1;
-       }
 
        /* Stop outbound asap */
        netif_stop_queue(net);
@@ -468,7 +439,6 @@ static int netvsc_remove(struct device *device)
        }
 
        free_netdev(net);
-       DPRINT_EXIT(NETVSC_DRV);
        return ret;
 }
 
@@ -488,8 +458,6 @@ static void netvsc_drv_exit(void)
        struct device *current_dev;
        int ret;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        while (1) {
                current_dev = NULL;
 
@@ -515,8 +483,6 @@ static void netvsc_drv_exit(void)
 
        vmbus_child_driver_unregister(drv_ctx);
 
-       DPRINT_EXIT(NETVSC_DRV);
-
        return;
 }
 
@@ -526,8 +492,6 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
        struct driver_context *drv_ctx = &g_netvsc_drv.drv_ctx;
        int ret;
 
-       DPRINT_ENTER(NETVSC_DRV);
-
        vmbus_get_interface(&net_drv_obj->Base.VmbusChannelInterface);
 
        net_drv_obj->RingBufferSize = ring_size * PAGE_SIZE;
@@ -547,8 +511,6 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
        /* The driver belongs to vmbus */
        ret = vmbus_child_driver_register(drv_ctx);
 
-       DPRINT_EXIT(NETVSC_DRV);
-
        return ret;
 }
 
@@ -568,26 +530,17 @@ MODULE_DEVICE_TABLE(dmi, hv_netvsc_dmi_table);
 
 static int __init netvsc_init(void)
 {
-       int ret;
-
-       DPRINT_ENTER(NETVSC_DRV);
        DPRINT_INFO(NETVSC_DRV, "Netvsc initializing....");
 
        if (!dmi_check_system(hv_netvsc_dmi_table))
                return -ENODEV;
 
-       ret = netvsc_drv_init(NetVscInitialize);
-
-       DPRINT_EXIT(NETVSC_DRV);
-
-       return ret;
+       return netvsc_drv_init(NetVscInitialize);
 }
 
 static void __exit netvsc_exit(void)
 {
-       DPRINT_ENTER(NETVSC_DRV);
        netvsc_drv_exit();
-       DPRINT_EXIT(NETVSC_DRV);
 }
 
 static const struct pci_device_id __initconst
index ae2a10e24d92eabf21f9eb84049cd4ed48088719..17bc7626f70a71d991aa2bdc9c50a960657e4f90 100644 (file)
@@ -46,7 +46,7 @@ Description:
 
 --*/
 static inline void
-GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write)
+GetRingBufferAvailBytes(struct hv_ring_buffer_info *rbi, u32 *read, u32 *write)
 {
        u32 read_loc, write_loc;
 
@@ -68,7 +68,7 @@ Description:
 
 --*/
 static inline u32
-GetNextWriteLocation(RING_BUFFER_INFO *RingInfo)
+GetNextWriteLocation(struct hv_ring_buffer_info *RingInfo)
 {
        u32 next = RingInfo->RingBuffer->WriteIndex;
 
@@ -87,7 +87,8 @@ Description:
 
 --*/
 static inline void
-SetNextWriteLocation(RING_BUFFER_INFO *RingInfo, u32 NextWriteLocation)
+SetNextWriteLocation(struct hv_ring_buffer_info *RingInfo,
+                    u32 NextWriteLocation)
 {
        RingInfo->RingBuffer->WriteIndex = NextWriteLocation;
 }
@@ -102,7 +103,7 @@ Description:
 
 --*/
 static inline u32
-GetNextReadLocation(RING_BUFFER_INFO *RingInfo)
+GetNextReadLocation(struct hv_ring_buffer_info *RingInfo)
 {
        u32 next = RingInfo->RingBuffer->ReadIndex;
 
@@ -122,7 +123,7 @@ Description:
 
 --*/
 static inline u32
-GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset)
+GetNextReadLocationWithOffset(struct hv_ring_buffer_info *RingInfo, u32 Offset)
 {
        u32 next = RingInfo->RingBuffer->ReadIndex;
 
@@ -143,7 +144,7 @@ Description:
 
 --*/
 static inline void
-SetNextReadLocation(RING_BUFFER_INFO *RingInfo, u32 NextReadLocation)
+SetNextReadLocation(struct hv_ring_buffer_info *RingInfo, u32 NextReadLocation)
 {
        RingInfo->RingBuffer->ReadIndex = NextReadLocation;
 }
@@ -159,7 +160,7 @@ Description:
 
 --*/
 static inline void *
-GetRingBuffer(RING_BUFFER_INFO *RingInfo)
+GetRingBuffer(struct hv_ring_buffer_info *RingInfo)
 {
        return (void *)RingInfo->RingBuffer->Buffer;
 }
@@ -175,7 +176,7 @@ Description:
 
 --*/
 static inline u32
-GetRingBufferSize(RING_BUFFER_INFO *RingInfo)
+GetRingBufferSize(struct hv_ring_buffer_info *RingInfo)
 {
        return RingInfo->RingDataSize;
 }
@@ -190,7 +191,7 @@ Description:
 
 --*/
 static inline u64
-GetRingBufferIndices(RING_BUFFER_INFO *RingInfo)
+GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo)
 {
        return ((u64)RingInfo->RingBuffer->WriteIndex << 32)
        || RingInfo->RingBuffer->ReadIndex;
@@ -206,7 +207,7 @@ Description:
        Dump out to console the ring buffer info
 
 --*/
-void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix)
+void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix)
 {
        u32 bytesAvailToWrite;
        u32 bytesAvailToRead;
@@ -233,14 +234,14 @@ void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix)
 
 static u32
 CopyToRingBuffer(
-       RING_BUFFER_INFO        *RingInfo,
+       struct hv_ring_buffer_info      *RingInfo,
        u32                             StartWriteOffset,
        void                            *Src,
        u32                             SrcLen);
 
 static u32
 CopyFromRingBuffer(
-       RING_BUFFER_INFO        *RingInfo,
+       struct hv_ring_buffer_info      *RingInfo,
        void                            *Dest,
        u32                             DestLen,
        u32                             StartReadOffset);
@@ -256,8 +257,8 @@ Description:
        Get various debug metrics for the specified ring buffer
 
 --*/
-void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo,
-                           RING_BUFFER_DEBUG_INFO *DebugInfo)
+void RingBufferGetDebugInfo(struct hv_ring_buffer_info *RingInfo,
+                           struct hv_ring_buffer_debug_info *debug_info)
 {
        u32 bytesAvailToWrite;
        u32 bytesAvailToRead;
@@ -267,11 +268,11 @@ void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo,
                                        &bytesAvailToRead,
                                        &bytesAvailToWrite);
 
-               DebugInfo->BytesAvailToRead = bytesAvailToRead;
-               DebugInfo->BytesAvailToWrite = bytesAvailToWrite;
-               DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex;
-               DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex;
-               DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask;
+               debug_info->BytesAvailToRead = bytesAvailToRead;
+               debug_info->BytesAvailToWrite = bytesAvailToWrite;
+               debug_info->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex;
+               debug_info->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex;
+               debug_info->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask;
        }
 }
 
@@ -285,7 +286,7 @@ Description:
        Get the interrupt mask for the specified ring buffer
 
 --*/
-u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *rbi)
+u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *rbi)
 {
        return rbi->RingBuffer->InterruptMask;
 }
@@ -299,18 +300,18 @@ Description:
        Initialize the ring buffer
 
 --*/
-int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen)
+int RingBufferInit(struct hv_ring_buffer_info *RingInfo, void *Buffer, u32 BufferLen)
 {
-       if (sizeof(RING_BUFFER) != PAGE_SIZE)
+       if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
                return -EINVAL;
 
-       memset(RingInfo, 0, sizeof(RING_BUFFER_INFO));
+       memset(RingInfo, 0, sizeof(struct hv_ring_buffer_info));
 
-       RingInfo->RingBuffer = (RING_BUFFER *)Buffer;
+       RingInfo->RingBuffer = (struct hv_ring_buffer *)Buffer;
        RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0;
 
        RingInfo->RingSize = BufferLen;
-       RingInfo->RingDataSize = BufferLen - sizeof(RING_BUFFER);
+       RingInfo->RingDataSize = BufferLen - sizeof(struct hv_ring_buffer);
 
        spin_lock_init(&RingInfo->ring_lock);
 
@@ -326,7 +327,7 @@ Description:
        Cleanup the ring buffer
 
 --*/
-void RingBufferCleanup(RING_BUFFER_INFO *RingInfo)
+void RingBufferCleanup(struct hv_ring_buffer_info *RingInfo)
 {
 }
 
@@ -339,7 +340,7 @@ Description:
        Write to the ring buffer
 
 --*/
-int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
+int RingBufferWrite(struct hv_ring_buffer_info *OutRingInfo,
                    struct scatterlist *sglist, u32 sgcount)
 {
        int i = 0;
@@ -352,8 +353,6 @@ int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
        u64 prevIndices = 0;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        for_each_sg(sglist, sg, sgcount, i)
        {
                totalBytesToWrite += sg->length;
@@ -382,9 +381,6 @@ int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
                        byteAvailToWrite);
 
                spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
-
-               DPRINT_EXIT(VMBUS);
-
                return -1;
        }
 
@@ -416,9 +412,6 @@ int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
        /* DumpRingInfo(OutRingInfo, "AFTER "); */
 
        spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
-
        return 0;
 }
 
@@ -432,7 +425,7 @@ Description:
        Read without advancing the read index
 
 --*/
-int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen)
+int RingBufferPeek(struct hv_ring_buffer_info *InRingInfo, void *Buffer, u32 BufferLen)
 {
        u32 bytesAvailToWrite;
        u32 bytesAvailToRead;
@@ -481,7 +474,7 @@ Description:
        Read and advance the read index
 
 --*/
-int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer,
+int RingBufferRead(struct hv_ring_buffer_info *InRingInfo, void *Buffer,
                   u32 BufferLen, u32 Offset)
 {
        u32 bytesAvailToWrite;
@@ -556,7 +549,7 @@ Description:
 --*/
 static u32
 CopyToRingBuffer(
-       RING_BUFFER_INFO        *RingInfo,
+       struct hv_ring_buffer_info      *RingInfo,
        u32                             StartWriteOffset,
        void                            *Src,
        u32                             SrcLen)
@@ -594,7 +587,7 @@ Description:
 --*/
 static u32
 CopyFromRingBuffer(
-       RING_BUFFER_INFO        *RingInfo,
+       struct hv_ring_buffer_info      *RingInfo,
        void                            *Dest,
        u32                             DestLen,
        u32                             StartReadOffset)
index 6202157e145dc791b1412149c0dc94eb0066a2e8..a7f1717c6a5659b49b9a7c2aa56bbbea97e1e30a 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <linux/scatterlist.h>
 
-typedef struct _RING_BUFFER {
+struct hv_ring_buffer {
        /* Offset in bytes from the start of ring data below */
        volatile u32 WriteIndex;
 
@@ -51,51 +51,52 @@ typedef struct _RING_BUFFER {
         * !!! DO NOT place any fields below this !!!
         */
        u8 Buffer[0];
-} __attribute__((packed)) RING_BUFFER;
+} __attribute__((packed));
 
-typedef struct _RING_BUFFER_INFO {
-       RING_BUFFER *RingBuffer;
+struct hv_ring_buffer_info {
+       struct hv_ring_buffer *RingBuffer;
        u32 RingSize;                   /* Include the shared header */
        spinlock_t ring_lock;
 
        u32 RingDataSize;               /* < ringSize */
        u32 RingDataStartOffset;
+};
 
-} RING_BUFFER_INFO;
-
-typedef struct _RING_BUFFER_DEBUG_INFO {
+struct hv_ring_buffer_debug_info {
        u32 CurrentInterruptMask;
        u32 CurrentReadIndex;
        u32 CurrentWriteIndex;
        u32 BytesAvailToRead;
        u32 BytesAvailToWrite;
-} RING_BUFFER_DEBUG_INFO;
+};
 
 
 
 /* Interface */
 
 
-int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen);
+int RingBufferInit(struct hv_ring_buffer_info *RingInfo, void *Buffer,
+                  u32 BufferLen);
 
-void RingBufferCleanup(RING_BUFFER_INFO *RingInfo);
+void RingBufferCleanup(struct hv_ring_buffer_info *RingInfo);
 
-int RingBufferWrite(RING_BUFFER_INFO *RingInfo,
+int RingBufferWrite(struct hv_ring_buffer_info *RingInfo,
                    struct scatterlist *sglist,
                    u32 sgcount);
 
-int RingBufferPeek(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen);
+int RingBufferPeek(struct hv_ring_buffer_info *RingInfo, void *Buffer,
+                  u32 BufferLen);
 
-int RingBufferRead(RING_BUFFER_INFO *RingInfo,
+int RingBufferRead(struct hv_ring_buffer_info *RingInfo,
                   void *Buffer,
                   u32 BufferLen,
                   u32 Offset);
 
-u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *RingInfo);
+u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *RingInfo);
 
-void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix);
+void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix);
 
-void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo,
-                           RING_BUFFER_DEBUG_INFO *DebugInfo);
+void RingBufferGetDebugInfo(struct hv_ring_buffer_info *RingInfo,
+                           struct hv_ring_buffer_debug_info *debug_info);
 
 #endif /* _RING_BUFFER_H_ */
index 5edf0853c6afe03d3340253d647380c1a9c1a189..fa2141f454f0ce2739fa502addf1a1f259d35486 100644 (file)
@@ -244,8 +244,6 @@ static int RndisFilterSendRequest(struct rndis_device *Device,
        int ret;
        struct hv_netvsc_packet *packet;
 
-       DPRINT_ENTER(NETVSC);
-
        /* Setup the packet to send it */
        packet = &Request->Packet;
 
@@ -265,7 +263,6 @@ static int RndisFilterSendRequest(struct rndis_device *Device,
        packet->Completion.Send.SendCompletionTid = (unsigned long)Device;
 
        ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet);
-       DPRINT_EXIT(NETVSC);
        return ret;
 }
 
@@ -276,8 +273,6 @@ static void RndisFilterReceiveResponse(struct rndis_device *Device,
        bool found = false;
        unsigned long flags;
 
-       DPRINT_ENTER(NETVSC);
-
        spin_lock_irqsave(&Device->request_lock, flags);
        list_for_each_entry(request, &Device->RequestList, ListEntry) {
                /*
@@ -325,8 +320,6 @@ static void RndisFilterReceiveResponse(struct rndis_device *Device,
                           Response->Message.InitializeComplete.RequestId,
                           Response->NdisMessageType);
        }
-
-       DPRINT_EXIT(NETVSC);
 }
 
 static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device,
@@ -353,8 +346,6 @@ static void RndisFilterReceiveData(struct rndis_device *Device,
        struct rndis_packet *rndisPacket;
        u32 dataOffset;
 
-       DPRINT_ENTER(NETVSC);
-
        /* empty ethernet frame ?? */
        /* ASSERT(Packet->PageBuffers[0].Length > */
        /*      RNDIS_MESSAGE_SIZE(struct rndis_packet)); */
@@ -377,8 +368,6 @@ static void RndisFilterReceiveData(struct rndis_device *Device,
 
        gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device,
                                                   Packet);
-
-       DPRINT_EXIT(NETVSC);
 }
 
 static int RndisFilterOnReceive(struct hv_device *Device,
@@ -389,8 +378,6 @@ static int RndisFilterOnReceive(struct hv_device *Device,
        struct rndis_message rndisMessage;
        struct rndis_message *rndisHeader;
 
-       DPRINT_ENTER(NETVSC);
-
        if (!netDevice)
                return -EINVAL;
 
@@ -398,7 +385,6 @@ static int RndisFilterOnReceive(struct hv_device *Device,
        if (!netDevice->Extension) {
                DPRINT_ERR(NETVSC, "got rndis message but no rndis device..."
                          "dropping this message!");
-               DPRINT_EXIT(NETVSC);
                return -1;
        }
 
@@ -406,7 +392,6 @@ static int RndisFilterOnReceive(struct hv_device *Device,
        if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) {
                DPRINT_ERR(NETVSC, "got rndis message but rndis device "
                           "uninitialized...dropping this message!");
-               DPRINT_EXIT(NETVSC);
                return -1;
        }
 
@@ -431,7 +416,6 @@ static int RndisFilterOnReceive(struct hv_device *Device,
                           "bytes got %u)...dropping this message!",
                           rndisHeader->MessageLength,
                           Packet->TotalDataBufferLength);
-               DPRINT_EXIT(NETVSC);
                return -1;
        }
 #endif
@@ -479,7 +463,6 @@ static int RndisFilterOnReceive(struct hv_device *Device,
                break;
        }
 
-       DPRINT_EXIT(NETVSC);
        return 0;
 }
 
@@ -492,8 +475,6 @@ static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid,
        struct rndis_query_complete *queryComplete;
        int ret = 0;
 
-       DPRINT_ENTER(NETVSC);
-
        if (!Result)
                return -EINVAL;
 
@@ -536,7 +517,6 @@ static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid,
 Cleanup:
        if (request)
                PutRndisRequest(Device, request);
-       DPRINT_EXIT(NETVSC);
 
        return ret;
 }
@@ -568,8 +548,6 @@ static int RndisFilterSetPacketFilter(struct rndis_device *Device,
        u32 status;
        int ret;
 
-       DPRINT_ENTER(NETVSC);
-
        /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */
        /*      sizeof(struct rndis_message)); */
 
@@ -614,15 +592,11 @@ Cleanup:
        if (request)
                PutRndisRequest(Device, request);
 Exit:
-       DPRINT_EXIT(NETVSC);
-
        return ret;
 }
 
 int RndisFilterInit(struct netvsc_driver *Driver)
 {
-       DPRINT_ENTER(NETVSC);
-
        DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd",
                   sizeof(struct rndis_filter_packet));
 
@@ -658,8 +632,6 @@ int RndisFilterInit(struct netvsc_driver *Driver)
        /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */
        Driver->OnReceiveCallback = RndisFilterOnReceive;
 
-       DPRINT_EXIT(NETVSC);
-
        return 0;
 }
 
@@ -671,8 +643,6 @@ static int RndisFilterInitDevice(struct rndis_device *Device)
        u32 status;
        int ret;
 
-       DPRINT_ENTER(NETVSC);
-
        request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG,
                        RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
        if (!request) {
@@ -710,7 +680,6 @@ static int RndisFilterInitDevice(struct rndis_device *Device)
 Cleanup:
        if (request)
                PutRndisRequest(Device, request);
-       DPRINT_EXIT(NETVSC);
 
        return ret;
 }
@@ -720,8 +689,6 @@ static void RndisFilterHaltDevice(struct rndis_device *Device)
        struct rndis_request *request;
        struct rndis_halt_request *halt;
 
-       DPRINT_ENTER(NETVSC);
-
        /* Attempt to do a rndis device halt */
        request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG,
                                RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
@@ -740,7 +707,6 @@ static void RndisFilterHaltDevice(struct rndis_device *Device)
 Cleanup:
        if (request)
                PutRndisRequest(Device, request);
-       DPRINT_EXIT(NETVSC);
        return;
 }
 
@@ -748,8 +714,6 @@ static int RndisFilterOpenDevice(struct rndis_device *Device)
 {
        int ret;
 
-       DPRINT_ENTER(NETVSC);
-
        if (Device->State != RNDIS_DEV_INITIALIZED)
                return 0;
 
@@ -760,7 +724,6 @@ static int RndisFilterOpenDevice(struct rndis_device *Device)
        if (ret == 0)
                Device->State = RNDIS_DEV_DATAINITIALIZED;
 
-       DPRINT_EXIT(NETVSC);
        return ret;
 }
 
@@ -768,8 +731,6 @@ static int RndisFilterCloseDevice(struct rndis_device *Device)
 {
        int ret;
 
-       DPRINT_ENTER(NETVSC);
-
        if (Device->State != RNDIS_DEV_DATAINITIALIZED)
                return 0;
 
@@ -777,8 +738,6 @@ static int RndisFilterCloseDevice(struct rndis_device *Device)
        if (ret == 0)
                Device->State = RNDIS_DEV_INITIALIZED;
 
-       DPRINT_EXIT(NETVSC);
-
        return ret;
 }
 
@@ -790,13 +749,9 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device,
        struct rndis_device *rndisDevice;
        struct netvsc_device_info *deviceInfo = AdditionalInfo;
 
-       DPRINT_ENTER(NETVSC);
-
        rndisDevice = GetRndisDevice();
-       if (!rndisDevice) {
-               DPRINT_EXIT(NETVSC);
+       if (!rndisDevice)
                return -1;
-       }
 
        DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
 
@@ -808,7 +763,6 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device,
        ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
        if (ret != 0) {
                kfree(rndisDevice);
-               DPRINT_EXIT(NETVSC);
                return ret;
        }
 
@@ -849,8 +803,6 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device,
        DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice,
                    ((deviceInfo->LinkState) ? ("down") : ("up")));
 
-       DPRINT_EXIT(NETVSC);
-
        return ret;
 }
 
@@ -859,8 +811,6 @@ static int RndisFilterOnDeviceRemove(struct hv_device *Device)
        struct netvsc_device *netDevice = Device->Extension;
        struct rndis_device *rndisDevice = netDevice->Extension;
 
-       DPRINT_ENTER(NETVSC);
-
        /* Halt and release the rndis device */
        RndisFilterHaltDevice(rndisDevice);
 
@@ -870,50 +820,31 @@ static int RndisFilterOnDeviceRemove(struct hv_device *Device)
        /* Pass control to inner driver to remove the device */
        gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device);
 
-       DPRINT_EXIT(NETVSC);
-
        return 0;
 }
 
 static void RndisFilterOnCleanup(struct hv_driver *Driver)
 {
-       DPRINT_ENTER(NETVSC);
-
-       DPRINT_EXIT(NETVSC);
 }
 
 int RndisFilterOnOpen(struct hv_device *Device)
 {
-       int ret;
        struct netvsc_device *netDevice = Device->Extension;
 
-       DPRINT_ENTER(NETVSC);
-
        if (!netDevice)
                return -EINVAL;
 
-       ret = RndisFilterOpenDevice(netDevice->Extension);
-
-       DPRINT_EXIT(NETVSC);
-
-       return ret;
+       return RndisFilterOpenDevice(netDevice->Extension);
 }
 
 int RndisFilterOnClose(struct hv_device *Device)
 {
-       int ret;
        struct netvsc_device *netDevice = Device->Extension;
 
-       DPRINT_ENTER(NETVSC);
-
        if (!netDevice)
                return -EINVAL;
 
-       ret = RndisFilterCloseDevice(netDevice->Extension);
-
-       DPRINT_EXIT(NETVSC);
-
-       return ret;
+       return RndisFilterCloseDevice(netDevice->Extension);
 }
 
 static int RndisFilterOnSend(struct hv_device *Device,
@@ -925,8 +856,6 @@ static int RndisFilterOnSend(struct hv_device *Device,
        struct rndis_packet *rndisPacket;
        u32 rndisMessageSize;
 
-       DPRINT_ENTER(NETVSC);
-
        /* Add the rndis header */
        filterPacket = (struct rndis_filter_packet *)Packet->Extension;
        /* ASSERT(filterPacket); */
@@ -971,8 +900,6 @@ static int RndisFilterOnSend(struct hv_device *Device,
                                filterPacket->CompletionContext;
        }
 
-       DPRINT_EXIT(NETVSC);
-
        return ret;
 }
 
@@ -980,19 +907,12 @@ static void RndisFilterOnSendCompletion(void *Context)
 {
        struct rndis_filter_packet *filterPacket = Context;
 
-       DPRINT_ENTER(NETVSC);
-
        /* Pass it back to the original handler */
        filterPacket->OnCompletion(filterPacket->CompletionContext);
-
-       DPRINT_EXIT(NETVSC);
 }
 
 
 static void RndisFilterOnSendRequestCompletion(void *Context)
 {
-       DPRINT_ENTER(NETVSC);
-
        /* Noop */
-       DPRINT_EXIT(NETVSC);
 }
index 27a276e08ee9c45148d4eb95dde535b0a9b7cbbd..6bd2ff138d24527e6b2ba0f1428ea4bdf4063c03 100644 (file)
@@ -186,7 +186,6 @@ static int StorVscChannelInit(struct hv_device *Device)
        if (!storDevice) {
                DPRINT_ERR(STORVSC, "unable to get stor device..."
                           "device being destroyed?");
-               DPRINT_EXIT(STORVSC);
                return -1;
        }
 
@@ -344,8 +343,6 @@ Cleanup:
        request->WaitEvent = NULL;
 nomem:
        PutStorDevice(Device);
-
-       DPRINT_EXIT(STORVSC);
        return ret;
 }
 
@@ -356,13 +353,10 @@ static void StorVscOnIOCompletion(struct hv_device *Device,
        struct hv_storvsc_request *request;
        struct storvsc_device *storDevice;
 
-       DPRINT_ENTER(STORVSC);
-
        storDevice = MustGetStorDevice(Device);
        if (!storDevice) {
                DPRINT_ERR(STORVSC, "unable to get stor device..."
                           "device being destroyed?");
-               DPRINT_EXIT(STORVSC);
                return;
        }
 
@@ -414,8 +408,6 @@ static void StorVscOnIOCompletion(struct hv_device *Device,
        atomic_dec(&storDevice->NumOutstandingRequests);
 
        PutStorDevice(Device);
-
-       DPRINT_EXIT(STORVSC);
 }
 
 static void StorVscOnReceive(struct hv_device *Device,
@@ -449,15 +441,12 @@ static void StorVscOnChannelCallback(void *context)
        struct storvsc_request_extension *request;
        int ret;
 
-       DPRINT_ENTER(STORVSC);
-
        /* ASSERT(device); */
 
        storDevice = MustGetStorDevice(device);
        if (!storDevice) {
                DPRINT_ERR(STORVSC, "unable to get stor device..."
                           "device being destroyed?");
-               DPRINT_EXIT(STORVSC);
                return;
        }
 
@@ -501,8 +490,6 @@ static void StorVscOnChannelCallback(void *context)
        } while (1);
 
        PutStorDevice(device);
-
-       DPRINT_EXIT(STORVSC);
        return;
 }
 
@@ -547,8 +534,6 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
        struct storvsc_device_info *deviceInfo;
        int ret = 0;
 
-       DPRINT_ENTER(STORVSC);
-
        deviceInfo = (struct storvsc_device_info *)AdditionalInfo;
        storDevice = AllocStorDevice(Device);
        if (!storDevice) {
@@ -584,8 +569,6 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
                   storDevice->TargetId);
 
 Cleanup:
-       DPRINT_EXIT(STORVSC);
-
        return ret;
 }
 
@@ -596,8 +579,6 @@ static int StorVscOnDeviceRemove(struct hv_device *Device)
 {
        struct storvsc_device *storDevice;
 
-       DPRINT_ENTER(STORVSC);
-
        DPRINT_INFO(STORVSC, "disabling storage device (%p)...",
                    Device->Extension);
 
@@ -625,8 +606,6 @@ static int StorVscOnDeviceRemove(struct hv_device *Device)
        Device->Driver->VmbusChannelInterface.Close(Device);
 
        FreeStorDevice(storDevice);
-
-       DPRINT_EXIT(STORVSC);
        return 0;
 }
 
@@ -637,15 +616,12 @@ int StorVscOnHostReset(struct hv_device *Device)
        struct vstor_packet *vstorPacket;
        int ret;
 
-       DPRINT_ENTER(STORVSC);
-
        DPRINT_INFO(STORVSC, "resetting host adapter...");
 
        storDevice = GetStorDevice(Device);
        if (!storDevice) {
                DPRINT_ERR(STORVSC, "unable to get stor device..."
                           "device being destroyed?");
-               DPRINT_EXIT(STORVSC);
                return -1;
        }
 
@@ -687,7 +663,6 @@ int StorVscOnHostReset(struct hv_device *Device)
 
 Cleanup:
        PutStorDevice(Device);
-       DPRINT_EXIT(STORVSC);
        return ret;
 }
 
@@ -702,8 +677,6 @@ static int StorVscOnIORequest(struct hv_device *Device,
        struct vstor_packet *vstorPacket;
        int ret = 0;
 
-       DPRINT_ENTER(STORVSC);
-
        requestExtension =
                (struct storvsc_request_extension *)Request->Extension;
        vstorPacket = &requestExtension->VStorPacket;
@@ -720,7 +693,6 @@ static int StorVscOnIORequest(struct hv_device *Device,
        if (!storDevice) {
                DPRINT_ERR(STORVSC, "unable to get stor device..."
                           "device being destroyed?");
-               DPRINT_EXIT(STORVSC);
                return -2;
        }
 
@@ -786,8 +758,6 @@ static int StorVscOnIORequest(struct hv_device *Device,
        atomic_inc(&storDevice->NumOutstandingRequests);
 
        PutStorDevice(Device);
-
-       DPRINT_EXIT(STORVSC);
        return ret;
 }
 
@@ -796,8 +766,6 @@ static int StorVscOnIORequest(struct hv_device *Device,
  */
 static void StorVscOnCleanup(struct hv_driver *Driver)
 {
-       DPRINT_ENTER(STORVSC);
-       DPRINT_EXIT(STORVSC);
 }
 
 /*
@@ -807,8 +775,6 @@ int StorVscInitialize(struct hv_driver *Driver)
 {
        struct storvsc_driver_object *storDriver;
 
-       DPRINT_ENTER(STORVSC);
-
        storDriver = (struct storvsc_driver_object *)Driver;
 
        DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd "
@@ -852,7 +818,5 @@ int StorVscInitialize(struct hv_driver *Driver)
 
        storDriver->OnIORequest         = StorVscOnIORequest;
 
-       DPRINT_EXIT(STORVSC);
-
        return 0;
 }
index d22e35f598ba43a0925281a7df7403da3e7029c2..075b61bd492f19918c1ee3027994362b2b6aa900 100644 (file)
@@ -141,8 +141,6 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
        struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj;
        struct driver_context *drv_ctx = &g_storvsc_drv.drv_ctx;
 
-       DPRINT_ENTER(STORVSC_DRV);
-
        vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface);
 
        storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size;
@@ -175,8 +173,6 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
        /* The driver belongs to vmbus */
        ret = vmbus_child_driver_register(drv_ctx);
 
-       DPRINT_EXIT(STORVSC_DRV);
-
        return ret;
 }
 
@@ -194,8 +190,6 @@ static void storvsc_drv_exit(void)
        struct device *current_dev = NULL;
        int ret;
 
-       DPRINT_ENTER(STORVSC_DRV);
-
        while (1) {
                current_dev = NULL;
 
@@ -219,9 +213,6 @@ static void storvsc_drv_exit(void)
                storvsc_drv_obj->Base.OnCleanup(&storvsc_drv_obj->Base);
 
        vmbus_child_driver_unregister(drv_ctx);
-
-       DPRINT_EXIT(STORVSC_DRV);
-
        return;
 }
 
@@ -243,8 +234,6 @@ static int storvsc_probe(struct device *device)
        struct host_device_context *host_device_ctx;
        struct storvsc_device_info device_info;
 
-       DPRINT_ENTER(STORVSC_DRV);
-
        if (!storvsc_drv_obj->Base.OnDeviceAdd)
                return -1;
 
@@ -271,8 +260,6 @@ static int storvsc_probe(struct device *device)
 
        if (!host_device_ctx->request_pool) {
                scsi_host_put(host);
-               DPRINT_EXIT(STORVSC_DRV);
-
                return -ENOMEM;
        }
 
@@ -284,8 +271,6 @@ static int storvsc_probe(struct device *device)
                DPRINT_ERR(STORVSC_DRV, "unable to add scsi vsc device");
                kmem_cache_destroy(host_device_ctx->request_pool);
                scsi_host_put(host);
-               DPRINT_EXIT(STORVSC_DRV);
-
                return -1;
        }
 
@@ -309,15 +294,10 @@ static int storvsc_probe(struct device *device)
 
                kmem_cache_destroy(host_device_ctx->request_pool);
                scsi_host_put(host);
-               DPRINT_EXIT(STORVSC_DRV);
-
                return -1;
        }
 
        scsi_scan_host(host);
-
-       DPRINT_EXIT(STORVSC_DRV);
-
        return ret;
 }
 
@@ -340,12 +320,8 @@ static int storvsc_remove(struct device *device)
                        (struct host_device_context *)host->hostdata;
 
 
-       DPRINT_ENTER(STORVSC_DRV);
-
-       if (!storvsc_drv_obj->Base.OnDeviceRemove) {
-               DPRINT_EXIT(STORVSC_DRV);
+       if (!storvsc_drv_obj->Base.OnDeviceRemove)
                return -1;
-       }
 
        /*
         * Call to the vsc driver to let it know that the device is being
@@ -368,9 +344,6 @@ static int storvsc_remove(struct device *device)
 
        DPRINT_INFO(STORVSC, "releasing host adapter (%p)...", host);
        scsi_host_put(host);
-
-       DPRINT_EXIT(STORVSC_DRV);
-
        return ret;
 }
 
@@ -393,8 +366,6 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request)
        /*        (unsigned long)cmd_request); */
        /* ASSERT(scmnd->scsi_done); */
 
-       DPRINT_ENTER(STORVSC_DRV);
-
        if (cmd_request->bounce_sgl_count) {
                /* using bounce buffer */
                /* printk("copy_from_bounce_buffer\n"); */
@@ -427,8 +398,6 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request)
        scsi_done_fn(scmnd);
 
        kmem_cache_free(host_device_ctx->request_pool, cmd_request);
-
-       DPRINT_EXIT(STORVSC_DRV);
 }
 
 static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
@@ -647,8 +616,6 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
        int i;
        struct scatterlist *sgl;
 
-       DPRINT_ENTER(STORVSC_DRV);
-
        DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d "
                   "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction,
                   scsi_sg_count(scmnd), scsi_sglist(scmnd),
@@ -812,8 +779,6 @@ retry_request:
                ret = SCSI_MLQUEUE_DEVICE_BUSY;
        }
 
-       DPRINT_EXIT(STORVSC_DRV);
-
        return ret;
 }
 
@@ -873,23 +838,17 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
                (struct host_device_context *)scmnd->device->host->hostdata;
        struct vm_device *device_ctx = host_device_ctx->device_ctx;
 
-       DPRINT_ENTER(STORVSC_DRV);
-
        DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host resetting...",
                    scmnd->device, &device_ctx->device_obj);
 
        /* Invokes the vsc to reset the host/bus */
        ret = StorVscOnHostReset(&device_ctx->device_obj);
-       if (ret != 0) {
-               DPRINT_EXIT(STORVSC_DRV);
+       if (ret != 0)
                return ret;
-       }
 
        DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host reseted",
                    scmnd->device, &device_ctx->device_obj);
 
-       DPRINT_EXIT(STORVSC_DRV);
-
        return ret;
 }
 
@@ -977,18 +936,14 @@ static int __init storvsc_init(void)
 {
        int ret;
 
-       DPRINT_ENTER(STORVSC_DRV);
        DPRINT_INFO(STORVSC_DRV, "Storvsc initializing....");
        ret = storvsc_drv_init(StorVscInitialize);
-       DPRINT_EXIT(STORVSC_DRV);
        return ret;
 }
 
 static void __exit storvsc_exit(void)
 {
-       DPRINT_ENTER(STORVSC_DRV);
        storvsc_drv_exit();
-       DPRINT_ENTER(STORVSC_DRV);
 }
 
 MODULE_LICENSE("GPL");
index 007543bdb4100b31d8dba170217a5f46939ef491..ca1e18a620067869d9ca163a04e86e4d31923f4f 100644 (file)
@@ -57,9 +57,7 @@ static struct hv_device *gDevice; /* vmbus root device */
  */
 static void VmbusGetChannelOffers(void)
 {
-       DPRINT_ENTER(VMBUS);
        VmbusChannelRequestOffers();
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -120,8 +118,6 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo)
        u32 *irqvector = AdditionalInfo;
        int ret;
 
-       DPRINT_ENTER(VMBUS);
-
        gDevice = dev;
 
        memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid));
@@ -136,8 +132,6 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo)
        ret = VmbusConnect();
 
        /* VmbusSendEvent(device->localPortId+1); */
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -148,12 +142,9 @@ static int VmbusOnDeviceRemove(struct hv_device *dev)
 {
        int ret = 0;
 
-       DPRINT_ENTER(VMBUS);
        VmbusChannelReleaseUnattachedChannels();
        VmbusDisconnect();
        on_each_cpu(HvSynicCleanup, NULL, 1);
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
 
@@ -164,9 +155,7 @@ static void VmbusOnCleanup(struct hv_driver *drv)
 {
        /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */
 
-       DPRINT_ENTER(VMBUS);
        HvCleanup();
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -239,8 +228,6 @@ static int VmbusOnISR(struct hv_driver *drv)
        page_addr = gHvContext.synICMessagePage[cpu];
        msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Check if there are actual msgs to be process */
        if (msg->Header.MessageType != HvMessageTypeNone) {
                DPRINT_DBG(VMBUS, "received msg type %d size %d",
@@ -259,7 +246,6 @@ static int VmbusOnISR(struct hv_driver *drv)
                ret |= 0x2;
        }
 
-       DPRINT_EXIT(VMBUS);
        return ret;
 }
 
@@ -271,8 +257,6 @@ int VmbusInitialize(struct hv_driver *drv)
        struct vmbus_driver *driver = (struct vmbus_driver *)drv;
        int ret;
 
-       DPRINT_ENTER(VMBUS);
-
        DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++",
                    HV_DRV_VERSION);
        DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++",
@@ -305,7 +289,5 @@ int VmbusInitialize(struct hv_driver *drv)
                                ret);
        gDriver = drv;
 
-       DPRINT_EXIT(VMBUS);
-
        return ret;
 }
index 22c80ece6388c5e72661864105f4d35ebf7e1824..092f02ed6be1cfdfedf24e5b22c13a5eae3fca64 100644 (file)
@@ -254,8 +254,6 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
        int ret;
        unsigned int vector;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /*
         * Set this up to allow lower layer to callback to add/remove child
         * devices on the bus
@@ -360,8 +358,6 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
        wait_for_completion(&hv_channel_ready);
 
 cleanup:
-       DPRINT_EXIT(VMBUS_DRV);
-
        return ret;
 }
 
@@ -377,8 +373,6 @@ static void vmbus_bus_exit(void)
 
        struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* Remove the root device */
        if (vmbus_drv_obj->Base.OnDeviceRemove)
                vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj);
@@ -395,10 +389,6 @@ static void vmbus_bus_exit(void)
 
        tasklet_kill(&vmbus_drv_ctx->msg_dpc);
        tasklet_kill(&vmbus_drv_ctx->event_dpc);
-
-       DPRINT_EXIT(VMBUS_DRV);
-
-       return;
 }
 
 
@@ -419,8 +409,6 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx)
        struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
        int ret;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s",
                    driver_ctx, driver_ctx->driver.name);
 
@@ -431,8 +419,6 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx)
 
        vmbus_drv_obj->GetChannelOffers();
 
-       DPRINT_EXIT(VMBUS_DRV);
-
        return ret;
 }
 EXPORT_SYMBOL(vmbus_child_driver_register);
@@ -450,16 +436,12 @@ EXPORT_SYMBOL(vmbus_child_driver_register);
  */
 void vmbus_child_driver_unregister(struct driver_context *driver_ctx)
 {
-       DPRINT_ENTER(VMBUS_DRV);
-
        DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s",
                    driver_ctx, driver_ctx->driver.name);
 
        driver_unregister(&driver_ctx->driver);
 
        driver_ctx->driver.bus = NULL;
-
-       DPRINT_EXIT(VMBUS_DRV);
 }
 EXPORT_SYMBOL(vmbus_child_driver_unregister);
 
@@ -506,15 +488,11 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
        struct vm_device *child_device_ctx;
        struct hv_device *child_device_obj;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* Allocate the new child device */
        child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL);
        if (!child_device_ctx) {
                DPRINT_ERR(VMBUS_DRV,
                        "unable to allocate device_context for child device");
-               DPRINT_EXIT(VMBUS_DRV);
-
                return NULL;
        }
 
@@ -546,8 +524,6 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
        memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid));
        memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid));
 
-       DPRINT_EXIT(VMBUS_DRV);
-
        return child_device_obj;
 }
 
@@ -564,8 +540,6 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
                                to_vm_device(child_device_obj);
        static atomic_t device_num = ATOMIC_INIT(0);
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        DPRINT_DBG(VMBUS_DRV, "child device (%p) registering",
                   child_device_ctx);
 
@@ -594,8 +568,6 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
                DPRINT_INFO(VMBUS_DRV, "child device (%p) registered",
                            &child_device_ctx->device);
 
-       DPRINT_EXIT(VMBUS_DRV);
-
        return ret;
 }
 
@@ -607,8 +579,6 @@ static void vmbus_child_device_unregister(struct hv_device *device_obj)
 {
        struct vm_device *device_ctx = to_vm_device(device_obj);
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)",
                    &device_ctx->device);
 
@@ -620,8 +590,6 @@ static void vmbus_child_device_unregister(struct hv_device *device_obj)
 
        DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered",
                    &device_ctx->device);
-
-       DPRINT_EXIT(VMBUS_DRV);
 }
 
 /*
@@ -629,9 +597,6 @@ static void vmbus_child_device_unregister(struct hv_device *device_obj)
  */
 static void vmbus_child_device_destroy(struct hv_device *device_obj)
 {
-       DPRINT_ENTER(VMBUS_DRV);
-
-       DPRINT_EXIT(VMBUS_DRV);
 }
 
 /*
@@ -646,8 +611,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
        struct vm_device *device_ctx = device_to_vm_device(device);
        int ret;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={"
                    "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
                    "%02x%02x%02x%02x%02x%02x%02x%02x}",
@@ -708,8 +671,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
        if (ret)
                return ret;
 
-       DPRINT_EXIT(VMBUS_DRV);
-
        return 0;
 }
 
@@ -722,8 +683,6 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
        struct driver_context *driver_ctx = driver_to_driver_context(driver);
        struct vm_device *device_ctx = device_to_vm_device(device);
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* We found our driver ? */
        if (memcmp(&device_ctx->class_id, &driver_ctx->class_id,
                   sizeof(struct hv_guid)) == 0) {
@@ -742,9 +701,6 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
 
                match = 1;
        }
-
-       DPRINT_EXIT(VMBUS_DRV);
-
        return match;
 }
 
@@ -759,8 +715,6 @@ static void vmbus_probe_failed_cb(struct work_struct *context)
 {
        struct vm_device *device_ctx = (struct vm_device *)context;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /*
         * Kick off the process of unregistering the device.
         * This will call vmbus_remove() and eventually vmbus_device_release()
@@ -768,7 +722,6 @@ static void vmbus_probe_failed_cb(struct work_struct *context)
        device_unregister(&device_ctx->device);
 
        /* put_device(&device_ctx->device); */
-       DPRINT_EXIT(VMBUS_DRV);
 }
 
 /*
@@ -782,8 +735,6 @@ static int vmbus_probe(struct device *child_device)
        struct vm_device *device_ctx =
                        device_to_vm_device(child_device);
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* Let the specific open-source driver handles the probe if it can */
        if (driver_ctx->probe) {
                ret = device_ctx->probe_error = driver_ctx->probe(child_device);
@@ -802,8 +753,6 @@ static int vmbus_probe(struct device *child_device)
                           child_device->driver->name);
                ret = -1;
        }
-
-       DPRINT_EXIT(VMBUS_DRV);
        return ret;
 }
 
@@ -815,15 +764,12 @@ static int vmbus_remove(struct device *child_device)
        int ret;
        struct driver_context *driver_ctx;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* Special case root bus device */
        if (child_device->parent == NULL) {
                /*
                 * No-op since it is statically defined and handle in
                 * vmbus_bus_exit()
                 */
-               DPRINT_EXIT(VMBUS_DRV);
                return 0;
        }
 
@@ -844,8 +790,6 @@ static int vmbus_remove(struct device *child_device)
                }
        }
 
-       DPRINT_EXIT(VMBUS_DRV);
-
        return 0;
 }
 
@@ -856,23 +800,18 @@ static void vmbus_shutdown(struct device *child_device)
 {
        struct driver_context *driver_ctx;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* Special case root bus device */
        if (child_device->parent == NULL) {
                /*
                 * No-op since it is statically defined and handle in
                 * vmbus_bus_exit()
                 */
-               DPRINT_EXIT(VMBUS_DRV);
                return;
        }
 
        /* The device may not be attached yet */
-       if (!child_device->driver) {
-               DPRINT_EXIT(VMBUS_DRV);
+       if (!child_device->driver)
                return;
-       }
 
        driver_ctx = driver_to_driver_context(child_device->driver);
 
@@ -880,8 +819,6 @@ static void vmbus_shutdown(struct device *child_device)
        if (driver_ctx->shutdown)
                driver_ctx->shutdown(child_device);
 
-       DPRINT_EXIT(VMBUS_DRV);
-
        return;
 }
 
@@ -890,13 +827,11 @@ static void vmbus_shutdown(struct device *child_device)
  */
 static void vmbus_bus_release(struct device *device)
 {
-       DPRINT_ENTER(VMBUS_DRV);
        /* FIXME */
        /* Empty release functions are a bug, or a major sign
         * of a problem design, this MUST BE FIXED! */
        dev_err(device, "%s needs to be fixed!\n", __func__);
        WARN_ON(1);
-       DPRINT_EXIT(VMBUS_DRV);
 }
 
 /*
@@ -906,15 +841,10 @@ static void vmbus_device_release(struct device *device)
 {
        struct vm_device *device_ctx = device_to_vm_device(device);
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* vmbus_child_device_destroy(&device_ctx->device_obj); */
        kfree(device_ctx);
 
        /* !!DO NOT REFERENCE device_ctx anymore at this point!! */
-       DPRINT_EXIT(VMBUS_DRV);
-
-       return;
 }
 
 /*
@@ -924,14 +854,10 @@ static void vmbus_msg_dpc(unsigned long data)
 {
        struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); */
 
        /* Call to bus driver to handle interrupt */
        vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base);
-
-       DPRINT_EXIT(VMBUS_DRV);
 }
 
 /*
@@ -941,14 +867,10 @@ static void vmbus_event_dpc(unsigned long data)
 {
        struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* ASSERT(vmbus_drv_obj->OnEventDpc != NULL); */
 
        /* Call to bus driver to handle interrupt */
        vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base);
-
-       DPRINT_EXIT(VMBUS_DRV);
 }
 
 static irqreturn_t vmbus_isr(int irq, void *dev_id)
@@ -956,8 +878,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
        struct vmbus_driver *vmbus_driver_obj = &g_vmbus_drv.drv_obj;
        int ret;
 
-       DPRINT_ENTER(VMBUS_DRV);
-
        /* ASSERT(vmbus_driver_obj->OnIsr != NULL); */
 
        /* Call to bus driver to handle interrupt */
@@ -971,10 +891,8 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
                if (test_bit(1, (unsigned long *)&ret))
                        tasklet_schedule(&g_vmbus_drv.event_dpc);
 
-               DPRINT_EXIT(VMBUS_DRV);
                return IRQ_HANDLED;
        } else {
-               DPRINT_EXIT(VMBUS_DRV);
                return IRQ_NONE;
        }
 }
@@ -994,10 +912,6 @@ MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
 
 static int __init vmbus_init(void)
 {
-       int ret = 0;
-
-       DPRINT_ENTER(VMBUS_DRV);
-
        DPRINT_INFO(VMBUS_DRV,
                "Vmbus initializing.... current log level 0x%x (%x,%x)",
                vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
@@ -1006,20 +920,13 @@ static int __init vmbus_init(void)
        if (!dmi_check_system(microsoft_hv_dmi_table))
                return -ENODEV;
 
-       ret = vmbus_bus_init(VmbusInitialize);
-
-       DPRINT_EXIT(VMBUS_DRV);
-       return ret;
+       return vmbus_bus_init(VmbusInitialize);
 }
 
 static void __exit vmbus_exit(void)
 {
-       DPRINT_ENTER(VMBUS_DRV);
-
        vmbus_bus_exit();
        /* Todo: it is used for loglevel, to be ported to new kernel. */
-       DPRINT_EXIT(VMBUS_DRV);
-       return;
 }
 
 /*
@@ -1028,7 +935,7 @@ static void __exit vmbus_exit(void)
  * installed and/or configured.  We don't do anything else with the table, but
  * it needs to be present.
  */
-const static struct pci_device_id microsoft_hv_pci_table[] = {
+static const struct pci_device_id microsoft_hv_pci_table[] = {
        { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
        { 0 }
 };
index e39dfc1705aaba2489f8afd33b007853f830cfec..cc6ecad4035ce05e72488acc75a7edae04af7a91 100644 (file)
@@ -44,7 +44,7 @@ which the raw data it self may be read back.
 applications it it useful to be able to capture data based on some
 external signal (trigger).  These triggers might be a data ready
 signal, a gpio line connected to some external system or an on
-processor periodic interrupt.  A single trigger many initialize data
+processor periodic interrupt.  A single trigger may initialize data
 capture or reading from a number of sensors.  These triggers are
 used in iio to fill software ring buffers acting in a very similar
 fashion to the hardware buffers described above.
index b0e62449c621aebe8439cfd505470bcbc06fbc7e..ed48815a916b37b1d5c5ffd2aca810b863276baf 100644 (file)
@@ -21,6 +21,7 @@ config IIO_RING_BUFFER
 if IIO_RING_BUFFER
 
 config IIO_SW_RING
+       select IIO_TRIGGER
        tristate "Industrial I/O lock free software ring"
        help
          Example software ring buffer implementation.  The design aim
@@ -44,6 +45,7 @@ source "drivers/staging/iio/adc/Kconfig"
 source "drivers/staging/iio/gyro/Kconfig"
 source "drivers/staging/iio/imu/Kconfig"
 source "drivers/staging/iio/light/Kconfig"
+source "drivers/staging/iio/magnetometer/Kconfig"
 
 source "drivers/staging/iio/trigger/Kconfig"
 
index 3502b39f0847e167ba0fc738956673d7d1577505..e909674920fc4924cfdd98a2c2b69ff2514b3645 100644 (file)
@@ -14,5 +14,5 @@ obj-y += adc/
 obj-y += gyro/
 obj-y += imu/
 obj-y += light/
-
-obj-y += trigger/
\ No newline at end of file
+obj-y += trigger/
+obj-y += magnetometer/
index 15da0c2bb784309de54afc36414086da8df0d346..898cba1c939f939299ac16ab3f8dc152662bf01d 100644 (file)
@@ -66,4 +66,4 @@ Documentation
 2) Some device require indvidual docs.
 
 Contact: Jonathan Cameron <jic23@cam.ac.uk>.
-Mailing list: LKML.
+Mailing list: linux-iio@vger.kernel.org
index b4e57d1bc87d0d9f6d588d8c10ddc4bd22b51c30..5926c03be1a5fddfb6723ba7c6ba36ded0f89b65 100644 (file)
@@ -4,29 +4,29 @@
 comment "Accelerometers"
 
 config ADIS16209
-       tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer"
-       depends on SPI
-       select IIO_TRIGGER if IIO_RING_BUFFER
-       select IIO_SW_RING if IIO_RING_BUFFER
-       help
-         Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer
-        and accelerometer.
+       tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer"
+       depends on SPI
+       select IIO_TRIGGER if IIO_RING_BUFFER
+       select IIO_SW_RING if IIO_RING_BUFFER
+       help
+         Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer
+         and accelerometer.
 
 config ADIS16220
-       tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices adis16220 programmable
-         digital vibration sensor.
+       tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices adis16220 programmable
+         digital vibration sensor.
 
 config ADIS16240
-       tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder"
-       depends on SPI
-       select IIO_TRIGGER if IIO_RING_BUFFER
-       select IIO_SW_RING if IIO_RING_BUFFER
-       help
-         Say yes here to build support for Analog Devices adis16240 programmable
-        impact Sensor and recorder.
+       tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder"
+       depends on SPI
+       select IIO_TRIGGER if IIO_RING_BUFFER
+       select IIO_SW_RING if IIO_RING_BUFFER
+       help
+         Say yes here to build support for Analog Devices adis16240 programmable
+         impact Sensor and recorder.
 
 config KXSD9
        tristate "Kionix KXSD9 Accelerometer Driver"
@@ -46,9 +46,9 @@ config LIS3L02DQ
          and an event interface via a character device.
 
 config SCA3000
-       depends on IIO_RING_BUFFER
-       depends on SPI
-       tristate "VTI SCA3000 series accelerometers"
-       help
-         Say yes here to build support for the VTI SCA3000 series of SPI
-        accelerometers. These devices use a hardware ring buffer.
\ No newline at end of file
+       depends on IIO_RING_BUFFER
+       depends on SPI
+       tristate "VTI SCA3000 series accelerometers"
+       help
+         Say yes here to build support for the VTI SCA3000 series of SPI
+         accelerometers. These devices use a hardware ring buffer.
index c34b13634c2d8e9abedd8c4f6770442fac29b48b..ff84703a16f6863a039c5354f8a8249c002c9792 100644 (file)
@@ -1,6 +1,7 @@
 #
 # Makefile for industrial I/O accelerometer drivers
 #
+
 adis16209-y             := adis16209_core.o
 adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o
 obj-$(CONFIG_ADIS16209) += adis16209.o
@@ -19,4 +20,4 @@ lis3l02dq-$(CONFIG_IIO_RING_BUFFER) += lis3l02dq_ring.o
 obj-$(CONFIG_LIS3L02DQ)        += lis3l02dq.o
 
 sca3000-y              := sca3000_core.o sca3000_ring.o
-obj-$(CONFIG_SCA3000)  += sca3000.o
\ No newline at end of file
+obj-$(CONFIG_SCA3000)  += sca3000.o
index 877fd2a4838060cfb261f2f029cf27eac2182539..4e97596620ef0ddf71091a3630a032729448956b 100644 (file)
  * struct adis16209_state - device instance specific data
  * @us:                        actual spi_device
  * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
- * @inter:             used to check if new interrupt has been triggered
  * @last_timestamp:    passing timestamp from th to bh of interrupt handler
  * @indio_dev:         industrial I/O device structure
  * @trig:              data ready trigger registered with iio
 struct adis16209_state {
        struct spi_device               *us;
        struct work_struct              work_trigger_to_ring;
-       struct iio_work_cont            work_cont_thresh;
        s64                             last_timestamp;
        struct iio_dev                  *indio_dev;
        struct iio_trigger              *trig;
@@ -129,16 +126,15 @@ struct adis16209_state {
 int adis16209_set_irq(struct device *dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
-enum adis16209_scan {
-       ADIS16209_SCAN_SUPPLY,
-       ADIS16209_SCAN_ACC_X,
-       ADIS16209_SCAN_ACC_Y,
-       ADIS16209_SCAN_AUX_ADC,
-       ADIS16209_SCAN_TEMP,
-       ADIS16209_SCAN_INCLI_X,
-       ADIS16209_SCAN_INCLI_Y,
-       ADIS16209_SCAN_ROT,
-};
+
+#define ADIS16209_SCAN_SUPPLY  0
+#define ADIS16209_SCAN_ACC_X   1
+#define ADIS16209_SCAN_ACC_Y   2
+#define ADIS16209_SCAN_AUX_ADC 3
+#define ADIS16209_SCAN_TEMP    4
+#define ADIS16209_SCAN_INCLI_X 5
+#define ADIS16209_SCAN_INCLI_Y 6
+#define ADIS16209_SCAN_ROT     7
 
 void adis16209_remove_trigger(struct iio_dev *indio_dev);
 int adis16209_probe_trigger(struct iio_dev *indio_dev);
@@ -150,8 +146,6 @@ ssize_t adis16209_read_data_from_ring(struct device *dev,
 int adis16209_configure_ring(struct iio_dev *indio_dev);
 void adis16209_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16209_initialize_ring(struct iio_ring_buffer *ring);
-void adis16209_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16209_remove_trigger(struct iio_dev *indio_dev)
@@ -180,14 +174,5 @@ static inline void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
 {
 }
 
-static inline int adis16209_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return 0;
-}
-
-static inline void adis16209_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16209_H_ */
index ac375c50f56fa9077f828eed0567127142c78dd7..6c6923f2eaa53bf41b17020009cffa0635ff3429 100644 (file)
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
-
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "accel.h"
 #include "inclinometer.h"
 #include "../gyro/gyro.h"
@@ -76,11 +77,13 @@ static int adis16209_spi_write_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
+                       .delay_usecs = 30,
                }, {
                        .tx_buf = st->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
+                       .delay_usecs = 30,
                },
        };
 
@@ -120,13 +123,13 @@ static int adis16209_spi_read_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 20,
+                       .delay_usecs = 30,
                }, {
                        .rx_buf = st->rx,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 20,
+                       .delay_usecs = 30,
                },
        };
 
@@ -518,7 +521,7 @@ static int __devinit adis16209_probe(struct spi_device *spi)
                goto error_unreg_ring_funcs;
        regdone = 1;
 
-       ret = adis16209_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
        if (ret) {
                printk(KERN_ERR "failed to initialize the ring\n");
                goto error_unreg_ring_funcs;
@@ -550,7 +553,7 @@ error_unregister_line:
        if (spi->irq)
                iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-       adis16209_uninitialize_ring(st->indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
        adis16209_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -579,7 +582,7 @@ static int adis16209_remove(struct spi_device *spi)
        if (spi->irq)
                iio_unregister_interrupt_line(indio_dev, 0);
 
-       adis16209_uninitialize_ring(indio_dev->ring);
+       iio_ring_buffer_unregister(indio_dev->ring);
        iio_device_unregister(indio_dev);
        adis16209_unconfigure_ring(indio_dev);
        kfree(st->tx);
index 533e285749107f2ee3e8808fd467c2cdab50581a..25fde659d09889c5d761cee172989f991095d106 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../trigger.h"
 #include "adis16209.h"
 
-/**
- * combine_8_to_16() utility function to munge to u8s into u16
- **/
-static inline u16 combine_8_to_16(u8 lower, u8 upper)
-{
-       u16 _lower = lower;
-       u16 _upper = upper;
-       return _lower | (_upper << 8);
-}
-
 static IIO_SCAN_EL_C(supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
                     ADIS16209_SUPPLY_OUT, NULL);
 static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, IIO_SIGNED(14),
@@ -67,10 +58,10 @@ static struct attribute_group adis16209_scan_el_group = {
  * adis16209_poll_func_th() top half interrupt handler called by trigger
  * @private_data:      iio_dev
  **/
-static void adis16209_poll_func_th(struct iio_dev *indio_dev)
+static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
        struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
-       st->last_timestamp = indio_dev->trig->timestamp;
+       st->last_timestamp = time;
        schedule_work(&st->work_trigger_to_ring);
 }
 
@@ -138,10 +129,9 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
 
        if (st->indio_dev->scan_count)
                if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++) {
-                               data[i] = combine_8_to_16(st->rx[i*2+1],
-                                                         st->rx[i*2]);
-                       }
+                       for (; i < st->indio_dev->scan_count; i++)
+                               data[i] = be16_to_cpup(
+                                       (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
        if (st->indio_dev->scan_timestamp)
@@ -157,50 +147,6 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
        return;
 }
 
-/* in these circumstances is it better to go with unaligned packing and
- * deal with the cost?*/
-static int adis16209_data_rdy_ring_preenable(struct iio_dev *indio_dev)
-{
-       size_t size;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-       /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
-               return -EINVAL;
-
-       if (indio_dev->ring->access.set_bpd) {
-               if (indio_dev->scan_timestamp)
-                       if (indio_dev->scan_count)
-                               /* Timestamp (aligned to s64) and data */
-                               size = (((indio_dev->scan_count * sizeof(s16))
-                                        + sizeof(s64) - 1)
-                                       & ~(sizeof(s64) - 1))
-                                       + sizeof(s64);
-                       else /* Timestamp only  */
-                               size = sizeof(s64);
-               else /* Data only */
-                       size = indio_dev->scan_count*sizeof(s16);
-               indio_dev->ring->access.set_bpd(indio_dev->ring, size);
-       }
-
-       return 0;
-}
-
-static int adis16209_data_rdy_ring_postenable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_attach_poll_func(indio_dev->trig,
-                                              indio_dev->pollfunc)
-               : 0;
-}
-
-static int adis16209_data_rdy_ring_predisable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_dettach_poll_func(indio_dev->trig,
-                                               indio_dev->pollfunc)
-               : 0;
-}
-
 void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
 {
        kfree(indio_dev->pollfunc);
@@ -235,18 +181,16 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
        indio_dev->ring = ring;
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
-       ring->preenable = &adis16209_data_rdy_ring_preenable;
-       ring->postenable = &adis16209_data_rdy_ring_postenable;
-       ring->predisable = &adis16209_data_rdy_ring_predisable;
+       ring->bpe = 2;
+       ring->preenable = &iio_sw_ring_preenable;
+       ring->postenable = &iio_triggered_ring_postenable;
+       ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
-               goto error_iio_sw_rb_free;;
-       }
-       indio_dev->pollfunc->poll_func_main = &adis16209_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
+       if (ret)
+               goto error_iio_sw_rb_free;
+
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
 
@@ -254,13 +198,3 @@ error_iio_sw_rb_free:
        iio_sw_rb_free(indio_dev->ring);
        return ret;
 }
-
-int adis16209_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16209_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-}
index 4a0507c9a13b13af340dca673aad1e693b5eb3b8..1487effa2e3007e61f85cb0536b9775339b87724 100644 (file)
@@ -23,8 +23,7 @@ static int adis16209_data_rdy_trig_poll(struct iio_dev *dev_info,
        struct adis16209_state *st = iio_dev_get_devdata(dev_info);
        struct iio_trigger *trig = st->trig;
 
-       trig->timestamp = timestamp;
-       iio_trigger_poll(trig);
+       iio_trigger_poll(trig, timestamp);
 
        return IRQ_HANDLED;
 }
@@ -83,14 +82,13 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev)
        struct adis16209_state *st = indio_dev->dev_data;
 
        st->trig = iio_allocate_trigger();
-       st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+       st->trig->name = kasprintf(GFP_KERNEL,
+                                  "adis16209-dev%d",
+                                  indio_dev->id);
        if (!st->trig->name) {
                ret = -ENOMEM;
                goto error_free_trig;
        }
-       snprintf((char *)st->trig->name,
-                IIO_TRIGGER_NAME_LENGTH,
-                "adis16209-dev%d", indio_dev->id);
        st->trig->dev.parent = &st->us->dev;
        st->trig->owner = THIS_MODULE;
        st->trig->private_data = st;
index 2abf4850b3735742c7a3b993597c0b9791721b85..7013314a9d7775c45a45c371e31c59b8683aab10 100644 (file)
  * struct adis16220_state - device instance specific data
  * @us:                        actual spi_device
  * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
  * @inter:             used to check if new interrupt has been triggered
  * @last_timestamp:    passing timestamp from th to bh of interrupt handler
  * @indio_dev:         industrial I/O device structure
index 6de439fd167572d40eeb81082e039121520ea1de..bb7d76539cd76c63bac5004538ba9fcabb86917a 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
-
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
@@ -72,13 +72,13 @@ static int adis16220_spi_write_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                }, {
                        .tx_buf = st->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                },
        };
 
@@ -118,13 +118,13 @@ static int adis16220_spi_read_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                }, {
                        .rx_buf = st->rx,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                },
        };
 
@@ -291,9 +291,9 @@ static int adis16220_check_status(struct device *dev)
        if (status & ADIS16220_DIAG_STAT_FLASH_UPT)
                dev_err(dev, "Flash update failed\n");
        if (status & ADIS16220_DIAG_STAT_POWER_HIGH)
-               dev_err(dev, "Power supply above 5.25V\n");
+               dev_err(dev, "Power supply above 3.625V\n");
        if (status & ADIS16220_DIAG_STAT_POWER_LOW)
-               dev_err(dev, "Power supply below 4.75V\n");
+               dev_err(dev, "Power supply below 3.15V\n");
 
 error_ret:
        return ret;
@@ -414,7 +414,7 @@ static ssize_t adis16220_capture_buffer_read(struct adis16220_state *st,
        return count;
 }
 
-static ssize_t adis16220_accel_bin_read(struct kobject *kobj,
+static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj,
                                        struct bin_attribute *attr,
                                        char *buf,
                                        loff_t off,
@@ -438,7 +438,7 @@ static struct bin_attribute accel_bin = {
        .size = ADIS16220_CAPTURE_SIZE,
 };
 
-static ssize_t adis16220_adc1_bin_read(struct kobject *kobj,
+static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj,
                                struct bin_attribute *attr,
                                char *buf, loff_t off,
                                size_t count)
@@ -461,7 +461,7 @@ static struct bin_attribute adc1_bin = {
        .size = ADIS16220_CAPTURE_SIZE,
 };
 
-static ssize_t adis16220_adc2_bin_read(struct kobject *kobj,
+static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj,
                                struct bin_attribute *attr,
                                char *buf, loff_t off,
                                size_t count)
index dcff43c75235a10343b10206162b095272791a6b..51a807dde27ce6041663aacd7a452751e5bb3a51 100644 (file)
  * struct adis16240_state - device instance specific data
  * @us:                        actual spi_device
  * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
  * @inter:             used to check if new interrupt has been triggered
  * @last_timestamp:    passing timestamp from th to bh of interrupt handler
  * @indio_dev:         industrial I/O device structure
 struct adis16240_state {
        struct spi_device               *us;
        struct work_struct              work_trigger_to_ring;
-       struct iio_work_cont            work_cont_thresh;
        s64                             last_timestamp;
        struct iio_dev                  *indio_dev;
        struct iio_trigger              *trig;
@@ -155,14 +153,12 @@ int adis16240_set_irq(struct device *dev, bool enable);
  * filling. This may change!
  */
 
-enum adis16240_scan {
-       ADIS16240_SCAN_SUPPLY,
-       ADIS16240_SCAN_ACC_X,
-       ADIS16240_SCAN_ACC_Y,
-       ADIS16240_SCAN_ACC_Z,
-       ADIS16240_SCAN_AUX_ADC,
-       ADIS16240_SCAN_TEMP,
-};
+#define ADIS16240_SCAN_SUPPLY  0
+#define ADIS16240_SCAN_ACC_X   1
+#define ADIS16240_SCAN_ACC_Y   2
+#define ADIS16240_SCAN_ACC_Z   3
+#define ADIS16240_SCAN_AUX_ADC 4
+#define ADIS16240_SCAN_TEMP    5
 
 void adis16240_remove_trigger(struct iio_dev *indio_dev);
 int adis16240_probe_trigger(struct iio_dev *indio_dev);
@@ -175,8 +171,6 @@ ssize_t adis16240_read_data_from_ring(struct device *dev,
 int adis16240_configure_ring(struct iio_dev *indio_dev);
 void adis16240_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16240_initialize_ring(struct iio_ring_buffer *ring);
-void adis16240_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16240_remove_trigger(struct iio_dev *indio_dev)
@@ -205,14 +199,5 @@ static inline void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
 {
 }
 
-static inline int adis16240_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return 0;
-}
-
-static inline void adis16240_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16240_H_ */
index 54fd6d77412fa032dd93ed312996cd96132c5506..3e9531dd0000363a9c5796243a30a1ed9a5f3bef 100644 (file)
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
-
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "accel.h"
 #include "../adc/adc.h"
 
@@ -74,13 +75,13 @@ static int adis16240_spi_write_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                }, {
                        .tx_buf = st->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                },
        };
 
@@ -120,13 +121,13 @@ static int adis16240_spi_read_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                }, {
                        .rx_buf = st->rx,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                },
        };
 
@@ -502,7 +503,7 @@ static int __devinit adis16240_probe(struct spi_device *spi)
                goto error_unreg_ring_funcs;
        regdone = 1;
 
-       ret = adis16240_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
        if (ret) {
                printk(KERN_ERR "failed to initialize the ring\n");
                goto error_unreg_ring_funcs;
@@ -534,7 +535,7 @@ error_unregister_line:
        if (spi->irq)
                iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-       adis16240_uninitialize_ring(st->indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
        adis16240_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -563,7 +564,7 @@ static int adis16240_remove(struct spi_device *spi)
        if (spi->irq)
                iio_unregister_interrupt_line(indio_dev, 0);
 
-       adis16240_uninitialize_ring(indio_dev->ring);
+       iio_ring_buffer_unregister(indio_dev->ring);
        iio_device_unregister(indio_dev);
        adis16240_unconfigure_ring(indio_dev);
        kfree(st->tx);
index 26b677bd84c0a6214f0530802222dae579797816..cd69a2e2bb9a611a8baf53a1496811abb50fc964 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../trigger.h"
 #include "adis16240.h"
 
-/**
- * combine_8_to_16() utility function to munge to u8s into u16
- **/
-static inline u16 combine_8_to_16(u8 lower, u8 upper)
-{
-       u16 _lower = lower;
-       u16 _upper = upper;
-       return _lower | (_upper << 8);
-}
-
 static IIO_SCAN_EL_C(supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
                ADIS16240_SUPPLY_OUT, NULL);
 static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, IIO_SIGNED(10),
@@ -61,10 +52,10 @@ static struct attribute_group adis16240_scan_el_group = {
  * adis16240_poll_func_th() top half interrupt handler called by trigger
  * @private_data:      iio_dev
  **/
-static void adis16240_poll_func_th(struct iio_dev *indio_dev)
+static void adis16240_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
        struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
-       st->last_timestamp = indio_dev->trig->timestamp;
+       st->last_timestamp = time;
        schedule_work(&st->work_trigger_to_ring);
 }
 
@@ -130,10 +121,9 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
 
        if (st->indio_dev->scan_count)
                if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++) {
-                               data[i] = combine_8_to_16(st->rx[i*2+1],
-                                               st->rx[i*2]);
-                       }
+                       for (; i < st->indio_dev->scan_count; i++)
+                               data[i] = be16_to_cpup(
+                                       (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
        if (st->indio_dev->scan_timestamp)
@@ -149,48 +139,6 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
        return;
 }
 
-static int adis16240_data_rdy_ring_preenable(struct iio_dev *indio_dev)
-{
-       size_t size;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-       /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
-               return -EINVAL;
-
-       if (indio_dev->ring->access.set_bpd) {
-               if (indio_dev->scan_timestamp)
-                       if (indio_dev->scan_count)
-                               /* Timestamp (aligned sizeof(s64) and data */
-                               size = (((indio_dev->scan_count * sizeof(s16))
-                                        + sizeof(s64) - 1)
-                                       & ~(sizeof(s64) - 1))
-                                       + sizeof(s64);
-                       else /* Timestamp only  */
-                               size = sizeof(s64);
-               else /* Data only */
-                       size = indio_dev->scan_count*sizeof(s16);
-               indio_dev->ring->access.set_bpd(indio_dev->ring, size);
-       }
-
-       return 0;
-}
-
-static int adis16240_data_rdy_ring_postenable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_attach_poll_func(indio_dev->trig,
-                               indio_dev->pollfunc)
-               : 0;
-}
-
-static int adis16240_data_rdy_ring_predisable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_dettach_poll_func(indio_dev->trig,
-                               indio_dev->pollfunc)
-               : 0;
-}
-
 void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
 {
        kfree(indio_dev->pollfunc);
@@ -223,18 +171,16 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
        indio_dev->ring = ring;
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
-       ring->preenable = &adis16240_data_rdy_ring_preenable;
-       ring->postenable = &adis16240_data_rdy_ring_postenable;
-       ring->predisable = &adis16240_data_rdy_ring_predisable;
+       ring->bpe = 2;
+       ring->preenable = &iio_sw_ring_preenable;
+       ring->postenable = &iio_triggered_ring_postenable;
+       ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
-               goto error_iio_sw_rb_free;;
-       }
-       indio_dev->pollfunc->poll_func_main = &adis16240_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
+       if (ret)
+               goto error_iio_sw_rb_free;
+
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
 
@@ -243,12 +189,3 @@ error_iio_sw_rb_free:
        return ret;
 }
 
-int adis16240_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16240_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-}
index df1312e17f4b588e2247df98e4c42d02d4d4f5d5..2ba71fd73a47694a1b765e1469157dbcd5058a1a 100644 (file)
@@ -23,8 +23,7 @@ static int adis16240_data_rdy_trig_poll(struct iio_dev *dev_info,
        struct adis16240_state *st = iio_dev_get_devdata(dev_info);
        struct iio_trigger *trig = st->trig;
 
-       trig->timestamp = timestamp;
-       iio_trigger_poll(trig);
+       iio_trigger_poll(trig, timestamp);
 
        return IRQ_HANDLED;
 }
@@ -83,14 +82,13 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev)
        struct adis16240_state *st = indio_dev->dev_data;
 
        st->trig = iio_allocate_trigger();
-       st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+       st->trig->name = kasprintf(GFP_KERNEL,
+                                  "adis16240-dev%d",
+                                  indio_dev->id);
        if (!st->trig->name) {
                ret = -ENOMEM;
                goto error_free_trig;
        }
-       snprintf((char *)st->trig->name,
-                IIO_TRIGGER_NAME_LENGTH,
-                "adis16240-dev%d", indio_dev->id);
        st->trig->dev.parent = &st->us->dev;
        st->trig->owner = THIS_MODULE;
        st->trig->private_data = st;
index ae7ffe114fc585e11a08a410ff5e5005a41b44e8..79f57950ebeb00c2613c11370ddbf5856729d4d7 100644 (file)
  *             heavily optimized ring buffer access function.
  */
 
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/fs.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
-#include <linux/rtc.h>
-#include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/string.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
index e76a97937a360f364408e1487b2d07ef8e7075e4..6e730553fca8c947ec8f02c8f3ce2ecc8be35386 100644 (file)
@@ -148,30 +148,31 @@ Form of high byte dependant on justification set in ctrl reg */
 #define LIS3L02DQ_MAX_RX 12
 /**
  * struct lis3l02dq_state - device instance specific data
+ * @helper:            data and func pointer allowing generic functions
  * @us:                        actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
+ * @work_thresh:       bh for threshold events
+ * @thresh_timestamp:  timestamp for threshold interrupts.
  * @inter:             used to check if new interrupt has been triggered
- * @last_timestamp:    passing timestamp from th to bh of interrupt handler
- * @indio_dev:         industrial I/O device structure
  * @trig:              data ready trigger registered with iio
  * @tx:                        transmit buffer
  * @rx:                        recieve buffer
  * @buf_lock:          mutex to protect tx and rx
  **/
 struct lis3l02dq_state {
+       struct iio_sw_ring_helper_state help;
        struct spi_device               *us;
-       struct work_struct              work_trigger_to_ring;
-       struct iio_work_cont            work_cont_thresh;
+       struct work_struct              work_thresh;
+       s64                             thresh_timestamp;
        bool                            inter;
-       s64                             last_timestamp;
-       struct iio_dev                  *indio_dev;
        struct iio_trigger              *trig;
        u8                              *tx;
        u8                              *rx;
        struct mutex                    buf_lock;
 };
 
+#define lis3l02dq_h_to_s(_h)                           \
+       container_of(_h, struct lis3l02dq_state, help)
+
 int lis3l02dq_spi_read_reg_8(struct device *dev,
                             u8 reg_address,
                             u8 *val);
@@ -195,15 +196,15 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev);
 void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev);
 
-int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring);
-void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
-static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) {};
+static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
+{
+}
 static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 {
        return 0;
-};
+}
 
 static inline ssize_t
 lis3l02dq_read_accel_from_ring(struct device *dev,
@@ -211,18 +212,14 @@ lis3l02dq_read_accel_from_ring(struct device *dev,
                               char *buf)
 {
        return 0;
-};
+}
 
 static int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 {
        return 0;
-};
+}
 static inline void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
-{};
-static inline int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring)
 {
-       return 0;
-};
-static inline void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring) {};
+}
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_LIS3L02DQ_H_ */
index 6b5577d7d8de742caf73627abfc39447c08edb52..0ee9337375450c24d4ef7372532941d6a8bb9a75 100644 (file)
@@ -27,6 +27,9 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
+#include "../ring_sw.h"
+
 #include "accel.h"
 
 #include "lis3l02dq.h"
@@ -47,7 +50,9 @@ int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
        int ret;
        struct spi_message msg;
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+       struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+
        struct spi_transfer xfer = {
                .tx_buf = st->tx,
                .rx_buf = st->rx,
@@ -82,7 +87,9 @@ int lis3l02dq_spi_write_reg_8(struct device *dev,
        int ret;
        struct spi_message msg;
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+       struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
        struct spi_transfer xfer = {
                .tx_buf = st->tx,
                .bits_per_word = 8,
@@ -96,7 +103,7 @@ int lis3l02dq_spi_write_reg_8(struct device *dev,
 
        spi_message_init(&msg);
        spi_message_add_tail(&xfer, &msg);
-       ret =  spi_sync(st->us, &msg);
+       ret = spi_sync(st->us, &msg);
        mutex_unlock(&st->buf_lock);
 
        return ret;
@@ -116,7 +123,9 @@ static int lis3l02dq_spi_write_reg_s16(struct device *dev,
        int ret;
        struct spi_message msg;
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+       struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
        struct spi_transfer xfers[] = { {
                        .tx_buf = st->tx,
                        .bits_per_word = 8,
@@ -158,7 +167,9 @@ static int lis3l02dq_spi_read_reg_s16(struct device *dev,
 {
        struct spi_message msg;
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+       struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
        int ret;
        struct spi_transfer xfers[] = { {
                        .tx_buf = st->tx,
@@ -411,7 +422,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 
        val = LIS3L02DQ_DEFAULT_CTRL1;
        /* Write suitable defaults to ctrl1 */
-       ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+       ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
                                        LIS3L02DQ_REG_CTRL_1_ADDR,
                                        &val);
        if (ret) {
@@ -419,7 +430,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
                goto err_ret;
        }
        /* Repeat as sometimes doesn't work first time?*/
-       ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+       ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
                                        LIS3L02DQ_REG_CTRL_1_ADDR,
                                        &val);
        if (ret) {
@@ -429,17 +440,17 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 
        /* Read back to check this has worked acts as loose test of correct
         * chip */
-       ret = lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+       ret = lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
                                       LIS3L02DQ_REG_CTRL_1_ADDR,
                                       &valtest);
        if (ret || (valtest != val)) {
-               dev_err(&st->indio_dev->dev, "device not playing ball");
+               dev_err(&st->help.indio_dev->dev, "device not playing ball");
                ret = -EINVAL;
                goto err_ret;
        }
 
        val = LIS3L02DQ_DEFAULT_CTRL2;
-       ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+       ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
                                        LIS3L02DQ_REG_CTRL_2_ADDR,
                                        &val);
        if (ret) {
@@ -448,7 +459,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
        }
 
        val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
-       ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+       ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
                                        LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
                                        &val);
        if (ret)
@@ -524,8 +535,7 @@ static ssize_t lis3l02dq_read_interrupt_config(struct device *dev,
                                       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
                                       (u8 *)&val);
 
-       return ret ? ret : sprintf(buf, "%d\n",
-                                  (val & this_attr->mask) ? 1 : 0);;
+       return ret ? ret : sprintf(buf, "%d\n", !!(val & this_attr->mask));
 }
 
 static ssize_t lis3l02dq_write_interrupt_config(struct device *dev,
@@ -595,16 +605,18 @@ error_mutex_unlock:
 }
 
 
-static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info,
+static int lis3l02dq_thresh_handler_th(struct iio_dev *indio_dev,
                                       int index,
                                       s64 timestamp,
                                       int no_test)
 {
-       struct lis3l02dq_state *st = dev_info->dev_data;
+       struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
        /* Stash the timestamp somewhere convenient for the bh */
-       st->last_timestamp = timestamp;
-       schedule_work(&st->work_cont_thresh.ws);
+       st->thresh_timestamp = timestamp;
+       schedule_work(&st->work_thresh);
 
        return 0;
 }
@@ -615,48 +627,49 @@ static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info,
  */
 static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 {
-       struct iio_work_cont *wc
-               = container_of(work_s, struct iio_work_cont, ws);
-       struct lis3l02dq_state *st = wc->st;
+       struct lis3l02dq_state *st
+              = container_of(work_s,
+                      struct lis3l02dq_state, work_thresh);
+
        u8 t;
 
-       lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+       lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
                                 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
                                 &t);
 
        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
-               iio_push_event(st->indio_dev, 0,
+               iio_push_event(st->help.indio_dev, 0,
                               IIO_EVENT_CODE_ACCEL_Z_HIGH,
-                              st->last_timestamp);
+                              st->thresh_timestamp);
 
        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
-               iio_push_event(st->indio_dev, 0,
+               iio_push_event(st->help.indio_dev, 0,
                               IIO_EVENT_CODE_ACCEL_Z_LOW,
-                              st->last_timestamp);
+                              st->thresh_timestamp);
 
        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
-               iio_push_event(st->indio_dev, 0,
+               iio_push_event(st->help.indio_dev, 0,
                               IIO_EVENT_CODE_ACCEL_Y_HIGH,
-                              st->last_timestamp);
+                              st->thresh_timestamp);
 
        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
-               iio_push_event(st->indio_dev, 0,
+               iio_push_event(st->help.indio_dev, 0,
                               IIO_EVENT_CODE_ACCEL_Y_LOW,
-                              st->last_timestamp);
+                              st->thresh_timestamp);
 
        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
-               iio_push_event(st->indio_dev, 0,
+               iio_push_event(st->help.indio_dev, 0,
                               IIO_EVENT_CODE_ACCEL_X_HIGH,
-                              st->last_timestamp);
+                              st->thresh_timestamp);
 
        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
-               iio_push_event(st->indio_dev, 0,
+               iio_push_event(st->help.indio_dev, 0,
                               IIO_EVENT_CODE_ACCEL_X_LOW,
-                              st->last_timestamp);
+                              st->thresh_timestamp);
        /* reenable the irq */
        enable_irq(st->us->irq);
        /* Ack and allow for new interrupts */
-       lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+       lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
                                 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
                                 &t);
 
@@ -750,6 +763,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
                ret =  -ENOMEM;
                goto error_ret;
        }
+       INIT_WORK(&st->work_thresh, lis3l02dq_thresh_handler_bh_no_check);
        /* this is only used tor removal purposes */
        spi_set_drvdata(spi, st);
 
@@ -767,56 +781,46 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
        st->us = spi;
        mutex_init(&st->buf_lock);
        /* setup the industrialio driver allocated elements */
-       st->indio_dev = iio_allocate_device();
-       if (st->indio_dev == NULL) {
+       st->help.indio_dev = iio_allocate_device();
+       if (st->help.indio_dev == NULL) {
                ret = -ENOMEM;
                goto error_free_tx;
        }
 
-       st->indio_dev->dev.parent = &spi->dev;
-       st->indio_dev->num_interrupt_lines = 1;
-       st->indio_dev->event_attrs = &lis3l02dq_event_attribute_group;
-       st->indio_dev->attrs = &lis3l02dq_attribute_group;
-       st->indio_dev->dev_data = (void *)(st);
-       st->indio_dev->driver_module = THIS_MODULE;
-       st->indio_dev->modes = INDIO_DIRECT_MODE;
+       st->help.indio_dev->dev.parent = &spi->dev;
+       st->help.indio_dev->num_interrupt_lines = 1;
+       st->help.indio_dev->event_attrs = &lis3l02dq_event_attribute_group;
+       st->help.indio_dev->attrs = &lis3l02dq_attribute_group;
+       st->help.indio_dev->dev_data = (void *)(&st->help);
+       st->help.indio_dev->driver_module = THIS_MODULE;
+       st->help.indio_dev->modes = INDIO_DIRECT_MODE;
 
-       ret = lis3l02dq_configure_ring(st->indio_dev);
+       ret = lis3l02dq_configure_ring(st->help.indio_dev);
        if (ret)
                goto error_free_dev;
 
-       ret = iio_device_register(st->indio_dev);
+       ret = iio_device_register(st->help.indio_dev);
        if (ret)
                goto error_unreg_ring_funcs;
        regdone = 1;
 
-       ret = lis3l02dq_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->help.indio_dev->ring, 0);
        if (ret) {
                printk(KERN_ERR "failed to initialize the ring\n");
                goto error_unreg_ring_funcs;
        }
 
        if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-               /* This is a little unusual, in that the device seems
-                  to need a full read of the interrupt source reg before
-                  the interrupt will reset.
-                  Hence the two handlers are the same */
-               iio_init_work_cont(&st->work_cont_thresh,
-                                  lis3l02dq_thresh_handler_bh_no_check,
-                                  lis3l02dq_thresh_handler_bh_no_check,
-                                  LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
-                                  0,
-                                  st);
                st->inter = 0;
                ret = iio_register_interrupt_line(spi->irq,
-                                                 st->indio_dev,
+                                                 st->help.indio_dev,
                                                  0,
                                                  IRQF_TRIGGER_RISING,
                                                  "lis3l02dq");
                if (ret)
                        goto error_uninitialize_ring;
 
-               ret = lis3l02dq_probe_trigger(st->indio_dev);
+               ret = lis3l02dq_probe_trigger(st->help.indio_dev);
                if (ret)
                        goto error_unregister_line;
        }
@@ -828,20 +832,20 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
        return 0;
 
 error_remove_trigger:
-       if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-               lis3l02dq_remove_trigger(st->indio_dev);
+       if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
+               lis3l02dq_remove_trigger(st->help.indio_dev);
 error_unregister_line:
-       if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-               iio_unregister_interrupt_line(st->indio_dev, 0);
+       if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
+               iio_unregister_interrupt_line(st->help.indio_dev, 0);
 error_uninitialize_ring:
-       lis3l02dq_uninitialize_ring(st->indio_dev->ring);
+       iio_ring_buffer_unregister(st->help.indio_dev->ring);
 error_unreg_ring_funcs:
-       lis3l02dq_unconfigure_ring(st->indio_dev);
+       lis3l02dq_unconfigure_ring(st->help.indio_dev);
 error_free_dev:
        if (regdone)
-               iio_device_unregister(st->indio_dev);
+               iio_device_unregister(st->help.indio_dev);
        else
-               iio_free_device(st->indio_dev);
+               iio_free_device(st->help.indio_dev);
 error_free_tx:
        kfree(st->tx);
 error_free_rx:
@@ -856,7 +860,9 @@ error_ret:
 static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 {
        int ret;
-       struct lis3l02dq_state *st = indio_dev->dev_data;
+       struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
        u8 val = 0;
 
        mutex_lock(&indio_dev->mlock);
@@ -883,7 +889,7 @@ static int lis3l02dq_remove(struct spi_device *spi)
 {
        int ret;
        struct lis3l02dq_state *st = spi_get_drvdata(spi);
-       struct iio_dev *indio_dev = st->indio_dev;
+       struct iio_dev *indio_dev = st->help.indio_dev;
 
        ret = lis3l02dq_stop_device(indio_dev);
        if (ret)
@@ -895,7 +901,7 @@ static int lis3l02dq_remove(struct spi_device *spi)
        if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
                iio_unregister_interrupt_line(indio_dev, 0);
 
-       lis3l02dq_uninitialize_ring(indio_dev->ring);
+       iio_ring_buffer_unregister(indio_dev->ring);
        lis3l02dq_unconfigure_ring(indio_dev);
        iio_device_unregister(indio_dev);
        kfree(st->tx);
index e4e202e6cb3a94bd84d4ea471cbb2762918c8443..a960a8ff3c40bc48d001a367371e9cc30ebe7fdc 100644 (file)
@@ -103,13 +103,15 @@ static struct attribute_group lis3l02dq_scan_el_group = {
  * lis3l02dq_poll_func_th() top half interrupt handler called by trigger
  * @private_data:      iio_dev
  **/
-static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev)
+static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
-  struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
-       st->last_timestamp = indio_dev->trig->timestamp;
-       schedule_work(&st->work_trigger_to_ring);
-       /* Indicate that this interrupt is being handled */
+       struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+       /* in this case we need to slightly extend the helper function */
+       iio_sw_poll_func_th(indio_dev, time);
 
+       /* Indicate that this interrupt is being handled */
        /* Technically this is trigger related, but without this
         * handler running there is currently now way for the interrupt
         * to clear.
@@ -120,16 +122,16 @@ static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev)
 /**
  * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
  **/
-static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *dev_info,
+static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *indio_dev,
                                       int index,
                                       s64 timestamp,
                                       int no_test)
 {
-       struct lis3l02dq_state *st = iio_dev_get_devdata(dev_info);
-       struct iio_trigger *trig = st->trig;
+       struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-       trig->timestamp = timestamp;
-       iio_trigger_poll(trig);
+       iio_trigger_poll(st->trig, timestamp);
 
        return IRQ_HANDLED;
 }
@@ -213,7 +215,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
        struct spi_message msg;
        int ret, i, j = 0;
 
-       xfers = kzalloc((st->indio_dev->scan_count) * 2
+       xfers = kzalloc((st->help.indio_dev->scan_count) * 2
                        * sizeof(*xfers), GFP_KERNEL);
        if (!xfers)
                return -ENOMEM;
@@ -221,7 +223,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
        mutex_lock(&st->buf_lock);
 
        for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
-               if (st->indio_dev->scan_mask & (1 << i)) {
+               if (st->help.indio_dev->scan_mask & (1 << i)) {
                        /* lower byte */
                        xfers[j].tx_buf = st->tx + 2*j;
                        st->tx[2*j] = read_all_tx_array[i*4];
@@ -249,7 +251,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
         * values in alternate bytes
         */
        spi_message_init(&msg);
-       for (j = 0; j < st->indio_dev->scan_count * 2; j++)
+       for (j = 0; j < st->help.indio_dev->scan_count * 2; j++)
                spi_message_add_tail(&xfers[j], &msg);
 
        ret = spi_sync(st->us, &msg);
@@ -259,102 +261,37 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
        return ret;
 }
 
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
 static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s)
 {
-       struct lis3l02dq_state *st
-               = container_of(work_s, struct lis3l02dq_state,
-                              work_trigger_to_ring);
-
-       u8 *rx_array;
-       int i = 0;
-       u16 *data;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bpd(st->indio_dev->ring);
-
-       data = kmalloc(datasize , GFP_KERNEL);
-       if (data == NULL) {
-               dev_err(&st->us->dev, "memory alloc failed in ring bh");
-               return;
-       }
-       /* Due to interleaved nature of transmission this buffer must be
-        * twice the number of bytes, or 4 times the number of channels
-        */
-       rx_array = kmalloc(4 * (st->indio_dev->scan_count), GFP_KERNEL);
-       if (rx_array == NULL) {
-               dev_err(&st->us->dev, "memory alloc failed in ring bh");
-               kfree(data);
-               return;
-       }
+       struct iio_sw_ring_helper_state *h
+               = container_of(work_s, struct iio_sw_ring_helper_state,
+                       work_trigger_to_ring);
+       struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-       /* whilst trigger specific, if this read does nto occur the data
-          ready interrupt will not be cleared.  Need to add a mechanism
-          to provide a dummy read function if this is not triggering on
-          the data ready function but something else is.
-       */
        st->inter = 0;
-
-       if (st->indio_dev->scan_count)
-               if (lis3l02dq_read_all(st, rx_array) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++)
-                               data[i] = combine_8_to_16(rx_array[i*4+1],
-                                                         rx_array[i*4+3]);
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
-               *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
-
-       st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-                                           (u8 *)data,
-                                           st->last_timestamp);
-
-       iio_trigger_notify_done(st->indio_dev->trig);
-       kfree(rx_array);
-       kfree(data);
-
-       return;
-}
-/* in these circumstances is it better to go with unaligned packing and
- * deal with the cost?*/
-static int lis3l02dq_data_rdy_ring_preenable(struct iio_dev *indio_dev)
-{
-       size_t size;
-       /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
-               return -EINVAL;
-
-       if (indio_dev->ring->access.set_bpd) {
-               if (indio_dev->scan_timestamp)
-                       if (indio_dev->scan_count) /* Timestamp and data */
-                               size = 2*sizeof(s64);
-                       else /* Timestamp only  */
-                               size = sizeof(s64);
-               else /* Data only */
-                       size = indio_dev->scan_count*sizeof(s16);
-               indio_dev->ring->access.set_bpd(indio_dev->ring, size);
-       }
-
-       return 0;
+       iio_sw_trigger_bh_to_ring(work_s);
 }
 
-static int lis3l02dq_data_rdy_ring_postenable(struct iio_dev *indio_dev)
+static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
+                               u8 *buf)
 {
-       return indio_dev->trig
-               ? iio_trigger_attach_poll_func(indio_dev->trig,
-                                              indio_dev->pollfunc)
-               : 0;
-}
+       int ret, i;
+       u8 *rx_array ;
+       s16 *data = (s16 *)buf;
 
-static int lis3l02dq_data_rdy_ring_predisable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_dettach_poll_func(indio_dev->trig,
-                                               indio_dev->pollfunc)
-               : 0;
-}
+       rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
+       if (rx_array == NULL)
+               return -ENOMEM;
+       ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
+       if (ret < 0)
+               return ret;
+       for (i = 0; i < h->indio_dev->scan_count; i++)
+               data[i] = combine_8_to_16(rx_array[i*4+1],
+                                       rx_array[i*4+3]);
+       kfree(rx_array);
 
+       return i*sizeof(data[0]);
+}
 
 /* Caller responsible for locking as necessary. */
 static int
@@ -427,7 +364,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
        struct lis3l02dq_state *st = trig->private_data;
        int ret = 0;
        u8 t;
-       __lis3l02dq_write_data_ready_config(&st->indio_dev->dev,
+       __lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev,
                                            &iio_event_data_rdy_trig,
                                            state);
        if (state == false) {
@@ -437,7 +374,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
                /* Clear any outstanding ready events */
                ret = lis3l02dq_read_all(st, NULL);
        }
-       lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+       lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
                                 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
                                 &t);
        return ret;
@@ -495,14 +432,14 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
        if (!state->trig)
                return -ENOMEM;
 
-       state->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+       state->trig->name = kasprintf(GFP_KERNEL,
+                                     "lis3l02dq-dev%d",
+                                     indio_dev->id);
        if (!state->trig->name) {
                ret = -ENOMEM;
                goto error_free_trig;
        }
-       snprintf((char *)state->trig->name,
-                IIO_TRIGGER_NAME_LENGTH,
-                "lis3l02dq-dev%d", indio_dev->id);
+
        state->trig->dev.parent = &state->us->dev;
        state->trig->owner = THIS_MODULE;
        state->trig->private_data = state;
@@ -540,12 +477,12 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
 
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 {
-       int ret = 0;
-       struct lis3l02dq_state *st = indio_dev->dev_data;
-       struct iio_ring_buffer *ring;
-       INIT_WORK(&st->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
-       /* Set default scan mode */
+       int ret;
+       struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
 
+       INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
+       /* Set default scan mode */
+       h->get_ring_element = &lis3l02dq_get_ring_element;
        iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
        iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
        iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
@@ -553,26 +490,21 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 
        indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
 
-       ring = iio_sw_rb_allocate(indio_dev);
-       if (!ring) {
-               ret = -ENOMEM;
-               return ret;
-       }
-       indio_dev->ring = ring;
+       indio_dev->ring = iio_sw_rb_allocate(indio_dev);
+       if (!indio_dev->ring)
+               return -ENOMEM;
+
        /* Effectively select the ring buffer implementation */
-       iio_ring_sw_register_funcs(&ring->access);
-       ring->preenable = &lis3l02dq_data_rdy_ring_preenable;
-       ring->postenable = &lis3l02dq_data_rdy_ring_postenable;
-       ring->predisable = &lis3l02dq_data_rdy_ring_predisable;
-       ring->owner = THIS_MODULE;
-
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
+       iio_ring_sw_register_funcs(&indio_dev->ring->access);
+       indio_dev->ring->bpe = 2;
+       indio_dev->ring->preenable = &iio_sw_ring_preenable;
+       indio_dev->ring->postenable = &iio_triggered_ring_postenable;
+       indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+       indio_dev->ring->owner = THIS_MODULE;
+
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
+       if (ret)
                goto error_iio_sw_rb_free;;
-       }
-       indio_dev->pollfunc->poll_func_main = &lis3l02dq_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
 
@@ -580,23 +512,3 @@ error_iio_sw_rb_free:
        iio_sw_rb_free(indio_dev->ring);
        return ret;
 }
-
-int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-}
-
-void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-}
-
-int lis3l02dq_set_ring_length(struct iio_dev *indio_dev, int length)
-{
-       /* Set sensible defaults for the ring buffer */
-       if (indio_dev->ring->access.set_length)
-               return indio_dev->ring->access.set_length(indio_dev->ring, 500);
-       return 0;
-}
-
-
index e5321999b263f264b40a5051429753859061eca7..09d9470bb9a0ba9c4af23da13e2857fa1f3182bd 100644 (file)
@@ -242,7 +242,7 @@ static inline int sca3000_11bit_convert(uint8_t msb, uint8_t lsb)
        val |= (val & (1 << 12)) ? 0xE000 : 0;
 
        return val;
-};
+}
 
 static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb)
 {
@@ -253,7 +253,7 @@ static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb)
        val |= (val & (1 << 12)) ? 0xE000 : 0;
 
        return val;
-};
+}
 
 
 #ifdef CONFIG_IIO_RING_BUFFER
@@ -286,15 +286,19 @@ void sca3000_unconfigure_ring(struct iio_dev *indio_dev);
 void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring);
 
 #else
-static inline void sca3000_register_ring_funcs(struct iio_dev *indio_dev) {};
+static inline void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
+{
+}
 
 static inline
 int sca3000_register_ring_access_and_init(struct iio_dev *indio_dev)
 {
        return 0;
-};
+}
 
-static inline void sca3000_ring_int_process(u8 val, void *ring) {};
+static inline void sca3000_ring_int_process(u8 val, void *ring)
+{
+}
 
 #endif
 
index d4f82c39f33514dbdc7848f14461cdadf7dc9ed8..b78b6b66ffe0c6b25102a8c151fd32280a840d42 100644 (file)
@@ -387,7 +387,7 @@ sca3000_show_available_measurement_modes(struct device *dev,
        case SCA3000_OP_MODE_BYPASS:
                len += sprintf(buf + len, ", 1 - bypass mode");
                break;
-       };
+       }
        switch (st->info->option_mode_2) {
        case SCA3000_OP_MODE_WIDE:
                len += sprintf(buf + len, ", 2 - wide mode");
@@ -433,7 +433,7 @@ sca3000_show_measurement_mode(struct device *dev,
                case SCA3000_OP_MODE_BYPASS:
                        len += sprintf(buf + len, "1 - bypass mode\n");
                        break;
-               };
+               }
                break;
        case SCA3000_MEAS_MODE_OP_2:
                switch (st->info->option_mode_2) {
@@ -442,7 +442,7 @@ sca3000_show_measurement_mode(struct device *dev,
                        break;
                }
                break;
-       };
+       }
 
 error_ret:
        mutex_unlock(&st->lock);
@@ -559,7 +559,7 @@ static ssize_t sca3000_read_av_freq(struct device *dev,
                               st->info->option_mode_2_freq/2,
                               st->info->option_mode_2_freq/4);
                break;
-       };
+       }
        kfree(rx);
        return len;
 error_ret:
@@ -590,7 +590,7 @@ static inline int __sca3000_get_base_freq(struct sca3000_state *st,
        case SCA3000_MEAS_MODE_OP_2:
                *base_freq = info->option_mode_2_freq;
                break;
-       };
+       }
        kfree(rx);
 error_ret:
        return ret;
@@ -627,8 +627,8 @@ static ssize_t sca3000_read_frequency(struct device *dev,
                case 0x02:
                        len = sprintf(buf, "%d\n", base_freq/4);
                        break;
-       };
-                       kfree(rx);
+       }
+       kfree(rx);
        return len;
 error_ret_mut:
        mutex_unlock(&st->lock);
index 18c9376ecbb2a8403d03a2b2c6578962911f2713..688510fd8bbb790d4e94f8743c326c4717fe16ab 100644 (file)
@@ -1,4 +1,4 @@
-
+#
 # Makefile for industrial I/O ADC drivers
 #
 
index 04eb16fd0a955c2209e54e5bf5359a142c733ef3..7841e6ad4349618ad0b26583366fd6e648803cdb 100644 (file)
@@ -26,3 +26,6 @@
                              _show,                                    \
                              NULL,                                     \
                              _addr)
+
+#define IIO_EVENT_CODE_IN_HIGH_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a)
+#define IIO_EVENT_CODE_IN_LOW_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a + 32)
index 72cf367093688f5f466ccf33e7b90677d6fc777d..8f0fe1ced2ced7618fa61b11a880ad79ffe18430 100644 (file)
 
 /* Specific to the max1363 */
 #define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
-#define MAX1363_MON_CONV_RATE_133ksps          0
-#define MAX1363_MON_CONV_RATE_66_5ksps         0x02
-#define MAX1363_MON_CONV_RATE_33_3ksps         0x04
-#define MAX1363_MON_CONV_RATE_16_6ksps         0x06
-#define MAX1363_MON_CONV_RATE_8_3ksps          0x08
-#define MAX1363_MON_CONV_RATE_4_2ksps          0x0A
-#define MAX1363_MON_CONV_RATE_2_0ksps          0x0C
-#define MAX1363_MON_CONV_RATE_1_0ksps          0x0E
 #define MAX1363_MON_INT_ENABLE                 0x01
 
 /* defined for readability reasons */
@@ -67,9 +59,8 @@
 
 /**
  * struct max1363_mode - scan mode information
- * @name:      Name used to identify the scan mode.
  * @conf:      The corresponding value of the configuration register
- * @numvals:   The number of values returned by a single scan
+ * @modemask:  Bit mask corresponding to channels enabled in this mode
  */
 struct max1363_mode {
        int8_t          conf;
@@ -122,15 +113,6 @@ struct max1363_mode {
                        .modemask = _mask                               \
 }
 
-/* Not currently handled */
-#define MAX1363_MODE_MONITOR {                                 \
-               .name = "monitor",                              \
-                       .conf = MAX1363_CHANNEL_SEL(3)          \
-                       | MAX1363_CONFIG_SCAN_MONITOR_MODE      \
-                       | MAX1363_CONFIG_SE,                    \
-                       .numvals = 10,                          \
-               }
-
 /* This may seem an overly long winded way to do this, but at least it makes
  * clear what all the various options actually do. Alternative suggestions
  * that don't require user to have intimate knowledge of the chip welcomed.
@@ -147,7 +129,7 @@ enum max1363_channels {
        max1363_in1min0, max1363_in3min2,
        max1363_in5min4, max1363_in7min6,
        max1363_in9min8, max1363_in11min10,
-       };
+};
 
 /* This must be maintained along side the max1363_mode_table in max1363_core */
 enum max1363_modes {
@@ -179,7 +161,6 @@ enum max1363_modes {
  * @default_mode:      the scan mode in which the chip starts up
  */
 struct max1363_chip_info {
-       const char                      *name;
        u8                              num_inputs;
        u8                              bits;
        u16                             int_vref_mv;
@@ -191,7 +172,6 @@ struct max1363_chip_info {
        struct attribute_group          *scan_attrs;
 };
 
-
 /**
  * struct max1363_state - driver instance specific data
  * @indio_dev:         the industrial I/O device
@@ -204,12 +184,20 @@ struct max1363_chip_info {
  * @poll_work:         bottom half of polling interrupt handler
  * @protect_ring:      used to ensure only one polling bh running at a time
  * @reg:               supply regulator
+ * @monitor_on:                whether monitor mode is enabled
+ * @monitor_speed:     parameter corresponding to device monitor speed setting
+ * @mask_high:         bitmask for enabled high thresholds
+ * @mask_low:          bitmask for enabled low thresholds
+ * @thresh_high:       high threshold values
+ * @thresh_low:                low threshold values
+ * @last_timestamp:    timestamp of last event interrupt
+ * @thresh_work:       bh work structure for event handling
  */
 struct max1363_state {
        struct iio_dev                  *indio_dev;
        struct i2c_client               *client;
-       char                            setupbyte;
-       char                            configbyte;
+       u8                              setupbyte;
+       u8                              configbyte;
        const struct max1363_chip_info  *chip_info;
        const struct max1363_mode       *current_mode;
        u32                             requestedmask;
@@ -217,6 +205,18 @@ struct max1363_state {
        atomic_t                        protect_ring;
        struct iio_trigger              *trig;
        struct regulator                *reg;
+
+       /* Using monitor modes and buffer at the same time is
+          currently not supported */
+       bool                            monitor_on;
+       unsigned int                    monitor_speed:3;
+       u8                              mask_high;
+       u8                              mask_low;
+       /* 4x unipolar first then the fours bipolar ones */
+       s16                             thresh_high[8];
+       s16                             thresh_low[8];
+       s64                             last_timestamp;
+       struct work_struct              thresh_work;
 };
 
 const struct max1363_mode
@@ -230,32 +230,21 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st);
 int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void max1363_ring_cleanup(struct iio_dev *indio_dev);
 
-int max1363_initialize_ring(struct iio_ring_buffer *ring);
-void max1363_uninitialize_ring(struct iio_ring_buffer *ring);
-
 #else /* CONFIG_MAX1363_RING_BUFFER */
 
-static inline void max1363_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-};
-
-static inline int max1363_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return 0;
-};
-
 int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
 {
        return -EINVAL;
-};
-
+}
 
 static inline int
 max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
        return 0;
-};
+}
 
-static inline void max1363_ring_cleanup(struct iio_dev *indio_dev) {};
+static inline void max1363_ring_cleanup(struct iio_dev *indio_dev)
+{
+}
 #endif /* CONFIG_MAX1363_RING_BUFFER */
 #endif /* _MAX1363_H_ */
index 905f8560d31f94d0a4651d54ab8b8191ca69d1f4..6435e509dd5637db38452219ad12c4d1b1450d5f 100644 (file)
   *
   * Not currently implemented.
   *
-  * - Monitor interrrupt generation.
   * - Control of internal reference.
   */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
 #include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/err.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -48,7 +46,7 @@
        IIO_SCAN_EL_C(in##number, number, IIO_UNSIGNED(16), 0, NULL);
 #define MAX1363_SCAN_EL_D(p, n, number)                                        \
        IIO_SCAN_NAMED_EL_C(in##p##m##in##n, in##p-in##n,               \
-                       number, IIO_SIGNED(16), 0 , NULL);
+                       number, IIO_SIGNED(16), 0, NULL);
 
 static MAX1363_SCAN_EL(0);
 static MAX1363_SCAN_EL(1);
@@ -148,7 +146,7 @@ const struct max1363_mode
                              mask))
                                return &max1363_mode_table[ci->mode_list[i]];
        return NULL;
-};
+}
 
 static ssize_t max1363_show_precision(struct device *dev,
                                struct device_attribute *attr,
@@ -167,7 +165,7 @@ static int max1363_write_basic_config(struct i2c_client *client,
                                      unsigned char d2)
 {
        int ret;
-       u8 *tx_buf = kmalloc(2 , GFP_KERNEL);
+       u8 *tx_buf = kmalloc(2, GFP_KERNEL);
 
        if (!tx_buf)
                return -ENOMEM;
@@ -206,6 +204,16 @@ static ssize_t max1363_read_single_channel(struct device *dev,
        long mask;
 
        mutex_lock(&dev_info->mlock);
+       /*
+        * If monitor mode is enabled, the method for reading a single
+        * channel will have to be rather different and has not yet
+        * been implemented.
+        */
+       if (st->monitor_on) {
+               ret = -EBUSY;
+               goto error_ret;
+       }
+
        /* If ring buffer capture is occuring, query the buffer */
        if (iio_ring_enabled(dev_info)) {
                mask = max1363_mode_table[this_attr->address].modemask;
@@ -305,7 +313,7 @@ static ssize_t max1363_show_name(struct device *dev,
 {
        struct iio_dev *dev_info = dev_get_drvdata(dev);
        struct max1363_state *st = iio_dev_get_devdata(dev_info);
-       return sprintf(buf, "%s\n", st->chip_info->name);
+       return sprintf(buf, "%s\n", st->client->name);
 }
 
 static IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0);
@@ -552,8 +560,7 @@ enum { max1361,
 
 /* max1363 and max1368 tested - rest from data sheet */
 static const struct max1363_chip_info max1363_chip_info_tbl[] = {
-       {
-               .name = "max1361",
+       [max1361] = {
                .num_inputs = 4,
                .bits = 10,
                .int_vref_mv = 2048,
@@ -563,8 +570,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1362",
+       },
+       [max1362] = {
                .num_inputs = 4,
                .bits = 10,
                .int_vref_mv = 4096,
@@ -574,8 +581,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1363",
+       },
+       [max1363] = {
                .num_inputs = 4,
                .bits = 12,
                .int_vref_mv = 2048,
@@ -585,8 +592,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1364",
+       },
+       [max1364] = {
                .num_inputs = 4,
                .bits = 12,
                .int_vref_mv = 4096,
@@ -596,8 +603,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1036",
+       },
+       [max1036] = {
                .num_inputs = 4,
                .bits = 8,
                .int_vref_mv = 4096,
@@ -606,8 +613,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1037",
+       },
+       [max1037] = {
                .num_inputs = 4,
                .bits = 8,
                .int_vref_mv = 2048,
@@ -616,8 +623,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1038",
+       },
+       [max1038] = {
                .num_inputs = 12,
                .bits = 8,
                .int_vref_mv = 4096,
@@ -626,8 +633,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max1039",
+       },
+       [max1039] = {
                .num_inputs = 12,
                .bits = 8,
                .int_vref_mv = 2048,
@@ -636,8 +643,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max1136",
+       },
+       [max1136] = {
                .num_inputs = 4,
                .bits = 10,
                .int_vref_mv = 4096,
@@ -646,8 +653,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1137",
+       },
+       [max1137] = {
                .num_inputs = 4,
                .bits = 10,
                .int_vref_mv = 2048,
@@ -656,8 +663,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1138",
+       },
+       [max1138] = {
                .num_inputs = 12,
                .bits = 10,
                .int_vref_mv = 4096,
@@ -666,8 +673,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max1139",
+       },
+       [max1139] = {
                .num_inputs = 12,
                .bits = 10,
                .int_vref_mv = 2048,
@@ -676,8 +683,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max1236",
+       },
+       [max1236] = {
                .num_inputs = 4,
                .bits = 12,
                .int_vref_mv = 4096,
@@ -686,8 +693,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1237",
+       },
+       [max1237] = {
                .num_inputs = 4,
                .bits = 12,
                .int_vref_mv = 2048,
@@ -696,8 +703,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max1238",
+       },
+       [max1238] = {
                .num_inputs = 12,
                .bits = 12,
                .int_vref_mv = 4096,
@@ -706,8 +713,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max1239",
+       },
+       [max1239] = {
                .num_inputs = 12,
                .bits = 12,
                .int_vref_mv = 2048,
@@ -716,8 +723,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max11600",
+       },
+       [max11600] = {
                .num_inputs = 4,
                .bits = 8,
                .int_vref_mv = 4096,
@@ -726,8 +733,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max11601",
+       },
+       [max11601] = {
                .num_inputs = 4,
                .bits = 8,
                .int_vref_mv = 2048,
@@ -736,8 +743,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max11602",
+       },
+       [max11602] = {
                .num_inputs = 8,
                .bits = 8,
                .int_vref_mv = 4096,
@@ -746,8 +753,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to7,
                .dev_attrs = &max11608_dev_attr_group,
                .scan_attrs = &max11608_scan_el_group,
-       }, {
-               .name = "max11603",
+       },
+       [max11603] = {
                .num_inputs = 8,
                .bits = 8,
                .int_vref_mv = 2048,
@@ -756,8 +763,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to7,
                .dev_attrs = &max11608_dev_attr_group,
                .scan_attrs = &max11608_scan_el_group,
-       }, {
-               .name = "max11604",
+       },
+       [max11604] = {
                .num_inputs = 12,
                .bits = 8,
                .int_vref_mv = 4098,
@@ -766,8 +773,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max11605",
+       },
+       [max11605] = {
                .num_inputs = 12,
                .bits = 8,
                .int_vref_mv = 2048,
@@ -776,8 +783,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max11606",
+       },
+       [max11606] = {
                .num_inputs = 4,
                .bits = 10,
                .int_vref_mv = 4096,
@@ -786,8 +793,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max11607",
+       },
+       [max11607] = {
                .num_inputs = 4,
                .bits = 10,
                .int_vref_mv = 2048,
@@ -796,8 +803,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max11608",
+       },
+       [max11608] = {
                .num_inputs = 8,
                .bits = 10,
                .int_vref_mv = 4096,
@@ -806,8 +813,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to7,
                .dev_attrs = &max11608_dev_attr_group,
                .scan_attrs = &max11608_scan_el_group,
-       }, {
-               .name = "max11609",
+       },
+       [max11609] = {
                .num_inputs = 8,
                .bits = 10,
                .int_vref_mv = 2048,
@@ -816,8 +823,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to7,
                .dev_attrs = &max11608_dev_attr_group,
                .scan_attrs = &max11608_scan_el_group,
-       }, {
-               .name = "max11610",
+       },
+       [max11610] = {
                .num_inputs = 12,
                .bits = 10,
                .int_vref_mv = 4098,
@@ -826,8 +833,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max11611",
+       },
+       [max11611] = {
                .num_inputs = 12,
                .bits = 10,
                .int_vref_mv = 2048,
@@ -836,8 +843,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max11612",
+       },
+       [max11612] = {
                .num_inputs = 4,
                .bits = 12,
                .int_vref_mv = 4096,
@@ -846,8 +853,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max11613",
+       },
+       [max11613] = {
                .num_inputs = 4,
                .bits = 12,
                .int_vref_mv = 2048,
@@ -856,8 +863,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to3,
                .dev_attrs = &max1363_dev_attr_group,
                .scan_attrs = &max1363_scan_el_group,
-       }, {
-               .name = "max11614",
+       },
+       [max11614] = {
                .num_inputs = 8,
                .bits = 12,
                .int_vref_mv = 4096,
@@ -866,8 +873,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to7,
                .dev_attrs = &max11608_dev_attr_group,
                .scan_attrs = &max11608_scan_el_group,
-       }, {
-               .name = "max11615",
+       },
+       [max11615] = {
                .num_inputs = 8,
                .bits = 12,
                .int_vref_mv = 2048,
@@ -876,8 +883,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to7,
                .dev_attrs = &max11608_dev_attr_group,
                .scan_attrs = &max11608_scan_el_group,
-       }, {
-               .name = "max11616",
+       },
+       [max11616] = {
                .num_inputs = 12,
                .bits = 12,
                .int_vref_mv = 4098,
@@ -886,8 +893,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
                .default_mode = s0to11,
                .dev_attrs = &max1238_dev_attr_group,
                .scan_attrs = &max1238_scan_el_group,
-       }, {
-               .name = "max11617",
+       },
+       [max11617] = {
                .num_inputs = 12,
                .bits = 12,
                .int_vref_mv = 2048,
@@ -899,6 +906,668 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
        }
 };
 
+static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600,
+                                             8300, 4200, 2000, 1000 };
+
+static ssize_t max1363_monitor_show_freq(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct max1363_state *st = iio_dev_get_devdata(dev_info);
+       return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]);
+}
+
+static ssize_t max1363_monitor_store_freq(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf,
+                                       size_t len)
+{
+       struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct max1363_state *st = iio_dev_get_devdata(dev_info);
+       int i, ret;
+       unsigned long val;
+       bool found = false;
+
+       ret = strict_strtoul(buf, 10, &val);
+       if (ret)
+               return -EINVAL;
+       for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++)
+               if (val == max1363_monitor_speeds[i]) {
+                       found = true;
+                       break;
+               }
+       if (!found)
+               return -EINVAL;
+
+       mutex_lock(&dev_info->mlock);
+       st->monitor_speed = i;
+       mutex_unlock(&dev_info->mlock);
+
+       return 0;
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
+                       max1363_monitor_show_freq,
+                       max1363_monitor_store_freq);
+
+static IIO_CONST_ATTR(sampling_frequency_available,
+               "133000 665000 33300 16600 8300 4200 2000 1000");
+
+static ssize_t max1363_show_thresh(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf,
+                               bool high)
+{
+       struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct max1363_state *st = iio_dev_get_devdata(dev_info);
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+       if (high)
+               return sprintf(buf, "%d\n",
+                       st->thresh_high[this_attr->address]);
+       else
+               return sprintf(buf, "%d\n",
+                       st->thresh_low[this_attr->address & 0x7]);
+}
+
+static ssize_t max1363_show_thresh_low(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       return max1363_show_thresh(dev, attr, buf, false);
+}
+
+static ssize_t max1363_show_thresh_high(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       return max1363_show_thresh(dev, attr, buf, true);
+}
+
+static ssize_t max1363_store_thresh_unsigned(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf,
+                                       size_t len,
+                                       bool high)
+{
+       struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct max1363_state *st = iio_dev_get_devdata(dev_info);
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       unsigned long val;
+       int ret;
+
+       ret = strict_strtoul(buf, 10, &val);
+       if (ret)
+               return -EINVAL;
+       switch (st->chip_info->bits) {
+       case 10:
+               if (val > 0x3FF)
+                       return -EINVAL;
+               break;
+       case 12:
+               if (val > 0xFFF)
+                       return -EINVAL;
+               break;
+       }
+
+       switch (high) {
+       case 1:
+               st->thresh_high[this_attr->address] = val;
+               break;
+       case 0:
+               st->thresh_low[this_attr->address & 0x7] = val;
+               break;
+       }
+
+       return len;
+}
+
+static ssize_t max1363_store_thresh_high_unsigned(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf,
+                                               size_t len)
+{
+       return max1363_store_thresh_unsigned(dev, attr, buf, len, true);
+}
+
+static ssize_t max1363_store_thresh_low_unsigned(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf,
+                                               size_t len)
+{
+       return max1363_store_thresh_unsigned(dev, attr, buf, len, false);
+}
+
+static ssize_t max1363_store_thresh_signed(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf,
+                                       size_t len,
+                                       bool high)
+{
+       struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct max1363_state *st = iio_dev_get_devdata(dev_info);
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       long val;
+       int ret;
+
+       ret = strict_strtol(buf, 10, &val);
+       if (ret)
+               return -EINVAL;
+       switch (st->chip_info->bits) {
+       case 10:
+               if (val < -512 || val > 511)
+                       return -EINVAL;
+               break;
+       case 12:
+               if (val < -2048 || val > 2047)
+                       return -EINVAL;
+               break;
+       }
+
+       switch (high) {
+       case 1:
+               st->thresh_high[this_attr->address] = val;
+               break;
+       case 0:
+               st->thresh_low[this_attr->address & 0x7] = val;
+               break;
+       }
+
+       return len;
+}
+
+static ssize_t max1363_store_thresh_high_signed(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf,
+                                               size_t len)
+{
+       return max1363_store_thresh_signed(dev, attr, buf, len, true);
+}
+
+static ssize_t max1363_store_thresh_low_signed(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf,
+                                               size_t len)
+{
+       return max1363_store_thresh_signed(dev, attr, buf, len, false);
+}
+
+static IIO_DEVICE_ATTR(in0_thresh_high_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_high,
+               max1363_store_thresh_high_unsigned, 0);
+static IIO_DEVICE_ATTR(in0_thresh_low_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_low,
+               max1363_store_thresh_low_unsigned, 0);
+static IIO_DEVICE_ATTR(in1_thresh_high_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_high,
+               max1363_store_thresh_high_unsigned, 1);
+static IIO_DEVICE_ATTR(in1_thresh_low_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_low,
+               max1363_store_thresh_low_unsigned, 1);
+static IIO_DEVICE_ATTR(in2_thresh_high_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_high,
+               max1363_store_thresh_high_unsigned, 2);
+static IIO_DEVICE_ATTR(in2_thresh_low_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_low,
+               max1363_store_thresh_low_unsigned, 2);
+static IIO_DEVICE_ATTR(in3_thresh_high_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_high,
+               max1363_store_thresh_high_unsigned, 3);
+static IIO_DEVICE_ATTR(in3_thresh_low_value, S_IRUGO | S_IWUSR,
+               max1363_show_thresh_low,
+               max1363_store_thresh_low_unsigned, 3);
+
+static IIO_DEVICE_ATTR_NAMED(in0min1_thresh_high_value,
+                       in0-in1_thresh_high_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_high,
+                       max1363_store_thresh_high_signed, 4);
+static IIO_DEVICE_ATTR_NAMED(in0min1_thresh_low_value,
+                       in0-in1_thresh_low_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_low,
+                       max1363_store_thresh_low_signed, 4);
+static IIO_DEVICE_ATTR_NAMED(in2min3_thresh_high_value,
+                       in2-in3_thresh_high_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_high,
+                       max1363_store_thresh_high_signed, 5);
+static IIO_DEVICE_ATTR_NAMED(in2min3_thresh_low_value,
+                       in2-in3_thresh_low_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_low,
+                       max1363_store_thresh_low_signed, 5);
+static IIO_DEVICE_ATTR_NAMED(in1min0_thresh_high_value,
+                       in1-in0_thresh_high_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_high,
+                       max1363_store_thresh_high_signed, 6);
+static IIO_DEVICE_ATTR_NAMED(in1min0_thresh_low_value,
+                       in1-in0_thresh_low_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_low,
+                       max1363_store_thresh_low_signed, 6);
+static IIO_DEVICE_ATTR_NAMED(in3min2_thresh_high_value,
+                       in3-in2_thresh_high_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_high,
+                       max1363_store_thresh_high_signed, 7);
+static IIO_DEVICE_ATTR_NAMED(in3min2_thresh_low_value,
+                       in3-in2_thresh_low_value,
+                       S_IRUGO | S_IWUSR, max1363_show_thresh_low,
+                       max1363_store_thresh_low_signed, 7);
+
+static int max1363_int_th(struct iio_dev *dev_info,
+                       int index,
+                       s64 timestamp,
+                       int not_test)
+{
+       struct max1363_state *st = dev_info->dev_data;
+
+       st->last_timestamp = timestamp;
+       schedule_work(&st->thresh_work);
+       return 0;
+}
+
+static void max1363_thresh_handler_bh(struct work_struct *work_s)
+{
+       struct max1363_state *st = container_of(work_s, struct max1363_state,
+                                               thresh_work);
+       u8 rx;
+       u8 tx[2] = { st->setupbyte,
+                    MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
+
+       i2c_master_recv(st->client, &rx, 1);
+       if (rx & (1 << 0))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_LOW_THRESH(3),
+                       st->last_timestamp);
+       if (rx & (1 << 1))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_HIGH_THRESH(3),
+                       st->last_timestamp);
+       if (rx & (1 << 2))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_LOW_THRESH(2),
+                       st->last_timestamp);
+       if (rx & (1 << 3))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_HIGH_THRESH(2),
+                       st->last_timestamp);
+       if (rx & (1 << 4))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_LOW_THRESH(1),
+                       st->last_timestamp);
+       if (rx & (1 << 5))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_HIGH_THRESH(1),
+                       st->last_timestamp);
+       if (rx & (1 << 6))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_LOW_THRESH(0),
+                       st->last_timestamp);
+       if (rx & (1 << 7))
+               iio_push_event(st->indio_dev, 0,
+                       IIO_EVENT_CODE_IN_HIGH_THRESH(0),
+                       st->last_timestamp);
+       enable_irq(st->client->irq);
+       i2c_master_send(st->client, tx, 2);
+}
+
+static ssize_t max1363_read_interrupt_config(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct max1363_state *st = iio_dev_get_devdata(dev_info);
+       struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+       int val;
+
+       mutex_lock(&dev_info->mlock);
+       if (this_attr->mask & 0x8)
+               val = (1 << (this_attr->mask & 0x7)) & st->mask_low;
+       else
+               val = (1 << this_attr->mask) & st->mask_high;
+       mutex_unlock(&dev_info->mlock);
+
+       return sprintf(buf, "%d\n", !!val);
+}
+
+static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
+{
+       u8 *tx_buf;
+       int ret, i = 3, j;
+       unsigned long numelements;
+       int len;
+       long modemask;
+
+       if (!enabled) {
+               /* transition to ring capture is not currently supported */
+               st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP;
+               st->configbyte &= ~MAX1363_SCAN_MASK;
+               st->monitor_on = false;
+               return max1363_write_basic_config(st->client,
+                                               st->setupbyte,
+                                               st->configbyte);
+       }
+
+       /* Ensure we are in the relevant mode */
+       st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP;
+       st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
+                           | MAX1363_SCAN_MASK
+                       | MAX1363_SE_DE_MASK);
+       st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE;
+       if ((st->mask_low | st->mask_high) & 0x0F) {
+               st->configbyte |= max1363_mode_table[s0to3].conf;
+               modemask = max1363_mode_table[s0to3].modemask;
+       } else if ((st->mask_low | st->mask_high) & 0x30) {
+               st->configbyte |= max1363_mode_table[d0m1to2m3].conf;
+               modemask = max1363_mode_table[d0m1to2m3].modemask;
+       } else {
+               st->configbyte |= max1363_mode_table[d1m0to3m2].conf;
+               modemask = max1363_mode_table[d1m0to3m2].modemask;
+       }
+       numelements = hweight_long(modemask);
+       len = 3 * numelements + 3;
+       tx_buf = kmalloc(len, GFP_KERNEL);
+       if (!tx_buf) {
+               ret = -ENOMEM;
+               goto error_ret;
+       }
+       tx_buf[0] = st->configbyte;
+       tx_buf[1] = st->setupbyte;
+       tx_buf[2] = (st->monitor_speed << 1);
+
+       /*
+        * So we need to do yet another bit of nefarious scan mode
+        * setup to match what we need.
+        */
+       for (j = 0; j < 8; j++)
+               if (modemask & (1 << j)) {
+                       /* Establish the mode is in the scan */
+                       if (st->mask_low & (1 << j)) {
+                               tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF;
+                               tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0;
+                       } else if (j < 4) {
+                               tx_buf[i] = 0;
+                               tx_buf[i + 1] = 0;
+                       } else {
+                               tx_buf[i] = 0x80;
+                               tx_buf[i + 1] = 0;
+                       }
+                       if (st->mask_high & (1 << j)) {
+                               tx_buf[i + 1] |=
+                                       (st->thresh_high[j] >> 8) & 0x0F;
+                               tx_buf[i + 2] = st->thresh_high[j] & 0xFF;
+                       } else if (j < 4) {
+                               tx_buf[i + 1] |= 0x0F;
+                               tx_buf[i + 2] = 0xFF;
+                       } else {
+                               tx_buf[i + 1] |= 0x07;
+                               tx_buf[i + 2] = 0xFF;
+                       }
+                       i += 3;
+               }
+
+
+       ret = i2c_master_send(st->client, tx_buf, len);
+       if (ret < 0)
+               goto error_ret;
+       if (ret != len) {
+               ret = -EIO;
+               goto error_ret;
+       }
+
+       /*
+        * Now that we hopefully have sensible thresholds in place it is
+        * time to turn the interrupts on.
+        * It is unclear from the data sheet if this should be necessary
+        * (i.e. whether monitor mode setup is atomic) but it appears to
+        * be in practice.
+        */
+       tx_buf[0] = st->setupbyte;
+       tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0;
+       ret = i2c_master_send(st->client, tx_buf, 2);
+       if (ret < 0)
+               goto error_ret;
+       if (ret != 2) {
+               ret = -EIO;
+               goto error_ret;
+       }
+       ret = 0;
+       st->monitor_on = true;
+error_ret:
+
+       kfree(tx_buf);
+
+       return ret;
+}
+
+/*
+ * To keep this managable we always use one of 3 scan modes.
+ * Scan 0...3, 0-1,2-3 and 1-0,3-2
+ */
+static inline int __max1363_check_event_mask(int thismask, int checkmask)
+{
+       int ret = 0;
+       /* Is it unipolar */
+       if (thismask < 4) {
+               if (checkmask & ~0x0F) {
+                       ret = -EBUSY;
+                       goto error_ret;
+               }
+       } else if (thismask < 6) {
+               if (checkmask & ~0x30) {
+                       ret = -EBUSY;
+                       goto error_ret;
+               }
+       } else if (checkmask & ~0xC0)
+               ret = -EBUSY;
+error_ret:
+       return ret;
+}
+
+static ssize_t max1363_write_interrupt_config(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf,
+                                       size_t len)
+{
+       struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct max1363_state *st = iio_dev_get_devdata(dev_info);
+       struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+       unsigned long val;
+       int ret;
+       u16 unifiedmask;
+       ret = strict_strtoul(buf, 10, &val);
+       if (ret)
+               return -EINVAL;
+       mutex_lock(&st->indio_dev->mlock);
+       unifiedmask = st->mask_low | st->mask_high;
+       if (this_attr->mask & 0x08) {
+               /* If we are disabling no need to test */
+               if (val == 0)
+                       st->mask_low &= ~(1 << (this_attr->mask & 0x7));
+               else {
+                       ret = __max1363_check_event_mask(this_attr->mask & 0x7,
+                                                       unifiedmask);
+                       if (ret)
+                               goto error_ret;
+                       st->mask_low |= (1 << (this_attr->mask & 0x7));
+               }
+       } else {
+               if (val == 0)
+                       st->mask_high &= ~(1 << (this_attr->mask));
+               else {
+                       ret = __max1363_check_event_mask(this_attr->mask,
+                                                       unifiedmask);
+                       if (ret)
+                               goto error_ret;
+                       st->mask_high |= (1 << this_attr->mask);
+               }
+       }
+       if (st->monitor_on && !st->mask_high && !st->mask_low)
+               iio_remove_event_from_list(this_attr->listel,
+                                       &dev_info->interrupts[0]->ev_list);
+       if (!st->monitor_on && val)
+               iio_add_event_to_list(this_attr->listel,
+                               &dev_info->interrupts[0]->ev_list);
+
+       max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low));
+error_ret:
+       mutex_unlock(&st->indio_dev->mlock);
+
+       return len;
+}
+
+IIO_EVENT_SH(max1363_thresh, max1363_int_th);
+
+#define MAX1363_HIGH_THRESH(a) a
+#define MAX1363_LOW_THRESH(a) (a | 0x8)
+
+IIO_EVENT_ATTR_SH(in0_thresh_high_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_HIGH_THRESH(0));
+
+IIO_EVENT_ATTR_SH(in0_thresh_low_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_LOW_THRESH(0));
+
+IIO_EVENT_ATTR_SH(in1_thresh_high_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_HIGH_THRESH(1));
+
+IIO_EVENT_ATTR_SH(in1_thresh_low_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_LOW_THRESH(1));
+
+IIO_EVENT_ATTR_SH(in2_thresh_high_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_HIGH_THRESH(2));
+
+IIO_EVENT_ATTR_SH(in2_thresh_low_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_LOW_THRESH(2));
+
+IIO_EVENT_ATTR_SH(in3_thresh_high_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_HIGH_THRESH(3));
+
+IIO_EVENT_ATTR_SH(in3_thresh_low_en,
+               iio_event_max1363_thresh,
+               max1363_read_interrupt_config,
+               max1363_write_interrupt_config,
+               MAX1363_LOW_THRESH(3));
+
+IIO_EVENT_ATTR_NAMED_SH(in0min1_thresh_high_en,
+                       in0-in1_thresh_high_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_HIGH_THRESH(4));
+
+IIO_EVENT_ATTR_NAMED_SH(in0min1_thresh_low_en,
+                       in0-in1_thresh_low_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_LOW_THRESH(4));
+
+IIO_EVENT_ATTR_NAMED_SH(in3min2_thresh_high_en,
+                       in3-in2_thresh_high_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_HIGH_THRESH(5));
+
+IIO_EVENT_ATTR_NAMED_SH(in3min2_thresh_low_en,
+                       in3-in2_thresh_low_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_LOW_THRESH(5));
+
+IIO_EVENT_ATTR_NAMED_SH(in1min0_thresh_high_en,
+                       in1-in0_thresh_high_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_HIGH_THRESH(6));
+
+IIO_EVENT_ATTR_NAMED_SH(in1min0_thresh_low_en,
+                       in1-in0_thresh_low_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_LOW_THRESH(6));
+
+IIO_EVENT_ATTR_NAMED_SH(in2min3_thresh_high_en,
+                       in2-in3_thresh_high_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_HIGH_THRESH(7));
+
+IIO_EVENT_ATTR_NAMED_SH(in2min3_thresh_low_en,
+                       in2-in3_thresh_low_en,
+                       iio_event_max1363_thresh,
+                       max1363_read_interrupt_config,
+                       max1363_write_interrupt_config,
+                       MAX1363_LOW_THRESH(7));
+
+/*
+ * As with scan_elements, only certain sets of these can
+ * be combined.
+ */
+static struct attribute *max1363_event_attributes[] = {
+       &iio_dev_attr_in0_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in0_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_in1_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in1_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_in2_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in2_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_in3_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in3_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_in0min1_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in0min1_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_in2min3_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in2min3_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_in1min0_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in1min0_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_in3min2_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_in3min2_thresh_low_value.dev_attr.attr,
+       &iio_dev_attr_sampling_frequency.dev_attr.attr,
+       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+       &iio_event_attr_in0_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in0_thresh_low_en.dev_attr.attr,
+       &iio_event_attr_in1_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in1_thresh_low_en.dev_attr.attr,
+       &iio_event_attr_in2_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in2_thresh_low_en.dev_attr.attr,
+       &iio_event_attr_in3_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in3_thresh_low_en.dev_attr.attr,
+       &iio_event_attr_in0min1_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in0min1_thresh_low_en.dev_attr.attr,
+       &iio_event_attr_in3min2_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in3min2_thresh_low_en.dev_attr.attr,
+       &iio_event_attr_in1min0_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in1min0_thresh_low_en.dev_attr.attr,
+       &iio_event_attr_in2min3_thresh_high_en.dev_attr.attr,
+       &iio_event_attr_in2min3_thresh_low_en.dev_attr.attr,
+       NULL,
+};
+
+static struct attribute_group max1363_event_attribute_group = {
+       .attrs = max1363_event_attributes,
+};
+
 static int max1363_initial_setup(struct max1363_state *st)
 {
        st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD
@@ -930,19 +1599,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
 
        atomic_set(&st->protect_ring, 0);
 
-       /* Find the chip model specific data */
-       for (i = 0; i < ARRAY_SIZE(max1363_chip_info_tbl); i++)
-               if (!strcmp(max1363_chip_info_tbl[i].name, id->name)) {
-                       st->chip_info = &max1363_chip_info_tbl[i];
-                       break;
-               };
-       /* Unsupported chip */
-       if (!st->chip_info) {
-               dev_err(&client->dev, "%s is not supported\n", id->name);
-               ret = -ENODEV;
-               goto error_free_st;
-       }
-
+       st->chip_info = &max1363_chip_info_tbl[id->driver_data];
        st->reg = regulator_get(&client->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
@@ -978,6 +1635,11 @@ static int __devinit max1363_probe(struct i2c_client *client,
        st->indio_dev->dev_data = (void *)(st);
        st->indio_dev->driver_module = THIS_MODULE;
        st->indio_dev->modes = INDIO_DIRECT_MODE;
+       if (st->chip_info->monitor_mode && client->irq) {
+               st->indio_dev->num_interrupt_lines = 1;
+               st->indio_dev->event_attrs
+                       = &max1363_event_attribute_group;
+       }
 
        ret = max1363_initial_setup(st);
        if (ret)
@@ -991,10 +1653,25 @@ static int __devinit max1363_probe(struct i2c_client *client,
        if (ret)
                goto error_cleanup_ring;
        regdone = 1;
-       ret = max1363_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
        if (ret)
                goto error_cleanup_ring;
+
+       if (st->chip_info->monitor_mode && client->irq) {
+               ret = iio_register_interrupt_line(client->irq,
+                                               st->indio_dev,
+                                               0,
+                                               IRQF_TRIGGER_RISING,
+                                               client->name);
+               if (ret)
+                       goto error_uninit_ring;
+
+               INIT_WORK(&st->thresh_work, max1363_thresh_handler_bh);
+       }
+
        return 0;
+error_uninit_ring:
+       iio_ring_buffer_unregister(st->indio_dev->ring);
 error_cleanup_ring:
        max1363_ring_cleanup(st->indio_dev);
 error_free_available_scan_masks:
@@ -1010,7 +1687,6 @@ error_disable_reg:
 error_put_reg:
        if (!IS_ERR(st->reg))
                regulator_put(st->reg);
-error_free_st:
        kfree(st);
 
 error_ret:
@@ -1021,7 +1697,10 @@ static int max1363_remove(struct i2c_client *client)
 {
        struct max1363_state *st = i2c_get_clientdata(client);
        struct iio_dev *indio_dev = st->indio_dev;
-       max1363_uninitialize_ring(indio_dev->ring);
+
+       if (st->chip_info->monitor_mode && client->irq)
+               iio_unregister_interrupt_line(st->indio_dev, 0);
+       iio_ring_buffer_unregister(indio_dev->ring);
        max1363_ring_cleanup(indio_dev);
        kfree(st->indio_dev->available_scan_masks);
        iio_device_unregister(indio_dev);
index 56688dc9c92f37f073737617627726246e438219..786b17a0d6b0b9f43e7d0ed4b5e65b1c4dcbd2fd 100644 (file)
@@ -68,7 +68,7 @@ error_ret:
 }
 
 /**
- * max1363_ring_preenable() setup the parameters of the ring before enabling
+ * max1363_ring_preenable() setup the parameters of the ring before enabling
  *
  * The complex nature of the setting of the nuber of bytes per datum is due
  * to this driver currently ensuring that the timestamp is stored at an 8
@@ -105,44 +105,15 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
        return 0;
 }
 
-/**
- * max1363_ring_postenable() typical ring post enable
- *
- * Only not moved into the core for the hardware ring buffer cases
- * that are more sophisticated.
- **/
-static int max1363_ring_postenable(struct iio_dev *indio_dev)
-{
-       if (indio_dev->trig == NULL)
-               return 0;
-       return iio_trigger_attach_poll_func(indio_dev->trig,
-                                           indio_dev->pollfunc);
-}
 
 /**
- * max1363_ring_predisable() runs just prior to ring buffer being disabled
- *
- * Typical predisable function which ensures that no trigger events can
- * occur before we disable the ring buffer (and hence would have no idea
- * what to do with them)
- **/
-static int max1363_ring_predisable(struct iio_dev *indio_dev)
-{
-       if (indio_dev->trig)
-               return iio_trigger_dettach_poll_func(indio_dev->trig,
-                                                    indio_dev->pollfunc);
-       else
-               return 0;
-}
-
-/**
- * max1363_poll_func_th() th of trigger launched polling to ring buffer
+ * max1363_poll_func_th() - th of trigger launched polling to ring buffer
  *
  * As sampling only occurs on i2c comms occuring, leave timestamping until
  * then.  Some triggers will generate their own time stamp.  Currently
  * there is no way of notifying them when no one cares.
  **/
-static void max1363_poll_func_th(struct iio_dev *indio_dev)
+static void max1363_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
        struct max1363_state *st = indio_dev->dev_data;
 
@@ -151,7 +122,7 @@ static void max1363_poll_func_th(struct iio_dev *indio_dev)
        return;
 }
 /**
- * max1363_poll_bh_to_ring() bh of trigger launched polling to ring buffer
+ * max1363_poll_bh_to_ring() bh of trigger launched polling to ring buffer
  * @work_s:    the work struct through which this was scheduled
  *
  * Currently there is no option in this driver to disable the saving of
@@ -223,19 +194,14 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
        }
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
+       if (ret)
                goto error_deallocate_sw_rb;
-       }
-       /* Configure the polling function called on trigger interrupts */
-       indio_dev->pollfunc->poll_func_main = &max1363_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
 
        /* Ring buffer functions - here trigger setup related */
-       indio_dev->ring->postenable = &max1363_ring_postenable;
+       indio_dev->ring->postenable = &iio_triggered_ring_postenable;
        indio_dev->ring->preenable = &max1363_ring_preenable;
-       indio_dev->ring->predisable = &max1363_ring_predisable;
+       indio_dev->ring->predisable = &iio_triggered_ring_predisable;
        INIT_WORK(&st->poll_work, &max1363_poll_bh_to_ring);
 
        /* Flag that polled ring buffering is possible */
@@ -258,13 +224,3 @@ void max1363_ring_cleanup(struct iio_dev *indio_dev)
        kfree(indio_dev->pollfunc);
        iio_sw_rb_free(indio_dev->ring);
 }
-
-void max1363_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-};
-
-int max1363_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-};
index 3f96f8696a412fa815e7fd90de245ea616b0457e..fd23bd1ea7b6962d795f023d927e4e98ed927952 100644 (file)
@@ -73,8 +73,6 @@ struct iio_shared_ev_pointer {
  * @det_events:                list of detected events
  * @max_events:                maximum number of events before new ones are dropped
  * @current_events:    number of events in detected list
- * @id:                        indentifier to allow the event interface to know which
- *                     physical line it corresponds to
  * @attr:              this chrdev's minor number sysfs attribute
  * @owner:             ensure the driver module owns the file, not iio
  * @private:           driver specific data
@@ -90,7 +88,6 @@ struct iio_event_interface {
        struct iio_detected_event_list          det_events;
        int                                     max_events;
        int                                     current_events;
-       int                                     id;
        struct iio_chrdev_minor_attr            attr;
        struct module                           *owner;
        void                                    *private;
index 6d2c547686cb2a4c82ee97299e3028966263ab49..b5f0dc01122c8b149fc9c42b0efc8c6e6529684d 100644 (file)
@@ -1,4 +1,4 @@
-
+#
 # Makefile for digital gyroscope sensor drivers
 #
 
index f19efb4c91ceb031a5c20b7c9671ea76742efc40..812440af57d694eb2893294105691330bd421e6d 100644 (file)
@@ -85,7 +85,6 @@
  * struct adis16260_state - device instance specific data
  * @us:                        actual spi_device
  * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
  * @inter:             used to check if new interrupt has been triggered
  * @last_timestamp:    passing timestamp from th to bh of interrupt handler
  * @indio_dev:         industrial I/O device structure
@@ -97,7 +96,6 @@
 struct adis16260_state {
        struct spi_device               *us;
        struct work_struct              work_trigger_to_ring;
-       struct iio_work_cont            work_cont_thresh;
        s64                             last_timestamp;
        struct iio_dev                  *indio_dev;
        struct iio_trigger              *trig;
@@ -113,13 +111,11 @@ int adis16260_set_irq(struct device *dev, bool enable);
  * filling. This may change!
  */
 
-enum adis16260_scan {
-       ADIS16260_SCAN_SUPPLY,
-       ADIS16260_SCAN_GYRO,
-       ADIS16260_SCAN_AUX_ADC,
-       ADIS16260_SCAN_TEMP,
-       ADIS16260_SCAN_ANGL,
-};
+#define ADIS16260_SCAN_SUPPLY  0
+#define ADIS16260_SCAN_GYRO    1
+#define ADIS16260_SCAN_AUX_ADC 2
+#define ADIS16260_SCAN_TEMP    3
+#define ADIS16260_SCAN_ANGL    4
 
 void adis16260_remove_trigger(struct iio_dev *indio_dev);
 int adis16260_probe_trigger(struct iio_dev *indio_dev);
@@ -132,8 +128,6 @@ ssize_t adis16260_read_data_from_ring(struct device *dev,
 int adis16260_configure_ring(struct iio_dev *indio_dev);
 void adis16260_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16260_initialize_ring(struct iio_ring_buffer *ring);
-void adis16260_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16260_remove_trigger(struct iio_dev *indio_dev)
@@ -162,14 +156,5 @@ static inline void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
 {
 }
 
-static inline int adis16260_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return 0;
-}
-
-static inline void adis16260_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16260_H_ */
index c93f4d580fce618c20f0599efc19f73fefcf3d9b..134dfaae2f0cd982ae493d9865ecc5c4ab57c80b 100644 (file)
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
-
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "../adc/adc.h"
 #include "gyro.h"
 
@@ -555,8 +556,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
        if (ret)
                goto error_unreg_ring_funcs;
        regdone = 1;
-
-       ret = adis16260_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
        if (ret) {
                printk(KERN_ERR "failed to initialize the ring\n");
                goto error_unreg_ring_funcs;
@@ -588,7 +588,7 @@ error_unregister_line:
        if (spi->irq)
                iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-       adis16260_uninitialize_ring(st->indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
        adis16260_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -622,15 +622,13 @@ static int adis16260_remove(struct spi_device *spi)
        if (spi->irq)
                iio_unregister_interrupt_line(indio_dev, 0);
 
-       adis16260_uninitialize_ring(indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
        iio_device_unregister(indio_dev);
        adis16260_unconfigure_ring(indio_dev);
        kfree(st->tx);
        kfree(st->rx);
        kfree(st);
 
-       return 0;
-
 err_ret:
        return ret;
 }
index 4c4390ca6d73c1b845448a464d23e56774c50270..9ef7f9080dcd6a7f63cb67a1b43e65ea77677bed 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../trigger.h"
 #include "adis16260.h"
 
-/**
- * combine_8_to_16() utility function to munge to u8s into u16
- **/
-static inline u16 combine_8_to_16(u8 lower, u8 upper)
-{
-       u16 _lower = lower;
-       u16 _upper = upper;
-       return _lower | (_upper << 8);
-}
-
 static IIO_SCAN_EL_C(supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12),
                ADIS16260_SUPPLY_OUT, NULL);
 static IIO_SCAN_EL_C(gyro, ADIS16260_SCAN_GYRO, IIO_SIGNED(14),
@@ -58,10 +49,10 @@ static struct attribute_group adis16260_scan_el_group = {
  * adis16260_poll_func_th() top half interrupt handler called by trigger
  * @private_data:      iio_dev
  **/
-static void adis16260_poll_func_th(struct iio_dev *indio_dev)
+static void adis16260_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
        struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
-       st->last_timestamp = indio_dev->trig->timestamp;
+       st->last_timestamp = time;
        schedule_work(&st->work_trigger_to_ring);
 }
 
@@ -133,10 +124,9 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
 
        if (st->indio_dev->scan_count)
                if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++) {
-                               data[i] = combine_8_to_16(st->rx[i*2+1],
-                                               st->rx[i*2]);
-                       }
+                       for (; i < st->indio_dev->scan_count; i++)
+                               data[i] = be16_to_cpup(
+                                       (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
        if (st->indio_dev->scan_timestamp)
@@ -152,48 +142,6 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
        return;
 }
 
-static int adis16260_data_rdy_ring_preenable(struct iio_dev *indio_dev)
-{
-       size_t size;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-       /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
-               return -EINVAL;
-
-       if (indio_dev->ring->access.set_bpd) {
-               if (indio_dev->scan_timestamp)
-                       if (indio_dev->scan_count)
-                               /* Timestamp (aligned s64) and data */
-                               size = (((indio_dev->scan_count * sizeof(s16))
-                                               + sizeof(s64) - 1)
-                                       & ~(sizeof(s64) - 1))
-                                       + sizeof(s64);
-                       else /* Timestamp only  */
-                               size = sizeof(s64);
-               else /* Data only */
-                       size = indio_dev->scan_count*sizeof(s16);
-               indio_dev->ring->access.set_bpd(indio_dev->ring, size);
-       }
-
-       return 0;
-}
-
-static int adis16260_data_rdy_ring_postenable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_attach_poll_func(indio_dev->trig,
-                               indio_dev->pollfunc)
-               : 0;
-}
-
-static int adis16260_data_rdy_ring_predisable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_dettach_poll_func(indio_dev->trig,
-                               indio_dev->pollfunc)
-               : 0;
-}
-
 void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
 {
        kfree(indio_dev->pollfunc);
@@ -225,18 +173,16 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
        indio_dev->ring = ring;
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
-       ring->preenable = &adis16260_data_rdy_ring_preenable;
-       ring->postenable = &adis16260_data_rdy_ring_postenable;
-       ring->predisable = &adis16260_data_rdy_ring_predisable;
+       ring->bpe = 2;
+       ring->preenable = &iio_sw_ring_preenable;
+       ring->postenable = &iio_triggered_ring_postenable;
+       ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
-               goto error_iio_sw_rb_free;;
-       }
-       indio_dev->pollfunc->poll_func_main = &adis16260_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16260_poll_func_th);
+       if (ret)
+               goto error_iio_sw_rb_free;
+
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
 
@@ -244,13 +190,3 @@ error_iio_sw_rb_free:
        iio_sw_rb_free(indio_dev->ring);
        return ret;
 }
-
-int adis16260_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16260_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-}
index b3c565942b8d3f5bd5206b121a7e3a319e2ac9bf..de01537d257eb710f3e0b61eec86228d2b83797e 100644 (file)
@@ -23,8 +23,7 @@ static int adis16260_data_rdy_trig_poll(struct iio_dev *dev_info,
        struct adis16260_state *st = iio_dev_get_devdata(dev_info);
        struct iio_trigger *trig = st->trig;
 
-       trig->timestamp = timestamp;
-       iio_trigger_poll(trig);
+       iio_trigger_poll(trig, timestamp);
 
        return IRQ_HANDLED;
 }
@@ -83,14 +82,13 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev)
        struct adis16260_state *st = indio_dev->dev_data;
 
        st->trig = iio_allocate_trigger();
-       st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+       st->trig->name = kasprintf(GFP_KERNEL,
+                                  "adis16260-dev%d",
+                                  indio_dev->id);
        if (!st->trig->name) {
                ret = -ENOMEM;
                goto error_free_trig;
        }
-       snprintf((char *)st->trig->name,
-                IIO_TRIGGER_NAME_LENGTH,
-                "adis16260-dev%d", indio_dev->id);
        st->trig->dev.parent = &st->us->dev;
        st->trig->owner = THIS_MODULE;
        st->trig->private_data = st;
index fcee47cbe894e34d658cbdb7ad26339d4013e6f2..9d0ca128679ea8fbc569b6a9b00ab5fe5a852ca7 100644 (file)
@@ -16,9 +16,7 @@
 #include "chrdev.h"
 
 /* IIO TODO LIST */
-/* Static device specific elements (conversion factors etc)
- * should be exported via sysfs
- *
+/*
  * Provide means of adjusting timer accuracy.
  * Currently assumes nano seconds.
  */
@@ -283,49 +281,6 @@ int iio_push_event(struct iio_dev *dev_info,
                  int ev_code,
                  s64 timestamp);
 
-/**
- * struct iio_work_cont - container for when singleton handler case matters
- * @ws:                        [DEVICE] work_struct when not only possible event
- * @ws_nocheck:                [DEVICE] work_struct when only possible event
- * @address:           [DEVICE] associated register address
- * @mask:              [DEVICE] associated mask for identifying event source
- * @st:                        [DEVICE] device specific state information
- **/
-struct iio_work_cont {
-       struct work_struct      ws;
-       struct work_struct      ws_nocheck;
-       int                     address;
-       int                     mask;
-       void                    *st;
-};
-
-#define to_iio_work_cont_check(_ws)                    \
-       container_of(_ws, struct iio_work_cont, ws)
-
-#define to_iio_work_cont_no_check(_ws)                         \
-       container_of(_ws, struct iio_work_cont, ws_nocheck)
-
-/**
- * iio_init_work_cont() - intiialize the elements of a work container
- * @cont: the work container
- * @_checkfunc: function called when there are multiple possible int sources
- * @_nocheckfunc: function for when there is only one int source
- * @_add: driver dependent, typically a register address
- * @_mask: driver dependent, typically a bit mask for a register
- * @_st: driver dependent, typically pointer to a device state structure
- **/
-static inline void
-iio_init_work_cont(struct iio_work_cont *cont,
-                  void (*_checkfunc)(struct work_struct *),
-                  void (*_nocheckfunc)(struct work_struct *),
-                  int _add, int _mask, void *_st)
-{
-       INIT_WORK(&(cont)->ws, _checkfunc);
-       INIT_WORK(&(cont)->ws_nocheck, _nocheckfunc);
-       cont->address = _add;
-       cont->mask = _mask;
-       cont->st = _st;
-}
 /**
  * __iio_push_event() - tries to add an event to the list associated with a chrdev
  * @ev_int:            the event interface to which we are pushing the event
@@ -428,7 +383,9 @@ void iio_put(void);
  **/
 void iio_get(void);
 
-/* Ring buffer related */
+/**
+ * iio_device_get_chrdev_minor() - get an unused minor number
+ **/
 int iio_device_get_chrdev_minor(void);
 void iio_device_free_chrdev_minor(int val);
 
index 6308d6faad57db0ee957bdb73f6b08ee6efb4c2c..31a6233a2068123df6f9fce8f2bf38fc3bd8cf2e 100644 (file)
@@ -6,9 +6,8 @@ comment "Inertial measurement units"
 config ADIS16300
        tristate "Analog Devices ADIS16300 IMU SPI driver"
        depends on SPI
-       select IIO_SW_RING
-       select IIO_RING_BUFFER
-       select IIO_TRIGGER
+       select IIO_SW_RING if IIO_RING_BUFFER
+       select IIO_TRIGGER if IIO_RING_BUFFER
        help
          Say yes here to build support for Analog Devices adis16300 four degrees
          of freedom inertial sensor.
@@ -24,10 +23,9 @@ config ADIS16350
 
 config ADIS16400
        tristate "Analog Devices ADIS16400/5 IMU SPI driver"
-       depends on SPI
-       select IIO_SW_RING
-       select IIO_RING_BUFFER
-       select IIO_TRIGGER
-       help
-         Say yes here to build support for Analog Devices adis16400/5 triaxial
-         inertial sensor with Magnetometer.
\ No newline at end of file
+       depends on SPI
+       select IIO_SW_RING if IIO_RING_BUFFER
+       select IIO_TRIGGER if IIO_RING_BUFFER
+       help
+         Say yes here to build support for Analog Devices adis16400/5 triaxial
+         inertial sensor with Magnetometer.
index 31df7359e20f3e22fe6536948cb3220e91f5f212..f3b450b6611350a90909bbb48ae20c1ed79b2ec0 100644 (file)
@@ -1,6 +1,7 @@
 #
 # Makefile for Inertial Measurement Units
 #
+
 adis16300-y             := adis16300_core.o
 adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o
 obj-$(CONFIG_ADIS16300) += adis16300.o
@@ -11,4 +12,4 @@ obj-$(CONFIG_ADIS16350) += adis16350.o
 
 adis16400-y             := adis16400_core.o
 adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o
-obj-$(CONFIG_ADIS16400) += adis16400.o
\ No newline at end of file
+obj-$(CONFIG_ADIS16400) += adis16400.o
index 1c7ea5c840efd2b4f35d0d92742c8d444789768d..1f25d68064a027105bc262e0433cceec473819bf 100644 (file)
@@ -94,7 +94,6 @@
  * struct adis16300_state - device instance specific data
  * @us:                        actual spi_device
  * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
  * @inter:             used to check if new interrupt has been triggered
  * @last_timestamp:    passing timestamp from th to bh of interrupt handler
  * @indio_dev:         industrial I/O device structure
 struct adis16300_state {
        struct spi_device               *us;
        struct work_struct              work_trigger_to_ring;
-       struct iio_work_cont            work_cont_thresh;
        s64                             last_timestamp;
        struct iio_dev                  *indio_dev;
        struct iio_trigger              *trig;
@@ -115,30 +113,22 @@ struct adis16300_state {
        struct mutex                    buf_lock;
 };
 
-int adis16300_spi_read_burst(struct device *dev, u8 *rx);
-
 int adis16300_set_irq(struct device *dev, bool enable);
 
-int adis16300_reset(struct device *dev);
-
-int adis16300_check_status(struct device *dev);
-
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
  * filling. This may change!
  */
 
-enum adis16300_scan {
-       ADIS16300_SCAN_SUPPLY,
-       ADIS16300_SCAN_GYRO_X,
-       ADIS16300_SCAN_ACC_X,
-       ADIS16300_SCAN_ACC_Y,
-       ADIS16300_SCAN_ACC_Z,
-       ADIS16300_SCAN_TEMP,
-       ADIS16300_SCAN_ADC_0,
-       ADIS16300_SCAN_INCLI_X,
-       ADIS16300_SCAN_INCLI_Y,
-};
+#define ADIS16300_SCAN_SUPPLY  0
+#define ADIS16300_SCAN_GYRO_X  1
+#define ADIS16300_SCAN_ACC_X   2
+#define ADIS16300_SCAN_ACC_Y   3
+#define ADIS16300_SCAN_ACC_Z   4
+#define ADIS16300_SCAN_TEMP    5
+#define ADIS16300_SCAN_ADC_0   6
+#define ADIS16300_SCAN_INCLI_X 7
+#define ADIS16300_SCAN_INCLI_Y 8
 
 void adis16300_remove_trigger(struct iio_dev *indio_dev);
 int adis16300_probe_trigger(struct iio_dev *indio_dev);
index 5a7e5ef9bc5d5e64037d296c2e947c570baa8e4d..f1950d56cb1f24a425f4305af831f26497d0f560 100644 (file)
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
-
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "../accel/accel.h"
 #include "../accel/inclinometer.h"
 #include "../gyro/gyro.h"
 
 #define DRIVER_NAME            "adis16300"
 
-/* At the moment the spi framework doesn't allow global setting of cs_change.
- * It's in the likely to be added comment at the top of spi.h.
- * This means that use cannot be made of spi_write etc.
- */
+static int adis16300_check_status(struct device *dev);
 
 /**
  * adis16300_spi_write_reg_8() - write single byte to a register
@@ -79,11 +77,13 @@ static int adis16300_spi_write_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
+                       .delay_usecs = 75,
                }, {
                        .tx_buf = st->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
+                       .delay_usecs = 75,
                },
        };
 
@@ -122,12 +122,14 @@ static int adis16300_spi_read_reg_16(struct device *dev,
                        .tx_buf = st->tx,
                        .bits_per_word = 8,
                        .len = 2,
-                       .cs_change = 0,
+                       .cs_change = 1,
+                       .delay_usecs = 75,
                }, {
                        .rx_buf = st->rx,
                        .bits_per_word = 8,
                        .len = 2,
-                       .cs_change = 0,
+                       .cs_change = 1,
+                       .delay_usecs = 75,
                },
        };
 
@@ -154,54 +156,6 @@ error_ret:
        return ret;
 }
 
-/**
- * adis16300_spi_read_burst() - read all data registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-int adis16300_spi_read_burst(struct device *dev, u8 *rx)
-{
-       struct spi_message msg;
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-       u32 old_speed_hz = st->us->max_speed_hz;
-       int ret;
-
-       struct spi_transfer xfers[] = {
-               {
-                       .tx_buf = st->tx,
-                       .bits_per_word = 8,
-                       .len = 2,
-                       .cs_change = 0,
-               }, {
-                       .rx_buf = rx,
-                       .bits_per_word = 8,
-                       .len = 18,
-                       .cs_change = 0,
-               },
-       };
-
-       mutex_lock(&st->buf_lock);
-       st->tx[0] = ADIS16300_READ_REG(ADIS16300_GLOB_CMD);
-       st->tx[1] = 0;
-
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-
-       st->us->max_speed_hz = min(ADIS16300_SPI_BURST, old_speed_hz);
-       spi_setup(st->us);
-
-       ret = spi_sync(st->us, &msg);
-       if (ret)
-               dev_err(&st->us->dev, "problem when burst reading");
-
-       st->us->max_speed_hz = old_speed_hz;
-       spi_setup(st->us);
-       mutex_unlock(&st->buf_lock);
-       return ret;
-}
-
 static ssize_t adis16300_spi_read_signed(struct device *dev,
                struct device_attribute *attr,
                char *buf,
@@ -240,6 +194,24 @@ static ssize_t adis16300_read_12bit_unsigned(struct device *dev,
        return sprintf(buf, "%u\n", val & 0x0FFF);
 }
 
+static ssize_t adis16300_read_14bit_unsigned(struct device *dev,
+               struct device_attribute *attr,
+               char *buf)
+{
+       int ret;
+       u16 val = 0;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+       ret = adis16300_spi_read_reg_16(dev, this_attr->address, &val);
+       if (ret)
+               return ret;
+
+       if (val & ADIS16300_ERROR_ACTIVE)
+               adis16300_check_status(dev);
+
+       return sprintf(buf, "%u\n", val & 0x3FFF);
+}
+
 static ssize_t adis16300_read_14bit_signed(struct device *dev,
                struct device_attribute *attr,
                char *buf)
@@ -356,6 +328,18 @@ static ssize_t adis16300_write_frequency(struct device *dev,
        return ret ? ret : len;
 }
 
+static int adis16300_reset(struct device *dev)
+{
+       int ret;
+       ret = adis16300_spi_write_reg_8(dev,
+                       ADIS16300_GLOB_CMD,
+                       ADIS16300_GLOB_CMD_SW_RESET);
+       if (ret)
+               dev_err(dev, "problem resetting device");
+
+       return ret;
+}
+
 static ssize_t adis16300_write_reset(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t len)
@@ -371,8 +355,6 @@ static ssize_t adis16300_write_reset(struct device *dev,
        return -1;
 }
 
-
-
 int adis16300_set_irq(struct device *dev, bool enable)
 {
        int ret;
@@ -396,32 +378,37 @@ error_ret:
        return ret;
 }
 
-int adis16300_reset(struct device *dev)
+/* Power down the device */
+static int adis16300_stop_device(struct device *dev)
 {
        int ret;
-       ret = adis16300_spi_write_reg_8(dev,
-                       ADIS16300_GLOB_CMD,
-                       ADIS16300_GLOB_CMD_SW_RESET);
+       u16 val = ADIS16300_SLP_CNT_POWER_OFF;
+
+       ret = adis16300_spi_write_reg_16(dev, ADIS16300_SLP_CNT, val);
        if (ret)
-               dev_err(dev, "problem resetting device");
+               dev_err(dev, "problem with turning device off: SLP_CNT");
 
        return ret;
 }
 
-/* Power down the device */
-static int adis16300_stop_device(struct device *dev)
+static int adis16300_self_test(struct device *dev)
 {
        int ret;
-       u16 val = ADIS16300_SLP_CNT_POWER_OFF;
+       ret = adis16300_spi_write_reg_16(dev,
+                       ADIS16300_MSC_CTRL,
+                       ADIS16300_MSC_CTRL_MEM_TEST);
+       if (ret) {
+               dev_err(dev, "problem starting self test");
+               goto err_ret;
+       }
 
-       ret = adis16300_spi_write_reg_16(dev, ADIS16300_SLP_CNT, val);
-       if (ret)
-               dev_err(dev, "problem with turning device off: SLP_CNT");
+       adis16300_check_status(dev);
 
+err_ret:
        return ret;
 }
 
-int adis16300_check_status(struct device *dev)
+static int adis16300_check_status(struct device *dev)
 {
        u16 status;
        int ret;
@@ -483,6 +470,11 @@ static int adis16300_initial_setup(struct adis16300_state *st)
        }
 
        /* Do self test */
+       ret = adis16300_self_test(dev);
+       if (ret) {
+               dev_err(dev, "self test failure");
+               goto err_ret;
+       }
 
        /* Read status register to check the result */
        ret = adis16300_check_status(dev);
@@ -526,7 +518,7 @@ static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
                adis16300_write_16bit,
                ADIS16300_ZACCL_OFF);
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16300_read_14bit_signed,
+static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16300_read_14bit_unsigned,
                           ADIS16300_SUPPLY_OUT);
 static IIO_CONST_ATTR(in_supply_scale, "0.00242");
 
@@ -548,7 +540,7 @@ static IIO_DEV_ATTR_INCLI_Y(adis16300_read_13bit_signed,
                ADIS16300_YINCLI_OUT);
 static IIO_CONST_ATTR(incli_scale, "0.044 d");
 
-static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_signed);
+static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
 static IIO_CONST_ATTR(temp_offset, "198.16 K");
 static IIO_CONST_ATTR(temp_scale, "0.14 K");
 
@@ -653,21 +645,13 @@ static int __devinit adis16300_probe(struct spi_device *spi)
                goto error_unreg_ring_funcs;
        regdone = 1;
 
-       ret = adis16300_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
        if (ret) {
                printk(KERN_ERR "failed to initialize the ring\n");
                goto error_unreg_ring_funcs;
        }
 
-       if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-#if 0 /* fixme: here we should support */
-               iio_init_work_cont(&st->work_cont_thresh,
-                               NULL,
-                               adis16300_thresh_handler_bh_no_check,
-                               0,
-                               0,
-                               st);
-#endif
+       if (spi->irq) {
                ret = iio_register_interrupt_line(spi->irq,
                                st->indio_dev,
                                0,
@@ -688,13 +672,12 @@ static int __devinit adis16300_probe(struct spi_device *spi)
        return 0;
 
 error_remove_trigger:
-       if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-               adis16300_remove_trigger(st->indio_dev);
+       adis16300_remove_trigger(st->indio_dev);
 error_unregister_line:
-       if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+       if (spi->irq)
                iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-       adis16300_uninitialize_ring(st->indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
        adis16300_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -712,7 +695,6 @@ error_ret:
        return ret;
 }
 
-/* fixme, confirm ordering in this function */
 static int adis16300_remove(struct spi_device *spi)
 {
        int ret;
@@ -726,12 +708,12 @@ static int adis16300_remove(struct spi_device *spi)
        flush_scheduled_work();
 
        adis16300_remove_trigger(indio_dev);
-       if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+       if (spi->irq)
                iio_unregister_interrupt_line(indio_dev, 0);
 
-       adis16300_uninitialize_ring(indio_dev->ring);
-       adis16300_unconfigure_ring(indio_dev);
+       iio_ring_buffer_unregister(indio_dev->ring);
        iio_device_unregister(indio_dev);
+       adis16300_unconfigure_ring(indio_dev);
        kfree(st->tx);
        kfree(st->rx);
        kfree(st);
index 76cf8a6f3c3f2365305bacf4171d25146bf59c83..fc93160acb26a163fed157cc0c564b9f238d8b48 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../trigger.h"
 #include "adis16300.h"
 
-/**
- * combine_8_to_16() utility function to munge to u8s into u16
- **/
-static inline u16 combine_8_to_16(u8 lower, u8 upper)
-{
-       u16 _lower = lower;
-       u16 _upper = upper;
-       return _lower | (_upper << 8);
-}
-
-static IIO_SCAN_EL_C(supply, ADIS16300_SCAN_SUPPLY, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(supply, ADIS16300_SCAN_SUPPLY, IIO_UNSIGNED(14),
                     ADIS16300_SUPPLY_OUT, NULL);
 
 static IIO_SCAN_EL_C(gyro_x, ADIS16300_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -39,9 +30,9 @@ static IIO_SCAN_EL_C(accel_y, ADIS16300_SCAN_ACC_Y, IIO_SIGNED(14),
 static IIO_SCAN_EL_C(accel_z, ADIS16300_SCAN_ACC_Z, IIO_SIGNED(14),
                     ADIS16300_ZACCL_OUT, NULL);
 
-static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, IIO_SIGNED(12),
+static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, IIO_UNSIGNED(12),
                     ADIS16300_TEMP_OUT, NULL);
-static IIO_SCAN_EL_C(adc_0, ADIS16300_SCAN_ADC_0, IIO_SIGNED(12),
+static IIO_SCAN_EL_C(adc_0, ADIS16300_SCAN_ADC_0, IIO_UNSIGNED(12),
                     ADIS16300_AUX_ADC, NULL);
 
 static IIO_SCAN_EL_C(incli_x, ADIS16300_SCAN_INCLI_X, IIO_SIGNED(12),
@@ -74,10 +65,10 @@ static struct attribute_group adis16300_scan_el_group = {
  * adis16300_poll_func_th() top half interrupt handler called by trigger
  * @private_data:      iio_dev
  **/
-static void adis16300_poll_func_th(struct iio_dev *indio_dev)
+static void adis16300_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
        struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-       st->last_timestamp = indio_dev->trig->timestamp;
+       st->last_timestamp = time;
        schedule_work(&st->work_trigger_to_ring);
        /* Indicate that this interrupt is being handled */
 
@@ -87,6 +78,54 @@ static void adis16300_poll_func_th(struct iio_dev *indio_dev)
         */
 }
 
+/**
+ * adis16300_spi_read_burst() - read all data registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @rx: somewhere to pass back the value read (min size is 24 bytes)
+ **/
+static int adis16300_spi_read_burst(struct device *dev, u8 *rx)
+{
+       struct spi_message msg;
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
+       u32 old_speed_hz = st->us->max_speed_hz;
+       int ret;
+
+       struct spi_transfer xfers[] = {
+               {
+                       .tx_buf = st->tx,
+                       .bits_per_word = 8,
+                       .len = 2,
+                       .cs_change = 0,
+               }, {
+                       .rx_buf = rx,
+                       .bits_per_word = 8,
+                       .len = 18,
+                       .cs_change = 0,
+               },
+       };
+
+       mutex_lock(&st->buf_lock);
+       st->tx[0] = ADIS16300_READ_REG(ADIS16300_GLOB_CMD);
+       st->tx[1] = 0;
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfers[0], &msg);
+       spi_message_add_tail(&xfers[1], &msg);
+
+       st->us->max_speed_hz = ADIS16300_SPI_BURST;
+       spi_setup(st->us);
+
+       ret = spi_sync(st->us, &msg);
+       if (ret)
+               dev_err(&st->us->dev, "problem when burst reading");
+
+       st->us->max_speed_hz = old_speed_hz;
+       spi_setup(st->us);
+       mutex_unlock(&st->buf_lock);
+       return ret;
+}
+
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
@@ -109,10 +148,9 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
 
        if (st->indio_dev->scan_count)
                if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++) {
-                               data[i] = combine_8_to_16(st->rx[i*2+1],
-                                                         st->rx[i*2]);
-                       }
+                       for (; i < st->indio_dev->scan_count; i++)
+                               data[i] = be16_to_cpup(
+                                       (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
        if (st->indio_dev->scan_timestamp)
@@ -127,45 +165,6 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
 
        return;
 }
-/* in these circumstances is it better to go with unaligned packing and
- * deal with the cost?*/
-static int adis16300_data_rdy_ring_preenable(struct iio_dev *indio_dev)
-{
-       size_t size;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-       /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
-               return -EINVAL;
-
-       if (indio_dev->ring->access.set_bpd) {
-               if (indio_dev->scan_timestamp)
-                       if (indio_dev->scan_count) /* Timestamp and data */
-                               size = 4*sizeof(s64);
-                       else /* Timestamp only  */
-                               size = sizeof(s64);
-               else /* Data only */
-                       size = indio_dev->scan_count*sizeof(s16);
-               indio_dev->ring->access.set_bpd(indio_dev->ring, size);
-       }
-
-       return 0;
-}
-
-static int adis16300_data_rdy_ring_postenable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_attach_poll_func(indio_dev->trig,
-                                              indio_dev->pollfunc)
-               : 0;
-}
-
-static int adis16300_data_rdy_ring_predisable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_dettach_poll_func(indio_dev->trig,
-                                               indio_dev->pollfunc)
-               : 0;
-}
 
 void adis16300_unconfigure_ring(struct iio_dev *indio_dev)
 {
@@ -202,18 +201,16 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
        indio_dev->ring = ring;
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
-       ring->preenable = &adis16300_data_rdy_ring_preenable;
-       ring->postenable = &adis16300_data_rdy_ring_postenable;
-       ring->predisable = &adis16300_data_rdy_ring_predisable;
+       ring->bpe = 2;
+       ring->preenable = &iio_sw_ring_preenable;
+       ring->postenable = &iio_triggered_ring_postenable;
+       ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
-               goto error_iio_sw_rb_free;;
-       }
-       indio_dev->pollfunc->poll_func_main = &adis16300_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16300_poll_func_th);
+       if (ret)
+               goto error_iio_sw_rb_free;
+
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
 
@@ -222,12 +219,3 @@ error_iio_sw_rb_free:
        return ret;
 }
 
-int adis16300_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16300_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-}
index 54edb20bf119d8739f117e08754b3adb86e30741..64036cd99102fac1f6b933bf1eb5599d36cd8f89 100644 (file)
@@ -23,8 +23,7 @@ static int adis16300_data_rdy_trig_poll(struct iio_dev *dev_info,
        struct adis16300_state *st = iio_dev_get_devdata(dev_info);
        struct iio_trigger *trig = st->trig;
 
-       trig->timestamp = timestamp;
-       iio_trigger_poll(trig);
+       iio_trigger_poll(trig, timestamp);
 
        return IRQ_HANDLED;
 }
@@ -86,14 +85,13 @@ int adis16300_probe_trigger(struct iio_dev *indio_dev)
        struct adis16300_state *st = indio_dev->dev_data;
 
        st->trig = iio_allocate_trigger();
-       st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+       st->trig->name = kasprintf(GFP_KERNEL,
+                                  "adis16300-dev%d",
+                                  indio_dev->id);
        if (!st->trig->name) {
                ret = -ENOMEM;
                goto error_free_trig;
        }
-       snprintf((char *)st->trig->name,
-                IIO_TRIGGER_NAME_LENGTH,
-                "adis16300-dev%d", indio_dev->id);
        st->trig->dev.parent = &st->us->dev;
        st->trig->owner = THIS_MODULE;
        st->trig->private_data = st;
index 334b18ace38e1632f2da99dca72bb81e7e964cb3..b00001e3edd0ba660610bc505eaaad1fd96fcce9 100644 (file)
  * struct adis16350_state - device instance specific data
  * @us:                        actual spi_device
  * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
  * @inter:             used to check if new interrupt has been triggered
  * @last_timestamp:    passing timestamp from th to bh of interrupt handler
  * @indio_dev:         industrial I/O device structure
 struct adis16350_state {
        struct spi_device               *us;
        struct work_struct              work_trigger_to_ring;
-       struct iio_work_cont            work_cont_data_rdy;
        s64                             last_timestamp;
        struct iio_dev                  *indio_dev;
        struct iio_trigger              *trig;
@@ -125,19 +123,17 @@ int adis16350_set_irq(struct device *dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 
-enum adis16350_scan {
-       ADIS16350_SCAN_SUPPLY,
-       ADIS16350_SCAN_GYRO_X,
-       ADIS16350_SCAN_GYRO_Y,
-       ADIS16350_SCAN_GYRO_Z,
-       ADIS16350_SCAN_ACC_X,
-       ADIS16350_SCAN_ACC_Y,
-       ADIS16350_SCAN_ACC_Z,
-       ADIS16350_SCAN_TEMP_X,
-       ADIS16350_SCAN_TEMP_Y,
-       ADIS16350_SCAN_TEMP_Z,
-       ADIS16350_SCAN_ADC_0
-};
+#define ADIS16350_SCAN_SUPPLY  0
+#define ADIS16350_SCAN_GYRO_X  1
+#define ADIS16350_SCAN_GYRO_Y  2
+#define ADIS16350_SCAN_GYRO_Z  3
+#define ADIS16350_SCAN_ACC_X   4
+#define ADIS16350_SCAN_ACC_Y   5
+#define ADIS16350_SCAN_ACC_Z   6
+#define ADIS16350_SCAN_TEMP_X  7
+#define ADIS16350_SCAN_TEMP_Y  8
+#define ADIS16350_SCAN_TEMP_Z  9
+#define ADIS16350_SCAN_ADC_0   10
 
 void adis16350_remove_trigger(struct iio_dev *indio_dev);
 int adis16350_probe_trigger(struct iio_dev *indio_dev);
@@ -150,8 +146,6 @@ ssize_t adis16350_read_data_from_ring(struct device *dev,
 int adis16350_configure_ring(struct iio_dev *indio_dev);
 void adis16350_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16350_initialize_ring(struct iio_ring_buffer *ring);
-void adis16350_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16350_remove_trigger(struct iio_dev *indio_dev)
@@ -171,7 +165,7 @@ adis16350_read_data_from_ring(struct device *dev,
        return 0;
 }
 
-static int adis16350_configure_ring(struct iio_dev *indio_dev)
+static inline int adis16350_configure_ring(struct iio_dev *indio_dev)
 {
        return 0;
 }
@@ -179,15 +173,5 @@ static int adis16350_configure_ring(struct iio_dev *indio_dev)
 static inline void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
 {
 }
-
-static inline int adis16350_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return 0;
-}
-
-static inline void adis16350_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16350_H_ */
index 0edde73ce5c244f281a7c7dbe3e403981444b766..1575b7b5d44faf0006798e45f1288e1c59262e41 100644 (file)
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
-
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "../accel/accel.h"
 #include "../adc/adc.h"
 #include "../gyro/gyro.h"
@@ -75,13 +76,13 @@ static int adis16350_spi_write_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                }, {
                        .tx_buf = st->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                },
        };
 
@@ -121,13 +122,13 @@ static int adis16350_spi_read_reg_16(struct device *dev,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                }, {
                        .rx_buf = st->rx,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = 25,
+                       .delay_usecs = 35,
                },
        };
 
@@ -619,7 +620,7 @@ static int __devinit adis16350_probe(struct spi_device *spi)
                goto error_unreg_ring_funcs;
        regdone = 1;
 
-       ret = adis16350_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
        if (ret) {
                printk(KERN_ERR "failed to initialize the ring\n");
                goto error_unreg_ring_funcs;
@@ -651,7 +652,7 @@ error_unregister_line:
        if (spi->irq)
                iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-       adis16350_uninitialize_ring(st->indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
        adis16350_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -685,7 +686,7 @@ static int adis16350_remove(struct spi_device *spi)
        if (spi->irq)
                iio_unregister_interrupt_line(indio_dev, 0);
 
-       adis16350_uninitialize_ring(indio_dev->ring);
+       iio_ring_buffer_unregister(indio_dev->ring);
        iio_device_unregister(indio_dev);
        adis16350_unconfigure_ring(indio_dev);
        kfree(st->tx);
index 5e9716ea7c77430ab29ad840bf572dbcc37843d4..e053e9aaa2edddb41335bc3b6350a89ab5322f38 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../trigger.h"
 #include "adis16350.h"
 
-/**
- * combine_8_to_16() utility function to munge to u8s into u16
- **/
-static inline u16 combine_8_to_16(u8 lower, u8 upper)
-{
-       u16 _lower = lower;
-       u16 _upper = upper;
-       return _lower | (_upper << 8);
-}
-
 static IIO_SCAN_EL_C(supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
                ADIS16350_SUPPLY_OUT, NULL);
 
@@ -80,10 +71,10 @@ static struct attribute_group adis16350_scan_el_group = {
  * adis16350_poll_func_th() top half interrupt handler called by trigger
  * @private_data:      iio_dev
  **/
-static void adis16350_poll_func_th(struct iio_dev *indio_dev)
+static void adis16350_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
        struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-       st->last_timestamp = indio_dev->trig->timestamp;
+       st->last_timestamp = time;
        schedule_work(&st->work_trigger_to_ring);
 }
 
@@ -157,10 +148,9 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
 
        if (st->indio_dev->scan_count)
                if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++) {
-                               data[i] = combine_8_to_16(st->rx[i*2+1],
-                                                         st->rx[i*2]);
-                       }
+                       for (; i < st->indio_dev->scan_count; i++)
+                               data[i] = be16_to_cpup(
+                                       (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
        if (st->indio_dev->scan_timestamp)
@@ -176,48 +166,6 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
        return;
 }
 
-static int adis16350_data_rdy_ring_preenable(struct iio_dev *indio_dev)
-{
-       size_t size;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-       /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
-               return -EINVAL;
-
-       if (indio_dev->ring->access.set_bpd) {
-               if (indio_dev->scan_timestamp)
-                       if (indio_dev->scan_count)
-                               /* Timestamp (aligned sizeof(s64) and data */
-                               size = (((indio_dev->scan_count * sizeof(s16))
-                                               + sizeof(s64) - 1)
-                                       & ~(sizeof(s64) - 1))
-                                       + sizeof(s64);
-                       else /* Timestamp only  */
-                               size = sizeof(s64);
-               else /* Data only */
-                       size = indio_dev->scan_count*sizeof(s16);
-               indio_dev->ring->access.set_bpd(indio_dev->ring, size);
-       }
-
-       return 0;
-}
-
-static int adis16350_data_rdy_ring_postenable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_attach_poll_func(indio_dev->trig,
-                                              indio_dev->pollfunc)
-               : 0;
-}
-
-static int adis16350_data_rdy_ring_predisable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_dettach_poll_func(indio_dev->trig,
-                                               indio_dev->pollfunc)
-               : 0;
-}
-
 void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
 {
        kfree(indio_dev->pollfunc);
@@ -255,18 +203,16 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
        indio_dev->ring = ring;
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
-       ring->preenable = &adis16350_data_rdy_ring_preenable;
-       ring->postenable = &adis16350_data_rdy_ring_postenable;
-       ring->predisable = &adis16350_data_rdy_ring_predisable;
+       ring->bpe = 2;
+       ring->preenable = &iio_sw_ring_preenable;
+       ring->postenable = &iio_triggered_ring_postenable;
+       ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
-               goto error_iio_sw_rb_free;;
-       }
-       indio_dev->pollfunc->poll_func_main = &adis16350_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
+       if (ret)
+               goto error_iio_sw_rb_free;
+
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
 
@@ -275,12 +221,3 @@ error_iio_sw_rb_free:
        return ret;
 }
 
-int adis16350_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16350_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-}
index 1ffa75d05fac31ef22945129a4f0ab09253ae5b7..76edccc85b71bac89ceae4d7b381183626fd22d1 100644 (file)
@@ -23,8 +23,7 @@ static int adis16350_data_rdy_trig_poll(struct iio_dev *dev_info,
        struct adis16350_state *st = iio_dev_get_devdata(dev_info);
        struct iio_trigger *trig = st->trig;
 
-       trig->timestamp = timestamp;
-       iio_trigger_poll(trig);
+       iio_trigger_poll(trig, timestamp);
 
        return IRQ_HANDLED;
 }
@@ -86,14 +85,13 @@ int adis16350_probe_trigger(struct iio_dev *indio_dev)
        struct adis16350_state *st = indio_dev->dev_data;
 
        st->trig = iio_allocate_trigger();
-       st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+       st->trig->name = kasprintf(GFP_KERNEL,
+                                  "adis16350-dev%d",
+                                  indio_dev->id);
        if (!st->trig->name) {
                ret = -ENOMEM;
                goto error_free_trig;
        }
-       snprintf((char *)st->trig->name,
-                IIO_TRIGGER_NAME_LENGTH,
-                "adis16350-dev%d", indio_dev->id);
        st->trig->dev.parent = &st->us->dev;
        st->trig->owner = THIS_MODULE;
        st->trig->private_data = st;
index 5a69a7ab91ce60de2570e4451a9ee2146f617091..6ff33e1ad8c19b871dd2897851ee5d3aa22c49f5 100644 (file)
  * struct adis16400_state - device instance specific data
  * @us:                        actual spi_device
  * @work_trigger_to_ring: bh for triggered event handling
- * @work_cont_thresh: CLEAN
  * @inter:             used to check if new interrupt has been triggered
  * @last_timestamp:    passing timestamp from th to bh of interrupt handler
  * @indio_dev:         industrial I/O device structure
 struct adis16400_state {
        struct spi_device               *us;
        struct work_struct              work_trigger_to_ring;
-       struct iio_work_cont            work_cont_thresh;
        s64                             last_timestamp;
        struct iio_dev                  *indio_dev;
        struct iio_trigger              *trig;
@@ -147,33 +145,25 @@ struct adis16400_state {
        struct mutex                    buf_lock;
 };
 
-int adis16400_spi_read_burst(struct device *dev, u8 *rx);
-
 int adis16400_set_irq(struct device *dev, bool enable);
 
-int adis16400_reset(struct device *dev);
-
-int adis16400_check_status(struct device *dev);
-
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
  * filling. This may change!
  */
 
-enum adis16400_scan {
-       ADIS16400_SCAN_SUPPLY,
-       ADIS16400_SCAN_GYRO_X,
-       ADIS16400_SCAN_GYRO_Y,
-       ADIS16400_SCAN_GYRO_Z,
-       ADIS16400_SCAN_ACC_X,
-       ADIS16400_SCAN_ACC_Y,
-       ADIS16400_SCAN_ACC_Z,
-       ADIS16400_SCAN_MAGN_X,
-       ADIS16400_SCAN_MAGN_Y,
-       ADIS16400_SCAN_MAGN_Z,
-       ADIS16400_SCAN_TEMP,
-       ADIS16400_SCAN_ADC_0
-};
+#define ADIS16400_SCAN_SUPPLY  0
+#define ADIS16400_SCAN_GYRO_X  1
+#define ADIS16400_SCAN_GYRO_Y  2
+#define ADIS16400_SCAN_GYRO_Z  3
+#define ADIS16400_SCAN_ACC_X   4
+#define ADIS16400_SCAN_ACC_Y   5
+#define ADIS16400_SCAN_ACC_Z   6
+#define ADIS16400_SCAN_MAGN_X  7
+#define ADIS16400_SCAN_MAGN_Y  8
+#define ADIS16400_SCAN_MAGN_Z  9
+#define ADIS16400_SCAN_TEMP    10
+#define ADIS16400_SCAN_ADC_0   11
 
 void adis16400_remove_trigger(struct iio_dev *indio_dev);
 int adis16400_probe_trigger(struct iio_dev *indio_dev);
@@ -186,8 +176,6 @@ ssize_t adis16400_read_data_from_ring(struct device *dev,
 int adis16400_configure_ring(struct iio_dev *indio_dev);
 void adis16400_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16400_initialize_ring(struct iio_ring_buffer *ring);
-void adis16400_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16400_remove_trigger(struct iio_dev *indio_dev)
@@ -216,14 +204,5 @@ static inline void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 {
 }
 
-static inline int adis16400_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return 0;
-}
-
-static inline void adis16400_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16400_H_ */
index e69e2ce47da3e20706e9e1ca76b3ca08b9b9eb2d..6013fee218e929c96d06d6699a28dc85ae50cc85 100644 (file)
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
-
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "../accel/accel.h"
 #include "../adc/adc.h"
 #include "../gyro/gyro.h"
@@ -36,6 +37,8 @@
 
 #define DRIVER_NAME            "adis16400"
 
+static int adis16400_check_status(struct device *dev);
+
 /* At the moment the spi framework doesn't allow global setting of cs_change.
  * It's in the likely to be added comment at the top of spi.h.
  * This means that use cannot be made of spi_write etc.
@@ -161,54 +164,6 @@ error_ret:
        return ret;
 }
 
-/**
- * adis16400_spi_read_burst() - read all data registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-int adis16400_spi_read_burst(struct device *dev, u8 *rx)
-{
-       struct spi_message msg;
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
-       u32 old_speed_hz = st->us->max_speed_hz;
-       int ret;
-
-       struct spi_transfer xfers[] = {
-               {
-                       .tx_buf = st->tx,
-                       .bits_per_word = 8,
-                       .len = 2,
-                       .cs_change = 0,
-               }, {
-                       .rx_buf = rx,
-                       .bits_per_word = 8,
-                       .len = 24,
-                       .cs_change = 1,
-               },
-       };
-
-       mutex_lock(&st->buf_lock);
-       st->tx[0] = ADIS16400_READ_REG(ADIS16400_GLOB_CMD);
-       st->tx[1] = 0;
-
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-
-       st->us->max_speed_hz = min(ADIS16400_SPI_BURST, old_speed_hz);
-       spi_setup(st->us);
-
-       ret = spi_sync(st->us, &msg);
-       if (ret)
-               dev_err(&st->us->dev, "problem when burst reading");
-
-       st->us->max_speed_hz = old_speed_hz;
-       spi_setup(st->us);
-       mutex_unlock(&st->buf_lock);
-       return ret;
-}
-
 static ssize_t adis16400_spi_read_signed(struct device *dev,
                struct device_attribute *attr,
                char *buf,
@@ -277,7 +232,6 @@ static ssize_t adis16400_read_12bit_signed(struct device *dev,
        return ret;
 }
 
-
 static ssize_t adis16400_write_16bit(struct device *dev,
                struct device_attribute *attr,
                const char *buf,
@@ -349,6 +303,18 @@ static ssize_t adis16400_write_frequency(struct device *dev,
        return ret ? ret : len;
 }
 
+static int adis16400_reset(struct device *dev)
+{
+       int ret;
+       ret = adis16400_spi_write_reg_8(dev,
+                       ADIS16400_GLOB_CMD,
+                       ADIS16400_GLOB_CMD_SW_RESET);
+       if (ret)
+               dev_err(dev, "problem resetting device");
+
+       return ret;
+}
+
 static ssize_t adis16400_write_reset(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t len)
@@ -364,8 +330,6 @@ static ssize_t adis16400_write_reset(struct device *dev,
        return -1;
 }
 
-
-
 int adis16400_set_irq(struct device *dev, bool enable)
 {
        int ret;
@@ -388,18 +352,6 @@ error_ret:
        return ret;
 }
 
-int adis16400_reset(struct device *dev)
-{
-       int ret;
-       ret = adis16400_spi_write_reg_8(dev,
-                       ADIS16400_GLOB_CMD,
-                       ADIS16400_GLOB_CMD_SW_RESET);
-       if (ret)
-               dev_err(dev, "problem resetting device");
-
-       return ret;
-}
-
 /* Power down the device */
 static int adis16400_stop_device(struct device *dev)
 {
@@ -430,7 +382,7 @@ err_ret:
        return ret;
 }
 
-int adis16400_check_status(struct device *dev)
+static int adis16400_check_status(struct device *dev)
 {
        u16 status;
        int ret;
@@ -496,6 +448,11 @@ static int adis16400_initial_setup(struct adis16400_state *st)
        }
 
        /* Do self test */
+       ret = adis16400_self_test(dev);
+       if (ret) {
+               dev_err(dev, "self test failure");
+               goto err_ret;
+       }
 
        /* Read status register to check the result */
        ret = adis16400_check_status(dev);
@@ -685,21 +642,13 @@ static int __devinit adis16400_probe(struct spi_device *spi)
                goto error_unreg_ring_funcs;
        regdone = 1;
 
-       ret = adis16400_initialize_ring(st->indio_dev->ring);
+       ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
        if (ret) {
                printk(KERN_ERR "failed to initialize the ring\n");
                goto error_unreg_ring_funcs;
        }
 
        if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-#if 0 /* fixme: here we should support */
-               iio_init_work_cont(&st->work_cont_thresh,
-                               NULL,
-                               adis16400_thresh_handler_bh_no_check,
-                               0,
-                               0,
-                               st);
-#endif
                ret = iio_register_interrupt_line(spi->irq,
                                st->indio_dev,
                                0,
@@ -726,7 +675,7 @@ error_unregister_line:
        if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
                iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-       adis16400_uninitialize_ring(st->indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
        adis16400_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -761,7 +710,7 @@ static int adis16400_remove(struct spi_device *spi)
        if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
                iio_unregister_interrupt_line(indio_dev, 0);
 
-       adis16400_uninitialize_ring(indio_dev->ring);
+       iio_ring_buffer_unregister(st->indio_dev->ring);
        adis16400_unconfigure_ring(indio_dev);
        iio_device_unregister(indio_dev);
        kfree(st->tx);
index 5529b32bd2e3a7f02713916b524d887463a2977e..949db76283d7188d1af5f190d69f80cea42d2869 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 
 #include "../trigger.h"
 #include "adis16400.h"
 
-/**
- * combine_8_to_16() utility function to munge to u8s into u16
- **/
-static inline u16 combine_8_to_16(u8 lower, u8 upper)
-{
-       u16 _lower = lower;
-       u16 _upper = upper;
-       return _lower | (_upper << 8);
-}
-
 static IIO_SCAN_EL_C(supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14),
                     ADIS16400_SUPPLY_OUT, NULL);
 
@@ -83,10 +74,10 @@ static struct attribute_group adis16400_scan_el_group = {
  * adis16400_poll_func_th() top half interrupt handler called by trigger
  * @private_data:      iio_dev
  **/
-static void adis16400_poll_func_th(struct iio_dev *indio_dev)
+static void adis16400_poll_func_th(struct iio_dev *indio_dev, s64 time)
 {
        struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
-       st->last_timestamp = indio_dev->trig->timestamp;
+       st->last_timestamp = time;
        schedule_work(&st->work_trigger_to_ring);
        /* Indicate that this interrupt is being handled */
 
@@ -96,6 +87,54 @@ static void adis16400_poll_func_th(struct iio_dev *indio_dev)
         */
 }
 
+/**
+ * adis16400_spi_read_burst() - read all data registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @rx: somewhere to pass back the value read (min size is 24 bytes)
+ **/
+static int adis16400_spi_read_burst(struct device *dev, u8 *rx)
+{
+       struct spi_message msg;
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+       u32 old_speed_hz = st->us->max_speed_hz;
+       int ret;
+
+       struct spi_transfer xfers[] = {
+               {
+                       .tx_buf = st->tx,
+                       .bits_per_word = 8,
+                       .len = 2,
+                       .cs_change = 0,
+               }, {
+                       .rx_buf = rx,
+                       .bits_per_word = 8,
+                       .len = 24,
+                       .cs_change = 1,
+               },
+       };
+
+       mutex_lock(&st->buf_lock);
+       st->tx[0] = ADIS16400_READ_REG(ADIS16400_GLOB_CMD);
+       st->tx[1] = 0;
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfers[0], &msg);
+       spi_message_add_tail(&xfers[1], &msg);
+
+       st->us->max_speed_hz = min(ADIS16400_SPI_BURST, old_speed_hz);
+       spi_setup(st->us);
+
+       ret = spi_sync(st->us, &msg);
+       if (ret)
+               dev_err(&st->us->dev, "problem when burst reading");
+
+       st->us->max_speed_hz = old_speed_hz;
+       spi_setup(st->us);
+       mutex_unlock(&st->buf_lock);
+       return ret;
+}
+
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
@@ -118,10 +157,9 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
 
        if (st->indio_dev->scan_count)
                if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++) {
-                               data[i] = combine_8_to_16(st->rx[i*2+1],
-                                                         st->rx[i*2]);
-                       }
+                       for (; i < st->indio_dev->scan_count; i++)
+                               data[i] = be16_to_cpup(
+                                       (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
        if (st->indio_dev->scan_timestamp)
@@ -136,45 +174,6 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
 
        return;
 }
-/* in these circumstances is it better to go with unaligned packing and
- * deal with the cost?*/
-static int adis16400_data_rdy_ring_preenable(struct iio_dev *indio_dev)
-{
-       size_t size;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-       /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
-               return -EINVAL;
-
-       if (indio_dev->ring->access.set_bpd) {
-               if (indio_dev->scan_timestamp)
-                       if (indio_dev->scan_count) /* Timestamp and data */
-                               size = 6*sizeof(s64);
-                       else /* Timestamp only  */
-                               size = sizeof(s64);
-               else /* Data only */
-                       size = indio_dev->scan_count*sizeof(s16);
-               indio_dev->ring->access.set_bpd(indio_dev->ring, size);
-       }
-
-       return 0;
-}
-
-static int adis16400_data_rdy_ring_postenable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_attach_poll_func(indio_dev->trig,
-                                              indio_dev->pollfunc)
-               : 0;
-}
-
-static int adis16400_data_rdy_ring_predisable(struct iio_dev *indio_dev)
-{
-       return indio_dev->trig
-               ? iio_trigger_dettach_poll_func(indio_dev->trig,
-                                               indio_dev->pollfunc)
-               : 0;
-}
 
 void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 {
@@ -214,18 +213,16 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
        indio_dev->ring = ring;
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
-       ring->preenable = &adis16400_data_rdy_ring_preenable;
-       ring->postenable = &adis16400_data_rdy_ring_postenable;
-       ring->predisable = &adis16400_data_rdy_ring_predisable;
+       ring->bpe = 2;
+       ring->preenable = &iio_sw_ring_preenable;
+       ring->postenable = &iio_triggered_ring_postenable;
+       ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
-       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-       if (indio_dev->pollfunc == NULL) {
-               ret = -ENOMEM;
-               goto error_iio_sw_rb_free;;
-       }
-       indio_dev->pollfunc->poll_func_main = &adis16400_poll_func_th;
-       indio_dev->pollfunc->private_data = indio_dev;
+       ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
+       if (ret)
+               goto error_iio_sw_rb_free;
+
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
 
@@ -233,13 +230,3 @@ error_iio_sw_rb_free:
        iio_sw_rb_free(indio_dev->ring);
        return ret;
 }
-
-int adis16400_initialize_ring(struct iio_ring_buffer *ring)
-{
-       return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16400_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-       iio_ring_buffer_unregister(ring);
-}
index 3b3250ac76804697f3e7a746e745fe09f8409f6d..aafe6010f1b1b3f36489482822212947231b648b 100644 (file)
@@ -23,8 +23,7 @@ static int adis16400_data_rdy_trig_poll(struct iio_dev *dev_info,
        struct adis16400_state *st = iio_dev_get_devdata(dev_info);
        struct iio_trigger *trig = st->trig;
 
-       trig->timestamp = timestamp;
-       iio_trigger_poll(trig);
+       iio_trigger_poll(trig, timestamp);
 
        return IRQ_HANDLED;
 }
@@ -86,14 +85,13 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev)
        struct adis16400_state *st = indio_dev->dev_data;
 
        st->trig = iio_allocate_trigger();
-       st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+       st->trig->name = kasprintf(GFP_KERNEL,
+                                  "adis16400-dev%d",
+                                  indio_dev->id);
        if (!st->trig->name) {
                ret = -ENOMEM;
                goto error_free_trig;
        }
-       snprintf((char *)st->trig->name,
-                IIO_TRIGGER_NAME_LENGTH,
-                "adis16400-dev%d", indio_dev->id);
        st->trig->dev.parent = &st->us->dev;
        st->trig->owner = THIS_MODULE;
        st->trig->private_data = st;
index 01030684ef2885082c11729b147a092e55116b1b..dd4d87a8bcaf1f101cc40ca4949eaafb1cecc3db 100644 (file)
@@ -30,9 +30,6 @@
 
 /* IDR to assign each registered device a unique id*/
 static DEFINE_IDR(iio_idr);
-
-/* IDR for general event identifiers */
-static DEFINE_IDR(iio_event_idr);
 /* IDR to allocate character device minor numbers */
 static DEFINE_IDR(iio_chrdev_idr);
 /* Lock used to protect both of the above */
@@ -654,16 +651,11 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 
        for (i = 0; i < dev_info->num_interrupt_lines; i++) {
                dev_info->event_interfaces[i].owner = dev_info->driver_module;
-               ret = iio_get_new_idr_val(&iio_event_idr);
-               if (ret < 0)
-                       goto error_free_setup_ev_ints;
-               else
-                       dev_info->event_interfaces[i].id = ret;
 
                snprintf(dev_info->event_interfaces[i]._name, 20,
                         "%s:event%d",
                         dev_name(&dev_info->dev),
-                        dev_info->event_interfaces[i].id);
+                        i);
 
                ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
                                       (const char *)(dev_info
@@ -674,8 +666,6 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
                if (ret) {
                        dev_err(&dev_info->dev,
                                "Could not get chrdev interface\n");
-                       iio_free_idr_val(&iio_event_idr,
-                                        dev_info->event_interfaces[i].id);
                        goto error_free_setup_ev_ints;
                }
 
@@ -711,11 +701,8 @@ error_remove_sysfs_interfaces:
                                   ->event_interfaces[j].dev.kobj,
                                   &dev_info->event_attrs[j]);
 error_free_setup_ev_ints:
-       for (j = 0; j < i; j++) {
-               iio_free_idr_val(&iio_event_idr,
-                                dev_info->event_interfaces[j].id);
+       for (j = 0; j < i; j++)
                iio_free_ev_int(&dev_info->event_interfaces[j]);
-       }
        kfree(dev_info->interrupts);
 error_free_event_interfaces:
        kfree(dev_info->event_interfaces);
@@ -735,11 +722,8 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
                                   ->event_interfaces[i].dev.kobj,
                                   &dev_info->event_attrs[i]);
 
-       for (i = 0; i < dev_info->num_interrupt_lines; i++) {
-               iio_free_idr_val(&iio_event_idr,
-                                dev_info->event_interfaces[i].id);
+       for (i = 0; i < dev_info->num_interrupt_lines; i++)
                iio_free_ev_int(&dev_info->event_interfaces[i]);
-       }
        kfree(dev_info->interrupts);
        kfree(dev_info->event_interfaces);
 }
index ada159bbb1f703a5df0e9aad54f00834890fa636..6ab578e4f5f36c99ffa9c938204dc06c84a40952 100644 (file)
@@ -149,12 +149,10 @@ __iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf,
 {
        int ret;
 
-       buf->ev_int.id = id;
-
        snprintf(buf->ev_int._name, sizeof(buf->ev_int._name),
                 "%s:event%d",
                 dev_name(&buf->dev),
-                buf->ev_int.id);
+                id);
        ret = iio_setup_ev_int(&(buf->ev_int),
                               buf->ev_int._name,
                               owner,
index 5682e61600f697539bded7a723dbc4aed84ede3f..57dd9232cf0d91884dad5af732ab9e21fdbe150b 100644 (file)
@@ -31,7 +31,6 @@
  * Any other suggestions?
  */
 
-
 static DEFINE_IDR(iio_trigger_idr);
 static DEFINE_SPINLOCK(iio_trigger_idr_lock);
 
@@ -173,7 +172,7 @@ struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len)
 }
 EXPORT_SYMBOL(iio_trigger_find_by_name);
 
-void iio_trigger_poll(struct iio_trigger *trig)
+void iio_trigger_poll(struct iio_trigger *trig, s64 time)
 {
        struct iio_poll_func *pf_cursor;
 
@@ -185,7 +184,8 @@ void iio_trigger_poll(struct iio_trigger *trig)
        }
        list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
                if (pf_cursor->poll_func_main) {
-                       pf_cursor->poll_func_main(pf_cursor->private_data);
+                       pf_cursor->poll_func_main(pf_cursor->private_data,
+                                                 time);
                        trig->use_count++;
                }
        }
@@ -198,8 +198,7 @@ void iio_trigger_notify_done(struct iio_trigger *trig)
        if (trig->use_count == 0 && trig->try_reenable)
                if (trig->try_reenable(trig)) {
                        /* Missed and interrupt so launch new poll now */
-                       trig->timestamp = 0;
-                       iio_trigger_poll(trig);
+                       iio_trigger_poll(trig, 0);
                }
 }
 EXPORT_SYMBOL(iio_trigger_notify_done);
@@ -284,7 +283,7 @@ error_ret:
 EXPORT_SYMBOL(iio_trigger_dettach_poll_func);
 
 /**
- * iio_trigger_read_currrent() trigger consumer sysfs query which trigger
+ * iio_trigger_read_currrent() trigger consumer sysfs query which trigger
  *
  * For trigger consumers the current_trigger interface allows the trigger
  * used by the device to be queried.
@@ -296,10 +295,9 @@ static ssize_t iio_trigger_read_current(struct device *dev,
        struct iio_dev *dev_info = dev_get_drvdata(dev);
        int len = 0;
        if (dev_info->trig)
-               len = snprintf(buf,
-                              IIO_TRIGGER_NAME_LENGTH,
-                              "%s\n",
-                              dev_info->trig->name);
+               len = sprintf(buf,
+                             "%s\n",
+                             dev_info->trig->name);
        return len;
 }
 
@@ -324,8 +322,6 @@ static ssize_t iio_trigger_write_current(struct device *dev,
        }
        mutex_unlock(&dev_info->mlock);
 
-       len = len < IIO_TRIGGER_NAME_LENGTH ? len : IIO_TRIGGER_NAME_LENGTH;
-
        dev_info->trig = iio_trigger_find_by_name(buf, len);
        if (oldtrig && dev_info->trig != oldtrig)
                iio_put_trigger(oldtrig);
@@ -402,3 +398,34 @@ int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
 }
 EXPORT_SYMBOL(iio_device_unregister_trigger_consumer);
 
+int iio_alloc_pollfunc(struct iio_dev *indio_dev,
+                      void (*immediate)(struct iio_dev *indio_dev),
+                      void (*main)(struct iio_dev *private_data, s64 time))
+{
+       indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+       if (indio_dev->pollfunc == NULL)
+               return -ENOMEM;
+       indio_dev->pollfunc->poll_func_immediate = immediate;
+       indio_dev->pollfunc->poll_func_main = main;
+       indio_dev->pollfunc->private_data = indio_dev;
+       return 0;
+}
+EXPORT_SYMBOL(iio_alloc_pollfunc);
+
+int iio_triggered_ring_postenable(struct iio_dev *indio_dev)
+{
+       return indio_dev->trig
+               ? iio_trigger_attach_poll_func(indio_dev->trig,
+                                              indio_dev->pollfunc)
+               : 0;
+}
+EXPORT_SYMBOL(iio_triggered_ring_postenable);
+
+int iio_triggered_ring_predisable(struct iio_dev *indio_dev)
+{
+       return indio_dev->trig
+               ? iio_trigger_dettach_poll_func(indio_dev->trig,
+                                               indio_dev->pollfunc)
+               : 0;
+}
+EXPORT_SYMBOL(iio_triggered_ring_predisable);
index 80cb6e590fbb6124065a65c835545f0e8bd152e7..3ddc478e6182cf9aee5be391e7222c356428cec4 100644 (file)
@@ -12,4 +12,3 @@ config SENSORS_TSL2563
 
         This driver can also be built as a module.  If so, the module
         will be called tsl2563.
-
index f00f827689c2efd57fda1f4a4e5ed0e55ee4cf16..e4e1e2c4139ca94d769c521ceff21570ede30f9c 100644 (file)
@@ -2,11 +2,6 @@
 
 /* Light to digital sensor attributes */
 
-#define IIO_DEV_ATTR_LIGHT_INFRARED(_num, _show, _addr)                        \
-       IIO_DEVICE_ATTR(light_infrared##_num, S_IRUGO, _show, NULL, _addr)
+#define IIO_EVENT_CODE_LIGHT_THRESH IIO_EVENT_CODE_LIGHT_BASE
 
-#define IIO_DEV_ATTR_LIGHT_BROAD(_num, _show, _addr)                   \
-       IIO_DEVICE_ATTR(light_broadspectrum##_num, S_IRUGO, _show, NULL, _addr)
 
-#define IIO_DEV_ATTR_LIGHT_VISIBLE(_num, _show, _addr)                 \
-       IIO_DEVICE_ATTR(light_visible##_num, S_IRUGO, _show, NULL, _addr)
index e4b0a5ef1c1f4913d39870c9ef363917ca552e83..98f8b78f5d8c1b2288964043849d8e3d007bce3e 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
@@ -117,15 +118,17 @@ struct tsl2563_chip {
        struct iio_dev          *indio_dev;
        struct delayed_work     poweroff_work;
 
+       struct work_struct      work_thresh;
+       s64                     event_timestamp;
        /* Remember state for suspend and resume functions */
        pm_message_t            state;
 
        struct tsl2563_gainlevel_coeff *gainlevel;
 
-       /* Thresholds are in lux */
        u16                     low_thres;
        u16                     high_thres;
        u8                      intr;
+       bool                    int_enabled;
 
        /* Calibration coefficients */
        u32                     calib0;
@@ -189,17 +192,29 @@ static int tsl2563_get_power(struct tsl2563_chip *chip)
 
 static int tsl2563_configure(struct tsl2563_chip *chip)
 {
-       struct i2c_client *client = chip->client;
        int ret;
 
-       ret = tsl2563_write(client, TSL2563_REG_TIMING,
+       ret = tsl2563_write(chip->client, TSL2563_REG_TIMING,
                        chip->gainlevel->gaintime);
        if (ret)
-               goto out;
-
-       ret = tsl2563_write(client, TSL2563_REG_INT, chip->intr);
-
-out:
+               goto error_ret;
+       ret = tsl2563_write(chip->client, TSL2563_REG_HIGHLOW,
+                       chip->high_thres & 0xFF);
+       if (ret)
+               goto error_ret;
+       ret = tsl2563_write(chip->client, TSL2563_REG_HIGHHIGH,
+                       (chip->high_thres >> 8) & 0xFF);
+       if (ret)
+               goto error_ret;
+       ret = tsl2563_write(chip->client, TSL2563_REG_LOWLOW,
+                       chip->low_thres & 0xFF);
+       if (ret)
+               goto error_ret;
+       ret = tsl2563_write(chip->client, TSL2563_REG_LOWHIGH,
+                       (chip->low_thres >> 8) & 0xFF);
+/* Interrupt register is automatically written anyway if it is relevant
+   so is not here */
+error_ret:
        return ret;
 }
 
@@ -323,21 +338,23 @@ static int tsl2563_get_adc(struct tsl2563_chip *chip)
        if (chip->state.event != PM_EVENT_ON)
                goto out;
 
-       cancel_delayed_work(&chip->poweroff_work);
-
-       if (!tsl2563_get_power(chip)) {
-               ret = tsl2563_set_power(chip, 1);
-               if (ret)
-                       goto out;
-               ret = tsl2563_configure(chip);
-               if (ret)
-                       goto out;
-               tsl2563_wait_adc(chip);
+       if (!chip->int_enabled) {
+               cancel_delayed_work(&chip->poweroff_work);
+
+               if (!tsl2563_get_power(chip)) {
+                       ret = tsl2563_set_power(chip, 1);
+                       if (ret)
+                               goto out;
+                       ret = tsl2563_configure(chip);
+                       if (ret)
+                               goto out;
+                       tsl2563_wait_adc(chip);
+               }
        }
 
        while (retry) {
                ret = tsl2563_read(client,
-                                  TSL2563_REG_DATA0LOW | TSL2563_CLEARINT,
+                                  TSL2563_REG_DATA0LOW,
                                   buf0, sizeof(buf0));
                if (ret != sizeof(buf0))
                        goto out;
@@ -356,7 +373,8 @@ static int tsl2563_get_adc(struct tsl2563_chip *chip)
        chip->data0 = normalize_adc(adc0, chip->gainlevel->gaintime);
        chip->data1 = normalize_adc(adc1, chip->gainlevel->gaintime);
 
-       schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
+       if (!chip->int_enabled)
+               schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
 
        ret = 0;
 out:
@@ -449,11 +467,12 @@ static unsigned int adc_to_lux(u32 adc0, u32 adc1)
 /*                      Sysfs interface                         */
 /*--------------------------------------------------------------*/
 
-static ssize_t tsl2563_adc0_show(struct device *dev,
+static ssize_t tsl2563_adc_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
        struct tsl2563_chip *chip = indio_dev->dev_data;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
 
        mutex_lock(&chip->lock);
@@ -462,26 +481,14 @@ static ssize_t tsl2563_adc0_show(struct device *dev,
        if (ret)
                goto out;
 
-       ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data0);
-out:
-       mutex_unlock(&chip->lock);
-       return ret;
-}
-
-static ssize_t tsl2563_adc1_show(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct tsl2563_chip *chip = indio_dev->dev_data;
-       int ret;
-
-       mutex_lock(&chip->lock);
-
-       ret = tsl2563_get_adc(chip);
-       if (ret)
-               goto out;
-
-       ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data1);
+       switch (this_attr->address) {
+       case 0:
+               ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data0);
+               break;
+       case 1:
+               ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data1);
+               break;
+       }
 out:
        mutex_unlock(&chip->lock);
        return ret;
@@ -527,37 +534,36 @@ static ssize_t format_calib(char *buf, int len, u32 calib)
        return snprintf(buf, PAGE_SIZE, "%d\n", calib_to_sysfs(calib));
 }
 
-static ssize_t tsl2563_calib0_show(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
-{
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct tsl2563_chip *chip = indio_dev->dev_data;
-       int ret;
-
-       mutex_lock(&chip->lock);
-       ret = format_calib(buf, PAGE_SIZE, chip->calib0);
-       mutex_unlock(&chip->lock);
-       return ret;
-}
-
-static ssize_t tsl2563_calib1_show(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
+static ssize_t tsl2563_calib_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
        struct tsl2563_chip *chip = indio_dev->dev_data;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
 
        mutex_lock(&chip->lock);
-       ret = format_calib(buf, PAGE_SIZE, chip->calib1);
+       switch (this_attr->address) {
+       case 0:
+               ret = format_calib(buf, PAGE_SIZE, chip->calib0);
+               break;
+       case 1:
+               ret = format_calib(buf, PAGE_SIZE, chip->calib1);
+               break;
+       default:
+               ret = -ENODEV;
+       }
        mutex_unlock(&chip->lock);
        return ret;
 }
 
-static int do_calib_store(struct device *dev, const char *buf, size_t len,
-                         int ch)
+static ssize_t tsl2563_calib_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t len)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
        struct tsl2563_chip *chip = indio_dev->dev_data;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int value;
        u32 calib;
 
@@ -566,37 +572,27 @@ static int do_calib_store(struct device *dev, const char *buf, size_t len,
 
        calib = calib_from_sysfs(value);
 
-       if (ch)
-               chip->calib1 = calib;
-       else
+       switch (this_attr->address) {
+       case 0:
                chip->calib0 = calib;
+               break;
+       case 1:
+               chip->calib1 = calib;
+               break;
+       }
 
        return len;
 }
 
-static ssize_t tsl2563_calib0_store(struct device *dev,
-                                   struct device_attribute *attr,
-                                   const char *buf, size_t len)
-{
-       return do_calib_store(dev, buf, len, 0);
-}
-
-static ssize_t tsl2563_calib1_store(struct device *dev,
-                                   struct device_attribute *attr,
-                                   const char *buf, size_t len)
-{
-       return do_calib_store(dev, buf, len, 1);
-}
-
-/* AmitXXXX: Convert to IIO_DEV_ATTR_LIGHT* as in tsl2561
- * once I understand what they mean */
-static DEVICE_ATTR(adc0, S_IRUGO, tsl2563_adc0_show, NULL);
-static DEVICE_ATTR(adc1, S_IRUGO, tsl2563_adc1_show, NULL);
+static IIO_DEVICE_ATTR(intensity_both_raw, S_IRUGO,
+               tsl2563_adc_show, NULL, 0);
+static IIO_DEVICE_ATTR(intensity_ir_raw, S_IRUGO,
+               tsl2563_adc_show, NULL, 1);
 static DEVICE_ATTR(illuminance0_input, S_IRUGO, tsl2563_lux_show, NULL);
-static DEVICE_ATTR(calib0, S_IRUGO | S_IWUSR,
-                  tsl2563_calib0_show, tsl2563_calib0_store);
-static DEVICE_ATTR(calib1, S_IRUGO | S_IWUSR,
-                  tsl2563_calib1_show, tsl2563_calib1_store);
+static IIO_DEVICE_ATTR(intensity_both_calibgain, S_IRUGO | S_IWUSR,
+               tsl2563_calib_show, tsl2563_calib_store, 0);
+static IIO_DEVICE_ATTR(intensity_ir_calibgain, S_IRUGO | S_IWUSR,
+               tsl2563_calib_show, tsl2563_calib_store, 1);
 
 static ssize_t tsl2563_show_name(struct device *dev,
                                struct device_attribute *attr,
@@ -610,11 +606,11 @@ static ssize_t tsl2563_show_name(struct device *dev,
 static DEVICE_ATTR(name, S_IRUGO, tsl2563_show_name, NULL);
 
 static struct attribute *tsl2563_attributes[] = {
-       &dev_attr_adc0.attr,
-       &dev_attr_adc1.attr,
+       &iio_dev_attr_intensity_both_raw.dev_attr.attr,
+       &iio_dev_attr_intensity_ir_raw.dev_attr.attr,
        &dev_attr_illuminance0_input.attr,
-       &dev_attr_calib0.attr,
-       &dev_attr_calib1.attr,
+       &iio_dev_attr_intensity_both_calibgain.dev_attr.attr,
+       &iio_dev_attr_intensity_ir_calibgain.dev_attr.attr,
        &dev_attr_name.attr,
        NULL
 };
@@ -623,6 +619,192 @@ static const struct attribute_group tsl2563_group = {
        .attrs = tsl2563_attributes,
 };
 
+static ssize_t tsl2563_read_thresh(struct device *dev,
+                       struct device_attribute *attr,
+                       char *buf)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct tsl2563_chip *chip = indio_dev->dev_data;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       u16 val = 0;
+       switch (this_attr->address) {
+       case TSL2563_REG_HIGHLOW:
+               val = chip->high_thres;
+               break;
+       case TSL2563_REG_LOWLOW:
+               val = chip->low_thres;
+               break;
+       }
+       return snprintf(buf, PAGE_SIZE, "%d\n", val);
+}
+
+static ssize_t tsl2563_write_thresh(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf,
+                               size_t len)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct tsl2563_chip *chip = indio_dev->dev_data;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       unsigned long val;
+       int ret;
+
+       ret = strict_strtoul(buf, 10, &val);
+       if (ret)
+               return ret;
+       mutex_lock(&chip->lock);
+       ret = tsl2563_write(chip->client, this_attr->address, val & 0xFF);
+       if (ret)
+               goto error_ret;
+       ret = tsl2563_write(chip->client, this_attr->address + 1,
+                       (val >> 8) & 0xFF);
+       switch (this_attr->address) {
+       case TSL2563_REG_HIGHLOW:
+               chip->high_thres = val;
+               break;
+       case TSL2563_REG_LOWLOW:
+               chip->low_thres = val;
+               break;
+       }
+
+error_ret:
+       mutex_unlock(&chip->lock);
+
+       return ret < 0 ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(intensity_both_thresh_high_value,
+               S_IRUGO | S_IWUSR,
+               tsl2563_read_thresh,
+               tsl2563_write_thresh,
+               TSL2563_REG_HIGHLOW);
+
+static IIO_DEVICE_ATTR(intensity_both_thresh_low_value,
+               S_IRUGO | S_IWUSR,
+               tsl2563_read_thresh,
+               tsl2563_write_thresh,
+               TSL2563_REG_LOWLOW);
+
+static int tsl2563_int_th(struct iio_dev *dev_info,
+                       int index,
+                       s64 timestamp,
+                       int not_test)
+{
+       struct tsl2563_chip *chip = dev_info->dev_data;
+
+       chip->event_timestamp = timestamp;
+       schedule_work(&chip->work_thresh);
+
+       return 0;
+}
+
+static void tsl2563_int_bh(struct work_struct *work_s)
+{
+       struct tsl2563_chip *chip
+               = container_of(work_s,
+                       struct tsl2563_chip, work_thresh);
+       u8 cmd = TSL2563_CMD | TSL2563_CLEARINT;
+
+       iio_push_event(chip->indio_dev, 0,
+               IIO_EVENT_CODE_LIGHT_BASE,
+               chip->event_timestamp);
+
+       /* reenable_irq */
+       enable_irq(chip->client->irq);
+       /* clear the interrupt and push the event */
+       i2c_master_send(chip->client, &cmd, sizeof(cmd));
+
+}
+
+static ssize_t tsl2563_write_interrupt_config(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf,
+                                       size_t len)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct tsl2563_chip *chip = indio_dev->dev_data;
+       struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+       int input, ret = 0;
+
+       ret = sscanf(buf, "%d", &input);
+       if (ret != 1)
+               return -EINVAL;
+       mutex_lock(&chip->lock);
+       if (input && !(chip->intr & 0x30)) {
+               iio_add_event_to_list(this_attr->listel,
+                               &indio_dev->interrupts[0]->ev_list);
+               chip->intr &= ~0x30;
+               chip->intr |= 0x10;
+               /* ensure the chip is actually on */
+               cancel_delayed_work(&chip->poweroff_work);
+               if (!tsl2563_get_power(chip)) {
+                       ret = tsl2563_set_power(chip, 1);
+                       if (ret)
+                               goto out;
+                       ret = tsl2563_configure(chip);
+                       if (ret)
+                               goto out;
+               }
+               ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr);
+               chip->int_enabled = true;
+       }
+
+       if (!input && (chip->intr & 0x30)) {
+               chip->intr |= ~0x30;
+               ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr);
+               iio_remove_event_from_list(this_attr->listel,
+                                       &indio_dev->interrupts[0]->ev_list);
+               chip->int_enabled = false;
+               /* now the interrupt is not enabled, we can go to sleep */
+               schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
+       }
+out:
+       mutex_unlock(&chip->lock);
+
+       return (ret < 0) ? ret : len;
+}
+
+static ssize_t tsl2563_read_interrupt_config(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct tsl2563_chip *chip = indio_dev->dev_data;
+       int ret;
+       u8 rxbuf;
+       ssize_t len;
+
+       mutex_lock(&chip->lock);
+       ret = tsl2563_read(chip->client,
+                       TSL2563_REG_INT,
+                       &rxbuf,
+                       sizeof(rxbuf));
+       mutex_unlock(&chip->lock);
+       if (ret < 0)
+               goto error_ret;
+       len = snprintf(buf, PAGE_SIZE, "%d\n", !!(rxbuf & 0x30));
+error_ret:
+
+       return (ret < 0) ? ret : len;
+}
+
+IIO_EVENT_ATTR(intensity_both_thresh_both_en,
+       tsl2563_read_interrupt_config,
+       tsl2563_write_interrupt_config,
+       0,
+       tsl2563_int_th);
+
+static struct attribute *tsl2563_event_attributes[] = {
+       &iio_event_attr_intensity_both_thresh_both_en.dev_attr.attr,
+       &iio_dev_attr_intensity_both_thresh_high_value.dev_attr.attr,
+       &iio_dev_attr_intensity_both_thresh_low_value.dev_attr.attr,
+       NULL,
+};
+
+static struct attribute_group tsl2563_event_attribute_group = {
+       .attrs = tsl2563_event_attributes,
+};
+
 /*--------------------------------------------------------------*/
 /*                      Probe, Attach, Remove                   */
 /*--------------------------------------------------------------*/
@@ -641,6 +823,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
        if (!chip)
                return -ENOMEM;
 
+       INIT_WORK(&chip->work_thresh, tsl2563_int_bh);
        i2c_set_clientdata(client, chip);
        chip->client = client;
 
@@ -679,18 +862,36 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
        chip->indio_dev->dev_data = (void *)(chip);
        chip->indio_dev->driver_module = THIS_MODULE;
        chip->indio_dev->modes = INDIO_DIRECT_MODE;
+       if (client->irq) {
+               chip->indio_dev->num_interrupt_lines = 1;
+               chip->indio_dev->event_attrs
+                       = &tsl2563_event_attribute_group;
+       }
        ret = iio_device_register(chip->indio_dev);
        if (ret)
                goto fail1;
 
+       if (client->irq) {
+               ret = iio_register_interrupt_line(client->irq,
+                                               chip->indio_dev,
+                                               0,
+                                               IRQF_TRIGGER_RISING,
+                                               client->name);
+               if (ret)
+                       goto fail2;
+       }
        err = tsl2563_configure(chip);
        if (err)
-               goto fail2;
+               goto fail3;
 
        INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
+       /* The interrupt cannot yet be enabled so this is fine without lock */
        schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
 
        return 0;
+fail3:
+       if (client->irq)
+               iio_unregister_interrupt_line(chip->indio_dev, 0);
 fail2:
        iio_device_unregister(chip->indio_dev);
 fail1:
@@ -701,7 +902,15 @@ fail1:
 static int tsl2563_remove(struct i2c_client *client)
 {
        struct tsl2563_chip *chip = i2c_get_clientdata(client);
-
+       if (!chip->int_enabled)
+               cancel_delayed_work(&chip->poweroff_work);
+       /* Ensure that interrupts are disabled - then flush any bottom halves */
+       chip->intr |= ~0x30;
+       tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr);
+       flush_scheduled_work();
+       tsl2563_set_power(chip, 0);
+       if (client->irq)
+               iio_unregister_interrupt_line(chip->indio_dev, 0);
        iio_device_unregister(chip->indio_dev);
 
        kfree(chip);
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
new file mode 100644 (file)
index 0000000..d014450
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Magnetometer sensors
+#
+comment "Magnetometer sensors"
+
+config SENSORS_HMC5843
+       tristate "Honeywell HMC5843 3-Axis Magnetometer"
+       depends on I2C
+       help
+         Say Y here to add support for the Honeywell HMC 5843 3-Axis
+         Magnetometer (digital compass).
+
+         To compile this driver as a module, choose M here: the module
+         will be called hmc5843
+
diff --git a/drivers/staging/iio/magnetometer/Makefile b/drivers/staging/iio/magnetometer/Makefile
new file mode 100644 (file)
index 0000000..f9bfb2e
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for industrial I/O Magnetometer sensors
+#
+
+obj-$(CONFIG_SENSORS_HMC5843)  += hmc5843.o
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
new file mode 100644 (file)
index 0000000..92f6c6f
--- /dev/null
@@ -0,0 +1,624 @@
+/*  Copyright (C) 2010 Texas Instruments
+    Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
+    Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include "../iio.h"
+#include "../sysfs.h"
+#include "magnet.h"
+
+#define HMC5843_I2C_ADDRESS                    0x1E
+
+#define HMC5843_CONFIG_REG_A                   0x00
+#define HMC5843_CONFIG_REG_B                   0x01
+#define HMC5843_MODE_REG                       0x02
+#define HMC5843_DATA_OUT_X_MSB_REG             0x03
+#define HMC5843_DATA_OUT_X_LSB_REG             0x04
+#define HMC5843_DATA_OUT_Y_MSB_REG             0x05
+#define HMC5843_DATA_OUT_Y_LSB_REG             0x06
+#define HMC5843_DATA_OUT_Z_MSB_REG             0x07
+#define HMC5843_DATA_OUT_Z_LSB_REG             0x08
+#define HMC5843_STATUS_REG                     0x09
+#define HMC5843_ID_REG_A                       0x0A
+#define HMC5843_ID_REG_B                       0x0B
+#define HMC5843_ID_REG_C                       0x0C
+
+#define HMC5843_ID_REG_LENGTH                  0x03
+#define HMC5843_ID_STRING                      "H43"
+
+/*
+ * Range settings in  (+-)Ga
+ * */
+#define RANGE_GAIN_OFFSET                      0x05
+
+#define        RANGE_0_7                               0x00
+#define        RANGE_1_0                               0x01 /* default */
+#define        RANGE_1_5                               0x02
+#define        RANGE_2_0                               0x03
+#define        RANGE_3_2                               0x04
+#define        RANGE_3_8                               0x05
+#define        RANGE_4_5                               0x06
+#define        RANGE_6_5                               0x07 /* Not recommended */
+
+/*
+ * Device status
+ */
+#define        DATA_READY                              0x01
+#define        DATA_OUTPUT_LOCK                        0x02
+#define        VOLTAGE_REGULATOR_ENABLED               0x04
+
+/*
+ * Mode register configuration
+ */
+#define        MODE_CONVERSION_CONTINUOUS              0x00
+#define        MODE_CONVERSION_SINGLE                  0x01
+#define        MODE_IDLE                               0x02
+#define        MODE_SLEEP                              0x03
+
+/* Minimum Data Output Rate in 1/10 Hz  */
+#define RATE_OFFSET                            0x02
+#define RATE_BITMASK                           0x1C
+#define        RATE_5                                  0x00
+#define        RATE_10                                 0x01
+#define        RATE_20                                 0x02
+#define        RATE_50                                 0x03
+#define        RATE_100                                0x04
+#define        RATE_200                                0x05
+#define        RATE_500                                0x06
+#define        RATE_NOT_USED                           0x07
+
+/*
+ * Device Configutration
+ */
+#define        CONF_NORMAL                             0x00
+#define        CONF_POSITIVE_BIAS                      0x01
+#define        CONF_NEGATIVE_BIAS                      0x02
+#define        CONF_NOT_USED                           0x03
+#define        MEAS_CONF_MASK                          0x03
+
+static const int regval_to_counts_per_mg[] = {
+       1620,
+       1300,
+       970,
+       780,
+       530,
+       460,
+       390,
+       280
+};
+static const int regval_to_input_field_mg[] = {
+       700,
+       1000,
+       1500,
+       2000,
+       3200,
+       3800,
+       4500,
+       6500
+};
+static const char *regval_to_samp_freq[] = {
+       "0.5",
+       "1",
+       "2",
+       "5",
+       "10",
+       "20",
+       "50",
+};
+
+/* Addresses to scan: 0x1E */
+static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
+                                                       I2C_CLIENT_END };
+
+/* Each client has this additional data */
+struct hmc5843_data {
+       struct iio_dev  *indio_dev;
+       struct mutex lock;
+       u8              rate;
+       u8              meas_conf;
+       u8              operating_mode;
+       u8              range;
+};
+
+static void hmc5843_init_client(struct i2c_client *client);
+
+static s32 hmc5843_configure(struct i2c_client *client,
+                                      u8 operating_mode)
+{
+       /* The lower two bits contain the current conversion mode */
+       return i2c_smbus_write_byte_data(client,
+                                       HMC5843_MODE_REG,
+                                       (operating_mode & 0x03));
+}
+
+/* Return the measurement value from the  specified channel */
+static ssize_t hmc5843_read_measurement(struct device *dev,
+               struct device_attribute *attr,
+               char *buf)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+       s16 coordinate_val;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       struct hmc5843_data *data = indio_dev->dev_data;
+       s32 result;
+
+       mutex_lock(&data->lock);
+
+       result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
+       while (!(result & DATA_READY))
+               result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
+
+       result = i2c_smbus_read_word_data(client, this_attr->address);
+       mutex_unlock(&data->lock);
+       if (result < 0)
+               return -EINVAL;
+
+       coordinate_val  = (s16)swab16((u16)result);
+       return sprintf(buf, "%d\n", coordinate_val);
+}
+static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement,
+               HMC5843_DATA_OUT_X_MSB_REG);
+static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement,
+               HMC5843_DATA_OUT_Y_MSB_REG);
+static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement,
+               HMC5843_DATA_OUT_Z_MSB_REG);
+
+/*
+ * From the datasheet
+ * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
+ * device continuously performs conversions an places the result in the
+ * data register.
+ *
+ * 1 - Single-Conversion Mode : device performs a single measurement,
+ *  sets RDY high and returned to sleep mode
+ *
+ * 2 - Idle Mode :  Device is placed in idle mode.
+ *
+ * 3 - Sleep Mode. Device is placed in sleep mode.
+ *
+ */
+static ssize_t hmc5843_show_operating_mode(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct hmc5843_data *data = indio_dev->dev_data;
+       return sprintf(buf, "%d\n", data->operating_mode);
+}
+
+static ssize_t hmc5843_set_operating_mode(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf,
+                               size_t count)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+       struct hmc5843_data *data = indio_dev->dev_data;
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       unsigned long operating_mode = 0;
+       s32 status;
+       int error;
+       mutex_lock(&data->lock);
+       error = strict_strtoul(buf, 10, &operating_mode);
+       if (error)
+               return error;
+       dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
+       if (operating_mode > MODE_SLEEP)
+                       return -EINVAL;
+
+       status = i2c_smbus_write_byte_data(client, this_attr->address,
+                                       operating_mode);
+       if (status) {
+               count = -EINVAL;
+               goto exit;
+       }
+       data->operating_mode = operating_mode;
+
+exit:
+       mutex_unlock(&data->lock);
+       return count;
+}
+static IIO_DEVICE_ATTR(operating_mode,
+                       S_IWUSR | S_IRUGO,
+                       hmc5843_show_operating_mode,
+                       hmc5843_set_operating_mode,
+                       HMC5843_MODE_REG);
+
+/*
+ * API for setting the measurement configuration to
+ * Normal, Positive bias and Negative bias
+ * From the datasheet
+ *
+ * Normal measurement configuration (default): In normal measurement
+ * configuration the device follows normal measurement flow. Pins BP and BN
+ * are left floating and high impedance.
+ *
+ * Positive bias configuration: In positive bias configuration, a positive
+ * current is forced across the resistive load on pins BP and BN.
+ *
+ * Negative bias configuration. In negative bias configuration, a negative
+ * current is forced across the resistive load on pins BP and BN.
+ *
+ */
+static s32 hmc5843_set_meas_conf(struct i2c_client *client,
+                                     u8 meas_conf)
+{
+       struct hmc5843_data *data = i2c_get_clientdata(client);
+       u8 reg_val;
+       reg_val = (meas_conf & MEAS_CONF_MASK) |  (data->rate << RATE_OFFSET);
+       return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+}
+
+static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
+                                               struct device_attribute *attr,
+                                               char *buf)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct hmc5843_data *data = indio_dev->dev_data;
+       return sprintf(buf, "%d\n", data->meas_conf);
+}
+
+static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf,
+                                               size_t count)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+       struct hmc5843_data *data = i2c_get_clientdata(client);
+       unsigned long meas_conf = 0;
+       int error = strict_strtoul(buf, 10, &meas_conf);
+       if (error)
+               return error;
+       mutex_lock(&data->lock);
+
+       dev_dbg(dev, "set mode to %lu\n", meas_conf);
+       if (hmc5843_set_meas_conf(client, meas_conf)) {
+               count = -EINVAL;
+               goto exit;
+       }
+       data->meas_conf = meas_conf;
+
+exit:
+       mutex_unlock(&data->lock);
+       return count;
+}
+static IIO_DEVICE_ATTR(meas_conf,
+                       S_IWUSR | S_IRUGO,
+                       hmc5843_show_measurement_configuration,
+                       hmc5843_set_measurement_configuration,
+                       0);
+
+/*
+ * From Datasheet
+ * The table shows the minimum data output
+ * Value       | Minimum data output rate(Hz)
+ * 0           | 0.5
+ * 1           | 1
+ * 2           | 2
+ * 3           | 5
+ * 4           | 10 (default)
+ * 5           | 20
+ * 6           | 50
+ * 7           | Not used
+ */
+static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
+
+static s32 hmc5843_set_rate(struct i2c_client *client,
+                               u8 rate)
+{
+       struct hmc5843_data *data = i2c_get_clientdata(client);
+       u8 reg_val;
+
+       reg_val = (data->meas_conf) |  (rate << RATE_OFFSET);
+       if (rate >= RATE_NOT_USED) {
+               dev_err(&client->dev,
+                       "This data output rate is not supported \n");
+               return -EINVAL;
+       }
+       return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+}
+
+static ssize_t set_sampling_frequency(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+       struct hmc5843_data *data = indio_dev->dev_data;
+       unsigned long rate = 0;
+
+       if (strncmp(buf, "0.5" , 3) == 0)
+               rate = RATE_5;
+       else if (strncmp(buf, "1" , 1) == 0)
+               rate = RATE_10;
+       else if (strncmp(buf, "2", 1) == 0)
+               rate = RATE_20;
+       else if (strncmp(buf, "5", 1) == 0)
+               rate = RATE_50;
+       else if (strncmp(buf, "10", 2) == 0)
+               rate = RATE_100;
+       else if (strncmp(buf, "20" , 2) == 0)
+               rate = RATE_200;
+       else if (strncmp(buf, "50" , 2) == 0)
+               rate = RATE_500;
+       else
+               return -EINVAL;
+
+       mutex_lock(&data->lock);
+       dev_dbg(dev, "set rate to %lu\n", rate);
+       if (hmc5843_set_rate(client, rate)) {
+               count = -EINVAL;
+               goto exit;
+       }
+       data->rate = rate;
+
+exit:
+       mutex_unlock(&data->lock);
+       return count;
+}
+
+static ssize_t show_sampling_frequency(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       u32 rate;
+
+       rate = i2c_smbus_read_byte_data(client,  this_attr->address);
+       if (rate < 0)
+               return -EINVAL;
+       rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
+       return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
+}
+static IIO_DEVICE_ATTR(sampling_frequency,
+                       S_IWUSR | S_IRUGO,
+                       show_sampling_frequency,
+                       set_sampling_frequency,
+                       HMC5843_CONFIG_REG_A);
+
+/*
+ * From Datasheet
+ *     Nominal gain settings
+ * Value       | Sensor Input Field Range(Ga)  | Gain(counts/ milli-gauss)
+ *0            |(+-)0.7                        |1620
+ *1            |(+-)1.0                        |1300
+ *2            |(+-)1.5                        |970
+ *3            |(+-)2.0                        |780
+ *4            |(+-)3.2                        |530
+ *5            |(+-)3.8                        |460
+ *6            |(+-)4.5                        |390
+ *7            |(+-)6.5                        |280
+ */
+static ssize_t show_range(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       u8 range;
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct hmc5843_data *data = indio_dev->dev_data;
+
+       range = data->range;
+       return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
+}
+
+static ssize_t set_range(struct device *dev,
+                       struct device_attribute *attr,
+                       const char *buf,
+                       size_t count)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       struct hmc5843_data *data = indio_dev->dev_data;
+       unsigned long range = 0;
+       int error;
+       mutex_lock(&data->lock);
+       error = strict_strtoul(buf, 10, &range);
+       if (error)
+               return error;
+       dev_dbg(dev, "set range to %lu\n", range);
+
+       if (range > RANGE_6_5)
+               return -EINVAL;
+
+       data->range = range;
+       range = range << RANGE_GAIN_OFFSET;
+       if (i2c_smbus_write_byte_data(client, this_attr->address, range))
+               count = -EINVAL;
+
+       mutex_unlock(&data->lock);
+       return count;
+
+}
+static IIO_DEVICE_ATTR(magn_range,
+                       S_IWUSR | S_IRUGO,
+                       show_range,
+                       set_range,
+                       HMC5843_CONFIG_REG_B);
+
+static ssize_t show_gain(struct device *dev,
+                       struct device_attribute *attr,
+                       char *buf)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct hmc5843_data *data = indio_dev->dev_data;
+       return sprintf(buf, "%d\n", regval_to_counts_per_mg[data->range]);
+}
+static IIO_DEVICE_ATTR(magn_gain,
+                       S_IRUGO,
+                       show_gain,
+                       NULL , 0);
+
+static struct attribute *hmc5843_attributes[] = {
+       &iio_dev_attr_meas_conf.dev_attr.attr,
+       &iio_dev_attr_operating_mode.dev_attr.attr,
+       &iio_dev_attr_sampling_frequency.dev_attr.attr,
+       &iio_dev_attr_magn_range.dev_attr.attr,
+       &iio_dev_attr_magn_gain.dev_attr.attr,
+       &iio_dev_attr_magn_x_raw.dev_attr.attr,
+       &iio_dev_attr_magn_y_raw.dev_attr.attr,
+       &iio_dev_attr_magn_z_raw.dev_attr.attr,
+       &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group hmc5843_group = {
+       .attrs = hmc5843_attributes,
+};
+
+static int hmc5843_detect(struct i2c_client *client,
+                         struct i2c_board_info *info)
+{
+       unsigned char id_str[HMC5843_ID_REG_LENGTH];
+
+       if (client->addr != HMC5843_I2C_ADDRESS)
+               return -ENODEV;
+
+       if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
+                               HMC5843_ID_REG_LENGTH, id_str)
+                       != HMC5843_ID_REG_LENGTH)
+               return -ENODEV;
+
+       if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
+               return -ENODEV;
+
+       return 0;
+}
+
+/* Called when we have found a new HMC5843. */
+static void hmc5843_init_client(struct i2c_client *client)
+{
+       struct hmc5843_data *data = i2c_get_clientdata(client);
+       hmc5843_set_meas_conf(client, data->meas_conf);
+       hmc5843_set_rate(client, data->rate);
+       hmc5843_configure(client, data->operating_mode);
+       i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
+       mutex_init(&data->lock);
+       pr_info("HMC5843 initialized\n");
+}
+
+static int hmc5843_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct hmc5843_data *data;
+       int err = 0;
+
+       data = kzalloc(sizeof(struct hmc5843_data), GFP_KERNEL);
+       if (!data) {
+               err = -ENOMEM;
+               goto exit;
+       }
+
+       /* default settings at probe */
+
+       data->meas_conf = CONF_NORMAL;
+       data->range = RANGE_1_0;
+       data->operating_mode = MODE_CONVERSION_CONTINUOUS;
+
+       i2c_set_clientdata(client, data);
+
+       /* Initialize the HMC5843 chip */
+       hmc5843_init_client(client);
+
+       data->indio_dev = iio_allocate_device();
+       if (!data->indio_dev) {
+               err = -ENOMEM;
+               goto exit_free1;
+       }
+       data->indio_dev->attrs = &hmc5843_group;
+       data->indio_dev->dev.parent = &client->dev;
+       data->indio_dev->dev_data = (void *)(data);
+       data->indio_dev->driver_module = THIS_MODULE;
+       data->indio_dev->modes = INDIO_DIRECT_MODE;
+       err = iio_device_register(data->indio_dev);
+       if (err)
+               goto exit_free2;
+       return 0;
+exit_free2:
+       iio_free_device(data->indio_dev);
+exit_free1:
+       kfree(data);
+exit:
+       return err;
+}
+
+static int hmc5843_remove(struct i2c_client *client)
+{
+       struct hmc5843_data *data = i2c_get_clientdata(client);
+        /*  sleep mode to save power */
+       hmc5843_configure(client, MODE_SLEEP);
+       iio_device_unregister(data->indio_dev);
+       kfree(i2c_get_clientdata(client));
+       return 0;
+}
+
+static int hmc5843_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+       hmc5843_configure(client, MODE_SLEEP);
+       return 0;
+}
+
+static int hmc5843_resume(struct i2c_client *client)
+{
+       struct hmc5843_data *data = i2c_get_clientdata(client);
+       hmc5843_configure(client, data->operating_mode);
+       return 0;
+}
+
+static const struct i2c_device_id hmc5843_id[] = {
+       { "hmc5843", 0 },
+       { }
+};
+
+static struct i2c_driver hmc5843_driver = {
+       .driver = {
+               .name   = "hmc5843",
+       },
+       .id_table       = hmc5843_id,
+       .probe          = hmc5843_probe,
+       .remove         = hmc5843_remove,
+       .detect         = hmc5843_detect,
+       .address_list   = normal_i2c,
+       .suspend        = hmc5843_suspend,
+       .resume         = hmc5843_resume,
+};
+
+static int __init hmc5843_init(void)
+{
+       return i2c_add_driver(&hmc5843_driver);
+}
+
+static void __exit hmc5843_exit(void)
+{
+       i2c_del_driver(&hmc5843_driver);
+}
+
+MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
+MODULE_DESCRIPTION("HMC5843 driver");
+MODULE_LICENSE("GPL");
+
+module_init(hmc5843_init);
+module_exit(hmc5843_exit);
index 0e443757b029ab6a928aa07fa8a60aba8a863445..a872d3904a33e8af6f33c535d2e157b7d6871c3d 100644 (file)
@@ -11,6 +11,8 @@
 #define _IIO_RING_GENERIC_H_
 #include "iio.h"
 
+#ifdef CONFIG_IIO_RING_BUFFER
+
 struct iio_handler;
 struct iio_ring_buffer;
 struct iio_dev;
@@ -98,6 +100,7 @@ struct iio_ring_access_funcs {
  * @access_id:         device id number
  * @length:            [DEVICE] number of datums in ring
  * @bpd:               [DEVICE] size of individual datum including timestamp
+ * @bpe:               [DEVICE] size of individual channel value
  * @loopcount:         [INTERN] number of times the ring has looped
  * @access_handler:    [INTERN] chrdev access handling
  * @ev_int:            [INTERN] chrdev interface for the event chrdev
@@ -119,6 +122,7 @@ struct iio_ring_buffer {
        int                             access_id;
        int                             length;
        int                             bpd;
+       int                             bpe;
        int                             loopcount;
        struct iio_handler              access_handler;
        struct iio_event_interface      ev_int;
@@ -213,7 +217,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
  * @_label:    indentification variable used by drivers.  Often a reg address.
  * @_controlfunc: function used to notify hardware of whether state changes
  **/
-#define IIO_SCAN_EL_C(_name, _number, _bits, _label, _controlfunc)     \
+#define __IIO_SCAN_EL_C(_name, _number, _bits, _label, _controlfunc)   \
        struct iio_scan_el iio_scan_el_##_name = {                      \
                .dev_attr = __ATTR(_number##_##_name##_en,              \
                                   S_IRUGO | S_IWUSR,                   \
@@ -225,7 +229,10 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
                .set_state = _controlfunc,                              \
        }
 
-#define IIO_SCAN_NAMED_EL_C(_name, _string, _number, _bits, _label, _cf) \
+#define IIO_SCAN_EL_C(_name, _number, _bits, _label, _controlfunc)     \
+       __IIO_SCAN_EL_C(_name, _number, _bits, _label, _controlfunc)
+
+#define __IIO_SCAN_NAMED_EL_C(_name, _string, _number, _bits, _label, _cf) \
        struct iio_scan_el iio_scan_el_##_name = {                      \
                .dev_attr = __ATTR(_number##_##_string##_en,            \
                                   S_IRUGO | S_IWUSR,                   \
@@ -236,7 +243,8 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
                .label = _label,                                        \
                .set_state = _cf,                                       \
        }
-
+#define IIO_SCAN_NAMED_EL_C(_name, _string, _number, _bits, _label, _cf) \
+       __IIO_SCAN_NAMED_EL_C(_name, _string, _number, _bits, _label, _cf)
 /**
  * IIO_SCAN_EL_TIMESTAMP - declare a special scan element for timestamps
  *
@@ -287,5 +295,14 @@ ssize_t iio_show_ring_enable(struct device *dev,
 #define IIO_RING_ENABLE_ATTR DEVICE_ATTR(ring_enable, S_IRUGO | S_IWUSR, \
                                         iio_show_ring_enable,          \
                                         iio_store_ring_enable)
+#else /* CONFIG_IIO_RING_BUFFER */
+static inline int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
+{
+       return 0;
+};
+static inline void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
+{};
+
+#endif /* CONFIG_IIO_RING_BUFFER */
 
 #endif /* _IIO_RING_GENERIC_H_ */
index 294272d0619fd0567143392d41bb6dae1babfe30..e2f01c640baf810896f2d50645441640b71d20a8 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/workqueue.h>
 #include "ring_sw.h"
+#include "trigger.h"
 
 static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
                                                int bytes_per_datum, int length)
@@ -431,5 +432,73 @@ void iio_sw_rb_free(struct iio_ring_buffer *r)
                iio_put_ring_buffer(r);
 }
 EXPORT_SYMBOL(iio_sw_rb_free);
+
+int iio_sw_ring_preenable(struct iio_dev *indio_dev)
+{
+       size_t size;
+       dev_dbg(&indio_dev->dev, "%s\n", __func__);
+       /* Check if there are any scan elements enabled, if not fail*/
+       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
+               return -EINVAL;
+       if (indio_dev->scan_timestamp)
+               if (indio_dev->scan_count)
+                       /* Timestamp (aligned to s64) and data */
+                       size = (((indio_dev->scan_count * indio_dev->ring->bpe)
+                                       + sizeof(s64) - 1)
+                               & ~(sizeof(s64) - 1))
+                               + sizeof(s64);
+               else /* Timestamp only  */
+                       size = sizeof(s64);
+       else /* Data only */
+               size = indio_dev->scan_count * indio_dev->ring->bpe;
+       indio_dev->ring->access.set_bpd(indio_dev->ring, size);
+
+       return 0;
+}
+EXPORT_SYMBOL(iio_sw_ring_preenable);
+
+void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
+{
+       struct iio_sw_ring_helper_state *st
+               = container_of(work_s, struct iio_sw_ring_helper_state,
+                       work_trigger_to_ring);
+       int len = 0;
+       size_t datasize = st->indio_dev
+               ->ring->access.get_bpd(st->indio_dev->ring);
+       char *data = kmalloc(datasize, GFP_KERNEL);
+
+       if (data == NULL) {
+               dev_err(st->indio_dev->dev.parent,
+                       "memory alloc failed in ring bh");
+               return;
+       }
+
+       if (st->indio_dev->scan_count)
+               len = st->get_ring_element(st, data);
+
+         /* Guaranteed to be aligned with 8 byte boundary */
+       if (st->indio_dev->scan_timestamp)
+               *(s64 *)(((phys_addr_t)data + len
+                               + sizeof(s64) - 1) & ~(sizeof(s64) - 1))
+                       = st->last_timestamp;
+         st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+                                       (u8 *)data,
+                       st->last_timestamp);
+
+       iio_trigger_notify_done(st->indio_dev->trig);
+       kfree(data);
+
+       return;
+}
+EXPORT_SYMBOL(iio_sw_trigger_bh_to_ring);
+
+void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time)
+{      struct iio_sw_ring_helper_state *h
+               = iio_dev_get_devdata(indio_dev);
+       h->last_timestamp = time;
+       schedule_work(&h->work_trigger_to_ring);
+}
+EXPORT_SYMBOL(iio_sw_poll_func_th);
+
 MODULE_DESCRIPTION("Industrialio I/O software ring buffer");
 MODULE_LICENSE("GPL");
index fd677f008365115abd0b23f7b47d740e5ff873c9..61f1ed650392e2af15d60ca17d9c81ce968bcf3b 100644 (file)
@@ -207,10 +207,21 @@ struct iio_sw_ring_buffer {
 struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
 void iio_sw_rb_free(struct iio_ring_buffer *ring);
 
+int iio_sw_ring_preenable(struct iio_dev *indio_dev);
 
+struct iio_sw_ring_helper_state {
+       struct work_struct              work_trigger_to_ring;
+       struct iio_dev                  *indio_dev;
+       int (*get_ring_element)(struct iio_sw_ring_helper_state *st, u8 *buf);
+       s64                             last_timestamp;
+};
+
+void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time);
+void iio_sw_trigger_bh_to_ring(struct work_struct *work_s);
 
 #else /* CONFIG_IIO_RING_BUFFER*/
-static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
-{};
+struct iio_sw_ring_helper_state {
+       struct iio_dev                  *indio_dev;
+};
 #endif /* !CONFIG_IIO_RING_BUFFER */
 #endif /* _IIO_RING_SW_H_ */
index afcf5ab85f482dad9295d14883c7e8403aac2b6a..60834162eb320a7a3b529324fc2844220c2d0ace 100644 (file)
@@ -284,6 +284,14 @@ struct iio_const_attr {
            .mask = _mask,                                              \
            .listel = &_ev_list };
 
+#define IIO_EVENT_ATTR_NAMED_SH(_vname, _name, _ev_list, _show, _store, _mask) \
+       static struct iio_event_attr                                    \
+       iio_event_attr_##_vname                                         \
+       = { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,                \
+                              _show, _store),                          \
+           .mask = _mask,                                              \
+           .listel = &_ev_list };
+
 /**
  * IIO_EVENT_ATTR - non-shared event attribute
  * @_name: event name
@@ -293,10 +301,7 @@ struct iio_const_attr {
  * @_handler: handler function to be called
  **/
 #define IIO_EVENT_ATTR(_name, _show, _store, _mask, _handler)          \
-       static struct iio_event_handler_list                            \
-       iio_event_##_name = {                                           \
-               .handler = _handler,                                    \
-       };                                                              \
+       IIO_EVENT_SH(_name, _handler);                                  \
        static struct                                                   \
        iio_event_attr                                                  \
        iio_event_attr_##_name                                          \
@@ -324,6 +329,7 @@ struct iio_const_attr {
 #define IIO_EVENT_CODE_GYRO_BASE       400
 #define IIO_EVENT_CODE_ADC_BASE                500
 #define IIO_EVENT_CODE_MISC_BASE       600
+#define IIO_EVENT_CODE_LIGHT_BASE      700
 
 #define IIO_EVENT_CODE_DEVICE_SPECIFIC 1000
 
index 784e7b6fac1cc745157746ca632b288861296684..4699586a593139c5049e997d1571946ed33a3793 100644 (file)
@@ -8,10 +8,6 @@
  */
 #ifndef _IIO_TRIGGER_H_
 #define _IIO_TRIGGER_H_
-#define IIO_TRIGGER_NAME_LENGTH 20
-#define IIO_TRIGGER_ID_PREFIX "iio:trigger"
-#define IIO_TRIGGER_ID_FORMAT IIO_TRIGGER_ID_PREFIX "%d"
-
 
 /**
  * struct iio_trigger - industrial I/O trigger device
@@ -25,7 +21,6 @@
  * @pollfunc_list_lock:        [INTERN] protection of the polling function list
  * @pollfunc_list:     [INTERN] list of functions to run on trigger.
  * @control_attrs:     [DRIVER] sysfs attributes relevant to trigger type
- * @timestamp:         [INTERN] timestamp usesd by some trigs (e.g. datardy)
  * @owner:             [DRIVER] used to monitor usage count of the trigger.
  * @use_count:         use count for the trigger
  * @set_trigger_state: [DRIVER] switch on/off the trigger on demand
@@ -43,7 +38,6 @@ struct iio_trigger {
        spinlock_t                      pollfunc_list_lock;
        struct list_head                pollfunc_list;
        const struct attribute_group    *control_attrs;
-       s64                             timestamp;
        struct module                   *owner;
        int use_count;
 
@@ -124,7 +118,7 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
  *
  * Typically called in relevant hardware interrupt handler.
  **/
-void iio_trigger_poll(struct iio_trigger *trig);
+void iio_trigger_poll(struct iio_trigger *trig, s64 time);
 void iio_trigger_notify_done(struct iio_trigger *trig);
 
 /**
@@ -148,13 +142,27 @@ struct iio_poll_func {
        struct                          list_head list;
        void                            *private_data;
        void (*poll_func_immediate)(struct iio_dev *indio_dev);
-       void (*poll_func_main)(struct iio_dev  *private_data);
+       void (*poll_func_main)(struct iio_dev *private_data, s64 time);
 
 };
 
+int iio_alloc_pollfunc(struct iio_dev *indio_dev,
+                      void (*immediate)(struct iio_dev *indio_dev),
+                      void (*main)(struct iio_dev *private_data, s64 time));
+
+/*
+ * Two functions for common case where all that happens is a pollfunc
+ * is attached and detached form a trigger
+ */
+int iio_triggered_ring_postenable(struct iio_dev *indio_dev);
+int iio_triggered_ring_predisable(struct iio_dev *indio_dev);
+
 struct iio_trigger *iio_allocate_trigger(void);
 
 void iio_free_trigger(struct iio_trigger *trig);
 
 
+struct iio_simple_trigger {
+       struct iio_trigger trig;
+};
 #endif /* _IIO_TRIGGER_H_ */
index e5f96d2fe64a2392fede5c2e17f5324566ea0dba..10aeca5e347a04d164ab417c62d7dd345f7d1699 100644 (file)
@@ -1,5 +1,6 @@
 #
 # Makefile for triggers not associated with iio-devices
 #
+
 obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o
-obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o
\ No newline at end of file
+obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o
index 1da285d28632a611eb0a930f71c7aeeffae445f8..f93cc916983242b38ea409271694b8d53a08a9ef 100644 (file)
@@ -42,7 +42,8 @@ struct iio_gpio_trigger_info {
 
 static irqreturn_t iio_gpio_trigger_poll(int irq, void *private)
 {
-       iio_trigger_poll(private);
+       /* Timestamp not currently provided */
+       iio_trigger_poll(private, 0);
        return IRQ_HANDLED;
 }
 
@@ -93,16 +94,11 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev)
                        trig->private_data = trig_info;
                        trig_info->irq = irq;
                        trig->owner = THIS_MODULE;
-                       trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH,
-                                       GFP_KERNEL);
-                       if (!trig->name) {
+                       trig->name = kasprintf(GFP_KERNEL, "irqtrig%d", irq);
+                       if (trig->name == NULL) {
                                ret = -ENOMEM;
                                goto error_free_trig_info;
                        }
-                       snprintf((char *)trig->name,
-                                IIO_TRIGGER_NAME_LENGTH,
-                                "irqtrig%d", irq);
-
                        ret = request_irq(irq, iio_gpio_trigger_poll,
                                          irqflags, trig->name, trig);
                        if (ret) {
index 4ee3ae1ef8923a1ad1cbddc70e2693aa42870798..b0b52f84edfd76ee0bdc2a2ebfcd9efc4202ba05 100644 (file)
@@ -25,7 +25,6 @@ static DEFINE_MUTEX(iio_prtc_trigger_list_lock);
 struct iio_prtc_trigger_info {
        struct rtc_device *rtc;
        int frequency;
-       char *name;
        struct rtc_task task;
 };
 
@@ -78,8 +77,7 @@ static ssize_t iio_trig_periodic_read_name(struct device *dev,
                                           char *buf)
 {
        struct iio_trigger *trig = dev_get_drvdata(dev);
-       struct iio_prtc_trigger_info *trig_info = trig->private_data;
-       return sprintf(buf, "%s\n", trig_info->name);
+       return sprintf(buf, "%s\n", trig->name);
 }
 
 static DEVICE_ATTR(name, S_IRUGO,
@@ -100,7 +98,8 @@ static const struct attribute_group iio_trig_prtc_attr_group = {
 
 static void iio_prtc_trigger_poll(void *private_data)
 {
-       iio_trigger_poll(private_data);
+       /* Timestamp is not provided currently */
+       iio_trigger_poll(private_data, 0);
 }
 
 static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
@@ -129,16 +128,12 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
                trig->private_data = trig_info;
                trig->owner = THIS_MODULE;
                trig->set_trigger_state = &iio_trig_periodic_rtc_set_state;
-               trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+               trig->name = kasprintf(GFP_KERNEL, "periodic%s", pdata[i]);
                if (trig->name == NULL) {
                        ret = -ENOMEM;
                        goto error_free_trig_info;
                }
-               snprintf((char *)trig->name,
-                        IIO_TRIGGER_NAME_LENGTH,
-                        "periodic%s",
-                        pdata[i]);
-               trig_info->name = (char *)trig->name;
+
                /* RTC access */
                trig_info->rtc
                        = rtc_class_open(pdata[i]);
index 7852d4a960c50fec42842826c209a135eb9dd71d..bc1ffbed3c8a30ae3421633f52a48826a8c3319d 100644 (file)
@@ -2,6 +2,7 @@ config LINE6_USB
        tristate "Line6 USB support"
        depends on USB && SND
        select SND_RAWMIDI
+       select SND_PCM
        help
          This is a driver for the guitar amp, cab, and effects modeller
          PODxt Pro by Line6 (and similar devices), supporting the
index 1d5a4730276363877f3f6e26f8e9710fc8811dd7..27b986a50a0390788e002871d741daa183e97b4d 100644 (file)
@@ -679,8 +679,10 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
        usb_get_dev(usbdev);
 
        /* we don't handle multiple configurations */
-       if (usbdev->descriptor.bNumConfigurations != 1)
-               return -ENODEV;
+       if (usbdev->descriptor.bNumConfigurations != 1) {
+               ret = -ENODEV;
+               goto err_put;
+       }
 
        /* check vendor and product id */
        for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) {
@@ -692,16 +694,20 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
                        break;
        }
 
-       if (devtype < 0)
-               return -ENODEV;
+       if (devtype < 0) {
+               ret = -ENODEV;
+               goto err_put;
+       }
 
        /* find free slot in device table: */
        for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum)
                if (line6_devices[devnum] == NULL)
                        break;
 
-       if (devnum == LINE6_MAX_DEVICES)
-               return -ENODEV;
+       if (devnum == LINE6_MAX_DEVICES) {
+               ret = -ENODEV;
+               goto err_put;
+       }
 
        /* initialize device info: */
        properties = &line6_properties_table[devtype];
@@ -762,13 +768,14 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
 
        default:
                MISSING_CASE;
-               return -ENODEV;
+               ret = -ENODEV;
+               goto err_put;
        }
 
        ret = usb_set_interface(usbdev, interface_number, alternate);
        if (ret < 0) {
                dev_err(&interface->dev, "set_interface failed\n");
-               return ret;
+               goto err_put;
        }
 
        /* initialize device data based on product id: */
@@ -815,7 +822,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
                        break;
 
                default:
-                       return -ENODEV;
+                       ret = -ENODEV;
+                       goto err_put;
                }
                break;
 
@@ -827,19 +835,22 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
 
        default:
                MISSING_CASE;
-               return -ENODEV;
+               ret = -ENODEV;
+               goto err_put;
        }
 
        if (size == 0) {
                dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto err_put;
        }
 
        line6 = kzalloc(size, GFP_KERNEL);
 
        if (line6 == NULL) {
                dev_err(&interface->dev, "Out of memory\n");
-               return -ENOMEM;
+               ret = -ENODEV;
+               goto err_put;
        }
 
        /* store basic data: */
@@ -875,16 +886,16 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
 
                if (line6->buffer_listen == NULL) {
                        dev_err(&interface->dev, "Out of memory\n");
-                       line6_destruct(interface);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_destruct;
                }
 
                line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
 
                if (line6->buffer_message == NULL) {
                        dev_err(&interface->dev, "Out of memory\n");
-                       line6_destruct(interface);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_destruct;
                }
 
                line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
@@ -892,15 +903,15 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
                if (line6->urb_listen == NULL) {
                        dev_err(&interface->dev, "Out of memory\n");
                        line6_destruct(interface);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_destruct;
                }
 
                ret = line6_start_listen(line6);
                if (ret < 0) {
                        dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
                                __func__);
-                       line6_destruct(interface);
-                       return ret;
+                       goto err_destruct;
                }
        }
 
@@ -952,22 +963,25 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
                ret = -ENODEV;
        }
 
-       if (ret < 0) {
-               line6_destruct(interface);
-               return ret;
-       }
+       if (ret < 0)
+               goto err_destruct;
 
        ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
                                "usb_device");
-       if (ret < 0) {
-               line6_destruct(interface);
-               return ret;
-       }
+       if (ret < 0)
+               goto err_destruct;
 
        dev_info(&interface->dev, "Line6 %s now attached\n",
                 line6->properties->name);
        line6_devices[devnum] = line6;
        line6_list_devices();
+       return 0;
+
+err_destruct:
+       line6_destruct(interface);
+err_put:
+       usb_put_intf(interface);
+       usb_put_dev(usbdev);
        return ret;
 }
 
index 0087447d503474623bbc72cdbd08fdd71e41aa39..435e09ba44c51cfd925cb1d76a9457302cf39e99 100644 (file)
@@ -1,7 +1,7 @@
 RAR Handler (memrar) Driver TODO Items
 ======================================
 
-Maintainer: Ossama Othman <ossama.othman@intel.com>
+Maintainer: Eugene Epshteyn <eugene.epshteyn@intel.com>
 
 memrar.h
 --------
index 98a6bb158baf7998701293a4cece9b1fcde6bede..c23fc996a4356b257c18c67a6ad59ae530e366a6 100644 (file)
@@ -1,7 +1,7 @@
 What:          /dev/memrar
 Date:          March 2010
-KernelVersion: Kernel version this feature first showed up in.
-Contact:       Ossama Othman <ossama.othman@intel.com>
+KernelVersion: 2.6.34
+Contact:       Eugene Epshteyn <eugene.epshteyn@intel.com>
 Description:   The Intel Moorestown Restricted Access Region (RAR)
                Handler driver exposes an ioctl() based interface that
                allows a user to reserve and release blocks of RAR
index 41876f2b0e548b1c31ef585110e8501f22019439..a98b3f1f11e00a11293c548b2389ed684714c818 100644 (file)
@@ -278,19 +278,10 @@ static int memrar_init_rar_resources(int rarnum, char const *devname)
        BUG_ON(!memrar_is_valid_rar_type(rarnum));
        BUG_ON(rar->allocated);
 
-       mutex_init(&rar->lock);
-
-       /*
-        * Initialize the process table before we reach any
-        * code that exit on failure since the finalization
-        * code requires an initialized list.
-        */
-       INIT_LIST_HEAD(&rar->buffers.list);
-
        if (rar_get_address(rarnum, &low, &high) != 0)
                /* No RAR is available. */
                return -ENODEV;
-       
+
        if (low == 0 || high == 0) {
                rar->base      = 0;
                rar->length    = 0;
@@ -310,7 +301,8 @@ static int memrar_init_rar_resources(int rarnum, char const *devname)
        /* Claim RAR memory as our own. */
        if (request_mem_region(low, rar->length, devname) == NULL) {
                rar->length = 0;
-               pr_err("%s: Unable to claim RAR[%d] memory.\n", devname, rarnum);
+               pr_err("%s: Unable to claim RAR[%d] memory.\n",
+                      devname, rarnum);
                pr_err("%s: RAR[%d] disabled.\n", devname, rarnum);
                return -EBUSY;
        }
@@ -346,7 +338,7 @@ static int memrar_init_rar_resources(int rarnum, char const *devname)
        }
 
        pr_info("%s: BRAR[%d] bus address range = [0x%lx, 0x%lx]\n",
-                       devname, rarnum, (unsigned long) low, (unsigned long) high);
+               devname, rarnum, (unsigned long) low, (unsigned long) high);
 
        pr_info("%s: BRAR[%d] size = %zu KiB\n",
                        devname, rarnum, rar->allocator->capacity / 1024);
@@ -530,7 +522,7 @@ static long memrar_get_stat(struct RAR_stat *r)
 {
        struct memrar_allocator *allocator;
 
-       if (!memrar_is_valid_rar_type(r->type))
+       if (!memrar_is_valid_rar_type(r->type))
                return -EINVAL;
 
        if (!memrars[r->type].allocated)
@@ -939,9 +931,28 @@ static int memrar_registration_callback(unsigned long rar)
 static int __init memrar_init(void)
 {
        int err;
+       int i;
 
        printk(banner);
 
+       /*
+        * Some delayed initialization is performed in this driver.
+        * Make sure resources that are used during driver clean-up
+        * (e.g. during driver's release() function) are fully
+        * initialized before first use.  This is particularly
+        * important for the case when the delayed initialization
+        * isn't completed, leaving behind a partially initialized
+        * driver.
+        *
+        * Such a scenario can occur when RAR is not available on the
+        * platform, and the driver is release()d.
+        */
+       for (i = 0; i != ARRAY_SIZE(memrars); ++i) {
+               struct memrar_rar_info * const rar = &memrars[i];
+               mutex_init(&rar->lock);
+               INIT_LIST_HEAD(&rar->buffers.list);
+       }
+
        err = misc_register(&memrar_miscdev);
        if (err)
                return err;
index c57039f2060b29d76e5794fd954e1bf5e5ef89f4..c5309eec58fa96ca34a547b7bfbc3bda9275adb4 100644 (file)
@@ -46,21 +46,11 @@ config FB_MSM_LCDC_PRISM_WVGA
        select FB_MSM_LCDC_PANEL
        default n
 
-config FB_MSM_LCDC_ST1_WXGA
-       bool
-       select FB_MSM_LCDC_PANEL
-       default n
-
 config FB_MSM_LCDC_ST15_WXGA
         bool
         select FB_MSM_LCDC_PANEL
         default n
 
-config FB_MSM_LCDC_WXGA
-       bool
-       select FB_MSM_LCDC_PANEL
-       default n
-
 choice
        prompt "LCD Panel"
        default FB_MSM_LCDC_ST15_PANEL
index 98a0ce177cb28c8ee7d585f5f3200708f658f86d..bb3606faf20e975bc76db09d488f1615a5b73244 100644 (file)
@@ -61,14 +61,12 @@ obj-y += mddi_prism.o
 obj-y += mddi_toshiba.o
 obj-y += mddi_toshiba_vga.o
 obj-y += mddi_toshiba_wvga_pt.o
-obj-y += mddi_toshiba_wvga.o
 obj-y += mddi_sharp.o
 else
 obj-$(CONFIG_FB_MSM_MDDI_PRISM_WVGA) += mddi_prism.o
 obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON) += mddi_toshiba.o
 obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON_VGA) += mddi_toshiba_vga.o
 obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT) += mddi_toshiba_wvga_pt.o
-obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA) += mddi_toshiba_wvga.o
 obj-$(CONFIG_FB_MSM_MDDI_SHARP_QVGA_128x128) += mddi_sharp.o
 endif
 
@@ -76,11 +74,8 @@ obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
 obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o
 obj-$(CONFIG_FB_MSM_LCDC_EXTERNAL_WXGA) += lcdc_external.o
 obj-$(CONFIG_FB_MSM_LCDC_GORDON_VGA) += lcdc_gordon.o
-obj-$(CONFIG_FB_MSM_LCDC_WXGA) += lcdc_wxga.o
 obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_WVGA_PT) += lcdc_toshiba_wvga_pt.o
 obj-$(CONFIG_FB_MSM_LCDC_SHARP_WVGA_PT) += lcdc_sharp_wvga_pt.o
-obj-$(CONFIG_FB_MSM_LCDC_GRAPEFRUIT_VGA) += lcdc_grapefruit.o
-obj-$(CONFIG_FB_MSM_LCDC_ST1_WXGA) += lcdc_st1_wxga.o
 obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
 obj-$(CONFIG_FB_MSM_HDMI_SII_EXTERNAL_720P) += hdmi_sii9022.o
 
diff --git a/drivers/staging/msm/lcdc_grapefruit.c b/drivers/staging/msm/lcdc_grapefruit.c
deleted file mode 100644 (file)
index 7284649..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "msm_fb.h"
-
-#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
-#include "mddihosti.h"
-#endif
-
-static int __init lcdc_grapefruit_init(void)
-{
-       int ret;
-       struct msm_panel_info pinfo;
-
-#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
-       if (msm_fb_detect_client("lcdc_grapefruit_vga"))
-               return 0;
-#endif
-
-       pinfo.xres = 1024;
-       pinfo.yres = 600;
-       pinfo.type = LCDC_PANEL;
-       pinfo.pdest = DISPLAY_1;
-       pinfo.wait_cycle = 0;
-       pinfo.bpp = 18;
-       pinfo.fb_num = 2;
-       pinfo.clk_rate = 40000000;
-
-       pinfo.lcdc.h_back_porch = 88;
-       pinfo.lcdc.h_front_porch = 40;
-       pinfo.lcdc.h_pulse_width = 128;
-       pinfo.lcdc.v_back_porch = 23;
-       pinfo.lcdc.v_front_porch = 1;
-       pinfo.lcdc.v_pulse_width = 4;
-       pinfo.lcdc.border_clr = 0;      /* blk */
-       pinfo.lcdc.underflow_clr = 0xff;        /* blue */
-       pinfo.lcdc.hsync_skew = 0;
-
-       ret = lcdc_device_register(&pinfo);
-       if (ret)
-               printk(KERN_ERR "%s: failed to register device!\n", __func__);
-
-       return ret;
-}
-
-module_init(lcdc_grapefruit_init);
diff --git a/drivers/staging/msm/lcdc_st1_wxga.c b/drivers/staging/msm/lcdc_st1_wxga.c
deleted file mode 100644 (file)
index 7376001..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "msm_fb.h"
-
-static int __init lcdc_st1_wxga_init(void)
-{
-       int ret;
-       struct msm_panel_info pinfo;
-
-       if (msm_fb_detect_client("lcdc_st1_wxga"))
-               return 0;
-
-       pinfo.xres = 1280;
-       pinfo.yres = 720;
-       pinfo.type = LCDC_PANEL;
-       pinfo.pdest = DISPLAY_1;
-       pinfo.wait_cycle = 0;
-       pinfo.bpp = 18;
-       pinfo.fb_num = 2;
-       pinfo.clk_rate = 74250000;
-
-       pinfo.lcdc.h_back_porch = 124;
-       pinfo.lcdc.h_front_porch = 110;
-       pinfo.lcdc.h_pulse_width = 136;
-       pinfo.lcdc.v_back_porch = 19;
-       pinfo.lcdc.v_front_porch = 5;
-       pinfo.lcdc.v_pulse_width = 6;
-       pinfo.lcdc.border_clr = 0;      /* blk */
-       pinfo.lcdc.underflow_clr = 0xff;        /* blue */
-       pinfo.lcdc.hsync_skew = 0;
-
-       ret = lcdc_device_register(&pinfo);
-       if (ret)
-               printk(KERN_ERR "%s: failed to register device!\n", __func__);
-
-       return ret;
-}
-
-module_init(lcdc_st1_wxga_init);
diff --git a/drivers/staging/msm/lcdc_wxga.c b/drivers/staging/msm/lcdc_wxga.c
deleted file mode 100644 (file)
index 202c92c..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "msm_fb.h"
-
-static int __init lcdc_wxga_init(void)
-{
-       int ret;
-       struct msm_panel_info pinfo;
-
-#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
-       if (msm_fb_detect_client("lcdc_wxga"))
-               return 0;
-#endif
-
-       pinfo.xres = 1280;
-       pinfo.yres = 720;
-       pinfo.type = LCDC_PANEL;
-       pinfo.pdest = DISPLAY_1;
-       pinfo.wait_cycle = 0;
-       pinfo.bpp = 24;
-       pinfo.fb_num = 2;
-       pinfo.clk_rate = 74250000;
-
-       pinfo.lcdc.h_back_porch = 124;
-       pinfo.lcdc.h_front_porch = 110;
-       pinfo.lcdc.h_pulse_width = 136;
-       pinfo.lcdc.v_back_porch = 19;
-       pinfo.lcdc.v_front_porch = 5;
-       pinfo.lcdc.v_pulse_width = 6;
-       pinfo.lcdc.border_clr = 0;      /* blk */
-       pinfo.lcdc.underflow_clr = 0xff;        /* blue */
-       pinfo.lcdc.hsync_skew = 0;
-
-       ret = lcdc_device_register(&pinfo);
-       if (ret)
-               printk(KERN_ERR "%s: failed to register device!\n", __func__);
-
-       return ret;
-}
-
-module_init(lcdc_wxga_init);
diff --git a/drivers/staging/msm/mddi_toshiba_wvga.c b/drivers/staging/msm/mddi_toshiba_wvga.c
deleted file mode 100644 (file)
index 557b0f0..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "msm_fb.h"
-#include "mddihost.h"
-#include "mddi_toshiba.h"
-
-static int __init mddi_toshiba_wvga_init(void)
-{
-       int ret;
-       struct msm_panel_info pinfo;
-
-#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
-       if (msm_fb_detect_client("mddi_toshiba_wvga"))
-               return 0;
-#endif
-
-       pinfo.xres = 800;
-       pinfo.yres = 480;
-       pinfo.pdest = DISPLAY_2;
-       pinfo.type = MDDI_PANEL;
-       pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
-       pinfo.wait_cycle = 0;
-       pinfo.bpp = 18;
-       pinfo.lcd.vsync_enable = TRUE;
-       pinfo.lcd.refx100 = 6118;
-       pinfo.lcd.v_back_porch = 6;
-       pinfo.lcd.v_front_porch = 0;
-       pinfo.lcd.v_pulse_width = 0;
-       pinfo.lcd.hw_vsync_mode = FALSE;
-       pinfo.lcd.vsync_notifier_period = (1 * HZ);
-       pinfo.bl_max = 4;
-       pinfo.bl_min = 1;
-       pinfo.clk_rate = 192000000;
-       pinfo.clk_min =  190000000;
-       pinfo.clk_max =  200000000;
-       pinfo.fb_num = 2;
-
-       ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM,
-                                          LCD_TOSHIBA_2P4_WVGA);
-       if (ret) {
-               printk(KERN_ERR "%s: failed to register device!\n", __func__);
-               return ret;
-       }
-
-       return ret;
-}
-
-module_init(mddi_toshiba_wvga_init);
index 20b817841c4a93c755389cf13917f41adfb06821..c46f24aea25020348530ea1ffadef1a9c2df7344 100644 (file)
@@ -44,8 +44,6 @@
 
 #include <asm/system.h>
 #include <asm/mach-types.h>
-#include <linux/types.h>
-#include <linux/dma-mapping.h>
 
 #include "msm_fb_panel.h"
 
index 844d46775ecd3cfa630b9ad8c88cfcdc1c95442b..36954e89478c78cd7f8872ec86fe3eac069aeeb7 100644 (file)
@@ -63,13 +63,6 @@ DEFINE_SIMPLE_ATTRIBUTE(
                        "%llx\n");
 
 
-static int mdp4_debugfs_open(struct inode *inode, struct file *file)
-{
-       /* non-seekable */
-       file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
-       return 0;
-}
-
 static int mdp4_debugfs_release(struct inode *inode, struct file *file)
 {
        return 0;
@@ -144,10 +137,11 @@ static ssize_t mdp4_debugfs_read(
 }
 
 static const struct file_operations mdp4_debugfs_fops = {
-       .open = mdp4_debugfs_open,
+       .open = nonseekable_open,
        .release = mdp4_debugfs_release,
        .read = mdp4_debugfs_read,
        .write = mdp4_debugfs_write,
+       .llseek = no_llseek,
 };
 
 int mdp4_debugfs_init(void)
index 304bb829763508f57723516db30c06b94d4bdd35..de284c28faa123ad4fa749e94105d45490c2038e 100644 (file)
@@ -874,8 +874,8 @@ struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void)
                if (pipe->pipe_ndx == 0) {
                        pipe->pipe_ndx = i + 1; /* start from 1 */
                        init_completion(&pipe->comp);
-       printk(KERN_INFO "mdp4_overlay_pipe_alloc: pipe=%x ndx=%d\n",
-                                       (int)pipe, pipe->pipe_ndx);
+       printk(KERN_INFO "mdp4_overlay_pipe_alloc: pipe=%p ndx=%d\n",
+                                       pipe, pipe->pipe_ndx);
                        return pipe;
                }
                pipe++;
@@ -887,8 +887,8 @@ struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void)
 
 void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
 {
-       printk(KERN_INFO "mdp4_overlay_pipe_free: pipe=%x ndx=%d\n",
-                                       (int)pipe, pipe->pipe_ndx);
+       printk(KERN_INFO "mdp4_overlay_pipe_free: pipe=%p ndx=%d\n",
+                                       pipe, pipe->pipe_ndx);
        memset(pipe, 0, sizeof(*pipe));
 }
 
index 6de4409374221700eb243ad180f1e4b7f1397fd3..c5f9e9e670fbb54c48d6a56df6429c7c76c6a97d 100644 (file)
 #include <linux/debugfs.h>
 #include <linux/console.h>
 
-#include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/time.h>
-#include <linux/init.h>
 #include <linux/interrupt.h>
-#include "linux/proc_fs.h"
 #include <mach/hardware.h>
 #include <linux/io.h>
-#include <linux/fb.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 #include <linux/platform_device.h>
index 0f8ec3e260132417dba1c7e7d32e29040f93fb76..861f330723144082af5f745dc97b9d53204ed3fa 100644 (file)
@@ -18,7 +18,6 @@
 #include "msm_mdp.h"
 #include "memory_ll.h"
 //#include "android_pmem.h"
-#include <mach/board.h>
 
 #ifdef CONFIG_MSM_SOC_REV_A
 #define MSM_SMI_BASE 0xE0000000
@@ -115,17 +114,7 @@ static int msm_fb_detect_panel(const char *name)
        } else if ((machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf())
                        && !strcmp(name, "lcdc_external"))
                ret = 0;
-       else if (0 /*machine_is_qsd8x50_grapefruit() */) {
-               if (!strcmp(name, "lcdc_grapefruit_vga"))
-                       ret = 0;
-               else
-                       ret = -ENODEV;
-       } else if (machine_is_qsd8x50_st1()) {
-               if (!strcmp(name, "lcdc_st1_wxga"))
-                       ret = 0;
-               else
-                       ret = -ENODEV;
-       } else if (machine_is_qsd8x50a_st1_5()) {
+       else if (machine_is_qsd8x50a_st1_5()) {
                if (!strcmp(name, "lcdc_st15") ||
                    !strcmp(name, "hdmi_sii9022"))
                        ret = 0;
index 976227b01273605542485fe575320fb03b2c1f52..e9809d375162b0870f2830583720b1da0126b5de 100644 (file)
@@ -140,21 +140,21 @@ cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
        if (qstate->base_ptr_div128) {
                if (max_depth != (int)qstate->max_depth) {
                        cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
-                               "Queue already initalized with different "
+                               "Queue already initialized with different "
                                "max_depth (%d).\n",
                             (int)qstate->max_depth);
                        return CVMX_CMD_QUEUE_INVALID_PARAM;
                }
                if (fpa_pool != qstate->fpa_pool) {
                        cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
-                               "Queue already initalized with different "
+                               "Queue already initialized with different "
                                "FPA pool (%u).\n",
                             qstate->fpa_pool);
                        return CVMX_CMD_QUEUE_INVALID_PARAM;
                }
                if ((pool_size >> 3) - 1 != qstate->pool_size_m1) {
                        cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
-                               "Queue already initalized with different "
+                               "Queue already initialized with different "
                                "FPA pool size (%u).\n",
                             (qstate->pool_size_m1 + 1) << 3);
                        return CVMX_CMD_QUEUE_INVALID_PARAM;
index 29bdce66cdf8eca7dc9f3d8e1195f4107969c96c..a6939fc8ba188110dc2730927cb46c00856e0ca3 100644 (file)
@@ -299,7 +299,7 @@ cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
 /**
  * Builds I/O data for async operations
  *
- * @scraddr: Scratch pad byte addres to write to.  Must be 8 byte aligned
+ * @scraddr: Scratch pad byte address to write to.  Must be 8 byte aligned
  * @value:   Signed value to add.
  *                Note: When performing 32 and 64 bit access, only the low
  *                22 bits are available.
index b58b8971f93938327e28e0c9761024ce7913ca2d..970825421884d44526385d7782d4faa40207501c 100644 (file)
@@ -294,6 +294,8 @@ int cvm_oct_spi_init(struct net_device *dev)
        if (number_spi_ports == 0) {
                r = request_irq(OCTEON_IRQ_RML, cvm_oct_spi_rml_interrupt,
                                IRQF_SHARED, "SPI", &number_spi_ports);
+               if (r)
+                       return r;
        }
        number_spi_ports++;
 
index a127196260e6847cd343c4ffd5b0d3d9836530df..135167d23d0ff8b988cb23386937e12ca732f08d 100644 (file)
@@ -3117,7 +3117,7 @@ u16_t zfWlanRxFilter(zdev_t* dev, zbuf_t* buf)
 
     index = (src[2]+up) & (ZM_FILTER_TABLE_ROW-1);
 
-    /* TBD : filter frame with source address == own MAC adress */
+    /* TBD : filter frame with source address == own MAC address */
     if ((wd->macAddr[0] == src[0]) && (wd->macAddr[1] == src[1])
             && (wd->macAddr[2] == src[2]))
     {
index 4caf026a4915df1466c5c7df386af673fd0cf35b..6fea974fcc9fb2fe35017cebdd353a9f247b7c96 100644 (file)
@@ -2,15 +2,7 @@ I'm hesitant to add a TODO file here, as the wireless developers would
 really have people help them out on the "clean" ar9170 driver that can
 be found at the linux-wireless developer site.
 
-But, if you wish to clean up this driver instead, here's a short list of
-things that need to be done to get it into a more mergable shape:
-
-TODO:
-       - checkpatch.pl cleanups
-       - sparse cleanups
-       - port to in-kernel 80211 stack
-       - review by the wireless developer community
-
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Luis Rodriguez <Luis.Rodriguez@Atheros.com> and the
-otus-devel@lists.madwifi-project.org mailing list.
+This driver is unmaintained and its only purpose is as a
+source of documentation for developers working on ar9170 and carl9170.
+Once carl9170 gets 11n support and merged upstream then this driver
+can be removed.
index b59028e7e33c607ff4555b48a0b5aaa808d2df43..09415a6b93cab3ecf6c67837492471c79a491dc5 100644 (file)
@@ -90,28 +90,6 @@ struct zdap_ioctl {
 
 #endif
 
-static char hex(char v)
-{
-       if (isdigit(v))
-               return v - '0';
-       else if (isxdigit(v))
-               return tolower(v) - 'a' + 10;
-       else
-               return 0;
-}
-
-static unsigned char asctohex(char *str)
-{
-       unsigned char value;
-
-       value = hex(*str) & 0x0f;
-       value = value << 4;
-       str++;
-       value |= hex(*str) & 0x0f;
-
-       return value;
-}
-
 char *prgname;
 
 int set_ioctl(int sock, struct ifreq *req)
@@ -180,7 +158,7 @@ int main(int argc, char **argv)
        if (argc < 3) {
                fprintf(stderr, "%s: usage is \"%s <ifname> <operation>"
                                "[<address>] [<value>]\"\n", prgname, prgname);
-               fprintf(stderr, "valid operation : read, write, mem, reg, \n");
+               fprintf(stderr, "valid operation : read, write, mem, reg,\n");
                fprintf(stderr, "               : txd, rxd, rmem, wmem\n");
                fprintf(stderr, "               : dmat, regt, test\n");
 
index f53e483b394dfe45f59e805725c94f2bc42ba88a..9b9420c75d4217370b05a0d6080ce7dff244d0bb 100644 (file)
@@ -72,7 +72,6 @@ s32_t BEACON_RSSI(zdev_t *dev)
 
 void zfHpAniAttach(zdev_t *dev)
 {
-#define N(a)     (sizeof(a) / sizeof(a[0]))
     u32_t i;
     struct zsHpPriv *HpPriv;
 
@@ -125,7 +124,6 @@ void zfHpAniAttach(zdev_t *dev)
     HpPriv->stats.ast_nodestats.ns_avgbrssi = ZM_RSSI_DUMMY_MARKER;
     HpPriv->stats.ast_nodestats.ns_avgrssi = ZM_RSSI_DUMMY_MARKER;
     HpPriv->stats.ast_nodestats.ns_avgtxrssi = ZM_RSSI_DUMMY_MARKER;
-#undef N
 }
 
 /*
@@ -133,7 +131,6 @@ void zfHpAniAttach(zdev_t *dev)
  */
 u8_t zfHpAniControl(zdev_t *dev, ZM_HAL_ANI_CMD cmd, int param)
 {
-#define N(a) (sizeof(a)/sizeof(a[0]))
     typedef s32_t TABLE[];
     struct zsHpPriv *HpPriv;
     struct zsAniState *aniState;
@@ -148,9 +145,9 @@ u8_t zfHpAniControl(zdev_t *dev, ZM_HAL_ANI_CMD cmd, int param)
     {
         u32_t level = param;
 
-        if (level >= N(HpPriv->totalSizeDesired)) {
+        if (level >= ARRAY_SIZE(HpPriv->totalSizeDesired)) {
           zm_debug_msg1("level out of range, desired level : ", level);
-          zm_debug_msg1("max level : ", N(HpPriv->totalSizeDesired));
+          zm_debug_msg1("max level : ", ARRAY_SIZE(HpPriv->totalSizeDesired));
           return FALSE;
         }
 
@@ -260,10 +257,10 @@ u8_t zfHpAniControl(zdev_t *dev, ZM_HAL_ANI_CMD cmd, int param)
         const TABLE firstep = { 0, 4, 8 };
         u32_t level = param;
 
-        if (level >= N(firstep))
+        if (level >= ARRAY_SIZE(firstep))
         {
             zm_debug_msg1("level out of range, desired level : ", level);
-            zm_debug_msg1("max level : ", N(firstep));
+            zm_debug_msg1("max level : ", ARRAY_SIZE(firstep));
             return FALSE;
         }
         zfDelayWriteInternalReg(dev, AR_PHY_FIND_SIG,
@@ -283,10 +280,10 @@ u8_t zfHpAniControl(zdev_t *dev, ZM_HAL_ANI_CMD cmd, int param)
         const TABLE cycpwrThr1 = { 2, 4, 6, 8, 10, 12, 14, 16 };
         u32_t level = param;
 
-        if (level >= N(cycpwrThr1))
+        if (level >= ARRAY_SIZE(cycpwrThr1))
         {
             zm_debug_msg1("level out of range, desired level : ", level);
-            zm_debug_msg1("max level : ", N(cycpwrThr1));
+            zm_debug_msg1("max level : ", ARRAY_SIZE(cycpwrThr1));
             return FALSE;
         }
         zfDelayWriteInternalReg(dev, AR_PHY_TIMING5,
@@ -335,7 +332,6 @@ u8_t zfHpAniControl(zdev_t *dev, ZM_HAL_ANI_CMD cmd, int param)
         return FALSE;
     }
     return TRUE;
-#undef  N
 }
 
 void zfHpAniRestart(zdev_t* dev)
index 5f412e0204572de572679ec07cfe5ae20592aa82..6d2d358d5ca9299324f21f377d66c0c15f530284 100644 (file)
@@ -430,7 +430,7 @@ void zfInitPhy(zdev_t* dev,  u32_t frequency, u8_t bw40)
      * Register setting by mode
      */
 
-    entries = sizeof(ar5416Modes) / sizeof(*ar5416Modes);
+    entries = ARRAY_SIZE(ar5416Modes);
     zm_msg1_scan(ZM_LV_2, "Modes register setting entries=", entries);
     for (i=0; i<entries; i++)
     {
@@ -496,7 +496,7 @@ void zfInitPhy(zdev_t* dev,  u32_t frequency, u8_t bw40)
     /*
      * Common Register setting
      */
-    entries = sizeof(ar5416Common) / sizeof(*ar5416Common);
+    entries = ARRAY_SIZE(ar5416Common);
     for (i=0; i<entries; i++)
     {
         reg_write(ar5416Common[i][0], ar5416Common[i][1]);
@@ -506,7 +506,7 @@ void zfInitPhy(zdev_t* dev,  u32_t frequency, u8_t bw40)
     /*
      * RF Gain setting by freqIndex
      */
-    entries = sizeof(ar5416BB_RfGain) / sizeof(*ar5416BB_RfGain);
+    entries = ARRAY_SIZE(ar5416BB_RfGain);
     for (i=0; i<entries; i++)
     {
         reg_write(ar5416BB_RfGain[i][0], ar5416BB_RfGain[i][freqIndex]);
@@ -963,7 +963,6 @@ u32_t reverse_bits(u32_t chan_sel)
 /* Bank 0 1 2 3 5 6 7 */
 void zfSetRfRegs(zdev_t* dev, u32_t frequency)
 {
-    u16_t entries;
     u16_t freqIndex = 0;
     u16_t i;
 
@@ -984,33 +983,28 @@ void zfSetRfRegs(zdev_t* dev, u32_t frequency)
     }
 
 #if 1
-    entries = sizeof(otusBank) / sizeof(*otusBank);
-    for (i=0; i<entries; i++)
+    for (i=0; i<ARRAY_SIZE(otusBank); i++)
     {
         reg_write(otusBank[i][0], otusBank[i][freqIndex]);
     }
 #else
     /* Bank0 */
-    entries = sizeof(ar5416Bank0) / sizeof(*ar5416Bank0);
-    for (i=0; i<entries; i++)
+    for (i=0; i<ARRAY_SIZE(ar5416Bank0); i++)
     {
         reg_write(ar5416Bank0[i][0], ar5416Bank0[i][1]);
     }
     /* Bank1 */
-    entries = sizeof(ar5416Bank1) / sizeof(*ar5416Bank1);
-    for (i=0; i<entries; i++)
+    for (i=0; i<ARRAY_SIZE(ar5416Bank1); i++)
     {
         reg_write(ar5416Bank1[i][0], ar5416Bank1[i][1]);
     }
     /* Bank2 */
-    entries = sizeof(ar5416Bank2) / sizeof(*ar5416Bank2);
-    for (i=0; i<entries; i++)
+    for (i=0; i<ARRAY_SIZE(ar5416Bank2); i++)
     {
         reg_write(ar5416Bank2[i][0], ar5416Bank2[i][1]);
     }
     /* Bank3 */
-    entries = sizeof(ar5416Bank3) / sizeof(*ar5416Bank3);
-    for (i=0; i<entries; i++)
+    for (i=0; i<ARRAY_SIZE(ar5416Bank3); i++)
     {
         reg_write(ar5416Bank3[i][0], ar5416Bank3[i][freqIndex]);
     }
@@ -1018,14 +1012,12 @@ void zfSetRfRegs(zdev_t* dev, u32_t frequency)
     reg_write (0x98b0,  0x00000013);
     reg_write (0x98e4,  0x00000002);
     /* Bank6 */
-    entries = sizeof(ar5416Bank6) / sizeof(*ar5416Bank6);
-    for (i=0; i<entries; i++)
+    for (i=0; i<ARRAY_SIZE(ar5416Bank6); i++)
     {
         reg_write(ar5416Bank6[i][0], ar5416Bank6[i][freqIndex]);
     }
     /* Bank7 */
-    entries = sizeof(ar5416Bank7) / sizeof(*ar5416Bank7);
-    for (i=0; i<entries; i++)
+    for (i=0; i<ARRAY_SIZE(ar5416Bank7); i++)
     {
         reg_write(ar5416Bank7[i][0], ar5416Bank7[i][1]);
     }
index da3b774338749a1fd95ad6502f2f49f8d5848cd0..9b04653c1c53b091ca812771c184d7fd322803da 100644 (file)
@@ -29,9 +29,6 @@
 #include "hpreg.h"
 #include "hpusb.h"
 
-/* used throughout this file... */
-#define        N(a)    (sizeof(a) / sizeof(a[0]))
-
 #define HAL_MODE_11A_TURBO     HAL_MODE_108A
 #define HAL_MODE_11G_TURBO     HAL_MODE_108G
 
@@ -1557,7 +1554,7 @@ u8_t GetWmRD(u16_t regionCode, u16_t channelFlag, REG_DOMAIN *rd)
        u64_t flags = NO_REQ;
        REG_DMN_PAIR_MAPPING *regPair = NULL;
 
-       for (i = 0, found = 0; (i < N(regDomainPairs)) && (!found); i++) {
+       for (i = 0, found = 0; (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
                if (regDomainPairs[i].regDmnEnum == regionCode) {
                        regPair = &regDomainPairs[i];
                        found = 1;
@@ -1581,7 +1578,7 @@ u8_t GetWmRD(u16_t regionCode, u16_t channelFlag, REG_DOMAIN *rd)
         * unitary reg domain of the pair
         */
 
-       for (i = 0 ; i < N(regDomains) ; i++) {
+       for (i = 0 ; i < ARRAY_SIZE(regDomains) ; i++) {
                if (regDomains[i].regDmnEnum == regDmn) {
                        if (rd != NULL) {
                                        zfMemoryCopy((u8_t *)rd, (u8_t *)&regDomains[i],
@@ -1653,7 +1650,7 @@ void zfHpGetRegulationTable(zdev_t *dev, u16_t regionCode, u16_t c_lo, u16_t c_h
 
        zmw_enter_critical_section(dev);
 
-       for (cm = modes; cm < &modes[N(modes)]; cm++) {
+       for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
                u16_t c;
                u64_t *channelBM = NULL;
                REG_DOMAIN *rd = NULL;
@@ -1846,7 +1843,7 @@ void zfHpGetRegulationTablefromCountry(zdev_t *dev, u16_t CountryCode)
 
        zmw_declare_for_critical_section();
 
-       for (i = 0; i < N(allCountries); i++) {
+       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
                if (CountryCode == allCountries[i].countryCode) {
                        RegDomain = allCountries[i].regDmnEnum;
 
@@ -1881,7 +1878,7 @@ u8_t zfHpGetRegulationTablefromISO(zdev_t *dev, u8_t *countryInfo, u8_t length)
                strLen = 3; */
        }
        /* zm_debug_msg_s("Desired iso name = ", isoName); */
-       for (i = 0; i < N(allCountries); i++) {
+       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
                /* zm_debug_msg_s("Current iso name = ", allCountries[i].isoName); */
                if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, (u8_t *)&countryInfo[2], length-1)) {
                        /* DbgPrint("Set current iso name = %s\n", allCountries[i].isoName); */
@@ -1937,7 +1934,7 @@ const char *zfHpGetisoNamefromregionCode(zdev_t *dev, u16_t regionCode)
 {
        u16_t i;
 
-       for (i = 0; i < N(allCountries); i++) {
+       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
                if (allCountries[i].regDmnEnum == regionCode)
                        return allCountries[i].isoName;
        }
@@ -1953,7 +1950,7 @@ u16_t zfHpGetRegionCodeFromIsoName(zdev_t *dev, u8_t *countryIsoName)
        /* if no matching item, return default */
        regionCode = DEF_REGDMN;
 
-       for (i = 0; i < N(allCountries); i++) {
+       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
                if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, countryIsoName, 2)) {
                        regionCode = allCountries[i].regDmnEnum;
                break;
index a48c8e4a9ea769d91d054ae2f9206c7f1ade996c..dc3066d28845a476b8a1444e4e97407c7b93efae 100644 (file)
@@ -63,8 +63,7 @@
 
 extern u16_t zfLnxGetVapId(zdev_t *dev);
 
-static const u32_t channel_frequency_11A[] =
-{
+static const u32_t channel_frequency_11A[] = {
        /* Even element for Channel Number, Odd for Frequency */
        36, 5180,
        40, 5200,
@@ -507,7 +506,7 @@ int usbdrvwext_giwname(struct net_device *dev,
 {
        /* struct usbdrv_private *macp = dev->ml_priv; */
 
-       strcpy(wrq->name, "IEEE 802.11-MIMO");
+       strcpy(wrq->name, "IEEE 802.11abgn");
 
        return 0;
 }
@@ -1361,7 +1360,7 @@ int usbdrvwext_giwpower(struct net_device *dev,
 }
 
 /*int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
-*                       void *w, char *extra)
+*                              void *w, char *extra)
 *{
 *      struct ieee80211vap *vap = dev->ml_priv;
 *      struct ieee80211com *ic = vap->iv_ic;
@@ -2261,10 +2260,10 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
                printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);
 
                /* DUMP WPA IE */
-               for(ii = 0; ii < len;) {
+               for (ii = 0; ii < len;) {
                        printk(KERN_ERR "0x%02x ", wpaie[ii]);
 
-                       if((++ii % 16) == 0)
+                       if ((++ii % 16) == 0)
                                printk(KERN_ERR "\n");
                }
                printk(KERN_ERR "\n");
@@ -2309,11 +2308,10 @@ int usbdrv_cenc_ioctl(struct net_device *dev, struct zydas_cenc_param *zdparm)
        /* Get the AP Id */
        apId = zfLnxGetVapId(dev);
 
-       if (apId == 0xffff) {
+       if (apId == 0xffff)
                apId = 0;
-       } else {
+       else
                apId = apId + 1;
-       }
 
        switch (zdparm->cmd) {
        case ZM_CMD_CENC_SETCENC:
@@ -2334,15 +2332,15 @@ int usbdrv_cenc_ioctl(struct net_device *dev, struct zydas_cenc_param *zdparm)
 
                printk(KERN_ERR "Key Index : % d\n", zdparm->u.crypt.keyid);
                printk(KERN_ERR "Encryption key = ");
-               for (ii = 0; ii < 16; ii++) {
+               for (ii = 0; ii < 16; ii++)
                        printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
-               }
+
                printk(KERN_ERR "\n");
 
                printk(KERN_ERR "MIC key = ");
-               for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++) {
+               for (ii = 16; ii < ZM_CENC_KEY_SIZE; ii++)
                        printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
-               }
+
                printk(KERN_ERR "\n");
 
                /* Set up key information */
@@ -2424,7 +2422,7 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                break;
        case SIOCSIWRTS:
                err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
-               if (! err)
+               if (!err)
                        changed = 1;
                break;
        /* set_auth */
@@ -2582,8 +2580,7 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                                                        ZM_AUTH_MODE_WPA);
                                        } else if ((macp->supIe[17] == 0xf) &&
                                                (macp->supIe[18] == 0xac) &&
-                                               (macp->supIe[19] == 0x2))
-                                       {
+                                               (macp->supIe[19] == 0x2)) {
                                                printk(KERN_ERR
                                "wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
                                /* wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK; */
@@ -2592,8 +2589,7 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                                ZM_AUTH_MODE_WPA2PSK);
                        } else if ((macp->supIe[17] == 0xf) &&
                                (macp->supIe[18] == 0xac) &&
-                               (macp->supIe[19] == 0x1))
-                               {
+                               (macp->supIe[19] == 0x1)) {
                                        printk(KERN_ERR
                                "wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
                                /* wd->sta.authMode = ZM_AUTH_MODE_WPA2; */
@@ -2618,7 +2614,7 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                                zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
                                }
                        }
-                       //WPA2 or WPA2PSK
+                       /*WPA2 or WPA2PSK*/
                        if ((macp->supIe[17] == 0xf) ||
                                (macp->supIe[18] == 0xac)) {
                                if (macp->supIe[13] == 0x2) {
@@ -2656,7 +2652,7 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                        printk(KERN_ERR
                                "****************ZD_PARAM_COUNTERMEASURES : ");
 
-                       if(arg) {
+                       if (arg) {
                                /*    mCounterMeasureState=1; */
                                printk(KERN_ERR "enable\n");
                        } else {
@@ -2667,20 +2663,18 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (op == ZD_PARAM_DROPUNENCRYPTED) {
                        printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED : ");
 
-                       if(arg) {
+                       if (arg)
                                printk(KERN_ERR "enable\n");
-                       } else {
+                       else
                                printk(KERN_ERR "disable\n");
-                       }
                }
                if (op == ZD_PARAM_AUTH_ALGS) {
                        printk(KERN_ERR "ZD_PARAM_AUTH_ALGS : ");
 
-                       if (arg == 0) {
+                       if (arg == 0)
                                printk(KERN_ERR "OPEN_SYSTEM\n");
-                       } else {
+                       else
                                printk(KERN_ERR "SHARED_KEY\n");
-                       }
                }
                if (op == ZD_PARAM_WPS_FILTER) {
                        printk(KERN_ERR "ZD_PARAM_WPS_FILTER : ");
@@ -2705,11 +2699,10 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                /* Get the AP Id */
                apId = zfLnxGetVapId(dev);
 
-               if (apId == 0xffff) {
+               if (apId == 0xffff)
                        apId = 0;
-               } else {
+               else
                        apId = apId + 1;
-               }
 
                if (copy_from_user(&req_wpaie, ifr->ifr_data,
                                        sizeof(struct ieee80211req_wpaie))) {
@@ -2721,10 +2714,10 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                        for (j = 0; j < IEEE80211_ADDR_LEN; j++) {
                                if (macp->stawpaie[i].wpa_macaddr[j] !=
                                                req_wpaie.wpa_macaddr[j])
-                               break;
+                                       break;
                        }
                        if (j == 6)
-                       break;
+                               break;
                }
 
                if (i < ZM_OAL_MAX_STA_SUPPORT) {
index 0b238e9999bf0d097ff12a85fe17fc05437ebac5..1fba7a98d52bdec16b2756964bbb20fbfd7ecdce 100644 (file)
@@ -36,7 +36,7 @@ extern int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len);
 u16_t zfLnxCencAsocNotify(zdev_t *dev, u16_t *macAddr, u8_t *body,
                                u16_t bodySize, u16_t port)
 {
-       struct usbdrv_private *macp = (struct usbdrv_private *)dev->priv;
+       struct usbdrv_private *macp = dev->priv;
        struct zydas_cenc_sta_info cenc_info;
        /* struct sock *netlink_sk;     */
        u8_t ie_len;
index 93459cadc472f75dee6c3ff52f4409ba992e6d8e..9f04047bf5a6b18296b19bbc8f9019beb4661fe1 100644 (file)
@@ -104,6 +104,11 @@ u32_t zfwUsbSubmitControl(zdev_t *dev, u8_t req, u16_t value, u16_t index,
 
        if (size > 0) {
                buf = kmalloc(size, GFP_KERNEL);
+               if (buf == NULL) {
+                       pr_err("zfwUsbSubmitControl() failed, "
+                                 "kmalloc() returned NULL\n");
+                       return 1;
+               }
                memcpy(buf, (u8_t *)data, size);
        } else
                buf = NULL;
index b02eb42cd796e2c6becf158e968454d7534e7f10..fcd3da07155bf57484dd37f588f43eb94e28b5dc 100644 (file)
 #include <linux/slab.h>
 #include <net/iw_handler.h>
 
-extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo);
-extern void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo);
-extern void zfIdlChkRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen);
-extern void zfIdlRsp(zdev_tdev, u32_t *rsp, u16_t rspLen);
+extern void zfiRecv80211(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo);
+extern void zfCoreRecv(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo);
+extern void zfIdlChkRsp(zdev_t *dev, u32_t *rsp, u16_t rspLen);
+extern void zfIdlRsp(zdev_t *dev, u32_t *rsp, u16_t rspLen);
 
 
 
-//extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
+/*extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];*/
 extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
 
-u32_t zfLnxUsbSubmitTxData(zdev_tdev);
-u32_t zfLnxUsbIn(zdev_tdev, urb_t *urb, zbuf_t *buf);
+u32_t zfLnxUsbSubmitTxData(zdev_t *dev);
+u32_t zfLnxUsbIn(zdev_t *dev, urb_t *urb, zbuf_t *buf);
 u32_t zfLnxSubmitRegInUrb(zdev_t *dev);
 u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
-        void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context);
+       void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context);
 u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
-        void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context,
-        u32_t interval);
+       void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context,
+       u32_t interval);
 
 u16_t zfLnxGetFreeTxUrb(zdev_t *dev)
 {
@@ -56,22 +56,19 @@ u16_t zfLnxGetFreeTxUrb(zdev_t *dev)
 
     spin_lock_irqsave(&macp->cs_lock, irqFlag);
 
-    //idx = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1));
+    /*idx = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1));*/
 
-    //if (idx != macp->TxUrbHead)
-    if (macp->TxUrbCnt != 0)
-    {
-        idx = macp->TxUrbTail;
-        macp->TxUrbTail = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1));
-        macp->TxUrbCnt--;
-    }
-    else
-    {
-        //printk(KERN_ERR "macp->TxUrbCnt: %d\n", macp->TxUrbCnt);
-        idx = 0xffff;
-    }
+    /*if (idx != macp->TxUrbHead)*/
+    if (macp->TxUrbCnt != 0) {
+       idx = macp->TxUrbTail;
+       macp->TxUrbTail = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1));
+       macp->TxUrbCnt--;
+       } else {
+       /*printk(KERN_ERR "macp->TxUrbCnt: %d\n", macp->TxUrbCnt);*/
+       idx = 0xffff;
+       }
 
-    spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+       spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
     return idx;
 }
 
@@ -85,16 +82,13 @@ void zfLnxPutTxUrb(zdev_t *dev)
 
     idx = ((macp->TxUrbHead + 1) & (ZM_MAX_TX_URB_NUM - 1));
 
-    //if (idx != macp->TxUrbTail)
-    if (macp->TxUrbCnt < ZM_MAX_TX_URB_NUM)
-    {
-        macp->TxUrbHead = idx;
-        macp->TxUrbCnt++;
-    }
-    else
-    {
-        printk("UsbTxUrbQ inconsistent: TxUrbHead: %d, TxUrbTail: %d\n",
-                macp->TxUrbHead, macp->TxUrbTail);
+    /*if (idx != macp->TxUrbTail)*/
+    if (macp->TxUrbCnt < ZM_MAX_TX_URB_NUM) {
+       macp->TxUrbHead = idx;
+       macp->TxUrbCnt++;
+    } else {
+       printk("UsbTxUrbQ inconsistent: TxUrbHead: %d, TxUrbTail: %d\n",
+       macp->TxUrbHead, macp->TxUrbTail);
     }
 
     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
@@ -125,24 +119,20 @@ UsbTxQ_t *zfLnxGetUsbTxBuffer(zdev_t *dev)
 
     idx = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1));
 
-    //if (idx != macp->TxBufTail)
-    if (macp->TxBufCnt > 0)
-    {
-        //printk("CWY - zfwGetUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt);
-        TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufHead]);
-        macp->TxBufHead = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1));
-        macp->TxBufCnt--;
-    }
-    else
-    {
-        if (macp->TxBufHead != macp->TxBufTail)
-        {
-            printk(KERN_ERR "zfwGetUsbTxBuf UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d\n",
-                    macp->TxBufHead, macp->TxBufTail);
-        }
-
-        spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
-        return NULL;
+    /*if (idx != macp->TxBufTail)*/
+    if (macp->TxBufCnt > 0) {
+       /*printk("CWY - zfwGetUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt);*/
+       TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufHead]);
+       macp->TxBufHead = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1));
+       macp->TxBufCnt--;
+       } else {
+       if (macp->TxBufHead != macp->TxBufTail) {
+               printk(KERN_ERR "zfwGetUsbTxBuf UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d\n",
+               macp->TxBufHead, macp->TxBufTail);
+       }
+
+       spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+       return NULL;
     }
 
     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
@@ -150,8 +140,8 @@ UsbTxQ_t *zfLnxGetUsbTxBuffer(zdev_t *dev)
 }
 
 u16_t zfLnxPutUsbTxBuffer(zdev_t *dev, u8_t *hdr, u16_t hdrlen,
-        u8_t *snap, u16_t snapLen, u8_t *tail, u16_t tailLen,
-        zbuf_t *buf, u16_t offset)
+       u8_t *snap, u16_t snapLen, u8_t *tail, u16_t tailLen,
+       zbuf_t *buf, u16_t offset)
 {
     struct usbdrv_private *macp = dev->ml_priv;
     u16_t idx;
@@ -163,32 +153,29 @@ u16_t zfLnxPutUsbTxBuffer(zdev_t *dev, u8_t *hdr, u16_t hdrlen,
     idx = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1));
 
     /* For Tx debug */
-    //zm_assert(macp->TxBufCnt >= 0); // deleted because of always true
-
-    //if (idx != macp->TxBufHead)
-    if (macp->TxBufCnt < ZM_MAX_TX_BUF_NUM)
-    {
-        //printk("CWY - zfwPutUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt);
-        TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufTail]);
-        memcpy(TxQ->hdr, hdr, hdrlen);
-        TxQ->hdrlen = hdrlen;
-        memcpy(TxQ->snap, snap, snapLen);
-        TxQ->snapLen = snapLen;
-        memcpy(TxQ->tail, tail, tailLen);
-        TxQ->tailLen = tailLen;
-        TxQ->buf = buf;
-        TxQ->offset = offset;
-
-        macp->TxBufTail = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1));
-        macp->TxBufCnt++;
-    }
-    else
-    {
-        printk(KERN_ERR "zfLnxPutUsbTxBuffer UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d, TxBufCnt: %d\n",
-            macp->TxBufHead, macp->TxBufTail, macp->TxBufCnt);
-        spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
-        return 0xffff;
-    }
+    /*zm_assert(macp->TxBufCnt >= 0); // deleted because of always true*/
+
+    /*if (idx != macp->TxBufHead)*/
+    if (macp->TxBufCnt < ZM_MAX_TX_BUF_NUM) {
+       /*printk("CWY - zfwPutUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt);*/
+       TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufTail]);
+       memcpy(TxQ->hdr, hdr, hdrlen);
+       TxQ->hdrlen = hdrlen;
+       memcpy(TxQ->snap, snap, snapLen);
+       TxQ->snapLen = snapLen;
+       memcpy(TxQ->tail, tail, tailLen);
+       TxQ->tailLen = tailLen;
+       TxQ->buf = buf;
+       TxQ->offset = offset;
+
+       macp->TxBufTail = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1));
+       macp->TxBufCnt++;
+       } else {
+       printk(KERN_ERR "zfLnxPutUsbTxBuffer UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d, TxBufCnt: %d\n",
+               macp->TxBufHead, macp->TxBufTail, macp->TxBufCnt);
+       spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+       return 0xffff;
+       }
 
     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
     return 0;
@@ -197,28 +184,25 @@ u16_t zfLnxPutUsbTxBuffer(zdev_t *dev, u8_t *hdr, u16_t hdrlen,
 zbuf_t *zfLnxGetUsbRxBuffer(zdev_t *dev)
 {
     struct usbdrv_private *macp = dev->ml_priv;
-    //u16_t idx;
+    /*u16_t idx;*/
     zbuf_t *buf;
     unsigned long irqFlag;
 
     spin_lock_irqsave(&macp->cs_lock, irqFlag);
 
-    //idx = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1));
-
-    //if (idx != macp->RxBufTail)
-    if (macp->RxBufCnt != 0)
-    {
-        buf = macp->UsbRxBufQ[macp->RxBufHead];
-        macp->RxBufHead = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1));
-        macp->RxBufCnt--;
-    }
-    else
-    {
-        printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n",
-                macp->RxBufHead, macp->RxBufTail);
-        spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
-        return NULL;
-    }
+    /*idx = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1));*/
+
+    /*if (idx != macp->RxBufTail)*/
+    if (macp->RxBufCnt != 0) {
+       buf = macp->UsbRxBufQ[macp->RxBufHead];
+       macp->RxBufHead = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1));
+       macp->RxBufCnt--;
+    } else {
+       printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n",
+               macp->RxBufHead, macp->RxBufTail);
+       spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+       return NULL;
+       }
 
     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
     return buf;
@@ -234,61 +218,56 @@ u32_t zfLnxPutUsbRxBuffer(zdev_t *dev, zbuf_t *buf)
 
     idx = ((macp->RxBufTail+1) & (ZM_MAX_RX_URB_NUM - 1));
 
-    //if (idx != macp->RxBufHead)
-    if (macp->RxBufCnt != ZM_MAX_RX_URB_NUM)
-    {
-        macp->UsbRxBufQ[macp->RxBufTail] = buf;
-        macp->RxBufTail = idx;
-        macp->RxBufCnt++;
-    }
-    else
-    {
-        printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n",
-                macp->RxBufHead, macp->RxBufTail);
-        spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
-        return 0xffff;
-    }
+    /*if (idx != macp->RxBufHead)*/
+    if (macp->RxBufCnt != ZM_MAX_RX_URB_NUM) {
+       macp->UsbRxBufQ[macp->RxBufTail] = buf;
+       macp->RxBufTail = idx;
+       macp->RxBufCnt++;
+    } else {
+       printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n",
+               macp->RxBufHead, macp->RxBufTail);
+       spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+       return 0xffff;
+       }
 
-    spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
-    return 0;
+       spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+       return 0;
 }
 
 void zfLnxUsbDataOut_callback(urb_t *urb)
 {
-    zdev_tdev = urb->context;
-    //UsbTxQ_t *TxData;
+    zdev_t *dev = urb->context;
+    /*UsbTxQ_t *TxData;*/
 
     /* Give the urb back */
     zfLnxPutTxUrb(dev);
 
     /* Check whether there is any pending buffer needed */
     /* to be sent */
-    if (zfLnxCheckTxBufferCnt(dev) != 0)
-    {
-        //TxData = zfwGetUsbTxBuffer(dev);
-
-        //if (TxData == NULL)
-        //{
-        //    printk("Get a NULL buffer from zfwGetUsbTxBuffer\n");
-        //    return;
-        //}
-        //else
-        //{
-            zfLnxUsbSubmitTxData(dev);
-        //}
+    if (zfLnxCheckTxBufferCnt(dev) != 0) {
+       /*TxData = zfwGetUsbTxBuffer(dev);
+       //if (TxData == NULL)
+       //{
+       //    printk("Get a NULL buffer from zfwGetUsbTxBuffer\n");
+       //    return;
+       //}
+       //else
+       //{
+               zfLnxUsbSubmitTxData(dev);
+       //}*/
     }
 }
 
 void zfLnxUsbDataIn_callback(urb_t *urb)
 {
-    zdev_tdev = urb->context;
+    zdev_t *dev = urb->context;
     struct usbdrv_private *macp = dev->ml_priv;
     zbuf_t *buf;
     zbuf_t *new_buf;
     int status;
 
 #if ZM_USB_STREAM_MODE == 1
-    static int remain_len = 0, check_pad = 0, check_len = 0;
+    static int remain_len, check_pad, check_len;
     int index = 0;
     int chk_idx;
     u16_t pkt_len;
@@ -299,47 +278,45 @@ void zfLnxUsbDataIn_callback(urb_t *urb)
 #endif
 
     /* Check status for URB */
-    if (urb->status != 0){
-        printk("zfLnxUsbDataIn_callback() : status=0x%x\n", urb->status);
-        if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)
-            && (urb->status != -ESHUTDOWN))
-        {
-                if (urb->status == -EPIPE){
-                    //printk(KERN_ERR "nonzero read bulk status received: -EPIPE");
-                    status = -1;
-                }
-
-                if (urb->status == -EPROTO){
-                    //printk(KERN_ERR "nonzero read bulk status received: -EPROTO");
-                    status = -1;
-                }
-        }
-
-        //printk(KERN_ERR "urb->status: 0x%08x\n", urb->status);
-
-        /* Dequeue skb buffer */
-        buf = zfLnxGetUsbRxBuffer(dev);
-        dev_kfree_skb_any(buf);
-        #if 0
-        /* Enqueue skb buffer */
-        zfLnxPutUsbRxBuffer(dev, buf);
-
-        /* Submit a Rx urb */
-        zfLnxUsbIn(dev, urb, buf);
-        #endif
-        return;
-    }
+    if (urb->status != 0) {
+       printk("zfLnxUsbDataIn_callback() : status=0x%x\n", urb->status);
+       if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)
+               && (urb->status != -ESHUTDOWN)) {
+               if (urb->status == -EPIPE) {
+                       /*printk(KERN_ERR "nonzero read bulk status received: -EPIPE");*/
+                       status = -1;
+               }
+
+               if (urb->status == -EPROTO) {
+                       /*printk(KERN_ERR "nonzero read bulk status received: -EPROTO");*/
+                       status = -1;
+               }
+       }
+
+       /*printk(KERN_ERR "urb->status: 0x%08x\n", urb->status);*/
+
+       /* Dequeue skb buffer */
+       buf = zfLnxGetUsbRxBuffer(dev);
+       dev_kfree_skb_any(buf);
+       #if 0
+       /* Enqueue skb buffer */
+       zfLnxPutUsbRxBuffer(dev, buf);
 
-    if (urb->actual_length == 0)
-    {
-        printk(KERN_ERR "Get an URB whose length is zero");
-        status = -1;
+       /* Submit a Rx urb */
+       zfLnxUsbIn(dev, urb, buf);
+       #endif
+       return;
+       }
+
+    if (urb->actual_length == 0) {
+       printk(KERN_ERR "Get an URB whose length is zero");
+       status = -1;
     }
 
     /* Dequeue skb buffer */
     buf = zfLnxGetUsbRxBuffer(dev);
 
-    //zfwBufSetSize(dev, buf, urb->actual_length);
+    /*zfwBufSetSize(dev, buf, urb->actual_length);*/
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
     buf->tail = 0;
     buf->len = 0;
@@ -353,134 +330,122 @@ void zfLnxUsbDataIn_callback(urb_t *urb)
     skb_put(buf, urb->actual_length);
 
 #if ZM_USB_STREAM_MODE == 1
-    if (remain_len != 0)
-    {
-        zbuf_t *remain_buf = macp->reamin_buf;
+    if (remain_len != 0) {
+       zbuf_t *remain_buf = macp->reamin_buf;
 
-        index = remain_len;
-        remain_len -= check_pad;
+       index = remain_len;
+       remain_len -= check_pad;
 
-        /*  Copy data */
-        memcpy(&(remain_buf->data[check_len]), buf->data, remain_len);
-        check_len += remain_len;
-        remain_len = 0;
+       /*  Copy data */
+       memcpy(&(remain_buf->data[check_len]), buf->data, remain_len);
+       check_len += remain_len;
+       remain_len = 0;
 
-        rxBufPool[rxBufPoolIndex++] = remain_buf;
+       rxBufPool[rxBufPoolIndex++] = remain_buf;
     }
 
-    while(index < urb->actual_length)
-    {
-        pkt_len = buf->data[index] + (buf->data[index+1] << 8);
-        pkt_tag = buf->data[index+2] + (buf->data[index+3] << 8);
-
-        if (pkt_tag == 0x4e00)
-        {
-            int pad_len;
-
-            //printk("Get a packet, index: %d, pkt_len: 0x%04x\n", index, pkt_len);
-            #if 0
-            /* Dump data */
-            for (ii = index; ii < pkt_len+4;)
-            {
-                printk("%02x ", (buf->data[ii] & 0xff));
-
-                if ((++ii % 16) == 0)
-                    printk("\n");
-            }
-
-            printk("\n");
-            #endif
-
-            pad_len = 4 - (pkt_len & 0x3);
-
-            if(pad_len == 4)
-                pad_len = 0;
-
-            chk_idx = index;
-            index = index + 4 + pkt_len + pad_len;
-
-            if (index > ZM_MAX_RX_BUFFER_SIZE)
-            {
-                remain_len = index - ZM_MAX_RX_BUFFER_SIZE; // - pad_len;
-                check_len = ZM_MAX_RX_BUFFER_SIZE - chk_idx - 4;
-                check_pad = pad_len;
-
-                /* Allocate a skb buffer */
-                //new_buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE);
-                new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
-
-                /* Set skb buffer length */
-            #ifdef NET_SKBUFF_DATA_USES_OFFSET
-                new_buf->tail = 0;
-                new_buf->len = 0;
-            #else
-                new_buf->tail = new_buf->data;
-                new_buf->len = 0;
-            #endif
-
-                skb_put(new_buf, pkt_len);
-
-                /* Copy the buffer */
-                memcpy(new_buf->data, &(buf->data[chk_idx+4]), check_len);
-
-                /* Record the buffer pointer */
-                macp->reamin_buf = new_buf;
-            }
-            else
-            {
-        #ifdef ZM_DONT_COPY_RX_BUFFER
-                if (rxBufPoolIndex == 0)
-                {
-                    new_buf = skb_clone(buf, GFP_ATOMIC);
-
-                    new_buf->data = &(buf->data[chk_idx+4]);
-                    new_buf->len = pkt_len;
-                }
-                else
-                {
-        #endif
-                /* Allocate a skb buffer */
-                new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
-
-                /* Set skb buffer length */
-            #ifdef NET_SKBUFF_DATA_USES_OFFSET
-                new_buf->tail = 0;
-                new_buf->len = 0;
-            #else
-                new_buf->tail = new_buf->data;
-                new_buf->len = 0;
-            #endif
-
-                skb_put(new_buf, pkt_len);
-
-                /* Copy the buffer */
-                memcpy(new_buf->data, &(buf->data[chk_idx+4]), pkt_len);
-
-        #ifdef ZM_DONT_COPY_RX_BUFFER
-                }
-        #endif
-                rxBufPool[rxBufPoolIndex++] = new_buf;
-            }
-        }
-        else
-        {
-            printk(KERN_ERR "Can't find tag, pkt_len: 0x%04x, tag: 0x%04x\n", pkt_len, pkt_tag);
-
-            /* Free buffer */
-            dev_kfree_skb_any(buf);
-
-            /* Allocate a skb buffer */
-            new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
-
-            /* Enqueue skb buffer */
-            zfLnxPutUsbRxBuffer(dev, new_buf);
-
-            /* Submit a Rx urb */
-            zfLnxUsbIn(dev, urb, new_buf);
-
-            return;
-        }
-    }
+    while (index < urb->actual_length) {
+       pkt_len = buf->data[index] + (buf->data[index+1] << 8);
+       pkt_tag = buf->data[index+2] + (buf->data[index+3] << 8);
+
+       if (pkt_tag == 0x4e00) {
+               int pad_len;
+
+               /*printk("Get a packet, index: %d, pkt_len: 0x%04x\n", index, pkt_len);*/
+               #if 0
+               /* Dump data */
+               for (ii = index; ii < pkt_len+4;) {
+                       printk("%02x ", (buf->data[ii] & 0xff));
+
+                       if ((++ii % 16) == 0)
+                       printk("\n");
+                       }
+
+                       printk("\n");
+               #endif
+
+               pad_len = 4 - (pkt_len & 0x3);
+
+               if (pad_len == 4)
+               pad_len = 0;
+
+               chk_idx = index;
+               index = index + 4 + pkt_len + pad_len;
+
+               if (index > ZM_MAX_RX_BUFFER_SIZE) {
+                       remain_len = index - ZM_MAX_RX_BUFFER_SIZE; /* - pad_len;*/
+                       check_len = ZM_MAX_RX_BUFFER_SIZE - chk_idx - 4;
+                       check_pad = pad_len;
+
+                       /* Allocate a skb buffer */
+                       /*new_buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE);*/
+                       new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
+
+                       /* Set skb buffer length */
+                       #ifdef NET_SKBUFF_DATA_USES_OFFSET
+                       new_buf->tail = 0;
+                       new_buf->len = 0;
+                       #else
+                       new_buf->tail = new_buf->data;
+                       new_buf->len = 0;
+                       #endif
+
+                       skb_put(new_buf, pkt_len);
+
+                       /* Copy the buffer */
+                       memcpy(new_buf->data, &(buf->data[chk_idx+4]), check_len);
+
+                       /* Record the buffer pointer */
+                       macp->reamin_buf = new_buf;
+               } else  {
+                       #ifdef ZM_DONT_COPY_RX_BUFFER
+                       if (rxBufPoolIndex == 0) {
+                               new_buf = skb_clone(buf, GFP_ATOMIC);
+
+                               new_buf->data = &(buf->data[chk_idx+4]);
+                               new_buf->len = pkt_len;
+                       } else  {
+                               #endif
+                               /* Allocate a skb buffer */
+                               new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
+
+                               /* Set skb buffer length */
+                               #ifdef NET_SKBUFF_DATA_USES_OFFSET
+                               new_buf->tail = 0;
+                               new_buf->len = 0;
+                               #else
+                               new_buf->tail = new_buf->data;
+                               new_buf->len = 0;
+                               #endif
+
+                               skb_put(new_buf, pkt_len);
+
+                               /* Copy the buffer */
+                               memcpy(new_buf->data, &(buf->data[chk_idx+4]), pkt_len);
+
+                               #ifdef ZM_DONT_COPY_RX_BUFFER
+                               }
+                       #endif
+                       rxBufPool[rxBufPoolIndex++] = new_buf;
+                       }
+               } else {
+                       printk(KERN_ERR "Can't find tag, pkt_len: 0x%04x, tag: 0x%04x\n", pkt_len, pkt_tag);
+
+                       /* Free buffer */
+                       dev_kfree_skb_any(buf);
+
+                       /* Allocate a skb buffer */
+                       new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
+
+                       /* Enqueue skb buffer */
+                       zfLnxPutUsbRxBuffer(dev, new_buf);
+
+                       /* Submit a Rx urb */
+                       zfLnxUsbIn(dev, urb, new_buf);
+
+                       return;
+                       }
+               }
 
     /* Free buffer */
     dev_kfree_skb_any(buf);
@@ -496,9 +461,8 @@ void zfLnxUsbDataIn_callback(urb_t *urb)
     zfLnxUsbIn(dev, urb, new_buf);
 
 #if ZM_USB_STREAM_MODE == 1
-    for(ii = 0; ii < rxBufPoolIndex; ii++)
-    {
-        macp->usbCbFunctions.zfcbUsbRecv(dev, rxBufPool[ii]);
+    for (ii = 0; ii < rxBufPoolIndex; ii++) {
+       macp->usbCbFunctions.zfcbUsbRecv(dev, rxBufPool[ii]);
     }
 #else
     /* pass data to upper layer */
@@ -508,51 +472,48 @@ void zfLnxUsbDataIn_callback(urb_t *urb)
 
 void zfLnxUsbRegOut_callback(urb_t *urb)
 {
-    //dev_t* dev = urb->context;
+    /*dev_t* dev = urb->context;*/
 
-    //printk(KERN_ERR "zfwUsbRegOut_callback\n");
+       /*printk(KERN_ERR "zfwUsbRegOut_callback\n");*/
 }
 
 void zfLnxUsbRegIn_callback(urb_t *urb)
 {
-    zdev_tdev = urb->context;
+    zdev_t *dev = urb->context;
     u32_t rsp[64/4];
     int status;
     struct usbdrv_private *macp = dev->ml_priv;
 
     /* Check status for URB */
-    if (urb->status != 0){
-        printk("zfLnxUsbRegIn_callback() : status=0x%x\n", urb->status);
-        if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)
-            && (urb->status != -ESHUTDOWN))
-        {
-                if (urb->status == -EPIPE){
-                    //printk(KERN_ERR "nonzero read bulk status received: -EPIPE");
-                    status = -1;
-                }
-
-                if (urb->status == -EPROTO){
-                    //printk(KERN_ERR "nonzero read bulk status received: -EPROTO");
-                    status = -1;
-                }
-        }
-
-        //printk(KERN_ERR "urb->status: 0x%08x\n", urb->status);
-        return;
-    }
+    if (urb->status != 0) {
+       printk("zfLnxUsbRegIn_callback() : status=0x%x\n", urb->status);
+       if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET) && (urb->status != -ESHUTDOWN)) {
+               if (urb->status == -EPIPE) {
+                       /*printk(KERN_ERR "nonzero read bulk status received: -EPIPE");*/
+                       status = -1;
+               }
+
+               if (urb->status == -EPROTO) {
+                       /*printk(KERN_ERR "nonzero read bulk status received: -EPROTO");*/
+                       status = -1;
+               }
+       }
+
+       /*printk(KERN_ERR "urb->status: 0x%08x\n", urb->status);*/
+       return;
+       }
 
-    if (urb->actual_length == 0)
-    {
-        printk(KERN_ERR "Get an URB whose length is zero");
-        status = -1;
+    if (urb->actual_length == 0) {
+       printk(KERN_ERR "Get an URB whose length is zero");
+       status = -1;
     }
 
     /* Copy data into respone buffer */
     memcpy(rsp, macp->regUsbReadBuf, urb->actual_length);
 
     /* Notify to upper layer */
-    //zfIdlChkRsp(dev, rsp, (u16_t)urb->actual_length);
-    //zfiUsbRegIn(dev, rsp, (u16_t)urb->actual_length);
+    /*zfIdlChkRsp(dev, rsp, (u16_t)urb->actual_length);*/
+    /*zfiUsbRegIn(dev, rsp, (u16_t)urb->actual_length);*/
     macp->usbCbFunctions.zfcbUsbRegIn(dev, rsp, (u16_t)urb->actual_length);
 
     /* Issue another USB IN URB */
@@ -564,22 +525,22 @@ u32_t zfLnxSubmitRegInUrb(zdev_t *dev)
     u32_t ret;
     struct usbdrv_private *macp = dev->ml_priv;
 
-    /* Submit a rx urb */
+    /* Submit a rx urb
     //ret = zfLnxUsbSubmitBulkUrb(macp->RegInUrb, macp->udev,
     //        USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf,
     //        ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev);
     //CWYang(-)
     //if (ret != 0)
-    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);
+    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
 
     ret = zfLnxUsbSubmitIntUrb(macp->RegInUrb, macp->udev,
-            USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf,
-            ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev, 1);
+       USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf,
+       ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev, 1);
 
     return ret;
 }
 
-u32_t zfLnxUsbSubmitTxData(zdev_tdev)
+u32_t zfLnxUsbSubmitTxData(zdev_t *dev)
 {
     u32_t i;
     u32_t ret;
@@ -600,39 +561,33 @@ u32_t zfLnxUsbSubmitTxData(zdev_t* dev)
     freeTxUrb = zfLnxGetFreeTxUrb(dev);
 
     /* If there is no any free Tx Urb */
-    if (freeTxUrb == 0xffff)
-    {
-        //printk(KERN_ERR "Can't get free Tx Urb\n");
-        //printk("CWY - Can't get free Tx Urb\n");
-        return 0xffff;
+    if (freeTxUrb == 0xffff) {
+       /*printk(KERN_ERR "Can't get free Tx Urb\n");
+       //printk("CWY - Can't get free Tx Urb\n");*/
+       return 0xffff;
     }
 
 #if ZM_USB_TX_STREAM_MODE == 1
     usbTxAggCnt = zfLnxCheckTxBufferCnt(dev);
 
-    if (usbTxAggCnt >= ZM_MAX_TX_AGGREGATE_NUM)
-    {
-       usbTxAggCnt = ZM_MAX_TX_AGGREGATE_NUM;
-    }
-    else
-    {
-       usbTxAggCnt = 1;
+    if (usbTxAggCnt >= ZM_MAX_TX_AGGREGATE_NUM) {
+       usbTxAggCnt = ZM_MAX_TX_AGGREGATE_NUM;
+    } else {
+       usbTxAggCnt = 1;
     }
 
-    //printk("usbTxAggCnt: %d\n", usbTxAggCnt);
+    /*printk("usbTxAggCnt: %d\n", usbTxAggCnt);*/
 #endif
 
 #if ZM_USB_TX_STREAM_MODE == 1
-    for(ii = 0; ii < usbTxAggCnt; ii++)
-    {
+    for (ii = 0; ii < usbTxAggCnt; ii++) {
 #endif
     /* Dequeue the packet from UsbTxBufQ */
     TxData = zfLnxGetUsbTxBuffer(dev);
-    if (TxData == NULL)
-    {
-        /* Give the urb back */
-        zfLnxPutTxUrb(dev);
-        return 0xffff;
+    if (TxData == NULL) {
+       /* Give the urb back */
+       zfLnxPutTxUrb(dev);
+       return 0xffff;
     }
 
     /* Point to the freeTxUrb buffer */
@@ -644,114 +599,103 @@ u32_t zfLnxUsbSubmitTxData(zdev_t* dev)
 
     /* Add the packet length and tag information */
     *pUsbTxHdr++ = TxData->hdrlen + TxData->snapLen +
-             (TxData->buf->len - TxData->offset) +  TxData->tailLen;
+       (TxData->buf->len - TxData->offset) +  TxData->tailLen;
 
     *pUsbTxHdr++ = 0x697e;
 
     puTxBuf += 4;
-#endif // #ifdef ZM_USB_TX_STREAM_MODE
+#endif /* #ifdef ZM_USB_TX_STREAM_MODE*/
 
     /* Copy WLAN header and packet buffer into USB buffer */
-    for(i = 0; i < TxData->hdrlen; i++)
-    {
-        *puTxBuf++ = TxData->hdr[i];
+    for (i = 0; i < TxData->hdrlen; i++) {
+       *puTxBuf++ = TxData->hdr[i];
     }
 
     /* Copy SNAP header */
-    for(i = 0; i < TxData->snapLen; i++)
-    {
-        *puTxBuf++ = TxData->snap[i];
+    for (i = 0; i < TxData->snapLen; i++) {
+       *puTxBuf++ = TxData->snap[i];
     }
 
     /* Copy packet buffer */
-    for(i = 0; i < TxData->buf->len - TxData->offset; i++)
-    {
-       //*puTxBuf++ = zmw_rx_buf_readb(dev, TxData->buf, i);
-       *puTxBuf++ = *(u8_t*)((u8_t*)TxData->buf->data+i+TxData->offset);
+    for (i = 0; i < TxData->buf->len - TxData->offset; i++) {
+       /*puTxBuf++ = zmw_rx_buf_readb(dev, TxData->buf, i);*/
+       *puTxBuf++ = *(u8_t *)((u8_t *)TxData->buf->data+i+TxData->offset);
     }
 
     /* Copy tail */
-    for(i = 0; i < TxData->tailLen; i++)
-    {
-        *puTxBuf++ = TxData->tail[i];
+    for (i = 0; i < TxData->tailLen; i++) {
+       *puTxBuf++ = TxData->tail[i];
     }
 
     len = TxData->hdrlen+TxData->snapLen+TxData->buf->len+TxData->tailLen-TxData->offset;
 
     #if 0
-    if (TxData->hdrlen != 0)
-    {
-        puTxBuf = macp->txUsbBuf[freeTxUrb];
-        for (i = 0; i < len; i++)
-        {
-            printk("%02x ", puTxBuf[i]);
-            if (i % 16 == 15)
-                printk("\n");
-        }
-        printk("\n");
-    }
+    if (TxData->hdrlen != 0) {
+       puTxBuf = macp->txUsbBuf[freeTxUrb];
+       for (i = 0; i < len; i++) {
+               printk("%02x ", puTxBuf[i]);
+               if (i % 16 == 15)
+               printk("\n");
+               }
+               printk("\n");
+       }
     #endif
     #if 0
     /* For debug purpose */
-    if(TxData->hdr[9] & 0x40)
-    {
-        int i;
-        u16_t ctrlLen = TxData->hdr[0] + (TxData->hdr[1] << 8);
-
-        if (ctrlLen != len + 4)
-        {
-        /* Dump control setting */
-        for(i = 0; i < 8; i++)
-        {
-            printk(KERN_ERR "0x%02x ", TxData->hdr[i]);
-        }
-        printk(KERN_ERR "\n");
-
-        printk(KERN_ERR "ctrLen: %d, hdrLen: %d, snapLen: %d\n", ctrlLen, TxData->hdrlen, TxData->snapLen);
-        printk(KERN_ERR "bufLen: %d, tailLen: %d, len: %d\n", TxData->buf->len, TxData->tailLen, len);
-        }
+    if (TxData->hdr[9] & 0x40) {
+       int i;
+       u16_t ctrlLen = TxData->hdr[0] + (TxData->hdr[1] << 8);
+
+       if (ctrlLen != len + 4) {
+       /* Dump control setting */
+       for (i = 0; i < 8; i++) {
+               printk(KERN_ERR "0x%02x ", TxData->hdr[i]);
+       }
+       printk(KERN_ERR "\n");
+
+       printk(KERN_ERR "ctrLen: %d, hdrLen: %d, snapLen: %d\n", ctrlLen, TxData->hdrlen, TxData->snapLen);
+       printk(KERN_ERR "bufLen: %d, tailLen: %d, len: %d\n", TxData->buf->len, TxData->tailLen, len);
+       }
     }
     #endif
 
 #if ZM_USB_TX_STREAM_MODE == 1
-    // Add the Length and Tag
+    /* Add the Length and Tag*/
     len += 4;
 
-    //printk("%d packet, length: %d\n", ii+1, len);
+    /*printk("%d packet, length: %d\n", ii+1, len);*/
 
-    if (ii < (ZM_MAX_TX_AGGREGATE_NUM-1))
-    {
-        /* Pad the buffer to firmware descriptor boundary */
-        offset += (((len-1) / 4) + 1) * 4;
+    if (ii < (ZM_MAX_TX_AGGREGATE_NUM-1)) {
+       /* Pad the buffer to firmware descriptor boundary */
+       offset += (((len-1) / 4) + 1) * 4;
     }
 
-    if (ii == (ZM_MAX_TX_AGGREGATE_NUM-1))
-    {
-        len += offset;
+    if (ii == (ZM_MAX_TX_AGGREGATE_NUM-1)) {
+       len += offset;
     }
 
     TxQPool[ii] = TxData;
 
-    //DbgPrint("%d packet, offset: %d\n", ii+1, pUsbTxTransfer->offset);
+    /*DbgPrint("%d packet, offset: %d\n", ii+1, pUsbTxTransfer->offset);*/
 
     /* free packet */
-    //zfBufFree(dev, txData->buf);
+    /*zfBufFree(dev, txData->buf);*/
     }
 #endif
-    //printk("CWY - call zfwUsbSubmitBulkUrb(), len = 0x%d\n", len);
+    /*printk("CWY - call zfwUsbSubmitBulkUrb(), len = 0x%d\n", len);*/
     /* Submit a tx urb */
     ret = zfLnxUsbSubmitBulkUrb(macp->WlanTxDataUrb[freeTxUrb], macp->udev,
-            USB_WLAN_TX_PIPE, USB_DIR_OUT, macp->txUsbBuf[freeTxUrb],
-            len, zfLnxUsbDataOut_callback, dev);
-    //CWYang(-)
+       USB_WLAN_TX_PIPE, USB_DIR_OUT, macp->txUsbBuf[freeTxUrb],
+       len, zfLnxUsbDataOut_callback, dev);
+    /*CWYang(-)
     //if (ret != 0)
-    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);
+    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
 
     /* free packet */
-    //dev_kfree_skb_any(TxData->buf);
+    /*dev_kfree_skb_any(TxData->buf);*/
 #if ZM_USB_TX_STREAM_MODE == 1
-    for(ii = 0; ii < usbTxAggCnt; ii++)
-        macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxQPool[ii]->buf, 1, TxQPool[ii]->hdr);
+    for (ii = 0; ii < usbTxAggCnt; ii++)
+       macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxQPool[ii]->buf, 1, TxQPool[ii]->hdr);
 #else
     macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxData->buf, 1, TxData->hdr);
 #endif
@@ -761,23 +705,23 @@ u32_t zfLnxUsbSubmitTxData(zdev_t* dev)
 
 
 
-u32_t zfLnxUsbIn(zdev_tdev, urb_t *urb, zbuf_t *buf)
+u32_t zfLnxUsbIn(zdev_t *dev, urb_t *urb, zbuf_t *buf)
 {
     u32_t ret;
     struct usbdrv_private *macp = dev->ml_priv;
 
     /* Submit a rx urb */
     ret = zfLnxUsbSubmitBulkUrb(urb, macp->udev, USB_WLAN_RX_PIPE,
-            USB_DIR_IN, buf->data, ZM_MAX_RX_BUFFER_SIZE,
-            zfLnxUsbDataIn_callback, dev);
-    //CWYang(-)
+       USB_DIR_IN, buf->data, ZM_MAX_RX_BUFFER_SIZE,
+       zfLnxUsbDataIn_callback, dev);
+    /*CWYang(-)
     //if (ret != 0)
-    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);
+    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
 
     return ret;
 }
 
-u32_t zfLnxUsbWriteReg(zdev_t* dev, u32_t* cmd, u16_t cmdLen)
+u32_t zfLnxUsbWriteReg(zdev_t *dev, u32_t *cmd, u16_t cmdLen)
 {
     struct usbdrv_private *macp = dev->ml_priv;
     u32_t ret;
@@ -785,7 +729,7 @@ u32_t zfLnxUsbWriteReg(zdev_t* dev, u32_t* cmd, u16_t cmdLen)
 #ifdef ZM_CONFIG_BIG_ENDIAN
     int ii = 0;
 
-    for(ii=0; ii<(cmdLen>>2); ii++)
+    for (ii = 0; ii < (cmdLen>>2); ii++)
        cmd[ii] = cpu_to_le32(cmd[ii]);
 #endif
 
@@ -794,39 +738,38 @@ u32_t zfLnxUsbWriteReg(zdev_t* dev, u32_t* cmd, u16_t cmdLen)
     /* Issue an USB Out transfer */
     /* Submit a tx urb */
     ret = zfLnxUsbSubmitIntUrb(macp->RegOutUrb, macp->udev,
-            USB_REG_OUT_PIPE, USB_DIR_OUT, macp->regUsbWriteBuf,
-            cmdLen, zfLnxUsbRegOut_callback, dev, 1);
+       USB_REG_OUT_PIPE, USB_DIR_OUT, macp->regUsbWriteBuf,
+       cmdLen, zfLnxUsbRegOut_callback, dev, 1);
 
     return ret;
 }
 
 
-u32_t zfLnxUsbOut(zdev_tdev, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen,
-        u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset)
+u32_t zfLnxUsbOut(zdev_t *dev, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen,
+       u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset)
 {
     u32_t ret;
     struct usbdrv_private *macp = dev->ml_priv;
 
     /* Check length of tail buffer */
-    //zm_assert((tailLen <= 16));
+    /*zm_assert((tailLen <= 16));*/
 
     /* Enqueue the packet into UsbTxBufQ */
-    if (zfLnxPutUsbTxBuffer(dev, hdr, hdrlen, snap, snapLen, tail, tailLen, buf, offset) == 0xffff)
-    {
-        /* free packet */
-        //printk("CWY - zfwPutUsbTxBuffer Error, free packet\n");
-        //dev_kfree_skb_any(buf);
-        macp->usbCbFunctions.zfcbUsbOutComplete(dev, buf, 0, hdr);
-        return 0xffff;
-    }
+    if (zfLnxPutUsbTxBuffer(dev, hdr, hdrlen, snap, snapLen, tail, tailLen, buf, offset) == 0xffff) {
+       /* free packet */
+       /*printk("CWY - zfwPutUsbTxBuffer Error, free packet\n");
+       //dev_kfree_skb_any(buf);*/
+       macp->usbCbFunctions.zfcbUsbOutComplete(dev, buf, 0, hdr);
+       return 0xffff;
+       }
 
-    //return 0;
-    //printk("CWY - call zfwUsbSubmitTxData()\n");
+    /*return 0;
+    //printk("CWY - call zfwUsbSubmitTxData()\n");*/
     ret = zfLnxUsbSubmitTxData(dev);
     return ret;
 }
 
-void zfLnxInitUsbTxQ(zdev_tdev)
+void zfLnxInitUsbTxQ(zdev_t *dev)
 {
     struct usbdrv_private *macp = dev->ml_priv;
 
@@ -842,7 +785,7 @@ void zfLnxInitUsbTxQ(zdev_t* dev)
     macp->TxUrbCnt = ZM_MAX_TX_URB_NUM;
 }
 
-void zfLnxInitUsbRxQ(zdev_tdev)
+void zfLnxInitUsbRxQ(zdev_t *dev)
 {
     u16_t i;
     zbuf_t *buf;
@@ -853,76 +796,65 @@ void zfLnxInitUsbRxQ(zdev_t* dev)
 
     macp->RxBufHead = 0;
 
-    for (i = 0; i < ZM_MAX_RX_URB_NUM; i++)
-    {
-        //buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE);
-        buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
-        macp->UsbRxBufQ[i] = buf;
-    }
+    for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) {
+       /*buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE);*/
+       buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
+       macp->UsbRxBufQ[i] = buf;
+       }
 
-    //macp->RxBufTail = ZM_MAX_RX_URB_NUM - 1;
+    /*macp->RxBufTail = ZM_MAX_RX_URB_NUM - 1;*/
     macp->RxBufTail = 0;
 
     /* Submit all Rx urbs */
-    for (i = 0; i < ZM_MAX_RX_URB_NUM; i++)
-    {
-        zfLnxPutUsbRxBuffer(dev, macp->UsbRxBufQ[i]);
-        zfLnxUsbIn(dev, macp->WlanRxDataUrb[i], macp->UsbRxBufQ[i]);
-    }
+    for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) {
+       zfLnxPutUsbRxBuffer(dev, macp->UsbRxBufQ[i]);
+       zfLnxUsbIn(dev, macp->WlanRxDataUrb[i], macp->UsbRxBufQ[i]);
+       }
 }
 
 
 
 u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
-        void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context)
+       void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context)
 {
     u32_t ret;
 
-    if(direction == USB_DIR_OUT)
-    {
-        usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, epnum),
-                transfer_buffer, buffer_length, complete, context);
+    if (direction == USB_DIR_OUT) {
+       usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, epnum),
+               transfer_buffer, buffer_length, complete, context);
 
-        urb->transfer_flags |= URB_ZERO_PACKET;
-    }
-    else
-    {
-        usb_fill_bulk_urb(urb, usb, usb_rcvbulkpipe(usb, epnum),
-                transfer_buffer, buffer_length, complete, context);
+       urb->transfer_flags |= URB_ZERO_PACKET;
+    } else {
+       usb_fill_bulk_urb(urb, usb, usb_rcvbulkpipe(usb, epnum),
+               transfer_buffer, buffer_length, complete, context);
     }
 
-    if (epnum == 4)
-    {
-        if (urb->hcpriv)
-        {
-            //printk("CWY - urb->hcpriv set by unknown reason, reset it\n");
-            //urb->hcpriv = 0;
-        }
-    }
+    if (epnum == 4) {
+       if (urb->hcpriv) {
+               /*printk("CWY - urb->hcpriv set by unknown reason, reset it\n");
+               //urb->hcpriv = 0;*/
+               }
+       }
 
     ret = usb_submit_urb(urb, GFP_ATOMIC);
-    if ((epnum == 4) & (ret != 0))
-    {
-        //printk("CWY - ret = %x\n", ret);
+    if ((epnum == 4) & (ret != 0)) {
+       /*printk("CWY - ret = %x\n", ret);*/
     }
     return ret;
 }
 
 u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
-        void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context,
-        u32_t interval)
+       void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context,
+       u32_t interval)
 {
     u32_t ret;
 
-    if(direction == USB_DIR_OUT)
-    {
-        usb_fill_int_urb(urb, usb, usb_sndbulkpipe(usb, epnum),
-                transfer_buffer, buffer_length, complete, context, interval);
-    }
-    else
-    {
-        usb_fill_int_urb(urb, usb, usb_rcvbulkpipe(usb, epnum),
-                transfer_buffer, buffer_length, complete, context, interval);
+    if (direction == USB_DIR_OUT) {
+       usb_fill_int_urb(urb, usb, usb_sndbulkpipe(usb, epnum),
+               transfer_buffer, buffer_length, complete, context, interval);
+    } else {
+       usb_fill_int_urb(urb, usb, usb_rcvbulkpipe(usb, epnum),
+       transfer_buffer, buffer_length, complete, context, interval);
     }
 
     ret = usb_submit_urb(urb, GFP_ATOMIC);
@@ -946,51 +878,48 @@ int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len)
        size = NLMSG_SPACE(len);
        skb = alloc_skb(size, GFP_ATOMIC);
 
-       if(skb == NULL)
-       {
+       if (skb == NULL) {
                printk("dev_alloc_skb failure \n");
                goto out;
        }
        old_tail = skb->tail;
 
-       /*ÌîдÊý¾Ý±¨Ïà¹ØÐÅÏ¢*/
+       /* */
        nlh = NLMSG_PUT(skb, 0, 0, WAI_K_MSG, size-sizeof(*nlh));
        pos = NLMSG_DATA(nlh);
 
-       /*´«Êäµ½Óû§¿Õ¼äµÄÊý¾Ý*/
+       /* */
        memcpy(pos, msg,  len);
-       /*¼ÆËã¾­¹ý×Ö½Ú¶ÔÆäºóµÄÊý¾Ýʵ¼Ê³¤¶È*/
+       /* */
        nlh->nlmsg_len = skb->tail - old_tail;
        NETLINK_CB(skb).dst_group = COMMTYPE_GROUP;
        netlink_broadcast(netlink_sk, skb, 0, COMMTYPE_GROUP, GFP_ATOMIC);
        ret = 0;
 out:
        return ret;
-nlmsg_failure: /*NLMSG_PUT Ê§°Ü£¬Ôò³·ÏúÌ×½Ó×Ö»º´æ*/
+nlmsg_failure: /* */
        kfree_skb(skb);
        goto out;
 
 #undef COMMTYPE_GROUP
 #undef WAI_K_MSG
 }
-#endif //ZM_ENABLE_CENC
+#endif /*ZM_ENABLE_CENC*/
 
 /* Simply return 0xffff if VAP function is not supported */
-u16_t zfLnxGetVapId(zdev_tdev)
+u16_t zfLnxGetVapId(zdev_t *dev)
 {
     u16_t i;
 
-    for (i=0; i<ZM_VAP_PORT_NUMBER; i++)
-    {
-        if (vap[i].dev == dev)
-        {
-            return i;
-        }
-    }
-    return 0xffff;
+    for (i = 0; i < ZM_VAP_PORT_NUMBER; i++) {
+       if (vap[i].dev == dev) {
+               return i;
+               }
+       }
+       return 0xffff;
 }
 
-u32_t zfwReadReg(zdev_tdev, u32_t offset)
+u32_t zfwReadReg(zdev_t *dev, u32_t offset)
 {
     return 0;
 }
@@ -1012,25 +941,23 @@ u32_t smp_kevent_Lock = 0;
 void kevent(struct work_struct *work)
 {
     struct usbdrv_private *macp =
-               container_of(work, struct usbdrv_private, kevent);
-    zdev_t *dev = macp->device;
+       container_of(work, struct usbdrv_private, kevent);
+       zdev_t *dev = macp->device;
 
-    if (test_and_set_bit(0, (void *)&smp_kevent_Lock))
-    {
-        //schedule_work(&macp->kevent);
-        return;
+    if (test_and_set_bit(0, (void *)&smp_kevent_Lock)) {
+       /*schedule_work(&macp->kevent);*/
+       return;
     }
 
     down(&macp->ioctl_sem);
 
-    if (test_and_clear_bit(KEVENT_WATCHDOG, &macp->kevent_flags))
-    {
+    if (test_and_clear_bit(KEVENT_WATCHDOG, &macp->kevent_flags)) {
     extern u16_t zfHpStartRecv(zdev_t *dev);
-        //zfiHwWatchDogReinit(dev);
-        printk(("\n ************ Hw watchDog occur!! ************** \n"));
-        zfiWlanSuspend(dev);
-        zfiWlanResume(dev,0);
-        zfHpStartRecv(dev);
+       /*zfiHwWatchDogReinit(dev);*/
+       printk(("\n ************ Hw watchDog occur!! ************** \n"));
+       zfiWlanSuspend(dev);
+       zfiWlanResume(dev , 0);
+       zfHpStartRecv(dev);
     }
 
     clear_bit(0, (void *)&smp_kevent_Lock);
@@ -1083,41 +1010,38 @@ void zfLnxSignalThread(zdev_t *dev, int flag)
 {
     struct usbdrv_private *macp = dev->ml_priv;
 
-    if (macp == NULL)
-    {
-        printk("macp is NULL\n");
-        return;
+    if (macp == NULL) {
+       printk("macp is NULL\n");
+       return;
     }
 
-    if (0 && macp->kevent_ready != 1)
-    {
-        printk("Kevent not ready\n");
-        return;
+    if (0 && macp->kevent_ready != 1) {
+       printk("Kevent not ready\n");
+       return;
     }
 
     set_bit(flag, &macp->kevent_flags);
 
-    if (!schedule_work(&macp->kevent))
-    {
-        //Fails is Normal
-        //printk(KERN_ERR "schedule_task failed, flag = %x\n", flag);
-    }
+    if (!schedule_work(&macp->kevent)) {
+       /*Fails is Normal
+       //printk(KERN_ERR "schedule_task failed, flag = %x\n", flag);*/
+       }
 }
 
 /* Notify wrapper todo redownload firmware and reinit procedure when */
 /* hardware watchdog occur : zfiHwWatchDogReinit() */
-void zfLnxWatchDogNotify(zdev_tdev)
+void zfLnxWatchDogNotify(zdev_t *dev)
 {
     zfLnxSignalThread(dev, KEVENT_WATCHDOG);
 }
 
 /* Query Durantion of Active Scan */
-void zfwGetActiveScanDur(zdev_t* dev, u8_t* Dur)
+void zfwGetActiveScanDur(zdev_t *dev, u8_t *Dur)
 {
-    *Dur = 30; // default 30 ms
+    *Dur = 30; /* default 30 ms*/
 }
 
-void zfwGetShowZeroLengthSSID(zdev_t* dev, u8_t* Dur)
+void zfwGetShowZeroLengthSSID(zdev_t *dev, u8_t *Dur)
 {
     *Dur = 0;
 }
index 2c799a2502949f0f6423c1dd28a1c19790f92fda..4014b747245402f443a0bb35a16d1a734089bd30 100644 (file)
@@ -48,7 +48,7 @@ static const char driver_name[] = "Otus";
 /* table of devices that work with this driver */
 static const struct usb_device_id zd1221_ids[] = {
        { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) },
-        { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) },
+       { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) },
        { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) },
        { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WN111v2) },
        { }                                     /* Terminating entry */
@@ -60,9 +60,9 @@ extern u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp);
 extern int usbdrv_close(struct net_device *dev);
 extern u8_t zfLnxClearStructs(struct net_device *dev);
 extern int zfWdsClose(struct net_device *dev);
-extern int zfUnregisterWdsDev(struct net_deviceparentDev, u16_t wdsId);
+extern int zfUnregisterWdsDev(struct net_device *parentDev, u16_t wdsId);
 extern int zfLnxVapClose(struct net_device *dev);
-extern int zfLnxUnregisterVapDev(struct net_deviceparentDev, u16_t vapId);
+extern int zfLnxUnregisterVapDev(struct net_device *parentDev, u16_t vapId);
 
 /* WDS */
 extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
@@ -73,148 +73,135 @@ extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
 static int zfLnxProbe(struct usb_interface *interface,
        const struct usb_device_id *id)
 {
-    struct usb_device *dev = interface_to_usbdev(interface);
-
-    struct net_device *net = NULL;
-    struct usbdrv_private *macp = NULL;
-    int vendor_id, product_id;
-    int result = 0;
-
-    usb_get_dev(dev);
-
-    vendor_id = dev->descriptor.idVendor;
-    product_id = dev->descriptor.idProduct;
-
-#ifdef HMAC_DEBUG
-    printk(KERN_NOTICE "vendor_id = %04x\n", vendor_id);
-    printk(KERN_NOTICE "product_id = %04x\n", product_id);
-
-    if (dev->speed == USB_SPEED_HIGH)
-        printk(KERN_NOTICE "USB 2.0 Host\n");
-    else
-        printk(KERN_NOTICE "USB 1.1 Host\n");
-#endif
-
-    macp = kzalloc(sizeof(struct usbdrv_private), GFP_KERNEL);
-    if (!macp)
-    {
-        printk(KERN_ERR "out of memory allocating device structure\n");
-        result = -ENOMEM;
-        goto fail;
-    }
-
-    net = alloc_etherdev(0);
-
-    if (net == NULL)
-    {
-        printk(KERN_ERR "zfLnxProbe: Not able to alloc etherdev struct\n");
-        result = -ENOMEM;
-        goto fail1;
-    }
-
-    strcpy(net->name, "ath%d");
-
-    net->ml_priv = macp;   //kernel 2.6
-    macp->udev = dev;
-    macp->device = net;
-
-    /* set up the endpoint information */
-    /* check out the endpoints */
-    macp->interface = interface;
-
-    //init_waitqueue_head(&macp->regSet_wait);
-    //init_waitqueue_head(&macp->iorwRsp_wait);
-    //init_waitqueue_head(&macp->term_wait);
-
-    if (!zfLnxAllocAllUrbs(macp))
-    {
-        result = -ENOMEM;
-        goto fail2;
-    }
-
-    if (!zfLnxInitSetup(net, macp))
-    {
-        result = -EIO;
-        goto fail3;
-    }
-    else
-    {
-        usb_set_intfdata(interface, macp);
-        SET_NETDEV_DEV(net, &interface->dev);
-
-        if (register_netdev(net) != 0)
-        {
-            usb_set_intfdata(interface, NULL);
-            goto fail3;
-        }
-    }
-
-    netif_carrier_off(net);
-    goto done;
-
+       struct usb_device *dev = interface_to_usbdev(interface);
+
+       struct net_device *net = NULL;
+       struct usbdrv_private *macp = NULL;
+       int vendor_id, product_id;
+       int result = 0;
+
+       usb_get_dev(dev);
+
+       vendor_id = dev->descriptor.idVendor;
+       product_id = dev->descriptor.idProduct;
+
+       #ifdef HMAC_DEBUG
+               printk(KERN_NOTICE "vendor_id = %04x\n", vendor_id);
+               printk(KERN_NOTICE "product_id = %04x\n", product_id);
+
+       if (dev->speed == USB_SPEED_HIGH)
+               printk(KERN_NOTICE "USB 2.0 Host\n");
+       else
+               printk(KERN_NOTICE "USB 1.1 Host\n");
+       #endif
+
+       macp = kzalloc(sizeof(struct usbdrv_private), GFP_KERNEL);
+       if (!macp) {
+               printk(KERN_ERR "out of memory allocating device structure\n");
+               result = -ENOMEM;
+               goto fail;
+       }
+
+       net = alloc_etherdev(0);
+
+       if (net == NULL) {
+               printk(KERN_ERR "zfLnxProbe: Not able to alloc etherdev struct\n");
+               result = -ENOMEM;
+               goto fail1;
+       }
+
+       strcpy(net->name, "ath%d");
+
+       net->ml_priv = macp;   /* kernel 2.6 */
+       macp->udev = dev;
+       macp->device = net;
+
+       /* set up the endpoint information */
+       /* check out the endpoints */
+       macp->interface = interface;
+
+       /* init_waitqueue_head(&macp->regSet_wait); */
+       /* init_waitqueue_head(&macp->iorwRsp_wait); */
+       /* init_waitqueue_head(&macp->term_wait); */
+
+       if (!zfLnxAllocAllUrbs(macp)) {
+               result = -ENOMEM;
+               goto fail2;
+       }
+
+       if (!zfLnxInitSetup(net, macp)) {
+               result = -EIO;
+               goto fail3;
+       } else {
+               usb_set_intfdata(interface, macp);
+               SET_NETDEV_DEV(net, &interface->dev);
+
+               if (register_netdev(net) != 0) {
+                       usb_set_intfdata(interface, NULL);
+                       goto fail3;
+               }
+       }
+
+       netif_carrier_off(net);
+           goto done;
 fail3:
-    zfLnxFreeAllUrbs(macp);
+       zfLnxFreeAllUrbs(macp);
 fail2:
-    free_netdev(net);  //kernel 2.6
+       free_netdev(net);  /* kernel 2.6 */
 fail1:
-    kfree(macp);
-
+       kfree(macp);
 fail:
-    usb_put_dev(dev);
-    macp = NULL;
-
+       usb_put_dev(dev);
+       macp = NULL;
 done:
-    return result;
+       return result;
 }
 
 static void zfLnxDisconnect(struct usb_interface *interface)
 {
-    struct usbdrv_private *macp = (struct usbdrv_private *) usb_get_intfdata(interface);
-
-    printk(KERN_DEBUG "zfLnxDisconnect\n");
-
-    if (!macp)
-    {
-        printk(KERN_ERR "unregistering non-existant device\n");
-        return;
-    }
-
-    if (macp->driver_isolated)
-    {
-        if (macp->device->flags & IFF_UP)
-            usbdrv_close(macp->device);
-    }
-
-#if 0
-    /* Close WDS */
-    //zfWdsClose(wds[0].dev);
-    /* Unregister WDS */
-    //zfUnregisterWdsDev(macp->device, 0);
-
-    /* Close VAP */
-    zfLnxVapClose(vap[0].dev);
-    /* Unregister VAP */
-    zfLnxUnregisterVapDev(macp->device, 0);
-#endif
+       struct usbdrv_private *macp = (struct usbdrv_private *) usb_get_intfdata(interface);
+
+       printk(KERN_DEBUG "zfLnxDisconnect\n");
+
+       if (!macp) {
+               printk(KERN_ERR "unregistering non-existant device\n");
+               return;
+       }
+
+       if (macp->driver_isolated)
+               if (macp->device->flags & IFF_UP)
+                       usbdrv_close(macp->device);
+
+       #if 0
+               /* Close WDS */
+               /* zfWdsClose(wds[0].dev); */
+               /* Unregister WDS */
+               /* zfUnregisterWdsDev(macp->device, 0); */
+
+               /* Close VAP */
+               zfLnxVapClose(vap[0].dev);
+               /* Unregister VAP */
+               zfLnxUnregisterVapDev(macp->device, 0);
+       #endif
 
-    zfLnxClearStructs(macp->device);
+       zfLnxClearStructs(macp->device);
 
-    unregister_netdev(macp->device);
+       unregister_netdev(macp->device);
 
-    usb_put_dev(interface_to_usbdev(interface));
+       usb_put_dev(interface_to_usbdev(interface));
 
-    //printk(KERN_ERR "3. zfLnxUnlinkAllUrbs\n");
-    //zfLnxUnlinkAllUrbs(macp);
+       /* printk(KERN_ERR "3. zfLnxUnlinkAllUrbs\n"); */
+       /* zfLnxUnlinkAllUrbs(macp); */
 
-    /* Free network interface */
-    free_netdev(macp->device);
+       /* Free network interface */
+       free_netdev(macp->device);
 
-    zfLnxFreeAllUrbs(macp);
-    //zfLnxClearStructs(macp->device);
-    kfree(macp);
-    macp = NULL;
+       zfLnxFreeAllUrbs(macp);
+       /* zfLnxClearStructs(macp->device); */
+       kfree(macp);
+       macp = NULL;
 
-    usb_set_intfdata(interface, NULL);
+       usb_set_intfdata(interface, NULL);
 }
 
 static struct usb_driver zd1221_driver = {
@@ -226,13 +213,13 @@ static struct usb_driver zd1221_driver = {
 
 int __init zfLnxIinit(void)
 {
-    printk(KERN_NOTICE "%s - version %s\n",  DRIVER_NAME, VERSIONID);
-    return usb_register(&zd1221_driver);
+       printk(KERN_NOTICE "%s - version %s\n",  DRIVER_NAME, VERSIONID);
+       return usb_register(&zd1221_driver);
 }
 
 void __exit zfLnxExit(void)
 {
-    usb_deregister(&zd1221_driver);
+       usb_deregister(&zd1221_driver);
 }
 
 module_init(zfLnxIinit);
index 9ca0e9e2a96174c1f25672c0b9614315af3b0312..3221814a856ea3b8dab8befa616ab03f50da0fbf 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/parport.h>
 #include <linux/version.h>
 #define LCD_MAXBYTES           256     /* max burst write */
 
 #define KEYPAD_BUFFER          64
-#define INPUT_POLL_TIME                (HZ/50) /* poll the keyboard this every second */
-#define KEYPAD_REP_START       (10)    /* a key starts to repeat after this times INPUT_POLL_TIME */
-#define KEYPAD_REP_DELAY       (2)     /* a key repeats this times INPUT_POLL_TIME */
 
-#define FLASH_LIGHT_TEMPO      (200)   /* keep the light on this times INPUT_POLL_TIME for each flash */
+/* poll the keyboard this every second */
+#define INPUT_POLL_TIME                (HZ/50)
+/* a key starts to repeat after this times INPUT_POLL_TIME */
+#define KEYPAD_REP_START       (10)
+/* a key repeats this times INPUT_POLL_TIME */
+#define KEYPAD_REP_DELAY       (2)
+
+/* keep the light on this times INPUT_POLL_TIME for each flash */
+#define FLASH_LIGHT_TEMPO      (200)
 
 /* converts an r_str() input to an active high, bits string : 000BAOSE */
 #define PNL_PINPUT(a)          ((((unsigned char)(a)) ^ 0x7F) >> 3)
@@ -84,7 +90,8 @@
 #define PNL_PERRORP            0x08    /* direct input, active low */
 
 #define PNL_PBIDIR             0x20    /* bi-directional ports */
-#define PNL_PINTEN             0x10    /* high to read data in or-ed with data out */
+/* high to read data in or-ed with data out */
+#define PNL_PINTEN             0x10
 #define PNL_PSELECP            0x08    /* inverted output, active low */
 #define PNL_PINITP             0x04    /* direct output, active low */
 #define PNL_PAUTOLF            0x02    /* inverted output, active low */
 #define LCD_FLAG_N             0x0040  /* 2-rows mode */
 #define LCD_FLAG_L             0x0080  /* backlight enabled */
 
-#define LCD_ESCAPE_LEN         24      /* 24 chars max for an LCD escape command */
+#define LCD_ESCAPE_LEN         24      /* max chars for LCD escape command */
 #define LCD_ESCAPE_CHAR        27      /* use char 27 for escape command */
 
 /* macros to simplify use of the parallel port */
 #define w_dtr(x, y)     do { parport_write_data((x)->port, (y)); } while (0)
 
 /* this defines which bits are to be used and which ones to be ignored */
-static __u8 scan_mask_o;       /* logical or of the output bits involved in the scan matrix */
-static __u8 scan_mask_i;       /* logical or of the input bits involved in the scan matrix */
+/* logical or of the output bits involved in the scan matrix */
+static __u8 scan_mask_o;
+/* logical or of the input bits involved in the scan matrix */
+static __u8 scan_mask_i;
 
 typedef __u64 pmask_t;
 
@@ -161,14 +170,14 @@ struct logical_input {
        __u8 rise_timer, fall_timer, high_timer;
 
        union {
-               struct {        /* this structure is valid when type == INPUT_TYPE_STD */
+               struct {        /* valid when type == INPUT_TYPE_STD */
                        void (*press_fct) (int);
                        void (*release_fct) (int);
                        int press_data;
                        int release_data;
                } std;
-               struct {        /* this structure is valid when type == INPUT_TYPE_KBD */
-                       /* strings can be full-length (ie. non null-terminated) */
+               struct {        /* valid when type == INPUT_TYPE_KBD */
+                       /* strings can be non null-terminated */
                        char press_str[sizeof(void *) + sizeof(int)];
                        char repeat_str[sizeof(void *) + sizeof(int)];
                        char release_str[sizeof(void *) + sizeof(int)];
@@ -188,11 +197,17 @@ LIST_HEAD(logical_inputs);        /* list of all defined logical inputs */
  * 0000000000000000000BAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSE
  * <-----unused------><gnd><d07><d06><d05><d04><d03><d02><d01><d00>
  */
-static pmask_t phys_read;      /* what has just been read from the I/O ports */
-static pmask_t phys_read_prev; /* previous phys_read */
-static pmask_t phys_curr;      /* stabilized phys_read (phys_read|phys_read_prev) */
-static pmask_t phys_prev;      /* previous phys_curr */
-static char inputs_stable;     /* 0 means that at least one logical signal needs be computed */
+
+/* what has just been read from the I/O ports */
+static pmask_t phys_read;
+/* previous phys_read */
+static pmask_t phys_read_prev;
+/* stabilized phys_read (phys_read|phys_read_prev) */
+static pmask_t phys_curr;
+/* previous phys_curr */
+static pmask_t phys_prev;
+/* 0 means that at least one logical signal needs be computed */
+static char inputs_stable;
 
 /* these variables are specific to the keypad */
 static char keypad_buffer[KEYPAD_BUFFER];
@@ -202,11 +217,17 @@ static char keypressed;
 static wait_queue_head_t keypad_read_wait;
 
 /* lcd-specific variables */
-static unsigned long int lcd_flags;    /* contains the LCD config state */
-static unsigned long int lcd_addr_x;   /* contains the LCD X offset */
-static unsigned long int lcd_addr_y;   /* contains the LCD Y offset */
-static char lcd_escape[LCD_ESCAPE_LEN + 1];    /* current escape sequence, 0 terminated */
-static int lcd_escape_len = -1;        /* not in escape state. >=0 = escape cmd len */
+
+/* contains the LCD config state */
+static unsigned long int lcd_flags;
+/* contains the LCD X offset */
+static unsigned long int lcd_addr_x;
+/* contains the LCD Y offset */
+static unsigned long int lcd_addr_y;
+/* current escape sequence, 0 terminated */
+static char lcd_escape[LCD_ESCAPE_LEN + 1];
+/* not in escape state. >=0 = escape cmd len */
+static int lcd_escape_len = -1;
 
 /*
  * Bit masks to convert LCD signals to parallel port outputs.
@@ -436,11 +457,13 @@ MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead");
 static int lcd_type = -1;
 module_param(lcd_type, int, 0000);
 MODULE_PARM_DESC(lcd_type,
-                "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in");
+                "LCD type: 0=none, 1=old //, 2=serial ks0074, "
+                "3=hantronix //, 4=nexcom //, 5=compiled-in");
 
 static int lcd_proto = -1;
 module_param(lcd_proto, int, 0000);
-MODULE_PARM_DESC(lcd_proto, "LCD communication: 0=parallel (//), 1=serial,"
+MODULE_PARM_DESC(lcd_proto,
+               "LCD communication: 0=parallel (//), 1=serial,"
                "2=TI LCD Interface");
 
 static int lcd_charset = -1;
@@ -450,12 +473,14 @@ MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074");
 static int keypad_type = -1;
 module_param(keypad_type, int, 0000);
 MODULE_PARM_DESC(keypad_type,
-                "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys");
+                "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, "
+                "3=nexcom 4 keys");
 
 static int profile = DEFAULT_PROFILE;
 module_param(profile, int, 0000);
 MODULE_PARM_DESC(profile,
-                "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; 4=16x2 nexcom; default=40x2, old kp");
+                "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; "
+                "4=16x2 nexcom; default=40x2, old kp");
 
 /*
  * These are the parallel port pins the LCD control signals are connected to.
@@ -469,32 +494,38 @@ MODULE_PARM_DESC(profile,
 static int lcd_e_pin  = PIN_NOT_SET;
 module_param(lcd_e_pin, int, 0000);
 MODULE_PARM_DESC(lcd_e_pin,
-                "# of the // port pin connected to LCD 'E' signal, with polarity (-17..17)");
+                "# of the // port pin connected to LCD 'E' signal, "
+                "with polarity (-17..17)");
 
 static int lcd_rs_pin = PIN_NOT_SET;
 module_param(lcd_rs_pin, int, 0000);
 MODULE_PARM_DESC(lcd_rs_pin,
-                "# of the // port pin connected to LCD 'RS' signal, with polarity (-17..17)");
+                "# of the // port pin connected to LCD 'RS' signal, "
+                "with polarity (-17..17)");
 
 static int lcd_rw_pin = PIN_NOT_SET;
 module_param(lcd_rw_pin, int, 0000);
 MODULE_PARM_DESC(lcd_rw_pin,
-                "# of the // port pin connected to LCD 'RW' signal, with polarity (-17..17)");
+                "# of the // port pin connected to LCD 'RW' signal, "
+                "with polarity (-17..17)");
 
 static int lcd_bl_pin = PIN_NOT_SET;
 module_param(lcd_bl_pin, int, 0000);
 MODULE_PARM_DESC(lcd_bl_pin,
-                "# of the // port pin connected to LCD backlight, with polarity (-17..17)");
+                "# of the // port pin connected to LCD backlight, "
+                "with polarity (-17..17)");
 
 static int lcd_da_pin = PIN_NOT_SET;
 module_param(lcd_da_pin, int, 0000);
 MODULE_PARM_DESC(lcd_da_pin,
-                "# of the // port pin connected to serial LCD 'SDA' signal, with polarity (-17..17)");
+                "# of the // port pin connected to serial LCD 'SDA' "
+                "signal, with polarity (-17..17)");
 
 static int lcd_cl_pin = PIN_NOT_SET;
 module_param(lcd_cl_pin, int, 0000);
 MODULE_PARM_DESC(lcd_cl_pin,
-                "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)");
+                "# of the // port pin connected to serial LCD 'SCL' "
+                "signal, with polarity (-17..17)");
 
 static unsigned char *lcd_char_conv;
 
@@ -572,12 +603,12 @@ static char (*keypad_profile)[4][9] = old_keypad_profile;
 
 /* FIXME: this should be converted to a bit array containing signals states */
 static struct {
-       unsigned char e;        /* parallel LCD E   (data latch on falling edge) */
-       unsigned char rs;       /* parallel LCD RS  (0 = cmd, 1 = data) */
-       unsigned char rw;       /* parallel LCD R/W (0 = W, 1 = R) */
-       unsigned char bl;       /* parallel LCD backlight (0 = off, 1 = on) */
-       unsigned char cl;       /* serial LCD clock (latch on rising edge) */
-       unsigned char da;       /* serial LCD data */
+       unsigned char e;  /* parallel LCD E (data latch on falling edge) */
+       unsigned char rs; /* parallel LCD RS  (0 = cmd, 1 = data) */
+       unsigned char rw; /* parallel LCD R/W (0 = W, 1 = R) */
+       unsigned char bl; /* parallel LCD backlight (0 = off, 1 = on) */
+       unsigned char cl; /* serial LCD clock (latch on rising edge) */
+       unsigned char da; /* serial LCD data */
 } bits;
 
 static void init_scan_timer(void);
@@ -666,7 +697,7 @@ void pin_to_bits(int pin, unsigned char *d_val, unsigned char *c_val)
                c_bit = PNL_PAUTOLF;
                inv = !inv;
                break;
-       case PIN_INITP: /* init, direct */
+       case PIN_INITP:         /* init, direct */
                c_bit = PNL_PINITP;
                break;
        case PIN_SELECP:        /* select_in, inverted */
@@ -698,23 +729,23 @@ static void long_sleep(int ms)
        }
 }
 
-/* send a serial byte to the LCD panel. The caller is responsible for locking if needed. */
+/* send a serial byte to the LCD panel. The caller is responsible for locking
+   if needed. */
 static void lcd_send_serial(int byte)
 {
        int bit;
 
        /* the data bit is set on D0, and the clock on STROBE.
-        * LCD reads D0 on STROBE's rising edge.
-        */
+        * LCD reads D0 on STROBE's rising edge. */
        for (bit = 0; bit < 8; bit++) {
                bits.cl = BIT_CLR;      /* CLK low */
                panel_set_bits();
                bits.da = byte & 1;
                panel_set_bits();
-               udelay(2);      /* maintain the data during 2 us before CLK up */
+               udelay(2);  /* maintain the data during 2 us before CLK up */
                bits.cl = BIT_SET;      /* CLK high */
                panel_set_bits();
-               udelay(1);      /* maintain the strobe during 1 us */
+               udelay(1);  /* maintain the strobe during 1 us */
                byte >>= 1;
        }
 }
@@ -760,19 +791,19 @@ static void lcd_write_cmd_p8(int cmd)
        spin_lock(&pprt_lock);
        /* present the data to the data port */
        w_dtr(pprt, cmd);
-       udelay(20);             /* maintain the data during 20 us before the strobe */
+       udelay(20);     /* maintain the data during 20 us before the strobe */
 
        bits.e = BIT_SET;
        bits.rs = BIT_CLR;
        bits.rw = BIT_CLR;
        set_ctrl_bits();
 
-       udelay(40);             /* maintain the strobe during 40 us */
+       udelay(40);     /* maintain the strobe during 40 us */
 
        bits.e = BIT_CLR;
        set_ctrl_bits();
 
-       udelay(120);            /* the shortest command takes at least 120 us */
+       udelay(120);    /* the shortest command takes at least 120 us */
        spin_unlock(&pprt_lock);
 }
 
@@ -782,19 +813,19 @@ static void lcd_write_data_p8(int data)
        spin_lock(&pprt_lock);
        /* present the data to the data port */
        w_dtr(pprt, data);
-       udelay(20);             /* maintain the data during 20 us before the strobe */
+       udelay(20);     /* maintain the data during 20 us before the strobe */
 
        bits.e = BIT_SET;
        bits.rs = BIT_SET;
        bits.rw = BIT_CLR;
        set_ctrl_bits();
 
-       udelay(40);             /* maintain the strobe during 40 us */
+       udelay(40);     /* maintain the strobe during 40 us */
 
        bits.e = BIT_CLR;
        set_ctrl_bits();
 
-       udelay(45);             /* the shortest data takes at least 45 us */
+       udelay(45);     /* the shortest data takes at least 45 us */
        spin_unlock(&pprt_lock);
 }
 
@@ -822,7 +853,8 @@ static void lcd_gotoxy(void)
 {
        lcd_write_cmd(0x80      /* set DDRAM address */
                      | (lcd_addr_y ? lcd_hwidth : 0)
-                     /* we force the cursor to stay at the end of the line if it wants to go farther */
+                     /* we force the cursor to stay at the end of the
+                        line if it wants to go farther */
                      | ((lcd_addr_x < lcd_bwidth) ? lcd_addr_x &
                         (lcd_hwidth - 1) : lcd_bwidth - 1));
 }
@@ -871,19 +903,23 @@ static void lcd_clear_fast_p8(void)
        for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
                /* present the data to the data port */
                w_dtr(pprt, ' ');
-               udelay(20);     /* maintain the data during 20 us before the strobe */
+
+               /* maintain the data during 20 us before the strobe */
+               udelay(20);
 
                bits.e = BIT_SET;
                bits.rs = BIT_SET;
                bits.rw = BIT_CLR;
                set_ctrl_bits();
 
-               udelay(40);     /* maintain the strobe during 40 us */
+               /* maintain the strobe during 40 us */
+               udelay(40);
 
                bits.e = BIT_CLR;
                set_ctrl_bits();
 
-               udelay(45);     /* the shortest data takes at least 45 us */
+               /* the shortest data takes at least 45 us */
+               udelay(45);
        }
        spin_unlock(&pprt_lock);
 
@@ -954,7 +990,8 @@ static void lcd_init_display(void)
 
        long_sleep(10);
 
-       lcd_write_cmd(0x06);    /* entry mode set : increment, cursor shifting */
+       /* entry mode set : increment, cursor shifting */
+       lcd_write_cmd(0x06);
 
        lcd_clear_display();
 }
@@ -966,317 +1003,336 @@ static void lcd_init_display(void)
  *
  */
 
+static inline int handle_lcd_special_code(void)
+{
+       /* LCD special codes */
+
+       int processed = 0;
+
+       char *esc = lcd_escape + 2;
+       int oldflags = lcd_flags;
+
+       /* check for display mode flags */
+       switch (*esc) {
+       case 'D':       /* Display ON */
+               lcd_flags |= LCD_FLAG_D;
+               processed = 1;
+               break;
+       case 'd':       /* Display OFF */
+               lcd_flags &= ~LCD_FLAG_D;
+               processed = 1;
+               break;
+       case 'C':       /* Cursor ON */
+               lcd_flags |= LCD_FLAG_C;
+               processed = 1;
+               break;
+       case 'c':       /* Cursor OFF */
+               lcd_flags &= ~LCD_FLAG_C;
+               processed = 1;
+               break;
+       case 'B':       /* Blink ON */
+               lcd_flags |= LCD_FLAG_B;
+               processed = 1;
+               break;
+       case 'b':       /* Blink OFF */
+               lcd_flags &= ~LCD_FLAG_B;
+               processed = 1;
+               break;
+       case '+':       /* Back light ON */
+               lcd_flags |= LCD_FLAG_L;
+               processed = 1;
+               break;
+       case '-':       /* Back light OFF */
+               lcd_flags &= ~LCD_FLAG_L;
+               processed = 1;
+               break;
+       case '*':
+               /* flash back light using the keypad timer */
+               if (scan_timer.function != NULL) {
+                       if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
+                               lcd_backlight(1);
+                       light_tempo = FLASH_LIGHT_TEMPO;
+               }
+               processed = 1;
+               break;
+       case 'f':       /* Small Font */
+               lcd_flags &= ~LCD_FLAG_F;
+               processed = 1;
+               break;
+       case 'F':       /* Large Font */
+               lcd_flags |= LCD_FLAG_F;
+               processed = 1;
+               break;
+       case 'n':       /* One Line */
+               lcd_flags &= ~LCD_FLAG_N;
+               processed = 1;
+               break;
+       case 'N':       /* Two Lines */
+               lcd_flags |= LCD_FLAG_N;
+               break;
+       case 'l':       /* Shift Cursor Left */
+               if (lcd_addr_x > 0) {
+                       /* back one char if not at end of line */
+                       if (lcd_addr_x < lcd_bwidth)
+                               lcd_write_cmd(0x10);
+                       lcd_addr_x--;
+               }
+               processed = 1;
+               break;
+       case 'r':       /* shift cursor right */
+               if (lcd_addr_x < lcd_width) {
+                       /* allow the cursor to pass the end of the line */
+                       if (lcd_addr_x <
+                           (lcd_bwidth - 1))
+                               lcd_write_cmd(0x14);
+                       lcd_addr_x++;
+               }
+               processed = 1;
+               break;
+       case 'L':       /* shift display left */
+               lcd_left_shift++;
+               lcd_write_cmd(0x18);
+               processed = 1;
+               break;
+       case 'R':       /* shift display right */
+               lcd_left_shift--;
+               lcd_write_cmd(0x1C);
+               processed = 1;
+               break;
+       case 'k': {     /* kill end of line */
+               int x;
+               for (x = lcd_addr_x; x < lcd_bwidth; x++)
+                       lcd_write_data(' ');
+
+               /* restore cursor position */
+               lcd_gotoxy();
+               processed = 1;
+               break;
+       }
+       case 'I':       /* reinitialize display */
+               lcd_init_display();
+               lcd_left_shift = 0;
+               processed = 1;
+               break;
+       case 'G': {
+               /* Generator : LGcxxxxx...xx; must have <c> between '0'
+                * and '7', representing the numerical ASCII code of the
+                * redefined character, and <xx...xx> a sequence of 16
+                * hex digits representing 8 bytes for each character.
+                * Most LCDs will only use 5 lower bits of the 7 first
+                * bytes.
+                */
+
+               unsigned char cgbytes[8];
+               unsigned char cgaddr;
+               int cgoffset;
+               int shift;
+               char value;
+               int addr;
+
+               if (strchr(esc, ';') == NULL)
+                       break;
+
+               esc++;
+
+               cgaddr = *(esc++) - '0';
+               if (cgaddr > 7) {
+                       processed = 1;
+                       break;
+               }
+
+               cgoffset = 0;
+               shift = 0;
+               value = 0;
+               while (*esc && cgoffset < 8) {
+                       shift ^= 4;
+                       if (*esc >= '0' && *esc <= '9')
+                               value |= (*esc - '0') << shift;
+                       else if (*esc >= 'A' && *esc <= 'Z')
+                               value |= (*esc - 'A' + 10) << shift;
+                       else if (*esc >= 'a' && *esc <= 'z')
+                               value |= (*esc - 'a' + 10) << shift;
+                       else {
+                               esc++;
+                               continue;
+                       }
+
+                       if (shift == 0) {
+                               cgbytes[cgoffset++] = value;
+                               value = 0;
+                       }
+
+                       esc++;
+               }
+
+               lcd_write_cmd(0x40 | (cgaddr * 8));
+               for (addr = 0; addr < cgoffset; addr++)
+                       lcd_write_data(cgbytes[addr]);
+
+               /* ensures that we stop writing to CGRAM */
+               lcd_gotoxy();
+               processed = 1;
+               break;
+       }
+       case 'x':       /* gotoxy : LxXXX[yYYY]; */
+       case 'y':       /* gotoxy : LyYYY[xXXX]; */
+               if (strchr(esc, ';') == NULL)
+                       break;
+
+               while (*esc) {
+                       char *endp;
+
+                       if (*esc == 'x') {
+                               esc++;
+                               lcd_addr_x = simple_strtoul(esc, &endp, 10);
+                               esc = endp;
+                       } else if (*esc == 'y') {
+                               esc++;
+                               lcd_addr_y = simple_strtoul(esc, &endp, 10);
+                               esc = endp;
+                       } else
+                               break;
+               }
+
+               lcd_gotoxy();
+               processed = 1;
+               break;
+       }
+
+       /* Check wether one flag was changed */
+       if (oldflags != lcd_flags) {
+               /* check whether one of B,C,D flags were changed */
+               if ((oldflags ^ lcd_flags) &
+                   (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
+                       /* set display mode */
+                       lcd_write_cmd(0x08
+                                     | ((lcd_flags & LCD_FLAG_D) ? 4 : 0)
+                                     | ((lcd_flags & LCD_FLAG_C) ? 2 : 0)
+                                     | ((lcd_flags & LCD_FLAG_B) ? 1 : 0));
+               /* check whether one of F,N flags was changed */
+               else if ((oldflags ^ lcd_flags) & (LCD_FLAG_F | LCD_FLAG_N))
+                       lcd_write_cmd(0x30
+                                     | ((lcd_flags & LCD_FLAG_F) ? 4 : 0)
+                                     | ((lcd_flags & LCD_FLAG_N) ? 8 : 0));
+               /* check wether L flag was changed */
+               else if ((oldflags ^ lcd_flags) & (LCD_FLAG_L)) {
+                       if (lcd_flags & (LCD_FLAG_L))
+                               lcd_backlight(1);
+                       else if (light_tempo == 0)
+                               /* switch off the light only when the tempo
+                                  lighting is gone */
+                               lcd_backlight(0);
+               }
+       }
+
+       return processed;
+}
+
 static ssize_t lcd_write(struct file *file,
                         const char *buf, size_t count, loff_t *ppos)
 {
-
        const char *tmp = buf;
        char c;
 
        for (; count-- > 0; (ppos ? (*ppos)++ : 0), ++tmp) {
                if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
-                       schedule();     /* let's be a little nice with other processes that need some CPU */
+                       /* let's be a little nice with other processes
+                          that need some CPU */
+                       schedule();
 
                if (ppos == NULL && file == NULL)
-                       c = *tmp;       /* let's not use get_user() from the kernel ! */
+                       /* let's not use get_user() from the kernel ! */
+                       c = *tmp;
                else if (get_user(c, tmp))
                        return -EFAULT;
 
                /* first, we'll test if we're in escape mode */
-               if ((c != '\n') && lcd_escape_len >= 0) {       /* yes, let's add this char to the buffer */
+               if ((c != '\n') && lcd_escape_len >= 0) {
+                       /* yes, let's add this char to the buffer */
                        lcd_escape[lcd_escape_len++] = c;
                        lcd_escape[lcd_escape_len] = 0;
                } else {
-                       lcd_escape_len = -1;    /* aborts any previous escape sequence */
+                       /* aborts any previous escape sequence */
+                       lcd_escape_len = -1;
 
                        switch (c) {
-                       case LCD_ESCAPE_CHAR:   /* start of an escape sequence */
+                       case LCD_ESCAPE_CHAR:
+                               /* start of an escape sequence */
                                lcd_escape_len = 0;
                                lcd_escape[lcd_escape_len] = 0;
                                break;
-                       case '\b':      /* go back one char and clear it */
+                       case '\b':
+                               /* go back one char and clear it */
                                if (lcd_addr_x > 0) {
-                                       if (lcd_addr_x < lcd_bwidth)    /* check if we're not at the end of the line */
-                                               lcd_write_cmd(0x10);    /* back one char */
+                                       /* check if we're not at the
+                                          end of the line */
+                                       if (lcd_addr_x < lcd_bwidth)
+                                               /* back one char */
+                                               lcd_write_cmd(0x10);
                                        lcd_addr_x--;
                                }
-                               lcd_write_data(' ');    /* replace with a space */
-                               lcd_write_cmd(0x10);    /* back one char again */
+                               /* replace with a space */
+                               lcd_write_data(' ');
+                               /* back one char again */
+                               lcd_write_cmd(0x10);
                                break;
-                       case '\014':    /* quickly clear the display */
+                       case '\014':
+                               /* quickly clear the display */
                                lcd_clear_fast();
                                break;
-                       case '\n':      /* flush the remainder of the current line and go to the
-                                          beginning of the next line */
+                       case '\n':
+                               /* flush the remainder of the current line and
+                                  go to the beginning of the next line */
                                for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++)
                                        lcd_write_data(' ');
                                lcd_addr_x = 0;
                                lcd_addr_y = (lcd_addr_y + 1) % lcd_height;
                                lcd_gotoxy();
                                break;
-                       case '\r':      /* go to the beginning of the same line */
+                       case '\r':
+                               /* go to the beginning of the same line */
                                lcd_addr_x = 0;
                                lcd_gotoxy();
                                break;
-                       case '\t':      /* print a space instead of the tab */
+                       case '\t':
+                               /* print a space instead of the tab */
                                lcd_print(' ');
                                break;
-                       default:        /* simply print this char */
+                       default:
+                               /* simply print this char */
                                lcd_print(c);
                                break;
                        }
                }
 
                /* now we'll see if we're in an escape mode and if the current
-                  escape sequence can be understood.
-                */
-               if (lcd_escape_len >= 2) {      /* minimal length for an escape command */
-                       int processed = 0;      /* 1 means the command has been processed */
+                  escape sequence can be understood. */
+               if (lcd_escape_len >= 2) {
+                       int processed = 0;
 
-                       if (!strcmp(lcd_escape, "[2J")) {       /* Clear the display */
-                               lcd_clear_fast();       /* clear display */
+                       if (!strcmp(lcd_escape, "[2J")) {
+                               /* clear the display */
+                               lcd_clear_fast();
                                processed = 1;
-                       } else if (!strcmp(lcd_escape, "[H")) { /* Cursor to home */
+                       } else if (!strcmp(lcd_escape, "[H")) {
+                               /* cursor to home */
                                lcd_addr_x = lcd_addr_y = 0;
                                lcd_gotoxy();
                                processed = 1;
                        }
                        /* codes starting with ^[[L */
                        else if ((lcd_escape_len >= 3) &&
-                                (lcd_escape[0] == '[') && (lcd_escape[1] == 'L')) {    /* LCD special codes */
-
-                               char *esc = lcd_escape + 2;
-                               int oldflags = lcd_flags;
-
-                               /* check for display mode flags */
-                               switch (*esc) {
-                               case 'D':       /* Display ON */
-                                       lcd_flags |= LCD_FLAG_D;
-                                       processed = 1;
-                                       break;
-                               case 'd':       /* Display OFF */
-                                       lcd_flags &= ~LCD_FLAG_D;
-                                       processed = 1;
-                                       break;
-                               case 'C':       /* Cursor ON */
-                                       lcd_flags |= LCD_FLAG_C;
-                                       processed = 1;
-                                       break;
-                               case 'c':       /* Cursor OFF */
-                                       lcd_flags &= ~LCD_FLAG_C;
-                                       processed = 1;
-                                       break;
-                               case 'B':       /* Blink ON */
-                                       lcd_flags |= LCD_FLAG_B;
-                                       processed = 1;
-                                       break;
-                               case 'b':       /* Blink OFF */
-                                       lcd_flags &= ~LCD_FLAG_B;
-                                       processed = 1;
-                                       break;
-                               case '+':       /* Back light ON */
-                                       lcd_flags |= LCD_FLAG_L;
-                                       processed = 1;
-                                       break;
-                               case '-':       /* Back light OFF */
-                                       lcd_flags &= ~LCD_FLAG_L;
-                                       processed = 1;
-                                       break;
-                               case '*':       /* flash back light using the keypad timer */
-                                       if (scan_timer.function != NULL) {
-                                               if (light_tempo == 0
-                                                   && ((lcd_flags & LCD_FLAG_L)
-                                                       == 0))
-                                                       lcd_backlight(1);
-                                               light_tempo = FLASH_LIGHT_TEMPO;
-                                       }
-                                       processed = 1;
-                                       break;
-                               case 'f':       /* Small Font */
-                                       lcd_flags &= ~LCD_FLAG_F;
-                                       processed = 1;
-                                       break;
-                               case 'F':       /* Large Font */
-                                       lcd_flags |= LCD_FLAG_F;
-                                       processed = 1;
-                                       break;
-                               case 'n':       /* One Line */
-                                       lcd_flags &= ~LCD_FLAG_N;
-                                       processed = 1;
-                                       break;
-                               case 'N':       /* Two Lines */
-                                       lcd_flags |= LCD_FLAG_N;
-                                       break;
-
-                               case 'l':       /* Shift Cursor Left */
-                                       if (lcd_addr_x > 0) {
-                                               if (lcd_addr_x < lcd_bwidth)
-                                                       lcd_write_cmd(0x10);    /* back one char if not at end of line */
-                                               lcd_addr_x--;
-                                       }
-                                       processed = 1;
-                                       break;
-
-                               case 'r':       /* shift cursor right */
-                                       if (lcd_addr_x < lcd_width) {
-                                               if (lcd_addr_x < (lcd_bwidth - 1))
-                                                       lcd_write_cmd(0x14);    /* allow the cursor to pass the end of the line */
-                                               lcd_addr_x++;
-                                       }
-                                       processed = 1;
-                                       break;
-
-                               case 'L':       /* shift display left */
-                                       lcd_left_shift++;
-                                       lcd_write_cmd(0x18);
-                                       processed = 1;
-                                       break;
-
-                               case 'R':       /* shift display right */
-                                       lcd_left_shift--;
-                                       lcd_write_cmd(0x1C);
-                                       processed = 1;
-                                       break;
-
-                               case 'k':{      /* kill end of line */
-                                               int x;
-                                               for (x = lcd_addr_x; x < lcd_bwidth; x++)
-                                                       lcd_write_data(' ');
-                                               lcd_gotoxy();   /* restore cursor position */
-                                               processed = 1;
-                                               break;
-                                       }
-                               case 'I':       /* reinitialize display */
-                                       lcd_init_display();
-                                       lcd_left_shift = 0;
-                                       processed = 1;
-                                       break;
-
-                               case 'G':       /* Generator : LGcxxxxx...xx; */  {
-                                               /* must have <c> between '0' and '7', representing the numerical
-                                                * ASCII code of the redefined character, and <xx...xx> a sequence
-                                                * of 16 hex digits representing 8 bytes for each character. Most
-                                                * LCDs will only use 5 lower bits of the 7 first bytes.
-                                                */
-
-                                               unsigned char cgbytes[8];
-                                               unsigned char cgaddr;
-                                               int cgoffset;
-                                               int shift;
-                                               char value;
-                                               int addr;
-
-                                               if (strchr(esc, ';') == NULL)
-                                                       break;
-
-                                               esc++;
-
-                                               cgaddr = *(esc++) - '0';
-                                               if (cgaddr > 7) {
-                                                       processed = 1;
-                                                       break;
-                                               }
-
-                                               cgoffset = 0;
-                                               shift = 0;
-                                               value = 0;
-                                               while (*esc && cgoffset < 8) {
-                                                       shift ^= 4;
-                                                       if (*esc >= '0' && *esc <= '9')
-                                                               value |= (*esc - '0') << shift;
-                                                       else if (*esc >= 'A' && *esc <= 'Z')
-                                                               value |= (*esc - 'A' + 10) << shift;
-                                                       else if (*esc >= 'a' && *esc <= 'z')
-                                                               value |= (*esc - 'a' + 10) << shift;
-                                                       else {
-                                                               esc++;
-                                                               continue;
-                                                       }
-
-                                                       if (shift == 0) {
-                                                               cgbytes[cgoffset++] = value;
-                                                               value = 0;
-                                                       }
-
-                                                       esc++;
-                                               }
-
-                                               lcd_write_cmd(0x40 | (cgaddr * 8));
-                                               for (addr = 0; addr < cgoffset; addr++)
-                                                       lcd_write_data(cgbytes[addr]);
-
-                                               lcd_gotoxy();   /* ensures that we stop writing to CGRAM */
-                                               processed = 1;
-                                               break;
-                                       }
-                               case 'x':       /* gotoxy : LxXXX[yYYY]; */
-                               case 'y':       /* gotoxy : LyYYY[xXXX]; */
-                                       if (strchr(esc, ';') == NULL)
-                                               break;
-
-                                       while (*esc) {
-                                               if (*esc == 'x') {
-                                                       esc++;
-                                                       lcd_addr_x = 0;
-                                                       while (isdigit(*esc)) {
-                                                               lcd_addr_x =
-                                                                   lcd_addr_x *
-                                                                   10 + (*esc -
-                                                                         '0');
-                                                               esc++;
-                                                       }
-                                               } else if (*esc == 'y') {
-                                                       esc++;
-                                                       lcd_addr_y = 0;
-                                                       while (isdigit(*esc)) {
-                                                               lcd_addr_y =
-                                                                   lcd_addr_y *
-                                                                   10 + (*esc -
-                                                                         '0');
-                                                               esc++;
-                                                       }
-                                               } else
-                                                       break;
-                                       }
-
-                                       lcd_gotoxy();
-                                       processed = 1;
-                                       break;
-                               }       /* end of switch */
-
-                               /* Check wether one flag was changed */
-                               if (oldflags != lcd_flags) {
-                                       /* check wether one of B,C,D flags was changed */
-                                       if ((oldflags ^ lcd_flags) &
-                                           (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
-                                               /* set display mode */
-                                               lcd_write_cmd(0x08 |
-                                                             ((lcd_flags & LCD_FLAG_D) ? 4 : 0) |
-                                                             ((lcd_flags & LCD_FLAG_C) ? 2 : 0) |
-                                                             ((lcd_flags & LCD_FLAG_B) ? 1 : 0));
-                                       /* check wether one of F,N flags was changed */
-                                       else if ((oldflags ^ lcd_flags) &
-                                                (LCD_FLAG_F | LCD_FLAG_N))
-                                               lcd_write_cmd(0x30 |
-                                                             ((lcd_flags & LCD_FLAG_F) ? 4 : 0) |
-                                                             ((lcd_flags & LCD_FLAG_N) ? 8 : 0));
-                                       /* check wether L flag was changed */
-                                       else if ((oldflags ^ lcd_flags) &
-                                                (LCD_FLAG_L)) {
-                                               if (lcd_flags & (LCD_FLAG_L))
-                                                       lcd_backlight(1);
-                                               else if (light_tempo == 0)      /* switch off the light only when the tempo lighting is gone */
-                                                       lcd_backlight(0);
-                                       }
-                               }
+                                (lcd_escape[0] == '[') &&
+                                (lcd_escape[1] == 'L')) {
+                               processed = handle_lcd_special_code();
                        }
 
                        /* LCD special escape codes */
-                       /* flush the escape sequence if it's been processed or if it is
-                          getting too long. */
+                       /* flush the escape sequence if it's been processed
+                          or if it is getting too long. */
                        if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN))
                                lcd_escape_len = -1;
-               }               /* escape codes */
+               } /* escape codes */
        }
 
        return tmp - buf;
@@ -1295,7 +1351,7 @@ static int lcd_open(struct inode *inode, struct file *file)
                lcd_must_clear = 0;
        }
        lcd_open_cnt++;
-       return 0;
+       return nonseekable_open(inode, file);
 }
 
 static int lcd_release(struct inode *inode, struct file *file)
@@ -1304,10 +1360,11 @@ static int lcd_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations lcd_fops = {
+static const struct file_operations lcd_fops = {
        .write   = lcd_write,
        .open    = lcd_open,
        .release = lcd_release,
+       .llseek  = no_llseek,
 };
 
 static struct miscdevice lcd_dev = {
@@ -1327,7 +1384,8 @@ void panel_lcd_print(char *s)
 void lcd_init(void)
 {
        switch (lcd_type) {
-       case LCD_TYPE_OLD:      /* parallel mode, 8 bits */
+       case LCD_TYPE_OLD:
+               /* parallel mode, 8 bits */
                if (lcd_proto < 0)
                        lcd_proto = LCD_PROTO_PARALLEL;
                if (lcd_charset < 0)
@@ -1346,7 +1404,8 @@ void lcd_init(void)
                if (lcd_height < 0)
                        lcd_height = 2;
                break;
-       case LCD_TYPE_KS0074:   /* serial mode, ks0074 */
+       case LCD_TYPE_KS0074:
+               /* serial mode, ks0074 */
                if (lcd_proto < 0)
                        lcd_proto = LCD_PROTO_SERIAL;
                if (lcd_charset < 0)
@@ -1367,7 +1426,8 @@ void lcd_init(void)
                if (lcd_height < 0)
                        lcd_height = 2;
                break;
-       case LCD_TYPE_NEXCOM:   /* parallel mode, 8 bits, generic */
+       case LCD_TYPE_NEXCOM:
+               /* parallel mode, 8 bits, generic */
                if (lcd_proto < 0)
                        lcd_proto = LCD_PROTO_PARALLEL;
                if (lcd_charset < 0)
@@ -1388,14 +1448,16 @@ void lcd_init(void)
                if (lcd_height < 0)
                        lcd_height = 2;
                break;
-       case LCD_TYPE_CUSTOM:   /* customer-defined */
+       case LCD_TYPE_CUSTOM:
+               /* customer-defined */
                if (lcd_proto < 0)
                        lcd_proto = DEFAULT_LCD_PROTO;
                if (lcd_charset < 0)
                        lcd_charset = DEFAULT_LCD_CHARSET;
                /* default geometry will be set later */
                break;
-       case LCD_TYPE_HANTRONIX:        /* parallel mode, 8 bits, hantronix-like */
+       case LCD_TYPE_HANTRONIX:
+               /* parallel mode, 8 bits, hantronix-like */
        default:
                if (lcd_proto < 0)
                        lcd_proto = LCD_PROTO_PARALLEL;
@@ -1496,8 +1558,7 @@ void lcd_init(void)
 
        /* before this line, we must NOT send anything to the display.
         * Since lcd_init_display() needs to write data, we have to
-        * enable mark the LCD initialized just before.
-        */
+        * enable mark the LCD initialized just before. */
        lcd_initialized = 1;
        lcd_init_display();
 
@@ -1511,7 +1572,8 @@ void lcd_init(void)
                        PANEL_VERSION);
 #endif
        lcd_addr_x = lcd_addr_y = 0;
-       lcd_must_clear = 1;     /* clear the display on the next device opening */
+       /* clear the display on the next device opening */
+       lcd_must_clear = 1;
        lcd_gotoxy();
 }
 
@@ -1535,7 +1597,8 @@ static ssize_t keypad_read(struct file *file,
                        return -EINTR;
        }
 
-       for (; count-- > 0 && (keypad_buflen > 0); ++i, ++tmp, --keypad_buflen) {
+       for (; count-- > 0 && (keypad_buflen > 0);
+            ++i, ++tmp, --keypad_buflen) {
                put_user(keypad_buffer[keypad_start], tmp);
                keypad_start = (keypad_start + 1) % KEYPAD_BUFFER;
        }
@@ -1564,7 +1627,7 @@ static int keypad_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations keypad_fops = {
+static const struct file_operations keypad_fops = {
        .read    = keypad_read,         /* read */
        .open    = keypad_open,         /* open */
        .release = keypad_release,      /* close */
@@ -1591,14 +1654,15 @@ static void keypad_send_key(char *string, int max_len)
        }
 }
 
-/* this function scans all the bits involving at least one logical signal, and puts the
- * results in the bitfield "phys_read" (one bit per established contact), and sets
- * "phys_read_prev" to "phys_read".
+/* this function scans all the bits involving at least one logical signal,
+ * and puts the results in the bitfield "phys_read" (one bit per established
+ * contact), and sets "phys_read_prev" to "phys_read".
  *
- * Note: to debounce input signals, we will only consider as switched a signal which is
- * stable across 2 measures. Signals which are different between two reads will be kept
- * as they previously were in their logical form (phys_prev). A signal which has just
- * switched will have a 1 in (phys_read ^ phys_read_prev).
+ * Note: to debounce input signals, we will only consider as switched a signal
+ * which is stable across 2 measures. Signals which are different between two
+ * reads will be kept as they previously were in their logical form (phys_prev).
+ * A signal which has just switched will have a 1 in
+ * (phys_read ^ phys_read_prev).
  */
 static void phys_scan_contacts(void)
 {
@@ -1611,21 +1675,30 @@ static void phys_scan_contacts(void)
        phys_read_prev = phys_read;
        phys_read = 0;          /* flush all signals */
 
-       oldval = r_dtr(pprt) | scan_mask_o;     /* keep track of old value, with all outputs disabled */
-       w_dtr(pprt, oldval & ~scan_mask_o);     /* activate all keyboard outputs (active low) */
-       bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;        /* will have a 1 for each bit set to gnd */
-       w_dtr(pprt, oldval);    /* disable all matrix signals */
+       /* keep track of old value, with all outputs disabled */
+       oldval = r_dtr(pprt) | scan_mask_o;
+       /* activate all keyboard outputs (active low) */
+       w_dtr(pprt, oldval & ~scan_mask_o);
+
+       /* will have a 1 for each bit set to gnd */
+       bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
+       /* disable all matrix signals */
+       w_dtr(pprt, oldval);
 
        /* now that all outputs are cleared, the only active input bits are
         * directly connected to the ground
         */
-       gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;        /* 1 for each grounded input */
 
-       phys_read |= (pmask_t) gndmask << 40;   /* grounded inputs are signals 40-44 */
+       /* 1 for each grounded input */
+       gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
+
+       /* grounded inputs are signals 40-44 */
+       phys_read |= (pmask_t) gndmask << 40;
 
        if (bitmask != gndmask) {
-               /* since clearing the outputs changed some inputs, we know that some
-                * input signals are currently tied to some outputs. So we'll scan them.
+               /* since clearing the outputs changed some inputs, we know
+                * that some input signals are currently tied to some outputs.
+                * So we'll scan them.
                 */
                for (bit = 0; bit < 8; bit++) {
                        bitval = 1 << bit;
@@ -1639,11 +1712,127 @@ static void phys_scan_contacts(void)
                }
                w_dtr(pprt, oldval);    /* disable all outputs */
        }
-       /* this is easy: use old bits when they are flapping, use new ones when stable */
-       phys_curr =
-           (phys_prev & (phys_read ^ phys_read_prev)) | (phys_read &
-                                                         ~(phys_read ^
-                                                           phys_read_prev));
+       /* this is easy: use old bits when they are flapping,
+        * use new ones when stable */
+       phys_curr = (phys_prev & (phys_read ^ phys_read_prev)) |
+                   (phys_read & ~(phys_read ^ phys_read_prev));
+}
+
+static inline int input_state_high(struct logical_input *input)
+{
+#if 0
+       /* FIXME:
+        * this is an invalid test. It tries to catch
+        * transitions from single-key to multiple-key, but
+        * doesn't take into account the contacts polarity.
+        * The only solution to the problem is to parse keys
+        * from the most complex to the simplest combinations,
+        * and mark them as 'caught' once a combination
+        * matches, then unmatch it for all other ones.
+        */
+
+       /* try to catch dangerous transitions cases :
+        * someone adds a bit, so this signal was a false
+        * positive resulting from a transition. We should
+        * invalidate the signal immediately and not call the
+        * release function.
+        * eg: 0 -(press A)-> A -(press B)-> AB : don't match A's release.
+        */
+       if (((phys_prev & input->mask) == input->value)
+           && ((phys_curr & input->mask) > input->value)) {
+               input->state = INPUT_ST_LOW; /* invalidate */
+               return 1;
+       }
+#endif
+
+       if ((phys_curr & input->mask) == input->value) {
+               if ((input->type == INPUT_TYPE_STD) &&
+                   (input->high_timer == 0)) {
+                       input->high_timer++;
+                       if (input->u.std.press_fct != NULL)
+                               input->u.std.press_fct(input->u.std.press_data);
+               } else if (input->type == INPUT_TYPE_KBD) {
+                       /* will turn on the light */
+                       keypressed = 1;
+
+                       if (input->high_timer == 0) {
+                               char *press_str = input->u.kbd.press_str;
+                               if (press_str[0])
+                                       keypad_send_key(press_str,
+                                                       sizeof(press_str));
+                       }
+
+                       if (input->u.kbd.repeat_str[0]) {
+                               char *repeat_str = input->u.kbd.repeat_str;
+                               if (input->high_timer >= KEYPAD_REP_START) {
+                                       input->high_timer -= KEYPAD_REP_DELAY;
+                                       keypad_send_key(repeat_str,
+                                                       sizeof(repeat_str));
+                               }
+                               /* we will need to come back here soon */
+                               inputs_stable = 0;
+                       }
+
+                       if (input->high_timer < 255)
+                               input->high_timer++;
+               }
+               return 1;
+       } else {
+               /* else signal falling down. Let's fall through. */
+               input->state = INPUT_ST_FALLING;
+               input->fall_timer = 0;
+       }
+       return 0;
+}
+
+static inline void input_state_falling(struct logical_input *input)
+{
+#if 0
+       /* FIXME !!! same comment as in input_state_high */
+       if (((phys_prev & input->mask) == input->value)
+           && ((phys_curr & input->mask) > input->value)) {
+               input->state = INPUT_ST_LOW;    /* invalidate */
+               return;
+       }
+#endif
+
+       if ((phys_curr & input->mask) == input->value) {
+               if (input->type == INPUT_TYPE_KBD) {
+                       /* will turn on the light */
+                       keypressed = 1;
+
+                       if (input->u.kbd.repeat_str[0]) {
+                               char *repeat_str = input->u.kbd.repeat_str;
+                               if (input->high_timer >= KEYPAD_REP_START)
+                                       input->high_timer -= KEYPAD_REP_DELAY;
+                                       keypad_send_key(repeat_str,
+                                                       sizeof(repeat_str));
+                               /* we will need to come back here soon */
+                               inputs_stable = 0;
+                       }
+
+                       if (input->high_timer < 255)
+                               input->high_timer++;
+               }
+               input->state = INPUT_ST_HIGH;
+       } else if (input->fall_timer >= input->fall_time) {
+               /* call release event */
+               if (input->type == INPUT_TYPE_STD) {
+                       void (*release_fct)(int) = input->u.std.release_fct;
+                       if (release_fct != NULL)
+                               release_fct(input->u.std.release_data);
+               } else if (input->type == INPUT_TYPE_KBD) {
+                       char *release_str = input->u.kbd.release_str;
+                       if (release_str[0])
+                               keypad_send_key(release_str,
+                                               sizeof(release_str));
+               }
+
+               input->state = INPUT_ST_LOW;
+       } else {
+               input->fall_timer++;
+               inputs_stable = 0;
+       }
 }
 
 static void panel_process_inputs(void)
@@ -1666,10 +1855,12 @@ static void panel_process_inputs(void)
                case INPUT_ST_LOW:
                        if ((phys_curr & input->mask) != input->value)
                                break;
-                       /* if all needed ones were already set previously, this means that
-                        * this logical signal has been activated by the releasing of
-                        * another combined signal, so we don't want to match.
-                        * eg: AB -(release B)-> A -(release A)-> 0 : don't match A.
+                       /* if all needed ones were already set previously,
+                        * this means that this logical signal has been
+                        * activated by the releasing of another combined
+                        * signal, so we don't want to match.
+                        * eg: AB -(release B)-> A -(release A)-> 0 :
+                        *     don't match A.
                         */
                        if ((phys_prev & input->mask) == input->value)
                                break;
@@ -1690,122 +1881,11 @@ static void panel_process_inputs(void)
                        input->state = INPUT_ST_HIGH;
                        /* no break here, fall through */
                case INPUT_ST_HIGH:
-#if 0
-                       /* FIXME:
-                        * this is an invalid test. It tries to catch transitions from single-key
-                        * to multiple-key, but doesn't take into account the contacts polarity.
-                        * The only solution to the problem is to parse keys from the most complex
-                        * to the simplest combinations, and mark them as 'caught' once a combination
-                        * matches, then unmatch it for all other ones.
-                        */
-
-                       /* try to catch dangerous transitions cases :
-                        * someone adds a bit, so this signal was a false
-                        * positive resulting from a transition. We should invalidate
-                        * the signal immediately and not call the release function.
-                        * eg: 0 -(press A)-> A -(press B)-> AB : don't match A's release.
-                        */
-                       if (((phys_prev & input->mask) == input->value)
-                           && ((phys_curr & input->mask) > input->value)) {
-                               input->state = INPUT_ST_LOW;    /* invalidate */
-                               break;
-                       }
-#endif
-
-                       if ((phys_curr & input->mask) == input->value) {
-                               if ((input->type == INPUT_TYPE_STD)
-                                   && (input->high_timer == 0)) {
-                                       input->high_timer++;
-                                       if (input->u.std.press_fct != NULL)
-                                               input->u.std.press_fct(input->u.
-                                                                      std.
-                                                                      press_data);
-                               } else if (input->type == INPUT_TYPE_KBD) {
-                                       keypressed = 1; /* will turn on the light */
-
-                                       if (input->high_timer == 0) {
-                                               if (input->u.kbd.press_str[0])
-                                                       keypad_send_key(input->
-                                                                       u.kbd.
-                                                                       press_str,
-                                                                       sizeof
-                                                                       (input->
-                                                                        u.kbd.
-                                                                        press_str));
-                                       }
-
-                                       if (input->u.kbd.repeat_str[0]) {
-                                               if (input->high_timer >=
-                                                   KEYPAD_REP_START) {
-                                                       input->high_timer -=
-                                                           KEYPAD_REP_DELAY;
-                                                       keypad_send_key(input->
-                                                                       u.kbd.
-                                                                       repeat_str,
-                                                                       sizeof
-                                                                       (input->
-                                                                        u.kbd.
-                                                                        repeat_str));
-                                               }
-                                               inputs_stable = 0;      /* we will need to come back here soon */
-                                       }
-
-                                       if (input->high_timer < 255)
-                                               input->high_timer++;
-                               }
+                       if (input_state_high(input))
                                break;
-                       } else {
-                               /* else signal falling down. Let's fall through. */
-                               input->state = INPUT_ST_FALLING;
-                               input->fall_timer = 0;
-                       }
                        /* no break here, fall through */
                case INPUT_ST_FALLING:
-#if 0
-                       /* FIXME !!! same comment as above */
-                       if (((phys_prev & input->mask) == input->value)
-                           && ((phys_curr & input->mask) > input->value)) {
-                               input->state = INPUT_ST_LOW;    /* invalidate */
-                               break;
-                       }
-#endif
-
-                       if ((phys_curr & input->mask) == input->value) {
-                               if (input->type == INPUT_TYPE_KBD) {
-                                       keypressed = 1; /* will turn on the light */
-
-                                       if (input->u.kbd.repeat_str[0]) {
-                                               if (input->high_timer >= KEYPAD_REP_START)
-                                                       input->high_timer -= KEYPAD_REP_DELAY;
-                                               keypad_send_key(input->u.kbd.repeat_str,
-                                                               sizeof(input->u.kbd.repeat_str));
-                                               inputs_stable = 0;      /* we will need to come back here soon */
-                                       }
-
-                                       if (input->high_timer < 255)
-                                               input->high_timer++;
-                               }
-                               input->state = INPUT_ST_HIGH;
-                               break;
-                       } else if (input->fall_timer >= input->fall_time) {
-                               /* call release event */
-                               if (input->type == INPUT_TYPE_STD) {
-                                       if (input->u.std.release_fct != NULL)
-                                               input->u.std.release_fct(input->u.std.release_data);
-
-                               } else if (input->type == INPUT_TYPE_KBD) {
-                                       if (input->u.kbd.release_str[0])
-                                               keypad_send_key(input->u.kbd.release_str,
-                                                               sizeof(input->u.kbd.release_str));
-                               }
-
-                               input->state = INPUT_ST_LOW;
-                               break;
-                       } else {
-                               input->fall_timer++;
-                               inputs_stable = 0;
-                               break;
-                       }
+                       input_state_falling(input);
                }
        }
 }
@@ -1815,7 +1895,9 @@ static void panel_scan_timer(void)
        if (keypad_enabled && keypad_initialized) {
                if (spin_trylock(&pprt_lock)) {
                        phys_scan_contacts();
-                       spin_unlock(&pprt_lock);        /* no need for the parport anymore */
+
+                       /* no need for the parport anymore */
+                       spin_unlock(&pprt_lock);
                }
 
                if (!inputs_stable || phys_curr != phys_prev)
@@ -1850,8 +1932,8 @@ static void init_scan_timer(void)
 }
 
 /* converts a name of the form "({BbAaPpSsEe}{01234567-})*" to a series of bits.
- * if <omask> or <imask> are non-null, they will be or'ed with the bits corresponding
- * to out and in bits respectively.
+ * if <omask> or <imask> are non-null, they will be or'ed with the bits
+ * corresponding to out and in bits respectively.
  * returns 1 if ok, 0 if error (in which case, nothing is written).
  */
 static int input_name2mask(char *name, pmask_t *mask, pmask_t *value,
@@ -1864,7 +1946,8 @@ static int input_name2mask(char *name, pmask_t *mask, pmask_t *value,
        om = im = m = v = 0ULL;
        while (*name) {
                int in, out, bit, neg;
-               for (in = 0; (in < sizeof(sigtab)) && (sigtab[in] != *name); in++)
+               for (in = 0; (in < sizeof(sigtab)) &&
+                            (sigtab[in] != *name); in++)
                        ;
                if (in >= sizeof(sigtab))
                        return 0;       /* input name not found */
@@ -1912,8 +1995,10 @@ static struct logical_input *panel_bind_key(char *name, char *press,
                return NULL;
        }
        if (!input_name2mask(name, &key->mask, &key->value, &scan_mask_i,
-                            &scan_mask_o))
+                            &scan_mask_o)) {
+               kfree(key);
                return NULL;
+       }
 
        key->type = INPUT_TYPE_KBD;
        key->state = INPUT_ST_LOW;
@@ -1936,7 +2021,8 @@ static struct logical_input *panel_bind_key(char *name, char *press,
 /* tries to bind a callback function to the signal name <name>. The function
  * <press_fct> will be called with the <press_data> arg when the signal is
  * activated, and so on for <release_fct>/<release_data>
- * Returns the pointer to the new signal if ok, NULL if the signal could not be bound.
+ * Returns the pointer to the new signal if ok, NULL if the signal could not
+ * be bound.
  */
 static struct logical_input *panel_bind_callback(char *name,
                                                 void (*press_fct) (int),
@@ -2028,33 +2114,52 @@ static void panel_attach(struct parport *port)
 
        if (pprt) {
                printk(KERN_ERR
-                      "panel_attach(): port->number=%d parport=%d, already registered !\n",
+                      "panel_attach(): port->number=%d parport=%d, "
+                      "already registered !\n",
                       port->number, parport);
                return;
        }
 
-       pprt = parport_register_device(port, "panel", NULL, NULL,       /* pf, kf */
+       pprt = parport_register_device(port, "panel", NULL, NULL,  /* pf, kf */
                                       NULL,
                                       /*PARPORT_DEV_EXCL */
                                       0, (void *)&pprt);
+       if (pprt == NULL) {
+               pr_err("panel_attach(): port->number=%d parport=%d, "
+                      "parport_register_device() failed\n",
+                      port->number, parport);
+               return;
+       }
 
        if (parport_claim(pprt)) {
                printk(KERN_ERR
-                      "Panel: could not claim access to parport%d. Aborting.\n",
-                      parport);
-               return;
+                      "Panel: could not claim access to parport%d. "
+                      "Aborting.\n", parport);
+               goto err_unreg_device;
        }
 
-       /* must init LCD first, just in case an IRQ from the keypad is generated at keypad init */
+       /* must init LCD first, just in case an IRQ from the keypad is
+        * generated at keypad init
+        */
        if (lcd_enabled) {
                lcd_init();
-               misc_register(&lcd_dev);
+               if (misc_register(&lcd_dev))
+                       goto err_unreg_device;
        }
 
        if (keypad_enabled) {
                keypad_init();
-               misc_register(&keypad_dev);
+               if (misc_register(&keypad_dev))
+                       goto err_lcd_unreg;
        }
+       return;
+
+err_lcd_unreg:
+       if (lcd_enabled)
+               misc_deregister(&lcd_dev);
+err_unreg_device:
+       parport_unregister_device(pprt);
+       pprt = NULL;
 }
 
 static void panel_detach(struct parport *port)
@@ -2064,7 +2169,8 @@ static void panel_detach(struct parport *port)
 
        if (!pprt) {
                printk(KERN_ERR
-                      "panel_detach(): port->number=%d parport=%d, nothing to unregister.\n",
+                      "panel_detach(): port->number=%d parport=%d, "
+                      "nothing to unregister.\n",
                       port->number, parport);
                return;
        }
@@ -2105,13 +2211,15 @@ int panel_init(void)
 
        /* take care of an eventual profile */
        switch (profile) {
-       case PANEL_PROFILE_CUSTOM:      /* custom profile */
+       case PANEL_PROFILE_CUSTOM:
+               /* custom profile */
                if (keypad_type < 0)
                        keypad_type = DEFAULT_KEYPAD;
                if (lcd_type < 0)
                        lcd_type = DEFAULT_LCD;
                break;
-       case PANEL_PROFILE_OLD: /* 8 bits, 2*16, old keypad */
+       case PANEL_PROFILE_OLD:
+               /* 8 bits, 2*16, old keypad */
                if (keypad_type < 0)
                        keypad_type = KEYPAD_TYPE_OLD;
                if (lcd_type < 0)
@@ -2121,25 +2229,29 @@ int panel_init(void)
                if (lcd_hwidth < 0)
                        lcd_hwidth = 16;
                break;
-       case PANEL_PROFILE_NEW: /* serial, 2*16, new keypad */
+       case PANEL_PROFILE_NEW:
+               /* serial, 2*16, new keypad */
                if (keypad_type < 0)
                        keypad_type = KEYPAD_TYPE_NEW;
                if (lcd_type < 0)
                        lcd_type = LCD_TYPE_KS0074;
                break;
-       case PANEL_PROFILE_HANTRONIX:   /* 8 bits, 2*16 hantronix-like, no keypad */
+       case PANEL_PROFILE_HANTRONIX:
+               /* 8 bits, 2*16 hantronix-like, no keypad */
                if (keypad_type < 0)
                        keypad_type = KEYPAD_TYPE_NONE;
                if (lcd_type < 0)
                        lcd_type = LCD_TYPE_HANTRONIX;
                break;
-       case PANEL_PROFILE_NEXCOM:      /* generic 8 bits, 2*16, nexcom keypad, eg. Nexcom. */
+       case PANEL_PROFILE_NEXCOM:
+               /* generic 8 bits, 2*16, nexcom keypad, eg. Nexcom. */
                if (keypad_type < 0)
                        keypad_type = KEYPAD_TYPE_NEXCOM;
                if (lcd_type < 0)
                        lcd_type = LCD_TYPE_NEXCOM;
                break;
-       case PANEL_PROFILE_LARGE:       /* 8 bits, 2*40, old keypad */
+       case PANEL_PROFILE_LARGE:
+               /* 8 bits, 2*40, old keypad */
                if (keypad_type < 0)
                        keypad_type = KEYPAD_TYPE_OLD;
                if (lcd_type < 0)
@@ -2179,6 +2291,7 @@ int panel_init(void)
                if (pprt) {
                        parport_release(pprt);
                        parport_unregister_device(pprt);
+                       pprt = NULL;
                }
                parport_unregister_driver(&panel_driver);
                printk(KERN_ERR "Panel driver version " PANEL_VERSION
@@ -2195,7 +2308,8 @@ int panel_init(void)
        else
                printk(KERN_INFO "Panel driver version " PANEL_VERSION
                       " not yet registered\n");
-       /* tells various subsystems about the fact that initialization is finished */
+       /* tells various subsystems about the fact that initialization
+          is finished */
        init_in_progress = 0;
        return 0;
 }
@@ -2228,6 +2342,7 @@ static void __exit panel_cleanup_module(void)
                /* TODO: free all input signals */
                parport_release(pprt);
                parport_unregister_device(pprt);
+               pprt = NULL;
        }
        parport_unregister_driver(&panel_driver);
 }
index 643b413d9f0f395fca978a56641cbe582beee773..bc1c6051a6f66847d8d6dc9d9c84810517d6520f 100644 (file)
@@ -815,7 +815,7 @@ static int pohmelfs_readpages(struct file *file, struct address_space *mapping,
 }
 
 /*
- * Small addres space operations for POHMELFS.
+ * Small address space operations for POHMELFS.
  */
 const struct address_space_operations pohmelfs_aops = {
        .readpage               = pohmelfs_readpage,
@@ -847,7 +847,7 @@ static void pohmelfs_destroy_inode(struct inode *inode)
 }
 
 /*
- * ->alloc_inode() callback. Allocates inode and initilizes private data.
+ * ->alloc_inode() callback. Allocates inode and initializes private data.
  */
 static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
 {
@@ -1266,7 +1266,7 @@ static void pohmelfs_put_super(struct super_block *sb)
 {
        struct pohmelfs_sb *psb = POHMELFS_SB(sb);
        struct pohmelfs_inode *pi;
-       unsigned int count;
+       unsigned int count = 0;
        unsigned int in_drop_list = 0;
        struct inode *inode, *tmp;
 
index ecd73135b3194f91a4838c1993e9e0415ffb30de..9838ea279c5c222fd6ad8283fe7d7f4e27d73e2b 100644 (file)
@@ -258,8 +258,6 @@ static int qt2_box_get_register(struct usb_serial *serial,
 static int qt2_box_set_register(struct usb_serial *serial,
                unsigned short Uart_Number, unsigned short Register_Num,
                unsigned short Value);
-static int qt2_box_flush(struct usb_serial *serial,  unsigned char uart_number,
-               unsigned short rcv_or_xmit);
 static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
                unsigned short default_divisor, unsigned char default_LCR);
 static int qt2_boxsethw_flowctl(struct usb_serial *serial,
@@ -645,9 +643,6 @@ static void qt2_close(struct usb_serial_port *port)
        /* get the device private data */
        port_extra = qt2_get_port_private(port); /* port private data */
 
-       /* we don't need to force flush though the hardware, so we skip using
-        * qt2_box_flush() here */
-
        /* we can now (and only now) stop reading data */
        port_extra->close_pending = true;
        dbg("%s(): port_extra->close_pending = true", __func__);
@@ -1841,24 +1836,6 @@ static int qt2_box_set_register(struct usb_serial *serial,
        return result;
 }
 
-
-/** @brief Request the Tx or Rx buffers on the USB side be flushed
- *
- * Tx flush: When all the currently buffered data has been sent, send an escape
- * sequence back up the data stream to us
- * Rx flush: add a flag in the data stream now so we know when it's made it's
- * way up to us.
- */
-static int qt2_box_flush(struct usb_serial *serial,  unsigned char uart_number,
-                   unsigned short rcv_or_xmit)
-{
-       int result;
-       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-               QT2_FLUSH_DEVICE, 0x40, rcv_or_xmit, uart_number, NULL, 0,
-               300);
-       return result;
-}
-
 /** qt2_boxsetuart - Issue a SET_UART vendor-spcific request on the default
  * control pipe. If successful sets baud rate divisor and LCR value.
  */
@@ -1873,6 +1850,7 @@ static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
                        QT2_GET_SET_UART, 0x40, default_divisor, UartNumandLCR,
                        NULL, 0, 300);
 }
+
 /** qt2_boxsethw_flowctl - Turn hardware (RTS/CTS) flow control on and off for
  * a hardware UART.
  */
diff --git a/drivers/staging/quickstart/Kconfig b/drivers/staging/quickstart/Kconfig
new file mode 100644 (file)
index 0000000..5bea487
--- /dev/null
@@ -0,0 +1,10 @@
+config ACPI_QUICKSTART
+       tristate "ACPI Quickstart key driver"
+       depends on ACPI && INPUT
+       help
+         Say Y here if you have a platform that supports the ACPI
+         quickstart key protocol.
+
+         To compile this driver as a module, choose M here: the module will be
+         called quickstart.
+
diff --git a/drivers/staging/quickstart/Makefile b/drivers/staging/quickstart/Makefile
new file mode 100644 (file)
index 0000000..290e0e4
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_ACPI_QUICKSTART)          += quickstart.o
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c
new file mode 100644 (file)
index 0000000..6612247
--- /dev/null
@@ -0,0 +1,474 @@
+/*
+ *  quickstart.c - ACPI Direct App Launch driver
+ *
+ *
+ *  Copyright (C) 2007-2010 Angelo Arrifano <miknix@gmail.com>
+ *
+ *  Information gathered from disassebled dsdt and from here:
+ *  "http://download.microsoft.com/download/9/c/5/
+ *  9c5b2167-8017-4bae-9fde-d599bac8184a/DirAppLaunch_Vista.doc"
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define QUICKSTART_VERSION "1.03"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+
+MODULE_AUTHOR("Angelo Arrifano");
+MODULE_DESCRIPTION("ACPI Direct App Launch driver");
+MODULE_LICENSE("GPL");
+
+#define QUICKSTART_ACPI_DEVICE_NAME   "quickstart"
+#define QUICKSTART_ACPI_CLASS         "quickstart"
+#define QUICKSTART_ACPI_HID           "PNP0C32"
+
+#define QUICKSTART_PF_DRIVER_NAME     "quickstart"
+#define QUICKSTART_PF_DEVICE_NAME     "quickstart"
+#define QUICKSTART_PF_DEVATTR_NAME    "pressed_button"
+
+#define QUICKSTART_MAX_BTN_NAME_LEN   16
+
+/* There will be two events:
+        * 0x02 - A hot button was pressed while device was off/sleeping.
+        * 0x80 - A hot button was pressed while device was up. */
+#define QUICKSTART_EVENT_WAKE         0x02
+#define QUICKSTART_EVENT_RUNTIME      0x80
+
+struct quickstart_btn {
+       char *name;
+       unsigned int id;
+       struct quickstart_btn *next;
+};
+
+static struct quickstart_driver_data {
+       struct quickstart_btn *btn_lst;
+       struct quickstart_btn *pressed;
+} quickstart_data;
+
+/* ACPI driver Structs */
+struct quickstart_acpi {
+       struct acpi_device *device;
+       struct quickstart_btn *btn;
+};
+static int quickstart_acpi_add(struct acpi_device *device);
+static int quickstart_acpi_remove(struct acpi_device *device, int type);
+static const struct acpi_device_id  quickstart_device_ids[] = {
+       {QUICKSTART_ACPI_HID, 0},
+       {"", 0},
+};
+
+static struct acpi_driver quickstart_acpi_driver = {
+       .name = "quickstart",
+       .class = QUICKSTART_ACPI_CLASS,
+       .ids = quickstart_device_ids,
+       .ops = {
+                       .add = quickstart_acpi_add,
+                       .remove = quickstart_acpi_remove,
+               },
+};
+
+/* Input device structs */
+struct input_dev *quickstart_input;
+
+/* Platform driver structs */
+static ssize_t buttons_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf);
+static ssize_t pressed_button_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf);
+static ssize_t pressed_button_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                        const char *buf,
+                                        size_t count);
+static DEVICE_ATTR(pressed_button, 0666, pressed_button_show,
+                                        pressed_button_store);
+static DEVICE_ATTR(buttons, 0444, buttons_show, NULL);
+static struct platform_device *pf_device;
+static struct platform_driver pf_driver = {
+       .driver = {
+               .name = QUICKSTART_PF_DRIVER_NAME,
+               .owner = THIS_MODULE,
+       }
+};
+
+/*
+ * Platform driver functions
+ */
+static ssize_t buttons_show(struct device *dev,
+                                        struct device_attribute *attr,
+                                        char *buf)
+{
+       int count = 0;
+       struct quickstart_btn *ptr = quickstart_data.btn_lst;
+
+       if (!ptr)
+               return snprintf(buf, PAGE_SIZE, "none");
+
+       while (ptr && (count < PAGE_SIZE)) {
+               if (ptr->name) {
+                       count += snprintf(buf + count,
+                                       PAGE_SIZE - count,
+                                       "%d\t%s\n", ptr->id, ptr->name);
+               }
+               ptr = ptr->next;
+       }
+
+       return count;
+}
+
+static ssize_t pressed_button_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+               (quickstart_data.pressed?quickstart_data.pressed->name:"none"));
+}
+
+
+static ssize_t pressed_button_store(struct device *dev,
+                                        struct device_attribute *attr,
+                                        const char *buf, size_t count)
+{
+       if (count < 2)
+               return -EINVAL;
+
+       if (strncasecmp(buf, "none", 4) != 0)
+               return -EINVAL;
+
+       quickstart_data.pressed = NULL;
+       return count;
+}
+
+/* Hotstart Helper functions */
+static int quickstart_btnlst_add(struct quickstart_btn **data)
+{
+       struct quickstart_btn **ptr = &quickstart_data.btn_lst;
+
+       while (*ptr)
+               ptr = &((*ptr)->next);
+
+       *ptr = kzalloc(sizeof(struct quickstart_btn), GFP_KERNEL);
+       if (!*ptr) {
+               *data = NULL;
+               return -ENOMEM;
+       }
+       *data = *ptr;
+
+       return 0;
+}
+
+static void quickstart_btnlst_del(struct quickstart_btn *data)
+{
+       struct quickstart_btn **ptr = &quickstart_data.btn_lst;
+
+       if (!data)
+               return;
+
+       while (*ptr) {
+               if (*ptr == data) {
+                       *ptr = (*ptr)->next;
+                       kfree(data);
+                       return;
+               }
+               ptr = &((*ptr)->next);
+       }
+
+       return;
+}
+
+static void quickstart_btnlst_free(void)
+{
+       struct quickstart_btn *ptr = quickstart_data.btn_lst;
+       struct quickstart_btn *lptr = NULL;
+
+       while (ptr) {
+               lptr = ptr;
+               ptr = ptr->next;
+               kfree(lptr->name);
+               kfree(lptr);
+       }
+
+       return;
+}
+
+/* ACPI Driver functions */
+static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data)
+{
+       struct quickstart_acpi *quickstart = data;
+
+       if (!quickstart)
+               return;
+
+       if (event == QUICKSTART_EVENT_WAKE)
+               quickstart_data.pressed = quickstart->btn;
+       else if (event == QUICKSTART_EVENT_RUNTIME) {
+               input_report_key(quickstart_input, quickstart->btn->id, 1);
+               input_sync(quickstart_input);
+               input_report_key(quickstart_input, quickstart->btn->id, 0);
+               input_sync(quickstart_input);
+       }
+       return;
+}
+
+static void quickstart_acpi_ghid(struct quickstart_acpi *quickstart)
+{
+       acpi_status status;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       uint32_t usageid = 0;
+
+       if (!quickstart)
+               return;
+
+       /* This returns a buffer telling the button usage ID,
+        * and triggers pending notify events (The ones before booting). */
+       status = acpi_evaluate_object(quickstart->device->handle,
+                                       "GHID", NULL, &buffer);
+       if (ACPI_FAILURE(status) || !buffer.pointer) {
+               printk(KERN_ERR "quickstart: %s GHID method failed.\n",
+                      quickstart->btn->name);
+               return;
+       }
+
+       if (buffer.length < 8)
+               return;
+
+       /* <<The GHID method can return a BYTE, WORD, or DWORD.
+        * The value must be encoded in little-endian byte
+        * order (least significant byte first).>> */
+       usageid = *((uint32_t *)(buffer.pointer + (buffer.length - 8)));
+       quickstart->btn->id = usageid;
+
+       kfree(buffer.pointer);
+}
+
+static int quickstart_acpi_config(struct quickstart_acpi *quickstart, char *bid)
+{
+       int len = strlen(bid);
+       int ret;
+
+       /* Add button to list */
+       ret = quickstart_btnlst_add(&quickstart->btn);
+       if (ret)
+               return ret;
+
+       quickstart->btn->name = kzalloc(len + 1, GFP_KERNEL);
+       if (!quickstart->btn->name) {
+               quickstart_btnlst_free();
+               return -ENOMEM;
+       }
+       strcpy(quickstart->btn->name, bid);
+
+       return 0;
+}
+
+static int quickstart_acpi_add(struct acpi_device *device)
+{
+       int ret = 0;
+       acpi_status status = AE_OK;
+       struct quickstart_acpi *quickstart = NULL;
+
+       if (!device)
+               return -EINVAL;
+
+       quickstart = kzalloc(sizeof(struct quickstart_acpi), GFP_KERNEL);
+       if (!quickstart)
+               return -ENOMEM;
+
+       quickstart->device = device;
+       strcpy(acpi_device_name(device), QUICKSTART_ACPI_DEVICE_NAME);
+       strcpy(acpi_device_class(device), QUICKSTART_ACPI_CLASS);
+       device->driver_data = quickstart;
+
+       /* Add button to list and initialize some stuff */
+       ret = quickstart_acpi_config(quickstart, acpi_device_bid(device));
+       if (ret)
+               goto fail_config;
+
+       status = acpi_install_notify_handler(device->handle,
+                                               ACPI_ALL_NOTIFY,
+                                               quickstart_acpi_notify,
+                                               quickstart);
+       if (ACPI_FAILURE(status)) {
+               printk(KERN_ERR "quickstart: Notify handler install error\n");
+               ret = -ENODEV;
+               goto fail_installnotify;
+       }
+
+       quickstart_acpi_ghid(quickstart);
+
+       return 0;
+
+fail_installnotify:
+       quickstart_btnlst_del(quickstart->btn);
+
+fail_config:
+
+       kfree(quickstart);
+
+       return ret;
+}
+
+static int quickstart_acpi_remove(struct acpi_device *device, int type)
+{
+       acpi_status status = 0;
+       struct quickstart_acpi *quickstart = NULL;
+
+       if (!device || !acpi_driver_data(device))
+               return -EINVAL;
+
+       quickstart = acpi_driver_data(device);
+
+       status = acpi_remove_notify_handler(device->handle,
+                                                ACPI_ALL_NOTIFY,
+                                           quickstart_acpi_notify);
+       if (ACPI_FAILURE(status))
+               printk(KERN_ERR "quickstart: Error removing notify handler\n");
+
+
+       kfree(quickstart);
+
+       return 0;
+}
+
+/* Module functions */
+
+static void quickstart_exit(void)
+{
+       input_unregister_device(quickstart_input);
+       input_free_device(quickstart_input);
+
+       device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
+       device_remove_file(&pf_device->dev, &dev_attr_buttons);
+
+       platform_device_unregister(pf_device);
+
+       platform_driver_unregister(&pf_driver);
+
+       acpi_bus_unregister_driver(&quickstart_acpi_driver);
+
+       quickstart_btnlst_free();
+
+       return;
+}
+
+static int __init quickstart_init_input(void)
+{
+       struct quickstart_btn **ptr = &quickstart_data.btn_lst;
+       int count;
+
+       quickstart_input = input_allocate_device();
+
+       if (!quickstart_input)
+               return -ENOMEM;
+
+       quickstart_input->name = "Quickstart ACPI Buttons";
+       quickstart_input->id.bustype = BUS_HOST;
+
+       while (*ptr) {
+               count++;
+               set_bit(EV_KEY, quickstart_input->evbit);
+               set_bit((*ptr)->id, quickstart_input->keybit);
+               ptr = &((*ptr)->next);
+       }
+
+       return input_register_device(quickstart_input);
+}
+
+static int __init quickstart_init(void)
+{
+       int ret;
+       acpi_status status = 0;
+
+       /* ACPI Check */
+       if (acpi_disabled)
+               return -ENODEV;
+
+       /* ACPI driver register */
+       status = acpi_bus_register_driver(&quickstart_acpi_driver);
+       if (status < 0)
+               return -ENODEV;
+
+       /* If existing bus with no devices */
+       if (!quickstart_data.btn_lst) {
+               ret = -ENODEV;
+               goto fail_pfdrv_reg;
+       }
+
+       /* Platform driver register */
+       ret = platform_driver_register(&pf_driver);
+       if (ret)
+               goto fail_pfdrv_reg;
+
+       /* Platform device register */
+       pf_device = platform_device_alloc(QUICKSTART_PF_DEVICE_NAME, -1);
+       if (!pf_device) {
+               ret = -ENOMEM;
+               goto fail_pfdev_alloc;
+       }
+       ret = platform_device_add(pf_device);
+       if (ret)
+               goto fail_pfdev_add;
+
+       /* Create device sysfs file */
+       ret = device_create_file(&pf_device->dev, &dev_attr_pressed_button);
+       if (ret)
+               goto fail_dev_file;
+
+       ret = device_create_file(&pf_device->dev, &dev_attr_buttons);
+       if (ret)
+               goto fail_dev_file2;
+
+
+       /* Input device */
+       ret = quickstart_init_input();
+       if (ret)
+               goto fail_input;
+
+       printk(KERN_INFO "quickstart: ACPI Direct App Launch ver %s\n",
+                                               QUICKSTART_VERSION);
+
+       return 0;
+fail_input:
+       device_remove_file(&pf_device->dev, &dev_attr_buttons);
+
+fail_dev_file2:
+       device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
+
+fail_dev_file:
+       platform_device_del(pf_device);
+
+fail_pfdev_add:
+       platform_device_put(pf_device);
+
+fail_pfdev_alloc:
+       platform_driver_unregister(&pf_driver);
+
+fail_pfdrv_reg:
+       acpi_bus_unregister_driver(&quickstart_acpi_driver);
+
+       return ret;
+}
+
+module_init(quickstart_init);
+module_exit(quickstart_exit);
diff --git a/drivers/staging/ramzswap/Kconfig b/drivers/staging/ramzswap/Kconfig
deleted file mode 100644 (file)
index 127b3c6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-config RAMZSWAP
-       tristate "Compressed in-memory swap device (ramzswap)"
-       depends on SWAP
-       select LZO_COMPRESS
-       select LZO_DECOMPRESS
-       default n
-       help
-         Creates virtual block devices which can (only) be used as swap
-         disks. Pages swapped to these disks are compressed and stored in
-         memory itself.
-
-         See ramzswap.txt for more information.
-         Project home: http://compcache.googlecode.com/
-
-config RAMZSWAP_STATS
-       bool "Enable ramzswap stats"
-       depends on RAMZSWAP
-       default y
-       help
-         Enable statistics collection for ramzswap. This adds only a minimal
-         overhead. In unsure, say Y.
diff --git a/drivers/staging/ramzswap/Makefile b/drivers/staging/ramzswap/Makefile
deleted file mode 100644 (file)
index 507d7dc..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-ramzswap-objs  :=      ramzswap_drv.o xvmalloc.o
-
-obj-$(CONFIG_RAMZSWAP) +=      ramzswap.o
diff --git a/drivers/staging/ramzswap/ramzswap.txt b/drivers/staging/ramzswap/ramzswap.txt
deleted file mode 100644 (file)
index 9694acf..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-ramzswap: Compressed RAM based swap device
--------------------------------------------
-
-Project home: http://compcache.googlecode.com/
-
-* Introduction
-
-The ramzswap module creates RAM based block devices which can (only) be used as
-swap disks. Pages swapped to these devices are compressed and stored in memory
-itself. See project home for use cases, performance numbers and a lot more.
-
-Individual ramzswap devices are configured and initialized using rzscontrol
-userspace utility as shown in examples below. See rzscontrol man page for more
-details.
-
-* Usage
-
-Following shows a typical sequence of steps for using ramzswap.
-
-1) Load Modules:
-       modprobe ramzswap num_devices=4
-       This creates 4 (uninitialized) devices: /dev/ramzswap{0,1,2,3}
-       (num_devices parameter is optional. Default: 1)
-
-2) Initialize:
-       Use rzscontrol utility to configure and initialize individual
-       ramzswap devices. Example:
-       rzscontrol /dev/ramzswap2 --init # uses default value of disksize_kb
-
-       *See rzscontrol man page for more details and examples*
-
-3) Activate:
-       swapon /dev/ramzswap2 # or any other initialized ramzswap device
-
-4) Stats:
-       rzscontrol /dev/ramzswap2 --stats
-
-5) Deactivate:
-       swapoff /dev/ramzswap2
-
-6) Reset:
-       rzscontrol /dev/ramzswap2 --reset
-       (This frees all the memory allocated for this device).
-
-
-Please report any problems at:
- - Mailing list: linux-mm-cc at laptop dot org
- - Issue tracker: http://code.google.com/p/compcache/issues/list
-
-Nitin Gupta
-ngupta@vflare.org
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
deleted file mode 100644 (file)
index d14bf91..0000000
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * Compressed RAM based swap device
- *
- * Copyright (C) 2008, 2009, 2010  Nitin Gupta
- *
- * This code is released using a dual license strategy: BSD/GPL
- * You can choose the licence that better fits your requirements.
- *
- * Released under the terms of 3-clause BSD License
- * Released under the terms of GNU General Public License Version 2.0
- *
- * Project home: http://compcache.googlecode.com
- */
-
-#define KMSG_COMPONENT "ramzswap"
-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitops.h>
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
-#include <linux/device.h>
-#include <linux/genhd.h>
-#include <linux/highmem.h>
-#include <linux/slab.h>
-#include <linux/lzo.h>
-#include <linux/string.h>
-#include <linux/swap.h>
-#include <linux/swapops.h>
-#include <linux/vmalloc.h>
-
-#include "ramzswap_drv.h"
-
-/* Globals */
-static int ramzswap_major;
-static struct ramzswap *devices;
-
-/* Module params (documentation at end) */
-static unsigned int num_devices;
-
-static int rzs_test_flag(struct ramzswap *rzs, u32 index,
-                       enum rzs_pageflags flag)
-{
-       return rzs->table[index].flags & BIT(flag);
-}
-
-static void rzs_set_flag(struct ramzswap *rzs, u32 index,
-                       enum rzs_pageflags flag)
-{
-       rzs->table[index].flags |= BIT(flag);
-}
-
-static void rzs_clear_flag(struct ramzswap *rzs, u32 index,
-                       enum rzs_pageflags flag)
-{
-       rzs->table[index].flags &= ~BIT(flag);
-}
-
-static int page_zero_filled(void *ptr)
-{
-       unsigned int pos;
-       unsigned long *page;
-
-       page = (unsigned long *)ptr;
-
-       for (pos = 0; pos != PAGE_SIZE / sizeof(*page); pos++) {
-               if (page[pos])
-                       return 0;
-       }
-
-       return 1;
-}
-
-static void ramzswap_set_disksize(struct ramzswap *rzs, size_t totalram_bytes)
-{
-       if (!rzs->disksize) {
-               pr_info(
-               "disk size not provided. You can use disksize_kb module "
-               "param to specify size.\nUsing default: (%u%% of RAM).\n",
-               default_disksize_perc_ram
-               );
-               rzs->disksize = default_disksize_perc_ram *
-                                       (totalram_bytes / 100);
-       }
-
-       if (rzs->disksize > 2 * (totalram_bytes)) {
-               pr_info(
-               "There is little point creating a ramzswap of greater than "
-               "twice the size of memory since we expect a 2:1 compression "
-               "ratio. Note that ramzswap uses about 0.1%% of the size of "
-               "the swap device when not in use so a huge ramzswap is "
-               "wasteful.\n"
-               "\tMemory Size: %zu kB\n"
-               "\tSize you selected: %zu kB\n"
-               "Continuing anyway ...\n",
-               totalram_bytes >> 10, rzs->disksize
-               );
-       }
-
-       rzs->disksize &= PAGE_MASK;
-}
-
-/*
- * Swap header (1st page of swap device) contains information
- * about a swap file/partition. Prepare such a header for the
- * given ramzswap device so that swapon can identify it as a
- * swap partition.
- */
-static void setup_swap_header(struct ramzswap *rzs, union swap_header *s)
-{
-       s->info.version = 1;
-       s->info.last_page = (rzs->disksize >> PAGE_SHIFT) - 1;
-       s->info.nr_badpages = 0;
-       memcpy(s->magic.magic, "SWAPSPACE2", 10);
-}
-
-static void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
-                       struct ramzswap_ioctl_stats *s)
-{
-       s->disksize = rzs->disksize;
-
-#if defined(CONFIG_RAMZSWAP_STATS)
-       {
-       struct ramzswap_stats *rs = &rzs->stats;
-       size_t succ_writes, mem_used;
-       unsigned int good_compress_perc = 0, no_compress_perc = 0;
-
-       mem_used = xv_get_total_size_bytes(rzs->mem_pool)
-                       + (rs->pages_expand << PAGE_SHIFT);
-       succ_writes = rzs_stat64_read(rzs, &rs->num_writes) -
-                       rzs_stat64_read(rzs, &rs->failed_writes);
-
-       if (succ_writes && rs->pages_stored) {
-               good_compress_perc = rs->good_compress * 100
-                                       / rs->pages_stored;
-               no_compress_perc = rs->pages_expand * 100
-                                       / rs->pages_stored;
-       }
-
-       s->num_reads = rzs_stat64_read(rzs, &rs->num_reads);
-       s->num_writes = rzs_stat64_read(rzs, &rs->num_writes);
-       s->failed_reads = rzs_stat64_read(rzs, &rs->failed_reads);
-       s->failed_writes = rzs_stat64_read(rzs, &rs->failed_writes);
-       s->invalid_io = rzs_stat64_read(rzs, &rs->invalid_io);
-       s->notify_free = rzs_stat64_read(rzs, &rs->notify_free);
-       s->pages_zero = rs->pages_zero;
-
-       s->good_compress_pct = good_compress_perc;
-       s->pages_expand_pct = no_compress_perc;
-
-       s->pages_stored = rs->pages_stored;
-       s->pages_used = mem_used >> PAGE_SHIFT;
-       s->orig_data_size = rs->pages_stored << PAGE_SHIFT;
-       s->compr_data_size = rs->compr_size;
-       s->mem_used_total = mem_used;
-       }
-#endif /* CONFIG_RAMZSWAP_STATS */
-}
-
-static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
-{
-       u32 clen;
-       void *obj;
-
-       struct page *page = rzs->table[index].page;
-       u32 offset = rzs->table[index].offset;
-
-       if (unlikely(!page)) {
-               /*
-                * No memory is allocated for zero filled pages.
-                * Simply clear zero page flag.
-                */
-               if (rzs_test_flag(rzs, index, RZS_ZERO)) {
-                       rzs_clear_flag(rzs, index, RZS_ZERO);
-                       rzs_stat_dec(&rzs->stats.pages_zero);
-               }
-               return;
-       }
-
-       if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED))) {
-               clen = PAGE_SIZE;
-               __free_page(page);
-               rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED);
-               rzs_stat_dec(&rzs->stats.pages_expand);
-               goto out;
-       }
-
-       obj = kmap_atomic(page, KM_USER0) + offset;
-       clen = xv_get_object_size(obj) - sizeof(struct zobj_header);
-       kunmap_atomic(obj, KM_USER0);
-
-       xv_free(rzs->mem_pool, page, offset);
-       if (clen <= PAGE_SIZE / 2)
-               rzs_stat_dec(&rzs->stats.good_compress);
-
-out:
-       rzs->stats.compr_size -= clen;
-       rzs_stat_dec(&rzs->stats.pages_stored);
-
-       rzs->table[index].page = NULL;
-       rzs->table[index].offset = 0;
-}
-
-static int handle_zero_page(struct bio *bio)
-{
-       void *user_mem;
-       struct page *page = bio->bi_io_vec[0].bv_page;
-
-       user_mem = kmap_atomic(page, KM_USER0);
-       memset(user_mem, 0, PAGE_SIZE);
-       kunmap_atomic(user_mem, KM_USER0);
-
-       flush_dcache_page(page);
-
-       set_bit(BIO_UPTODATE, &bio->bi_flags);
-       bio_endio(bio, 0);
-       return 0;
-}
-
-static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio)
-{
-       u32 index;
-       struct page *page;
-       unsigned char *user_mem, *cmem;
-
-       page = bio->bi_io_vec[0].bv_page;
-       index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
-
-       user_mem = kmap_atomic(page, KM_USER0);
-       cmem = kmap_atomic(rzs->table[index].page, KM_USER1) +
-                       rzs->table[index].offset;
-
-       memcpy(user_mem, cmem, PAGE_SIZE);
-       kunmap_atomic(user_mem, KM_USER0);
-       kunmap_atomic(cmem, KM_USER1);
-
-       flush_dcache_page(page);
-
-       set_bit(BIO_UPTODATE, &bio->bi_flags);
-       bio_endio(bio, 0);
-       return 0;
-}
-
-/*
- * Called when request page is not present in ramzswap.
- * This is an attempt to read before any previous write
- * to this location - this happens due to readahead when
- * swap device is read from user-space (e.g. during swapon)
- */
-static int handle_ramzswap_fault(struct ramzswap *rzs, struct bio *bio)
-{
-       pr_debug("Read before write on swap device: "
-               "sector=%lu, size=%u, offset=%u\n",
-               (ulong)(bio->bi_sector), bio->bi_size,
-               bio->bi_io_vec[0].bv_offset);
-
-       /* Do nothing. Just return success */
-       set_bit(BIO_UPTODATE, &bio->bi_flags);
-       bio_endio(bio, 0);
-       return 0;
-}
-
-static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
-{
-       int ret;
-       u32 index;
-       size_t clen;
-       struct page *page;
-       struct zobj_header *zheader;
-       unsigned char *user_mem, *cmem;
-
-       rzs_stat64_inc(rzs, &rzs->stats.num_reads);
-
-       page = bio->bi_io_vec[0].bv_page;
-       index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
-
-       if (rzs_test_flag(rzs, index, RZS_ZERO))
-               return handle_zero_page(bio);
-
-       /* Requested page is not present in compressed area */
-       if (!rzs->table[index].page)
-               return handle_ramzswap_fault(rzs, bio);
-
-       /* Page is stored uncompressed since it's incompressible */
-       if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
-               return handle_uncompressed_page(rzs, bio);
-
-       user_mem = kmap_atomic(page, KM_USER0);
-       clen = PAGE_SIZE;
-
-       cmem = kmap_atomic(rzs->table[index].page, KM_USER1) +
-                       rzs->table[index].offset;
-
-       ret = lzo1x_decompress_safe(
-               cmem + sizeof(*zheader),
-               xv_get_object_size(cmem) - sizeof(*zheader),
-               user_mem, &clen);
-
-       kunmap_atomic(user_mem, KM_USER0);
-       kunmap_atomic(cmem, KM_USER1);
-
-       /* should NEVER happen */
-       if (unlikely(ret != LZO_E_OK)) {
-               pr_err("Decompression failed! err=%d, page=%u\n",
-                       ret, index);
-               rzs_stat64_inc(rzs, &rzs->stats.failed_reads);
-               goto out;
-       }
-
-       flush_dcache_page(page);
-
-       set_bit(BIO_UPTODATE, &bio->bi_flags);
-       bio_endio(bio, 0);
-       return 0;
-
-out:
-       bio_io_error(bio);
-       return 0;
-}
-
-static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
-{
-       int ret;
-       u32 offset, index;
-       size_t clen;
-       struct zobj_header *zheader;
-       struct page *page, *page_store;
-       unsigned char *user_mem, *cmem, *src;
-
-       rzs_stat64_inc(rzs, &rzs->stats.num_writes);
-
-       page = bio->bi_io_vec[0].bv_page;
-       index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
-
-       src = rzs->compress_buffer;
-
-       mutex_lock(&rzs->lock);
-
-       user_mem = kmap_atomic(page, KM_USER0);
-       if (page_zero_filled(user_mem)) {
-               kunmap_atomic(user_mem, KM_USER0);
-               mutex_unlock(&rzs->lock);
-               rzs_stat_inc(&rzs->stats.pages_zero);
-               rzs_set_flag(rzs, index, RZS_ZERO);
-
-               set_bit(BIO_UPTODATE, &bio->bi_flags);
-               bio_endio(bio, 0);
-               return 0;
-       }
-
-       ret = lzo1x_1_compress(user_mem, PAGE_SIZE, src, &clen,
-                               rzs->compress_workmem);
-
-       kunmap_atomic(user_mem, KM_USER0);
-
-       if (unlikely(ret != LZO_E_OK)) {
-               mutex_unlock(&rzs->lock);
-               pr_err("Compression failed! err=%d\n", ret);
-               rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
-               goto out;
-       }
-
-       /*
-        * Page is incompressible. Store it as-is (uncompressed)
-        * since we do not want to return too many swap write
-        * errors which has side effect of hanging the system.
-        */
-       if (unlikely(clen > max_zpage_size)) {
-               clen = PAGE_SIZE;
-               page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
-               if (unlikely(!page_store)) {
-                       mutex_unlock(&rzs->lock);
-                       pr_info("Error allocating memory for incompressible "
-                               "page: %u\n", index);
-                       rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
-                       goto out;
-               }
-
-               offset = 0;
-               rzs_set_flag(rzs, index, RZS_UNCOMPRESSED);
-               rzs_stat_inc(&rzs->stats.pages_expand);
-               rzs->table[index].page = page_store;
-               src = kmap_atomic(page, KM_USER0);
-               goto memstore;
-       }
-
-       if (xv_malloc(rzs->mem_pool, clen + sizeof(*zheader),
-                       &rzs->table[index].page, &offset,
-                       GFP_NOIO | __GFP_HIGHMEM)) {
-               mutex_unlock(&rzs->lock);
-               pr_info("Error allocating memory for compressed "
-                       "page: %u, size=%zu\n", index, clen);
-               rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
-               goto out;
-       }
-
-memstore:
-       rzs->table[index].offset = offset;
-
-       cmem = kmap_atomic(rzs->table[index].page, KM_USER1) +
-                       rzs->table[index].offset;
-
-#if 0
-       /* Back-reference needed for memory defragmentation */
-       if (!rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)) {
-               zheader = (struct zobj_header *)cmem;
-               zheader->table_idx = index;
-               cmem += sizeof(*zheader);
-       }
-#endif
-
-       memcpy(cmem, src, clen);
-
-       kunmap_atomic(cmem, KM_USER1);
-       if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
-               kunmap_atomic(src, KM_USER0);
-
-       /* Update stats */
-       rzs->stats.compr_size += clen;
-       rzs_stat_inc(&rzs->stats.pages_stored);
-       if (clen <= PAGE_SIZE / 2)
-               rzs_stat_inc(&rzs->stats.good_compress);
-
-       mutex_unlock(&rzs->lock);
-
-       set_bit(BIO_UPTODATE, &bio->bi_flags);
-       bio_endio(bio, 0);
-       return 0;
-
-out:
-       bio_io_error(bio);
-       return 0;
-}
-
-/*
- * Check if request is within bounds and page aligned.
- */
-static inline int valid_swap_request(struct ramzswap *rzs, struct bio *bio)
-{
-       if (unlikely(
-               (bio->bi_sector >= (rzs->disksize >> SECTOR_SHIFT)) ||
-               (bio->bi_sector & (SECTORS_PER_PAGE - 1)) ||
-               (bio->bi_vcnt != 1) ||
-               (bio->bi_size != PAGE_SIZE) ||
-               (bio->bi_io_vec[0].bv_offset != 0))) {
-
-               return 0;
-       }
-
-       /* swap request is valid */
-       return 1;
-}
-
-/*
- * Handler function for all ramzswap I/O requests.
- */
-static int ramzswap_make_request(struct request_queue *queue, struct bio *bio)
-{
-       int ret = 0;
-       struct ramzswap *rzs = queue->queuedata;
-
-       if (unlikely(!rzs->init_done)) {
-               bio_io_error(bio);
-               return 0;
-       }
-
-       if (!valid_swap_request(rzs, bio)) {
-               rzs_stat64_inc(rzs, &rzs->stats.invalid_io);
-               bio_io_error(bio);
-               return 0;
-       }
-
-       switch (bio_data_dir(bio)) {
-       case READ:
-               ret = ramzswap_read(rzs, bio);
-               break;
-
-       case WRITE:
-               ret = ramzswap_write(rzs, bio);
-               break;
-       }
-
-       return ret;
-}
-
-static void reset_device(struct ramzswap *rzs)
-{
-       size_t index;
-
-       /* Do not accept any new I/O request */
-       rzs->init_done = 0;
-
-       /* Free various per-device buffers */
-       kfree(rzs->compress_workmem);
-       free_pages((unsigned long)rzs->compress_buffer, 1);
-
-       rzs->compress_workmem = NULL;
-       rzs->compress_buffer = NULL;
-
-       /* Free all pages that are still in this ramzswap device */
-       for (index = 0; index < rzs->disksize >> PAGE_SHIFT; index++) {
-               struct page *page;
-               u16 offset;
-
-               page = rzs->table[index].page;
-               offset = rzs->table[index].offset;
-
-               if (!page)
-                       continue;
-
-               if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
-                       __free_page(page);
-               else
-                       xv_free(rzs->mem_pool, page, offset);
-       }
-
-       vfree(rzs->table);
-       rzs->table = NULL;
-
-       xv_destroy_pool(rzs->mem_pool);
-       rzs->mem_pool = NULL;
-
-       /* Reset stats */
-       memset(&rzs->stats, 0, sizeof(rzs->stats));
-
-       rzs->disksize = 0;
-}
-
-static int ramzswap_ioctl_init_device(struct ramzswap *rzs)
-{
-       int ret;
-       size_t num_pages;
-       struct page *page;
-       union swap_header *swap_header;
-
-       if (rzs->init_done) {
-               pr_info("Device already initialized!\n");
-               return -EBUSY;
-       }
-
-       ramzswap_set_disksize(rzs, totalram_pages << PAGE_SHIFT);
-
-       rzs->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
-       if (!rzs->compress_workmem) {
-               pr_err("Error allocating compressor working memory!\n");
-               ret = -ENOMEM;
-               goto fail;
-       }
-
-       rzs->compress_buffer = (void *)__get_free_pages(__GFP_ZERO, 1);
-       if (!rzs->compress_buffer) {
-               pr_err("Error allocating compressor buffer space\n");
-               ret = -ENOMEM;
-               goto fail;
-       }
-
-       num_pages = rzs->disksize >> PAGE_SHIFT;
-       rzs->table = vmalloc(num_pages * sizeof(*rzs->table));
-       if (!rzs->table) {
-               pr_err("Error allocating ramzswap address table\n");
-               /* To prevent accessing table entries during cleanup */
-               rzs->disksize = 0;
-               ret = -ENOMEM;
-               goto fail;
-       }
-       memset(rzs->table, 0, num_pages * sizeof(*rzs->table));
-
-       page = alloc_page(__GFP_ZERO);
-       if (!page) {
-               pr_err("Error allocating swap header page\n");
-               ret = -ENOMEM;
-               goto fail;
-       }
-       rzs->table[0].page = page;
-       rzs_set_flag(rzs, 0, RZS_UNCOMPRESSED);
-
-       swap_header = kmap(page);
-       setup_swap_header(rzs, swap_header);
-       kunmap(page);
-
-       set_capacity(rzs->disk, rzs->disksize >> SECTOR_SHIFT);
-
-       /* ramzswap devices sort of resembles non-rotational disks */
-       queue_flag_set_unlocked(QUEUE_FLAG_NONROT, rzs->disk->queue);
-
-       rzs->mem_pool = xv_create_pool();
-       if (!rzs->mem_pool) {
-               pr_err("Error creating memory pool\n");
-               ret = -ENOMEM;
-               goto fail;
-       }
-
-       rzs->init_done = 1;
-
-       pr_debug("Initialization done!\n");
-       return 0;
-
-fail:
-       reset_device(rzs);
-
-       pr_err("Initialization failed: err=%d\n", ret);
-       return ret;
-}
-
-static int ramzswap_ioctl_reset_device(struct ramzswap *rzs)
-{
-       if (rzs->init_done)
-               reset_device(rzs);
-
-       return 0;
-}
-
-static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode,
-                       unsigned int cmd, unsigned long arg)
-{
-       int ret = 0;
-       size_t disksize_kb;
-
-       struct ramzswap *rzs = bdev->bd_disk->private_data;
-
-       switch (cmd) {
-       case RZSIO_SET_DISKSIZE_KB:
-               if (rzs->init_done) {
-                       ret = -EBUSY;
-                       goto out;
-               }
-               if (copy_from_user(&disksize_kb, (void *)arg,
-                                               _IOC_SIZE(cmd))) {
-                       ret = -EFAULT;
-                       goto out;
-               }
-               rzs->disksize = disksize_kb << 10;
-               pr_info("Disk size set to %zu kB\n", disksize_kb);
-               break;
-
-       case RZSIO_GET_STATS:
-       {
-               struct ramzswap_ioctl_stats *stats;
-               if (!rzs->init_done) {
-                       ret = -ENOTTY;
-                       goto out;
-               }
-               stats = kzalloc(sizeof(*stats), GFP_KERNEL);
-               if (!stats) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               ramzswap_ioctl_get_stats(rzs, stats);
-               if (copy_to_user((void *)arg, stats, sizeof(*stats))) {
-                       kfree(stats);
-                       ret = -EFAULT;
-                       goto out;
-               }
-               kfree(stats);
-               break;
-       }
-       case RZSIO_INIT:
-               ret = ramzswap_ioctl_init_device(rzs);
-               break;
-
-       case RZSIO_RESET:
-               /* Do not reset an active device! */
-               if (bdev->bd_holders) {
-                       ret = -EBUSY;
-                       goto out;
-               }
-
-               /* Make sure all pending I/O is finished */
-               if (bdev)
-                       fsync_bdev(bdev);
-
-               ret = ramzswap_ioctl_reset_device(rzs);
-               break;
-
-       default:
-               pr_info("Invalid ioctl %u\n", cmd);
-               ret = -ENOTTY;
-       }
-
-out:
-       return ret;
-}
-
-void ramzswap_slot_free_notify(struct block_device *bdev, unsigned long index)
-{
-       struct ramzswap *rzs;
-
-       rzs = bdev->bd_disk->private_data;
-       ramzswap_free_page(rzs, index);
-       rzs_stat64_inc(rzs, &rzs->stats.notify_free);
-
-       return;
-}
-
-static struct block_device_operations ramzswap_devops = {
-       .ioctl = ramzswap_ioctl,
-       .swap_slot_free_notify = ramzswap_slot_free_notify,
-       .owner = THIS_MODULE
-};
-
-static int create_device(struct ramzswap *rzs, int device_id)
-{
-       int ret = 0;
-
-       mutex_init(&rzs->lock);
-       spin_lock_init(&rzs->stat64_lock);
-
-       rzs->queue = blk_alloc_queue(GFP_KERNEL);
-       if (!rzs->queue) {
-               pr_err("Error allocating disk queue for device %d\n",
-                       device_id);
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       blk_queue_make_request(rzs->queue, ramzswap_make_request);
-       rzs->queue->queuedata = rzs;
-
-        /* gendisk structure */
-       rzs->disk = alloc_disk(1);
-       if (!rzs->disk) {
-               blk_cleanup_queue(rzs->queue);
-               pr_warning("Error allocating disk structure for device %d\n",
-                       device_id);
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       rzs->disk->major = ramzswap_major;
-       rzs->disk->first_minor = device_id;
-       rzs->disk->fops = &ramzswap_devops;
-       rzs->disk->queue = rzs->queue;
-       rzs->disk->private_data = rzs;
-       snprintf(rzs->disk->disk_name, 16, "ramzswap%d", device_id);
-
-       /* Actual capacity set using RZSIO_SET_DISKSIZE_KB ioctl */
-       set_capacity(rzs->disk, 0);
-
-       blk_queue_physical_block_size(rzs->disk->queue, PAGE_SIZE);
-       blk_queue_logical_block_size(rzs->disk->queue, PAGE_SIZE);
-
-       add_disk(rzs->disk);
-
-       rzs->init_done = 0;
-
-out:
-       return ret;
-}
-
-static void destroy_device(struct ramzswap *rzs)
-{
-       if (rzs->disk) {
-               del_gendisk(rzs->disk);
-               put_disk(rzs->disk);
-       }
-
-       if (rzs->queue)
-               blk_cleanup_queue(rzs->queue);
-}
-
-static int __init ramzswap_init(void)
-{
-       int ret, dev_id;
-
-       if (num_devices > max_num_devices) {
-               pr_warning("Invalid value for num_devices: %u\n",
-                               num_devices);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ramzswap_major = register_blkdev(0, "ramzswap");
-       if (ramzswap_major <= 0) {
-               pr_warning("Unable to get major number\n");
-               ret = -EBUSY;
-               goto out;
-       }
-
-       if (!num_devices) {
-               pr_info("num_devices not specified. Using default: 1\n");
-               num_devices = 1;
-       }
-
-       /* Allocate the device array and initialize each one */
-       pr_info("Creating %u devices ...\n", num_devices);
-       devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL);
-       if (!devices) {
-               ret = -ENOMEM;
-               goto unregister;
-       }
-
-       for (dev_id = 0; dev_id < num_devices; dev_id++) {
-               ret = create_device(&devices[dev_id], dev_id);
-               if (ret)
-                       goto free_devices;
-       }
-
-       return 0;
-
-free_devices:
-       while (dev_id)
-               destroy_device(&devices[--dev_id]);
-unregister:
-       unregister_blkdev(ramzswap_major, "ramzswap");
-out:
-       return ret;
-}
-
-static void __exit ramzswap_exit(void)
-{
-       int i;
-       struct ramzswap *rzs;
-
-       for (i = 0; i < num_devices; i++) {
-               rzs = &devices[i];
-
-               destroy_device(rzs);
-               if (rzs->init_done)
-                       reset_device(rzs);
-       }
-
-       unregister_blkdev(ramzswap_major, "ramzswap");
-
-       kfree(devices);
-       pr_debug("Cleanup done!\n");
-}
-
-module_param(num_devices, uint, 0);
-MODULE_PARM_DESC(num_devices, "Number of ramzswap devices");
-
-module_init(ramzswap_init);
-module_exit(ramzswap_exit);
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>");
-MODULE_DESCRIPTION("Compressed RAM Based Swap Device");
index 3f744a52aac79a404abc5925b6007224d49c982d..faac85d931d11548d68cc5bb6f4fbb690e06c897 100644 (file)
@@ -42,7 +42,8 @@
 
 /* ap_wpa.c */
 void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
-                        struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[]);
+                        struct rt_state_machine *Sm,
+                        OUT STATE_MACHINE_FUNC Trans[]);
 
 #ifdef RTMP_MAC_USB
 void BeaconUpdateExec(void *SystemSpecific1,
@@ -61,6 +62,7 @@ struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
 BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
                            u16 wcid, u8 *pAddr);
 
-struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr);
+struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd,
+                                                               u8 *pAddr);
 
 #endif /* __AP_H__ */
index ada65e5ac610934bce514a53b55e2d3df4f163e7..1231e69d518b8b5bf184214c6e2eabf6c219da66 100644 (file)
@@ -73,35 +73,31 @@ struct rt_ch_freq_map {
 extern struct rt_ch_freq_map CH_HZ_ID_MAP[];
 extern int CH_HZ_ID_MAP_NUM;
 
-#define     MAP_CHANNEL_ID_TO_KHZ(_ch, _khz)                                   \
-               do{                                                                                                     \
-                       int _chIdx;                                                                                     \
-                       for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
-                       {                                                                                                       \
-                               if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel)                      \
-                               {                                                                                               \
-                                       (_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;   \
-                                       break;                                                                          \
-                               }                                                                                               \
-                       }                                                                                                       \
-                       if (_chIdx == CH_HZ_ID_MAP_NUM)                                 \
-                               (_khz) = 2412000;                                                                       \
-            }while(0)
+#define     MAP_CHANNEL_ID_TO_KHZ(_ch, _khz)           \
+               do {                                                    \
+                       int _chIdx;                                     \
+                       for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++) {\
+                               if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel) { \
+                                       (_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;\
+                                       break;                          \
+                               }                                       \
+                       }                                               \
+                       if (_chIdx == CH_HZ_ID_MAP_NUM) \
+                               (_khz) = 2412000;               \
+               } while (0)
 
 #define     MAP_KHZ_TO_CHANNEL_ID(_khz, _ch)                 \
-               do{                                                                                                     \
-                       int _chIdx;                                                                                     \
-                       for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
-                       {                                                                                                       \
-                               if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz)                     \
-                               {                                                                                               \
-                                       (_ch) = CH_HZ_ID_MAP[_chIdx].channel;                   \
-                                       break;                                                                          \
-                               }                                                                                               \
-                       }                                                                                                       \
-                       if (_chIdx == CH_HZ_ID_MAP_NUM)                                 \
-                               (_ch) = 1;                                                                                      \
-               }while(0)
+               do {                                                    \
+                       int _chIdx;                             \
+                       for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++) {\
+                               if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz) {\
+                                       (_ch) = CH_HZ_ID_MAP[_chIdx].channel; \
+                                       break;                  \
+                               }                                       \
+                       }                                               \
+                       if (_chIdx == CH_HZ_ID_MAP_NUM)                 \
+                               (_ch) = 1;                              \
+               } while (0)
 
 void BuildChannelListEx(struct rt_rtmp_adapter *pAd);
 
index c16f3763cca66ec4e4b57966be08c4cced987152..9414aa344375e1a9c570b3fd8f71ff39cf9dfce6 100644 (file)
@@ -427,7 +427,7 @@ void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
 /*
     ==========================================================================
     Description:
-        This is a function to initilize 4-way handshake
+        This is a function to initialize 4-way handshake
 
     Return:
 
@@ -867,7 +867,7 @@ void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
     ==========================================================================
     Description:
         When receiving the last packet of 4-way pairwisekey handshake.
-        Initilize 2-way groupkey handshake following.
+        Initialize 2-way groupkey handshake following.
     Return:
     ==========================================================================
 */
index 42e47d9dc2c90416395357b38bd4312b9b5b47bd..ab520909490f7f0ba42b8b0c5c7cf20297c9df30 100644 (file)
@@ -143,8 +143,8 @@ int RtmpTimerQThread(IN void *Context)
        struct rt_rtmp_os_task *pTask;
        struct rt_rtmp_adapter *pAd;
 
-       pTask = (struct rt_rtmp_os_task *)Context;
-       pAd = (struct rt_rtmp_adapter *)pTask->priv;
+       pTask = Context;
+       pAd = pTask->priv;
 
        RtmpOSTaskCustomize(pTask);
 
index 99c9362bae864cb8c591c901c7cb4cde8ed3d43d..01414c3b488999751480e5cc9a574e046e052484 100644 (file)
@@ -31,7 +31,7 @@
 
        Revision History:
        Who                     When                    What
-       --------        ----------              ----------------------------------------------
+       --------        ----------              ------------------------------
        John Chang      2003-08-28              Created
        John Chang  2004-09-06      modified for RT2600
 
@@ -50,7 +50,7 @@
 #define MLME_TASK_EXEC_INTV         100/*200*/ /* */
 #define LEAD_TIME                   5
 #define MLME_TASK_EXEC_MULTIPLE       10  /*5*/        /* MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec */
-#define REORDER_EXEC_INTV              100     /* 0.1 sec */
+#define REORDER_EXEC_INTV              100     /* 0.1 sec */
 
 /* The definition of Radar detection duration region */
 #define CE             0
@@ -60,7 +60,7 @@
 #define JAP_W56        4
 #define MAX_RD_REGION 5
 
-#define BEACON_LOST_TIME            4 * OS_HZ  /* 2048 msec = 2 sec */
+#define BEACON_LOST_TIME            (4 * OS_HZ)        /* 2048 msec = 2 sec */
 
 #define DLS_TIMEOUT                 1200       /* unit: msec */
 #define AUTH_TIMEOUT                300        /* unit: msec */
 #define MAC_ADDR_IS_GROUP(Addr)       (((Addr[0]) & 0x01))
 #define MAC_ADDR_HASH(Addr)            (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
 #define MAC_ADDR_HASH_INDEX(Addr)      (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
-#define TID_MAC_HASH(Addr,TID)            (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
-#define TID_MAC_HASH_INDEX(Addr,TID)      (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
+#define TID_MAC_HASH(Addr, TID)            (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define TID_MAC_HASH_INDEX(Addr, TID)      (TID_MAC_HASH(Addr, TID) % HASH_TABLE_SIZE)
 
 /* LED Control */
 /* assoiation ON. one LED ON. another blinking when TX, OFF when idle */
 #define CAP_IS_DSSS_OFDM(x)              (((x) & 0x2000) != 0)
 #define CAP_IS_DELAY_BA(x)               (((x) & 0x4000) != 0) /* 802.11e d9 */
 
-#define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum)  (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
+#define CAP_GENERATE(ess, ibss, priv, s_pre, s_slot, spectrum)  (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
 
 #define ERP_IS_NON_ERP_PRESENT(x)        (((x) & 0x01) != 0)   /* 802.11g */
 #define ERP_IS_USE_PROTECTION(x)         (((x) & 0x02) != 0)   /* 802.11g */
 #define DRS_TX_QUALITY_WORST_BOUND       8     /* 3  // just test by gary */
 #define DRS_PENALTY                      8
 
-#define BA_NOTUSE      2
+#define BA_NOTUSE      2
 /*BA Policy subfiled value in ADDBA frame */
-#define IMMED_BA       1
+#define IMMED_BA       1
 #define DELAY_BA       0
 
 /* BA Initiator subfield in DELBA frame */
 
 /* reset all OneSecTx counters */
 #define RESET_ONE_SEC_TX_CNT(__pEntry) \
-if (((__pEntry)) != NULL) \
-{ \
+if (((__pEntry)) != NULL) { \
        (__pEntry)->OneSecTxRetryOkCount = 0; \
        (__pEntry)->OneSecTxFailCount = 0; \
        (__pEntry)->OneSecTxNoRetryOkCount = 0; \
@@ -846,7 +845,7 @@ struct rt_mlme_queue {
        struct rt_mlme_queue_elem Entry[MAX_LEN_OF_MLME_QUEUE];
 };
 
-typedef void(*STATE_MACHINE_FUNC) (void * Adaptor, struct rt_mlme_queue_elem *Elem);
+typedef void(*STATE_MACHINE_FUNC) (void *Adaptor, struct rt_mlme_queue_elem *Elem);
 
 struct rt_state_machine {
        unsigned long Base;
index 0029b2d73b706333f4a23fe96a5b303ae7aa21f6..6536965df3f30ed86a5238e976bd4542553eacad 100644 (file)
@@ -1015,7 +1015,7 @@ int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
        struct rt_rtmp_adapter *pAd;
        int ret = NDIS_STATUS_FAILURE;
 
-       pAd = (struct rt_rtmp_adapter *)pTask->priv;
+       pAd = pTask->priv;
 
 #ifdef KTHREAD_SUPPORT
        if (pTask->kthread_task) {
index 82b6e783b33fd4916f65cbe0a978850019a3ec5d..282935caba2c29a4f046c63791b2d2fa9bebd63c 100644 (file)
@@ -2511,7 +2511,7 @@ void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pTxWI, IN BOOLE
                   u8 TID,
                   u8 TxRate,
                   u8 Txopmode,
-                  IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit);
+                  IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING *pTransmit);
 
 void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd,
                        struct rt_txwi *pTxWI, struct rt_tx_blk *pTxBlk);
@@ -3059,7 +3059,7 @@ BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd,
                                    u16 *pBeaconPeriod,
                                    u8 *pChannel,
                                    u8 *pNewChannel,
-                                   OUT LARGE_INTEGER * pTimestamp,
+                                   OUT LARGE_INTEGER *pTimestamp,
                                    struct rt_cf_parm *pCfParm,
                                    u16 *pAtimWin,
                                    u16 *pCapabilityInfo,
index 674769d2b59b0e7c35b8fc9b58d02cca48a23fe2..a0fe31de0a6d1299c802062cff4007b971d6a594 100644 (file)
@@ -64,6 +64,7 @@ struct usb_device_id rtusb_usb_id[] = {
        {USB_DEVICE(0x14B2, 0x3C07)},   /* AL */
        {USB_DEVICE(0x050D, 0x8053)},   /* Belkin */
        {USB_DEVICE(0x050D, 0x825B)},   /* Belkin */
+       {USB_DEVICE(0x050D, 0x935B)},   /* Belkin F6D4050 v2 */
        {USB_DEVICE(0x14B2, 0x3C23)},   /* Airlink */
        {USB_DEVICE(0x14B2, 0x3C27)},   /* Airlink */
        {USB_DEVICE(0x07AA, 0x002F)},   /* Corega */
@@ -422,8 +423,8 @@ int MlmeThread(IN void *Context)
        int status;
        status = 0;
 
-       pTask = (struct rt_rtmp_os_task *)Context;
-       pAd = (struct rt_rtmp_adapter *)pTask->priv;
+       pTask = Context;
+       pAd = pTask->priv;
 
        RtmpOSTaskCustomize(pTask);
 
@@ -491,8 +492,8 @@ int RTUSBCmdThread(IN void *Context)
        int status;
        status = 0;
 
-       pTask = (struct rt_rtmp_os_task *)Context;
-       pAd = (struct rt_rtmp_adapter *)pTask->priv;
+       pTask = Context;
+       pAd = pTask->priv;
 
        RtmpOSTaskCustomize(pTask);
 
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
deleted file mode 100644 (file)
index b3fb637..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __MD4_H__
-#define __MD4_H__
-
-/* MD4 context. */
-typedef        struct  _MD4_CTX_       {
-       unsigned long   state[4];        /* state (ABCD) */
-       unsigned long   count[2];        /* number of bits, modulo 2^64 (lsb first) */
-       u8      buffer[64];      /* input buffer */
-}      MD4_CTX;
-
-void MD4Init(MD4_CTX *);
-void MD4Update(MD4_CTX *, u8 *, UINT);
-void MD4Final(u8 [16], MD4_CTX *);
-
-#endif /*__MD4_H__*/
index 155a78e07405dd1b6a5ff67981191d4a2c31849f..1b3103fbf29c4c8fce6b7ab6ee80090afc322de6 100644 (file)
@@ -4,6 +4,7 @@ config R8187SE
        select WIRELESS_EXT
        select WEXT_PRIV
        select EEPROM_93CX6
+       select CRYPTO
        default N
        ---help---
          If built as a module, it will be called r8187se.ko.
index 2ae3745f775f6f1fa8af6d2befcc66f0be3ecbc1..2e64b239e24197c26dd16ba9eb4bb1e44cb7a008 100644 (file)
@@ -3,5 +3,6 @@ config RTL8192E
        depends on PCI && WLAN
        select WIRELESS_EXT
        select WEXT_PRIV
+       select CRYPTO
        default N
        ---help---
index 908f6051d57cd59594aeab51c181a8a3edc07658..6bbf0919cdff75e49532956fd9f382c8b1711ebd 100644 (file)
@@ -218,22 +218,4 @@ int ToLegalChannel(
 
        return default_chn;
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(Dot11d_Init);
-//EXPORT_SYMBOL(Dot11d_Reset);
-//EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
-//EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
-//EXPORT_SYMBOL(DOT11D_ScanComplete);
-//EXPORT_SYMBOL(IsLegalChannel);
-//EXPORT_SYMBOL(ToLegalChannel);
-#else
-EXPORT_SYMBOL_NOVERS(Dot11d_Init);
-EXPORT_SYMBOL_NOVERS(Dot11d_Reset);
-EXPORT_SYMBOL_NOVERS(Dot11d_UpdateCountryIe);
-EXPORT_SYMBOL_NOVERS(DOT11D_GetMaxTxPwrInDbm);
-EXPORT_SYMBOL_NOVERS(DOT11D_ScanComplete);
-EXPORT_SYMBOL_NOVERS(IsLegalChannel);
-EXPORT_SYMBOL_NOVERS(ToLegalChannel);
-#endif
-
 #endif
index 50728f6e9c55032ca16043231c04dd3c97bb2d19..dda6719234c9ae582d696050f6f5a9be1c4bbd7d 100644 (file)
 #include <linux/kernel.h>   /* ARRAY_SIZE */
 #include <linux/version.h>
 #include <linux/module.h>
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 #include <linux/jiffies.h>
-#else
-#include <linux/jffs.h>
-#include <linux/tqueue.h>
-#endif
 #include <linux/timer.h>
 #include <linux/sched.h>
 #include <linux/semaphore.h>
 #include "rtl819x_BA.h"
 #include "rtl819x_TS.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-#ifndef bool
-typedef enum{false = 0, true} bool;
-#endif
-#endif
-
 #ifndef IW_MODE_MONITOR
 #define IW_MODE_MONITOR 6
 #endif
@@ -428,46 +417,9 @@ typedef struct ieee_param {
 #define IW_QUAL_NOISE_UPDATED  0x4
 #endif
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
-{
-       task->routine = func;
-       task->data      = data;
-       //task->next = NULL;
-       INIT_LIST_HEAD(&task->list);
-       task->sync = 0;
-}
-#endif
-
 // linux under 2.6.9 release may not support it, so modify it for common use
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
-//#define MSECS(t)     (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
-#define MSECS(t)       (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
-static inline unsigned long msleep_interruptible_rsl(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_INTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-         return timeout;
-}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
-static inline void msleep(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_UNINTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-}
-#endif
-#else
 #define MSECS(t) msecs_to_jiffies(t)
 #define msleep_interruptible_rsl  msleep_interruptible
-#endif
 
 #define IEEE80211_DATA_LEN             2304
 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
@@ -1747,21 +1699,6 @@ enum ieee80211_state {
 #define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
                                   IEEE80211_52GHZ_MIN_CHANNEL + 1)
 
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
-extern inline int is_multicast_ether_addr(const u8 *addr)
-{
-        return ((addr[0] != 0xff) && (0x01 & addr[0]));
-}
-#endif
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
-extern inline int is_broadcast_ether_addr(const u8 *addr)
-{
-       return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
-               (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
-}
-#endif
-
 typedef struct tx_pending_t{
        int frag;
        struct ieee80211_txb *txb;
@@ -1838,11 +1775,7 @@ typedef struct _RT_POWER_SAVE_CONTROL
        bool                            bIPSModeBackup;
        bool                            bSwRfProcessing;
        RT_RF_POWER_STATE       eInactivePowerState;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        struct work_struct      InactivePsWorkItem;
-#else
-       struct tq_struct        InactivePsWorkItem;
-#endif
        struct timer_list       InactivePsTimer;
 
        // Return point for join action
@@ -2329,36 +2262,16 @@ struct ieee80211_device {
 
        /* used if IEEE_SOFTMAC_BEACONS is set */
        struct timer_list beacon_timer;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
         struct work_struct associate_complete_wq;
         struct work_struct associate_procedure_wq;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
         struct delayed_work softmac_scan_wq;
         struct delayed_work associate_retry_wq;
         struct delayed_work start_ibss_wq;
         struct delayed_work hw_wakeup_wq;
        struct delayed_work hw_sleep_wq;
-#else
-        struct work_struct softmac_scan_wq;
-        struct work_struct associate_retry_wq;
-       struct work_struct start_ibss_wq;
-       struct work_struct hw_wakeup_wq;
-       struct work_struct hw_sleep_wq;
-#endif
+
         struct work_struct wx_sync_scan_wq;
         struct workqueue_struct *wq;
-#else
-       /* used for periodly scan */
-       struct timer_list scan_timer;
-
-       struct tq_struct associate_complete_wq;
-       struct tq_struct associate_retry_wq;
-       struct tq_struct start_ibss_wq;
-       struct tq_struct associate_procedure_wq;
-       struct tq_struct softmac_scan_wq;
-       struct tq_struct wx_sync_scan_wq;
-
-#endif
         // Qos related. Added by Annie, 2005-11-01.
         //STA_QOS  StaQos;
 
@@ -2557,11 +2470,7 @@ struct ieee80211_device {
 
 static inline void *ieee80211_priv(struct net_device *dev)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-#else
-       return ((struct ieee80211_device *)dev->priv)->priv;
-#endif
 }
 
 extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
@@ -2814,11 +2723,7 @@ extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_reques
                             union iwreq_data *wrqu, char *b);
 
 //extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-#else
- extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#endif
 
 
 extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
index d5aa9af3d9f4db2c499666bceade07ef3e381cd0..ae503791890454180e31ee93fe4675dc044144cd 100644 (file)
@@ -243,23 +243,3 @@ void ieee80211_crypto_deinit(void)
        kfree(hcrypt);
 }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
-//EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
-//EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
-
-//EXPORT_SYMBOL(ieee80211_register_crypto_ops);
-//EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
-//EXPORT_SYMBOL(ieee80211_get_crypto_ops);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries);
-EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler);
-EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit);
-
-EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops);
-EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops);
-EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops);
-#endif
-
-//module_init(ieee80211_crypto_init);
-//module_exit(ieee80211_crypto_deinit);
index a84df4b76489e96310e6143a658f60a8fed4bca9..ca7dd0dda82d6b2017c591a8d1631f466b14a741 100644 (file)
@@ -82,12 +82,4 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
 void ieee80211_crypt_deinit_handler(unsigned long);
 void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
                                    struct ieee80211_crypt_data **crypt);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
-#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
-#define crypto_alloc_tfm crypto_alloc_tfm_rsl
-#define crypto_free_tfm crypto_free_tfm_rsl
-#endif
-
 #endif
index 7165c4c75c7edd5fabee95efd20c58860164ac5b..a4e21cbcdf196deb07f073d461ba7bbc13ecc12e 100644 (file)
 
 #include "ieee80211.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
     #include <linux/scatterlist.h>
-#endif
-//#include <asm/scatterlist.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: CCMP");
@@ -75,21 +66,7 @@ struct ieee80211_ccmp_data {
 void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
                             const u8 pt[16], u8 ct[16])
 {
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       struct scatterlist src, dst;
-
-       src.page = virt_to_page(pt);
-       src.offset = offset_in_page(pt);
-       src.length = AES_BLOCK_LEN;
-
-       dst.page = virt_to_page(ct);
-       dst.offset = offset_in_page(ct);
-       dst.length = AES_BLOCK_LEN;
-
-       crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
-#else
        crypto_cipher_encrypt_one((void*)tfm, ct, pt);
-#endif
 }
 
 static void * ieee80211_ccmp_init(int key_idx)
@@ -101,14 +78,6 @@ static void * ieee80211_ccmp_init(int key_idx)
                goto fail;
        priv->key_idx = key_idx;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       priv->tfm = crypto_alloc_tfm("aes", 0);
-       if (priv->tfm == NULL) {
-               printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
-                      "crypto API aes\n");
-               goto fail;
-       }
-       #else
        priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(priv->tfm)) {
                printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
@@ -116,17 +85,12 @@ static void * ieee80211_ccmp_init(int key_idx)
                priv->tfm = NULL;
                goto fail;
        }
-       #endif
        return priv;
 
 fail:
        if (priv) {
                if (priv->tfm)
-                       #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-                       crypto_free_tfm(priv->tfm);
-                    #else
                        crypto_free_cipher((void*)priv->tfm);
-                     #endif
                kfree(priv);
        }
 
@@ -138,11 +102,7 @@ static void ieee80211_ccmp_deinit(void *priv)
 {
        struct ieee80211_ccmp_data *_priv = priv;
        if (_priv && _priv->tfm)
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-               crypto_free_tfm(_priv->tfm);
-#else
                crypto_free_cipher((void*)_priv->tfm);
-#endif
        kfree(priv);
 }
 
@@ -528,11 +488,3 @@ void ieee80211_crypto_ccmp_exit(void)
        ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
 }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_ccmp_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
-#endif
-
-//module_init(ieee80211_crypto_ccmp_init);
-//module_exit(ieee80211_crypto_ccmp_exit);
index 65f48896bfaa1c10387b3262bf5e9b3da296eb4a..14ca61087c011385d1860e4643d912de2546adfd 100644 (file)
 #include "ieee80211.h"
 
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
-//#include <asm/scatterlist.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
-        #include <linux/scatterlist.h>
-#endif
+#include <linux/scatterlist.h>
 
 #include <linux/crc32.h>
 
@@ -68,17 +59,10 @@ struct ieee80211_tkip_data {
        u32 dot11RSNAStatsTKIPLocalMICFailures;
 
        int key_idx;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
        struct crypto_blkcipher *rx_tfm_arc4;
        struct crypto_hash *rx_tfm_michael;
        struct crypto_blkcipher *tx_tfm_arc4;
        struct crypto_hash *tx_tfm_michael;
-#else
-       struct crypto_tfm *tx_tfm_arc4;
-       struct crypto_tfm *tx_tfm_michael;
-       struct crypto_tfm *rx_tfm_arc4;
-       struct crypto_tfm *rx_tfm_michael;
-#endif
        /* scratch buffers for virt_to_page() (crypto API) */
        u8 rx_hdr[16], tx_hdr[16];
 };
@@ -91,35 +75,6 @@ static void * ieee80211_tkip_init(int key_idx)
        if (priv == NULL)
                goto fail;
        priv->key_idx = key_idx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
-       if (priv->tx_tfm_arc4 == NULL) {
-               printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-                               "crypto API arc4\n");
-               goto fail;
-       }
-
-       priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
-       if (priv->tx_tfm_michael == NULL) {
-               printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-                               "crypto API michael_mic\n");
-               goto fail;
-       }
-
-       priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
-       if (priv->rx_tfm_arc4 == NULL) {
-               printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-                               "crypto API arc4\n");
-               goto fail;
-       }
-
-       priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
-       if (priv->rx_tfm_michael == NULL) {
-               printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-                               "crypto API michael_mic\n");
-               goto fail;
-       }
-#else
        priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
                        CRYPTO_ALG_ASYNC);
        if (IS_ERR(priv->tx_tfm_arc4)) {
@@ -155,22 +110,10 @@ static void * ieee80211_tkip_init(int key_idx)
                priv->rx_tfm_michael = NULL;
                goto fail;
        }
-#endif
        return priv;
 
 fail:
        if (priv) {
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-               if (priv->tx_tfm_michael)
-                       crypto_free_tfm(priv->tx_tfm_michael);
-               if (priv->tx_tfm_arc4)
-                       crypto_free_tfm(priv->tx_tfm_arc4);
-               if (priv->rx_tfm_michael)
-                       crypto_free_tfm(priv->rx_tfm_michael);
-               if (priv->rx_tfm_arc4)
-                       crypto_free_tfm(priv->rx_tfm_arc4);
-
-#else
                if (priv->tx_tfm_michael)
                        crypto_free_hash(priv->tx_tfm_michael);
                if (priv->tx_tfm_arc4)
@@ -179,7 +122,6 @@ fail:
                        crypto_free_hash(priv->rx_tfm_michael);
                if (priv->rx_tfm_arc4)
                        crypto_free_blkcipher(priv->rx_tfm_arc4);
-#endif
                kfree(priv);
        }
 
@@ -190,16 +132,6 @@ fail:
 static void ieee80211_tkip_deinit(void *priv)
 {
        struct ieee80211_tkip_data *_priv = priv;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       if (_priv->tx_tfm_michael)
-               crypto_free_tfm(_priv->tx_tfm_michael);
-       if (_priv->tx_tfm_arc4)
-               crypto_free_tfm(_priv->tx_tfm_arc4);
-       if (_priv->rx_tfm_michael)
-               crypto_free_tfm(_priv->rx_tfm_michael);
-       if (_priv->rx_tfm_arc4)
-               crypto_free_tfm(_priv->rx_tfm_arc4);
-#else
        if (_priv) {
                if (_priv->tx_tfm_michael)
                        crypto_free_hash(_priv->tx_tfm_michael);
@@ -210,7 +142,6 @@ static void ieee80211_tkip_deinit(void *priv)
                if (_priv->rx_tfm_arc4)
                        crypto_free_blkcipher(_priv->rx_tfm_arc4);
        }
-#endif
        kfree(priv);
 }
 
@@ -381,10 +312,8 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        struct ieee80211_hdr_4addr *hdr;
        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
 
-       #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
        struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
        int ret = 0;
-       #endif
        u8 rc4key[16],  *icv;
        u32 crc;
        struct scatterlist sg;
@@ -447,32 +376,14 @@ printk("%x\n", ((u32*)tkey->key)[7]);
        if (!tcb_desc->bHwSec)
        {
                icv = skb_put(skb, 4);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
                crc = ~crc32_le(~0, pos, len);
-#else
-               crc = ~ether_crc_le(len, pos);
-#endif
                icv[0] = crc;
                icv[1] = crc >> 8;
                icv[2] = crc >> 16;
                icv[3] = crc >> 24;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-               crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = len + 4;
-               crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
-#else
                crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = len + 4;
-#else
                sg_init_one(&sg, pos, len+4);
-#endif
                ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-#endif
 
        }
 
@@ -483,11 +394,7 @@ printk("%x\n", ((u32*)tkey->key)[7]);
        }
 
        if (!tcb_desc->bHwSec)
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-               return 0;
-       #else
                return ret;
-       #endif
        else
                return 0;
 
@@ -502,9 +409,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        u16 iv16;
        struct ieee80211_hdr_4addr *hdr;
        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-       #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
        struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
-       #endif
        u8 rc4key[16];
        u8 icv[4];
        u32 crc;
@@ -563,21 +468,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
                plen = skb->len - hdr_len - 12;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-               crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = plen + 4;
-               crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
-#else
                crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = plen + 4;
-#else
                sg_init_one(&sg, pos, plen+4);
-#endif
                if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
                        if (net_ratelimit()) {
                                printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -586,13 +478,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
                        }
                        return -7;
                }
-#endif
 
-       #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
                crc = ~crc32_le(~0, pos, plen);
-       #else
-               crc = ~ether_crc_le(plen, pos);
-       #endif
                icv[0] = crc;
                icv[1] = crc >> 8;
                icv[2] = crc >> 16;
@@ -641,47 +528,6 @@ if( ((u16*)skb->data)[0] & 0x4000){
 }
 
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr,
-                      u8 *data, size_t data_len, u8 *mic)
-{
-       struct scatterlist sg[2];
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-        struct hash_desc desc;
-        int ret = 0;
-#endif
-
-       if (tfm_michael == NULL){
-               printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
-               return -1;
-       }
-       sg[0].page = virt_to_page(hdr);
-       sg[0].offset = offset_in_page(hdr);
-       sg[0].length = 16;
-
-       sg[1].page = virt_to_page(data);
-       sg[1].offset = offset_in_page(data);
-       sg[1].length = data_len;
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-       crypto_digest_init(tfm_michael);
-        crypto_digest_setkey(tfm_michael, key, 8);
-        crypto_digest_update(tfm_michael, sg, 2);
-        crypto_digest_final(tfm_michael, mic);
-        return 0;
-#else
-if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
-                return -1;
-
-//      return 0;
-              desc.tfm = tkey->tfm_michael;
-              desc.flags = 0;
-              ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
-              return ret;
-#endif
-}
-#else
 static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                        u8 * data, size_t data_len, u8 * mic)
 {
@@ -692,19 +538,9 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
                 return -1;
         }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-        sg[0].page = virt_to_page(hdr);
-        sg[0].offset = offset_in_page(hdr);
-        sg[0].length = 16;
-
-        sg[1].page = virt_to_page(data);
-        sg[1].offset = offset_in_page(data);
-        sg[1].length = data_len;
-#else
         sg_init_table(sg, 2);
         sg_set_buf(&sg[0], hdr, 16);
         sg_set_buf(&sg[1], data, data_len);
-#endif
 
         if (crypto_hash_setkey(tfm_michael, key, 8))
                 return -1;
@@ -713,7 +549,6 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
         desc.flags = 0;
         return crypto_hash_digest(&desc, sg, data_len + 16, mic);
 }
-#endif
 
 
 
@@ -772,13 +607,8 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
        }
        // }
        pos = skb_put(skb, 8);
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
-                               skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
-#else
        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
                                skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
-#endif
                return -1;
 
        return 0;
@@ -850,13 +680,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
        }
        // }
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
-                               skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
-#else
        if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
                                skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
-#endif
                return -1;
        if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
                struct ieee80211_hdr_4addr *hdr;
@@ -886,32 +711,18 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
 {
        struct ieee80211_tkip_data *tkey = priv;
        int keyidx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       struct crypto_tfm *tfm = tkey->tx_tfm_michael;
-       struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
-       struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
-       struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
-#else
        struct crypto_hash *tfm = tkey->tx_tfm_michael;
        struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
        struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
        struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-#endif
 
        keyidx = tkey->key_idx;
        memset(tkey, 0, sizeof(*tkey));
        tkey->key_idx = keyidx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
        tkey->tx_tfm_michael = tfm;
        tkey->tx_tfm_arc4 = tfm2;
        tkey->rx_tfm_michael = tfm3;
        tkey->rx_tfm_arc4 = tfm4;
-#else
-       tkey->tx_tfm_michael = tfm;
-       tkey->tx_tfm_arc4 = tfm2;
-       tkey->rx_tfm_michael = tfm3;
-       tkey->rx_tfm_arc4 = tfm4;
-#endif
 
        if (len == TKIP_KEY_LEN) {
                memcpy(tkey->key, key, TKIP_KEY_LEN);
@@ -1021,11 +832,4 @@ void ieee80211_tkip_null(void)
 //    printk("============>%s()\n", __FUNCTION__);
         return;
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_tkip_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
-#endif
 
-//module_init(ieee80211_crypto_tkip_init);
-//module_exit(ieee80211_crypto_tkip_exit);
index c4bbc8ddbad127c5787b61147b7d59aadee2465f..5dc976498aae049fe89b50a943597b2f7c2b69ee 100644 (file)
 #include "ieee80211.h"
 
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
-    #include <linux/scatterlist.h>
-#endif
-//#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
-//
-/*
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
-#include <linux/crypto.h>
-#endif
 
-#include <asm/scatterlist.h>
-#include <linux/crc32.h>
-*/
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: WEP");
 MODULE_LICENSE("GPL");
@@ -58,12 +39,8 @@ struct prism2_wep_data {
        u8 key[WEP_KEY_LEN + 1];
        u8 key_len;
        u8 key_idx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       struct crypto_tfm *tfm;
-       #else
         struct crypto_blkcipher *tx_tfm;
         struct crypto_blkcipher *rx_tfm;
-        #endif
 };
 
 
@@ -76,14 +53,6 @@ static void * prism2_wep_init(int keyidx)
                goto fail;
        priv->key_idx = keyidx;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       priv->tfm = crypto_alloc_tfm("arc4", 0);
-       if (priv->tfm == NULL) {
-               printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
-                      "crypto API arc4\n");
-               goto fail;
-       }
-       #else
        priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
         if (IS_ERR(priv->tx_tfm)) {
                 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
@@ -98,7 +67,6 @@ static void * prism2_wep_init(int keyidx)
                 priv->rx_tfm = NULL;
                 goto fail;
         }
-        #endif
 
        /* start WEP IV from a random value */
        get_random_bytes(&priv->iv, 4);
@@ -106,13 +74,6 @@ static void * prism2_wep_init(int keyidx)
        return priv;
 
 fail:
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       if (priv) {
-               if (priv->tfm)
-                       crypto_free_tfm(priv->tfm);
-               kfree(priv);
-       }
-       #else
        if (priv) {
                 if (priv->tx_tfm)
                         crypto_free_blkcipher(priv->tx_tfm);
@@ -120,7 +81,6 @@ fail:
                         crypto_free_blkcipher(priv->rx_tfm);
                 kfree(priv);
         }
-        #endif
        return NULL;
 }
 
@@ -128,17 +88,12 @@ fail:
 static void prism2_wep_deinit(void *priv)
 {
        struct prism2_wep_data *_priv = priv;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-       if (_priv && _priv->tfm)
-               crypto_free_tfm(_priv->tfm);
-       #else
        if (_priv) {
                 if (_priv->tx_tfm)
                         crypto_free_blkcipher(_priv->tx_tfm);
                 if (_priv->rx_tfm)
                         crypto_free_blkcipher(_priv->rx_tfm);
         }
-        #endif
        kfree(priv);
 }
 
@@ -155,9 +110,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        u8 key[WEP_KEY_LEN + 3];
        u8 *pos;
        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-       #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
        struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
-       #endif
        u32 crc;
        u8 *icv;
        struct scatterlist sg;
@@ -196,35 +149,16 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        {
 
                /* Append little-endian CRC32 and encrypt it to produce ICV */
-       #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
                crc = ~crc32_le(~0, pos, len);
-       #else
-               crc = ~ether_crc_le(len, pos);
-       #endif
                icv = skb_put(skb, 4);
                icv[0] = crc;
                icv[1] = crc >> 8;
                icv[2] = crc >> 16;
                icv[3] = crc >> 24;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-               crypto_cipher_setkey(wep->tfm, key, klen);
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = len + 4;
-               crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
-               return 0;
-       #else
                crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-       #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = len + 4;
-       #else
                sg_init_one(&sg, pos, len+4);
-       #endif
                return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-       #endif
        }
 
        return 0;
@@ -245,9 +179,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        u8 key[WEP_KEY_LEN + 3];
        u8 keyidx, *pos;
        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-       #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
        struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
-       #endif
        u32 crc;
        u8 icv[4];
        struct scatterlist sg;
@@ -272,29 +204,11 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
        if (!tcb_desc->bHwSec)
        {
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-               crypto_cipher_setkey(wep->tfm, key, klen);
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = plen + 4;
-               crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
-       #else
                crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-       #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-               sg.page = virt_to_page(pos);
-               sg.offset = offset_in_page(pos);
-               sg.length = plen + 4;
-       #else
                sg_init_one(&sg, pos, plen+4);
-       #endif
                if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
                        return -7;
-       #endif
-       #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
                crc = ~crc32_le(~0, pos, plen);
-       #else
-               crc = ~ether_crc_le(plen, pos);
-       #endif
                icv[0] = crc;
                icv[1] = crc >> 8;
                icv[2] = crc >> 16;
@@ -379,14 +293,6 @@ void __exit ieee80211_crypto_wep_exit(void)
 
 void ieee80211_wep_null(void)
 {
-//     printk("============>%s()\n", __FUNCTION__);
         return;
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_wep_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
-#endif
 
-//module_init(ieee80211_crypto_wep_init);
-//module_exit(ieee80211_crypto_wep_exit);
index 614a8b630e67b4b14700873c5f0c3e9678582ea0..7edf5c897a6807fe5844f646dd5d378ceaaeeda3 100644 (file)
@@ -31,7 +31,6 @@
 *******************************************************************************/
 
 #include <linux/compiler.h>
-//#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -110,14 +109,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
                goto failed;
        }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
        ieee = netdev_priv(dev);
-#else
-       ieee = (struct ieee80211_device *)dev->priv;
-#endif
-#if 0
-       dev->hard_start_xmit = ieee80211_rtl_xmit;
-#endif
 
        memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
        ieee->dev = dev;
@@ -166,12 +158,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
        ieee80211_softmac_init(ieee);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
        ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
-#else
-       ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kmalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
-       memset(ieee->pHTInfo,0,sizeof(RT_HIGH_THROUGHPUT));
-#endif
        if (ieee->pHTInfo == NULL)
        {
                IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
@@ -180,13 +167,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        HTUpdateDefaultSetting(ieee);
        HTInitializeHTInfo(ieee); //may move to other place.
        TSInitialize(ieee);
-#if 0
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-       INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq);
-#else
-       INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq, ieee);
-#endif
-#endif
        for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
                INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
 
@@ -205,32 +185,20 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
  failed:
        if (dev)
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
                free_netdev(dev);
-#else
-               kfree(dev);
-#endif
        return NULL;
 }
 
 
 void free_ieee80211(struct net_device *dev)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
        struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-       struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
        int i;
-       //struct list_head *p, *q;
-//     del_timer_sync(&ieee->SwBwTimer);
-#if 1
        if (ieee->pHTInfo != NULL)
        {
                kfree(ieee->pHTInfo);
                ieee->pHTInfo = NULL;
        }
-#endif
        RemoveAllTS(ieee);
        ieee80211_softmac_free(ieee);
        del_timer_sync(&ieee->crypt_deinit_timer);
@@ -247,20 +215,7 @@ void free_ieee80211(struct net_device *dev)
        }
 
        ieee80211_networks_free(ieee);
-#if 0
-       for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
-               list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
-                       kfree(list_entry(p, struct ieee_ibss_seq, list));
-                       list_del(p);
-               }
-       }
-
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
        free_netdev(dev);
-#else
-       kfree(dev);
-#endif
 }
 
 #ifdef CONFIG_IEEE80211_DEBUG
@@ -358,11 +313,7 @@ int __init ieee80211_rtl_init(void)
        }
 
        ieee80211_debug_level = debug;
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-       ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
-#else
        ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
-#endif
        if (ieee80211_proc == NULL) {
                IEEE80211_ERROR("Unable to create " DRV_NAME
                                " proc directory\n");
@@ -371,11 +322,7 @@ int __init ieee80211_rtl_init(void)
        e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
                              ieee80211_proc);
        if (!e) {
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-               remove_proc_entry(DRV_NAME, proc_net);
-#else
                remove_proc_entry(DRV_NAME, init_net.proc_net);
-#endif
                ieee80211_proc = NULL;
                return -EIO;
        }
@@ -390,11 +337,7 @@ void __exit ieee80211_rtl_exit(void)
 {
        if (ieee80211_proc) {
                remove_proc_entry("debug_level", ieee80211_proc);
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-               remove_proc_entry(DRV_NAME, proc_net);
-#else
                remove_proc_entry(DRV_NAME, init_net.proc_net);
-#endif
                ieee80211_proc = NULL;
        }
        ieee80211_crypto_wep_exit();
@@ -403,21 +346,10 @@ void __exit ieee80211_rtl_exit(void)
        ieee80211_crypto_deinit();
 }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 #include <linux/moduleparam.h>
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
 
 
-//module_exit(ieee80211_rtl_exit);
-//module_init(ieee80211_rtl_init);
-#endif
 #endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(alloc_ieee80211);
-//EXPORT_SYMBOL(free_ieee80211);
-#else
-EXPORT_SYMBOL_NOVERS(alloc_ieee80211);
-EXPORT_SYMBOL_NOVERS(free_ieee80211);
-#endif
index da10067485e3c8fe0a58c7a14506bb7a26b710dc..aaf9b9dc45e648b87ce77aada3a83b46e3d370e9 100644 (file)
@@ -55,11 +55,7 @@ static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
        u16 fc = le16_to_cpu(hdr->frame_ctl);
 
        skb->dev = ieee->dev;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
         skb_reset_mac_header(skb);
-#else
-        skb->mac.raw = skb->data;
-#endif
 
        skb_pull(skb, ieee80211_get_hdrlen(fc));
        skb->pkt_type = PACKET_OTHERHOST;
@@ -2793,8 +2789,6 @@ static inline void ieee80211_process_probe_response(
 #endif
                memcpy(target, &network, sizeof(*target));
                list_add_tail(&target->list, &ieee->network_list);
-               if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
-                       ieee80211_softmac_new_net(ieee,&network);
        } else {
                IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
                                     escape_essid(target->ssid,
@@ -2821,8 +2815,6 @@ static inline void ieee80211_process_probe_response(
                //YJ,add,080819,for hidden ap,end
 
                update_network(target, &network);
-               if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
-                       ieee80211_softmac_new_net(ieee,&network);
        }
 
        spin_unlock_irqrestore(&ieee->lock, flags);
@@ -2880,11 +2872,3 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
 
        }
 }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_rx_mgt);
-//EXPORT_SYMBOL(ieee80211_rx);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
-EXPORT_SYMBOL_NOVERS(ieee80211_rx);
-#endif
index 46b6e8c900e943cb8ba4417657ae338b7f35a203..b7ec1ddee7043b4c98d96e9b80b73f5158fed597 100644 (file)
@@ -510,34 +510,11 @@ out:
 }
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/* called both by wq with ieee->lock held */
-void ieee80211_softmac_scan(struct ieee80211_device *ieee)
-{
-#if 0
-       short watchdog = 0;
-       do{
-               ieee->current_network.channel =
-                       (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
-               if (watchdog++ > MAX_CHANNEL_NUMBER)
-                               return; /* no good chans */
 
-       }while(!ieee->channel_map[ieee->current_network.channel]);
-#endif
-
-       schedule_task(&ieee->softmac_scan_wq);
-}
-#endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_softmac_scan_wq(struct work_struct *work)
 {
         struct delayed_work *dwork = container_of(work, struct delayed_work, work);
         struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
-#else
-void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
        static short watchdog = 0;
        u8 last_channel = ieee->current_network.channel;
 #ifdef ENABLE_DOT11D
@@ -575,13 +552,7 @@ void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
        ieee80211_send_probe_requests(ieee);
 
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
-#else
-       //ieee->scan_timer.expires = jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME);
-       if (ieee->scanning == 1)
-               mod_timer(&ieee->scan_timer,(jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME)));
-#endif
 
        up(&ieee->scan_sem);
        return;
@@ -597,19 +568,6 @@ out:
        up(&ieee->scan_sem);
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-void ieee80211_softmac_scan_cb(unsigned long _dev)
-{
-       unsigned long flags;
-       struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
-
-       spin_lock_irqsave(&ieee->lock, flags);
-       ieee80211_softmac_scan(ieee);
-       spin_unlock_irqrestore(&ieee->lock, flags);
-}
-#endif
-
-
 void ieee80211_beacons_start(struct ieee80211_device *ieee)
 {
        unsigned long flags;
@@ -665,11 +623,7 @@ void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
        if (ieee->scanning == 1){
                ieee->scanning = 0;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                cancel_delayed_work(&ieee->softmac_scan_wq);
-#else
-               del_timer_sync(&ieee->scan_timer);
-#endif
        }
 
 //     spin_unlock_irqrestore(&ieee->lock, flags);
@@ -704,16 +658,7 @@ void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
        if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
                if (ieee->scanning == 0){
                        ieee->scanning = 1;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
                        queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
-#else
-
-                       queue_work(ieee->wq, &ieee->softmac_scan_wq);
-#endif
-#else
-                       ieee80211_softmac_scan(ieee);
-#endif
                }
        }else
                ieee->start_scan(ieee->dev);
@@ -1428,13 +1373,8 @@ void ieee80211_associate_abort(struct ieee80211_device *ieee)
 
        ieee->state = IEEE80211_ASSOCIATING_RETRY;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
                            IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
-#else
-       schedule_task(&ieee->associate_retry_wq);
-#endif
-
        spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
@@ -1527,14 +1467,9 @@ void ieee80211_associate_step2(struct ieee80211_device *ieee)
                //dev_kfree_skb_any(skb);//edit by thomas
        }
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_associate_complete_wq(struct work_struct *work)
 {
         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
-#else
-void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
-{
-#endif
        printk(KERN_INFO "Associated successfully\n");
        ieee->is_roaming = false;
        if(ieee80211_is_54g(ieee->current_network) &&
@@ -1606,21 +1541,12 @@ void ieee80211_associate_complete(struct ieee80211_device *ieee)
        }
 #endif
        //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        queue_work(ieee->wq, &ieee->associate_complete_wq);
-#else
-       schedule_task(&ieee->associate_complete_wq);
-#endif
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_associate_procedure_wq(struct work_struct *work)
 {
         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
-#else
-void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
-{
-#endif
        ieee->sync_scan_hurryup = 1;
 #ifdef ENABLE_IPS
        if(ieee->ieee80211_ips_leave != NULL)
@@ -1734,11 +1660,7 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee
                                        }
 
                                        ieee->state = IEEE80211_ASSOCIATING;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                                        queue_work(ieee->wq, &ieee->associate_procedure_wq);
-#else
-                                       schedule_task(&ieee->associate_procedure_wq);
-#endif
                                }else{
                                        if(ieee80211_is_54g(ieee->current_network) &&
                                                (ieee->modulation & IEEE80211_OFDM_MODULATION)){
@@ -2332,11 +2254,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
                                                "Association response status code 0x%x\n",
                                                errcode);
                                        if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                                                queue_work(ieee->wq, &ieee->associate_procedure_wq);
-#else
-                                               schedule_task(&ieee->associate_procedure_wq);
-#endif
                                        } else {
                                                ieee80211_associate_abort(ieee);
                                        }
@@ -2446,11 +2364,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
                        //      notify_wx_assoc_event(ieee);
                                //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
                                RemovePeerTS(ieee, header->addr2);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                                queue_work(ieee->wq, &ieee->associate_procedure_wq);
-#else
-                               schedule_task(&ieee->associate_procedure_wq);
-#endif
                        }
                        break;
                case IEEE80211_STYPE_MANAGE_ACT:
@@ -2687,16 +2601,11 @@ void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
                netif_carrier_on(ieee->dev);
        }
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_start_ibss_wq(struct work_struct *work)
 {
 
         struct delayed_work *dwork = container_of(work, struct delayed_work, work);
         struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
-#else
-void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
-{
-#endif
        /* iwconfig mode ad-hoc will schedule this and return
         * on the other hand this will block further iwconfig SET
         * operations because of the wx_sem hold.
@@ -2807,11 +2716,7 @@ void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
 
 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
-#else
-       schedule_task(&ieee->start_ibss_wq);
-#endif
 }
 
 /* this is called only in user context, with wx_sem held */
@@ -2873,22 +2778,22 @@ void ieee80211_disassociate(struct ieee80211_device *ieee)
        if(IS_DOT11D_ENABLE(ieee))
                Dot11d_Reset(ieee);
 #endif
-       ieee->state = IEEE80211_NOLINK;
        ieee->is_set_key = false;
        ieee->link_change(ieee->dev);
        //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
-       notify_wx_assoc_event(ieee);
+       if (ieee->state == IEEE80211_LINKED ||
+           ieee->state == IEEE80211_ASSOCIATING) {
+               ieee->state = IEEE80211_NOLINK;
+               notify_wx_assoc_event(ieee);
+       }
+
+       ieee->state = IEEE80211_NOLINK;
 
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_associate_retry_wq(struct work_struct *work)
 {
         struct delayed_work *dwork = container_of(work, struct delayed_work, work);
         struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
-#else
-void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
-{
-#endif
        unsigned long flags;
 
        down(&ieee->wx_sem);
@@ -2990,10 +2895,8 @@ void ieee80211_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
 
        ieee80211_stop_send_beacons(ieee);
        del_timer_sync(&ieee->associate_timer);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        cancel_delayed_work(&ieee->associate_retry_wq);
        cancel_delayed_work(&ieee->start_ibss_wq);
-#endif
        ieee80211_stop_scan(ieee);
 
        ieee80211_disassociate(ieee);
@@ -3114,11 +3017,6 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
        ieee->sta_edca_param[3] = 0x002F3262;
        ieee->aggregation = true;
        ieee->enable_rx_imm_BA = 1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       init_timer(&ieee->scan_timer);
-       ieee->scan_timer.data = (unsigned long)ieee;
-       ieee->scan_timer.function = ieee80211_softmac_scan_cb;
-#endif
        ieee->tx_pending.txb = NULL;
 
        init_timer(&ieee->associate_timer);
@@ -3129,16 +3027,12 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
        ieee->beacon_timer.data = (unsigned long) ieee;
        ieee->beacon_timer.function = ieee80211_send_beacon_cb;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 #ifdef PF_SYNCTHREAD
        ieee->wq = create_workqueue(DRV_NAME,0);
 #else
        ieee->wq = create_workqueue(DRV_NAME);
 #endif
-#endif
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
         INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
         INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
         INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
@@ -3146,23 +3040,6 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
         INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
         INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
 
-#else
-       INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
-       INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
-       INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
-       INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
-       INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
-       INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
-#endif
-
-#else
-       tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
-       tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
-       tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
-       tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
-       tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
-       tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
-#endif
        sema_init(&ieee->wx_sem, 1);
        sema_init(&ieee->scan_sem, 1);
 #ifdef ENABLE_IPS
@@ -3189,10 +3066,8 @@ void ieee80211_softmac_free(struct ieee80211_device *ieee)
 #endif
        del_timer_sync(&ieee->associate_timer);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        cancel_delayed_work(&ieee->associate_retry_wq);
        destroy_workqueue(ieee->wq);
-#endif
 
        up(&ieee->wx_sem);
 }
@@ -3647,49 +3522,3 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee)
                memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
        wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
 }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_get_beacon);
-//EXPORT_SYMBOL(ieee80211_rtl_wake_queue);
-//EXPORT_SYMBOL(ieee80211_rtl_stop_queue);
-//EXPORT_SYMBOL(ieee80211_reset_queue);
-//EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
-//EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
-//EXPORT_SYMBOL(ieee80211_is_shortslot);
-//EXPORT_SYMBOL(ieee80211_is_54g);
-//EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
-//EXPORT_SYMBOL(ieee80211_ps_tx_ack);
-//EXPORT_SYMBOL(ieee80211_softmac_xmit);
-//EXPORT_SYMBOL(ieee80211_stop_send_beacons);
-//EXPORT_SYMBOL(notify_wx_assoc_event);
-//EXPORT_SYMBOL(SendDisassociation);
-//EXPORT_SYMBOL(ieee80211_disassociate);
-//EXPORT_SYMBOL(ieee80211_start_send_beacons);
-//EXPORT_SYMBOL(ieee80211_stop_scan);
-//EXPORT_SYMBOL(ieee80211_send_probe_requests);
-//EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
-//EXPORT_SYMBOL(ieee80211_start_scan_syncro);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
-EXPORT_SYMBOL_NOVERS(ieee80211_rtl_wake_queue);
-EXPORT_SYMBOL_NOVERS(ieee80211_rtl_stop_queue);
-EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
-EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot);
-EXPORT_SYMBOL_NOVERS(ieee80211_is_54g);
-EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl);
-EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_xmit);
-EXPORT_SYMBOL_NOVERS(ieee80211_stop_send_beacons);
-EXPORT_SYMBOL_NOVERS(notify_wx_assoc_event);
-EXPORT_SYMBOL_NOVERS(SendDisassociation);
-EXPORT_SYMBOL_NOVERS(ieee80211_disassociate);
-EXPORT_SYMBOL_NOVERS(ieee80211_start_send_beacons);
-EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
-EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro);
-EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro);
-EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_null_frame);
-EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_pspoll_frame);
-#endif
index 1bbd49f1d6f6d8f1686c1c2487ac31e6e957c0bb..d0a10807f7f66bdd44988660b18b182d63ccb69a 100644 (file)
@@ -312,14 +312,9 @@ out:
        return 0;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 void ieee80211_wx_sync_scan_wq(struct work_struct *work)
 {
         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
-#else
-void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
        short chan;
        HT_EXTCHNL_OFFSET chan_offset=0;
        HT_CHANNEL_WIDTH bandwidth=0;
@@ -337,8 +332,6 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
        ieee80211_sta_ps_send_null_frame(ieee, 1);
 #endif
 
-       netif_carrier_off(ieee->dev);
-
        if (ieee->data_hard_stop)
                ieee->data_hard_stop(ieee->dev);
 
@@ -389,7 +382,6 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
        if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
                ieee80211_start_send_beacons(ieee);
 
-       netif_carrier_on(ieee->dev);
        count = 0;
        up(&ieee->wx_sem);
 
@@ -408,11 +400,7 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info
        }
 
        if ( ieee->state == IEEE80211_LINKED){
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
-#else
-               schedule_task(&ieee->wx_sync_scan_wq);
-#endif
                /* intentionally forget to up sem */
                return 0;
        }
@@ -459,29 +447,8 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
        if (wrqu->essid.flags && wrqu->essid.length) {
                //first flush current network.ssid
                len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
-#if LINUX_VERSION_CODE <  KERNEL_VERSION(2,6,20)
-               strncpy(ieee->current_network.ssid, extra, len);
-               ieee->current_network.ssid_len = len;
-#if 0
-               {
-                       int i;
-                       for (i=0; i<len; i++)
-                               printk("%c ", extra[i]);
-                       printk("\n");
-               }
-#endif
-#else
                strncpy(ieee->current_network.ssid, extra, len+1);
                ieee->current_network.ssid_len = len+1;
-#if 0
-               {
-                       int i;
-                       for (i=0; i<len + 1; i++)
-                               printk("%c ", extra[i]);
-                       printk("\n");
-               }
-#endif
-#endif
                ieee->ssid_set = 1;
        }
        else{
@@ -659,42 +626,4 @@ exit:
        return ret;
 
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_wx_get_essid);
-//EXPORT_SYMBOL(ieee80211_wx_set_essid);
-//EXPORT_SYMBOL(ieee80211_wx_set_rate);
-//EXPORT_SYMBOL(ieee80211_wx_get_rate);
-//EXPORT_SYMBOL(ieee80211_wx_set_wap);
-//EXPORT_SYMBOL(ieee80211_wx_get_wap);
-//EXPORT_SYMBOL(ieee80211_wx_set_mode);
-//EXPORT_SYMBOL(ieee80211_wx_get_mode);
-//EXPORT_SYMBOL(ieee80211_wx_set_scan);
-//EXPORT_SYMBOL(ieee80211_wx_get_freq);
-//EXPORT_SYMBOL(ieee80211_wx_set_freq);
-//EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
-//EXPORT_SYMBOL(ieee80211_wx_get_name);
-//EXPORT_SYMBOL(ieee80211_wx_set_power);
-//EXPORT_SYMBOL(ieee80211_wx_get_power);
-//EXPORT_SYMBOL(ieee80211_wlan_frequencies);
-//EXPORT_SYMBOL(ieee80211_wx_set_rts);
-//EXPORT_SYMBOL(ieee80211_wx_get_rts);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power);
-EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rts);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rts);
-#endif
+
index a75f3668a40a67256fe96b43cec2c9b8527efc65..dd8a221e21ae72eb2b395e7c321c7d5377d8a9b2 100644 (file)
@@ -286,12 +286,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
        if (eth->h_proto != htons(ETH_P_IP))
                return 0;
 
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
        ip = ip_hdr(skb);
-#else
-       ip = (struct iphdr*)(skb->data + sizeof(struct ether_header));
-#endif
        switch (ip->tos & 0xfc) {
                case 0x20:
                        return 2;
@@ -613,11 +608,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u
 
 int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
        struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-       struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
        struct ieee80211_txb *txb = NULL;
        struct ieee80211_hdr_3addrqos *frag_hdr;
        int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
index 4971b1c8e7d762b2cf33d917f02e8338ce109565..b74491c38ec5b50570f2b8c306aa1d8b1896990a 100644 (file)
@@ -54,25 +54,7 @@ struct modes_unit ieee80211_modes[] = {
        {"N-5G",4},
 };
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static inline char *
-iwe_stream_add_event_rsl(char *     stream,         /* Stream of events */
-                     char *     ends,           /* End of stream */
-                     struct iw_event *iwe,      /* Payload */
-                     int        event_len)      /* Real size of payload */
-{
-        /* Check if it's possible */
-        if((stream + event_len) < ends) {
-                iwe->len = event_len;
-               ndelay(1);   //new
-                memcpy(stream, (char *) iwe, event_len);
-                stream += event_len;
-        }
-        return stream;
-}
-#else
 #define iwe_stream_add_event_rsl iwe_stream_add_event
-#endif
 
 #define MAX_CUSTOM_LEN 64
 static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
@@ -93,11 +75,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
        iwe.cmd = SIOCGIWAP;
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
        memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
        start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-#else
-       start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_ADDR_LEN);
-#endif
        /* Remaining entries will be displayed in the order we provide them */
 
        /* Add the ESSID */
@@ -106,22 +84,14 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 //     if (network->flags & NETWORK_EMPTY_ESSID) {
        if (network->ssid_len == 0) {
                iwe.u.data.length = sizeof("<hidden>");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
-#endif
         } else {
                iwe.u.data.length = min(network->ssid_len, (u8)32);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
-#endif
         }
        /* Add the protocol name */
        iwe.cmd = SIOCGIWNAME;
-       for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) {
+       for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) {
                if(network->mode&(1<<i)) {
                        sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
                        pname +=ieee80211_modes[i].mode_size;
@@ -129,11 +99,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
        }
        *pname = '\0';
        snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_CHAR_LEN);
-#endif
         /* Add mode */
         iwe.cmd = SIOCGIWMODE;
         if (network->capability &
@@ -142,11 +108,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
                        iwe.u.mode = IW_MODE_MASTER;
                else
                        iwe.u.mode = IW_MODE_ADHOC;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
-#else
-                start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_UINT_LEN);
-#endif
         }
 
         /* Add frequency/channel */
@@ -156,11 +118,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
        iwe.u.freq.m = network->channel;
        iwe.u.freq.e = 0;
        iwe.u.freq.i = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_FREQ_LEN);
-#endif
        /* Add encryption capability */
        iwe.cmd = SIOCGIWENCODE;
        if (network->capability & WLAN_CAPABILITY_PRIVACY)
@@ -168,11 +126,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
        else
                iwe.u.data.flags = IW_ENCODE_DISABLED;
        iwe.u.data.length = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-#else
-        start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
-#endif
        /* Add basic and extended rates */
        max_rate = 0;
        p = custom;
@@ -216,33 +170,15 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
                if (rate > max_rate)
                        max_rate = rate;
        }
-#if 0
-       printk("max rate:%d ===basic rate:\n", max_rate);
-       for (i=0;i<network->rates_len;i++)
-               printk(" %x", network->rates[i]);
-       printk("\n=======extend rate\n");
-       for (i=0; i<network->rates_ex_len; i++)
-               printk(" %x", network->rates_ex[i]);
-       printk("\n");
-#endif
        iwe.cmd = SIOCGIWRATE;
        iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
        iwe.u.bitrate.value = max_rate * 500000;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
                                     IW_EV_PARAM_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe,
-                                    IW_EV_PARAM_LEN);
-#endif
        iwe.cmd = IWEVCUSTOM;
        iwe.u.data.length = p - custom;
        if (iwe.u.data.length)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-        start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
        /* Add quality statistics */
        /* TODO: Fix these values... */
        iwe.cmd = IWEVQUAL;
@@ -257,21 +193,13 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
        if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
                iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
        iwe.u.qual.updated = 7;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_QUAL_LEN);
-#endif
        iwe.cmd = IWEVCUSTOM;
        p = custom;
 
        iwe.u.data.length = p - custom;
        if (iwe.u.data.length)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
             start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-            start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
 #if (WIRELESS_EXT < 18)
        if (ieee->wpa_enabled && network->wpa_ie_len){
                char buf[MAX_WPA_IE_LEN * 2 + 30];
@@ -285,11 +213,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;
                iwe.u.data.length = strlen(buf);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
         }
 
        if (ieee->wpa_enabled && network->rsn_ie_len){
@@ -304,11 +228,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;
                iwe.u.data.length = strlen(buf);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
         }
 #else
        memset(&iwe, 0, sizeof(iwe));
@@ -318,11 +238,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
                memcpy(buf, network->wpa_ie, network->wpa_ie_len);
                iwe.cmd = IWEVGENIE;
                iwe.u.data.length = network->wpa_ie_len;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
         }
        memset(&iwe, 0, sizeof(iwe));
        if (network->rsn_ie_len)
@@ -331,11 +247,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
                memcpy(buf, network->rsn_ie, network->rsn_ie_len);
                iwe.cmd = IWEVGENIE;
                iwe.u.data.length = network->rsn_ie_len;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
         }
 #endif
 
@@ -348,11 +260,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
                      " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
        iwe.u.data.length = p - custom;
        if (iwe.u.data.length)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
             start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-            start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
 
        return start;
 }
@@ -632,7 +540,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                                union iwreq_data *wrqu, char *extra)
 {
        int ret = 0;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        struct net_device *dev = ieee->dev;
         struct iw_point *encoding = &wrqu->encoding;
         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
@@ -807,7 +714,6 @@ done:
                 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
                 return -EINVAL;
         }
-#endif
         return ret;
 }
 
@@ -870,7 +776,6 @@ int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        struct iw_mlme *mlme = (struct iw_mlme *) extra;
        switch (mlme->cmd) {
         case IW_MLME_DEAUTH:
@@ -880,7 +785,6 @@ int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
         default:
                 return -EOPNOTSUPP;
         }
-#endif
        return 0;
 }
 
@@ -888,7 +792,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
                                struct iw_request_info *info,
                                struct iw_param *data, char *extra)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        switch (data->flags & IW_AUTH_INDEX) {
         case IW_AUTH_WPA_VERSION:
             /*need to support wpa2 here*/
@@ -946,23 +849,12 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
        default:
                 return -EOPNOTSUPP;
        }
-#endif
        return 0;
 }
 #endif
 #if 1
 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-#if 0
-       printk("====>%s()\n", __FUNCTION__);
-       {
-               int i;
-               for (i=0; i<len; i++)
-               printk("%2x ", ie[i]&0xff);
-               printk("\n");
-       }
-#endif
        u8 *buf;
 
        if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
@@ -992,29 +884,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
                ieee->wpa_ie = NULL;
                ieee->wpa_ie_len = 0;
        }
-#endif
        return 0;
 
 }
 #endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-//EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
-#if (WIRELESS_EXT >= 18)
-//EXPORT_SYMBOL(ieee80211_wx_set_mlme);
-//EXPORT_SYMBOL(ieee80211_wx_set_auth);
-//EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
-//EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
-#endif
-//EXPORT_SYMBOL(ieee80211_wx_get_scan);
-//EXPORT_SYMBOL(ieee80211_wx_set_encode);
-//EXPORT_SYMBOL(ieee80211_wx_get_encode);
-#else
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_gen_ie);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mlme);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_auth);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode_ext);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode);
-#endif
index 4c4b1df350ac41fef0563ca844fcb83dd57cbdad..b0c9c78eca4ead881654017220102c5f50ee71d1 100644 (file)
@@ -1024,17 +1024,6 @@ u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperate
        return true;
 }
 void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH        Bandwidth, HT_EXTCHNL_OFFSET    Offset);
-#if 0
-//I need move this function to other places, such as rx?
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void HTOnAssocRsp_wq(struct work_struct *work)
-{
-       struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ht_onAssRsp);
-#else
-void HTOnAssocRsp_wq(struct ieee80211_device *ieee)
-{
-#endif
-#endif
 void HTOnAssocRsp(struct ieee80211_device *ieee)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
@@ -1760,9 +1749,3 @@ void HTSetConnectBwModeCallback(struct ieee80211_device* ieee)
 
        pHTInfo->bSwBwInProgress = false;
 }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-//EXPORT_SYMBOL_NOVERS(HTUpdateSelfAndPeerSetting);
-#else
-//EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting);
-#endif
index 7391f5f8f25f823ac47a2d8fb56c8471eb78fd24..8bd5b173a7d2127398c92f069716e6fd4582811c 100644 (file)
@@ -501,13 +501,13 @@ SetRFPowerState8190(
                                if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
                                { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC.
                                        bool rtstatus = true;
-                                       u32 InitilizeCount = 3;
+                                       u32 InitializeCount = 3;
                                        do
                                        {
-                                               InitilizeCount--;
+                                               InitializeCount--;
                                                priv->RegRfOff = false;
                                                rtstatus = NicIFEnableNIC(dev);
-                                       }while( (rtstatus != true) &&(InitilizeCount >0) );
+                                       }while( (rtstatus != true) &&(InitializeCount >0) );
 
                                        if(rtstatus != true)
                                        {
index f4be9cc1100531d15046f62b97c96332c2adbc0f..865cdc008975cc08df22a8ab545034715b9de20f 100644 (file)
@@ -1468,7 +1468,6 @@ typedef   union _AC_PARAM{
 
 #endif
 bool init_firmware(struct net_device *dev);
-void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
 u32 read_cam(struct net_device *dev, u8 addr);
 void write_cam(struct net_device *dev, u8 addr, u32 data);
@@ -1503,10 +1502,9 @@ void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
 void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
 void rtl8187_set_rxconf(struct net_device *dev);
 //short check_nic_enough_desc(struct net_device *dev, priority_t priority);
-void rtl8192_start_beacon(struct net_device *dev);
 void CamResetAllEntry(struct net_device* dev);
 void EnableHWSecurityConfig8192(struct net_device *dev);
-void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
+void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
 void CamPrintDbgReg(struct net_device* dev);
 extern void    dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
 extern void firmware_init_param(struct net_device *dev);
index eb41402d1d3716179e3761f5219da671b44750ee..4cd071adf84b8f05052629616d5b3bf057568c8d 100644 (file)
@@ -92,12 +92,8 @@ u32 rt_global_debug_component = \
                        //      COMP_POWER_TRACKING     |
                         //     COMP_INTR       |
                                COMP_ERR ; //always open err flags on
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend,dev)\
-       .vendor=(vend),.device=(dev),\
-       .subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID
-#endif
-static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
+
+static const struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
 #ifdef RTL8190P
        /* Realtek */
        /* Dlink */
@@ -155,6 +151,16 @@ static struct pci_driver rtl8192_pci_driver = {
 #endif
 };
 
+static void rtl8192_start_beacon(struct net_device *dev);
+static void rtl8192_stop_beacon(struct net_device *dev);
+static void rtl819x_watchdog_wqcallback(struct work_struct *work);
+static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
+static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
+static void rtl8192_prepare_beacon(struct r8192_priv *priv);
+static irqreturn_t rtl8192_interrupt(int irq, void *netdev);
+static void rtl8192_try_wake_queue(struct net_device *dev, int pri);
+static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
+
 #ifdef ENABLE_DOT11D
 
 typedef struct _CHANNEL_LIST
@@ -163,7 +169,7 @@ typedef struct _CHANNEL_LIST
        u8      Len;
 }CHANNEL_LIST, *PCHANNEL_LIST;
 
-static CHANNEL_LIST ChannelPlan[] = {
+static const CHANNEL_LIST ChannelPlan[] = {
        {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24},             //FCC
        {{1,2,3,4,5,6,7,8,9,10,11},11},                                                 //IC
        {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},   //ETSI
@@ -349,8 +355,8 @@ u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
        //struct r8192_priv* priv = ieee80211_priv(dev);
        //struct ieee80211_device *ieee = priv->ieee80211;
 
-       static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
-       static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+       static const u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
+       static const u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
        int wpa_ie_len= ieee->wpa_ie_len;
        struct ieee80211_crypt_data* crypt;
        int encrypt;
@@ -487,15 +493,13 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
 /* this might still called in what was the PHY rtl8185/rtl8192 common code
  * plans are to possibilty turn it again in one common code...
  */
-inline void force_pci_posting(struct net_device *dev)
+void force_pci_posting(struct net_device *dev)
 {
 }
 
 
 //warning message WB
-irqreturn_t rtl8192_interrupt(int irq, void *netdev);
 //static struct net_device_stats *rtl8192_stats(struct net_device *dev);
-void rtl8192_commit(struct net_device *dev);
 //void rtl8192_restart(struct net_device *dev);
 void rtl8192_restart(struct work_struct *work);
 //void rtl8192_rq_tx_ack(struct work_struct *work);
@@ -940,7 +944,7 @@ void rtl8192_rx_enable(struct net_device *dev)
  *  HIGH_QUEUE     ===>                        7
  *  BEACON_QUEUE   ===>                        8
  *  */
-static u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
+static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
 void rtl8192_tx_enable(struct net_device *dev)
 {
     struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -1116,7 +1120,7 @@ static void rtl8192_reset(struct net_device *dev)
 }
 #endif
 
-static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
+static const u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
 inline u16 rtl8192_rate2rate(short rate)
 {
        if (rate >11) return 0;
@@ -1252,8 +1256,6 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
 }
 
 
-void rtl8192_try_wake_queue(struct net_device *dev, int pri);
-
 static void rtl8192_tx_isr(struct net_device *dev, int prio)
 {
     struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -1733,11 +1735,6 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
     pdesc->NoEnc = 1;
     pdesc->SecType = 0x0;
     if (tcb_desc->bHwSec) {
-        static u8 tmp =0;
-        if (!tmp) {
-            printk("==>================hw sec\n");
-            tmp = 1;
-        }
         switch (priv->ieee80211->pairwise_key_type) {
             case KEY_TYPE_WEP40:
             case KEY_TYPE_WEP104:
@@ -1988,7 +1985,7 @@ static void rtl8192_update_beacon(struct work_struct * work)
 /*
 * background support to run QoS activate functionality
 */
-static int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
+static const int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
 static void rtl8192_qos_activate(struct work_struct * work)
 {
         struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
@@ -2646,11 +2643,6 @@ static void rtl8192_init_priv_lock(struct r8192_priv* priv)
        mutex_init(&priv->mutex);
 }
 
-extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
-
-void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
-void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
-void rtl8192_prepare_beacon(struct r8192_priv *priv);
 //init tasklet and wait_queue here. only 2.6 above kernel is considered
 #define DRV_NAME "wlan0"
 static void rtl8192_init_priv_task(struct net_device* dev)
@@ -3807,7 +3799,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
 
 }
 
-void rtl8192_prepare_beacon(struct r8192_priv *priv)
+static void rtl8192_prepare_beacon(struct r8192_priv *priv)
 {
        struct sk_buff *skb;
        //unsigned long flags;
@@ -3837,7 +3829,7 @@ void rtl8192_prepare_beacon(struct r8192_priv *priv)
  * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
  * be used to stop beacon transmission
  */
-void rtl8192_start_beacon(struct net_device *dev)
+static void rtl8192_start_beacon(struct net_device *dev)
 {
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
        struct ieee80211_network *net = &priv->ieee80211->current_network;
@@ -4124,14 +4116,14 @@ static void CamRestoreAllEntry(struct net_device *dev)
 {
        u8 EntryId = 0;
        struct r8192_priv *priv = ieee80211_priv(dev);
-       u8*     MacAddr = priv->ieee80211->current_network.bssid;
+       const u8*       MacAddr = priv->ieee80211->current_network.bssid;
 
-       static u8       CAM_CONST_ADDR[4][6] = {
+       static const u8 CAM_CONST_ADDR[4][6] = {
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
-       static u8       CAM_CONST_BROAD[] =
+       static const u8 CAM_CONST_BROAD[] =
                {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
        RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
@@ -4318,7 +4310,6 @@ RESET_START:
                        del_timer_sync(&ieee->associate_timer);
                         cancel_delayed_work(&ieee->associate_retry_wq);
                        ieee80211_stop_scan(ieee);
-                       netif_carrier_off(dev);
                        up(&ieee->wx_sem);
                }
                else{
@@ -4669,7 +4660,7 @@ static void rtl819x_update_rxcounts(
 }
 
 
-void rtl819x_watchdog_wqcallback(struct work_struct *work)
+static void rtl819x_watchdog_wqcallback(struct work_struct *work)
 {
        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
@@ -6076,7 +6067,7 @@ static void rtl8192_tx_resume(struct net_device *dev)
        }
 }
 
-void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
+static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
 {
        rtl8192_tx_resume(priv->ieee80211->dev);
 }
@@ -6305,7 +6296,7 @@ done:
 
 }
 
-void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
+static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
 {
        rtl8192_rx(priv->ieee80211->dev);
        /* unmask RDU */
@@ -6640,7 +6631,7 @@ static void __exit rtl8192_pci_module_exit(void)
 }
 
 //warning message WB
-irqreturn_t rtl8192_interrupt(int irq, void *netdev)
+static irqreturn_t rtl8192_interrupt(int irq, void *netdev)
 {
     struct net_device *dev = (struct net_device *) netdev;
     struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -6784,7 +6775,7 @@ irqreturn_t rtl8192_interrupt(int irq, void *netdev)
     return IRQ_HANDLED;
 }
 
-void rtl8192_try_wake_queue(struct net_device *dev, int pri)
+static void rtl8192_try_wake_queue(struct net_device *dev, int pri)
 {
 #if 0
        unsigned long flags;
@@ -6847,7 +6838,7 @@ void setKey(      struct net_device *dev,
                u8 EntryNo,
                u8 KeyIndex,
                u16 KeyType,
-               u8 *MacAddr,
+               const u8 *MacAddr,
                u8 DefaultKey,
                u32 *KeyContent )
 {
index a249f00da60deea0797da0ecebbc27a2de5f77c2..a5884c6bcc251a68476b436db87c8319d27da4ee 100644 (file)
@@ -26,20 +26,20 @@ Major Change History:
 // Indicate different AP vendor for IOT issue.
 //
 #ifdef  RTL8190P
-static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
 { 0x5e4322,    0x5e4322,       0x5e4322,       0x604322,       0xa44f,         0x5e4322,       0x5e4322};
-static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
 { 0x5e4322,    0xa44f,         0x5e4322,       0x604322,       0x5e4322,       0x5e4322,       0x5e4322};
 #else
 #ifdef RTL8192E
-static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
 { 0x5e4322,    0x5e4322,       0x5e4322,       0x604322,       0xa44f,         0x5e4322,       0x5e4322};
-static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
 { 0x5e4322,    0xa44f,         0x5e4322,       0x604322,       0x5e4322,       0x5e4322,       0x5e4322};
 #else
-static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
 { 0x5e4322,    0x5e4322,       0x5e4322,       0x604322,       0xa44f,         0x5ea44f,       0x5e4322};
-static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
 { 0x5e4322,    0xa44f,         0x5e4322,       0x604322,       0x5ea44f,       0x5ea44f,       0x5e4322};
 #endif
 #endif
@@ -592,7 +592,7 @@ static void dm_bandwidth_autoswitch(struct net_device * dev)
 
 //OFDM default at 0db, index=6.
 #ifndef RTL8190P
-static u32 OFDMSwingTable[OFDM_Table_Length] = {
+static const u32 OFDMSwingTable[OFDM_Table_Length] = {
        0x7f8001fe,     // 0, +6db
        0x71c001c7,     // 1, +5db
        0x65400195,     // 2, +4db
@@ -613,7 +613,7 @@ static u32 OFDMSwingTable[OFDM_Table_Length] = {
        0x12000048,     // 17, -11db
        0x10000040      // 18, -12db
 };
-static u8      CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
+static const u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
        {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},       // 0, +0db ===> CCK40M default
        {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},       // 1, -1db
        {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},       // 2, -2db
@@ -628,7 +628,7 @@ static u8   CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
        {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}        // 11, -11db
 };
 
-static u8      CCKSwingTable_Ch14[CCK_Table_length][8] = {
+static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
        {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},       // 0, +0db  ===> CCK40M default
        {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},       // 1, -1db
        {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},       // 2, -2db
@@ -2094,8 +2094,6 @@ static void dm_ctrl_initgain_byrssi(struct net_device *dev)
                dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
        else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
                dm_ctrl_initgain_byrssi_by_driverrssi(dev);
-       else
-               return;
 }
 
 
@@ -2938,8 +2936,6 @@ void dm_gpio_change_rf_callback(struct work_struct *work)
        RT_RF_POWER_STATE       eRfPowerStateToSet;
        bool bActuallySet = false;
 
-               bActuallySet=false;
-
                if(!priv->up)
                {
                RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
index 0b0f39ce3ced93f41271d82f3bedd4ec57e72bdd..5742cee812031251d78519558f6a31f7c92663fc 100644 (file)
@@ -26,7 +26,7 @@
 #endif
 
 #define RATE_COUNT 12
-static u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
+static const u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
        6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
 
 
@@ -137,161 +137,6 @@ static int r8192_wx_get_power(struct net_device *dev,
        return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
 }
 
-#ifdef JOHN_IOCTL
-u16 read_rtl8225(struct net_device *dev, u8 addr);
-void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-u32 john_read_rtl8225(struct net_device *dev, u8 adr);
-void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-
-static int r8192_wx_read_regs(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 addr;
-       u16 data1;
-
-       down(&priv->wx_sem);
-
-
-       get_user(addr,(u8*)wrqu->data.pointer);
-       data1 = read_rtl8225(dev, addr);
-       wrqu->data.length = data1;
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-
-static int r8192_wx_write_regs(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-        u8 addr;
-
-        down(&priv->wx_sem);
-
-        get_user(addr, (u8*)wrqu->data.pointer);
-       write_rtl8225(dev, addr, wrqu->data.length);
-
-        up(&priv->wx_sem);
-       return 0;
-
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
-
-static int r8192_wx_read_bb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 databb;
-#if 0
-       int i;
-       for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
-#endif
-
-        down(&priv->wx_sem);
-
-       databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
-       wrqu->data.length = databb;
-
-       up(&priv->wx_sem);
-       return 0;
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-static int r8192_wx_write_bb(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-        u8 databb;
-
-        down(&priv->wx_sem);
-
-        get_user(databb, (u8*)wrqu->data.pointer);
-        rtl8187_write_phy(dev, wrqu->data.length, databb);
-
-        up(&priv->wx_sem);
-        return 0;
-
-}
-
-
-static int r8192_wx_write_nicb(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-        u32 addr;
-
-        down(&priv->wx_sem);
-
-        get_user(addr, (u32*)wrqu->data.pointer);
-        write_nic_byte(dev, addr, wrqu->data.length);
-
-        up(&priv->wx_sem);
-        return 0;
-
-}
-static int r8192_wx_read_nicb(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-        u32 addr;
-        u16 data1;
-
-        down(&priv->wx_sem);
-
-        get_user(addr,(u32*)wrqu->data.pointer);
-        data1 = read_nic_byte(dev, addr);
-        wrqu->data.length = data1;
-
-        up(&priv->wx_sem);
-        return 0;
-}
-
-static int r8192_wx_get_ap_status(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-        struct ieee80211_device *ieee = priv->ieee80211;
-        struct ieee80211_network *target;
-       int name_len;
-
-        down(&priv->wx_sem);
-
-       //count the length of input ssid
-       for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
-
-       //search for the correspoding info which is received
-        list_for_each_entry(target, &ieee->network_list, list) {
-                if ( (target->ssid_len == name_len) &&
-                    (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
-                       if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
-                               //set flags=1 to indicate this ap is WPA
-                               wrqu->data.flags = 1;
-                       else wrqu->data.flags = 0;
-
-
-               break;
-                }
-        }
-
-        up(&priv->wx_sem);
-        return 0;
-}
-
-
-
-#endif
-
 static int r8192_wx_set_rawtx(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
index 7bd4fae0667eb8d077f13756065de300c94631cc..ffd1e97e27b9c20bebe0daa78cd158723f403472 100644 (file)
@@ -7,7 +7,7 @@
 #ifdef ENABLE_DOT11D
 #include "ieee80211/dot11d.h"
 #endif
-static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
+static const u32 RF_CHANNEL_TABLE_ZEBRA[] = {
        0,
        0x085c, //2412 1
        0x08dc, //2417 2
index b422ea1ecf9cf08e310feb79bb4462a91230a8f3..27b89a432670a135190769d896731d58400d5de9 100644 (file)
@@ -4,5 +4,6 @@ config RTL8192SU
        select WIRELESS_EXT
        select WEXT_PRIV
        select EEPROM_93CX6
+       select CRYPTO
        default N
        ---help---
index 3c8da157a93c7b713a7dab944c9ab4340c4784f5..b15204ea4ec4932307f21d9be160ba0b089f668e 100644 (file)
@@ -1,4 +1,10 @@
 TODO:
+- merge realteks bugfixes and new features into the driver:
+  - an updated version of this driver can be found here:
+    http://www.getnet.eu/products_GN-621U.html
+  - note:
+    realtek has stripped alomost all comments from the source,
+    so please leave all comments that may help in development in the code.
 - prepare private ieee80211 stack for merge with rtl8187se's version:
   - remove rtl8192su's specific dead code
   - cleanup ieee80211.h
@@ -7,7 +13,6 @@ TODO:
 - switch to use shared "librtl" instead of private ieee80211 stack
 - switch to use LIB80211
 - switch to use MAC80211
-- switch to use EEPROM_93CX6
 - use kernel coding style
 - checkpatch.pl fixes
 - sparse fixes
index 22484621478084a6386ca6646f3502d0706f247f..6275cc75ec8572553b160279bc6a6870cd07c718 100644 (file)
@@ -1,11 +1,21 @@
-//-----------------------------------------------------------------------------
-//     File:
-//             Dot11d.c
-//
-//     Description:
-//             Implement 802.11d.
-//
-//-----------------------------------------------------------------------------
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 
 #include "dot11d.h"
 
@@ -50,7 +60,6 @@ Dot11d_Reset(struct ieee80211_device *ieee)
        pDot11dInfo->CountryIeLen = 0;
        RESET_CIE_WATCHDOG(ieee);
 
-       //printk("Dot11d_Reset()\n");
 }
 
 //
@@ -105,7 +114,6 @@ Dot11d_UpdateCountryIe(
                pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
        }
 #if 1
-       //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
        printk("Channel List:");
        for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
                if(pDot11dInfo->channel_map[i] > 0)
index 913ac5d97e753b583aef1467a72f8fd5d6f304aa..62a2c905e1fa724690e32b41fa6975dffb71e0ce 100644 (file)
@@ -1,10 +1,26 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #ifndef __INC_DOT11D_H
 #define __INC_DOT11D_H
 
 #include "ieee80211.h"
 
-//#define DOT11D_MAX_CHNL_NUM 83
-
 typedef struct _CHNL_TXPOWER_TRIPLE {
        u8 FirstChnl;
        u8  NumChnls;
@@ -18,7 +34,6 @@ typedef enum _DOT11D_STATE {
 }DOT11D_STATE;
 
 typedef struct _RT_DOT11D_INFO {
-       //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
 
        bool bEnabled; // dot11MultiDomainCapabilityEnabled
 
@@ -28,8 +43,6 @@ typedef struct _RT_DOT11D_INFO {
        u8  CountryIeWatchdog;
 
        u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
-       //u8  ChnlListLen; // #Bytes valid in ChnlList[].
-       //u8  ChnlList[DOT11D_MAX_CHNL_NUM];
        u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
 
        DOT11D_STATE State;
@@ -95,4 +108,4 @@ int ToLegalChannel(
        struct ieee80211_device * dev,
        u8 channel
 );
-#endif // #ifndef __INC_DOT11D_H
+#endif
index bcb2b12a8398d6d3d8b1e1c09f89f61be0fe2a5f..1d6789db4e4d843789c867183ace3f9d40188a2e 100644 (file)
@@ -168,6 +168,10 @@ typedef struct ieee_param {
 /* QOS control */
 #define IEEE80211_QCTL_TID              0x000F
 
+#define OUI_SUBTYPE_WMM_INFO           0
+#define OUI_SUBTYPE_WMM_PARAM  1
+#define OUI_SUBTYPE_QOS_CAPABI 5
+
 /* debug macros */
 #define CONFIG_IEEE80211_DEBUG
 #ifdef CONFIG_IEEE80211_DEBUG
@@ -1120,11 +1124,27 @@ enum {
        COUNTRY_CODE_MKK = 5,
        COUNTRY_CODE_MKK1 = 6,
        COUNTRY_CODE_ISRAEL = 7,
-       COUNTRY_CODE_TELEC,
-       COUNTRY_CODE_MIC,
-       COUNTRY_CODE_GLOBAL_DOMAIN
+       COUNTRY_CODE_TELEC = 8,
+       COUNTRY_CODE_MIC = 9,
+       COUNTRY_CODE_GLOBAL_DOMAIN = 10,
+       COUNTRY_CODE_WORLD_WIDE_13 = 11,
+       COUNTRY_CODE_TELEC_NETGEAR = 12,
+       COUNTRY_CODE_MAX
 };
 
+#define        NUM_PMKID_CACHE         16
+
+typedef struct _RT_PMKID_LIST
+{
+       u8                                              bUsed;
+       u8                                              Bssid[6];
+       u8                                              PMKID[16];
+       u8                                              SsidBuf[33];
+       u8*                                             ssid_octet;
+       u16                                     ssid_length;
+} RT_PMKID_LIST, *PRT_PMKID_LIST;
+
+
 #include "ieee80211_r8192s.h"
 
 struct ieee80211_device {
@@ -1134,6 +1154,7 @@ struct ieee80211_device {
        /* hw security related */
        u8 hwsec_active;
        bool is_silent_reset;
+       bool force_mic_error;
        bool is_roaming;
        bool ieee_up;
        bool bSupportRemoteWakeUp;
@@ -1247,6 +1268,7 @@ struct ieee80211_device {
        int bcrx_sta_key; /* use individual keys to override default keys even
                           * with RX of broad/multicast frames */
 
+       RT_PMKID_LIST           PMKIDList[NUM_PMKID_CACHE];
        /* Fragmentation structures */
        // each streaming contain a entry
        struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
@@ -1295,6 +1317,10 @@ struct ieee80211_device {
         */
        void *pDot11dInfo;
        bool bGlobalDomain;
+
+       u8   IbssStartChnl;
+       u8   ibss_maxjoin_chal;
+
        int rate;       /* current rate */
        int basic_rate;
        //FIXME: pleace callback, see if redundant with softmac_features
index 8019423394379d4c1d947e9192adb0863108fbd7..24e7d595e3cef80c7f9e9d0b94022f63b27f1bea 100644 (file)
@@ -11,7 +11,6 @@
  *
  */
 
-//#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -201,7 +200,7 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
        .owner                  = THIS_MODULE,
 };
 
-int __init ieee80211_crypto_init(void)
+int ieee80211_crypto_init(void)
 {
        int ret = -ENOMEM;
 
@@ -221,7 +220,7 @@ out:
        return ret;
 }
 
-void __exit ieee80211_crypto_deinit(void)
+void ieee80211_crypto_deinit(void)
 {
        struct list_head *ptr, *n;
        struct ieee80211_crypto_alg *alg = NULL;
index b58a3bcc0dc0972c882f5992ad02264510769bf5..42e52aedd2925706aa7a5ef1be71c71791383028 100644 (file)
@@ -49,7 +49,7 @@ struct ieee80211_crypto_ops {
         * These can be NULL if full MSDU operations are not needed. */
        int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
        int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-                           void *priv);
+                           void *priv, struct ieee80211_device* ieee);
 
        int (*set_key)(void *key, int len, u8 *seq, void *priv);
        int (*get_key)(void *key, int len, u8 *seq, void *priv);
index 77de957f1b1f7eebce8c5906b7ed310c693f0dba..caee44ba3bc3619cbbb41438d50862de1b8bebfd 100644 (file)
@@ -9,7 +9,6 @@
  * more details.
  */
 
-//#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -131,7 +130,6 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
        qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
                       (WLAN_FC_GET_STYPE(fc) & 0x08));
         */
-       // fixed by David :2006.9.6
        qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
                       (WLAN_FC_GET_STYPE(fc) & 0x80));
        aad_len = 22;
@@ -210,7 +208,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        pos = skb_push(skb, CCMP_HDR_LEN);
        memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
        pos += hdr_len;
-//     mic = skb_put(skb, CCMP_MIC_LEN);
 
        i = CCMP_PN_LEN - 1;
        while (i >= 0) {
@@ -240,7 +237,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
                u8 *e = key->tx_e;
                u8 *s0 = key->tx_s0;
 
-               //mic is moved to here by john
                mic = skb_put(skb, CCMP_MIC_LEN);
 
                ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
@@ -445,7 +441,6 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
 
 void ieee80211_ccmp_null(void)
 {
-//    printk("============>%s()\n", __FUNCTION__);
        return;
 }
 
@@ -470,7 +465,7 @@ int __init ieee80211_crypto_ccmp_init(void)
        return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
 }
 
-void __exit ieee80211_crypto_ccmp_exit(void)
+void ieee80211_crypto_ccmp_exit(void)
 {
        ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
 }
index ade5f6f13667de9d4b1ff0b80d785da225d7674c..5ab94a9665e5427386af34d28910ce93b872d402 100644 (file)
@@ -9,7 +9,6 @@
  * more details.
  */
 
-//#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -43,6 +42,7 @@ struct ieee80211_tkip_data {
 
        u32 rx_iv32;
        u16 rx_iv16;
+       bool initialized;
        u16 rx_ttak[5];
        int rx_phase1_done;
        u32 rx_iv32_new;
@@ -433,8 +433,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
        if (!tcb_desc->bHwSec)
        {
-               if (iv32 < tkey->rx_iv32 ||
-               (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
+               if ((iv32 < tkey->rx_iv32 ||
+               (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16))&&tkey->initialized) {
                        if (net_ratelimit()) {
                                printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
                                " previous TSC %08x%04x received TSC "
@@ -444,6 +444,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
                        tkey->dot11RSNAStatsTKIPReplays++;
                        return -4;
                }
+                tkey->initialized = true;
 
                if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
                        tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
@@ -452,10 +453,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
                tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
 
                plen = skb->len - hdr_len - 12;
-
+               sg_init_one(&sg, pos, plen+4);
                crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-               sg_init_one(&sg, pos, plen + 4);
-
                if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
                        if (net_ratelimit()) {
                                printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -571,12 +570,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
 
        michael_mic_hdr(skb, tkey->tx_hdr);
 
-       // { david, 2006.9.1
-       // fix the wpa process with wmm enabled.
        if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
                tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
        }
-       // }
        pos = skb_put(skb, 8);
 
        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
@@ -608,7 +604,7 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
 }
 
 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
-                                    int hdr_len, void *priv)
+                                    int hdr_len, void *priv, struct ieee80211_device* ieee)
 {
        struct ieee80211_tkip_data *tkey = priv;
        u8 mic[8];
@@ -620,12 +616,9 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
                return -1;
 
        michael_mic_hdr(skb, tkey->rx_hdr);
-       // { david, 2006.9.1
-       // fix the wpa process with wmm enabled.
        if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
                tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
        }
-       // }
 
        if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
                        skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
@@ -637,9 +630,14 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
                       "MSDU from %pM keyidx=%d\n",
                       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
                       keyidx);
-               if (skb->dev)
+                printk("%d, force_mic_error = %d\n", (memcmp(mic, skb->data + skb->len - 8, 8) != 0),\
+                        ieee->force_mic_error);
+               if (skb->dev) {
+                        printk("skb->dev != NULL\n");
                        ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
+                }
                tkey->dot11RSNAStatsTKIPLocalMICFailures++;
+                ieee->force_mic_error = false;
                return -1;
        }
 
@@ -762,18 +760,17 @@ static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
        .owner                  = THIS_MODULE,
 };
 
-int __init ieee80211_crypto_tkip_init(void)
+int ieee80211_crypto_tkip_init(void)
 {
        return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
 }
 
-void __exit ieee80211_crypto_tkip_exit(void)
+void ieee80211_crypto_tkip_exit(void)
 {
        ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
 }
 
 void ieee80211_tkip_null(void)
 {
-//    printk("============>%s()\n", __FUNCTION__);
         return;
 }
index a1c0a59122b88eccad81def54d36aa592fe5421b..5219bfd4ea8e9044182cc3296215ae6a7708ca59 100644 (file)
@@ -9,7 +9,6 @@
  * more details.
  */
 
-//#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -279,18 +278,17 @@ static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
        .owner                  = THIS_MODULE,
 };
 
-int __init ieee80211_crypto_wep_init(void)
+int ieee80211_crypto_wep_init(void)
 {
        return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
 }
 
-void __exit ieee80211_crypto_wep_exit(void)
+void ieee80211_crypto_wep_exit(void)
 {
        ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
 }
 
 void ieee80211_wep_null(void)
 {
-//     printk("============>%s()\n", __FUNCTION__);
         return;
 }
index a87650a517bd0b9456a246a8a14cf3318c31e343..4945b3dbf72b11d37b168fbd1a6d6bccb3b668ec 100644 (file)
@@ -31,7 +31,6 @@
 *******************************************************************************/
 
 #include <linux/compiler.h>
-//#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -142,7 +141,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        spin_lock_init(&ieee->wpax_suitlist_lock);
        spin_lock_init(&ieee->bw_spinlock);
        spin_lock_init(&ieee->reorder_spinlock);
-       //added by WB
        atomic_set(&(ieee->atm_chnlop), 0);
        atomic_set(&(ieee->atm_swbw), 0);
 
@@ -153,7 +151,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        ieee->privacy_invoked = 0;
        ieee->ieee802_1x = 1;
        ieee->raw_tx = 0;
-       //ieee->hwsec_support = 1; //default support hw security. //use module_param instead.
        ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
 
        ieee80211_softmac_init(ieee);
@@ -196,8 +193,6 @@ void free_ieee80211(struct net_device *dev)
 {
        struct ieee80211_device *ieee = netdev_priv(dev);
        int i;
-       //struct list_head *p, *q;
-//     del_timer_sync(&ieee->SwBwTimer);
 #if 1
        if (ieee->pHTInfo != NULL)
        {
@@ -228,23 +223,6 @@ void free_ieee80211(struct net_device *dev)
 
 u32 ieee80211_debug_level = 0;
 static int debug = \
-       //                  IEEE80211_DL_INFO   |
-       //                  IEEE80211_DL_WX     |
-       //                  IEEE80211_DL_SCAN   |
-       //                  IEEE80211_DL_STATE  |
-       //                  IEEE80211_DL_MGMT   |
-       //                  IEEE80211_DL_FRAG   |
-       //                  IEEE80211_DL_EAP    |
-       //                  IEEE80211_DL_DROP   |
-       //                  IEEE80211_DL_TX     |
-       //                  IEEE80211_DL_RX     |
-                           //IEEE80211_DL_QOS    |
-       //                  IEEE80211_DL_HT     |
-       //                  IEEE80211_DL_TS     |
-//                         IEEE80211_DL_BA     |
-       //                  IEEE80211_DL_REORDER|
-//                         IEEE80211_DL_TRACE  |
-                           //IEEE80211_DL_DATA |
                            IEEE80211_DL_ERR      //awayls open this flags to show error out
                            ;
 struct proc_dir_entry *ieee80211_proc = NULL;
@@ -282,7 +260,7 @@ static int store_debug_level(struct file *file, const char *buffer,
        return strnlen(buf, count);
 }
 
-int __init ieee80211_debug_init(void)
+int ieee80211_debug_init(void)
 {
        struct proc_dir_entry *e;
 
@@ -308,7 +286,7 @@ int __init ieee80211_debug_init(void)
        return 0;
 }
 
-void __exit ieee80211_debug_exit(void)
+void ieee80211_debug_exit(void)
 {
        if (ieee80211_proc) {
                remove_proc_entry("debug_level", ieee80211_proc);
index 1824cda790d8ff84d8d0f1be16e921961313d770..7e7fbb2698000e50ee1bfec9bb1225c2880b3545 100644 (file)
@@ -339,28 +339,39 @@ enum {
 };
 
 /* Firmware related CMD IO. */
-typedef enum _FW_CMD_IO_TYPE {
-       FW_CMD_DIG_ENABLE = 0,          /* for DIG DM */
+typedef        enum _FW_CMD_IO_TYPE{
+       FW_CMD_DIG_ENABLE = 0, /* for DIG DM */
        FW_CMD_DIG_DISABLE = 1,
        FW_CMD_DIG_HALT = 2,
        FW_CMD_DIG_RESUME = 3,
-       FW_CMD_HIGH_PWR_ENABLE = 4,     /* for High Power DM */
+       FW_CMD_HIGH_PWR_ENABLE = 4, /* for DIG DM */
        FW_CMD_HIGH_PWR_DISABLE = 5,
-       FW_CMD_RA_RESET = 6,            /* for Rate adaptive DM */
-       FW_CMD_RA_ACTIVE = 7,
-       FW_CMD_RA_REFRESH_N = 8,
-       FW_CMD_RA_REFRESH_BG = 9,
-       FW_CMD_IQK_ENABLE = 10,         /* for FW supported IQK */
-       FW_CMD_TXPWR_TRACK_ENABLE = 11, /* Tx power tracking switch */
-       FW_CMD_TXPWR_TRACK_DISABLE = 12,/* Tx power tracking switch */
-       FW_CMD_PAUSE_DM_BY_SCAN = 13,
-       FW_CMD_RESUME_DM_BY_SCAN = 14,
-       FW_CMD_MID_HIGH_PWR_ENABLE = 15,
+       FW_CMD_RA_RESET = 6, /* for DIG DM */
+       FW_CMD_RA_ACTIVE= 7,
+       FW_CMD_RA_REFRESH_N= 8,
+       FW_CMD_RA_REFRESH_BG= 9,
+       FW_CMD_RA_INIT= 10, /* for FW supported IQK */
+       FW_CMD_IQK_ENABLE = 11, /* Tx power tracking switch */
+       FW_CMD_TXPWR_TRACK_ENABLE = 12, /* Tx power tracking switch */
+       FW_CMD_TXPWR_TRACK_DISABLE = 13,
+       FW_CMD_TXPWR_TRACK_THERMAL = 14,
+       FW_CMD_PAUSE_DM_BY_SCAN = 15,
        /* indicate firmware that driver enters LPS, for PS-Poll hardware bug */
-       FW_CMD_LPS_ENTER = 16,
+       FW_CMD_RESUME_DM_BY_SCAN = 16,
        /* indicate firmware that driver leave LPS */
-       FW_CMD_LPS_LEAVE = 17,
-} FW_CMD_IO_TYPE;
+       FW_CMD_RA_REFRESH_N_COMB = 17,
+       FW_CMD_RA_REFRESH_BG_COMB = 18,
+       FW_CMD_ANTENNA_SW_ENABLE = 19,
+       FW_CMD_ANTENNA_SW_DISABLE = 20,
+       FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21,
+       FW_CMD_LPS_ENTER = 22,
+       FW_CMD_LPS_LEAVE = 23,
+       FW_CMD_DIG_MODE_SS = 24,
+       FW_CMD_DIG_MODE_FA = 25,
+       FW_CMD_ADD_A2_ENTRY = 26,
+       FW_CMD_CTRL_DM_BY_DRIVER = 27,
+       FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28,
+}FW_CMD_IO_TYPE,*PFW_CMD_IO_TYPE;
 
 #define RT_MAX_LD_SLOT_NUM     10
 struct rt_link_detect {
index 1f2bc7ac6f7909adda805b81c906c5d2a311fa11..09a02f7e39ff2c3d7e0248fcc99a899de7e551a2 100644 (file)
@@ -360,7 +360,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
        hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
        atomic_inc(&crypt->refcnt);
-       res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
+       res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv,ieee);
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
                printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
index 4f1f2f08b2d7d77c347d7b4579054d47bbcf4e46..02850479dd62015d364ff51a0ac4cbe97f557739 100644 (file)
@@ -160,7 +160,6 @@ void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
        ieee->mgmt_queue_head = nh;
        ieee->mgmt_queue_ring[nh] = skb;
 
-       //return 0;
 }
 
 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
@@ -183,19 +182,53 @@ void init_mgmt_queue(struct ieee80211_device *ieee)
        ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
 }
 
+u8
+MgntQuery_TxRateExcludeCCKRates(struct ieee80211_device *ieee)
+{
+       u16     i;
+       u8      QueryRate = 0;
+       u8      BasicRate;
+
+
+       for( i = 0; i < ieee->current_network.rates_len; i++)
+       {
+               BasicRate = ieee->current_network.rates[i]&0x7F;
+               if(!ieee80211_is_cck_rate(BasicRate))
+               {
+                       if(QueryRate == 0)
+                       {
+                               QueryRate = BasicRate;
+                       }
+                       else
+                       {
+                               if(BasicRate < QueryRate)
+                               {
+                                       QueryRate = BasicRate;
+                               }
+                       }
+               }
+       }
+
+       if(QueryRate == 0)
+       {
+               QueryRate = 12;
+               printk("No BasicRate found!!\n");
+       }
+       return QueryRate;
+}
 u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
 {
        PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
        u8 rate;
 
-       // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
-       if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
-               rate = 0x0c;
+       if(pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
+       {
+               rate = MgntQuery_TxRateExcludeCCKRates(ieee);
+       }
        else
                rate = ieee->basic_rate & 0x7f;
 
        if(rate == 0){
-               // 2005.01.26, by rcnjko.
                if(ieee->mode == IEEE_A||
                   ieee->mode== IEEE_N_5G||
                   (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
@@ -203,17 +236,6 @@ u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
                else
                        rate = 0x02;
        }
-
-       /*
-       // Data rate of ProbeReq is already decided. Annie, 2005-03-31
-       if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
-       {
-       if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
-       rate = 0x0c;
-       else
-       rate = 0x02;
-       }
-        */
        return rate;
 }
 
@@ -251,9 +273,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee
                                ieee->seq_ctrl[0]++;
 
                        /* avoid watchdog triggers */
-       //              ieee->dev->trans_start = jiffies;
                        ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
-                       //dev_kfree_skb_any(skb);//edit by thomas
                }
 
                spin_unlock_irqrestore(&ieee->lock, flags);
@@ -279,9 +299,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee
                        printk("%s():insert to waitqueue!\n",__FUNCTION__);
                        skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
                } else {
-                       //printk("TX packet!\n");
                        ieee->softmac_hard_start_xmit(skb,ieee->dev);
-                       //dev_kfree_skb_any(skb);//edit by thomas
                }
                spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
        }
@@ -293,16 +311,24 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
        short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
        struct ieee80211_hdr_3addr  *header =
                (struct ieee80211_hdr_3addr  *) skb->data;
+       u16 fc,type,stype;
         cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
 
+       fc = header->frame_control;
+       type = WLAN_FC_GET_TYPE(fc);
+       stype = WLAN_FC_GET_STYPE(fc);
+
+
+       if(stype != IEEE80211_STYPE_PSPOLL)
        tcb_desc->queue_index = MGNT_QUEUE;
+       else
+               tcb_desc->queue_index = HIGH_QUEUE;
        tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
        tcb_desc->RATRIndex = 7;
        tcb_desc->bTxDisableRateFallBack = 1;
        tcb_desc->bTxUseDriverAssingedRate = 1;
-       //printk("=============>%s()\n", __FUNCTION__);
        if(single){
-
+               if(!(type == IEEE80211_FTYPE_CTL)) {
                header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
                if (ieee->seq_ctrl[0] == 0xFFF)
@@ -310,12 +336,12 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
                else
                        ieee->seq_ctrl[0]++;
 
+               }
                /* avoid watchdog triggers */
-       //      ieee->dev->trans_start = jiffies;
                ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
 
        }else{
-
+               if(!(type == IEEE80211_FTYPE_CTL)) {
                header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
                if (ieee->seq_ctrl[0] == 0xFFF)
@@ -323,10 +349,10 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
                else
                        ieee->seq_ctrl[0]++;
 
+               }
                ieee->softmac_hard_start_xmit(skb,ieee->dev);
 
        }
-       //dev_kfree_skb_any(skb);//edit by thomas
 }
 
 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
@@ -373,24 +399,16 @@ void ieee80211_send_beacon(struct ieee80211_device *ieee)
        struct sk_buff *skb;
        if(!ieee->ieee_up)
                return;
-       //unsigned long flags;
        skb = ieee80211_get_beacon_(ieee);
 
        if (skb){
                softmac_mgmt_xmit(skb, ieee);
                ieee->softmac_stats.tx_beacons++;
-               //dev_kfree_skb_any(skb);//edit by thomas
        }
-//     ieee->beacon_timer.expires = jiffies +
-//             (MSECS( ieee->current_network.beacon_interval -5));
 
-       //spin_lock_irqsave(&ieee->beacon_lock,flags);
        if(ieee->beacon_txing && ieee->ieee_up){
-//             if(!timer_pending(&ieee->beacon_timer))
-//                     add_timer(&ieee->beacon_timer);
                mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
        }
-       //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
 }
 
 
@@ -414,7 +432,6 @@ void ieee80211_send_probe(struct ieee80211_device *ieee)
        if (skb){
                softmac_mgmt_xmit(skb, ieee);
                ieee->softmac_stats.tx_probe_rq++;
-               //dev_kfree_skb_any(skb);//edit by thomas
        }
 }
 
@@ -585,12 +602,8 @@ void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
 
 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
 {
-//     unsigned long flags;
-
-       //ieee->sync_scan_hurryup = 1;
 
        down(&ieee->scan_sem);
-//     spin_lock_irqsave(&ieee->lock, flags);
        ieee->scan_watch_dog = 0;
        if (ieee->scanning == 1){
                ieee->scanning = 0;
@@ -598,7 +611,6 @@ void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
                cancel_delayed_work(&ieee->softmac_scan_wq);
        }
 
-//     spin_unlock_irqrestore(&ieee->lock, flags);
        up(&ieee->scan_sem);
 }
 
@@ -672,7 +684,6 @@ inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *be
        memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
        memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
 
-       //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
        if(ieee->auth_mode == 0)
                auth->algorithm = WLAN_AUTH_OPEN;
        else if(ieee->auth_mode == 1)
@@ -689,6 +700,26 @@ inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *be
 
 }
 
+void constructWMMIE(u8* wmmie, u8* wmm_len,u8 oui_subtype)
+{
+       u8      szQoSOUI[] ={221, 0, 0x00, 0x50, 0xf2, 0x02, 0, 1};
+
+       if (oui_subtype == OUI_SUBTYPE_QOS_CAPABI)
+       {
+               szQoSOUI[0] = 46;
+               szQoSOUI[1] = *wmm_len;
+               memcpy(wmmie,szQoSOUI,3);
+               *wmm_len = 3;
+       }
+       else
+       {
+               szQoSOUI[1] = *wmm_len + 6;
+               szQoSOUI[6] = oui_subtype;
+               memcpy(wmmie, szQoSOUI, 8);
+               *(wmmie+8) = 0;
+               *wmm_len = 9;
+       }
+}
 
 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
 {
@@ -707,14 +738,18 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
        int wpa_ie_len = ieee->wpa_ie_len;
        u8 erpinfo_content = 0;
 
-       u8* tmp_ht_cap_buf;
+       u8* tmp_ht_cap_buf=NULL;
        u8 tmp_ht_cap_len=0;
-       u8* tmp_ht_info_buf;
+       u8* tmp_ht_info_buf=NULL;
        u8 tmp_ht_info_len=0;
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
        u8* tmp_generic_ie_buf=NULL;
        u8 tmp_generic_ie_len=0;
 
+
+       u8 wmmie[9] = {0};
+       u8 wmm_len = 0;
+
        if(rate_ex_len > 0) rate_ex_len+=2;
 
        if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
@@ -722,7 +757,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
        else
                atim_len = 0;
 
-#if 1
+#if 0
        if(ieee80211_is_54g(ieee->current_network))
                erp_len = 3;
        else
@@ -747,22 +782,35 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
                ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
        //HT ralated element
 #if 1
-       tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
-       tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
-       tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
-       tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
-       HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
-       HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
-
-
-        if(pHTInfo->bRegRT2RTAggregation)
-        {
-               tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
-               tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
-               HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
-        }
-//     printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len);
+       if(ieee->pHTInfo->bCurrentHTSupport){
+               tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
+               tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
+               tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
+               tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
+
+               HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
+
+               HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
+
+
+               if(pHTInfo->bRegRT2RTAggregation)
+               {
+                       tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
+                       tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
+                       HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
+               }
+       }
 #endif
+
+       if(ieee->qos_support){
+
+               if(ieee->iw_mode == IW_MODE_ADHOC)
+               {
+                       wmm_len = 1;
+                       constructWMMIE(wmmie,&wmm_len,OUI_SUBTYPE_WMM_INFO);
+               }
+       }
+
        beacon_size = sizeof(struct ieee80211_probe_response)+2+
                ssid_len
                +3 //channel
@@ -825,7 +873,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
        u16 val16;
                *(tag++) = MFIE_TYPE_IBSS_SET;
                *(tag++) = 2;
-               //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
                 val16 = cpu_to_le16(ieee->current_network.atim_window);
                memcpy((u8 *)tag, (u8 *)&val16, 2);
                tag+=2;
@@ -854,7 +901,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
                tag += wpa_ie_len;
        }
 
-       //skb->dev = ieee->dev;
        return skb;
 }
 
@@ -996,19 +1042,39 @@ void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
 }
 
 
+inline int SecIsInPMKIDList(struct ieee80211_device *ieee, u8 *bssid)
+{
+       int i = 0;
+
+       do
+       {
+               if ((ieee->PMKIDList[i].bUsed) && (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0))
+               {
+                       break;
+               }
+               else
+               {
+                       i++;
+               }
+       } while (i < NUM_PMKID_CACHE);
+
+       if (i == NUM_PMKID_CACHE)
+       {
+               i = -1;
+       }
+       else
+       {
+       }
+
+       return (i);
+
+}
 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
 {
        struct sk_buff *skb;
-       //unsigned long flags;
 
        struct ieee80211_assoc_request_frame *hdr;
        u8 *tag;//,*rsn_ie;
-       //short info_addr = 0;
-       //int i;
-       //u16 suite_count = 0;
-       //u8 suit_select = 0;
-       //unsigned int wpa_len = beacon->wpa_ie_len;
-       //for HT
        u8* ht_cap_buf = NULL;
        u8 ht_cap_len=0;
        u8* realtek_ie_buf=NULL;
@@ -1019,6 +1085,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
        unsigned int cxvernum_ie_len=0;
        struct ieee80211_crypt_data* crypt;
        int encrypt;
+       int     PMKCacheIdx;
 
        unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
        unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
@@ -1060,6 +1127,14 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
        {
                cxvernum_ie_len = 5+2;
        }
+
+       PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid);
+       if (PMKCacheIdx >= 0)
+       {
+               wpa_ie_len += 18;
+               printk("[PMK cache]: WPA2 IE length: %x\n", wpa_ie_len);
+       }
+
        len = sizeof(struct ieee80211_assoc_request_frame)+ 2
                + beacon->ssid_len//essid tagged val
                + rate_len//rates tagged val
@@ -1187,6 +1262,13 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
        tag = skb_put(skb, wpa_ie_len);
        if (wpa_ie_len){
                memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
+               if (PMKCacheIdx >= 0)
+               {
+                       tag = skb_put(skb, 18);
+                       *tag = 1;
+                       *(tag + 1) = 0;
+                       memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID, 16);
+               }
        }
 
        tag = skb_put(skb,wmm_info_len);
@@ -1215,8 +1297,6 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
                        memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
                }
        }
-//     printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
        return skb;
 }
 
@@ -1271,7 +1351,6 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee)
        else{
                ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
                IEEE80211_DEBUG_MGMT("Sending authentication request\n");
-               //printk(KERN_WARNING "Sending authentication request\n");
                softmac_mgmt_xmit(skb, ieee);
                //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
                if(!timer_pending(&ieee->associate_timer)){
@@ -1287,7 +1366,6 @@ void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge,
        u8 *c;
        struct sk_buff *skb;
        struct ieee80211_network *beacon = &ieee->current_network;
-//     int hlen = sizeof(struct ieee80211_authentication);
 
        ieee->associate_seq++;
        ieee->softmac_stats.tx_auth_rq++;
@@ -1307,7 +1385,6 @@ void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge,
 
                softmac_mgmt_xmit(skb, ieee);
                mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
-               //dev_kfree_skb_any(skb);//edit by thomas
        }
        kfree(challenge);
 }
@@ -1328,7 +1405,6 @@ void ieee80211_associate_step2(struct ieee80211_device *ieee)
        else{
                softmac_mgmt_xmit(skb, ieee);
                mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
-               //dev_kfree_skb_any(skb);//edit by thomas
        }
 }
 
@@ -1356,7 +1432,6 @@ void ieee80211_associate_complete_wq(struct work_struct *work)
        {
                printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
                memset(ieee->dot11HTOperationalRateSet, 0, 16);
-               //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
        }
        ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
        // To prevent the immediately calling watch_dog after association.
@@ -1388,7 +1463,6 @@ void ieee80211_associate_complete(struct ieee80211_device *ieee)
        del_timer_sync(&ieee->associate_timer);
 
        ieee->state = IEEE80211_LINKED;
-       //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
        queue_work(ieee->wq, &ieee->associate_complete_wq);
 }
 
@@ -1404,9 +1478,14 @@ void ieee80211_associate_procedure_wq(struct work_struct *work)
 
        ieee80211_stop_scan(ieee);
        printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
-       //ieee->set_chan(ieee->dev, ieee->current_network.channel);
        HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
 
+       if(ieee->eRFPowerState == eRfOff)
+       {
+            printk("=============>%s():Rf state is eRfOff, schedule ipsleave wq again,return\n",__FUNCTION__);
+               up(&ieee->wx_sem);
+               return;
+       }
        ieee->associate_seq = 1;
        ieee80211_associate_step1(ieee);
 
@@ -1432,14 +1511,16 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee
        if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
                return;
 
+       if ((ieee->iw_mode == IW_MODE_ADHOC) && (net->channel > ieee->ibss_maxjoin_chal))
+               return;
 
        if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
                /* if the user specified the AP MAC, we need also the essid
                 * This could be obtained by beacons or, if the network does not
                 * broadcast it, it can be put manually.
                 */
-               apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
-               ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
+               apset = ieee->wap_set;
+               ssidset = ieee->ssid_set;
                ssidbroad =  !(net->ssid_len == 0 || net->ssid[0]== '\0');
                apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
                ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
@@ -1480,7 +1561,6 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee
                                        ieee->AsocRetryCount = 0;
                                        //for HT by amy 080514
                                        if((ieee->current_network.qos_data.supported == 1) &&
-                                         // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
                                           ieee->current_network.bssht.bdSupportHT)
 /*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
                                        {
@@ -1508,7 +1588,6 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee
                                                printk(KERN_INFO"Using B rates\n");
                                        }
                                        memset(ieee->dot11HTOperationalRateSet, 0, 16);
-                                       //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
                                        ieee->state = IEEE80211_LINKED;
                                }
 
@@ -1598,6 +1677,16 @@ static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb,
        if (skb->len < sizeof (struct ieee80211_hdr_3addr  ))
                return -1; /* corrupted */
 
+        if((memcmp(header->addr3,ieee->current_network.bssid,ETH_ALEN) != 0)&&
+                (memcmp(header->addr3,"\xff\xff\xff\xff\xff\xff",ETH_ALEN) != 0)) {
+            return -1;
+        }
+
+        if(memcmp(header->addr3,ieee->current_network.bssid,ETH_ALEN) == 0) {
+        }
+
+        if(memcmp(header->addr3,"\xff\xff\xff\xff\xff\xff",ETH_ALEN) == 0) {
+        }
        memcpy(src,header->addr2, ETH_ALEN);
 
        skbend = (u8*)skb->data + skb->len;
@@ -1615,7 +1704,6 @@ static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb,
                tag++; /* point to the next tag */
        }
 
-       //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
        if (ssidlen == 0) return 1;
 
        if (!ssid) return 1; /* ssid not found in tagged param */
@@ -1673,11 +1761,8 @@ ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
        u8 dest[ETH_ALEN];
 
-       //IEEE80211DMESG("Rx probe");
        ieee->softmac_stats.rx_probe_rq++;
-       //DMESG("Dest is "MACSTR, MAC2STR(dest));
        if (probe_rq_parse(ieee, skb, dest)){
-               //IEEE80211DMESG("Was for me!");
                ieee->softmac_stats.tx_probe_rs++;
                ieee80211_resp_to_probe(ieee, dest);
        }
@@ -1688,14 +1773,12 @@ ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
        u8 dest[ETH_ALEN];
        int status;
-       //IEEE80211DMESG("Rx probe");
        ieee->softmac_stats.rx_auth_rq++;
 
        status = auth_rq_parse(skb, dest);
        if (status != -1) {
                ieee80211_resp_to_auth(ieee, status, dest);
        }
-       //DMESG("Dest is "MACSTR, MAC2STR(dest));
 
 }
 
@@ -1704,7 +1787,6 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
 
        u8 dest[ETH_ALEN];
-       //unsigned long flags;
 
        ieee->softmac_stats.rx_ass_rq++;
        if (assoc_rq_parse(skb,dest) != -1){
@@ -1739,7 +1821,6 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti
                return 0;
        */
        dtim = ieee->current_network.dtim_data;
-       //printk("DTIM\n");
        if(!(dtim & IEEE80211_DTIM_VALID))
                return 0;
        timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
@@ -1762,7 +1843,6 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti
        if(time_l){
                *time_l = ieee->current_network.last_dtim_sta_time[0]
                        + (ieee->current_network.beacon_interval);
-               //      * ieee->current_network.dtim_period) * 1000;
        }
 
        if(time_h){
@@ -1790,7 +1870,6 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
                ieee->iw_mode != IW_MODE_INFRA ||
                ieee->state != IEEE80211_LINKED)){
 
-       //      #warning CHECK_LOCK_HERE
                spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
 
                ieee80211_sta_wakeup(ieee, 1);
@@ -1809,7 +1888,6 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
                        ieee->enter_sleep_state(ieee->dev,th,tl);
 
                else if(ieee->sta_sleep == 0){
-               //      printk("send null 1\n");
                        spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
 
                        if(ieee->ps_is_queue_empty(ieee->dev)){
@@ -1918,8 +1996,6 @@ void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb
                        ieee80211_rx_DELBA(ieee, skb);
                        break;
                default:
-//                     if (net_ratelimit())
-//                     IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
                        break;
        }
        return;
@@ -1936,7 +2012,6 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
        int chlen=0;
        int aid;
        struct ieee80211_assoc_response_frame *assoc_resp;
-//     struct ieee80211_info_element *info_element;
        bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
 
        if(!ieee->proto_started)
@@ -2095,8 +2170,6 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
                                ieee->softmac_stats.reassoc++;
                                ieee->is_roaming = true;
                                ieee80211_disassociate(ieee);
-                       //      notify_wx_assoc_event(ieee);
-                               //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
                                RemovePeerTS(ieee, header->addr2);
                                if(ieee->LedControlHandler != NULL)
                                        ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK); //added by amy for LED 090318
@@ -2111,7 +2184,6 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
                        break;
        }
 
-       //dev_kfree_skb_any(skb);
        return 0;
 }
 
@@ -2163,22 +2235,16 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
                        /* as for the completion function, it does not need
                         * to check it any more.
                         * */
-                       //printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index));
-                       //ieee80211_rtl_stop_queue(ieee);
                        skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
                }else{
                        ieee->softmac_data_hard_start_xmit(
                                        txb->fragments[i],
                                        ieee->dev,ieee->rate);
-                       //ieee->stats.tx_packets++;
-                       //ieee->stats.tx_bytes += txb->fragments[i]->len;
-                       //ieee->dev->trans_start = jiffies;
                }
        }
 #endif
        ieee80211_txb_free(txb);
 
-//exit:
        spin_unlock_irqrestore(&ieee->lock,flags);
 
 }
@@ -2197,9 +2263,7 @@ void ieee80211_resume_tx(struct ieee80211_device *ieee)
                        ieee->softmac_data_hard_start_xmit(
                                ieee->tx_pending.txb->fragments[i],
                                ieee->dev,ieee->rate);
-                               //(i+1)<ieee->tx_pending.txb->nr_frags);
                        ieee->stats.tx_packets++;
-               //      ieee->dev->trans_start = jiffies;
                }
        }
 
@@ -2249,7 +2313,6 @@ void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
                                ieee->seq_ctrl[0]++;
 
                        ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
-                       //dev_kfree_skb_any(skb);//edit by thomas
                }
        }
        if (!ieee->queue_stop && ieee->tx_pending.txb)
@@ -2267,15 +2330,12 @@ exit :
 
 void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
 {
-       //unsigned long flags;
-       //spin_lock_irqsave(&ieee->lock,flags);
 
        if (! netif_queue_stopped(ieee->dev)){
                netif_stop_queue(ieee->dev);
                ieee->softmac_stats.swtxstop++;
        }
        ieee->queue_stop = 1;
-       //spin_unlock_irqrestore(&ieee->lock,flags);
 
 }
 
@@ -2362,7 +2422,7 @@ void ieee80211_start_ibss_wq(struct work_struct *work)
 
 //     if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
        if (ieee->state == IEEE80211_NOLINK)
-               ieee->current_network.channel = 6;
+               ieee->current_network.channel = ieee->IbssStartChnl;
        /* if not then the state is not linked. Maybe the user swithced to
         * ad-hoc mode just after being in monitor mode, or just after
         * being very few time in managed mode (so the card have had no
@@ -2509,11 +2569,9 @@ void ieee80211_disassociate(struct ieee80211_device *ieee)
        ieee->state = IEEE80211_NOLINK;
        ieee->is_set_key = false;
 
-       //LZM for usb dev crash.
-       //ieee->link_change(ieee->dev);
        queue_delayed_work(ieee->wq, &ieee->link_change_wq, 0);
 
-       //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+
        notify_wx_assoc_event(ieee);
 
 }
@@ -2657,8 +2715,6 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee)
 
        if (ieee->current_network.beacon_interval == 0)
                ieee->current_network.beacon_interval = 100;
-//     printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
-//     ieee->set_chan(ieee->dev,ieee->current_network.channel);
 
                for(i = 0; i < 17; i++) {
          ieee->last_rxseq_num[i] = -1;
@@ -2721,7 +2777,6 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
        ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
        ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
        ieee->Regdot11HTOperationalRateSet[4]= 0x01;
-       //added by amy
        ieee->actscanning = false;
        ieee->beinretry = false;
        ieee->is_set_key = false;
@@ -2891,8 +2946,6 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
 
        if (ieee->set_security)
                ieee->set_security(ieee->dev, &sec);
-       //else
-       //      ret = -EOPNOTSUPP;
 
        return ret;
 }
@@ -3173,7 +3226,6 @@ int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_poin
        int ret=0;
 
        down(&ieee->wx_sem);
-       //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
 
        if (p->length < sizeof(struct ieee_param) || !p->pointer){
                ret = -EINVAL;
index 484c3aba5cb3a7e579cdd5aef5cd27427fd1c9c4..a6a5d68df3aade503b7034aaeb792f4d6c8e4c2d 100644 (file)
@@ -32,7 +32,6 @@
 ******************************************************************************/
 
 #include <linux/compiler.h>
-//#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -208,7 +207,6 @@ int ieee80211_encrypt_fragment(
        /* To encrypt, frame format is:
         * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
 
-       // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
        /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
         * call both MSDU and MPDU encryption functions from here. */
        atomic_inc(&crypt->refcnt);
@@ -231,7 +229,6 @@ int ieee80211_encrypt_fragment(
 
 
 void ieee80211_txb_free(struct ieee80211_txb *txb) {
-       //int i;
        if (unlikely(!txb))
                return;
        kfree(txb);
@@ -280,7 +277,6 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
        if (eth->h_proto != htons(ETH_P_IP))
                return 0;
 
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
        ip = ip_hdr(skb);
 
        switch (ip->tos & 0xfc) {
@@ -681,10 +677,8 @@ int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
                if (encrypt)
                        fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
                else
-
                         fc = IEEE80211_FTYPE_DATA;
 
-               //if(ieee->current_network.QoS_Enable)
                if(qos_actived)
                        fc |= IEEE80211_STYPE_QOS_DATA;
                else
@@ -765,7 +759,6 @@ int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
                txb->encrypted = encrypt;
                txb->payload_size = bytes;
 
-               //if (ieee->current_network.QoS_Enable)
                if(qos_actived)
                {
                        txb->queue_index = UP2AC(skb->priority);
@@ -812,7 +805,6 @@ int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
                                /* The last fragment takes the remaining length */
                                bytes = bytes_last_frag;
                        }
-                       //if(ieee->current_network.QoS_Enable)
                        if(qos_actived)
                        {
                                // add 1 only indicate to corresponding seq number control 2006/7/12
@@ -889,7 +881,6 @@ int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
                if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
                        tcb_desc->data_rate = ieee->basic_rate;
                else
-                       //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
                        tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
                ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
                ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
@@ -897,8 +888,6 @@ int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
                ieee80211_query_BandwidthMode(ieee, tcb_desc);
                ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
                ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
-//             IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
-               //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
 #endif
        }
        spin_unlock_irqrestore(&ieee->lock, flags);
index 2ce5bd543eaec3bf79d3be586a4b2f37d4be9ab6..984a3608561cf754d7038da29394cd93614ec1ae 100644 (file)
@@ -77,7 +77,6 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
        /* Add the ESSID */
        iwe.cmd = SIOCGIWESSID;
        iwe.u.data.flags = 1;
-//     if (network->flags & NETWORK_EMPTY_ESSID) {
        if (network->ssid_len == 0) {
                iwe.u.data.length = sizeof("<hidden>");
                 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
@@ -240,9 +239,7 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
        unsigned long flags;
 
        char *ev = extra;
-//     char *stop = ev + IW_SCAN_MAX_DATA;
        char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
-       //char *stop = ev + IW_SCAN_MAX_DATA;
        int i = 0;
        int err = 0;
        IEEE80211_DEBUG_WX("Getting scan\n");
@@ -511,7 +508,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         struct ieee80211_security sec = {
                 .flags = 0,
         };
-       //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
         idx = encoding->flags & IW_ENCODE_INDEX;
         if (idx) {
                 if (idx < 1 || idx > WEP_KEYS)
@@ -562,7 +558,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         }
 
        sec.enabled = 1;
-    //    sec.encrypt = 1;
 
         switch (ext->alg) {
         case IW_ENCODE_ALG_WEP:
@@ -580,7 +575,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                 ret = -EINVAL;
                 goto done;
         }
-       printk("alg name:%s\n",alg);
+       IEEE80211_DEBUG_WX("alg name: %s\n", alg);
 
         ops = ieee80211_get_crypto_ops(alg);
         if (ops == NULL)
@@ -624,8 +619,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                 goto done;
         }
 #if 1
- //skip_host_crypt:
-       //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
                 ieee->tx_keyidx = idx;
                 sec.active_key = idx;
@@ -633,7 +626,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         }
 
         if (ext->alg != IW_ENCODE_ALG_NONE) {
-                //memcpy(sec.keys[idx], ext->key, ext->key_len);
                 sec.key_sizes[idx] = ext->key_len;
                 sec.flags |= (1 << idx);
                 if (ext->alg == IW_ENCODE_ALG_WEP) {
@@ -690,7 +682,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
        switch (data->flags & IW_AUTH_INDEX) {
         case IW_AUTH_WPA_VERSION:
             /*need to support wpa2 here*/
-               //printk("wpa version:%x\n", data->value);
                break;
         case IW_AUTH_CIPHER_PAIRWISE:
         case IW_AUTH_CIPHER_GROUP:
@@ -708,8 +699,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
                break;
 
        case IW_AUTH_80211_AUTH_ALG:
-               //printk("======>%s():data->value is %d\n",__FUNCTION__,data->value);
-       //      ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
                if(data->value & IW_AUTH_ALG_SHARED_KEY){
                        ieee->open_wep = 0;
                        ieee->auth_mode = 1;
@@ -721,17 +710,14 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
                else if(data->value & IW_AUTH_ALG_LEAP){
                        ieee->open_wep = 1;
                        ieee->auth_mode = 2;
-                       //printk("hahahaa:LEAP\n");
                }
                else
                        return -EINVAL;
-               //printk("open_wep:%d\n", ieee->open_wep);
                break;
 
 #if 1
        case IW_AUTH_WPA_ENABLED:
                ieee->wpa_enabled = (data->value)?1:0;
-               //printk("enable wpa:%d\n", ieee->wpa_enabled);
                break;
 
 #endif
@@ -755,7 +741,6 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
 
        if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
        {
-       //      printk("return error out, len:%d\n", len);
        return -EINVAL;
        }
 
index 8ddc8bf9dc268332b43bf47b152411fe0ff31b48..1c2a40b75a19e1d1d2cd183b32487d132a435b77 100644 (file)
@@ -1,3 +1,21 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #ifndef _BATYPE_H_
 #define _BATYPE_H_
 
 #define        DELBA_REASON_END_BA                     37
 #define        DELBA_REASON_UNKNOWN_BA 38
 #define        DELBA_REASON_TIMEOUT                    39
-/*  whether need define BA Action frames here?
-struct ieee80211_ADDBA_Req{
-       struct ieee80211_header_data header;
-       u8      category;
-       u8
-} __attribute__ ((packed));
-*/
-//Is this need?I put here just to make it easier to define structure BA_RECORD //WB
+
 typedef union _SEQUENCE_CONTROL{
        u16 ShortData;
        struct
@@ -65,5 +76,4 @@ typedef struct _BA_RECORD {
        SEQUENCE_CONTROL        BaStartSeqCtrl;
 } BA_RECORD, *PBA_RECORD;
 
-#endif //end _BATYPE_H_
-
+#endif
index 8c37dd124fc9fd08aaaa96daa5ccd278e8b6e7da..ca611faf17bc4f91e47717496281c2de503d6bc3 100644 (file)
@@ -1,9 +1,21 @@
-/********************************************************************************************************************************
- * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is
- * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send
- * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
- * WB 2008-05-27
- * *****************************************************************************************************************************/
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #include "ieee80211.h"
 #include "rtl819x_BA.h"
 
@@ -112,7 +124,6 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
        u8* tag = NULL;
        u16 tmp = 0;
        u16 len = ieee->tx_headroom + 9;
-       //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
        IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
        if (pBA == NULL||ieee == NULL)
        {
@@ -138,7 +149,6 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
 
        BAReq->frame_control = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
 
-       //tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
        tag = (u8*)skb_put(skb, 9);
        *tag ++= ACT_CAT_BA;
        *tag ++= type;
@@ -171,7 +181,6 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
 
        IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
        return skb;
-       //return NULL;
 }
 
 /********************************************************************************************************************
@@ -196,7 +205,6 @@ static struct sk_buff* ieee80211_DELBA(
         struct ieee80211_hdr_3addr* Delba = NULL;
        u8* tag = NULL;
        u16 tmp = 0;
-       //len = head len + DELBA Parameter Set(2) + Reason Code(2)
        u16 len = 6 + ieee->tx_headroom;
 
        if (net_ratelimit())
@@ -213,7 +221,6 @@ static struct sk_buff* ieee80211_DELBA(
                IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
                return NULL;
        }
-//     memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
        skb_reserve(skb, ieee->tx_headroom);
 
        Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
@@ -258,9 +265,6 @@ void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8*     dst, PBA_RECORD
        if (skb)
        {
                softmac_mgmt_xmit(skb, ieee);
-               //add statistic needed here.
-               //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
-               //WB
        }
        else
        {
@@ -284,7 +288,6 @@ void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD
        if (skb)
        {
                softmac_mgmt_xmit(skb, ieee);
-               //same above
        }
        else
        {
@@ -311,7 +314,6 @@ void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA
        if (skb)
        {
                softmac_mgmt_xmit(skb, ieee);
-               //same above
        }
        else
        {
@@ -361,8 +363,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
 //some other capability is not ready now.
        if(     (ieee->current_network.qos_data.active == 0) ||
                (ieee->pHTInfo->bCurrentHTSupport == false) ||
-               (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) //||
-       //      (ieee->pStaQos->bEnableRxImmBA == false)        )
+               (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ))
        {
                rc = ADDBA_STATUS_REFUSED;
                IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
@@ -394,7 +395,6 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
                goto OnADDBAReq_Fail;
        }
                // Admit the ADDBA Request
-       //
        DeActivateBAEntry(ieee, pBA);
        pBA->DialogToken = *pDialogToken;
        pBA->BaParamSet = *pBaParamSet;
@@ -406,10 +406,9 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
        pBA->BaParamSet.field.BufferSize = 1;
        else
        pBA->BaParamSet.field.BufferSize = 32;
-       ActivateBAEntry(ieee, pBA, 0);//pBA->BaTimeoutValue);
+       ActivateBAEntry(ieee, pBA, 0);
        ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
 
-       // End of procedure.
        return 0;
 
 OnADDBAReq_Fail:
@@ -541,11 +540,11 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
                pAdmittedBA->BaParamSet = *pBaParamSet;
                DeActivateBAEntry(ieee, pAdmittedBA);
                ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
-       }
-       else
-       {
-               // Delay next ADDBA process.
+       } else {
                pTS->bAddBaReqDelayed = true;
+               pTS->bDisable_AddBa = true;
+               ReasonCode = DELBA_REASON_END_BA;
+               goto OnADDBARsp_Reject;
        }
 
        // End of procedure
@@ -635,7 +634,6 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
                pTxTs->bAddBaReqInProgress = false;
                pTxTs->bAddBaReqDelayed = false;
                del_timer_sync(&pTxTs->TsAddBaTimer);
-               //PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
                TxTsDeleteBA(ieee, pTxTs);
        }
        return 0;
index a97c901edbf53874a82ac2cea242e053cf95e0a2..17121891433257b793a95bd8ada33d714d2bdbe3 100644 (file)
@@ -1,3 +1,21 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #ifndef _RTL819XU_HTTYPE_H_
 #define _RTL819XU_HTTYPE_H_
 
@@ -381,8 +399,7 @@ typedef struct _BSS_HT{
        u16                                     bdHTInfoLen;
 
        HT_SPEC_VER                             bdHTSpecVer;
-       //HT_CAPABILITY_ELE                     bdHTCapEle;
-       //HT_INFORMATION_ELE            bdHTInfoEle;
+       HT_CHANNEL_WIDTH                        bdBandWidth;
 
        u8                                      bdRT2RTAggregation;
        u8                                      bdRT2RTLongSlotTime;
@@ -406,7 +423,7 @@ typedef struct _MIMO_EVM{
 
 typedef struct _FALSE_ALARM_STATISTICS{
        u32     Cnt_Parity_Fail;
-       u32    Cnt_Rate_Illegal;
+       u32     Cnt_Rate_Illegal;
        u32     Cnt_Crc8_fail;
        u32     Cnt_all;
 }FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
@@ -476,10 +493,9 @@ typedef enum _HT_IOT_ACTION{
        HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
        HT_IOT_ACT_FORCED_RTS = 0x00000400,
        HT_IOT_ACT_AMSDU_ENABLE = 0x00000800,
-       HT_IOT_ACT_MID_HIGHPOWER = 0x00001000,
-       HT_IOT_ACT_REJECT_ADDBA_REQ = 0x00002000,
-       HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT = 0x00004000,
-       HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00008000,
+       HT_IOT_ACT_REJECT_ADDBA_REQ = 0x00001000,
+       HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT = 0x00002000,
+       HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000,
 
        HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000,
        HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000,
@@ -487,12 +503,19 @@ typedef enum _HT_IOT_ACTION{
        HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000,
        HT_IOT_ACT_TX_NO_AGGREGATION = 0x00100000,
        HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000,
+       
+        HT_IOT_ACT_MID_HIGHPOWER = 0x00400000,
+        HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000,
+        
+        HT_IOT_ACT_DISABLE_CCK_RATE = 0x01000000,
+       HT_IOT_ACT_FORCED_ENABLE_BE_TXOP = 0x02000000,
+       HT_IOT_ACT_WA_IOT_Broadcom = 0x04000000,
 }HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
 
 typedef enum _HT_IOT_RAFUNC{
+       HT_IOT_RAFUNC_DISABLE_ALL = 0x00,
        HT_IOT_RAFUNC_PEER_1R = 0x01,
        HT_IOT_RAFUNC_TX_AMSDU = 0x02,
-       HT_IOT_RAFUNC_DISABLE_ALL = 0x80,
 }HT_IOT_RAFUNC, *PHT_IOT_RAFUNC;
 
 typedef enum _RT_HT_CAP{
@@ -504,5 +527,4 @@ typedef enum _RT_HT_CAP{
        RT_HT_CAP_USE_92SE = 0x20,
 }RT_HT_CAPBILITY, *PRT_HT_CAPBILITY;
 
-#endif //_RTL819XU_HTTYPE_H_
-
+#endif
index 01114c5181bba6376bf8e81cea1a03e36c327a13..cfd9a1a5b38d91580da924e6a66a2e8cfd4174bb 100644 (file)
@@ -1,5 +1,21 @@
-
-//As this function is mainly ported from Windows driver, so leave the name little changed. If any confusion caused, tell me. Created by WB. 2008.05.08
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #include "ieee80211.h"
 #include "rtl819x_HT.h"
 u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -8,32 +24,31 @@ u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0
 
 u16 MCS_DATA_RATE[2][2][77] =
        {       {       {13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260,
-                       39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520,
+                       39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520, 
                        0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195,
-                       195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260,
-                       286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429},                       // Long GI, 20MHz
-                       {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
-                       43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578,
-                       0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217,
-                       217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289,
-                       318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477}        },              // Short GI, 20MHz
-               {       {27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,
-                       81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080,
-                       12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405,
-                       405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540,
-                       594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891},       // Long GI, 40MHz
-                       {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,
-                       90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200,
-                       13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450,
-                       450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600,
-                       660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990}        }       // Short GI, 40MHz
+                       195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260, 
+                       286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429},                       
+                       {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, 
+                       43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578, 
+                       0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217, 
+                       217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289, 
+                       318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477}        },              
+               {       {27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, 
+                       81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080, 
+                       12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405, 
+                       405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540, 
+                       594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891},       
+                       {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, 
+                       90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200, 
+                       13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450, 
+                       450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600, 
+                       660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990}        }       
        };
 
 static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
 static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
 static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
-static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
-static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};      //cosa 03202008
+static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};      
 static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
 static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
 static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
@@ -41,10 +56,9 @@ static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
 static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
 static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
 static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
+static u8 NETGEAR_BROADCOM[3] = {0x00, 0x1f, 0x33};
 static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
-// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
-// code in other place??
-//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
+
 /********************************************************************************************************************
  *function:  This function update default settings in pHTInfo structure
  *   input:  PRT_HIGH_THROUGHPUT       pHTInfo
@@ -55,10 +69,7 @@ static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
 void HTUpdateDefaultSetting(struct ieee80211_device* ieee)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
-       //const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo;
 
-       //printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p,  offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo));
-       //printk("===>ieee:%p,\n", ieee);
        // ShortGI support
        pHTInfo->bRegShortGI20MHz= 1;
        pHTInfo->bRegShortGI40MHz= 1;
@@ -291,7 +302,6 @@ u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate)
  * *****************************************************************************************************************/
 u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate)
 {
-       //PRT_HIGH_THROUGHPUT   pHTInfo = ieee->pHTInfo;
        u16             CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c};
        u8      is40MHz = 0;
        u8      isShortGI = 0;
@@ -307,28 +317,24 @@ u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate)
                        is40MHz = 0;
                        isShortGI = 0;
 
-                     // nDataRate = nDataRate - 12;
                }
                else if(nDataRate >=0x20  && nDataRate <= 0x2f ) //(27, 44)
                {
                        is40MHz = 1;
                        isShortGI = 0;
 
-                       //nDataRate = nDataRate - 28;
                }
                else if(nDataRate >= 0x30  && nDataRate <= 0x3f )  //(43, 60)
                {
                        is40MHz = 0;
                        isShortGI = 1;
 
-                       //nDataRate = nDataRate - 44;
                }
                else if(nDataRate >= 0x40  && nDataRate <= 0x4f ) //(59, 76)
                {
                        is40MHz = 1;
                        isShortGI = 1;
 
-                       //nDataRate = nDataRate - 60;
                }
                return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
        }
@@ -351,7 +357,6 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
        else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
                    (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
                    (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
-                   (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
                    (net->broadcom_cap_exist))
                  retValue = true;
        else if(net->bssht.bdRT2RTAggregation)
@@ -379,13 +384,15 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee)
                if(net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE){
                        pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE;
                }
+               if(net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP){
+                       pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP;
+               }
        }
        else if(net->broadcom_cap_exist)
                pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
        else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
                        (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
-                       (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
-                       (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) )
+                       (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0))
                pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
        else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
                        (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
@@ -398,7 +405,7 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee)
                (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0)||
                (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0))
                pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
-       else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
+       else if ((memcmp(net->bssid, CISCO_BROADCOM, 3)==0)||net->cisco_cap_exist)
                pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
        else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
                  net->marvell_cap_exist)
@@ -439,25 +446,6 @@ u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
 bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee)
 {
        bool retValue = false;
-
-#ifdef TODO
-       // Apply for 819u only
-#if (HAL_CODE_BASE==RTL8192)
-
-#if (DEV_BUS_TYPE == USB_INTERFACE)
-       // Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15
-       retValue = true;
-#elif (DEV_BUS_TYPE == PCI_INTERFACE)
-       // Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12
-//     if(pBssDesc->bCiscoCapExist)
-//             retValue = false;
-//     else
-               retValue = false;
-#endif
-#endif
-#endif
-       // Jerry Chang suggest that 8190 1x2 does not need to disable MCS15
-
        return retValue;
 }
 
@@ -624,17 +612,11 @@ HTIOCActRejcectADDBARequest(struct ieee80211_network *network)
   HTIOTActIsEDCABiasRx(struct ieee80211_device* ieee,struct ieee80211_network *network)
 {
        u8      retValue = 0;
-       //if(IS_HARDWARE_TYPE_8192SU(Adapter))
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
        {
-//#if UNDER_VISTA
-//             if(pBssDesc->Vender==HT_IOT_PEER_ATHEROS ||
-//                     pBssDesc->Vender==HT_IOT_PEER_RALINK)
-//#else
                if(pHTInfo->IOTPeer==HT_IOT_PEER_ATHEROS ||
                   pHTInfo->IOTPeer==HT_IOT_PEER_BROADCOM ||
                   pHTInfo->IOTPeer==HT_IOT_PEER_RALINK)
-//#endif
                        return 1;
 
        }
@@ -649,7 +631,6 @@ HTIOTActDisableShortGI(struct ieee80211_device* ieee,struct ieee80211_network *n
 
        if(pHTInfo->IOTPeer==HT_IOT_PEER_RALINK)
        {
-               if(network->bssht.bdHT1R)
                        retValue = 1;
        }
 
@@ -662,9 +643,10 @@ HTIOTActDisableHighPower(struct ieee80211_device* ieee,struct ieee80211_network
        u8      retValue = 0;
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 
-       if(pHTInfo->IOTPeer==HT_IOT_PEER_RALINK)
+       if(pHTInfo->IOTPeer==HT_IOT_PEER_RALINK ||
+               pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK ||
+               pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK_92SE)
        {
-               if(network->bssht.bdHT1R)
                        retValue = 1;
        }
 
@@ -718,8 +700,7 @@ HTIOTActIsTxNoAggregation(struct ieee80211_device* ieee,struct ieee80211_network
                (KEY_TYPE_WEP40 == ieee->group_key_type) ||
                (KEY_TYPE_TKIP == ieee->pairwise_key_type) )
        {
-               if(pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK ||
-                   pHTInfo->IOTPeer==HT_IOT_PEER_UNKNOWN)
+               if(pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK)
                        retValue = 1;
        }
 
@@ -751,10 +732,11 @@ bool HTIOCActAllowPeerAggOnePacket(struct ieee80211_device* ieee,struct ieee8021
 {
        bool    retValue = false;
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
+       if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
        {
-               if(pHTInfo->IOTPeer == HT_IOT_PEER_MARVELL)
+               if((memcmp(network->bssid, NETGEAR_BROADCOM, 3)==0)
+                       && (network->bssht.bdBandWidth == HT_CHANNEL_WIDTH_20_40))
                        return true;
-
        }
        return retValue;
 }
@@ -783,7 +765,6 @@ void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u
 {
        PRT_HIGH_THROUGHPUT     pHT = ieee->pHTInfo;
        PHT_CAPABILITY_ELE      pCapELE = NULL;
-       //u8 bIsDeclareMCS13;
 
        if ((posHTCap == NULL) || (pHT == NULL))
        {
@@ -813,13 +794,11 @@ void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u
                pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
        }
 
-//     pCapELE->ChlWidth               = (pHT->bRegBW40MHz?1:0);
        pCapELE->MimoPwrSave            = pHT->SelfMimoPs;
        pCapELE->GreenField             = 0; // This feature is not supported now!!
        pCapELE->ShortGI20Mhz           = 1; // We can receive Short GI!!
        pCapELE->ShortGI40Mhz           = 1; // We can receive Short GI!!
-       //DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r",
-               //pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz);
+
        pCapELE->TxSTBC                 = 1;
        pCapELE->RxSTBC                 = 0;
        pCapELE->DelayBA                = 0;    // Do not support now!!
@@ -879,12 +858,6 @@ void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u
        else
                *len = 26 + 2;
 
-
-
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2);
-
-       //Print each field in detail. Driver should not print out this message by default
-//     HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()");
        return;
 
 }
@@ -938,8 +911,6 @@ void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* le
                //STA should not generate High Throughput Information Element
                *len = 0;
        }
-       //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2);
-       //HTDebugHTInfo(posHTInfo, "HTConstructInforElement");
        return;
 }
 
@@ -1005,7 +976,6 @@ void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg,
        */
 
 #else
-       // Do Nothing
 #endif
 
        posRT2RTAgg->Length = 6;
@@ -1188,12 +1158,7 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
                return;
        }
        IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE));
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE));
 
-//     HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq");
-//     HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq");
-       //
        if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap)))
                pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
        else
@@ -1209,12 +1174,10 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
        // Configurations:
        ////////////////////////////////////////////////////////
        IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE));
-       // Config Supported Channel Width setting
-       //
+
        HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset));
 
-//     if(pHTInfo->bCurBW40MHz == true)
+       if(pHTInfo->bCurBW40MHz == true)
                pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false);
 
        //
@@ -1295,7 +1258,7 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
 
        // <2> Set AMPDU Minimum MPDU Start Spacing
        // 802.11n 3.0 section 9.7d.3
-#if 1
+#if 0
        if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
                pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
        else
index d4565ecc7ab4c7dab63fdc28074065ed3f9bf3bd..928062f357136585fc3b5987b98ddcfe187b9f77 100644 (file)
@@ -1,3 +1,21 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #ifndef __INC_QOS_TYPE_H
 #define __INC_QOS_TYPE_H
 
 
 #define        MAX_WMMELE_LENGTH       64
 
-//
-// QoS mode.
-// enum 0, 1, 2, 4: since we can use the OR(|) operation.
-//
-// QOS_MODE is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
-//typedef      enum _QOS_MODE{
-//     QOS_DISABLE             = 0,
-//     QOS_WMM                 = 1,
-//     QOS_EDCA                        = 2,
-//     QOS_HCCA                        = 4,
-//}QOS_MODE,*PQOS_MODE;
-//
 typedef u32 QOS_MODE, *PQOS_MODE;
 #define QOS_DISABLE            0
 #define QOS_WMM                        1
@@ -219,19 +225,6 @@ typedef    union _QOS_INFO_FIELD{
 
 }QOS_INFO_FIELD, *PQOS_INFO_FIELD;
 
-//
-// ACI to AC coding.
-// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
-//
-// AC_CODING is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
-//typedef      enum _AC_CODING{
-//     AC0_BE  = 0,            // ACI: 0x00    // Best Effort
-//     AC1_BK  = 1,            // ACI: 0x01    // Background
-//     AC2_VI  = 2,            // ACI: 0x10    // Video
-//     AC3_VO  = 3,            // ACI: 0x11    // Voice
-//     AC_MAX = 4,             // Max: define total number; Should not to be used as a real enum.
-//}AC_CODING,*PAC_CODING;
-//
 typedef u32 AC_CODING;
 #define AC0_BE 0               // ACI: 0x00    // Best Effort
 #define AC1_BK 1               // ACI: 0x01    // Background
@@ -252,7 +245,7 @@ typedef     union _ACI_AIFSN{
                u8      ACM:1;
                u8      ACI:2;
                u8      Reserved:1;
-       }f;     // Field
+       }f;
 }ACI_AIFSN, *PACI_AIFSN;
 
 //
@@ -265,7 +258,7 @@ typedef     union _ECW{
        {
                u8      ECWmin:4;
                u8      ECWmax:4;
-       }f;     // Field
+       }f;
 }ECW, *PECW;
 
 //
@@ -281,7 +274,7 @@ typedef     union _AC_PARAM{
                ACI_AIFSN       AciAifsn;
                ECW             Ecw;
                u16             TXOPLimit;
-       }f;     // Field
+       }f;
 }AC_PARAM, *PAC_PARAM;
 
 
@@ -354,7 +347,7 @@ typedef union _TSPEC_BODY{
                u32     MinPhyRate;
                u16     SurplusBandwidthAllowance;
                u16     MediumTime;
-       } f;    // Field
+       } f;
 }TSPEC_BODY, *PTSPEC_BODY;
 
 
@@ -384,7 +377,6 @@ typedef     enum _ACM_METHOD{
 
 
 typedef struct _ACM{
-//     u8              RegEnableACM;
        u64             UsedTime;
        u64             MediumTime;
        u8              HwAcmCtl;       // TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B).
@@ -404,10 +396,6 @@ typedef    u8              AC_UAPSD, *PAC_UAPSD;
 #define        GET_BE_UAPSD(_apsd) ((_apsd) & BIT3)
 #define        SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3)
 
-
-//typedef struct _TCLASS{
-// TODO
-//} TCLASS, *PTCLASS;
 typedef union _QOS_TCLAS{
 
        struct _TYPE_GENERAL{
@@ -459,32 +447,12 @@ typedef union _QOS_TCLAS{
        } TYPE2_8021Q;
 } QOS_TCLAS, *PQOS_TCLAS;
 
-//typedef struct _WMM_TSTREAM{
-//
-//- TSPEC
-//- AC (which to mapping)
-//} WMM_TSTREAM, *PWMM_TSTREAM;
 typedef struct _QOS_TSTREAM{
        u8                      AC;
        WMM_TSPEC               TSpec;
        QOS_TCLAS               TClass;
 } QOS_TSTREAM, *PQOS_TSTREAM;
 
-//typedef struct _U_APSD{
-//- TriggerEnable [4]
-//- MaxSPLength
-//- HighestAcBuffered
-//} U_APSD, *PU_APSD;
-
-//joseph TODO:
-//     UAPSD function should be implemented by 2 data structure
-//     "Qos control field" and "Qos info field"
-//typedef struct _QOS_UAPSD{
-//     u8                      bTriggerEnable[4];
-//     u8                      MaxSPLength;
-//     u8                      HighestBufAC;
-//} QOS_UAPSD, *PQOS_APSD;
-
 //----------------------------------------------------------------------------
 //      802.11 Management frame Status Code field
 //----------------------------------------------------------------------------
@@ -498,7 +466,6 @@ typedef struct _OCTET_STRING{
 // Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h]
 //
 typedef struct _STA_QOS{
-       //DECLARE_RT_OBJECT(STA_QOS);
        u8                              WMMIEBuf[MAX_WMMELE_LENGTH];
        u8*                             WMMIE;
 
@@ -565,18 +532,9 @@ typedef struct _BSS_QOS{
        AC_PARAM                AcParameter[4];
 }BSS_QOS, *PBSS_QOS;
 
-
-//
-// Ref: sQoSCtlLng and QoSCtl definition in 8185 QoS code.
-//#define QoSCtl   ((  (Adapter->bRegQoS) && (Adapter->dot11QoS.QoSMode &(QOS_EDCA|QOS_HCCA))    )  ?sQoSCtlLng:0)
-//
 #define sQoSCtlLng                     2
 #define        QOS_CTRL_LEN(_QosMode)          ((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0)
 
-
-//Added by joseph
-//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
-//#define UP2AC(up)                    ((up<3)?((up==0)?1:0):(up>>1))
 #define IsACValid(ac)                  ((ac<=7 )?true:false )
 
-#endif // #ifndef __INC_QOS_TYPE_H
+#endif
index baaac2149de1fb129660c42d8639c5535ba7e9b0..a07b2344a6f8cfedd89a940e4dedd432d159dc6b 100644 (file)
@@ -1,3 +1,21 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #ifndef _TSTYPE_H_
 #define _TSTYPE_H_
 #include "rtl819x_Qos.h"
@@ -30,10 +48,10 @@ typedef struct _TX_TS_RECORD{
        u16                             TxCurSeq;
        BA_RECORD                       TxPendingBARecord;      // For BA Originator
        BA_RECORD                       TxAdmittedBARecord;     // For BA Originator
-//     QOS_DL_RECORD           DLRecord;
        u8                              bAddBaReqInProgress;
        u8                              bAddBaReqDelayed;
        u8                              bUsingBa;
+       u8                              bDisable_AddBa;
        struct timer_list               TsAddBaTimer;
        u8                              num;
 } TX_TS_RECORD, *PTX_TS_RECORD;
@@ -48,9 +66,6 @@ typedef struct _RX_TS_RECORD {
        u16                             RxLastSeqNum;
        u8                              RxLastFragNum;
        u8                              num;
-//     QOS_DL_RECORD           DLRecord;
 } RX_TS_RECORD, *PRX_TS_RECORD;
 
-
 #endif
-
index de143ecae5fa1aa47f0a5442494eb0ae9ffc0973..7ffc06ca89a81676ec98e8aab149d52fe4af8270 100644 (file)
@@ -1,3 +1,21 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #include "ieee80211.h"
 #include <linux/etherdevice.h>
 #include <linux/slab.h>
@@ -29,7 +47,6 @@ void RxPktPendingTimeout(unsigned long data)
 
        PRX_REORDER_ENTRY       pReorderEntry = NULL;
 
-       //u32 flags = 0;
        unsigned long flags = 0;
        struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
        u8 index = 0;
@@ -37,7 +54,6 @@ void RxPktPendingTimeout(unsigned long data)
 
 
        spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
-       //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
        IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__);
        if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
        {
@@ -72,7 +88,6 @@ void RxPktPendingTimeout(unsigned long data)
 
        if(index>0)
        {
-               // Set RxTimeoutIndicateSeq to 0xffff to indicate no pending packets in buffer now.
                pRxTs->RxTimeoutIndicateSeq = 0xffff;
 
                // Indicate packets
@@ -82,6 +97,7 @@ void RxPktPendingTimeout(unsigned long data)
                        return;
                }
                ieee80211_indicate_packets(ieee, stats_IndicateArray, index);
+                bPktInBuf = false;
        }
 
        if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
@@ -126,6 +142,7 @@ void ResetTxTsEntry(PTX_TS_RECORD pTS)
        pTS->bAddBaReqInProgress = false;
        pTS->bAddBaReqDelayed = false;
        pTS->bUsingBa = false;
+       pTS->bDisable_AddBa = false;
        ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator
        ResetBaEntry(&pTS->TxPendingBARecord);
 }
@@ -212,7 +229,6 @@ void TSInitialize(struct ieee80211_device *ieee)
        }
        // Initialize unused Rx Reorder List.
        INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
-//#ifdef TO_DO_LIST
        for(count = 0; count < REORDER_ENTRY_NUM; count++)
        {
                list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
@@ -220,7 +236,6 @@ void TSInitialize(struct ieee80211_device *ieee)
                        break;
                pRxReorderEntry = &ieee->RxReorderEntry[count+1];
        }
-//#endif
 
 }
 
@@ -236,7 +251,6 @@ void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 I
 
 PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 TID, TR_SELECT TxRxSelect)
 {
-       //DIRECTION_VALUE       dir;
        u8      dir;
        bool                            search_dir[4] = {0, 0, 0, 0};
        struct list_head*               psearch_list; //FIXME
@@ -282,18 +296,15 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8*    Addr, u8
        else
                psearch_list = &ieee->Rx_TS_Admit_List;
 
-       //for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++)
        for(dir = 0; dir <= DIR_BI_DIR; dir++)
        {
                if(search_dir[dir] ==false )
                        continue;
                list_for_each_entry(pRet, psearch_list, List){
-       //              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);
                        if (memcmp(pRet->Addr, Addr, 6) == 0)
                                if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
                                        if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
                                        {
-       //                                      printk("Bingo! got it\n");
                                                break;
                                        }
 
@@ -352,10 +363,9 @@ bool GetTs(
        //
        if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr))
        {
-               IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n");
+               IEEE80211_DEBUG(IEEE80211_DL_ERR, "ERR! get TS for Broadcast or Multicast\n");
                return false;
        }
-
        if (ieee->current_network.qos_data.supported == 0)
                UP = 0;
        else
@@ -363,7 +373,7 @@ bool GetTs(
                // In WMM case: we use 4 TID only
                if (!IsACValid(TID))
                {
-                       IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __FUNCTION__, TID);
+                       IEEE80211_DEBUG(IEEE80211_DL_ERR, "ERR! in %s(), TID(%d) is not valid\n", __FUNCTION__, TID);
                        return false;
                }
 
@@ -478,7 +488,6 @@ void RemoveTsEntry(
        TR_SELECT                       TxRxSelect
        )
 {
-       //u32 flags = 0;
        unsigned long flags = 0;
        del_timer_sync(&pTs->SetupTimer);
        del_timer_sync(&pTs->InactTimer);
@@ -486,7 +495,6 @@ void RemoveTsEntry(
 
        if(TxRxSelect == RX_DIR)
        {
-//#ifdef TO_DO_LIST
                PRX_REORDER_ENTRY       pRxReorderEntry;
                PRX_TS_RECORD           pRxTS = (PRX_TS_RECORD)pTs;
                if(timer_pending(&pRxTS->RxPktPendingTimer))
@@ -494,9 +502,7 @@ void RemoveTsEntry(
 
                 while(!list_empty(&pRxTS->RxPendingPktList))
                 {
-                //      PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
                         spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
-                        //pRxReorderEntry = list_entry(&pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
                        pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
                         list_del_init(&pRxReorderEntry->List);
                         {
@@ -514,11 +520,8 @@ void RemoveTsEntry(
                                 prxb = NULL;
                         }
                         list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
-                        //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
                         spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
                 }
-
-//#endif
        }
        else
        {
index ba8e12c209cae3cd8e770f23a08ab112f762019b..7c4fd18d89c6c9d4b351f36dc8ad9809b621c792 100644 (file)
@@ -93,7 +93,7 @@ u32 Rtl8192SUPHY_REG_2T2RArray[PHY_REG_2T2RArrayLength] = {
 0x900,0x00000000,
 0x904,0x00000023,
 0x908,0x00000000,
-0x90c,0x03321333,
+0x90c,0x01121313,
 0xa00,0x00d047c8,
 0xa04,0x80ff0008,
 0xa08,0x8ccd8300,
@@ -135,7 +135,7 @@ u32 Rtl8192SUPHY_REG_2T2RArray[PHY_REG_2T2RArrayLength] = {
 0xc68,0x69543420,
 0xc6c,0x433c0094,
 0xc70,0x2c7f000d,
-0xc74,0x0186155b,
+0xc74,0x0186175b,
 0xc78,0x0000001f,
 0xc7c,0x00b91612,
 0xc80,0x40000100,
@@ -256,13 +256,34 @@ u32 Rtl8192SUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength] = {
 };
 
 u32 Rtl8192SUPHY_REG_Array_PG[PHY_REG_Array_PGLength] = {
-0xe00,0xffffffff,0x06090909,
-0xe04,0xffffffff,0x00030406,
+0xe00,0xffffffff,0x04060606,
+0xe04,0xffffffff,0x00020204,
 0xe08,0x0000ff00,0x00000000,
-0xe10,0xffffffff,0x0a0c0d0e,
-0xe14,0xffffffff,0x04070809,
-0xe18,0xffffffff,0x0a0c0d0e,
-0xe1c,0xffffffff,0x04070809,
+0xe10,0xffffffff,0x0408080a,
+0xe14,0xffffffff,0x00020204,
+0xe18,0xffffffff,0x0408080a,
+0xe1c,0xffffffff,0x00020204,
+0xe00,0xffffffff,0x00000000,
+0xe04,0xffffffff,0x00000000,
+0xe08,0x0000ff00,0x00000000,
+0xe10,0xffffffff,0x00000000,
+0xe14,0xffffffff,0x00000000,
+0xe18,0xffffffff,0x00000000,
+0xe1c,0xffffffff,0x00000000,
+0xe00,0xffffffff,0x00000000,
+0xe04,0xffffffff,0x00000000,
+0xe08,0x0000ff00,0x00000000,
+0xe10,0xffffffff,0x00000000,
+0xe14,0xffffffff,0x00000000,
+0xe18,0xffffffff,0x00000000,
+0xe1c,0xffffffff,0x00000000,
+0xe00,0xffffffff,0x00000000,
+0xe04,0xffffffff,0x00000000,
+0xe08,0x0000ff00,0x00000000,
+0xe10,0xffffffff,0x00000000,
+0xe14,0xffffffff,0x00000000,
+0xe18,0xffffffff,0x00000000,
+0xe1c,0xffffffff,0x00000000,
 };
 
 u32 Rtl8192SURadioA_1T_Array[RadioA_1T_ArrayLength] = {
index 36e84aff6ed6f7968e745e2d77c6f349393a47cc..69a66c3996060dddb400c345f90e0506035af614 100644 (file)
@@ -1,3 +1,21 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #ifndef __INC_HAL8192SU_FW_IMG_H
 #define __INC_HAL8192SU_FW_IMG_H
 
@@ -19,7 +37,7 @@ extern u32 Rtl8192SUPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength];
 extern u32 Rtl8192SUPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength];
 #define PHY_ChangeTo_2T2RArrayLength 45
 extern u32 Rtl8192SUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength];
-#define PHY_REG_Array_PGLength 21
+#define PHY_REG_Array_PGLength 84
 extern u32 Rtl8192SUPHY_REG_Array_PG[PHY_REG_Array_PGLength];
 #define RadioA_1T_ArrayLength 202
 extern u32 Rtl8192SURadioA_1T_Array[RadioA_1T_ArrayLength];
@@ -38,5 +56,5 @@ extern u32 Rtl8192SUMACPHY_Array_PG[MACPHY_Array_PGLength];
 #define AGCTAB_ArrayLength 320
 extern u32 Rtl8192SUAGCTAB_Array[AGCTAB_ArrayLength];
 
-#endif //__INC_HAL8192SU_FW_IMG_H
+#endif
 
index 609dba67eb4e05a882240c599b8d7d8c7a907172..5d96b356bf123ead9f3f2c85a14c0e7efe7f422f 100644 (file)
@@ -1087,22 +1087,13 @@ BlinkTimerCallback(
        struct net_device       *dev = (struct net_device *)data;
        struct r8192_priv       *priv = ieee80211_priv(dev);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        schedule_work(&(priv->BlinkWorkItem));
-#endif
 }
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 void BlinkWorkItemCallback(struct work_struct *work)
 {
        struct r8192_priv *priv = container_of(work, struct r8192_priv, BlinkWorkItem);
-#else
-void BlinkWorkItemCallback(void * Context)
-{
-       struct net_device *dev = (struct net_device *)Context;
-       struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
 
        PLED_819xUsb     pLed = priv->pLed;
 
index f0ce6562c23bc376519246aa17cf34750c9adca0..bbefd0f30348020936b0397d81bb9cf09af7f3cd 100644 (file)
@@ -1,27 +1,26 @@
 /******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
  *
- *     (c) Copyright  2008, RealTEK Technologies Inc. All Rights Reserved.
+ * Based on the r8180 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
  *
- * Module:     Efuse.c ( Source C File)
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
  *
- * Note:               Copy from WMAC for the first version!!!!
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
  *
- * Function:
- *
- * Export:
- *
- * Abbrev:
- *
- * History:
- * Data                        Who             Remark
- *
- * 09/23/2008  MHC             Porting Efuse R/W API from WMAC.
- * 11/10/2008  MHC             1. Porting from 8712 EFUSE.
- *                                             2. Add description and reorganize code arch.
- * 11/16/2008  MHC             1. Reorganize code architecture.
- *                                             2. Rename for some API and change extern or static type.
- *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
 ******************************************************************************/
 #include "r8192U.h"
 #include "r8192S_hw.h"
 #include "r8192S_Efuse.h"
 
 #include <linux/types.h>
+#include <linux/ctype.h>
 
-//typedef  int INT32;
-//
-// In the future, we will always support EFUSE!!
-//
-/*---------------------------Define Local Constant---------------------------*/
 #define        _POWERON_DELAY_
 #define        _PRE_EXECUTE_READ_CMD_
 
 #define                EFUSE_REPEAT_THRESHOLD_         3
 #define                EFUSE_ERROE_HANDLE              1
 
-
-// From 8712!!!!!
 typedef struct _EFUSE_MAP_A{
        u8 offset;              //0~15
        u8 word_start;  //0~3
@@ -91,14 +84,11 @@ struct efuse_priv
        u8              tx_power_g[14];
 };
 
-/*---------------------------Define Local Constant---------------------------*/
-
-
-/*------------------------Define global variable-----------------------------*/
 const u8 MAX_PGPKT_SIZE = 9; //header+ 2* 4 words (BYTES)
 const u8 PGPKT_DATA_SIZE = 8; //BYTES sizeof(u8)*8
 const u32 EFUSE_MAX_SIZE = 512;
 
+const u8 EFUSE_OOB_PROTECT_BYTES = 14;
 
 const EFUSE_MAP RTL8712_SDIO_EFUSE_TABLE[]={
                                //offset        word_s  byte_start      byte_cnts
@@ -117,15 +107,6 @@ const EFUSE_MAP RTL8712_SDIO_EFUSE_TABLE[]={
 /*TxPwIndex */ {11             ,0              ,0                      ,28     }  // 58~73h  3...4
 };
 
-/*------------------------Define global variable-----------------------------*/
-
-
-/*------------------------Define local variable------------------------------*/
-
-/*------------------------Define local variable------------------------------*/
-
-
-/*--------------------Define function prototype-----------------------*/
 //
 // From WMAC Efuse one byte R/W
 //
@@ -176,7 +157,7 @@ efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove);
 //
 static u8
 efuse_PgPacketRead(    struct net_device* dev,u8       offset,u8 *data);
-static u8
+static u32
 efuse_PgPacketWrite(struct net_device* dev,u8 offset,u8 word_en,u8     *data);
 static void
 efuse_WordEnableDataRead(      u8 word_en,u8 *sourdata,u8 *targetdata);
@@ -194,7 +175,6 @@ efuse_CalculateWordCnts(u8 word_en);
 #ifdef TO_DO_LIST
 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn);
 #endif
-/*--------------------Define function prototype-----------------------*/
 
 
 
@@ -242,8 +222,7 @@ EFUSE_Initialize(struct net_device* dev)
        //Set E-fuse program time & read time : 0x30[30:24]=1110010b
        write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
 
-}      /* EFUSE_Initialize */
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   EFUSE_Read1Byte
@@ -302,7 +281,7 @@ EFUSE_Read1Byte(struct net_device* dev, u16 Address)
        else
                return 0xFF;
 
-}      /* EFUSE_Read1Byte */
+}
 
 
 /*-----------------------------------------------------------------------------
@@ -324,13 +303,10 @@ EFUSE_Read1Byte(struct net_device* dev, u16       Address)
 extern void
 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
 {
-       //u8    data;
        u8      Bytetemp = {0x00};
        u8      temp = {0x00};
        u32     k=0;
 
-       //RT_TRACE(COMP_EFUSE, "Addr=%x Data =%x\n", Address, Value);
-
        if( Address < EFUSE_MAC_LEN)    //E-fuse 512Byte
        {
                write_nic_byte(dev, EFUSE_CTRL, Value);
@@ -349,7 +325,6 @@ EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
                temp = Bytetemp | 0x80;
                write_nic_byte(dev, EFUSE_CTRL+3, temp);
 
-               //Wait Write-ready (0x30[31]=0)
                Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
                while(Bytetemp & 0x80)
                {
@@ -363,8 +338,7 @@ EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
                }
        }
 
-}      /* EFUSE_Write1Byte */
-
+}
 
 #ifdef EFUSE_FOR_92SU
 //
@@ -380,12 +354,10 @@ EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
 //
 void do_93c46(struct net_device* dev,  u8 addorvalue)
 {
-       //u8  clear[1] = {0x0};      // cs=0 , sk=0 , di=0 , do=0
        u8  cs[1] = {0x88};        // cs=1 , sk=0 , di=0 , do=0
        u8  cssk[1] = {0x8c};      // cs=1 , sk=1 , di=0 , do=0
        u8  csdi[1] = {0x8a};      // cs=1 , sk=0 , di=1 , do=0
        u8  csskdi[1] = {0x8e};    // cs=1 , sk=1 , di=1 , do=0
-       //u8  di[1] = {0x82};        // cs=0 , sk=0 , di=1 , do=0
        u8  count;
 
        for(count=0 ; count<8 ; count++)
@@ -424,7 +396,6 @@ u16 Read93C46(struct net_device*    dev,    u16     Reg     )
        u8      cssk[1] = {0x8c};      // cs=1 , sk=1 , di=0 , do=0
        u8      csdi[1] = {0x8a};      // cs=1 , sk=0 , di=1 , do=0
        u8      csskdi[1] = {0x8e};    // cs=1 , sk=1 , di=1 , do=0
-       //u8    di[1] = {0x82};        // cs=0 , sk=0 , di=1 , do=0
        u8      EepromSEL[1]={0x00};
        u8      address;
 
@@ -434,7 +405,6 @@ u16 Read93C46(struct net_device*    dev,    u16     Reg     )
 
        address = (u8)Reg;
 
-       // Suggested by SD1 Alex, 2008.10.20. Revised by Roger.
        *EepromSEL= read_nic_byte(dev, EPROM_CMD);
 
        if((*EepromSEL & 0x10) == 0x10) // select 93c46
@@ -486,13 +456,10 @@ u16 Read93C46(struct net_device*  dev,    u16     Reg     )
 void
 ReadEFuseByte(struct net_device* dev,u16 _offset, u8 *pbuf)
 {
-
-       //u16   indexk=0;
        u32  value32;
        u8      readbyte;
        u16     retry;
 
-
        //Write Address
        write_nic_byte(dev, EFUSE_CTRL+1, (_offset & 0xff));
        readbyte = read_nic_byte(dev, EFUSE_CTRL+2);
@@ -505,7 +472,6 @@ ReadEFuseByte(struct net_device* dev,u16 _offset, u8 *pbuf)
        //Check bit 32 read-ready
        retry = 0;
        value32 = read_nic_dword(dev, EFUSE_CTRL);
-       //while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10))
        while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10000))
        {
                value32 = read_nic_dword(dev, EFUSE_CTRL);
@@ -532,78 +498,145 @@ void
 ReadEFuse(struct net_device* dev, u16   _offset, u16 _size_byte, u8 *pbuf)
 {
 
-       u8      efuseTbl[128];
+       struct r8192_priv *priv = ieee80211_priv(dev);
+       u8      efuseTbl[EFUSE_MAP_LEN];
        u8      rtemp8[1];
        u16     eFuse_Addr = 0;
        u8      offset, wren;
        u16     i, j;
-       u16     eFuseWord[16][4];// = {0xFF};//FIXLZM
-
-       for(i=0; i<16; i++)
-               for(j=0; j<4; j++)
-                       eFuseWord[i][j]=0xFF;
+       u16     eFuseWord[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
+       u16     efuse_utilized = 0;
+       u16     efuse_usage = 0;
 
-       // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
-       if((_offset + _size_byte)>128)
-       {// total E-Fuse table is 128bytes
-               //RT_TRACE(COMP_EFUSE, "ReadEFuse(): Invalid offset(%#x) with read bytes(%#x)!!\n",_offset, _size_byte);
+       if((_offset + _size_byte)>EFUSE_MAP_LEN)
+       {
                printk("ReadEFuse(): Invalid offset with read bytes!!\n");
                return;
        }
 
-       // Refresh efuse init map as all oxFF.
-       for (i = 0; i < 128; i++)
-               efuseTbl[i] = 0xFF;
+       for(i = 0; i < EFUSE_MAX_SECTION; i++)
+               for(j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
+                       eFuseWord[i][j]=0xFFFF;
 
 #if (EFUSE_READ_SWITCH == 1)
        ReadEFuseByte(dev, eFuse_Addr, rtemp8);
 #else
        rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);
 #endif
-       if(*rtemp8 != 0xFF)             eFuse_Addr++;
-       while((*rtemp8 != 0xFF) && (eFuse_Addr < 512)){
+       if(*rtemp8 != 0xFF){
+               efuse_utilized++;
+               RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
+               eFuse_Addr++;
+       }
+
+       while((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN))
+       {
                offset = ((*rtemp8 >> 4) & 0x0f);
-               if(offset <= 0x0F){
+               if(offset < EFUSE_MAX_SECTION)
+               {
                        wren = (*rtemp8 & 0x0f);
-                       for(i=0; i<4; i++){
-                               if(!(wren & 0x01)){
+                       RT_TRACE(COMP_EPROM, "Offset-%d Worden=%x\n", offset, wren);
+
+                       for(i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
+                       {
+                               if(!(wren & 0x01))
+                               {
+                                       RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
 #if (EFUSE_READ_SWITCH == 1)
                                        ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
 #else
                                        rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
 #endif
+                                       efuse_utilized++;
                                        eFuseWord[offset][i] = (*rtemp8 & 0xff);
-                                       if(eFuse_Addr >= 512) break;
+                                       if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
+                                               break;
+
+                                       RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
 #if (EFUSE_READ_SWITCH == 1)
                                        ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
 #else
                                        rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
 #endif
+                                       efuse_utilized++;
                                        eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
-                                       if(eFuse_Addr >= 512) break;
+                                       if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
+                                               break;
                                }
                                wren >>= 1;
                        }
                }
+
+               RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
 #if (EFUSE_READ_SWITCH == 1)
                ReadEFuseByte(dev, eFuse_Addr, rtemp8);
 #else
                rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
 #endif
-               if(*rtemp8 != 0xFF && (eFuse_Addr < 512))       eFuse_Addr++;
+               if(*rtemp8 != 0xFF && (eFuse_Addr < 512))
+               {
+                       efuse_utilized++;
+                       eFuse_Addr++;
+               }
        }
 
-       for(i=0; i<16; i++){
-               for(j=0; j<4; j++){
+       for(i=0; i<EFUSE_MAX_SECTION; i++)
+       {
+               for(j=0; j<EFUSE_MAX_WORD_UNIT; j++)
+               {
                        efuseTbl[(i*8)+(j*2)]=(eFuseWord[i][j] & 0xff);
                        efuseTbl[(i*8)+((j*2)+1)]=((eFuseWord[i][j] >> 8) & 0xff);
                }
        }
        for(i=0; i<_size_byte; i++)
                pbuf[i] = efuseTbl[_offset+i];
+
+       efuse_usage = (u8)((efuse_utilized*100)/EFUSE_REAL_CONTENT_LEN);
+       priv->EfuseUsedBytes = efuse_utilized;
+       priv->EfuseUsedPercentage = (u8)efuse_usage;
 }
-#endif // #if (EFUSE_FOR_92SU == 1)
+#endif
+
+extern bool
+EFUSE_ShadowUpdateChk(struct net_device* dev)
+{
+       struct r8192_priv *priv = ieee80211_priv(dev);
+       u8      SectionIdx, i, Base;
+       u16     WordsNeed = 0, HdrNum = 0, TotalBytes = 0, EfuseUsed = 0;
+       bool    bWordChanged, bResult = true;
+
+       for (SectionIdx = 0; SectionIdx < 16; SectionIdx++)
+       {
+               Base = SectionIdx * 8;
+               bWordChanged = false;
+
+               for (i = 0; i < 8; i=i+2)
+               {
+                       if((priv->EfuseMap[EFUSE_INIT_MAP][Base+i] !=
+                               priv->EfuseMap[EFUSE_MODIFY_MAP][Base+i]) ||
+                               (priv->EfuseMap[EFUSE_INIT_MAP][Base+i+1] !=
+                               priv->EfuseMap[EFUSE_MODIFY_MAP][Base+i+1]))
+                       {
+                               WordsNeed++;
+                               bWordChanged = true;
+                       }
+               }
 
+               if( bWordChanged==true )
+                       HdrNum++;
+       }
+
+       TotalBytes = HdrNum + WordsNeed*2;
+       EfuseUsed = priv->EfuseUsedBytes;
+
+       if( (TotalBytes + EfuseUsed) >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
+               bResult = true;
+
+       RT_TRACE(COMP_EPROM, "EFUSE_ShadowUpdateChk(): TotalBytes(%x), HdrNum(%x), WordsNeed(%x), EfuseUsed(%d)\n",
+               TotalBytes, HdrNum, WordsNeed, EfuseUsed);
+
+       return bResult;
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   EFUSE_ShadowRead
@@ -624,8 +657,6 @@ ReadEFuse(struct net_device* dev, u16        _offset, u16 _size_byte, u8 *pbuf)
 extern void
 EFUSE_ShadowRead(      struct net_device*      dev,    u8 Type, u16 Offset, u32 *Value)
 {
-       //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
-
        if (Type == 1)
                efuse_ShadowRead1Byte(dev, Offset, (u8 *)Value);
        else if (Type == 2)
@@ -633,8 +664,7 @@ EFUSE_ShadowRead(   struct net_device*      dev,    u8 Type, u16 Offset, u32 *Value)
        else if (Type == 4)
                efuse_ShadowRead4Byte(dev, Offset, (u32 *)Value);
 
-}      // EFUSE_ShadowRead
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   EFUSE_ShadowWrite
@@ -655,8 +685,6 @@ EFUSE_ShadowRead(   struct net_device*      dev,    u8 Type, u16 Offset, u32 *Value)
 extern void
 EFUSE_ShadowWrite(     struct net_device*      dev,    u8 Type, u16 Offset,u32 Value)
 {
-       //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
-
        if (Offset >= 0x18 && Offset <= 0x1F)
                return;
 
@@ -667,8 +695,7 @@ EFUSE_ShadowWrite(  struct net_device*      dev,    u8 Type, u16 Offset,u32 Value)
        else if (Type == 4)
                efuse_ShadowWrite4Byte(dev, Offset, (u32)Value);
 
-}      // EFUSE_ShadowWrite
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   EFUSE_ShadowUpdate
@@ -686,15 +713,25 @@ EFUSE_ShadowWrite(        struct net_device*      dev,    u8 Type, u16 Offset,u32 Value)
  * 11/12/2008  MHC             Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-extern void
+extern bool
 EFUSE_ShadowUpdate(struct net_device* dev)
 {
-       //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
        struct r8192_priv *priv = ieee80211_priv(dev);
        u16                     i, offset, base = 0;
        u8                      word_en = 0x0F;
-       bool first_pg = false;
-       // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
+       bool                    first_pg = false;
+
+       RT_TRACE(COMP_EPROM, "--->EFUSE_ShadowUpdate()\n");
+
+       if(!EFUSE_ShadowUpdateChk(dev))
+       {
+               efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
+               memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
+                       (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
+
+               RT_TRACE(COMP_EPROM, "<---EFUSE_ShadowUpdate(): Efuse out of capacity!!\n");
+               return false;
+       }
        efuse_PowerSwitch(dev, TRUE);
 
        //
@@ -712,16 +749,12 @@ EFUSE_ShadowUpdate(struct net_device* dev)
                //
                for (i = 0; i < 8; i++)
                {
-                       if (offset == 0 && priv->EfuseMap[EFUSE_INIT_MAP][base+i] == 0xFF)
-                       {
-                               first_pg = TRUE;
-                       }
-
-                       // 2008/12/11 MH HW autoload fail workaround for A/BCUT.
-
                        if (first_pg == TRUE)
                        {
                                word_en &= ~(1<<(i/2));
+                               RT_TRACE(COMP_EPROM,"Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
+                               offset, base+i, priv->EfuseMap[EFUSE_INIT_MAP][base+i],
+                               priv->EfuseMap[EFUSE_MODIFY_MAP][base+i],word_en);
                                priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
                                priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
                        }else
@@ -730,8 +763,9 @@ EFUSE_ShadowUpdate(struct net_device* dev)
                                priv->EfuseMap[EFUSE_MODIFY_MAP][base+i])
                        {
                                word_en &= ~(EFUSE_BIT(i/2));
-                               //RT_TRACE(COMP_EFUSE,  "Offset=%d Addr%x %x ==> %x Word_En=%02x\n",
-                               //offset, base+i, priv->EfuseMap[0][base+i], priv->EfuseMap[1][base+i],word_en);
+                               RT_TRACE(COMP_EPROM, "Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
+                               offset, base+i, priv->EfuseMap[0][base+i],
+                               priv->EfuseMap[1][base+i],word_en);
 
                                // Update init table!!!
                                priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
@@ -747,25 +781,27 @@ EFUSE_ShadowUpdate(struct net_device* dev)
                {
                        u8      tmpdata[8];
 
-                       //FIXLZM
-                       memcpy(tmpdata, &(priv->EfuseMap[EFUSE_MODIFY_MAP][base]), 8);
-                       //RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("U-EFUSE\n"), tmpdata, 8);
-                       efuse_PgPacketWrite(dev,(u8)offset,word_en,tmpdata);
+                       memcpy((void *)tmpdata, (void *)&(priv->EfuseMap[EFUSE_MODIFY_MAP][base]), 8);
+                       RT_TRACE(COMP_INIT, "U-EFUSE\n");
+
+                       if(!efuse_PgPacketWrite(dev,(u8)offset,word_en,tmpdata))
+                       {
+                               RT_TRACE(COMP_EPROM,"EFUSE_ShadowUpdate(): PG section(%x) fail!!\n", offset);
+                               break;
+                       }
                }
 
        }
-       // 2008/12/01 MH For Efuse HW load bug workarounf method!!!!
-       // We will force write 0x10EC into address 10&11 after all Efuse content.
-       //
-
-
        // For warm reboot, we must resume Efuse clock to 500K.
+
        efuse_PowerSwitch(dev, FALSE);
-       // 2008/12/01 MH We update shadow content again!!!!
-       EFUSE_ShadowMapUpdate(dev);
 
-}      // EFUSE_ShadowUpdate
+       efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
+       memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
+               (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
 
+       return true;
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   EFUSE_ShadowMapUpdate
@@ -792,12 +828,10 @@ extern void EFUSE_ShadowMapUpdate(struct net_device* dev)
        }else{
                efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
        }
-       //PlatformMoveMemory(&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
-               //&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);//FIXLZM
-       memcpy(&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
-               &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
+       memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
+               (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
 
-}      // EFUSE_ShadowMapUpdate
+}
 
 extern void
 EFUSE_ForceWriteVendorId( struct net_device* dev)
@@ -810,7 +844,7 @@ EFUSE_ForceWriteVendorId( struct net_device* dev)
 
        efuse_PowerSwitch(dev, FALSE);
 
-}      // EFUSE_ForceWriteVendorId
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_ShadowRead1Byte
@@ -837,7 +871,7 @@ efuse_ShadowRead1Byte(struct net_device*    dev,    u16 Offset,     u8 *Value)
 
        *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
 
-}      // EFUSE_ShadowRead1Byte
+}
 
 //---------------Read Two Bytes
 static void
@@ -848,7 +882,7 @@ efuse_ShadowRead2Byte(struct net_device*    dev,    u16 Offset,     u16 *Value)
        *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
        *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
 
-}      // EFUSE_ShadowRead2Byte
+}
 
 //---------------Read Four Bytes
 static void
@@ -861,7 +895,7 @@ efuse_ShadowRead4Byte(struct net_device*    dev,    u16 Offset,     u32 *Value)
        *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2]<<16;
        *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3]<<24;
 
-}      // efuse_ShadowRead4Byte
+}
 
 
 
@@ -890,7 +924,7 @@ efuse_ShadowWrite1Byte(struct net_device*   dev,    u16 Offset,     u8 Value)
 
        priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value;
 
-}      // efuse_ShadowWrite1Byte
+}
 
 //---------------Write Two Bytes
 static void
@@ -901,7 +935,7 @@ efuse_ShadowWrite2Byte(struct net_device*   dev,    u16 Offset,     u16 Value)
        priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value&0x00FF;
        priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = Value>>8;
 
-}      // efuse_ShadowWrite1Byte
+}
 
 //---------------Write Four Bytes
 static void
@@ -914,10 +948,8 @@ efuse_ShadowWrite4Byte(struct net_device*  dev,    u16 Offset,     u32 Value)
        priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2] = (u8)((Value>>16)&0x00FF);
        priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3] = (u8)((Value>>24)&0xFF);
 
-}      // efuse_ShadowWrite1Byte
-
+}
 
-/*  11/16/2008 MH Read one byte from real Efuse. */
 static u8
 efuse_OneByteRead(struct net_device* dev, u16 addr,u8 *data)
 {
@@ -947,7 +979,7 @@ efuse_OneByteRead(struct net_device* dev, u16 addr,u8 *data)
                bResult = FALSE;
        }
        return bResult;
-}      // efuse_OneByteRead
+}
 
 /*  11/16/2008 MH Write one byte to reald Efuse. */
 static u8
@@ -956,10 +988,6 @@ efuse_OneByteWrite(struct net_device* dev,  u16 addr, u8 data)
        u8 tmpidx = 0;
        u8 bResult;
 
-       //RT_TRACE(COMP_EFUSE, "Addr = %x Data=%x\n", addr, data);
-
-       //return        0;
-
        // -----------------e-fuse reg ctrl ---------------------------------
        //address
        write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));
@@ -983,8 +1011,7 @@ efuse_OneByteWrite(struct net_device* dev,  u16 addr, u8 data)
        }
 
        return bResult;
-}      // efuse_OneByteWrite
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_ReadAllMap
@@ -1005,19 +1032,13 @@ efuse_OneByteWrite(struct net_device* dev,  u16 addr, u8 data)
 static void
 efuse_ReadAllMap(struct net_device*    dev, u8 *Efuse)
 {
-       //u8    pg_data[8];
-       //u8    offset = 0;
-       //u8    tmpidx;
-       //static        u8      index = 0;
-
        //
        // We must enable clock and LDO 2.5V otherwise, read all map will be fail!!!!
        //
        efuse_PowerSwitch(dev, TRUE);
        ReadEFuse(dev, 0, 128, Efuse);
        efuse_PowerSwitch(dev, FALSE);
-}      // efuse_ReadAllMap
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_WriteAllMap
@@ -1057,18 +1078,11 @@ efuse_WriteAllMap(struct net_device* dev,u8 *eeprom, u32 eeprom_size)
                        // 0x18-1f Reserve >0x50 Reserve for tx power
                        if (offset == 3/* || offset > 9*/)
                                continue;//word_en = 0x0F;
-                       //else if (offset == 9) // 0x4c-4f Reserve
-                               //word_en = 0x0C;
                        else
                                word_en = 0x00;
                }
-               //RT_TRACE(COMP_EFUSE, ("Addr=%d size=%d Word_En=%02x\n", offset, eeprom_size, word_en));
 
-               //memcpy(tmpdata,eeprom+(offset*PGPKT_DATA_SIZE),8);
                memcpy(tmpdata, (eeprom+(offset*PGPKT_DATA_SIZE)), 8);
-
-               //RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("EFUSE\t"), tmpdata, 8);
-
                efuse_PgPacketWrite(dev,offset,word_en,tmpdata);
 
 
@@ -1077,7 +1091,7 @@ efuse_WriteAllMap(struct net_device* dev,u8 *eeprom, u32 eeprom_size)
        // For warm reboot, we must resume Efuse clock to 500K.
        efuse_PowerSwitch(dev, FALSE);
 
-}      // efuse_WriteAllMap
+}
 #endif
 
 /*-----------------------------------------------------------------------------
@@ -1114,15 +1128,9 @@ efuse_PgPacketRead(      struct net_device*      dev,    u8 offset, u8   *data)
        if(data==NULL)  return FALSE;
        if(offset>15)           return FALSE;
 
-       //FIXLZM
-       //PlatformFillMemory((PVOID)data, sizeof(u8)*PGPKT_DATA_SIZE, 0xff);
-       //PlatformFillMemory((PVOID)tmpdata, sizeof(u8)*PGPKT_DATA_SIZE, 0xff);
        memset(data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
        memset(tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
 
-       //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("efuse_PgPacketRead-1\n"), data, 8);
-
-       //efuse_reg_ctrl(pAdapter,TRUE);//power on
        while(bContinual && (efuse_addr  < EFUSE_MAX_SIZE) )
        {
                //-------  Header Read -------------
@@ -1169,9 +1177,6 @@ efuse_PgPacketRead(       struct net_device*      dev,    u8 offset, u8   *data)
                }
 
        }
-       //efuse_reg_ctrl(pAdapter,FALSE);//power off
-
-       //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("efuse_PgPacketRead-2\n"), data, 8);
 
        if(     (data[0]==0xff) &&(data[1]==0xff) && (data[2]==0xff)  && (data[3]==0xff) &&
                (data[4]==0xff) &&(data[5]==0xff) && (data[6]==0xff)  && (data[7]==0xff))
@@ -1179,8 +1184,7 @@ efuse_PgPacketRead(       struct net_device*      dev,    u8 offset, u8   *data)
        else
                return TRUE;
 
-}      // efuse_PgPacketRead
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_PgPacketWrite
@@ -1200,7 +1204,7 @@ efuse_PgPacketRead(       struct net_device*      dev,    u8 offset, u8   *data)
  * 11/16/2008  MHC             Reorganize code Arch and assign as local API.
  *
  *---------------------------------------------------------------------------*/
-static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *data)
+static u32 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *data)
 {
        u8 WriteState = PG_STATE_HEADER;
 
@@ -1210,12 +1214,9 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
 
        u8 pg_header = 0;
 
-       //u16 tmp_addr=0;
        u8 tmp_word_cnts=0,target_word_cnts=0;
        u8 tmp_header,match_word_en,tmp_word_en;
 
-       //u8    efuse_clk_ori,efuse_clk_new;
-
        PGPKT_STRUCT target_pkt;
        PGPKT_STRUCT tmp_pkt;
 
@@ -1240,7 +1241,6 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
        efuse_WordEnableDataRead(word_en,data,target_pkt.data);
        target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
 
-       //efuse_reg_ctrl(pAdapter,TRUE);//power on
        printk("EFUSE Power ON\n");
 
        while( bContinual && (efuse_addr  < EFUSE_MAX_SIZE) )
@@ -1312,14 +1312,12 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
                                                        badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1, tmp_pkt.word_en ,target_pkt.data);
 
                                                        //************  so-2-2-A-1 *******************
-                                                       //############################
                                                        if(0x0F != (badworden&0x0F))
                                                        {
                                                                u8 reorg_offset = offset;
                                                                u8 reorg_worden=badworden;
                                                                efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
                                                        }
-                                                       //############################
 
                                                        tmp_word_en = 0x0F;
                                                        if(  (target_pkt.word_en&BIT0)^(match_word_en&BIT0)  )
@@ -1342,13 +1340,13 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
                                                        //************  so-2-2-A-2 *******************
                                                        if((tmp_word_en&0x0F)!=0x0F){
                                                                //reorganize other pg packet
-                                                               //efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr
-                                                               efuse_addr = efuse_GetCurrentSize(dev);
-                                                               //===========================
-                                                               target_pkt.offset = offset;
+
+                                                       efuse_addr = efuse_GetCurrentSize(dev);
+
+                                                       target_pkt.offset = offset;
                                                                target_pkt.word_en= tmp_word_en;
-                                                               //===========================
-                                                       }else{
+
+                                               }else{
                                                                bContinual = FALSE;
                                                        }
                                                        #if (EFUSE_ERROE_HANDLE == 1)
@@ -1363,10 +1361,8 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
                                                else{//************  so-2-2-B *******************
                                                        //reorganize other pg packet
                                                        efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr
-                                                       //===========================
                                                        target_pkt.offset = offset;
                                                        target_pkt.word_en= target_pkt.word_en;
-                                                       //===========================
                                                        #if (EFUSE_ERROE_HANDLE == 1)
                                                        WriteState=PG_STATE_HEADER;
                                                        #endif
@@ -1405,13 +1401,10 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
 
                                        //************  s1-2-A :cover the exist data *******************
                                        memset(originaldata,0xff,sizeof(u8)*8);
-                                       //PlatformFillMemory((PVOID)originaldata, sizeof(u8)*8, 0xff);
 
                                        if(efuse_PgPacketRead( dev, tmp_pkt.offset,originaldata))
                                        {       //check if data exist
-                                               //efuse_reg_ctrl(pAdapter,TRUE);//power on
                                                badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,tmp_pkt.word_en,originaldata);
-                                               //############################
                                                if(0x0F != (badworden&0x0F))
                                                {
                                                        u8 reorg_offset = tmp_pkt.offset;
@@ -1419,7 +1412,6 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
                                                        efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
                                                        efuse_addr = efuse_GetCurrentSize(dev);
                                                }
-                                               //############################
                                                else{
                                                        efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
                                                }
@@ -1459,11 +1451,9 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
                        {//reorganize other pg packet //************  s1-1-B *******************
                                efuse_addr = efuse_addr + (2*target_word_cnts) +1;//next pg packet addr
 
-                               //===========================
                                target_pkt.offset = offset;
                                target_pkt.word_en= badworden;
                                target_word_cnts =  efuse_CalculateWordCnts(target_pkt.word_en);
-                               //===========================
                                #if (EFUSE_ERROE_HANDLE == 1)
                                WriteState=PG_STATE_HEADER;
                                repeat_times++;
@@ -1477,11 +1467,12 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
                }
        }
 
-       //efuse_reg_ctrl(pAdapter,FALSE);//power off
-
+       if(efuse_addr  >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
+       {
+               RT_TRACE(COMP_EPROM, "efuse_PgPacketWrite(): efuse_addr(%x) Out of size!!\n", efuse_addr);
+       }
        return TRUE;
-}      // efuse_PgPacketWrite
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_WordEnableDataRead
@@ -1503,12 +1494,6 @@ static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *
 static void
 efuse_WordEnableDataRead(      u8 word_en,u8 *sourdata,u8 *targetdata)
 {
-       //u8 tmpindex = 0;
-
-       //DbgPrint("efuse_WordEnableDataRead word_en = %x\n", word_en);
-
-       //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("sourdata\n"), sourdata, 8);
-       //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("targetdata\n"), targetdata, 8);
 
        if (!(word_en&BIT0))
        {
@@ -1530,8 +1515,7 @@ efuse_WordEnableDataRead( u8 word_en,u8 *sourdata,u8 *targetdata)
                targetdata[6] = sourdata[6];//sourdata[tmpindex++];
                targetdata[7] = sourdata[7];//sourdata[tmpindex++];
        }
-}      // efuse_WordEnableDataRead
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_WordEnableDataWrite
@@ -1555,15 +1539,9 @@ efuse_WordEnableDataWrite(       struct net_device*      dev,    u16 efuse_addr, u8 word_en, u
        u16 tmpaddr = 0;
        u16 start_addr = efuse_addr;
        u8 badworden = 0x0F;
-       //u8 NextState;
        u8 tmpdata[8];
 
        memset(tmpdata,0xff,PGPKT_DATA_SIZE);
-       //PlatformFillMemory((PVOID)tmpdata, PGPKT_DATA_SIZE, 0xff);
-
-       //RT_TRACE(COMP_EFUSE, "word_en = %x efuse_addr=%x\n", word_en, efuse_addr);
-
-       //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("U-EFUSE\n"), data, 8);
 
        if(!(word_en&BIT0))
        {
@@ -1614,8 +1592,7 @@ efuse_WordEnableDataWrite(        struct net_device*      dev,    u16 efuse_addr, u8 word_en, u
                }
        }
        return badworden;
-}      // efuse_WordEnableDataWrite
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_PowerSwitch
@@ -1658,8 +1635,7 @@ efuse_PowerSwitch(struct net_device* dev, u8 PwrState)
                write_nic_byte(dev, EFUSE_CLK, 0x02);
        }
 
-}      /* efuse_PowerSwitch */
-
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_GetCurrentSize
@@ -1686,8 +1662,6 @@ efuse_GetCurrentSize(struct net_device*   dev)
        u8 hoffset=0,hworden=0;
        u8 efuse_data,word_cnts=0;
 
-       //efuse_reg_ctrl(pAdapter,TRUE);//power on
-
        while ( bContinual &&
                        efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
                        (efuse_addr  < EFUSE_MAX_SIZE) )
@@ -1706,12 +1680,9 @@ efuse_GetCurrentSize(struct net_device*  dev)
                }
        }
 
-       //efuse_reg_ctrl(pAdapter,FALSE);//power off
-
        return efuse_addr;
 
-}      // efuse_GetCurrentSize}
-
+}
 
 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
 static u8
@@ -1723,7 +1694,7 @@ efuse_CalculateWordCnts(u8        word_en)
        if(!(word_en & BIT2))   word_cnts++;
        if(!(word_en & BIT3))   word_cnts++;
        return word_cnts;
-}      // efuse_CalculateWordCnts
+}
 
 /*-----------------------------------------------------------------------------
  * Function:   EFUSE_ProgramMap
@@ -1786,12 +1757,10 @@ EFUSE_ProgramMap(struct net_device* dev, char* pFileName,u8     TableType)
                                {
                                        u32     j;
 
-                                       //GetHexValueFromString(szLine, &u4bRegValue, &u4bMove);
                                        efuse_ParsingMap(szLine, &u4bRegValue, &u4bMove);
 
                                        // Get next hex value as EEPROM value.
                                        szLine += u4bMove;
-                                       //WriteEEprom(dev, (u16)(ithLine*8+i), (u16)u4bRegValue);
                                        eeprom[index++] = (u8)(u4bRegValue&0xff);
                                        eeprom[index++] = (u8)((u4bRegValue>>8)&0xff);
 
@@ -1808,9 +1777,6 @@ EFUSE_ProgramMap(struct net_device* dev, char* pFileName,u8       TableType)
                return  RT_STATUS_FAILURE;
        }
 
-
-       //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("EFUSE "), eeprom, HWSET_MAX_SIZE_92S);
-
        // Use map file to update real Efuse or shadow modify table.
        if (TableType == 1)
        {
@@ -1824,45 +1790,9 @@ EFUSE_ProgramMap(struct net_device* dev, char* pFileName,u8      TableType)
        }
 
        return  rtStatus;
-}      /* EFUSE_ProgramMap */
-
-#endif
-
-//
-//     Description:
-//             Return TRUE if chTmp is represent for hex digit and
-//             FALSE otherwise.
-//
-//
-bool IsHexDigit(       char chTmp)
-{
-       if( (chTmp >= '0' && chTmp <= '9') ||
-               (chTmp >= 'a' && chTmp <= 'f') ||
-               (chTmp >= 'A' && chTmp <= 'F') )
-       {
-               return TRUE;
-       }
-       else
-       {
-               return FALSE;
-       }
 }
 
-//
-//     Description:
-//             Translate a character to hex digit.
-//
-u32 MapCharToHexDigit(char chTmp)
-{
-       if(chTmp >= '0' && chTmp <= '9')
-               return (chTmp - '0');
-       else if(chTmp >= 'a' && chTmp <= 'f')
-               return (10 + (chTmp - 'a'));
-       else if(chTmp >= 'A' && chTmp <= 'F')
-               return (10 + (chTmp - 'A'));
-       else
-               return 0;
-}
+#endif
 
 /*-----------------------------------------------------------------------------
  * Function:   efuse_ParsingMap
@@ -1889,9 +1819,6 @@ efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove)
        // Check input parameter.
        if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
        {
-               //RT_TRACE(COMP_EFUSE,
-               //"eeprom_ParsingMap(): Invalid IN args! szStr: %p, pu4bVal: %p, pu4bMove: %p\n",
-               //szStr, pu4bVal, pu4bMove);
                return FALSE;
        }
 
@@ -1909,34 +1836,26 @@ efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove)
 
        // Check if szScan is now pointer to a character for hex digit,
        // if not, it means this is not a valid hex number.
-       if(!IsHexDigit(*szScan))
-       {
+       if (!isxdigit(*szScan))
                return FALSE;
-       }
 
        // Parse each digit.
        do
        {
-               (*pu4bVal) <<= 4;
-               *pu4bVal += MapCharToHexDigit(*szScan);
+               *pu4bVal = (*pu4bVal << 4) + hex_to_bin(*szScan);
 
                szScan++;
                (*pu4bMove)++;
-       } while(IsHexDigit(*szScan));
+       } while (isxdigit(*szScan));
 
        return TRUE;
 
-}      /* efuse_ParsingMap */
+}
 #endif
 
-//
-// Useless Section Code Now!!!!!!
-//
-// Porting from 8712 SDIO
 int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
 {
        u32 bResult;
-       //u8 efuse_ctlreg,tmpidx = 0;
        u8 tmpidx = 0;
        u8 tmpv8=0;
 
@@ -1965,7 +1884,6 @@ int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
 
        }
        else{
-               //return        0;
                write_nic_byte(dev, EFUSE_CTRL, *data);//data
 
                write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
@@ -1987,21 +1905,18 @@ int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
        }
        return bResult;
 }
-//------------------------------------------------------------------------------
+
 void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *data)
 {
        u8      efuse_clk_ori,efuse_clk_new;//,tmp8;
        u32 i = 0;
 
        if(start_addr>0x200) return;
-       //RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,
-       //      ("\n ===> efuse_access [start_addr=0x%x cnts:%d dataarray:0x%08x  Query Efuse].\n",start_addr,cnts,data));
        // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
        efuse_clk_ori = read_nic_byte(dev,SYS_FUNC_EN+1);
        efuse_clk_new = efuse_clk_ori|0x20;
 
        if(efuse_clk_new!= efuse_clk_ori){
-               //RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n"));
                write_nic_byte(dev, SYS_FUNC_EN+1, efuse_clk_new);
        }
 #ifdef _POWERON_DELAY_
@@ -2021,9 +1936,8 @@ void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *
        //-----------------e-fuse one byte read / write ------------------------------
        for(i=0;i<cnts;i++){
                efuse_one_byte_rw(dev,bRead, start_addr+i , data+i);
-               ////RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("==>efuse_access addr:0x%02x value:0x%02x\n",data+i,*(data+i)));
+
        }
-       // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
        write_nic_byte(dev, EFUSE_TEST+3, read_nic_byte(dev, EFUSE_TEST+3)&0x7f);
        write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
 
@@ -2031,8 +1945,6 @@ void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *
        if(efuse_clk_new != efuse_clk_ori)      write_nic_byte(dev, 0x10250003, efuse_clk_ori);
 
 }
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
 
 #ifdef TO_DO_LIST
 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn)
@@ -2060,15 +1972,12 @@ static  void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn)
                write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
                // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
 
-               //write_nic_byte(pAdapter, SYS_FUNC_EN+1,  read_nic_byte(pAdapter,SYS_FUNC_EN+1)&0xDF);
        }
 
 
 }
 #endif
-//------------------------------------------------------------------------------
 
-//------------------------------------------------------------------------------
 void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data_size)
 {
        u8 offset, word_start,byte_start,byte_cnts;
@@ -2079,10 +1988,8 @@ void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data
 
        u8 tmpidx;
        u8 pg_data[8];
-       //u8    temp_value[8] = {0xff};
 
        if(efuse_read_item>  (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
-               //error msg
                return ;
        }
 
@@ -2092,48 +1999,39 @@ void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data
        byte_cnts       = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].byte_cnts;
 
        if(data_size!=byte_cnts){
-               //error msg
                return;
        }
 
        pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
 
        if(pg_pkt_cnts > 1){
-               //tmpdata = _malloc(pg_pkt_cnts*PGPKT_DATA_SIZE);
                tmpdata = efusedata;
 
                if(tmpdata!=NULL)
                {
                        memset(tmpdata,0xff,pg_pkt_cnts*PGPKT_DATA_SIZE);
-                       //PlatformFillMemory((PVOID)pg_data, pg_pkt_cnts*PGPKT_DATA_SIZE, 0xff);
 
                        for(tmpidx=0;tmpidx<pg_pkt_cnts;tmpidx++)
                        {
                                memset(pg_data,0xff,PGPKT_DATA_SIZE);
-                               //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
                                if(TRUE== efuse_PgPacketRead(dev,offset+tmpidx,pg_data))
                                {
                                        memcpy(tmpdata+(PGPKT_DATA_SIZE*tmpidx),pg_data,PGPKT_DATA_SIZE);
-                                       //PlatformMoveMemory((PVOID)(tmpdata+(PGPKT_DATA_SIZE*tmpidx)), (PVOID)pg_data, PGPKT_DATA_SIZE);
                                }
                        }
                        memcpy(data,(tmpdata+ (2*word_start)+byte_start ),data_size);
-                       //PlatformMoveMemory((PVOID)data, (PVOID)(tmpdata+ (2*word_start)+byte_start ), data_size);
-                       //_mfree(tmpdata, pg_pkt_cnts*PGPKT_DATA_SIZE);
                }
        }
        else
        {
                memset(pg_data,0xff,PGPKT_DATA_SIZE);
-               //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
                if(TRUE==efuse_PgPacketRead(dev,offset,pg_data)){
                        memcpy(data,pg_data+ (2*word_start)+byte_start ,data_size);
-                       //PlatformMoveMemory((PVOID)data, (PVOID)(pg_data+ (2*word_start)+byte_start), data_size);
                }
        }
 
 }
-//------------------------------------------------------------------------------
+
 //per interface doesn't alike
 void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 data_size,u32 bWordUnit)
 {
@@ -2145,7 +2043,6 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
        u8 pg_data[8],tmpbytes=0;
 
        if(efuse_write_item>  (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
-               //error msg
                return ;
        }
 
@@ -2155,7 +2052,6 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
        byte_cnts       = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].byte_cnts;
 
        if(data_size >  byte_cnts){
-               //error msg
                return;
        }
        pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
@@ -2168,13 +2064,11 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
 
                if((efuse_write_item==EFUSE_F0CIS)||(efuse_write_item==EFUSE_F1CIS)){
                        memset(pg_data,0xff,PGPKT_DATA_SIZE);
-                       //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
                        efuse_PgPacketRead(dev,offset,pg_data);
 
                        if(efuse_write_item==EFUSE_F0CIS){
                                word_en = 0x07;
                                memcpy(pg_data+word_start*2+byte_start,data,sizeof(u8)*2);
-                               //PlatformMoveMemory((PVOID)(pg_data+word_start*2+byte_start), (PVOID)data, sizeof(u8)*2);
                                efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
 
                                word_en = 0x00;
@@ -2183,7 +2077,6 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
                                word_en = 0x00;
                                efuse_PgPacketRead(dev,offset+2,pg_data);
                                memcpy(pg_data,data+2+8,sizeof(u8)*7);
-                               //PlatformMoveMemory((PVOID)(pg_data), (PVOID)(data+2+8), sizeof(u8)*7);
 
                                efuse_PgPacketWrite(dev,(offset+2),word_en,pg_data);
                        }
@@ -2202,7 +2095,6 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
                }
                else{
                        memset(pg_data,0xff,PGPKT_DATA_SIZE);
-                       //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
                        if((efuse_write_item==EFUSE_SDIO_SETTING)||(efuse_write_item==EFUSE_CCCR)){
                                word_en = 0x0e ;
                                tmpbytes = 2;
@@ -2221,12 +2113,10 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
                        }
                        if(bWordUnit==TRUE){
                                memcpy(pg_data+word_start*2 ,data,sizeof(u8)*tmpbytes);
-                               //PlatformMoveMemory((PVOID)(pg_data+word_start*2), (PVOID)(data), sizeof(u8)*tmpbytes);
                        }
                        else{
                                efuse_PgPacketRead(dev,offset,pg_data);
                                memcpy(pg_data+(2*word_start)+byte_start,data,sizeof(u8)*byte_cnts);
-                               //PlatformMoveMemory((PVOID)(pg_data+(2*word_start)+byte_start), (PVOID)(data), sizeof(u8)*byte_cnts);
                        }
 
                        efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
@@ -2234,7 +2124,6 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
                }
 
        }
-       //========================================================================
        else if(pg_pkt_cnts>1){//situation B
                if(word_start==0){
                        word_en = 0x00;
@@ -2255,7 +2144,6 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
 
                }
        }
-       //========================================================================
        else{//situation C
                word_en = 0x0f;
                for(tmpidx= 0; tmpidx<word_cnts ; tmpidx++)
@@ -2267,7 +2155,6 @@ void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 da
        }
 
 }
-//------------------------------------------------------------------------------
 
 void efuset_test_func_read(struct net_device* dev)
 {
@@ -2288,7 +2175,6 @@ void efuset_test_func_read(struct net_device* dev)
        memset(txpowertable,0,sizeof(u8)*28);
        efuse_read_data(dev,EFUSE_TXPW_TAB,txpowertable,sizeof(txpowertable));
 }
-//------------------------------------------------------------------------------
 
 void efuset_test_func_write(struct net_device* dev)
 {
@@ -2311,19 +2197,3 @@ void efuset_test_func_write(struct net_device* dev)
        efuse_write_data(dev,EFUSE_SDIO_SETTING,tmpdata,sizeof(tmpdata),bWordUnit);
 
 }
-//------------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-/* End of Efuse.c */
-
-
-
-
index 1e50153ba02ceea5bfb27f50c035e51d1d1fc8cd..c48a11bc06fe1f21bf8613168ed1cc1fbbf2ad42 100644 (file)
@@ -1,39 +1,38 @@
 /******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
  *
- *     (c) Copyright  2008, RealTEK Technologies Inc. All Rights Reserved.
+ * Based on the r8180 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
  *
- * Module:     Efuse.h ( Header File)
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
  *
- * Note:
- *
- * Function:
- *
- * Export:
- *
- * Abbrev:
- *
- * History:
- * Data                        Who             Remark
- *
- * 09/23/2008  MHC             Porting Efuse R/W API from WMAC.
- * 11/10/2008  MHC             Porting Efuse.h from 8712 SDIO.
- *                                             1. We muse redefine the header file to fit our coding
- *                                                style.
- *                                             2. THe API we export to other module, we must redefine
- *                                                for 8192S series.
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
  *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
 ******************************************************************************/
-/* Check to see if the file has been included already.  */
 
 #ifndef __INC_EFUSE_H
 #define __INC_EFUSE_H
 
-// Roger porting for 8192SU
 #define                EFUSE_FOR_92SU          1
 
-/*--------------------------Define Parameters-------------------------------*/
 #define                EFUSE_MAC_LEN                                   0x200
+#define                EFUSE_REAL_CONTENT_LEN          512
+#define                EFUSE_MAP_LEN                                   128
+#define                EFUSE_MAX_SECTION                       16
+#define                EFUSE_MAX_WORD_UNIT                     4
 
 #define                EFUSE_INIT_MAP                          0
 #define                EFUSE_MODIFY_MAP                                1
@@ -41,7 +40,6 @@
 #define                EFUSE_CLK_CTRL                  EFUSE_CTRL
 #define        EFUSE_BIT(x)  (1 << (x))
 
-// From 8712!!!!!!!!
 #define                PG_STATE_HEADER         0x01
 #define                PG_STATE_WORD_0         0x02
 #define                PG_STATE_WORD_1         0x04
 #define                PG_SWBYTE_H                     0x01
 #define                PG_SWBYTE_L                     0x02
 
-/*--------------------------Define Parameters-------------------------------*/
-
-
-/*------------------------------Define structure----------------------------*/
-
-/*------------------------------Define structure----------------------------*/
-
-
-/*------------------------Export global variable----------------------------*/
-/*------------------------Export global variable----------------------------*/
-
-/*------------------------Export Marco Definition---------------------------*/
-
-/*------------------------Export Marco Definition---------------------------*/
-
-
-/*--------------------------Exported Function prototype---------------------*/
 extern void
 EFUSE_Initialize(struct net_device* dev);
 extern u8
@@ -81,21 +62,18 @@ extern      void
 ReadEFuse(struct net_device* dev,u16 _offset,u16 _size_byte,u8* pbuf);
 extern void
 ReadEFuseByte(struct net_device* dev,u16  _offset,u8  *pbuf);
-#endif // #if (EFUSE_FOR_92SU == 1)
+#endif
 
 extern void
 EFUSE_ShadowRead(struct net_device* dev,unsigned char Type,unsigned short Offset,u32 *Value);
 extern void
 EFUSE_ShadowWrite(struct net_device* dev,unsigned char Type,unsigned short Offset,u32 Value);
-extern void
+extern bool
 EFUSE_ShadowUpdate(struct net_device* dev);
 extern void
 EFUSE_ShadowMapUpdate(struct net_device* dev);
 
 extern bool
 EFUSE_ProgramMap(struct net_device* dev,char* pFileName, u8 TableType);                // 0=Shadow 1=Real Efuse
-/*--------------------------Exported Function prototype---------------------*/
-
-/* End of Efuse.h */
 
-#endif //__INC_EFUSE_H
+#endif
index 5036d547d5d389ee5bda0a2d69d9eac9d595daf2..db0d2d5fc61b30bb2d5c94a7a29af1f9c3a8d2a7 100644 (file)
@@ -1,16 +1,22 @@
-/**************************************************************************************************
- * Procedure:    Init boot code/firmware code/data session
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
  *
- * Description: This routine will intialize firmware. If any error occurs during the initialization
- *             process, the routine shall terminate immediately and return fail.
- *             NIC driver should call NdisOpenFile only from MiniportInitialize.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
  *
- * Arguments:   The pointer of the adapter
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 
- * Returns:
- *        NDIS_STATUS_FAILURE - the following initialization process should be terminated
- *        NDIS_STATUS_SUCCESS - if firmware initialization process success
-**************************************************************************************************/
 #include "r8192U.h"
 #include "r8192S_firmware.h"
 #include <linux/unistd.h>
index 2c2cf8032deda9b4cba5567b08f5eed463b8aaf0..7f268a8de5e8820095706eee31dd8fde3e9965f9 100644 (file)
@@ -1,44 +1,32 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #ifndef __INC_FIRMWARE_H
 #define __INC_FIRMWARE_H
 
 
-//#define RTL8190_CPU_START_OFFSET     0x80
-/* TODO: this definition is TBD */
-//#define USB_HWDESC_HEADER_LEN        0
-
-/* It should be double word alignment */
-//#if DEV_BUS_TYPE==PCI_INTERFACE
-//#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) 4*(v/4) - 8
-//#else
-//#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
-//#endif
-
-//typedef enum _firmware_init_step{
-//     FW_INIT_STEP0_BOOT = 0,
-//     FW_INIT_STEP1_MAIN = 1,
-//     FW_INIT_STEP2_DATA = 2,
-//}firmware_init_step_e;
-
-//typedef enum _DESC_PACKET_TYPE{
-//     DESC_PACKET_TYPE_INIT = 0,
-//     DESC_PACKET_TYPE_NORMAL = 1,
-//}DESC_PACKET_TYPE;
-#define        RTL8192S_FW_PKT_FRAG_SIZE               0xFF00  // 64K
-
-
 #define        RTL8190_MAX_FIRMWARE_CODE_SIZE  64000   //64k
 #define        MAX_FIRMWARE_CODE_SIZE  0xFF00 // Firmware Local buffer size.
 #define        RTL8190_CPU_START_OFFSET                        0x80
-
+#define        RTL8192S_FW_PKT_FRAG_SIZE               0x4000
 #define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)   (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
 
-//typedef enum _DESC_PACKET_TYPE{
-//     DESC_PACKET_TYPE_INIT = 0,
-//     DESC_PACKET_TYPE_NORMAL = 1,
-//}DESC_PACKET_TYPE;
 
-// Forward declaration.
-//typedef      struct _ADAPTER ADAPTER, *PADAPTER;
 #ifdef RTL8192S
 typedef enum _firmware_init_step{
        FW_INIT_STEP0_IMEM = 0,
@@ -64,17 +52,8 @@ typedef enum _opt_rst_type{
        OPT_FIRMWARE_RESET = 1,
 }opt_rst_type_e;
 
-/*typedef enum _FIRMWARE_STATUS{
-       FW_STATUS_0_INIT = 0,
-       FW_STATUS_1_MOVE_BOOT_CODE = 1,
-       FW_STATUS_2_MOVE_MAIN_CODE = 2,
-       FW_STATUS_3_TURNON_CPU = 3,
-       FW_STATUS_4_MOVE_DATA_CODE = 4,
-       FW_STATUS_5_READY = 5,
-}FIRMWARE_STATUS;
-*/
 //--------------------------------------------------------------------------------
-// RTL8192S Firmware related, Revised by Roger, 2008.12.18.
+// RTL8192S Firmware related
 //--------------------------------------------------------------------------------
 typedef  struct _RT_8192S_FIRMWARE_PRIV { //8-bytes alignment required
 
@@ -181,7 +160,6 @@ typedef enum _FIRMWARE_8192S_STATUS{
 typedef struct _rt_firmware{
        PRT_8192S_FIRMWARE_HDR  pFwHeader;
        FIRMWARE_8192S_STATUS   FWStatus;
-       u16             FirmwareVersion;
        u8              FwIMEM[RTL8190_MAX_FIRMWARE_CODE_SIZE];
        u8              FwEMEM[RTL8190_MAX_FIRMWARE_CODE_SIZE];
        u32             FwIMEMLen;
@@ -189,11 +167,43 @@ typedef struct _rt_firmware{
        u8              szFwTmpBuffer[164000];
         u32             szFwTmpBufferLen;
        u16             CmdPacketFragThresold;
+       u16             FirmwareVersion;
 }rt_firmware, *prt_firmware;
 
-//typedef struct _RT_FIRMWARE_INFO_8192SU{
-//     u8              szInfo[16];
-//}RT_FIRMWARE_INFO_8192SU, *PRT_FIRMWARE_INFO_8192SU;
+#define                FW_DIG_ENABLE_CTL                       BIT0
+#define                FW_HIGH_PWR_ENABLE_CTL          BIT1
+#define                FW_SS_CTL                                               BIT2
+#define                FW_RA_INIT_CTL                          BIT3
+#define                FW_RA_BG_CTL                                    BIT4
+#define                FW_RA_N_CTL                                     BIT5
+#define                FW_PWR_TRK_CTL                          BIT6
+#define                FW_IQK_CTL                                              BIT7
+#define                FW_ANTENNA_SW                           BIT8
+#define                FW_DISABLE_ALL_DM                       0
+
+#define                FW_PWR_TRK_PARAM_CLR            0x0000ffff
+#define                FW_RA_PARAM_CLR                         0xffff0000
+
+#define        FW_CMD_IO_CLR(_pdev, _Bit)              \
+       udelay(1000);           \
+       ((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap &= (~_Bit);
+
+#define        FW_CMD_IO_UPDATE(_pdev, _val)           \
+       ((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap = _val;
+
+#define                FW_CMD_IO_SET(_pdev, _val)      \
+       write_nic_word(_pdev, LBUS_MON_ADDR, (u16)_val);        \
+       FW_CMD_IO_UPDATE(_pdev, _val);
+
+#define                FW_CMD_PARA_SET(_pdev, _val)            \
+       write_nic_dword(_pdev, LBUS_ADDR_MASK, _val);   \
+       ((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOParam = _val;
+
+#define                FW_CMD_IO_QUERY(_pdev)  (u16)(((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap)
+#define        FW_CMD_IO_PARA_QUERY(_pdev)     (u32)(((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOParam)
+
+
+
 bool FirmwareDownload92S(struct net_device *dev);
 
 #endif
index 82ea96b6f4d1c388803cfaaeb863bc2ec2817179..e62b79df5ba5b50441dae8d20397e6f6cede6e47 100644 (file)
@@ -1,25 +1,22 @@
-/*****************************************************************************
- *     Copyright(c) 2008,  RealTEK Technology Inc. All Right Reserved.
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
  *
- * Module:     __INC_HAL8192SEREG_H
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
  *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  *
- * Note:       1. Define Mac register address and corresponding bit mask map
- *                     2. CCX register
- *                     3. Backward compatible register with useless address.
- *                     4. Define 92SU required register address and definition.
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
  *
- *
- * Export:     Constants, macro, functions(API), global variables(None).
- *
- * Abbrev:
- *
- * History:
- *             Data            Who             Remark
- *      08/07/2007  MHC        1. Porting from 9x series PHYCFG.h.
- *                                                     2. Reorganize code architecture.
- *
- *****************************************************************************/
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
+
 #ifndef R8192S_HW
 #define R8192S_HW
 
@@ -29,21 +26,14 @@ typedef enum _VERSION_8192S{
        VERSION_8192S_CCUT
 }VERSION_8192S,*PVERSION_8192S;
 
-//#ifdef RTL8192SU
 typedef enum _VERSION_8192SUsb{
        VERSION_8192SU_A, //A-Cut
        VERSION_8192SU_B, //B-Cut
        VERSION_8192SU_C, //C-Cut
 }VERSION_8192SUsb, *PVERSION_8192SUsb;
-//#else
-typedef enum _VERSION_819xU{
-       VERSION_819xU_A, // A-cut
-       VERSION_819xU_B, // B-cut
-       VERSION_819xU_C,// C-cut
-}VERSION_819xU,*PVERSION_819xU;
-//#endif
-
-/* 2007/11/15 MH Define different RF type. */
+
+
+/* RF type. */
 typedef        enum _RT_RF_TYPE_DEFINITION
 {
        RF_1T2R = 0,
@@ -51,9 +41,6 @@ typedef       enum _RT_RF_TYPE_DEFINITION
        RF_2T2R,
        RF_1T1R,
        RF_2T2R_GREEN,
-       //RF_3T3R,
-       //RF_3T4R,
-       //RF_4T4R,
        RF_819X_MAX_TYPE
 }RT_RF_TYPE_DEF_E;
 
@@ -68,12 +55,10 @@ typedef enum _BaseBand_Config_Type{
 #define        RTL8187_REQ_SET_REGS    0x05
 
 #define MAX_TX_URB 5
-#define MAX_RX_URB 16
+#define MAX_RX_URB 8
 
 #define R8180_MAX_RETRY 255
-//#define MAX_RX_NORMAL_URB 3
-//#define MAX_RX_COMMAND_URB 2
-#define RX_URB_SIZE            9100
+#define RX_URB_SIZE            0x4000
 
 #define BB_ANTATTEN_CHAN14     0x0c
 #define BB_ANTENNA_B           0x40
@@ -134,7 +119,6 @@ typedef enum _BaseBand_Config_Type{
 #define MSR_LINK_ENEDCA                (1<<4)
 
 
-//#define Cmd9346CR_9356SEL    (1<<4)
 #define EPROM_CMD_RESERVED_MASK                        (1<<5)
 #define EPROM_CMD_OPERATING_MODE_SHIFT         6
 #define EPROM_CMD_OPERATING_MODE_MASK  ((1<<7)|(1<<6))
@@ -147,13 +131,6 @@ typedef enum _BaseBand_Config_Type{
 #define EPROM_W_SHIFT                  1
 #define EPROM_R_SHIFT                  0
 
-//#define      MAC0                     0x000,
-//#define      MAC1                     0x001,
-//#define      MAC2                     0x002,
-//#define      MAC3                     0x003,
-//#define      MAC4                     0x004,
-//#define      MAC5                     0x005,
-
 //============================================================
 //       8192S Regsiter offset definition
 //============================================================
@@ -529,14 +506,6 @@ typedef enum _BaseBand_Config_Type{
 // USB RPWM register
 #define        USB_RPWM                        0xFE58
 
-//FIXLZM SVN_BRACH NOT MOD HERE, IF MOD RX IS LITTLE LOW
-//#if ((HAL_CODE_BASE == RTL8192_S) &&  (DEV_BUS_TYPE==PCI_INTERFACE))
-//#define      RPWM            PCI_RPWM
-//#elif ((HAL_CODE_BASE == RTL8192_S) &&  (DEV_BUS_TYPE==USB_INTERFACE))
-//#define      RPWM            USB_RPWM
-//#endif
-
-
 //============================================================================
 //       8190 Regsiter offset definition
 //============================================================================
@@ -777,13 +746,11 @@ typedef enum _BaseBand_Config_Type{
 #define                RCR_MXDMA_OFFSET                8
 #define                RCR_FIFO_OFFSET         13
 
-//in 92U FIXLZM
-//#ifdef RTL8192U
 #define RCR_ONLYERLPKT         BIT31                   // Early Receiving based on Packet Size.
 #define RCR_ENCS2                      BIT30                   // Enable Carrier Sense Detection Method 2
 #define RCR_ENCS1                      BIT29                   // Enable Carrier Sense Detection Method 1
 #define RCR_ACKTXBW                    (BIT24|BIT25)           // TXBW Setting of ACK frames
-//#endif
+
 //----------------------------------------------------------------------------
 //       8192S (MSR) Media Status Register     (Offset 0x4C, 8 bits)
 //----------------------------------------------------------------------------
@@ -1259,17 +1226,18 @@ Default: 00b.
 #define                EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN       0x9
 #define                EEPROM_CHANNEL_PLAN_WORLD_WIDE_13       0xA
 #define                EEPROM_CHANNEL_PLAN_BY_HW_MASK  0x80
+#define        EEPROM_CID_DEFAULT                      0x0
+#define        EEPROM_CID_ALPHA                        0x1
+#define        EEPROM_CID_Senao                        0x3
+#define                EEPROM_CID_CAMEO                        0X8
+#define        EEPROM_CID_SITECOM                      0x9
+#define        EEPROM_CID_COREGA                       0xB
+#define        EEPROM_CID_EDIMAX_BELKIN                0xC
+#define                EEPROM_CID_SERCOMM_BELKIN               0xE
+#define                EEPROM_CID_CAMEO1                       0xF
+#define        EEPROM_CID_WHQL                         0xFE
+#define                EEPROM_CID_NetCore                      0x5
 
-#define                EEPROM_CID_DEFAULT                              0x0
-#define                EEPROM_CID_ALPHA                                0x1
-#define                EEPROM_CID_CAMEO                                        0X8
-#define                EEPROM_CID_SITECOM                              0x9
-
-//#define EEPROM_CID_RUNTOP                                            0x2
-//#define EEPROM_CID_Senao                                             0x3
-//#define EEPROM_CID_TOSHIBA                                           0x4
-//#define EEPROM_CID_NetCore                                           0x5
-#define                EEPROM_CID_WHQL                                 0xFE // added by chiyoko for dtm, 20090108
 
 //-----------------------------------------------------------------
 // 0x2c0 FW Command Control register definition, added by Roger, 2008.11.27.
@@ -1282,18 +1250,32 @@ Default: 00b.
 #define                FW_HIGH_PWR_ENABLE                      0xfd000009
 #define                FW_TXPWR_TRACK_ENABLE           0xfd000017
 #define                FW_TXPWR_TRACK_DISABLE          0xfd000018
-#define                FW_RA_RESET                                     0xfd0000af
-#define                FW_RA_ACTIVE                                    0xfd0000a6
+#define                FW_TXPWR_TRACK_THERMAL          0xfd000019
+#define                FW_RA_INIT                                              0xfd000026
+#define                FW_RA_IOT_BG_COMB                       0xfd000030
+#define                FW_RA_IOT_N_COMB                                0xfd000031
 #define                FW_RA_REFRESH                                   0xfd0000a0
-#define                FW_RA_ENABLE_BG                         0xfd0000ac
+#define                FW_RA_DISABLE                                   0xfd0000a4
+#define                FW_RA_ACTIVE                                    0xfd0000a6
+#define                FW_RA_DISABLE_RSSI_MASK         0xfd0000ac
+#define                FW_RA_ENABLE_RSSI_MASK          0xfd0000ad
+#define                FW_RA_RESET                                     0xfd0000af
+#define                FW_DM_DISABLE                                   0xfd00aa00
 #define                FW_IQK_ENABLE                                   0xf0000020
 #define                FW_IQK_SUCCESS                          0x0000dddd
 #define                FW_IQK_FAIL                                     0x0000ffff
 #define                FW_OP_FAILURE                                   0xffffffff
-#define                FW_DM_DISABLE                                   0xfd00aa00
+#define                FW_TX_FEEDBACK_NONE                             0xfb000000
+#define                FW_TX_FEEDBACK_DTM_ENABLE               (FW_TX_FEEDBACK_NONE | 0x1)
+#define                FW_TX_FEEDBACK_CCX_ENABLE               (FW_TX_FEEDBACK_NONE | 0x2)
 #define                FW_BB_RESET_ENABLE                      0xff00000d
 #define                FW_BB_RESET_DISABLE                     0xff00000e
-
+#define                FW_LPS_ENTER                                    0xfe000010
+#define                FW_LPS_LEAVE                                    0xfe000011
+#define                FW_INDIRECT_READ                                0xf2000000
+#define                FW_INDIRECT_WRITE                               0xf2000001
+#define                FW_TXANT_SWITCH_ENABLE          0xfd000023
+#define                FW_TXANT_SWITCH_DISABLE         0xfd000024
 //
 //--------------92SU require delete or move to other place later
 //
@@ -1460,34 +1442,4 @@ Default: 00b.
 #define                HAL_8192S_HW_GPIO_OFF_MASK      0xF7
 #define                HAL_8192S_HW_GPIO_WPS_BIT       BIT4
 
-#endif  //R8192S_HW
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+#endif
index b6c0f19907428f5d62999ada41c31678c0285cb7..a5fc2d1cb062b3bbcd364fa28ed2fc4317312d58 100644 (file)
@@ -1,35 +1,20 @@
 /******************************************************************************
-
-     (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
-
- Module:       hal8192sphy.c
-
- Note:         Merge 92SE/SU PHY config as below
-                       1. BB register R/W API
-                       2. RF register R/W API
-                       3. Initial BB/RF/MAC config by reading BB/MAC/RF txt.
-                       3. Power setting API
-                       4. Channel switch API
-                       5. Initial gain switch API.
-                       6. Other BB/MAC/RF API.
-
- Function:     PHY: Extern function, phy: local function
-
- Export:       PHY_FunctionName
-
- Abbrev:       NONE
-
- History:
-       Data            Who             Remark
-       08/08/2008  MHC         1. Port from 9x series phycfg.c
-                                               2. Reorganize code arch and ad description.
-                                               3. Collect similar function.
-                                               4. Seperate extern/local API.
-       08/12/2008      MHC             We must merge or move USB PHY relative function later.
-       10/07/2008      MHC             Add IQ calibration for PHY.(Only 1T2R mode now!!!)
-       11/06/2008      MHC             Add TX Power index PG file to config in 0xExx register
-                                               area to map with EEPROM/EFUSE tx pwr index.
-
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
 ******************************************************************************/
 #include "r8192U.h"
 #include "r8192U_dm.h"
 
 #include "ieee80211/dot11d.h"
 
-/*---------------------------Define Local Constant---------------------------*/
 /* Channel switch:The size of command tables for switch channel*/
 #define MAX_PRECMD_CNT 16
 #define MAX_RFDEPENDCMD_CNT 16
 #define MAX_POSTCMD_CNT 16
 #define MAX_DOZE_WAITING_TIMES_9x 64
 
-/*------------------------Define local variable------------------------------*/
-// 2004-05-11
-
 static u32
 phy_CalculateBitShift(u32 BitMask);
 static RT_STATUS
@@ -86,7 +67,6 @@ static long phy_TxPwrIdxToDbm( struct net_device* dev, WIRELESS_MODE   WirelessM
 static u8 phy_DbmToTxPwrIdx( struct net_device* dev, WIRELESS_MODE WirelessMode, long PowerInDbm);
 void phy_SetFwCmdIOCallback(struct net_device* dev);
 
-//#if ((HAL_CODE_BASE == RTL8192_S) && (DEV_BUS_TYPE==USB_INTERFACE))
 //
 // Description:
 //     Base Band read by 4181 to make sure that operation could be done in unlimited cycle.
@@ -95,8 +75,6 @@ void phy_SetFwCmdIOCallback(struct net_device* dev);
 //             -       Only use on RTL8192S USB interface.
 //             -       PASSIVE LEVEL
 //
-// Created by Roger, 2008.09.06.
-//
 //use in phy only
 u32 phy_QueryUsbBBReg(struct net_device* dev, u32      RegAddr)
 {
@@ -118,7 +96,7 @@ u32 phy_QueryUsbBBReg(struct net_device* dev, u32    RegAddr)
                msleep(1); // 1 ms
 
                // Wait too long, return FALSE to avoid to be stuck here.
-               if((BBWaitCounter > 100) )//||RT_USB_CANNOT_IO(Adapter))
+               if((BBWaitCounter > 100) )
                {
                        RT_TRACE(COMP_RF, "phy_QueryUsbBBReg(): (%d) Wait too logn to query BB!!\n", BBWaitCounter);
                        return ReturnValue;
@@ -160,9 +138,6 @@ u32 phy_QueryUsbBBReg(struct net_device* dev, u32   RegAddr)
 // Assumption:
 //             -       Only use on RTL8192S USB interface.
 //             -       PASSIVE LEVEL
-//
-// Created by Roger, 2008.09.06.
-//
 //use in phy only
 void
 phy_SetUsbBBReg(struct net_device* dev,u32     RegAddr,u32 Data)
@@ -191,7 +166,6 @@ phy_SetUsbBBReg(struct net_device* dev,u32  RegAddr,u32 Data)
        }
 
        priv->bChangeBBInProgress = true;
-       //printk("**************%s: RegAddr:%x Data:%x\n", __FUNCTION__,RegAddr, Data);
        write_nic_dword(dev, RegAddr, Data);
 
        priv->bChangeBBInProgress = false;
@@ -215,9 +189,7 @@ u32 phy_QueryUsbRFReg(      struct net_device* dev, RF90_RADIO_PATH_E eRFPath,      u32     Of
 {
 
        struct r8192_priv *priv = ieee80211_priv(dev);
-       //u32   value  = 0, ReturnValue = 0;
        u32     ReturnValue = 0;
-       //u32   tmplong,tmplong2;
        u8      PollingCnt = 50;
        u8      RFWaitCounter = 0;
 
@@ -229,8 +201,6 @@ u32 phy_QueryUsbRFReg(      struct net_device* dev, RF90_RADIO_PATH_E eRFPath,      u32     Of
        //
        while(priv->bChangeRFInProgress)
        {
-               //PlatformReleaseSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
-               //spin_lock_irqsave(&priv->rf_lock, flags);     //LZM,090318
                down(&priv->rf_sem);
 
                RFWaitCounter ++;
@@ -244,14 +214,10 @@ u32 phy_QueryUsbRFReg(    struct net_device* dev, RF90_RADIO_PATH_E eRFPath,      u32     Of
                }
                else
                {
-                       //PlatformAcquireSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
                }
        }
 
        priv->bChangeRFInProgress = true;
-       //PlatformReleaseSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
-
-
        Offset &= 0x3f; //RF_Offset= 0x00~0x3F
 
        write_nic_dword(dev, RF_BB_CMD_ADDR, 0xF0000002|
@@ -267,8 +233,6 @@ u32 phy_QueryUsbRFReg(      struct net_device* dev, RF90_RADIO_PATH_E eRFPath,      u32     Of
        // Data FW read back.
        ReturnValue = read_nic_dword(dev, RF_BB_CMD_DATA);
 
-       //PlatformAcquireSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
-       //spin_unlock_irqrestore(&priv->rf_lock, flags);   //LZM,090318
        up(&priv->rf_sem);
        priv->bChangeRFInProgress = false;
 
@@ -306,27 +270,23 @@ void phy_SetUsbRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 RegAdd
        //
        while(priv->bChangeRFInProgress)
        {
-               //PlatformReleaseSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
-               //spin_lock_irqsave(&priv->rf_lock, flags);     //LZM,090318
                down(&priv->rf_sem);
 
                RFWaitCounter ++;
                RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): Wait 1 ms (%d times)...\n", RFWaitCounter);
                msleep(1); // 1 ms
 
-               if((RFWaitCounter > 100))// || RT_USB_CANNOT_IO(Adapter))
+               if((RFWaitCounter > 100))
                {
                        RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): (%d) Wait too logn to query BB!!\n", RFWaitCounter);
                        return;
                }
                else
                {
-                       //PlatformAcquireSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
                }
        }
 
        priv->bChangeRFInProgress = true;
-       //PlatformReleaseSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
 
 
        RegAddr &= 0x3f; //RF_Offset= 0x00~0x3F
@@ -347,18 +307,11 @@ void phy_SetUsbRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 RegAdd
                RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): Set RegAddr(%#x) = %#x Fail!!!\n", RegAddr, Data);
        }
 
-       //PlatformAcquireSpinLock(Adapter, RT_RF_OPERATE_SPINLOCK);
-       //spin_unlock_irqrestore(&priv->rf_lock, flags);   //LZM,090318
        up(&priv->rf_sem);
        priv->bChangeRFInProgress = false;
 
 }
 
-
-/*---------------------Define local function prototype-----------------------*/
-
-
-/*----------------------------Function Body----------------------------------*/
 //
 // 1. BB register R/W API
 //
@@ -376,8 +329,6 @@ void phy_SetUsbRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32   RegAdd
 * Return:              u32                     Data                    //The readback register value
 * Note:                This function is equal to "GetRegSetting" in PHY programming guide
 */
-//use phy dm core 8225 8256 6052
-//u32 PHY_QueryBBReg(struct net_device* dev,u32                RegAddr,        u32             BitMask)
 u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
 {
 
@@ -392,10 +343,8 @@ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
        // infinite cycle.
        // 2008.09.06.
        //
-//#if ((HAL_CODE_BASE == RTL8192_S) && (DEV_BUS_TYPE==USB_INTERFACE))
        if(IS_BB_REG_OFFSET_92S(RegAddr))
        {
-               //if(RT_USB_CANNOT_IO(Adapter)) return  FALSE;
 
                if((RegAddr & 0x03) != 0)
                {
@@ -413,7 +362,7 @@ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
        BitShift = phy_CalculateBitShift(BitMask);
        ReturnValue = (OriginalValue & BitMask) >> BitShift;
 
-       //RTPRINT(FPHY, PHY_BBR, ("BBR MASK=0x%x Addr[0x%x]=0x%x\n", BitMask, RegAddr, OriginalValue));
+
        RT_TRACE(COMP_RF, "<---PHY_QueryBBReg(): RegAddr(%#x), BitMask(%#x), OriginalValue(%#x)\n", RegAddr, BitMask, OriginalValue);
        return (ReturnValue);
 }
@@ -435,8 +384,6 @@ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
 * Return:              None
 * Note:                This function is equal to "PutRegSetting" in PHY programming guide
 */
-//use phy dm core 8225 8256
-//void PHY_SetBBReg(struct net_device* dev,u32         RegAddr,        u32             BitMask,        u32             Data    )
 void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data)
 {
        u32     OriginalValue, BitShift, NewValue;
@@ -450,7 +397,6 @@ void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data
        // infinite cycle.
        // 2008.09.06.
        //
-//#if ((HAL_CODE_BASE == RTL8192_S) && (DEV_BUS_TYPE==USB_INTERFACE))
        if(IS_BB_REG_OFFSET_92S(RegAddr))
        {
                if((RegAddr & 0x03) != 0)
@@ -480,7 +426,6 @@ void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data
                        write_nic_dword(dev, RegAddr, Data);
        }
 
-       //RT_TRACE(COMP_RF, "<---PHY_SetBBReg(): RegAddr(%#x), BitMask(%#x), Data(%#x)\n", RegAddr, BitMask, Data);
 
        return;
 }
@@ -505,8 +450,6 @@ void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data
 * Return:              u32                     Readback value
 * Note:                This function is equal to "GetRFRegSetting" in PHY programming guide
 */
-//in dm 8256 and phy
-//u32 PHY_QueryRFReg(struct net_device* dev,   RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask)
 u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask)
 {
        u32 Original_Value, Readback_Value, BitShift;//, flags;
@@ -527,9 +470,6 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3
                return 0;
        }
 
-       /* 2008/01/17 MH We get and release spin lock when reading RF register. */
-       //PlatformAcquireSpinLock(dev, RT_RF_OPERATE_SPINLOCK);FIXLZM
-       //spin_lock_irqsave(&priv->rf_lock, flags);     //YJ,test,090113
        down(&priv->rf_sem);
        //
        // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
@@ -537,17 +477,11 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3
        // infinite cycle.
        // 2008.09.06.
        //
-//#if (HAL_CODE_BASE == RTL8192_S && DEV_BUS_TYPE==USB_INTERFACE)
-       //if(RT_USB_CANNOT_IO(Adapter)) return FALSE;
        Original_Value = phy_QueryUsbRFReg(dev, eRFPath, RegAddr);
 
        BitShift =  phy_CalculateBitShift(BitMask);
        Readback_Value = (Original_Value & BitMask) >> BitShift;
-       //spin_unlock_irqrestore(&priv->rf_lock, flags);   //YJ,test,090113
        up(&priv->rf_sem);
-       //PlatformReleaseSpinLock(dev, RT_RF_OPERATE_SPINLOCK);
-
-       //RTPRINT(FPHY, PHY_RFR, ("RFR-%d MASK=0x%x Addr[0x%x]=0x%x\n", eRFPath, BitMask, RegAddr, Original_Value));
 
        return (Readback_Value);
 }
@@ -570,8 +504,6 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3
 * Return:              None
 * Note:                This function is equal to "PutRFRegSetting" in PHY programming guide
 */
-//use phy  8225 8256
-//void PHY_SetRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath, u32      RegAddr,        u32 BitMask,u32 Data    )
 void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
 {
 
@@ -592,18 +524,11 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32
                return;
        }
 
-       /* 2008/01/17 MH We get and release spin lock when writing RF register. */
-       //PlatformAcquireSpinLock(dev, RT_RF_OPERATE_SPINLOCK);
-       //spin_lock_irqsave(&priv->rf_lock, flags);     //YJ,test,090113
        down(&priv->rf_sem);
        //
        // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
        // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
        // infinite cycle.
-       // 2008.09.06.
-       //
-//#if (HAL_CODE_BASE == RTL8192_S && DEV_BUS_TYPE==USB_INTERFACE)
-               //if(RT_USB_CANNOT_IO(Adapter)) return;
 
                if (BitMask != bRFRegOffsetMask) // RF data is 12 bits only
                {
@@ -614,10 +539,7 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32
                }
                else
                        phy_SetUsbRFReg(dev, eRFPath, RegAddr, Data);
-       //PlatformReleaseSpinLock(dev, RT_RF_OPERATE_SPINLOCK);
-       //spin_unlock_irqrestore(&priv->rf_lock, flags);   //YJ,test,090113
        up(&priv->rf_sem);
-       //RTPRINT(FPHY, PHY_RFW, ("RFW-%d MASK=0x%x Addr[0x%x]=0x%x\n", eRFPath, BitMask, RegAddr, Data));
        RT_TRACE(COMP_RF, "<---PHY_SetRFReg(): RegAddr(%#x), BitMask(%#x), Data(%#x), eRFPath(%#x)\n",
                        RegAddr, BitMask, Data, eRFPath);
 
@@ -691,29 +613,9 @@ PHY_BBConfig8192S(struct net_device* dev)
        struct r8192_priv       *priv = ieee80211_priv(dev);
        phy_InitBBRFRegisterDefinition(dev);
 
-       //
-       // Config BB and AGC
-       //
-       //switch( Adapter->MgntInfo.bRegHwParaFile )
-       //{
-       //      case 0:
-       //              phy_BB8190_Config_HardCode(dev);
-       //              break;
 
-       //      case 1:
                        rtStatus = phy_BB8192S_Config_ParaFile(dev);
-       //              break;
-
-       //      case 2:
-                       // Partial Modify.
-       //              phy_BB8190_Config_HardCode(dev);
-       //              phy_BB8192S_Config_ParaFile(dev);
-       //              break;
-
-       //      default:
-       //              phy_BB8190_Config_HardCode(dev);
-       //              break;
-       //}
+
        PathMap = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_TxInfo, 0xf) |
                                rtl8192_QueryBBReg(dev, rOFDM0_TRxPathEnable, 0xf));
        priv->rf_pathmap = PathMap;
@@ -774,15 +676,10 @@ PHY_RFConfig8192S(struct net_device* dev)
 }
 
 
-// Joseph test: new initialize order!!
-// Test only!! This part need to be re-organized.
-// Now it is just for 8256.
-//use in phy only
 #ifdef TO_DO_LIST
 static RT_STATUS
 phy_BB8190_Config_HardCode(struct net_device* dev)
 {
-       //RT_ASSERT(FALSE, ("This function is not implement yet!! \n"));
        return RT_STATUS_SUCCESS;
 }
 #endif
@@ -811,7 +708,6 @@ phy_SetBBtoDiffRFWithHeaderFile(struct net_device* dev, u8 ConfigType)
        u32*                    Rtl819XPHY_REGArraytoXTXR_Table;
        u16                             PHY_REGArraytoXTXRLen;
 
-//#if (HAL_CODE_BASE != RTL8192_S)
 
        if(priv->rf_type == RF_1T1R)
        {
@@ -823,11 +719,6 @@ phy_SetBBtoDiffRFWithHeaderFile(struct net_device* dev, u8 ConfigType)
                Rtl819XPHY_REGArraytoXTXR_Table = Rtl819XPHY_REG_to1T2R_Array;
                PHY_REGArraytoXTXRLen = PHY_ChangeTo_1T2RArrayLength;
        }
-       //else if(priv->rf_type == RF_2T2R || priv->rf_type == RF_2T2R_GREEN)
-       //{
-       //      Rtl819XPHY_REGArraytoXTXR_Table = Rtl819XPHY_REG_to2T2R_Array;
-       //      PHY_REGArraytoXTXRLen = PHY_ChangeTo_2T2RArrayLength;
-       //}
        else
        {
                return RT_STATUS_FAILURE;
@@ -850,15 +741,11 @@ phy_SetBBtoDiffRFWithHeaderFile(struct net_device* dev, u8 ConfigType)
                        else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xf9)
                                udelay(1);
                        rtl8192_setBBreg(dev, Rtl819XPHY_REGArraytoXTXR_Table[i], Rtl819XPHY_REGArraytoXTXR_Table[i+1], Rtl819XPHY_REGArraytoXTXR_Table[i+2]);
-                       //RT_TRACE(COMP_SEND,
-                       //"The Rtl819XPHY_REGArraytoXTXR_Table[0] is %lx Rtl819XPHY_REGArraytoXTXR_Table[1] is %lx Rtl819XPHY_REGArraytoXTXR_Table[2] is %lx \n",
-                       //Rtl819XPHY_REGArraytoXTXR_Table[i],Rtl819XPHY_REGArraytoXTXR_Table[i+1], Rtl819XPHY_REGArraytoXTXR_Table[i+2]);
                }
        }
        else {
                RT_TRACE(COMP_SEND, "phy_SetBBtoDiffRFWithHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
        }
-//#endif       // #if (HAL_CODE_BASE != RTL8192_S)
        return RT_STATUS_SUCCESS;
 }
 
@@ -869,14 +756,6 @@ phy_BB8192S_Config_ParaFile(struct net_device* dev)
 {
        struct r8192_priv       *priv = ieee80211_priv(dev);
        RT_STATUS                       rtStatus = RT_STATUS_SUCCESS;
-       //u8                            u2RegValue;
-       //u16                           u4RegValue;
-       //char                          szBBRegFile[] = RTL819X_PHY_REG;
-       //char                          szBBRegFile1T2R[] = RTL819X_PHY_REG_1T2R;
-       //char                          szBBRegPgFile[] = RTL819X_PHY_REG_PG;
-       //char                          szAGCTableFile[] = RTL819X_AGC_TAB;
-       //char                          szBBRegto1T1RFile[] = RTL819X_PHY_REG_to1T1R;
-       //char                          szBBRegto1T2RFile[] = RTL819X_PHY_REG_to1T2R;
 
        RT_TRACE(COMP_INIT, "==>phy_BB8192S_Config_ParaFile\n");
 
@@ -956,42 +835,16 @@ phy_ConfigMACWithHeaderFile(struct net_device* dev)
        u32                                     i = 0;
        u32                                     ArrayLength = 0;
        u32*                                    ptrArray;
-       //struct r8192_priv     *priv = ieee80211_priv(dev);
 
-//#if (HAL_CODE_BASE != RTL8192_S)
-       /*if(Adapter->bInHctTest)
-       {
-               RT_TRACE(COMP_INIT, DBG_LOUD, ("Rtl819XMACPHY_ArrayDTM\n"));
-               ArrayLength = MACPHY_ArrayLengthDTM;
-               ptrArray = Rtl819XMACPHY_ArrayDTM;
-       }
-       else if(pHalData->bTXPowerDataReadFromEEPORM)
-       {
-//             RT_TRACE(COMP_INIT, DBG_LOUD, ("Rtl819XMACPHY_Array_PG\n"));
-//             ArrayLength = MACPHY_Array_PGLength;
-//             ptrArray = Rtl819XMACPHY_Array_PG;
-
-       }else*/
        { //2008.11.06 Modified by tynli.
                RT_TRACE(COMP_INIT, "Read Rtl819XMACPHY_Array\n");
                ArrayLength = MAC_2T_ArrayLength;
                ptrArray = Rtl819XMAC_Array;
        }
 
-       /*for(i = 0 ;i < ArrayLength;i=i+3){
-               RT_TRACE(COMP_SEND, DBG_LOUD, ("The Rtl819XMACPHY_Array[0] is %lx Rtl819XMACPHY_Array[1] is %lx Rtl819XMACPHY_Array[2] is %lx\n",ptrArray[i], ptrArray[i+1], ptrArray[i+2]));
-               if(ptrArray[i] == 0x318)
-               {
-                       ptrArray[i+2] = 0x00000800;
-                       //DbgPrint("ptrArray[i], ptrArray[i+1], ptrArray[i+2] = %x, %x, %x\n",
-                       //      ptrArray[i], ptrArray[i+1], ptrArray[i+2]);
-               }
-               PHY_SetBBReg(Adapter, ptrArray[i], ptrArray[i+1], ptrArray[i+2]);
-       }*/
        for(i = 0 ;i < ArrayLength;i=i+2){ // Add by tynli for 2 column
                write_nic_byte(dev, ptrArray[i], (u8)ptrArray[i+1]);
        }
-//#endif
        return RT_STATUS_SUCCESS;
 }
 
@@ -1015,41 +868,14 @@ static   RT_STATUS
 phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType)
 {
        int             i;
-       //u8            ArrayLength;
        u32*    Rtl819XPHY_REGArray_Table;
        u32*    Rtl819XAGCTAB_Array_Table;
        u16             PHY_REGArrayLen, AGCTAB_ArrayLen;
-       //struct r8192_priv *priv = ieee80211_priv(dev);
-//#if (HAL_CODE_BASE != RTL8192_S)
-       /*if(Adapter->bInHctTest)
-       {
-
-               AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM;
-               Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
-
-               if(pHalData->RF_Type == RF_2T4R)
-               {
-                       PHY_REGArrayLen = PHY_REGArrayLengthDTM;
-                       Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArrayDTM;
-               }
-               else if (pHalData->RF_Type == RF_1T2R)
-               {
-                       PHY_REGArrayLen = PHY_REG_1T2RArrayLengthDTM;
-                       Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArrayDTM;
-               }
 
-       }
-       else
-       */
-       //{
-       //
-       // 2008.11.06 Modified by tynli.
-       //
        AGCTAB_ArrayLen = AGCTAB_ArrayLength;
        Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_Array;
        PHY_REGArrayLen = PHY_REG_2T2RArrayLength; // Default RF_type: 2T2R
        Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_Array;
-       //}
 
        if(ConfigType == BaseBand_Config_PHY_REG)
        {
@@ -1068,7 +894,6 @@ phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType)
                        else if (Rtl819XPHY_REGArray_Table[i] == 0xf9)
                                udelay(1);
                        rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table[i], bMaskDWord, Rtl819XPHY_REGArray_Table[i+1]);
-                       //RT_TRACE(COMP_SEND, "The Rtl819XPHY_REGArray_Table[0] is %lx Rtl819XPHY_REGArray[1] is %lx \n",Rtl819XPHY_REGArray_Table[i], Rtl819XPHY_REGArray_Table[i+1]);
 
                }
        }
@@ -1078,7 +903,6 @@ phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType)
                        rtl8192_setBBreg(dev, Rtl819XAGCTAB_Array_Table[i], bMaskDWord, Rtl819XAGCTAB_Array_Table[i+1]);
                }
        }
-//#endif       // #if (HAL_CODE_BASE != RTL8192_S)
        return RT_STATUS_SUCCESS;
 }
 
@@ -1103,12 +927,8 @@ static RT_STATUS
 phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType)
 {
        int i;
-       //u8 ArrayLength;
        u32*    Rtl819XPHY_REGArray_Table_PG;
        u16     PHY_REGArrayPGLen;
-       //struct r8192_priv *priv = ieee80211_priv(dev);
-//#if (HAL_CODE_BASE != RTL8192_S)
-       // Default: pHalData->RF_Type = RF_2T2R.
 
        PHY_REGArrayPGLen = PHY_REG_Array_PGLength;
        Rtl819XPHY_REGArray_Table_PG = Rtl819XPHY_REG_Array_PG;
@@ -1130,15 +950,13 @@ phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType)
                        else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xf9)
                                udelay(1);
                        rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table_PG[i], Rtl819XPHY_REGArray_Table_PG[i+1], Rtl819XPHY_REGArray_Table_PG[i+2]);
-                       //RT_TRACE(COMP_SEND, "The Rtl819XPHY_REGArray_Table_PG[0] is %lx Rtl819XPHY_REGArray_Table_PG[1] is %lx \n",
-                       //              Rtl819XPHY_REGArray_Table_PG[i], Rtl819XPHY_REGArray_Table_PG[i+1]);
                }
        }else{
                RT_TRACE(COMP_SEND, "phy_ConfigBBWithPgHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
        }
        return RT_STATUS_SUCCESS;
 
-}      /* phy_ConfigBBWithPgHeaderFile */
+}
 
 /*-----------------------------------------------------------------------------
  * Function:    PHY_ConfigRFWithHeaderFile()
@@ -1155,19 +973,14 @@ phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType)
  *
  * Note:               Delay may be required for RF configuration
  *---------------------------------------------------------------------------*/
-//in 8256 phy_RF8256_Config_ParaFile only
-//RT_STATUS PHY_ConfigRFWithHeaderFile(struct net_device* dev,RF90_RADIO_PATH_E eRFPath)
 u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E        eRFPath)
 {
 
        struct r8192_priv *priv = ieee80211_priv(dev);
        int                     i;
-       //u32*  pRFArray;
        RT_STATUS       rtStatus = RT_STATUS_SUCCESS;
        u32                     *Rtl819XRadioA_Array_Table;
        u32                     *Rtl819XRadioB_Array_Table;
-       //u32*  Rtl819XRadioC_Array_Table;
-       //u32*  Rtl819XRadioD_Array_Table;
        u16                     RadioA_ArrayLen,RadioB_ArrayLen;
 
        {       //2008.11.06 Modified by tynli
@@ -1190,18 +1003,12 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E
 
        rtStatus = RT_STATUS_SUCCESS;
 
-       // When initialization, we want the delay function(mdelay(), delay_us()
-       // ==> actually we call PlatformStallExecution()) to do NdisStallExecution()
-       // [busy wait] instead of NdisMSleep(). So we acquire RT_INITIAL_SPINLOCK
-       // to run at Dispatch level to achive it.
-       //cosa PlatformAcquireSpinLock(Adapter, RT_INITIAL_SPINLOCK);
 
        switch(eRFPath){
                case RF90_PATH_A:
                        for(i = 0;i<RadioA_ArrayLen; i=i+2){
                                if(Rtl819XRadioA_Array_Table[i] == 0xfe)
                                        { // Deay specific ms. Only RF configuration require delay.
-//#if (DEV_BUS_TYPE == USB_INTERFACE)
                                                mdelay(1000);
                                }
                                        else if (Rtl819XRadioA_Array_Table[i] == 0xfd)
@@ -1210,7 +1017,6 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E
                                                mdelay(1);
                                        else if (Rtl819XRadioA_Array_Table[i] == 0xfb)
                                                udelay(50);
-                                               //PlatformStallExecution(50);
                                        else if (Rtl819XRadioA_Array_Table[i] == 0xfa)
                                                udelay(5);
                                        else if (Rtl819XRadioA_Array_Table[i] == 0xf9)
@@ -1225,7 +1031,6 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E
                        for(i = 0;i<RadioB_ArrayLen; i=i+2){
                                if(Rtl819XRadioB_Array_Table[i] == 0xfe)
                                        { // Deay specific ms. Only RF configuration require delay.
-//#if (DEV_BUS_TYPE == USB_INTERFACE)
                                                mdelay(1000);
                                }
                                        else if (Rtl819XRadioB_Array_Table[i] == 0xfd)
@@ -1281,7 +1086,6 @@ PHY_CheckBBAndRFOK(
        RF90_RADIO_PATH_E       eRFPath
        )
 {
-       //struct r8192_priv *priv = ieee80211_priv(dev);
        RT_STATUS                       rtStatus = RT_STATUS_SUCCESS;
        u32                             i, CheckTimes = 4,ulRegRead = 0;
        u32                             WriteAddr[4];
@@ -1302,7 +1106,6 @@ PHY_CheckBBAndRFOK(
                switch(CheckBlock)
                {
                case HW90_BLOCK_MAC:
-                       //RT_ASSERT(FALSE, ("PHY_CheckBBRFOK(): Never Write 0x100 here!"));
                        RT_TRACE(COMP_INIT, "PHY_CheckBBRFOK(): Never Write 0x100 here!\n");
                        break;
 
@@ -1313,18 +1116,12 @@ PHY_CheckBBAndRFOK(
                        break;
 
                case HW90_BLOCK_RF:
-                       // When initialization, we want the delay function(mdelay(), delay_us()
-                       // ==> actually we call PlatformStallExecution()) to do NdisStallExecution()
-                       // [busy wait] instead of NdisMSleep(). So we acquire RT_INITIAL_SPINLOCK
-                       // to run at Dispatch level to achive it.
-                       //cosa PlatformAcquireSpinLock(dev, RT_INITIAL_SPINLOCK);
                        WriteData[i] &= 0xfff;
                        rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bRFRegOffsetMask, WriteData[i]);
                        // TODO: we should not delay for such a long time. Ask SD3
                        mdelay(10);
                        ulRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord);
                        mdelay(10);
-                       //cosa PlatformReleaseSpinLock(dev, RT_INITIAL_SPINLOCK);
                        break;
 
                default:
@@ -1338,7 +1135,6 @@ PHY_CheckBBAndRFOK(
                //
                if(ulRegRead != WriteData[i])
                {
-                       //RT_TRACE(COMP_FPGA,  ("ulRegRead: %x, WriteData: %x \n", ulRegRead, WriteData[i]));
                        RT_TRACE(COMP_ERR, "read back error(read:%x, write:%x)\n", ulRegRead, WriteData[i]);
                        rtStatus = RT_STATUS_FAILURE;
                        break;
@@ -1348,7 +1144,6 @@ PHY_CheckBBAndRFOK(
        return rtStatus;
 }
 
-//no use temp in windows driver
 #ifdef TO_DO_LIST
 void
 PHY_SetRFPowerState8192SUsb(
@@ -1359,7 +1154,6 @@ PHY_SetRFPowerState8192SUsb(
        struct r8192_priv *priv = ieee80211_priv(dev);
        bool                    WaitShutDown = FALSE;
        u32                     DWordContent;
-       //RF90_RADIO_PATH_E     eRFPath;
        u8                              eRFPath;
        BB_REGISTER_DEFINITION_T        *pPhyReg;
 
@@ -1368,7 +1162,6 @@ PHY_SetRFPowerState8192SUsb(
 
        priv->SetRFPowerStateInProgress = TRUE;
 
-       // TODO: Emily, 2006.11.21, we should rewrite this function
 
        if(RFPowerState==RF_SHUT_DOWN)
        {
@@ -1420,22 +1213,20 @@ PHY_SetRFPowerState8192SUsb(
 
        case RF_8258:
                break;
-       }// switch( priv->rf_chip )
+       }
 
        priv->SetRFPowerStateInProgress = FALSE;
 }
 #endif
 
 #ifdef RTL8192U
-//no use temp in windows driver
 void
 PHY_UpdateInitialGain(
        struct net_device* dev
        )
 {
        struct r8192_priv       *priv = ieee80211_priv(dev);
-       //unsigned char                 *IGTable;
-       //u8                    DIG_CurrentInitialGain = 4;
+
 
        switch(priv->rf_chip)
        {
@@ -1456,7 +1247,6 @@ PHY_UpdateInitialGain(
 }
 #endif
 
-//YJ,modified,090107
 void PHY_GetHWRegOriginalValue(struct net_device* dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -1625,8 +1415,6 @@ static void phy_InitBBRFRegisterDefinition(       struct net_device* dev)
        // Tranceiver LSSI Readback PI mode
        priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
        priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
-       //pHalData->PHYRegDef[RF90_PATH_C].rfLSSIReadBackPi = rFPGA0_XC_LSSIReadBack;
-       //pHalData->PHYRegDef[RF90_PATH_D].rfLSSIReadBackPi = rFPGA0_XD_LSSIReadBack;
 
 }
 
@@ -1637,9 +1425,7 @@ static void phy_InitBBRFRegisterDefinition(       struct net_device* dev)
 //     Assumption: This function must be executed in re-schdulable context,
 //             ie. PASSIVE_LEVEL.
 //
-//     050823, by rcnjko.
-//not understand it seem's use in init
-//SetHwReg8192SUsb--->HalFunc.SetHwRegHandler
+
 bool PHY_SetRFPowerState(struct net_device* dev, RT_RF_POWER_STATE eRFPowerState)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -1665,8 +1451,6 @@ static bool phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE e
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        bool                    bResult = TRUE;
-       //u8            eRFPath;
-       //u8            i, QueueID;
        u8              u1bTmp;
 
        if(priv->SetRFPowerStateInProgress == TRUE)
@@ -1697,9 +1481,6 @@ static bool phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE e
                                                break;
                                //
                                //RF Off/Sleep sequence. Designed/tested from SD4 Scott, SD1 Grent and Jonbon.
-                               // Added by Bruce, 2008-11-22.
-                               //
-                               //==================================================================
                                // (0) Disable FW BB reset checking
                                write_nic_dword(dev, WFM5, FW_BB_RESET_DISABLE);
 
@@ -1728,7 +1509,6 @@ static bool phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE e
 
                        default:
                                bResult = FALSE;
-                               //RT_ASSERT(FALSE, ("phy_SetRFPowerState8192SU(): unknown state to set: 0x%X!!!\n", eRFPowerState));
                                break;
                }
                break;
@@ -1860,7 +1640,6 @@ PHY_GetTxPowerLevel8192S(
  void PHY_SetTxPowerLevel8192S(struct net_device* dev, u8      channel)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
-       //HAL_DATA_TYPE         *pHalData = GET_HAL_DATA(dev);
        u8      powerlevel = (u8)EEPROM_Default_TxPower, powerlevelOFDM24G = 0x10;
        s8      ant_pwr_diff = 0;
        u32     u4RegValue;
@@ -1909,14 +1688,6 @@ PHY_GetTxPowerLevel8192S(
                        // RF B HT OFDM pwr-RFA HT OFDM pwr
                ant_pwr_diff =  priv->RfTxPwrLevelOfdm2T[1][index] -
                                                priv->RfTxPwrLevelOfdm2T[0][index];
-                       // RF B (HT OFDM pwr+legacy-ht-diff) -(RFA HT OFDM pwr+legacy-ht-diff)
-               // We can not handle Path B&A HT/Legacy pwr diff for 92S now.
-
-               //RTPRINT(FPHY, PHY_TXPWR, ("CH-%d HT40 A/B Pwr index = %x/%x(%d/%d)\n",
-               //channel, priv->RfTxPwrLevelOfdm2T[0][index],
-               //priv->RfTxPwrLevelOfdm2T[1][index],
-               //priv->RfTxPwrLevelOfdm2T[0][index],
-               //priv->RfTxPwrLevelOfdm2T[1][index]));
 
                ht20pwr[0] = ht40pwr[0] = priv->RfTxPwrLevelOfdm2T[0][index];
                ht20pwr[1] = ht40pwr[1] = priv->RfTxPwrLevelOfdm2T[1][index];
@@ -1949,10 +1720,6 @@ PHY_GetTxPowerLevel8192S(
                        // RF B HT OFDM pwr-RFA HT OFDM pwr
                        if (priv->rf_type == RF_2T2R)
                                ant_pwr_diff = ht20pwr[1] - ht20pwr[0];
-
-                       //RTPRINT(FPHY, PHY_TXPWR,
-                       //("HT20 to HT40 pwrdiff[A/B]=%d/%d, ant_pwr_diff=%d(B-A=%d-%d)\n",
-                       //pwrdiff[0], pwrdiff[1], ant_pwr_diff, ht20pwr[1], ht20pwr[0]));
                }
 
                // Band Edge scheme is enabled for FCC mode
@@ -1997,18 +1764,12 @@ PHY_GetTxPowerLevel8192S(
                        {
                                if (channel <= 1 || channel >= 11)
                                {
-                                       //RTPRINT(FPHY, PHY_TXPWR,
-                                       //("HT20 Band-edge pwrdiff[A/B]=%d/%d, ant_pwr_diff=%d(B-A=%d-%d)\n",
-                                       //pwrdiff[0], pwrdiff[1], ant_pwr_diff, ht20pwr[1], ht20pwr[0]));
                                }
                        }
                        else
                        {
                                if (channel <= 3 || channel >= 9)
                                {
-                                       //RTPRINT(FPHY, PHY_TXPWR,
-                                       //("HT40 Band-edge pwrdiff[A/B]=%d/%d, ant_pwr_diff=%d(B-A=%d-%d)\n",
-                                       //pwrdiff[0], pwrdiff[1], ant_pwr_diff, ht40pwr[1], ht40pwr[0]));
                                }
                        }
                }
@@ -2021,10 +1782,6 @@ PHY_GetTxPowerLevel8192S(
        if(ant_pwr_diff < -8)
                ant_pwr_diff = -8;
 
-               //RTPRINT(FPHY, PHY_TXPWR,
-               //("CCK/HT Power index = %x/%x(%d/%d), ant_pwr_diff=%d\n",
-               //powerlevel, powerlevelOFDM24G, powerlevel, powerlevelOFDM24G, ant_pwr_diff));
-
                ant_pwr_diff &= 0xf;
 
                // Antenna TX power difference
@@ -2050,7 +1807,6 @@ PHY_GetTxPowerLevel8192S(
        // TODO:
        // 1. 802.11h power contraint
        //
-       // 071011, by rcnjko.
        //
 #ifdef TODO //WB, 11h has not implemented now.
        if(     priv->ieee80211->iw_mode != IW_MODE_INFRA && priv->bWithCcxCellPwr &&
@@ -2095,8 +1851,6 @@ PHY_GetTxPowerLevel8192S(
        switch(priv->rf_chip)
        {
                case RF_8225:
-                       //PHY_SetRF8225CckTxPower(dev, powerlevel);
-                       //PHY_SetRF8225OfdmTxPower(dev, powerlevelOFDM24G);
                break;
 
                case RF_8256:
@@ -2121,8 +1875,6 @@ PHY_GetTxPowerLevel8192S(
 //
 //     TODO:
 //             A mode.
-//     By Bruce, 2008-02-04.
-//    no use temp
 bool PHY_UpdateTxPowerDbm8192S(struct net_device* dev, long powerInDbm)
 {
        struct r8192_priv       *priv = ieee80211_priv(dev);
@@ -2164,8 +1916,6 @@ bool PHY_UpdateTxPowerDbm8192S(struct net_device* dev, long powerInDbm)
        Description:
                When beacon interval is changed, the values of the
                hw registers should be modified.
-       By tynli, 2008.10.24.
-
 */
 
 extern void PHY_SetBeaconHwReg(        struct net_device* dev, u16 BeaconInterval)
@@ -2173,8 +1923,6 @@ extern void PHY_SetBeaconHwReg(   struct net_device* dev, u16 BeaconInterval)
        u32 NewBeaconNum;
 
        NewBeaconNum = BeaconInterval *32 - 64;
-       //PlatformEFIOWrite4Byte(Adapter, WFM3+4, NewBeaconNum);
-       //PlatformEFIOWrite4Byte(Adapter, WFM3, 0xB026007C);
        write_nic_dword(dev, WFM3+4, NewBeaconNum);
        write_nic_dword(dev, WFM3, 0xB026007C);
 }
@@ -2184,7 +1932,6 @@ extern void PHY_SetBeaconHwReg(   struct net_device* dev, u16 BeaconInterval)
 //             Map dBm into Tx power index according to
 //             current HW model, for example, RF and PA, and
 //             current wireless mode.
-//     By Bruce, 2008-01-29.
 //    use in phy only
 static u8 phy_DbmToTxPwrIdx(
        struct net_device* dev,
@@ -2192,7 +1939,6 @@ static u8 phy_DbmToTxPwrIdx(
        long                    PowerInDbm
        )
 {
-       //struct r8192_priv *priv = ieee80211_priv(dev);
        u8                              TxPwrIdx = 0;
        long                            Offset = 0;
 
@@ -2202,7 +1948,6 @@ static u8 phy_DbmToTxPwrIdx(
        // 3dbm, and OFDM HT equals to 0dbm repectively.
        // Note:
        //      The mapping may be different by different NICs. Do not use this formula for what needs accurate result.
-       // By Bruce, 2008-01-29.
        //
        switch(WirelessMode)
        {
@@ -2238,7 +1983,6 @@ static u8 phy_DbmToTxPwrIdx(
 //             Map Tx power index into dBm according to
 //             current HW model, for example, RF and PA, and
 //             current wireless mode.
-//     By Bruce, 2008-01-29.
 //    use in phy only
 static long phy_TxPwrIdxToDbm(
        struct net_device* dev,
@@ -2255,7 +1999,6 @@ static long phy_TxPwrIdxToDbm(
        // 3dbm, and OFDM HT equals to 0dbm repectively.
        // Note:
        //      The mapping may be different by different NICs. Do not use this formula for what needs accurate result.
-       // By Bruce, 2008-01-29.
        //
        switch(WirelessMode)
        {
@@ -2327,9 +2070,6 @@ PHY_ScanOperationBackup8192S(
 void PHY_InitialGain8192S(struct net_device* dev,u8 Operation  )
 {
 
-       //struct r8192_priv *priv = ieee80211_priv(dev);
-       //u32                                   BitMask;
-       //u8                                    initial_gain;
 }
 
 /*-----------------------------------------------------------------------------
@@ -2353,11 +2093,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
        struct r8192_priv *priv = ieee80211_priv(dev);
        u8                              regBwOpMode;
 
-       //return;
-
-       // Added it for 20/40 mhz switch time evaluation by guangan 070531
-       //u32                           NowL, NowH;
-       //u8Byte                                BeginTime, EndTime;
        u8                              regRRSR_RSC;
 
        RT_TRACE(COMP_SWBW, "==>SetBWModeCallback8190Pci()  Switch to %s bandwidth\n", \
@@ -2372,10 +2107,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
        if(!priv->up)
                return;
 
-       // Added it for 20/40 mhz switch time evaluation by guangan 070531
-       //NowL = read_nic_dword(dev, TSFR);
-       //NowH = read_nic_dword(dev, TSFR+4);
-       //BeginTime = ((u8Byte)NowH << 32) + NowL;
 
        //3//
        //3//<1>Set MAC register
@@ -2386,8 +2117,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
        switch(priv->CurrentChannelBW)
        {
                case HT_CHANNEL_WIDTH_20:
-                       //if(priv->card_8192_version >= VERSION_8192S_BCUT)
-                       //      write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x58);
 
                        regBwOpMode |= BW_OPMODE_20MHZ;
                        // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
@@ -2395,8 +2124,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
                        break;
 
                case HT_CHANNEL_WIDTH_20_40:
-                       //if(priv->card_8192_version >= VERSION_8192S_BCUT)
-                       //      write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x18);
 
                        regBwOpMode &= ~BW_OPMODE_20MHZ;
                        // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
@@ -2421,12 +2148,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
                        rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
                        rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
 
-                       // Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207
-                       // It is set in Tx descriptor for 8192x series
-                       //write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000);
-                       //write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317);
-                       //write_nic_dword(dev, rCCK0_DebugPort, 0x00000204);
-
                        if (priv->card_8192_version >= VERSION_8192S_BCUT)
                                write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x58);
 
@@ -2438,16 +2159,11 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
                        rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
                        rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
 
-                       // Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207
-                       //write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000);
-                       //write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e);
-                       //write_nic_dword(dev, rCCK0_DebugPort, 0x00000409);
 
                        // Set Control channel to upper or lower. These settings are required only for 40MHz
                        rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
                        rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
 
-                       //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00300000, 3);
                        if (priv->card_8192_version >= VERSION_8192S_BCUT)
                                write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x18);
 
@@ -2461,11 +2177,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
        }
        //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
 
-       // Added it for 20/40 mhz switch time evaluation by guangan 070531
-       //NowL = read_nic_dword(dev, TSFR);
-       //NowH = read_nic_dword(dev, TSFR+4);
-       //EndTime = ((u8Byte)NowH << 32) + NowL;
-       //RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWModeCallback8190Pci: time of SetBWMode = %I64d us!\n", (EndTime - BeginTime)));
 
        //3<3>Set RF related register
        switch( priv->rf_chip )
@@ -2516,36 +2227,11 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
  *
  * Note:               We do not take j mode into consideration now
  *---------------------------------------------------------------------------*/
-//extern void PHY_SetBWMode8192S(      struct net_device* dev,
-//     HT_CHANNEL_WIDTH        Bandwidth,      // 20M or 40M
-//     HT_EXTCHNL_OFFSET       Offset          // Upper, Lower, or Don't care
 void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH        Bandwidth, HT_EXTCHNL_OFFSET Offset)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        HT_CHANNEL_WIDTH tmpBW = priv->CurrentChannelBW;
 
-
-       // Modified it for 20/40 mhz switch by guangan 070531
-
-       //return;
-
-       //if(priv->SwChnlInProgress)
-//     if(pMgntInfo->bScanInProgress)
-//     {
-//             RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWMode8190Pci() %s Exit because bScanInProgress!\n",
-//                                     Bandwidth == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz"));
-//             return;
-//     }
-
-//     if(priv->SetBWModeInProgress)
-//     {
-//             // Modified it for 20/40 mhz switch by guangan 070531
-//             RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWMode8190Pci() %s cancel last timer because SetBWModeInProgress!\n",
-//                                     Bandwidth == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz"));
-//             PlatformCancelTimer(dev, &priv->SetBWModeTimer);
-//             //return;
-//     }
-
        if(priv->SetBWModeInProgress)
                return;
 
@@ -2560,7 +2246,7 @@ void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH   Bandwidth, HT_EX
        else
                priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 
-       if((priv->up) )// && !(RT_CANNOT_IO(Adapter) && Adapter->bInSetPower) )
+       if((priv->up) )
        {
        SetBWModeCallback8192SUsbWorkItem(dev);
        }
@@ -2578,7 +2264,6 @@ void PHY_SwChnlCallback8192S(struct net_device *dev)
 
        struct r8192_priv *priv = ieee80211_priv(dev);
        u32             delay;
-       //bool                  ret;
 
        RT_TRACE(COMP_CH, "==>SwChnlCallback8190Pci(), switch to channel %d\n", priv->chan);
 
@@ -2595,16 +2280,11 @@ void PHY_SwChnlCallback8192S(struct net_device *dev)
                if(!priv->SwChnlInProgress)
                        break;
 
-               //if(!phy_SwChnlStepByStep(dev, priv->CurrentChannel, &priv->SwChnlStage, &priv->SwChnlStep, &delay))
                if(!phy_SwChnlStepByStep(dev, priv->chan, &priv->SwChnlStage, &priv->SwChnlStep, &delay))
                {
                        if(delay>0)
                        {
                                mdelay(delay);
-                               //PlatformSetTimer(dev, &priv->SwChnlTimer, delay);
-                               //mod_timer(&priv->SwChnlTimer,  jiffies + MSECS(delay));
-                               //==>PHY_SwChnlCallback8192S(dev); for 92se
-                               //==>SwChnlCallback8192SUsb(dev) for 92su
                        }
                        else
                        continue;
@@ -2618,12 +2298,9 @@ void PHY_SwChnlCallback8192S(struct net_device *dev)
 }
 
 // Call after initialization
-//extern void PHY_SwChnl8192S(struct net_device* dev,  u8 channel)
 u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
-       //u8                    tmpchannel =channel;
-       //bool                  bResult = false;
 
         if(!priv->up)
                return false;
@@ -2634,7 +2311,6 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
        if(priv->SetBWModeInProgress)
                return false;
 
-       //--------------------------------------------
        switch(priv->ieee80211->mode)
        {
        case WIRELESS_MODE_A:
@@ -2661,10 +2337,9 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
                break;
 
        default:
-                       ;//RT_TRACE(COMP_ERR, "Invalid WirelessMode(%#x)!!\n", priv->ieee80211->mode);
+                       ;
                break;
        }
-       //--------------------------------------------
 
        priv->SwChnlInProgress = TRUE;
        if( channel == 0)
@@ -2675,7 +2350,7 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
        priv->SwChnlStage=0;
        priv->SwChnlStep=0;
 
-       if((priv->up))// && !(RT_CANNOT_IO(Adapter) && Adapter->bInSetPower))
+       if((priv->up))
        {
        SwChnlCallback8192SUsbWorkItem(dev);
 #ifdef TO_DO_LIST
@@ -2695,7 +2370,6 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
        {
                RT_TRACE(COMP_SCAN, "PHY_SwChnl8192S SwChnlInProgress FALSE driver sleep or unload\n");
                priv->SwChnlInProgress = false;
-               //priv->CurrentChannel = tmpchannel;
        }
         return true;
 }
@@ -2709,8 +2383,7 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
 // The following procedure is operted according to SwChanlCallback8190Pci().
 // However, this procedure is performed synchronously  which should be running under
 // passive level.
-//
-//not understand it
+
 void PHY_SwChnlPhy8192S(       // Only called during initialize
        struct net_device* dev,
        u8              channel
@@ -2767,14 +2440,10 @@ phy_SetSwChnlCmdArray(
 
        if(CmdTable == NULL)
        {
-               //RT_ASSERT(FALSE, ("phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n"));
                return FALSE;
        }
        if(CmdTableIdx >= CmdTableSz)
        {
-               //RT_ASSERT(FALSE,
-                       //      ("phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
-                               //CmdTableIdx, CmdTableSz));
                return FALSE;
        }
 
@@ -2798,7 +2467,6 @@ phy_SwChnlStepByStep(
        )
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
-       //PCHANNEL_ACCESS_SETTING       pChnlAccessSetting;
        SwChnlCmd                               PreCommonCmd[MAX_PRECMD_CNT];
        u32                                     PreCommonCmdCnt;
        SwChnlCmd                               PostCommonCmd[MAX_POSTCMD_CNT];
@@ -2808,22 +2476,13 @@ phy_SwChnlStepByStep(
        SwChnlCmd                               *CurrentCmd = NULL;
        u8                                      eRFPath;
 
-       //RT_ASSERT((dev != NULL), ("Adapter should not be NULL\n"));
-       //RT_ASSERT(IsLegalChannel(dev, channel), ("illegal channel: %d\n", channel));
        RT_TRACE(COMP_CH, "===========>%s(), channel:%d, stage:%d, step:%d\n", __FUNCTION__, channel, *stage, *step);
-       //RT_ASSERT((pHalData != NULL), ("pHalData should not be NULL\n"));
        if (!IsLegalChannel(priv->ieee80211, channel))
        {
                RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
                return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
        }
 
-       //pChnlAccessSetting = &Adapter->MgntInfo.Info8185.ChannelAccessSetting;
-       //RT_ASSERT((pChnlAccessSetting != NULL), ("pChnlAccessSetting should not be NULL\n"));
-
-       //for(eRFPath = RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
-       //for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
-       //{
                // <1> Fill up pre common command.
        PreCommonCmdCnt = 0;
        phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
@@ -2844,8 +2503,7 @@ phy_SwChnlStepByStep(
                case RF_8225:
                if (channel < 1 || channel > 14)
                        RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
-               //RT_ASSERT((channel >= 1 && channel <= 14), ("illegal channel for Zebra: %d\n", channel));
-               // 2008/09/04 MH Change channel.
+
                phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
                        CmdID_RF_WriteReg, rRfChannel, channel, 10);
                phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
@@ -2855,8 +2513,6 @@ phy_SwChnlStepByStep(
        case RF_8256:
                if (channel < 1 || channel > 14)
                        RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
-               // TEST!! This is not the table for 8256!!
-               //RT_ASSERT((channel >= 1 && channel <= 14), ("illegal channel for Zebra: %d\n", channel));
                phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
                        CmdID_RF_WriteReg, rRfChannel, channel, 10);
                phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
@@ -2876,7 +2532,6 @@ phy_SwChnlStepByStep(
                break;
 
        default:
-               //RT_ASSERT(FALSE, ("Unknown rf_chip: %d\n", priv->rf_chip));
                return FALSE;
                break;
        }
@@ -2913,7 +2568,6 @@ phy_SwChnlStepByStep(
                switch(CurrentCmd->CmdID)
                {
                case CmdID_SetTxPowerLevel:
-                       //if(priv->card_8192_version > VERSION_8190_BD)
                                PHY_SetTxPowerLevel8192S(dev,channel);
                        break;
                case CmdID_WritePortUlong:
@@ -2930,7 +2584,6 @@ phy_SwChnlStepByStep(
                        {
                        // For new T65 RF 0222d register 0x18 bit 0-9 = channel number.
                                rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, 0x1f, (CurrentCmd->Para2));
-                               //printk("====>%x, %x, read_back:%x\n", CurrentCmd->Para2,CurrentCmd->Para1, rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, 0x1f));
                        }
                        break;
                 default:
@@ -2939,7 +2592,6 @@ phy_SwChnlStepByStep(
 
                break;
        }while(TRUE);
-       //cosa }/*for(Number of RF paths)*/
 
        (*delay)=CurrentCmd->msDelay;
        (*step)++;
@@ -2985,14 +2637,8 @@ phy_FinishSwChnlNow(     // We should not call this function directly
  *     11/15/2007      MHC             Create Version 0.
  *
  *---------------------------------------------------------------------------*/
- //called by rtl8192_phy_QueryRFReg, rtl8192_phy_SetRFReg, PHY_SetRFPowerState8192SUsb
-//extern       bool
-//PHY_CheckIsLegalRfPath8192S(
-//     struct net_device* dev,
-//     u32     eRFPath)
 u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
 {
-//     struct r8192_priv *priv = ieee80211_priv(dev);
        bool                            rtValue = TRUE;
 
        // NOt check RF Path now.!
@@ -3023,7 +2669,6 @@ u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
 void
 PHY_IQCalibrate(       struct net_device* dev)
 {
-       //struct r8192_priv     *priv = ieee80211_priv(dev);
        u32                             i, reg;
        u32                             old_value;
        long                            X, Y, TX0[4];
@@ -3039,7 +2684,6 @@ PHY_IQCalibrate(  struct net_device* dev)
        {
                // IQK
                rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05430);
-               //PlatformStallExecution(5);
                udelay(5);
                rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000800e4);
                udelay(5);
@@ -3169,8 +2813,6 @@ PHY_IQCalibrate(  struct net_device* dev)
  *---------------------------------------------------------------------------*/
 extern void PHY_IQCalibrateBcut(struct net_device* dev)
 {
-       //struct r8192_priv     *priv = ieee80211_priv(dev);
-       //PMGNT_INFO            pMgntInfo = &pAdapter->MgntInfo;
        u32                             i, reg;
        u32                             old_value;
        long                            X, Y, TX0[4];
@@ -3184,21 +2826,6 @@ extern void PHY_IQCalibrateBcut(struct net_device* dev)
        //
        // 1. Save e70~ee0 register setting, and load calibration setting
        //
-       /*
-       0xee0[31:0]=0x3fed92fb;
-       0xedc[31:0] =0x3fed92fb;
-       0xe70[31:0] =0x3fed92fb;
-       0xe74[31:0] =0x3fed92fb;
-       0xe78[31:0] =0x3fed92fb;
-       0xe7c[31:0]= 0x3fed92fb;
-       0xe80[31:0]= 0x3fed92fb;
-       0xe84[31:0]= 0x3fed92fb;
-       0xe88[31:0]= 0x3fed92fb;
-       0xe8c[31:0]= 0x3fed92fb;
-       0xed0[31:0]= 0x3fed92fb;
-       0xed4[31:0]= 0x3fed92fb;
-       0xed8[31:0]= 0x3fed92fb;
-       */
        calibrate_set [0] = 0xee0;
        calibrate_set [1] = 0xedc;
        calibrate_set [2] = 0xe70;
@@ -3212,7 +2839,6 @@ extern void PHY_IQCalibrateBcut(struct net_device* dev)
        calibrate_set [10] = 0xed0;
        calibrate_set [11] = 0xed4;
        calibrate_set [12] = 0xed8;
-       //RT_TRACE(COMP_INIT, DBG_LOUD, ("Save e70~ee0 register setting\n"));
        for (i = 0; i < 13; i++)
        {
                load_value[i] = rtl8192_QueryBBReg(dev, calibrate_set[i], bMaskDWord);
@@ -3232,7 +2858,6 @@ extern void PHY_IQCalibrateBcut(struct net_device* dev)
                //BB switch to PI mode. If default is PI mode, ignoring 2 commands below.
                if (!RfPiEnable)        //if original is SI mode, then switch to PI mode.
                {
-                       //DbgPrint("IQK Switch to PI mode\n");
                        rtl8192_setBBreg(dev, 0x820, bMaskDWord, 0x01000100);
                        rtl8192_setBBreg(dev, 0x828, bMaskDWord, 0x01000100);
                }
@@ -3286,7 +2911,6 @@ extern void PHY_IQCalibrateBcut(struct net_device* dev)
 
                if (!RfPiEnable)        //if original is SI mode, then switch to PI mode.
                {
-                       //DbgPrint("IQK Switch back to SI mode\n");
                        rtl8192_setBBreg(dev, 0x820, bMaskDWord, 0x01000000);
                        rtl8192_setBBreg(dev, 0x828, bMaskDWord, 0x01000000);
                }
@@ -3369,7 +2993,6 @@ extern void PHY_IQCalibrateBcut(struct net_device* dev)
        //
        // 4. Reload e70~ee0 register setting.
        //
-       //RT_TRACE(COMP_INIT, DBG_LOUD, ("Reload e70~ee0 register setting.\n"));
        for (i = 0; i < 13; i++)
                rtl8192_setBBreg(dev, calibrate_set[i], bMaskDWord, load_value[i]);
 
@@ -3380,14 +3003,12 @@ extern void PHY_IQCalibrateBcut(struct net_device* dev)
 
 
 
-}      // PHY_IQCalibrateBcut
+}
 
 
 //
 // Move from phycfg.c to gen.c to be code independent later
 //
-//-------------------------Move to other DIR later----------------------------*/
-//#if (DEV_BUS_TYPE == USB_INTERFACE)
 
 //    use in phy only (in win it's timer)
 void SwChnlCallback8192SUsb(struct net_device *dev)
@@ -3395,7 +3016,6 @@ void SwChnlCallback8192SUsb(struct net_device *dev)
 
        struct r8192_priv *priv = ieee80211_priv(dev);
        u32                     delay;
-//     bool                    ret;
 
        RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n",
                 priv->chan);
@@ -3418,7 +3038,6 @@ void SwChnlCallback8192SUsb(struct net_device *dev)
                {
                        if(delay>0)
                        {
-                               //PlatformSetTimer(dev, &priv->SwChnlTimer, delay);
 
                        }
                        else
@@ -3473,16 +3092,12 @@ void SwChnlCallback8192SUsbWorkItem(struct net_device *dev )
  *                     (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
  *                          concurrently?
  *---------------------------------------------------------------------------*/
-//====>//rtl8192_SetBWMode
-//    use in phy only (in win it's timer)
+//    use in phy only
 void SetBWModeCallback8192SUsb(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        u8                              regBwOpMode;
 
-       // Added it for 20/40 mhz switch time evaluation by guangan 070531
-       //u32                           NowL, NowH;
-       //u8Byte                                BeginTime, EndTime;
        u8                              regRRSR_RSC;
 
        RT_TRACE(COMP_SCAN, "==>SetBWModeCallback8190Pci()  Switch to %s bandwidth\n", \
@@ -3497,10 +3112,6 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
        if(!priv->up)
                return;
 
-       // Added it for 20/40 mhz switch time evaluation by guangan 070531
-       //NowL = read_nic_dword(dev, TSFR);
-       //NowH = read_nic_dword(dev, TSFR+4);
-       //BeginTime = ((u8Byte)NowH << 32) + NowL;
 
        //3<1>Set MAC register
        regBwOpMode = read_nic_byte(dev, BW_OPMODE);
@@ -3510,13 +3121,11 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
        {
                case HT_CHANNEL_WIDTH_20:
                        regBwOpMode |= BW_OPMODE_20MHZ;
-                      // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
                        write_nic_byte(dev, BW_OPMODE, regBwOpMode);
                        break;
 
                case HT_CHANNEL_WIDTH_20_40:
                        regBwOpMode &= ~BW_OPMODE_20MHZ;
-                       // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
                        write_nic_byte(dev, BW_OPMODE, regBwOpMode);
 
                        regRRSR_RSC = (regRRSR_RSC&0x90) |(priv->nCur40MhzPrimeSC<<5);
@@ -3546,12 +3155,6 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
                        rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
                        rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
 
-                       // Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207
-                       //PHY_SetBBReg(Adapter, rCCK0_TxFilter1, bMaskDWord, 0x35360000);
-                       //PHY_SetBBReg(Adapter, rCCK0_TxFilter2, bMaskDWord, 0x121c252e);
-                       //PHY_SetBBReg(Adapter, rCCK0_DebugPort, bMaskDWord, 0x00000409);
-                       //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, bADClkPhase, 0);
-
                        if (priv->card_8192_version >= VERSION_8192S_BCUT)
                                rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18);
 
@@ -3564,12 +3167,6 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
        }
        //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
 
-       // Added it for 20/40 mhz switch time evaluation by guangan 070531
-       //NowL = read_nic_dword(dev, TSFR);
-       //NowH = read_nic_dword(dev, TSFR+4);
-       //EndTime = ((u8Byte)NowH << 32) + NowL;
-       //RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWModeCallback8190Pci: time of SetBWMode = %I64d us!\n", (EndTime - BeginTime)));
-
 #if 1
        //3<3>Set RF related register
        switch( priv->rf_chip )
@@ -3597,7 +3194,6 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
                        break;
 
                default:
-                       //RT_ASSERT(FALSE, ("Unknown rf_chip: %d\n", priv->rf_chip));
                        break;
        }
 #endif
@@ -3705,7 +3301,6 @@ void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
        priv->SetBWModeInProgress= FALSE;
 }
 
-//--------------------------Move to oter DIR later-------------------------------*/
 void InitialGain8192S(struct net_device *dev,  u8 Operation)
 {
 #ifdef TO_DO_LIST
@@ -3812,7 +3407,6 @@ bool HalSetFwCmd8192S(struct net_device* dev, FW_CMD_IO_TYPE      FwCmdIO)
 
        u16     FwCmdWaitLimit = 1000;
 
-       //if(IS_HARDWARE_TYPE_8192SU(Adapter) && Adapter->bInHctTest)
        if(priv->bInHctTest)
                return true;
 
@@ -3828,11 +3422,6 @@ bool HalSetFwCmd8192S(struct net_device* dev, FW_CMD_IO_TYPE     FwCmdIO)
 #if 1
        while(priv->SetFwCmdInProgress && FwCmdWaitCounter<FwCmdWaitLimit)
        {
-               //if(RT_USB_CANNOT_IO(Adapter))
-               //{
-               //      RT_TRACE(COMP_CMD, DBG_WARNING, ("HalSetFwCmd8192S(): USB can NOT IO!!\n"));
-               //      return FALSE;
-               //}
 
                RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): previous workitem not finish!!\n");
                return false;
@@ -3843,9 +3432,7 @@ bool HalSetFwCmd8192S(struct net_device* dev, FW_CMD_IO_TYPE      FwCmdIO)
 
        if(FwCmdWaitCounter == FwCmdWaitLimit)
        {
-               //RT_ASSERT(FALSE, ("SetFwCmdIOWorkItemCallback(): Wait too logn to set FW CMD\n"));
                RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): Wait too logn to set FW CMD\n");
-               //return false;
        }
 #endif
        if (priv->SetFwCmdInProgress)
@@ -3898,10 +3485,10 @@ void ChkFwCmdIoDone(struct net_device* dev)
 //
 void phy_SetFwCmdIOCallback(struct net_device* dev)
 {
-       //struct net_device* dev = (struct net_device*) data;
-       u32             input;
-       static u32 ScanRegister;
        struct r8192_priv *priv = ieee80211_priv(dev);
+       PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
+       rt_firmware             *pFirmware = priv->pFirmware;
+       u32     input, CurrentAID = 0;;
        if(!priv->up)
        {
                RT_TRACE(COMP_CMD, "SetFwCmdIOTimerCallback(): driver is going to unload\n");
@@ -3910,61 +3497,22 @@ void phy_SetFwCmdIOCallback(struct net_device* dev)
 
        RT_TRACE(COMP_CMD, "--->SetFwCmdIOTimerCallback(): Cmd(%#x), SetFwCmdInProgress(%d)\n", priv->CurrentFwCmdIO, priv->SetFwCmdInProgress);
 
-       switch(priv->CurrentFwCmdIO)
+       if(pFirmware->FirmwareVersion >= 0x34)
        {
-               case FW_CMD_HIGH_PWR_ENABLE:
-                       if((priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_HIGH_POWER)==0)
-                               write_nic_dword(dev, WFM5, FW_HIGH_PWR_ENABLE);
-                       break;
-
-               case FW_CMD_HIGH_PWR_DISABLE:
-                       write_nic_dword(dev, WFM5, FW_HIGH_PWR_DISABLE);
-                       break;
-
-               case FW_CMD_DIG_RESUME:
-                       write_nic_dword(dev, WFM5, FW_DIG_RESUME);
-                       break;
-
-               case FW_CMD_DIG_HALT:
-                       write_nic_dword(dev, WFM5, FW_DIG_HALT);
-                       break;
-
-               //
-               // <Roger_Notes> The following FW CMD IO was combined into single operation
-               // (i.e., to prevent number of system workitem out of resource!!).
-               // 2008.12.04.
-               //
-               case FW_CMD_RESUME_DM_BY_SCAN:
-                       RT_TRACE(COMP_CMD, "[FW CMD] Set HIGHPWR enable and DIG resume!!\n");
-                       if((priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_HIGH_POWER)==0)
-                       {
-                               write_nic_dword(dev, WFM5, FW_HIGH_PWR_ENABLE); //break;
-                               ChkFwCmdIoDone(dev);
-                       }
-                       write_nic_dword(dev, WFM5, FW_DIG_RESUME);
-                       break;
-
-               case FW_CMD_PAUSE_DM_BY_SCAN:
-                       RT_TRACE(COMP_CMD, "[FW CMD] Set HIGHPWR disable and DIG halt!!\n");
-                       write_nic_dword(dev, WFM5, FW_HIGH_PWR_DISABLE); //break;
-                       ChkFwCmdIoDone(dev);
-                       write_nic_dword(dev, WFM5, FW_DIG_HALT);
+               switch(priv->CurrentFwCmdIO)
+               {
+                       case FW_CMD_RA_REFRESH_N:
+                               priv->CurrentFwCmdIO = FW_CMD_RA_REFRESH_N_COMB;
                        break;
-
-               //
-               // <Roger_Notes> The following FW CMD IO should be checked
-               // (i.e., workitem schedule timing issue!!).
-               // 2008.12.04.
-               //
-               case FW_CMD_DIG_DISABLE:
-                       RT_TRACE(COMP_CMD, "[FW CMD] Set DIG disable!!\n");
-                       write_nic_dword(dev, WFM5, FW_DIG_DISABLE);
+                       case FW_CMD_RA_REFRESH_BG:
+                               priv->CurrentFwCmdIO = FW_CMD_RA_REFRESH_BG_COMB;
                        break;
-
-               case FW_CMD_DIG_ENABLE:
-                       RT_TRACE(COMP_CMD, "[FW CMD] Set DIG enable!!\n");
-                       write_nic_dword(dev, WFM5, FW_DIG_ENABLE);
+                       default:
                        break;
+               }
+       }
+       switch(priv->CurrentFwCmdIO)
+       {
 
                case FW_CMD_RA_RESET:
                        write_nic_dword(dev, WFM5, FW_RA_RESET);
@@ -3975,82 +3523,111 @@ void phy_SetFwCmdIOCallback(struct net_device* dev)
                        break;
 
                case FW_CMD_RA_REFRESH_N:
-                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA refresh!! N\n");
-                       if(priv->ieee80211->pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
+                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA n refresh!!\n");
+                       if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
                                input = FW_RA_REFRESH;
                        else
-                               input = FW_RA_REFRESH | (priv->ieee80211->pHTInfo->IOTRaFunc << 8);
+                               input = FW_RA_REFRESH | (pHTInfo->IOTRaFunc << 8);
                        write_nic_dword(dev, WFM5, input);
+                       ChkFwCmdIoDone(dev);
+                       write_nic_dword(dev, WFM5, FW_RA_ENABLE_RSSI_MASK);
+                       ChkFwCmdIoDone(dev);
                        break;
                case FW_CMD_RA_REFRESH_BG:
-                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA refresh!! B/G\n");
+                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA BG refresh!!\n");
                        write_nic_dword(dev, WFM5, FW_RA_REFRESH);
                        ChkFwCmdIoDone(dev);
-                       write_nic_dword(dev, WFM5, FW_RA_ENABLE_BG);
+                       write_nic_dword(dev, WFM5, FW_RA_DISABLE_RSSI_MASK);
+                       ChkFwCmdIoDone(dev);
+                       break;
+
+               case FW_CMD_RA_REFRESH_N_COMB:
+                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA n Combo refresh!!\n");
+                       if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
+                               input = FW_RA_IOT_N_COMB;
+                       else
+                               input = FW_RA_IOT_N_COMB | (((pHTInfo->IOTRaFunc)&0x0f) << 8);
+                       input = input |((pHTInfo->IOTPeer & 0xf) <<12);
+                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA/IOT Comb in n mode!! input(%#x)\n", input);
+                       write_nic_dword(dev, WFM5, input);
+                       ChkFwCmdIoDone(dev);
+                       break;
+
+               case FW_CMD_RA_REFRESH_BG_COMB:
+                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA B/G Combo refresh!!\n");
+                       if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
+                               input = FW_RA_IOT_BG_COMB;
+                       else
+                               input = FW_RA_IOT_BG_COMB | (((pHTInfo->IOTRaFunc)&0x0f) << 8);
+                       input = input |((pHTInfo->IOTPeer & 0xf) <<12);
+                       RT_TRACE(COMP_CMD, "[FW CMD] Set RA/IOT Comb in B/G mode!! input(%#x)\n", input);
+                       write_nic_dword(dev, WFM5, input);
+                       ChkFwCmdIoDone(dev);
                        break;
 
                case FW_CMD_IQK_ENABLE:
                        write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
+                       ChkFwCmdIoDone(dev);
                        break;
 
                case FW_CMD_TXPWR_TRACK_ENABLE:
                        write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_ENABLE);
+                       ChkFwCmdIoDone(dev);
                        break;
 
                case FW_CMD_TXPWR_TRACK_DISABLE:
                        write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_DISABLE);
+                       ChkFwCmdIoDone(dev);
                        break;
 
-               default:
-                       RT_TRACE(COMP_CMD,"Unknown FW Cmd IO(%#x)\n", priv->CurrentFwCmdIO);
+               case FW_CMD_PAUSE_DM_BY_SCAN:
+                       RT_TRACE(COMP_CMD,"[FW CMD] Pause DM by Scan!!\n");
+                       rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x17);
+                       rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x17);
+                       rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x40);
                        break;
-       }
-
-       ChkFwCmdIoDone(dev);
 
-       switch(priv->CurrentFwCmdIO)
-       {
+               case FW_CMD_RESUME_DM_BY_SCAN:
+                       RT_TRACE(COMP_CMD, "[FW CMD] Resume DM by Scan!!\n");
+                       rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x83);
+                       PHY_SetTxPowerLevel8192S(dev, priv->chan);
+                       break;
                case FW_CMD_HIGH_PWR_DISABLE:
-                       //if(pMgntInfo->bTurboScan)
-                       {
-                               //Lower initial gain
-                               rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x17);
-                               rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x17);
-                               // CCA threshold
-                               rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x40);
-                               // Disable OFDM Part
-                               rtl8192_setBBreg(dev, rOFDM0_TRMuxPar, bMaskByte2, 0x1);
-                               ScanRegister = rtl8192_QueryBBReg(dev, rOFDM0_RxDetector1,bMaskDWord);
-                               rtl8192_setBBreg(dev, rOFDM0_RxDetector1, 0xf, 0xf);
-                               rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
-                       }
+                       RT_TRACE(COMP_CMD, "[FW CMD] High Pwr Disable!!\n");
+                       if(priv->DMFlag & HAL_DM_HIPWR_DISABLE)
+                               break;
+                       rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x17);
+                       rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x17);
+                       rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x40);
                        break;
 
                case FW_CMD_HIGH_PWR_ENABLE:
-                       //if(pMgntInfo->bTurboScan)
-                       {
-                               rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x36);
-                               rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x36);
+                       RT_TRACE(COMP_CMD, "[FW CMD] High Pwr Enable!!\n");
+                       if(priv->DMFlag & HAL_DM_HIPWR_DISABLE)
+                               break;
+                       rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x83);
+                       break;
 
-                               // CCA threshold
-                               rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x83);
-                               // Enable OFDM Part
-                               rtl8192_setBBreg(dev, rOFDM0_TRMuxPar, bMaskByte2, 0x0);
+               case FW_CMD_LPS_ENTER:
+                       RT_TRACE(COMP_CMD, "[FW CMD] Enter LPS mode!!\n");
+                       CurrentAID = priv->ieee80211->assoc_id;
+                       write_nic_dword(dev, WFM5, (FW_LPS_ENTER| ((CurrentAID|0xc000)<<8))    );
+                       ChkFwCmdIoDone(dev);
+                       pHTInfo->IOTAction |=  HT_IOT_ACT_DISABLE_EDCA_TURBO;
+                       break;
 
-                               //LZM ADD because sometimes there is no FW_CMD_HIGH_PWR_DISABLE, this value will be 0.
-                               if(ScanRegister != 0){
-                               rtl8192_setBBreg(dev, rOFDM0_RxDetector1, bMaskDWord, ScanRegister);
-                               }
+               case FW_CMD_LPS_LEAVE:
+                       RT_TRACE(COMP_CMD, "[FW CMD] Leave LPS mode!!\n");
+                       write_nic_dword(dev, WFM5, FW_LPS_LEAVE );
+                       ChkFwCmdIoDone(dev);
+                       pHTInfo->IOTAction &=  (~HT_IOT_ACT_DISABLE_EDCA_TURBO);
+                       break;
 
-                               if(priv->rf_type == RF_1T2R || priv->rf_type == RF_2T2R)
-                                       rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x3);
-                               else
-                                       rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x1);
-                       }
+               default:
                        break;
        }
 
-       priv->SetFwCmdInProgress = false;// Clear FW CMD operation flag.
+       priv->SetFwCmdInProgress = false;
        RT_TRACE(COMP_CMD, "<---SetFwCmdIOWorkItemCallback()\n");
 
 }
index eccf4478fba80f6218d35508396ec479cbf4910e..741c6bf9a0180cf853bb7684669238b0ceee5c89 100644 (file)
@@ -1,33 +1,40 @@
-/*
-   This is part of rtl8187 OpenSource driver.
-   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-   Released under the terms of GPL (General Public Licence)
-
-   Parts of this driver are based on the GPL part of the
-   official realtek driver
-
-   Parts of this driver are based on the rtl8192 driver skeleton
-   from Patric Schenke & Andres Salomon
-
-   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
-   We want to tanks the Authors of those projects and the Ndiswrapper
-   project Authors.
-*/
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192U
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 
 #ifndef R819xU_H
 #define R819xU_H
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-//#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
-//#include <linux/pci.h>
 #include <linux/usb.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -51,9 +58,7 @@
 #define RTL819X_EEPROM_CMD_CK          (1 << 2)
 #define RTL819X_EEPROM_CMD_CS          (1 << 3)
 
-//#define RTL8192U
 #define RTL819xU_MODULE_NAME "rtl819xU"
-//added for HW security, john.0629
 #define FALSE 0
 #define TRUE 1
 #define MAX_KEY_LEN     61
@@ -114,6 +119,7 @@ do { if(rt_global_debug_component & component) \
 
 #define COMP_TRACE                             BIT0            // For function call tracing.
 #define COMP_DBG                               BIT1            // Only for temporary debug message.
+#define COMP_MLME                              BIT1
 #define COMP_INIT                              BIT2            // during driver initialization / halt / reset.
 
 
@@ -137,14 +143,14 @@ do { if(rt_global_debug_component & component) \
 #define COMP_SEC                               BIT20   // Event handling
 #define COMP_LED                               BIT21   // For LED.
 #define COMP_RF                                        BIT22   // For RF.
-//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#define COMP_RXDESC                            BIT23
+
 #define COMP_RXDESC                            BIT23   // Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15.
-//1//1Attention Please!!!<11n or 8190 specific code should be put below this line>
-//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 #define COMP_FIRMWARE                          BIT24   //for firmware downloading
 #define COMP_HT                                        BIT25   // For 802.11n HT related information. by Emily 2006-8-11
 #define COMP_AMSDU                             BIT26   // For A-MSDU Debugging
+#define COMP_PS                                        BIT26
 
 #define COMP_SCAN                              BIT27
 #define COMP_CMD                               BIT28
@@ -159,8 +165,7 @@ do { if(rt_global_debug_component & component) \
                 printk( "Assertion failed! %s,%s,%s,line=%d\n", \
                 #expr,__FILE__,__FUNCTION__,__LINE__);          \
         }
-//wb added to debug out data buf
-//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+
 #define RT_DEBUG_DATA(level, data, datalen)      \
         do{ if ((rt_global_debug_component & (level)) == (level))   \
                 {       \
@@ -180,25 +185,17 @@ do { if(rt_global_debug_component & component) \
 #define RT_DEBUG_DATA(level, data, datalen) do {} while(0)
 #endif /* RTL8169_DEBUG */
 
-//#ifdef RTL8192SU
        //2TODO: We should define 8192S firmware related macro settings here!!
        #define RTL819X_DEFAULT_RF_TYPE                         RF_1T2R
        #define RTL819X_TOTAL_RF_PATH                           2
 
-       //#define Rtl819XFwBootArray                                    Rtl8192UsbFwBootArray
-       //#define Rtl819XFwMainArray                                    Rtl8192UsbFwMainArray
-       //#define Rtl819XFwDataArray                                    Rtl8192UsbFwDataArray
-
        #define Rtl819XMACPHY_Array_PG                          Rtl8192UsbMACPHY_Array_PG
        #define Rtl819XMACPHY_Array                                     Rtl8192UsbMACPHY_Array
        #define Rtl819XPHY_REGArray                                     Rtl8192UsbPHY_REGArray
        #define Rtl819XPHY_REG_1T2RArray                                Rtl8192UsbPHY_REG_1T2RArray
-       //#define Rtl819XRadioA_Array                                   Rtl8192UsbRadioA_Array
-       //#define Rtl819XRadioB_Array                                   Rtl8192UsbRadioB_Array
        #define Rtl819XRadioC_Array                                     Rtl8192UsbRadioC_Array
        #define Rtl819XRadioD_Array                                     Rtl8192UsbRadioD_Array
 
-       //2008.11.06 Add.
        #define Rtl819XFwImageArray                                     Rtl8192SUFwImgArray
        #define Rtl819XMAC_Array                                                Rtl8192SUMAC_2T_Array
        #define Rtl819XAGCTAB_Array                                     Rtl8192SUAGCTAB_Array
@@ -212,8 +209,6 @@ do { if(rt_global_debug_component & component) \
        #define Rtl819XRadioB_GM_Array                          Rtl8192SURadioB_GM_Array
        #define Rtl819XRadioA_to1T_Array                                Rtl8192SURadioA_to1T_Array
        #define Rtl819XRadioA_to2T_Array                                Rtl8192SURadioA_to2T_Array
-//#endif
-
 //
 // Queue Select Value in TxDesc
 //
@@ -256,7 +251,6 @@ do { if(rt_global_debug_component & component) \
 #define DESC90_RATEMCS15                        0x0f
 #define DESC90_RATEMCS32                        0x20
 
-//#ifdef RTL8192SU
 // CCK Rates, TxHT = 0
 #define DESC92S_RATE1M                                 0x00
 #define DESC92S_RATE2M                                 0x01
@@ -292,13 +286,12 @@ do { if(rt_global_debug_component & component) \
 #define DESC92S_RATEMCS15                              0x1b
 #define DESC92S_RATEMCS15_SG                   0x1c
 #define DESC92S_RATEMCS32                              0x20
-//#endif
 
 #define RTL819X_DEFAULT_RF_TYPE RF_1T2R
 
 #define IEEE80211_WATCH_DOG_TIME    2000
 #define                PHY_Beacon_RSSI_SLID_WIN_MAX            10
-//for txpowertracking by amy
+//for txpowertracking
 #define        OFDM_Table_Length       19
 #define        CCK_Table_length        12
 
@@ -522,7 +515,6 @@ typedef struct rtl8192_rx_info {
        u8 out_pipe;
 }rtl8192_rx_info ;
 
-//typedef struct _RX_DESC_STATUS_8192SU{
 typedef struct rx_desc_819x_usb{
        //DWORD 0
        u16             Length:14;
@@ -582,77 +574,34 @@ typedef struct rx_desc_819x_usb{
 
        //DWORD 5
        u32             TSFL;
-//}RX_DESC_STATUS_8192SU, *PRX_DESC_STATUS_8192SU;
 }rx_desc_819x_usb, *prx_desc_819x_usb;
 
 
 //
 // Driver info are written to the begining of the RxBuffer
 //
-//typedef struct _RX_DRIVER_INFO_8192S{
 typedef struct rx_drvinfo_819x_usb{
-       //
-       // Driver info contain PHY status and other variabel size info
-       // PHY Status content as below
-       //
-
-       //DWORD 0
-       /*u4Byte                        gain_0:7;
-       u4Byte                  trsw_0:1;
-       u4Byte                  gain_1:7;
-       u4Byte                  trsw_1:1;
-       u4Byte                  gain_2:7;
-       u4Byte                  trsw_2:1;
-       u4Byte                  gain_3:7;
-       u4Byte                  trsw_3:1;       */
        u8                      gain_trsw[4];
 
        //DWORD 1
-       /*u4Byte                        pwdb_all:8;
-       u4Byte                  cfosho_0:8;
-       u4Byte                  cfosho_1:8;
-       u4Byte                  cfosho_2:8;*/
        u8                      pwdb_all;
        u8                      cfosho[4];
 
        //DWORD 2
-       /*u4Byte                        cfosho_3:8;
-       u4Byte                  cfotail_0:8;
-       u4Byte                  cfotail_1:8;
-       u4Byte                  cfotail_2:8;*/
        u8                      cfotail[4];
 
        //DWORD 3
-       /*u4Byte                        cfotail_3:8;
-       u4Byte                  rxevm_0:8;
-       u4Byte                  rxevm_1:8;
-       u4Byte                  rxsnr_0:8;*/
        char                            rxevm[2];
        char                            rxsnr[4];
 
        //DWORD 4
-       /*u4Byte                        rxsnr_1:8;
-       u4Byte                  rxsnr_2:8;
-       u4Byte                  rxsnr_3:8;
-       u4Byte                  pdsnr_0:8;*/
        u8                      pdsnr[2];
 
        //DWORD 5
-       /*u4Byte                        pdsnr_1:8;
-       u4Byte                  csi_current_0:8;
-       u4Byte                  csi_current_1:8;
-       u4Byte                  csi_target_0:8;*/
        u8                      csi_current[2];
        u8                      csi_target[2];
 
        //DWORD 6
-       /*u4Byte                        csi_target_1:8;
-       u4Byte                  sigevm:8;
-       u4Byte                  max_ex_pwr:8;
-       u4Byte                  ex_intf_flag:1;
-       u4Byte                  sgi_en:1;
-       u4Byte                  rxsc:2;
-       u4Byte                  reserve:4;*/
        u8                      sigevm;
        u8                      max_ex_pwr;
        u8                      ex_intf_flag:1;
@@ -669,10 +618,8 @@ typedef struct rx_drvinfo_819x_usb{
 
 #define MAX_DEV_ADDR_SIZE              8  /* support till 64 bit bus width OS */
 #define MAX_FIRMWARE_INFORMATION_SIZE   32 /*2006/04/30 by Emily forRTL8190*/
-//#define MAX_802_11_HEADER_LENGTH        (40 + MAX_FIRMWARE_INFORMATION_SIZE)
 #define ENCRYPTION_MAX_OVERHEAD                128
 #define        USB_HWDESC_HEADER_LEN           sizeof(tx_desc_819x_usb)
-//#define TX_PACKET_SHIFT_BYTES                (USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb))
 #define MAX_FRAGMENT_COUNT             8
 #ifdef RTL8192U
 #define MAX_TRANSMIT_BUFFER_SIZE                       8000
@@ -681,19 +628,15 @@ typedef struct rx_drvinfo_819x_usb{
 #endif
 #define scrclng                                        4               // octets for crc32 (FCS, ICV)
 
+#define                HAL_DM_DIG_DISABLE                              BIT0
+#define                HAL_DM_HIPWR_DISABLE                            BIT1
+
 typedef enum rf_optype
 {
        RF_OP_By_SW_3wire = 0,
        RF_OP_By_FW,
        RF_OP_MAX
 }rf_op_type;
-/* 8190 Loopback Mode definition */
-typedef enum _rtl819xUsb_loopback{
-       RTL819xU_NO_LOOPBACK = 0,
-       RTL819xU_MAC_LOOPBACK = 1,
-       RTL819xU_DMA_LOOPBACK = 2,
-       RTL819xU_CCK_LOOPBACK = 3,
-}rtl819xUsb_loopback_e;
 
 /* for rtl819x */
 typedef enum _RT_STATUS{
@@ -703,16 +646,13 @@ typedef enum _RT_STATUS{
        RT_STATUS_RESOURCE = 3
 }RT_STATUS,*PRT_STATUS;
 
-//#ifdef RTL8192SU
 typedef enum _RTL8192SUSB_LOOPBACK{
        RTL8192SU_NO_LOOPBACK = 0,
        RTL8192SU_MAC_LOOPBACK = 1,
        RTL8192SU_DMA_LOOPBACK = 2,
        RTL8192SU_CCK_LOOPBACK = 3,
 }RTL8192SUSB_LOOPBACK_E;
-//#endif
 
-//+by amy 080507
 #define MAX_RECEIVE_BUFFER_SIZE        9100    // Add this to 9100 bytes to receive A-MSDU from RT-AP
 
 
@@ -790,10 +730,6 @@ typedef struct rtl_reg_debug{
 typedef struct _rt_9x_tx_rate_history {
        u32             cck[4];
        u32             ofdm[8];
-       // HT_MCS[0][]: BW=0 SG=0
-       // HT_MCS[1][]: BW=1 SG=0
-       // HT_MCS[2][]: BW=0 SG=1
-       // HT_MCS[3][]: BW=1 SG=1
        u32             ht_mcs[4][16];
 }rt_tx_rahis_t, *prt_tx_rahis_t;
 typedef struct _RT_SMOOTH_DATA_4RF {
@@ -808,11 +744,6 @@ typedef struct _RT_SMOOTH_DATA_4RF {
 typedef struct Stats
 {
        unsigned long txrdu;
-//     unsigned long rxrdu;
-       //unsigned long rxnolast;
-       //unsigned long rxnodata;
-//     unsigned long rxreset;
-//     unsigned long rxnopointer;
        unsigned long rxok;
        unsigned long rxframgment;
        unsigned long rxcmdpkt[4];              //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query
@@ -832,18 +763,8 @@ typedef struct Stats
        unsigned long txnperr;
        unsigned long txnpdrop;
        unsigned long txresumed;
-//     unsigned long rxerr;
-//     unsigned long rxoverflow;
-//     unsigned long rxint;
        unsigned long txnpokint;
-//     unsigned long txhpokint;
-//     unsigned long txhperr;
-//     unsigned long ints;
-//     unsigned long shints;
        unsigned long txoverflow;
-//     unsigned long rxdmafail;
-//     unsigned long txbeacon;
-//     unsigned long txbeaconerr;
        unsigned long txlpokint;
        unsigned long txlpdrop;
        unsigned long txlperr;
@@ -909,14 +830,11 @@ typedef struct Stats
        u32     CurrentShowTxate;
 } Stats;
 
-
 // Bandwidth Offset
 #define HAL_PRIME_CHNL_OFFSET_DONT_CARE                0
 #define HAL_PRIME_CHNL_OFFSET_LOWER                    1
 #define HAL_PRIME_CHNL_OFFSET_UPPER                    2
 
-//+by amy 080507
-
 typedef struct         ChnlAccessSetting {
        u16 SIFS_Timer;
        u16 DIFS_Timer;
@@ -956,14 +874,12 @@ typedef enum _RT_RF_TYPE_819xU{
         RF_PSEUDO_11N = 5,
 }RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
 
-//#ifdef RTL8192SU
 typedef enum _RF_POWER_STATE{
        RF_ON,
        RF_SLEEP,
        RF_OFF,
        RF_SHUT_DOWN,
 }RF_POWER_STATE, *PRF_POWER_STATE;
-//#endif
 
 typedef struct _rate_adaptive
 {
@@ -1014,7 +930,6 @@ typedef struct _init_gain
        u8                              cca;
 
 } init_gain, *pinit_gain;
-//by amy 0606
 
 typedef struct _phy_ofdm_rx_status_report_819xusb
 {
@@ -1066,8 +981,26 @@ typedef enum _RT_CUSTOMER_ID
        RT_CID_Nettronix = 11,
        RT_CID_DLINK = 12,
        RT_CID_PRONET = 13,
+       RT_CID_COREGA = 14,
+       RT_CID_819x_ALPHA = 15,
+       RT_CID_819x_Sitecom = 16,
+       RT_CID_CCX = 17,
+       RT_CID_819x_Lenovo = 18,
+       RT_CID_819x_QMI = 19,
+       RT_CID_819x_Edimax_Belkin = 20,
+       RT_CID_819x_Sercomm_Belkin = 21,
+       RT_CID_819x_CAMEO1 = 22,
+       RT_CID_819x_MSI = 23,
+       RT_CID_819x_Acer = 24,
 }RT_CUSTOMER_ID, *PRT_CUSTOMER_ID;
 
+typedef enum _RT_OP_MODE{
+    RT_OP_MODE_AP,
+    RT_OP_MODE_INFRASTRUCTURE,
+    RT_OP_MODE_IBSS,
+    RT_OP_MODE_NO_LINK,
+}RT_OP_MODE, *PRT_OP_MODE;
+
 typedef enum _RESET_TYPE {
        RESET_TYPE_NORESET = 0x00,
        RESET_TYPE_NORMAL = 0x01,
@@ -1093,8 +1026,6 @@ typedef enum{
        NIC_8192SU = 5,
        } nic_t;
 
-//definded by WB. Ready to fill handlers for different NIC types.
-//add handle here when necessary.
 struct rtl819x_ops{
        nic_t nic_type;
        void (* rtl819x_read_eeprom_info)(struct net_device *dev);
@@ -1113,11 +1044,12 @@ typedef struct r8192_priv
        struct rtl819x_ops* ops;
        struct usb_device *udev;
        /* added for maintain info from eeprom */
+       short epromtype;
        u16 eeprom_vid;
        u16 eeprom_pid;
        u8  eeprom_CustomerID;
        u8  eeprom_SubCustomerID;
-       u8  eeprom_ChannelPlan;
+       u16  eeprom_ChannelPlan;
        RT_CUSTOMER_ID CustomerID;
        LED_STRATEGY_819xUsb    LedStrategy;
        u8  txqueue_to_outpipemap[9];
@@ -1129,76 +1061,55 @@ typedef struct r8192_priv
        int irq;
        struct ieee80211_device *ieee80211;
 
+       u8 RATRTableBitmap;
+
+       u32     IC_Cut;
        short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
-       u8 card_8192_version; /* if TCR reports card V B/C this discriminates */
-//     short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
+       u32 card_8192_version; /* if TCR reports card V B/C this discriminates */
        short enable_gpio0;
        enum card_type {PCI,MINIPCI,CARDBUS,USB}card_type;
        short hw_plcp_len;
        short plcp_preamble_mode;
 
        spinlock_t irq_lock;
-//     spinlock_t irq_th_lock;
        spinlock_t tx_lock;
        spinlock_t ps_lock;
         struct mutex mutex;
+       bool ps_force;
        spinlock_t rf_lock; //used to lock rf write operation added by wb
+       spinlock_t rf_ps_lock;
 
        u16 irq_mask;
-//     short irq_enabled;
-//     struct net_device *dev; //comment this out.
        short chan;
        short sens;
        short max_sens;
 
-
-       //      u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
-//     u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
-//     u8 cck_txpwr_base;
-//     u8 ofdm_txpwr_base;
-//     u8 challow[15]; //channels from 1 to 14, 0 not used
        short up;
        short crcmon; //if 1 allow bad crc frame reception in monitor mode
-//     short prism_hdr;
-
-//     struct timer_list scan_timer;
-       /*short scanpending;
-       short stopscan;*/
-//     spinlock_t scan_lock;
-//     u8 active_probe;
-       //u8 active_scan_num;
+       bool bSurpriseRemoved;
+
        struct semaphore wx_sem;
        struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david
-//     short hw_wep;
 
-//     short digphy;
-//     short antb;
-//     short diversity;
-//     u8 cs_treshold;
-//     short rcr_csense;
        u8 rf_type; //0 means 1T2R, 1 means 2T4R
        RT_RF_TYPE_819xU rf_chip;
 
-//     u32 key0[4];
        short (*rf_set_sens)(struct net_device *dev,short sens);
        u8 (*rf_set_chan)(struct net_device *dev,u8 ch);
        void (*rf_close)(struct net_device *dev);
        void (*rf_init)(struct net_device *dev);
-       //short rate;
        short promisc;
+        u32 mc_filter[2];
        /*stats*/
        struct Stats stats;
        struct iw_statistics wstats;
        struct proc_dir_entry *dir_dev;
 
        /*RX stuff*/
-//     u32 *rxring;
-//     u32 *rxringtail;
-//     dma_addr_t rxringdma;
        struct urb **rx_urb;
        struct urb **rx_cmd_urb;
 
-/* modified by davad for Rx process */
+/* for Rx process */
        struct sk_buff_head rx_queue;
        struct sk_buff_head skb_queue;
 
@@ -1209,6 +1120,7 @@ typedef struct r8192_priv
 
 
        struct tasklet_struct irq_rx_tasklet;
+       struct tasklet_struct irq_tx_tasklet;
        struct urb *rxurb_task;
 
        //2 Tx Related variables
@@ -1235,6 +1147,7 @@ typedef struct r8192_priv
        struct  ChnlAccessSetting  ChannelAccessSetting;
 
        struct work_struct reset_wq;
+        struct work_struct mcast_wq;
 
 /**********************************************************/
        //for rtl819xUsb
@@ -1244,21 +1157,28 @@ typedef struct r8192_priv
        bool    bDcut;
        bool bCurrentRxAggrEnable;
        u8 Rf_Mode; //add for Firmware RF -R/W switch
+       u8 FwRsvdTxPageCfg;
        prt_firmware            pFirmware;
-       rtl819xUsb_loopback_e   LoopbackMode;
+       RTL8192SUSB_LOOPBACK_E  LoopbackMode;
        bool usb_error;
 
        u16 EEPROMTxPowerDiff;
        u8 EEPROMThermalMeter;
        u8 EEPROMPwDiff;
        u8 EEPROMCrystalCap;
+       u8 EEPROMBluetoothCoexist;
        u8 EEPROM_Def_Ver;
        u8 EEPROMTxPowerLevelCCK;// CCK channel 1~14
        u8 EEPROMTxPowerLevelCCK_V1[3];
        u8 EEPROMTxPowerLevelOFDM24G[3]; // OFDM 2.4G channel 1~14
        u8 EEPROMTxPowerLevelOFDM5G[24];        // OFDM 5G
 
-//RTL8192SU
+       u8 EEPROMOptional;
+       u8 ShowRateMode;
+       bool bForcedShowRxRate;
+
+       u32     RfRegChnlVal[2];
+
        bool    bDmDisableProtect;
        bool    bIgnoreDiffRateTxPowerOffset;
 
@@ -1278,6 +1198,9 @@ typedef struct r8192_priv
        bool            EepromOrEfuse;
        bool            bBootFromEfuse; // system boot form EFUSE
        u8              EfuseMap[2][HWSET_MAX_SIZE_92S];
+       u16             EfuseUsedBytes;
+       u8              EfuseUsedPercentage;
+
 
        u8              EEPROMUsbOption;
        u8              EEPROMUsbPhyParam[5];
@@ -1290,6 +1213,8 @@ typedef struct r8192_priv
        u8              EEPROMTxPwrTkMode;
 
        u8              bTXPowerDataReadFromEEPORM;
+       u8              EEPROMRegulatory;
+       u8              EEPROMPwrGroup[2][3];
 
        u8              EEPROMVersion;
        u8              EEPROMUsbEndPointNumber;
@@ -1298,7 +1223,7 @@ typedef struct r8192_priv
        u8      RfTxPwrLevelCck[2][14];
        u8      RfTxPwrLevelOfdm1T[2][14];
        u8      RfTxPwrLevelOfdm2T[2][14];
-       // 2009/01/20 MH Add for new EEPROM format.
+       // new EEPROM format.
        u8                                      TxPwrHt20Diff[2][14];                           // HT 20<->40 Pwr diff
        u8                                      TxPwrLegacyHtDiff[2][14];               // For HT<->legacy pwr diff
        u8                                      TxPwrbandEdgeHt40[2][2];                // Band edge for HY 40MHZlow/up channel
@@ -1310,7 +1235,6 @@ typedef struct r8192_priv
        u8                              MidHighPwrTHR_L1;
        u8                              MidHighPwrTHR_L2;
        u8                              TxPwrSafetyFlag;                                // for Tx power safety spec
-//RTL8192SU
 
 /*PHY related*/
        BB_REGISTER_DEFINITION_T        PHYRegDef[4];   //Radio A/B/C/D
@@ -1323,8 +1247,11 @@ typedef struct r8192_priv
        u32     Pwr_Track;
        u8      TxPowerDiff;
        u8      AntennaTxPwDiff[2];                             // Antenna gain offset, index 0 for B, 1 for C, and 2 for D
+       u8      ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1
+       u8      ThermalValue;
        u8      CrystalCap;                                             // CrystalCap.
-       u8      ThermalMeter[2];                                // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1
+       u8      BluetoothCoexist;
+       u8      ExternalPA;
 
        u8      CckPwEnl;
        // Use to calculate PWBD.
@@ -1337,24 +1264,22 @@ typedef struct r8192_priv
        u8      SwChnlStep;
        u8      SetBWModeInProgress;
        HT_CHANNEL_WIDTH                CurrentChannelBW;
+       bool bChnlPlanFromHW;
        u8      ChannelPlan;
+       u16     RegChannelPlan;
        u8      pwrGroupCnt;
        // 8190 40MHz mode
        //
        u8      nCur40MhzPrimeSC;       // Control channel sub-carrier
-       // Joseph test for shorten RF configuration time.
-       // We save RF reg0 in this variable to reduce RF reading.
-       //
+
        u32                                     RfReg0Value[4];
        u8                                      NumTotalRFPath;
        bool                            brfpath_rxenable[4];
        //RF set related
        bool                            SetRFPowerStateInProgress;
-//+by amy 080507
+
        struct timer_list watch_dog_timer;
 
-//+by amy 080515 for dynamic mechenism
-       //Add by amy Tx Power Control for Near/Far Range 2008/05/15
        bool    bdynamic_txpower;  //bDynamicTxPower
        bool    bDynamicTxHighPower;  // Tx high power state
        bool    bDynamicTxLowPower;  // Tx low power state
@@ -1363,17 +1288,18 @@ typedef struct r8192_priv
 
        bool    bstore_last_dtpflag;
        bool    bstart_txctrl_bydtp;   //Define to discriminate on High power State or on sitesuvey to change Tx gain index
-       //Add by amy for Rate Adaptive
+
        rate_adaptive rate_adaptive;
-       //Add by amy for TX power tracking
-       //2008/05/15  Mars OPEN/CLOSE TX POWER TRACKING
+       // TX power tracking
        txbbgain_struct txbbgain_table[TxBBGainTableLength];
        u8      EEPROMTxPowerTrackEnable;
        u8                         txpower_count;//For 6 sec do tracking again
        bool                       btxpower_trackingInit;
        u8                         OFDM_index;
        u8                         CCK_index;
-       //2007/09/10 Mars Add CCK TX Power Tracking
+       u8                         Record_CCK_20Mindex;
+       u8                         Record_CCK_40Mindex;
+       // CCK TX Power Tracking
        ccktxbbgain_struct      cck_txbbgain_table[CCKTxBBGainTableLength];
        ccktxbbgain_struct      cck_txbbgain_ch14_table[CCKTxBBGainTableLength];
        u8 rfa_txpowertrackingindex;
@@ -1390,10 +1316,15 @@ typedef struct r8192_priv
        bool bcck_in_ch14;
        bool btxpowerdata_readfromEEPORM;
        u16     TSSI_13dBm;
+       u8      CCKPresentAttentuation_20Mdefault;
+       u8      CCKPresentAttentuation_40Mdefault;
+       char    CCKPresentAttentuation_difference;
+       char    CCKPresentAttentuation;
+       bool bDMInitialGainEnable;
        //For Backup Initial Gain
        init_gain initgain_backup;
        u8 DefaultInitialGain[4];
-       // For EDCA Turbo mode, Added by amy 080515.
+       // For EDCA Turbo mode
        bool            bis_any_nonbepkts;
        bool            bcurrent_turbo_EDCA;
        bool            bis_cur_rdlstate;
@@ -1407,17 +1338,23 @@ typedef struct r8192_priv
        u8      framesync;
        u32     framesyncC34;
        u8      framesyncMonitor;
-               //Added by amy 080516  for RX related
+               // RX related
        u16     nrxAMPDU_size;
        u8      nrxAMPDU_aggr_num;
 
-       //by amy for gpio
+       // gpio
         bool bHwRadioOff;
 
-       //by amy for reset_count
+       bool isRFOff;
+       bool bInPowerSaveMode;
+
+       bool RFChangeInProgress;
+       bool RegRfOff;
+       u8      bHwRfOffAction;
+
        u32 reset_count;
        bool bpbc_pressed;
-       //by amy for debug
+       // debug
        u32 txpower_checkcnt;
        u32 txpower_tracking_callback_cnt;
        u8 thermal_read_val[40];
@@ -1426,7 +1363,7 @@ typedef struct r8192_priv
        u32 ccktxpower_adjustcnt_ch14;
        u8 tx_fwinfo_force_subcarriermode;
        u8 tx_fwinfo_force_subcarrierval;
-       //by amy for silent reset
+       // silent reset
        RESET_TYPE      ResetProgress;
        bool            bForcedSilentReset;
        bool            bDisableNormalResetCheck;
@@ -1435,11 +1372,11 @@ typedef struct r8192_priv
        int             IrpPendingCount;
        bool            bResetInProgress;
        bool            force_reset;
+       bool            force_lps;
        u8              InitialGainOperateType;
 
        u16             SifsTime;
 
-       //define work item by amy 080526
        struct delayed_work update_beacon_wq;
        struct delayed_work watch_dog_wq;
        struct delayed_work txpower_tracking_wq;
@@ -1448,8 +1385,7 @@ typedef struct r8192_priv
        struct delayed_work initialgain_operate_wq;
 
        struct workqueue_struct *priv_wq;
-//#ifdef RTL8192SU
-       //lzm add for 8192S
+
         u32                    IntrMask;
        // RF and BB access related synchronization flags.
        bool                            bChangeBBInProgress; // BaseBand RW is still in progress.
@@ -1464,7 +1400,6 @@ typedef struct r8192_priv
        u8                              ThermalReadBackIndex;                   //debug only
        u8                              ThermalReadVal[40];                             //debug only
 
-       // For HCT test, 2005.07.15, by rcnjko.
        // not realize true, just define it, set it 0 default, because some func use it
        bool                            bInHctTest;
 
@@ -1481,7 +1416,6 @@ typedef struct r8192_priv
        char                                    RF_C_TxPwDiff;                                  // Antenna gain offset, rf-c to rf-a
 
        bool    bRFSiOrPi;//0=si, 1=pi.
-       //lzm add for 8192S
 
        bool SetFwCmdInProgress; //is set FW CMD in Progress? 92S only
        u8 CurrentFwCmdIO;
@@ -1495,25 +1429,17 @@ typedef struct r8192_priv
        LED_819xUsb                     SwLed0;
        LED_819xUsb                     SwLed1;
         u8                              bRegUseLed;
-       struct work_struct              BlinkWorkItem; 
+       struct work_struct              BlinkWorkItem;
        /* added for led control */
        u16                             FwCmdIOMap;
        u32                             FwCmdIOParam;
-       u8                              DMFlag; 
+       u8                              DMFlag;
 
 
 
 
 }r8192_priv;
 
-// for rtl8187
-// now mirging to rtl8187B
-/*
-typedef enum{
-       LOW_PRIORITY = 0x02,
-       NORM_PRIORITY
-       } priority_t;
-*/
 //for rtl8187B
 typedef enum{
        BULK_PRIORITY = 0x01,
@@ -1542,6 +1468,9 @@ struct ssid_thread {
 };
 #endif
 
+void LedControl8192SUsb(struct net_device *dev, LED_CTL_MODE LedAction);
+void InitSwLeds(struct net_device *dev);
+void DeInitSwLeds(struct net_device *dev);
 short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
 short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
 bool FirmwareDownload92S(struct net_device *dev);
@@ -1567,7 +1496,6 @@ void rtl8192_rx_enable(struct net_device *);
 void rtl8192_tx_enable(struct net_device *);
 
 void rtl8192_disassociate(struct net_device *dev);
-//void fix_rx_fifo(struct net_device *dev);
 void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
 
 void rtl8192_set_anaparam(struct net_device *dev,u32 a);
@@ -1582,7 +1510,6 @@ void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
 void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
 void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
 void rtl8192_set_rxconf(struct net_device *dev);
-//short check_nic_enough_desc(struct net_device *dev, priority_t priority);
 extern void rtl819xusb_beacon_tx(struct net_device *dev,u16  tx_rate);
 void CamResetAllEntry(struct net_device* dev);
 void EnableHWSecurityConfig8192(struct net_device *dev);
index 1b6890611fb6dc822156e6ffbee719fb156712c3..6970c97713d8e8611df165dbfaafaf3489bc995e 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/notifier.h>
 
 #undef LOOP_TEST
 #undef DUMP_RX
@@ -162,6 +163,8 @@ MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
                         const struct usb_device_id *id);
 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
+static const struct net_device_ops rtl8192_netdev_ops;
+static struct notifier_block proc_netdev_notifier;
 
 static struct usb_driver rtl8192_usb_driver = {
        .name           = RTL819xU_MODULE_NAME,           /* Driver name   */
@@ -252,53 +255,49 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
 {
        int i, max_chan=-1, min_chan=-1;
        struct ieee80211_device* ieee = priv->ieee80211;
-       switch (channel_plan)
-       {
-               case COUNTRY_CODE_FCC:
-               case COUNTRY_CODE_IC:
-               case COUNTRY_CODE_ETSI:
-               case COUNTRY_CODE_SPAIN:
-               case COUNTRY_CODE_FRANCE:
-               case COUNTRY_CODE_MKK:
-               case COUNTRY_CODE_MKK1:
-               case COUNTRY_CODE_ISRAEL:
-               case COUNTRY_CODE_TELEC:
-               case COUNTRY_CODE_MIC:
-               {
-                       Dot11d_Init(ieee);
-                       ieee->bGlobalDomain = false;
-                       //acturally 8225 & 8256 rf chip only support B,G,24N mode
-                        if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256) || (priv->rf_chip == RF_6052))
-                       {
-                               min_chan = 1;
-                               max_chan = 14;
-                       }
-                       else
-                       {
-                               RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
-                       }
-                       if (ChannelPlan[channel_plan].Len != 0){
-                               // Clear old channel map
-                               memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
-                               // Set new channel map
-                               for (i=0;i<ChannelPlan[channel_plan].Len;i++)
-                               {
-                                       if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
-                                       break;
-                                       GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
-                               }
-                       }
-                       break;
-               }
-               case COUNTRY_CODE_GLOBAL_DOMAIN:
-               {
-                       GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
-                       Dot11d_Reset(ieee);
-                       ieee->bGlobalDomain = true;
-                       break;
+
+       ieee->bGlobalDomain = false;
+       switch (priv->rf_chip) {
+       case RF_8225:
+       case RF_8256:
+       case RF_6052:
+               min_chan = 1;
+               max_chan = 14;
+               break;
+       default:
+               pr_err("%s(): unknown rf chip, can't set channel map\n",
+                                                               __func__);
+               break;
+       }
+       if (ChannelPlan[channel_plan].Len != 0) {
+               memset(GET_DOT11D_INFO(ieee)->channel_map, 0,
+                               sizeof(GET_DOT11D_INFO(ieee)->channel_map));
+
+               for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
+                       if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
+                               break;
+                       GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
                }
-               default:
-                       break;
+       }
+       switch (channel_plan) {
+       case COUNTRY_CODE_GLOBAL_DOMAIN:
+               ieee->bGlobalDomain = true;
+               for (i = 12; i <= 14; i++)
+                       GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
+               ieee->IbssStartChnl = 10;
+               ieee->ibss_maxjoin_chal = 11;
+               break;
+       case COUNTRY_CODE_WORLD_WIDE_13:
+               printk(KERN_INFO "world wide 13\n");
+               for (i = 12; i <= 13; i++)
+                       GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
+               ieee->IbssStartChnl = 10;
+               ieee->ibss_maxjoin_chal = 11;
+               break;
+       default:
+               ieee->IbssStartChnl = 1;
+               ieee->ibss_maxjoin_chal = 14;
+               break;
        }
        return;
 }
@@ -991,15 +990,24 @@ static int proc_get_stats_rx(char *page, char **start,
        return len;
 }
 
-void rtl8192_proc_module_init(void)
+int rtl8192_proc_module_init(void)
 {
+       int ret;
+
        RT_TRACE(COMP_INIT, "Initializing proc filesystem");
        rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
+       if (!rtl8192_proc)
+               return -ENOMEM;
+       ret = register_netdevice_notifier(&proc_netdev_notifier);
+       if (ret)
+               remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
+       return ret;
 }
 
 
 void rtl8192_proc_module_remove(void)
 {
+       unregister_netdevice_notifier(&proc_netdev_notifier);
        remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
 }
 
@@ -1027,8 +1035,7 @@ void rtl8192_proc_remove_one(struct net_device *dev)
                remove_proc_entry("registers-e", priv->dir_dev);
        //      remove_proc_entry("cck-registers",priv->dir_dev);
        //      remove_proc_entry("ofdm-registers",priv->dir_dev);
-               //remove_proc_entry(dev->name, rtl8192_proc);
-               remove_proc_entry("wlan0", rtl8192_proc);
+               remove_proc_entry(priv->dir_dev->name, rtl8192_proc);
                priv->dir_dev = NULL;
        }
 }
@@ -1145,6 +1152,25 @@ void rtl8192_proc_init_one(struct net_device *dev)
                      dev->name);
        }
 }
+
+static int proc_netdev_event(struct notifier_block *this,
+                            unsigned long event, void *ptr)
+{
+       struct net_device *net_dev = ptr;
+
+       if (net_dev->netdev_ops == &rtl8192_netdev_ops &&
+           event == NETDEV_CHANGENAME) {
+               rtl8192_proc_remove_one(net_dev);
+               rtl8192_proc_init_one(net_dev);
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block proc_netdev_notifier = {
+       .notifier_call = proc_netdev_event,
+};
+
 /****************************************************************************
    -----------------------------MISC STUFF-------------------------
 *****************************************************************************/
@@ -7355,6 +7381,8 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
         RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
 
        dev = alloc_ieee80211(sizeof(struct r8192_priv));
+       if (dev == NULL)
+               return -ENOMEM;
 
        usb_set_intfdata(intf, dev);
        SET_NETDEV_DEV(dev, &intf->dev);
@@ -7392,7 +7420,8 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
        netif_carrier_off(dev);
        netif_stop_queue(dev);
 
-       register_netdev(dev);
+       if (register_netdev(dev))
+               goto fail;
        RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
        rtl8192_proc_init_one(dev);
 
@@ -7474,35 +7503,63 @@ static int __init rtl8192_usb_module_init(void)
        ret = ieee80211_crypto_init();
        if (ret) {
                printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
-               return ret;
+               goto fail_crypto;
        }
 
        ret = ieee80211_crypto_tkip_init();
        if (ret) {
                printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
                        ret);
-               return ret;
+               goto fail_crypto_tkip;
        }
 
        ret = ieee80211_crypto_ccmp_init();
        if (ret) {
                printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
                        ret);
-               return ret;
+               goto fail_crypto_ccmp;
        }
 
        ret = ieee80211_crypto_wep_init();
        if (ret) {
                printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
-               return ret;
+               goto fail_crypto_wep;
        }
 
        printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
        printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
        RT_TRACE(COMP_INIT, "Initializing module");
        RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
-       rtl8192_proc_module_init();
-       return usb_register(&rtl8192_usb_driver);
+
+       ret = rtl8192_proc_module_init();
+       if (ret) {
+               pr_err("rtl8192_proc_module_init() failed %d\n", ret);
+               goto fail_proc;
+       }
+
+       ret = usb_register(&rtl8192_usb_driver);
+       if (ret) {
+               pr_err("usb_register() failed %d\n", ret);
+               goto fail_usb;
+       }
+
+       return 0;
+
+fail_usb:
+       rtl8192_proc_module_remove();
+fail_proc:
+       ieee80211_crypto_wep_exit();
+fail_crypto_wep:
+       ieee80211_crypto_ccmp_exit();
+fail_crypto_ccmp:
+       ieee80211_crypto_tkip_exit();
+fail_crypto_tkip:
+       ieee80211_crypto_deinit();
+fail_crypto:
+#ifdef CONFIG_IEEE80211_DEBUG
+       ieee80211_debug_exit();
+#endif
+       return ret;
 }
 
 
index fa5e24416ddef36734b8c496958795c5763f015a..ce7e1ee4c3a773692a29c3a521ff95641d52b17c 100644 (file)
@@ -2673,7 +2673,6 @@ static void dm_check_edca_turbo(
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
-       //PSTA_QOS                      pStaQos = pMgntInfo->pStaQos;
 
        // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
        static unsigned long                    lastTxOkCnt = 0;
@@ -2681,10 +2680,8 @@ static void dm_check_edca_turbo(
        unsigned long                           curTxOkCnt = 0;
        unsigned long                           curRxOkCnt = 0;
 
-       //
-       // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
-       // should follow the settings from QAP. By Bruce, 2007-12-07.
-       //
+       u32                             EDCA_BE_UL = edca_setting_UL[pHTInfo->IOTPeer];
+       u32                             EDCA_BE_DL = edca_setting_DL[pHTInfo->IOTPeer];
        #if 1
        if(priv->ieee80211->state != IEEE80211_LINKED)
                goto dm_CheckEdcaTurbo_EXIT;
@@ -2693,6 +2690,14 @@ static void dm_check_edca_turbo(
        if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
                goto dm_CheckEdcaTurbo_EXIT;
 
+       if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_FORCED_ENABLE_BE_TXOP)
+       {
+               if(!(EDCA_BE_UL & 0xffff0000))
+                       EDCA_BE_UL |= 0x005e0000;
+               if(!(EDCA_BE_DL & 0xffff0000))
+                       EDCA_BE_DL |= 0x005e0000;
+       }
+
        {
                u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"};
                static int wb_tmp = 0;
@@ -2714,7 +2719,7 @@ static void dm_check_edca_turbo(
                        {
                                if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
                                {
-                                       write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
+                                       write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_UL);
                                        priv->bis_cur_rdlstate = false;
                                }
                        }
@@ -2722,7 +2727,7 @@ static void dm_check_edca_turbo(
                        {
                                if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
                                {
-                                       write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
+                                       write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_DL);
                                        priv->bis_cur_rdlstate = true;
                                }
                        }
@@ -2734,7 +2739,7 @@ static void dm_check_edca_turbo(
                        {
                                if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
                                {
-                                       write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
+                                       write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_DL);
                                        priv->bis_cur_rdlstate = true;
                                }
                        }
@@ -2742,7 +2747,7 @@ static void dm_check_edca_turbo(
                        {
                                if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
                                {
-                                       write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
+                                       write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_UL);
                                        priv->bis_cur_rdlstate = false;
                                }
                        }
@@ -2771,7 +2776,7 @@ static void dm_check_edca_turbo(
                                        (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
                                        (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
                                        ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-                       //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
+
                                write_nic_dword(dev, EDCAPARA_BE,  u4bAcParam);
 
                        // Check ACM bit.
@@ -2780,7 +2785,7 @@ static void dm_check_edca_turbo(
                        // TODO:  Modified this part and try to set acm control in only 1 IO processing!!
 
                                        PACI_AIFSN      pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
-                                       u8              AcmCtrl = read_nic_byte( dev, AcmHwCtrl );
+                                       u8              AcmCtrl = priv->AcmControl | 0x1;
                                        if( pAciAifsn->f.ACM )
                                        { // ACM bit is 1.
                                                AcmCtrl |= AcmHw_BeqEn;
@@ -2804,7 +2809,7 @@ dm_CheckEdcaTurbo_EXIT:
        priv->ieee80211->bis_any_nonbepkts = false;
        lastTxOkCnt = priv->stats.txbytesunicast;
        lastRxOkCnt = priv->stats.rxbytesunicast;
-}      // dm_CheckEdcaTurbo
+}
 #endif
 
 extern void DM_CTSToSelfSetting(struct net_device * dev,u32 DM_Type, u32 DM_Value)
index a7cc6f9a4739d4f9a6a78e819c5689aa1a020c44..2005b811ebab590e1f004ac680808d774383f407 100644 (file)
@@ -1,21 +1,23 @@
-/*
-   This file contains wireless extension handlers.
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192U
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 
-   This is part of rtl8180 OpenSource driver.
-   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-   Released under the terms of GPL (General Public Licence)
-
-   Parts of this driver are based on the GPL part
-   of the official realtek driver.
-
-   Parts of this driver are based on the rtl8180 driver skeleton
-   from Patric Schenke & Andres Salomon.
-
-   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
-   We want to tanks the Authors of those projects and the Ndiswrapper
-   project Authors.
-*/
 
 #include <linux/string.h>
 #include "r8192U.h"
@@ -248,6 +250,7 @@ static int r8192_wx_get_ap_status(struct net_device *dev,
         struct r8192_priv *priv = ieee80211_priv(dev);
         struct ieee80211_device *ieee = priv->ieee80211;
         struct ieee80211_network *target;
+       struct ieee80211_network *latest = NULL;
        int name_len;
 
         down(&priv->wx_sem);
@@ -259,13 +262,20 @@ static int r8192_wx_get_ap_status(struct net_device *dev,
         list_for_each_entry(target, &ieee->network_list, list) {
                 if ( (target->ssid_len == name_len) &&
                     (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
-                       if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
-                               //set flags=1 to indicate this ap is WPA
-                               wrqu->data.flags = 1;
-                       else wrqu->data.flags = 0;
+                       if ((latest == NULL) ||(target->last_scanned > latest->last_scanned))
+                               latest = target;
+
+               }
+        }
 
+        if(latest != NULL)
+        {
+               wrqu->data.length = latest->SignalStrength;
 
-               break;
+               if(latest->wpa_ie_len>0 || latest->rsn_ie_len>0 ) {
+                       wrqu->data.flags = 1;
+               } else {
+                       wrqu->data.flags = 0;
                 }
         }
 
@@ -460,14 +470,6 @@ static int rtl8180_wx_get_range(struct net_device *dev,
        range->we_version_compiled = WIRELESS_EXT;
        range->we_version_source = 16;
 
-//     range->retry_capa;      /* What retry options are supported */
-//     range->retry_flags;     /* How to decode max/min retry limit */
-//     range->r_time_flags;    /* How to decode max/min retry life */
-//     range->min_retry;       /* Minimal number of retries */
-//     range->max_retry;       /* Maximal number of retries */
-//     range->min_r_time;      /* Minimal retry lifetime */
-//     range->max_r_time;      /* Maximal retry lifetime */
-
 
        for (i = 0, val = 0; i < 14; i++) {
 
@@ -1011,6 +1013,70 @@ static int r8192_wx_set_mlme(struct net_device *dev,
        return ret;
 }
 
+static int r8192_wx_set_pmkid(struct net_device *dev,
+                                        struct iw_request_info *info,
+                                        union iwreq_data *wrqu, char *extra)
+{
+       int i;
+       struct r8192_priv *priv = ieee80211_priv(dev);
+       struct ieee80211_device* ieee = priv->ieee80211;
+       struct iw_pmksa*  pPMK = (struct iw_pmksa*)extra;
+       int     intReturn = false;
+
+       switch (pPMK->cmd)
+       {
+               case IW_PMKSA_ADD:
+                       for (i = 0; i < NUM_PMKID_CACHE; i++)
+                       {
+                               if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == 0)
+                               {
+                                       memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
+                                       memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
+                                       ieee->PMKIDList[i].bUsed = true;
+                                       intReturn = true;
+                                       goto __EXIT__;
+                               }
+                       }
+
+                       for (i = 0; i < NUM_PMKID_CACHE; i++)
+                       {
+                               if (ieee->PMKIDList[i].bUsed == false)
+                               {
+                                       memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
+                                       memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
+                                       ieee->PMKIDList[i].bUsed = true;
+                                       intReturn = true;
+                                       goto __EXIT__;
+                               }
+                       }
+                       break;
+
+               case IW_PMKSA_REMOVE:
+                       for (i = 0; i < NUM_PMKID_CACHE; i++)
+                       {
+                               if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == true)
+                               {
+                                       memset(&ieee->PMKIDList[i], 0x00, sizeof(RT_PMKID_LIST));
+                                       intReturn = true;
+                                       break;
+                               }
+               }
+                       break;
+
+               case IW_PMKSA_FLUSH:
+                       memset(&ieee->PMKIDList[0], 0x00, (sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE));
+            intReturn = true;
+                       break;
+
+               default:
+                       break;
+       }
+
+__EXIT__:
+       return (intReturn);
+
+}
+
 static int r8192_wx_set_gen_ie(struct net_device *dev,
                                         struct iw_request_info *info,
                                         union iwreq_data *data, char *extra)
@@ -1093,7 +1159,7 @@ static iw_handler r8192_wx_handlers[] =
        NULL,//r8192_wx_get_auth,//NULL,                        /* SIOCSIWAUTH */
        r8192_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
        NULL,//r8192_wx_get_enc_ext,//NULL,                     /* SIOCSIWENCODEEXT */
-       NULL,                   /* SIOCSIWPMKSA */
+       r8192_wx_set_pmkid, /* SIOCSIWPMKSA */
        NULL,                    /*---hole---*/
 
 };
index a8e9d2d96f5b8cd413bab96d4209e5b88a30b263..7ab9e22f8957df0cac610b50ffa75d7585c102be 100644 (file)
@@ -1,13 +1,22 @@
-/*
- * (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192U
  *
- * Module: r819xusb_cmdpkt.c
- * (RTL8190 TX/RX command packet handler Source C File)
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
  *
- * Note: The module is responsible for handling TX and RX command packet.
- * 1.TX: Send set and query configuration command packet.
- * 2.RX: Receive tx feedback, beacon state, query configuration, command packet.
- */
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
 #include "r8192U.h"
 #include "r819xU_cmdpkt.h"
 
@@ -19,19 +28,13 @@ bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen)
        cb_desc             *tcb_desc;
        unsigned char       *ptr_buf;
 
-       /* PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); */
-
        /*
         * Get TCB and local buffer from common pool.
         * (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
         */
        skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4);
-       if (skb == NULL) {
-               RT_TRACE(COMP_ERR, "(%s): unable to alloc skb buffer\n",
-                                                               __func__);
-               rtStatus = false;
-               return rtStatus;
-       }
+       if (!skb)
+               return false;
        memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
        tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
        tcb_desc->queue_index = TXCMD_QUEUE;
@@ -51,7 +54,6 @@ bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen)
                        priv->ieee80211->softmac_hard_start_xmit(skb, dev);
                }
 
-       //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
        return rtStatus;
 }
 
@@ -224,7 +226,6 @@ static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg)
        if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
                //2 maybe need endian transform?
                rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
-               //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4)));
 
                DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
 
@@ -491,6 +492,13 @@ cmpk_message_handle_rx(
                        cmpk_handle_tx_rate_history(dev, pcmd_buff);
                        cmd_length = CMPK_TX_RAHIS_SIZE;
                        break;
+               case RX_TX_TSSI_MEAN_BACK:
+                       {
+                               u32     *pMsg;
+                               pMsg = (u32 *)pcmd_buff;
+                       }
+                       cmd_length = 32;
+                       break;
                default:
                         RT_TRACE(COMP_ERR, "(%s): unknown CMD Element\n",
                                                                __func__);
index d3c56155188074edc89f56d13914fe677affee10..95885bee7a483a8221886a7ce1dade3770e86bb3 100644 (file)
@@ -173,6 +173,7 @@ typedef enum tag_command_packet_directories {
     RX_DBGINFO_FEEDBACK = 5,
     RX_TX_PER_PKT_FEEDBACK = 6,
     RX_TX_RATE_HISTORY = 7,
+    RX_TX_TSSI_MEAN_BACK = 8,
     RX_CMD_ELE_MAX
 } cmpk_element_e;
 
index 0439c90b416346efefc20ec58d2c260036a85b2a..28969198e7e2c22c5ad6c963cced4c69cfb1b23d 100644 (file)
@@ -3,5 +3,6 @@ config RTL8192U
        depends on PCI && WLAN && USB
        select WIRELESS_EXT
        select WEXT_PRIV
+       select CRYPTO
        default N
        ---help---
index 0851b9db17a68d2e08f1bb59d08aca0bff4b9580..d99cc030ec7a286ff930e3eba1701f80ba87333d 100644 (file)
@@ -2,7 +2,7 @@
 #define __INC_DOT11D_H
 
 #ifdef ENABLE_DOT11D
-#include "ieee80211.h"
+#include "ieee80211/ieee80211.h"
 
 
 typedef struct _CHNL_TXPOWER_TRIPLE {
diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h
deleted file mode 100644 (file)
index 9c72611..0000000
+++ /dev/null
@@ -1,2595 +0,0 @@
-/*
- * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andreamrl@tiscali.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h>   /* ARRAY_SIZE */
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-
-#include <linux/delay.h>
-#include <linux/wireless.h>
-
-#include "ieee80211/rtl819x_HT.h"
-#include "ieee80211/rtl819x_BA.h"
-#include "ieee80211/rtl819x_TS.h"
-
-
-#ifndef IW_MODE_MONITOR
-#define IW_MODE_MONITOR 6
-#endif
-
-#ifndef IWEVCUSTOM
-#define IWEVCUSTOM 0x8c02
-#endif
-
-
-#ifndef container_of
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr:        the pointer to the member.
- * @type:       the type of the container struct this is embedded in.
- * @member:     the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({                      \
-       const typeof(((type *)0)->member) (*__mptr = (ptr));    \
-       (type *)((char *)__mptr - offsetof(type, member)); })
-#endif
-
-#define KEY_TYPE_NA            0x0
-#define KEY_TYPE_WEP40         0x1
-#define KEY_TYPE_TKIP          0x2
-#define KEY_TYPE_CCMP          0x4
-#define KEY_TYPE_WEP104                0x5
-
-/* added for rtl819x tx procedure */
-#define MAX_QUEUE_SIZE         0x10
-
-/*
- * 8190 queue mapping
- */
-#define BK_QUEUE                               0
-#define BE_QUEUE                               1
-#define VI_QUEUE                               2
-#define VO_QUEUE                               3
-#define HCCA_QUEUE                             4
-#define TXCMD_QUEUE                            5
-#define MGNT_QUEUE                             6
-#define HIGH_QUEUE                             7
-#define BEACON_QUEUE                           8
-
-#define LOW_QUEUE                              BE_QUEUE
-#define NORMAL_QUEUE                           MGNT_QUEUE
-
-/* added by amy for ps */
-#define SWRF_TIMEOUT                           50
-
-/* added by amy for LEAP related */
-#define IE_CISCO_FLAG_POSITION         0x08    /* Flag byte: byte 8, numbered from 0. */
-#define SUPPORT_CKIP_MIC                       0x08    /* bit3 */
-#define SUPPORT_CKIP_PK                        0x10    /* bit4 */
-/* defined for skb cb field */
-/* At most 28 byte */
-typedef struct cb_desc {
-       /* Tx Desc Related flags (8-9) */
-       u8 bLastIniPkt:1;
-       u8 bCmdOrInit:1;
-       u8 bFirstSeg:1;
-       u8 bLastSeg:1;
-       u8 bEncrypt:1;
-       u8 bTxDisableRateFallBack:1;
-       u8 bTxUseDriverAssingedRate:1;
-       u8 bHwSec:1; /* indicate whether use Hw security. WB */
-
-       u8 reserved1;
-
-       /* Tx Firmware Relaged flags (10-11)*/
-       u8 bCTSEnable:1;
-       u8 bRTSEnable:1;
-       u8 bUseShortGI:1;
-       u8 bUseShortPreamble:1;
-       u8 bTxEnableFwCalcDur:1;
-       u8 bAMPDUEnable:1;
-       u8 bRTSSTBC:1;
-       u8 RTSSC:1;
-
-       u8 bRTSBW:1;
-       u8 bPacketBW:1;
-       u8 bRTSUseShortPreamble:1;
-       u8 bRTSUseShortGI:1;
-       u8 bMulticast:1;
-       u8 bBroadcast:1;
-       u8 drv_agg_enable:1;
-       u8 reserved2:1;
-
-       /* Tx Desc related element(12-19) */
-       u8 rata_index;
-       u8 queue_index;
-       u16 txbuf_size;
-       u8 RATRIndex;
-       u8 reserved6;
-       u8 reserved7;
-       u8 reserved8;
-
-       /* Tx firmware related element(20-27) */
-       u8 data_rate;
-       u8 rts_rate;
-       u8 ampdu_factor;
-       u8 ampdu_density;
-       u8 DrvAggrNum;
-       u16 pkt_size;
-       u8 reserved12;
-} cb_desc, *pcb_desc;
-
-/*--------------------------Define -------------------------------------------*/
-#define MGN_1M                  0x02
-#define MGN_2M                  0x04
-#define MGN_5_5M                0x0b
-#define MGN_11M                 0x16
-
-#define MGN_6M                  0x0c
-#define MGN_9M                  0x12
-#define MGN_12M                 0x18
-#define MGN_18M                 0x24
-#define MGN_24M                 0x30
-#define MGN_36M                 0x48
-#define MGN_48M                 0x60
-#define MGN_54M                 0x6c
-
-#define MGN_MCS0                0x80
-#define MGN_MCS1                0x81
-#define MGN_MCS2                0x82
-#define MGN_MCS3                0x83
-#define MGN_MCS4                0x84
-#define MGN_MCS5                0x85
-#define MGN_MCS6                0x86
-#define MGN_MCS7                0x87
-#define MGN_MCS8                0x88
-#define MGN_MCS9                0x89
-#define MGN_MCS10               0x8a
-#define MGN_MCS11               0x8b
-#define MGN_MCS12               0x8c
-#define MGN_MCS13               0x8d
-#define MGN_MCS14               0x8e
-#define MGN_MCS15               0x8f
-
-/*
- *             802.11 Management frame Reason Code field
- */
-enum   _ReasonCode{
-       unspec_reason   = 0x1,
-       auth_not_valid  = 0x2,
-       deauth_lv_ss    = 0x3,
-       inactivity              = 0x4,
-       ap_overload     = 0x5,
-       class2_err              = 0x6,
-       class3_err              = 0x7,
-       disas_lv_ss     = 0x8,
-       asoc_not_auth   = 0x9,
-
-       /* ----MIC_CHECK */
-       mic_failure     = 0xe,
-       /* ----END MIC_CHECK */
-
-       /* Reason code defined in 802.11i D10.0 p.28. */
-       invalid_IE              = 0x0d,
-       four_way_tmout  = 0x0f,
-       two_way_tmout   = 0x10,
-       IE_dismatch     = 0x11,
-       invalid_Gcipher = 0x12,
-       invalid_Pcipher = 0x13,
-       invalid_AKMP    = 0x14,
-       unsup_RSNIEver = 0x15,
-       invalid_RSNIE   = 0x16,
-       auth_802_1x_fail = 0x17,
-       ciper_reject            = 0x18,
-
-       /* Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. */
-       QoS_unspec              = 0x20, /* 32 */
-       QAP_bandwidth   = 0x21, /* 33 */
-       poor_condition  = 0x22, /* 34 */
-       no_facility     = 0x23, /* 35 */
-                                                       /* Where is 36??? */
-       req_declined    = 0x25, /* 37 */
-       invalid_param   = 0x26, /* 38 */
-       req_not_honored = 0x27, /* 39 */
-       TS_not_created  = 0x2F, /* 47 */
-       DL_not_allowed  = 0x30, /* 48 */
-       dest_not_exist  = 0x31, /* 49 */
-       dest_not_QSTA   = 0x32, /* 50 */
-};
-
-
-
-#define aSifsTime       ((priv->ieee80211->current_network.mode == IEEE_A) || \
-               (priv->ieee80211->current_network.mode == IEEE_N_24G) || \
-               (priv->ieee80211->current_network.mode == IEEE_N_5G)) ? 16 : 10
-
-#define MGMT_QUEUE_NUM 5
-
-#define IEEE_CMD_SET_WPA_PARAM                 1
-#define        IEEE_CMD_SET_WPA_IE                     2
-#define IEEE_CMD_SET_ENCRYPTION                        3
-#define IEEE_CMD_MLME                          4
-
-#define IEEE_PARAM_WPA_ENABLED                 1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES                2
-#define IEEE_PARAM_DROP_UNENCRYPTED            3
-#define IEEE_PARAM_PRIVACY_INVOKED             4
-#define IEEE_PARAM_AUTH_ALGS                   5
-#define IEEE_PARAM_IEEE_802_1X                 6
-/* It should consistent with the driver_XXX.c */
-#define IEEE_PARAM_WPAX_SELECT                 7
-/* Added for notify the encryption type selection */
-#define IEEE_PROTO_WPA                         1
-#define IEEE_PROTO_RSN                         2
-/* Added for notify the encryption type selection */
-#define IEEE_WPAX_USEGROUP                     0
-#define IEEE_WPAX_WEP40                                1
-#define IEEE_WPAX_TKIP                         2
-#define IEEE_WPAX_WRAP                         3
-#define IEEE_WPAX_CCMP                         4
-#define IEEE_WPAX_WEP104                       5
-
-#define IEEE_KEY_MGMT_IEEE8021X                        1
-#define IEEE_KEY_MGMT_PSK                      2
-
-#define IEEE_MLME_STA_DEAUTH                   1
-#define IEEE_MLME_STA_DISASSOC                 2
-
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG             2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR            3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED       4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED          5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED       6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED                7
-
-
-#define        IEEE_CRYPT_ALG_NAME_LEN                 16
-
-#define MAX_IE_LEN  0xff
-
-/* added for kernel conflict */
-#define ieee80211_crypt_deinit_entries         ieee80211_crypt_deinit_entries_rsl
-#define ieee80211_crypt_deinit_handler         ieee80211_crypt_deinit_handler_rsl
-#define ieee80211_crypt_delayed_deinit         ieee80211_crypt_delayed_deinit_rsl
-#define ieee80211_register_crypto_ops          ieee80211_register_crypto_ops_rsl
-#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
-#define ieee80211_get_crypto_ops       ieee80211_get_crypto_ops_rsl
-
-#define ieee80211_ccmp_null            ieee80211_ccmp_null_rsl
-
-#define ieee80211_tkip_null            ieee80211_tkip_null_rsl
-
-#define ieee80211_wep_null             ieee80211_wep_null_rsl
-
-#define free_ieee80211                 free_ieee80211_rsl
-#define alloc_ieee80211                        alloc_ieee80211_rsl
-
-#define ieee80211_rx                   ieee80211_rx_rsl
-#define ieee80211_rx_mgt               ieee80211_rx_mgt_rsl
-
-#define ieee80211_get_beacon           ieee80211_get_beacon_rsl
-#define ieee80211_wake_queue           ieee80211_wake_queue_rsl
-#define ieee80211_stop_queue           ieee80211_stop_queue_rsl
-#define ieee80211_reset_queue          ieee80211_reset_queue_rsl
-#define ieee80211_softmac_stop_protocol        ieee80211_softmac_stop_protocol_rsl
-#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
-#define ieee80211_is_shortslot         ieee80211_is_shortslot_rsl
-#define ieee80211_is_54g               ieee80211_is_54g_rsl
-#define ieee80211_wpa_supplicant_ioctl ieee80211_wpa_supplicant_ioctl_rsl
-#define ieee80211_ps_tx_ack            ieee80211_ps_tx_ack_rsl
-#define ieee80211_softmac_xmit         ieee80211_softmac_xmit_rsl
-#define ieee80211_stop_send_beacons    ieee80211_stop_send_beacons_rsl
-#define notify_wx_assoc_event          notify_wx_assoc_event_rsl
-#define SendDisassociation             SendDisassociation_rsl
-#define ieee80211_disassociate         ieee80211_disassociate_rsl
-#define ieee80211_start_send_beacons   ieee80211_start_send_beacons_rsl
-#define ieee80211_stop_scan            ieee80211_stop_scan_rsl
-#define ieee80211_send_probe_requests  ieee80211_send_probe_requests_rsl
-#define ieee80211_softmac_scan_syncro  ieee80211_softmac_scan_syncro_rsl
-#define ieee80211_start_scan_syncro    ieee80211_start_scan_syncro_rsl
-
-#define ieee80211_wx_get_essid         ieee80211_wx_get_essid_rsl
-#define ieee80211_wx_set_essid         ieee80211_wx_set_essid_rsl
-#define ieee80211_wx_set_rate          ieee80211_wx_set_rate_rsl
-#define ieee80211_wx_get_rate          ieee80211_wx_get_rate_rsl
-#define ieee80211_wx_set_wap           ieee80211_wx_set_wap_rsl
-#define ieee80211_wx_get_wap           ieee80211_wx_get_wap_rsl
-#define ieee80211_wx_set_mode          ieee80211_wx_set_mode_rsl
-#define ieee80211_wx_get_mode          ieee80211_wx_get_mode_rsl
-#define ieee80211_wx_set_scan          ieee80211_wx_set_scan_rsl
-#define ieee80211_wx_get_freq          ieee80211_wx_get_freq_rsl
-#define ieee80211_wx_set_freq          ieee80211_wx_set_freq_rsl
-#define ieee80211_wx_set_rawtx         ieee80211_wx_set_rawtx_rsl
-#define ieee80211_wx_get_name          ieee80211_wx_get_name_rsl
-#define ieee80211_wx_set_power         ieee80211_wx_set_power_rsl
-#define ieee80211_wx_get_power         ieee80211_wx_get_power_rsl
-#define ieee80211_wlan_frequencies     ieee80211_wlan_frequencies_rsl
-#define ieee80211_wx_set_rts           ieee80211_wx_set_rts_rsl
-#define ieee80211_wx_get_rts           ieee80211_wx_get_rts_rsl
-
-#define ieee80211_txb_free             ieee80211_txb_free_rsl
-
-#define ieee80211_wx_set_gen_ie                ieee80211_wx_set_gen_ie_rsl
-#define ieee80211_wx_get_scan          ieee80211_wx_get_scan_rsl
-#define ieee80211_wx_set_encode                ieee80211_wx_set_encode_rsl
-#define ieee80211_wx_get_encode                ieee80211_wx_get_encode_rsl
-#if WIRELESS_EXT >= 18
-#define ieee80211_wx_set_mlme          ieee80211_wx_set_mlme_rsl
-#define ieee80211_wx_set_auth          ieee80211_wx_set_auth_rsl
-#define ieee80211_wx_set_encode_ext    ieee80211_wx_set_encode_ext_rsl
-#define ieee80211_wx_get_encode_ext    ieee80211_wx_get_encode_ext_rsl
-#endif
-
-
-typedef struct ieee_param {
-       u32 cmd;
-       u8 sta_addr[ETH_ALEN];
-       union {
-               struct {
-                       u8 name;
-                       u32 value;
-               } wpa_param;
-               struct {
-                       u32 len;
-                       u8 reserved[32];
-                       u8 data[0];
-               } wpa_ie;
-               struct{
-                       int command;
-                       int reason_code;
-               } mlme;
-               struct {
-                       u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
-                       u8 set_tx;
-                       u32 err;
-                       u8 idx;
-                       u8 seq[8]; /* sequence counter (set: RX, get: TX) */
-                       u16 key_len;
-                       u8 key[0];
-               } crypt;
-       } u;
-} ieee_param;
-
-
-#if WIRELESS_EXT < 17
-#define IW_QUAL_QUAL_INVALID   0x10
-#define IW_QUAL_LEVEL_INVALID  0x20
-#define IW_QUAL_NOISE_INVALID  0x40
-#define IW_QUAL_QUAL_UPDATED   0x1
-#define IW_QUAL_LEVEL_UPDATED  0x2
-#define IW_QUAL_NOISE_UPDATED  0x4
-#endif
-
-
-/* linux under 2.6.9 release may not support it, so modify it for common use */
-#define MSECS(t) msecs_to_jiffies(t)
-#define msleep_interruptible_rsl  msleep_interruptible
-
-#define IEEE80211_DATA_LEN             2304
-/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
-   6.2.1.1.2.
-
-   The figure in section 7.1.2 suggests a body size of up to 2312
-   bytes is allowed, which is a bit confusing, I suspect this
-   represents the 2304 bytes of real data, plus a possible 8 bytes of
-   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-#define IEEE80211_1ADDR_LEN 10
-#define IEEE80211_2ADDR_LEN 16
-#define IEEE80211_3ADDR_LEN 24
-#define IEEE80211_4ADDR_LEN 30
-#define IEEE80211_FCS_LEN    4
-#define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
-#define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-#define MIN_FRAG_THRESHOLD     256U
-#define MAX_FRAG_THRESHOLD     2346U
-
-
-/* Frame control field constants */
-#define IEEE80211_FCTL_VERS            0x0003
-#define IEEE80211_FCTL_FTYPE           0x000c
-#define IEEE80211_FCTL_STYPE           0x00f0
-#define IEEE80211_FCTL_FRAMETYPE       0x00fc
-#define IEEE80211_FCTL_TODS            0x0100
-#define IEEE80211_FCTL_FROMDS          0x0200
-#define IEEE80211_FCTL_DSTODS          0x0300
-#define IEEE80211_FCTL_MOREFRAGS       0x0400
-#define IEEE80211_FCTL_RETRY           0x0800
-#define IEEE80211_FCTL_PM              0x1000
-#define IEEE80211_FCTL_MOREDATA                0x2000
-#define IEEE80211_FCTL_WEP             0x4000
-#define IEEE80211_FCTL_ORDER           0x8000
-
-#define IEEE80211_FTYPE_MGMT           0x0000
-#define IEEE80211_FTYPE_CTL            0x0004
-#define IEEE80211_FTYPE_DATA           0x0008
-
-/* management */
-#define IEEE80211_STYPE_ASSOC_REQ      0x0000
-#define IEEE80211_STYPE_ASSOC_RESP     0x0010
-#define IEEE80211_STYPE_REASSOC_REQ    0x0020
-#define IEEE80211_STYPE_REASSOC_RESP   0x0030
-#define IEEE80211_STYPE_PROBE_REQ      0x0040
-#define IEEE80211_STYPE_PROBE_RESP     0x0050
-#define IEEE80211_STYPE_BEACON         0x0080
-#define IEEE80211_STYPE_ATIM           0x0090
-#define IEEE80211_STYPE_DISASSOC       0x00A0
-#define IEEE80211_STYPE_AUTH           0x00B0
-#define IEEE80211_STYPE_DEAUTH         0x00C0
-#define IEEE80211_STYPE_MANAGE_ACT     0x00D0
-
-/* control */
-#define IEEE80211_STYPE_PSPOLL         0x00A0
-#define IEEE80211_STYPE_RTS            0x00B0
-#define IEEE80211_STYPE_CTS            0x00C0
-#define IEEE80211_STYPE_ACK            0x00D0
-#define IEEE80211_STYPE_CFEND          0x00E0
-#define IEEE80211_STYPE_CFENDACK       0x00F0
-#define IEEE80211_STYPE_BLOCKACK   0x0094
-
-/* data */
-#define IEEE80211_STYPE_DATA           0x0000
-#define IEEE80211_STYPE_DATA_CFACK     0x0010
-#define IEEE80211_STYPE_DATA_CFPOLL    0x0020
-#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
-#define IEEE80211_STYPE_NULLFUNC       0x0040
-#define IEEE80211_STYPE_CFACK          0x0050
-#define IEEE80211_STYPE_CFPOLL         0x0060
-#define IEEE80211_STYPE_CFACKPOLL      0x0070
-#define IEEE80211_STYPE_QOS_DATA       0x0080
-#define IEEE80211_STYPE_QOS_NULL       0x00C0
-
-#define IEEE80211_SCTL_FRAG            0x000F
-#define IEEE80211_SCTL_SEQ             0xFFF0
-
-/* QOS control */
-#define IEEE80211_QCTL_TID              0x000F
-
-#define        FC_QOS_BIT                                      BIT7
-#define IsDataFrame(pdu)                       (((pdu[0] & 0x0C) == 0x08) ? true : false)
-#define        IsLegacyDataFrame(pdu)  (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)))
-
-#define IsQoSDataFrame(pframe)  ((*(u16 *)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
-#define Frame_Order(pframe)     (*(u16 *)pframe&IEEE80211_FCTL_ORDER)
-#define SN_LESS(a, b)          (((a-b)&0x800) != 0)
-#define SN_EQUAL(a, b) (a == b)
-#define MAX_DEV_ADDR_SIZE 8
-typedef enum _ACT_CATEGORY{
-       ACT_CAT_QOS = 1,
-       ACT_CAT_DLS = 2,
-       ACT_CAT_BA  = 3,
-       ACT_CAT_HT  = 7,
-       ACT_CAT_WMM = 17,
-} ACT_CATEGORY, *PACT_CATEGORY;
-
-typedef enum _TS_ACTION{
-       ACT_ADDTSREQ = 0,
-       ACT_ADDTSRSP = 1,
-       ACT_DELTS    = 2,
-       ACT_SCHEDULE = 3,
-} TS_ACTION, *PTS_ACTION;
-
-typedef enum _BA_ACTION{
-       ACT_ADDBAREQ = 0,
-       ACT_ADDBARSP = 1,
-       ACT_DELBA    = 2,
-} BA_ACTION, *PBA_ACTION;
-
-typedef enum _InitialGainOpType{
-       IG_Backup = 0,
-       IG_Restore,
-       IG_Max
-} InitialGainOpType;
-
-/* debug macros */
-#define CONFIG_IEEE80211_DEBUG
-#ifdef CONFIG_IEEE80211_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
-  printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0)
-/* wb added to debug out data buf
- * if you want print DATA buffer related BA, please set ieee80211_debug_level
- * to DATA|BA
- */
-#define IEEE80211_DEBUG_DATA(level, data, datalen)     \
-       do { if ((ieee80211_debug_level & (level)) == (level)) {        \
-                       int i;                                  \
-                       u8* pdata = (u8 *) data;                        \
-                       printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);   \
-                       for (i = 0; i < (int)(datalen); i++) {          \
-                               printk("%2x ", pdata[i]);               \
-                               if ((i+1)%16 == 0) \
-                                       printk("\n");   \
-                       }       \
-                       printk("\n");                   \
-               }                                       \
-       } while (0)
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while (0)
-#endif /* CONFIG_IEEE80211_DEBUG */
-
-/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IEEE80211_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/ipw/debug_level
- *
- * you simply need to add your entry to the ipw_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
- *
- */
-
-#define IEEE80211_DL_INFO          (1<<0)
-#define IEEE80211_DL_WX            (1<<1)
-#define IEEE80211_DL_SCAN          (1<<2)
-#define IEEE80211_DL_STATE         (1<<3)
-#define IEEE80211_DL_MGMT          (1<<4)
-#define IEEE80211_DL_FRAG          (1<<5)
-#define IEEE80211_DL_EAP           (1<<6)
-#define IEEE80211_DL_DROP          (1<<7)
-
-#define IEEE80211_DL_TX            (1<<8)
-#define IEEE80211_DL_RX            (1<<9)
-
-#define IEEE80211_DL_HT                   (1<<10)  /* HT */
-#define IEEE80211_DL_BA                   (1<<11)  /* ba */
-#define IEEE80211_DL_TS                   (1<<12)  /* TS */
-#define IEEE80211_DL_QOS           (1<<13)
-#define IEEE80211_DL_REORDER      (1<<14)
-#define IEEE80211_DL_IOT          (1<<15)
-#define IEEE80211_DL_IPS          (1<<16)
-#define IEEE80211_DL_TRACE        (1<<29)  /* trace function, need to user net_ratelimit() together in order not to print too much to the screen */
-#define IEEE80211_DL_DATA         (1<<30)   /* use this flag to control whether print data buf out. */
-#define IEEE80211_DL_ERR          (1<<31)   /* always open */
-#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
-#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
-#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
-
-#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
-#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
-#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
-#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
-#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
-#define IEEE80211_DEBUG_EAP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
-#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
-#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
-#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
-#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
-
-#ifdef CONFIG_IEEE80211_DEBUG
-/* Added by Annie, 2005-11-22. */
-#define MAX_STR_LEN     64
-/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
-#define PRINTABLE(_ch)  (_ch > '!' && _ch < '~')
-#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                                   \
-                       if ((_Comp) & level) {                                                                       \
-                               int             __i;                                            \
-                               u8  buffer[MAX_STR_LEN];                                        \
-                               int length = (_Len < MAX_STR_LEN) ? _Len : (MAX_STR_LEN - 1);   \
-                               memset(buffer, 0, MAX_STR_LEN);                                 \
-                               memcpy(buffer, (u8 *)_Ptr, length);                     \
-                               for (__i = 0; __i < MAX_STR_LEN; __i++) {                                                               \
-                                    if (!PRINTABLE(buffer[__i]))   \
-                                               buffer[__i] = '?';      \
-                               }                                                               \
-                               buffer[length] = '\0';                                          \
-                               printk("Rtl819x: ");                                            \
-                               printk(_TitleString);                                         \
-                               printk(": %d, <%s>\n", _Len, buffer);                         \
-                       }
-#else
-#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
-#endif
-
-#include <linux/netdevice.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY           /* enable iwspy support */
-#endif
-#include <net/iw_handler.h>    /* new driver API */
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
-
-       u8    dsap;   /* always 0xAA */
-       u8    ssap;   /* always 0xAA */
-       u8    ctrl;   /* always 0x03 */
-       u8    oui[P80211_OUI_LEN];    /* organizational universal id */
-
-} __attribute__ ((packed));
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
-#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
-
-#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_LEAP 2
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_IBSS (1<<1)
-#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
-#define WLAN_CAPABILITY_PRIVACY (1<<4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
-#define WLAN_CAPABILITY_PBCC (1<<6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
-#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
-#define WLAN_CAPABILITY_QOS (1<<9)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
-
-/* 802.11g ERP information element */
-#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
-#define WLAN_ERP_USE_PROTECTION (1<<1)
-#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
-
-/* Status codes */
-enum ieee80211_statuscode {
-       WLAN_STATUS_SUCCESS = 0,
-       WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
-       WLAN_STATUS_CAPS_UNSUPPORTED = 10,
-       WLAN_STATUS_REASSOC_NO_ASSOC = 11,
-       WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
-       WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
-       WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
-       WLAN_STATUS_CHALLENGE_FAIL = 15,
-       WLAN_STATUS_AUTH_TIMEOUT = 16,
-       WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
-       WLAN_STATUS_ASSOC_DENIED_RATES = 18,
-       /* 802.11b */
-       WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
-       WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
-       WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
-       /* 802.11h */
-       WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
-       WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
-       WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
-       /* 802.11g */
-       WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
-       WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
-       /* 802.11i */
-       WLAN_STATUS_INVALID_IE = 40,
-       WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
-       WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
-       WLAN_STATUS_INVALID_AKMP = 43,
-       WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
-       WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
-       WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
-};
-
-/* Reason codes */
-enum ieee80211_reasoncode {
-       WLAN_REASON_UNSPECIFIED = 1,
-       WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
-       WLAN_REASON_DEAUTH_LEAVING = 3,
-       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
-       WLAN_REASON_DISASSOC_AP_BUSY = 5,
-       WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
-       WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
-       WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
-       WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
-       /* 802.11h */
-       WLAN_REASON_DISASSOC_BAD_POWER = 10,
-       WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
-       /* 802.11i */
-       WLAN_REASON_INVALID_IE = 13,
-       WLAN_REASON_MIC_FAILURE = 14,
-       WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
-       WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
-       WLAN_REASON_IE_DIFFERENT = 17,
-       WLAN_REASON_INVALID_GROUP_CIPHER = 18,
-       WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
-       WLAN_REASON_INVALID_AKMP = 20,
-       WLAN_REASON_UNSUPP_RSN_VERSION = 21,
-       WLAN_REASON_INVALID_RSN_IE_CAP = 22,
-       WLAN_REASON_IEEE8021X_FAILED = 23,
-       WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
-};
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-#define IEEE80211_CCK_MODULATION    (1<<0)
-#define IEEE80211_OFDM_MODULATION   (1<<1)
-
-#define IEEE80211_24GHZ_BAND     (1<<0)
-#define IEEE80211_52GHZ_BAND     (1<<1)
-
-#define IEEE80211_CCK_RATE_LEN                 4
-#define IEEE80211_CCK_RATE_1MB                 0x02
-#define IEEE80211_CCK_RATE_2MB                 0x04
-#define IEEE80211_CCK_RATE_5MB                 0x0B
-#define IEEE80211_CCK_RATE_11MB                        0x16
-#define IEEE80211_OFDM_RATE_LEN                8
-#define IEEE80211_OFDM_RATE_6MB                        0x0C
-#define IEEE80211_OFDM_RATE_9MB                        0x12
-#define IEEE80211_OFDM_RATE_12MB               0x18
-#define IEEE80211_OFDM_RATE_18MB               0x24
-#define IEEE80211_OFDM_RATE_24MB               0x30
-#define IEEE80211_OFDM_RATE_36MB               0x48
-#define IEEE80211_OFDM_RATE_48MB               0x60
-#define IEEE80211_OFDM_RATE_54MB               0x6C
-#define IEEE80211_BASIC_RATE_MASK              0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK            (1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK            (1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK            (1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK           (1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK           (1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK           (1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK          (1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK          (1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK          (1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK          (1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK          (1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK          (1<<11)
-
-#define IEEE80211_CCK_RATES_MASK               0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
-       IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK       (IEEE80211_CCK_BASIC_RATES_MASK | \
-       IEEE80211_CCK_RATE_5MB_MASK | \
-       IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK              0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK        (IEEE80211_OFDM_RATE_6MB_MASK | \
-       IEEE80211_OFDM_RATE_12MB_MASK | \
-       IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK      (IEEE80211_OFDM_BASIC_RATES_MASK | \
-       IEEE80211_OFDM_RATE_9MB_MASK  | \
-       IEEE80211_OFDM_RATE_18MB_MASK | \
-       IEEE80211_OFDM_RATE_36MB_MASK | \
-       IEEE80211_OFDM_RATE_48MB_MASK | \
-       IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
-                               IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES           8
-#define IEEE80211_NUM_CCK_RATES                    4
-#define IEEE80211_OFDM_SHIFT_MASK_A         4
-
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK                0x0c
-#define IEEE80211_FC0_TYPE_DATA                0x08
-#define IEEE80211_FC0_SUBTYPE_MASK     0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS      0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
-       (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
-        (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
-       u8 mac[ETH_ALEN];
-       u16 seq_num[17];
-       u16 frag_num[17];
-       unsigned long packet_time[17];
-       struct list_head list;
-};
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- *       information for frames received.  Not setting these will not cause
- *       any adverse affects. */
-struct ieee80211_rx_stats {
-       u32 mac_time[2];
-       s8 rssi;
-       u8 signal;
-       u8 noise;
-       u16 rate; /* in 100 kbps */
-       u8 received_channel;
-       u8 control;
-       u8 mask;
-       u8 freq;
-       u16 len;
-       u64 tsf;
-       u32 beacon_time;
-       u8 nic_type;
-       u16       Length;
-       u8        SignalQuality; /* in 0-100 index. */
-       s32       RecvSignalPower; /* Real power in dBm for this packet, no beautification and aggregation. */
-       s8        RxPower; /* in dBm Translate from PWdB */
-       u8        SignalStrength; /* in 0-100 index. */
-       u16       bHwError:1;
-       u16       bCRC:1;
-       u16       bICV:1;
-       u16       bShortPreamble:1;
-       u16       Antenna:1;      /* for rtl8185 */
-       u16       Decrypted:1;    /* for rtl8185, rtl8187 */
-       u16       Wakeup:1;       /* for rtl8185 */
-       u16       Reserved0:1;    /* for rtl8185 */
-       u8        AGC;
-       u32       TimeStampLow;
-       u32       TimeStampHigh;
-       bool      bShift;
-       bool      bIsQosData;
-       u8        UserPriority;
-
-       /*
-        * 1Attention Please!!!<11n or 8190 specific code should be put below this line>
-        */
-
-       u8        RxDrvInfoSize;
-       u8        RxBufShift;
-       bool      bIsAMPDU;
-       bool      bFirstMPDU;
-       bool      bContainHTC;
-       bool      RxIs40MHzPacket;
-       u32       RxPWDBAll;
-       u8        RxMIMOSignalStrength[4];        /* in 0~100 index */
-       s8        RxMIMOSignalQuality[2];
-       bool      bPacketMatchBSSID;
-       bool      bIsCCK;
-       bool      bPacketToSelf;
-       u8      *virtual_address;
-       u16          packetlength;              /* Total packet length: Must equal to sum of all FragLength */
-       u16          fraglength;                        /* FragLength should equal to PacketLength in non-fragment case */
-       u16          fragoffset;                        /* Data offset for this fragment */
-       u16          ntotalfrag;
-       bool              bisrxaggrsubframe;
-       bool              bPacketBeacon;        /* cosa add for rssi */
-       bool              bToSelfBA;            /* cosa add for rssi */
-       char      cck_adc_pwdb[4];      /* cosa add for rx path selection */
-       u16               Seq_Num;
-
-};
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
-#define IEEE80211_FRAG_CACHE_LEN 4
-
-struct ieee80211_frag_entry {
-       unsigned long first_frag_time;
-       unsigned int seq;
-       unsigned int last_frag;
-       struct sk_buff *skb;
-       u8 src_addr[ETH_ALEN];
-       u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
-       unsigned int tx_unicast_frames;
-       unsigned int tx_multicast_frames;
-       unsigned int tx_fragments;
-       unsigned int tx_unicast_octets;
-       unsigned int tx_multicast_octets;
-       unsigned int tx_deferred_transmissions;
-       unsigned int tx_single_retry_frames;
-       unsigned int tx_multiple_retry_frames;
-       unsigned int tx_retry_limit_exceeded;
-       unsigned int tx_discards;
-       unsigned int rx_unicast_frames;
-       unsigned int rx_multicast_frames;
-       unsigned int rx_fragments;
-       unsigned int rx_unicast_octets;
-       unsigned int rx_multicast_octets;
-       unsigned int rx_fcs_errors;
-       unsigned int rx_discards_no_buffer;
-       unsigned int tx_discards_wrong_sa;
-       unsigned int rx_discards_undecryptable;
-       unsigned int rx_message_in_msg_fragments;
-       unsigned int rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_device;
-
-#include "ieee80211_crypt.h"
-
-#define SEC_KEY_1         (1<<0)
-#define SEC_KEY_2         (1<<1)
-#define SEC_KEY_3         (1<<2)
-#define SEC_KEY_4         (1<<3)
-#define SEC_ACTIVE_KEY    (1<<4)
-#define SEC_AUTH_MODE     (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL         (1<<7)
-#define SEC_ENABLED       (1<<8)
-#define SEC_ENCRYPT       (1<<9)
-
-#define SEC_LEVEL_0      0 /* None */
-#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
-
-#define SEC_ALG_NONE            0
-#define SEC_ALG_WEP             1
-#define SEC_ALG_TKIP            2
-#define SEC_ALG_CCMP            3
-
-#define WEP_KEYS               4
-#define WEP_KEY_LEN            13
-#define SCM_KEY_LEN             32
-#define SCM_TEMPORAL_KEY_LENGTH 16
-
-struct ieee80211_security {
-       u16 active_key:2,
-           enabled:1,
-           auth_mode:2,
-           auth_algo:4,
-           unicast_uses_group:1,
-           encrypt:1;
-       u8 key_sizes[WEP_KEYS];
-       u8 keys[WEP_KEYS][SCM_KEY_LEN];
-       u8 level;
-       u16 flags;
-} __attribute__ ((packed));
-
-
-/*
- 802.11 data frame from AP
-      ,-------------------------------------------------------------------.
-Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
-      |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
-      |      | tion | (BSSID) |         |         | ence |  data   |      |
-      `-------------------------------------------------------------------'
-Total: 28-2340 bytes
-*/
-
-/* Management Frame Information Element Types */
-enum ieee80211_mfie {
-       MFIE_TYPE_SSID = 0,
-       MFIE_TYPE_RATES = 1,
-       MFIE_TYPE_FH_SET = 2,
-       MFIE_TYPE_DS_SET = 3,
-       MFIE_TYPE_CF_SET = 4,
-       MFIE_TYPE_TIM = 5,
-       MFIE_TYPE_IBSS_SET = 6,
-       MFIE_TYPE_COUNTRY = 7,
-       MFIE_TYPE_HOP_PARAMS = 8,
-       MFIE_TYPE_HOP_TABLE = 9,
-       MFIE_TYPE_REQUEST = 10,
-       MFIE_TYPE_CHALLENGE = 16,
-       MFIE_TYPE_POWER_CONSTRAINT = 32,
-       MFIE_TYPE_POWER_CAPABILITY = 33,
-       MFIE_TYPE_TPC_REQUEST = 34,
-       MFIE_TYPE_TPC_REPORT = 35,
-       MFIE_TYPE_SUPP_CHANNELS = 36,
-       MFIE_TYPE_CSA = 37,
-       MFIE_TYPE_MEASURE_REQUEST = 38,
-       MFIE_TYPE_MEASURE_REPORT = 39,
-       MFIE_TYPE_QUIET = 40,
-       MFIE_TYPE_IBSS_DFS = 41,
-       MFIE_TYPE_ERP = 42,
-       MFIE_TYPE_RSN = 48,
-       MFIE_TYPE_RATES_EX = 50,
-       MFIE_TYPE_HT_CAP = 45,
-       MFIE_TYPE_HT_INFO = 61,
-       MFIE_TYPE_AIRONET = 133,
-       MFIE_TYPE_GENERIC = 221,
-       MFIE_TYPE_QOS_PARAMETER = 222,
-};
-
-/* Minimal header; can be used for passing 802.11 frames with sufficient
- * information to determine what type of underlying data type is actually
- * stored in the data. */
-struct ieee80211_hdr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_1addr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_2addr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-       u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_4addr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-       u8 addr4[ETH_ALEN];
-       u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addrqos {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-       u8 payload[0];
-       __le16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_4addrqos {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-       u8 addr4[ETH_ALEN];
-       u8 payload[0];
-       __le16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
-       u8 id;
-       u8 len;
-       u8 data[0];
-} __attribute__ ((packed));
-
-struct ieee80211_authentication {
-       struct ieee80211_hdr_3addr header;
-       __le16 algorithm;
-       __le16 transaction;
-       __le16 status;
-       /*challenge*/
-       struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc {
-       struct ieee80211_hdr_3addr header;
-       __le16 reason;
-} __attribute__ ((packed));
-
-struct ieee80211_probe_request {
-       struct ieee80211_hdr_3addr header;
-       /* SSID, supported rates */
-       struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_probe_response {
-       struct ieee80211_hdr_3addr header;
-       u32 time_stamp[2];
-       __le16 beacon_interval;
-       __le16 capability;
-       /* SSID, supported rates, FH params, DS params,
-        * CF params, IBSS params, TIM (if beacon), RSN */
-       struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-/* Alias beacon for probe_response */
-#define ieee80211_beacon ieee80211_probe_response
-
-struct ieee80211_assoc_request_frame {
-       struct ieee80211_hdr_3addr header;
-       __le16 capability;
-       __le16 listen_interval;
-       /* SSID, supported rates, RSN */
-       struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_reassoc_request_frame {
-       struct ieee80211_hdr_3addr header;
-       __le16 capability;
-       __le16 listen_interval;
-       u8 current_ap[ETH_ALEN];
-       /* SSID, supported rates, RSN */
-       struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_response_frame {
-       struct ieee80211_hdr_3addr header;
-       __le16 capability;
-       __le16 status;
-       __le16 aid;
-       struct ieee80211_info_element info_element[0]; /* supported rates */
-} __attribute__ ((packed));
-
-struct ieee80211_txb {
-       u8 nr_frags;
-       u8 encrypted;
-       u8 queue_index;
-       u8 rts_included;
-       u16 reserved;
-       __le16 frag_size;
-       __le16 payload_size;
-       struct sk_buff *fragments[0];
-};
-
-#define MAX_TX_AGG_COUNT                 16
-struct ieee80211_drv_agg_txb {
-       u8 nr_drv_agg_frames;
-       struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
-} __attribute__((packed));
-
-#define MAX_SUBFRAME_COUNT               64
-struct ieee80211_rxb {
-       u8 nr_subframes;
-       struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
-       u8 dst[ETH_ALEN];
-       u8 src[ETH_ALEN];
-} __attribute__((packed));
-
-typedef union _frameqos {
-       u16 shortdata;
-       u8  chardata[2];
-       struct {
-               u16 tid:4;
-               u16 eosp:1;
-               u16 ack_policy:2;
-               u16 reserved:1;
-               u16 txop:8;
-       } field;
-} frameqos, *pframeqos;
-
-/* SWEEP TABLE ENTRIES NUMBER*/
-#define MAX_SWEEP_TAB_ENTRIES            42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
-/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates.  Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH                  ((u8)12)
-#define MAX_RATES_EX_LENGTH               ((u8)16)
-#define MAX_NETWORK_COUNT                  128
-
-#define MAX_CHANNEL_NUMBER                 161
-#define IEEE80211_SOFTMAC_SCAN_TIME       100
-/* (HZ / 2) */
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH                 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM    (1<<1)
-#define NETWORK_HAS_CCK     (1<<2)
-
-/* QoS structure */
-#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
-#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
-#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
-                                        NETWORK_HAS_QOS_INFORMATION)
-/* 802.11h */
-#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
-#define NETWORK_HAS_CSA                 (1<<6)
-#define NETWORK_HAS_QUIET               (1<<7)
-#define NETWORK_HAS_IBSS_DFS            (1<<8)
-#define NETWORK_HAS_TPC_REPORT          (1<<9)
-
-#define NETWORK_HAS_ERP_VALUE           (1<<10)
-
-#define QOS_QUEUE_NUM                   4
-#define QOS_OUI_LEN                     3
-#define QOS_OUI_TYPE                    2
-#define QOS_ELEMENT_ID                  221
-#define QOS_OUI_INFO_SUB_TYPE           0
-#define QOS_OUI_PARAM_SUB_TYPE          1
-#define QOS_VERSION_1                   1
-#define QOS_AIFSN_MIN_VALUE             2
-struct ieee80211_qos_information_element {
-       u8 elementID;
-       u8 length;
-       u8 qui[QOS_OUI_LEN];
-       u8 qui_type;
-       u8 qui_subtype;
-       u8 version;
-       u8 ac_info;
-} __attribute__ ((packed));
-
-struct ieee80211_qos_ac_parameter {
-       u8 aci_aifsn;
-       u8 ecw_min_max;
-       __le16 tx_op_limit;
-} __attribute__ ((packed));
-
-struct ieee80211_qos_parameter_info {
-       struct ieee80211_qos_information_element info_element;
-       u8 reserved;
-       struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
-} __attribute__ ((packed));
-
-struct ieee80211_qos_parameters {
-       __le16 cw_min[QOS_QUEUE_NUM];
-       __le16 cw_max[QOS_QUEUE_NUM];
-       u8 aifs[QOS_QUEUE_NUM];
-       u8 flag[QOS_QUEUE_NUM];
-       __le16 tx_op_limit[QOS_QUEUE_NUM];
-} __attribute__ ((packed));
-
-struct ieee80211_qos_data {
-       struct ieee80211_qos_parameters parameters;
-       int active;
-       int supported;
-       u8 param_count;
-       u8 old_param_count;
-};
-
-struct ieee80211_tim_parameters {
-       u8 tim_count;
-       u8 tim_period;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_ac_param {
-       u8 ac_aci_acm_aifsn;
-       u8 ac_ecwmin_ecwmax;
-       u16 ac_txop_limit;
-};
-
-struct ieee80211_wmm_ts_info {
-       u8 ac_dir_tid;
-       u8 ac_up_psb;
-       u8 reserved;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_tspec_elem {
-       struct ieee80211_wmm_ts_info ts_info;
-       u16 norm_msdu_size;
-       u16 max_msdu_size;
-       u32 min_serv_inter;
-       u32 max_serv_inter;
-       u32 inact_inter;
-       u32 suspen_inter;
-       u32 serv_start_time;
-       u32 min_data_rate;
-       u32 mean_data_rate;
-       u32 peak_data_rate;
-       u32 max_burst_size;
-       u32 delay_bound;
-       u32 min_phy_rate;
-       u16 surp_band_allow;
-       u16 medium_time;
-} __attribute__((packed));
-enum eap_type {
-       EAP_PACKET = 0,
-       EAPOL_START,
-       EAPOL_LOGOFF,
-       EAPOL_KEY,
-       EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
-       [EAP_PACKET]            = "EAP-Packet",
-       [EAPOL_START]           = "EAPOL-Start",
-       [EAPOL_LOGOFF]          = "EAPOL-Logoff",
-       [EAPOL_KEY]             = "EAPOL-Key",
-       [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
-       return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-static inline u8 Frame_QoSTID(u8 *buf)
-{
-       struct ieee80211_hdr_3addr *hdr;
-       u16 fc;
-       hdr = (struct ieee80211_hdr_3addr *)buf;
-       fc = le16_to_cpu(hdr->frame_ctl);
-       return (u8)((frameqos *)(buf + (((fc & IEEE80211_FCTL_TODS) && (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid;
-}
-
-
-struct eapol {
-       u8 snap[6];
-       u16 ethertype;
-       u8 version;
-       u8 type;
-       u16 length;
-} __attribute__ ((packed));
-
-struct ieee80211_softmac_stats{
-       unsigned int rx_ass_ok;
-       unsigned int rx_ass_err;
-       unsigned int rx_probe_rq;
-       unsigned int tx_probe_rs;
-       unsigned int tx_beacons;
-       unsigned int rx_auth_rq;
-       unsigned int rx_auth_rs_ok;
-       unsigned int rx_auth_rs_err;
-       unsigned int tx_auth_rq;
-       unsigned int no_auth_rs;
-       unsigned int no_ass_rs;
-       unsigned int tx_ass_rq;
-       unsigned int rx_ass_rq;
-       unsigned int tx_probe_rq;
-       unsigned int reassoc;
-       unsigned int swtxstop;
-       unsigned int swtxawake;
-       unsigned char CurrentShowTxate;
-       unsigned char last_packet_rate;
-       unsigned int txretrycount;
-};
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-struct ieee80211_info_element_hdr {
-       u8 id;
-       u8 len;
-} __attribute__ ((packed));
-
-/*
- * These are the data types that can make up management packets
- *
-       u16 auth_algorithm;
-       u16 auth_sequence;
-       u16 beacon_interval;
-       u16 capability;
-       u8 current_ap[ETH_ALEN];
-       u16 listen_interval;
-       struct {
-               u16 association_id:14, reserved:2;
-       } __attribute__ ((packed));
-       u32 time_stamp[2];
-       u16 reason;
-       u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 2 /* 1Mbps */
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len  (WMM_all_frame << 4)
-#define IEEE80211_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-
-
-#ifdef WMM_Hang_8187
-#undef WMM_Hang_8187
-#endif
-
-#define WME_AC_BK   0x00
-#define WME_AC_BE   0x01
-#define WME_AC_VI   0x02
-#define WME_AC_VO   0x03
-#define WME_ACI_MASK 0x03
-#define WME_AIFSN_MASK 0x03
-#define WME_AC_PRAM_LEN 16
-
-#define MAX_RECEIVE_BUFFER_SIZE 9100
-
-/* UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP */
-#define UP2AC(up) (               \
-       ((up) < 1) ? WME_AC_BE : \
-       ((up) < 3) ? WME_AC_BK : \
-       ((up) < 4) ? WME_AC_BE : \
-       ((up) < 6) ? WME_AC_VI : \
-       WME_AC_VO)
-/* AC Mapping to UP, using in Tx part for selecting the corresponding TX queue */
-#define AC2UP(_ac)     (       \
-       ((_ac) == WME_AC_VO) ? 6 : \
-       ((_ac) == WME_AC_VI) ? 5 : \
-       ((_ac) == WME_AC_BK) ? 1 : \
-       0)
-
-#define        ETHER_ADDR_LEN          6       /* length of an Ethernet address */
-#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
-
-struct ether_header {
-       u8 ether_dhost[ETHER_ADDR_LEN];
-       u8 ether_shost[ETHER_ADDR_LEN];
-       u16 ether_type;
-} __attribute__((packed));
-
-#ifndef ETHERTYPE_PAE
-#define        ETHERTYPE_PAE   0x888e          /* EAPOL PAE/802.1x */
-#endif
-#ifndef ETHERTYPE_IP
-#define        ETHERTYPE_IP    0x0800          /* IP protocol */
-#endif
-
-typedef struct _bss_ht{
-
-       bool                            support_ht;
-
-       /* HT related elements */
-       u8                                      ht_cap_buf[32];
-       u16                                     ht_cap_len;
-       u8                                      ht_info_buf[32];
-       u16                                     ht_info_len;
-
-       HT_SPEC_VER                     ht_spec_ver;
-       /* HT_CAPABILITY_ELE                    bdHTCapEle; */
-       /* HT_INFORMATION_ELE           bdHTInfoEle; */
-
-       bool                            aggregation;
-       bool                            long_slot_time;
-} bss_ht, *pbss_ht;
-
-typedef enum _erp_t{
-       ERP_NonERPpresent       = 0x01,
-       ERP_UseProtection       = 0x02,
-       ERP_BarkerPreambleMode = 0x04,
-} erp_t;
-
-
-struct ieee80211_network {
-       /* These entries are used to identify a unique network */
-       u8 bssid[ETH_ALEN];
-       u8 channel;
-       /* Ensure null-terminated for any debug msgs */
-       u8 ssid[IW_ESSID_MAX_SIZE + 1];
-       u8 ssid_len;
-       struct ieee80211_qos_data qos_data;
-       bool    bWithAironetIE;
-       bool    bCkipSupported;
-       bool    bCcxRmEnable;
-       u16     CcxRmState[2];
-       /* CCXv4 S59, MBSSID. */
-       bool    bMBssidValid;
-       u8      MBssidMask;
-       u8      MBssid[6];
-       /* CCX 2 S38, WLAN Device Version Number element. */
-       bool    bWithCcxVerNum;
-       u8      BssCcxVerNumber;
-       /* These are network statistics */
-       struct ieee80211_rx_stats stats;
-       u16 capability;
-       u8  rates[MAX_RATES_LENGTH];
-       u8  rates_len;
-       u8  rates_ex[MAX_RATES_EX_LENGTH];
-       u8  rates_ex_len;
-       unsigned long last_scanned;
-       u8  mode;
-       u32 flags;
-       u32 last_associate;
-       u32 time_stamp[2];
-       u16 beacon_interval;
-       u16 listen_interval;
-       u16 atim_window;
-       u8  erp_value;
-       u8  wpa_ie[MAX_WPA_IE_LEN];
-       size_t wpa_ie_len;
-       u8  rsn_ie[MAX_WPA_IE_LEN];
-       size_t rsn_ie_len;
-
-       struct ieee80211_tim_parameters tim;
-       u8  dtim_period;
-       u8  dtim_data;
-       u32 last_dtim_sta_time[2];
-
-       /* appeded for QoS */
-       u8 wmm_info;
-       struct ieee80211_wmm_ac_param wmm_param[4];
-       u8 QoS_Enable;
-#ifdef THOMAS_TURBO
-       u8 Turbo_Enable;/* enable turbo mode, added by thomas */
-#endif
-#ifdef ENABLE_DOT11D
-       u16 CountryIeLen;
-       u8 CountryIeBuf[MAX_IE_LEN];
-#endif
-       /* HT Related */
-       BSS_HT  bssht;
-       /* Add to handle broadcom AP management frame CCK rate. */
-       bool broadcom_cap_exist;
-       bool ralink_cap_exist;
-       bool atheros_cap_exist;
-       bool cisco_cap_exist;
-       bool unknown_cap_exist;
-       bool    berp_info_valid;
-       bool buseprotection;
-       /* put at the end of the structure. */
-       struct list_head list;
-};
-
-enum ieee80211_state {
-
-       /* the card is not linked at all */
-       IEEE80211_NOLINK = 0,
-
-       /* IEEE80211_ASSOCIATING* are for BSS client mode
-        * the driver shall not perform RX filtering unless
-        * the state is LINKED.
-        * The driver shall just check for the state LINKED and
-        * defaults to NOLINK for ALL the other states (including
-        * LINKED_SCANNING)
-        */
-
-       /* the association procedure will start (wq scheduling)*/
-       IEEE80211_ASSOCIATING,
-       IEEE80211_ASSOCIATING_RETRY,
-
-       /* the association procedure is sending AUTH request*/
-       IEEE80211_ASSOCIATING_AUTHENTICATING,
-
-       /* the association procedure has successfully authentcated
-        * and is sending association request
-        */
-       IEEE80211_ASSOCIATING_AUTHENTICATED,
-
-       /* the link is ok. the card associated to a BSS or linked
-        * to a ibss cell or acting as an AP and creating the bss
-        */
-       IEEE80211_LINKED,
-
-       /* same as LINKED, but the driver shall apply RX filter
-        * rules as we are in NO_LINK mode. As the card is still
-        * logically linked, but it is doing a syncro site survey
-        * then it will be back to LINKED state.
-        */
-       IEEE80211_LINKED_SCANNING,
-
-};
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-#define CFG_IEEE80211_RTS (1<<2)
-
-#define IEEE80211_24GHZ_MIN_CHANNEL 1
-#define IEEE80211_24GHZ_MAX_CHANNEL 14
-#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
-                                 IEEE80211_24GHZ_MIN_CHANNEL + 1)
-
-#define IEEE80211_52GHZ_MIN_CHANNEL 34
-#define IEEE80211_52GHZ_MAX_CHANNEL 165
-#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
-                                 IEEE80211_52GHZ_MIN_CHANNEL + 1)
-
-
-
-typedef struct tx_pending_t{
-       int frag;
-       struct ieee80211_txb *txb;
-} tx_pending_t;
-
-typedef struct _bandwidth_autoswitch {
-       long threshold_20Mhzto40Mhz;
-       long    threshold_40Mhzto20Mhz;
-       bool bforced_tx20Mhz;
-       bool bautoswitch_enable;
-} bandwidth_autoswitch, *pbandwidth_autoswitch;
-
-
-
-#define REORDER_WIN_SIZE       128
-#define REORDER_ENTRY_NUM      128
-typedef struct _RX_REORDER_ENTRY {
-       struct list_head        List;
-       u16                     SeqNum;
-       struct ieee80211_rxb *prxb;
-} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
-
-typedef enum _Fsync_State {
-       Default_Fsync,
-       HW_Fsync,
-       SW_Fsync
-} Fsync_State;
-
-/* Power save mode configured. */
-typedef        enum _RT_PS_MODE {
-       eActive,        /* Active/Continuous access. */
-       eMaxPs,         /* Max power save mode. */
-       eFastPs         /* Fast power save mode. */
-} RT_PS_MODE;
-
-typedef enum _IPS_CALLBACK_FUNCION {
-       IPS_CALLBACK_NONE = 0,
-       IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
-       IPS_CALLBACK_JOIN_REQUEST = 2,
-} IPS_CALLBACK_FUNCION;
-
-typedef enum _RT_JOIN_ACTION {
-       RT_JOIN_INFRA   = 1,
-       RT_JOIN_IBSS  = 2,
-       RT_START_IBSS = 3,
-       RT_NO_ACTION  = 4,
-} RT_JOIN_ACTION;
-
-typedef struct _IbssParms {
-       u16   atimWin;
-} IbssParms, *PIbssParms;
-#define MAX_NUM_RATES  264 /* Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko. */
-
-/* RF state. */
-typedef        enum _RT_RF_POWER_STATE {
-       eRfOn,
-       eRfSleep,
-       eRfOff
-} RT_RF_POWER_STATE;
-
-typedef struct _RT_POWER_SAVE_CONTROL {
-
-       /* Inactive Power Save(IPS) : Disable RF when disconnected */
-       bool                            bInactivePs;
-       bool                            bIPSModeBackup;
-       bool                            bSwRfProcessing;
-       RT_RF_POWER_STATE       eInactivePowerState;
-       struct work_struct      InactivePsWorkItem;
-       struct timer_list       InactivePsTimer;
-
-       /* Return point for join action */
-       IPS_CALLBACK_FUNCION    ReturnPoint;
-
-       /* Recored Parameters for rescheduled JoinRequest */
-       bool                            bTmpBssDesc;
-       RT_JOIN_ACTION          tmpJoinAction;
-       struct ieee80211_network tmpBssDesc;
-
-       /* Recored Parameters for rescheduled MgntLinkRequest */
-       bool                            bTmpScanOnly;
-       bool                            bTmpActiveScan;
-       bool                            bTmpFilterHiddenAP;
-       bool                            bTmpUpdateParms;
-       u8                                      tmpSsidBuf[33];
-       OCTET_STRING                    tmpSsid2Scan;
-       bool                            bTmpSsid2Scan;
-       u8                                      tmpNetworkType;
-       u8                                      tmpChannelNumber;
-       u16                                     tmpBcnPeriod;
-       u8                                      tmpDtimPeriod;
-       u16                                     tmpmCap;
-       OCTET_STRING                    tmpSuppRateSet;
-       u8                                      tmpSuppRateBuf[MAX_NUM_RATES];
-       bool                            bTmpSuppRate;
-       IbssParms                               tmpIbpm;
-       bool                            bTmpIbpm;
-
-       /* Leisre Poswer Save : Disable RF if connected but traffic is not busy */
-       bool                            bLeisurePs;
-
-} RT_POWER_SAVE_CONTROL, *PRT_POWER_SAVE_CONTROL;
-
-typedef u32 RT_RF_CHANGE_SOURCE;
-#define RF_CHANGE_BY_SW BIT31
-#define RF_CHANGE_BY_HW BIT30
-#define RF_CHANGE_BY_PS BIT29
-#define RF_CHANGE_BY_IPS BIT28
-#define RF_CHANGE_BY_INIT      0       /* Do not change the RFOff reason. */
-
-#ifdef ENABLE_DOT11D
-typedef enum {
-       COUNTRY_CODE_FCC = 0,
-       COUNTRY_CODE_IC = 1,
-       COUNTRY_CODE_ETSI = 2,
-       COUNTRY_CODE_SPAIN = 3,
-       COUNTRY_CODE_FRANCE = 4,
-       COUNTRY_CODE_MKK = 5,
-       COUNTRY_CODE_MKK1 = 6,
-       COUNTRY_CODE_ISRAEL = 7,
-       COUNTRY_CODE_TELEC,
-       COUNTRY_CODE_MIC,
-       COUNTRY_CODE_GLOBAL_DOMAIN
-} country_code_type_t;
-#endif
-
-#define RT_MAX_LD_SLOT_NUM     10
-typedef struct _RT_LINK_DETECT_T {
-
-       u32                             NumRecvBcnInPeriod;
-       u32                             NumRecvDataInPeriod;
-
-       u32                             RxBcnNum[RT_MAX_LD_SLOT_NUM];   /* number of Rx beacon / CheckForHang_period  to determine link status */
-       u32                             RxDataNum[RT_MAX_LD_SLOT_NUM];  /* number of Rx data / CheckForHang_period  to determine link status */
-       u16                             SlotNum;        /* number of CheckForHang period to determine link status */
-       u16                             SlotIndex;
-
-       u32                             NumTxOkInPeriod;
-       u32                             NumRxOkInPeriod;
-       bool                            bBusyTraffic;
-} RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
-
-
-struct ieee80211_device {
-       struct net_device *dev;
-       struct ieee80211_security sec;
-
-       /* hw security related */
-       u8 hwsec_active;  /* hw security active. */
-       bool is_silent_reset;
-       bool ieee_up;
-       bool bSupportRemoteWakeUp;
-       RT_PS_MODE      dot11PowerSaveMode; /* Power save mode configured. */
-       bool actscanning;
-       bool beinretry;
-       RT_RF_POWER_STATE               eRFPowerState;
-       RT_RF_CHANGE_SOURCE     RfOffReason;
-       bool is_set_key;
-       /* 11n spec related I wonder if These info structure need to be moved out of ieee80211_device */
-
-       /* 11n HT below */
-       PRT_HIGH_THROUGHPUT     pHTInfo;
-       spinlock_t bw_spinlock;
-
-       spinlock_t reorder_spinlock;
-       /* for HT operation rate set.  we use this one for HT data rate to
-        * separate different descriptors
-        * the way fill this is the same as in the IE
-        */
-       u8      Regdot11HTOperationalRateSet[16];               /* use RATR format */
-       u8      dot11HTOperationalRateSet[16];          /* use RATR format */
-       u8      RegHTSuppRateSet[16];
-       u8                              HTCurrentOperaRate;
-       u8                              HTHighestOperaRate;
-       /* wb added for rate operation mode to firmware */
-       u8      bTxDisableRateFallBack;
-       u8      bTxUseDriverAssingedRate;
-       atomic_t        atm_chnlop;
-       atomic_t        atm_swbw;
-
-       /* 802.11e and WMM Traffic Stream Info (TX) */
-       struct list_head                Tx_TS_Admit_List;
-       struct list_head                Tx_TS_Pending_List;
-       struct list_head                Tx_TS_Unused_List;
-       TX_TS_RECORD            TxTsRecord[TOTAL_TS_NUM];
-       /* 802.11e and WMM Traffic Stream Info (RX) */
-       struct list_head                Rx_TS_Admit_List;
-       struct list_head                Rx_TS_Pending_List;
-       struct list_head                Rx_TS_Unused_List;
-       RX_TS_RECORD            RxTsRecord[TOTAL_TS_NUM];
-       RX_REORDER_ENTRY        RxReorderEntry[128];
-       struct list_head                RxReorder_Unused_List;
-       /* Qos related. */
-/*     PSTA_QOS                        pStaQos; */
-       u8                              ForcedPriority;         /* Force per-packet priority 1~7. (default: 0, not to force it.) */
-
-
-       /* Bookkeeping structures */
-       struct net_device_stats stats;
-       struct ieee80211_stats ieee_stats;
-       struct ieee80211_softmac_stats softmac_stats;
-
-       /* Probe / Beacon management */
-       struct list_head network_free_list;
-       struct list_head network_list;
-       struct ieee80211_network *networks;
-       int scans;
-       int scan_age;
-
-       int iw_mode; /* operating mode (IW_MODE_*) */
-       struct iw_spy_data spy_data;
-
-       spinlock_t lock;
-       spinlock_t wpax_suitlist_lock;
-
-       int tx_headroom; /* Set to size of any additional room needed at front
-                         * of allocated Tx SKBs */
-       u32 config;
-
-       /* WEP and other encryption related settings at the device level */
-       int open_wep; /* Set to 1 to allow unencrypted frames */
-       int auth_mode;
-       int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
-                                * WEP key changes */
-
-       /* If the host performs {en,de}cryption, then set to 1 */
-       int host_encrypt;
-       int host_encrypt_msdu;
-       int host_decrypt;
-       /* host performs multicast decryption */
-       int host_mc_decrypt;
-
-       /* host should strip IV and ICV from protected frames */
-       /* meaningful only when hardware decryption is being used */
-       int host_strip_iv_icv;
-
-       int host_open_frag;
-       int host_build_iv;
-       int ieee802_1x; /* is IEEE 802.1X used */
-
-       /* WPA data */
-       bool bHalfWirelessN24GMode;
-       int wpa_enabled;
-       int drop_unencrypted;
-       int tkip_countermeasures;
-       int privacy_invoked;
-       size_t wpa_ie_len;
-       u8 *wpa_ie;
-       u8 ap_mac_addr[6];
-       u16 pairwise_key_type;
-       u16 group_key_type;
-       struct list_head crypt_deinit_list;
-       struct ieee80211_crypt_data *crypt[WEP_KEYS];
-       int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
-       struct timer_list crypt_deinit_timer;
-       int crypt_quiesced;
-
-       int bcrx_sta_key; /* use individual keys to override default keys even
-                          * with RX of broad/multicast frames */
-
-       /* Fragmentation structures */
-       /* each streaming contain a entry */
-       struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
-       unsigned int frag_next_idx[17];
-       u16 fts; /* Fragmentation Threshold */
-#define DEFAULT_RTS_THRESHOLD 2346U
-#define MIN_RTS_THRESHOLD 1
-#define MAX_RTS_THRESHOLD 2346U
-       u16 rts; /* RTS threshold */
-
-       /* Association info */
-       u8 bssid[ETH_ALEN];
-
-       /* This stores infos for the current network.
-        * Either the network we are associated in INFRASTRUCTURE
-        * or the network that we are creating in MASTER mode.
-        * ad-hoc is a mixture ;-).
-        * Note that in infrastructure mode, even when not associated,
-        * fields bssid and essid may be valid (if wpa_set and essid_set
-        * are true) as thy carry the value set by the user via iwconfig
-        */
-       struct ieee80211_network current_network;
-
-       enum ieee80211_state state;
-
-       int short_slot;
-       int reg_mode;
-       int mode;       /* A, B, G */
-       int modulation; /* CCK, OFDM */
-       int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
-       int abg_true;   /* ABG flag              */
-
-       /* used for forcing the ibss workqueue to terminate
-        * without wait for the syncro scan to terminate
-        */
-       short sync_scan_hurryup;
-
-       int perfect_rssi;
-       int worst_rssi;
-
-       u16 prev_seq_ctl;       /* used to drop duplicate frames */
-
-       /* map of allowed channels. 0 is dummy */
-       /* FIXME: remeber to default to a basic channel plan depending of the PHY type */
-#ifdef ENABLE_DOT11D
-       void *pDot11dInfo;
-       bool bGlobalDomain;
-#else
-       int channel_map[MAX_CHANNEL_NUMBER+1];
-#endif
-       int rate;       /* current rate */
-       int basic_rate;
-       /* FIXME: pleace callback, see if redundant with softmac_features */
-       short active_scan;
-
-       /* this contains flags for selectively enable softmac support */
-       u16 softmac_features;
-
-       /* if the sequence control field is not filled by HW */
-       u16 seq_ctrl[5];
-
-       /* association procedure transaction sequence number */
-       u16 associate_seq;
-
-       /* AID for RTXed association responses */
-       u16 assoc_id;
-
-       /* power save mode related*/
-       short ps;
-       short sta_sleep;
-       int ps_timeout;
-       int ps_period;
-       struct tasklet_struct ps_task;
-       u32 ps_th;
-       u32 ps_tl;
-
-       short raw_tx;
-       /* used if IEEE_SOFTMAC_TX_QUEUE is set */
-       short queue_stop;
-       short scanning;
-       short proto_started;
-
-       struct semaphore wx_sem;
-       struct semaphore scan_sem;
-
-       spinlock_t mgmt_tx_lock;
-       spinlock_t beacon_lock;
-
-       short beacon_txing;
-
-       short wap_set;
-       short ssid_set;
-
-       u8  wpax_type_set;
-       u32 wpax_type_notify;
-
-       /* QoS related flag */
-       char init_wmmparam_flag;
-       /* set on initialization */
-       u8  qos_support;
-
-       /* for discarding duplicated packets in IBSS */
-       struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
-       /* for discarding duplicated packets in BSS */
-       u16 last_rxseq_num[17]; /* rx seq previous per-tid */
-       u16 last_rxfrag_num[17];/* tx frag previous per-tid */
-       unsigned long last_packet_time[17];
-
-       /* for PS mode */
-       unsigned long last_rx_ps_time;
-
-       /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
-       struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
-       int mgmt_queue_head;
-       int mgmt_queue_tail;
-/* added for rtl819x */
-#define IEEE80211_QUEUE_LIMIT 128
-       u8 AsocRetryCount;
-       unsigned int hw_header;
-       struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
-       struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE];
-       struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE];
-       u32     sta_edca_param[4];
-       bool aggregation;
-       /* Enable/Disable Rx immediate BA capability. */
-       bool enable_rx_imm_BA;
-       bool bibsscoordinator;
-
-       /*+by amy for DM ,080515 */
-       /* Dynamic Tx power for near/far range enable/Disable  */
-       bool    bdynamic_txpower_enable;
-
-       bool bCTSToSelfEnable;
-       u8      CTSToSelfTH;
-
-       u32     fsync_time_interval;
-       u32     fsync_rate_bitmap;
-       u8      fsync_rssi_threshold;
-       bool    bfsync_enable;
-
-       u8      fsync_multiple_timeinterval;            /* FsyncMultipleTimeInterval * FsyncTimeInterval */
-       u32     fsync_firstdiff_ratethreshold;          /* low threshold */
-       u32     fsync_seconddiff_ratethreshold;  /* decrease threshold */
-       Fsync_State                     fsync_state;
-       bool            bis_any_nonbepkts;
-       /* 20Mhz 40Mhz AutoSwitch Threshold */
-       bandwidth_autoswitch bandwidth_auto_switch;
-       /* for txpower tracking */
-       bool FwRWRF;
-
-       /* added by amy for AP roaming */
-       RT_LINK_DETECT_T        LinkDetectInfo;
-       /* added by amy for ps */
-       RT_POWER_SAVE_CONTROL   PowerSaveControl;
-       /* used if IEEE_SOFTMAC_TX_QUEUE is set */
-       struct  tx_pending_t tx_pending;
-
-       /* used if IEEE_SOFTMAC_ASSOCIATE is set */
-       struct timer_list associate_timer;
-
-       /* used if IEEE_SOFTMAC_BEACONS is set */
-       struct timer_list beacon_timer;
-       struct work_struct associate_complete_wq;
-       struct work_struct associate_procedure_wq;
-       struct delayed_work softmac_scan_wq;
-       struct delayed_work associate_retry_wq;
-        struct delayed_work start_ibss_wq;
-       struct work_struct wx_sync_scan_wq;
-       struct workqueue_struct *wq;
-       /* Qos related. Added by Annie, 2005-11-01. */
-       /* STA_QOS  StaQos; */
-
-
-       /* Callback functions */
-       void (*set_security)(struct net_device *dev,
-                            struct ieee80211_security *sec);
-
-       /* Used to TX data frame by using txb structs.
-        * this is not used if in the softmac_features
-        * is set the flag IEEE_SOFTMAC_TX_QUEUE
-        */
-       int (*hard_start_xmit)(struct ieee80211_txb *txb,
-                              struct net_device *dev);
-
-       int (*reset_port)(struct net_device *dev);
-       int (*is_queue_full) (struct net_device *dev, int pri);
-
-       int (*handle_management) (struct net_device *dev,
-                                 struct ieee80211_network *network, u16 type);
-       int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
-
-       /* Softmac-generated frames (mamagement) are TXed via this
-        * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
-        * not set. As some cards may have different HW queues that
-        * one might want to use for data and management frames
-        * the option to have two callbacks might be useful.
-        * This fucntion can't sleep.
-        */
-       int (*softmac_hard_start_xmit)(struct sk_buff *skb,
-                              struct net_device *dev);
-
-       /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
-        * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
-        * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
-        * then also management frames are sent via this callback.
-        * This function can't sleep.
-        */
-       void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
-                              struct net_device *dev, int rate);
-
-       /* stops the HW queue for DATA frames. Useful to avoid
-        * waste time to TX data frame when we are reassociating
-        * This function can sleep.
-        */
-       void (*data_hard_stop)(struct net_device *dev);
-
-       /* OK this is complementar to data_poll_hard_stop */
-       void (*data_hard_resume)(struct net_device *dev);
-
-       /* ask to the driver to retune the radio .
-        * This function can sleep. the driver should ensure
-        * the radio has been swithced before return.
-        */
-       void (*set_chan)(struct net_device *dev, short ch);
-
-       /* These are not used if the ieee stack takes care of
-        * scanning (IEEE_SOFTMAC_SCAN feature set).
-        * In this case only the set_chan is used.
-        *
-        * The syncro version is similar to the start_scan but
-        * does not return until all channels has been scanned.
-        * this is called in user context and should sleep,
-        * it is called in a work_queue when swithcing to ad-hoc mode
-        * or in behalf of iwlist scan when the card is associated
-        * and root user ask for a scan.
-        * the fucntion stop_scan should stop both the syncro and
-        * background scanning and can sleep.
-        * The fucntion start_scan should initiate the background
-        * scanning and can't sleep.
-        */
-       void (*scan_syncro)(struct net_device *dev);
-       void (*start_scan)(struct net_device *dev);
-       void (*stop_scan)(struct net_device *dev);
-
-       /* indicate the driver that the link state is changed
-        * for example it may indicate the card is associated now.
-        * Driver might be interested in this to apply RX filter
-        * rules or simply light the LINK led
-        */
-       void (*link_change)(struct net_device *dev);
-
-       /* these two function indicates to the HW when to start
-        * and stop to send beacons. This is used when the
-        * IEEE_SOFTMAC_BEACONS is not set. For now the
-        * stop_send_bacons is NOT guaranteed to be called only
-        * after start_send_beacons.
-        */
-       void (*start_send_beacons) (struct net_device *dev, u16 tx_rate);
-       void (*stop_send_beacons) (struct net_device *dev);
-
-       /* power save mode related */
-       void (*sta_wake_up) (struct net_device *dev);
-       void (*ps_request_tx_ack) (struct net_device *dev);
-       void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
-       short (*ps_is_queue_empty) (struct net_device *dev);
-       int (*handle_beacon) (struct net_device *dev, struct ieee80211_beacon *beacon, struct ieee80211_network *network);
-       int (*handle_assoc_response) (struct net_device *dev, struct ieee80211_assoc_response_frame *resp, struct ieee80211_network *network);
-
-
-       /* check whether Tx hw resouce available */
-       short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
-       /* added by wb for HT related */
-       void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
-       bool (*GetNmodeSupportBySecCfg)(struct net_device *dev);
-       void (*SetWirelessMode)(struct net_device *dev, u8 wireless_mode);
-       bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device *dev);
-       void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
-
-       /* This must be the last item so that it points to the data
-        * allocated beyond this structure by alloc_ieee80211 */
-       u8 priv[0];
-};
-
-#define IEEE_A            (1<<0)
-#define IEEE_B            (1<<1)
-#define IEEE_G            (1<<2)
-#define IEEE_N_24G               (1<<4)
-#define        IEEE_N_5G                 (1<<5)
-#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1<<2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1<<4)
-
-/* Generate respones to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1<<5)
-
-/* The ieee802.11 stack will manages the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details. */
-#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
-
-/* Generate beacons.  The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1<<6)
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
-       return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-}
-
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
-{
-       /* Single white space is for Linksys APs */
-       if (essid_len == 1 && essid[0] == ' ')
-               return 1;
-
-       /* Otherwise, if the entire essid is 0, we assume it is hidden */
-       while (essid_len) {
-               essid_len--;
-               if (essid[essid_len] != '\0')
-                       return 0;
-       }
-
-       return 1;
-}
-
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
-{
-       /*
-        * It is possible for both access points and our device to support
-        * combinations of modes, so as long as there is one valid combination
-        * of ap/device supported modes, then return success
-        *
-        */
-       if ((mode & IEEE_A) &&
-           (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-           (ieee->freq_band & IEEE80211_52GHZ_BAND))
-               return 1;
-
-       if ((mode & IEEE_G) &&
-           (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-           (ieee->freq_band & IEEE80211_24GHZ_BAND))
-               return 1;
-
-       if ((mode & IEEE_B) &&
-           (ieee->modulation & IEEE80211_CCK_MODULATION) &&
-           (ieee->freq_band & IEEE80211_24GHZ_BAND))
-               return 1;
-
-       return 0;
-}
-
-extern inline int ieee80211_get_hdrlen(u16 fc)
-{
-       int hdrlen = IEEE80211_3ADDR_LEN;
-
-       switch (WLAN_FC_GET_TYPE(fc)) {
-       case IEEE80211_FTYPE_DATA:
-               if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-                       hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */
-               if (IEEE80211_QOS_HAS_SEQ(fc))
-                       hdrlen += 2; /* QOS ctrl*/
-               break;
-       case IEEE80211_FTYPE_CTL:
-               switch (WLAN_FC_GET_STYPE(fc)) {
-               case IEEE80211_STYPE_CTS:
-               case IEEE80211_STYPE_ACK:
-                       hdrlen = IEEE80211_1ADDR_LEN;
-                       break;
-               default:
-                       hdrlen = IEEE80211_2ADDR_LEN;
-                       break;
-               }
-               break;
-       }
-
-       return hdrlen;
-}
-
-static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
-{
-       switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
-       case IEEE80211_1ADDR_LEN:
-               return ((struct ieee80211_hdr_1addr *)hdr)->payload;
-       case IEEE80211_2ADDR_LEN:
-               return ((struct ieee80211_hdr_2addr *)hdr)->payload;
-       case IEEE80211_3ADDR_LEN:
-               return ((struct ieee80211_hdr_3addr *)hdr)->payload;
-       case IEEE80211_4ADDR_LEN:
-               return ((struct ieee80211_hdr_4addr *)hdr)->payload;
-       }
-       return NULL;
-}
-
-static inline int ieee80211_is_ofdm_rate(u8 rate)
-{
-       switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
-       case IEEE80211_OFDM_RATE_6MB:
-       case IEEE80211_OFDM_RATE_9MB:
-       case IEEE80211_OFDM_RATE_12MB:
-       case IEEE80211_OFDM_RATE_18MB:
-       case IEEE80211_OFDM_RATE_24MB:
-       case IEEE80211_OFDM_RATE_36MB:
-       case IEEE80211_OFDM_RATE_48MB:
-       case IEEE80211_OFDM_RATE_54MB:
-               return 1;
-       }
-       return 0;
-}
-
-static inline int ieee80211_is_cck_rate(u8 rate)
-{
-       switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
-       case IEEE80211_CCK_RATE_1MB:
-       case IEEE80211_CCK_RATE_2MB:
-       case IEEE80211_CCK_RATE_5MB:
-       case IEEE80211_CCK_RATE_11MB:
-               return 1;
-       }
-       return 0;
-}
-
-
-/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
-
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-
-extern int ieee80211_encrypt_fragment(
-       struct ieee80211_device *ieee,
-       struct sk_buff *frag,
-       int hdr_len);
-
-extern int ieee80211_xmit(struct sk_buff *skb,
-                         struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-
-/* ieee80211_rx.c */
-extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-                       struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-                            struct ieee80211_hdr_4addr *header,
-                            struct ieee80211_rx_stats *stats);
-
-/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
-                                struct iw_request_info *info,
-                                union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
-                                  struct iw_request_info *info,
-                                  union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
-                                  struct iw_request_info *info,
-                                  union iwreq_data *wrqu, char *key);
-#if WIRELESS_EXT >= 18
-extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
-                              struct iw_request_info *info,
-                              struct iw_param *data, char *extra);
-extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra);
-#endif
-extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
-
-/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(struct ieee80211_network net);
-extern short ieee80211_is_shortslot(struct ieee80211_network net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
-                       struct ieee80211_rx_stats *rx_stats, u16 type,
-                       u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
-
-void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
-
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-
-extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
-
-/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
-
-/* ieee80211_softmac_wx.c */
-
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *ext);
-
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
-                        struct iw_request_info *info,
-                        union iwreq_data *awrq,
-                        char *extra);
-
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
-                               struct iw_request_info *a,
-                               union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
-                             struct iw_request_info *a,
-                             union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
-
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-
-
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
-                                struct iw_request_info *info,
-                                union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
-                                struct iw_request_info *info,
-                                union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
-/* HT */
-#define MAX_RECEIVE_BUFFER_SIZE 9100
-extern void HTDebugHTCapability(u8 *CapIE, u8 *TitleString);
-extern void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString);
-
-void HTSetConnectBwMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
-extern void HTUpdateDefaultSetting(struct ieee80211_device *ieee);
-extern void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u8 *len, u8 isEncrypt);
-extern void HTConstructInfoElement(struct ieee80211_device *ieee, u8 *posHTInfo, u8 *len, u8 isEncrypt);
-extern void HTConstructRT2RTAggElement(struct ieee80211_device *ieee, u8 *posRT2RTAgg, u8 *len);
-extern void HTOnAssocRsp(struct ieee80211_device *ieee);
-extern void HTInitializeHTInfo(struct ieee80211_device *ieee);
-extern void HTInitializeBssDesc(PBSS_HT pBssHT);
-extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork);
-extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee,   struct ieee80211_network *pNetwork);
-extern u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet, u8 *pMCSFilter);
-extern u8 MCS_FILTER_ALL[];
-extern u16 MCS_DATA_RATE[2][2][77] ;
-extern u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame);
-extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
-extern bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee);
-extern u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee,  u8      nMcsRate);
-extern u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
-extern u16  TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate);
-/* function in BAPROC.c */
-extern int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb);
-extern int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb);
-extern int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb);
-extern void TsInitAddBA(struct ieee80211_device *ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
-extern void TsInitDelBA(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
-extern void BaSetupTimeOut(unsigned long data);
-extern void TxBaInactTimeout(unsigned long data);
-extern void RxBaInactTimeout(unsigned long data);
-extern void ResetBaEntry(PBA_RECORD pBA);
-/* function in TS.c */
-extern bool GetTs(
-       struct ieee80211_device *ieee,
-       PTS_COMMON_INFO *ppTS,
-       u8                              *Addr,
-       u8                              TID,
-       TR_SELECT                       TxRxSelect,  /* Rx:1, Tx:0 */
-       bool                            bAddNewTs
-       );
-extern void TSInitialize(struct ieee80211_device *ieee);
-extern  void TsStartAddBaProcess(struct ieee80211_device *ieee, PTX_TS_RECORD   pTxTS);
-extern void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr);
-extern void RemoveAllTS(struct ieee80211_device *ieee);
-void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
-
-extern const long ieee80211_wlan_frequencies[];
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
-       ieee->scans++;
-}
-
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
-       return ieee->scans;
-}
-
-static inline const char *escape_essid(const char *essid, u8 essid_len)
-{
-       static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-       const char *s = essid;
-       char *d = escaped;
-
-       if (ieee80211_is_empty_essid(essid, essid_len)) {
-               memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-               return escaped;
-       }
-
-       essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
-       while (essid_len--) {
-               if (*s == '\0') {
-                       *d++ = '\\';
-                       *d++ = '0';
-                       s++;
-               } else {
-                       *d++ = *s++;
-               }
-       }
-       *d = '\0';
-       return escaped;
-}
-
-/* For the function is more related to hardware setting, it's better to use the
- * ieee handler to refer to it.
- */
-extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
-extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
-extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
-               struct ieee80211_info_element *info_element,
-               u16 length,
-               struct ieee80211_network *network,
-               struct ieee80211_rx_stats *stats);
-
-void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb **prxbIndicateArray, u8  index);
-#define RT_ASOC_RETRY_LIMIT    5
-#endif /* IEEE80211_H */
index fb78ed2876e51492b9ffaa556cb2f9132cc94a6a..d6f55c290dbec367ebae0aaeecb4c05741e063d2 100644 (file)
@@ -85,7 +85,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
        }
        /* Add the protocol name */
        iwe.cmd = SIOCGIWNAME;
-       for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) {
+       for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) {
                if(network->mode&(1<<i)) {
                        sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
                        pname +=ieee80211_modes[i].mode_size;
index 69a2721e850c220f2856a8a193c1a3ced8c9d1f9..6206f929a6550e77d9b0d82f43de22358be400b8 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/random.h>
 #include <linux/version.h>
 #include <asm/io.h>
-#include "ieee80211.h"
+#include "ieee80211/ieee80211.h"
 
 #define RTL8192U
 #define RTL819xU_MODULE_NAME "rtl819xU"
index f38472c2e75cc78847c191883b28e781d712805a..1ff7850cc1e72f9be0eca8f33dee850fe568a1b1 100644 (file)
@@ -410,14 +410,12 @@ u16 read_nic_word(struct net_device *dev, int indx)
        struct usb_device *udev = priv->udev;
 
        status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-                              RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-                              (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
+                                      RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+                                      (indx&0xff)|0xff00, (indx>>8)&0x0f,
+                                                       &data, 2, HZ / 2);
 
        if (status < 0)
-       {
                printk("read_nic_word TimeOut! status:%d\n", status);
-       }
-
 
        return data;
 }
@@ -431,13 +429,10 @@ u16 read_nic_word_E(struct net_device *dev, int indx)
 
        status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                               RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-                              indx|0xfe00, 0, &data, 2, HZ / 2);
+                                      indx|0xfe00, 0, &data, 2, HZ / 2);
 
        if (status < 0)
-       {
                printk("read_nic_word TimeOut! status:%d\n", status);
-       }
-
 
        return data;
 }
@@ -446,31 +441,29 @@ u32 read_nic_dword(struct net_device *dev, int indx)
 {
        u32 data;
        int status;
-//     int result;
+       /* int result; */
 
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
        struct usb_device *udev = priv->udev;
 
        status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-                              RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-                              (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
-//     if(0 != result) {
-//       printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
-//     }
+                                      RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+                                       (indx&0xff)|0xff00, (indx>>8)&0x0f,
+                                                       &data, 4, HZ / 2);
+       /* if(0 != result) {
+        *      printk(KERN_WARNING "read size of data = %d\, date = %d\n",
+        *                                                       result, data);
+        * }
+        */
 
        if (status < 0)
-       {
                printk("read_nic_dword TimeOut! status:%d\n", status);
-       }
-
-
 
        return data;
 }
 
-
-//u8 read_phy_cck(struct net_device *dev, u8 adr);
-//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
+/* u8 read_phy_cck(struct net_device *dev, u8 adr); */
+/* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */
 /* this might still called in what was the PHY rtl8185/rtl8192 common code
  * plans are to possibilty turn it again in one common code...
  */
@@ -478,26 +471,22 @@ inline void force_pci_posting(struct net_device *dev)
 {
 }
 
-
 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
 void rtl8192_commit(struct net_device *dev);
-//void rtl8192_restart(struct net_device *dev);
+/* void rtl8192_restart(struct net_device *dev); */
 void rtl8192_restart(struct work_struct *work);
-//void rtl8192_rq_tx_ack(struct work_struct *work);
-
+/* void rtl8192_rq_tx_ack(struct work_struct *work); */
 void watch_dog_timer_callback(unsigned long data);
 
 /****************************************************************************
-   -----------------------------PROCFS STUFF-------------------------
-*****************************************************************************/
-
-static struct proc_dir_entry *rtl8192_proc = NULL;
-
+ *   -----------------------------PROCFS STUFF-------------------------
+*****************************************************************************
+ */
 
+static struct proc_dir_entry *rtl8192_proc;
 
-static int proc_get_stats_ap(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_stats_ap(char *page, char **start, off_t offset, int count,
+                                                       int *eof, void *data)
 {
        struct net_device *dev = data;
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -508,18 +497,12 @@ static int proc_get_stats_ap(char *page, char **start,
 
        list_for_each_entry(target, &ieee->network_list, list) {
 
-               len += snprintf(page + len, count - len,
-               "%s ", target->ssid);
-
-               if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
-                       len += snprintf(page + len, count - len,
-                       "WPA\n");
-               }
-               else{
-                       len += snprintf(page + len, count - len,
-                       "non_WPA\n");
-               }
+               len += snprintf(page + len, count - len, "%s ", target->ssid);
 
+               if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
+                       len += snprintf(page + len, count - len, "WPA\n");
+               else
+                       len += snprintf(page + len, count - len, "non_WPA\n");
        }
 
        *eof = 1;
index b2f7a571b1c8ffbf361694d9e936b0093e9d5f76..f4cf2801136a6606763f9bb0df6a0979f71b56ab 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef R8180_WX_H
 #define R8180_WX_H
 //#include <linux/wireless.h>
-//#include "ieee80211.h"
+
 extern struct iw_handler_def r8192_wx_handlers_def;
 /* Enable  the rtl819x_core.c to share this function, david 2008.9.22 */
 extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
index 3cc2d571f9bd491a6d56357e3bfcc2b9e5efa9b5..b136ee48828ae7ebfd578345f4ce8ba001bf18c3 100644 (file)
@@ -11,7 +11,7 @@
  *        NDIS_STATUS_FAILURE - the following initialization process should be terminated
  *        NDIS_STATUS_SUCCESS - if firmware initialization process success
 **************************************************************************************************/
-//#include "ieee80211.h"
+
 #include "r8192U.h"
 #include "r8192U_hw.h"
 #include "r819xU_firmware_img.h"
index 383543d97f9c45fa05ffa39fe4148ab7249d361a..7ef16da7c4ef8c7e79d8652de6f5a140412b7f60 100644 (file)
@@ -65,7 +65,7 @@
 /* free dynamic data aalocated during table creation */
 #define SEP_IOCFREEDMATABLEDATA                _IO(SEP_IOC_MAGIC_NUMBER , 7)
 
-/* get the static pool area addersses (physical and virtual) */
+/* get the static pool area addresses (physical and virtual) */
 #define SEP_IOCGETSTATICPOOLADDR               _IO(SEP_IOC_MAGIC_NUMBER , 8)
 
 /* set flow id command */
index eb3a619c6a94be47f2f84170edaa735ce810eeba..beab400805af89cff386584ad23fdabb6f60a5fe 100644 (file)
@@ -168,17 +168,6 @@ struct slic_cmdqueue {
        struct slic_spinlock lock;
 };
 
-#ifdef STATUS_SUCCESS
-#undef STATUS_SUCCESS
-#endif
-
-#define STATUS_SUCCESS              0
-#define STATUS_PENDING              0
-#define STATUS_FAILURE             -1
-#define STATUS_ERROR               -2
-#define STATUS_NOT_SUPPORTED       -3
-#define STATUS_BUFFER_TOO_SHORT    -4
-
 #define SLIC_MAX_CARDS              32
 #define SLIC_MAX_PORTS              4        /* Max # of ports per card   */
 
@@ -510,7 +499,6 @@ struct adapter {
     struct slic_ifevents  if_events;
     struct slic_stats        inicstats_prev;
     struct slicnet_stats     slic_stats;
-    struct net_device_stats stats;
 };
 
 
index bebf0fd2af859a6b98f55915d2fcb84b05df8d40..f8c4b127e83a7456cd297e8bf77214e50212f1c4 100644 (file)
 #include "slichw.h"
 #include "slic.h"
 
-static struct net_device_stats *slic_get_stats(struct net_device *dev);
-static int slic_entry_open(struct net_device *dev);
-static int slic_entry_halt(struct net_device *dev);
-static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
-static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb,
-                          void *cmd, u32 skbtype, u32 status);
-static void slic_config_pci(struct pci_dev *pcidev);
-static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter);
-static int slic_mac_set_address(struct net_device *dev, void *ptr);
-static void slic_link_event_handler(struct adapter *adapter);
-static void slic_upr_request_complete(struct adapter *adapter, u32 isr);
-static int slic_rspqueue_init(struct adapter *adapter);
-static void slic_rspqueue_free(struct adapter *adapter);
-static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter);
-static int slic_cmdq_init(struct adapter *adapter);
-static void slic_cmdq_free(struct adapter *adapter);
-static void slic_cmdq_reset(struct adapter *adapter);
-static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page);
-static void slic_cmdq_getdone(struct adapter *adapter);
-static void slic_cmdq_putdone_irq(struct adapter *adapter,
-                                 struct slic_hostcmd *cmd);
-static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter);
-static int slic_rcvqueue_init(struct adapter *adapter);
-static int slic_rcvqueue_fill(struct adapter *adapter);
-static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb);
-static void slic_rcvqueue_free(struct adapter *adapter);
-static void slic_adapter_set_hwaddr(struct adapter *adapter);
-static int slic_card_init(struct sliccard *card, struct adapter *adapter);
-static void slic_intagg_set(struct adapter *adapter, u32 value);
-static int slic_card_download(struct adapter *adapter);
-static u32 slic_card_locate(struct adapter *adapter);
-static int slic_if_init(struct adapter *adapter);
-static int slic_adapter_allocresources(struct adapter *adapter);
-static void slic_adapter_freeresources(struct adapter *adapter);
-static void slic_link_config(struct adapter *adapter, u32 linkspeed,
-                            u32 linkduplex);
-static void slic_unmap_mmio_space(struct adapter *adapter);
-static void slic_card_cleanup(struct sliccard *card);
-static void slic_soft_reset(struct adapter *adapter);
-static bool slic_mac_filter(struct adapter *adapter,
-                           struct ether_header *ether_frame);
-static void slic_mac_address_config(struct adapter *adapter);
-static void slic_mac_config(struct adapter *adapter);
-static void slic_mcast_set_mask(struct adapter *adapter);
-static void slic_config_set(struct adapter *adapter, bool linkchange);
-static void slic_config_clear(struct adapter *adapter);
-static void slic_config_get(struct adapter *adapter, u32 config,
-                           u32 configh);
-static void slic_timer_load_check(ulong context);
-static void slic_assert_fail(void);
-static ushort slic_eeprom_cksum(char *m, int len);
-static void slic_upr_start(struct adapter *adapter);
-static void slic_link_upr_complete(struct adapter *adapter, u32 Isr);
-static int  slic_upr_request(struct adapter *adapter, u32 upr_request,
-                            u32 upr_data, u32 upr_data_h, u32 upr_buffer,
-                            u32 upr_buffer_h);
-static void slic_mcast_set_list(struct net_device *dev);
-
-
 static uint slic_first_init = 1;
 static char *slic_banner = "Alacritech SLIC Technology(tm) Server "\
                "and Storage Accelerator (Non-Accelerated)";
@@ -206,6 +146,17 @@ MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
 #undef ASSERT
 #endif
 
+static void slic_assert_fail(void)
+{
+       u32 cpuid;
+       u32 curr_pid;
+       cpuid = smp_processor_id();
+       curr_pid = current->pid;
+
+       printk(KERN_ERR "%s CPU # %d ---- PID # %d\n",
+              __func__, cpuid, curr_pid);
+}
+
 #ifndef ASSERT
 #define ASSERT(a) do {                                                 \
        if (!(a)) {                                                     \
@@ -241,13 +192,6 @@ MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
                        _adapter->handle_lock.flags);                   \
 }
 
-static void slic_debug_init(void);
-static void slic_debug_cleanup(void);
-static void slic_debug_adapter_create(struct adapter *adapter);
-static void slic_debug_adapter_destroy(struct adapter *adapter);
-static void slic_debug_card_create(struct sliccard *card);
-static void slic_debug_card_destroy(struct sliccard *card);
-
 static inline void slic_reg32_write(void __iomem *reg, u32 value, bool flush)
 {
        writel(value, reg);
@@ -272,3776 +216,3764 @@ static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
                                adapter->bit64reglock.flags);
 }
 
-static void slic_init_driver(void)
-{
-       if (slic_first_init) {
-               slic_first_init = 0;
-               spin_lock_init(&slic_global.driver_lock.lock);
-               slic_debug_init();
-       }
-}
+/*
+ * Functions to obtain the CRC corresponding to the destination mac address.
+ * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
+ * the polynomial:
+ *   x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 +
+ *   x^4 + x^2 + x^1.
+ *
+ * After the CRC for the 6 bytes is generated (but before the value is
+ * complemented),
+ * we must then transpose the value and return bits 30-23.
+ *
+ */
+static u32 slic_crc_table[256];        /* Table of CRCs for all possible byte values */
+static u32 slic_crc_init;      /* Is table initialized */
 
-static void slic_init_adapter(struct net_device *netdev,
-                             struct pci_dev *pcidev,
-                             const struct pci_device_id *pci_tbl_entry,
-                             void __iomem *memaddr, int chip_idx)
+/*
+ *  Contruct the CRC32 table
+ */
+static void slic_mcast_init_crc32(void)
 {
-       ushort index;
-       struct slic_handle *pslic_handle;
-       struct adapter *adapter = netdev_priv(netdev);
+       u32 c;          /*  CRC shit reg                 */
+       u32 e = 0;              /*  Poly X-or pattern            */
+       int i;                  /*  counter                      */
+       int k;                  /*  byte being shifted into crc  */
 
-/*     adapter->pcidev = pcidev;*/
-       adapter->vendid = pci_tbl_entry->vendor;
-       adapter->devid = pci_tbl_entry->device;
-       adapter->subsysid = pci_tbl_entry->subdevice;
-       adapter->busnumber = pcidev->bus->number;
-       adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
-       adapter->functionnumber = (pcidev->devfn & 0x7);
-       adapter->memorylength = pci_resource_len(pcidev, 0);
-       adapter->slic_regs = (__iomem struct slic_regs *)memaddr;
-       adapter->irq = pcidev->irq;
-/*     adapter->netdev = netdev;*/
-       adapter->next_netdevice = head_netdevice;
-       head_netdevice = netdev;
-       adapter->chipid = chip_idx;
-       adapter->port = 0;      /*adapter->functionnumber;*/
-       adapter->cardindex = adapter->port;
-       adapter->memorybase = memaddr;
-       spin_lock_init(&adapter->upr_lock.lock);
-       spin_lock_init(&adapter->bit64reglock.lock);
-       spin_lock_init(&adapter->adapter_lock.lock);
-       spin_lock_init(&adapter->reset_lock.lock);
-       spin_lock_init(&adapter->handle_lock.lock);
+       static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
 
-       adapter->card_size = 1;
-       /*
-         Initialize slic_handle array
-       */
-       ASSERT(SLIC_CMDQ_MAXCMDS <= 0xFFFF);
-       /*
-        Start with 1.  0 is an invalid host handle.
-       */
-       for (index = 1, pslic_handle = &adapter->slic_handles[1];
-            index < SLIC_CMDQ_MAXCMDS; index++, pslic_handle++) {
+       for (i = 0; i < ARRAY_SIZE(p); i++)
+               e |= 1L << (31 - p[i]);
 
-               pslic_handle->token.handle_index = index;
-               pslic_handle->type = SLIC_HANDLE_FREE;
-               pslic_handle->next = adapter->pfree_slic_handles;
-               adapter->pfree_slic_handles = pslic_handle;
+       for (i = 1; i < 256; i++) {
+               c = i;
+               for (k = 8; k; k--)
+                       c = c & 1 ? (c >> 1) ^ e : c >> 1;
+               slic_crc_table[i] = c;
        }
-       adapter->pshmem = (struct slic_shmem *)
-                                       pci_alloc_consistent(adapter->pcidev,
-                                       sizeof(struct slic_shmem),
-                                       &adapter->
-                                       phys_shmem);
-       ASSERT(adapter->pshmem);
-
-       memset(adapter->pshmem, 0, sizeof(struct slic_shmem));
-
-       return;
 }
 
-static const struct net_device_ops slic_netdev_ops = {
-       .ndo_open               = slic_entry_open,
-       .ndo_stop               = slic_entry_halt,
-       .ndo_start_xmit         = slic_xmit_start,
-       .ndo_do_ioctl           = slic_ioctl,
-       .ndo_set_mac_address    = slic_mac_set_address,
-       .ndo_get_stats          = slic_get_stats,
-       .ndo_set_multicast_list = slic_mcast_set_list,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_change_mtu         = eth_change_mtu,
-};
-
-static int __devinit slic_entry_probe(struct pci_dev *pcidev,
-                              const struct pci_device_id *pci_tbl_entry)
+/*
+ *  Return the MAC hast as described above.
+ */
+static unsigned char slic_mcast_get_mac_hash(char *macaddr)
 {
-       static int cards_found;
-       static int did_version;
-       int err = -ENODEV;
-       struct net_device *netdev;
-       struct adapter *adapter;
-       void __iomem *memmapped_ioaddr = NULL;
-       u32 status = 0;
-       ulong mmio_start = 0;
-       ulong mmio_len = 0;
-       struct sliccard *card = NULL;
-       int pci_using_dac = 0;
-
-       slic_global.dynamic_intagg = dynamic_intagg;
-
-       err = pci_enable_device(pcidev);
-
-       if (err)
-               return err;
+       u32 crc;
+       char *p;
+       int i;
+       unsigned char machash = 0;
 
-       if (slic_debug > 0 && did_version++ == 0) {
-               printk(KERN_DEBUG "%s\n", slic_banner);
-               printk(KERN_DEBUG "%s\n", slic_proc_version);
+       if (!slic_crc_init) {
+               slic_mcast_init_crc32();
+               slic_crc_init = 1;
        }
 
-       if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
-               pci_using_dac = 1;
-               if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
-                       dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for "
-                                       "consistent allocations\n");
-                       goto err_out_disable_pci;
-               }
-       } else if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
-               pci_using_dac = 0;
-               pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
-       } else {
-               dev_err(&pcidev->dev, "no usable DMA configuration\n");
-               goto err_out_disable_pci;
-       }
+       crc = 0xFFFFFFFF;       /* Preload shift register, per crc-32 spec */
+       for (i = 0, p = macaddr; i < 6; ++p, ++i)
+               crc = (crc >> 8) ^ slic_crc_table[(crc ^ *p) & 0xFF];
 
-       err = pci_request_regions(pcidev, DRV_NAME);
-       if (err) {
-               dev_err(&pcidev->dev, "can't obtain PCI resources\n");
-               goto err_out_disable_pci;
-       }
+       /* Return bits 1-8, transposed */
+       for (i = 1; i < 9; i++)
+               machash |= (((crc >> i) & 1) << (8 - i));
 
-       pci_set_master(pcidev);
+       return machash;
+}
 
-       netdev = alloc_etherdev(sizeof(struct adapter));
-       if (!netdev) {
-               err = -ENOMEM;
-               goto err_out_exit_slic_probe;
-       }
+static void slic_mcast_set_bit(struct adapter *adapter, char *address)
+{
+       unsigned char crcpoly;
 
-       SET_NETDEV_DEV(netdev, &pcidev->dev);
+       /* Get the CRC polynomial for the mac address */
+       crcpoly = slic_mcast_get_mac_hash(address);
 
-       pci_set_drvdata(pcidev, netdev);
-       adapter = netdev_priv(netdev);
-       adapter->netdev = netdev;
-       adapter->pcidev = pcidev;
-       if (pci_using_dac)
-               netdev->features |= NETIF_F_HIGHDMA;
+       /* We only have space on the SLIC for 64 entries.  Lop
+        * off the top two bits. (2^6 = 64)
+        */
+       crcpoly &= 0x3F;
 
-       mmio_start = pci_resource_start(pcidev, 0);
-       mmio_len = pci_resource_len(pcidev, 0);
+       /* OR in the new bit into our 64 bit mask. */
+       adapter->mcastmask |= (u64) 1 << crcpoly;
+}
 
+static void slic_mcast_set_mask(struct adapter *adapter)
+{
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
-/*     memmapped_ioaddr =  (u32)ioremap_nocache(mmio_start, mmio_len);*/
-       memmapped_ioaddr = ioremap(mmio_start, mmio_len);
-       if (!memmapped_ioaddr) {
-               dev_err(&pcidev->dev, "cannot remap MMIO region %lx @ %lx\n",
-                       mmio_len, mmio_start);
-               goto err_out_free_netdev;
+       if (adapter->macopts & (MAC_ALLMCAST | MAC_PROMISC)) {
+               /* Turn on all multicast addresses. We have to do this for
+                * promiscuous mode as well as ALLMCAST mode.  It saves the
+                * Microcode from having to keep state about the MAC
+                * configuration.
+                */
+               slic_reg32_write(&slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
+               slic_reg32_write(&slic_regs->slic_mcasthigh, 0xFFFFFFFF,
+                                FLUSH);
+       } else {
+               /* Commit our multicast mast to the SLIC by writing to the
+                * multicast address mask registers
+                */
+               slic_reg32_write(&slic_regs->slic_mcastlow,
+                       (u32)(adapter->mcastmask & 0xFFFFFFFF), FLUSH);
+               slic_reg32_write(&slic_regs->slic_mcasthigh,
+                       (u32)((adapter->mcastmask >> 32) & 0xFFFFFFFF), FLUSH);
        }
+}
 
-       slic_config_pci(pcidev);
-
-       slic_init_driver();
-
-       slic_init_adapter(netdev,
-                         pcidev, pci_tbl_entry, memmapped_ioaddr, cards_found);
-
-       status = slic_card_locate(adapter);
-       if (status) {
-               dev_err(&pcidev->dev, "cannot locate card\n");
-               goto err_out_free_mmio_region;
-       }
+static void slic_timer_ping(ulong dev)
+{
+       struct adapter *adapter;
+       struct sliccard *card;
 
+       ASSERT(dev);
+       adapter = netdev_priv((struct net_device *)dev);
+       ASSERT(adapter);
        card = adapter->card;
+       ASSERT(card);
 
-       if (!adapter->allocated) {
-               card->adapters_allocated++;
-               adapter->allocated = 1;
-       }
+       adapter->pingtimer.expires = jiffies + (PING_TIMER_INTERVAL * HZ);
+       add_timer(&adapter->pingtimer);
+}
 
-       status = slic_card_init(card, adapter);
+static void slic_unmap_mmio_space(struct adapter *adapter)
+{
+       if (adapter->slic_regs)
+               iounmap(adapter->slic_regs);
+       adapter->slic_regs = NULL;
+}
 
-       if (status != STATUS_SUCCESS) {
-               card->state = CARD_FAIL;
-               adapter->state = ADAPT_FAIL;
-               adapter->linkstate = LINK_DOWN;
-               dev_err(&pcidev->dev, "FAILED status[%x]\n", status);
-       } else {
-               slic_adapter_set_hwaddr(adapter);
-       }
+/*
+ *  slic_link_config
+ *
+ *  Write phy control to configure link duplex/speed
+ *
+ */
+static void slic_link_config(struct adapter *adapter,
+                     u32 linkspeed, u32 linkduplex)
+{
+       u32 __iomem *wphy;
+       u32 speed;
+       u32 duplex;
+       u32 phy_config;
+       u32 phy_advreg;
+       u32 phy_gctlreg;
 
-       netdev->base_addr = (unsigned long)adapter->memorybase;
-       netdev->irq = adapter->irq;
-       netdev->netdev_ops = &slic_netdev_ops;
+       if (adapter->state != ADAPT_UP)
+               return;
 
-       slic_debug_adapter_create(adapter);
+       ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
+              || (adapter->devid == SLIC_2GB_DEVICE_ID));
 
-       strcpy(netdev->name, "eth%d");
-       err = register_netdev(netdev);
-       if (err) {
-               dev_err(&pcidev->dev, "Cannot register net device, aborting.\n");
-               goto err_out_unmap;
-       }
+       if (linkspeed > LINK_1000MB)
+               linkspeed = LINK_AUTOSPEED;
+       if (linkduplex > LINK_AUTOD)
+               linkduplex = LINK_AUTOD;
 
-       cards_found++;
+       wphy = &adapter->slic_regs->slic_wphy;
 
-       return status;
+       if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
+               if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
+                       /*  We've got a fiber gigabit interface, and register
+                        *  4 is different in fiber mode than in copper mode
+                        */
 
-err_out_unmap:
-       iounmap(memmapped_ioaddr);
-err_out_free_mmio_region:
-       release_mem_region(mmio_start, mmio_len);
-err_out_free_netdev:
-       free_netdev(netdev);
-err_out_exit_slic_probe:
-       pci_release_regions(pcidev);
-err_out_disable_pci:
-       pci_disable_device(pcidev);
-       return err;
-}
+                       /* advertise FD only @1000 Mb */
+                       phy_advreg = (MIICR_REG_4 | (PAR_ADV1000XFD));
+                       /* enable PAUSE frames        */
+                       phy_advreg |= PAR_ASYMPAUSE_FIBER;
+                       slic_reg32_write(wphy, phy_advreg, FLUSH);
 
-static int slic_entry_open(struct net_device *dev)
-{
-       struct adapter *adapter = netdev_priv(dev);
-       struct sliccard *card = adapter->card;
-       u32 locked = 0;
-       int status;
+                       if (linkspeed == LINK_AUTOSPEED) {
+                               /* reset phy, enable auto-neg  */
+                               phy_config =
+                                   (MIICR_REG_PCR |
+                                    (PCR_RESET | PCR_AUTONEG |
+                                     PCR_AUTONEG_RST));
+                               slic_reg32_write(wphy, phy_config, FLUSH);
+                       } else {        /* forced 1000 Mb FD*/
+                               /* power down phy to break link
+                                  this may not work) */
+                               phy_config = (MIICR_REG_PCR | PCR_POWERDOWN);
+                               slic_reg32_write(wphy, phy_config, FLUSH);
+                               /* wait, Marvell says 1 sec,
+                                  try to get away with 10 ms  */
+                               mdelay(10);
 
-       ASSERT(adapter);
-       ASSERT(card);
+                               /* disable auto-neg, set speed/duplex,
+                                  soft reset phy, powerup */
+                               phy_config =
+                                   (MIICR_REG_PCR |
+                                    (PCR_RESET | PCR_SPEED_1000 |
+                                     PCR_DUPLEX_FULL));
+                               slic_reg32_write(wphy, phy_config, FLUSH);
+                       }
+               } else {        /* copper gigabit */
 
-       netif_stop_queue(adapter->netdev);
+                       /* Auto-Negotiate or 1000 Mb must be auto negotiated
+                        * We've got a copper gigabit interface, and
+                        * register 4 is different in copper mode than
+                        * in fiber mode
+                        */
+                       if (linkspeed == LINK_AUTOSPEED) {
+                               /* advertise 10/100 Mb modes   */
+                               phy_advreg =
+                                   (MIICR_REG_4 |
+                                    (PAR_ADV100FD | PAR_ADV100HD | PAR_ADV10FD
+                                     | PAR_ADV10HD));
+                       } else {
+                       /* linkspeed == LINK_1000MB -
+                          don't advertise 10/100 Mb modes  */
+                               phy_advreg = MIICR_REG_4;
+                       }
+                       /* enable PAUSE frames  */
+                       phy_advreg |= PAR_ASYMPAUSE;
+                       /* required by the Cicada PHY  */
+                       phy_advreg |= PAR_802_3;
+                       slic_reg32_write(wphy, phy_advreg, FLUSH);
+                       /* advertise FD only @1000 Mb  */
+                       phy_gctlreg = (MIICR_REG_9 | (PGC_ADV1000FD));
+                       slic_reg32_write(wphy, phy_gctlreg, FLUSH);
 
-       spin_lock_irqsave(&slic_global.driver_lock.lock,
-                               slic_global.driver_lock.flags);
-       locked = 1;
-       if (!adapter->activated) {
-               card->adapters_activated++;
-               slic_global.num_slic_ports_active++;
-               adapter->activated = 1;
-       }
-       status = slic_if_init(adapter);
+                       if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
+                               /* if a Marvell PHY
+                                  enable auto crossover */
+                               phy_config =
+                                   (MIICR_REG_16 | (MRV_REG16_XOVERON));
+                               slic_reg32_write(wphy, phy_config, FLUSH);
 
-       if (status != STATUS_SUCCESS) {
-               if (adapter->activated) {
-                       card->adapters_activated--;
-                       slic_global.num_slic_ports_active--;
-                       adapter->activated = 0;
+                               /* reset phy, enable auto-neg  */
+                               phy_config =
+                                   (MIICR_REG_PCR |
+                                    (PCR_RESET | PCR_AUTONEG |
+                                     PCR_AUTONEG_RST));
+                               slic_reg32_write(wphy, phy_config, FLUSH);
+                       } else {        /* it's a Cicada PHY  */
+                               /* enable and restart auto-neg (don't reset)  */
+                               phy_config =
+                                   (MIICR_REG_PCR |
+                                    (PCR_AUTONEG | PCR_AUTONEG_RST));
+                               slic_reg32_write(wphy, phy_config, FLUSH);
+                       }
                }
-               if (locked) {
-                       spin_unlock_irqrestore(&slic_global.driver_lock.lock,
-                                               slic_global.driver_lock.flags);
-                       locked = 0;
+       } else {
+               /* Forced 10/100  */
+               if (linkspeed == LINK_10MB)
+                       speed = 0;
+               else
+                       speed = PCR_SPEED_100;
+               if (linkduplex == LINK_HALFD)
+                       duplex = 0;
+               else
+                       duplex = PCR_DUPLEX_FULL;
+
+               if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
+                       /* if a Marvell PHY
+                          disable auto crossover  */
+                       phy_config = (MIICR_REG_16 | (MRV_REG16_XOVEROFF));
+                       slic_reg32_write(wphy, phy_config, FLUSH);
                }
-               return status;
-       }
-       if (!card->master)
-               card->master = adapter;
 
-       if (locked) {
-               spin_unlock_irqrestore(&slic_global.driver_lock.lock,
-                                       slic_global.driver_lock.flags);
-               locked = 0;
-       }
+               /* power down phy to break link (this may not work)  */
+               phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN | speed | duplex));
+               slic_reg32_write(wphy, phy_config, FLUSH);
+
+               /* wait, Marvell says 1 sec, try to get away with 10 ms */
+               mdelay(10);
 
-       return STATUS_SUCCESS;
+               if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
+                       /* if a Marvell PHY
+                          disable auto-neg, set speed,
+                          soft reset phy, powerup */
+                       phy_config =
+                           (MIICR_REG_PCR | (PCR_RESET | speed | duplex));
+                       slic_reg32_write(wphy, phy_config, FLUSH);
+               } else {        /* it's a Cicada PHY  */
+                       /* disable auto-neg, set speed, powerup  */
+                       phy_config = (MIICR_REG_PCR | (speed | duplex));
+                       slic_reg32_write(wphy, phy_config, FLUSH);
+               }
+       }
 }
 
-static void __devexit slic_entry_remove(struct pci_dev *pcidev)
+static int slic_card_download_gbrcv(struct adapter *adapter)
 {
-       struct net_device *dev = pci_get_drvdata(pcidev);
-       u32 mmio_start = 0;
-       uint mmio_len = 0;
-       struct adapter *adapter = netdev_priv(dev);
-       struct sliccard *card;
-       struct mcast_address *mcaddr, *mlist;
-
-       ASSERT(adapter);
-       slic_adapter_freeresources(adapter);
-       slic_unmap_mmio_space(adapter);
-       unregister_netdev(dev);
+       const struct firmware *fw;
+       const char *file = "";
+       int ret;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+       u32 codeaddr;
+       u32 instruction;
+       int index = 0;
+       u32 rcvucodelen = 0;
 
-       mmio_start = pci_resource_start(pcidev, 0);
-       mmio_len = pci_resource_len(pcidev, 0);
+       switch (adapter->devid) {
+       case SLIC_2GB_DEVICE_ID:
+               file = "slicoss/oasisrcvucode.sys";
+               break;
+       case SLIC_1GB_DEVICE_ID:
+               file = "slicoss/gbrcvucode.sys";
+               break;
+       default:
+               ASSERT(0);
+               break;
+       }
 
-       release_mem_region(mmio_start, mmio_len);
+       ret = request_firmware(&fw, file, &adapter->pcidev->dev);
+       if (ret) {
+               dev_err(&adapter->pcidev->dev,
+                       "SLICOSS: Failed to load firmware %s\n", file);
+               return ret;
+       }
 
-       iounmap((void __iomem *)dev->base_addr);
-       /* free multicast addresses */
-       mlist = adapter->mcastaddrs;
-       while (mlist) {
-               mcaddr = mlist;
-               mlist = mlist->next;
-               kfree(mcaddr);
+       rcvucodelen = *(u32 *)(fw->data + index);
+       index += 4;
+       switch (adapter->devid) {
+       case SLIC_2GB_DEVICE_ID:
+               if (rcvucodelen != OasisRcvUCodeLen)
+                       return -EINVAL;
+               break;
+       case SLIC_1GB_DEVICE_ID:
+               if (rcvucodelen != GBRcvUCodeLen)
+                       return -EINVAL;
+               break;
+       default:
+               ASSERT(0);
+               break;
        }
-       ASSERT(adapter->card);
-       card = adapter->card;
-       ASSERT(card->adapters_allocated);
-       card->adapters_allocated--;
-       adapter->allocated = 0;
-       if (!card->adapters_allocated) {
-               struct sliccard *curr_card = slic_global.slic_card;
-               if (curr_card == card) {
-                       slic_global.slic_card = card->next;
-               } else {
-                       while (curr_card->next != card)
-                               curr_card = curr_card->next;
-                       ASSERT(curr_card);
-                       curr_card->next = card->next;
-               }
-               ASSERT(slic_global.num_slic_cards);
-               slic_global.num_slic_cards--;
-               slic_card_cleanup(card);
+       /* start download */
+       slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
+       /* download the rcv sequencer ucode */
+       for (codeaddr = 0; codeaddr < rcvucodelen; codeaddr++) {
+               /* write out instruction address */
+               slic_reg32_write(&slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+
+               instruction = *(u32 *)(fw->data + index);
+               index += 4;
+               /* write out the instruction data low addr */
+               slic_reg32_write(&slic_regs->slic_rcv_wcs, instruction, FLUSH);
+
+               instruction = *(u8 *)(fw->data + index);
+               index++;
+               /* write out the instruction data high addr */
+               slic_reg32_write(&slic_regs->slic_rcv_wcs, (u8)instruction,
+                                FLUSH);
        }
-       kfree(dev);
-       pci_release_regions(pcidev);
+
+       /* download finished */
+       release_firmware(fw);
+       slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
+       return 0;
 }
 
-static int slic_entry_halt(struct net_device *dev)
+MODULE_FIRMWARE("slicoss/oasisrcvucode.sys");
+MODULE_FIRMWARE("slicoss/gbrcvucode.sys");
+
+static int slic_card_download(struct adapter *adapter)
 {
-       struct adapter *adapter = netdev_priv(dev);
-       struct sliccard *card = adapter->card;
+       const struct firmware *fw;
+       const char *file = "";
+       int ret;
+       u32 section;
+       int thissectionsize;
+       int codeaddr;
        __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+       u32 instruction;
+       u32 baseaddress;
+       u32 i;
+       u32 numsects = 0;
+       u32 sectsize[3];
+       u32 sectstart[3];
+       int ucode_start, index = 0;
 
-       spin_lock_irqsave(&slic_global.driver_lock.lock,
-                               slic_global.driver_lock.flags);
-       ASSERT(card);
-       netif_stop_queue(adapter->netdev);
-       adapter->state = ADAPT_DOWN;
-       adapter->linkstate = LINK_DOWN;
-       adapter->upr_list = NULL;
-       adapter->upr_busy = 0;
-       adapter->devflags_prev = 0;
-       ASSERT(card->adapter[adapter->cardindex] == adapter);
-       slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
-       adapter->all_reg_writes++;
-       adapter->icr_reg_writes++;
-       slic_config_clear(adapter);
-       if (adapter->activated) {
-               card->adapters_activated--;
-               slic_global.num_slic_ports_active--;
-               adapter->activated = 0;
+       switch (adapter->devid) {
+       case SLIC_2GB_DEVICE_ID:
+               file = "slicoss/oasisdownload.sys";
+               break;
+       case SLIC_1GB_DEVICE_ID:
+               file = "slicoss/gbdownload.sys";
+               break;
+       default:
+               ASSERT(0);
+               break;
        }
-#ifdef AUTOMATIC_RESET
-       slic_reg32_write(&slic_regs->slic_reset_iface, 0, FLUSH);
-#endif
-       /*
-        *  Reset the adapter's cmd queues
-        */
-       slic_cmdq_reset(adapter);
+       ret = request_firmware(&fw, file, &adapter->pcidev->dev);
+       if (ret) {
+               dev_err(&adapter->pcidev->dev,
+                       "SLICOSS: Failed to load firmware %s\n", file);
+               return ret;
+       }
+       numsects = *(u32 *)(fw->data + index);
+       index += 4;
+       ASSERT(numsects <= 3);
+       for (i = 0; i < numsects; i++) {
+               sectsize[i] = *(u32 *)(fw->data + index);
+               index += 4;
+       }
+       for (i = 0; i < numsects; i++) {
+               sectstart[i] = *(u32 *)(fw->data + index);
+               index += 4;
+       }
+       ucode_start = index;
+       instruction = *(u32 *)(fw->data + index);
+       index += 4;
+       for (section = 0; section < numsects; section++) {
+               baseaddress = sectstart[section];
+               thissectionsize = sectsize[section] >> 3;
 
-#ifdef AUTOMATIC_RESET
-       if (!card->adapters_activated)
-               slic_card_init(card, adapter);
-#endif
+               for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
+                       /* Write out instruction address */
+                       slic_reg32_write(&slic_regs->slic_wcs,
+                                        baseaddress + codeaddr, FLUSH);
+                       /* Write out instruction to low addr */
+                       slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+                       instruction = *(u32 *)(fw->data + index);
+                       index += 4;
 
-       spin_unlock_irqrestore(&slic_global.driver_lock.lock,
-                               slic_global.driver_lock.flags);
-       return STATUS_SUCCESS;
-}
+                       /* Write out instruction to high addr */
+                       slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+                       instruction = *(u32 *)(fw->data + index);
+                       index += 4;
+               }
+       }
+       index = ucode_start;
+       for (section = 0; section < numsects; section++) {
+               instruction = *(u32 *)(fw->data + index);
+               baseaddress = sectstart[section];
+               if (baseaddress < 0x8000)
+                       continue;
+               thissectionsize = sectsize[section] >> 3;
 
-static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct adapter *adapter = netdev_priv(dev);
-       struct ethtool_cmd edata;
-       struct ethtool_cmd ecmd;
-       u32 data[7];
-       u32 intagg;
+               for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
+                       /* Write out instruction address */
+                       slic_reg32_write(&slic_regs->slic_wcs,
+                               SLIC_WCS_COMPARE | (baseaddress + codeaddr),
+                               FLUSH);
+                       /* Write out instruction to low addr */
+                       slic_reg32_write(&slic_regs->slic_wcs, instruction,
+                                        FLUSH);
+                       instruction = *(u32 *)(fw->data + index);
+                       index += 4;
+                       /* Write out instruction to high addr */
+                       slic_reg32_write(&slic_regs->slic_wcs, instruction,
+                                        FLUSH);
+                       instruction = *(u32 *)(fw->data + index);
+                       index += 4;
 
-       ASSERT(rq);
-       switch (cmd) {
-       case SIOCSLICSETINTAGG:
-               if (copy_from_user(data, rq->ifr_data, 28))
-                       return -EFAULT;
-               intagg = data[0];
-               dev_err(&dev->dev, "%s: set interrupt aggregation to %d\n",
-                       __func__, intagg);
-               slic_intagg_set(adapter, intagg);
-               return 0;
+                       /* Check SRAM location zero. If it is non-zero. Abort.*/
+/*                     failure = readl((u32 __iomem *)&slic_regs->slic_reset);
+                       if (failure) {
+                               release_firmware(fw);
+                               return -EIO;
+                       }*/
+               }
+       }
+       release_firmware(fw);
+       /* Everything OK, kick off the card */
+       mdelay(10);
+       slic_reg32_write(&slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
 
-#ifdef SLIC_TRACE_DUMP_ENABLED
-       case SIOCSLICTRACEDUMP:
-               {
-                       u32 value;
-                       DBG_IOCTL("slic_ioctl  SIOCSLIC_TRACE_DUMP\n");
+       /* stall for 20 ms, long enough for ucode to init card
+          and reach mainloop */
+       mdelay(20);
 
-                       if (copy_from_user(data, rq->ifr_data, 28)) {
-                               PRINT_ERROR
-                                   ("slic: copy_from_user FAILED getting initial simba param\n");
-                               return -EFAULT;
-                       }
+       return 0;
+}
 
-                       value = data[0];
-                       if (tracemon_request == SLIC_DUMP_DONE) {
-                               PRINT_ERROR
-                                   ("ATK Diagnostic Trace Dump Requested\n");
-                               tracemon_request = SLIC_DUMP_REQUESTED;
-                               tracemon_request_type = value;
-                               tracemon_timestamp = jiffies;
-                       } else if ((tracemon_request == SLIC_DUMP_REQUESTED) ||
-                                  (tracemon_request ==
-                                   SLIC_DUMP_IN_PROGRESS)) {
-                               PRINT_ERROR
-                                   ("ATK Diagnostic Trace Dump Requested but already in progress... ignore\n");
-                       } else {
-                               PRINT_ERROR
-                                   ("ATK Diagnostic Trace Dump Requested\n");
-                               tracemon_request = SLIC_DUMP_REQUESTED;
-                               tracemon_request_type = value;
-                               tracemon_timestamp = jiffies;
-                       }
-                       return 0;
-               }
-#endif
-       case SIOCETHTOOL:
-               ASSERT(adapter);
-               if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
-                       return -EFAULT;
+MODULE_FIRMWARE("slicoss/oasisdownload.sys");
+MODULE_FIRMWARE("slicoss/gbdownload.sys");
 
-               if (ecmd.cmd == ETHTOOL_GSET) {
-                       edata.supported = (SUPPORTED_10baseT_Half |
-                                          SUPPORTED_10baseT_Full |
-                                          SUPPORTED_100baseT_Half |
-                                          SUPPORTED_100baseT_Full |
-                                          SUPPORTED_Autoneg | SUPPORTED_MII);
-                       edata.port = PORT_MII;
-                       edata.transceiver = XCVR_INTERNAL;
-                       edata.phy_address = 0;
-                       if (adapter->linkspeed == LINK_100MB)
-                               edata.speed = SPEED_100;
-                       else if (adapter->linkspeed == LINK_10MB)
-                               edata.speed = SPEED_10;
-                       else
-                               edata.speed = 0;
-
-                       if (adapter->linkduplex == LINK_FULLD)
-                               edata.duplex = DUPLEX_FULL;
-                       else
-                               edata.duplex = DUPLEX_HALF;
-
-                       edata.autoneg = AUTONEG_ENABLE;
-                       edata.maxtxpkt = 1;
-                       edata.maxrxpkt = 1;
-                       if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
-                               return -EFAULT;
-
-               } else if (ecmd.cmd == ETHTOOL_SSET) {
-                       if (!capable(CAP_NET_ADMIN))
-                               return -EPERM;
-
-                       if (adapter->linkspeed == LINK_100MB)
-                               edata.speed = SPEED_100;
-                       else if (adapter->linkspeed == LINK_10MB)
-                               edata.speed = SPEED_10;
-                       else
-                               edata.speed = 0;
-
-                       if (adapter->linkduplex == LINK_FULLD)
-                               edata.duplex = DUPLEX_FULL;
-                       else
-                               edata.duplex = DUPLEX_HALF;
-
-                       edata.autoneg = AUTONEG_ENABLE;
-                       edata.maxtxpkt = 1;
-                       edata.maxrxpkt = 1;
-                       if ((ecmd.speed != edata.speed) ||
-                           (ecmd.duplex != edata.duplex)) {
-                               u32 speed;
-                               u32 duplex;
+static void slic_adapter_set_hwaddr(struct adapter *adapter)
+{
+       struct sliccard *card = adapter->card;
 
-                               if (ecmd.speed == SPEED_10)
-                                       speed = 0;
-                               else
-                                       speed = PCR_SPEED_100;
-                               if (ecmd.duplex == DUPLEX_FULL)
-                                       duplex = PCR_DUPLEX_FULL;
-                               else
-                                       duplex = 0;
-                               slic_link_config(adapter, speed, duplex);
-                               slic_link_event_handler(adapter);
-                       }
+       if ((adapter->card) && (card->config_set)) {
+               memcpy(adapter->macaddr,
+                      card->config.MacInfo[adapter->functionnumber].macaddrA,
+                      sizeof(struct slic_config_mac));
+               if (!(adapter->currmacaddr[0] || adapter->currmacaddr[1] ||
+                     adapter->currmacaddr[2] || adapter->currmacaddr[3] ||
+                     adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
+                       memcpy(adapter->currmacaddr, adapter->macaddr, 6);
+               }
+               if (adapter->netdev) {
+                       memcpy(adapter->netdev->dev_addr, adapter->currmacaddr,
+                              6);
                }
-               return 0;
-       default:
-               return -EOPNOTSUPP;
        }
 }
 
-#define  XMIT_FAIL_LINK_STATE               1
-#define  XMIT_FAIL_ZERO_LENGTH              2
-#define  XMIT_FAIL_HOSTCMD_FAIL             3
-
-static void slic_xmit_build_request(struct adapter *adapter,
-                            struct slic_hostcmd *hcmd, struct sk_buff *skb)
+static void slic_intagg_set(struct adapter *adapter, u32 value)
 {
-       struct slic_host64_cmd *ihcmd;
-       ulong phys_addr;
+       slic_reg32_write(&adapter->slic_regs->slic_intagg, value, FLUSH);
+       adapter->card->loadlevel_current = value;
+}
 
-       ihcmd = &hcmd->cmd64;
+static void slic_soft_reset(struct adapter *adapter)
+{
+       if (adapter->card->state == CARD_UP) {
+               slic_reg32_write(&adapter->slic_regs->slic_quiesce, 0, FLUSH);
+               mdelay(1);
+       }
 
-       ihcmd->flags = (adapter->port << IHFLG_IFSHFT);
-       ihcmd->command = IHCMD_XMT_REQ;
-       ihcmd->u.slic_buffers.totlen = skb->len;
-       phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len,
-                       PCI_DMA_TODEVICE);
-       ihcmd->u.slic_buffers.bufs[0].paddrl = SLIC_GET_ADDR_LOW(phys_addr);
-       ihcmd->u.slic_buffers.bufs[0].paddrh = SLIC_GET_ADDR_HIGH(phys_addr);
-       ihcmd->u.slic_buffers.bufs[0].length = skb->len;
-#if defined(CONFIG_X86_64)
-       hcmd->cmdsize = (u32) ((((u64)&ihcmd->u.slic_buffers.bufs[1] -
-                                    (u64) hcmd) + 31) >> 5);
-#elif defined(CONFIG_X86)
-       hcmd->cmdsize = ((((u32) &ihcmd->u.slic_buffers.bufs[1] -
-                          (u32) hcmd) + 31) >> 5);
-#else
-       Stop Compilation;
-#endif
+       slic_reg32_write(&adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC,
+                        FLUSH);
+       mdelay(1);
 }
 
-#define NORMAL_ETHFRAME     0
-
-static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static void slic_mac_address_config(struct adapter *adapter)
 {
-       struct sliccard *card;
-       struct adapter *adapter = netdev_priv(dev);
-       struct slic_hostcmd *hcmd = NULL;
-       u32 status = 0;
-       u32 skbtype = NORMAL_ETHFRAME;
-       void *offloadcmd = NULL;
+       u32 value;
+       u32 value2;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
-       card = adapter->card;
-       ASSERT(card);
-       if ((adapter->linkstate != LINK_UP) ||
-           (adapter->state != ADAPT_UP) || (card->state != CARD_UP)) {
-               status = XMIT_FAIL_LINK_STATE;
-               goto xmit_fail;
+       value = *(u32 *) &adapter->currmacaddr[2];
+       value = ntohl(value);
+       slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH);
+       slic_reg32_write(&slic_regs->slic_wraddrbl, value, FLUSH);
 
-       } else if (skb->len == 0) {
-               status = XMIT_FAIL_ZERO_LENGTH;
-               goto xmit_fail;
-       }
+       value2 = (u32) ((adapter->currmacaddr[0] << 8 |
+                            adapter->currmacaddr[1]) & 0xFFFF);
 
-       if (skbtype == NORMAL_ETHFRAME) {
-               hcmd = slic_cmdq_getfree(adapter);
-               if (!hcmd) {
-                       adapter->xmitq_full = 1;
-                       status = XMIT_FAIL_HOSTCMD_FAIL;
-                       goto xmit_fail;
-               }
-               ASSERT(hcmd->pslic_handle);
-               ASSERT(hcmd->cmd64.hosthandle ==
-                      hcmd->pslic_handle->token.handle_token);
-               hcmd->skb = skb;
-               hcmd->busy = 1;
-               hcmd->type = SLIC_CMD_DUMB;
-               if (skbtype == NORMAL_ETHFRAME)
-                       slic_xmit_build_request(adapter, hcmd, skb);
-       }
-       adapter->stats.tx_packets++;
-       adapter->stats.tx_bytes += skb->len;
+       slic_reg32_write(&slic_regs->slic_wraddrah, value2, FLUSH);
+       slic_reg32_write(&slic_regs->slic_wraddrbh, value2, FLUSH);
 
-#ifdef DEBUG_DUMP
-       if (adapter->kill_card) {
-               struct slic_host64_cmd ihcmd;
+       /* Write our multicast mask out to the card.  This is done */
+       /* here in addition to the slic_mcast_addr_set routine     */
+       /* because ALL_MCAST may have been enabled or disabled     */
+       slic_mcast_set_mask(adapter);
+}
 
-               ihcmd = &hcmd->cmd64;
+static void slic_mac_config(struct adapter *adapter)
+{
+       u32 value;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
-               ihcmd->flags |= 0x40;
-               adapter->kill_card = 0; /* only do this once */
-       }
-#endif
-       if (hcmd->paddrh == 0) {
-               slic_reg32_write(&adapter->slic_regs->slic_cbar,
-                                (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
+       /* Setup GMAC gaps */
+       if (adapter->linkspeed == LINK_1000MB) {
+               value = ((GMCR_GAPBB_1000 << GMCR_GAPBB_SHIFT) |
+                        (GMCR_GAPR1_1000 << GMCR_GAPR1_SHIFT) |
+                        (GMCR_GAPR2_1000 << GMCR_GAPR2_SHIFT));
        } else {
-               slic_reg64_write(adapter, &adapter->slic_regs->slic_cbar64,
-                                (hcmd->paddrl | hcmd->cmdsize),
-                                &adapter->slic_regs->slic_addr_upper,
-                                hcmd->paddrh, DONT_FLUSH);
+               value = ((GMCR_GAPBB_100 << GMCR_GAPBB_SHIFT) |
+                        (GMCR_GAPR1_100 << GMCR_GAPR1_SHIFT) |
+                        (GMCR_GAPR2_100 << GMCR_GAPR2_SHIFT));
        }
-xmit_done:
-       return NETDEV_TX_OK;
-xmit_fail:
-       slic_xmit_fail(adapter, skb, offloadcmd, skbtype, status);
-       goto xmit_done;
-}
 
-static void slic_xmit_fail(struct adapter *adapter,
-                   struct sk_buff *skb,
-                   void *cmd, u32 skbtype, u32 status)
-{
-       if (adapter->xmitq_full)
-               netif_stop_queue(adapter->netdev);
-       if ((cmd == NULL) && (status <= XMIT_FAIL_HOSTCMD_FAIL)) {
-               switch (status) {
-               case XMIT_FAIL_LINK_STATE:
-                       dev_err(&adapter->netdev->dev,
-                               "reject xmit skb[%p: %x] linkstate[%s] "
-                               "adapter[%s:%d] card[%s:%d]\n",
-                               skb, skb->pkt_type,
-                               SLIC_LINKSTATE(adapter->linkstate),
-                               SLIC_ADAPTER_STATE(adapter->state),
-                               adapter->state,
-                               SLIC_CARD_STATE(adapter->card->state),
-                               adapter->card->state);
-                       break;
-               case XMIT_FAIL_ZERO_LENGTH:
-                       dev_err(&adapter->netdev->dev,
-                               "xmit_start skb->len == 0 skb[%p] type[%x]\n",
-                               skb, skb->pkt_type);
-                       break;
-               case XMIT_FAIL_HOSTCMD_FAIL:
-                       dev_err(&adapter->netdev->dev,
-                               "xmit_start skb[%p] type[%x] No host commands "
-                               "available\n", skb, skb->pkt_type);
-                       break;
-               default:
-                       ASSERT(0);
-               }
+       /* enable GMII */
+       if (adapter->linkspeed == LINK_1000MB)
+               value |= GMCR_GBIT;
+
+       /* enable fullduplex */
+       if ((adapter->linkduplex == LINK_FULLD)
+           || (adapter->macopts & MAC_LOOPBACK)) {
+               value |= GMCR_FULLD;
        }
-       dev_kfree_skb(skb);
-       adapter->stats.tx_dropped++;
+
+       /* write mac config */
+       slic_reg32_write(&slic_regs->slic_wmcfg, value, FLUSH);
+
+       /* setup mac addresses */
+       slic_mac_address_config(adapter);
 }
 
-static void slic_rcv_handle_error(struct adapter *adapter,
-                                       struct slic_rcvbuf *rcvbuf)
+static void slic_config_set(struct adapter *adapter, bool linkchange)
 {
-       struct slic_hddr_wds *hdr = (struct slic_hddr_wds *)rcvbuf->data;
-
-       if (adapter->devid != SLIC_1GB_DEVICE_ID) {
-               if (hdr->frame_status14 & VRHSTAT_802OE)
-                       adapter->if_events.oflow802++;
-               if (hdr->frame_status14 & VRHSTAT_TPOFLO)
-                       adapter->if_events.Tprtoflow++;
-               if (hdr->frame_status_b14 & VRHSTATB_802UE)
-                       adapter->if_events.uflow802++;
-               if (hdr->frame_status_b14 & VRHSTATB_RCVE) {
-                       adapter->if_events.rcvearly++;
-                       adapter->stats.rx_fifo_errors++;
-               }
-               if (hdr->frame_status_b14 & VRHSTATB_BUFF) {
-                       adapter->if_events.Bufov++;
-                       adapter->stats.rx_over_errors++;
-               }
-               if (hdr->frame_status_b14 & VRHSTATB_CARRE) {
-                       adapter->if_events.Carre++;
-                       adapter->stats.tx_carrier_errors++;
-               }
-               if (hdr->frame_status_b14 & VRHSTATB_LONGE)
-                       adapter->if_events.Longe++;
-               if (hdr->frame_status_b14 & VRHSTATB_PREA)
-                       adapter->if_events.Invp++;
-               if (hdr->frame_status_b14 & VRHSTATB_CRC) {
-                       adapter->if_events.Crc++;
-                       adapter->stats.rx_crc_errors++;
-               }
-               if (hdr->frame_status_b14 & VRHSTATB_DRBL)
-                       adapter->if_events.Drbl++;
-               if (hdr->frame_status_b14 & VRHSTATB_CODE)
-                       adapter->if_events.Code++;
-               if (hdr->frame_status_b14 & VRHSTATB_TPCSUM)
-                       adapter->if_events.TpCsum++;
-               if (hdr->frame_status_b14 & VRHSTATB_TPHLEN)
-                       adapter->if_events.TpHlen++;
-               if (hdr->frame_status_b14 & VRHSTATB_IPCSUM)
-                       adapter->if_events.IpCsum++;
-               if (hdr->frame_status_b14 & VRHSTATB_IPLERR)
-                       adapter->if_events.IpLen++;
-               if (hdr->frame_status_b14 & VRHSTATB_IPHERR)
-                       adapter->if_events.IpHlen++;
+       u32 value;
+       u32 RcrReset;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+       if (linkchange) {
+               /* Setup MAC */
+               slic_mac_config(adapter);
+               RcrReset = GRCR_RESET;
        } else {
-               if (hdr->frame_statusGB & VGBSTAT_XPERR) {
-                       u32 xerr = hdr->frame_statusGB >> VGBSTAT_XERRSHFT;
+               slic_mac_address_config(adapter);
+               RcrReset = 0;
+       }
 
-                       if (xerr == VGBSTAT_XCSERR)
-                               adapter->if_events.TpCsum++;
-                       if (xerr == VGBSTAT_XUFLOW)
-                               adapter->if_events.Tprtoflow++;
-                       if (xerr == VGBSTAT_XHLEN)
-                               adapter->if_events.TpHlen++;
-               }
-               if (hdr->frame_statusGB & VGBSTAT_NETERR) {
-                       u32 nerr =
-                           (hdr->
-                            frame_statusGB >> VGBSTAT_NERRSHFT) &
-                           VGBSTAT_NERRMSK;
-                       if (nerr == VGBSTAT_NCSERR)
-                               adapter->if_events.IpCsum++;
-                       if (nerr == VGBSTAT_NUFLOW)
-                               adapter->if_events.IpLen++;
-                       if (nerr == VGBSTAT_NHLEN)
-                               adapter->if_events.IpHlen++;
-               }
-               if (hdr->frame_statusGB & VGBSTAT_LNKERR) {
-                       u32 lerr = hdr->frame_statusGB & VGBSTAT_LERRMSK;
+       if (adapter->linkduplex == LINK_FULLD) {
+               /* setup xmtcfg */
+               value = (GXCR_RESET |   /* Always reset     */
+                        GXCR_XMTEN |   /* Enable transmit  */
+                        GXCR_PAUSEEN); /* Enable pause     */
 
-                       if (lerr == VGBSTAT_LDEARLY)
-                               adapter->if_events.rcvearly++;
-                       if (lerr == VGBSTAT_LBOFLO)
-                               adapter->if_events.Bufov++;
-                       if (lerr == VGBSTAT_LCODERR)
-                               adapter->if_events.Code++;
-                       if (lerr == VGBSTAT_LDBLNBL)
-                               adapter->if_events.Drbl++;
-                       if (lerr == VGBSTAT_LCRCERR)
-                               adapter->if_events.Crc++;
-                       if (lerr == VGBSTAT_LOFLO)
-                               adapter->if_events.oflow802++;
-                       if (lerr == VGBSTAT_LUFLO)
-                               adapter->if_events.uflow802++;
-               }
+               slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+
+               /* Setup rcvcfg last */
+               value = (RcrReset |     /* Reset, if linkchange */
+                        GRCR_CTLEN |   /* Enable CTL frames    */
+                        GRCR_ADDRAEN | /* Address A enable     */
+                        GRCR_RCVBAD |  /* Rcv bad frames       */
+                        (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
+       } else {
+               /* setup xmtcfg */
+               value = (GXCR_RESET |   /* Always reset     */
+                        GXCR_XMTEN);   /* Enable transmit  */
+
+               slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+
+               /* Setup rcvcfg last */
+               value = (RcrReset |     /* Reset, if linkchange */
+                        GRCR_ADDRAEN | /* Address A enable     */
+                        GRCR_RCVBAD |  /* Rcv bad frames       */
+                        (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
        }
-       return;
+
+       if (adapter->state != ADAPT_DOWN) {
+               /* Only enable receive if we are restarting or running */
+               value |= GRCR_RCVEN;
+       }
+
+       if (adapter->macopts & MAC_PROMISC)
+               value |= GRCR_RCVALL;
+
+       slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
 }
 
-#define TCP_OFFLOAD_FRAME_PUSHFLAG  0x10000000
-#define M_FAST_PATH                 0x0040
+/*
+ *  Turn off RCV and XMT, power down PHY
+ */
+static void slic_config_clear(struct adapter *adapter)
+{
+       u32 value;
+       u32 phy_config;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
-static void slic_rcv_handler(struct adapter *adapter)
+       /* Setup xmtcfg */
+       value = (GXCR_RESET |   /* Always reset */
+                GXCR_PAUSEEN); /* Enable pause */
+
+       slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+
+       value = (GRCR_RESET |   /* Always reset      */
+                GRCR_CTLEN |   /* Enable CTL frames */
+                GRCR_ADDRAEN | /* Address A enable  */
+                (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
+
+       slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
+
+       /* power down phy */
+       phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN));
+       slic_reg32_write(&slic_regs->slic_wphy, phy_config, FLUSH);
+}
+
+static bool slic_mac_filter(struct adapter *adapter,
+                       struct ether_header *ether_frame)
 {
-       struct sk_buff *skb;
-       struct slic_rcvbuf *rcvbuf;
-       u32 frames = 0;
+       struct net_device *netdev = adapter->netdev;
+       u32 opts = adapter->macopts;
+       u32 *dhost4 = (u32 *)&ether_frame->ether_dhost[0];
+       u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
 
-       while ((skb = slic_rcvqueue_getnext(adapter))) {
-               u32 rx_bytes;
+       if (opts & MAC_PROMISC)
+               return true;
 
-               ASSERT(skb->head);
-               rcvbuf = (struct slic_rcvbuf *)skb->head;
-               adapter->card->events++;
-               if (rcvbuf->status & IRHDDR_ERR) {
-                       adapter->rx_errors++;
-                       slic_rcv_handle_error(adapter, rcvbuf);
-                       slic_rcvqueue_reinsert(adapter, skb);
-                       continue;
+       if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) {
+               if (opts & MAC_BCAST) {
+                       adapter->rcv_broadcasts++;
+                       return true;
+               } else {
+                       return false;
                }
+       }
 
-               if (!slic_mac_filter(adapter, (struct ether_header *)
-                                       rcvbuf->data)) {
-                       slic_rcvqueue_reinsert(adapter, skb);
-                       continue;
+       if (ether_frame->ether_dhost[0] & 0x01) {
+               if (opts & MAC_ALLMCAST) {
+                       adapter->rcv_multicasts++;
+                       netdev->stats.multicast++;
+                       return true;
                }
-               skb_pull(skb, SLIC_RCVBUF_HEADSIZE);
-               rx_bytes = (rcvbuf->length & IRHDDR_FLEN_MSK);
-               skb_put(skb, rx_bytes);
-               adapter->stats.rx_packets++;
-               adapter->stats.rx_bytes += rx_bytes;
-#if SLIC_OFFLOAD_IP_CHECKSUM
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-#endif
-
-               skb->dev = adapter->netdev;
-               skb->protocol = eth_type_trans(skb, skb->dev);
-               netif_rx(skb);
+               if (opts & MAC_MCAST) {
+                       struct mcast_address *mcaddr = adapter->mcastaddrs;
 
-               ++frames;
-#if SLIC_INTERRUPT_PROCESS_LIMIT
-               if (frames >= SLIC_RCVQ_MAX_PROCESS_ISR) {
-                       adapter->rcv_interrupt_yields++;
-                       break;
+                       while (mcaddr) {
+                               if (!compare_ether_addr(mcaddr->address,
+                                                       ether_frame->ether_dhost)) {
+                                       adapter->rcv_multicasts++;
+                                       netdev->stats.multicast++;
+                                       return true;
+                               }
+                               mcaddr = mcaddr->next;
+                       }
+                       return false;
+               } else {
+                       return false;
                }
-#endif
        }
-       adapter->max_isr_rcvs = max(adapter->max_isr_rcvs, frames);
+       if (opts & MAC_DIRECTED) {
+               adapter->rcv_unicasts++;
+               return true;
+       }
+       return false;
+
 }
 
-static void slic_xmit_complete(struct adapter *adapter)
+static int slic_mac_set_address(struct net_device *dev, void *ptr)
 {
-       struct slic_hostcmd *hcmd;
-       struct slic_rspbuf *rspbuf;
-       u32 frames = 0;
-       struct slic_handle_word slic_handle_word;
+       struct adapter *adapter = netdev_priv(dev);
+       struct sockaddr *addr = ptr;
 
-       do {
-               rspbuf = slic_rspqueue_getnext(adapter);
-               if (!rspbuf)
-                       break;
-               adapter->xmit_completes++;
-               adapter->card->events++;
-               /*
-                Get the complete host command buffer
-               */
-               slic_handle_word.handle_token = rspbuf->hosthandle;
-               ASSERT(slic_handle_word.handle_index);
-               ASSERT(slic_handle_word.handle_index <= SLIC_CMDQ_MAXCMDS);
-               hcmd =
-                   (struct slic_hostcmd *)
-                       adapter->slic_handles[slic_handle_word.handle_index].
-                                                                       address;
-/*      hcmd = (struct slic_hostcmd *) rspbuf->hosthandle; */
-               ASSERT(hcmd);
-               ASSERT(hcmd->pslic_handle ==
-                      &adapter->slic_handles[slic_handle_word.handle_index]);
-               if (hcmd->type == SLIC_CMD_DUMB) {
-                       if (hcmd->skb)
-                               dev_kfree_skb_irq(hcmd->skb);
-                       slic_cmdq_putdone_irq(adapter, hcmd);
-               }
-               rspbuf->status = 0;
-               rspbuf->hosthandle = 0;
-               frames++;
-       } while (1);
-       adapter->max_isr_xmits = max(adapter->max_isr_xmits, frames);
-}
-
-static irqreturn_t slic_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = (struct net_device *)dev_id;
-       struct adapter *adapter = netdev_priv(dev);
-       u32 isr;
+       if (netif_running(dev))
+               return -EBUSY;
+       if (!adapter)
+               return -EBUSY;
 
-       if ((adapter->pshmem) && (adapter->pshmem->isr)) {
-               slic_reg32_write(&adapter->slic_regs->slic_icr,
-                                ICR_INT_MASK, FLUSH);
-               isr = adapter->isrcopy = adapter->pshmem->isr;
-               adapter->pshmem->isr = 0;
-               adapter->num_isrs++;
-               switch (adapter->card->state) {
-               case CARD_UP:
-                       if (isr & ~ISR_IO) {
-                               if (isr & ISR_ERR) {
-                                       adapter->error_interrupts++;
-                                       if (isr & ISR_RMISS) {
-                                               int count;
-                                               int pre_count;
-                                               int errors;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EINVAL;
 
-                                               struct slic_rcvqueue *rcvq =
-                                                   &adapter->rcvqueue;
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
 
-                                               adapter->
-                                                   error_rmiss_interrupts++;
-                                               if (!rcvq->errors)
-                                                       rcv_count = rcvq->count;
-                                               pre_count = rcvq->count;
-                                               errors = rcvq->errors;
+       slic_config_set(adapter, true);
+       return 0;
+}
 
-                                               while (rcvq->count <
-                                                      SLIC_RCVQ_FILLTHRESH) {
-                                                       count =
-                                                           slic_rcvqueue_fill
-                                                           (adapter);
-                                                       if (!count)
-                                                               break;
-                                               }
-                                       } else if (isr & ISR_XDROP) {
-                                               dev_err(&dev->dev,
-                                                       "isr & ISR_ERR [%x] "
-                                                       "ISR_XDROP \n", isr);
-                                       } else {
-                                               dev_err(&dev->dev,
-                                                       "isr & ISR_ERR [%x]\n",
-                                                       isr);
-                                       }
-                               }
+static void slic_timer_load_check(ulong cardaddr)
+{
+       struct sliccard *card = (struct sliccard *)cardaddr;
+       struct adapter *adapter = card->master;
+       u32 __iomem *intagg;
+       u32 load = card->events;
+       u32 level = 0;
 
-                               if (isr & ISR_LEVENT) {
-                                       adapter->linkevent_interrupts++;
-                                       slic_link_event_handler(adapter);
-                               }
+       intagg = &adapter->slic_regs->slic_intagg;
 
-                               if ((isr & ISR_UPC) ||
-                                   (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
-                                       adapter->upr_interrupts++;
-                                       slic_upr_request_complete(adapter, isr);
-                               }
+       if ((adapter) && (adapter->state == ADAPT_UP) &&
+           (card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
+               if (adapter->devid == SLIC_1GB_DEVICE_ID) {
+                       if (adapter->linkspeed == LINK_1000MB)
+                               level = 100;
+                       else {
+                               if (load > SLIC_LOAD_5)
+                                       level = SLIC_INTAGG_5;
+                               else if (load > SLIC_LOAD_4)
+                                       level = SLIC_INTAGG_4;
+                               else if (load > SLIC_LOAD_3)
+                                       level = SLIC_INTAGG_3;
+                               else if (load > SLIC_LOAD_2)
+                                       level = SLIC_INTAGG_2;
+                               else if (load > SLIC_LOAD_1)
+                                       level = SLIC_INTAGG_1;
+                               else
+                                       level = SLIC_INTAGG_0;
                        }
-
-                       if (isr & ISR_RCV) {
-                               adapter->rcv_interrupts++;
-                               slic_rcv_handler(adapter);
+                       if (card->loadlevel_current != level) {
+                               card->loadlevel_current = level;
+                               slic_reg32_write(intagg, level, FLUSH);
                        }
-
-                       if (isr & ISR_CMD) {
-                               adapter->xmit_interrupts++;
-                               slic_xmit_complete(adapter);
+               } else {
+                       if (load > SLIC_LOAD_5)
+                               level = SLIC_INTAGG_5;
+                       else if (load > SLIC_LOAD_4)
+                               level = SLIC_INTAGG_4;
+                       else if (load > SLIC_LOAD_3)
+                               level = SLIC_INTAGG_3;
+                       else if (load > SLIC_LOAD_2)
+                               level = SLIC_INTAGG_2;
+                       else if (load > SLIC_LOAD_1)
+                               level = SLIC_INTAGG_1;
+                       else
+                               level = SLIC_INTAGG_0;
+                       if (card->loadlevel_current != level) {
+                               card->loadlevel_current = level;
+                               slic_reg32_write(intagg, level, FLUSH);
                        }
-                       break;
+               }
+       }
+       card->events = 0;
+       card->loadtimer.expires = jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
+       add_timer(&card->loadtimer);
+}
 
-               case CARD_DOWN:
-                       if ((isr & ISR_UPC) ||
-                           (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
-                               adapter->upr_interrupts++;
-                               slic_upr_request_complete(adapter, isr);
-                       }
-                       break;
+static int slic_upr_queue_request(struct adapter *adapter,
+                          u32 upr_request,
+                          u32 upr_data,
+                          u32 upr_data_h,
+                          u32 upr_buffer, u32 upr_buffer_h)
+{
+       struct slic_upr *upr;
+       struct slic_upr *uprqueue;
 
-               default:
-                       break;
-               }
+       upr = kmalloc(sizeof(struct slic_upr), GFP_ATOMIC);
+       if (!upr)
+               return -ENOMEM;
 
-               adapter->isrcopy = 0;
-               adapter->all_reg_writes += 2;
-               adapter->isr_reg_writes++;
-               slic_reg32_write(&adapter->slic_regs->slic_isr, 0, FLUSH);
+       upr->adapter = adapter->port;
+       upr->upr_request = upr_request;
+       upr->upr_data = upr_data;
+       upr->upr_buffer = upr_buffer;
+       upr->upr_data_h = upr_data_h;
+       upr->upr_buffer_h = upr_buffer_h;
+       upr->next = NULL;
+       if (adapter->upr_list) {
+               uprqueue = adapter->upr_list;
+
+               while (uprqueue->next)
+                       uprqueue = uprqueue->next;
+               uprqueue->next = upr;
        } else {
-               adapter->false_interrupts++;
+               adapter->upr_list = upr;
        }
-       return IRQ_HANDLED;
+       return 0;
 }
 
-/*
- * slic_link_event_handler -
- *
- * Initiate a link configuration sequence.  The link configuration begins
- * by issuing a READ_LINK_STATUS command to the Utility Processor on the
- * SLIC.  Since the command finishes asynchronously, the slic_upr_comlete
- * routine will follow it up witha UP configuration write command, which
- * will also complete asynchronously.
- *
- */
-static void slic_link_event_handler(struct adapter *adapter)
+static void slic_upr_start(struct adapter *adapter)
 {
-       int status;
-       struct slic_shmem *pshmem;
-
-       if (adapter->state != ADAPT_UP) {
-               /* Adapter is not operational.  Ignore.  */
+       struct slic_upr *upr;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+/*
+    char * ptr1;
+    char * ptr2;
+    uint cmdoffset;
+*/
+       upr = adapter->upr_list;
+       if (!upr)
                return;
-       }
+       if (adapter->upr_busy)
+               return;
+       adapter->upr_busy = 1;
 
-       pshmem = (struct slic_shmem *)adapter->phys_shmem;
+       switch (upr->upr_request) {
+       case SLIC_UPR_STATS:
+               if (upr->upr_data_h == 0) {
+                       slic_reg32_write(&slic_regs->slic_stats, upr->upr_data,
+                                        FLUSH);
+               } else {
+                       slic_reg64_write(adapter, &slic_regs->slic_stats64,
+                                        upr->upr_data,
+                                        &slic_regs->slic_addr_upper,
+                                        upr->upr_data_h, FLUSH);
+               }
+               break;
 
-#if defined(CONFIG_X86_64)
-       status = slic_upr_request(adapter,
-                                 SLIC_UPR_RLSR,
-                                 SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
-                                 SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
-                                 0, 0);
-#elif defined(CONFIG_X86)
-       status = slic_upr_request(adapter, SLIC_UPR_RLSR,
-               (u32) &pshmem->linkstatus,      /* no 4GB wrap guaranteed */
-                                 0, 0, 0);
-#else
-       Stop compilation;
-#endif
-       ASSERT((status == STATUS_SUCCESS) || (status == STATUS_PENDING));
+       case SLIC_UPR_RLSR:
+               slic_reg64_write(adapter, &slic_regs->slic_rlsr, upr->upr_data,
+                                &slic_regs->slic_addr_upper, upr->upr_data_h,
+                                FLUSH);
+               break;
+
+       case SLIC_UPR_RCONFIG:
+               slic_reg64_write(adapter, &slic_regs->slic_rconfig,
+                                upr->upr_data, &slic_regs->slic_addr_upper,
+                                upr->upr_data_h, FLUSH);
+               break;
+       case SLIC_UPR_PING:
+               slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH);
+               break;
+       default:
+               ASSERT(0);
+       }
 }
 
-static void slic_init_cleanup(struct adapter *adapter)
+static int slic_upr_request(struct adapter *adapter,
+                    u32 upr_request,
+                    u32 upr_data,
+                    u32 upr_data_h,
+                    u32 upr_buffer, u32 upr_buffer_h)
 {
-       if (adapter->intrregistered) {
-               adapter->intrregistered = 0;
-               free_irq(adapter->netdev->irq, adapter->netdev);
+       int rc;
 
-       }
-       if (adapter->pshmem) {
-               pci_free_consistent(adapter->pcidev,
-                                   sizeof(struct slic_shmem),
-                                   adapter->pshmem, adapter->phys_shmem);
-               adapter->pshmem = NULL;
-               adapter->phys_shmem = (dma_addr_t) NULL;
-       }
-
-       if (adapter->pingtimerset) {
-               adapter->pingtimerset = 0;
-               del_timer(&adapter->pingtimer);
-       }
+       spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
+       rc = slic_upr_queue_request(adapter,
+                                       upr_request,
+                                       upr_data,
+                                       upr_data_h, upr_buffer, upr_buffer_h);
+       if (rc)
+               goto err_unlock_irq;
 
-       slic_rspqueue_free(adapter);
-       slic_cmdq_free(adapter);
-       slic_rcvqueue_free(adapter);
+       slic_upr_start(adapter);
+err_unlock_irq:
+       spin_unlock_irqrestore(&adapter->upr_lock.lock,
+                               adapter->upr_lock.flags);
+       return rc;
 }
 
-static struct net_device_stats *slic_get_stats(struct net_device *dev)
+static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
 {
-       struct adapter *adapter = netdev_priv(dev);
-
-       ASSERT(adapter);
-       dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions;
-       dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors;
-       dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors;
-       dev->stats.rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
-       dev->stats.tx_heartbeat_errors = 0;
-       dev->stats.tx_aborted_errors = 0;
-       dev->stats.tx_window_errors = 0;
-       dev->stats.tx_fifo_errors = 0;
-       dev->stats.rx_frame_errors = 0;
-       dev->stats.rx_length_errors = 0;
-
-       return &dev->stats;
-}
+       u32 linkstatus = adapter->pshmem->linkstatus;
+       uint linkup;
+       unsigned char linkspeed;
+       unsigned char linkduplex;
 
-/*
- *  Allocate a mcast_address structure to hold the multicast address.
- *  Link it in.
- */
-static int slic_mcast_add_list(struct adapter *adapter, char *address)
-{
-       struct mcast_address *mcaddr, *mlist;
+       if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
+               struct slic_shmem *pshmem;
 
-       /* Check to see if it already exists */
-       mlist = adapter->mcastaddrs;
-       while (mlist) {
-               if (!compare_ether_addr(mlist->address, address))
-                       return STATUS_SUCCESS;
-               mlist = mlist->next;
+               pshmem = (struct slic_shmem *)adapter->phys_shmem;
+#if defined(CONFIG_X86_64)
+               slic_upr_queue_request(adapter,
+                                      SLIC_UPR_RLSR,
+                                      SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
+                                      SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
+                                      0, 0);
+#elif defined(CONFIG_X86)
+               slic_upr_queue_request(adapter,
+                                      SLIC_UPR_RLSR,
+                                      (u32) &pshmem->linkstatus,
+                                      SLIC_GET_ADDR_HIGH(pshmem), 0, 0);
+#else
+               Stop Compilation;
+#endif
+               return;
        }
+       if (adapter->state != ADAPT_UP)
+               return;
 
-       /* Doesn't already exist.  Allocate a structure to hold it */
-       mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
-       if (mcaddr == NULL)
-               return 1;
+       ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
+              || (adapter->devid == SLIC_2GB_DEVICE_ID));
 
-       memcpy(mcaddr->address, address, 6);
+       linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
+       if (linkstatus & GIG_SPEED_1000)
+               linkspeed = LINK_1000MB;
+       else if (linkstatus & GIG_SPEED_100)
+               linkspeed = LINK_100MB;
+       else
+               linkspeed = LINK_10MB;
 
-       mcaddr->next = adapter->mcastaddrs;
-       adapter->mcastaddrs = mcaddr;
+       if (linkstatus & GIG_FULLDUPLEX)
+               linkduplex = LINK_FULLD;
+       else
+               linkduplex = LINK_HALFD;
 
-       return STATUS_SUCCESS;
-}
+       if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN))
+               return;
 
-/*
- * Functions to obtain the CRC corresponding to the destination mac address.
- * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
- * the polynomial:
- *   x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 +
- *   x^4 + x^2 + x^1.
- *
- * After the CRC for the 6 bytes is generated (but before the value is
- * complemented),
- * we must then transpose the value and return bits 30-23.
- *
- */
-static u32 slic_crc_table[256];        /* Table of CRCs for all possible byte values */
-static u32 slic_crc_init;      /* Is table initialized */
+       /* link up event, but nothing has changed */
+       if ((adapter->linkstate == LINK_UP) &&
+           (linkup == LINK_UP) &&
+           (adapter->linkspeed == linkspeed) &&
+           (adapter->linkduplex == linkduplex))
+               return;
 
-/*
- *  Contruct the CRC32 table
- */
-static void slic_mcast_init_crc32(void)
-{
-       u32 c;          /*  CRC shit reg                 */
-       u32 e = 0;              /*  Poly X-or pattern            */
-       int i;                  /*  counter                      */
-       int k;                  /*  byte being shifted into crc  */
+       /* link has changed at this point */
 
-       static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
+       /* link has gone from up to down */
+       if (linkup == LINK_DOWN) {
+               adapter->linkstate = LINK_DOWN;
+               return;
+       }
 
-       for (i = 0; i < ARRAY_SIZE(p); i++)
-               e |= 1L << (31 - p[i]);
+       /* link has gone from down to up */
+       adapter->linkspeed = linkspeed;
+       adapter->linkduplex = linkduplex;
 
-       for (i = 1; i < 256; i++) {
-               c = i;
-               for (k = 8; k; k--)
-                       c = c & 1 ? (c >> 1) ^ e : c >> 1;
-               slic_crc_table[i] = c;
+       if (adapter->linkstate != LINK_UP) {
+               /* setup the mac */
+               slic_config_set(adapter, true);
+               adapter->linkstate = LINK_UP;
+               netif_start_queue(adapter->netdev);
        }
 }
 
-/*
- *  Return the MAC hast as described above.
- */
-static unsigned char slic_mcast_get_mac_hash(char *macaddr)
+static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
 {
-       u32 crc;
-       char *p;
-       int i;
-       unsigned char machash = 0;
+       struct sliccard *card = adapter->card;
+       struct slic_upr *upr;
 
-       if (!slic_crc_init) {
-               slic_mcast_init_crc32();
-               slic_crc_init = 1;
+       spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
+       upr = adapter->upr_list;
+       if (!upr) {
+               ASSERT(0);
+               spin_unlock_irqrestore(&adapter->upr_lock.lock,
+                                       adapter->upr_lock.flags);
+               return;
        }
+       adapter->upr_list = upr->next;
+       upr->next = NULL;
+       adapter->upr_busy = 0;
+       ASSERT(adapter->port == upr->adapter);
+       switch (upr->upr_request) {
+       case SLIC_UPR_STATS:
+               {
+                       struct slic_stats *slicstats =
+                           (struct slic_stats *) &adapter->pshmem->inicstats;
+                       struct slic_stats *newstats = slicstats;
+                       struct slic_stats  *old = &adapter->inicstats_prev;
+                       struct slicnet_stats *stst = &adapter->slic_stats;
 
-       crc = 0xFFFFFFFF;       /* Preload shift register, per crc-32 spec */
-       for (i = 0, p = macaddr; i < 6; ++p, ++i)
-               crc = (crc >> 8) ^ slic_crc_table[(crc ^ *p) & 0xFF];
+                       if (isr & ISR_UPCERR) {
+                               dev_err(&adapter->netdev->dev,
+                                       "SLIC_UPR_STATS command failed isr[%x]\n",
+                                       isr);
 
-       /* Return bits 1-8, transposed */
-       for (i = 1; i < 9; i++)
-               machash |= (((crc >> i) & 1) << (8 - i));
+                               break;
+                       }
+                       UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs,
+                                       newstats->xmit_tcp_segs_gb,
+                                       old->xmit_tcp_segs_gb);
 
-       return machash;
-}
+                       UPDATE_STATS_GB(stst->tcp.xmit_tcp_bytes,
+                                       newstats->xmit_tcp_bytes_gb,
+                                       old->xmit_tcp_bytes_gb);
 
-static void slic_mcast_set_bit(struct adapter *adapter, char *address)
-{
-       unsigned char crcpoly;
+                       UPDATE_STATS_GB(stst->tcp.rcv_tcp_segs,
+                                       newstats->rcv_tcp_segs_gb,
+                                       old->rcv_tcp_segs_gb);
 
-       /* Get the CRC polynomial for the mac address */
-       crcpoly = slic_mcast_get_mac_hash(address);
+                       UPDATE_STATS_GB(stst->tcp.rcv_tcp_bytes,
+                                       newstats->rcv_tcp_bytes_gb,
+                                       old->rcv_tcp_bytes_gb);
 
-       /* We only have space on the SLIC for 64 entries.  Lop
-        * off the top two bits. (2^6 = 64)
-        */
-       crcpoly &= 0x3F;
+                       UPDATE_STATS_GB(stst->iface.xmt_bytes,
+                                       newstats->xmit_bytes_gb,
+                                       old->xmit_bytes_gb);
 
-       /* OR in the new bit into our 64 bit mask. */
-       adapter->mcastmask |= (u64) 1 << crcpoly;
-}
+                       UPDATE_STATS_GB(stst->iface.xmt_ucast,
+                                       newstats->xmit_unicasts_gb,
+                                       old->xmit_unicasts_gb);
 
-static void slic_mcast_set_list(struct net_device *dev)
-{
-       struct adapter *adapter = netdev_priv(dev);
-       int status = STATUS_SUCCESS;
-       char *addresses;
-       struct netdev_hw_addr *ha;
+                       UPDATE_STATS_GB(stst->iface.rcv_bytes,
+                                       newstats->rcv_bytes_gb,
+                                       old->rcv_bytes_gb);
 
-       ASSERT(adapter);
+                       UPDATE_STATS_GB(stst->iface.rcv_ucast,
+                                       newstats->rcv_unicasts_gb,
+                                       old->rcv_unicasts_gb);
 
-       netdev_for_each_mc_addr(ha, dev) {
-               addresses = (char *) &ha->addr;
-               status = slic_mcast_add_list(adapter, addresses);
-               if (status != STATUS_SUCCESS)
-                       break;
-               slic_mcast_set_bit(adapter, addresses);
-       }
+                       UPDATE_STATS_GB(stst->iface.xmt_errors,
+                                       newstats->xmit_collisions_gb,
+                                       old->xmit_collisions_gb);
 
-       if (adapter->devflags_prev != dev->flags) {
-               adapter->macopts = MAC_DIRECTED;
-               if (dev->flags) {
-                       if (dev->flags & IFF_BROADCAST)
-                               adapter->macopts |= MAC_BCAST;
-                       if (dev->flags & IFF_PROMISC)
-                               adapter->macopts |= MAC_PROMISC;
-                       if (dev->flags & IFF_ALLMULTI)
-                               adapter->macopts |= MAC_ALLMCAST;
-                       if (dev->flags & IFF_MULTICAST)
-                               adapter->macopts |= MAC_MCAST;
-               }
-               adapter->devflags_prev = dev->flags;
-               slic_config_set(adapter, true);
-       } else {
-               if (status == STATUS_SUCCESS)
-                       slic_mcast_set_mask(adapter);
-       }
-       return;
-}
+                       UPDATE_STATS_GB(stst->iface.xmt_errors,
+                                       newstats->xmit_excess_collisions_gb,
+                                       old->xmit_excess_collisions_gb);
 
-static void slic_mcast_set_mask(struct adapter *adapter)
-{
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+                       UPDATE_STATS_GB(stst->iface.xmt_errors,
+                                       newstats->xmit_other_error_gb,
+                                       old->xmit_other_error_gb);
 
-       if (adapter->macopts & (MAC_ALLMCAST | MAC_PROMISC)) {
-               /* Turn on all multicast addresses. We have to do this for
-                * promiscuous mode as well as ALLMCAST mode.  It saves the
-                * Microcode from having to keep state about the MAC
-                * configuration.
-                */
-               slic_reg32_write(&slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
-               slic_reg32_write(&slic_regs->slic_mcasthigh, 0xFFFFFFFF,
-                                FLUSH);
-       } else {
-               /* Commit our multicast mast to the SLIC by writing to the
-                * multicast address mask registers
-                */
-               slic_reg32_write(&slic_regs->slic_mcastlow,
-                       (u32)(adapter->mcastmask & 0xFFFFFFFF), FLUSH);
-               slic_reg32_write(&slic_regs->slic_mcasthigh,
-                       (u32)((adapter->mcastmask >> 32) & 0xFFFFFFFF), FLUSH);
+                       UPDATE_STATS_GB(stst->iface.rcv_errors,
+                                       newstats->rcv_other_error_gb,
+                                       old->rcv_other_error_gb);
+
+                       UPDATE_STATS_GB(stst->iface.rcv_discards,
+                                       newstats->rcv_drops_gb,
+                                       old->rcv_drops_gb);
+
+                       if (newstats->rcv_drops_gb > old->rcv_drops_gb) {
+                               adapter->rcv_drops +=
+                                   (newstats->rcv_drops_gb -
+                                    old->rcv_drops_gb);
+                       }
+                       memcpy(old, newstats, sizeof(struct slic_stats));
+                       break;
+               }
+       case SLIC_UPR_RLSR:
+               slic_link_upr_complete(adapter, isr);
+               break;
+       case SLIC_UPR_RCONFIG:
+               break;
+       case SLIC_UPR_RPHY:
+               ASSERT(0);
+               break;
+       case SLIC_UPR_ENLB:
+               ASSERT(0);
+               break;
+       case SLIC_UPR_ENCT:
+               ASSERT(0);
+               break;
+       case SLIC_UPR_PDWN:
+               ASSERT(0);
+               break;
+       case SLIC_UPR_PING:
+               card->pingstatus |= (isr & ISR_PINGDSMASK);
+               break;
+       default:
+               ASSERT(0);
        }
+       kfree(upr);
+       slic_upr_start(adapter);
+       spin_unlock_irqrestore(&adapter->upr_lock.lock,
+                               adapter->upr_lock.flags);
 }
 
-static void slic_timer_ping(ulong dev)
+static void slic_config_get(struct adapter *adapter, u32 config,
+                                                       u32 config_h)
 {
-       struct adapter *adapter;
-       struct sliccard *card;
-
-       ASSERT(dev);
-       adapter = netdev_priv((struct net_device *)dev);
-       ASSERT(adapter);
-       card = adapter->card;
-       ASSERT(card);
+       int status;
 
-       adapter->pingtimer.expires = jiffies + (PING_TIMER_INTERVAL * HZ);
-       add_timer(&adapter->pingtimer);
+       status = slic_upr_request(adapter,
+                                 SLIC_UPR_RCONFIG,
+                                 (u32) config, (u32) config_h, 0, 0);
+       ASSERT(status == 0);
 }
 
 /*
- *  slic_if_init
- *
- *  Perform initialization of our slic interface.
- *
+ *  this is here to checksum the eeprom, there is some ucode bug
+ *  which prevens us from using the ucode result.
+ *  remove this once ucode is fixed.
  */
-static int slic_if_init(struct adapter *adapter)
+static ushort slic_eeprom_cksum(char *m, int len)
 {
-       struct sliccard *card = adapter->card;
-       struct net_device *dev = adapter->netdev;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-       struct slic_shmem *pshmem;
-       int status = 0;
-
-       ASSERT(card);
-
-       /* adapter should be down at this point */
-       if (adapter->state != ADAPT_DOWN) {
-               dev_err(&dev->dev, "%s: adapter->state != ADAPT_DOWN\n",
-                       __func__);
-               return -EIO;
-       }
-       ASSERT(adapter->linkstate == LINK_DOWN);
-
-       adapter->devflags_prev = dev->flags;
-       adapter->macopts = MAC_DIRECTED;
-       if (dev->flags) {
-               if (dev->flags & IFF_BROADCAST)
-                       adapter->macopts |= MAC_BCAST;
-               if (dev->flags & IFF_PROMISC)
-                       adapter->macopts |= MAC_PROMISC;
-               if (dev->flags & IFF_ALLMULTI)
-                       adapter->macopts |= MAC_ALLMCAST;
-               if (dev->flags & IFF_MULTICAST)
-                       adapter->macopts |= MAC_MCAST;
-       }
-       status = slic_adapter_allocresources(adapter);
-       if (status != STATUS_SUCCESS) {
-               dev_err(&dev->dev,
-                       "%s: slic_adapter_allocresources FAILED %x\n",
-                       __func__, status);
-               slic_adapter_freeresources(adapter);
-               return status;
-       }
+#define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
+#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);\
+               }
 
-       if (!adapter->queues_initialized) {
-               if (slic_rspqueue_init(adapter))
-                       return -ENOMEM;
-               if (slic_cmdq_init(adapter))
-                       return -ENOMEM;
-               if (slic_rcvqueue_init(adapter))
-                       return -ENOMEM;
-               adapter->queues_initialized = 1;
-       }
+       u16 *w;
+       u32 sum = 0;
+       u32 byte_swapped = 0;
+       u32 w_int;
 
-       slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
-       mdelay(1);
+       union {
+               char c[2];
+               ushort s;
+       } s_util;
 
-       if (!adapter->isp_initialized) {
-               pshmem = (struct slic_shmem *)adapter->phys_shmem;
+       union {
+               ushort s[2];
+               int l;
+       } l_util;
 
-               spin_lock_irqsave(&adapter->bit64reglock.lock,
-                                       adapter->bit64reglock.flags);
+       l_util.l = 0;
+       s_util.s = 0;
 
-#if defined(CONFIG_X86_64)
-               slic_reg32_write(&slic_regs->slic_addr_upper,
-                                SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
-               slic_reg32_write(&slic_regs->slic_isp,
-                                SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
-#elif defined(CONFIG_X86)
-               slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
-               slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH);
+       w = (u16 *)m;
+#ifdef CONFIG_X86_64
+       w_int = (u32) ((ulong) w & 0x00000000FFFFFFFF);
 #else
-               Stop Compilations
+       w_int = (u32) (w);
 #endif
-               spin_unlock_irqrestore(&adapter->bit64reglock.lock,
-                                       adapter->bit64reglock.flags);
-               adapter->isp_initialized = 1;
+       if ((1 & w_int) && (len > 0)) {
+               REDUCE;
+               sum <<= 8;
+               s_util.c[0] = *(unsigned char *)w;
+               w = (u16 *)((char *)w + 1);
+               len--;
+               byte_swapped = 1;
        }
 
-       adapter->state = ADAPT_UP;
-       if (!card->loadtimerset) {
-               init_timer(&card->loadtimer);
-               card->loadtimer.expires =
-                   jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
-               card->loadtimer.data = (ulong) card;
-               card->loadtimer.function = &slic_timer_load_check;
-               add_timer(&card->loadtimer);
-
-               card->loadtimerset = 1;
+       /* Unroll the loop to make overhead from branches &c small. */
+       while ((len -= 32) >= 0) {
+               sum += w[0];
+               sum += w[1];
+               sum += w[2];
+               sum += w[3];
+               sum += w[4];
+               sum += w[5];
+               sum += w[6];
+               sum += w[7];
+               sum += w[8];
+               sum += w[9];
+               sum += w[10];
+               sum += w[11];
+               sum += w[12];
+               sum += w[13];
+               sum += w[14];
+               sum += w[15];
+               w = (u16 *)((ulong) w + 16);    /* verify */
        }
-
-       if (!adapter->pingtimerset) {
-               init_timer(&adapter->pingtimer);
-               adapter->pingtimer.expires =
-                   jiffies + (PING_TIMER_INTERVAL * HZ);
-               adapter->pingtimer.data = (ulong) dev;
-               adapter->pingtimer.function = &slic_timer_ping;
-               add_timer(&adapter->pingtimer);
-               adapter->pingtimerset = 1;
-               adapter->card->pingstatus = ISR_PINGMASK;
+       len += 32;
+       while ((len -= 8) >= 0) {
+               sum += w[0];
+               sum += w[1];
+               sum += w[2];
+               sum += w[3];
+               w = (u16 *)((ulong) w + 4);     /* verify */
        }
+       len += 8;
+       if (len != 0 || byte_swapped != 0) {
+               REDUCE;
+               while ((len -= 2) >= 0)
+                       sum += *w++;    /* verify */
+               if (byte_swapped) {
+                       REDUCE;
+                       sum <<= 8;
+                       byte_swapped = 0;
+                       if (len == -1) {
+                               s_util.c[1] = *(char *) w;
+                               sum += s_util.s;
+                               len = 0;
+                       } else {
+                               len = -1;
+                       }
 
-       /*
-        *    clear any pending events, then enable interrupts
-        */
-       adapter->isrcopy = 0;
-       adapter->pshmem->isr = 0;
-       slic_reg32_write(&slic_regs->slic_isr, 0, FLUSH);
-       slic_reg32_write(&slic_regs->slic_icr, ICR_INT_ON, FLUSH);
-
-       slic_link_config(adapter, LINK_AUTOSPEED, LINK_AUTOD);
-       slic_link_event_handler(adapter);
+               } else if (len == -1) {
+                       s_util.c[0] = *(char *) w;
+               }
 
-       return STATUS_SUCCESS;
+               if (len == -1) {
+                       s_util.c[1] = 0;
+                       sum += s_util.s;
+               }
+       }
+       REDUCE;
+       return (ushort) sum;
 }
 
-static void slic_unmap_mmio_space(struct adapter *adapter)
+static void slic_rspqueue_free(struct adapter *adapter)
 {
-       if (adapter->slic_regs)
-               iounmap(adapter->slic_regs);
-       adapter->slic_regs = NULL;
+       int i;
+       struct slic_rspqueue *rspq = &adapter->rspqueue;
+
+       for (i = 0; i < rspq->num_pages; i++) {
+               if (rspq->vaddr[i]) {
+                       pci_free_consistent(adapter->pcidev, PAGE_SIZE,
+                                           rspq->vaddr[i], rspq->paddr[i]);
+               }
+               rspq->vaddr[i] = NULL;
+               rspq->paddr[i] = 0;
+       }
+       rspq->offset = 0;
+       rspq->pageindex = 0;
+       rspq->rspbuf = NULL;
 }
 
-static int slic_adapter_allocresources(struct adapter *adapter)
+static int slic_rspqueue_init(struct adapter *adapter)
 {
-       if (!adapter->intrregistered) {
-               int retval;
+       int i;
+       struct slic_rspqueue *rspq = &adapter->rspqueue;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+       u32 paddrh = 0;
 
-               spin_unlock_irqrestore(&slic_global.driver_lock.lock,
-                                       slic_global.driver_lock.flags);
+       ASSERT(adapter->state == ADAPT_DOWN);
+       memset(rspq, 0, sizeof(struct slic_rspqueue));
 
-               retval = request_irq(adapter->netdev->irq,
-                                    &slic_interrupt,
-                                    IRQF_SHARED,
-                                    adapter->netdev->name, adapter->netdev);
+       rspq->num_pages = SLIC_RSPQ_PAGES_GB;
 
-               spin_lock_irqsave(&slic_global.driver_lock.lock,
-                                       slic_global.driver_lock.flags);
+       for (i = 0; i < rspq->num_pages; i++) {
+               rspq->vaddr[i] = pci_alloc_consistent(adapter->pcidev,
+                                                     PAGE_SIZE,
+                                                     &rspq->paddr[i]);
+               if (!rspq->vaddr[i]) {
+                       dev_err(&adapter->pcidev->dev,
+                               "pci_alloc_consistent failed\n");
+                       slic_rspqueue_free(adapter);
+                       return -ENOMEM;
+               }
+#ifndef CONFIG_X86_64
+               ASSERT(((u32) rspq->vaddr[i] & 0xFFFFF000) ==
+                      (u32) rspq->vaddr[i]);
+               ASSERT(((u32) rspq->paddr[i] & 0xFFFFF000) ==
+                      (u32) rspq->paddr[i]);
+#endif
+               memset(rspq->vaddr[i], 0, PAGE_SIZE);
 
-               if (retval) {
-                       dev_err(&adapter->netdev->dev,
-                               "request_irq (%s) FAILED [%x]\n",
-                               adapter->netdev->name, retval);
-                       return retval;
+               if (paddrh == 0) {
+                       slic_reg32_write(&slic_regs->slic_rbar,
+                               (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+                               DONT_FLUSH);
+               } else {
+                       slic_reg64_write(adapter, &slic_regs->slic_rbar64,
+                               (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+                               &slic_regs->slic_addr_upper,
+                               paddrh, DONT_FLUSH);
                }
-               adapter->intrregistered = 1;
        }
-       return STATUS_SUCCESS;
+       rspq->offset = 0;
+       rspq->pageindex = 0;
+       rspq->rspbuf = (struct slic_rspbuf *)rspq->vaddr[0];
+       return 0;
 }
 
-static void slic_config_pci(struct pci_dev *pcidev)
+static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
 {
-       u16 pci_command;
-       u16 new_command;
+       struct slic_rspqueue *rspq = &adapter->rspqueue;
+       struct slic_rspbuf *buf;
 
-       pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
+       if (!(rspq->rspbuf->status))
+               return NULL;
 
-       new_command = pci_command | PCI_COMMAND_MASTER
-           | PCI_COMMAND_MEMORY
-           | PCI_COMMAND_INVALIDATE
-           | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
-       if (pci_command != new_command)
-               pci_write_config_word(pcidev, PCI_COMMAND, new_command);
+       buf = rspq->rspbuf;
+#ifndef CONFIG_X86_64
+       ASSERT((buf->status & 0xFFFFFFE0) == 0);
+#endif
+       ASSERT(buf->hosthandle);
+       if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) {
+               rspq->rspbuf++;
+#ifndef CONFIG_X86_64
+               ASSERT(((u32) rspq->rspbuf & 0xFFFFFFE0) ==
+                      (u32) rspq->rspbuf);
+#endif
+       } else {
+               ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE);
+               slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64,
+                       (rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
+                       &adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+               rspq->pageindex = (++rspq->pageindex) % rspq->num_pages;
+               rspq->offset = 0;
+               rspq->rspbuf = (struct slic_rspbuf *)
+                                               rspq->vaddr[rspq->pageindex];
+#ifndef CONFIG_X86_64
+               ASSERT(((u32) rspq->rspbuf & 0xFFFFF000) ==
+                      (u32) rspq->rspbuf);
+#endif
+       }
+#ifndef CONFIG_X86_64
+       ASSERT(((u32) buf & 0xFFFFFFE0) == (u32) buf);
+#endif
+       return buf;
 }
 
-static void slic_adapter_freeresources(struct adapter *adapter)
+static void slic_cmdqmem_init(struct adapter *adapter)
 {
-       slic_init_cleanup(adapter);
-       memset(&adapter->stats, 0, sizeof(struct net_device_stats));
-       adapter->error_interrupts = 0;
-       adapter->rcv_interrupts = 0;
-       adapter->xmit_interrupts = 0;
-       adapter->linkevent_interrupts = 0;
-       adapter->upr_interrupts = 0;
-       adapter->num_isrs = 0;
-       adapter->xmit_completes = 0;
-       adapter->rcv_broadcasts = 0;
-       adapter->rcv_multicasts = 0;
-       adapter->rcv_unicasts = 0;
+       struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
+
+       memset(cmdqmem, 0, sizeof(struct slic_cmdqmem));
 }
 
-/*
- *  slic_link_config
- *
- *  Write phy control to configure link duplex/speed
- *
- */
-static void slic_link_config(struct adapter *adapter,
-                     u32 linkspeed, u32 linkduplex)
+static void slic_cmdqmem_free(struct adapter *adapter)
 {
-       u32 __iomem *wphy;
-       u32 speed;
-       u32 duplex;
-       u32 phy_config;
-       u32 phy_advreg;
-       u32 phy_gctlreg;
-
-       if (adapter->state != ADAPT_UP)
-               return;
-
-       ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
-              || (adapter->devid == SLIC_2GB_DEVICE_ID));
+       struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
+       int i;
 
-       if (linkspeed > LINK_1000MB)
-               linkspeed = LINK_AUTOSPEED;
-       if (linkduplex > LINK_AUTOD)
-               linkduplex = LINK_AUTOD;
+       for (i = 0; i < SLIC_CMDQ_MAXPAGES; i++) {
+               if (cmdqmem->pages[i]) {
+                       pci_free_consistent(adapter->pcidev,
+                                           PAGE_SIZE,
+                                           (void *) cmdqmem->pages[i],
+                                           cmdqmem->dma_pages[i]);
+               }
+       }
+       memset(cmdqmem, 0, sizeof(struct slic_cmdqmem));
+}
 
-       wphy = &adapter->slic_regs->slic_wphy;
+static u32 *slic_cmdqmem_addpage(struct adapter *adapter)
+{
+       struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
+       u32 *pageaddr;
 
-       if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
-               if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
-                       /*  We've got a fiber gigabit interface, and register
-                        *  4 is different in fiber mode than in copper mode
-                        */
+       if (cmdqmem->pagecnt >= SLIC_CMDQ_MAXPAGES)
+               return NULL;
+       pageaddr = pci_alloc_consistent(adapter->pcidev,
+                                       PAGE_SIZE,
+                                       &cmdqmem->dma_pages[cmdqmem->pagecnt]);
+       if (!pageaddr)
+               return NULL;
+#ifndef CONFIG_X86_64
+       ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
+#endif
+       cmdqmem->pages[cmdqmem->pagecnt] = pageaddr;
+       cmdqmem->pagecnt++;
+       return pageaddr;
+}
 
-                       /* advertise FD only @1000 Mb */
-                       phy_advreg = (MIICR_REG_4 | (PAR_ADV1000XFD));
-                       /* enable PAUSE frames        */
-                       phy_advreg |= PAR_ASYMPAUSE_FIBER;
-                       slic_reg32_write(wphy, phy_advreg, FLUSH);
+static void slic_cmdq_free(struct adapter *adapter)
+{
+       struct slic_hostcmd *cmd;
 
-                       if (linkspeed == LINK_AUTOSPEED) {
-                               /* reset phy, enable auto-neg  */
-                               phy_config =
-                                   (MIICR_REG_PCR |
-                                    (PCR_RESET | PCR_AUTONEG |
-                                     PCR_AUTONEG_RST));
-                               slic_reg32_write(wphy, phy_config, FLUSH);
-                       } else {        /* forced 1000 Mb FD*/
-                               /* power down phy to break link
-                                  this may not work) */
-                               phy_config = (MIICR_REG_PCR | PCR_POWERDOWN);
-                               slic_reg32_write(wphy, phy_config, FLUSH);
-                               /* wait, Marvell says 1 sec,
-                                  try to get away with 10 ms  */
-                               mdelay(10);
+       cmd = adapter->cmdq_all.head;
+       while (cmd) {
+               if (cmd->busy) {
+                       struct sk_buff *tempskb;
 
-                               /* disable auto-neg, set speed/duplex,
-                                  soft reset phy, powerup */
-                               phy_config =
-                                   (MIICR_REG_PCR |
-                                    (PCR_RESET | PCR_SPEED_1000 |
-                                     PCR_DUPLEX_FULL));
-                               slic_reg32_write(wphy, phy_config, FLUSH);
+                       tempskb = cmd->skb;
+                       if (tempskb) {
+                               cmd->skb = NULL;
+                               dev_kfree_skb_irq(tempskb);
                        }
-               } else {        /* copper gigabit */
-
-                       /* Auto-Negotiate or 1000 Mb must be auto negotiated
-                        * We've got a copper gigabit interface, and
-                        * register 4 is different in copper mode than
-                        * in fiber mode
-                        */
-                       if (linkspeed == LINK_AUTOSPEED) {
-                               /* advertise 10/100 Mb modes   */
-                               phy_advreg =
-                                   (MIICR_REG_4 |
-                                    (PAR_ADV100FD | PAR_ADV100HD | PAR_ADV10FD
-                                     | PAR_ADV10HD));
-                       } else {
-                       /* linkspeed == LINK_1000MB -
-                          don't advertise 10/100 Mb modes  */
-                               phy_advreg = MIICR_REG_4;
-                       }
-                       /* enable PAUSE frames  */
-                       phy_advreg |= PAR_ASYMPAUSE;
-                       /* required by the Cicada PHY  */
-                       phy_advreg |= PAR_802_3;
-                       slic_reg32_write(wphy, phy_advreg, FLUSH);
-                       /* advertise FD only @1000 Mb  */
-                       phy_gctlreg = (MIICR_REG_9 | (PGC_ADV1000FD));
-                       slic_reg32_write(wphy, phy_gctlreg, FLUSH);
-
-                       if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
-                               /* if a Marvell PHY
-                                  enable auto crossover */
-                               phy_config =
-                                   (MIICR_REG_16 | (MRV_REG16_XOVERON));
-                               slic_reg32_write(wphy, phy_config, FLUSH);
-
-                               /* reset phy, enable auto-neg  */
-                               phy_config =
-                                   (MIICR_REG_PCR |
-                                    (PCR_RESET | PCR_AUTONEG |
-                                     PCR_AUTONEG_RST));
-                               slic_reg32_write(wphy, phy_config, FLUSH);
-                       } else {        /* it's a Cicada PHY  */
-                               /* enable and restart auto-neg (don't reset)  */
-                               phy_config =
-                                   (MIICR_REG_PCR |
-                                    (PCR_AUTONEG | PCR_AUTONEG_RST));
-                               slic_reg32_write(wphy, phy_config, FLUSH);
-                       }
-               }
-       } else {
-               /* Forced 10/100  */
-               if (linkspeed == LINK_10MB)
-                       speed = 0;
-               else
-                       speed = PCR_SPEED_100;
-               if (linkduplex == LINK_HALFD)
-                       duplex = 0;
-               else
-                       duplex = PCR_DUPLEX_FULL;
-
-               if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
-                       /* if a Marvell PHY
-                          disable auto crossover  */
-                       phy_config = (MIICR_REG_16 | (MRV_REG16_XOVEROFF));
-                       slic_reg32_write(wphy, phy_config, FLUSH);
-               }
-
-               /* power down phy to break link (this may not work)  */
-               phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN | speed | duplex));
-               slic_reg32_write(wphy, phy_config, FLUSH);
-
-               /* wait, Marvell says 1 sec, try to get away with 10 ms */
-               mdelay(10);
-
-               if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
-                       /* if a Marvell PHY
-                          disable auto-neg, set speed,
-                          soft reset phy, powerup */
-                       phy_config =
-                           (MIICR_REG_PCR | (PCR_RESET | speed | duplex));
-                       slic_reg32_write(wphy, phy_config, FLUSH);
-               } else {        /* it's a Cicada PHY  */
-                       /* disable auto-neg, set speed, powerup  */
-                       phy_config = (MIICR_REG_PCR | (speed | duplex));
-                       slic_reg32_write(wphy, phy_config, FLUSH);
                }
+               cmd = cmd->next_all;
        }
+       memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
+       memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
+       memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue));
+       slic_cmdqmem_free(adapter);
 }
 
-static void slic_card_cleanup(struct sliccard *card)
+static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
 {
-       if (card->loadtimerset) {
-               card->loadtimerset = 0;
-               del_timer(&card->loadtimer);
-       }
+       struct slic_hostcmd *cmd;
+       struct slic_hostcmd *prev;
+       struct slic_hostcmd *tail;
+       struct slic_cmdqueue *cmdq;
+       int cmdcnt;
+       void *cmdaddr;
+       ulong phys_addr;
+       u32 phys_addrl;
+       u32 phys_addrh;
+       struct slic_handle *pslic_handle;
 
-       slic_debug_card_destroy(card);
+       cmdaddr = page;
+       cmd = (struct slic_hostcmd *)cmdaddr;
+       cmdcnt = 0;
 
-       kfree(card);
-}
+       phys_addr = virt_to_bus((void *)page);
+       phys_addrl = SLIC_GET_ADDR_LOW(phys_addr);
+       phys_addrh = SLIC_GET_ADDR_HIGH(phys_addr);
 
-static int slic_card_download_gbrcv(struct adapter *adapter)
-{
-       const struct firmware *fw;
-       const char *file = "";
-       int ret;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-       u32 codeaddr;
-       u32 instruction;
-       int index = 0;
-       u32 rcvucodelen = 0;
+       prev = NULL;
+       tail = cmd;
+       while ((cmdcnt < SLIC_CMDQ_CMDSINPAGE) &&
+              (adapter->slic_handle_ix < 256)) {
+               /* Allocate and initialize a SLIC_HANDLE for this command */
+               SLIC_GET_SLIC_HANDLE(adapter, pslic_handle);
+               if (pslic_handle == NULL)
+                       ASSERT(0);
+               ASSERT(pslic_handle ==
+                      &adapter->slic_handles[pslic_handle->token.
+                                             handle_index]);
+               pslic_handle->type = SLIC_HANDLE_CMD;
+               pslic_handle->address = (void *) cmd;
+               pslic_handle->offset = (ushort) adapter->slic_handle_ix++;
+               pslic_handle->other_handle = NULL;
+               pslic_handle->next = NULL;
 
-       switch (adapter->devid) {
-       case SLIC_2GB_DEVICE_ID:
-               file = "slicoss/oasisrcvucode.sys";
-               break;
-       case SLIC_1GB_DEVICE_ID:
-               file = "slicoss/gbrcvucode.sys";
-               break;
-       default:
-               ASSERT(0);
-               break;
-       }
+               cmd->pslic_handle = pslic_handle;
+               cmd->cmd64.hosthandle = pslic_handle->token.handle_token;
+               cmd->busy = false;
+               cmd->paddrl = phys_addrl;
+               cmd->paddrh = phys_addrh;
+               cmd->next_all = prev;
+               cmd->next = prev;
+               prev = cmd;
+               phys_addrl += SLIC_HOSTCMD_SIZE;
+               cmdaddr += SLIC_HOSTCMD_SIZE;
 
-       ret = request_firmware(&fw, file, &adapter->pcidev->dev);
-       if (ret) {
-               dev_err(&adapter->pcidev->dev,
-                       "SLICOSS: Failed to load firmware %s\n", file);
-               return ret;
+               cmd = (struct slic_hostcmd *)cmdaddr;
+               cmdcnt++;
        }
 
-       rcvucodelen = *(u32 *)(fw->data + index);
-       index += 4;
-       switch (adapter->devid) {
-       case SLIC_2GB_DEVICE_ID:
-               if (rcvucodelen != OasisRcvUCodeLen)
-                       return -EINVAL;
-               break;
-       case SLIC_1GB_DEVICE_ID:
-               if (rcvucodelen != GBRcvUCodeLen)
-                       return -EINVAL;
-               break;
-       default:
-               ASSERT(0);
-               break;
-       }
-       /* start download */
-       slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
-       /* download the rcv sequencer ucode */
-       for (codeaddr = 0; codeaddr < rcvucodelen; codeaddr++) {
-               /* write out instruction address */
-               slic_reg32_write(&slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+       cmdq = &adapter->cmdq_all;
+       cmdq->count += cmdcnt;  /*  SLIC_CMDQ_CMDSINPAGE;   mooktodo */
+       tail->next_all = cmdq->head;
+       cmdq->head = prev;
+       cmdq = &adapter->cmdq_free;
+       spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
+       cmdq->count += cmdcnt;  /*  SLIC_CMDQ_CMDSINPAGE;   mooktodo */
+       tail->next = cmdq->head;
+       cmdq->head = prev;
+       spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
+}
 
-               instruction = *(u32 *)(fw->data + index);
-               index += 4;
-               /* write out the instruction data low addr */
-               slic_reg32_write(&slic_regs->slic_rcv_wcs, instruction, FLUSH);
+static int slic_cmdq_init(struct adapter *adapter)
+{
+       int i;
+       u32 *pageaddr;
 
-               instruction = *(u8 *)(fw->data + index);
-               index++;
-               /* write out the instruction data high addr */
-               slic_reg32_write(&slic_regs->slic_rcv_wcs, (u8)instruction,
-                                FLUSH);
+       ASSERT(adapter->state == ADAPT_DOWN);
+       memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
+       memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
+       memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue));
+       spin_lock_init(&adapter->cmdq_all.lock.lock);
+       spin_lock_init(&adapter->cmdq_free.lock.lock);
+       spin_lock_init(&adapter->cmdq_done.lock.lock);
+       slic_cmdqmem_init(adapter);
+       adapter->slic_handle_ix = 1;
+       for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) {
+               pageaddr = slic_cmdqmem_addpage(adapter);
+#ifndef CONFIG_X86_64
+               ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
+#endif
+               if (!pageaddr) {
+                       slic_cmdq_free(adapter);
+                       return -ENOMEM;
+               }
+               slic_cmdq_addcmdpage(adapter, pageaddr);
        }
+       adapter->slic_handle_ix = 1;
 
-       /* download finished */
-       release_firmware(fw);
-       slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
        return 0;
 }
 
-MODULE_FIRMWARE("slicoss/oasisrcvucode.sys");
-MODULE_FIRMWARE("slicoss/gbrcvucode.sys");
-
-static int slic_card_download(struct adapter *adapter)
+static void slic_cmdq_reset(struct adapter *adapter)
 {
-       const struct firmware *fw;
-       const char *file = "";
-       int ret;
-       u32 section;
-       int thissectionsize;
-       int codeaddr;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-       u32 instruction;
-       u32 baseaddress;
-       u32 i;
-       u32 numsects = 0;
-       u32 sectsize[3];
-       u32 sectstart[3];
-       int ucode_start, index = 0;
+       struct slic_hostcmd *hcmd;
+       struct sk_buff *skb;
+       u32 outstanding;
 
-       switch (adapter->devid) {
-       case SLIC_2GB_DEVICE_ID:
-               file = "slicoss/oasisdownload.sys";
-               break;
-       case SLIC_1GB_DEVICE_ID:
-               file = "slicoss/gbdownload.sys";
-               break;
-       default:
-               ASSERT(0);
-               break;
-       }
-       ret = request_firmware(&fw, file, &adapter->pcidev->dev);
-       if (ret) {
-               dev_err(&adapter->pcidev->dev,
-                       "SLICOSS: Failed to load firmware %s\n", file);
-               return ret;
-       }
-       numsects = *(u32 *)(fw->data + index);
-       index += 4;
-       ASSERT(numsects <= 3);
-       for (i = 0; i < numsects; i++) {
-               sectsize[i] = *(u32 *)(fw->data + index);
-               index += 4;
+       spin_lock_irqsave(&adapter->cmdq_free.lock.lock,
+                       adapter->cmdq_free.lock.flags);
+       spin_lock_irqsave(&adapter->cmdq_done.lock.lock,
+                       adapter->cmdq_done.lock.flags);
+       outstanding = adapter->cmdq_all.count - adapter->cmdq_done.count;
+       outstanding -= adapter->cmdq_free.count;
+       hcmd = adapter->cmdq_all.head;
+       while (hcmd) {
+               if (hcmd->busy) {
+                       skb = hcmd->skb;
+                       ASSERT(skb);
+                       hcmd->busy = 0;
+                       hcmd->skb = NULL;
+                       dev_kfree_skb_irq(skb);
+               }
+               hcmd = hcmd->next_all;
        }
-       for (i = 0; i < numsects; i++) {
-               sectstart[i] = *(u32 *)(fw->data + index);
-               index += 4;
+       adapter->cmdq_free.count = 0;
+       adapter->cmdq_free.head = NULL;
+       adapter->cmdq_free.tail = NULL;
+       adapter->cmdq_done.count = 0;
+       adapter->cmdq_done.head = NULL;
+       adapter->cmdq_done.tail = NULL;
+       adapter->cmdq_free.head = adapter->cmdq_all.head;
+       hcmd = adapter->cmdq_all.head;
+       while (hcmd) {
+               adapter->cmdq_free.count++;
+               hcmd->next = hcmd->next_all;
+               hcmd = hcmd->next_all;
        }
-       ucode_start = index;
-       instruction = *(u32 *)(fw->data + index);
-       index += 4;
-       for (section = 0; section < numsects; section++) {
-               baseaddress = sectstart[section];
-               thissectionsize = sectsize[section] >> 3;
-
-               for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
-                       /* Write out instruction address */
-                       slic_reg32_write(&slic_regs->slic_wcs,
-                                        baseaddress + codeaddr, FLUSH);
-                       /* Write out instruction to low addr */
-                       slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
-                       instruction = *(u32 *)(fw->data + index);
-                       index += 4;
-
-                       /* Write out instruction to high addr */
-                       slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
-                       instruction = *(u32 *)(fw->data + index);
-                       index += 4;
-               }
+       if (adapter->cmdq_free.count != adapter->cmdq_all.count) {
+               dev_err(&adapter->netdev->dev,
+                       "free_count %d != all count %d\n",
+                       adapter->cmdq_free.count, adapter->cmdq_all.count);
        }
-       index = ucode_start;
-       for (section = 0; section < numsects; section++) {
-               instruction = *(u32 *)(fw->data + index);
-               baseaddress = sectstart[section];
-               if (baseaddress < 0x8000)
-                       continue;
-               thissectionsize = sectsize[section] >> 3;
-
-               for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
-                       /* Write out instruction address */
-                       slic_reg32_write(&slic_regs->slic_wcs,
-                               SLIC_WCS_COMPARE | (baseaddress + codeaddr),
-                               FLUSH);
-                       /* Write out instruction to low addr */
-                       slic_reg32_write(&slic_regs->slic_wcs, instruction,
-                                        FLUSH);
-                       instruction = *(u32 *)(fw->data + index);
-                       index += 4;
-                       /* Write out instruction to high addr */
-                       slic_reg32_write(&slic_regs->slic_wcs, instruction,
-                                        FLUSH);
-                       instruction = *(u32 *)(fw->data + index);
-                       index += 4;
+       spin_unlock_irqrestore(&adapter->cmdq_done.lock.lock,
+                               adapter->cmdq_done.lock.flags);
+       spin_unlock_irqrestore(&adapter->cmdq_free.lock.lock,
+                               adapter->cmdq_free.lock.flags);
+}
 
-                       /* Check SRAM location zero. If it is non-zero. Abort.*/
-/*                     failure = readl((u32 __iomem *)&slic_regs->slic_reset);
-                       if (failure) {
-                               release_firmware(fw);
-                               return -EIO;
-                       }*/
-               }
-       }
-       release_firmware(fw);
-       /* Everything OK, kick off the card */
-       mdelay(10);
-       slic_reg32_write(&slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
+static void slic_cmdq_getdone(struct adapter *adapter)
+{
+       struct slic_cmdqueue *done_cmdq = &adapter->cmdq_done;
+       struct slic_cmdqueue *free_cmdq = &adapter->cmdq_free;
 
-       /* stall for 20 ms, long enough for ucode to init card
-          and reach mainloop */
-       mdelay(20);
+       ASSERT(free_cmdq->head == NULL);
+       spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags);
 
-       return STATUS_SUCCESS;
+       free_cmdq->head = done_cmdq->head;
+       free_cmdq->count = done_cmdq->count;
+       done_cmdq->head = NULL;
+       done_cmdq->tail = NULL;
+       done_cmdq->count = 0;
+       spin_unlock_irqrestore(&done_cmdq->lock.lock, done_cmdq->lock.flags);
 }
 
-MODULE_FIRMWARE("slicoss/oasisdownload.sys");
-MODULE_FIRMWARE("slicoss/gbdownload.sys");
-
-static void slic_adapter_set_hwaddr(struct adapter *adapter)
+static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter)
 {
-       struct sliccard *card = adapter->card;
+       struct slic_cmdqueue *cmdq = &adapter->cmdq_free;
+       struct slic_hostcmd *cmd = NULL;
 
-       if ((adapter->card) && (card->config_set)) {
-               memcpy(adapter->macaddr,
-                      card->config.MacInfo[adapter->functionnumber].macaddrA,
-                      sizeof(struct slic_config_mac));
-               if (!(adapter->currmacaddr[0] || adapter->currmacaddr[1] ||
-                     adapter->currmacaddr[2] || adapter->currmacaddr[3] ||
-                     adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
-                       memcpy(adapter->currmacaddr, adapter->macaddr, 6);
-               }
-               if (adapter->netdev) {
-                       memcpy(adapter->netdev->dev_addr, adapter->currmacaddr,
-                              6);
+lock_and_retry:
+       spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
+retry:
+       cmd = cmdq->head;
+       if (cmd) {
+               cmdq->head = cmd->next;
+               cmdq->count--;
+               spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
+       } else {
+               slic_cmdq_getdone(adapter);
+               cmd = cmdq->head;
+               if (cmd) {
+                       goto retry;
+               } else {
+                       u32 *pageaddr;
+
+                       spin_unlock_irqrestore(&cmdq->lock.lock,
+                                               cmdq->lock.flags);
+                       pageaddr = slic_cmdqmem_addpage(adapter);
+                       if (pageaddr) {
+                               slic_cmdq_addcmdpage(adapter, pageaddr);
+                               goto lock_and_retry;
+                       }
                }
        }
+       return cmd;
 }
 
-static void slic_intagg_set(struct adapter *adapter, u32 value)
+static void slic_cmdq_putdone_irq(struct adapter *adapter,
+                               struct slic_hostcmd *cmd)
 {
-       slic_reg32_write(&adapter->slic_regs->slic_intagg, value, FLUSH);
-       adapter->card->loadlevel_current = value;
+       struct slic_cmdqueue *cmdq = &adapter->cmdq_done;
+
+       spin_lock(&cmdq->lock.lock);
+       cmd->busy = 0;
+       cmd->next = cmdq->head;
+       cmdq->head = cmd;
+       cmdq->count++;
+       if ((adapter->xmitq_full) && (cmdq->count > 10))
+               netif_wake_queue(adapter->netdev);
+       spin_unlock(&cmdq->lock.lock);
 }
 
-static int slic_card_init(struct sliccard *card, struct adapter *adapter)
+static int slic_rcvqueue_fill(struct adapter *adapter)
 {
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-       struct slic_eeprom *peeprom;
-       struct oslic_eeprom *pOeeprom;
-       dma_addr_t phys_config;
-       u32 phys_configh;
-       u32 phys_configl;
-       u32 i = 0;
-       struct slic_shmem *pshmem;
-       int status;
-       uint macaddrs = card->card_size;
-       ushort eecodesize;
-       ushort dramsize;
-       ushort ee_chksum;
-       ushort calc_chksum;
-       struct slic_config_mac *pmac;
-       unsigned char fruformat;
-       unsigned char oemfruformat;
-       struct atk_fru *patkfru;
-       union oemfru *poemfru;
-
-       /* Reset everything except PCI configuration space */
-       slic_soft_reset(adapter);
-
-       /* Download the microcode */
-       status = slic_card_download(adapter);
-
-       if (status != STATUS_SUCCESS) {
-               dev_err(&adapter->pcidev->dev,
-                       "download failed bus %d slot %d\n",
-                       adapter->busnumber, adapter->slotnumber);
-               return status;
-       }
-
-       if (!card->config_set) {
-               peeprom = pci_alloc_consistent(adapter->pcidev,
-                                              sizeof(struct slic_eeprom),
-                                              &phys_config);
+       void *paddr;
+       u32 paddrl;
+       u32 paddrh;
+       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+       int i = 0;
+       struct device *dev = &adapter->netdev->dev;
 
-               phys_configl = SLIC_GET_ADDR_LOW(phys_config);
-               phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
+       while (i < SLIC_RCVQ_FILLENTRIES) {
+               struct slic_rcvbuf *rcvbuf;
+               struct sk_buff *skb;
+#ifdef KLUDGE_FOR_4GB_BOUNDARY
+retry_rcvqfill:
+#endif
+               skb = alloc_skb(SLIC_RCVQ_RCVBUFSIZE, GFP_ATOMIC);
+               if (skb) {
+                       paddr = (void *)pci_map_single(adapter->pcidev,
+                                                         skb->data,
+                                                         SLIC_RCVQ_RCVBUFSIZE,
+                                                         PCI_DMA_FROMDEVICE);
+                       paddrl = SLIC_GET_ADDR_LOW(paddr);
+                       paddrh = SLIC_GET_ADDR_HIGH(paddr);
 
-               if (!peeprom) {
-                       dev_err(&adapter->pcidev->dev,
-                               "eeprom read failed to get memory "
-                               "bus %d slot %d\n", adapter->busnumber,
-                               adapter->slotnumber);
-                       return -ENOMEM;
-               } else {
-                       memset(peeprom, 0, sizeof(struct slic_eeprom));
-               }
-               slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
-               mdelay(1);
-               pshmem = (struct slic_shmem *)adapter->phys_shmem;
-
-               spin_lock_irqsave(&adapter->bit64reglock.lock,
-                                       adapter->bit64reglock.flags);
-               slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
-               slic_reg32_write(&slic_regs->slic_isp,
-                                SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
-               spin_unlock_irqrestore(&adapter->bit64reglock.lock,
-                                       adapter->bit64reglock.flags);
-
-               slic_config_get(adapter, phys_configl, phys_configh);
-
-               for (;;) {
-                       if (adapter->pshmem->isr) {
-                               if (adapter->pshmem->isr & ISR_UPC) {
-                                       adapter->pshmem->isr = 0;
-                                       slic_reg64_write(adapter,
-                                               &slic_regs->slic_isp, 0,
-                                               &slic_regs->slic_addr_upper,
-                                               0, FLUSH);
-                                       slic_reg32_write(&slic_regs->slic_isr,
-                                                        0, FLUSH);
-
-                                       slic_upr_request_complete(adapter, 0);
-                                       break;
-                               } else {
-                                       adapter->pshmem->isr = 0;
-                                       slic_reg32_write(&slic_regs->slic_isr,
-                                                        0, FLUSH);
-                               }
+                       skb->len = SLIC_RCVBUF_HEADSIZE;
+                       rcvbuf = (struct slic_rcvbuf *)skb->head;
+                       rcvbuf->status = 0;
+                       skb->next = NULL;
+#ifdef KLUDGE_FOR_4GB_BOUNDARY
+                       if (paddrl == 0) {
+                               dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+                                       __func__);
+                               dev_err(dev, "skb[%p] PROBLEM\n", skb);
+                               dev_err(dev, "         skbdata[%p]\n", skb->data);
+                               dev_err(dev, "         skblen[%x]\n", skb->len);
+                               dev_err(dev, "         paddr[%p]\n", paddr);
+                               dev_err(dev, "         paddrl[%x]\n", paddrl);
+                               dev_err(dev, "         paddrh[%x]\n", paddrh);
+                               dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
+                               dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
+                               dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
+                               dev_err(dev, "SKIP THIS SKB!!!!!!!!\n");
+                               goto retry_rcvqfill;
+                       }
+#else
+                       if (paddrl == 0) {
+                               dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+                                       __func__);
+                               dev_err(dev, "skb[%p] PROBLEM\n", skb);
+                               dev_err(dev, "         skbdata[%p]\n", skb->data);
+                               dev_err(dev, "         skblen[%x]\n", skb->len);
+                               dev_err(dev, "         paddr[%p]\n", paddr);
+                               dev_err(dev, "         paddrl[%x]\n", paddrl);
+                               dev_err(dev, "         paddrh[%x]\n", paddrh);
+                               dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
+                               dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
+                               dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
+                               dev_err(dev, "GIVE TO CARD ANYWAY\n");
+                       }
+#endif
+                       if (paddrh == 0) {
+                               slic_reg32_write(&adapter->slic_regs->slic_hbar,
+                                                (u32)paddrl, DONT_FLUSH);
                        } else {
-                               mdelay(1);
-                               i++;
-                               if (i > 5000) {
-                                       dev_err(&adapter->pcidev->dev,
-                                               "%d config data fetch timed out!\n",
-                                               adapter->port);
-                                       slic_reg64_write(adapter,
-                                               &slic_regs->slic_isp, 0,
-                                               &slic_regs->slic_addr_upper,
-                                               0, FLUSH);
-                                       return -EINVAL;
-                               }
+                               slic_reg64_write(adapter,
+                                       &adapter->slic_regs->slic_hbar64,
+                                       paddrl,
+                                       &adapter->slic_regs->slic_addr_upper,
+                                       paddrh, DONT_FLUSH);
                        }
-               }
-
-               switch (adapter->devid) {
-               /* Oasis card */
-               case SLIC_2GB_DEVICE_ID:
-                       /* extract EEPROM data and pointers to EEPROM data */
-                       pOeeprom = (struct oslic_eeprom *) peeprom;
-                       eecodesize = pOeeprom->EecodeSize;
-                       dramsize = pOeeprom->DramSize;
-                       pmac = pOeeprom->MacInfo;
-                       fruformat = pOeeprom->FruFormat;
-                       patkfru = &pOeeprom->AtkFru;
-                       oemfruformat = pOeeprom->OemFruFormat;
-                       poemfru = &pOeeprom->OemFru;
-                       macaddrs = 2;
-                       /* Minor kludge for Oasis card
-                            get 2 MAC addresses from the
-                            EEPROM to ensure that function 1
-                            gets the Port 1 MAC address */
-                       break;
-               default:
-                       /* extract EEPROM data and pointers to EEPROM data */
-                       eecodesize = peeprom->EecodeSize;
-                       dramsize = peeprom->DramSize;
-                       pmac = peeprom->u2.mac.MacInfo;
-                       fruformat = peeprom->FruFormat;
-                       patkfru = &peeprom->AtkFru;
-                       oemfruformat = peeprom->OemFruFormat;
-                       poemfru = &peeprom->OemFru;
+                       if (rcvq->head)
+                               rcvq->tail->next = skb;
+                       else
+                               rcvq->head = skb;
+                       rcvq->tail = skb;
+                       rcvq->count++;
+                       i++;
+               } else {
+                       dev_err(&adapter->netdev->dev,
+                               "slic_rcvqueue_fill could only get [%d] skbuffs\n",
+                               i);
                        break;
                }
+       }
+       return i;
+}
 
-               card->config.EepromValid = false;
+static void slic_rcvqueue_free(struct adapter *adapter)
+{
+       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+       struct sk_buff *skb;
 
-               /*  see if the EEPROM is valid by checking it's checksum */
-               if ((eecodesize <= MAX_EECODE_SIZE) &&
-                   (eecodesize >= MIN_EECODE_SIZE)) {
+       while (rcvq->head) {
+               skb = rcvq->head;
+               rcvq->head = rcvq->head->next;
+               dev_kfree_skb(skb);
+       }
+       rcvq->tail = NULL;
+       rcvq->head = NULL;
+       rcvq->count = 0;
+}
 
-                       ee_chksum =
-                           *(u16 *) ((char *) peeprom + (eecodesize - 2));
-                       /*
-                           calculate the EEPROM checksum
-                       */
-                       calc_chksum =
-                           ~slic_eeprom_cksum((char *) peeprom,
-                                              (eecodesize - 2));
-                       /*
-                           if the ucdoe chksum flag bit worked,
-                           we wouldn't need this shit
-                       */
-                       if (ee_chksum == calc_chksum)
-                               card->config.EepromValid = true;
-               }
-               /*  copy in the DRAM size */
-               card->config.DramSize = dramsize;
+static int slic_rcvqueue_init(struct adapter *adapter)
+{
+       int i, count;
+       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
 
-               /*  copy in the MAC address(es) */
-               for (i = 0; i < macaddrs; i++) {
-                       memcpy(&card->config.MacInfo[i],
-                              &pmac[i], sizeof(struct slic_config_mac));
-               }
+       ASSERT(adapter->state == ADAPT_DOWN);
+       rcvq->tail = NULL;
+       rcvq->head = NULL;
+       rcvq->size = SLIC_RCVQ_ENTRIES;
+       rcvq->errors = 0;
+       rcvq->count = 0;
+       i = (SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES);
+       count = 0;
+       while (i) {
+               count += slic_rcvqueue_fill(adapter);
+               i--;
+       }
+       if (rcvq->count < SLIC_RCVQ_MINENTRIES) {
+               slic_rcvqueue_free(adapter);
+               return -ENOMEM;
+       }
+       return 0;
+}
 
-               /*  copy the Alacritech FRU information */
-               card->config.FruFormat = fruformat;
-               memcpy(&card->config.AtkFru, patkfru,
-                                               sizeof(struct atk_fru));
+static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter)
+{
+       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+       struct sk_buff *skb;
+       struct slic_rcvbuf *rcvbuf;
+       int count;
 
-               pci_free_consistent(adapter->pcidev,
-                                   sizeof(struct slic_eeprom),
-                                   peeprom, phys_config);
+       if (rcvq->count) {
+               skb = rcvq->head;
+               rcvbuf = (struct slic_rcvbuf *)skb->head;
+               ASSERT(rcvbuf);
 
-               if ((!card->config.EepromValid) &&
-                   (adapter->reg_params.fail_on_bad_eeprom)) {
-                       slic_reg64_write(adapter, &slic_regs->slic_isp, 0,
-                                        &slic_regs->slic_addr_upper,
-                                        0, FLUSH);
-                       dev_err(&adapter->pcidev->dev,
-                               "unsupported CONFIGURATION EEPROM invalid\n");
-                       return -EINVAL;
+               if (rcvbuf->status & IRHDDR_SVALID) {
+                       rcvq->head = rcvq->head->next;
+                       skb->next = NULL;
+                       rcvq->count--;
+               } else {
+                       skb = NULL;
                }
-
-               card->config_set = 1;
+       } else {
+               dev_err(&adapter->netdev->dev,
+                       "RcvQ Empty!! rcvq[%p] count[%x]\n", rcvq, rcvq->count);
+               skb = NULL;
        }
-
-       if (slic_card_download_gbrcv(adapter)) {
-               dev_err(&adapter->pcidev->dev,
-                       "unable to download GB receive microcode\n");
-               return -EINVAL;
+       while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
+               count = slic_rcvqueue_fill(adapter);
+               if (!count)
+                       break;
        }
+       if (skb)
+               rcvq->errors = 0;
+       return skb;
+}
 
-       if (slic_global.dynamic_intagg)
-               slic_intagg_set(adapter, 0);
-       else
-               slic_intagg_set(adapter, intagg_delay);
+static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
+{
+       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+       void *paddr;
+       u32 paddrl;
+       u32 paddrh;
+       struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head;
+       struct device *dev;
 
-       /*
-        *  Initialize ping status to "ok"
-        */
-       card->pingstatus = ISR_PINGMASK;
+       ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
 
-       /*
-        * Lastly, mark our card state as up and return success
-        */
-       card->state = CARD_UP;
-       card->reset_in_progress = 0;
+       paddr = (void *)pci_map_single(adapter->pcidev, skb->head,
+                                 SLIC_RCVQ_RCVBUFSIZE, PCI_DMA_FROMDEVICE);
+       rcvbuf->status = 0;
+       skb->next = NULL;
+
+       paddrl = SLIC_GET_ADDR_LOW(paddr);
+       paddrh = SLIC_GET_ADDR_HIGH(paddr);
 
-       return STATUS_SUCCESS;
+       if (paddrl == 0) {
+               dev = &adapter->netdev->dev;
+               dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+                       __func__);
+               dev_err(dev, "skb[%p] PROBLEM\n", skb);
+               dev_err(dev, "         skbdata[%p]\n", skb->data);
+               dev_err(dev, "         skblen[%x]\n", skb->len);
+               dev_err(dev, "         paddr[%p]\n", paddr);
+               dev_err(dev, "         paddrl[%x]\n", paddrl);
+               dev_err(dev, "         paddrh[%x]\n", paddrh);
+               dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
+               dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
+               dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
+       }
+       if (paddrh == 0) {
+               slic_reg32_write(&adapter->slic_regs->slic_hbar, (u32)paddrl,
+                                DONT_FLUSH);
+       } else {
+               slic_reg64_write(adapter, &adapter->slic_regs->slic_hbar64,
+                                paddrl, &adapter->slic_regs->slic_addr_upper,
+                                paddrh, DONT_FLUSH);
+       }
+       if (rcvq->head)
+               rcvq->tail->next = skb;
+       else
+               rcvq->head = skb;
+       rcvq->tail = skb;
+       rcvq->count++;
+       return rcvq->count;
 }
 
-static u32 slic_card_locate(struct adapter *adapter)
+static int slic_debug_card_show(struct seq_file *seq, void *v)
 {
-       struct sliccard *card = slic_global.slic_card;
-       struct physcard *physcard = slic_global.phys_card;
-       ushort card_hostid;
-       u16 __iomem *hostid_reg;
-       uint i;
-       uint rdhostid_offset = 0;
+#ifdef MOOKTODO
+       int i;
+       struct sliccard *card = seq->private;
+       struct slic_config *config = &card->config;
+       unsigned char *fru = (unsigned char *)(&card->config.atk_fru);
+       unsigned char *oemfru = (unsigned char *)(&card->config.OemFru);
+#endif
 
-       switch (adapter->devid) {
-       case SLIC_2GB_DEVICE_ID:
-               rdhostid_offset = SLIC_RDHOSTID_2GB;
-               break;
-       case SLIC_1GB_DEVICE_ID:
-               rdhostid_offset = SLIC_RDHOSTID_1GB;
-               break;
-       default:
-               ASSERT(0);
-               break;
+       seq_printf(seq, "driver_version           : %s\n", slic_proc_version);
+       seq_printf(seq, "Microcode versions:           \n");
+       seq_printf(seq, "    Gigabit (gb)         : %s %s\n",
+                   MOJAVE_UCODE_VERS_STRING, MOJAVE_UCODE_VERS_DATE);
+       seq_printf(seq, "    Gigabit Receiver     : %s %s\n",
+                   GB_RCVUCODE_VERS_STRING, GB_RCVUCODE_VERS_DATE);
+       seq_printf(seq, "Vendor                   : %s\n", slic_vendor);
+       seq_printf(seq, "Product Name             : %s\n", slic_product_name);
+#ifdef MOOKTODO
+       seq_printf(seq, "VendorId                 : %4.4X\n",
+                   config->VendorId);
+       seq_printf(seq, "DeviceId                 : %4.4X\n",
+                   config->DeviceId);
+       seq_printf(seq, "RevisionId               : %2.2x\n",
+                   config->RevisionId);
+       seq_printf(seq, "Bus    #                 : %d\n", card->busnumber);
+       seq_printf(seq, "Device #                 : %d\n", card->slotnumber);
+       seq_printf(seq, "Interfaces               : %d\n", card->card_size);
+       seq_printf(seq, "     Initialized         : %d\n",
+                   card->adapters_activated);
+       seq_printf(seq, "     Allocated           : %d\n",
+                   card->adapters_allocated);
+       ASSERT(card->card_size <= SLIC_NBR_MACS);
+       for (i = 0; i < card->card_size; i++) {
+               seq_printf(seq,
+                          "     MAC%d : %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+                          i, config->macinfo[i].macaddrA[0],
+                          config->macinfo[i].macaddrA[1],
+                          config->macinfo[i].macaddrA[2],
+                          config->macinfo[i].macaddrA[3],
+                          config->macinfo[i].macaddrA[4],
+                          config->macinfo[i].macaddrA[5]);
        }
+       seq_printf(seq, "     IF  Init State Duplex/Speed irq\n");
+       seq_printf(seq, "     -------------------------------\n");
+       for (i = 0; i < card->adapters_allocated; i++) {
+               struct adapter *adapter;
 
-       hostid_reg =
-           (u16 __iomem *) (((u8 __iomem *) (adapter->slic_regs)) +
-           rdhostid_offset);
-
-       /* read the 16 bit hostid from SRAM */
-       card_hostid = (ushort) readw(hostid_reg);
-
-       /* Initialize a new card structure if need be */
-       if (card_hostid == SLIC_HOSTID_DEFAULT) {
-               card = kzalloc(sizeof(struct sliccard), GFP_KERNEL);
-               if (card == NULL)
-                       return -ENOMEM;
+               adapter = card->adapter[i];
+               if (adapter) {
+                       seq_printf(seq,
+                                   "     %d   %d   %s  %s  %s    0x%X\n",
+                                   adapter->physport, adapter->state,
+                                   SLIC_LINKSTATE(adapter->linkstate),
+                                   SLIC_DUPLEX(adapter->linkduplex),
+                                   SLIC_SPEED(adapter->linkspeed),
+                                   (uint) adapter->irq);
+               }
+       }
+       seq_printf(seq, "Generation #             : %4.4X\n", card->gennumber);
+       seq_printf(seq, "RcvQ max entries         : %4.4X\n",
+                   SLIC_RCVQ_ENTRIES);
+       seq_printf(seq, "Ping Status              : %8.8X\n",
+                   card->pingstatus);
+       seq_printf(seq, "Minimum grant            : %2.2x\n",
+                   config->MinGrant);
+       seq_printf(seq, "Maximum Latency          : %2.2x\n", config->MaxLat);
+       seq_printf(seq, "PciStatus                : %4.4x\n",
+                   config->Pcistatus);
+       seq_printf(seq, "Debug Device Id          : %4.4x\n",
+                   config->DbgDevId);
+       seq_printf(seq, "DRAM ROM Function        : %4.4x\n",
+                   config->DramRomFn);
+       seq_printf(seq, "Network interface Pin 1  : %2.2x\n",
+                   config->NetIntPin1);
+       seq_printf(seq, "Network interface Pin 2  : %2.2x\n",
+                   config->NetIntPin1);
+       seq_printf(seq, "Network interface Pin 3  : %2.2x\n",
+                   config->NetIntPin1);
+       seq_printf(seq, "PM capabilities          : %4.4X\n",
+                   config->PMECapab);
+       seq_printf(seq, "Network Clock Controls   : %4.4X\n",
+                   config->NwClkCtrls);
 
-               card->next = slic_global.slic_card;
-               slic_global.slic_card = card;
-               card->busnumber = adapter->busnumber;
-               card->slotnumber = adapter->slotnumber;
+       switch (config->FruFormat) {
+       case ATK_FRU_FORMAT:
+               {
+                       seq_printf(seq,
+                           "Vendor                   : Alacritech, Inc.\n");
+                       seq_printf(seq,
+                           "Assembly #               : %c%c%c%c%c%c\n",
+                                   fru[0], fru[1], fru[2], fru[3], fru[4],
+                                   fru[5]);
+                       seq_printf(seq,
+                                   "Revision #               : %c%c\n",
+                                   fru[6], fru[7]);
 
-               /* Find an available cardnum */
-               for (i = 0; i < SLIC_MAX_CARDS; i++) {
-                       if (slic_global.cardnuminuse[i] == 0) {
-                               slic_global.cardnuminuse[i] = 1;
-                               card->cardnum = i;
-                               break;
+                       if (config->OEMFruFormat == VENDOR4_FRU_FORMAT) {
+                               seq_printf(seq,
+                                           "Serial   #               : "
+                                           "%c%c%c%c%c%c%c%c%c%c%c%c\n",
+                                           fru[8], fru[9], fru[10],
+                                           fru[11], fru[12], fru[13],
+                                           fru[16], fru[17], fru[18],
+                                           fru[19], fru[20], fru[21]);
+                       } else {
+                               seq_printf(seq,
+                                           "Serial   #               : "
+                                           "%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
+                                           fru[8], fru[9], fru[10],
+                                           fru[11], fru[12], fru[13],
+                                           fru[14], fru[15], fru[16],
+                                           fru[17], fru[18], fru[19],
+                                           fru[20], fru[21]);
                        }
+                       break;
                }
-               slic_global.num_slic_cards++;
 
-               slic_debug_card_create(card);
-       } else {
-               /* Card exists, find the card this adapter belongs to */
-               while (card) {
-                       if (card->cardnum == card_hostid)
-                               break;
-                       card = card->next;
+       default:
+               {
+                       seq_printf(seq,
+                           "Vendor                   : Alacritech, Inc.\n");
+                       seq_printf(seq,
+                           "Serial   #               : Empty FRU\n");
+                       break;
                }
        }
 
-       ASSERT(card);
-       if (!card)
-               return STATUS_FAILURE;
-       /* Put the adapter in the card's adapter list */
-       ASSERT(card->adapter[adapter->port] == NULL);
-       if (!card->adapter[adapter->port]) {
-               card->adapter[adapter->port] = adapter;
-               adapter->card = card;
-       }
-
-       card->card_size = 1;    /* one port per *logical* card */
-
-       while (physcard) {
-               for (i = 0; i < SLIC_MAX_PORTS; i++) {
-                       if (!physcard->adapter[i])
-                               continue;
-                       else
-                               break;
-               }
-               ASSERT(i != SLIC_MAX_PORTS);
-               if (physcard->adapter[i]->slotnumber == adapter->slotnumber)
+       switch (config->OEMFruFormat) {
+       case VENDOR1_FRU_FORMAT:
+               {
+                       seq_printf(seq, "FRU Information:\n");
+                       seq_printf(seq, "    Commodity #          : %c\n",
+                                   oemfru[0]);
+                       seq_printf(seq,
+                                   "    Assembly #           : %c%c%c%c\n",
+                                   oemfru[1], oemfru[2], oemfru[3], oemfru[4]);
+                       seq_printf(seq,
+                                   "    Revision #           : %c%c\n",
+                                   oemfru[5], oemfru[6]);
+                       seq_printf(seq,
+                                   "    Supplier #           : %c%c\n",
+                                   oemfru[7], oemfru[8]);
+                       seq_printf(seq,
+                                   "    Date                 : %c%c\n",
+                                   oemfru[9], oemfru[10]);
+                       seq_sprintf(seq,
+                                   "    Sequence #           : %c%c%c\n",
+                                   oemfru[11], oemfru[12], oemfru[13]);
                        break;
-               physcard = physcard->next;
-       }
-       if (!physcard) {
-               /* no structure allocated for this physical card yet */
-               physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC);
-               ASSERT(physcard);
+               }
 
-               physcard->next = slic_global.phys_card;
-               slic_global.phys_card = physcard;
-               physcard->adapters_allocd = 1;
-       } else {
-               physcard->adapters_allocd++;
-       }
-       /* Note - this is ZERO relative */
-       adapter->physport = physcard->adapters_allocd - 1;
+       case VENDOR2_FRU_FORMAT:
+               {
+                       seq_printf(seq, "FRU Information:\n");
+                       seq_printf(seq,
+                                   "    Part     #           : "
+                                   "%c%c%c%c%c%c%c%c\n",
+                                   oemfru[0], oemfru[1], oemfru[2],
+                                   oemfru[3], oemfru[4], oemfru[5],
+                                   oemfru[6], oemfru[7]);
+                       seq_printf(seq,
+                                   "    Supplier #           : %c%c%c%c%c\n",
+                                   oemfru[8], oemfru[9], oemfru[10],
+                                   oemfru[11], oemfru[12]);
+                       seq_printf(seq,
+                                   "    Date                 : %c%c%c\n",
+                                   oemfru[13], oemfru[14], oemfru[15]);
+                       seq_sprintf(seq,
+                                   "    Sequence #           : %c%c%c%c\n",
+                                   oemfru[16], oemfru[17], oemfru[18],
+                                   oemfru[19]);
+                       break;
+               }
 
-       ASSERT(physcard->adapter[adapter->physport] == NULL);
-       physcard->adapter[adapter->physport] = adapter;
-       adapter->physcard = physcard;
+       case VENDOR3_FRU_FORMAT:
+               {
+                       seq_printf(seq, "FRU Information:\n");
+               }
 
-       return 0;
-}
+       case VENDOR4_FRU_FORMAT:
+               {
+                       seq_printf(seq, "FRU Information:\n");
+                       seq_printf(seq,
+                                   "    FRU Number           : "
+                                   "%c%c%c%c%c%c%c%c\n",
+                                   oemfru[0], oemfru[1], oemfru[2],
+                                   oemfru[3], oemfru[4], oemfru[5],
+                                   oemfru[6], oemfru[7]);
+                       seq_sprintf(seq,
+                                   "    Part Number          : "
+                                   "%c%c%c%c%c%c%c%c\n",
+                                   oemfru[8], oemfru[9], oemfru[10],
+                                   oemfru[11], oemfru[12], oemfru[13],
+                                   oemfru[14], oemfru[15]);
+                       seq_printf(seq,
+                                   "    EC Level             : "
+                                   "%c%c%c%c%c%c%c%c\n",
+                                   oemfru[16], oemfru[17], oemfru[18],
+                                   oemfru[19], oemfru[20], oemfru[21],
+                                   oemfru[22], oemfru[23]);
+                       break;
+               }
 
-static void slic_soft_reset(struct adapter *adapter)
-{
-       if (adapter->card->state == CARD_UP) {
-               slic_reg32_write(&adapter->slic_regs->slic_quiesce, 0, FLUSH);
-               mdelay(1);
+       default:
+               break;
        }
+#endif
 
-       slic_reg32_write(&adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC,
-                        FLUSH);
-       mdelay(1);
+       return 0;
 }
 
-static void slic_config_set(struct adapter *adapter, bool linkchange)
+static int slic_debug_adapter_show(struct seq_file *seq, void *v)
 {
-       u32 value;
-       u32 RcrReset;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-
-       if (linkchange) {
-               /* Setup MAC */
-               slic_mac_config(adapter);
-               RcrReset = GRCR_RESET;
-       } else {
-               slic_mac_address_config(adapter);
-               RcrReset = 0;
-       }
+       struct adapter *adapter = seq->private;
+       struct net_device *netdev = adapter->netdev;
 
-       if (adapter->linkduplex == LINK_FULLD) {
-               /* setup xmtcfg */
-               value = (GXCR_RESET |   /* Always reset     */
-                        GXCR_XMTEN |   /* Enable transmit  */
-                        GXCR_PAUSEEN); /* Enable pause     */
+       seq_printf(seq, "info: interface          : %s\n",
+                           adapter->netdev->name);
+       seq_printf(seq, "info: status             : %s\n",
+               SLIC_LINKSTATE(adapter->linkstate));
+       seq_printf(seq, "info: port               : %d\n",
+               adapter->physport);
+       seq_printf(seq, "info: speed              : %s\n",
+               SLIC_SPEED(adapter->linkspeed));
+       seq_printf(seq, "info: duplex             : %s\n",
+               SLIC_DUPLEX(adapter->linkduplex));
+       seq_printf(seq, "info: irq                : 0x%X\n",
+               (uint) adapter->irq);
+       seq_printf(seq, "info: Interrupt Agg Delay: %d usec\n",
+               adapter->card->loadlevel_current);
+       seq_printf(seq, "info: RcvQ max entries   : %4.4X\n",
+               SLIC_RCVQ_ENTRIES);
+       seq_printf(seq, "info: RcvQ current       : %4.4X\n",
+                   adapter->rcvqueue.count);
+       seq_printf(seq, "rx stats: packets                  : %8.8lX\n",
+                   netdev->stats.rx_packets);
+       seq_printf(seq, "rx stats: bytes                    : %8.8lX\n",
+                   netdev->stats.rx_bytes);
+       seq_printf(seq, "rx stats: broadcasts               : %8.8X\n",
+                   adapter->rcv_broadcasts);
+       seq_printf(seq, "rx stats: multicasts               : %8.8X\n",
+                   adapter->rcv_multicasts);
+       seq_printf(seq, "rx stats: unicasts                 : %8.8X\n",
+                   adapter->rcv_unicasts);
+       seq_printf(seq, "rx stats: errors                   : %8.8X\n",
+                   (u32) adapter->slic_stats.iface.rcv_errors);
+       seq_printf(seq, "rx stats: Missed errors            : %8.8X\n",
+                   (u32) adapter->slic_stats.iface.rcv_discards);
+       seq_printf(seq, "rx stats: drops                    : %8.8X\n",
+                       (u32) adapter->rcv_drops);
+       seq_printf(seq, "tx stats: packets                  : %8.8lX\n",
+                       netdev->stats.tx_packets);
+       seq_printf(seq, "tx stats: bytes                    : %8.8lX\n",
+                       netdev->stats.tx_bytes);
+       seq_printf(seq, "tx stats: errors                   : %8.8X\n",
+                       (u32) adapter->slic_stats.iface.xmt_errors);
+       seq_printf(seq, "rx stats: multicasts               : %8.8lX\n",
+                       netdev->stats.multicast);
+       seq_printf(seq, "tx stats: collision errors         : %8.8X\n",
+                       (u32) adapter->slic_stats.iface.xmit_collisions);
+       seq_printf(seq, "perf: Max rcv frames/isr           : %8.8X\n",
+                       adapter->max_isr_rcvs);
+       seq_printf(seq, "perf: Rcv interrupt yields         : %8.8X\n",
+                       adapter->rcv_interrupt_yields);
+       seq_printf(seq, "perf: Max xmit complete/isr        : %8.8X\n",
+                       adapter->max_isr_xmits);
+       seq_printf(seq, "perf: error interrupts             : %8.8X\n",
+                       adapter->error_interrupts);
+       seq_printf(seq, "perf: error rmiss interrupts       : %8.8X\n",
+                       adapter->error_rmiss_interrupts);
+       seq_printf(seq, "perf: rcv interrupts               : %8.8X\n",
+                       adapter->rcv_interrupts);
+       seq_printf(seq, "perf: xmit interrupts              : %8.8X\n",
+                       adapter->xmit_interrupts);
+       seq_printf(seq, "perf: link event interrupts        : %8.8X\n",
+                       adapter->linkevent_interrupts);
+       seq_printf(seq, "perf: UPR interrupts               : %8.8X\n",
+                       adapter->upr_interrupts);
+       seq_printf(seq, "perf: interrupt count              : %8.8X\n",
+                       adapter->num_isrs);
+       seq_printf(seq, "perf: false interrupts             : %8.8X\n",
+                       adapter->false_interrupts);
+       seq_printf(seq, "perf: All register writes          : %8.8X\n",
+                       adapter->all_reg_writes);
+       seq_printf(seq, "perf: ICR register writes          : %8.8X\n",
+                       adapter->icr_reg_writes);
+       seq_printf(seq, "perf: ISR register writes          : %8.8X\n",
+                       adapter->isr_reg_writes);
+       seq_printf(seq, "ifevents: overflow 802 errors      : %8.8X\n",
+                       adapter->if_events.oflow802);
+       seq_printf(seq, "ifevents: transport overflow errors: %8.8X\n",
+                       adapter->if_events.Tprtoflow);
+       seq_printf(seq, "ifevents: underflow errors         : %8.8X\n",
+                       adapter->if_events.uflow802);
+       seq_printf(seq, "ifevents: receive early            : %8.8X\n",
+                       adapter->if_events.rcvearly);
+       seq_printf(seq, "ifevents: buffer overflows         : %8.8X\n",
+                       adapter->if_events.Bufov);
+       seq_printf(seq, "ifevents: carrier errors           : %8.8X\n",
+                       adapter->if_events.Carre);
+       seq_printf(seq, "ifevents: Long                     : %8.8X\n",
+                       adapter->if_events.Longe);
+       seq_printf(seq, "ifevents: invalid preambles        : %8.8X\n",
+                       adapter->if_events.Invp);
+       seq_printf(seq, "ifevents: CRC errors               : %8.8X\n",
+                       adapter->if_events.Crc);
+       seq_printf(seq, "ifevents: dribble nibbles          : %8.8X\n",
+                       adapter->if_events.Drbl);
+       seq_printf(seq, "ifevents: Code violations          : %8.8X\n",
+                       adapter->if_events.Code);
+       seq_printf(seq, "ifevents: TCP checksum errors      : %8.8X\n",
+                       adapter->if_events.TpCsum);
+       seq_printf(seq, "ifevents: TCP header short errors  : %8.8X\n",
+                       adapter->if_events.TpHlen);
+       seq_printf(seq, "ifevents: IP checksum errors       : %8.8X\n",
+                       adapter->if_events.IpCsum);
+       seq_printf(seq, "ifevents: IP frame incompletes     : %8.8X\n",
+                       adapter->if_events.IpLen);
+       seq_printf(seq, "ifevents: IP headers shorts        : %8.8X\n",
+                       adapter->if_events.IpHlen);
 
-               slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+       return 0;
+}
+static int slic_debug_adapter_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, slic_debug_adapter_show, inode->i_private);
+}
 
-               /* Setup rcvcfg last */
-               value = (RcrReset |     /* Reset, if linkchange */
-                        GRCR_CTLEN |   /* Enable CTL frames    */
-                        GRCR_ADDRAEN | /* Address A enable     */
-                        GRCR_RCVBAD |  /* Rcv bad frames       */
-                        (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
-       } else {
-               /* setup xmtcfg */
-               value = (GXCR_RESET |   /* Always reset     */
-                        GXCR_XMTEN);   /* Enable transmit  */
+static int slic_debug_card_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, slic_debug_card_show, inode->i_private);
+}
 
-               slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+static const struct file_operations slic_debug_adapter_fops = {
+       .owner          = THIS_MODULE,
+       .open           = slic_debug_adapter_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-               /* Setup rcvcfg last */
-               value = (RcrReset |     /* Reset, if linkchange */
-                        GRCR_ADDRAEN | /* Address A enable     */
-                        GRCR_RCVBAD |  /* Rcv bad frames       */
-                        (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
-       }
+static const struct file_operations slic_debug_card_fops = {
+       .owner          = THIS_MODULE,
+       .open           = slic_debug_card_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-       if (adapter->state != ADAPT_DOWN) {
-               /* Only enable receive if we are restarting or running */
-               value |= GRCR_RCVEN;
-       }
+static void slic_debug_adapter_create(struct adapter *adapter)
+{
+       struct dentry *d;
+       char    name[7];
+       struct sliccard *card = adapter->card;
 
-       if (adapter->macopts & MAC_PROMISC)
-               value |= GRCR_RCVALL;
+       if (!card->debugfs_dir)
+               return;
 
-       slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
+       sprintf(name, "port%d", adapter->port);
+       d = debugfs_create_file(name, S_IRUGO,
+                               card->debugfs_dir, adapter,
+                               &slic_debug_adapter_fops);
+       if (!d || IS_ERR(d))
+               pr_info(PFX "%s: debugfs create failed\n", name);
+       else
+               adapter->debugfs_entry = d;
 }
 
-/*
- *  Turn off RCV and XMT, power down PHY
- */
-static void slic_config_clear(struct adapter *adapter)
+static void slic_debug_adapter_destroy(struct adapter *adapter)
 {
-       u32 value;
-       u32 phy_config;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-
-       /* Setup xmtcfg */
-       value = (GXCR_RESET |   /* Always reset */
-                GXCR_PAUSEEN); /* Enable pause */
-
-       slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
-
-       value = (GRCR_RESET |   /* Always reset      */
-                GRCR_CTLEN |   /* Enable CTL frames */
-                GRCR_ADDRAEN | /* Address A enable  */
-                (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
-
-       slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
-
-       /* power down phy */
-       phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN));
-       slic_reg32_write(&slic_regs->slic_wphy, phy_config, FLUSH);
+       debugfs_remove(adapter->debugfs_entry);
+       adapter->debugfs_entry = NULL;
 }
 
-static void slic_config_get(struct adapter *adapter, u32 config,
-                                                       u32 config_h)
+static void slic_debug_card_create(struct sliccard *card)
 {
-       int status;
+       struct dentry *d;
+       char    name[IFNAMSIZ];
 
-       status = slic_upr_request(adapter,
-                                 SLIC_UPR_RCONFIG,
-                                 (u32) config, (u32) config_h, 0, 0);
-       ASSERT(status == 0);
+       snprintf(name, sizeof(name), "slic%d", card->cardnum);
+       d = debugfs_create_dir(name, slic_debugfs);
+       if (!d || IS_ERR(d))
+               pr_info(PFX "%s: debugfs create dir failed\n",
+                               name);
+       else {
+               card->debugfs_dir = d;
+               d = debugfs_create_file("cardinfo", S_IRUGO,
+                               slic_debugfs, card,
+                               &slic_debug_card_fops);
+               if (!d || IS_ERR(d))
+                       pr_info(PFX "%s: debugfs create failed\n",
+                                       name);
+               else
+                       card->debugfs_cardinfo = d;
+       }
 }
 
-static void slic_mac_address_config(struct adapter *adapter)
+static void slic_debug_card_destroy(struct sliccard *card)
 {
-       u32 value;
-       u32 value2;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+       int i;
 
-       value = *(u32 *) &adapter->currmacaddr[2];
-       value = ntohl(value);
-       slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH);
-       slic_reg32_write(&slic_regs->slic_wraddrbl, value, FLUSH);
+       for (i = 0; i < card->card_size; i++) {
+               struct adapter *adapter;
 
-       value2 = (u32) ((adapter->currmacaddr[0] << 8 |
-                            adapter->currmacaddr[1]) & 0xFFFF);
+               adapter = card->adapter[i];
+               if (adapter)
+                       slic_debug_adapter_destroy(adapter);
+       }
+       if (card->debugfs_cardinfo) {
+               debugfs_remove(card->debugfs_cardinfo);
+               card->debugfs_cardinfo = NULL;
+       }
+       if (card->debugfs_dir) {
+               debugfs_remove(card->debugfs_dir);
+               card->debugfs_dir = NULL;
+       }
+}
 
-       slic_reg32_write(&slic_regs->slic_wraddrah, value2, FLUSH);
-       slic_reg32_write(&slic_regs->slic_wraddrbh, value2, FLUSH);
+static void slic_debug_init(void)
+{
+       struct dentry *ent;
 
-       /* Write our multicast mask out to the card.  This is done */
-       /* here in addition to the slic_mcast_addr_set routine     */
-       /* because ALL_MCAST may have been enabled or disabled     */
-       slic_mcast_set_mask(adapter);
+       ent = debugfs_create_dir("slic", NULL);
+       if (!ent || IS_ERR(ent)) {
+               pr_info(PFX "debugfs create directory failed\n");
+               return;
+       }
+
+       slic_debugfs = ent;
 }
 
-static void slic_mac_config(struct adapter *adapter)
+static void slic_debug_cleanup(void)
 {
-       u32 value;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-
-       /* Setup GMAC gaps */
-       if (adapter->linkspeed == LINK_1000MB) {
-               value = ((GMCR_GAPBB_1000 << GMCR_GAPBB_SHIFT) |
-                        (GMCR_GAPR1_1000 << GMCR_GAPR1_SHIFT) |
-                        (GMCR_GAPR2_1000 << GMCR_GAPR2_SHIFT));
-       } else {
-               value = ((GMCR_GAPBB_100 << GMCR_GAPBB_SHIFT) |
-                        (GMCR_GAPR1_100 << GMCR_GAPR1_SHIFT) |
-                        (GMCR_GAPR2_100 << GMCR_GAPR2_SHIFT));
+       if (slic_debugfs) {
+               debugfs_remove(slic_debugfs);
+               slic_debugfs = NULL;
        }
+}
 
-       /* enable GMII */
-       if (adapter->linkspeed == LINK_1000MB)
-               value |= GMCR_GBIT;
+/*
+ * slic_link_event_handler -
+ *
+ * Initiate a link configuration sequence.  The link configuration begins
+ * by issuing a READ_LINK_STATUS command to the Utility Processor on the
+ * SLIC.  Since the command finishes asynchronously, the slic_upr_comlete
+ * routine will follow it up witha UP configuration write command, which
+ * will also complete asynchronously.
+ *
+ */
+static void slic_link_event_handler(struct adapter *adapter)
+{
+       int status;
+       struct slic_shmem *pshmem;
 
-       /* enable fullduplex */
-       if ((adapter->linkduplex == LINK_FULLD)
-           || (adapter->macopts & MAC_LOOPBACK)) {
-               value |= GMCR_FULLD;
+       if (adapter->state != ADAPT_UP) {
+               /* Adapter is not operational.  Ignore.  */
+               return;
        }
 
-       /* write mac config */
-       slic_reg32_write(&slic_regs->slic_wmcfg, value, FLUSH);
+       pshmem = (struct slic_shmem *)adapter->phys_shmem;
 
-       /* setup mac addresses */
-       slic_mac_address_config(adapter);
+#if defined(CONFIG_X86_64)
+       status = slic_upr_request(adapter,
+                                 SLIC_UPR_RLSR,
+                                 SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
+                                 SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
+                                 0, 0);
+#elif defined(CONFIG_X86)
+       status = slic_upr_request(adapter, SLIC_UPR_RLSR,
+               (u32) &pshmem->linkstatus,      /* no 4GB wrap guaranteed */
+                                 0, 0, 0);
+#else
+       Stop compilation;
+#endif
+       ASSERT(status == 0);
 }
 
-static bool slic_mac_filter(struct adapter *adapter,
-                       struct ether_header *ether_frame)
+static void slic_init_cleanup(struct adapter *adapter)
 {
-       u32 opts = adapter->macopts;
-       u32 *dhost4 = (u32 *)&ether_frame->ether_dhost[0];
-       u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
-
-       if (opts & MAC_PROMISC)
-               return true;
+       if (adapter->intrregistered) {
+               adapter->intrregistered = 0;
+               free_irq(adapter->netdev->irq, adapter->netdev);
 
-       if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) {
-               if (opts & MAC_BCAST) {
-                       adapter->rcv_broadcasts++;
-                       return true;
-               } else {
-                       return false;
-               }
        }
-
-       if (ether_frame->ether_dhost[0] & 0x01) {
-               if (opts & MAC_ALLMCAST) {
-                       adapter->rcv_multicasts++;
-                       adapter->stats.multicast++;
-                       return true;
-               }
-               if (opts & MAC_MCAST) {
-                       struct mcast_address *mcaddr = adapter->mcastaddrs;
-
-                       while (mcaddr) {
-                               if (!compare_ether_addr(mcaddr->address,
-                                                       ether_frame->ether_dhost)) {
-                                       adapter->rcv_multicasts++;
-                                       adapter->stats.multicast++;
-                                       return true;
-                               }
-                               mcaddr = mcaddr->next;
-                       }
-                       return false;
-               } else {
-                       return false;
-               }
+       if (adapter->pshmem) {
+               pci_free_consistent(adapter->pcidev,
+                                   sizeof(struct slic_shmem),
+                                   adapter->pshmem, adapter->phys_shmem);
+               adapter->pshmem = NULL;
+               adapter->phys_shmem = (dma_addr_t) NULL;
        }
-       if (opts & MAC_DIRECTED) {
-               adapter->rcv_unicasts++;
-               return true;
+
+       if (adapter->pingtimerset) {
+               adapter->pingtimerset = 0;
+               del_timer(&adapter->pingtimer);
        }
-       return false;
 
+       slic_rspqueue_free(adapter);
+       slic_cmdq_free(adapter);
+       slic_rcvqueue_free(adapter);
 }
 
-static int slic_mac_set_address(struct net_device *dev, void *ptr)
+/*
+ *  Allocate a mcast_address structure to hold the multicast address.
+ *  Link it in.
+ */
+static int slic_mcast_add_list(struct adapter *adapter, char *address)
 {
-       struct adapter *adapter = netdev_priv(dev);
-       struct sockaddr *addr = ptr;
+       struct mcast_address *mcaddr, *mlist;
 
-       if (netif_running(dev))
-               return -EBUSY;
-       if (!adapter)
-               return -EBUSY;
+       /* Check to see if it already exists */
+       mlist = adapter->mcastaddrs;
+       while (mlist) {
+               if (!compare_ether_addr(mlist->address, address))
+                       return 0;
+               mlist = mlist->next;
+       }
 
-       if (!is_valid_ether_addr(addr->sa_data))
-               return -EINVAL;
+       /* Doesn't already exist.  Allocate a structure to hold it */
+       mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
+       if (mcaddr == NULL)
+               return 1;
 
-       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-       memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
+       memcpy(mcaddr->address, address, 6);
+
+       mcaddr->next = adapter->mcastaddrs;
+       adapter->mcastaddrs = mcaddr;
 
-       slic_config_set(adapter, true);
        return 0;
 }
 
-static void slic_timer_load_check(ulong cardaddr)
+static void slic_mcast_set_list(struct net_device *dev)
 {
-       struct sliccard *card = (struct sliccard *)cardaddr;
-       struct adapter *adapter = card->master;
-       u32 __iomem *intagg;
-       u32 load = card->events;
-       u32 level = 0;
-
-       intagg = &adapter->slic_regs->slic_intagg;
+       struct adapter *adapter = netdev_priv(dev);
+       int status = 0;
+       char *addresses;
+       struct netdev_hw_addr *ha;
 
-       if ((adapter) && (adapter->state == ADAPT_UP) &&
-           (card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
-               if (adapter->devid == SLIC_1GB_DEVICE_ID) {
-                       if (adapter->linkspeed == LINK_1000MB)
-                               level = 100;
-                       else {
-                               if (load > SLIC_LOAD_5)
-                                       level = SLIC_INTAGG_5;
-                               else if (load > SLIC_LOAD_4)
-                                       level = SLIC_INTAGG_4;
-                               else if (load > SLIC_LOAD_3)
-                                       level = SLIC_INTAGG_3;
-                               else if (load > SLIC_LOAD_2)
-                                       level = SLIC_INTAGG_2;
-                               else if (load > SLIC_LOAD_1)
-                                       level = SLIC_INTAGG_1;
-                               else
-                                       level = SLIC_INTAGG_0;
-                       }
-                       if (card->loadlevel_current != level) {
-                               card->loadlevel_current = level;
-                               slic_reg32_write(intagg, level, FLUSH);
-                       }
-               } else {
-                       if (load > SLIC_LOAD_5)
-                               level = SLIC_INTAGG_5;
-                       else if (load > SLIC_LOAD_4)
-                               level = SLIC_INTAGG_4;
-                       else if (load > SLIC_LOAD_3)
-                               level = SLIC_INTAGG_3;
-                       else if (load > SLIC_LOAD_2)
-                               level = SLIC_INTAGG_2;
-                       else if (load > SLIC_LOAD_1)
-                               level = SLIC_INTAGG_1;
-                       else
-                               level = SLIC_INTAGG_0;
-                       if (card->loadlevel_current != level) {
-                               card->loadlevel_current = level;
-                               slic_reg32_write(intagg, level, FLUSH);
-                       }
+       ASSERT(adapter);
+
+       netdev_for_each_mc_addr(ha, dev) {
+               addresses = (char *) &ha->addr;
+               status = slic_mcast_add_list(adapter, addresses);
+               if (status != 0)
+                       break;
+               slic_mcast_set_bit(adapter, addresses);
+       }
+
+       if (adapter->devflags_prev != dev->flags) {
+               adapter->macopts = MAC_DIRECTED;
+               if (dev->flags) {
+                       if (dev->flags & IFF_BROADCAST)
+                               adapter->macopts |= MAC_BCAST;
+                       if (dev->flags & IFF_PROMISC)
+                               adapter->macopts |= MAC_PROMISC;
+                       if (dev->flags & IFF_ALLMULTI)
+                               adapter->macopts |= MAC_ALLMCAST;
+                       if (dev->flags & IFF_MULTICAST)
+                               adapter->macopts |= MAC_MCAST;
                }
+               adapter->devflags_prev = dev->flags;
+               slic_config_set(adapter, true);
+       } else {
+               if (status == 0)
+                       slic_mcast_set_mask(adapter);
        }
-       card->events = 0;
-       card->loadtimer.expires = jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
-       add_timer(&card->loadtimer);
+       return;
 }
 
-static void slic_assert_fail(void)
-{
-       u32 cpuid;
-       u32 curr_pid;
-       cpuid = smp_processor_id();
-       curr_pid = current->pid;
-
-       printk(KERN_ERR "%s CPU # %d ---- PID # %d\n",
-              __func__, cpuid, curr_pid);
-}
+#define  XMIT_FAIL_LINK_STATE               1
+#define  XMIT_FAIL_ZERO_LENGTH              2
+#define  XMIT_FAIL_HOSTCMD_FAIL             3
 
-static int slic_upr_queue_request(struct adapter *adapter,
-                          u32 upr_request,
-                          u32 upr_data,
-                          u32 upr_data_h,
-                          u32 upr_buffer, u32 upr_buffer_h)
+static void slic_xmit_build_request(struct adapter *adapter,
+                            struct slic_hostcmd *hcmd, struct sk_buff *skb)
 {
-       struct slic_upr *upr;
-       struct slic_upr *uprqueue;
-
-       upr = kmalloc(sizeof(struct slic_upr), GFP_ATOMIC);
-       if (!upr)
-               return -ENOMEM;
+       struct slic_host64_cmd *ihcmd;
+       ulong phys_addr;
 
-       upr->adapter = adapter->port;
-       upr->upr_request = upr_request;
-       upr->upr_data = upr_data;
-       upr->upr_buffer = upr_buffer;
-       upr->upr_data_h = upr_data_h;
-       upr->upr_buffer_h = upr_buffer_h;
-       upr->next = NULL;
-       if (adapter->upr_list) {
-               uprqueue = adapter->upr_list;
+       ihcmd = &hcmd->cmd64;
 
-               while (uprqueue->next)
-                       uprqueue = uprqueue->next;
-               uprqueue->next = upr;
-       } else {
-               adapter->upr_list = upr;
-       }
-       return STATUS_SUCCESS;
+       ihcmd->flags = (adapter->port << IHFLG_IFSHFT);
+       ihcmd->command = IHCMD_XMT_REQ;
+       ihcmd->u.slic_buffers.totlen = skb->len;
+       phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len,
+                       PCI_DMA_TODEVICE);
+       ihcmd->u.slic_buffers.bufs[0].paddrl = SLIC_GET_ADDR_LOW(phys_addr);
+       ihcmd->u.slic_buffers.bufs[0].paddrh = SLIC_GET_ADDR_HIGH(phys_addr);
+       ihcmd->u.slic_buffers.bufs[0].length = skb->len;
+#if defined(CONFIG_X86_64)
+       hcmd->cmdsize = (u32) ((((u64)&ihcmd->u.slic_buffers.bufs[1] -
+                                    (u64) hcmd) + 31) >> 5);
+#elif defined(CONFIG_X86)
+       hcmd->cmdsize = ((((u32) &ihcmd->u.slic_buffers.bufs[1] -
+                          (u32) hcmd) + 31) >> 5);
+#else
+       Stop Compilation;
+#endif
 }
 
-static int slic_upr_request(struct adapter *adapter,
-                    u32 upr_request,
-                    u32 upr_data,
-                    u32 upr_data_h,
-                    u32 upr_buffer, u32 upr_buffer_h)
+static void slic_xmit_fail(struct adapter *adapter,
+                   struct sk_buff *skb,
+                   void *cmd, u32 skbtype, u32 status)
 {
-       int status;
-
-       spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
-       status = slic_upr_queue_request(adapter,
-                                       upr_request,
-                                       upr_data,
-                                       upr_data_h, upr_buffer, upr_buffer_h);
-       if (status != STATUS_SUCCESS) {
-               spin_unlock_irqrestore(&adapter->upr_lock.lock,
-                                       adapter->upr_lock.flags);
-               return status;
+       if (adapter->xmitq_full)
+               netif_stop_queue(adapter->netdev);
+       if ((cmd == NULL) && (status <= XMIT_FAIL_HOSTCMD_FAIL)) {
+               switch (status) {
+               case XMIT_FAIL_LINK_STATE:
+                       dev_err(&adapter->netdev->dev,
+                               "reject xmit skb[%p: %x] linkstate[%s] "
+                               "adapter[%s:%d] card[%s:%d]\n",
+                               skb, skb->pkt_type,
+                               SLIC_LINKSTATE(adapter->linkstate),
+                               SLIC_ADAPTER_STATE(adapter->state),
+                               adapter->state,
+                               SLIC_CARD_STATE(adapter->card->state),
+                               adapter->card->state);
+                       break;
+               case XMIT_FAIL_ZERO_LENGTH:
+                       dev_err(&adapter->netdev->dev,
+                               "xmit_start skb->len == 0 skb[%p] type[%x]\n",
+                               skb, skb->pkt_type);
+                       break;
+               case XMIT_FAIL_HOSTCMD_FAIL:
+                       dev_err(&adapter->netdev->dev,
+                               "xmit_start skb[%p] type[%x] No host commands "
+                               "available\n", skb, skb->pkt_type);
+                       break;
+               default:
+                       ASSERT(0);
+               }
        }
-       slic_upr_start(adapter);
-       spin_unlock_irqrestore(&adapter->upr_lock.lock,
-                               adapter->upr_lock.flags);
-       return STATUS_PENDING;
+       dev_kfree_skb(skb);
+       adapter->netdev->stats.tx_dropped++;
 }
 
-static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
+static void slic_rcv_handle_error(struct adapter *adapter,
+                                       struct slic_rcvbuf *rcvbuf)
 {
-       struct sliccard *card = adapter->card;
-       struct slic_upr *upr;
-
-       spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
-       upr = adapter->upr_list;
-       if (!upr) {
-               ASSERT(0);
-               spin_unlock_irqrestore(&adapter->upr_lock.lock,
-                                       adapter->upr_lock.flags);
-               return;
-       }
-       adapter->upr_list = upr->next;
-       upr->next = NULL;
-       adapter->upr_busy = 0;
-       ASSERT(adapter->port == upr->adapter);
-       switch (upr->upr_request) {
-       case SLIC_UPR_STATS:
-               {
-                       struct slic_stats *slicstats =
-                           (struct slic_stats *) &adapter->pshmem->inicstats;
-                       struct slic_stats *newstats = slicstats;
-                       struct slic_stats  *old = &adapter->inicstats_prev;
-                       struct slicnet_stats *stst = &adapter->slic_stats;
+       struct slic_hddr_wds *hdr = (struct slic_hddr_wds *)rcvbuf->data;
+       struct net_device *netdev = adapter->netdev;
 
-                       if (isr & ISR_UPCERR) {
-                               dev_err(&adapter->netdev->dev,
-                                       "SLIC_UPR_STATS command failed isr[%x]\n",
-                                       isr);
+       if (adapter->devid != SLIC_1GB_DEVICE_ID) {
+               if (hdr->frame_status14 & VRHSTAT_802OE)
+                       adapter->if_events.oflow802++;
+               if (hdr->frame_status14 & VRHSTAT_TPOFLO)
+                       adapter->if_events.Tprtoflow++;
+               if (hdr->frame_status_b14 & VRHSTATB_802UE)
+                       adapter->if_events.uflow802++;
+               if (hdr->frame_status_b14 & VRHSTATB_RCVE) {
+                       adapter->if_events.rcvearly++;
+                       netdev->stats.rx_fifo_errors++;
+               }
+               if (hdr->frame_status_b14 & VRHSTATB_BUFF) {
+                       adapter->if_events.Bufov++;
+                       netdev->stats.rx_over_errors++;
+               }
+               if (hdr->frame_status_b14 & VRHSTATB_CARRE) {
+                       adapter->if_events.Carre++;
+                       netdev->stats.tx_carrier_errors++;
+               }
+               if (hdr->frame_status_b14 & VRHSTATB_LONGE)
+                       adapter->if_events.Longe++;
+               if (hdr->frame_status_b14 & VRHSTATB_PREA)
+                       adapter->if_events.Invp++;
+               if (hdr->frame_status_b14 & VRHSTATB_CRC) {
+                       adapter->if_events.Crc++;
+                       netdev->stats.rx_crc_errors++;
+               }
+               if (hdr->frame_status_b14 & VRHSTATB_DRBL)
+                       adapter->if_events.Drbl++;
+               if (hdr->frame_status_b14 & VRHSTATB_CODE)
+                       adapter->if_events.Code++;
+               if (hdr->frame_status_b14 & VRHSTATB_TPCSUM)
+                       adapter->if_events.TpCsum++;
+               if (hdr->frame_status_b14 & VRHSTATB_TPHLEN)
+                       adapter->if_events.TpHlen++;
+               if (hdr->frame_status_b14 & VRHSTATB_IPCSUM)
+                       adapter->if_events.IpCsum++;
+               if (hdr->frame_status_b14 & VRHSTATB_IPLERR)
+                       adapter->if_events.IpLen++;
+               if (hdr->frame_status_b14 & VRHSTATB_IPHERR)
+                       adapter->if_events.IpHlen++;
+       } else {
+               if (hdr->frame_statusGB & VGBSTAT_XPERR) {
+                       u32 xerr = hdr->frame_statusGB >> VGBSTAT_XERRSHFT;
 
-                               break;
-                       }
-                       UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs,
-                                       newstats->xmit_tcp_segs_gb,
-                                       old->xmit_tcp_segs_gb);
-
-                       UPDATE_STATS_GB(stst->tcp.xmit_tcp_bytes,
-                                       newstats->xmit_tcp_bytes_gb,
-                                       old->xmit_tcp_bytes_gb);
-
-                       UPDATE_STATS_GB(stst->tcp.rcv_tcp_segs,
-                                       newstats->rcv_tcp_segs_gb,
-                                       old->rcv_tcp_segs_gb);
-
-                       UPDATE_STATS_GB(stst->tcp.rcv_tcp_bytes,
-                                       newstats->rcv_tcp_bytes_gb,
-                                       old->rcv_tcp_bytes_gb);
-
-                       UPDATE_STATS_GB(stst->iface.xmt_bytes,
-                                       newstats->xmit_bytes_gb,
-                                       old->xmit_bytes_gb);
-
-                       UPDATE_STATS_GB(stst->iface.xmt_ucast,
-                                       newstats->xmit_unicasts_gb,
-                                       old->xmit_unicasts_gb);
+                       if (xerr == VGBSTAT_XCSERR)
+                               adapter->if_events.TpCsum++;
+                       if (xerr == VGBSTAT_XUFLOW)
+                               adapter->if_events.Tprtoflow++;
+                       if (xerr == VGBSTAT_XHLEN)
+                               adapter->if_events.TpHlen++;
+               }
+               if (hdr->frame_statusGB & VGBSTAT_NETERR) {
+                       u32 nerr =
+                           (hdr->
+                            frame_statusGB >> VGBSTAT_NERRSHFT) &
+                           VGBSTAT_NERRMSK;
+                       if (nerr == VGBSTAT_NCSERR)
+                               adapter->if_events.IpCsum++;
+                       if (nerr == VGBSTAT_NUFLOW)
+                               adapter->if_events.IpLen++;
+                       if (nerr == VGBSTAT_NHLEN)
+                               adapter->if_events.IpHlen++;
+               }
+               if (hdr->frame_statusGB & VGBSTAT_LNKERR) {
+                       u32 lerr = hdr->frame_statusGB & VGBSTAT_LERRMSK;
 
-                       UPDATE_STATS_GB(stst->iface.rcv_bytes,
-                                       newstats->rcv_bytes_gb,
-                                       old->rcv_bytes_gb);
+                       if (lerr == VGBSTAT_LDEARLY)
+                               adapter->if_events.rcvearly++;
+                       if (lerr == VGBSTAT_LBOFLO)
+                               adapter->if_events.Bufov++;
+                       if (lerr == VGBSTAT_LCODERR)
+                               adapter->if_events.Code++;
+                       if (lerr == VGBSTAT_LDBLNBL)
+                               adapter->if_events.Drbl++;
+                       if (lerr == VGBSTAT_LCRCERR)
+                               adapter->if_events.Crc++;
+                       if (lerr == VGBSTAT_LOFLO)
+                               adapter->if_events.oflow802++;
+                       if (lerr == VGBSTAT_LUFLO)
+                               adapter->if_events.uflow802++;
+               }
+       }
+       return;
+}
 
-                       UPDATE_STATS_GB(stst->iface.rcv_ucast,
-                                       newstats->rcv_unicasts_gb,
-                                       old->rcv_unicasts_gb);
+#define TCP_OFFLOAD_FRAME_PUSHFLAG  0x10000000
+#define M_FAST_PATH                 0x0040
 
-                       UPDATE_STATS_GB(stst->iface.xmt_errors,
-                                       newstats->xmit_collisions_gb,
-                                       old->xmit_collisions_gb);
+static void slic_rcv_handler(struct adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct sk_buff *skb;
+       struct slic_rcvbuf *rcvbuf;
+       u32 frames = 0;
 
-                       UPDATE_STATS_GB(stst->iface.xmt_errors,
-                                       newstats->xmit_excess_collisions_gb,
-                                       old->xmit_excess_collisions_gb);
+       while ((skb = slic_rcvqueue_getnext(adapter))) {
+               u32 rx_bytes;
 
-                       UPDATE_STATS_GB(stst->iface.xmt_errors,
-                                       newstats->xmit_other_error_gb,
-                                       old->xmit_other_error_gb);
+               ASSERT(skb->head);
+               rcvbuf = (struct slic_rcvbuf *)skb->head;
+               adapter->card->events++;
+               if (rcvbuf->status & IRHDDR_ERR) {
+                       adapter->rx_errors++;
+                       slic_rcv_handle_error(adapter, rcvbuf);
+                       slic_rcvqueue_reinsert(adapter, skb);
+                       continue;
+               }
 
-                       UPDATE_STATS_GB(stst->iface.rcv_errors,
-                                       newstats->rcv_other_error_gb,
-                                       old->rcv_other_error_gb);
+               if (!slic_mac_filter(adapter, (struct ether_header *)
+                                       rcvbuf->data)) {
+                       slic_rcvqueue_reinsert(adapter, skb);
+                       continue;
+               }
+               skb_pull(skb, SLIC_RCVBUF_HEADSIZE);
+               rx_bytes = (rcvbuf->length & IRHDDR_FLEN_MSK);
+               skb_put(skb, rx_bytes);
+               netdev->stats.rx_packets++;
+               netdev->stats.rx_bytes += rx_bytes;
+#if SLIC_OFFLOAD_IP_CHECKSUM
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+#endif
 
-                       UPDATE_STATS_GB(stst->iface.rcv_discards,
-                                       newstats->rcv_drops_gb,
-                                       old->rcv_drops_gb);
+               skb->dev = adapter->netdev;
+               skb->protocol = eth_type_trans(skb, skb->dev);
+               netif_rx(skb);
 
-                       if (newstats->rcv_drops_gb > old->rcv_drops_gb) {
-                               adapter->rcv_drops +=
-                                   (newstats->rcv_drops_gb -
-                                    old->rcv_drops_gb);
-                       }
-                       memcpy(old, newstats, sizeof(struct slic_stats));
+               ++frames;
+#if SLIC_INTERRUPT_PROCESS_LIMIT
+               if (frames >= SLIC_RCVQ_MAX_PROCESS_ISR) {
+                       adapter->rcv_interrupt_yields++;
                        break;
                }
-       case SLIC_UPR_RLSR:
-               slic_link_upr_complete(adapter, isr);
-               break;
-       case SLIC_UPR_RCONFIG:
-               break;
-       case SLIC_UPR_RPHY:
-               ASSERT(0);
-               break;
-       case SLIC_UPR_ENLB:
-               ASSERT(0);
-               break;
-       case SLIC_UPR_ENCT:
-               ASSERT(0);
-               break;
-       case SLIC_UPR_PDWN:
-               ASSERT(0);
-               break;
-       case SLIC_UPR_PING:
-               card->pingstatus |= (isr & ISR_PINGDSMASK);
-               break;
-       default:
-               ASSERT(0);
+#endif
        }
-       kfree(upr);
-       slic_upr_start(adapter);
-       spin_unlock_irqrestore(&adapter->upr_lock.lock,
-                               adapter->upr_lock.flags);
+       adapter->max_isr_rcvs = max(adapter->max_isr_rcvs, frames);
 }
 
-static void slic_upr_start(struct adapter *adapter)
+static void slic_xmit_complete(struct adapter *adapter)
 {
-       struct slic_upr *upr;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-/*
-    char * ptr1;
-    char * ptr2;
-    uint cmdoffset;
-*/
-       upr = adapter->upr_list;
-       if (!upr)
-               return;
-       if (adapter->upr_busy)
-               return;
-       adapter->upr_busy = 1;
+       struct slic_hostcmd *hcmd;
+       struct slic_rspbuf *rspbuf;
+       u32 frames = 0;
+       struct slic_handle_word slic_handle_word;
 
-       switch (upr->upr_request) {
-       case SLIC_UPR_STATS:
-               if (upr->upr_data_h == 0) {
-                       slic_reg32_write(&slic_regs->slic_stats, upr->upr_data,
-                                        FLUSH);
-               } else {
-                       slic_reg64_write(adapter, &slic_regs->slic_stats64,
-                                        upr->upr_data,
-                                        &slic_regs->slic_addr_upper,
-                                        upr->upr_data_h, FLUSH);
+       do {
+               rspbuf = slic_rspqueue_getnext(adapter);
+               if (!rspbuf)
+                       break;
+               adapter->xmit_completes++;
+               adapter->card->events++;
+               /*
+                Get the complete host command buffer
+               */
+               slic_handle_word.handle_token = rspbuf->hosthandle;
+               ASSERT(slic_handle_word.handle_index);
+               ASSERT(slic_handle_word.handle_index <= SLIC_CMDQ_MAXCMDS);
+               hcmd =
+                   (struct slic_hostcmd *)
+                       adapter->slic_handles[slic_handle_word.handle_index].
+                                                                       address;
+/*      hcmd = (struct slic_hostcmd *) rspbuf->hosthandle; */
+               ASSERT(hcmd);
+               ASSERT(hcmd->pslic_handle ==
+                      &adapter->slic_handles[slic_handle_word.handle_index]);
+               if (hcmd->type == SLIC_CMD_DUMB) {
+                       if (hcmd->skb)
+                               dev_kfree_skb_irq(hcmd->skb);
+                       slic_cmdq_putdone_irq(adapter, hcmd);
                }
-               break;
-
-       case SLIC_UPR_RLSR:
-               slic_reg64_write(adapter, &slic_regs->slic_rlsr, upr->upr_data,
-                                &slic_regs->slic_addr_upper, upr->upr_data_h,
-                                FLUSH);
-               break;
-
-       case SLIC_UPR_RCONFIG:
-               slic_reg64_write(adapter, &slic_regs->slic_rconfig,
-                                upr->upr_data, &slic_regs->slic_addr_upper,
-                                upr->upr_data_h, FLUSH);
-               break;
-       case SLIC_UPR_PING:
-               slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH);
-               break;
-       default:
-               ASSERT(0);
-       }
+               rspbuf->status = 0;
+               rspbuf->hosthandle = 0;
+               frames++;
+       } while (1);
+       adapter->max_isr_xmits = max(adapter->max_isr_xmits, frames);
 }
 
-static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
+static irqreturn_t slic_interrupt(int irq, void *dev_id)
 {
-       u32 linkstatus = adapter->pshmem->linkstatus;
-       uint linkup;
-       unsigned char linkspeed;
-       unsigned char linkduplex;
+       struct net_device *dev = (struct net_device *)dev_id;
+       struct adapter *adapter = netdev_priv(dev);
+       u32 isr;
 
-       if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
-               struct slic_shmem *pshmem;
+       if ((adapter->pshmem) && (adapter->pshmem->isr)) {
+               slic_reg32_write(&adapter->slic_regs->slic_icr,
+                                ICR_INT_MASK, FLUSH);
+               isr = adapter->isrcopy = adapter->pshmem->isr;
+               adapter->pshmem->isr = 0;
+               adapter->num_isrs++;
+               switch (adapter->card->state) {
+               case CARD_UP:
+                       if (isr & ~ISR_IO) {
+                               if (isr & ISR_ERR) {
+                                       adapter->error_interrupts++;
+                                       if (isr & ISR_RMISS) {
+                                               int count;
+                                               int pre_count;
+                                               int errors;
 
-               pshmem = (struct slic_shmem *)adapter->phys_shmem;
-#if defined(CONFIG_X86_64)
-               slic_upr_queue_request(adapter,
-                                      SLIC_UPR_RLSR,
-                                      SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
-                                      SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
-                                      0, 0);
-#elif defined(CONFIG_X86)
-               slic_upr_queue_request(adapter,
-                                      SLIC_UPR_RLSR,
-                                      (u32) &pshmem->linkstatus,
-                                      SLIC_GET_ADDR_HIGH(pshmem), 0, 0);
-#else
-               Stop Compilation;
-#endif
-               return;
-       }
-       if (adapter->state != ADAPT_UP)
-               return;
+                                               struct slic_rcvqueue *rcvq =
+                                                   &adapter->rcvqueue;
 
-       ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
-              || (adapter->devid == SLIC_2GB_DEVICE_ID));
+                                               adapter->
+                                                   error_rmiss_interrupts++;
+                                               if (!rcvq->errors)
+                                                       rcv_count = rcvq->count;
+                                               pre_count = rcvq->count;
+                                               errors = rcvq->errors;
 
-       linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
-       if (linkstatus & GIG_SPEED_1000)
-               linkspeed = LINK_1000MB;
-       else if (linkstatus & GIG_SPEED_100)
-               linkspeed = LINK_100MB;
-       else
-               linkspeed = LINK_10MB;
+                                               while (rcvq->count <
+                                                      SLIC_RCVQ_FILLTHRESH) {
+                                                       count =
+                                                           slic_rcvqueue_fill
+                                                           (adapter);
+                                                       if (!count)
+                                                               break;
+                                               }
+                                       } else if (isr & ISR_XDROP) {
+                                               dev_err(&dev->dev,
+                                                       "isr & ISR_ERR [%x] "
+                                                       "ISR_XDROP \n", isr);
+                                       } else {
+                                               dev_err(&dev->dev,
+                                                       "isr & ISR_ERR [%x]\n",
+                                                       isr);
+                                       }
+                               }
 
-       if (linkstatus & GIG_FULLDUPLEX)
-               linkduplex = LINK_FULLD;
-       else
-               linkduplex = LINK_HALFD;
+                               if (isr & ISR_LEVENT) {
+                                       adapter->linkevent_interrupts++;
+                                       slic_link_event_handler(adapter);
+                               }
 
-       if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN))
-               return;
+                               if ((isr & ISR_UPC) ||
+                                   (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
+                                       adapter->upr_interrupts++;
+                                       slic_upr_request_complete(adapter, isr);
+                               }
+                       }
 
-       /* link up event, but nothing has changed */
-       if ((adapter->linkstate == LINK_UP) &&
-           (linkup == LINK_UP) &&
-           (adapter->linkspeed == linkspeed) &&
-           (adapter->linkduplex == linkduplex))
-               return;
+                       if (isr & ISR_RCV) {
+                               adapter->rcv_interrupts++;
+                               slic_rcv_handler(adapter);
+                       }
 
-       /* link has changed at this point */
+                       if (isr & ISR_CMD) {
+                               adapter->xmit_interrupts++;
+                               slic_xmit_complete(adapter);
+                       }
+                       break;
 
-       /* link has gone from up to down */
-       if (linkup == LINK_DOWN) {
-               adapter->linkstate = LINK_DOWN;
-               return;
-       }
+               case CARD_DOWN:
+                       if ((isr & ISR_UPC) ||
+                           (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
+                               adapter->upr_interrupts++;
+                               slic_upr_request_complete(adapter, isr);
+                       }
+                       break;
 
-       /* link has gone from down to up */
-       adapter->linkspeed = linkspeed;
-       adapter->linkduplex = linkduplex;
+               default:
+                       break;
+               }
 
-       if (adapter->linkstate != LINK_UP) {
-               /* setup the mac */
-               slic_config_set(adapter, true);
-               adapter->linkstate = LINK_UP;
-               netif_start_queue(adapter->netdev);
+               adapter->isrcopy = 0;
+               adapter->all_reg_writes += 2;
+               adapter->isr_reg_writes++;
+               slic_reg32_write(&adapter->slic_regs->slic_isr, 0, FLUSH);
+       } else {
+               adapter->false_interrupts++;
        }
+       return IRQ_HANDLED;
 }
 
-/*
- *  this is here to checksum the eeprom, there is some ucode bug
- *  which prevens us from using the ucode result.
- *  remove this once ucode is fixed.
- */
-static ushort slic_eeprom_cksum(char *m, int len)
+#define NORMAL_ETHFRAME     0
+
+static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
-#define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
-#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);\
-               }
+       struct sliccard *card;
+       struct adapter *adapter = netdev_priv(dev);
+       struct slic_hostcmd *hcmd = NULL;
+       u32 status = 0;
+       u32 skbtype = NORMAL_ETHFRAME;
+       void *offloadcmd = NULL;
 
-       u16 *w;
-       u32 sum = 0;
-       u32 byte_swapped = 0;
-       u32 w_int;
+       card = adapter->card;
+       ASSERT(card);
+       if ((adapter->linkstate != LINK_UP) ||
+           (adapter->state != ADAPT_UP) || (card->state != CARD_UP)) {
+               status = XMIT_FAIL_LINK_STATE;
+               goto xmit_fail;
 
-       union {
-               char c[2];
-               ushort s;
-       } s_util;
+       } else if (skb->len == 0) {
+               status = XMIT_FAIL_ZERO_LENGTH;
+               goto xmit_fail;
+       }
 
-       union {
-               ushort s[2];
-               int l;
-       } l_util;
+       if (skbtype == NORMAL_ETHFRAME) {
+               hcmd = slic_cmdq_getfree(adapter);
+               if (!hcmd) {
+                       adapter->xmitq_full = 1;
+                       status = XMIT_FAIL_HOSTCMD_FAIL;
+                       goto xmit_fail;
+               }
+               ASSERT(hcmd->pslic_handle);
+               ASSERT(hcmd->cmd64.hosthandle ==
+                      hcmd->pslic_handle->token.handle_token);
+               hcmd->skb = skb;
+               hcmd->busy = 1;
+               hcmd->type = SLIC_CMD_DUMB;
+               if (skbtype == NORMAL_ETHFRAME)
+                       slic_xmit_build_request(adapter, hcmd, skb);
+       }
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += skb->len;
 
-       l_util.l = 0;
-       s_util.s = 0;
+#ifdef DEBUG_DUMP
+       if (adapter->kill_card) {
+               struct slic_host64_cmd ihcmd;
 
-       w = (u16 *)m;
-#ifdef CONFIG_X86_64
-       w_int = (u32) ((ulong) w & 0x00000000FFFFFFFF);
-#else
-       w_int = (u32) (w);
-#endif
-       if ((1 & w_int) && (len > 0)) {
-               REDUCE;
-               sum <<= 8;
-               s_util.c[0] = *(unsigned char *)w;
-               w = (u16 *)((char *)w + 1);
-               len--;
-               byte_swapped = 1;
-       }
+               ihcmd = &hcmd->cmd64;
 
-       /* Unroll the loop to make overhead from branches &c small. */
-       while ((len -= 32) >= 0) {
-               sum += w[0];
-               sum += w[1];
-               sum += w[2];
-               sum += w[3];
-               sum += w[4];
-               sum += w[5];
-               sum += w[6];
-               sum += w[7];
-               sum += w[8];
-               sum += w[9];
-               sum += w[10];
-               sum += w[11];
-               sum += w[12];
-               sum += w[13];
-               sum += w[14];
-               sum += w[15];
-               w = (u16 *)((ulong) w + 16);    /* verify */
+               ihcmd->flags |= 0x40;
+               adapter->kill_card = 0; /* only do this once */
        }
-       len += 32;
-       while ((len -= 8) >= 0) {
-               sum += w[0];
-               sum += w[1];
-               sum += w[2];
-               sum += w[3];
-               w = (u16 *)((ulong) w + 4);     /* verify */
+#endif
+       if (hcmd->paddrh == 0) {
+               slic_reg32_write(&adapter->slic_regs->slic_cbar,
+                                (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
+       } else {
+               slic_reg64_write(adapter, &adapter->slic_regs->slic_cbar64,
+                                (hcmd->paddrl | hcmd->cmdsize),
+                                &adapter->slic_regs->slic_addr_upper,
+                                hcmd->paddrh, DONT_FLUSH);
        }
-       len += 8;
-       if (len != 0 || byte_swapped != 0) {
-               REDUCE;
-               while ((len -= 2) >= 0)
-                       sum += *w++;    /* verify */
-               if (byte_swapped) {
-                       REDUCE;
-                       sum <<= 8;
-                       byte_swapped = 0;
-                       if (len == -1) {
-                               s_util.c[1] = *(char *) w;
-                               sum += s_util.s;
-                               len = 0;
-                       } else {
-                               len = -1;
-                       }
+xmit_done:
+       return NETDEV_TX_OK;
+xmit_fail:
+       slic_xmit_fail(adapter, skb, offloadcmd, skbtype, status);
+       goto xmit_done;
+}
 
-               } else if (len == -1) {
-                       s_util.c[0] = *(char *) w;
-               }
 
-               if (len == -1) {
-                       s_util.c[1] = 0;
-                       sum += s_util.s;
-               }
-       }
-       REDUCE;
-       return (ushort) sum;
+static void slic_adapter_freeresources(struct adapter *adapter)
+{
+       slic_init_cleanup(adapter);
+       adapter->error_interrupts = 0;
+       adapter->rcv_interrupts = 0;
+       adapter->xmit_interrupts = 0;
+       adapter->linkevent_interrupts = 0;
+       adapter->upr_interrupts = 0;
+       adapter->num_isrs = 0;
+       adapter->xmit_completes = 0;
+       adapter->rcv_broadcasts = 0;
+       adapter->rcv_multicasts = 0;
+       adapter->rcv_unicasts = 0;
 }
 
-static int slic_rspqueue_init(struct adapter *adapter)
+static int slic_adapter_allocresources(struct adapter *adapter)
 {
-       int i;
-       struct slic_rspqueue *rspq = &adapter->rspqueue;
-       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-       u32 paddrh = 0;
+       if (!adapter->intrregistered) {
+               int retval;
 
-       ASSERT(adapter->state == ADAPT_DOWN);
-       memset(rspq, 0, sizeof(struct slic_rspqueue));
+               spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+                                       slic_global.driver_lock.flags);
 
-       rspq->num_pages = SLIC_RSPQ_PAGES_GB;
+               retval = request_irq(adapter->netdev->irq,
+                                    &slic_interrupt,
+                                    IRQF_SHARED,
+                                    adapter->netdev->name, adapter->netdev);
 
-       for (i = 0; i < rspq->num_pages; i++) {
-               rspq->vaddr[i] = pci_alloc_consistent(adapter->pcidev,
-                                                     PAGE_SIZE,
-                                                     &rspq->paddr[i]);
-               if (!rspq->vaddr[i]) {
-                       dev_err(&adapter->pcidev->dev,
-                               "pci_alloc_consistent failed\n");
-                       slic_rspqueue_free(adapter);
-                       return STATUS_FAILURE;
-               }
-#ifndef CONFIG_X86_64
-               ASSERT(((u32) rspq->vaddr[i] & 0xFFFFF000) ==
-                      (u32) rspq->vaddr[i]);
-               ASSERT(((u32) rspq->paddr[i] & 0xFFFFF000) ==
-                      (u32) rspq->paddr[i]);
-#endif
-               memset(rspq->vaddr[i], 0, PAGE_SIZE);
+               spin_lock_irqsave(&slic_global.driver_lock.lock,
+                                       slic_global.driver_lock.flags);
 
-               if (paddrh == 0) {
-                       slic_reg32_write(&slic_regs->slic_rbar,
-                               (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
-                               DONT_FLUSH);
-               } else {
-                       slic_reg64_write(adapter, &slic_regs->slic_rbar64,
-                               (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
-                               &slic_regs->slic_addr_upper,
-                               paddrh, DONT_FLUSH);
+               if (retval) {
+                       dev_err(&adapter->netdev->dev,
+                               "request_irq (%s) FAILED [%x]\n",
+                               adapter->netdev->name, retval);
+                       return retval;
                }
+               adapter->intrregistered = 1;
        }
-       rspq->offset = 0;
-       rspq->pageindex = 0;
-       rspq->rspbuf = (struct slic_rspbuf *)rspq->vaddr[0];
-       return STATUS_SUCCESS;
+       return 0;
 }
 
-static void slic_rspqueue_free(struct adapter *adapter)
+/*
+ *  slic_if_init
+ *
+ *  Perform initialization of our slic interface.
+ *
+ */
+static int slic_if_init(struct adapter *adapter)
 {
-       int i;
-       struct slic_rspqueue *rspq = &adapter->rspqueue;
+       struct sliccard *card = adapter->card;
+       struct net_device *dev = adapter->netdev;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+       struct slic_shmem *pshmem;
+       int rc;
 
-       for (i = 0; i < rspq->num_pages; i++) {
-               if (rspq->vaddr[i]) {
-                       pci_free_consistent(adapter->pcidev, PAGE_SIZE,
-                                           rspq->vaddr[i], rspq->paddr[i]);
-               }
-               rspq->vaddr[i] = NULL;
-               rspq->paddr[i] = 0;
+       ASSERT(card);
+
+       /* adapter should be down at this point */
+       if (adapter->state != ADAPT_DOWN) {
+               dev_err(&dev->dev, "%s: adapter->state != ADAPT_DOWN\n",
+                       __func__);
+               rc = -EIO;
+               goto err;
        }
-       rspq->offset = 0;
-       rspq->pageindex = 0;
-       rspq->rspbuf = NULL;
-}
+       ASSERT(adapter->linkstate == LINK_DOWN);
 
-static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
-{
-       struct slic_rspqueue *rspq = &adapter->rspqueue;
-       struct slic_rspbuf *buf;
+       adapter->devflags_prev = dev->flags;
+       adapter->macopts = MAC_DIRECTED;
+       if (dev->flags) {
+               if (dev->flags & IFF_BROADCAST)
+                       adapter->macopts |= MAC_BCAST;
+               if (dev->flags & IFF_PROMISC)
+                       adapter->macopts |= MAC_PROMISC;
+               if (dev->flags & IFF_ALLMULTI)
+                       adapter->macopts |= MAC_ALLMCAST;
+               if (dev->flags & IFF_MULTICAST)
+                       adapter->macopts |= MAC_MCAST;
+       }
+       rc = slic_adapter_allocresources(adapter);
+       if (rc) {
+               dev_err(&dev->dev,
+                       "%s: slic_adapter_allocresources FAILED %x\n",
+                       __func__, rc);
+               slic_adapter_freeresources(adapter);
+               goto err;
+       }
 
-       if (!(rspq->rspbuf->status))
-               return NULL;
+       if (!adapter->queues_initialized) {
+               if ((rc = slic_rspqueue_init(adapter)))
+                       goto err;
+               if ((rc = slic_cmdq_init(adapter)))
+                       goto err;
+               if ((rc = slic_rcvqueue_init(adapter)))
+                       goto err;
+               adapter->queues_initialized = 1;
+       }
 
-       buf = rspq->rspbuf;
-#ifndef CONFIG_X86_64
-       ASSERT((buf->status & 0xFFFFFFE0) == 0);
-#endif
-       ASSERT(buf->hosthandle);
-       if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) {
-               rspq->rspbuf++;
-#ifndef CONFIG_X86_64
-               ASSERT(((u32) rspq->rspbuf & 0xFFFFFFE0) ==
-                      (u32) rspq->rspbuf);
-#endif
-       } else {
-               ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE);
-               slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64,
-                       (rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
-                       &adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
-               rspq->pageindex = (++rspq->pageindex) % rspq->num_pages;
-               rspq->offset = 0;
-               rspq->rspbuf = (struct slic_rspbuf *)
-                                               rspq->vaddr[rspq->pageindex];
-#ifndef CONFIG_X86_64
-               ASSERT(((u32) rspq->rspbuf & 0xFFFFF000) ==
-                      (u32) rspq->rspbuf);
+       slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+       mdelay(1);
+
+       if (!adapter->isp_initialized) {
+               pshmem = (struct slic_shmem *)adapter->phys_shmem;
+
+               spin_lock_irqsave(&adapter->bit64reglock.lock,
+                                       adapter->bit64reglock.flags);
+
+#if defined(CONFIG_X86_64)
+               slic_reg32_write(&slic_regs->slic_addr_upper,
+                                SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
+               slic_reg32_write(&slic_regs->slic_isp,
+                                SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+#elif defined(CONFIG_X86)
+               slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+               slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH);
+#else
+               Stop Compilations
 #endif
+               spin_unlock_irqrestore(&adapter->bit64reglock.lock,
+                                       adapter->bit64reglock.flags);
+               adapter->isp_initialized = 1;
        }
-#ifndef CONFIG_X86_64
-       ASSERT(((u32) buf & 0xFFFFFFE0) == (u32) buf);
-#endif
-       return buf;
-}
-
-static void slic_cmdqmem_init(struct adapter *adapter)
-{
-       struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
 
-       memset(cmdqmem, 0, sizeof(struct slic_cmdqmem));
-}
+       adapter->state = ADAPT_UP;
+       if (!card->loadtimerset) {
+               init_timer(&card->loadtimer);
+               card->loadtimer.expires =
+                   jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
+               card->loadtimer.data = (ulong) card;
+               card->loadtimer.function = &slic_timer_load_check;
+               add_timer(&card->loadtimer);
 
-static void slic_cmdqmem_free(struct adapter *adapter)
-{
-       struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
-       int i;
+               card->loadtimerset = 1;
+       }
 
-       for (i = 0; i < SLIC_CMDQ_MAXPAGES; i++) {
-               if (cmdqmem->pages[i]) {
-                       pci_free_consistent(adapter->pcidev,
-                                           PAGE_SIZE,
-                                           (void *) cmdqmem->pages[i],
-                                           cmdqmem->dma_pages[i]);
-               }
+       if (!adapter->pingtimerset) {
+               init_timer(&adapter->pingtimer);
+               adapter->pingtimer.expires =
+                   jiffies + (PING_TIMER_INTERVAL * HZ);
+               adapter->pingtimer.data = (ulong) dev;
+               adapter->pingtimer.function = &slic_timer_ping;
+               add_timer(&adapter->pingtimer);
+               adapter->pingtimerset = 1;
+               adapter->card->pingstatus = ISR_PINGMASK;
        }
-       memset(cmdqmem, 0, sizeof(struct slic_cmdqmem));
-}
 
-static u32 *slic_cmdqmem_addpage(struct adapter *adapter)
-{
-       struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
-       u32 *pageaddr;
+       /*
+        *    clear any pending events, then enable interrupts
+        */
+       adapter->isrcopy = 0;
+       adapter->pshmem->isr = 0;
+       slic_reg32_write(&slic_regs->slic_isr, 0, FLUSH);
+       slic_reg32_write(&slic_regs->slic_icr, ICR_INT_ON, FLUSH);
 
-       if (cmdqmem->pagecnt >= SLIC_CMDQ_MAXPAGES)
-               return NULL;
-       pageaddr = pci_alloc_consistent(adapter->pcidev,
-                                       PAGE_SIZE,
-                                       &cmdqmem->dma_pages[cmdqmem->pagecnt]);
-       if (!pageaddr)
-               return NULL;
-#ifndef CONFIG_X86_64
-       ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
-#endif
-       cmdqmem->pages[cmdqmem->pagecnt] = pageaddr;
-       cmdqmem->pagecnt++;
-       return pageaddr;
+       slic_link_config(adapter, LINK_AUTOSPEED, LINK_AUTOD);
+       slic_link_event_handler(adapter);
+
+err:
+       return rc;
 }
 
-static int slic_cmdq_init(struct adapter *adapter)
+static int slic_entry_open(struct net_device *dev)
 {
-       int i;
-       u32 *pageaddr;
+       struct adapter *adapter = netdev_priv(dev);
+       struct sliccard *card = adapter->card;
+       u32 locked = 0;
+       int status;
 
-       ASSERT(adapter->state == ADAPT_DOWN);
-       memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
-       memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
-       memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue));
-       spin_lock_init(&adapter->cmdq_all.lock.lock);
-       spin_lock_init(&adapter->cmdq_free.lock.lock);
-       spin_lock_init(&adapter->cmdq_done.lock.lock);
-       slic_cmdqmem_init(adapter);
-       adapter->slic_handle_ix = 1;
-       for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) {
-               pageaddr = slic_cmdqmem_addpage(adapter);
-#ifndef CONFIG_X86_64
-               ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
-#endif
-               if (!pageaddr) {
-                       slic_cmdq_free(adapter);
-                       return STATUS_FAILURE;
-               }
-               slic_cmdq_addcmdpage(adapter, pageaddr);
-       }
-       adapter->slic_handle_ix = 1;
-
-       return STATUS_SUCCESS;
-}
-
-static void slic_cmdq_free(struct adapter *adapter)
-{
-       struct slic_hostcmd *cmd;
+       ASSERT(adapter);
+       ASSERT(card);
 
-       cmd = adapter->cmdq_all.head;
-       while (cmd) {
-               if (cmd->busy) {
-                       struct sk_buff *tempskb;
+       netif_stop_queue(adapter->netdev);
 
-                       tempskb = cmd->skb;
-                       if (tempskb) {
-                               cmd->skb = NULL;
-                               dev_kfree_skb_irq(tempskb);
-                       }
-               }
-               cmd = cmd->next_all;
+       spin_lock_irqsave(&slic_global.driver_lock.lock,
+                               slic_global.driver_lock.flags);
+       locked = 1;
+       if (!adapter->activated) {
+               card->adapters_activated++;
+               slic_global.num_slic_ports_active++;
+               adapter->activated = 1;
        }
-       memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
-       memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
-       memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue));
-       slic_cmdqmem_free(adapter);
-}
-
-static void slic_cmdq_reset(struct adapter *adapter)
-{
-       struct slic_hostcmd *hcmd;
-       struct sk_buff *skb;
-       u32 outstanding;
+       status = slic_if_init(adapter);
 
-       spin_lock_irqsave(&adapter->cmdq_free.lock.lock,
-                       adapter->cmdq_free.lock.flags);
-       spin_lock_irqsave(&adapter->cmdq_done.lock.lock,
-                       adapter->cmdq_done.lock.flags);
-       outstanding = adapter->cmdq_all.count - adapter->cmdq_done.count;
-       outstanding -= adapter->cmdq_free.count;
-       hcmd = adapter->cmdq_all.head;
-       while (hcmd) {
-               if (hcmd->busy) {
-                       skb = hcmd->skb;
-                       ASSERT(skb);
-                       hcmd->busy = 0;
-                       hcmd->skb = NULL;
-                       dev_kfree_skb_irq(skb);
+       if (status != 0) {
+               if (adapter->activated) {
+                       card->adapters_activated--;
+                       slic_global.num_slic_ports_active--;
+                       adapter->activated = 0;
                }
-               hcmd = hcmd->next_all;
-       }
-       adapter->cmdq_free.count = 0;
-       adapter->cmdq_free.head = NULL;
-       adapter->cmdq_free.tail = NULL;
-       adapter->cmdq_done.count = 0;
-       adapter->cmdq_done.head = NULL;
-       adapter->cmdq_done.tail = NULL;
-       adapter->cmdq_free.head = adapter->cmdq_all.head;
-       hcmd = adapter->cmdq_all.head;
-       while (hcmd) {
-               adapter->cmdq_free.count++;
-               hcmd->next = hcmd->next_all;
-               hcmd = hcmd->next_all;
+               if (locked) {
+                       spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+                                               slic_global.driver_lock.flags);
+                       locked = 0;
+               }
+               return status;
        }
-       if (adapter->cmdq_free.count != adapter->cmdq_all.count) {
-               dev_err(&adapter->netdev->dev,
-                       "free_count %d != all count %d\n",
-                       adapter->cmdq_free.count, adapter->cmdq_all.count);
+       if (!card->master)
+               card->master = adapter;
+
+       if (locked) {
+               spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+                                       slic_global.driver_lock.flags);
+               locked = 0;
        }
-       spin_unlock_irqrestore(&adapter->cmdq_done.lock.lock,
-                               adapter->cmdq_done.lock.flags);
-       spin_unlock_irqrestore(&adapter->cmdq_free.lock.lock,
-                               adapter->cmdq_free.lock.flags);
+
+       return 0;
 }
 
-static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
+static void slic_card_cleanup(struct sliccard *card)
 {
-       struct slic_hostcmd *cmd;
-       struct slic_hostcmd *prev;
-       struct slic_hostcmd *tail;
-       struct slic_cmdqueue *cmdq;
-       int cmdcnt;
-       void *cmdaddr;
-       ulong phys_addr;
-       u32 phys_addrl;
-       u32 phys_addrh;
-       struct slic_handle *pslic_handle;
-
-       cmdaddr = page;
-       cmd = (struct slic_hostcmd *)cmdaddr;
-       cmdcnt = 0;
+       if (card->loadtimerset) {
+               card->loadtimerset = 0;
+               del_timer(&card->loadtimer);
+       }
 
-       phys_addr = virt_to_bus((void *)page);
-       phys_addrl = SLIC_GET_ADDR_LOW(phys_addr);
-       phys_addrh = SLIC_GET_ADDR_HIGH(phys_addr);
+       slic_debug_card_destroy(card);
 
-       prev = NULL;
-       tail = cmd;
-       while ((cmdcnt < SLIC_CMDQ_CMDSINPAGE) &&
-              (adapter->slic_handle_ix < 256)) {
-               /* Allocate and initialize a SLIC_HANDLE for this command */
-               SLIC_GET_SLIC_HANDLE(adapter, pslic_handle);
-               if (pslic_handle == NULL)
-                       ASSERT(0);
-               ASSERT(pslic_handle ==
-                      &adapter->slic_handles[pslic_handle->token.
-                                             handle_index]);
-               pslic_handle->type = SLIC_HANDLE_CMD;
-               pslic_handle->address = (void *) cmd;
-               pslic_handle->offset = (ushort) adapter->slic_handle_ix++;
-               pslic_handle->other_handle = NULL;
-               pslic_handle->next = NULL;
+       kfree(card);
+}
 
-               cmd->pslic_handle = pslic_handle;
-               cmd->cmd64.hosthandle = pslic_handle->token.handle_token;
-               cmd->busy = false;
-               cmd->paddrl = phys_addrl;
-               cmd->paddrh = phys_addrh;
-               cmd->next_all = prev;
-               cmd->next = prev;
-               prev = cmd;
-               phys_addrl += SLIC_HOSTCMD_SIZE;
-               cmdaddr += SLIC_HOSTCMD_SIZE;
+static void __devexit slic_entry_remove(struct pci_dev *pcidev)
+{
+       struct net_device *dev = pci_get_drvdata(pcidev);
+       u32 mmio_start = 0;
+       uint mmio_len = 0;
+       struct adapter *adapter = netdev_priv(dev);
+       struct sliccard *card;
+       struct mcast_address *mcaddr, *mlist;
 
-               cmd = (struct slic_hostcmd *)cmdaddr;
-               cmdcnt++;
-       }
+       ASSERT(adapter);
+       slic_adapter_freeresources(adapter);
+       slic_unmap_mmio_space(adapter);
+       unregister_netdev(dev);
 
-       cmdq = &adapter->cmdq_all;
-       cmdq->count += cmdcnt;  /*  SLIC_CMDQ_CMDSINPAGE;   mooktodo */
-       tail->next_all = cmdq->head;
-       cmdq->head = prev;
-       cmdq = &adapter->cmdq_free;
-       spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
-       cmdq->count += cmdcnt;  /*  SLIC_CMDQ_CMDSINPAGE;   mooktodo */
-       tail->next = cmdq->head;
-       cmdq->head = prev;
-       spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
-}
+       mmio_start = pci_resource_start(pcidev, 0);
+       mmio_len = pci_resource_len(pcidev, 0);
 
-static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter)
-{
-       struct slic_cmdqueue *cmdq = &adapter->cmdq_free;
-       struct slic_hostcmd *cmd = NULL;
+       release_mem_region(mmio_start, mmio_len);
 
-lock_and_retry:
-       spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
-retry:
-       cmd = cmdq->head;
-       if (cmd) {
-               cmdq->head = cmd->next;
-               cmdq->count--;
-               spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
-       } else {
-               slic_cmdq_getdone(adapter);
-               cmd = cmdq->head;
-               if (cmd) {
-                       goto retry;
+       iounmap((void __iomem *)dev->base_addr);
+       /* free multicast addresses */
+       mlist = adapter->mcastaddrs;
+       while (mlist) {
+               mcaddr = mlist;
+               mlist = mlist->next;
+               kfree(mcaddr);
+       }
+       ASSERT(adapter->card);
+       card = adapter->card;
+       ASSERT(card->adapters_allocated);
+       card->adapters_allocated--;
+       adapter->allocated = 0;
+       if (!card->adapters_allocated) {
+               struct sliccard *curr_card = slic_global.slic_card;
+               if (curr_card == card) {
+                       slic_global.slic_card = card->next;
                } else {
-                       u32 *pageaddr;
-
-                       spin_unlock_irqrestore(&cmdq->lock.lock,
-                                               cmdq->lock.flags);
-                       pageaddr = slic_cmdqmem_addpage(adapter);
-                       if (pageaddr) {
-                               slic_cmdq_addcmdpage(adapter, pageaddr);
-                               goto lock_and_retry;
-                       }
+                       while (curr_card->next != card)
+                               curr_card = curr_card->next;
+                       ASSERT(curr_card);
+                       curr_card->next = card->next;
                }
+               ASSERT(slic_global.num_slic_cards);
+               slic_global.num_slic_cards--;
+               slic_card_cleanup(card);
        }
-       return cmd;
+       kfree(dev);
+       pci_release_regions(pcidev);
 }
 
-static void slic_cmdq_getdone(struct adapter *adapter)
+static int slic_entry_halt(struct net_device *dev)
 {
-       struct slic_cmdqueue *done_cmdq = &adapter->cmdq_done;
-       struct slic_cmdqueue *free_cmdq = &adapter->cmdq_free;
-
-       ASSERT(free_cmdq->head == NULL);
-       spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags);
+       struct adapter *adapter = netdev_priv(dev);
+       struct sliccard *card = adapter->card;
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
-       free_cmdq->head = done_cmdq->head;
-       free_cmdq->count = done_cmdq->count;
-       done_cmdq->head = NULL;
-       done_cmdq->tail = NULL;
-       done_cmdq->count = 0;
-       spin_unlock_irqrestore(&done_cmdq->lock.lock, done_cmdq->lock.flags);
-}
+       spin_lock_irqsave(&slic_global.driver_lock.lock,
+                               slic_global.driver_lock.flags);
+       ASSERT(card);
+       netif_stop_queue(adapter->netdev);
+       adapter->state = ADAPT_DOWN;
+       adapter->linkstate = LINK_DOWN;
+       adapter->upr_list = NULL;
+       adapter->upr_busy = 0;
+       adapter->devflags_prev = 0;
+       ASSERT(card->adapter[adapter->cardindex] == adapter);
+       slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+       adapter->all_reg_writes++;
+       adapter->icr_reg_writes++;
+       slic_config_clear(adapter);
+       if (adapter->activated) {
+               card->adapters_activated--;
+               slic_global.num_slic_ports_active--;
+               adapter->activated = 0;
+       }
+#ifdef AUTOMATIC_RESET
+       slic_reg32_write(&slic_regs->slic_reset_iface, 0, FLUSH);
+#endif
+       /*
+        *  Reset the adapter's cmd queues
+        */
+       slic_cmdq_reset(adapter);
 
-static void slic_cmdq_putdone_irq(struct adapter *adapter,
-                               struct slic_hostcmd *cmd)
-{
-       struct slic_cmdqueue *cmdq = &adapter->cmdq_done;
+#ifdef AUTOMATIC_RESET
+       if (!card->adapters_activated)
+               slic_card_init(card, adapter);
+#endif
 
-       spin_lock(&cmdq->lock.lock);
-       cmd->busy = 0;
-       cmd->next = cmdq->head;
-       cmdq->head = cmd;
-       cmdq->count++;
-       if ((adapter->xmitq_full) && (cmdq->count > 10))
-               netif_wake_queue(adapter->netdev);
-       spin_unlock(&cmdq->lock.lock);
+       spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+                               slic_global.driver_lock.flags);
+       return 0;
 }
 
-static int slic_rcvqueue_init(struct adapter *adapter)
+static struct net_device_stats *slic_get_stats(struct net_device *dev)
 {
-       int i, count;
-       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+       struct adapter *adapter = netdev_priv(dev);
 
-       ASSERT(adapter->state == ADAPT_DOWN);
-       rcvq->tail = NULL;
-       rcvq->head = NULL;
-       rcvq->size = SLIC_RCVQ_ENTRIES;
-       rcvq->errors = 0;
-       rcvq->count = 0;
-       i = (SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES);
-       count = 0;
-       while (i) {
-               count += slic_rcvqueue_fill(adapter);
-               i--;
-       }
-       if (rcvq->count < SLIC_RCVQ_MINENTRIES) {
-               slic_rcvqueue_free(adapter);
-               return STATUS_FAILURE;
-       }
-       return STATUS_SUCCESS;
+       ASSERT(adapter);
+       dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions;
+       dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors;
+       dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors;
+       dev->stats.rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
+       dev->stats.tx_heartbeat_errors = 0;
+       dev->stats.tx_aborted_errors = 0;
+       dev->stats.tx_window_errors = 0;
+       dev->stats.tx_fifo_errors = 0;
+       dev->stats.rx_frame_errors = 0;
+       dev->stats.rx_length_errors = 0;
+
+       return &dev->stats;
 }
 
-static void slic_rcvqueue_free(struct adapter *adapter)
+static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
-       struct sk_buff *skb;
+       struct adapter *adapter = netdev_priv(dev);
+       struct ethtool_cmd edata;
+       struct ethtool_cmd ecmd;
+       u32 data[7];
+       u32 intagg;
 
-       while (rcvq->head) {
-               skb = rcvq->head;
-               rcvq->head = rcvq->head->next;
-               dev_kfree_skb(skb);
-       }
-       rcvq->tail = NULL;
-       rcvq->head = NULL;
-       rcvq->count = 0;
-}
+       ASSERT(rq);
+       switch (cmd) {
+       case SIOCSLICSETINTAGG:
+               if (copy_from_user(data, rq->ifr_data, 28))
+                       return -EFAULT;
+               intagg = data[0];
+               dev_err(&dev->dev, "%s: set interrupt aggregation to %d\n",
+                       __func__, intagg);
+               slic_intagg_set(adapter, intagg);
+               return 0;
 
-static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter)
-{
-       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
-       struct sk_buff *skb;
-       struct slic_rcvbuf *rcvbuf;
-       int count;
+#ifdef SLIC_TRACE_DUMP_ENABLED
+       case SIOCSLICTRACEDUMP:
+               {
+                       u32 value;
+                       DBG_IOCTL("slic_ioctl  SIOCSLIC_TRACE_DUMP\n");
 
-       if (rcvq->count) {
-               skb = rcvq->head;
-               rcvbuf = (struct slic_rcvbuf *)skb->head;
-               ASSERT(rcvbuf);
+                       if (copy_from_user(data, rq->ifr_data, 28)) {
+                               PRINT_ERROR
+                                   ("slic: copy_from_user FAILED getting initial simba param\n");
+                               return -EFAULT;
+                       }
 
-               if (rcvbuf->status & IRHDDR_SVALID) {
-                       rcvq->head = rcvq->head->next;
-                       skb->next = NULL;
-                       rcvq->count--;
-               } else {
-                       skb = NULL;
+                       value = data[0];
+                       if (tracemon_request == SLIC_DUMP_DONE) {
+                               PRINT_ERROR
+                                   ("ATK Diagnostic Trace Dump Requested\n");
+                               tracemon_request = SLIC_DUMP_REQUESTED;
+                               tracemon_request_type = value;
+                               tracemon_timestamp = jiffies;
+                       } else if ((tracemon_request == SLIC_DUMP_REQUESTED) ||
+                                  (tracemon_request ==
+                                   SLIC_DUMP_IN_PROGRESS)) {
+                               PRINT_ERROR
+                                   ("ATK Diagnostic Trace Dump Requested but already in progress... ignore\n");
+                       } else {
+                               PRINT_ERROR
+                                   ("ATK Diagnostic Trace Dump Requested\n");
+                               tracemon_request = SLIC_DUMP_REQUESTED;
+                               tracemon_request_type = value;
+                               tracemon_timestamp = jiffies;
+                       }
+                       return 0;
                }
-       } else {
-               dev_err(&adapter->netdev->dev,
-                       "RcvQ Empty!! rcvq[%p] count[%x]\n", rcvq, rcvq->count);
-               skb = NULL;
-       }
-       while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
-               count = slic_rcvqueue_fill(adapter);
-               if (!count)
-                       break;
+#endif
+       case SIOCETHTOOL:
+               ASSERT(adapter);
+               if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+                       return -EFAULT;
+
+               if (ecmd.cmd == ETHTOOL_GSET) {
+                       edata.supported = (SUPPORTED_10baseT_Half |
+                                          SUPPORTED_10baseT_Full |
+                                          SUPPORTED_100baseT_Half |
+                                          SUPPORTED_100baseT_Full |
+                                          SUPPORTED_Autoneg | SUPPORTED_MII);
+                       edata.port = PORT_MII;
+                       edata.transceiver = XCVR_INTERNAL;
+                       edata.phy_address = 0;
+                       if (adapter->linkspeed == LINK_100MB)
+                               edata.speed = SPEED_100;
+                       else if (adapter->linkspeed == LINK_10MB)
+                               edata.speed = SPEED_10;
+                       else
+                               edata.speed = 0;
+
+                       if (adapter->linkduplex == LINK_FULLD)
+                               edata.duplex = DUPLEX_FULL;
+                       else
+                               edata.duplex = DUPLEX_HALF;
+
+                       edata.autoneg = AUTONEG_ENABLE;
+                       edata.maxtxpkt = 1;
+                       edata.maxrxpkt = 1;
+                       if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
+                               return -EFAULT;
+
+               } else if (ecmd.cmd == ETHTOOL_SSET) {
+                       if (!capable(CAP_NET_ADMIN))
+                               return -EPERM;
+
+                       if (adapter->linkspeed == LINK_100MB)
+                               edata.speed = SPEED_100;
+                       else if (adapter->linkspeed == LINK_10MB)
+                               edata.speed = SPEED_10;
+                       else
+                               edata.speed = 0;
+
+                       if (adapter->linkduplex == LINK_FULLD)
+                               edata.duplex = DUPLEX_FULL;
+                       else
+                               edata.duplex = DUPLEX_HALF;
+
+                       edata.autoneg = AUTONEG_ENABLE;
+                       edata.maxtxpkt = 1;
+                       edata.maxrxpkt = 1;
+                       if ((ecmd.speed != edata.speed) ||
+                           (ecmd.duplex != edata.duplex)) {
+                               u32 speed;
+                               u32 duplex;
+
+                               if (ecmd.speed == SPEED_10)
+                                       speed = 0;
+                               else
+                                       speed = PCR_SPEED_100;
+                               if (ecmd.duplex == DUPLEX_FULL)
+                                       duplex = PCR_DUPLEX_FULL;
+                               else
+                                       duplex = 0;
+                               slic_link_config(adapter, speed, duplex);
+                               slic_link_event_handler(adapter);
+                       }
+               }
+               return 0;
+       default:
+               return -EOPNOTSUPP;
        }
-       if (skb)
-               rcvq->errors = 0;
-       return skb;
 }
 
-static int slic_rcvqueue_fill(struct adapter *adapter)
+static void slic_config_pci(struct pci_dev *pcidev)
 {
-       void *paddr;
-       u32 paddrl;
-       u32 paddrh;
-       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
-       int i = 0;
-       struct device *dev = &adapter->netdev->dev;
+       u16 pci_command;
+       u16 new_command;
 
-       while (i < SLIC_RCVQ_FILLENTRIES) {
-               struct slic_rcvbuf *rcvbuf;
-               struct sk_buff *skb;
-#ifdef KLUDGE_FOR_4GB_BOUNDARY
-retry_rcvqfill:
-#endif
-               skb = alloc_skb(SLIC_RCVQ_RCVBUFSIZE, GFP_ATOMIC);
-               if (skb) {
-                       paddr = (void *)pci_map_single(adapter->pcidev,
-                                                         skb->data,
-                                                         SLIC_RCVQ_RCVBUFSIZE,
-                                                         PCI_DMA_FROMDEVICE);
-                       paddrl = SLIC_GET_ADDR_LOW(paddr);
-                       paddrh = SLIC_GET_ADDR_HIGH(paddr);
+       pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
 
-                       skb->len = SLIC_RCVBUF_HEADSIZE;
-                       rcvbuf = (struct slic_rcvbuf *)skb->head;
-                       rcvbuf->status = 0;
-                       skb->next = NULL;
-#ifdef KLUDGE_FOR_4GB_BOUNDARY
-                       if (paddrl == 0) {
-                               dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
-                                       __func__);
-                               dev_err(dev, "skb[%p] PROBLEM\n", skb);
-                               dev_err(dev, "         skbdata[%p]\n", skb->data);
-                               dev_err(dev, "         skblen[%x]\n", skb->len);
-                               dev_err(dev, "         paddr[%p]\n", paddr);
-                               dev_err(dev, "         paddrl[%x]\n", paddrl);
-                               dev_err(dev, "         paddrh[%x]\n", paddrh);
-                               dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
-                               dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
-                               dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
-                               dev_err(dev, "SKIP THIS SKB!!!!!!!!\n");
-                               goto retry_rcvqfill;
-                       }
-#else
-                       if (paddrl == 0) {
-                               dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
-                                       __func__);
-                               dev_err(dev, "skb[%p] PROBLEM\n", skb);
-                               dev_err(dev, "         skbdata[%p]\n", skb->data);
-                               dev_err(dev, "         skblen[%x]\n", skb->len);
-                               dev_err(dev, "         paddr[%p]\n", paddr);
-                               dev_err(dev, "         paddrl[%x]\n", paddrl);
-                               dev_err(dev, "         paddrh[%x]\n", paddrh);
-                               dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
-                               dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
-                               dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
-                               dev_err(dev, "GIVE TO CARD ANYWAY\n");
-                       }
-#endif
-                       if (paddrh == 0) {
-                               slic_reg32_write(&adapter->slic_regs->slic_hbar,
-                                                (u32)paddrl, DONT_FLUSH);
+       new_command = pci_command | PCI_COMMAND_MASTER
+           | PCI_COMMAND_MEMORY
+           | PCI_COMMAND_INVALIDATE
+           | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
+       if (pci_command != new_command)
+               pci_write_config_word(pcidev, PCI_COMMAND, new_command);
+}
+
+static int slic_card_init(struct sliccard *card, struct adapter *adapter)
+{
+       __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+       struct slic_eeprom *peeprom;
+       struct oslic_eeprom *pOeeprom;
+       dma_addr_t phys_config;
+       u32 phys_configh;
+       u32 phys_configl;
+       u32 i = 0;
+       struct slic_shmem *pshmem;
+       int status;
+       uint macaddrs = card->card_size;
+       ushort eecodesize;
+       ushort dramsize;
+       ushort ee_chksum;
+       ushort calc_chksum;
+       struct slic_config_mac *pmac;
+       unsigned char fruformat;
+       unsigned char oemfruformat;
+       struct atk_fru *patkfru;
+       union oemfru *poemfru;
+
+       /* Reset everything except PCI configuration space */
+       slic_soft_reset(adapter);
+
+       /* Download the microcode */
+       status = slic_card_download(adapter);
+
+       if (status != 0) {
+               dev_err(&adapter->pcidev->dev,
+                       "download failed bus %d slot %d\n",
+                       adapter->busnumber, adapter->slotnumber);
+               return status;
+       }
+
+       if (!card->config_set) {
+               peeprom = pci_alloc_consistent(adapter->pcidev,
+                                              sizeof(struct slic_eeprom),
+                                              &phys_config);
+
+               phys_configl = SLIC_GET_ADDR_LOW(phys_config);
+               phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
+
+               if (!peeprom) {
+                       dev_err(&adapter->pcidev->dev,
+                               "eeprom read failed to get memory "
+                               "bus %d slot %d\n", adapter->busnumber,
+                               adapter->slotnumber);
+                       return -ENOMEM;
+               } else {
+                       memset(peeprom, 0, sizeof(struct slic_eeprom));
+               }
+               slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+               mdelay(1);
+               pshmem = (struct slic_shmem *)adapter->phys_shmem;
+
+               spin_lock_irqsave(&adapter->bit64reglock.lock,
+                                       adapter->bit64reglock.flags);
+               slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+               slic_reg32_write(&slic_regs->slic_isp,
+                                SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+               spin_unlock_irqrestore(&adapter->bit64reglock.lock,
+                                       adapter->bit64reglock.flags);
+
+               slic_config_get(adapter, phys_configl, phys_configh);
+
+               for (;;) {
+                       if (adapter->pshmem->isr) {
+                               if (adapter->pshmem->isr & ISR_UPC) {
+                                       adapter->pshmem->isr = 0;
+                                       slic_reg64_write(adapter,
+                                               &slic_regs->slic_isp, 0,
+                                               &slic_regs->slic_addr_upper,
+                                               0, FLUSH);
+                                       slic_reg32_write(&slic_regs->slic_isr,
+                                                        0, FLUSH);
+
+                                       slic_upr_request_complete(adapter, 0);
+                                       break;
+                               } else {
+                                       adapter->pshmem->isr = 0;
+                                       slic_reg32_write(&slic_regs->slic_isr,
+                                                        0, FLUSH);
+                               }
                        } else {
-                               slic_reg64_write(adapter,
-                                       &adapter->slic_regs->slic_hbar64,
-                                       paddrl,
-                                       &adapter->slic_regs->slic_addr_upper,
-                                       paddrh, DONT_FLUSH);
+                               mdelay(1);
+                               i++;
+                               if (i > 5000) {
+                                       dev_err(&adapter->pcidev->dev,
+                                               "%d config data fetch timed out!\n",
+                                               adapter->port);
+                                       slic_reg64_write(adapter,
+                                               &slic_regs->slic_isp, 0,
+                                               &slic_regs->slic_addr_upper,
+                                               0, FLUSH);
+                                       return -EINVAL;
+                               }
                        }
-                       if (rcvq->head)
-                               rcvq->tail->next = skb;
-                       else
-                               rcvq->head = skb;
-                       rcvq->tail = skb;
-                       rcvq->count++;
-                       i++;
-               } else {
-                       dev_err(&adapter->netdev->dev,
-                               "slic_rcvqueue_fill could only get [%d] skbuffs\n",
-                               i);
+               }
+
+               switch (adapter->devid) {
+               /* Oasis card */
+               case SLIC_2GB_DEVICE_ID:
+                       /* extract EEPROM data and pointers to EEPROM data */
+                       pOeeprom = (struct oslic_eeprom *) peeprom;
+                       eecodesize = pOeeprom->EecodeSize;
+                       dramsize = pOeeprom->DramSize;
+                       pmac = pOeeprom->MacInfo;
+                       fruformat = pOeeprom->FruFormat;
+                       patkfru = &pOeeprom->AtkFru;
+                       oemfruformat = pOeeprom->OemFruFormat;
+                       poemfru = &pOeeprom->OemFru;
+                       macaddrs = 2;
+                       /* Minor kludge for Oasis card
+                            get 2 MAC addresses from the
+                            EEPROM to ensure that function 1
+                            gets the Port 1 MAC address */
+                       break;
+               default:
+                       /* extract EEPROM data and pointers to EEPROM data */
+                       eecodesize = peeprom->EecodeSize;
+                       dramsize = peeprom->DramSize;
+                       pmac = peeprom->u2.mac.MacInfo;
+                       fruformat = peeprom->FruFormat;
+                       patkfru = &peeprom->AtkFru;
+                       oemfruformat = peeprom->OemFruFormat;
+                       poemfru = &peeprom->OemFru;
                        break;
                }
-       }
-       return i;
-}
 
-static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
-{
-       struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
-       void *paddr;
-       u32 paddrl;
-       u32 paddrh;
-       struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head;
-       struct device *dev;
+               card->config.EepromValid = false;
 
-       ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
+               /*  see if the EEPROM is valid by checking it's checksum */
+               if ((eecodesize <= MAX_EECODE_SIZE) &&
+                   (eecodesize >= MIN_EECODE_SIZE)) {
 
-       paddr = (void *)pci_map_single(adapter->pcidev, skb->head,
-                                 SLIC_RCVQ_RCVBUFSIZE, PCI_DMA_FROMDEVICE);
-       rcvbuf->status = 0;
-       skb->next = NULL;
+                       ee_chksum =
+                           *(u16 *) ((char *) peeprom + (eecodesize - 2));
+                       /*
+                           calculate the EEPROM checksum
+                       */
+                       calc_chksum =
+                           ~slic_eeprom_cksum((char *) peeprom,
+                                              (eecodesize - 2));
+                       /*
+                           if the ucdoe chksum flag bit worked,
+                           we wouldn't need this shit
+                       */
+                       if (ee_chksum == calc_chksum)
+                               card->config.EepromValid = true;
+               }
+               /*  copy in the DRAM size */
+               card->config.DramSize = dramsize;
 
-       paddrl = SLIC_GET_ADDR_LOW(paddr);
-       paddrh = SLIC_GET_ADDR_HIGH(paddr);
+               /*  copy in the MAC address(es) */
+               for (i = 0; i < macaddrs; i++) {
+                       memcpy(&card->config.MacInfo[i],
+                              &pmac[i], sizeof(struct slic_config_mac));
+               }
 
-       if (paddrl == 0) {
-               dev = &adapter->netdev->dev;
-               dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
-                       __func__);
-               dev_err(dev, "skb[%p] PROBLEM\n", skb);
-               dev_err(dev, "         skbdata[%p]\n", skb->data);
-               dev_err(dev, "         skblen[%x]\n", skb->len);
-               dev_err(dev, "         paddr[%p]\n", paddr);
-               dev_err(dev, "         paddrl[%x]\n", paddrl);
-               dev_err(dev, "         paddrh[%x]\n", paddrh);
-               dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
-               dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
-               dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
+               /*  copy the Alacritech FRU information */
+               card->config.FruFormat = fruformat;
+               memcpy(&card->config.AtkFru, patkfru,
+                                               sizeof(struct atk_fru));
+
+               pci_free_consistent(adapter->pcidev,
+                                   sizeof(struct slic_eeprom),
+                                   peeprom, phys_config);
+
+               if ((!card->config.EepromValid) &&
+                   (adapter->reg_params.fail_on_bad_eeprom)) {
+                       slic_reg64_write(adapter, &slic_regs->slic_isp, 0,
+                                        &slic_regs->slic_addr_upper,
+                                        0, FLUSH);
+                       dev_err(&adapter->pcidev->dev,
+                               "unsupported CONFIGURATION EEPROM invalid\n");
+                       return -EINVAL;
+               }
+
+               card->config_set = 1;
        }
-       if (paddrh == 0) {
-               slic_reg32_write(&adapter->slic_regs->slic_hbar, (u32)paddrl,
-                                DONT_FLUSH);
-       } else {
-               slic_reg64_write(adapter, &adapter->slic_regs->slic_hbar64,
-                                paddrl, &adapter->slic_regs->slic_addr_upper,
-                                paddrh, DONT_FLUSH);
+
+       if (slic_card_download_gbrcv(adapter)) {
+               dev_err(&adapter->pcidev->dev,
+                       "unable to download GB receive microcode\n");
+               return -EINVAL;
        }
-       if (rcvq->head)
-               rcvq->tail->next = skb;
+
+       if (slic_global.dynamic_intagg)
+               slic_intagg_set(adapter, 0);
        else
-               rcvq->head = skb;
-       rcvq->tail = skb;
-       rcvq->count++;
-       return rcvq->count;
+               slic_intagg_set(adapter, intagg_delay);
+
+       /*
+        *  Initialize ping status to "ok"
+        */
+       card->pingstatus = ISR_PINGMASK;
+
+       /*
+        * Lastly, mark our card state as up and return success
+        */
+       card->state = CARD_UP;
+       card->reset_in_progress = 0;
+
+       return 0;
 }
 
-static int slic_debug_card_show(struct seq_file *seq, void *v)
+static void slic_init_driver(void)
 {
-#ifdef MOOKTODO
-       int i;
-       struct sliccard *card = seq->private;
-       struct slic_config *config = &card->config;
-       unsigned char *fru = (unsigned char *)(&card->config.atk_fru);
-       unsigned char *oemfru = (unsigned char *)(&card->config.OemFru);
-#endif
-
-       seq_printf(seq, "driver_version           : %s\n", slic_proc_version);
-       seq_printf(seq, "Microcode versions:           \n");
-       seq_printf(seq, "    Gigabit (gb)         : %s %s\n",
-                   MOJAVE_UCODE_VERS_STRING, MOJAVE_UCODE_VERS_DATE);
-       seq_printf(seq, "    Gigabit Receiver     : %s %s\n",
-                   GB_RCVUCODE_VERS_STRING, GB_RCVUCODE_VERS_DATE);
-       seq_printf(seq, "Vendor                   : %s\n", slic_vendor);
-       seq_printf(seq, "Product Name             : %s\n", slic_product_name);
-#ifdef MOOKTODO
-       seq_printf(seq, "VendorId                 : %4.4X\n",
-                   config->VendorId);
-       seq_printf(seq, "DeviceId                 : %4.4X\n",
-                   config->DeviceId);
-       seq_printf(seq, "RevisionId               : %2.2x\n",
-                   config->RevisionId);
-       seq_printf(seq, "Bus    #                 : %d\n", card->busnumber);
-       seq_printf(seq, "Device #                 : %d\n", card->slotnumber);
-       seq_printf(seq, "Interfaces               : %d\n", card->card_size);
-       seq_printf(seq, "     Initialized         : %d\n",
-                   card->adapters_activated);
-       seq_printf(seq, "     Allocated           : %d\n",
-                   card->adapters_allocated);
-       ASSERT(card->card_size <= SLIC_NBR_MACS);
-       for (i = 0; i < card->card_size; i++) {
-               seq_printf(seq,
-                          "     MAC%d : %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-                          i, config->macinfo[i].macaddrA[0],
-                          config->macinfo[i].macaddrA[1],
-                          config->macinfo[i].macaddrA[2],
-                          config->macinfo[i].macaddrA[3],
-                          config->macinfo[i].macaddrA[4],
-                          config->macinfo[i].macaddrA[5]);
+       if (slic_first_init) {
+               slic_first_init = 0;
+               spin_lock_init(&slic_global.driver_lock.lock);
+               slic_debug_init();
        }
-       seq_printf(seq, "     IF  Init State Duplex/Speed irq\n");
-       seq_printf(seq, "     -------------------------------\n");
-       for (i = 0; i < card->adapters_allocated; i++) {
-               struct adapter *adapter;
+}
 
-               adapter = card->adapter[i];
-               if (adapter) {
-                       seq_printf(seq,
-                                   "     %d   %d   %s  %s  %s    0x%X\n",
-                                   adapter->physport, adapter->state,
-                                   SLIC_LINKSTATE(adapter->linkstate),
-                                   SLIC_DUPLEX(adapter->linkduplex),
-                                   SLIC_SPEED(adapter->linkspeed),
-                                   (uint) adapter->irq);
-               }
-       }
-       seq_printf(seq, "Generation #             : %4.4X\n", card->gennumber);
-       seq_printf(seq, "RcvQ max entries         : %4.4X\n",
-                   SLIC_RCVQ_ENTRIES);
-       seq_printf(seq, "Ping Status              : %8.8X\n",
-                   card->pingstatus);
-       seq_printf(seq, "Minimum grant            : %2.2x\n",
-                   config->MinGrant);
-       seq_printf(seq, "Maximum Latency          : %2.2x\n", config->MaxLat);
-       seq_printf(seq, "PciStatus                : %4.4x\n",
-                   config->Pcistatus);
-       seq_printf(seq, "Debug Device Id          : %4.4x\n",
-                   config->DbgDevId);
-       seq_printf(seq, "DRAM ROM Function        : %4.4x\n",
-                   config->DramRomFn);
-       seq_printf(seq, "Network interface Pin 1  : %2.2x\n",
-                   config->NetIntPin1);
-       seq_printf(seq, "Network interface Pin 2  : %2.2x\n",
-                   config->NetIntPin1);
-       seq_printf(seq, "Network interface Pin 3  : %2.2x\n",
-                   config->NetIntPin1);
-       seq_printf(seq, "PM capabilities          : %4.4X\n",
-                   config->PMECapab);
-       seq_printf(seq, "Network Clock Controls   : %4.4X\n",
-                   config->NwClkCtrls);
+static void slic_init_adapter(struct net_device *netdev,
+                             struct pci_dev *pcidev,
+                             const struct pci_device_id *pci_tbl_entry,
+                             void __iomem *memaddr, int chip_idx)
+{
+       ushort index;
+       struct slic_handle *pslic_handle;
+       struct adapter *adapter = netdev_priv(netdev);
 
-       switch (config->FruFormat) {
-       case ATK_FRU_FORMAT:
-               {
-                       seq_printf(seq,
-                           "Vendor                   : Alacritech, Inc.\n");
-                       seq_printf(seq,
-                           "Assembly #               : %c%c%c%c%c%c\n",
-                                   fru[0], fru[1], fru[2], fru[3], fru[4],
-                                   fru[5]);
-                       seq_printf(seq,
-                                   "Revision #               : %c%c\n",
-                                   fru[6], fru[7]);
+/*     adapter->pcidev = pcidev;*/
+       adapter->vendid = pci_tbl_entry->vendor;
+       adapter->devid = pci_tbl_entry->device;
+       adapter->subsysid = pci_tbl_entry->subdevice;
+       adapter->busnumber = pcidev->bus->number;
+       adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
+       adapter->functionnumber = (pcidev->devfn & 0x7);
+       adapter->memorylength = pci_resource_len(pcidev, 0);
+       adapter->slic_regs = (__iomem struct slic_regs *)memaddr;
+       adapter->irq = pcidev->irq;
+/*     adapter->netdev = netdev;*/
+       adapter->next_netdevice = head_netdevice;
+       head_netdevice = netdev;
+       adapter->chipid = chip_idx;
+       adapter->port = 0;      /*adapter->functionnumber;*/
+       adapter->cardindex = adapter->port;
+       adapter->memorybase = memaddr;
+       spin_lock_init(&adapter->upr_lock.lock);
+       spin_lock_init(&adapter->bit64reglock.lock);
+       spin_lock_init(&adapter->adapter_lock.lock);
+       spin_lock_init(&adapter->reset_lock.lock);
+       spin_lock_init(&adapter->handle_lock.lock);
 
-                       if (config->OEMFruFormat == VENDOR4_FRU_FORMAT) {
-                               seq_printf(seq,
-                                           "Serial   #               : "
-                                           "%c%c%c%c%c%c%c%c%c%c%c%c\n",
-                                           fru[8], fru[9], fru[10],
-                                           fru[11], fru[12], fru[13],
-                                           fru[16], fru[17], fru[18],
-                                           fru[19], fru[20], fru[21]);
-                       } else {
-                               seq_printf(seq,
-                                           "Serial   #               : "
-                                           "%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
-                                           fru[8], fru[9], fru[10],
-                                           fru[11], fru[12], fru[13],
-                                           fru[14], fru[15], fru[16],
-                                           fru[17], fru[18], fru[19],
-                                           fru[20], fru[21]);
-                       }
-                       break;
-               }
+       adapter->card_size = 1;
+       /*
+         Initialize slic_handle array
+       */
+       ASSERT(SLIC_CMDQ_MAXCMDS <= 0xFFFF);
+       /*
+        Start with 1.  0 is an invalid host handle.
+       */
+       for (index = 1, pslic_handle = &adapter->slic_handles[1];
+            index < SLIC_CMDQ_MAXCMDS; index++, pslic_handle++) {
 
-       default:
-               {
-                       seq_printf(seq,
-                           "Vendor                   : Alacritech, Inc.\n");
-                       seq_printf(seq,
-                           "Serial   #               : Empty FRU\n");
-                       break;
-               }
+               pslic_handle->token.handle_index = index;
+               pslic_handle->type = SLIC_HANDLE_FREE;
+               pslic_handle->next = adapter->pfree_slic_handles;
+               adapter->pfree_slic_handles = pslic_handle;
        }
+       adapter->pshmem = (struct slic_shmem *)
+                                       pci_alloc_consistent(adapter->pcidev,
+                                       sizeof(struct slic_shmem),
+                                       &adapter->
+                                       phys_shmem);
+       ASSERT(adapter->pshmem);
 
-       switch (config->OEMFruFormat) {
-       case VENDOR1_FRU_FORMAT:
-               {
-                       seq_printf(seq, "FRU Information:\n");
-                       seq_printf(seq, "    Commodity #          : %c\n",
-                                   oemfru[0]);
-                       seq_printf(seq,
-                                   "    Assembly #           : %c%c%c%c\n",
-                                   oemfru[1], oemfru[2], oemfru[3], oemfru[4]);
-                       seq_printf(seq,
-                                   "    Revision #           : %c%c\n",
-                                   oemfru[5], oemfru[6]);
-                       seq_printf(seq,
-                                   "    Supplier #           : %c%c\n",
-                                   oemfru[7], oemfru[8]);
-                       seq_printf(seq,
-                                   "    Date                 : %c%c\n",
-                                   oemfru[9], oemfru[10]);
-                       seq_sprintf(seq,
-                                   "    Sequence #           : %c%c%c\n",
-                                   oemfru[11], oemfru[12], oemfru[13]);
-                       break;
-               }
+       memset(adapter->pshmem, 0, sizeof(struct slic_shmem));
 
-       case VENDOR2_FRU_FORMAT:
-               {
-                       seq_printf(seq, "FRU Information:\n");
-                       seq_printf(seq,
-                                   "    Part     #           : "
-                                   "%c%c%c%c%c%c%c%c\n",
-                                   oemfru[0], oemfru[1], oemfru[2],
-                                   oemfru[3], oemfru[4], oemfru[5],
-                                   oemfru[6], oemfru[7]);
-                       seq_printf(seq,
-                                   "    Supplier #           : %c%c%c%c%c\n",
-                                   oemfru[8], oemfru[9], oemfru[10],
-                                   oemfru[11], oemfru[12]);
-                       seq_printf(seq,
-                                   "    Date                 : %c%c%c\n",
-                                   oemfru[13], oemfru[14], oemfru[15]);
-                       seq_sprintf(seq,
-                                   "    Sequence #           : %c%c%c%c\n",
-                                   oemfru[16], oemfru[17], oemfru[18],
-                                   oemfru[19]);
-                       break;
-               }
+       return;
+}
 
-       case VENDOR3_FRU_FORMAT:
-               {
-                       seq_printf(seq, "FRU Information:\n");
-               }
+static const struct net_device_ops slic_netdev_ops = {
+       .ndo_open               = slic_entry_open,
+       .ndo_stop               = slic_entry_halt,
+       .ndo_start_xmit         = slic_xmit_start,
+       .ndo_do_ioctl           = slic_ioctl,
+       .ndo_set_mac_address    = slic_mac_set_address,
+       .ndo_get_stats          = slic_get_stats,
+       .ndo_set_multicast_list = slic_mcast_set_list,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_change_mtu         = eth_change_mtu,
+};
 
-       case VENDOR4_FRU_FORMAT:
-               {
-                       seq_printf(seq, "FRU Information:\n");
-                       seq_printf(seq,
-                                   "    FRU Number           : "
-                                   "%c%c%c%c%c%c%c%c\n",
-                                   oemfru[0], oemfru[1], oemfru[2],
-                                   oemfru[3], oemfru[4], oemfru[5],
-                                   oemfru[6], oemfru[7]);
-                       seq_sprintf(seq,
-                                   "    Part Number          : "
-                                   "%c%c%c%c%c%c%c%c\n",
-                                   oemfru[8], oemfru[9], oemfru[10],
-                                   oemfru[11], oemfru[12], oemfru[13],
-                                   oemfru[14], oemfru[15]);
-                       seq_printf(seq,
-                                   "    EC Level             : "
-                                   "%c%c%c%c%c%c%c%c\n",
-                                   oemfru[16], oemfru[17], oemfru[18],
-                                   oemfru[19], oemfru[20], oemfru[21],
-                                   oemfru[22], oemfru[23]);
-                       break;
-               }
+static u32 slic_card_locate(struct adapter *adapter)
+{
+       struct sliccard *card = slic_global.slic_card;
+       struct physcard *physcard = slic_global.phys_card;
+       ushort card_hostid;
+       u16 __iomem *hostid_reg;
+       uint i;
+       uint rdhostid_offset = 0;
 
+       switch (adapter->devid) {
+       case SLIC_2GB_DEVICE_ID:
+               rdhostid_offset = SLIC_RDHOSTID_2GB;
+               break;
+       case SLIC_1GB_DEVICE_ID:
+               rdhostid_offset = SLIC_RDHOSTID_1GB;
+               break;
        default:
+               ASSERT(0);
                break;
        }
-#endif
 
-       return 0;
-}
+       hostid_reg =
+           (u16 __iomem *) (((u8 __iomem *) (adapter->slic_regs)) +
+           rdhostid_offset);
 
-static int slic_debug_adapter_show(struct seq_file *seq, void *v)
-{
-       struct adapter *adapter = seq->private;
+       /* read the 16 bit hostid from SRAM */
+       card_hostid = (ushort) readw(hostid_reg);
 
-       if ((adapter->netdev) && (adapter->netdev->name)) {
-               seq_printf(seq, "info: interface          : %s\n",
-                           adapter->netdev->name);
-       }
-       seq_printf(seq, "info: status             : %s\n",
-               SLIC_LINKSTATE(adapter->linkstate));
-       seq_printf(seq, "info: port               : %d\n",
-               adapter->physport);
-       seq_printf(seq, "info: speed              : %s\n",
-               SLIC_SPEED(adapter->linkspeed));
-       seq_printf(seq, "info: duplex             : %s\n",
-               SLIC_DUPLEX(adapter->linkduplex));
-       seq_printf(seq, "info: irq                : 0x%X\n",
-               (uint) adapter->irq);
-       seq_printf(seq, "info: Interrupt Agg Delay: %d usec\n",
-               adapter->card->loadlevel_current);
-       seq_printf(seq, "info: RcvQ max entries   : %4.4X\n",
-               SLIC_RCVQ_ENTRIES);
-       seq_printf(seq, "info: RcvQ current       : %4.4X\n",
-                   adapter->rcvqueue.count);
-       seq_printf(seq, "rx stats: packets                  : %8.8lX\n",
-                   adapter->stats.rx_packets);
-       seq_printf(seq, "rx stats: bytes                    : %8.8lX\n",
-                   adapter->stats.rx_bytes);
-       seq_printf(seq, "rx stats: broadcasts               : %8.8X\n",
-                   adapter->rcv_broadcasts);
-       seq_printf(seq, "rx stats: multicasts               : %8.8X\n",
-                   adapter->rcv_multicasts);
-       seq_printf(seq, "rx stats: unicasts                 : %8.8X\n",
-                   adapter->rcv_unicasts);
-       seq_printf(seq, "rx stats: errors                   : %8.8X\n",
-                   (u32) adapter->slic_stats.iface.rcv_errors);
-       seq_printf(seq, "rx stats: Missed errors            : %8.8X\n",
-                   (u32) adapter->slic_stats.iface.rcv_discards);
-       seq_printf(seq, "rx stats: drops                    : %8.8X\n",
-                       (u32) adapter->rcv_drops);
-       seq_printf(seq, "tx stats: packets                  : %8.8lX\n",
-                       adapter->stats.tx_packets);
-       seq_printf(seq, "tx stats: bytes                    : %8.8lX\n",
-                       adapter->stats.tx_bytes);
-       seq_printf(seq, "tx stats: errors                   : %8.8X\n",
-                       (u32) adapter->slic_stats.iface.xmt_errors);
-       seq_printf(seq, "rx stats: multicasts               : %8.8lX\n",
-                       adapter->stats.multicast);
-       seq_printf(seq, "tx stats: collision errors         : %8.8X\n",
-                       (u32) adapter->slic_stats.iface.xmit_collisions);
-       seq_printf(seq, "perf: Max rcv frames/isr           : %8.8X\n",
-                       adapter->max_isr_rcvs);
-       seq_printf(seq, "perf: Rcv interrupt yields         : %8.8X\n",
-                       adapter->rcv_interrupt_yields);
-       seq_printf(seq, "perf: Max xmit complete/isr        : %8.8X\n",
-                       adapter->max_isr_xmits);
-       seq_printf(seq, "perf: error interrupts             : %8.8X\n",
-                       adapter->error_interrupts);
-       seq_printf(seq, "perf: error rmiss interrupts       : %8.8X\n",
-                       adapter->error_rmiss_interrupts);
-       seq_printf(seq, "perf: rcv interrupts               : %8.8X\n",
-                       adapter->rcv_interrupts);
-       seq_printf(seq, "perf: xmit interrupts              : %8.8X\n",
-                       adapter->xmit_interrupts);
-       seq_printf(seq, "perf: link event interrupts        : %8.8X\n",
-                       adapter->linkevent_interrupts);
-       seq_printf(seq, "perf: UPR interrupts               : %8.8X\n",
-                       adapter->upr_interrupts);
-       seq_printf(seq, "perf: interrupt count              : %8.8X\n",
-                       adapter->num_isrs);
-       seq_printf(seq, "perf: false interrupts             : %8.8X\n",
-                       adapter->false_interrupts);
-       seq_printf(seq, "perf: All register writes          : %8.8X\n",
-                       adapter->all_reg_writes);
-       seq_printf(seq, "perf: ICR register writes          : %8.8X\n",
-                       adapter->icr_reg_writes);
-       seq_printf(seq, "perf: ISR register writes          : %8.8X\n",
-                       adapter->isr_reg_writes);
-       seq_printf(seq, "ifevents: overflow 802 errors      : %8.8X\n",
-                       adapter->if_events.oflow802);
-       seq_printf(seq, "ifevents: transport overflow errors: %8.8X\n",
-                       adapter->if_events.Tprtoflow);
-       seq_printf(seq, "ifevents: underflow errors         : %8.8X\n",
-                       adapter->if_events.uflow802);
-       seq_printf(seq, "ifevents: receive early            : %8.8X\n",
-                       adapter->if_events.rcvearly);
-       seq_printf(seq, "ifevents: buffer overflows         : %8.8X\n",
-                       adapter->if_events.Bufov);
-       seq_printf(seq, "ifevents: carrier errors           : %8.8X\n",
-                       adapter->if_events.Carre);
-       seq_printf(seq, "ifevents: Long                     : %8.8X\n",
-                       adapter->if_events.Longe);
-       seq_printf(seq, "ifevents: invalid preambles        : %8.8X\n",
-                       adapter->if_events.Invp);
-       seq_printf(seq, "ifevents: CRC errors               : %8.8X\n",
-                       adapter->if_events.Crc);
-       seq_printf(seq, "ifevents: dribble nibbles          : %8.8X\n",
-                       adapter->if_events.Drbl);
-       seq_printf(seq, "ifevents: Code violations          : %8.8X\n",
-                       adapter->if_events.Code);
-       seq_printf(seq, "ifevents: TCP checksum errors      : %8.8X\n",
-                       adapter->if_events.TpCsum);
-       seq_printf(seq, "ifevents: TCP header short errors  : %8.8X\n",
-                       adapter->if_events.TpHlen);
-       seq_printf(seq, "ifevents: IP checksum errors       : %8.8X\n",
-                       adapter->if_events.IpCsum);
-       seq_printf(seq, "ifevents: IP frame incompletes     : %8.8X\n",
-                       adapter->if_events.IpLen);
-       seq_printf(seq, "ifevents: IP headers shorts        : %8.8X\n",
-                       adapter->if_events.IpHlen);
+       /* Initialize a new card structure if need be */
+       if (card_hostid == SLIC_HOSTID_DEFAULT) {
+               card = kzalloc(sizeof(struct sliccard), GFP_KERNEL);
+               if (card == NULL)
+                       return -ENOMEM;
+
+               card->next = slic_global.slic_card;
+               slic_global.slic_card = card;
+               card->busnumber = adapter->busnumber;
+               card->slotnumber = adapter->slotnumber;
+
+               /* Find an available cardnum */
+               for (i = 0; i < SLIC_MAX_CARDS; i++) {
+                       if (slic_global.cardnuminuse[i] == 0) {
+                               slic_global.cardnuminuse[i] = 1;
+                               card->cardnum = i;
+                               break;
+                       }
+               }
+               slic_global.num_slic_cards++;
+
+               slic_debug_card_create(card);
+       } else {
+               /* Card exists, find the card this adapter belongs to */
+               while (card) {
+                       if (card->cardnum == card_hostid)
+                               break;
+                       card = card->next;
+               }
+       }
+
+       ASSERT(card);
+       if (!card)
+               return -ENXIO;
+       /* Put the adapter in the card's adapter list */
+       ASSERT(card->adapter[adapter->port] == NULL);
+       if (!card->adapter[adapter->port]) {
+               card->adapter[adapter->port] = adapter;
+               adapter->card = card;
+       }
+
+       card->card_size = 1;    /* one port per *logical* card */
+
+       while (physcard) {
+               for (i = 0; i < SLIC_MAX_PORTS; i++) {
+                       if (!physcard->adapter[i])
+                               continue;
+                       else
+                               break;
+               }
+               ASSERT(i != SLIC_MAX_PORTS);
+               if (physcard->adapter[i]->slotnumber == adapter->slotnumber)
+                       break;
+               physcard = physcard->next;
+       }
+       if (!physcard) {
+               /* no structure allocated for this physical card yet */
+               physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC);
+               ASSERT(physcard);
+
+               physcard->next = slic_global.phys_card;
+               slic_global.phys_card = physcard;
+               physcard->adapters_allocd = 1;
+       } else {
+               physcard->adapters_allocd++;
+       }
+       /* Note - this is ZERO relative */
+       adapter->physport = physcard->adapters_allocd - 1;
+
+       ASSERT(physcard->adapter[adapter->physport] == NULL);
+       physcard->adapter[adapter->physport] = adapter;
+       adapter->physcard = physcard;
 
        return 0;
 }
-static int slic_debug_adapter_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, slic_debug_adapter_show, inode->i_private);
-}
 
-static int slic_debug_card_open(struct inode *inode, struct file *file)
+static int __devinit slic_entry_probe(struct pci_dev *pcidev,
+                              const struct pci_device_id *pci_tbl_entry)
 {
-       return single_open(file, slic_debug_card_show, inode->i_private);
-}
+       static int cards_found;
+       static int did_version;
+       int err = -ENODEV;
+       struct net_device *netdev;
+       struct adapter *adapter;
+       void __iomem *memmapped_ioaddr = NULL;
+       u32 status = 0;
+       ulong mmio_start = 0;
+       ulong mmio_len = 0;
+       struct sliccard *card = NULL;
+       int pci_using_dac = 0;
 
-static const struct file_operations slic_debug_adapter_fops = {
-       .owner          = THIS_MODULE,
-       .open           = slic_debug_adapter_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
+       slic_global.dynamic_intagg = dynamic_intagg;
 
-static const struct file_operations slic_debug_card_fops = {
-       .owner          = THIS_MODULE,
-       .open           = slic_debug_card_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
+       err = pci_enable_device(pcidev);
 
-static void slic_debug_adapter_create(struct adapter *adapter)
-{
-       struct dentry *d;
-       char    name[7];
-       struct sliccard *card = adapter->card;
+       if (err)
+               return err;
 
-       if (!card->debugfs_dir)
-               return;
+       if (slic_debug > 0 && did_version++ == 0) {
+               printk(KERN_DEBUG "%s\n", slic_banner);
+               printk(KERN_DEBUG "%s\n", slic_proc_version);
+       }
 
-       sprintf(name, "port%d", adapter->port);
-       d = debugfs_create_file(name, S_IRUGO,
-                               card->debugfs_dir, adapter,
-                               &slic_debug_adapter_fops);
-       if (!d || IS_ERR(d))
-               pr_info(PFX "%s: debugfs create failed\n", name);
-       else
-               adapter->debugfs_entry = d;
-}
+       if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
+               pci_using_dac = 1;
+               if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
+                       dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for "
+                                       "consistent allocations\n");
+                       goto err_out_disable_pci;
+               }
+       } else if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
+               pci_using_dac = 0;
+               pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
+       } else {
+               dev_err(&pcidev->dev, "no usable DMA configuration\n");
+               goto err_out_disable_pci;
+       }
 
-static void slic_debug_adapter_destroy(struct adapter *adapter)
-{
-       debugfs_remove(adapter->debugfs_entry);
-       adapter->debugfs_entry = NULL;
-}
+       err = pci_request_regions(pcidev, DRV_NAME);
+       if (err) {
+               dev_err(&pcidev->dev, "can't obtain PCI resources\n");
+               goto err_out_disable_pci;
+       }
 
-static void slic_debug_card_create(struct sliccard *card)
-{
-       struct dentry *d;
-       char    name[IFNAMSIZ];
+       pci_set_master(pcidev);
 
-       snprintf(name, sizeof(name), "slic%d", card->cardnum);
-       d = debugfs_create_dir(name, slic_debugfs);
-       if (!d || IS_ERR(d))
-               pr_info(PFX "%s: debugfs create dir failed\n",
-                               name);
-       else {
-               card->debugfs_dir = d;
-               d = debugfs_create_file("cardinfo", S_IRUGO,
-                               slic_debugfs, card,
-                               &slic_debug_card_fops);
-               if (!d || IS_ERR(d))
-                       pr_info(PFX "%s: debugfs create failed\n",
-                                       name);
-               else
-                       card->debugfs_cardinfo = d;
+       netdev = alloc_etherdev(sizeof(struct adapter));
+       if (!netdev) {
+               err = -ENOMEM;
+               goto err_out_exit_slic_probe;
        }
-}
 
-static void slic_debug_card_destroy(struct sliccard *card)
-{
-       int i;
+       SET_NETDEV_DEV(netdev, &pcidev->dev);
 
-       for (i = 0; i < card->card_size; i++) {
-               struct adapter *adapter;
+       pci_set_drvdata(pcidev, netdev);
+       adapter = netdev_priv(netdev);
+       adapter->netdev = netdev;
+       adapter->pcidev = pcidev;
+       if (pci_using_dac)
+               netdev->features |= NETIF_F_HIGHDMA;
 
-               adapter = card->adapter[i];
-               if (adapter)
-                       slic_debug_adapter_destroy(adapter);
+       mmio_start = pci_resource_start(pcidev, 0);
+       mmio_len = pci_resource_len(pcidev, 0);
+
+
+/*     memmapped_ioaddr =  (u32)ioremap_nocache(mmio_start, mmio_len);*/
+       memmapped_ioaddr = ioremap(mmio_start, mmio_len);
+       if (!memmapped_ioaddr) {
+               dev_err(&pcidev->dev, "cannot remap MMIO region %lx @ %lx\n",
+                       mmio_len, mmio_start);
+               goto err_out_free_netdev;
        }
-       if (card->debugfs_cardinfo) {
-               debugfs_remove(card->debugfs_cardinfo);
-               card->debugfs_cardinfo = NULL;
+
+       slic_config_pci(pcidev);
+
+       slic_init_driver();
+
+       slic_init_adapter(netdev,
+                         pcidev, pci_tbl_entry, memmapped_ioaddr, cards_found);
+
+       status = slic_card_locate(adapter);
+       if (status) {
+               dev_err(&pcidev->dev, "cannot locate card\n");
+               goto err_out_free_mmio_region;
        }
-       if (card->debugfs_dir) {
-               debugfs_remove(card->debugfs_dir);
-               card->debugfs_dir = NULL;
+
+       card = adapter->card;
+
+       if (!adapter->allocated) {
+               card->adapters_allocated++;
+               adapter->allocated = 1;
        }
-}
 
-static void slic_debug_init(void)
-{
-       struct dentry *ent;
+       status = slic_card_init(card, adapter);
 
-       ent = debugfs_create_dir("slic", NULL);
-       if (!ent || IS_ERR(ent)) {
-               pr_info(PFX "debugfs create directory failed\n");
-               return;
+       if (status != 0) {
+               card->state = CARD_FAIL;
+               adapter->state = ADAPT_FAIL;
+               adapter->linkstate = LINK_DOWN;
+               dev_err(&pcidev->dev, "FAILED status[%x]\n", status);
+       } else {
+               slic_adapter_set_hwaddr(adapter);
        }
 
-       slic_debugfs = ent;
-}
+       netdev->base_addr = (unsigned long)adapter->memorybase;
+       netdev->irq = adapter->irq;
+       netdev->netdev_ops = &slic_netdev_ops;
 
-static void slic_debug_cleanup(void)
-{
-       if (slic_debugfs) {
-               debugfs_remove(slic_debugfs);
-               slic_debugfs = NULL;
+       slic_debug_adapter_create(adapter);
+
+       strcpy(netdev->name, "eth%d");
+       err = register_netdev(netdev);
+       if (err) {
+               dev_err(&pcidev->dev, "Cannot register net device, aborting.\n");
+               goto err_out_unmap;
        }
-}
 
-/******************************************************************************/
-/****************   MODULE INITIATION / TERMINATION FUNCTIONS   ***************/
-/******************************************************************************/
+       cards_found++;
+
+       return status;
+
+err_out_unmap:
+       iounmap(memmapped_ioaddr);
+err_out_free_mmio_region:
+       release_mem_region(mmio_start, mmio_len);
+err_out_free_netdev:
+       free_netdev(netdev);
+err_out_exit_slic_probe:
+       pci_release_regions(pcidev);
+err_out_disable_pci:
+       pci_disable_device(pcidev);
+       return err;
+}
 
 static struct pci_driver slic_driver = {
        .name = DRV_NAME,
index 9ffeb36ddde6528218a8704b01f62ad34286c0b7..f6b401c0ccc92eacaa903398b157d67b27c6fdad 100644 (file)
@@ -835,7 +835,7 @@ __setup("vga=", sm712vga_setup);
  * Original init function changed to probe method to be used by pci_drv
  * process used to detect chips replaced with kernel process in pci_drv
  */
-static int __init smtcfb_pci_probe(struct pci_dev *pdev,
+static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
                                   const struct pci_device_id *ent)
 {
        struct smtcfb_info *sfb;
diff --git a/drivers/staging/solo6x10/Kconfig b/drivers/staging/solo6x10/Kconfig
new file mode 100644 (file)
index 0000000..d96398c
--- /dev/null
@@ -0,0 +1,7 @@
+config SOLO6X10
+       tristate "Softlogic 6x10 MPEG codec cards"
+       depends on PCI && VIDEO_DEV && SND
+       select VIDEOBUF_DMA_CONTIG
+       ---help---
+         This driver supports the Softlogic based MPEG-4 and h.264 codec
+         codec cards.
diff --git a/drivers/staging/solo6x10/Makefile b/drivers/staging/solo6x10/Makefile
new file mode 100644 (file)
index 0000000..7e70044
--- /dev/null
@@ -0,0 +1,6 @@
+solo6x10-objs  := solo6010-core.o solo6010-i2c.o solo6010-p2m.o \
+                  solo6010-v4l2.o solo6010-tw28.o solo6010-gpio.o \
+                  solo6010-disp.o solo6010-enc.o solo6010-v4l2-enc.o \
+                  solo6010-g723.o
+
+obj-$(CONFIG_SOLO6X10) := solo6x10.o
diff --git a/drivers/staging/solo6x10/TODO b/drivers/staging/solo6x10/TODO
new file mode 100644 (file)
index 0000000..e6a2ee2
--- /dev/null
@@ -0,0 +1,28 @@
+TODO (staging => main):
+
+       * checkpatch.pl (haven't run it yet)
+       * Lindent (should be clean, but check)
+       * Motion detection flags need to be moved to v4l2
+       * Some private CIDs need to be moved to v4l2
+
+TODO (general):
+
+       * encoder on/off controls
+       * mpeg cid bitrate mode (vbr/cbr)
+       * mpeg cid bitrate/bitrate-peak
+       * mpeg encode of user data
+       * mpeg decode of user data
+       * switch between 4 frames/irq to 1 when using mjpeg (and then back
+         when not)
+       * implement a CID control for motion areas/thresholds
+       * implement CID controls for mozaic areas
+       * allow for higher level of interval (for < 1 fps)
+       * sound:
+         - implement playback via external sound jack
+         - implement loopback of external sound jack with incoming audio?
+         - implement pause/resume
+         - check into jacking sound from tx28xx chips directly (to avoid
+           g.723/8khz limitations)
+
+Plase send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc Ben Collins
+<bcollins@bluecherry.net>
diff --git a/drivers/staging/solo6x10/solo6010-core.c b/drivers/staging/solo6x10/solo6010-core.c
new file mode 100644 (file)
index 0000000..98c6739
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/videodev2.h>
+
+#include "solo6010.h"
+#include "solo6010-tw28.h"
+
+MODULE_DESCRIPTION("Softlogic 6010 MP4 Encoder/Decoder V4L2/ALSA Driver");
+MODULE_AUTHOR("Ben Collins <bcollins@bluecherry.net>");
+MODULE_VERSION(SOLO6010_VERSION);
+MODULE_LICENSE("GPL");
+
+void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask)
+{
+       solo_dev->irq_mask |= mask;
+       solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask);
+}
+
+void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask)
+{
+       solo_dev->irq_mask &= ~mask;
+       solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask);
+}
+
+/* XXX We should check the return value of the sub-device ISR's */
+static irqreturn_t solo6010_isr(int irq, void *data)
+{
+       struct solo6010_dev *solo_dev = data;
+       u32 status;
+       int i;
+
+       status = solo_reg_read(solo_dev, SOLO_IRQ_STAT);
+       if (!status)
+               return IRQ_NONE;
+
+       if (status & ~solo_dev->irq_mask) {
+               solo_reg_write(solo_dev, SOLO_IRQ_STAT,
+                              status & ~solo_dev->irq_mask);
+               status &= solo_dev->irq_mask;
+       }
+
+       if (status & SOLO_IRQ_PCI_ERR) {
+               u32 err = solo_reg_read(solo_dev, SOLO_PCI_ERR);
+               solo_p2m_error_isr(solo_dev, err);
+               solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_PCI_ERR);
+       }
+
+       for (i = 0; i < SOLO_NR_P2M; i++)
+               if (status & SOLO_IRQ_P2M(i))
+                       solo_p2m_isr(solo_dev, i);
+
+       if (status & SOLO_IRQ_IIC)
+               solo_i2c_isr(solo_dev);
+
+       if (status & SOLO_IRQ_VIDEO_IN)
+               solo_video_in_isr(solo_dev);
+
+       /* Call this first so enc gets detected flag set */
+       if (status & SOLO_IRQ_MOTION)
+               solo_motion_isr(solo_dev);
+
+       if (status & SOLO_IRQ_ENCODER)
+               solo_enc_v4l2_isr(solo_dev);
+
+       if (status & SOLO_IRQ_G723)
+               solo_g723_isr(solo_dev);
+
+       return IRQ_HANDLED;
+}
+
+static void free_solo_dev(struct solo6010_dev *solo_dev)
+{
+       struct pci_dev *pdev;
+
+       if (!solo_dev)
+               return;
+
+       pdev = solo_dev->pdev;
+
+       /* If we never initialized the PCI device, then nothing else
+        * below here needs cleanup */
+       if (!pdev) {
+               kfree(solo_dev);
+               return;
+       }
+
+       /* Bring down the sub-devices first */
+       solo_g723_exit(solo_dev);
+       solo_enc_v4l2_exit(solo_dev);
+       solo_enc_exit(solo_dev);
+       solo_v4l2_exit(solo_dev);
+       solo_disp_exit(solo_dev);
+       solo_gpio_exit(solo_dev);
+       solo_p2m_exit(solo_dev);
+       solo_i2c_exit(solo_dev);
+
+       /* Now cleanup the PCI device */
+       if (solo_dev->reg_base) {
+               solo6010_irq_off(solo_dev, ~0);
+               pci_iounmap(pdev, solo_dev->reg_base);
+               free_irq(pdev->irq, solo_dev);
+       }
+
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+
+       kfree(solo_dev);
+}
+
+static int __devinit solo6010_pci_probe(struct pci_dev *pdev,
+                                       const struct pci_device_id *id)
+{
+       struct solo6010_dev *solo_dev;
+       int ret;
+       int sdram;
+       u8 chip_id;
+
+       if ((solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL)) == NULL)
+               return -ENOMEM;
+
+       solo_dev->pdev = pdev;
+       spin_lock_init(&solo_dev->reg_io_lock);
+       pci_set_drvdata(pdev, solo_dev);
+
+       if ((ret = pci_enable_device(pdev)))
+               goto fail_probe;
+
+       pci_set_master(pdev);
+
+       if ((ret = pci_request_regions(pdev, SOLO6010_NAME)))
+               goto fail_probe;
+
+       if ((solo_dev->reg_base = pci_ioremap_bar(pdev, 0)) == NULL) {
+               ret = -ENOMEM;
+               goto fail_probe;
+       }
+
+       chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) &
+                                       SOLO_CHIP_ID_MASK;
+       switch (chip_id) {
+               case 7:
+                       solo_dev->nr_chans = 16;
+                       solo_dev->nr_ext = 5;
+                       break;
+               case 6:
+                       solo_dev->nr_chans = 8;
+                       solo_dev->nr_ext = 2;
+                       break;
+               default:
+                       dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, "
+                                "defaulting to 4 channels\n",
+                                chip_id);
+               case 5:
+                       solo_dev->nr_chans = 4;
+                       solo_dev->nr_ext = 1;
+       }
+
+       /* Disable all interrupts to start */
+       solo6010_irq_off(solo_dev, ~0);
+
+       /* Initial global settings */
+       solo_reg_write(solo_dev, SOLO_SYS_CFG, SOLO_SYS_CFG_SDRAM64BIT |
+                      SOLO_SYS_CFG_INPUTDIV(25) |
+                      SOLO_SYS_CFG_FEEDBACKDIV((SOLO_CLOCK_MHZ * 2) - 2) |
+                      SOLO_SYS_CFG_OUTDIV(3));
+       solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, SOLO_CLOCK_MHZ - 1);
+
+       /* PLL locking time of 1ms */
+       mdelay(1);
+
+       ret = request_irq(pdev->irq, solo6010_isr, IRQF_SHARED, SOLO6010_NAME,
+                         solo_dev);
+       if (ret)
+               goto fail_probe;
+
+       /* Handle this from the start */
+       solo6010_irq_on(solo_dev, SOLO_IRQ_PCI_ERR);
+
+       if ((ret = solo_i2c_init(solo_dev)))
+               goto fail_probe;
+
+       /* Setup the DMA engine */
+       sdram = (solo_dev->nr_chans >= 8) ? 2 : 1;
+       solo_reg_write(solo_dev, SOLO_DMA_CTRL,
+                      SOLO_DMA_CTRL_REFRESH_CYCLE(1) |
+                      SOLO_DMA_CTRL_SDRAM_SIZE(sdram) |
+                      SOLO_DMA_CTRL_SDRAM_CLK_INVERT |
+                      SOLO_DMA_CTRL_READ_CLK_SELECT |
+                      SOLO_DMA_CTRL_LATENCY(1));
+
+       if ((ret = solo_p2m_init(solo_dev)))
+               goto fail_probe;
+
+       if ((ret = solo_disp_init(solo_dev)))
+               goto fail_probe;
+
+       if ((ret = solo_gpio_init(solo_dev)))
+               goto fail_probe;
+
+       if ((ret = solo_tw28_init(solo_dev)))
+               goto fail_probe;
+
+       if ((ret = solo_v4l2_init(solo_dev)))
+               goto fail_probe;
+
+       if ((ret = solo_enc_init(solo_dev)))
+               goto fail_probe;
+
+       if ((ret = solo_enc_v4l2_init(solo_dev)))
+               goto fail_probe;
+
+       if ((ret = solo_g723_init(solo_dev)))
+               goto fail_probe;
+
+       return 0;
+
+fail_probe:
+       free_solo_dev(solo_dev);
+       return ret;
+}
+
+static void __devexit solo6010_pci_remove(struct pci_dev *pdev)
+{
+       struct solo6010_dev *solo_dev = pci_get_drvdata(pdev);
+
+       free_solo_dev(solo_dev);
+}
+
+static struct pci_device_id solo6010_id_table[] = {
+       {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_4)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_9)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_16)},
+       {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, solo6010_id_table);
+
+static struct pci_driver solo6010_pci_driver = {
+       .name = SOLO6010_NAME,
+       .id_table = solo6010_id_table,
+       .probe = solo6010_pci_probe,
+       .remove = solo6010_pci_remove,
+};
+
+static int __init solo6010_module_init(void)
+{
+       return pci_register_driver(&solo6010_pci_driver);
+}
+
+static void __exit solo6010_module_exit(void)
+{
+       pci_unregister_driver(&solo6010_pci_driver);
+}
+
+module_init(solo6010_module_init);
+module_exit(solo6010_module_exit);
diff --git a/drivers/staging/solo6x10/solo6010-disp.c b/drivers/staging/solo6x10/solo6010-disp.c
new file mode 100644 (file)
index 0000000..555f024
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-ioctl.h>
+
+#include "solo6010.h"
+
+#define SOLO_VCLK_DELAY                        3
+#define SOLO_PROGRESSIVE_VSIZE         1024
+
+#define SOLO_MOT_THRESH_W              64
+#define SOLO_MOT_THRESH_H              64
+#define SOLO_MOT_THRESH_SIZE           8192
+#define SOLO_MOT_THRESH_REAL           (SOLO_MOT_THRESH_W * SOLO_MOT_THRESH_H)
+#define SOLO_MOT_FLAG_SIZE             512
+#define SOLO_MOT_FLAG_AREA             (SOLO_MOT_FLAG_SIZE * 32)
+
+static unsigned video_type;
+module_param(video_type, uint, 0644);
+MODULE_PARM_DESC(video_type, "video_type (0 = NTSC/Default, 1 = PAL)");
+
+static void solo_vin_config(struct solo6010_dev *solo_dev)
+{
+       solo_dev->vin_hstart = 8;
+       solo_dev->vin_vstart = 2;
+
+       solo_reg_write(solo_dev, SOLO_SYS_VCLK,
+                      SOLO_VCLK_SELECT(2) |
+                      SOLO_VCLK_VIN1415_DELAY(SOLO_VCLK_DELAY) |
+                      SOLO_VCLK_VIN1213_DELAY(SOLO_VCLK_DELAY) |
+                      SOLO_VCLK_VIN1011_DELAY(SOLO_VCLK_DELAY) |
+                      SOLO_VCLK_VIN0809_DELAY(SOLO_VCLK_DELAY) |
+                      SOLO_VCLK_VIN0607_DELAY(SOLO_VCLK_DELAY) |
+                      SOLO_VCLK_VIN0405_DELAY(SOLO_VCLK_DELAY) |
+                      SOLO_VCLK_VIN0203_DELAY(SOLO_VCLK_DELAY) |
+                      SOLO_VCLK_VIN0001_DELAY(SOLO_VCLK_DELAY));
+
+       solo_reg_write(solo_dev, SOLO_VI_ACT_I_P,
+                      SOLO_VI_H_START(solo_dev->vin_hstart) |
+                      SOLO_VI_V_START(solo_dev->vin_vstart) |
+                      SOLO_VI_V_STOP(solo_dev->vin_vstart +
+                                     solo_dev->video_vsize));
+
+       solo_reg_write(solo_dev, SOLO_VI_ACT_I_S,
+                      SOLO_VI_H_START(solo_dev->vout_hstart) |
+                      SOLO_VI_V_START(solo_dev->vout_vstart) |
+                      SOLO_VI_V_STOP(solo_dev->vout_vstart +
+                                     solo_dev->video_vsize));
+
+       solo_reg_write(solo_dev, SOLO_VI_ACT_P,
+                      SOLO_VI_H_START(0) |
+                      SOLO_VI_V_START(1) |
+                      SOLO_VI_V_STOP(SOLO_PROGRESSIVE_VSIZE));
+
+       solo_reg_write(solo_dev, SOLO_VI_CH_FORMAT,
+                      SOLO_VI_FD_SEL_MASK(0) | SOLO_VI_PROG_MASK(0));
+
+       solo_reg_write(solo_dev, SOLO_VI_FMT_CFG, 0);
+       solo_reg_write(solo_dev, SOLO_VI_PAGE_SW, 2);
+
+       if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
+               solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG,
+                              SOLO_VI_PB_USER_MODE);
+               solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV,
+                              SOLO_VI_PB_HSIZE(858) | SOLO_VI_PB_VSIZE(246));
+               solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V,
+                              SOLO_VI_PB_VSTART(4) |
+                              SOLO_VI_PB_VSTOP(4 + 240));
+       } else {
+               solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG,
+                              SOLO_VI_PB_USER_MODE | SOLO_VI_PB_PAL);
+               solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV,
+                              SOLO_VI_PB_HSIZE(864) | SOLO_VI_PB_VSIZE(294));
+               solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V,
+                              SOLO_VI_PB_VSTART(4) |
+                              SOLO_VI_PB_VSTOP(4 + 288));
+       }
+       solo_reg_write(solo_dev, SOLO_VI_PB_ACT_H, SOLO_VI_PB_HSTART(16) |
+                      SOLO_VI_PB_HSTOP(16 + 720));
+}
+
+static void solo_disp_config(struct solo6010_dev *solo_dev)
+{
+       solo_dev->vout_hstart = 6;
+       solo_dev->vout_vstart = 8;
+
+       solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_COLOR,
+                      (0xa0 << 24) | (0x88 << 16) | (0xa0 << 8) | 0x88);
+       solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_COLOR,
+                      (0x10 << 24) | (0x8f << 16) | (0x10 << 8) | 0x8f);
+       solo_reg_write(solo_dev, SOLO_VO_BKG_COLOR,
+                      (16 << 24) | (128 << 16) | (16 << 8) | 128);
+
+       solo_reg_write(solo_dev, SOLO_VO_FMT_ENC,
+                      solo_dev->video_type |
+                      SOLO_VO_USER_COLOR_SET_NAV |
+                      SOLO_VO_NA_COLOR_Y(0) |
+                      SOLO_VO_NA_COLOR_CB(0) |
+                      SOLO_VO_NA_COLOR_CR(0));
+
+       solo_reg_write(solo_dev, SOLO_VO_ACT_H,
+                      SOLO_VO_H_START(solo_dev->vout_hstart) |
+                      SOLO_VO_H_STOP(solo_dev->vout_hstart +
+                                     solo_dev->video_hsize));
+
+       solo_reg_write(solo_dev, SOLO_VO_ACT_V,
+                      SOLO_VO_V_START(solo_dev->vout_vstart) |
+                      SOLO_VO_V_STOP(solo_dev->vout_vstart +
+                                     solo_dev->video_vsize));
+
+       solo_reg_write(solo_dev, SOLO_VO_RANGE_HV,
+                      SOLO_VO_H_LEN(solo_dev->video_hsize) |
+                      SOLO_VO_V_LEN(solo_dev->video_vsize));
+
+       solo_reg_write(solo_dev, SOLO_VI_WIN_SW, 5);
+
+       solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, SOLO_VO_DISP_ON |
+                      SOLO_VO_DISP_ERASE_COUNT(8) |
+                      SOLO_VO_DISP_BASE(SOLO_DISP_EXT_ADDR(solo_dev)));
+
+       solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON);
+
+       /* Enable channels we support */
+       solo_reg_write(solo_dev, SOLO_VI_CH_ENA, (1 << solo_dev->nr_chans) - 1);
+
+       /* Disable the watchdog */
+       solo_reg_write(solo_dev, SOLO_WATCHDOG, 0);
+}
+
+static int solo_dma_vin_region(struct solo6010_dev *solo_dev, u32 off,
+                              u16 val, int reg_size)
+{
+       u16 buf[64];
+       int i;
+       int ret = 0;
+
+       for (i = 0; i < sizeof(buf) >> 1; i++)
+               buf[i] = val;
+
+       for (i = 0; i < reg_size; i += sizeof(buf))
+               ret |= solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_VIN, 1, buf,
+                                   SOLO_MOTION_EXT_ADDR(solo_dev) + off + i,
+                                   sizeof(buf));
+
+       return ret;
+}
+
+void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val)
+{
+       if (ch > solo_dev->nr_chans)
+               return;
+
+       solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA +
+                           (ch * SOLO_MOT_THRESH_SIZE * 2),
+                           val, SOLO_MOT_THRESH_REAL);
+}
+
+/* First 8k is motion flag (512 bytes * 16). Following that is an 8k+8k
+ * threshold and working table for each channel. Atleast that's what the
+ * spec says. However, this code (take from rdk) has some mystery 8k
+ * block right after the flag area, before the first thresh table. */
+static void solo_motion_config(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               /* Clear motion flag area */
+               solo_dma_vin_region(solo_dev, i * SOLO_MOT_FLAG_SIZE, 0x0000,
+                                   SOLO_MOT_FLAG_SIZE);
+
+               /* Clear working cache table */
+               solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA +
+                                   SOLO_MOT_THRESH_SIZE +
+                                   (i * SOLO_MOT_THRESH_SIZE * 2),
+                                   0x0000, SOLO_MOT_THRESH_REAL);
+
+               /* Set default threshold table */
+               solo_set_motion_threshold(solo_dev, i, SOLO_DEF_MOT_THRESH);
+       }
+
+       /* Default motion settings */
+        solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) |
+                      (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16));
+       solo_reg_write(solo_dev, SOLO_VI_MOT_CTRL,
+                      SOLO_VI_MOTION_FRAME_COUNT(3) |
+                      SOLO_VI_MOTION_SAMPLE_LENGTH(solo_dev->video_hsize / 16)
+                      | //SOLO_VI_MOTION_INTR_START_STOP |
+                      SOLO_VI_MOTION_SAMPLE_COUNT(10));
+
+       solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0);
+       solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0);
+}
+
+int solo_disp_init(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       solo_dev->video_hsize = 704;
+       if (video_type == 0) {
+               solo_dev->video_type = SOLO_VO_FMT_TYPE_NTSC;
+               solo_dev->video_vsize = 240;
+               solo_dev->fps = 30;
+       } else {
+               solo_dev->video_type = SOLO_VO_FMT_TYPE_PAL;
+               solo_dev->video_vsize = 288;
+               solo_dev->fps = 25;
+       }
+
+       solo_vin_config(solo_dev);
+       solo_motion_config(solo_dev);
+       solo_disp_config(solo_dev);
+
+       for (i = 0; i < solo_dev->nr_chans; i++)
+               solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 1);
+
+       return 0;
+}
+
+void solo_disp_exit(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION);
+
+       solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, 0);
+       solo_reg_write(solo_dev, SOLO_VO_ZOOM_CTRL, 0);
+       solo_reg_write(solo_dev, SOLO_VO_FREEZE_CTRL, 0);
+
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(i), 0);
+               solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(i), 0);
+               solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 0);
+       }
+
+       /* Set default border */
+       for (i = 0; i < 5; i++)
+               solo_reg_write(solo_dev, SOLO_VO_BORDER_X(i), 0);
+
+       for (i = 0; i < 5; i++)
+               solo_reg_write(solo_dev, SOLO_VO_BORDER_Y(i), 0);
+
+       solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_MASK, 0);
+       solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_MASK, 0);
+
+       solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(0), 0);
+       solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(0), 0);
+       solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(0), 0);
+       
+       solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(1), 0);
+       solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(1), 0);
+       solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(1), 0);
+}
diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c
new file mode 100644 (file)
index 0000000..a6cf0a8
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+
+#include "solo6010.h"
+#include "solo6010-osd-font.h"
+
+#define CAPTURE_MAX_BANDWIDTH          32      // D1 4channel (D1 == 4)
+#define OSG_BUFFER_SIZE                        1024
+
+#define VI_PROG_HSIZE                  (1280 - 16)
+#define VI_PROG_VSIZE                  (1024 - 16)
+
+static void solo_capture_config(struct solo6010_dev *solo_dev)
+{
+       int i, j;
+       unsigned long height;
+       unsigned long width;
+       unsigned char *buf;
+
+       solo_reg_write(solo_dev, SOLO_CAP_BASE,
+                      SOLO_CAP_MAX_PAGE(SOLO_CAP_EXT_MAX_PAGE *
+                                        solo_dev->nr_chans) |
+                      SOLO_CAP_BASE_ADDR(SOLO_CAP_EXT_ADDR(solo_dev) >> 16));
+       solo_reg_write(solo_dev, SOLO_CAP_BTW,
+                      (1 << 17) | SOLO_CAP_PROG_BANDWIDTH(2) |
+                      SOLO_CAP_MAX_BANDWIDTH(CAPTURE_MAX_BANDWIDTH));
+
+       /* Set scale 1, 9 dimension */
+       width = solo_dev->video_hsize;
+       height = solo_dev->video_vsize;
+       solo_reg_write(solo_dev, SOLO_DIM_SCALE1,
+                      SOLO_DIM_H_MB_NUM(width / 16) |
+                      SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
+                      SOLO_DIM_V_MB_NUM_FIELD(height / 16));
+
+       /* Set scale 2, 10 dimension */
+       width = solo_dev->video_hsize / 2;
+       height = solo_dev->video_vsize;
+       solo_reg_write(solo_dev, SOLO_DIM_SCALE2,
+                      SOLO_DIM_H_MB_NUM(width / 16) |
+                      SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
+                      SOLO_DIM_V_MB_NUM_FIELD(height / 16));
+
+       /* Set scale 3, 11 dimension */
+       width = solo_dev->video_hsize / 2;
+       height = solo_dev->video_vsize / 2;
+       solo_reg_write(solo_dev, SOLO_DIM_SCALE3,
+                      SOLO_DIM_H_MB_NUM(width / 16) |
+                      SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
+                      SOLO_DIM_V_MB_NUM_FIELD(height / 16));
+
+       /* Set scale 4, 12 dimension */
+       width = solo_dev->video_hsize / 3;
+       height = solo_dev->video_vsize / 3;
+       solo_reg_write(solo_dev, SOLO_DIM_SCALE4,
+                      SOLO_DIM_H_MB_NUM(width / 16) |
+                      SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
+                      SOLO_DIM_V_MB_NUM_FIELD(height / 16));
+
+       /* Set scale 5, 13 dimension */
+       width = solo_dev->video_hsize / 4;
+       height = solo_dev->video_vsize / 2;
+       solo_reg_write(solo_dev, SOLO_DIM_SCALE5,
+                      SOLO_DIM_H_MB_NUM(width / 16) |
+                      SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
+                      SOLO_DIM_V_MB_NUM_FIELD(height / 16));
+
+       /* Progressive */
+       width = VI_PROG_HSIZE;
+       height = VI_PROG_VSIZE;
+       solo_reg_write(solo_dev, SOLO_DIM_PROG,
+                      SOLO_DIM_H_MB_NUM(width / 16) |
+                      SOLO_DIM_V_MB_NUM_FRAME(height / 16) |
+                      SOLO_DIM_V_MB_NUM_FIELD(height / 16));
+
+       /* Clear OSD */
+       solo_reg_write(solo_dev, SOLO_VE_OSD_CH, 0);
+       solo_reg_write(solo_dev, SOLO_VE_OSD_BASE,
+                      SOLO_EOSD_EXT_ADDR(solo_dev) >> 16);
+       solo_reg_write(solo_dev, SOLO_VE_OSD_CLR,
+                      0xF0 << 16 | 0x80 << 8 | 0x80);
+       solo_reg_write(solo_dev, SOLO_VE_OSD_OPT, 0);
+
+       /* Clear OSG buffer */
+       buf = kzalloc(OSG_BUFFER_SIZE, GFP_KERNEL);
+       if (!buf)
+               return;
+
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               for (j = 0; j < SOLO_EOSD_EXT_SIZE; j += OSG_BUFFER_SIZE) {
+                       solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_MP4E, 1, buf,
+                                    SOLO_EOSD_EXT_ADDR(solo_dev) +
+                                    (i * SOLO_EOSD_EXT_SIZE) + j,
+                                    OSG_BUFFER_SIZE);
+               }
+       }
+       kfree(buf);
+}
+
+int solo_osd_print(struct solo_enc_dev *solo_enc)
+{
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       char *str = solo_enc->osd_text;
+       u8 *buf;
+       u32 reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH);
+       int len = strlen(str);
+       int i, j;
+       int x = 1, y = 1;
+
+       if (len == 0) {
+               reg &= ~(1 << solo_enc->ch);
+               solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg);
+               return 0;
+       }
+
+       buf = kzalloc(SOLO_EOSD_EXT_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       for (i = 0; i < len; i++) {
+               for (j = 0; j < 16; j++) {
+                       buf[(j*2) + (i%2) + ((x + (i/2)) * 32) + (y * 2048)] =
+                               (solo_osd_font[(str[i] * 4) + (j / 4)]
+                                       >> ((3 - (j % 4)) * 8)) & 0xff;
+               }
+       }
+
+       solo_p2m_dma(solo_dev, 0, 1, buf, SOLO_EOSD_EXT_ADDR(solo_dev) +
+                    (solo_enc->ch * SOLO_EOSD_EXT_SIZE), SOLO_EOSD_EXT_SIZE);
+        reg |= (1 << solo_enc->ch);
+        solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg);
+
+       kfree(buf);
+
+       return 0;
+}
+
+static void solo_jpeg_config(struct solo6010_dev *solo_dev)
+{
+       solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL,
+                      (2 << 24) | (2 << 16) | (2 << 8) | (2 << 0));
+       solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_L, 0);
+       solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_H, 0);
+       solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG,
+               (SOLO_JPEG_EXT_SIZE(solo_dev) & 0xffff0000) |
+               ((SOLO_JPEG_EXT_ADDR(solo_dev) >> 16) & 0x0000ffff));
+       solo_reg_write(solo_dev, SOLO_VE_JPEG_CTRL, 0xffffffff);
+}
+
+static void solo_mp4e_config(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       /* We can only use VE_INTR_CTRL(0) if we want to support mjpeg */
+       solo_reg_write(solo_dev, SOLO_VE_CFG0,
+                      SOLO_VE_INTR_CTRL(0) |
+                      SOLO_VE_BLOCK_SIZE(SOLO_MP4E_EXT_SIZE(solo_dev) >> 16) |
+                      SOLO_VE_BLOCK_BASE(SOLO_MP4E_EXT_ADDR(solo_dev) >> 16));
+
+       solo_reg_write(solo_dev, SOLO_VE_CFG1,
+                      SOLO_VE_BYTE_ALIGN(2) |
+                      SOLO_VE_INSERT_INDEX | SOLO_VE_MOTION_MODE(0));
+
+       solo_reg_write(solo_dev, SOLO_VE_WMRK_POLY, 0);
+       solo_reg_write(solo_dev, SOLO_VE_VMRK_INIT_KEY, 0);
+       solo_reg_write(solo_dev, SOLO_VE_WMRK_STRL, 0);
+       solo_reg_write(solo_dev, SOLO_VE_ENCRYP_POLY, 0);
+       solo_reg_write(solo_dev, SOLO_VE_ENCRYP_INIT, 0);
+
+       solo_reg_write(solo_dev, SOLO_VE_ATTR,
+                      SOLO_VE_LITTLE_ENDIAN |
+                      SOLO_COMP_ATTR_FCODE(1) |
+                      SOLO_COMP_TIME_INC(0) |
+                      SOLO_COMP_TIME_WIDTH(15) |
+                      SOLO_DCT_INTERVAL(36 / 4));
+
+       for (i = 0; i < solo_dev->nr_chans; i++)
+               solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE(i),
+                              (SOLO_EREF_EXT_ADDR(solo_dev) +
+                              (i * SOLO_EREF_EXT_SIZE)) >> 16);
+}
+
+int solo_enc_init(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       solo_capture_config(solo_dev);
+       solo_mp4e_config(solo_dev);
+       solo_jpeg_config(solo_dev);
+
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0);
+               solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0);
+       }
+
+       solo6010_irq_on(solo_dev, SOLO_IRQ_ENCODER);
+
+       return 0;
+}
+
+void solo_enc_exit(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       solo6010_irq_off(solo_dev, SOLO_IRQ_ENCODER);
+
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0);
+               solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0);
+       }
+}
diff --git a/drivers/staging/solo6x10/solo6010-g723.c b/drivers/staging/solo6x10/solo6010-g723.c
new file mode 100644 (file)
index 0000000..e82846c
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mempool.h>
+#include <linux/poll.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/control.h>
+
+#include "solo6010.h"
+#include "solo6010-tw28.h"
+
+#define G723_INTR_ORDER                0
+#define G723_FDMA_PAGES                32
+#define G723_PERIOD_BYTES      48
+#define G723_PERIOD_BLOCK      1024
+#define G723_FRAMES_PER_PAGE   48
+
+/* Sets up channels 16-19 for decoding and 0-15 for encoding */
+#define OUTMODE_MASK           0x300
+
+#define SAMPLERATE             8000
+#define BITRATE                        25
+
+/* The solo writes to 1k byte pages, 32 pages, in the dma. Each 1k page
+ * is broken down to 20 * 48 byte regions (one for each channel possible)
+ * with the rest of the page being dummy data. */
+#define MAX_BUFFER             (G723_PERIOD_BYTES * PERIODS_MAX)
+#define IRQ_PAGES              4 // 0 - 4
+#define PERIODS_MIN            (1 << IRQ_PAGES)
+#define PERIODS_MAX            G723_FDMA_PAGES
+
+struct solo_snd_pcm {
+       int                             on;
+       spinlock_t                      lock;
+       struct solo6010_dev             *solo_dev;
+       unsigned char                   g723_buf[G723_PERIOD_BYTES];
+};
+
+static void solo_g723_config(struct solo6010_dev *solo_dev)
+{
+       int clk_div;
+
+       clk_div = SOLO_CLOCK_MHZ / (SAMPLERATE * (BITRATE * 2) * 2);
+
+       solo_reg_write(solo_dev, SOLO_AUDIO_SAMPLE,
+                      SOLO_AUDIO_BITRATE(BITRATE) |
+                      SOLO_AUDIO_CLK_DIV(clk_div));
+
+       solo_reg_write(solo_dev, SOLO_AUDIO_FDMA_INTR,
+                     SOLO_AUDIO_FDMA_INTERVAL(IRQ_PAGES) |
+                     SOLO_AUDIO_INTR_ORDER(G723_INTR_ORDER) |
+                     SOLO_AUDIO_FDMA_BASE(SOLO_G723_EXT_ADDR(solo_dev) >> 16));
+
+       solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL,
+                      SOLO_AUDIO_ENABLE | SOLO_AUDIO_I2S_MODE |
+                      SOLO_AUDIO_I2S_MULTI(3) | SOLO_AUDIO_MODE(OUTMODE_MASK));
+}
+
+void solo_g723_isr(struct solo6010_dev *solo_dev)
+{
+       struct snd_pcm_str *pstr =
+               &solo_dev->snd_pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
+       struct snd_pcm_substream *ss;
+       struct solo_snd_pcm *solo_pcm;
+
+       solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_G723);
+
+       for (ss = pstr->substream; ss != NULL; ss = ss->next) {
+               if (snd_pcm_substream_chip(ss) == NULL)
+                       continue;
+
+               /* This means open() hasn't been called on this one */
+               if (snd_pcm_substream_chip(ss) == solo_dev)
+                       continue;
+
+               /* Haven't triggered a start yet */
+               solo_pcm = snd_pcm_substream_chip(ss);
+               if (!solo_pcm->on)
+                       continue;
+
+               snd_pcm_period_elapsed(ss);
+       }
+}
+
+static int snd_solo_hw_params(struct snd_pcm_substream *ss,
+                             struct snd_pcm_hw_params *hw_params)
+{
+       return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
+}
+
+static int snd_solo_hw_free(struct snd_pcm_substream *ss)
+{
+       return snd_pcm_lib_free_pages(ss);
+}
+
+static struct snd_pcm_hardware snd_solo_pcm_hw = {
+       .info                   = (SNDRV_PCM_INFO_MMAP |
+                                  SNDRV_PCM_INFO_INTERLEAVED |
+                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                  SNDRV_PCM_INFO_MMAP_VALID),
+       .formats                = SNDRV_PCM_FMTBIT_U8,
+       .rates                  = SNDRV_PCM_RATE_8000,
+       .rate_min               = 8000,
+       .rate_max               = 8000,
+       .channels_min           = 1,
+       .channels_max           = 1,
+       .buffer_bytes_max       = MAX_BUFFER,
+       .period_bytes_min       = G723_PERIOD_BYTES,
+       .period_bytes_max       = G723_PERIOD_BYTES,
+       .periods_min            = PERIODS_MIN,
+       .periods_max            = PERIODS_MAX,
+};
+
+static int snd_solo_pcm_open(struct snd_pcm_substream *ss)
+{
+       struct solo6010_dev *solo_dev = snd_pcm_substream_chip(ss);
+       struct solo_snd_pcm *solo_pcm;
+
+       solo_pcm = kzalloc(sizeof(*solo_pcm), GFP_KERNEL);
+       if (solo_pcm == NULL)
+               return -ENOMEM;
+
+       spin_lock_init(&solo_pcm->lock);
+       solo_pcm->solo_dev = solo_dev;
+       ss->runtime->hw = snd_solo_pcm_hw;
+
+       snd_pcm_substream_chip(ss) = solo_pcm;
+
+       return 0;
+}
+
+static int snd_solo_pcm_close(struct snd_pcm_substream *ss)
+{
+       struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
+
+       snd_pcm_substream_chip(ss) = solo_pcm->solo_dev;
+       kfree(solo_pcm);
+
+        return 0;
+}
+
+static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
+{
+       struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
+       struct solo6010_dev *solo_dev = solo_pcm->solo_dev;
+       int ret = 0;
+
+       spin_lock(&solo_pcm->lock);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               if (solo_pcm->on == 0) {
+                       /* If this is the first user, switch on interrupts */
+                       if (atomic_inc_return(&solo_dev->snd_users) == 1)
+                               solo6010_irq_on(solo_dev, SOLO_IRQ_G723);
+                       solo_pcm->on = 1;
+               }
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               if (solo_pcm->on) {
+                       /* If this was our last user, switch them off */
+                       if (atomic_dec_return(&solo_dev->snd_users) == 0)
+                               solo6010_irq_off(solo_dev, SOLO_IRQ_G723);
+                       solo_pcm->on = 0;
+               }
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       spin_unlock(&solo_pcm->lock);
+
+       return ret;
+}
+
+static int snd_solo_pcm_prepare(struct snd_pcm_substream *ss)
+{
+        return 0;
+}
+
+static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss)
+{
+       struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
+       struct solo6010_dev *solo_dev = solo_pcm->solo_dev;
+       snd_pcm_uframes_t idx = solo_reg_read(solo_dev, SOLO_AUDIO_STA) & 0x1f;
+
+       return idx * G723_FRAMES_PER_PAGE;
+}
+
+static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel,
+                            snd_pcm_uframes_t pos, void __user *dst,
+                            snd_pcm_uframes_t count)
+{
+       struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
+       struct solo6010_dev *solo_dev = solo_pcm->solo_dev;
+       int err, i;
+
+       for (i = 0; i < (count / G723_FRAMES_PER_PAGE); i++) {
+               int page = (pos / G723_FRAMES_PER_PAGE) + i;
+
+               err = solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_G723E, 0,
+                                  solo_pcm->g723_buf,
+                                  SOLO_G723_EXT_ADDR(solo_dev) +
+                                  (page * G723_PERIOD_BLOCK) +
+                                  (ss->number * G723_PERIOD_BYTES),
+                                  G723_PERIOD_BYTES);
+               if (err)
+                       return err;
+
+               err = copy_to_user(dst + (i * G723_PERIOD_BYTES),
+                                  solo_pcm->g723_buf, G723_PERIOD_BYTES);
+
+               if (err)
+                       return err; 
+       }
+
+       return 0;
+}
+
+static struct snd_pcm_ops snd_solo_pcm_ops = {
+       .open = snd_solo_pcm_open,
+       .close = snd_solo_pcm_close,
+       .ioctl = snd_pcm_lib_ioctl,
+       .hw_params = snd_solo_hw_params,
+       .hw_free = snd_solo_hw_free,
+       .prepare = snd_solo_pcm_prepare,
+       .trigger = snd_solo_pcm_trigger,
+       .pointer = snd_solo_pcm_pointer,
+       .copy = snd_solo_pcm_copy,
+};
+
+static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_info *info)
+{
+       info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       info->count = 1;
+       info->value.integer.min = 0;
+       info->value.integer.max = 15;
+       info->value.integer.step = 1;
+
+       return 0;
+}
+
+static int snd_solo_capture_volume_get(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *value)
+{
+       struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol);
+       u8 ch = value->id.numid - 1;
+
+       value->value.integer.value[0] = tw28_get_audio_gain(solo_dev, ch);
+
+        return 0;
+}
+
+static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *value)
+{
+       struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol);
+       u8 ch = value->id.numid - 1;
+        u8 old_val;
+
+        old_val = tw28_get_audio_gain(solo_dev, ch);
+       if (old_val == value->value.integer.value[0])
+               return 0;
+
+       tw28_set_audio_gain(solo_dev, ch, value->value.integer.value[0]);
+
+        return 1;
+}
+
+static struct snd_kcontrol_new snd_solo_capture_volume = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Capture Volume",
+       .info = snd_solo_capture_volume_info,
+       .get = snd_solo_capture_volume_get,
+       .put = snd_solo_capture_volume_put,
+};
+
+static int solo_snd_pcm_init(struct solo6010_dev *solo_dev)
+{
+       struct snd_card *card = solo_dev->snd_card;
+       struct snd_pcm *pcm;
+       struct snd_pcm_substream *ss;
+       int ret;
+       int i;
+
+       ret = snd_pcm_new(card, card->driver, 0, 0, solo_dev->nr_chans,
+                         &pcm);
+       if (ret < 0)
+               return ret;
+
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                       &snd_solo_pcm_ops);
+
+       snd_pcm_chip(pcm) = solo_dev;
+       pcm->info_flags = 0;
+       strcpy(pcm->name, card->shortname);
+
+       for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
+            ss; ss = ss->next, i++)
+               sprintf(ss->name, "Camera #%d Audio", i);
+
+       ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
+                                       SNDRV_DMA_TYPE_CONTINUOUS,
+                                       snd_dma_continuous_data(GFP_KERNEL),
+                                       MAX_BUFFER, MAX_BUFFER);
+       if (ret < 0)
+               return ret;
+
+       solo_dev->snd_pcm = pcm;
+
+       return 0;
+}
+
+int solo_g723_init(struct solo6010_dev *solo_dev)
+{
+       static struct snd_device_ops ops = { NULL };
+       struct snd_card *card;
+       struct snd_kcontrol_new kctl;
+       char name[32];
+       int ret;
+
+       atomic_set(&solo_dev->snd_users, 0);
+
+       /* Allows for easier mapping between video and audio */
+       sprintf(name, "Softlogic%d", solo_dev->vfd->num);
+
+       ret = snd_card_create(SNDRV_DEFAULT_IDX1, name, THIS_MODULE, 0,
+                             &solo_dev->snd_card);
+       if (ret < 0)
+               return ret;
+
+       card = solo_dev->snd_card;
+
+       strcpy(card->driver, SOLO6010_NAME);
+       strcpy(card->shortname, "SOLO-6010 Audio");
+       sprintf(card->longname, "%s on %s IRQ %d", card->shortname,
+               pci_name(solo_dev->pdev), solo_dev->pdev->irq);
+       snd_card_set_dev(card, &solo_dev->pdev->dev);
+
+       ret = snd_device_new(card, SNDRV_DEV_LOWLEVEL, solo_dev, &ops);
+       if (ret < 0)
+               goto snd_error;
+
+       /* Mixer controls */
+       strcpy(card->mixername, "SOLO-6010");
+       kctl = snd_solo_capture_volume;
+       kctl.count = solo_dev->nr_chans;
+        ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev));
+       if (ret < 0)
+               return ret;
+
+       if ((ret = solo_snd_pcm_init(solo_dev)) < 0)
+               goto snd_error;
+
+       if ((ret = snd_card_register(card)) < 0)
+               goto snd_error;
+
+       solo_g723_config(solo_dev);
+
+       dev_info(&solo_dev->pdev->dev, "Alsa sound card as %s\n", name);
+
+       return 0;
+
+snd_error:
+       snd_card_free(card);
+       return ret;
+}
+
+void solo_g723_exit(struct solo6010_dev *solo_dev)
+{
+       solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, 0);
+       solo6010_irq_off(solo_dev, SOLO_IRQ_G723);
+
+       snd_card_free(solo_dev->snd_card);
+}
diff --git a/drivers/staging/solo6x10/solo6010-gpio.c b/drivers/staging/solo6x10/solo6010-gpio.c
new file mode 100644 (file)
index 0000000..46f7a71
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+
+#include "solo6010.h"
+
+static void solo_gpio_mode(struct solo6010_dev *solo_dev,
+                          unsigned int port_mask, unsigned int mode)
+{
+       int port;
+       unsigned int ret;
+
+       ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_0);
+
+       /* To set gpio */
+       for (port = 0; port < 16; port++) {
+               if (!((1 << port) & port_mask))
+                       continue;
+
+               ret &= (~(3 << (port << 1)));
+               ret |= ((mode & 3) << (port << 1));
+       }
+
+       solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_0, ret);
+
+       /* To set extended gpio - sensor */
+       ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_1);
+
+       for (port = 0; port < 16; port++) {
+               if (!((1 << (port + 16)) & port_mask))
+                       continue;
+
+               if (!mode)
+                       ret &= ~(1 << port);
+               else
+                       ret |= 1 << port;
+       }
+
+       solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_1, ret);
+}
+
+static void solo_gpio_set(struct solo6010_dev *solo_dev, unsigned int value)
+{
+       solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT,
+                      solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) | value);
+}
+
+static void solo_gpio_clear(struct solo6010_dev *solo_dev, unsigned int value)
+{
+       solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT,
+                      solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) & ~value);
+}
+
+static void solo_gpio_config(struct solo6010_dev *solo_dev)
+{
+       /* Video reset */
+       solo_gpio_mode(solo_dev, 0x30, 1);
+       solo_gpio_clear(solo_dev, 0x30);
+       udelay(100);
+       solo_gpio_set(solo_dev, 0x30);
+       udelay(100);
+
+       /* Warning: Don't touch the next line unless you're sure of what
+        * you're doing: first four gpio [0-3] are used for video. */
+       solo_gpio_mode(solo_dev, 0x0f, 2);
+
+       /* We use bit 8-15 of SOLO_GPIO_CONFIG_0 for relay purposes */
+       solo_gpio_mode(solo_dev, 0xff00, 1);
+
+       /* Initially set relay status to 0 */
+       solo_gpio_clear(solo_dev, 0xff00);
+}
+
+int solo_gpio_init(struct solo6010_dev *solo_dev)
+{
+        solo_gpio_config(solo_dev);
+        return 0;
+}
+
+void solo_gpio_exit(struct solo6010_dev *solo_dev)
+{
+       solo_gpio_clear(solo_dev, 0x30);
+       solo_gpio_config(solo_dev);
+}
diff --git a/drivers/staging/solo6x10/solo6010-i2c.c b/drivers/staging/solo6x10/solo6010-i2c.c
new file mode 100644 (file)
index 0000000..2bb86fa
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* XXX: The SOLO6010 i2c does not have separate interrupts for each i2c
+ * channel. The bus can only handle one i2c event at a time. The below handles
+ * this all wrong. We should be using the status registers to see if the bus
+ * is in use, and have a global lock to check the status register. Also,
+ * the bulk of the work should be handled out-of-interrupt. The ugly loops
+ * that occur during interrupt scare me. The ISR should merely signal
+ * thread context, ACK the interrupt, and move on. -- BenC */
+
+#include <linux/kernel.h>
+
+#include "solo6010.h"
+
+u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off)
+{
+       struct i2c_msg msgs[2];
+       u8 data;
+
+       msgs[0].flags = 0;
+       msgs[0].addr = addr;
+       msgs[0].len = 1;
+       msgs[0].buf = &off;
+
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].addr = addr;
+       msgs[1].len = 1;
+       msgs[1].buf = &data;
+
+       i2c_transfer(&solo_dev->i2c_adap[id], msgs, 2);
+
+        return data;
+}
+
+void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr,
+                       u8 off, u8 data)
+{
+       struct i2c_msg msgs;
+       u8 buf[2];
+
+       buf[0] = off;
+       buf[1] = data;
+       msgs.flags = 0;
+       msgs.addr = addr;
+       msgs.len = 2;
+       msgs.buf = buf;
+
+       i2c_transfer(&solo_dev->i2c_adap[id], &msgs, 1);
+}
+
+static void solo_i2c_flush(struct solo6010_dev *solo_dev, int wr)
+{
+       u32 ctrl;
+
+       ctrl = SOLO_IIC_CH_SET(solo_dev->i2c_id);
+
+       if (solo_dev->i2c_state == IIC_STATE_START)
+               ctrl |= SOLO_IIC_START;
+
+       if (wr) {
+               ctrl |= SOLO_IIC_WRITE;
+       } else {
+               ctrl |= SOLO_IIC_READ;
+               if (!(solo_dev->i2c_msg->flags & I2C_M_NO_RD_ACK))
+                       ctrl |= SOLO_IIC_ACK_EN;
+       }
+
+       if (solo_dev->i2c_msg_ptr == solo_dev->i2c_msg->len)
+               ctrl |= SOLO_IIC_STOP;
+
+       solo_reg_write(solo_dev, SOLO_IIC_CTRL, ctrl);
+}
+
+static void solo_i2c_start(struct solo6010_dev *solo_dev)
+{
+       u32 addr = solo_dev->i2c_msg->addr << 1;
+
+       if (solo_dev->i2c_msg->flags & I2C_M_RD)
+               addr |= 1;
+
+       solo_dev->i2c_state = IIC_STATE_START;
+       solo_reg_write(solo_dev, SOLO_IIC_TXD, addr);
+       solo_i2c_flush(solo_dev, 1);
+}
+
+static void solo_i2c_stop(struct solo6010_dev *solo_dev)
+{
+       solo6010_irq_off(solo_dev, SOLO_IRQ_IIC);
+       solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0);
+       solo_dev->i2c_state = IIC_STATE_STOP;
+       wake_up(&solo_dev->i2c_wait);
+}
+
+static int solo_i2c_handle_read(struct solo6010_dev *solo_dev)
+{
+prepare_read:
+       if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) {
+               solo_i2c_flush(solo_dev, 0);
+               return 0;
+       }
+
+       solo_dev->i2c_msg_ptr = 0;
+       solo_dev->i2c_msg++;
+       solo_dev->i2c_msg_num--;
+
+       if (solo_dev->i2c_msg_num == 0) {
+               solo_i2c_stop(solo_dev);
+               return 0;
+       }
+
+       if (!(solo_dev->i2c_msg->flags & I2C_M_NOSTART)) {
+               solo_i2c_start(solo_dev);
+       } else {
+               if (solo_dev->i2c_msg->flags & I2C_M_RD)
+                       goto prepare_read;
+               else
+                       solo_i2c_stop(solo_dev);
+       }
+
+       return 0;
+}
+
+static int solo_i2c_handle_write(struct solo6010_dev *solo_dev)
+{
+retry_write:
+       if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) {
+               solo_reg_write(solo_dev, SOLO_IIC_TXD,
+                              solo_dev->i2c_msg->buf[solo_dev->i2c_msg_ptr]);
+               solo_dev->i2c_msg_ptr++;
+               solo_i2c_flush(solo_dev, 1);
+               return 0;
+       }
+
+       solo_dev->i2c_msg_ptr = 0;
+       solo_dev->i2c_msg++;
+       solo_dev->i2c_msg_num--;
+
+       if (solo_dev->i2c_msg_num == 0) {
+               solo_i2c_stop(solo_dev);
+               return 0;
+       }
+
+       if (!(solo_dev->i2c_msg->flags & I2C_M_NOSTART)) {
+               solo_i2c_start(solo_dev);
+       } else {
+               if (solo_dev->i2c_msg->flags & I2C_M_RD)
+                       solo_i2c_stop(solo_dev);
+               else
+                       goto retry_write;
+       }
+
+       return 0;
+}
+
+int solo_i2c_isr(struct solo6010_dev *solo_dev)
+{
+       u32 status = solo_reg_read(solo_dev, SOLO_IIC_CTRL);
+       int ret = -EINVAL;
+
+       solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_IIC);
+
+       if (status & (SOLO_IIC_STATE_TRNS & SOLO_IIC_STATE_SIG_ERR) ||
+           solo_dev->i2c_id < 0) {
+               solo_i2c_stop(solo_dev);
+               return -ENXIO;
+       }
+
+       switch (solo_dev->i2c_state) {
+       case IIC_STATE_START:
+               if (solo_dev->i2c_msg->flags & I2C_M_RD) {
+                       solo_dev->i2c_state = IIC_STATE_READ;
+                       ret = solo_i2c_handle_read(solo_dev);
+                       break;
+               }
+
+               solo_dev->i2c_state = IIC_STATE_WRITE;
+       case IIC_STATE_WRITE:
+               ret = solo_i2c_handle_write(solo_dev);
+               break;
+
+       case IIC_STATE_READ:
+               solo_dev->i2c_msg->buf[solo_dev->i2c_msg_ptr] =
+                       solo_reg_read(solo_dev, SOLO_IIC_RXD);
+               solo_dev->i2c_msg_ptr++;
+
+               ret = solo_i2c_handle_read(solo_dev);
+               break;
+
+       default:
+               solo_i2c_stop(solo_dev);
+       }
+
+       return ret;
+}
+
+static int solo_i2c_master_xfer(struct i2c_adapter *adap,
+                               struct i2c_msg msgs[], int num)
+{
+       struct solo6010_dev *solo_dev = adap->algo_data;
+       unsigned long timeout;
+       int ret;
+       int i;
+       DEFINE_WAIT(wait);
+
+       for (i = 0; i < SOLO_I2C_ADAPTERS; i++) {
+               if (&solo_dev->i2c_adap[i] == adap)
+                       break;
+       }
+
+       if (i == SOLO_I2C_ADAPTERS)
+               return num; // XXX Right return value for failure?
+
+       down(&solo_dev->i2c_sem);
+       solo_dev->i2c_id = i;
+       solo_dev->i2c_msg = msgs;
+       solo_dev->i2c_msg_num = num;
+       solo_dev->i2c_msg_ptr = 0;
+
+       solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0);
+       solo6010_irq_on(solo_dev, SOLO_IRQ_IIC);
+       solo_i2c_start(solo_dev);
+
+       timeout = HZ / 2;
+
+       for (;;) {
+               prepare_to_wait(&solo_dev->i2c_wait, &wait, TASK_INTERRUPTIBLE);
+
+               if (solo_dev->i2c_state == IIC_STATE_STOP)
+                       break;
+
+               timeout = schedule_timeout(timeout);
+               if (!timeout)
+                       break;
+
+               if (signal_pending(current))
+                       break;
+       }
+
+       finish_wait(&solo_dev->i2c_wait, &wait);
+       ret = num - solo_dev->i2c_msg_num;
+       solo_dev->i2c_state = IIC_STATE_IDLE;
+       solo_dev->i2c_id = -1;
+
+       up(&solo_dev->i2c_sem);
+
+       return ret;
+}
+
+static u32 solo_i2c_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm solo_i2c_algo = {
+       .master_xfer    = solo_i2c_master_xfer,
+       .functionality  = solo_i2c_functionality,
+};
+
+int solo_i2c_init(struct solo6010_dev *solo_dev)
+{
+       int i;
+       int ret;
+
+       solo_reg_write(solo_dev, SOLO_IIC_CFG,
+                      SOLO_IIC_PRESCALE(8) | SOLO_IIC_ENABLE);
+
+       solo_dev->i2c_id = -1;
+       solo_dev->i2c_state = IIC_STATE_IDLE;
+       init_waitqueue_head(&solo_dev->i2c_wait);
+       init_MUTEX(&solo_dev->i2c_sem);
+
+       for (i = 0; i < SOLO_I2C_ADAPTERS; i++) {
+               struct i2c_adapter *adap = &solo_dev->i2c_adap[i];
+
+               snprintf(adap->name, I2C_NAME_SIZE, "%s I2C %d",
+                        SOLO6010_NAME, i);
+               adap->algo = &solo_i2c_algo;
+               adap->algo_data = solo_dev;
+               adap->retries = 1;
+               adap->dev.parent = &solo_dev->pdev->dev;
+
+               if ((ret = i2c_add_adapter(adap))) {
+                       adap->algo_data = NULL;
+                       break;
+               }
+       }
+
+       if (ret) {
+               for (i = 0; i < SOLO_I2C_ADAPTERS; i++) {
+                       if (!solo_dev->i2c_adap[i].algo_data)
+                               break;
+                       i2c_del_adapter(&solo_dev->i2c_adap[i]);
+                       solo_dev->i2c_adap[i].algo_data = NULL;
+               }
+               return ret;
+       }
+
+       dev_info(&solo_dev->pdev->dev, "Enabled %d i2c adapters\n",
+                SOLO_I2C_ADAPTERS);
+
+       return 0;
+}
+
+void solo_i2c_exit(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       for (i = 0; i < SOLO_I2C_ADAPTERS; i++) {
+               if (!solo_dev->i2c_adap[i].algo_data)
+                       continue;
+               i2c_del_adapter(&solo_dev->i2c_adap[i]);
+               solo_dev->i2c_adap[i].algo_data = NULL;
+       }
+}
diff --git a/drivers/staging/solo6x10/solo6010-jpeg.h b/drivers/staging/solo6x10/solo6010-jpeg.h
new file mode 100644 (file)
index 0000000..fb0507e
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SOLO6010_JPEG_H
+#define __SOLO6010_JPEG_H
+
+static unsigned char jpeg_header[] = {
+       0xff, 0xd8, 0xff, 0xfe, 0x00, 0x0d, 0x42, 0x6c,
+       0x75, 0x65, 0x63, 0x68, 0x65, 0x72, 0x72, 0x79,
+       0x20, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x20, 0x16,
+       0x18, 0x1c, 0x18, 0x14, 0x20, 0x1c, 0x1a, 0x1c,
+       0x24, 0x22, 0x20, 0x26, 0x30, 0x50, 0x34, 0x30,
+       0x2c, 0x2c, 0x30, 0x62, 0x46, 0x4a, 0x3a, 0x50,
+       0x74, 0x66, 0x7a, 0x78, 0x72, 0x66, 0x70, 0x6e,
+       0x80, 0x90, 0xb8, 0x9c, 0x80, 0x88, 0xae, 0x8a,
+       0x6e, 0x70, 0xa0, 0xda, 0xa2, 0xae, 0xbe, 0xc4,
+       0xce, 0xd0, 0xce, 0x7c, 0x9a, 0xe2, 0xf2, 0xe0,
+       0xc8, 0xf0, 0xb8, 0xca, 0xce, 0xc6, 0xff, 0xdb,
+       0x00, 0x43, 0x01, 0x22, 0x24, 0x24, 0x30, 0x2a,
+       0x30, 0x5e, 0x34, 0x34, 0x5e, 0xc6, 0x84, 0x70,
+       0x84, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+       0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+       0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+       0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+       0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+       0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+       0xc6, 0xc6, 0xc6, 0xff, 0xc4, 0x01, 0xa2, 0x00,
+       0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+       0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01,
+       0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
+       0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03,
+       0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41,
+       0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14,
+       0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1,
+       0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62,
+       0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19,
+       0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34,
+       0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
+       0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54,
+       0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
+       0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74,
+       0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84,
+       0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
+       0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2,
+       0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
+       0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
+       0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
+       0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+       0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5,
+       0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
+       0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x01,
+       0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+       0x08, 0x09, 0x0a, 0x0b, 0x11, 0x00, 0x02, 0x01,
+       0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
+       0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02,
+       0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12,
+       0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32,
+       0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1,
+       0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72,
+       0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1,
+       0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29,
+       0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43,
+       0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53,
+       0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63,
+       0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73,
+       0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82,
+       0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,
+       0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+       0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
+       0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+       0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
+       0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5,
+       0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4,
+       0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3,
+       0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff,
+       0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x02, 0xc0,
+       0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03,
+       0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01,
+       0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
+};
+
+/* This is the byte marker for the start of SOF0: 0xffc0 marker */
+#define SOF0_START     575
+
+#endif /* __SOLO6010_JPEG_H */
diff --git a/drivers/staging/solo6x10/solo6010-offsets.h b/drivers/staging/solo6x10/solo6010-offsets.h
new file mode 100644 (file)
index 0000000..2431de9
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SOLO6010_OFFSETS_H
+#define __SOLO6010_OFFSETS_H
+
+/* Offsets and sizes of the external address */
+#define SOLO_DISP_EXT_ADDR(__solo)             0x00000000
+#define SOLO_DISP_EXT_SIZE                     0x00480000
+
+#define SOLO_DEC2LIVE_EXT_ADDR(__solo) \
+               (SOLO_DISP_EXT_ADDR(__solo) + SOLO_DISP_EXT_SIZE)
+#define SOLO_DEC2LIVE_EXT_SIZE                 0x00240000
+
+#define SOLO_OSG_EXT_ADDR(__solo) \
+               (SOLO_DEC2LIVE_EXT_ADDR(__solo) + SOLO_DEC2LIVE_EXT_SIZE)
+#define SOLO_OSG_EXT_SIZE                      0x00120000
+
+#define SOLO_EOSD_EXT_ADDR(__solo) \
+               (SOLO_OSG_EXT_ADDR(__solo) + SOLO_OSG_EXT_SIZE)
+#define SOLO_EOSD_EXT_SIZE                     0x00010000
+
+#define SOLO_MOTION_EXT_ADDR(__solo) \
+               (SOLO_EOSD_EXT_ADDR(__solo) + \
+                (SOLO_EOSD_EXT_SIZE * __solo->nr_chans))
+#define SOLO_MOTION_EXT_SIZE                   0x00080000
+
+#define SOLO_G723_EXT_ADDR(__solo) \
+               (SOLO_MOTION_EXT_ADDR(__solo) + SOLO_MOTION_EXT_SIZE)
+#define SOLO_G723_EXT_SIZE                     0x00010000
+
+#define SOLO_CAP_EXT_ADDR(__solo) \
+               (SOLO_G723_EXT_ADDR(__solo) + SOLO_G723_EXT_SIZE)
+#define SOLO_CAP_EXT_MAX_PAGE                  (18 + 15)
+#define SOLO_CAP_EXT_SIZE                      (SOLO_CAP_EXT_MAX_PAGE * 65536)
+
+/* This +1 is very important -- Why?! -- BenC */
+#define SOLO_EREF_EXT_ADDR(__solo) \
+               (SOLO_CAP_EXT_ADDR(__solo) + \
+                (SOLO_CAP_EXT_SIZE * (__solo->nr_chans + 1)))
+#define SOLO_EREF_EXT_SIZE                     0x00140000
+
+#define SOLO_MP4E_EXT_ADDR(__solo) \
+               (SOLO_EREF_EXT_ADDR(__solo) + \
+                (SOLO_EREF_EXT_SIZE * __solo->nr_chans))
+#define SOLO_MP4E_EXT_SIZE(__solo)             (0x00080000 * __solo->nr_chans)
+
+#define SOLO_DREF_EXT_ADDR(__solo) \
+               (SOLO_MP4E_EXT_ADDR(__solo) + SOLO_MP4E_EXT_SIZE(__solo))
+#define SOLO_DREF_EXT_SIZE                     0x00140000
+
+#define SOLO_MP4D_EXT_ADDR(__solo) \
+               (SOLO_DREF_EXT_ADDR(__solo) + \
+                (SOLO_DREF_EXT_SIZE * __solo->nr_chans))
+#define SOLO_MP4D_EXT_SIZE                     0x00080000
+
+#define SOLO_JPEG_EXT_ADDR(__solo) \
+               (SOLO_MP4D_EXT_ADDR(__solo) + \
+                (SOLO_MP4D_EXT_SIZE * __solo->nr_chans))
+#define SOLO_JPEG_EXT_SIZE(__solo)             (0x00080000 * __solo->nr_chans)
+
+#endif /* __SOLO6010_OFFSETS_H */
diff --git a/drivers/staging/solo6x10/solo6010-osd-font.h b/drivers/staging/solo6x10/solo6010-osd-font.h
new file mode 100644 (file)
index 0000000..d6f565b
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SOLO6010_OSD_FONT_H
+#define __SOLO6010_OSD_FONT_H
+
+static const unsigned int solo_osd_font[] = {
+       0x00000000, 0x0000c0c8, 0xccfefe0c, 0x08000000,
+       0x00000000, 0x10103838, 0x7c7cfefe, 0x00000000, // 0
+       0x00000000, 0xfefe7c7c, 0x38381010, 0x10000000,
+       0x00000000, 0x7c82fefe, 0xfefefe7c, 0x00000000,
+       0x00000000, 0x00001038, 0x10000000, 0x00000000,
+       0x00000000, 0x0010387c, 0xfe7c3810, 0x00000000,
+       0x00000000, 0x00384444, 0x44380000, 0x00000000,
+       0x00000000, 0x38448282, 0x82443800, 0x00000000,
+       0x00000000, 0x007c7c7c, 0x7c7c0000, 0x00000000,
+       0x00000000, 0x6c6c6c6c, 0x6c6c6c6c, 0x00000000,
+       0x00000000, 0x061e7efe, 0xfe7e1e06, 0x00000000,
+       0x00000000, 0xc0f0fcfe, 0xfefcf0c0, 0x00000000,
+       0x00000000, 0xc6cedefe, 0xfedecec6, 0x00000000,
+       0x00000000, 0xc6e6f6fe, 0xfef6e6c6, 0x00000000,
+       0x00000000, 0x12367efe, 0xfe7e3612, 0x00000000,
+       0x00000000, 0x90d8fcfe, 0xfefcd890, 0x00000000,
+       0x00000038, 0x7cc692ba, 0x92c67c38, 0x00000000,
+       0x00000038, 0x7cc6aa92, 0xaac67c38, 0x00000000,
+       0x00000038, 0x7830107c, 0xbaa8680c, 0x00000000,
+       0x00000038, 0x3c18127c, 0xb8382c60, 0x00000000,
+       0x00000044, 0xaa6c8254, 0x38eec67c, 0x00000000,
+       0x00000082, 0x44288244, 0x38c6827c, 0x00000000,
+       0x00000038, 0x444444fe, 0xfeeec6fe, 0x00000000,
+       0x00000018, 0x78187818, 0x3c7e7e3c, 0x00000000,
+       0x00000000, 0x3854929a, 0x82443800, 0x00000000,
+       0x00000000, 0x00c0c8cc, 0xfefe0c08, 0x00000000,
+       0x0000e0a0, 0xe040e00e, 0x8a0ea40e, 0x00000000,
+       0x0000e0a0, 0xe040e00e, 0x0a8e440e, 0x00000000,
+       0x0000007c, 0x82829292, 0x929282fe, 0x00000000,
+       0x000000f8, 0xfc046494, 0x946404fc, 0x00000000,
+       0x0000003f, 0x7f404c52, 0x524c407f, 0x00000000,
+       0x0000007c, 0x82ba82ba, 0x82ba82fe, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x183c3c3c, 0x18180018, 0x18000000, // 32   !
+       0x00000066, 0x66240000, 0x00000000, 0x00000000,
+       0x00000000, 0x6c6cfe6c, 0x6c6cfe6c, 0x6c000000, // 34 " #
+       0x00001010, 0x7cd6d616, 0x7cd0d6d6, 0x7c101000,
+       0x00000000, 0x0086c660, 0x30180cc6, 0xc2000000, // 36 $ %
+       0x00000000, 0x386c6c38, 0xdc766666, 0xdc000000,
+       0x0000000c, 0x0c0c0600, 0x00000000, 0x00000000, // 38 & '
+       0x00000000, 0x30180c0c, 0x0c0c0c18, 0x30000000,
+       0x00000000, 0x0c183030, 0x30303018, 0x0c000000, // 40 ( )
+       0x00000000, 0x0000663c, 0xff3c6600, 0x00000000,
+       0x00000000, 0x00001818, 0x7e181800, 0x00000000, // 42 * +
+       0x00000000, 0x00000000, 0x00000e0e, 0x0c060000,
+       0x00000000, 0x00000000, 0x7e000000, 0x00000000, // 44 , -
+       0x00000000, 0x00000000, 0x00000006, 0x06000000,
+       0x00000000, 0x80c06030, 0x180c0602, 0x00000000, // 46 . /
+       0x0000007c, 0xc6e6f6de, 0xcec6c67c, 0x00000000,
+       0x00000030, 0x383c3030, 0x303030fc, 0x00000000, // 48 0 1
+       0x0000007c, 0xc6c06030, 0x180cc6fe, 0x00000000,
+       0x0000007c, 0xc6c0c07c, 0xc0c0c67c, 0x00000000, // 50 2 3
+       0x00000060, 0x70786c66, 0xfe6060f0, 0x00000000,
+       0x000000fe, 0x0606067e, 0xc0c0c67c, 0x00000000, // 52 4 5
+       0x00000038, 0x0c06067e, 0xc6c6c67c, 0x00000000,
+       0x000000fe, 0xc6c06030, 0x18181818, 0x00000000, // 54 6 7
+       0x0000007c, 0xc6c6c67c, 0xc6c6c67c, 0x00000000,
+       0x0000007c, 0xc6c6c6fc, 0xc0c06038, 0x00000000, // 56 8 9
+       0x00000000, 0x18180000, 0x00181800, 0x00000000,
+       0x00000000, 0x18180000, 0x0018180c, 0x00000000, // 58 : ;
+       0x00000060, 0x30180c06, 0x0c183060, 0x00000000,
+       0x00000000, 0x007e0000, 0x007e0000, 0x00000000,
+       0x00000006, 0x0c183060, 0x30180c06, 0x00000000,
+       0x0000007c, 0xc6c66030, 0x30003030, 0x00000000,
+       0x0000007c, 0xc6f6d6d6, 0x7606067c, 0x00000000,
+       0x00000010, 0x386cc6c6, 0xfec6c6c6, 0x00000000, // 64 @ A
+       0x0000007e, 0xc6c6c67e, 0xc6c6c67e, 0x00000000,
+       0x00000078, 0xcc060606, 0x0606cc78, 0x00000000, // 66
+       0x0000003e, 0x66c6c6c6, 0xc6c6663e, 0x00000000,
+       0x000000fe, 0x0606063e, 0x060606fe, 0x00000000, // 68
+       0x000000fe, 0x0606063e, 0x06060606, 0x00000000,
+       0x00000078, 0xcc060606, 0xf6c6ccb8, 0x00000000, // 70
+       0x000000c6, 0xc6c6c6fe, 0xc6c6c6c6, 0x00000000,
+       0x0000003c, 0x18181818, 0x1818183c, 0x00000000, // 72
+       0x00000060, 0x60606060, 0x6066663c, 0x00000000,
+       0x000000c6, 0xc666361e, 0x3666c6c6, 0x00000000, // 74
+       0x00000006, 0x06060606, 0x060606fe, 0x00000000,
+       0x000000c6, 0xeefed6c6, 0xc6c6c6c6, 0x00000000, // 76
+       0x000000c6, 0xcedefef6, 0xe6c6c6c6, 0x00000000,
+       0x00000038, 0x6cc6c6c6, 0xc6c66c38, 0x00000000, // 78
+       0x0000007e, 0xc6c6c67e, 0x06060606, 0x00000000,
+       0x00000038, 0x6cc6c6c6, 0xc6d67c38, 0x60000000, // 80
+       0x0000007e, 0xc6c6c67e, 0x66c6c6c6, 0x00000000,
+       0x0000007c, 0xc6c60c38, 0x60c6c67c, 0x00000000, // 82
+       0x0000007e, 0x18181818, 0x18181818, 0x00000000,
+       0x000000c6, 0xc6c6c6c6, 0xc6c6c67c, 0x00000000, // 84
+       0x000000c6, 0xc6c6c6c6, 0xc66c3810, 0x00000000,
+       0x000000c6, 0xc6c6c6c6, 0xd6d6fe6c, 0x00000000, // 86
+       0x000000c6, 0xc6c66c38, 0x6cc6c6c6, 0x00000000,
+       0x00000066, 0x66666666, 0x3c181818, 0x00000000, // 88
+       0x000000fe, 0xc0603018, 0x0c0606fe, 0x00000000,
+       0x0000003c, 0x0c0c0c0c, 0x0c0c0c3c, 0x00000000, // 90
+       0x00000002, 0x060c1830, 0x60c08000, 0x00000000,
+       0x0000003c, 0x30303030, 0x3030303c, 0x00000000, // 92
+       0x00001038, 0x6cc60000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00fe0000,
+       0x00001818, 0x30000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00003c60, 0x7c66667c, 0x00000000,
+       0x0000000c, 0x0c0c7ccc, 0xcccccc7c, 0x00000000,
+       0x00000000, 0x00007cc6, 0x0606c67c, 0x00000000,
+       0x00000060, 0x60607c66, 0x6666667c, 0x00000000,
+       0x00000000, 0x00007cc6, 0xfe06c67c, 0x00000000,
+       0x00000078, 0x0c0c0c3e, 0x0c0c0c0c, 0x00000000,
+       0x00000000, 0x00007c66, 0x6666667c, 0x60603e00,
+       0x0000000c, 0x0c0c7ccc, 0xcccccccc, 0x00000000,
+       0x00000030, 0x30003830, 0x30303078, 0x00000000,
+       0x00000030, 0x30003c30, 0x30303030, 0x30301f00,
+       0x0000000c, 0x0c0ccc6c, 0x3c6ccccc, 0x00000000,
+       0x00000030, 0x30303030, 0x30303030, 0x00000000,
+       0x00000000, 0x000066fe, 0xd6d6d6d6, 0x00000000,
+       0x00000000, 0x000078cc, 0xcccccccc, 0x00000000,
+       0x00000000, 0x00007cc6, 0xc6c6c67c, 0x00000000,
+       0x00000000, 0x00007ccc, 0xcccccc7c, 0x0c0c0c00,
+       0x00000000, 0x00007c66, 0x6666667c, 0x60606000,
+       0x00000000, 0x000076dc, 0x0c0c0c0c, 0x00000000,
+       0x00000000, 0x00007cc6, 0x1c70c67c, 0x00000000,
+       0x00000000, 0x1818fe18, 0x18181870, 0x00000000,
+       0x00000000, 0x00006666, 0x6666663c, 0x00000000,
+       0x00000000, 0x0000c6c6, 0xc66c3810, 0x00000000,
+       0x00000000, 0x0000c6d6, 0xd6d6fe6c, 0x00000000,
+       0x00000000, 0x0000c66c, 0x38386cc6, 0x00000000,
+       0x00000000, 0x00006666, 0x6666667c, 0x60603e00,
+       0x00000000, 0x0000fe60, 0x30180cfe, 0x00000000,
+       0x00000070, 0x1818180e, 0x18181870, 0x00000000,
+       0x00000018, 0x18181800, 0x18181818, 0x00000000,
+       0x0000000e, 0x18181870, 0x1818180e, 0x00000000,
+       0x000000dc, 0x76000000, 0x00000000, 0x00000000,
+       0x00000000, 0x0010386c, 0xc6c6fe00, 0x00000000
+};
+
+#endif /* __SOLO6010_OSD_FONT_H */
diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c
new file mode 100644 (file)
index 0000000..1b81f06
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+
+#include "solo6010.h"
+
+// #define SOLO_TEST_P2M
+
+int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr,
+                void *sys_addr, u32 ext_addr, u32 size)
+{
+       dma_addr_t dma_addr;
+       int ret;
+
+       WARN_ON(!size);
+       WARN_ON(id >= SOLO_NR_P2M);
+       if (!size || id >= SOLO_NR_P2M)
+               return -EINVAL;
+
+       dma_addr = pci_map_single(solo_dev->pdev, sys_addr, size,
+                                 wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+
+       ret = solo_p2m_dma_t(solo_dev, id, wr, dma_addr, ext_addr, size);
+
+       pci_unmap_single(solo_dev->pdev, dma_addr, size,
+                        wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+
+       return ret;
+}
+
+int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr,
+                  dma_addr_t dma_addr, u32 ext_addr, u32 size)
+{
+       struct solo_p2m_dev *p2m_dev;
+       unsigned int timeout = 0;
+
+       WARN_ON(!size);
+       WARN_ON(id >= SOLO_NR_P2M);
+       if (!size || id >= SOLO_NR_P2M)
+               return -EINVAL;
+
+       p2m_dev = &solo_dev->p2m_dev[id];
+
+       down(&p2m_dev->sem);
+
+start_dma:
+       INIT_COMPLETION(p2m_dev->completion);
+       p2m_dev->error = 0;
+       solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), dma_addr);
+       solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), ext_addr);
+       solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id),
+                      SOLO_P2M_COPY_SIZE(size >> 2));
+       solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id),
+                      SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) |
+                      (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON);
+
+       timeout = wait_for_completion_timeout(&p2m_dev->completion, HZ);
+
+       solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0);
+
+       /* XXX Really looks to me like we will get stuck here if a
+        * real PCI P2M error occurs */
+       if (p2m_dev->error)
+               goto start_dma;
+
+       up(&p2m_dev->sem);
+
+       return (timeout == 0) ? -EAGAIN : 0;
+}
+
+#ifdef SOLO_TEST_P2M
+
+#define P2M_TEST_CHAR          0xbe
+
+static unsigned long long p2m_test(struct solo6010_dev *solo_dev, u8 id,
+                                  u32 base, int size)
+{
+       u8 *wr_buf;
+       u8 *rd_buf;
+       int i;
+       unsigned long long err_cnt = 0;
+
+       wr_buf = kmalloc(size, GFP_KERNEL);
+       if (!wr_buf) {
+               printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n");
+               return size;
+       }
+
+       rd_buf = kmalloc(size, GFP_KERNEL);
+       if (!rd_buf) {
+               printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n");
+               kfree(wr_buf);
+               return size;
+       }
+
+       memset(wr_buf, P2M_TEST_CHAR, size);
+       memset(rd_buf, P2M_TEST_CHAR + 1, size);
+
+       solo_p2m_dma(solo_dev, id, 1, wr_buf, base, size);
+       solo_p2m_dma(solo_dev, id, 0, rd_buf, base, size);
+
+       for (i = 0; i < size; i++)
+               if (wr_buf[i] != rd_buf[i])
+                       err_cnt++;
+
+       kfree(wr_buf);
+       kfree(rd_buf);
+
+       return err_cnt;
+}
+
+#define TEST_CHUNK_SIZE                (8 * 1024)
+
+static void run_p2m_test(struct solo6010_dev *solo_dev)
+{
+       unsigned long long errs = 0;
+       u32 size = SOLO_JPEG_EXT_ADDR(solo_dev) + SOLO_JPEG_EXT_SIZE(solo_dev);
+       int i, d;
+
+       printk(KERN_WARNING "%s: Testing %u bytes of external ram\n",
+              SOLO6010_NAME, size);
+
+       for (i = 0; i < size; i += TEST_CHUNK_SIZE)
+               for (d = 0; d < 4; d++)
+                       errs += p2m_test(solo_dev, d, i, TEST_CHUNK_SIZE);
+
+       printk(KERN_WARNING "%s: Found %llu errors during p2m test\n",
+              SOLO6010_NAME, errs);
+
+       return;
+}
+#else
+#define run_p2m_test(__solo)   do{}while(0)
+#endif
+
+void solo_p2m_isr(struct solo6010_dev *solo_dev, int id)
+{
+       solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_P2M(id));
+       complete(&solo_dev->p2m_dev[id].completion);
+}
+
+void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status)
+{
+       struct solo_p2m_dev *p2m_dev;
+       int i;
+
+       if (!(status & SOLO_PCI_ERR_P2M))
+               return;
+
+       for (i = 0; i < SOLO_NR_P2M; i++) {
+               p2m_dev = &solo_dev->p2m_dev[i];
+               p2m_dev->error = 1;
+               solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0);
+               complete(&p2m_dev->completion);
+       }
+}
+
+void solo_p2m_exit(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       for (i = 0; i < SOLO_NR_P2M; i++)
+               solo6010_irq_off(solo_dev, SOLO_IRQ_P2M(i));
+}
+
+int solo_p2m_init(struct solo6010_dev *solo_dev)
+{
+       struct solo_p2m_dev *p2m_dev;
+       int i;
+
+       for (i = 0; i < SOLO_NR_P2M; i++) {
+               p2m_dev = &solo_dev->p2m_dev[i];
+
+               init_MUTEX(&p2m_dev->sem);
+               init_completion(&p2m_dev->completion);
+
+               solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(i),
+                              __pa(p2m_dev->desc));
+
+               solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0);
+               solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i),
+                              SOLO_P2M_CSC_16BIT_565 |
+                              SOLO_P2M_DMA_INTERVAL(0) |
+                              SOLO_P2M_PCI_MASTER_MODE);
+               solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i));
+       }
+
+       run_p2m_test(solo_dev);
+
+       return 0;
+}
diff --git a/drivers/staging/solo6x10/solo6010-registers.h b/drivers/staging/solo6x10/solo6010-registers.h
new file mode 100644 (file)
index 0000000..d39d3c6
--- /dev/null
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SOLO6010_REGISTERS_H
+#define __SOLO6010_REGISTERS_H
+
+#include "solo6010-offsets.h"
+
+/* Global 6010 system configuration */
+#define SOLO_SYS_CFG                           0x0000
+#define   SOLO_SYS_CFG_FOUT_EN                 0x00000001
+#define   SOLO_SYS_CFG_PLL_BYPASS              0x00000002
+#define   SOLO_SYS_CFG_PLL_PWDN                        0x00000004
+#define   SOLO_SYS_CFG_OUTDIV(__n)             (((__n) & 0x003) << 3)
+#define   SOLO_SYS_CFG_FEEDBACKDIV(__n)                (((__n) & 0x1ff) << 5)
+#define   SOLO_SYS_CFG_INPUTDIV(__n)           (((__n) & 0x01f) << 14)
+#define   SOLO_SYS_CFG_CLOCK_DIV               0x00080000
+#define   SOLO_SYS_CFG_NCLK_DELAY(__n)         (((__n) & 0x003) << 24)
+#define   SOLO_SYS_CFG_PCLK_DELAY(__n)         (((__n) & 0x00f) << 26)
+#define   SOLO_SYS_CFG_SDRAM64BIT              0x40000000
+#define   SOLO_SYS_CFG_RESET                   0x80000000
+
+#define        SOLO_DMA_CTRL                           0x0004
+#define          SOLO_DMA_CTRL_REFRESH_CYCLE(n)        ((n)<<8)
+/* 0=16/32MB, 1=32/64MB, 2=64/128MB, 3=128/256MB */
+#define          SOLO_DMA_CTRL_SDRAM_SIZE(n)           ((n)<<6)
+#define          SOLO_DMA_CTRL_SDRAM_CLK_INVERT        (1<<5)
+#define          SOLO_DMA_CTRL_STROBE_SELECT           (1<<4)
+#define          SOLO_DMA_CTRL_READ_DATA_SELECT        (1<<3)
+#define          SOLO_DMA_CTRL_READ_CLK_SELECT         (1<<2)
+#define          SOLO_DMA_CTRL_LATENCY(n)              ((n)<<0)
+
+#define SOLO_SYS_VCLK                          0x000C
+#define          SOLO_VCLK_INVERT                      (1<<22)
+/* 0=sys_clk/4, 1=sys_clk/2, 2=clk_in/2 of system input */
+#define          SOLO_VCLK_SELECT(n)                   ((n)<<20)
+#define          SOLO_VCLK_VIN1415_DELAY(n)            ((n)<<14)
+#define          SOLO_VCLK_VIN1213_DELAY(n)            ((n)<<12)
+#define          SOLO_VCLK_VIN1011_DELAY(n)            ((n)<<10)
+#define          SOLO_VCLK_VIN0809_DELAY(n)            ((n)<<8)
+#define          SOLO_VCLK_VIN0607_DELAY(n)            ((n)<<6)
+#define          SOLO_VCLK_VIN0405_DELAY(n)            ((n)<<4)
+#define          SOLO_VCLK_VIN0203_DELAY(n)            ((n)<<2)
+#define          SOLO_VCLK_VIN0001_DELAY(n)            ((n)<<0)
+
+#define SOLO_IRQ_STAT                          0x0010
+#define SOLO_IRQ_ENABLE                                0x0014
+#define          SOLO_IRQ_P2M(n)                       (1<<((n)+17))
+#define          SOLO_IRQ_GPIO                         (1<<16)
+#define          SOLO_IRQ_VIDEO_LOSS                   (1<<15)
+#define          SOLO_IRQ_VIDEO_IN                     (1<<14)
+#define          SOLO_IRQ_MOTION                       (1<<13)
+#define          SOLO_IRQ_ATA_CMD                      (1<<12)
+#define          SOLO_IRQ_ATA_DIR                      (1<<11)
+#define          SOLO_IRQ_PCI_ERR                      (1<<10)
+#define          SOLO_IRQ_PS2_1                        (1<<9)
+#define          SOLO_IRQ_PS2_0                        (1<<8)
+#define          SOLO_IRQ_SPI                          (1<<7)
+#define          SOLO_IRQ_IIC                          (1<<6)
+#define          SOLO_IRQ_UART(n)                      (1<<((n) + 4))
+#define          SOLO_IRQ_G723                         (1<<3)
+#define          SOLO_IRQ_DECODER                      (1<<1)
+#define          SOLO_IRQ_ENCODER                      (1<<0)
+
+#define SOLO_CHIP_OPTION                       0x001C
+#define   SOLO_CHIP_ID_MASK                    0x00000007
+
+#define SOLO_EEPROM_CTRL                       0x0060
+#define          SOLO_EEPROM_ACCESS_EN                 (1<<7)
+#define          SOLO_EEPROM_CS                        (1<<3)
+#define          SOLO_EEPROM_CLK                       (1<<2)
+#define          SOLO_EEPROM_DO                        (1<<1)
+#define          SOLO_EEPROM_DI                        (1<<0)
+#define          SOLO_EEPROM_ENABLE                    (EEPROM_ACCESS_EN | EEPROM_CS)
+
+#define SOLO_PCI_ERR                           0x0070
+#define   SOLO_PCI_ERR_FATAL                   0x00000001
+#define   SOLO_PCI_ERR_PARITY                  0x00000002
+#define   SOLO_PCI_ERR_TARGET                  0x00000004
+#define   SOLO_PCI_ERR_TIMEOUT                 0x00000008
+#define   SOLO_PCI_ERR_P2M                     0x00000010
+#define   SOLO_PCI_ERR_ATA                     0x00000020
+#define   SOLO_PCI_ERR_P2M_DESC                        0x00000040
+#define   SOLO_PCI_ERR_FSM0(__s)               (((__s) >> 16) & 0x0f)
+#define   SOLO_PCI_ERR_FSM1(__s)               (((__s) >> 20) & 0x0f)
+#define   SOLO_PCI_ERR_FSM2(__s)               (((__s) >> 24) & 0x1f)
+
+#define SOLO_P2M_BASE                          0x0080
+
+#define SOLO_P2M_CONFIG(n)                     (0x0080 + ((n)*0x20))
+#define          SOLO_P2M_DMA_INTERVAL(n)              ((n)<<6)/* N*32 clocks */
+#define          SOLO_P2M_CSC_BYTE_REORDER             (1<<5)  /* BGR -> RGB */
+/* 0:r=[14:10] g=[9:5] b=[4:0], 1:r=[15:11] g=[10:5] b=[4:0] */
+#define          SOLO_P2M_CSC_16BIT_565                (1<<4)
+#define          SOLO_P2M_UV_SWAP                      (1<<3)
+#define          SOLO_P2M_PCI_MASTER_MODE              (1<<2)
+#define          SOLO_P2M_DESC_INTR_OPT                (1<<1)  /* 1:Empty, 0:Each */
+#define          SOLO_P2M_DESC_MODE                    (1<<0)
+
+#define SOLO_P2M_DES_ADR(n)                    (0x0084 + ((n)*0x20))
+
+#define SOLO_P2M_DESC_ID(n)                    (0x0088 + ((n)*0x20))
+#define          SOLO_P2M_UPDATE_ID(n)                 ((n)<<0)
+
+#define SOLO_P2M_STATUS(n)                     (0x008C + ((n)*0x20))
+#define          SOLO_P2M_COMMAND_DONE                 (1<<8)
+#define          SOLO_P2M_CURRENT_ID(stat)             (0xff & (stat))
+
+#define SOLO_P2M_CONTROL(n)                    (0x0090 + ((n)*0x20))
+#define          SOLO_P2M_PCI_INC(n)                   ((n)<<20)
+#define          SOLO_P2M_REPEAT(n)                    ((n)<<10)
+/* 0:512, 1:256, 2:128, 3:64, 4:32, 5:128(2page) */
+#define          SOLO_P2M_BURST_SIZE(n)                ((n)<<7)
+#define            SOLO_P2M_BURST_512                  0
+#define            SOLO_P2M_BURST_256                  1
+#define            SOLO_P2M_BURST_128                  2
+#define            SOLO_P2M_BURST_64                   3
+#define            SOLO_P2M_BURST_32                   4
+#define          SOLO_P2M_CSC_16BIT                    (1<<6)  /* 0:24bit, 1:16bit */
+/* 0:Y[0]<-0(OFF), 1:Y[0]<-1(ON), 2:Y[0]<-G[0], 3:Y[0]<-Bit[15] */
+#define          SOLO_P2M_ALPHA_MODE(n)                ((n)<<4)
+#define          SOLO_P2M_CSC_ON                       (1<<3)
+#define          SOLO_P2M_INTERRUPT_REQ                (1<<2)
+#define          SOLO_P2M_WRITE                        (1<<1)
+#define          SOLO_P2M_TRANS_ON                     (1<<0)
+
+#define SOLO_P2M_EXT_CFG(n)                    (0x0094 + ((n)*0x20))
+#define          SOLO_P2M_EXT_INC(n)                   ((n)<<20)
+#define          SOLO_P2M_COPY_SIZE(n)                 ((n)<<0)
+
+#define SOLO_P2M_TAR_ADR(n)                    (0x0098 + ((n)*0x20))
+
+#define SOLO_P2M_EXT_ADR(n)                    (0x009C + ((n)*0x20))
+
+#define SOLO_P2M_BUFFER(i)                     (0x2000 + ((i)*4))
+
+#define SOLO_VI_CH_SWITCH_0                    0x0100
+#define SOLO_VI_CH_SWITCH_1                    0x0104
+#define SOLO_VI_CH_SWITCH_2                    0x0108
+
+#define        SOLO_VI_CH_ENA                          0x010C
+#define        SOLO_VI_CH_FORMAT                       0x0110
+#define          SOLO_VI_FD_SEL_MASK(n)                ((n)<<16)
+#define          SOLO_VI_PROG_MASK(n)                  ((n)<<0)
+
+#define SOLO_VI_FMT_CFG                                0x0114
+#define          SOLO_VI_FMT_CHECK_VCOUNT              (1<<31)
+#define          SOLO_VI_FMT_CHECK_HCOUNT              (1<<30)
+#define   SOLO_VI_FMT_TEST_SIGNAL              (1<<28)
+
+#define        SOLO_VI_PAGE_SW                         0x0118
+#define          SOLO_FI_INV_DISP_LIVE(n)              ((n)<<8)
+#define          SOLO_FI_INV_DISP_OUT(n)               ((n)<<7)
+#define          SOLO_DISP_SYNC_FI(n)                  ((n)<<6)
+#define          SOLO_PIP_PAGE_ADD(n)                  ((n)<<3)
+#define          SOLO_NORMAL_PAGE_ADD(n)               ((n)<<0)
+
+#define        SOLO_VI_ACT_I_P                         0x011C
+#define        SOLO_VI_ACT_I_S                         0x0120
+#define        SOLO_VI_ACT_P                           0x0124
+#define          SOLO_VI_FI_INVERT                     (1<<31)
+#define          SOLO_VI_H_START(n)                    ((n)<<21)
+#define          SOLO_VI_V_START(n)                    ((n)<<11)
+#define          SOLO_VI_V_STOP(n)                     ((n)<<0)
+
+#define SOLO_VI_STATUS0                                0x0128
+#define   SOLO_VI_STATUS0_PAGE(__n)            ((__n) & 0x07)
+#define SOLO_VI_STATUS1                                0x012C
+
+/* XXX: Might be better off in kernel level disp.h */
+#define DISP_PAGE(stat)                                ((stat) & 0x07)
+
+#define SOLO_VI_PB_CONFIG                      0x0130
+#define          SOLO_VI_PB_USER_MODE                  (1<<1)
+#define          SOLO_VI_PB_PAL                        (1<<0)
+#define SOLO_VI_PB_RANGE_HV                    0x0134
+#define          SOLO_VI_PB_HSIZE(h)                   ((h)<<12)
+#define          SOLO_VI_PB_VSIZE(v)                   ((v)<<0)
+#define SOLO_VI_PB_ACT_H                       0x0138
+#define          SOLO_VI_PB_HSTART(n)                  ((n)<<12)
+#define          SOLO_VI_PB_HSTOP(n)                   ((n)<<0)
+#define SOLO_VI_PB_ACT_V                       0x013C
+#define          SOLO_VI_PB_VSTART(n)                  ((n)<<12)
+#define          SOLO_VI_PB_VSTOP(n)                   ((n)<<0)
+
+#define        SOLO_VI_MOSAIC(ch)                      (0x0140 + ((ch)*4))
+#define          SOLO_VI_MOSAIC_SX(x)                  ((x)<<24)
+#define          SOLO_VI_MOSAIC_EX(x)                  ((x)<<16)
+#define          SOLO_VI_MOSAIC_SY(x)                  ((x)<<8)
+#define          SOLO_VI_MOSAIC_EY(x)                  ((x)<<0)
+
+#define        SOLO_VI_WIN_CTRL0(ch)                   (0x0180 + ((ch)*4))
+#define        SOLO_VI_WIN_CTRL1(ch)                   (0x01C0 + ((ch)*4))
+
+#define          SOLO_VI_WIN_CHANNEL(n)                ((n)<<28)
+
+#define          SOLO_VI_WIN_PIP(n)                    ((n)<<27)
+#define          SOLO_VI_WIN_SCALE(n)                  ((n)<<24)
+
+#define          SOLO_VI_WIN_SX(x)                     ((x)<<12)
+#define          SOLO_VI_WIN_EX(x)                     ((x)<<0)
+
+#define          SOLO_VI_WIN_SY(x)                     ((x)<<12)
+#define          SOLO_VI_WIN_EY(x)                     ((x)<<0)
+
+#define        SOLO_VI_WIN_ON(ch)                      (0x0200 + ((ch)*4))
+
+#define SOLO_VI_WIN_SW                         0x0240
+#define SOLO_VI_WIN_LIVE_AUTO_MUTE             0x0244
+
+#define        SOLO_VI_MOT_ADR                         0x0260
+#define          SOLO_VI_MOTION_EN(mask)               ((mask)<<16)
+#define        SOLO_VI_MOT_CTRL                        0x0264
+#define          SOLO_VI_MOTION_FRAME_COUNT(n)         ((n)<<24)
+#define          SOLO_VI_MOTION_SAMPLE_LENGTH(n)       ((n)<<16)
+#define          SOLO_VI_MOTION_INTR_START_STOP        (1<<15)
+#define          SOLO_VI_MOTION_FREEZE_DATA            (1<<14)
+#define          SOLO_VI_MOTION_SAMPLE_COUNT(n)        ((n)<<0)
+#define SOLO_VI_MOT_CLEAR                      0x0268
+#define SOLO_VI_MOT_STATUS                     0x026C
+#define          SOLO_VI_MOTION_CNT(n)                 ((n)<<0)
+#define SOLO_VI_MOTION_BORDER                  0x0270
+#define SOLO_VI_MOTION_BAR                     0x0274
+#define          SOLO_VI_MOTION_Y_SET                  (1<<29)
+#define          SOLO_VI_MOTION_Y_ADD                  (1<<28)
+#define          SOLO_VI_MOTION_CB_SET                 (1<<27)
+#define          SOLO_VI_MOTION_CB_ADD                 (1<<26)
+#define          SOLO_VI_MOTION_CR_SET                 (1<<25)
+#define          SOLO_VI_MOTION_CR_ADD                 (1<<24)
+#define          SOLO_VI_MOTION_Y_VALUE(v)             ((v)<<16)
+#define          SOLO_VI_MOTION_CB_VALUE(v)            ((v)<<8)
+#define          SOLO_VI_MOTION_CR_VALUE(v)            ((v)<<0)
+
+#define        SOLO_VO_FMT_ENC                         0x0300
+#define          SOLO_VO_SCAN_MODE_PROGRESSIVE         (1<<31)
+#define          SOLO_VO_FMT_TYPE_PAL                  (1<<30)
+#define   SOLO_VO_FMT_TYPE_NTSC                        0
+#define          SOLO_VO_USER_SET                      (1<<29)
+
+#define          SOLO_VO_FI_CHANGE                     (1<<20)
+#define          SOLO_VO_USER_COLOR_SET_VSYNC          (1<<19)
+#define          SOLO_VO_USER_COLOR_SET_HSYNC          (1<<18)
+#define          SOLO_VO_USER_COLOR_SET_NAV            (1<<17)
+#define          SOLO_VO_USER_COLOR_SET_NAH            (1<<16)
+#define          SOLO_VO_NA_COLOR_Y(Y)                 ((Y)<<8)
+#define          SOLO_VO_NA_COLOR_CB(CB)               (((CB)/16)<<4)
+#define          SOLO_VO_NA_COLOR_CR(CR)               (((CR)/16)<<0)
+
+#define        SOLO_VO_ACT_H                           0x0304
+#define          SOLO_VO_H_BLANK(n)                    ((n)<<22)
+#define          SOLO_VO_H_START(n)                    ((n)<<11)
+#define          SOLO_VO_H_STOP(n)                     ((n)<<0)
+
+#define        SOLO_VO_ACT_V                           0x0308
+#define          SOLO_VO_V_BLANK(n)                    ((n)<<22)
+#define          SOLO_VO_V_START(n)                    ((n)<<11)
+#define          SOLO_VO_V_STOP(n)                     ((n)<<0)
+
+#define        SOLO_VO_RANGE_HV                        0x030C
+#define          SOLO_VO_SYNC_INVERT                   (1<<24)
+#define          SOLO_VO_HSYNC_INVERT                  (1<<23)
+#define          SOLO_VO_VSYNC_INVERT                  (1<<22)
+#define          SOLO_VO_H_LEN(n)                      ((n)<<11)
+#define          SOLO_VO_V_LEN(n)                      ((n)<<0)
+
+#define        SOLO_VO_DISP_CTRL                       0x0310
+#define          SOLO_VO_DISP_ON                       (1<<31)
+#define          SOLO_VO_DISP_ERASE_COUNT(n)           ((n&0xf)<<24)
+#define          SOLO_VO_DISP_DOUBLE_SCAN              (1<<22)
+#define          SOLO_VO_DISP_SINGLE_PAGE              (1<<21)
+#define          SOLO_VO_DISP_BASE(n)                  (((n)>>16) & 0xffff)
+
+#define SOLO_VO_DISP_ERASE                     0x0314
+#define          SOLO_VO_DISP_ERASE_ON                 (1<<0)
+
+#define        SOLO_VO_ZOOM_CTRL                       0x0318
+#define          SOLO_VO_ZOOM_VER_ON                   (1<<24)
+#define          SOLO_VO_ZOOM_HOR_ON                   (1<<23)
+#define          SOLO_VO_ZOOM_V_COMP                   (1<<22)
+#define          SOLO_VO_ZOOM_SX(h)                    (((h)/2)<<11)
+#define          SOLO_VO_ZOOM_SY(v)                    (((v)/2)<<0)
+
+#define SOLO_VO_FREEZE_CTRL                    0x031C
+#define          SOLO_VO_FREEZE_ON                     (1<<1)
+#define          SOLO_VO_FREEZE_INTERPOLATION          (1<<0)
+
+#define        SOLO_VO_BKG_COLOR                       0x0320
+#define          SOLO_BG_Y(y)                          ((y)<<16)
+#define          SOLO_BG_U(u)                          ((u)<<8)
+#define          SOLO_BG_V(v)                          ((v)<<0)
+
+#define        SOLO_VO_DEINTERLACE                     0x0324
+#define          SOLO_VO_DEINTERLACE_THRESHOLD(n)      ((n)<<8)
+#define          SOLO_VO_DEINTERLACE_EDGE_VALUE(n)     ((n)<<0)
+
+#define SOLO_VO_BORDER_LINE_COLOR              0x0330
+#define SOLO_VO_BORDER_FILL_COLOR              0x0334
+#define SOLO_VO_BORDER_LINE_MASK               0x0338
+#define SOLO_VO_BORDER_FILL_MASK               0x033c
+
+#define SOLO_VO_BORDER_X(n)                    (0x0340+((n)*4))
+#define SOLO_VO_BORDER_Y(n)                    (0x0354+((n)*4))
+
+#define SOLO_VO_CELL_EXT_SET                   0x0368
+#define SOLO_VO_CELL_EXT_START                 0x036c
+#define SOLO_VO_CELL_EXT_STOP                  0x0370
+
+#define SOLO_VO_CELL_EXT_SET2                  0x0374
+#define SOLO_VO_CELL_EXT_START2                        0x0378
+#define SOLO_VO_CELL_EXT_STOP2                 0x037c
+
+#define SOLO_VO_RECTANGLE_CTRL(n)              (0x0368+((n)*12))
+#define SOLO_VO_RECTANGLE_START(n)             (0x036c+((n)*12))
+#define SOLO_VO_RECTANGLE_STOP(n)              (0x0370+((n)*12))
+
+#define SOLO_VO_CURSOR_POS                     (0x0380)
+#define SOLO_VO_CURSOR_CLR                     (0x0384)
+#define SOLO_VO_CURSOR_CLR2                    (0x0388)
+#define SOLO_VO_CURSOR_MASK(id)                        (0x0390+((id)*4))
+
+#define SOLO_VO_EXPANSION(id)                  (0x0250+((id)*4))
+
+#define        SOLO_OSG_CONFIG                         0x03E0
+#define          SOLO_VO_OSG_ON                        (1<<31)
+#define          SOLO_VO_OSG_COLOR_MUTE                (1<<28)
+#define          SOLO_VO_OSG_ALPHA_RATE(n)             ((n)<<22)
+#define          SOLO_VO_OSG_ALPHA_BG_RATE(n)          ((n)<<16)
+#define          SOLO_VO_OSG_BASE(offset)              (((offset)>>16)&0xffff)
+
+#define SOLO_OSG_ERASE                         0x03E4
+#define          SOLO_OSG_ERASE_ON                     (0x80)
+#define          SOLO_OSG_ERASE_OFF                    (0x00)
+
+#define SOLO_VO_OSG_BLINK                      0x03E8
+#define          SOLO_VO_OSG_BLINK_ON                  (1<<1)
+#define          SOLO_VO_OSG_BLINK_INTREVAL18          (1<<0)
+
+#define SOLO_CAP_BASE                          0x0400
+#define          SOLO_CAP_MAX_PAGE(n)                  ((n)<<16)
+#define          SOLO_CAP_BASE_ADDR(n)                 ((n)<<0)
+#define SOLO_CAP_BTW                           0x0404
+#define          SOLO_CAP_PROG_BANDWIDTH(n)            ((n)<<8)
+#define          SOLO_CAP_MAX_BANDWIDTH(n)             ((n)<<0)
+
+#define SOLO_DIM_SCALE1                                0x0408
+#define SOLO_DIM_SCALE2                                0x040C
+#define SOLO_DIM_SCALE3                                0x0410
+#define SOLO_DIM_SCALE4                                0x0414
+#define SOLO_DIM_SCALE5                                0x0418
+#define          SOLO_DIM_V_MB_NUM_FRAME(n)            ((n)<<16)
+#define          SOLO_DIM_V_MB_NUM_FIELD(n)            ((n)<<8)
+#define          SOLO_DIM_H_MB_NUM(n)                  ((n)<<0)
+
+#define SOLO_DIM_PROG                          0x041C
+#define SOLO_CAP_STATUS                                0x0420
+
+#define SOLO_CAP_CH_SCALE(ch)                  (0x0440+((ch)*4))
+#define SOLO_CAP_CH_COMP_ENA_E(ch)             (0x0480+((ch)*4))
+#define SOLO_CAP_CH_INTV(ch)                   (0x04C0+((ch)*4))
+#define SOLO_CAP_CH_INTV_E(ch)                 (0x0500+((ch)*4))
+
+
+#define SOLO_VE_CFG0                           0x0610
+#define          SOLO_VE_TWO_PAGE_MODE                 (1<<31)
+#define          SOLO_VE_INTR_CTRL(n)                  ((n)<<24)
+#define          SOLO_VE_BLOCK_SIZE(n)                 ((n)<<16)
+#define          SOLO_VE_BLOCK_BASE(n)                 ((n)<<0)
+
+#define SOLO_VE_CFG1                           0x0614
+#define          SOLO_VE_BYTE_ALIGN(n)                 ((n)<<24)
+#define          SOLO_VE_INSERT_INDEX                  (1<<18)
+#define          SOLO_VE_MOTION_MODE(n)                ((n)<<16)
+#define          SOLO_VE_MOTION_BASE(n)                ((n)<<0)
+
+#define SOLO_VE_WMRK_POLY                      0x061C
+#define SOLO_VE_VMRK_INIT_KEY                  0x0620
+#define SOLO_VE_WMRK_STRL                      0x0624
+#define SOLO_VE_ENCRYP_POLY                    0x0628
+#define SOLO_VE_ENCRYP_INIT                    0x062C
+#define SOLO_VE_ATTR                           0x0630
+#define          SOLO_VE_LITTLE_ENDIAN                 (1<<31)
+#define          SOLO_COMP_ATTR_RN                     (1<<30)
+#define          SOLO_COMP_ATTR_FCODE(n)               ((n)<<27)
+#define          SOLO_COMP_TIME_INC(n)                 ((n)<<25)
+#define          SOLO_COMP_TIME_WIDTH(n)               ((n)<<21)
+#define          SOLO_DCT_INTERVAL(n)                  ((n)<<16)
+
+#define SOLO_VE_STATE(n)                       (0x0640+((n)*4))
+struct videnc_status {
+       union {
+               u32 status0;
+               struct {
+                       u32 mp4_enc_code_size:20, sad_motion:1, vid_motion:1,
+                           vop_type:2, video_channel:5, source_field_idx:1,
+                           interlace:1, progressive:1;
+               } status0_st;
+       };
+       union {
+               u32 status1;
+               struct {
+                       u32 vsize:8, hsize:8, last_queue:4, foo1:8, scale:4;
+               } status1_st;
+       };
+       union {
+               u32 status4;
+               struct {
+                       u32 jpeg_code_size:20, interval:10, foo1:2;
+               } status4_st;
+       };
+       union {
+               u32 status9;
+               struct {
+                       u32 channel:5, foo1:27;
+               } status9_st;
+       };
+       union {
+               u32 status10;
+               struct {
+                       u32 mp4_code_size:20, foo:12;
+               } status10_st;
+       };
+       union {
+               u32 status11;
+               struct {
+                       u32 last_queue:8, foo1:24;
+               } status11_st;
+       };
+};
+
+#define SOLO_VE_JPEG_QP_TBL                    0x0670
+#define SOLO_VE_JPEG_QP_CH_L                   0x0674
+#define SOLO_VE_JPEG_QP_CH_H                   0x0678
+#define SOLO_VE_JPEG_CFG                       0x067C
+#define SOLO_VE_JPEG_CTRL                      0x0680
+
+#define SOLO_VE_OSD_CH                         0x0690
+#define SOLO_VE_OSD_BASE                       0x0694
+#define SOLO_VE_OSD_CLR                                0x0698
+#define SOLO_VE_OSD_OPT                                0x069C
+
+#define SOLO_VE_CH_INTL(ch)                    (0x0700+((ch)*4))
+#define SOLO_VE_CH_MOT(ch)                     (0x0740+((ch)*4))
+#define SOLO_VE_CH_QP(ch)                      (0x0780+((ch)*4))
+#define SOLO_VE_CH_QP_E(ch)                    (0x07C0+((ch)*4))
+#define SOLO_VE_CH_GOP(ch)                     (0x0800+((ch)*4))
+#define SOLO_VE_CH_GOP_E(ch)                   (0x0840+((ch)*4))
+#define SOLO_VE_CH_REF_BASE(ch)                        (0x0880+((ch)*4))
+#define SOLO_VE_CH_REF_BASE_E(ch)              (0x08C0+((ch)*4))
+
+#define SOLO_VE_MPEG4_QUE(n)                   (0x0A00+((n)*8))
+#define SOLO_VE_JPEG_QUE(n)                    (0x0A04+((n)*8))
+
+#define SOLO_VD_CFG0                           0x0900
+#define          SOLO_VD_CFG_NO_WRITE_NO_WINDOW        (1<<24)
+#define          SOLO_VD_CFG_BUSY_WIAT_CODE            (1<<23)
+#define          SOLO_VD_CFG_BUSY_WIAT_REF             (1<<22)
+#define          SOLO_VD_CFG_BUSY_WIAT_RES             (1<<21)
+#define          SOLO_VD_CFG_BUSY_WIAT_MS              (1<<20)
+#define          SOLO_VD_CFG_SINGLE_MODE               (1<<18)
+#define          SOLO_VD_CFG_SCAL_MANUAL               (1<<17)
+#define          SOLO_VD_CFG_USER_PAGE_CTRL            (1<<16)
+#define          SOLO_VD_CFG_LITTLE_ENDIAN             (1<<15)
+#define          SOLO_VD_CFG_START_FI                  (1<<14)
+#define          SOLO_VD_CFG_ERR_LOCK                  (1<<13)
+#define          SOLO_VD_CFG_ERR_INT_ENA               (1<<12)
+#define          SOLO_VD_CFG_TIME_WIDTH(n)             ((n)<<8)
+#define          SOLO_VD_CFG_DCT_INTERVAL(n)           ((n)<<0)
+
+#define SOLO_VD_CFG1                           0x0904
+
+#define        SOLO_VD_DEINTERLACE                     0x0908
+#define          SOLO_VD_DEINTERLACE_THRESHOLD(n)      ((n)<<8)
+#define          SOLO_VD_DEINTERLACE_EDGE_VALUE(n)     ((n)<<0)
+
+#define SOLO_VD_CODE_ADR                       0x090C
+
+#define SOLO_VD_CTRL                           0x0910
+#define          SOLO_VD_OPER_ON                       (1<<31)
+#define          SOLO_VD_MAX_ITEM(n)                   ((n)<<0)
+
+#define SOLO_VD_STATUS0                                0x0920
+#define          SOLO_VD_STATUS0_INTR_ACK              (1<<22)
+#define          SOLO_VD_STATUS0_INTR_EMPTY            (1<<21)
+#define          SOLO_VD_STATUS0_INTR_ERR              (1<<20)
+
+#define SOLO_VD_STATUS1                                0x0924
+
+#define SOLO_VD_IDX0                           0x0930
+#define          SOLO_VD_IDX_INTERLACE                 (1<<30)
+#define          SOLO_VD_IDX_CHANNEL(n)                ((n)<<24)
+#define          SOLO_VD_IDX_SIZE(n)                   ((n)<<0)
+
+#define SOLO_VD_IDX1                           0x0934
+#define          SOLO_VD_IDX_SRC_SCALE(n)              ((n)<<28)
+#define          SOLO_VD_IDX_WINDOW(n)                 ((n)<<24)
+#define          SOLO_VD_IDX_DEINTERLACE               (1<<16)
+#define          SOLO_VD_IDX_H_BLOCK(n)                ((n)<<8)
+#define          SOLO_VD_IDX_V_BLOCK(n)                ((n)<<0)
+
+#define SOLO_VD_IDX2                           0x0938
+#define          SOLO_VD_IDX_REF_BASE_SIDE             (1<<31)
+#define          SOLO_VD_IDX_REF_BASE(n)               (((n)>>16)&0xffff)
+
+#define SOLO_VD_IDX3                           0x093C
+#define          SOLO_VD_IDX_DISP_SCALE(n)             ((n)<<28)
+#define          SOLO_VD_IDX_INTERLACE_WR              (1<<27)
+#define          SOLO_VD_IDX_INTERPOL                  (1<<26)
+#define          SOLO_VD_IDX_HOR2X                     (1<<25)
+#define          SOLO_VD_IDX_OFFSET_X(n)               ((n)<<12)
+#define          SOLO_VD_IDX_OFFSET_Y(n)               ((n)<<0)
+
+#define SOLO_VD_IDX4                           0x0940
+#define          SOLO_VD_IDX_DEC_WR_PAGE(n)            ((n)<<8)
+#define          SOLO_VD_IDX_DISP_RD_PAGE(n)           ((n)<<0)
+
+#define SOLO_VD_WR_PAGE(n)                     (0x03F0 + ((n) * 4))
+
+
+#define SOLO_GPIO_CONFIG_0                     0x0B00
+#define SOLO_GPIO_CONFIG_1                     0x0B04
+#define SOLO_GPIO_DATA_OUT                     0x0B08
+#define SOLO_GPIO_DATA_IN                      0x0B0C
+#define SOLO_GPIO_INT_ACK_STA                  0x0B10
+#define SOLO_GPIO_INT_ENA                      0x0B14
+#define SOLO_GPIO_INT_CFG_0                    0x0B18
+#define SOLO_GPIO_INT_CFG_1                    0x0B1C
+
+
+#define SOLO_IIC_CFG                           0x0B20
+#define          SOLO_IIC_ENABLE                       (1<<8)
+#define          SOLO_IIC_PRESCALE(n)                  ((n)<<0)
+
+#define SOLO_IIC_CTRL                          0x0B24
+#define          SOLO_IIC_AUTO_CLEAR                   (1<<20)
+#define          SOLO_IIC_STATE_RX_ACK                 (1<<19)
+#define          SOLO_IIC_STATE_BUSY                   (1<<18)
+#define          SOLO_IIC_STATE_SIG_ERR                (1<<17)
+#define          SOLO_IIC_STATE_TRNS                   (1<<16)
+#define          SOLO_IIC_CH_SET(n)                    ((n)<<5)
+#define          SOLO_IIC_ACK_EN                       (1<<4)
+#define          SOLO_IIC_START                        (1<<3)
+#define          SOLO_IIC_STOP                         (1<<2)
+#define          SOLO_IIC_READ                         (1<<1)
+#define          SOLO_IIC_WRITE                        (1<<0)
+
+#define SOLO_IIC_TXD                           0x0B28
+#define SOLO_IIC_RXD                           0x0B2C
+
+/*
+ *     UART REGISTER
+ */
+#define SOLO_UART_CONTROL(n)                   (0x0BA0 + ((n)*0x20))
+#define          SOLO_UART_CLK_DIV(n)                  ((n)<<24)
+#define          SOLO_MODEM_CTRL_EN                    (1<<20)
+#define          SOLO_PARITY_ERROR_DROP                (1<<18)
+#define          SOLO_IRQ_ERR_EN                       (1<<17)
+#define          SOLO_IRQ_RX_EN                        (1<<16)
+#define          SOLO_IRQ_TX_EN                        (1<<15)
+#define          SOLO_RX_EN                            (1<<14)
+#define          SOLO_TX_EN                            (1<<13)
+#define          SOLO_UART_HALF_DUPLEX                 (1<<12)
+#define          SOLO_UART_LOOPBACK                    (1<<11)
+
+#define          SOLO_BAUDRATE_230400                  ((0<<9)|(0<<6))
+#define          SOLO_BAUDRATE_115200                  ((0<<9)|(1<<6))
+#define          SOLO_BAUDRATE_57600                   ((0<<9)|(2<<6))
+#define          SOLO_BAUDRATE_38400                   ((0<<9)|(3<<6))
+#define          SOLO_BAUDRATE_19200                   ((0<<9)|(4<<6))
+#define          SOLO_BAUDRATE_9600                    ((0<<9)|(5<<6))
+#define          SOLO_BAUDRATE_4800                    ((0<<9)|(6<<6))
+#define          SOLO_BAUDRATE_2400                    ((1<<9)|(6<<6))
+#define          SOLO_BAUDRATE_1200                    ((2<<9)|(6<<6))
+#define          SOLO_BAUDRATE_300                     ((3<<9)|(6<<6))
+
+#define          SOLO_UART_DATA_BIT_8                  (3<<4)
+#define          SOLO_UART_DATA_BIT_7                  (2<<4)
+#define          SOLO_UART_DATA_BIT_6                  (1<<4)
+#define          SOLO_UART_DATA_BIT_5                  (0<<4)
+
+#define          SOLO_UART_STOP_BIT_1                  (0<<2)
+#define          SOLO_UART_STOP_BIT_2                  (1<<2)
+
+#define          SOLO_UART_PARITY_NONE                 (0<<0)
+#define          SOLO_UART_PARITY_EVEN                 (2<<0)
+#define          SOLO_UART_PARITY_ODD                  (3<<0)
+
+#define SOLO_UART_STATUS(n)                    (0x0BA4 + ((n)*0x20))
+#define          SOLO_UART_CTS                         (1<<15)
+#define          SOLO_UART_RX_BUSY                     (1<<14)
+#define          SOLO_UART_OVERRUN                     (1<<13)
+#define          SOLO_UART_FRAME_ERR                   (1<<12)
+#define          SOLO_UART_PARITY_ERR                  (1<<11)
+#define          SOLO_UART_TX_BUSY                     (1<<5)
+
+#define          SOLO_UART_RX_BUFF_CNT(stat)           (((stat)>>6) & 0x1f)
+#define          SOLO_UART_RX_BUFF_SIZE                8
+#define          SOLO_UART_TX_BUFF_CNT(stat)           (((stat)>>0) & 0x1f)
+#define          SOLO_UART_TX_BUFF_SIZE                8
+
+#define SOLO_UART_TX_DATA(n)                   (0x0BA8 + ((n)*0x20))
+#define          SOLO_UART_TX_DATA_PUSH                (1<<8)
+#define SOLO_UART_RX_DATA(n)                   (0x0BAC + ((n)*0x20))
+#define          SOLO_UART_RX_DATA_POP                 (1<<8)
+
+#define SOLO_TIMER_CLOCK_NUM                   0x0be0
+#define SOLO_TIMER_WATCHDOG                    0x0be4
+#define SOLO_TIMER_USEC                                0x0be8
+#define SOLO_TIMER_SEC                         0x0bec
+
+#define SOLO_AUDIO_CONTROL                     0x0D00
+#define          SOLO_AUDIO_ENABLE                     (1<<31)
+#define          SOLO_AUDIO_MASTER_MODE                (1<<30)
+#define          SOLO_AUDIO_I2S_MODE                   (1<<29)
+#define          SOLO_AUDIO_I2S_LR_SWAP                (1<<27)
+#define          SOLO_AUDIO_I2S_8BIT                   (1<<26)
+#define          SOLO_AUDIO_I2S_MULTI(n)               ((n)<<24)
+#define          SOLO_AUDIO_MIX_9TO0                   (1<<23)
+#define          SOLO_AUDIO_DEC_9TO0_VOL(n)            ((n)<<20)
+#define          SOLO_AUDIO_MIX_19TO10                 (1<<19)
+#define          SOLO_AUDIO_DEC_19TO10_VOL(n)          ((n)<<16)
+#define          SOLO_AUDIO_MODE(n)                    ((n)<<0)
+#define SOLO_AUDIO_SAMPLE                      0x0D04
+#define          SOLO_AUDIO_EE_MODE_ON                 (1<<30)
+#define          SOLO_AUDIO_EE_ENC_CH(ch)              ((ch)<<25)
+#define          SOLO_AUDIO_BITRATE(n)                 ((n)<<16)
+#define          SOLO_AUDIO_CLK_DIV(n)                 ((n)<<0)
+#define SOLO_AUDIO_FDMA_INTR                   0x0D08
+#define          SOLO_AUDIO_FDMA_INTERVAL(n)           ((n)<<19)
+#define          SOLO_AUDIO_INTR_ORDER(n)              ((n)<<16)
+#define          SOLO_AUDIO_FDMA_BASE(n)               ((n)<<0)
+#define SOLO_AUDIO_EVOL_0                      0x0D0C
+#define SOLO_AUDIO_EVOL_1                      0x0D10
+#define          SOLO_AUDIO_EVOL(ch, value)            ((value)<<((ch)%10))
+#define SOLO_AUDIO_STA                         0x0D14
+
+
+#define SOLO_WATCHDOG                          0x0BE4
+#define WATCHDOG_STAT(status)                  (status<<8)
+#define WATCHDOG_TIME(sec)                     (sec&0xff)
+
+#endif /* __SOLO6010_REGISTERS_H */
diff --git a/drivers/staging/solo6x10/solo6010-tw28.c b/drivers/staging/solo6x10/solo6010-tw28.c
new file mode 100644 (file)
index 0000000..0159c83
--- /dev/null
@@ -0,0 +1,823 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+
+#include "solo6010.h"
+#include "solo6010-tw28.h"
+
+/* XXX: Some of these values are masked into an 8-bit regs, and shifted
+ * around for other 8-bit regs. What are the magic bits in these values? */
+#define DEFAULT_HDELAY_NTSC            (32 - 4)
+#define DEFAULT_HACTIVE_NTSC           (720 + 16)
+#define DEFAULT_VDELAY_NTSC            (7 - 2)
+#define DEFAULT_VACTIVE_NTSC           (240 + 4)
+
+#define DEFAULT_HDELAY_PAL             (32 + 4)
+#define DEFAULT_HACTIVE_PAL            (864-DEFAULT_HDELAY_PAL)
+#define DEFAULT_VDELAY_PAL             (6)
+#define DEFAULT_VACTIVE_PAL            (312-DEFAULT_VDELAY_PAL)
+
+static u8 tbl_tw2864_template[] = {
+       0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x00
+       0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x10
+       0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x20
+       0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x30
+       0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00,
+       0x00, 0x02, 0x00, 0xcc, 0x00, 0x80, 0x44, 0x50, // 0x80
+       0x22, 0x01, 0xd8, 0xbc, 0xb8, 0x44, 0x38, 0x00,
+       0x00, 0x78, 0x72, 0x3e, 0x14, 0xa5, 0xe4, 0x05, // 0x90
+       0x00, 0x28, 0x44, 0x44, 0xa0, 0x88, 0x5a, 0x01,
+       0x08, 0x08, 0x08, 0x08, 0x1a, 0x1a, 0x1a, 0x1a, // 0xa0
+       0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x44,
+       0x44, 0x0a, 0x00, 0xff, 0xef, 0xef, 0xef, 0xef, // 0xb0
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0
+       0x00, 0x00, 0x55, 0x00, 0xb1, 0xe4, 0x40, 0x00,
+       0x77, 0x77, 0x01, 0x13, 0x57, 0x9b, 0xdf, 0x20, // 0xd0
+       0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81,
+       0x10, 0xe0, 0xbb, 0xbb, 0x00, 0x11, 0x00, 0x00, // 0xe0
+       0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00,
+       0x83, 0xb5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, // 0xf0
+       0x64, 0x11, 0x40, 0xaf, 0xff, 0x00, 0x00, 0x00,
+};
+
+static u8 tbl_tw2865_ntsc_template[] = {
+       0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x00
+       0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x10
+       0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x20
+       0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0xf0, 0x70, 0x48, 0x80, 0x80, 0x00, 0x02, // 0x30
+       0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
+       0x00, 0x00, 0x90, 0x68, 0x00, 0x38, 0x80, 0x80, // 0x40
+       0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43,
+       0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, // 0x70
+       0xE9, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80,
+       0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, // 0x80
+       0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00,
+       0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, // 0x90
+       0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13,
+       0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1B, 0x1A, // 0xa0
+       0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44,
+       0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, // 0xb0
+       0xFF, 0xE7, 0xE9, 0xE9, 0xEB, 0xFF, 0xD6, 0xD8,
+       0xD8, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0
+       0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80,
+       0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, // 0xd0
+       0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81,
+       0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, // 0xe0
+       0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00,
+       0x83, 0xB5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, // 0xf0
+       0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0,
+};
+
+static u8 tbl_tw2865_pal_template[] = {
+       0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x00
+       0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
+       0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x10
+       0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
+       0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x20
+       0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
+       0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x30
+       0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
+       0x00, 0x94, 0x90, 0x48, 0x00, 0x38, 0x7F, 0x80, // 0x40
+       0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43,
+       0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, // 0x70
+       0xEA, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80,
+       0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, // 0x80
+       0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00,
+       0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, // 0x90
+       0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13,
+       0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1A, 0x1A, // 0xa0
+       0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44,
+       0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, // 0xb0
+       0xFF, 0xE7, 0xE9, 0xE9, 0xE9, 0xFF, 0xD7, 0xD8,
+       0xD9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0
+       0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80,
+       0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, // 0xd0
+       0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81,
+       0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, // 0xe0
+       0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00,
+       0x83, 0xB5, 0x09, 0x00, 0xA0, 0x00, 0x01, 0x20, // 0xf0
+       0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0,
+};
+
+#define is_tw286x(__solo, __id) (!(__solo->tw2815 & (1 << __id)))
+
+static u8 tw_readbyte(struct solo6010_dev *solo_dev, int chip_id, u8 tw6x_off,
+                     u8 tw_off)
+{
+       if (is_tw286x(solo_dev, chip_id))
+               return solo_i2c_readbyte(solo_dev, SOLO_I2C_TW,
+                                        TW_CHIP_OFFSET_ADDR(chip_id),
+                                        tw6x_off);
+       else
+               return solo_i2c_readbyte(solo_dev, SOLO_I2C_TW,
+                                        TW_CHIP_OFFSET_ADDR(chip_id),
+                                        tw_off);
+}
+
+static void tw_writebyte(struct solo6010_dev *solo_dev, int chip_id,
+                        u8 tw6x_off, u8 tw_off, u8 val)
+{
+       if (is_tw286x(solo_dev, chip_id))
+               solo_i2c_writebyte(solo_dev, SOLO_I2C_TW,
+                                  TW_CHIP_OFFSET_ADDR(chip_id),
+                                  tw6x_off, val);
+       else
+               solo_i2c_writebyte(solo_dev, SOLO_I2C_TW,
+                                  TW_CHIP_OFFSET_ADDR(chip_id),
+                                  tw_off, val);
+}
+
+static void tw_write_and_verify(struct solo6010_dev *solo_dev, u8 addr, u8 off,
+                               u8 val)
+{
+       int i;
+
+       for (i = 0; i < 5; i++) {
+               u8 rval = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, addr, off);
+               if (rval == val)
+                       return;
+
+               solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, addr, off, val);
+               msleep_interruptible(1);
+       }
+
+//     printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n",
+//             addr, off, val);
+}
+
+static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr)
+{
+       u8 tbl_tw2865_common[256];
+       int i;
+
+       if (solo_dev->video_type == SOLO_VO_FMT_TYPE_PAL)
+               memcpy(tbl_tw2865_common, tbl_tw2865_pal_template,
+                      sizeof(tbl_tw2865_common));
+       else
+               memcpy(tbl_tw2865_common, tbl_tw2865_ntsc_template,
+                      sizeof(tbl_tw2865_common));
+
+       /* ALINK Mode */
+       if (solo_dev->nr_chans == 4) {
+               tbl_tw2865_common[0xd2] = 0x01;
+               tbl_tw2865_common[0xcf] = 0x00;
+       } else if (solo_dev->nr_chans == 8) {
+               tbl_tw2865_common[0xd2] = 0x02;
+               if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                       tbl_tw2865_common[0xcf] = 0x80;
+       } else if (solo_dev->nr_chans == 16) {
+               tbl_tw2865_common[0xd2] = 0x03;
+               if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                       tbl_tw2865_common[0xcf] = 0x83;
+               else if (dev_addr == TW_CHIP_OFFSET_ADDR(2))
+                       tbl_tw2865_common[0xcf] = 0x83;
+               else if (dev_addr == TW_CHIP_OFFSET_ADDR(3))
+                       tbl_tw2865_common[0xcf] = 0x80;
+       }
+
+       for (i = 0; i < 0xff; i++) {
+               /* Skip read only registers */
+               if (i >= 0xb8 && i <= 0xc1 )
+                       continue;
+               if ((i & ~0x30) == 0x00 ||
+                   (i & ~0x30) == 0x0c ||
+                   (i & ~0x30) == 0x0d)
+                       continue;
+               if (i >= 0xc4 && i <= 0xc7)
+                       continue;
+               if (i == 0xfd)
+                       continue;
+
+               tw_write_and_verify(solo_dev, dev_addr, i,
+                                   tbl_tw2865_common[i]);
+       }
+
+       return 0;
+}
+
+static int tw2864_setup(struct solo6010_dev *solo_dev, u8 dev_addr)
+{
+       u8 tbl_tw2864_common[sizeof(tbl_tw2864_template)];
+       int i;
+
+       memcpy(tbl_tw2864_common, tbl_tw2864_template,
+              sizeof(tbl_tw2864_common));
+
+       if (solo_dev->tw2865 == 0) {
+               /* IRQ Mode */
+               if (solo_dev->nr_chans == 4) {
+                       tbl_tw2864_common[0xd2] = 0x01;
+                       tbl_tw2864_common[0xcf] = 0x00;
+               } else if (solo_dev->nr_chans == 8) {
+                       tbl_tw2864_common[0xd2] = 0x02;
+                       if (dev_addr == TW_CHIP_OFFSET_ADDR(0))
+                               tbl_tw2864_common[0xcf] = 0x43;
+                       else if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                               tbl_tw2864_common[0xcf] = 0x40;
+               } else if (solo_dev->nr_chans == 16) {
+                       tbl_tw2864_common[0xd2] = 0x03;
+                       if (dev_addr == TW_CHIP_OFFSET_ADDR(0))
+                               tbl_tw2864_common[0xcf] = 0x43;
+                       else if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                               tbl_tw2864_common[0xcf] = 0x43;
+                       else if (dev_addr == TW_CHIP_OFFSET_ADDR(2))
+                               tbl_tw2864_common[0xcf] = 0x43;
+                       else if (dev_addr == TW_CHIP_OFFSET_ADDR(3))
+                               tbl_tw2864_common[0xcf] = 0x40;
+               }
+       } else {
+               /* ALINK Mode. Assumes that the first tw28xx is a
+                * 2865 and these are in cascade. */
+               for (i = 0; i <= 4; i++)
+                       tbl_tw2864_common[0x08 | i << 4] = 0x12;
+
+               if (solo_dev->nr_chans == 8) {
+                       tbl_tw2864_common[0xd2] = 0x02;
+                       if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                               tbl_tw2864_common[0xcf] = 0x80;
+               } else if (solo_dev->nr_chans == 16) {
+                       tbl_tw2864_common[0xd2] = 0x03;
+                       if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                               tbl_tw2864_common[0xcf] = 0x83;
+                       else if (dev_addr == TW_CHIP_OFFSET_ADDR(2))
+                               tbl_tw2864_common[0xcf] = 0x83;
+                       else if (dev_addr == TW_CHIP_OFFSET_ADDR(3))
+                               tbl_tw2864_common[0xcf] = 0x80;
+               }
+       }
+
+       /* NTSC or PAL */
+       if (solo_dev->video_type == SOLO_VO_FMT_TYPE_PAL) {
+               for (i = 0; i < 4; i++) {
+                       tbl_tw2864_common[0x07 | (i << 4)] |= 0x10;
+                       tbl_tw2864_common[0x08 | (i << 4)] |= 0x06;
+                       tbl_tw2864_common[0x0a | (i << 4)] |= 0x08;
+                       tbl_tw2864_common[0x0b | (i << 4)] |= 0x13;
+                       tbl_tw2864_common[0x0e | (i << 4)] |= 0x01;
+               }
+               tbl_tw2864_common[0x9d] = 0x90;
+               tbl_tw2864_common[0xf3] = 0x00;
+               tbl_tw2864_common[0xf4] = 0xa0;
+       }
+
+       for (i = 0; i < 0xff; i++) {
+               /* Skip read only registers */
+               if (i >= 0xb8 && i <= 0xc1 )
+                       continue;
+               if ((i & ~0x30) == 0x00 ||
+                   (i & ~0x30) == 0x0c ||
+                   (i & ~0x30) == 0x0d)
+                       continue;
+               if (i == 0x74 || i == 0x77 || i == 0x78 ||
+                   i == 0x79 || i == 0x7a)
+                       continue;
+               if (i == 0xfd)
+                       continue;
+
+               tw_write_and_verify(solo_dev, dev_addr, i,
+                                   tbl_tw2864_common[i]);
+       }
+
+       return 0;
+}
+
+static int tw2815_setup(struct solo6010_dev *solo_dev, u8 dev_addr)
+{
+       u8 tbl_ntsc_tw2815_common[] = {
+               0x00, 0xc8, 0x20, 0xd0, 0x06, 0xf0, 0x08, 0x80,
+               0x80, 0x80, 0x80, 0x02, 0x06, 0x00, 0x11,
+       };
+
+       u8 tbl_pal_tw2815_common[] = {
+               0x00, 0x88, 0x20, 0xd0, 0x05, 0x20, 0x28, 0x80,
+               0x80, 0x80, 0x80, 0x82, 0x06, 0x00, 0x11,
+       };
+
+       u8 tbl_tw2815_sfr[] = {
+               0x00, 0x00, 0x00, 0xc0, 0x45, 0xa0, 0xd0, 0x2f, // 0x00
+               0x64, 0x80, 0x80, 0x82, 0x82, 0x00, 0x00, 0x00,
+               0x00, 0x0f, 0x05, 0x00, 0x00, 0x80, 0x06, 0x00, // 0x10
+               0x00, 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00,
+               0x88, 0x88, 0xc0, 0x00, 0x20, 0x64, 0xa8, 0xec, // 0x20
+               0x31, 0x75, 0xb9, 0xfd, 0x00, 0x00, 0x88, 0x88,
+               0x88, 0x11, 0x00, 0x88, 0x88, 0x00,             // 0x30
+       };
+       u8 *tbl_tw2815_common;
+       int i;
+       int ch;
+
+       tbl_ntsc_tw2815_common[0x06] = 0;
+
+       /* Horizontal Delay Control */
+       tbl_ntsc_tw2815_common[0x02] = DEFAULT_HDELAY_NTSC & 0xff;
+       tbl_ntsc_tw2815_common[0x06] |= 0x03 & (DEFAULT_HDELAY_NTSC >> 8);
+
+       /* Horizontal Active Control */
+       tbl_ntsc_tw2815_common[0x03] = DEFAULT_HACTIVE_NTSC & 0xff;
+       tbl_ntsc_tw2815_common[0x06] |=
+               ((0x03 & (DEFAULT_HACTIVE_NTSC >> 8)) << 2);
+
+       /* Vertical Delay Control */
+       tbl_ntsc_tw2815_common[0x04] = DEFAULT_VDELAY_NTSC & 0xff;
+       tbl_ntsc_tw2815_common[0x06] |=
+               ((0x01 & (DEFAULT_VDELAY_NTSC >> 8)) << 4);
+
+       /* Vertical Active Control */
+       tbl_ntsc_tw2815_common[0x05] = DEFAULT_VACTIVE_NTSC & 0xff;
+       tbl_ntsc_tw2815_common[0x06] |=
+               ((0x01 & (DEFAULT_VACTIVE_NTSC >> 8)) << 5);
+
+       tbl_pal_tw2815_common[0x06] = 0;
+
+       /* Horizontal Delay Control */
+       tbl_pal_tw2815_common[0x02] = DEFAULT_HDELAY_PAL & 0xff;
+       tbl_pal_tw2815_common[0x06] |= 0x03 & (DEFAULT_HDELAY_PAL >> 8);
+
+       /* Horizontal Active Control */
+       tbl_pal_tw2815_common[0x03] = DEFAULT_HACTIVE_PAL & 0xff;
+       tbl_pal_tw2815_common[0x06] |=
+               ((0x03 & (DEFAULT_HACTIVE_PAL >> 8)) << 2);
+
+       /* Vertical Delay Control */
+       tbl_pal_tw2815_common[0x04] = DEFAULT_VDELAY_PAL & 0xff;
+       tbl_pal_tw2815_common[0x06] |=
+               ((0x01 & (DEFAULT_VDELAY_PAL >> 8)) << 4);
+
+       /* Vertical Active Control */
+       tbl_pal_tw2815_common[0x05] = DEFAULT_VACTIVE_PAL & 0xff;
+       tbl_pal_tw2815_common[0x06] |=
+               ((0x01 & (DEFAULT_VACTIVE_PAL >> 8)) << 5);
+
+       tbl_tw2815_common =
+           (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) ?
+            tbl_ntsc_tw2815_common : tbl_pal_tw2815_common;
+
+       /* Dual ITU-R BT.656 format */
+       tbl_tw2815_common[0x0d] |= 0x04;
+
+       /* Audio configuration */
+       tbl_tw2815_sfr[0x62 - 0x40] &= ~(3 << 6);
+
+       if (solo_dev->nr_chans == 4) {
+               tbl_tw2815_sfr[0x63 - 0x40] |= 1;
+               tbl_tw2815_sfr[0x62 - 0x40] |= 3 << 6;
+       } else if (solo_dev->nr_chans == 8) {
+               tbl_tw2815_sfr[0x63 - 0x40] |= 2;
+               if (dev_addr == TW_CHIP_OFFSET_ADDR(0))
+                       tbl_tw2815_sfr[0x62 - 0x40] |= 1 << 6;
+               else if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                       tbl_tw2815_sfr[0x62 - 0x40] |= 2 << 6;
+       } else if (solo_dev->nr_chans == 16) {
+               tbl_tw2815_sfr[0x63 - 0x40] |= 3;
+               if (dev_addr == TW_CHIP_OFFSET_ADDR(0))
+                       tbl_tw2815_sfr[0x62 - 0x40] |= 1 << 6;
+               else if (dev_addr == TW_CHIP_OFFSET_ADDR(1))
+                       tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 6;
+               else if (dev_addr == TW_CHIP_OFFSET_ADDR(2))
+                       tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 6;
+               else if (dev_addr == TW_CHIP_OFFSET_ADDR(3))
+                       tbl_tw2815_sfr[0x62 - 0x40] |= 2 << 6;
+       }
+
+       /* Output mode of R_ADATM pin (0 mixing, 1 record) */
+       /* tbl_tw2815_sfr[0x63 - 0x40] |= 0 << 2; */
+
+       /* 8KHz, used to be 16KHz, but changed for remote client compat */
+       tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 2;
+       tbl_tw2815_sfr[0x6c - 0x40] |= 0 << 2;
+
+       /* Playback of right channel */
+       tbl_tw2815_sfr[0x6c - 0x40] |= 1 << 5;
+
+       /* Reserved value (XXX ??) */
+       tbl_tw2815_sfr[0x5c - 0x40] |= 1 << 5;
+
+       /* Analog output gain and mix ratio playback on full */
+       tbl_tw2815_sfr[0x70 - 0x40] |= 0xff;
+       /* Select playback audio and mute all except */
+       tbl_tw2815_sfr[0x71 - 0x40] |= 0x10;
+       tbl_tw2815_sfr[0x6d - 0x40] |= 0x0f;
+
+       /* End of audio configuration */
+
+       for (ch = 0; ch < 4; ch++) {
+               tbl_tw2815_common[0x0d] &= ~3;
+               switch (ch) {
+               case 0:
+                       tbl_tw2815_common[0x0d] |= 0x21;
+                       break;
+               case 1:
+                       tbl_tw2815_common[0x0d] |= 0x20;
+                       break;
+               case 2:
+                       tbl_tw2815_common[0x0d] |= 0x23;
+                       break;
+               case 3:
+                       tbl_tw2815_common[0x0d] |= 0x22;
+                       break;
+               }
+
+               for (i = 0; i < 0x0f; i++) {
+                       if (i == 0x00)
+                               continue;       // read-only
+                       solo_i2c_writebyte(solo_dev, SOLO_I2C_TW,
+                                          dev_addr, (ch * 0x10) + i,
+                                          tbl_tw2815_common[i]);
+               }
+       }
+
+       for (i = 0x40; i < 0x76; i++) {
+               /* Skip read-only and nop registers */
+               if (i == 0x40 || i == 0x59 || i == 0x5a ||
+                   i == 0x5d || i == 0x5e || i == 0x5f)
+                       continue;
+
+               solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, dev_addr, i,
+                                      tbl_tw2815_sfr[i - 0x40]);
+       }
+
+       return 0;
+}
+
+#define FIRST_ACTIVE_LINE      0x0008
+#define LAST_ACTIVE_LINE       0x0102
+
+static void saa7128_setup(struct solo6010_dev *solo_dev)
+{
+       int i;
+       unsigned char regs[128] = {
+               0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x1C, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
+               0x59, 0x1d, 0x75, 0x3f, 0x06, 0x3f, 0x00, 0x00,
+               0x1c, 0x33, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00,
+               0x1a, 0x1a, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x68, 0x10, 0x97, 0x4c, 0x18,
+               0x9b, 0x93, 0x9f, 0xff, 0x7c, 0x34, 0x3f, 0x3f,
+               0x3f, 0x83, 0x83, 0x80, 0x0d, 0x0f, 0xc3, 0x06,
+               0x02, 0x80, 0x71, 0x77, 0xa7, 0x67, 0x66, 0x2e,
+               0x7b, 0x11, 0x4f, 0x1f, 0x7c, 0xf0, 0x21, 0x77,
+               0x41, 0x88, 0x41, 0x12, 0xed, 0x10, 0x10, 0x00,
+               0x41, 0xc3, 0x00, 0x3e, 0xb8, 0x02, 0x00, 0x00,
+               0x00, 0x00, 0x08, 0xff, 0x80, 0x00, 0xff, 0xff,
+       };
+
+       regs[0x7A] = FIRST_ACTIVE_LINE & 0xff;
+       regs[0x7B] = LAST_ACTIVE_LINE & 0xff;
+       regs[0x7C] = ((1 << 7) |
+                       (((LAST_ACTIVE_LINE >> 8) & 1) << 6) |
+                       (((FIRST_ACTIVE_LINE >> 8) & 1) << 4));
+
+       /* PAL: XXX: We could do a second set of regs to avoid this */
+       if (solo_dev->video_type != SOLO_VO_FMT_TYPE_NTSC) {
+               regs[0x28] = 0xE1;
+
+               regs[0x5A] = 0x0F;
+               regs[0x61] = 0x02;
+               regs[0x62] = 0x35;
+               regs[0x63] = 0xCB;
+               regs[0x64] = 0x8A;
+               regs[0x65] = 0x09;
+               regs[0x66] = 0x2A;
+
+               regs[0x6C] = 0xf1;
+               regs[0x6E] = 0x20;
+
+               regs[0x7A] = 0x06 + 12;
+               regs[0x7b] = 0x24 + 12;
+               regs[0x7c] |= 1 << 6;
+       }
+
+       /* First 0x25 bytes are read-only? */
+       for (i = 0x26; i < 128; i++) {
+               if (i == 0x60 || i == 0x7D)
+                       continue;
+               solo_i2c_writebyte(solo_dev, SOLO_I2C_SAA, 0x46, i, regs[i]);
+       }
+
+       return;
+}
+
+int solo_tw28_init(struct solo6010_dev *solo_dev)
+{
+       int i;
+       u8 value;
+
+       /* Detect techwell chip type */
+       for (i = 0; i < TW_NUM_CHIP; i++) {
+               value = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW,
+                                         TW_CHIP_OFFSET_ADDR(i), 0xFF);
+
+               switch (value >> 3) {
+               case 0x18:
+                       solo_dev->tw2865 |= 1 << i;
+                       solo_dev->tw28_cnt++;
+                       break;
+               case 0x0c:
+                       solo_dev->tw2864 |= 1 << i;
+                       solo_dev->tw28_cnt++;
+                       break;
+               default:
+                       value = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW,
+                                                 TW_CHIP_OFFSET_ADDR(i), 0x59);
+                       if ((value >> 3) == 0x04) {
+                               solo_dev->tw2815 |= 1 << i;
+                               solo_dev->tw28_cnt++;
+                       }
+               }
+       }
+
+       if (!solo_dev->tw28_cnt)
+               return -EINVAL;
+
+       saa7128_setup(solo_dev);
+
+       for (i = 0; i < solo_dev->tw28_cnt; i++) {
+               if ((solo_dev->tw2865 & (1 << i)))
+                       tw2865_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i));
+               else if ((solo_dev->tw2864 & (1 << i)))
+                       tw2864_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i));
+               else
+                       tw2815_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i));
+       }
+
+       dev_info(&solo_dev->pdev->dev, "Initialized %d tw28xx chip%s:",
+                solo_dev->tw28_cnt, solo_dev->tw28_cnt == 1 ? "" : "s");
+
+       if (solo_dev->tw2865)
+               printk(" tw2865[%d]", hweight32(solo_dev->tw2865));
+       if (solo_dev->tw2864)
+               printk(" tw2864[%d]", hweight32(solo_dev->tw2864));
+       if (solo_dev->tw2815)
+               printk(" tw2815[%d]", hweight32(solo_dev->tw2815));
+       printk("\n");
+
+       return 0;
+}
+
+/* 
+ * We accessed the video status signal in the Techwell chip through
+ * iic/i2c because the video status reported by register REG_VI_STATUS1
+ * (address 0x012C) of the SOLO6010 chip doesn't give the correct video
+ * status signal values.
+ */
+int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch)
+{
+       u8 val, chip_num;
+
+       /* Get the right chip and on-chip channel */
+       chip_num = ch / 4;
+       ch %= 4;
+
+       val = tw_readbyte(solo_dev, chip_num, TW286X_AV_STAT_ADDR,
+                         TW_AV_STAT_ADDR) & 0x0f;
+
+       return val & (1 << ch) ? 1 : 0;
+}
+
+#if 0
+/* Status of audio from up to 4 techwell chips are combined into 1 variable.
+ * See techwell datasheet for details. */
+u16 tw28_get_audio_status(struct solo6010_dev *solo_dev)
+{
+       u8 val;
+       u16 status = 0;
+       int i;
+
+       for (i = 0; i < solo_dev->tw28_cnt; i++) {
+               val = (tw_readbyte(solo_dev, i, TW286X_AV_STAT_ADDR,
+                                  TW_AV_STAT_ADDR) & 0xf0) >> 4;
+               status |= val << (i * 4);
+       }
+
+       return status;
+}
+#endif
+
+int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch,
+                     s32 val)
+{
+       char sval;
+       u8 chip_num;
+
+       /* Get the right chip and on-chip channel */
+       chip_num = ch / 4;
+       ch %= 4;
+
+       if (val > 255 || val < 0)
+               return -ERANGE;
+
+       switch (ctrl) {
+       case V4L2_CID_SHARPNESS:
+               /* Only 286x has sharpness */
+               if (val > 0x0f || val < 0)
+                       return -ERANGE;
+               if (is_tw286x(solo_dev, chip_num)) {
+                       u8 v = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW,
+                                                TW_CHIP_OFFSET_ADDR(chip_num),
+                                                TW286x_SHARPNESS(chip_num));
+                       v &= 0xf0;
+                       v |= val;
+                       solo_i2c_writebyte(solo_dev, SOLO_I2C_TW,
+                                          TW_CHIP_OFFSET_ADDR(chip_num),
+                                          TW286x_SHARPNESS(chip_num), v);
+               } else if (val != 0)
+                       return -ERANGE;
+               break;
+
+       case V4L2_CID_HUE:
+               if (is_tw286x(solo_dev, chip_num))
+                       sval = val - 128;
+               else
+                       sval = (char)val;
+               tw_writebyte(solo_dev, chip_num, TW286x_HUE_ADDR(ch),
+                            TW_HUE_ADDR(ch), sval);
+
+               break;
+
+       case V4L2_CID_SATURATION:
+               if (is_tw286x(solo_dev, chip_num)) {
+                       solo_i2c_writebyte(solo_dev, SOLO_I2C_TW,
+                                          TW_CHIP_OFFSET_ADDR(chip_num),
+                                          TW286x_SATURATIONU_ADDR(ch), val);
+               }
+               tw_writebyte(solo_dev, chip_num, TW286x_SATURATIONV_ADDR(ch),
+                            TW_SATURATION_ADDR(ch), val);
+
+               break;
+
+       case V4L2_CID_CONTRAST:
+               tw_writebyte(solo_dev, chip_num, TW286x_CONTRAST_ADDR(ch),
+                            TW_CONTRAST_ADDR(ch), val);
+               break;
+
+       case V4L2_CID_BRIGHTNESS:
+               if (is_tw286x(solo_dev, chip_num))
+                       sval = val - 128;
+               else
+                       sval = (char)val;
+               tw_writebyte(solo_dev, chip_num, TW286x_BRIGHTNESS_ADDR(ch),
+                            TW_BRIGHTNESS_ADDR(ch), sval);
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch,
+                     s32 *val)
+{
+       u8 rval, chip_num;
+
+       /* Get the right chip and on-chip channel */
+       chip_num = ch / 4;
+       ch %= 4;
+
+       switch (ctrl) {
+       case V4L2_CID_SHARPNESS:
+               /* Only 286x has sharpness */
+               if (is_tw286x(solo_dev, chip_num)) {
+                       rval = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW,
+                                                TW_CHIP_OFFSET_ADDR(chip_num),
+                                                TW286x_SHARPNESS(chip_num));
+                       *val = rval & 0x0f;
+               } else
+                       *val = 0;
+               break;
+       case V4L2_CID_HUE:
+               rval = tw_readbyte(solo_dev, chip_num, TW286x_HUE_ADDR(ch),
+                                  TW_HUE_ADDR(ch));
+               if (is_tw286x(solo_dev, chip_num))
+                       *val = (s32)((char)rval) + 128;
+               else
+                       *val = rval;
+               break;
+       case V4L2_CID_SATURATION:
+               *val = tw_readbyte(solo_dev, chip_num,
+                                  TW286x_SATURATIONU_ADDR(ch),
+                                  TW_SATURATION_ADDR(ch));
+               break;
+       case V4L2_CID_CONTRAST:
+               *val = tw_readbyte(solo_dev, chip_num,
+                                  TW286x_CONTRAST_ADDR(ch),
+                                  TW_CONTRAST_ADDR(ch));
+               break;
+       case V4L2_CID_BRIGHTNESS:
+               rval = tw_readbyte(solo_dev, chip_num,
+                                  TW286x_BRIGHTNESS_ADDR(ch),
+                                  TW_BRIGHTNESS_ADDR(ch));
+               if (is_tw286x(solo_dev, chip_num)) 
+                       *val = (s32)((char)rval) + 128;
+               else
+                       *val = rval;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+#if 0
+/*
+ * For audio output volume, the output channel is only 1. In this case we
+ * don't need to offset TW_CHIP_OFFSET_ADDR. The TW_CHIP_OFFSET_ADDR used
+ * is the base address of the techwell chip.
+ */
+void tw2815_Set_AudioOutVol(struct solo6010_dev *solo_dev, unsigned int u_val)
+{
+       unsigned int val;
+       unsigned int chip_num;
+
+       chip_num = (solo_dev->nr_chans - 1) / 4;
+
+       val = tw_readbyte(solo_dev, chip_num, TW286x_AUDIO_OUTPUT_VOL_ADDR,
+                         TW_AUDIO_OUTPUT_VOL_ADDR);
+
+       u_val = (val & 0x0f) | (u_val << 4);
+
+       tw_writebyte(solo_dev, chip_num, TW286x_AUDIO_OUTPUT_VOL_ADDR,
+                    TW_AUDIO_OUTPUT_VOL_ADDR, u_val);
+}
+#endif
+
+u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch)
+{
+       u8 val;
+       u8 chip_num;
+
+       /* Get the right chip and on-chip channel */
+       chip_num = ch / 4;
+       ch %= 4;
+
+       val = tw_readbyte(solo_dev, chip_num,
+                         TW286x_AUDIO_INPUT_GAIN_ADDR(ch),
+                         TW_AUDIO_INPUT_GAIN_ADDR(ch));
+
+       return (ch % 2) ? (val >> 4) : (val & 0x0f);
+}
+
+void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val)
+{
+       u8 old_val;
+       u8 chip_num;
+
+       /* Get the right chip and on-chip channel */
+       chip_num = ch / 4;
+       ch %= 4;
+
+       old_val = tw_readbyte(solo_dev, chip_num,
+                             TW286x_AUDIO_INPUT_GAIN_ADDR(ch),
+                             TW_AUDIO_INPUT_GAIN_ADDR(ch));
+
+       val = (old_val & ((ch % 2) ? 0x0f : 0xf0)) |
+               ((ch % 2) ? (val << 4) : val);
+
+       tw_writebyte(solo_dev, chip_num, TW286x_AUDIO_INPUT_GAIN_ADDR(ch),
+                    TW_AUDIO_INPUT_GAIN_ADDR(ch), val);
+}
diff --git a/drivers/staging/solo6x10/solo6010-tw28.h b/drivers/staging/solo6x10/solo6010-tw28.h
new file mode 100644 (file)
index 0000000..a7eecfa
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SOLO6010_TW28_H
+#define __SOLO6010_TW28_H
+
+#include "solo6010.h"
+
+#define TW_NUM_CHIP                            4
+#define TW_BASE_ADDR                           0x28
+#define TW_CHIP_OFFSET_ADDR(n)                 (TW_BASE_ADDR + (n))
+
+/* tw2815 */
+#define TW_AV_STAT_ADDR                                0x5a
+#define TW_HUE_ADDR(n)                         (0x07 | ((n) << 4))
+#define TW_SATURATION_ADDR(n)                  (0x08 | ((n) << 4))
+#define TW_CONTRAST_ADDR(n)                    (0x09 | ((n) << 4))
+#define TW_BRIGHTNESS_ADDR(n)                  (0x0a | ((n) << 4))
+#define TW_AUDIO_OUTPUT_VOL_ADDR               0x70
+#define TW_AUDIO_INPUT_GAIN_ADDR(n)            (0x60 + ((n > 1) ? 1 : 0))
+
+/* tw286x */
+#define TW286X_AV_STAT_ADDR                    0xfd
+#define TW286x_HUE_ADDR(n)                     (0x06 | ((n) << 4))
+#define TW286x_SATURATIONU_ADDR(n)             (0x04 | ((n) << 4))
+#define TW286x_SATURATIONV_ADDR(n)             (0x05 | ((n) << 4))
+#define TW286x_CONTRAST_ADDR(n)                        (0x02 | ((n) << 4))
+#define TW286x_BRIGHTNESS_ADDR(n)              (0x01 | ((n) << 4))
+#define TW286x_SHARPNESS(n)                    (0x03 | ((n) << 4))
+#define TW286x_AUDIO_OUTPUT_VOL_ADDR           0xdf
+#define TW286x_AUDIO_INPUT_GAIN_ADDR(n)                (0xD0 + ((n > 1) ? 1 : 0))
+
+int solo_tw28_init(struct solo6010_dev *solo_dev);
+
+int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch,
+                     s32 val);
+int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch,
+                     s32 *val);
+
+u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch);
+void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val);
+int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch);
+
+#if 0
+unsigned int tw2815_get_audio_status(struct SOLO6010 *solo6010);
+void tw2815_Set_AudioOutVol(struct SOLO6010 *solo6010, unsigned int u_val);
+#endif
+
+#endif /* __SOLO6010_TW28_H */
diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c
new file mode 100644 (file)
index 0000000..f114b4b
--- /dev/null
@@ -0,0 +1,1564 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-common.h>
+#include <media/videobuf-dma-contig.h>
+
+#include "solo6010.h"
+#include "solo6010-tw28.h"
+#include "solo6010-jpeg.h"
+
+#define MIN_VID_BUFFERS                4
+#define FRAME_BUF_SIZE         (128 * 1024)
+#define MP4_QS                 16
+
+static int solo_enc_thread(void *data);
+
+extern unsigned video_nr;
+
+struct solo_enc_fh {
+       struct                  solo_enc_dev *enc;
+       u32                     fmt;
+       u16                     rd_idx;
+       u8                      enc_on;
+       enum solo_enc_types     type;
+       struct videobuf_queue   vidq;
+       struct list_head        vidq_active;
+       struct task_struct      *kthread;
+};
+
+static unsigned char vid_vop_header[] = {
+       0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
+       0x02, 0x48, 0x05, 0xc0, 0x00, 0x40, 0x00, 0x40,
+       0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
+       0x1f, 0x4c, 0x58, 0x10, 0x78, 0x51, 0x18, 0x3e,
+};
+
+/*
+ * Things we can change around:
+ *
+ * byte  10,        4-bits 01111000                   aspect
+ * bytes 21,22,23  16-bits 000x1111 11111111 1111x000 fps/res
+ * bytes 23,24,25  15-bits 00000n11 11111111 11111x00 interval
+ * bytes 25,26,27  13-bits 00000x11 11111111 111x0000 width
+ * bytes 27,28,29  13-bits 000x1111 11111111 1x000000 height
+ * byte  29         1-bit  0x100000                   interlace
+ */
+
+/* For aspect */
+#define XVID_PAR_43_PAL                2
+#define XVID_PAR_43_NTSC       3
+
+static const u32 solo_user_ctrls[] = {
+       V4L2_CID_BRIGHTNESS,
+       V4L2_CID_CONTRAST,
+       V4L2_CID_SATURATION,
+       V4L2_CID_HUE,
+       V4L2_CID_SHARPNESS,
+       0
+};
+
+static const u32 solo_mpeg_ctrls[] = {
+       V4L2_CID_MPEG_VIDEO_ENCODING,
+       V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+       0
+};
+
+static const u32 solo_private_ctrls[] = {
+       V4L2_CID_MOTION_ENABLE,
+       V4L2_CID_MOTION_THRESHOLD,
+       0
+};
+
+static const u32 solo_fmtx_ctrls[] = {
+       V4L2_CID_RDS_TX_RADIO_TEXT,
+       0
+};
+
+static const u32 *solo_ctrl_classes[] = {
+       solo_user_ctrls,
+       solo_mpeg_ctrls,
+       solo_fmtx_ctrls,
+       solo_private_ctrls,
+       NULL
+};
+
+struct vop_header {
+       /* VD_IDX0 */
+       u32 size:20, sync_start:1, page_stop:1, vop_type:2, channel:4,
+               nop0:1, source_fl:1, interlace:1, progressive:1;
+
+       /* VD_IDX1 */
+       u32 vsize:8, hsize:8, frame_interop:1, nop1:7, win_id:4, scale:4;
+
+       /* VD_IDX2 */
+       u32 base_addr:16, nop2:15, hoff:1;
+
+       /* VD_IDX3 - User set macros */
+       u32 sy:12, sx:12, nop3:1, hzoom:1, read_interop:1, write_interlace:1,
+               scale_mode:4;
+
+       /* VD_IDX4 - User set macros continued */
+       u32 write_page:8, nop4:24;
+
+       /* VD_IDX5 */
+       u32 next_code_addr;
+
+       u32 end_nops[10];
+} __attribute__((packed));
+
+static int solo_is_motion_on(struct solo_enc_dev *solo_enc)
+{
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       u8 ch = solo_enc->ch;
+
+       if (solo_dev->motion_mask & (1 << ch))
+               return 1;
+       return 0;
+}
+
+static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on)
+{
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       u8 ch = solo_enc->ch;
+
+       spin_lock(&solo_enc->lock);
+
+       if (on)
+               solo_dev->motion_mask |= (1 << ch);
+       else
+               solo_dev->motion_mask &= ~(1 << ch);
+
+       solo_reg_write(solo_dev, SOLO_VI_MOT_ADR,
+                      SOLO_VI_MOTION_EN(solo_dev->motion_mask) |
+                      (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16));
+
+       if (solo_dev->motion_mask)
+               solo6010_irq_on(solo_dev, SOLO_IRQ_MOTION);
+       else
+               solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION);
+
+       spin_unlock(&solo_enc->lock);
+}
+
+/* Should be called with solo_enc->lock held */
+static void solo_update_mode(struct solo_enc_dev *solo_enc)
+{
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+
+       assert_spin_locked(&solo_enc->lock);
+
+       solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0;
+       solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1);
+
+       switch (solo_enc->mode) {
+       case SOLO_ENC_MODE_CIF:
+               solo_enc->width = solo_dev->video_hsize >> 1;
+               solo_enc->height = solo_dev->video_vsize;
+               break;
+       case SOLO_ENC_MODE_D1:
+               solo_enc->width = solo_dev->video_hsize;
+               solo_enc->height = solo_dev->video_vsize << 1;
+               solo_enc->bw_weight <<= 2;
+               break;
+       default:
+               WARN(1, "mode is unknown");
+       }
+}
+
+/* Should be called with solo_enc->lock held */
+static int solo_enc_on(struct solo_enc_fh *fh)
+{
+       struct solo_enc_dev *solo_enc = fh->enc;
+       u8 ch = solo_enc->ch;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       u8 interval;
+
+       assert_spin_locked(&solo_enc->lock);
+
+       if (fh->enc_on)
+               return 0;
+
+       solo_update_mode(solo_enc);
+
+       /* Make sure to bw check on first reader */
+       if (!atomic_read(&solo_enc->readers)) {
+               if (solo_enc->bw_weight > solo_dev->enc_bw_remain)
+                       return -EBUSY;
+               else
+                       solo_dev->enc_bw_remain -= solo_enc->bw_weight;
+       }
+
+       fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc");
+
+       if (IS_ERR(fh->kthread))
+               return PTR_ERR(fh->kthread);
+
+       fh->enc_on = 1;
+       fh->rd_idx = solo_enc->solo_dev->enc_wr_idx;
+
+       if (fh->type == SOLO_ENC_TYPE_EXT)
+               solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1);
+
+       if (atomic_inc_return(&solo_enc->readers) > 1)
+               return 0;
+
+       /* Disable all encoding for this channel */
+       solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), 0);
+
+       /* Common for both std and ext encoding */
+       solo_reg_write(solo_dev, SOLO_VE_CH_INTL(ch),
+                      solo_enc->interlaced ? 1 : 0);
+
+       if (solo_enc->interlaced)
+               interval = solo_enc->interval - 1;
+       else
+               interval = solo_enc->interval;
+
+       /* Standard encoding only */
+       solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), solo_enc->gop);
+       solo_reg_write(solo_dev, SOLO_VE_CH_QP(ch), solo_enc->qp);
+       solo_reg_write(solo_dev, SOLO_CAP_CH_INTV(ch), interval);
+
+       /* Extended encoding only */
+       solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(ch), solo_enc->gop);
+       solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(ch), solo_enc->qp);
+       solo_reg_write(solo_dev, SOLO_CAP_CH_INTV_E(ch), interval);
+
+       /* Enables the standard encoder */
+       solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), solo_enc->mode);
+
+       /* Settle down Beavis... */
+       mdelay(10);
+
+       return 0;
+}
+
+static void solo_enc_off(struct solo_enc_fh *fh)
+{
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+
+       if (!fh->enc_on)
+               return;
+
+       if (fh->kthread) {
+               kthread_stop(fh->kthread);
+               fh->kthread = NULL;
+       }
+
+       solo_dev->enc_bw_remain += solo_enc->bw_weight;
+       fh->enc_on = 0;
+
+       if (atomic_dec_return(&solo_enc->readers) > 0)
+               return;
+
+       solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0);
+       solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0);
+}
+
+static void enc_reset_gop(struct solo6010_dev *solo_dev, u8 ch)
+{
+       BUG_ON(ch >= solo_dev->nr_chans);
+       solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), 1);
+       solo_dev->v4l2_enc[ch]->reset_gop = 1;
+}
+
+static int enc_gop_reset(struct solo6010_dev *solo_dev, u8 ch, u8 vop)
+{
+       BUG_ON(ch >= solo_dev->nr_chans);
+       if (!solo_dev->v4l2_enc[ch]->reset_gop)
+               return 0;
+       if (vop)
+               return 1;
+       solo_dev->v4l2_enc[ch]->reset_gop = 0;
+       solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch),
+                      solo_dev->v4l2_enc[ch]->gop);
+       return 0;
+}
+
+static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, dma_addr_t buf,
+                             unsigned int off, unsigned int size)
+{
+       int ret;
+
+       if (off > SOLO_MP4E_EXT_SIZE(solo_dev))
+               return -EINVAL;
+
+       if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev))
+               return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf,
+                                     SOLO_MP4E_EXT_ADDR(solo_dev) + off, size);
+
+       /* Buffer wrap */
+       ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf,
+                           SOLO_MP4E_EXT_ADDR(solo_dev) + off,
+                           SOLO_MP4E_EXT_SIZE(solo_dev) - off);
+
+       ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0,
+                             buf + SOLO_MP4E_EXT_SIZE(solo_dev) - off,
+                             SOLO_MP4E_EXT_ADDR(solo_dev),
+                             size + off - SOLO_MP4E_EXT_SIZE(solo_dev));
+
+       return ret;
+}
+
+static int enc_get_mpeg_dma(struct solo6010_dev *solo_dev, void *buf,
+                           unsigned int off, unsigned int size)
+{
+       int ret;
+
+       dma_addr_t dma_addr = pci_map_single(solo_dev->pdev, buf, size,
+                                            PCI_DMA_FROMDEVICE);
+       ret = enc_get_mpeg_dma_t(solo_dev, dma_addr, off, size);
+       pci_unmap_single(solo_dev->pdev, dma_addr, size, PCI_DMA_FROMDEVICE);
+
+       return ret;
+}
+
+static int enc_get_jpeg_dma(struct solo6010_dev *solo_dev, dma_addr_t buf,
+                           unsigned int off, unsigned int size)
+{
+       int ret;
+
+       if (off > SOLO_JPEG_EXT_SIZE(solo_dev))
+               return -EINVAL;
+
+       if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev))
+               return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0, buf,
+                                     SOLO_JPEG_EXT_ADDR(solo_dev) + off, size);
+
+       /* Buffer wrap */
+       ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0, buf,
+                            SOLO_JPEG_EXT_ADDR(solo_dev) + off,
+                            SOLO_JPEG_EXT_SIZE(solo_dev) - off);
+
+       ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0,
+                             buf + SOLO_JPEG_EXT_SIZE(solo_dev) - off,
+                             SOLO_JPEG_EXT_ADDR(solo_dev),
+                             size + off - SOLO_JPEG_EXT_SIZE(solo_dev));
+
+       return ret;
+}
+
+static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf,
+                         struct videobuf_buffer *vb, dma_addr_t vbuf)
+{
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
+
+       memcpy(p, jpeg_header, sizeof(jpeg_header));
+       p[SOF0_START + 5] = 0xff & (solo_enc->height >> 8);
+       p[SOF0_START + 6] = 0xff & solo_enc->height;
+       p[SOF0_START + 7] = 0xff & (solo_enc->width >> 8);
+       p[SOF0_START + 8] = 0xff & solo_enc->width;
+
+       vbuf += sizeof(jpeg_header);
+       vb->size = enc_buf->jpeg_size + sizeof(jpeg_header);
+
+       return enc_get_jpeg_dma(solo_dev, vbuf, enc_buf->jpeg_off,
+                               enc_buf->jpeg_size);
+}
+
+static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf,
+                         struct videobuf_buffer *vb, dma_addr_t vbuf)
+{
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       struct vop_header vh;
+       int ret;
+       int frame_size, frame_off;
+
+       if (WARN_ON_ONCE(enc_buf->size <= sizeof(vh)))
+               return -1;
+
+       /* First get the hardware vop header (not real mpeg) */
+       ret = enc_get_mpeg_dma(solo_dev, &vh, enc_buf->off, sizeof(vh));
+       if (ret)
+               return -1;
+
+       if (WARN_ON_ONCE(vh.size > enc_buf->size))
+               return -1;
+
+       vb->width = vh.hsize << 4;
+       vb->height = vh.vsize << 4;
+       vb->size = vh.size;
+
+       /* If this is a key frame, add extra m4v header */
+       if (!enc_buf->vop) {
+               u16 fps = solo_dev->fps * 1000;
+               u16 interval = solo_enc->interval * 1000;
+               u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
+
+               memcpy(p, vid_vop_header, sizeof(vid_vop_header));
+
+               if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
+                       p[10] |= ((XVID_PAR_43_NTSC << 3) & 0x78);
+               else
+                       p[10] |= ((XVID_PAR_43_PAL << 3) & 0x78);
+
+               /* Frame rate and interval */
+               p[22] = fps >> 4;
+               p[23] = ((fps << 4) & 0xf0) | 0x0c | ((interval >> 13) & 0x3);
+               p[24] = (interval >> 5) & 0xff;
+               p[25] = ((interval << 3) & 0xf8) | 0x04;
+
+               /* Width and height */
+               p[26] = (vb->width >> 3) & 0xff;
+               p[27] = ((vb->height >> 9) & 0x0f) | 0x10;
+               p[28] = (vb->height >> 1) & 0xff;
+
+               /* Interlace */
+               if (vh.interlace)
+                       p[29] |= 0x20;
+
+               /* Adjust the dma buffer past this header */
+               vb->size += sizeof(vid_vop_header);
+               vbuf += sizeof(vid_vop_header);
+       }
+
+       /* Now get the actual mpeg payload */
+       frame_off = (enc_buf->off + sizeof(vh)) % SOLO_MP4E_EXT_SIZE(solo_dev);
+       frame_size = enc_buf->size - sizeof(vh);
+       ret = enc_get_mpeg_dma_t(solo_dev, vbuf, frame_off, frame_size);
+       if (WARN_ON_ONCE(ret))
+               return -1;
+
+       return 0;
+}
+
+/* On successful return (0), leaves solo_enc->lock unlocked */
+static int solo_enc_fillbuf(struct solo_enc_fh *fh,
+                           struct videobuf_buffer *vb)
+{
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       struct solo_enc_buf *enc_buf = NULL;
+       dma_addr_t vbuf;
+       int ret;
+       u16 idx = fh->rd_idx;
+
+       while (idx != solo_dev->enc_wr_idx) {
+               struct solo_enc_buf *ebuf = &solo_dev->enc_buf[idx];
+               idx = (idx + 1) % SOLO_NR_RING_BUFS;
+               if (fh->fmt == V4L2_PIX_FMT_MPEG) {
+                       if (fh->type != ebuf->type)
+                               continue;
+                       if (ebuf->ch == solo_enc->ch) {
+                               enc_buf = ebuf;
+                               break;
+                       }
+               } else if (ebuf->ch == solo_enc->ch) {
+                       /* For mjpeg, keep reading to the newest frame */
+                       enc_buf = ebuf;
+               }
+       }
+
+       fh->rd_idx = idx;
+
+       if (!enc_buf)
+               return -1;
+
+       if ((fh->fmt == V4L2_PIX_FMT_MPEG &&
+            vb->bsize < enc_buf->size) ||
+           (fh->fmt == V4L2_PIX_FMT_MJPEG &&
+            vb->bsize < (enc_buf->jpeg_size + sizeof(jpeg_header)))) {
+               return -1;
+       }
+
+       if (!(vbuf = videobuf_to_dma_contig(vb)))
+               return -1;
+
+       /* Is it ok that we mess with this buffer out of lock? */
+       spin_unlock(&solo_enc->lock);
+
+       if (fh->fmt == V4L2_PIX_FMT_MPEG)
+               ret = solo_fill_mpeg(fh, enc_buf, vb, vbuf);
+       else
+               ret = solo_fill_jpeg(fh, enc_buf, vb, vbuf);
+
+       if (ret) // Ignore failures
+               return 0;
+
+       list_del(&vb->queue);
+       vb->field_count++;
+       vb->ts = enc_buf->ts;
+       vb->state = VIDEOBUF_DONE;
+
+       wake_up(&vb->done);
+
+       return 0;
+}
+
+static void solo_enc_thread_try(struct solo_enc_fh *fh)
+{
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct videobuf_buffer *vb;
+
+       for (;;) {
+               spin_lock(&solo_enc->lock);
+
+               if (list_empty(&fh->vidq_active))
+                       break;
+
+               vb = list_first_entry(&fh->vidq_active,
+                                     struct videobuf_buffer, queue);
+
+               if (!waitqueue_active(&vb->done))
+                       break;
+
+               /* On success, returns with solo_enc->lock unlocked */
+               if (solo_enc_fillbuf(fh, vb))
+                       break;
+       }
+
+       assert_spin_locked(&solo_enc->lock);
+       spin_unlock(&solo_enc->lock);
+}
+
+static int solo_enc_thread(void *data)
+{
+       struct solo_enc_fh *fh = data;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       DECLARE_WAITQUEUE(wait, current);
+
+       set_freezable();
+       add_wait_queue(&solo_enc->thread_wait, &wait);
+
+       for (;;) {
+               long timeout = schedule_timeout_interruptible(HZ);
+               if (timeout == -ERESTARTSYS || kthread_should_stop())
+                       break;
+               solo_enc_thread_try(fh);
+               try_to_freeze();
+       }
+
+       remove_wait_queue(&solo_enc->thread_wait, &wait);
+
+        return 0;
+}
+
+void solo_motion_isr(struct solo6010_dev *solo_dev)
+{
+       u32 status;
+       int i;
+
+       solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_MOTION);
+
+       status = solo_reg_read(solo_dev, SOLO_VI_MOT_STATUS);
+
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               struct solo_enc_dev *solo_enc = solo_dev->v4l2_enc[i];
+
+               BUG_ON(solo_enc == NULL);
+
+               if (solo_enc->motion_detected)
+                       continue;
+               if (!(status & (1 << i)))
+                       continue;
+
+               solo_enc->motion_detected = 1;
+       }
+}
+
+void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev)
+{
+       struct solo_enc_buf *enc_buf;
+       struct videnc_status vstatus;
+       u32 mpeg_current, mpeg_next, mpeg_size;
+       u32 jpeg_current, jpeg_next, jpeg_size;
+       u32 reg_mpeg_size;
+       u8 cur_q, vop_type;
+       u8 ch;
+       enum solo_enc_types enc_type;
+
+       solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_ENCODER);
+
+       vstatus.status11 = solo_reg_read(solo_dev, SOLO_VE_STATE(11));
+       cur_q = (vstatus.status11_st.last_queue + 1) % MP4_QS;
+
+       vstatus.status0 = solo_reg_read(solo_dev, SOLO_VE_STATE(0));
+       reg_mpeg_size = (vstatus.status0_st.mp4_enc_code_size + 64 + 32) &
+                       (~31);
+
+       while (solo_dev->enc_idx != cur_q) {
+               mpeg_current = solo_reg_read(solo_dev,
+                                       SOLO_VE_MPEG4_QUE(solo_dev->enc_idx));
+               jpeg_current = solo_reg_read(solo_dev,
+                                       SOLO_VE_JPEG_QUE(solo_dev->enc_idx));
+               solo_dev->enc_idx = (solo_dev->enc_idx + 1) % MP4_QS;
+               mpeg_next = solo_reg_read(solo_dev,
+                                       SOLO_VE_MPEG4_QUE(solo_dev->enc_idx));
+               jpeg_next = solo_reg_read(solo_dev,
+                                       SOLO_VE_JPEG_QUE(solo_dev->enc_idx));
+
+               if ((ch = (mpeg_current >> 24) & 0x1f) >= SOLO_MAX_CHANNELS) {
+                       ch -= SOLO_MAX_CHANNELS;
+                       enc_type = SOLO_ENC_TYPE_EXT;
+               } else
+                       enc_type = SOLO_ENC_TYPE_STD;
+
+               vop_type = (mpeg_current >> 29) & 3;
+
+               mpeg_current &= 0x00ffffff;
+               mpeg_next    &= 0x00ffffff;
+               jpeg_current &= 0x00ffffff;
+               jpeg_next    &= 0x00ffffff;
+
+               mpeg_size = (SOLO_MP4E_EXT_SIZE(solo_dev) +
+                            mpeg_next - mpeg_current) %
+                           SOLO_MP4E_EXT_SIZE(solo_dev);
+
+               jpeg_size = (SOLO_JPEG_EXT_SIZE(solo_dev) +
+                            jpeg_next - jpeg_current) %
+                           SOLO_JPEG_EXT_SIZE(solo_dev);
+
+               /* XXX I think this means we had a ring overflow? */
+               if (mpeg_current > mpeg_next && mpeg_size != reg_mpeg_size) {
+                       enc_reset_gop(solo_dev, ch);
+                       continue;
+               }
+
+               /* When resetting the GOP, skip frames until I-frame */
+               if (enc_gop_reset(solo_dev, ch, vop_type))
+                       continue;
+
+               enc_buf = &solo_dev->enc_buf[solo_dev->enc_wr_idx];
+
+               enc_buf->vop = vop_type;
+               enc_buf->ch = ch;
+               enc_buf->off = mpeg_current;
+               enc_buf->size = mpeg_size;
+               enc_buf->jpeg_off = jpeg_current;
+               enc_buf->jpeg_size = jpeg_size;
+               enc_buf->type = enc_type;
+
+               do_gettimeofday(&enc_buf->ts);
+
+               solo_dev->enc_wr_idx = (solo_dev->enc_wr_idx + 1) %
+                                       SOLO_NR_RING_BUFS;
+
+               wake_up_interruptible(&solo_dev->v4l2_enc[ch]->thread_wait);
+       }
+
+       return;
+}
+
+static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count,
+                             unsigned int *size)
+{
+        *size = FRAME_BUF_SIZE;
+
+        if (*count < MIN_VID_BUFFERS)
+               *count = MIN_VID_BUFFERS;
+
+        return 0;
+}
+
+static int solo_enc_buf_prepare(struct videobuf_queue *vq,
+                               struct videobuf_buffer *vb,
+                               enum v4l2_field field)
+{
+       struct solo_enc_fh *fh = vq->priv_data;
+       struct solo_enc_dev *solo_enc = fh->enc;
+
+       vb->size = FRAME_BUF_SIZE;
+       if (vb->baddr != 0 && vb->bsize < vb->size)
+               return -EINVAL;
+
+       /* These properties only change when queue is idle */
+       vb->width = solo_enc->width;
+       vb->height = solo_enc->height;
+       vb->field  = field;
+
+       if (vb->state == VIDEOBUF_NEEDS_INIT) {
+               int rc = videobuf_iolock(vq, vb, NULL);
+               if (rc < 0) {
+                       videobuf_dma_contig_free(vq, vb);
+                       vb->state = VIDEOBUF_NEEDS_INIT;
+                       return rc;
+               }
+       }
+       vb->state = VIDEOBUF_PREPARED;
+
+       return 0;
+}
+
+static void solo_enc_buf_queue(struct videobuf_queue *vq,
+                              struct videobuf_buffer *vb)
+{
+       struct solo_enc_fh *fh = vq->priv_data;
+
+       vb->state = VIDEOBUF_QUEUED;
+       list_add_tail(&vb->queue, &fh->vidq_active);
+       wake_up_interruptible(&fh->enc->thread_wait);
+}
+
+static void solo_enc_buf_release(struct videobuf_queue *vq,
+                                struct videobuf_buffer *vb)
+{
+       videobuf_dma_contig_free(vq, vb);
+       vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static struct videobuf_queue_ops solo_enc_video_qops = {
+       .buf_setup      = solo_enc_buf_setup,
+       .buf_prepare    = solo_enc_buf_prepare,
+       .buf_queue      = solo_enc_buf_queue,
+       .buf_release    = solo_enc_buf_release,
+};
+
+static unsigned int solo_enc_poll(struct file *file,
+                                 struct poll_table_struct *wait)
+{
+       struct solo_enc_fh *fh = file->private_data;
+
+       return videobuf_poll_stream(file, &fh->vidq, wait);
+}
+
+static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct solo_enc_fh *fh = file->private_data;
+
+       return videobuf_mmap_mapper(&fh->vidq, vma);
+}
+
+static int solo_enc_open(struct file *file)
+{
+       struct solo_enc_dev *solo_enc = video_drvdata(file);
+       struct solo_enc_fh *fh;
+
+       if ((fh = kzalloc(sizeof(*fh), GFP_KERNEL)) == NULL)
+               return -ENOMEM;
+
+       spin_lock(&solo_enc->lock);
+
+       fh->enc = solo_enc;
+       file->private_data = fh;
+       INIT_LIST_HEAD(&fh->vidq_active);
+       fh->fmt = V4L2_PIX_FMT_MPEG;
+       fh->type = SOLO_ENC_TYPE_STD;
+
+       videobuf_queue_dma_contig_init(&fh->vidq, &solo_enc_video_qops,
+                                   &solo_enc->solo_dev->pdev->dev,
+                                   &solo_enc->lock,
+                                   V4L2_BUF_TYPE_VIDEO_CAPTURE,
+                                   V4L2_FIELD_INTERLACED,
+                                   sizeof(struct videobuf_buffer), fh);
+
+       spin_unlock(&solo_enc->lock);
+
+       return 0;
+}
+
+static ssize_t solo_enc_read(struct file *file, char __user *data,
+                            size_t count, loff_t *ppos)
+{
+       struct solo_enc_fh *fh = file->private_data;
+       struct solo_enc_dev *solo_enc = fh->enc;
+
+       /* Make sure the encoder is on */
+       if (!fh->enc_on) {
+               int ret;
+
+               spin_lock(&solo_enc->lock);
+               ret = solo_enc_on(fh);
+               spin_unlock(&solo_enc->lock);
+               if (ret)
+                       return ret;
+       }
+
+       return videobuf_read_stream(&fh->vidq, data, count, ppos, 0,
+                                   file->f_flags & O_NONBLOCK);
+}
+
+static int solo_enc_release(struct file *file)
+{
+       struct solo_enc_fh *fh = file->private_data;
+
+       videobuf_stop(&fh->vidq);
+       videobuf_mmap_free(&fh->vidq);
+       solo_enc_off(fh);
+       kfree(fh);
+
+       return 0;
+}
+
+static int solo_enc_querycap(struct file *file, void  *priv,
+                            struct v4l2_capability *cap)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+
+       strcpy(cap->driver, SOLO6010_NAME);
+       snprintf(cap->card, sizeof(cap->card), "Softlogic 6010 Enc %d",
+                solo_enc->ch);
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s",
+                pci_name(solo_dev->pdev));
+       cap->version = SOLO6010_VER_NUM;
+       cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
+                               V4L2_CAP_READWRITE |
+                               V4L2_CAP_STREAMING;
+       return 0;
+}
+
+static int solo_enc_enum_input(struct file *file, void *priv,
+                              struct v4l2_input *input)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+
+       if (input->index)
+               return -EINVAL;
+
+       snprintf(input->name, sizeof(input->name), "Encoder %d",
+                solo_enc->ch + 1);
+       input->type = V4L2_INPUT_TYPE_CAMERA;
+
+       if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
+               input->std = V4L2_STD_NTSC_M;
+       else
+               input->std = V4L2_STD_PAL_M;
+
+       if (!tw28_get_video_status(solo_dev, solo_enc->ch))
+               input->status = V4L2_IN_ST_NO_SIGNAL;
+
+       return 0;
+}
+
+static int solo_enc_set_input(struct file *file, void *priv, unsigned int index)
+{
+       if (index)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int solo_enc_get_input(struct file *file, void *priv,
+                             unsigned int *index)
+{
+       *index = 0;
+
+       return 0;
+}
+
+static int solo_enc_enum_fmt_cap(struct file *file, void *priv,
+                                struct v4l2_fmtdesc *f)
+{
+       switch (f->index) {
+       case 0:
+               f->pixelformat = V4L2_PIX_FMT_MPEG;
+               strcpy(f->description, "MPEG-4 AVC");
+               break;
+       case 1:
+               f->pixelformat = V4L2_PIX_FMT_MJPEG;
+               strcpy(f->description, "MJPEG");
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       f->flags = V4L2_FMT_FLAG_COMPRESSED;
+
+       return 0;
+}
+
+static int solo_enc_try_fmt_cap(struct file *file, void *priv,
+                           struct v4l2_format *f)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+
+       if (pix->pixelformat != V4L2_PIX_FMT_MPEG &&
+           pix->pixelformat != V4L2_PIX_FMT_MJPEG)
+               return -EINVAL;
+
+       /* We cannot change width/height in mid read */
+       if (atomic_read(&solo_enc->readers) > 0) {
+               if (pix->width != solo_enc->width ||
+                   pix->height != solo_enc->height)
+                       return -EBUSY;
+       } else if (!(pix->width == solo_dev->video_hsize &&
+             pix->height == solo_dev->video_vsize << 1) &&
+           !(pix->width == solo_dev->video_hsize >> 1 &&
+             pix->height == solo_dev->video_vsize)) {
+               /* Default to CIF 1/2 size */
+               pix->width = solo_dev->video_hsize >> 1;
+               pix->height = solo_dev->video_vsize;
+       }
+
+       if (pix->field == V4L2_FIELD_ANY)
+               pix->field = V4L2_FIELD_INTERLACED;
+       else if (pix->field != V4L2_FIELD_INTERLACED) {
+               pix->field = V4L2_FIELD_INTERLACED;
+       }
+
+       /* Just set these */
+       pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
+       pix->sizeimage = FRAME_BUF_SIZE;
+
+       return 0;
+}
+
+static int solo_enc_set_fmt_cap(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       int ret;
+
+       spin_lock(&solo_enc->lock);
+
+       if ((ret = solo_enc_try_fmt_cap(file, priv, f))) {
+               spin_unlock(&solo_enc->lock);
+               return ret;
+       }
+
+       if (pix->width == solo_dev->video_hsize)
+               solo_enc->mode = SOLO_ENC_MODE_D1;
+       else
+               solo_enc->mode = SOLO_ENC_MODE_CIF;
+
+       /* This does not change the encoder at all */
+       fh->fmt = pix->pixelformat;
+
+       if (pix->priv)
+               fh->type = SOLO_ENC_TYPE_EXT;
+       ret = solo_enc_on(fh);
+
+       spin_unlock(&solo_enc->lock);
+
+       return ret;
+}
+
+static int solo_enc_get_fmt_cap(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+
+       pix->width = solo_enc->width;
+       pix->height = solo_enc->height;
+       pix->pixelformat = fh->fmt;
+       pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED :
+                    V4L2_FIELD_NONE;
+       pix->sizeimage = FRAME_BUF_SIZE;
+       pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+       return 0;
+}
+
+static int solo_enc_reqbufs(struct file *file, void *priv, 
+                           struct v4l2_requestbuffers *req)
+{
+       struct solo_enc_fh *fh = priv;
+
+       return videobuf_reqbufs(&fh->vidq, req);
+}
+
+static int solo_enc_querybuf(struct file *file, void *priv,
+                            struct v4l2_buffer *buf)
+{
+       struct solo_enc_fh *fh = priv;
+
+       return videobuf_querybuf(&fh->vidq, buf);
+}
+
+static int solo_enc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct solo_enc_fh *fh = priv;
+
+       return videobuf_qbuf(&fh->vidq, buf);
+}
+
+static int solo_enc_dqbuf(struct file *file, void *priv,
+                         struct v4l2_buffer *buf)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       int ret;
+
+       /* Make sure the encoder is on */
+       if (!fh->enc_on) {
+               spin_lock(&solo_enc->lock);
+               ret = solo_enc_on(fh);
+               spin_unlock(&solo_enc->lock);
+               if (ret)
+                       return ret;
+       }
+
+       ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK);
+       if (ret)
+               return ret;
+
+       /* Signal motion detection */
+       if (solo_is_motion_on(solo_enc)) {
+               buf->flags |= V4L2_BUF_FLAG_MOTION_ON;
+               if (solo_enc->motion_detected) {
+                       buf->flags |= V4L2_BUF_FLAG_MOTION_DETECTED;
+                       solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR,
+                                      1 << solo_enc->ch);
+                       solo_enc->motion_detected = 0;
+               }
+       }
+
+       /* Check for key frame on mpeg data */
+       if (fh->fmt == V4L2_PIX_FMT_MPEG) {
+               struct videobuf_buffer *vb = fh->vidq.bufs[buf->index];
+               u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
+               if (p[3] == 0x00)
+                       buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+               else
+                       buf->flags |= V4L2_BUF_FLAG_PFRAME;
+       }
+
+       return 0;
+}
+
+static int solo_enc_streamon(struct file *file, void *priv,
+                            enum v4l2_buf_type i)
+{
+       struct solo_enc_fh *fh = priv;
+
+       if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       return videobuf_streamon(&fh->vidq);
+}
+
+static int solo_enc_streamoff(struct file *file, void *priv,
+                             enum v4l2_buf_type i)
+{
+       struct solo_enc_fh *fh = priv;
+
+       if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       return videobuf_streamoff(&fh->vidq);
+}
+
+static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id *i)
+{
+       return 0;
+}
+
+static int solo_enum_framesizes(struct file *file, void *priv,
+                               struct v4l2_frmsizeenum *fsize)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo6010_dev *solo_dev = fh->enc->solo_dev;
+
+       if (fsize->pixel_format != V4L2_PIX_FMT_MPEG)
+               return -EINVAL;
+
+       switch (fsize->index) {
+       case 0:
+               fsize->discrete.width = solo_dev->video_hsize >> 1;
+               fsize->discrete.height = solo_dev->video_vsize;
+               break;
+       case 1:
+               fsize->discrete.width = solo_dev->video_hsize;
+               fsize->discrete.height = solo_dev->video_vsize << 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+
+       return 0;
+}
+
+static int solo_enum_frameintervals(struct file *file, void *priv,
+                                   struct v4l2_frmivalenum *fintv)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo6010_dev *solo_dev = fh->enc->solo_dev;
+
+       if (fintv->pixel_format != V4L2_PIX_FMT_MPEG || fintv->index)
+               return -EINVAL;
+
+       fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+
+       fintv->stepwise.min.numerator = solo_dev->fps;
+       fintv->stepwise.min.denominator = 1;
+
+       fintv->stepwise.max.numerator = solo_dev->fps;
+       fintv->stepwise.max.denominator = 15;
+
+       fintv->stepwise.step.numerator = 1;
+       fintv->stepwise.step.denominator = 1;
+
+       return 0;
+}
+
+static int solo_g_parm(struct file *file, void *priv,
+                      struct v4l2_streamparm *sp)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       struct v4l2_captureparm *cp = &sp->parm.capture;
+
+       cp->capability = V4L2_CAP_TIMEPERFRAME;
+       cp->timeperframe.numerator = solo_enc->interval;
+       cp->timeperframe.denominator = solo_dev->fps;
+       cp->capturemode = 0;
+       /* XXX: Shouldn't we be able to get/set this from videobuf? */
+       cp->readbuffers = 2;
+
+        return 0;
+}
+
+static int solo_s_parm(struct file *file, void *priv,
+                      struct v4l2_streamparm *sp)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+       struct v4l2_captureparm *cp = &sp->parm.capture;
+
+       spin_lock(&solo_enc->lock);
+
+       if (atomic_read(&solo_enc->readers) > 0) {
+               spin_unlock(&solo_enc->lock);
+               return -EBUSY;
+       }
+
+       if ((cp->timeperframe.numerator == 0) ||
+           (cp->timeperframe.denominator == 0)) {
+               /* reset framerate */
+               cp->timeperframe.numerator = 1;
+               cp->timeperframe.denominator = solo_dev->fps;
+       }
+
+       if (cp->timeperframe.denominator != solo_dev->fps)
+               cp->timeperframe.denominator = solo_dev->fps;
+
+       if (cp->timeperframe.numerator > 15)
+               cp->timeperframe.numerator = 15;
+
+       solo_enc->interval = cp->timeperframe.numerator;
+
+       cp->capability = V4L2_CAP_TIMEPERFRAME;
+
+       solo_enc->gop = max(solo_dev->fps / solo_enc->interval, 1);
+       solo_update_mode(solo_enc);
+
+       spin_unlock(&solo_enc->lock);
+
+        return 0;
+}
+
+static int solo_queryctrl(struct file *file, void *priv,
+                         struct v4l2_queryctrl *qc)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+
+       qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id);
+       if (!qc->id)
+               return -EINVAL;
+
+       switch (qc->id) {
+       case V4L2_CID_BRIGHTNESS:
+       case V4L2_CID_CONTRAST:
+       case V4L2_CID_SATURATION:
+       case V4L2_CID_HUE:
+               return v4l2_ctrl_query_fill(qc, 0x00, 0xff, 1, 0x80);
+       case V4L2_CID_SHARPNESS:
+               return v4l2_ctrl_query_fill(qc, 0x00, 0x0f, 1, 0x00);
+       case V4L2_CID_MPEG_VIDEO_ENCODING:
+               return v4l2_ctrl_query_fill(
+                       qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
+                       V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
+                       V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
+       case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+               return v4l2_ctrl_query_fill(qc, 1, 255, 1, solo_dev->fps);
+#ifdef PRIVATE_CIDS
+       case V4L2_CID_MOTION_THRESHOLD:
+               qc->flags |= V4L2_CTRL_FLAG_SLIDER;
+               qc->type = V4L2_CTRL_TYPE_INTEGER;
+               qc->minimum = 0;
+               qc->maximum = 0xffff;
+               qc->step = 1;
+               qc->default_value = SOLO_DEF_MOT_THRESH;
+               strlcpy(qc->name, "Motion Detection Threshold",
+                       sizeof(qc->name));
+               return 0;
+       case V4L2_CID_MOTION_ENABLE:
+               qc->type = V4L2_CTRL_TYPE_BOOLEAN;
+               qc->minimum = 0;
+               qc->maximum = qc->step = 1;
+               qc->default_value = 0;
+               strlcpy(qc->name, "Motion Detection Enable", sizeof(qc->name));
+               return 0;
+#else
+       case V4L2_CID_MOTION_THRESHOLD:
+               return v4l2_ctrl_query_fill(qc, 0, 0xffff, 1,
+                                           SOLO_DEF_MOT_THRESH);
+       case V4L2_CID_MOTION_ENABLE:
+               return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+#endif
+       case V4L2_CID_RDS_TX_RADIO_TEXT:
+               qc->type = V4L2_CTRL_TYPE_STRING;
+               qc->minimum = 0;
+               qc->maximum = OSD_TEXT_MAX;
+               qc->step = 1;
+               qc->default_value = 0;
+               strlcpy(qc->name, "OSD Text", sizeof(qc->name));
+               return 0;
+       }
+
+        return -EINVAL;
+}
+
+static int solo_querymenu(struct file *file, void *priv,
+                         struct v4l2_querymenu *qmenu)
+{
+       struct v4l2_queryctrl qctrl;
+       int err;
+
+       qctrl.id = qmenu->id;
+       if ((err = solo_queryctrl(file, priv, &qctrl)))
+               return err;
+
+       return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
+}
+
+static int solo_g_ctrl(struct file *file, void *priv,
+                      struct v4l2_control *ctrl)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+
+       switch (ctrl->id) {
+       case V4L2_CID_BRIGHTNESS:
+       case V4L2_CID_CONTRAST:
+       case V4L2_CID_SATURATION:
+       case V4L2_CID_HUE:
+       case V4L2_CID_SHARPNESS:
+               return tw28_get_ctrl_val(solo_dev, ctrl->id, solo_enc->ch,
+                                        &ctrl->value);
+       case V4L2_CID_MPEG_VIDEO_ENCODING:
+               ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
+               break;
+       case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+               ctrl->value = solo_enc->gop;
+               break;
+       case V4L2_CID_MOTION_THRESHOLD:
+               ctrl->value = solo_enc->motion_thresh;
+               break;
+       case V4L2_CID_MOTION_ENABLE:
+               ctrl->value = solo_is_motion_on(solo_enc);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int solo_s_ctrl(struct file *file, void *priv,
+                      struct v4l2_control *ctrl)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       struct solo6010_dev *solo_dev = solo_enc->solo_dev;
+
+       switch (ctrl->id) {
+       case V4L2_CID_BRIGHTNESS:
+       case V4L2_CID_CONTRAST:
+       case V4L2_CID_SATURATION:
+       case V4L2_CID_HUE:
+       case V4L2_CID_SHARPNESS:
+               return tw28_set_ctrl_val(solo_dev, ctrl->id, solo_enc->ch,
+                                        ctrl->value);
+       case V4L2_CID_MPEG_VIDEO_ENCODING:
+               if (ctrl->value != V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
+                       return -ERANGE;
+               break;
+       case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+               if (ctrl->value < 1 || ctrl->value > 255)
+                       return -ERANGE;
+               solo_enc->gop = ctrl->value;
+               solo_reg_write(solo_dev, SOLO_VE_CH_GOP(solo_enc->ch),
+                              solo_enc->gop);
+               solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(solo_enc->ch),
+                              solo_enc->gop);
+               break;
+       case V4L2_CID_MOTION_THRESHOLD:
+               /* TODO accept value on lower 16-bits and use high
+                * 16-bits to assign the value to a specific block */
+               if (ctrl->value < 0 || ctrl->value > 0xffff)
+                       return -ERANGE;
+               solo_enc->motion_thresh = ctrl->value;
+               solo_set_motion_threshold(solo_dev, solo_enc->ch, ctrl->value);
+               break;
+       case V4L2_CID_MOTION_ENABLE:
+               solo_motion_toggle(solo_enc, ctrl->value);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int solo_s_ext_ctrls(struct file *file, void *priv,
+                           struct v4l2_ext_controls *ctrls)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       int i;
+
+       for (i = 0; i < ctrls->count; i++) {
+               struct v4l2_ext_control *ctrl = (ctrls->controls + i);
+               int err;
+
+               switch (ctrl->id) {
+               case V4L2_CID_RDS_TX_RADIO_TEXT:
+                       if (ctrl->size - 1 > OSD_TEXT_MAX)
+                                err = -ERANGE;
+                       else {
+                               err = copy_from_user(solo_enc->osd_text,
+                                                    ctrl->string,
+                                                    OSD_TEXT_MAX);
+                               solo_enc->osd_text[OSD_TEXT_MAX] = '\0';
+                               if (!err)
+                                       err = solo_osd_print(solo_enc);
+                       }
+                       break;
+               default:
+                       err = -EINVAL;
+               }
+
+               if (err < 0) {
+                       ctrls->error_idx = i;
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
+static int solo_g_ext_ctrls(struct file *file, void *priv,
+                           struct v4l2_ext_controls *ctrls)
+{
+       struct solo_enc_fh *fh = priv;
+       struct solo_enc_dev *solo_enc = fh->enc;
+       int i;
+
+       for (i = 0; i < ctrls->count; i++) {
+               struct v4l2_ext_control *ctrl = (ctrls->controls + i);
+               int err;
+
+               switch (ctrl->id) {
+               case V4L2_CID_RDS_TX_RADIO_TEXT:
+                       if (ctrl->size < OSD_TEXT_MAX) {
+                               ctrl->size = OSD_TEXT_MAX;
+                               err = -ENOSPC;
+                       } else {
+                               err = copy_to_user(ctrl->string,
+                                                  solo_enc->osd_text,
+                                                  OSD_TEXT_MAX);
+                       }
+                       break;
+               default:
+                       err = -EINVAL;
+               }
+
+               if (err < 0) {
+                       ctrls->error_idx = i;
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
+static const struct v4l2_file_operations solo_enc_fops = {
+       .owner                  = THIS_MODULE,
+       .open                   = solo_enc_open,
+       .release                = solo_enc_release,
+       .read                   = solo_enc_read,
+       .poll                   = solo_enc_poll,
+       .mmap                   = solo_enc_mmap,
+       .ioctl                  = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = {
+       .vidioc_querycap                = solo_enc_querycap,
+       .vidioc_s_std                   = solo_enc_s_std,
+       /* Input callbacks */
+       .vidioc_enum_input              = solo_enc_enum_input,
+       .vidioc_s_input                 = solo_enc_set_input,
+       .vidioc_g_input                 = solo_enc_get_input,
+       /* Video capture format callbacks */
+       .vidioc_enum_fmt_vid_cap        = solo_enc_enum_fmt_cap,
+       .vidioc_try_fmt_vid_cap         = solo_enc_try_fmt_cap,
+       .vidioc_s_fmt_vid_cap           = solo_enc_set_fmt_cap,
+       .vidioc_g_fmt_vid_cap           = solo_enc_get_fmt_cap,
+       /* Streaming I/O */
+       .vidioc_reqbufs                 = solo_enc_reqbufs,
+       .vidioc_querybuf                = solo_enc_querybuf,
+       .vidioc_qbuf                    = solo_enc_qbuf,
+       .vidioc_dqbuf                   = solo_enc_dqbuf,
+       .vidioc_streamon                = solo_enc_streamon,
+       .vidioc_streamoff               = solo_enc_streamoff,
+       /* Frame size and interval */
+       .vidioc_enum_framesizes         = solo_enum_framesizes,
+       .vidioc_enum_frameintervals     = solo_enum_frameintervals,
+       /* Video capture parameters */
+       .vidioc_s_parm                  = solo_s_parm,
+       .vidioc_g_parm                  = solo_g_parm,
+       /* Controls */
+       .vidioc_queryctrl               = solo_queryctrl,
+       .vidioc_querymenu               = solo_querymenu,
+       .vidioc_g_ctrl                  = solo_g_ctrl,
+       .vidioc_s_ctrl                  = solo_s_ctrl,
+       .vidioc_g_ext_ctrls             = solo_g_ext_ctrls,
+       .vidioc_s_ext_ctrls             = solo_s_ext_ctrls,
+};
+
+static struct video_device solo_enc_template = {
+       .name                   = SOLO6010_NAME,
+       .fops                   = &solo_enc_fops,
+       .ioctl_ops              = &solo_enc_ioctl_ops,
+       .minor                  = -1,
+       .release                = video_device_release,
+
+       .tvnorms                = V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
+       .current_norm           = V4L2_STD_NTSC_M,
+};
+
+static struct solo_enc_dev *solo_enc_alloc(struct solo6010_dev *solo_dev, u8 ch)
+{
+       struct solo_enc_dev *solo_enc;
+       int ret;
+
+       solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL);
+       if (!solo_enc)
+               return ERR_PTR(-ENOMEM);
+
+       solo_enc->vfd = video_device_alloc();
+       if (!solo_enc->vfd) {
+               kfree(solo_enc);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       solo_enc->solo_dev = solo_dev;
+       solo_enc->ch = ch;
+
+       *solo_enc->vfd = solo_enc_template;
+       solo_enc->vfd->parent = &solo_dev->pdev->dev;
+       ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER,
+                                   video_nr);
+       if (ret < 0) {
+               video_device_release(solo_enc->vfd);
+               kfree(solo_enc);
+               return ERR_PTR(ret);
+       }
+
+       video_set_drvdata(solo_enc->vfd, solo_enc);
+
+       snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name),
+                "%s-enc (%i/%i)", SOLO6010_NAME, solo_dev->vfd->num,
+                solo_enc->vfd->num);
+
+       if (video_nr >= 0)
+               video_nr++;
+
+       spin_lock_init(&solo_enc->lock);
+       init_waitqueue_head(&solo_enc->thread_wait);
+       atomic_set(&solo_enc->readers, 0);
+
+       solo_enc->qp = SOLO_DEFAULT_QP;
+        solo_enc->gop = solo_dev->fps;
+       solo_enc->interval = 1;
+       solo_enc->mode = SOLO_ENC_MODE_CIF;
+       solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH;
+
+       spin_lock(&solo_enc->lock);
+       solo_update_mode(solo_enc);
+       spin_unlock(&solo_enc->lock);
+
+       return solo_enc;
+}
+
+static void solo_enc_free(struct solo_enc_dev *solo_enc)
+{
+       if (solo_enc == NULL)
+               return;
+
+       video_unregister_device(solo_enc->vfd);
+       kfree(solo_enc);
+}
+
+int solo_enc_v4l2_init(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               solo_dev->v4l2_enc[i] = solo_enc_alloc(solo_dev, i);
+               if (IS_ERR(solo_dev->v4l2_enc[i]))
+                       break;
+       }
+
+       if (i != solo_dev->nr_chans) {
+               int ret = PTR_ERR(solo_dev->v4l2_enc[i]);
+               while (i--)
+                       solo_enc_free(solo_dev->v4l2_enc[i]);
+               return ret;
+       }
+
+       /* D1@MAX-FPS * 4 */
+       solo_dev->enc_bw_remain = solo_dev->fps * 4 * 4;
+
+       dev_info(&solo_dev->pdev->dev, "Encoders as /dev/video%d-%d\n",
+                solo_dev->v4l2_enc[0]->vfd->num,
+                solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num);
+
+       return 0;
+}
+
+void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev)
+{
+       int i;
+
+       solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION);
+
+       for (i = 0; i < solo_dev->nr_chans; i++)
+               solo_enc_free(solo_dev->v4l2_enc[i]);
+}
diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c
new file mode 100644 (file)
index 0000000..9537cc6
--- /dev/null
@@ -0,0 +1,859 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-common.h>
+#include <media/videobuf-dma-contig.h>
+
+#include "solo6010.h"
+#include "solo6010-tw28.h"
+
+#define SOLO_HW_BPL            2048
+#define SOLO_DISP_PIX_FIELD    V4L2_FIELD_INTERLACED
+#define SOLO_DISP_BUF_SIZE     (64 * 1024) // 64k
+
+/* Image size is two fields, SOLO_HW_BPL is one horizontal line */
+#define solo_vlines(__solo)    (__solo->video_vsize * 2)
+#define solo_image_size(__solo) (solo_bytesperline(__solo) * \
+                                solo_vlines(__solo))
+#define solo_bytesperline(__solo) (__solo->video_hsize * 2)
+
+#define MIN_VID_BUFFERS                4
+
+/* Simple file handle */
+struct solo_filehandle {
+       struct solo6010_dev     *solo_dev;
+       struct videobuf_queue   vidq;
+       struct task_struct      *kthread;
+       spinlock_t              slock;
+       int                     old_write;
+       struct list_head        vidq_active;
+};
+
+unsigned video_nr = -1;
+module_param(video_nr, uint, 0644);
+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect (default)");
+
+static void erase_on(struct solo6010_dev *solo_dev)
+{
+       solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON);
+       solo_dev->erasing = 1;
+       solo_dev->frame_blank = 0;
+}
+
+static int erase_off(struct solo6010_dev *solo_dev)
+{
+       if (!solo_dev->erasing)
+               return 0;
+
+       /* First time around, assert erase off */
+       if (!solo_dev->frame_blank)
+               solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, 0);
+       /* Keep the erasing flag on for 8 frames minimum */
+       if (solo_dev->frame_blank++ >= 8)
+               solo_dev->erasing = 0;
+
+       return 1;
+}
+
+void solo_video_in_isr(struct solo6010_dev *solo_dev)
+{
+       solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_VIDEO_IN);
+       wake_up_interruptible(&solo_dev->disp_thread_wait);
+}
+
+static void solo_win_setup(struct solo6010_dev *solo_dev, u8 ch,
+                          int sx, int sy, int ex, int ey, int scale)
+{
+       if (ch >= solo_dev->nr_chans)
+               return;
+
+       /* Here, we just keep window/channel the same */
+       solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(ch),
+                      SOLO_VI_WIN_CHANNEL(ch) |
+                      SOLO_VI_WIN_SX(sx) |
+                      SOLO_VI_WIN_EX(ex) |
+                      SOLO_VI_WIN_SCALE(scale));
+
+        solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch),
+                      SOLO_VI_WIN_SY(sy) |
+                      SOLO_VI_WIN_EY(ey));
+}
+
+static int solo_v4l2_ch_ext_4up(struct solo6010_dev *solo_dev, u8 idx, int on)
+{
+       u8 ch = idx * 4;
+
+       if (ch >= solo_dev->nr_chans)
+               return -EINVAL;
+
+       if (!on) {
+               u8 i;
+               for (i = ch; i < ch + 4; i++)
+                       solo_win_setup(solo_dev, i, solo_dev->video_hsize,
+                                      solo_vlines(solo_dev),
+                                      solo_dev->video_hsize,
+                                      solo_vlines(solo_dev), 0);
+               return 0;
+       }
+
+       /* Row 1 */
+       solo_win_setup(solo_dev, ch, 0, 0, solo_dev->video_hsize / 2,
+                      solo_vlines(solo_dev) / 2, 3);
+       solo_win_setup(solo_dev, ch + 1, solo_dev->video_hsize / 2, 0,
+                      solo_dev->video_hsize, solo_vlines(solo_dev) / 2, 3);
+       /* Row 2 */
+       solo_win_setup(solo_dev, ch + 2, 0, solo_vlines(solo_dev) / 2,
+                      solo_dev->video_hsize / 2, solo_vlines(solo_dev), 3);
+       solo_win_setup(solo_dev, ch + 3, solo_dev->video_hsize / 2,
+                      solo_vlines(solo_dev) / 2, solo_dev->video_hsize,
+                      solo_vlines(solo_dev), 3);
+
+       return 0;
+}
+
+static int solo_v4l2_ch_ext_16up(struct solo6010_dev *solo_dev, int on)
+{
+       int sy, ysize, hsize, i;
+
+       if (!on) {
+               for (i = 0; i < 16; i++)
+                       solo_win_setup(solo_dev, i, solo_dev->video_hsize,
+                                      solo_vlines(solo_dev),
+                                      solo_dev->video_hsize,
+                                      solo_vlines(solo_dev), 0);
+               return 0;
+       }
+
+       ysize = solo_vlines(solo_dev) / 4;
+       hsize = solo_dev->video_hsize / 4;
+
+       for (sy = 0, i = 0; i < 4; i++, sy += ysize) {
+               solo_win_setup(solo_dev, i * 4, 0, sy, hsize,
+                              sy + ysize, 5);
+               solo_win_setup(solo_dev, (i * 4) + 1, hsize, sy,
+                              hsize * 2, sy + ysize, 5);
+               solo_win_setup(solo_dev, (i * 4) + 2, hsize * 2, sy,
+                              hsize * 3, sy + ysize, 5);
+               solo_win_setup(solo_dev, (i * 4) + 3, hsize * 3, sy,
+                              solo_dev->video_hsize, sy + ysize, 5);
+       }
+
+       return 0;
+}
+
+static int solo_v4l2_ch(struct solo6010_dev *solo_dev, u8 ch, int on)
+{
+       u8 ext_ch;
+
+       if (ch < solo_dev->nr_chans) {
+               solo_win_setup(solo_dev, ch, on ? 0 : solo_dev->video_hsize,
+                              on ? 0 : solo_vlines(solo_dev),
+                              solo_dev->video_hsize, solo_vlines(solo_dev),
+                              on ? 1 : 0);
+               return 0;
+       }
+
+       if (ch >= solo_dev->nr_chans + solo_dev->nr_ext)
+               return -EINVAL;
+
+       ext_ch = ch - solo_dev->nr_chans;
+
+       /* 4up's first */
+       if (ext_ch < 4)
+               return solo_v4l2_ch_ext_4up(solo_dev, ext_ch, on);
+
+       /* Remaining case is 16up for 16-port */
+       return solo_v4l2_ch_ext_16up(solo_dev, on);
+}
+
+static int solo_v4l2_set_ch(struct solo6010_dev *solo_dev, u8 ch)
+{
+       if (ch >= solo_dev->nr_chans + solo_dev->nr_ext)
+               return -EINVAL;
+
+       erase_on(solo_dev);
+
+       solo_v4l2_ch(solo_dev, solo_dev->cur_disp_ch, 0);
+       solo_v4l2_ch(solo_dev, ch, 1);
+
+       solo_dev->cur_disp_ch = ch;
+
+       return 0;
+}
+
+static void solo_fillbuf(struct solo_filehandle *fh,
+                        struct videobuf_buffer *vb)
+{
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+       dma_addr_t vbuf;
+       unsigned int fdma_addr;
+       int frame_size;
+       int error = 1;
+       int i;
+
+       if (!(vbuf = videobuf_to_dma_contig(vb)))
+               goto finish_buf;
+
+       if (erase_off(solo_dev)) {
+               void *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
+               int image_size = solo_image_size(solo_dev);
+               for (i = 0; i < image_size; i += 2) {
+                       ((u8 *)p)[i] = 0x80;
+                       ((u8 *)p)[i + 1] = 0x00;
+               }
+               error = 0;
+               goto finish_buf;
+       }
+
+       frame_size = SOLO_HW_BPL * solo_vlines(solo_dev);
+       fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write * frame_size);
+
+       for (i = 0; i < frame_size / SOLO_DISP_BUF_SIZE; i++) {
+               int j;
+               for (j = 0; j < (SOLO_DISP_BUF_SIZE / SOLO_HW_BPL); j++) {
+                       if (solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_DISP, 0,
+                                          vbuf, fdma_addr + (j * SOLO_HW_BPL),
+                                          solo_bytesperline(solo_dev)))
+                               goto finish_buf;
+                       vbuf += solo_bytesperline(solo_dev);
+               }
+               fdma_addr += SOLO_DISP_BUF_SIZE;
+       }
+       error = 0;
+
+finish_buf:
+       if (error) {
+               vb->state = VIDEOBUF_ERROR;
+       } else {
+               vb->state = VIDEOBUF_DONE;
+               vb->field_count++;
+               do_gettimeofday(&vb->ts);
+       }
+
+       wake_up(&vb->done);
+
+       return;
+}
+
+static void solo_thread_try(struct solo_filehandle *fh)
+{
+       struct videobuf_buffer *vb;
+       unsigned int cur_write;
+
+       for (;;) {
+               spin_lock(&fh->slock);
+
+               if (list_empty(&fh->vidq_active))
+                       break;
+
+               vb = list_first_entry(&fh->vidq_active, struct videobuf_buffer,
+                                     queue);
+
+               if (!waitqueue_active(&vb->done))
+                       break;
+
+               cur_write = SOLO_VI_STATUS0_PAGE(solo_reg_read(fh->solo_dev,
+                                                       SOLO_VI_STATUS0));
+               if (cur_write == fh->old_write)
+                       break;
+
+               fh->old_write = cur_write;
+               list_del(&vb->queue);
+
+               spin_unlock(&fh->slock);
+
+               solo_fillbuf(fh, vb);
+       }
+
+       assert_spin_locked(&fh->slock);
+       spin_unlock(&fh->slock);
+}
+
+static int solo_thread(void *data)
+{
+       struct solo_filehandle *fh = data;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+       DECLARE_WAITQUEUE(wait, current);
+
+       set_freezable();
+       add_wait_queue(&solo_dev->disp_thread_wait, &wait);
+
+       for (;;) {
+               long timeout = schedule_timeout_interruptible(HZ);
+               if (timeout == -ERESTARTSYS || kthread_should_stop())
+                       break;
+               solo_thread_try(fh);
+               try_to_freeze();
+       }
+
+       remove_wait_queue(&solo_dev->disp_thread_wait, &wait);
+
+        return 0;
+}
+
+static int solo_start_thread(struct solo_filehandle *fh)
+{
+       fh->kthread = kthread_run(solo_thread, fh, SOLO6010_NAME "_disp");
+
+       if (IS_ERR(fh->kthread))
+               return PTR_ERR(fh->kthread);
+
+       return 0;
+}
+
+static void solo_stop_thread(struct solo_filehandle *fh)
+{
+       if (fh->kthread) {
+               kthread_stop(fh->kthread);
+               fh->kthread = NULL;
+       }
+}
+
+static int solo_buf_setup(struct videobuf_queue *vq, unsigned int *count,
+                         unsigned int *size)
+{
+       struct solo_filehandle *fh = vq->priv_data;
+       struct solo6010_dev *solo_dev  = fh->solo_dev;
+
+        *size = solo_image_size(solo_dev);
+
+        if (*count < MIN_VID_BUFFERS)
+               *count = MIN_VID_BUFFERS;
+
+        return 0;
+}
+
+static int solo_buf_prepare(struct videobuf_queue *vq,
+                           struct videobuf_buffer *vb, enum v4l2_field field)
+{
+       struct solo_filehandle *fh  = vq->priv_data;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+
+       vb->size = solo_image_size(solo_dev);
+       if (vb->baddr != 0 && vb->bsize < vb->size)
+               return -EINVAL;
+
+       /* XXX: These properties only change when queue is idle */
+       vb->width  = solo_dev->video_hsize;
+       vb->height = solo_vlines(solo_dev);
+       vb->bytesperline = solo_bytesperline(solo_dev);
+       vb->field  = field;
+
+       if (vb->state == VIDEOBUF_NEEDS_INIT) {
+               int rc = videobuf_iolock(vq, vb, NULL);
+               if (rc < 0) {
+                       videobuf_dma_contig_free(vq, vb);
+                       vb->state = VIDEOBUF_NEEDS_INIT;
+                       return rc;
+               }
+       }
+       vb->state = VIDEOBUF_PREPARED;
+
+       return 0;
+}
+
+static void solo_buf_queue(struct videobuf_queue *vq,
+                          struct videobuf_buffer *vb)
+{
+       struct solo_filehandle *fh = vq->priv_data;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+
+       vb->state = VIDEOBUF_QUEUED;
+       list_add_tail(&vb->queue, &fh->vidq_active);
+       wake_up_interruptible(&solo_dev->disp_thread_wait);
+}
+
+static void solo_buf_release(struct videobuf_queue *vq,
+                            struct videobuf_buffer *vb)
+{
+       videobuf_dma_contig_free(vq, vb);
+       vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static struct videobuf_queue_ops solo_video_qops = {
+       .buf_setup      = solo_buf_setup,
+       .buf_prepare    = solo_buf_prepare,
+       .buf_queue      = solo_buf_queue,
+       .buf_release    = solo_buf_release,
+};
+
+static unsigned int solo_v4l2_poll(struct file *file,
+                                  struct poll_table_struct *wait)
+{
+       struct solo_filehandle *fh = file->private_data;
+
+        return videobuf_poll_stream(file, &fh->vidq, wait);
+}
+
+static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct solo_filehandle *fh = file->private_data;
+
+       return videobuf_mmap_mapper(&fh->vidq, vma);
+}
+
+static int solo_v4l2_open(struct file *file)
+{
+       struct solo6010_dev *solo_dev = video_drvdata(file);
+       struct solo_filehandle *fh;
+       int ret;
+
+       if ((fh = kzalloc(sizeof(*fh), GFP_KERNEL)) == NULL)
+               return -ENOMEM;
+
+       spin_lock_init(&fh->slock);
+       INIT_LIST_HEAD(&fh->vidq_active);
+       fh->solo_dev = solo_dev;
+       file->private_data = fh;
+
+       if ((ret = solo_start_thread(fh))) {
+               kfree(fh);
+               return ret;
+       }
+
+       videobuf_queue_dma_contig_init(&fh->vidq, &solo_video_qops,
+                                   &solo_dev->pdev->dev, &fh->slock,
+                                   V4L2_BUF_TYPE_VIDEO_CAPTURE,
+                                   SOLO_DISP_PIX_FIELD,
+                                   sizeof(struct videobuf_buffer), fh);
+
+       return 0;
+}
+
+static ssize_t solo_v4l2_read(struct file *file, char __user *data,
+                             size_t count, loff_t *ppos)
+{
+       struct solo_filehandle *fh = file->private_data;
+
+       return videobuf_read_stream(&fh->vidq, data, count, ppos, 0,
+                                   file->f_flags & O_NONBLOCK);
+}
+
+static int solo_v4l2_release(struct file *file)
+{
+       struct solo_filehandle *fh = file->private_data;
+
+       videobuf_stop(&fh->vidq);
+       videobuf_mmap_free(&fh->vidq);
+       solo_stop_thread(fh);
+       kfree(fh);
+
+       return 0;
+}
+
+static int solo_querycap(struct file *file, void  *priv,
+                        struct v4l2_capability *cap)
+{
+       struct solo_filehandle  *fh  = priv;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+
+       strcpy(cap->driver, SOLO6010_NAME);
+       strcpy(cap->card, "Softlogic 6010");
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s",
+                pci_name(solo_dev->pdev));
+       cap->version = SOLO6010_VER_NUM;
+       cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
+                               V4L2_CAP_READWRITE |
+                               V4L2_CAP_STREAMING;
+       return 0;
+}
+
+static int solo_enum_ext_input(struct solo6010_dev *solo_dev,
+                              struct v4l2_input *input)
+{
+       static const char *dispnames_1[] = { "4UP" };
+       static const char *dispnames_2[] = { "4UP-1", "4UP-2" };
+       static const char *dispnames_5[] = {
+               "4UP-1", "4UP-2", "4UP-3", "4UP-4", "16UP"
+       };
+       const char **dispnames;
+
+       if (input->index >= (solo_dev->nr_chans + solo_dev->nr_ext))
+               return -EINVAL;
+
+       if (solo_dev->nr_ext == 5)
+               dispnames = dispnames_5;
+       else if (solo_dev->nr_ext == 2)
+               dispnames = dispnames_2;
+       else
+               dispnames = dispnames_1;
+
+       snprintf(input->name, sizeof(input->name), "Multi %s",
+                dispnames[input->index - solo_dev->nr_chans]);
+
+       return 0;
+}
+
+static int solo_enum_input(struct file *file, void *priv,
+                          struct v4l2_input *input)
+{
+       struct solo_filehandle *fh  = priv;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+
+       if (input->index >= solo_dev->nr_chans) {
+               int ret = solo_enum_ext_input(solo_dev, input);
+               if (ret < 0)
+                       return ret;
+       } else {
+               snprintf(input->name, sizeof(input->name), "Camera %d",
+                        input->index + 1);
+
+               /* We can only check this for normal inputs */
+               if (!tw28_get_video_status(solo_dev, input->index))
+                       input->status = V4L2_IN_ST_NO_SIGNAL;
+       }
+
+       input->type = V4L2_INPUT_TYPE_CAMERA;
+
+       if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
+               input->std = V4L2_STD_NTSC_M;
+       else
+               input->std = V4L2_STD_PAL_M;
+
+       return 0;
+}
+
+static int solo_set_input(struct file *file, void *priv, unsigned int index)
+{
+       struct solo_filehandle *fh = priv;
+
+       return solo_v4l2_set_ch(fh->solo_dev, index);
+}
+
+static int solo_get_input(struct file *file, void *priv, unsigned int *index)
+{
+       struct solo_filehandle *fh = priv;
+
+       *index = fh->solo_dev->cur_disp_ch;
+
+       return 0;
+}
+
+static int solo_enum_fmt_cap(struct file *file, void *priv,
+                            struct v4l2_fmtdesc *f)
+{
+       if (f->index)
+               return -EINVAL;
+
+       f->pixelformat = V4L2_PIX_FMT_UYVY;
+       strlcpy(f->description, "UYUV 4:2:2 Packed", sizeof(f->description));
+
+       return 0;
+}
+
+static int solo_try_fmt_cap(struct file *file, void *priv,
+                           struct v4l2_format *f)
+{
+       struct solo_filehandle *fh = priv;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       int image_size = solo_image_size(solo_dev);
+
+       /* Check supported sizes */
+       if (pix->width != solo_dev->video_hsize)
+               pix->width = solo_dev->video_hsize;
+       if (pix->height != solo_vlines(solo_dev))
+               pix->height = solo_vlines(solo_dev);
+       if (pix->sizeimage != image_size)
+               pix->sizeimage = image_size;
+
+       /* Check formats */
+       if (pix->field == V4L2_FIELD_ANY)
+               pix->field = SOLO_DISP_PIX_FIELD;
+
+       if (pix->pixelformat != V4L2_PIX_FMT_UYVY ||
+           pix->field       != SOLO_DISP_PIX_FIELD ||
+           pix->colorspace  != V4L2_COLORSPACE_SMPTE170M)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int solo_set_fmt_cap(struct file *file, void *priv,
+                           struct v4l2_format *f)
+{
+       struct solo_filehandle *fh = priv;
+
+       if (videobuf_queue_is_busy(&fh->vidq))
+               return -EBUSY;
+
+       /* For right now, if it doesn't match our running config,
+        * then fail */
+       return solo_try_fmt_cap(file, priv, f);
+}
+
+static int solo_get_fmt_cap(struct file *file, void *priv,
+                           struct v4l2_format *f)
+{
+       struct solo_filehandle *fh = priv;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+
+       pix->width = solo_dev->video_hsize;
+       pix->height = solo_vlines(solo_dev);
+       pix->pixelformat = V4L2_PIX_FMT_UYVY;
+       pix->field = SOLO_DISP_PIX_FIELD;
+       pix->sizeimage = solo_image_size(solo_dev);
+       pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
+       pix->bytesperline = solo_bytesperline(solo_dev);
+
+       return 0;
+}
+
+static int solo_reqbufs(struct file *file, void *priv, 
+                       struct v4l2_requestbuffers *req)
+{
+       struct solo_filehandle *fh = priv;
+
+       return videobuf_reqbufs(&fh->vidq, req);
+}
+
+static int solo_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct solo_filehandle *fh = priv;
+
+       return videobuf_querybuf(&fh->vidq, buf);
+}
+
+static int solo_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct solo_filehandle *fh = priv;
+
+       return videobuf_qbuf(&fh->vidq, buf);
+}
+
+static int solo_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct solo_filehandle *fh = priv;
+
+       return videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK);
+}
+
+static int solo_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+       struct solo_filehandle *fh = priv;
+
+       if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       return videobuf_streamon(&fh->vidq);
+}
+
+static int solo_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+       struct solo_filehandle *fh = priv;
+
+       if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       return videobuf_streamoff(&fh->vidq);
+}
+
+static int solo_s_std(struct file *file, void *priv, v4l2_std_id *i)
+{
+       return 0;
+}
+
+static const u32 solo_motion_ctrls[] = {
+       V4L2_CID_MOTION_TRACE,
+       0
+};
+
+static const u32 *solo_ctrl_classes[] = {
+       solo_motion_ctrls,
+       NULL
+};
+
+static int solo_disp_queryctrl(struct file *file, void *priv,
+                              struct v4l2_queryctrl *qc)
+{
+       qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id);
+       if (!qc->id)
+               return -EINVAL;
+
+       switch (qc->id) {
+#ifdef PRIVATE_CIDS
+       case V4L2_CID_MOTION_TRACE:
+               qc->type = V4L2_CTRL_TYPE_BOOLEAN;
+               qc->minimum = 0;
+               qc->maximum = qc->step = 1;
+               qc->default_value = 0;
+               strlcpy(qc->name, "Motion Detection Trace", sizeof(qc->name));
+               return 0;
+#else
+       case V4L2_CID_MOTION_TRACE:
+               return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+#endif
+       }
+       return -EINVAL;
+}
+
+static int solo_disp_g_ctrl(struct file *file, void *priv,
+                           struct v4l2_control *ctrl)
+{
+       struct solo_filehandle *fh = priv;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+
+       switch (ctrl->id) {
+       case V4L2_CID_MOTION_TRACE:
+               ctrl->value = solo_reg_read(solo_dev, SOLO_VI_MOTION_BAR)
+                       ? 1 : 0;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int solo_disp_s_ctrl(struct file *file, void *priv,
+                           struct v4l2_control *ctrl)
+{
+       struct solo_filehandle *fh = priv;
+       struct solo6010_dev *solo_dev = fh->solo_dev;
+
+       switch (ctrl->id) {
+       case V4L2_CID_MOTION_TRACE:
+               if (ctrl->value) {
+                       solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER,
+                                       SOLO_VI_MOTION_Y_ADD |
+                                       SOLO_VI_MOTION_Y_VALUE(0x20) |
+                                       SOLO_VI_MOTION_CB_VALUE(0x10) |
+                                       SOLO_VI_MOTION_CR_VALUE(0x10));
+                       solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR,
+                                       SOLO_VI_MOTION_CR_ADD |
+                                       SOLO_VI_MOTION_Y_VALUE(0x10) |
+                                       SOLO_VI_MOTION_CB_VALUE(0x80) |
+                                       SOLO_VI_MOTION_CR_VALUE(0x10));
+               } else {
+                       solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0);
+                       solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0);
+               }
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static const struct v4l2_file_operations solo_v4l2_fops = {
+       .owner                  = THIS_MODULE,
+       .open                   = solo_v4l2_open,
+       .release                = solo_v4l2_release,
+       .read                   = solo_v4l2_read,
+       .poll                   = solo_v4l2_poll,
+       .mmap                   = solo_v4l2_mmap,
+       .ioctl                  = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = {
+       .vidioc_querycap                = solo_querycap,
+       .vidioc_s_std                   = solo_s_std,
+       /* Input callbacks */
+       .vidioc_enum_input              = solo_enum_input,
+       .vidioc_s_input                 = solo_set_input,
+       .vidioc_g_input                 = solo_get_input,
+       /* Video capture format callbacks */
+       .vidioc_enum_fmt_vid_cap        = solo_enum_fmt_cap,
+       .vidioc_try_fmt_vid_cap         = solo_try_fmt_cap,
+       .vidioc_s_fmt_vid_cap           = solo_set_fmt_cap,
+       .vidioc_g_fmt_vid_cap           = solo_get_fmt_cap,
+       /* Streaming I/O */
+       .vidioc_reqbufs                 = solo_reqbufs,
+       .vidioc_querybuf                = solo_querybuf,
+       .vidioc_qbuf                    = solo_qbuf,
+       .vidioc_dqbuf                   = solo_dqbuf,
+       .vidioc_streamon                = solo_streamon,
+        .vidioc_streamoff              = solo_streamoff,
+       /* Controls */
+       .vidioc_queryctrl               = solo_disp_queryctrl,
+        .vidioc_g_ctrl                 = solo_disp_g_ctrl,
+        .vidioc_s_ctrl                 = solo_disp_s_ctrl,
+};
+
+static struct video_device solo_v4l2_template = {
+       .name                   = SOLO6010_NAME,
+       .fops                   = &solo_v4l2_fops,
+       .ioctl_ops              = &solo_v4l2_ioctl_ops,
+       .minor                  = -1,
+       .release                = video_device_release,
+
+       .tvnorms                = V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
+       .current_norm           = V4L2_STD_NTSC_M,
+};
+
+int solo_v4l2_init(struct solo6010_dev *solo_dev)
+{
+       int ret;
+       int i;
+
+       init_waitqueue_head(&solo_dev->disp_thread_wait);
+
+       solo_dev->vfd = video_device_alloc();
+       if (!solo_dev->vfd)
+               return -ENOMEM;
+
+       *solo_dev->vfd = solo_v4l2_template;
+       solo_dev->vfd->parent = &solo_dev->pdev->dev;
+
+       ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, video_nr);
+       if (ret < 0) {
+               video_device_release(solo_dev->vfd);
+               solo_dev->vfd = NULL;
+               return ret;
+       }
+
+       video_set_drvdata(solo_dev->vfd, solo_dev);
+
+       snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)",
+                SOLO6010_NAME, solo_dev->vfd->num);
+
+       if (video_nr >= 0)
+               video_nr++;
+
+       dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with "
+                "%d inputs (%d extended)\n", solo_dev->vfd->num,
+                solo_dev->nr_chans, solo_dev->nr_ext);
+
+       /* Cycle all the channels and clear */
+       for (i = 0; i < solo_dev->nr_chans; i++) {
+               solo_v4l2_set_ch(solo_dev, i);
+               while (erase_off(solo_dev))
+                       ;// Do nothing
+       }
+
+       /* Set the default display channel */
+       solo_v4l2_set_ch(solo_dev, 0);
+       while (erase_off(solo_dev))
+               ;// Do nothing
+
+       solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN);
+
+       return 0;
+}
+
+void solo_v4l2_exit(struct solo6010_dev *solo_dev)
+{
+       solo6010_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN);
+       if (solo_dev->vfd) {
+               video_unregister_device(solo_dev->vfd);
+               solo_dev->vfd = NULL;
+       }
+}
diff --git a/drivers/staging/solo6x10/solo6010.h b/drivers/staging/solo6x10/solo6010.h
new file mode 100644 (file)
index 0000000..dca8e3e
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
+ * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SOLO6010_H
+#define __SOLO6010_H
+
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/semaphore.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf-core.h>
+
+#include "solo6010-registers.h"
+
+#ifndef PCI_VENDOR_ID_SOFTLOGIC
+#define PCI_VENDOR_ID_SOFTLOGIC                0x9413
+#define PCI_DEVICE_ID_SOLO6010         0x6010
+#endif
+
+#ifndef PCI_VENDOR_ID_BLUECHERRY
+#define PCI_VENDOR_ID_BLUECHERRY       0x1BB3
+/* Neugent Softlogic 6010 based cards */
+#define PCI_DEVICE_ID_NEUSOLO_4                0x4304
+#define PCI_DEVICE_ID_NEUSOLO_9                0x4309
+#define PCI_DEVICE_ID_NEUSOLO_16       0x4310
+/* Commell Softlogic 6010 based cards */
+#define PCI_DEVICE_ID_COMMSOLO_4       0x4E04
+#define PCI_DEVICE_ID_COMMSOLO_9       0x4E09
+#define PCI_DEVICE_ID_COMMSOLO_16      0x4E10
+#endif /* Bluecherry */
+
+#define SOLO6010_NAME                  "solo6010"
+
+#define SOLO_MAX_CHANNELS              16
+
+/* Make sure these two match */
+#define SOLO6010_VERSION               "2.0.0"
+#define SOLO6010_VER_MAJOR             2
+#define SOLO6010_VER_MINOR             0
+#define SOLO6010_VER_SUB               0
+#define SOLO6010_VER_NUM \
+    KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB)
+
+/*
+ * The SOLO6010 actually has 8 i2c channels, but we only use 2.
+ * 0 - Techwell chip(s)
+ * 1 - SAA7128
+ */
+#define SOLO_I2C_ADAPTERS              2
+#define SOLO_I2C_TW                    0
+#define SOLO_I2C_SAA                   1
+
+/* DMA Engine setup */
+#define SOLO_NR_P2M                    4
+#define SOLO_NR_P2M_DESC               256
+#define SOLO_P2M_DESC_SIZE             (SOLO_NR_P2M_DESC * 16)
+/* MPEG and JPEG share the same interrupt and locks so they must be together
+ * in the same dma channel. */
+#define SOLO_P2M_DMA_ID_MP4E           0
+#define SOLO_P2M_DMA_ID_JPEG           0
+#define SOLO_P2M_DMA_ID_MP4D           1
+#define SOLO_P2M_DMA_ID_G723D          1
+#define SOLO_P2M_DMA_ID_DISP           2
+#define SOLO_P2M_DMA_ID_OSG            2
+#define SOLO_P2M_DMA_ID_G723E          3
+#define SOLO_P2M_DMA_ID_VIN            3
+
+/* Encoder standard modes */
+#define SOLO_ENC_MODE_CIF              2
+#define SOLO_ENC_MODE_HD1              1
+#define SOLO_ENC_MODE_D1               9
+
+#define SOLO_DEFAULT_GOP               30
+#define SOLO_DEFAULT_QP                        3
+
+/* There is 8MB memory available for solo to buffer MPEG4 frames.
+ * This gives us 512 * 16kbyte queues. */
+#define SOLO_NR_RING_BUFS              512
+
+#define SOLO_CLOCK_MHZ                 108
+
+#ifndef V4L2_BUF_FLAG_MOTION_ON
+#define V4L2_BUF_FLAG_MOTION_ON                0x0400
+#define V4L2_BUF_FLAG_MOTION_DETECTED  0x0800
+#endif
+#ifndef V4L2_CID_MOTION_ENABLE
+#define PRIVATE_CIDS
+#define V4L2_CID_MOTION_ENABLE         (V4L2_CID_PRIVATE_BASE+0)
+#define V4L2_CID_MOTION_THRESHOLD      (V4L2_CID_PRIVATE_BASE+1)
+#define V4L2_CID_MOTION_TRACE          (V4L2_CID_PRIVATE_BASE+2)
+#endif
+
+enum SOLO_I2C_STATE {
+       IIC_STATE_IDLE,
+       IIC_STATE_START,
+       IIC_STATE_READ,
+       IIC_STATE_WRITE,
+       IIC_STATE_STOP
+};
+
+struct solo_p2m_dev {
+       struct semaphore        sem;
+       struct completion       completion;
+       int                     error;
+       u8                      desc[SOLO_P2M_DESC_SIZE];
+};
+
+#define OSD_TEXT_MAX           30
+
+enum solo_enc_types {
+       SOLO_ENC_TYPE_STD,
+       SOLO_ENC_TYPE_EXT,
+};
+
+struct solo_enc_dev {
+       struct solo6010_dev     *solo_dev;
+       /* V4L2 Items */
+       struct video_device     *vfd;
+       /* General accounting */
+       wait_queue_head_t       thread_wait;
+       spinlock_t              lock;
+       atomic_t                readers;
+       u8                      ch;
+       u8                      mode, gop, qp, interlaced, interval;
+       u8                      reset_gop;
+       u8                      bw_weight;
+       u8                      motion_detected;
+       u16                     motion_thresh;
+       u16                     width;
+       u16                     height;
+       char                    osd_text[OSD_TEXT_MAX + 1];
+};
+
+struct solo_enc_buf {
+       u8                      vop;
+       u8                      ch;
+       enum solo_enc_types     type;
+       u32                     off;
+       u32                     size;
+       u32                     jpeg_off;
+       u32                     jpeg_size;
+       struct timeval          ts;
+};
+
+/* The SOLO6010 PCI Device */
+struct solo6010_dev {
+       /* General stuff */
+       struct pci_dev          *pdev;
+       u8 __iomem              *reg_base;
+       int                     nr_chans;
+       int                     nr_ext;
+       u32                     irq_mask;
+       u32                     motion_mask;
+       spinlock_t              reg_io_lock;
+
+       /* tw28xx accounting */
+       u8                      tw2865, tw2864, tw2815;
+       u8                      tw28_cnt;
+
+       /* i2c related items */
+       struct i2c_adapter      i2c_adap[SOLO_I2C_ADAPTERS];
+       enum SOLO_I2C_STATE     i2c_state;
+       struct semaphore        i2c_sem;
+       int                     i2c_id;
+       wait_queue_head_t       i2c_wait;
+       struct i2c_msg          *i2c_msg;
+       unsigned int            i2c_msg_num;
+       unsigned int            i2c_msg_ptr;
+
+       /* P2M DMA Engine */
+       struct solo_p2m_dev     p2m_dev[SOLO_NR_P2M];
+
+       /* V4L2 Display items */
+       struct video_device     *vfd;
+       unsigned int            erasing;
+       unsigned int            frame_blank;
+       u8                      cur_disp_ch;
+       wait_queue_head_t       disp_thread_wait;
+
+       /* V4L2 Encoder items */
+       struct solo_enc_dev     *v4l2_enc[SOLO_MAX_CHANNELS];
+       u16                     enc_bw_remain;
+       /* IDX into hw mp4 encoder */
+       u8                      enc_idx;
+       /* Our software ring of enc buf references */
+       u16                     enc_wr_idx;
+       struct solo_enc_buf     enc_buf[SOLO_NR_RING_BUFS];
+
+       /* Current video settings */
+       u32                     video_type;
+       u16                     video_hsize, video_vsize;
+       u16                     vout_hstart, vout_vstart;
+       u16                     vin_hstart, vin_vstart;
+       u8                      fps;
+
+       /* Audio components */
+       struct snd_card         *snd_card;
+       struct snd_pcm          *snd_pcm;
+       atomic_t                snd_users;
+       int                     g723_hw_idx;
+};
+
+static inline u32 solo_reg_read(struct solo6010_dev *solo_dev, int reg)
+{
+       unsigned long flags;
+       u32 ret;
+       u16 val;
+
+       spin_lock_irqsave(&solo_dev->reg_io_lock, flags);
+
+       ret = readl(solo_dev->reg_base + reg);
+       rmb();
+       pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val);
+       rmb();
+
+       spin_unlock_irqrestore(&solo_dev->reg_io_lock, flags);
+
+       return ret;
+}
+
+static inline void solo_reg_write(struct solo6010_dev *solo_dev, int reg,
+                                     u32 data)
+{
+       unsigned long flags;
+       u16 val;
+
+       spin_lock_irqsave(&solo_dev->reg_io_lock, flags);
+
+       writel(data, solo_dev->reg_base + reg);
+       wmb();
+       pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val);
+       rmb();
+
+       spin_unlock_irqrestore(&solo_dev->reg_io_lock, flags);
+}
+
+void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask);
+void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask);
+
+/* Init/exit routeines for subsystems */
+int solo_disp_init(struct solo6010_dev *solo_dev);
+void solo_disp_exit(struct solo6010_dev *solo_dev);
+
+int solo_gpio_init(struct solo6010_dev *solo_dev);
+void solo_gpio_exit(struct solo6010_dev *solo_dev);
+
+int solo_i2c_init(struct solo6010_dev *solo_dev);
+void solo_i2c_exit(struct solo6010_dev *solo_dev);
+
+int solo_p2m_init(struct solo6010_dev *solo_dev);
+void solo_p2m_exit(struct solo6010_dev *solo_dev);
+
+int solo_v4l2_init(struct solo6010_dev *solo_dev);
+void solo_v4l2_exit(struct solo6010_dev *solo_dev);
+
+int solo_enc_init(struct solo6010_dev *solo_dev);
+void solo_enc_exit(struct solo6010_dev *solo_dev);
+
+int solo_enc_v4l2_init(struct solo6010_dev *solo_dev);
+void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev);
+
+int solo_g723_init(struct solo6010_dev *solo_dev);
+void solo_g723_exit(struct solo6010_dev *solo_dev);
+
+/* ISR's */
+int solo_i2c_isr(struct solo6010_dev *solo_dev);
+void solo_p2m_isr(struct solo6010_dev *solo_dev, int id);
+void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status);
+void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev);
+void solo_g723_isr(struct solo6010_dev *solo_dev);
+void solo_motion_isr(struct solo6010_dev *solo_dev);
+void solo_video_in_isr(struct solo6010_dev *solo_dev);
+
+/* i2c read/write */
+u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off);
+void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off,
+                       u8 data);
+
+/* P2M DMA */
+int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr,
+                  dma_addr_t dma_addr, u32 ext_addr, u32 size);
+int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr,
+                void *sys_addr, u32 ext_addr, u32 size);
+
+/* Set the threshold for motion detection */
+void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val);
+#define SOLO_DEF_MOT_THRESH            0x0300
+
+/* Write text on OSD */
+int solo_osd_print(struct solo_enc_dev *solo_enc);
+
+#endif /* __SOLO6010_H */
diff --git a/drivers/staging/spectra/Kconfig b/drivers/staging/spectra/Kconfig
new file mode 100644 (file)
index 0000000..5e2ffef
--- /dev/null
@@ -0,0 +1,40 @@
+
+menuconfig SPECTRA
+       tristate "Denali Spectra Flash Translation Layer"
+       depends on BLOCK
+       default n
+       ---help---
+         Enable the FTL pseudo-filesystem used with the NAND Flash
+         controller on Intel Moorestown Platform to pretend to be a disk
+
+choice
+       prompt "Compile for"
+       depends on SPECTRA
+       default SPECTRA_MRST_HW
+
+config SPECTRA_MRST_HW
+       bool "Moorestown hardware mode"
+       help
+         Driver communicates with the Moorestown hardware's register interface.
+         in DMA mode.
+
+config SPECTRA_MTD
+       bool "Linux MTD mode"
+       depends on MTD
+       help
+         Driver communicates with the kernel MTD subsystem instead of its own
+         built-in hardware driver.
+
+config SPECTRA_EMU
+       bool "RAM emulator testing"
+       help
+         Driver emulates Flash on a RAM buffer and / or disk file.  Useful to test the behavior of FTL layer.
+
+endchoice
+
+config SPECTRA_MRST_HW_DMA
+       bool
+       default n
+       depends on SPECTRA_MRST_HW
+       help
+         Use DMA for native hardware interface.
diff --git a/drivers/staging/spectra/Makefile b/drivers/staging/spectra/Makefile
new file mode 100644 (file)
index 0000000..f777dfb
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile of Intel Moorestown NAND controller driver
+#
+
+obj-$(CONFIG_SPECTRA) += spectra.o
+spectra-y := ffsport.o flash.o lld.o
+spectra-$(CONFIG_SPECTRA_MRST_HW) += lld_nand.o 
+spectra-$(CONFIG_SPECTRA_MRST_HW_DMA) += lld_cdma.o
+spectra-$(CONFIG_SPECTRA_EMU) += lld_emu.o
+spectra-$(CONFIG_SPECTRA_MTD) += lld_mtd.o
+
diff --git a/drivers/staging/spectra/README b/drivers/staging/spectra/README
new file mode 100644 (file)
index 0000000..ecba559
--- /dev/null
@@ -0,0 +1,29 @@
+This is a driver for NAND controller of Intel Moorestown platform.
+
+This driver is a standalone linux block device driver, it acts as if it's a normal hard disk.
+It includes three layer:
+       block layer interface - file ffsport.c
+       Flash Translation Layer (FTL) - file flash.c (implement the NAND flash Translation Layer, includs address mapping, garbage collection, wear-leveling and so on)
+       Low level layer - file lld_nand.c/lld_cdma.c/lld_emu.c (which implements actual controller hardware registers access)
+
+This driver can be build as modules or build-in.
+
+Dependency:
+This driver has dependency on IA Firmware of Intel Moorestown platform.
+It need the IA Firmware to create the block table for the first time.
+And to validate this driver code without IA Firmware, you can change the
+macro AUTO_FORMAT_FLASH from 0 to 1 in file spectraswconfig.h. Thus the
+driver will erase the whole nand flash and create a new block table.
+
+TODO:
+       - Enable Command DMA feature support
+       - lower the memory footprint
+       - Remove most of the unnecessary global variables
+       - Change all the upcase variable / functions name to lowercase
+       - Some other misc bugs
+
+Please send patches to:
+       Greg Kroah-Hartman <gregkh@suse.de>
+
+And Cc to: Gao Yunpeng <yunpeng.gao@intel.com>
+
diff --git a/drivers/staging/spectra/ffsdefs.h b/drivers/staging/spectra/ffsdefs.h
new file mode 100644 (file)
index 0000000..a9e9cd2
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _FFSDEFS_
+#define _FFSDEFS_
+
+#define CLEAR 0                        /*use this to clear a field instead of "fail"*/
+#define SET   1                        /*use this to set a field instead of "pass"*/
+#define FAIL 1                 /*failed flag*/
+#define PASS 0                 /*success flag*/
+#define ERR -1                 /*error flag*/
+
+#define   ERASE_CMD             10
+#define   WRITE_MAIN_CMD        11
+#define   READ_MAIN_CMD         12
+#define   WRITE_SPARE_CMD       13
+#define   READ_SPARE_CMD        14
+#define   WRITE_MAIN_SPARE_CMD  15
+#define   READ_MAIN_SPARE_CMD   16
+#define   MEMCOPY_CMD           17
+#define   DUMMY_CMD             99
+
+#define     EVENT_PASS                                  0x00
+#define     EVENT_CORRECTABLE_DATA_ERROR_FIXED         0x01
+#define     EVENT_UNCORRECTABLE_DATA_ERROR              0x02
+#define     EVENT_TIME_OUT                              0x03
+#define     EVENT_PROGRAM_FAILURE                       0x04
+#define     EVENT_ERASE_FAILURE                         0x05
+#define     EVENT_MEMCOPY_FAILURE                       0x06
+#define     EVENT_FAIL                                  0x07
+
+#define     EVENT_NONE                                  0x22
+#define     EVENT_DMA_CMD_COMP                          0x77
+#define     EVENT_ECC_TRANSACTION_DONE                  0x88
+#define     EVENT_DMA_CMD_FAIL                          0x99
+
+#define CMD_PASS        0
+#define CMD_FAIL        1
+#define CMD_ABORT       2
+#define CMD_NOT_DONE    3
+
+#endif /* _FFSDEFS_ */
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c
new file mode 100644 (file)
index 0000000..d0c5c97
--- /dev/null
@@ -0,0 +1,827 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "ffsport.h"
+#include "flash.h"
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/blkdev.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/log2.h>
+#include <linux/init.h>
+
+/**** Helper functions used for Div, Remainder operation on u64 ****/
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_Calc_Used_Bits
+* Inputs:       Power of 2 number
+* Outputs:      Number of Used Bits
+*               0, if the argument is 0
+* Description:  Calculate the number of bits used by a given power of 2 number
+*               Number can be upto 32 bit
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_Calc_Used_Bits(u32 n)
+{
+       int tot_bits = 0;
+
+       if (n >= 1 << 16) {
+               n >>= 16;
+               tot_bits += 16;
+       }
+
+       if (n >= 1 << 8) {
+               n >>=  8;
+               tot_bits +=  8;
+       }
+
+       if (n >= 1 << 4) {
+               n >>=  4;
+               tot_bits +=  4;
+       }
+
+       if (n >= 1 << 2) {
+               n >>=  2;
+               tot_bits +=  2;
+       }
+
+       if (n >= 1 << 1)
+               tot_bits +=  1;
+
+       return ((n == 0) ? (0) : tot_bits);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_u64_Div
+* Inputs:       Number of u64
+*               A power of 2 number as Division
+* Outputs:      Quotient of the Divisor operation
+* Description:  It divides the address by divisor by using bit shift operation
+*               (essentially without explicitely using "/").
+*               Divisor is a power of 2 number and Divided is of u64
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u64 GLOB_u64_Div(u64 addr, u32 divisor)
+{
+       return  (u64)(addr >> GLOB_Calc_Used_Bits(divisor));
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_u64_Remainder
+* Inputs:       Number of u64
+*               Divisor Type (1 -PageAddress, 2- BlockAddress)
+* Outputs:      Remainder of the Division operation
+* Description:  It calculates the remainder of a number (of u64) by
+*               divisor(power of 2 number ) by using bit shifting and multiply
+*               operation(essentially without explicitely using "/").
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type)
+{
+       u64 result = 0;
+
+       if (divisor_type == 1) { /* Remainder -- Page */
+               result = (addr >> DeviceInfo.nBitsInPageDataSize);
+               result = result * DeviceInfo.wPageDataSize;
+       } else if (divisor_type == 2) { /* Remainder -- Block */
+               result = (addr >> DeviceInfo.nBitsInBlockDataSize);
+               result = result * DeviceInfo.wBlockDataSize;
+       }
+
+       result = addr - result;
+
+       return result;
+}
+
+#define NUM_DEVICES             1
+#define PARTITIONS              8
+
+#define GLOB_SBD_NAME          "nd"
+#define GLOB_SBD_IRQ_NUM       (29)
+#define GLOB_VERSION           "driver version 20091110"
+
+#define GLOB_SBD_IOCTL_GC                        (0x7701)
+#define GLOB_SBD_IOCTL_WL                        (0x7702)
+#define GLOB_SBD_IOCTL_FORMAT                    (0x7703)
+#define GLOB_SBD_IOCTL_ERASE_FLASH               (0x7704)
+#define GLOB_SBD_IOCTL_FLUSH_CACHE               (0x7705)
+#define GLOB_SBD_IOCTL_COPY_BLK_TABLE            (0x7706)
+#define GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE  (0x7707)
+#define GLOB_SBD_IOCTL_GET_NAND_INFO             (0x7708)
+#define GLOB_SBD_IOCTL_WRITE_DATA                (0x7709)
+#define GLOB_SBD_IOCTL_READ_DATA                 (0x770A)
+
+static int reserved_mb = 0;
+module_param(reserved_mb, int, 0);
+MODULE_PARM_DESC(reserved_mb, "Reserved space for OS image, in MiB (default 25 MiB)");
+
+int nand_debug_level;
+module_param(nand_debug_level, int, 0644);
+MODULE_PARM_DESC(nand_debug_level, "debug level value: 1-3");
+
+MODULE_LICENSE("GPL");
+
+struct spectra_nand_dev {
+       struct pci_dev *dev;
+       u64 size;
+       u16 users;
+       spinlock_t qlock;
+       void __iomem *ioaddr;  /* Mapped address */
+       struct request_queue *queue;
+       struct task_struct *thread;
+       struct gendisk *gd;
+       u8 *tmp_buf;
+};
+
+
+static int GLOB_SBD_majornum;
+
+static char *GLOB_version = GLOB_VERSION;
+
+static struct spectra_nand_dev nand_device[NUM_DEVICES];
+
+static struct mutex spectra_lock;
+
+static int res_blks_os = 1;
+
+struct spectra_indentfy_dev_tag IdentifyDeviceData;
+
+static int force_flush_cache(void)
+{
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       if (ERR == GLOB_FTL_Flush_Cache()) {
+               printk(KERN_ERR "Fail to Flush FTL Cache!\n");
+               return -EFAULT;
+       }
+#if CMD_DMA
+               if (glob_ftl_execute_cmds())
+                       return -EIO;
+               else
+                       return 0;
+#endif
+       return 0;
+}
+
+struct ioctl_rw_page_info {
+       u8 *data;
+       unsigned int page;
+};
+
+static int ioctl_read_page_data(unsigned long arg)
+{
+       u8 *buf;
+       struct ioctl_rw_page_info info;
+       int result = PASS;
+
+       if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
+               return -EFAULT;
+
+       buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
+       if (!buf) {
+               printk(KERN_ERR "ioctl_read_page_data: "
+                      "failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       mutex_lock(&spectra_lock);
+       result = GLOB_FTL_Page_Read(buf,
+               (u64)info.page * IdentifyDeviceData.PageDataSize);
+       mutex_unlock(&spectra_lock);
+
+       if (copy_to_user((void __user *)info.data, buf,
+                          IdentifyDeviceData.PageDataSize)) {
+               printk(KERN_ERR "ioctl_read_page_data: "
+                      "failed to copy user data\n");
+               kfree(buf);
+               return -EFAULT;
+       }
+
+       kfree(buf);
+       return result;
+}
+
+static int ioctl_write_page_data(unsigned long arg)
+{
+       u8 *buf;
+       struct ioctl_rw_page_info info;
+       int result = PASS;
+
+       if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
+               return -EFAULT;
+
+       buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
+       if (!buf) {
+               printk(KERN_ERR "ioctl_write_page_data: "
+                      "failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       if (copy_from_user(buf, (void __user *)info.data,
+                          IdentifyDeviceData.PageDataSize)) {
+               printk(KERN_ERR "ioctl_write_page_data: "
+                      "failed to copy user data\n");
+               kfree(buf);
+               return -EFAULT;
+       }
+
+       mutex_lock(&spectra_lock);
+       result = GLOB_FTL_Page_Write(buf,
+               (u64)info.page * IdentifyDeviceData.PageDataSize);
+       mutex_unlock(&spectra_lock);
+
+       kfree(buf);
+       return result;
+}
+
+/* Return how many blocks should be reserved for bad block replacement */
+static int get_res_blk_num_bad_blk(void)
+{
+       return IdentifyDeviceData.wDataBlockNum / 10;
+}
+
+/* Return how many blocks should be reserved for OS image */
+static int get_res_blk_num_os(void)
+{
+       u32 res_blks, blk_size;
+
+       blk_size = IdentifyDeviceData.PageDataSize *
+               IdentifyDeviceData.PagesPerBlock;
+
+       res_blks = (reserved_mb * 1024 * 1024) / blk_size;
+
+       if ((res_blks < 1) || (res_blks >= IdentifyDeviceData.wDataBlockNum))
+               res_blks = 1; /* Reserved 1 block for block table */
+
+       return res_blks;
+}
+
+static void SBD_prepare_flush(struct request_queue *q, struct request *rq)
+{
+       rq->cmd_type = REQ_TYPE_LINUX_BLOCK;
+       /* rq->timeout = 5 * HZ; */
+       rq->cmd[0] = REQ_LB_OP_FLUSH;
+}
+
+/* Transfer a full request. */
+static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
+{
+       u64 start_addr, addr;
+       u32 logical_start_sect, hd_start_sect;
+       u32 nsect, hd_sects;
+       u32 rsect, tsect = 0;
+       char *buf;
+       u32 ratio = IdentifyDeviceData.PageDataSize >> 9;
+
+       start_addr = (u64)(blk_rq_pos(req)) << 9;
+       /* Add a big enough offset to prevent the OS Image from
+       *  being accessed or damaged by file system */
+       start_addr += IdentifyDeviceData.PageDataSize *
+                       IdentifyDeviceData.PagesPerBlock *
+                       res_blks_os;
+
+       if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+                       req->cmd[0] == REQ_LB_OP_FLUSH) {
+               if (force_flush_cache()) /* Fail to flush cache */
+                       return -EIO;
+               else
+                       return 0;
+       }
+
+       if (req->cmd_type != REQ_TYPE_FS)
+               return -EIO;
+
+       if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > get_capacity(tr->gd)) {
+               printk(KERN_ERR "Spectra error: request over the NAND "
+                       "capacity!sector %d, current_nr_sectors %d, "
+                       "while capacity is %d\n",
+                       (int)blk_rq_pos(req),
+                       blk_rq_cur_sectors(req),
+                       (int)get_capacity(tr->gd));
+               return -EIO;
+       }
+
+       logical_start_sect = start_addr >> 9;
+       hd_start_sect = logical_start_sect / ratio;
+       rsect = logical_start_sect - hd_start_sect * ratio;
+
+       addr = (u64)hd_start_sect * ratio * 512;
+       buf = req->buffer;
+       nsect = blk_rq_cur_sectors(req);
+
+       if (rsect)
+               tsect =  (ratio - rsect) < nsect ? (ratio - rsect) : nsect;
+
+       switch (rq_data_dir(req)) {
+       case READ:
+               /* Read the first NAND page */
+               if (rsect) {
+                       if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+                       memcpy(buf, tr->tmp_buf + (rsect << 9), tsect << 9);
+                       addr += IdentifyDeviceData.PageDataSize;
+                       buf += tsect << 9;
+                       nsect -= tsect;
+               }
+
+               /* Read the other NAND pages */
+               for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
+                       if (GLOB_FTL_Page_Read(buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+                       addr += IdentifyDeviceData.PageDataSize;
+                       buf += IdentifyDeviceData.PageDataSize;
+               }
+
+               /* Read the last NAND pages */
+               if (nsect % ratio) {
+                       if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+                       memcpy(buf, tr->tmp_buf, (nsect % ratio) << 9);
+               }
+#if CMD_DMA
+               if (glob_ftl_execute_cmds())
+                       return -EIO;
+               else
+                       return 0;
+#endif
+               return 0;
+
+       case WRITE:
+               /* Write the first NAND page */
+               if (rsect) {
+                       if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+                       memcpy(tr->tmp_buf + (rsect << 9), buf, tsect << 9);
+                       if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+                       addr += IdentifyDeviceData.PageDataSize;
+                       buf += tsect << 9;
+                       nsect -= tsect;
+               }
+
+               /* Write the other NAND pages */
+               for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
+                       if (GLOB_FTL_Page_Write(buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+                       addr += IdentifyDeviceData.PageDataSize;
+                       buf += IdentifyDeviceData.PageDataSize;
+               }
+
+               /* Write the last NAND pages */
+               if (nsect % ratio) {
+                       if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+                       memcpy(tr->tmp_buf, buf, (nsect % ratio) << 9);
+                       if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
+                               printk(KERN_ERR "Error in %s, Line %d\n",
+                                       __FILE__, __LINE__);
+                               return -EIO;
+                       }
+               }
+#if CMD_DMA
+               if (glob_ftl_execute_cmds())
+                       return -EIO;
+               else
+                       return 0;
+#endif
+               return 0;
+
+       default:
+               printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
+               return -EIO;
+       }
+}
+
+/* This function is copied from drivers/mtd/mtd_blkdevs.c */
+static int spectra_trans_thread(void *arg)
+{
+       struct spectra_nand_dev *tr = arg;
+       struct request_queue *rq = tr->queue;
+       struct request *req = NULL;
+
+       /* we might get involved when memory gets low, so use PF_MEMALLOC */
+       current->flags |= PF_MEMALLOC;
+
+       spin_lock_irq(rq->queue_lock);
+       while (!kthread_should_stop()) {
+               int res;
+
+               if (!req) {
+                       req = blk_fetch_request(rq);
+                       if (!req) {
+                               set_current_state(TASK_INTERRUPTIBLE);
+                               spin_unlock_irq(rq->queue_lock);
+                               schedule();
+                               spin_lock_irq(rq->queue_lock);
+                               continue;
+                       }
+               }
+
+               spin_unlock_irq(rq->queue_lock);
+
+               mutex_lock(&spectra_lock);
+               res = do_transfer(tr, req);
+               mutex_unlock(&spectra_lock);
+
+               spin_lock_irq(rq->queue_lock);
+
+               if (!__blk_end_request_cur(req, res))
+                       req = NULL;
+       }
+
+       if (req)
+               __blk_end_request_all(req, -EIO);
+
+       spin_unlock_irq(rq->queue_lock);
+
+       return 0;
+}
+
+
+/* Request function that "handles clustering". */
+static void GLOB_SBD_request(struct request_queue *rq)
+{
+       struct spectra_nand_dev *pdev = rq->queuedata;
+       wake_up_process(pdev->thread);
+}
+
+static int GLOB_SBD_open(struct block_device *bdev, fmode_t mode)
+
+{
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+       return 0;
+}
+
+static int GLOB_SBD_release(struct gendisk *disk, fmode_t mode)
+{
+       int ret;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       mutex_lock(&spectra_lock);
+       ret = force_flush_cache();
+       mutex_unlock(&spectra_lock);
+
+       return 0;
+}
+
+static int GLOB_SBD_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+       geo->heads = 4;
+       geo->sectors = 16;
+       geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+               "heads: %d, sectors: %d, cylinders: %d\n",
+               geo->heads, geo->sectors, geo->cylinders);
+
+       return 0;
+}
+
+int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
+               unsigned int cmd, unsigned long arg)
+{
+       int ret;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       switch (cmd) {
+       case GLOB_SBD_IOCTL_GC:
+               nand_dbg_print(NAND_DBG_DEBUG,
+                              "Spectra IOCTL: Garbage Collection "
+                              "being performed\n");
+               if (PASS != GLOB_FTL_Garbage_Collection())
+                       return -EFAULT;
+               return 0;
+
+       case GLOB_SBD_IOCTL_WL:
+               nand_dbg_print(NAND_DBG_DEBUG,
+                              "Spectra IOCTL: Static Wear Leveling "
+                              "being performed\n");
+               if (PASS != GLOB_FTL_Wear_Leveling())
+                       return -EFAULT;
+               return 0;
+
+       case GLOB_SBD_IOCTL_FORMAT:
+               nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Flash format "
+                              "being performed\n");
+               if (PASS != GLOB_FTL_Flash_Format())
+                       return -EFAULT;
+               return 0;
+
+       case GLOB_SBD_IOCTL_FLUSH_CACHE:
+               nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Cache flush "
+                              "being performed\n");
+               mutex_lock(&spectra_lock);
+               ret = force_flush_cache();
+               mutex_unlock(&spectra_lock);
+               return ret;
+
+       case GLOB_SBD_IOCTL_COPY_BLK_TABLE:
+               nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+                              "Copy block table\n");
+               if (copy_to_user((void __user *)arg,
+                       get_blk_table_start_addr(),
+                       get_blk_table_len()))
+                       return -EFAULT;
+               return 0;
+
+       case GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE:
+               nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+                              "Copy wear leveling table\n");
+               if (copy_to_user((void __user *)arg,
+                       get_wear_leveling_table_start_addr(),
+                       get_wear_leveling_table_len()))
+                       return -EFAULT;
+               return 0;
+
+       case GLOB_SBD_IOCTL_GET_NAND_INFO:
+               nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+                              "Get NAND info\n");
+               if (copy_to_user((void __user *)arg, &IdentifyDeviceData,
+                       sizeof(IdentifyDeviceData)))
+                       return -EFAULT;
+               return 0;
+
+       case GLOB_SBD_IOCTL_WRITE_DATA:
+               nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+                              "Write one page data\n");
+               return ioctl_write_page_data(arg);
+
+       case GLOB_SBD_IOCTL_READ_DATA:
+               nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+                              "Read one page data\n");
+               return ioctl_read_page_data(arg);
+       }
+
+       return -ENOTTY;
+}
+
+static struct block_device_operations GLOB_SBD_ops = {
+       .owner = THIS_MODULE,
+       .open = GLOB_SBD_open,
+       .release = GLOB_SBD_release,
+       .locked_ioctl = GLOB_SBD_ioctl,
+       .getgeo = GLOB_SBD_getgeo,
+};
+
+static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
+{
+       int res_blks;
+       u32 sects;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       memset(dev, 0, sizeof(struct spectra_nand_dev));
+
+       nand_dbg_print(NAND_DBG_WARN, "Reserved %d blocks "
+               "for OS image, %d blocks for bad block replacement.\n",
+               get_res_blk_num_os(),
+               get_res_blk_num_bad_blk());
+
+       res_blks = get_res_blk_num_bad_blk() + get_res_blk_num_os();
+
+       dev->size = (u64)IdentifyDeviceData.PageDataSize *
+               IdentifyDeviceData.PagesPerBlock *
+               (IdentifyDeviceData.wDataBlockNum - res_blks);
+
+       res_blks_os = get_res_blk_num_os();
+
+       spin_lock_init(&dev->qlock);
+
+       dev->tmp_buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
+       if (!dev->tmp_buf) {
+               printk(KERN_ERR "Failed to kmalloc memory in %s Line %d, exit.\n",
+                       __FILE__, __LINE__);
+               goto out_vfree;
+       }
+
+       dev->queue = blk_init_queue(GLOB_SBD_request, &dev->qlock);
+       if (dev->queue == NULL) {
+               printk(KERN_ERR
+                      "Spectra: Request queue could not be initialized."
+                       " Aborting\n ");
+               goto out_vfree;
+       }
+       dev->queue->queuedata = dev;
+
+       /* As Linux block layer doens't support >4KB hardware sector,  */
+       /* Here we force report 512 byte hardware sector size to Kernel */
+       blk_queue_logical_block_size(dev->queue, 512);
+
+       blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH,
+                                       SBD_prepare_flush);
+
+       dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
+       if (IS_ERR(dev->thread)) {
+               blk_cleanup_queue(dev->queue);
+               unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
+               return PTR_ERR(dev->thread);
+       }
+
+       dev->gd = alloc_disk(PARTITIONS);
+       if (!dev->gd) {
+               printk(KERN_ERR
+                      "Spectra: Could not allocate disk. Aborting \n ");
+               goto out_vfree;
+       }
+       dev->gd->major = GLOB_SBD_majornum;
+       dev->gd->first_minor = which * PARTITIONS;
+       dev->gd->fops = &GLOB_SBD_ops;
+       dev->gd->queue = dev->queue;
+       dev->gd->private_data = dev;
+       snprintf(dev->gd->disk_name, 32, "%s%c", GLOB_SBD_NAME, which + 'a');
+
+       sects = dev->size >> 9;
+       nand_dbg_print(NAND_DBG_WARN, "Capacity sects: %d\n", sects);
+       set_capacity(dev->gd, sects);
+
+       add_disk(dev->gd);
+
+       return 0;
+out_vfree:
+       return -ENOMEM;
+}
+
+/*
+static ssize_t show_nand_block_num(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+               (int)IdentifyDeviceData.wDataBlockNum);
+}
+
+static ssize_t show_nand_pages_per_block(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+               (int)IdentifyDeviceData.PagesPerBlock);
+}
+
+static ssize_t show_nand_page_size(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+               (int)IdentifyDeviceData.PageDataSize);
+}
+
+static DEVICE_ATTR(nand_block_num, 0444, show_nand_block_num, NULL);
+static DEVICE_ATTR(nand_pages_per_block, 0444, show_nand_pages_per_block, NULL);
+static DEVICE_ATTR(nand_page_size, 0444, show_nand_page_size, NULL);
+
+static void create_sysfs_entry(struct device *dev)
+{
+       if (device_create_file(dev, &dev_attr_nand_block_num))
+               printk(KERN_ERR "Spectra: "
+                       "failed to create sysfs entry nand_block_num.\n");
+       if (device_create_file(dev, &dev_attr_nand_pages_per_block))
+               printk(KERN_ERR "Spectra: "
+               "failed to create sysfs entry nand_pages_per_block.\n");
+       if (device_create_file(dev, &dev_attr_nand_page_size))
+               printk(KERN_ERR "Spectra: "
+               "failed to create sysfs entry nand_page_size.\n");
+}
+*/
+
+static int GLOB_SBD_init(void)
+{
+       int i;
+
+       /* Set debug output level (0~3) here. 3 is most verbose */
+       printk(KERN_ALERT "Spectra: %s\n", GLOB_version);
+
+       mutex_init(&spectra_lock);
+
+       GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME);
+       if (GLOB_SBD_majornum <= 0) {
+               printk(KERN_ERR "Unable to get the major %d for Spectra",
+                      GLOB_SBD_majornum);
+               return -EBUSY;
+       }
+
+       if (PASS != GLOB_FTL_Flash_Init()) {
+               printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. "
+                      "Aborting\n");
+               goto out_flash_register;
+       }
+
+       /* create_sysfs_entry(&dev->dev); */
+
+       if (PASS != GLOB_FTL_IdentifyDevice(&IdentifyDeviceData)) {
+               printk(KERN_ERR "Spectra: Unable to Read Flash Device. "
+                      "Aborting\n");
+               goto out_flash_register;
+       } else {
+               nand_dbg_print(NAND_DBG_WARN, "In GLOB_SBD_init: "
+                              "Num blocks=%d, pagesperblock=%d, "
+                              "pagedatasize=%d, ECCBytesPerSector=%d\n",
+                      (int)IdentifyDeviceData.NumBlocks,
+                      (int)IdentifyDeviceData.PagesPerBlock,
+                      (int)IdentifyDeviceData.PageDataSize,
+                      (int)IdentifyDeviceData.wECCBytesPerSector);
+       }
+
+       printk(KERN_ALERT "Spectra: searching block table, please wait ...\n");
+       if (GLOB_FTL_Init() != PASS) {
+               printk(KERN_ERR "Spectra: Unable to Initialize FTL Layer. "
+                      "Aborting\n");
+               goto out_ftl_flash_register;
+       }
+       printk(KERN_ALERT "Spectra: block table has been found.\n");
+
+       for (i = 0; i < NUM_DEVICES; i++)
+               if (SBD_setup_device(&nand_device[i], i) == -ENOMEM)
+                       goto out_ftl_flash_register;
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+                      "Spectra: module loaded with major number %d\n",
+                      GLOB_SBD_majornum);
+
+       return 0;
+
+out_ftl_flash_register:
+       GLOB_FTL_Cache_Release();
+out_flash_register:
+       GLOB_FTL_Flash_Release();
+       unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
+       printk(KERN_ERR "Spectra: Module load failed.\n");
+
+       return -ENOMEM;
+}
+
+static void __exit GLOB_SBD_exit(void)
+{
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < NUM_DEVICES; i++) {
+               struct spectra_nand_dev *dev = &nand_device[i];
+               if (dev->gd) {
+                       del_gendisk(dev->gd);
+                       put_disk(dev->gd);
+               }
+               if (dev->queue)
+                       blk_cleanup_queue(dev->queue);
+               kfree(dev->tmp_buf);
+       }
+
+       unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
+
+       mutex_lock(&spectra_lock);
+       force_flush_cache();
+       mutex_unlock(&spectra_lock);
+
+       GLOB_FTL_Cache_Release();
+
+       GLOB_FTL_Flash_Release();
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+                      "Spectra FTL module (major number %d) unloaded.\n",
+                      GLOB_SBD_majornum);
+}
+
+module_init(GLOB_SBD_init);
+module_exit(GLOB_SBD_exit);
diff --git a/drivers/staging/spectra/ffsport.h b/drivers/staging/spectra/ffsport.h
new file mode 100644 (file)
index 0000000..6c5d90c
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _FFSPORT_
+#define _FFSPORT_
+
+#include "ffsdefs.h"
+
+#if defined __GNUC__
+#define PACKED
+#define PACKED_GNU __attribute__ ((packed))
+#define UNALIGNED
+#endif
+
+#include <linux/semaphore.h>
+#include <linux/string.h>      /* for strcpy(), stricmp(), etc */
+#include <linux/mm.h>          /* for kmalloc(), kfree() */
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>      /* printk() */
+#include <linux/fs.h>          /* everything... */
+#include <linux/errno.h>       /* error codes */
+#include <linux/types.h>       /* size_t */
+#include <linux/genhd.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/pci.h>
+#include "flash.h"
+
+#define VERBOSE    1
+
+#define NAND_DBG_WARN  1
+#define NAND_DBG_DEBUG 2
+#define NAND_DBG_TRACE 3
+
+extern int nand_debug_level;
+
+#ifdef VERBOSE
+#define nand_dbg_print(level, args...)                 \
+       do {                                            \
+               if (level <= nand_debug_level)          \
+                       printk(KERN_ALERT args);        \
+       } while (0)
+#else
+#define nand_dbg_print(level, args...)
+#endif
+
+#ifdef SUPPORT_BIG_ENDIAN
+#define INVERTUINT16(w)   ((u16)(((u16)(w)) << 8) | \
+                          (u16)((u16)(w) >> 8))
+
+#define INVERTUINT32(dw)  (((u32)(dw) << 24) | \
+                          (((u32)(dw) << 8) & 0x00ff0000) | \
+                          (((u32)(dw) >> 8) & 0x0000ff00) | \
+                          ((u32)(dw) >> 24))
+#else
+#define INVERTUINT16(w)   w
+#define INVERTUINT32(dw)  dw
+#endif
+
+extern int GLOB_Calc_Used_Bits(u32 n);
+extern u64 GLOB_u64_Div(u64 addr, u32 divisor);
+extern u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type);
+
+#endif /* _FFSPORT_ */
diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c
new file mode 100644 (file)
index 0000000..134aa51
--- /dev/null
@@ -0,0 +1,4731 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+
+#include "flash.h"
+#include "ffsdefs.h"
+#include "lld.h"
+#include "lld_nand.h"
+#if CMD_DMA
+#include "lld_cdma.h"
+#endif
+
+#define BLK_FROM_ADDR(addr)  ((u32)(addr >> DeviceInfo.nBitsInBlockDataSize))
+#define PAGE_FROM_ADDR(addr, Block)  ((u16)((addr - (u64)Block * \
+       DeviceInfo.wBlockDataSize) >> DeviceInfo.nBitsInPageDataSize))
+
+#define IS_SPARE_BLOCK(blk)     (BAD_BLOCK != (pbt[blk] &\
+       BAD_BLOCK) && SPARE_BLOCK == (pbt[blk] & SPARE_BLOCK))
+
+#define IS_DATA_BLOCK(blk)      (0 == (pbt[blk] & BAD_BLOCK))
+
+#define IS_DISCARDED_BLOCK(blk) (BAD_BLOCK != (pbt[blk] &\
+       BAD_BLOCK) && DISCARD_BLOCK == (pbt[blk] & DISCARD_BLOCK))
+
+#define IS_BAD_BLOCK(blk)       (BAD_BLOCK == (pbt[blk] & BAD_BLOCK))
+
+#if DEBUG_BNDRY
+void debug_boundary_lineno_error(int chnl, int limit, int no,
+                               int lineno, char *filename)
+{
+       if (chnl >= limit)
+               printk(KERN_ERR "Boundary Check Fail value %d >= limit %d, "
+               "at  %s:%d. Other info:%d. Aborting...\n",
+               chnl, limit, filename, lineno, no);
+}
+/* static int globalmemsize; */
+#endif
+
+static u16 FTL_Cache_If_Hit(u64 dwPageAddr);
+static int FTL_Cache_Read(u64 dwPageAddr);
+static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr,
+                               u16 cache_blk);
+static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr,
+                                u8 cache_blk, u16 flag);
+static int FTL_Cache_Write(void);
+static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr);
+static void FTL_Calculate_LRU(void);
+static u32 FTL_Get_Block_Index(u32 wBlockNum);
+
+static int FTL_Search_Block_Table_IN_Block(u32 BT_Block,
+                                          u8 BT_Tag, u16 *Page);
+static int FTL_Read_Block_Table(void);
+static int FTL_Write_Block_Table(int wForce);
+static int FTL_Write_Block_Table_Data(void);
+static int FTL_Check_Block_Table(int wOldTable);
+static int FTL_Static_Wear_Leveling(void);
+static u32 FTL_Replace_Block_Table(void);
+static int FTL_Write_IN_Progress_Block_Table_Page(void);
+
+static u32 FTL_Get_Page_Num(u64 length);
+static u64 FTL_Get_Physical_Block_Addr(u64 blk_addr);
+
+static u32 FTL_Replace_OneBlock(u32 wBlockNum,
+                                     u32 wReplaceNum);
+static u32 FTL_Replace_LWBlock(u32 wBlockNum,
+                                    int *pGarbageCollect);
+static u32 FTL_Replace_MWBlock(void);
+static int FTL_Replace_Block(u64 blk_addr);
+static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX);
+
+static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr);
+
+struct device_info_tag DeviceInfo;
+struct flash_cache_tag Cache;
+static struct spectra_l2_cache_info cache_l2;
+
+static u8 *cache_l2_page_buf;
+static u8 *cache_l2_blk_buf;
+
+u8 *g_pBlockTable;
+u8 *g_pWearCounter;
+u16 *g_pReadCounter;
+u32 *g_pBTBlocks;
+static u16 g_wBlockTableOffset;
+static u32 g_wBlockTableIndex;
+static u8 g_cBlockTableStatus;
+
+static u8 *g_pTempBuf;
+static u8 *flag_check_blk_table;
+static u8 *tmp_buf_search_bt_in_block;
+static u8 *spare_buf_search_bt_in_block;
+static u8 *spare_buf_bt_search_bt_in_block;
+static u8 *tmp_buf1_read_blk_table;
+static u8 *tmp_buf2_read_blk_table;
+static u8 *flags_static_wear_leveling;
+static u8 *tmp_buf_write_blk_table_data;
+static u8 *tmp_buf_read_disturbance;
+
+u8 *buf_read_page_main_spare;
+u8 *buf_write_page_main_spare;
+u8 *buf_read_page_spare;
+u8 *buf_get_bad_block;
+
+#if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA)
+struct flash_cache_delta_list_tag int_cache[MAX_CHANS + MAX_DESCS];
+struct flash_cache_tag cache_start_copy;
+#endif
+
+int g_wNumFreeBlocks;
+u8 g_SBDCmdIndex;
+
+static u8 *g_pIPF;
+static u8 bt_flag = FIRST_BT_ID;
+static u8 bt_block_changed;
+
+static u16 cache_block_to_write;
+static u8 last_erased = FIRST_BT_ID;
+
+static u8 GC_Called;
+static u8 BT_GC_Called;
+
+#if CMD_DMA
+#define COPY_BACK_BUF_NUM 10
+
+static u8 ftl_cmd_cnt;  /* Init value is 0 */
+u8 *g_pBTDelta;
+u8 *g_pBTDelta_Free;
+u8 *g_pBTStartingCopy;
+u8 *g_pWearCounterCopy;
+u16 *g_pReadCounterCopy;
+u8 *g_pBlockTableCopies;
+u8 *g_pNextBlockTable;
+static u8 *cp_back_buf_copies[COPY_BACK_BUF_NUM];
+static int cp_back_buf_idx;
+
+static u8 *g_temp_buf;
+
+#pragma pack(push, 1)
+#pragma pack(1)
+struct BTableChangesDelta {
+       u8 ftl_cmd_cnt;
+       u8 ValidFields;
+       u16 g_wBlockTableOffset;
+       u32 g_wBlockTableIndex;
+       u32 BT_Index;
+       u32 BT_Entry_Value;
+       u32 WC_Index;
+       u8 WC_Entry_Value;
+       u32 RC_Index;
+       u16 RC_Entry_Value;
+};
+
+#pragma pack(pop)
+
+struct BTableChangesDelta *p_BTableChangesDelta;
+#endif
+
+
+#define MARK_BLOCK_AS_BAD(blocknode)      (blocknode |= BAD_BLOCK)
+#define MARK_BLK_AS_DISCARD(blk)  (blk = (blk & ~SPARE_BLOCK) | DISCARD_BLOCK)
+
+#define FTL_Get_LBAPBA_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+                                               sizeof(u32))
+#define FTL_Get_WearCounter_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+                                               sizeof(u8))
+#define FTL_Get_ReadCounter_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+                                               sizeof(u16))
+#if SUPPORT_LARGE_BLOCKNUM
+#define FTL_Get_LBAPBA_Table_Flash_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+                                               sizeof(u8) * 3)
+#else
+#define FTL_Get_LBAPBA_Table_Flash_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+                                               sizeof(u16))
+#endif
+#define FTL_Get_WearCounter_Table_Flash_Size_Bytes \
+       FTL_Get_WearCounter_Table_Mem_Size_Bytes
+#define FTL_Get_ReadCounter_Table_Flash_Size_Bytes \
+       FTL_Get_ReadCounter_Table_Mem_Size_Bytes
+
+static u32 FTL_Get_Block_Table_Flash_Size_Bytes(void)
+{
+       u32 byte_num;
+
+       if (DeviceInfo.MLCDevice) {
+               byte_num = FTL_Get_LBAPBA_Table_Flash_Size_Bytes() +
+                       DeviceInfo.wDataBlockNum * sizeof(u8) +
+                       DeviceInfo.wDataBlockNum * sizeof(u16);
+       } else {
+               byte_num = FTL_Get_LBAPBA_Table_Flash_Size_Bytes() +
+                       DeviceInfo.wDataBlockNum * sizeof(u8);
+       }
+
+       byte_num += 4 * sizeof(u8);
+
+       return byte_num;
+}
+
+static u16  FTL_Get_Block_Table_Flash_Size_Pages(void)
+{
+       return (u16)FTL_Get_Page_Num(FTL_Get_Block_Table_Flash_Size_Bytes());
+}
+
+static int FTL_Copy_Block_Table_To_Flash(u8 *flashBuf, u32 sizeToTx,
+                                       u32 sizeTxed)
+{
+       u32 wBytesCopied, blk_tbl_size, wBytes;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       blk_tbl_size = FTL_Get_LBAPBA_Table_Flash_Size_Bytes();
+       for (wBytes = 0;
+       (wBytes < sizeToTx) && ((wBytes + sizeTxed) < blk_tbl_size);
+       wBytes++) {
+#if SUPPORT_LARGE_BLOCKNUM
+               flashBuf[wBytes] = (u8)(pbt[(wBytes + sizeTxed) / 3]
+               >> (((wBytes + sizeTxed) % 3) ?
+               ((((wBytes + sizeTxed) % 3) == 2) ? 0 : 8) : 16)) & 0xFF;
+#else
+               flashBuf[wBytes] = (u8)(pbt[(wBytes + sizeTxed) / 2]
+               >> (((wBytes + sizeTxed) % 2) ? 0 : 8)) & 0xFF;
+#endif
+       }
+
+       sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+       blk_tbl_size = FTL_Get_WearCounter_Table_Flash_Size_Bytes();
+       wBytesCopied = wBytes;
+       wBytes = ((blk_tbl_size - sizeTxed) > (sizeToTx - wBytesCopied)) ?
+               (sizeToTx - wBytesCopied) : (blk_tbl_size - sizeTxed);
+       memcpy(flashBuf + wBytesCopied, g_pWearCounter + sizeTxed, wBytes);
+
+       sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+
+       if (DeviceInfo.MLCDevice) {
+               blk_tbl_size = FTL_Get_ReadCounter_Table_Flash_Size_Bytes();
+               wBytesCopied += wBytes;
+               for (wBytes = 0; ((wBytes + wBytesCopied) < sizeToTx) &&
+                       ((wBytes + sizeTxed) < blk_tbl_size); wBytes++)
+                       flashBuf[wBytes + wBytesCopied] =
+                       (g_pReadCounter[(wBytes + sizeTxed) / 2] >>
+                       (((wBytes + sizeTxed) % 2) ? 0 : 8)) & 0xFF;
+       }
+
+       return wBytesCopied + wBytes;
+}
+
+static int FTL_Copy_Block_Table_From_Flash(u8 *flashBuf,
+                               u32 sizeToTx, u32 sizeTxed)
+{
+       u32 wBytesCopied, blk_tbl_size, wBytes;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       blk_tbl_size = FTL_Get_LBAPBA_Table_Flash_Size_Bytes();
+       for (wBytes = 0; (wBytes < sizeToTx) &&
+               ((wBytes + sizeTxed) < blk_tbl_size); wBytes++) {
+#if SUPPORT_LARGE_BLOCKNUM
+               if (!((wBytes + sizeTxed) % 3))
+                       pbt[(wBytes + sizeTxed) / 3] = 0;
+               pbt[(wBytes + sizeTxed) / 3] |=
+                       (flashBuf[wBytes] << (((wBytes + sizeTxed) % 3) ?
+                       ((((wBytes + sizeTxed) % 3) == 2) ? 0 : 8) : 16));
+#else
+               if (!((wBytes + sizeTxed) % 2))
+                       pbt[(wBytes + sizeTxed) / 2] = 0;
+               pbt[(wBytes + sizeTxed) / 2] |=
+                       (flashBuf[wBytes] << (((wBytes + sizeTxed) % 2) ?
+                       0 : 8));
+#endif
+       }
+
+       sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+       blk_tbl_size = FTL_Get_WearCounter_Table_Flash_Size_Bytes();
+       wBytesCopied = wBytes;
+       wBytes = ((blk_tbl_size - sizeTxed) > (sizeToTx - wBytesCopied)) ?
+               (sizeToTx - wBytesCopied) : (blk_tbl_size - sizeTxed);
+       memcpy(g_pWearCounter + sizeTxed, flashBuf + wBytesCopied, wBytes);
+       sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+
+       if (DeviceInfo.MLCDevice) {
+               wBytesCopied += wBytes;
+               blk_tbl_size = FTL_Get_ReadCounter_Table_Flash_Size_Bytes();
+               for (wBytes = 0; ((wBytes + wBytesCopied) < sizeToTx) &&
+                       ((wBytes + sizeTxed) < blk_tbl_size); wBytes++) {
+                       if (((wBytes + sizeTxed) % 2))
+                               g_pReadCounter[(wBytes + sizeTxed) / 2] = 0;
+                       g_pReadCounter[(wBytes + sizeTxed) / 2] |=
+                               (flashBuf[wBytes] <<
+                               (((wBytes + sizeTxed) % 2) ? 0 : 8));
+               }
+       }
+
+       return wBytesCopied+wBytes;
+}
+
+static int FTL_Insert_Block_Table_Signature(u8 *buf, u8 tag)
+{
+       int i;
+
+       for (i = 0; i < BTSIG_BYTES; i++)
+               buf[BTSIG_OFFSET + i] =
+               ((tag + (i * BTSIG_DELTA) - FIRST_BT_ID) %
+               (1 + LAST_BT_ID-FIRST_BT_ID)) + FIRST_BT_ID;
+
+       return PASS;
+}
+
+static int FTL_Extract_Block_Table_Tag(u8 *buf, u8 **tagarray)
+{
+       static u8 tag[BTSIG_BYTES >> 1];
+       int i, j, k, tagi, tagtemp, status;
+
+       *tagarray = (u8 *)tag;
+       tagi = 0;
+
+       for (i = 0; i < (BTSIG_BYTES - 1); i++) {
+               for (j = i + 1; (j < BTSIG_BYTES) &&
+                       (tagi < (BTSIG_BYTES >> 1)); j++) {
+                       tagtemp = buf[BTSIG_OFFSET + j] -
+                               buf[BTSIG_OFFSET + i];
+                       if (tagtemp && !(tagtemp % BTSIG_DELTA)) {
+                               tagtemp = (buf[BTSIG_OFFSET + i] +
+                                       (1 + LAST_BT_ID - FIRST_BT_ID) -
+                                       (i * BTSIG_DELTA)) %
+                                       (1 + LAST_BT_ID - FIRST_BT_ID);
+                               status = FAIL;
+                               for (k = 0; k < tagi; k++) {
+                                       if (tagtemp == tag[k])
+                                               status = PASS;
+                               }
+
+                               if (status == FAIL) {
+                                       tag[tagi++] = tagtemp;
+                                       i = (j == (i + 1)) ? i + 1 : i;
+                                       j = (j == (i + 1)) ? i + 1 : i;
+                               }
+                       }
+               }
+       }
+
+       return tagi;
+}
+
+
+static int FTL_Execute_SPL_Recovery(void)
+{
+       u32 j, block, blks;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       int ret;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                               __FILE__, __LINE__, __func__);
+
+       blks = DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock;
+       for (j = 0; j <= blks; j++) {
+               block = (pbt[j]);
+               if (((block & BAD_BLOCK) != BAD_BLOCK) &&
+                       ((block & SPARE_BLOCK) == SPARE_BLOCK)) {
+                       ret =  GLOB_LLD_Erase_Block(block & ~BAD_BLOCK);
+                       if (FAIL == ret) {
+                               nand_dbg_print(NAND_DBG_WARN,
+                                       "NAND Program fail in %s, Line %d, "
+                                       "Function: %s, new Bad Block %d "
+                                       "generated!\n",
+                                       __FILE__, __LINE__, __func__,
+                                       (int)(block & ~BAD_BLOCK));
+                               MARK_BLOCK_AS_BAD(pbt[j]);
+                       }
+               }
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_IdentifyDevice
+* Inputs:       pointer to identify data structure
+* Outputs:      PASS / FAIL
+* Description:  the identify data structure is filled in with
+*                   information for the block driver.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *dev_data)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                               __FILE__, __LINE__, __func__);
+
+       dev_data->NumBlocks = DeviceInfo.wTotalBlocks;
+       dev_data->PagesPerBlock = DeviceInfo.wPagesPerBlock;
+       dev_data->PageDataSize = DeviceInfo.wPageDataSize;
+       dev_data->wECCBytesPerSector = DeviceInfo.wECCBytesPerSector;
+       dev_data->wDataBlockNum = DeviceInfo.wDataBlockNum;
+
+       return PASS;
+}
+
+/* ..... */
+static int allocate_memory(void)
+{
+       u32 block_table_size, page_size, block_size, mem_size;
+       u32 total_bytes = 0;
+       int i;
+#if CMD_DMA
+       int j;
+#endif
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       page_size = DeviceInfo.wPageSize;
+       block_size = DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize;
+
+       block_table_size = DeviceInfo.wDataBlockNum *
+               (sizeof(u32) + sizeof(u8) + sizeof(u16));
+       block_table_size += (DeviceInfo.wPageDataSize -
+               (block_table_size % DeviceInfo.wPageDataSize)) %
+               DeviceInfo.wPageDataSize;
+
+       /* Malloc memory for block tables */
+       g_pBlockTable = kmalloc(block_table_size, GFP_ATOMIC);
+       if (!g_pBlockTable)
+               goto block_table_fail;
+       memset(g_pBlockTable, 0, block_table_size);
+       total_bytes += block_table_size;
+
+       g_pWearCounter = (u8 *)(g_pBlockTable +
+               DeviceInfo.wDataBlockNum * sizeof(u32));
+
+       if (DeviceInfo.MLCDevice)
+               g_pReadCounter = (u16 *)(g_pBlockTable +
+                       DeviceInfo.wDataBlockNum *
+                       (sizeof(u32) + sizeof(u8)));
+
+       /* Malloc memory and init for cache items */
+       for (i = 0; i < CACHE_ITEM_NUM; i++) {
+               Cache.array[i].address = NAND_CACHE_INIT_ADDR;
+               Cache.array[i].use_cnt = 0;
+               Cache.array[i].changed = CLEAR;
+               Cache.array[i].buf = kmalloc(Cache.cache_item_size,
+                       GFP_ATOMIC);
+               if (!Cache.array[i].buf)
+                       goto cache_item_fail;
+               memset(Cache.array[i].buf, 0, Cache.cache_item_size);
+               total_bytes += Cache.cache_item_size;
+       }
+
+       /* Malloc memory for IPF */
+       g_pIPF = kmalloc(page_size, GFP_ATOMIC);
+       if (!g_pIPF)
+               goto ipf_fail;
+       memset(g_pIPF, 0, page_size);
+       total_bytes += page_size;
+
+       /* Malloc memory for data merging during Level2 Cache flush */
+       cache_l2_page_buf = kmalloc(page_size, GFP_ATOMIC);
+       if (!cache_l2_page_buf)
+               goto cache_l2_page_buf_fail;
+       memset(cache_l2_page_buf, 0xff, page_size);
+       total_bytes += page_size;
+
+       cache_l2_blk_buf = kmalloc(block_size, GFP_ATOMIC);
+       if (!cache_l2_blk_buf)
+               goto cache_l2_blk_buf_fail;
+       memset(cache_l2_blk_buf, 0xff, block_size);
+       total_bytes += block_size;
+
+       /* Malloc memory for temp buffer */
+       g_pTempBuf = kmalloc(Cache.cache_item_size, GFP_ATOMIC);
+       if (!g_pTempBuf)
+               goto Temp_buf_fail;
+       memset(g_pTempBuf, 0, Cache.cache_item_size);
+       total_bytes += Cache.cache_item_size;
+
+       /* Malloc memory for block table blocks */
+       mem_size = (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32);
+       g_pBTBlocks = kmalloc(mem_size, GFP_ATOMIC);
+       if (!g_pBTBlocks)
+               goto bt_blocks_fail;
+       memset(g_pBTBlocks, 0xff, mem_size);
+       total_bytes += mem_size;
+
+       /* Malloc memory for function FTL_Check_Block_Table */
+       flag_check_blk_table = kmalloc(DeviceInfo.wDataBlockNum, GFP_ATOMIC);
+       if (!flag_check_blk_table)
+               goto flag_check_blk_table_fail;
+       total_bytes += DeviceInfo.wDataBlockNum;
+
+       /* Malloc memory for function FTL_Search_Block_Table_IN_Block */
+       tmp_buf_search_bt_in_block = kmalloc(page_size, GFP_ATOMIC);
+       if (!tmp_buf_search_bt_in_block)
+               goto tmp_buf_search_bt_in_block_fail;
+       memset(tmp_buf_search_bt_in_block, 0xff, page_size);
+       total_bytes += page_size;
+
+       mem_size = DeviceInfo.wPageSize - DeviceInfo.wPageDataSize;
+       spare_buf_search_bt_in_block = kmalloc(mem_size, GFP_ATOMIC);
+       if (!spare_buf_search_bt_in_block)
+               goto spare_buf_search_bt_in_block_fail;
+       memset(spare_buf_search_bt_in_block, 0xff, mem_size);
+       total_bytes += mem_size;
+
+       spare_buf_bt_search_bt_in_block = kmalloc(mem_size, GFP_ATOMIC);
+       if (!spare_buf_bt_search_bt_in_block)
+               goto spare_buf_bt_search_bt_in_block_fail;
+       memset(spare_buf_bt_search_bt_in_block, 0xff, mem_size);
+       total_bytes += mem_size;
+
+       /* Malloc memory for function FTL_Read_Block_Table */
+       tmp_buf1_read_blk_table = kmalloc(page_size, GFP_ATOMIC);
+       if (!tmp_buf1_read_blk_table)
+               goto tmp_buf1_read_blk_table_fail;
+       memset(tmp_buf1_read_blk_table, 0xff, page_size);
+       total_bytes += page_size;
+
+       tmp_buf2_read_blk_table = kmalloc(page_size, GFP_ATOMIC);
+       if (!tmp_buf2_read_blk_table)
+               goto tmp_buf2_read_blk_table_fail;
+       memset(tmp_buf2_read_blk_table, 0xff, page_size);
+       total_bytes += page_size;
+
+       /* Malloc memory for function FTL_Static_Wear_Leveling */
+       flags_static_wear_leveling = kmalloc(DeviceInfo.wDataBlockNum,
+                                       GFP_ATOMIC);
+       if (!flags_static_wear_leveling)
+               goto flags_static_wear_leveling_fail;
+       total_bytes += DeviceInfo.wDataBlockNum;
+
+       /* Malloc memory for function FTL_Write_Block_Table_Data */
+       if (FTL_Get_Block_Table_Flash_Size_Pages() > 3)
+               mem_size = FTL_Get_Block_Table_Flash_Size_Bytes() -
+                               2 * DeviceInfo.wPageSize;
+       else
+               mem_size = DeviceInfo.wPageSize;
+       tmp_buf_write_blk_table_data = kmalloc(mem_size, GFP_ATOMIC);
+       if (!tmp_buf_write_blk_table_data)
+               goto tmp_buf_write_blk_table_data_fail;
+       memset(tmp_buf_write_blk_table_data, 0xff, mem_size);
+       total_bytes += mem_size;
+
+       /* Malloc memory for function FTL_Read_Disturbance */
+       tmp_buf_read_disturbance = kmalloc(block_size, GFP_ATOMIC);
+       if (!tmp_buf_read_disturbance)
+               goto tmp_buf_read_disturbance_fail;
+       memset(tmp_buf_read_disturbance, 0xff, block_size);
+       total_bytes += block_size;
+
+       /* Alloc mem for function NAND_Read_Page_Main_Spare of lld_nand.c */
+       buf_read_page_main_spare = kmalloc(DeviceInfo.wPageSize, GFP_ATOMIC);
+       if (!buf_read_page_main_spare)
+               goto buf_read_page_main_spare_fail;
+       total_bytes += DeviceInfo.wPageSize;
+
+       /* Alloc mem for function NAND_Write_Page_Main_Spare of lld_nand.c */
+       buf_write_page_main_spare = kmalloc(DeviceInfo.wPageSize, GFP_ATOMIC);
+       if (!buf_write_page_main_spare)
+               goto buf_write_page_main_spare_fail;
+       total_bytes += DeviceInfo.wPageSize;
+
+       /* Alloc mem for function NAND_Read_Page_Spare of lld_nand.c */
+       buf_read_page_spare = kmalloc(DeviceInfo.wPageSpareSize, GFP_ATOMIC);
+       if (!buf_read_page_spare)
+               goto buf_read_page_spare_fail;
+       memset(buf_read_page_spare, 0xff, DeviceInfo.wPageSpareSize);
+       total_bytes += DeviceInfo.wPageSpareSize;
+
+       /* Alloc mem for function NAND_Get_Bad_Block of lld_nand.c */
+       buf_get_bad_block = kmalloc(DeviceInfo.wPageSpareSize, GFP_ATOMIC);
+       if (!buf_get_bad_block)
+               goto buf_get_bad_block_fail;
+       memset(buf_get_bad_block, 0xff, DeviceInfo.wPageSpareSize);
+       total_bytes += DeviceInfo.wPageSpareSize;
+
+#if CMD_DMA
+       g_temp_buf = kmalloc(block_size, GFP_ATOMIC);
+       if (!g_temp_buf)
+               goto temp_buf_fail;
+       memset(g_temp_buf, 0xff, block_size);
+       total_bytes += block_size;
+
+       /* Malloc memory for copy of block table used in CDMA mode */
+       g_pBTStartingCopy = kmalloc(block_table_size, GFP_ATOMIC);
+       if (!g_pBTStartingCopy)
+               goto bt_starting_copy;
+       memset(g_pBTStartingCopy, 0, block_table_size);
+       total_bytes += block_table_size;
+
+       g_pWearCounterCopy = (u8 *)(g_pBTStartingCopy +
+               DeviceInfo.wDataBlockNum * sizeof(u32));
+
+       if (DeviceInfo.MLCDevice)
+               g_pReadCounterCopy = (u16 *)(g_pBTStartingCopy +
+                       DeviceInfo.wDataBlockNum *
+                       (sizeof(u32) + sizeof(u8)));
+
+       /* Malloc memory for block table copies */
+       mem_size = 5 * DeviceInfo.wDataBlockNum * sizeof(u32) +
+                       5 * DeviceInfo.wDataBlockNum * sizeof(u8);
+       if (DeviceInfo.MLCDevice)
+               mem_size += 5 * DeviceInfo.wDataBlockNum * sizeof(u16);
+       g_pBlockTableCopies = kmalloc(mem_size, GFP_ATOMIC);
+       if (!g_pBlockTableCopies)
+               goto blk_table_copies_fail;
+       memset(g_pBlockTableCopies, 0, mem_size);
+       total_bytes += mem_size;
+       g_pNextBlockTable = g_pBlockTableCopies;
+
+       /* Malloc memory for Block Table Delta */
+       mem_size = MAX_DESCS * sizeof(struct BTableChangesDelta);
+       g_pBTDelta = kmalloc(mem_size, GFP_ATOMIC);
+       if (!g_pBTDelta)
+               goto bt_delta_fail;
+       memset(g_pBTDelta, 0, mem_size);
+       total_bytes += mem_size;
+       g_pBTDelta_Free = g_pBTDelta;
+
+       /* Malloc memory for Copy Back Buffers */
+       for (j = 0; j < COPY_BACK_BUF_NUM; j++) {
+               cp_back_buf_copies[j] = kmalloc(block_size, GFP_ATOMIC);
+               if (!cp_back_buf_copies[j])
+                       goto cp_back_buf_copies_fail;
+               memset(cp_back_buf_copies[j], 0, block_size);
+               total_bytes += block_size;
+       }
+       cp_back_buf_idx = 0;
+
+       /* Malloc memory for pending commands list */
+       mem_size = sizeof(struct pending_cmd) * MAX_DESCS;
+       info.pcmds = kzalloc(mem_size, GFP_KERNEL);
+       if (!info.pcmds)
+               goto pending_cmds_buf_fail;
+       total_bytes += mem_size;
+
+       /* Malloc memory for CDMA descripter table */
+       mem_size = sizeof(struct cdma_descriptor) * MAX_DESCS;
+       info.cdma_desc_buf = kzalloc(mem_size, GFP_KERNEL);
+       if (!info.cdma_desc_buf)
+               goto cdma_desc_buf_fail;
+       total_bytes += mem_size;
+
+       /* Malloc memory for Memcpy descripter table */
+       mem_size = sizeof(struct memcpy_descriptor) * MAX_DESCS;
+       info.memcp_desc_buf = kzalloc(mem_size, GFP_KERNEL);
+       if (!info.memcp_desc_buf)
+               goto memcp_desc_buf_fail;
+       total_bytes += mem_size;
+#endif
+
+       nand_dbg_print(NAND_DBG_WARN,
+               "Total memory allocated in FTL layer: %d\n", total_bytes);
+
+       return PASS;
+
+#if CMD_DMA
+memcp_desc_buf_fail:
+       kfree(info.cdma_desc_buf);
+cdma_desc_buf_fail:
+       kfree(info.pcmds);
+pending_cmds_buf_fail:
+cp_back_buf_copies_fail:
+       j--;
+       for (; j >= 0; j--)
+               kfree(cp_back_buf_copies[j]);
+       kfree(g_pBTDelta);
+bt_delta_fail:
+       kfree(g_pBlockTableCopies);
+blk_table_copies_fail:
+       kfree(g_pBTStartingCopy);
+bt_starting_copy:
+       kfree(g_temp_buf);
+temp_buf_fail:
+       kfree(buf_get_bad_block);
+#endif
+
+buf_get_bad_block_fail:
+       kfree(buf_read_page_spare);
+buf_read_page_spare_fail:
+       kfree(buf_write_page_main_spare);
+buf_write_page_main_spare_fail:
+       kfree(buf_read_page_main_spare);
+buf_read_page_main_spare_fail:
+       kfree(tmp_buf_read_disturbance);
+tmp_buf_read_disturbance_fail:
+       kfree(tmp_buf_write_blk_table_data);
+tmp_buf_write_blk_table_data_fail:
+       kfree(flags_static_wear_leveling);
+flags_static_wear_leveling_fail:
+       kfree(tmp_buf2_read_blk_table);
+tmp_buf2_read_blk_table_fail:
+       kfree(tmp_buf1_read_blk_table);
+tmp_buf1_read_blk_table_fail:
+       kfree(spare_buf_bt_search_bt_in_block);
+spare_buf_bt_search_bt_in_block_fail:
+       kfree(spare_buf_search_bt_in_block);
+spare_buf_search_bt_in_block_fail:
+       kfree(tmp_buf_search_bt_in_block);
+tmp_buf_search_bt_in_block_fail:
+       kfree(flag_check_blk_table);
+flag_check_blk_table_fail:
+       kfree(g_pBTBlocks);
+bt_blocks_fail:
+       kfree(g_pTempBuf);
+Temp_buf_fail:
+       kfree(cache_l2_blk_buf);
+cache_l2_blk_buf_fail:
+       kfree(cache_l2_page_buf);
+cache_l2_page_buf_fail:
+       kfree(g_pIPF);
+ipf_fail:
+cache_item_fail:
+       i--;
+       for (; i >= 0; i--)
+               kfree(Cache.array[i].buf);
+       kfree(g_pBlockTable);
+block_table_fail:
+       printk(KERN_ERR "Failed to kmalloc memory in %s Line %d.\n",
+               __FILE__, __LINE__);
+
+       return -ENOMEM;
+}
+
+/* .... */
+static int free_memory(void)
+{
+       int i;
+
+#if CMD_DMA
+       kfree(info.memcp_desc_buf);
+       kfree(info.cdma_desc_buf);
+       kfree(info.pcmds);
+       for (i = COPY_BACK_BUF_NUM - 1; i >= 0; i--)
+               kfree(cp_back_buf_copies[i]);
+       kfree(g_pBTDelta);
+       kfree(g_pBlockTableCopies);
+       kfree(g_pBTStartingCopy);
+       kfree(g_temp_buf);
+       kfree(buf_get_bad_block);
+#endif
+       kfree(buf_read_page_spare);
+       kfree(buf_write_page_main_spare);
+       kfree(buf_read_page_main_spare);
+       kfree(tmp_buf_read_disturbance);
+       kfree(tmp_buf_write_blk_table_data);
+       kfree(flags_static_wear_leveling);
+       kfree(tmp_buf2_read_blk_table);
+       kfree(tmp_buf1_read_blk_table);
+       kfree(spare_buf_bt_search_bt_in_block);
+       kfree(spare_buf_search_bt_in_block);
+       kfree(tmp_buf_search_bt_in_block);
+       kfree(flag_check_blk_table);
+       kfree(g_pBTBlocks);
+       kfree(g_pTempBuf);
+       kfree(g_pIPF);
+       for (i = CACHE_ITEM_NUM - 1; i >= 0; i--)
+               kfree(Cache.array[i].buf);
+       kfree(g_pBlockTable);
+
+       return 0;
+}
+
+static void dump_cache_l2_table(void)
+{
+       struct list_head *p;
+       struct spectra_l2_cache_list *pnd;
+       int n, i;
+
+       n = 0;
+       list_for_each(p, &cache_l2.table.list) {
+               pnd = list_entry(p, struct spectra_l2_cache_list, list);
+               nand_dbg_print(NAND_DBG_WARN, "dump_cache_l2_table node: %d, logical_blk_num: %d\n", n, pnd->logical_blk_num);
+/*
+               for (i = 0; i < DeviceInfo.wPagesPerBlock; i++) {
+                       if (pnd->pages_array[i] != MAX_U32_VALUE)
+                               nand_dbg_print(NAND_DBG_WARN, "    pages_array[%d]: 0x%x\n", i, pnd->pages_array[i]);
+               }
+*/
+               n++;
+       }
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Init
+* Inputs:       none
+* Outputs:      PASS=0 / FAIL=1
+* Description:  allocates the memory for cache array,
+*               important data structures
+*               clears the cache array
+*               reads the block table from flash into array
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Init(void)
+{
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       Cache.pages_per_item = 1;
+       Cache.cache_item_size = 1 * DeviceInfo.wPageDataSize;
+
+       if (allocate_memory() != PASS)
+               return FAIL;
+
+#if CMD_DMA
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       memcpy((void *)&cache_start_copy, (void *)&Cache,
+               sizeof(struct flash_cache_tag));
+       memset((void *)&int_cache, -1,
+               sizeof(struct flash_cache_delta_list_tag) *
+               (MAX_CHANS + MAX_DESCS));
+#endif
+       ftl_cmd_cnt = 0;
+#endif
+
+       if (FTL_Read_Block_Table() != PASS)
+               return FAIL;
+
+       /* Init the Level2 Cache data structure */
+       for (i = 0; i < BLK_NUM_FOR_L2_CACHE; i++)
+               cache_l2.blk_array[i] = MAX_U32_VALUE;
+       cache_l2.cur_blk_idx = 0;
+       cache_l2.cur_page_num = 0;
+       INIT_LIST_HEAD(&cache_l2.table.list);
+       cache_l2.table.logical_blk_num = MAX_U32_VALUE;
+
+       dump_cache_l2_table();
+
+       return 0;
+}
+
+
+#if CMD_DMA
+#if 0
+static void save_blk_table_changes(u16 idx)
+{
+       u8 ftl_cmd;
+       u32 *pbt = (u32 *)g_pBTStartingCopy;
+
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       u16 id;
+       u8 cache_blks;
+
+       id = idx - MAX_CHANS;
+       if (int_cache[id].item != -1) {
+               cache_blks = int_cache[id].item;
+               cache_start_copy.array[cache_blks].address =
+                       int_cache[id].cache.address;
+               cache_start_copy.array[cache_blks].changed =
+                       int_cache[id].cache.changed;
+       }
+#endif
+
+       ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+
+       while (ftl_cmd <= PendingCMD[idx].Tag) {
+               if (p_BTableChangesDelta->ValidFields == 0x01) {
+                       g_wBlockTableOffset =
+                               p_BTableChangesDelta->g_wBlockTableOffset;
+               } else if (p_BTableChangesDelta->ValidFields == 0x0C) {
+                       pbt[p_BTableChangesDelta->BT_Index] =
+                               p_BTableChangesDelta->BT_Entry_Value;
+                       debug_boundary_error(((
+                               p_BTableChangesDelta->BT_Index)),
+                               DeviceInfo.wDataBlockNum, 0);
+               } else if (p_BTableChangesDelta->ValidFields == 0x03) {
+                       g_wBlockTableOffset =
+                               p_BTableChangesDelta->g_wBlockTableOffset;
+                       g_wBlockTableIndex =
+                               p_BTableChangesDelta->g_wBlockTableIndex;
+               } else if (p_BTableChangesDelta->ValidFields == 0x30) {
+                       g_pWearCounterCopy[p_BTableChangesDelta->WC_Index] =
+                               p_BTableChangesDelta->WC_Entry_Value;
+               } else if ((DeviceInfo.MLCDevice) &&
+                       (p_BTableChangesDelta->ValidFields == 0xC0)) {
+                       g_pReadCounterCopy[p_BTableChangesDelta->RC_Index] =
+                               p_BTableChangesDelta->RC_Entry_Value;
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "In event status setting read counter "
+                               "GLOB_ftl_cmd_cnt %u Count %u Index %u\n",
+                               ftl_cmd,
+                               p_BTableChangesDelta->RC_Entry_Value,
+                               (unsigned int)p_BTableChangesDelta->RC_Index);
+               } else {
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "This should never occur \n");
+               }
+               p_BTableChangesDelta += 1;
+               ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+       }
+}
+
+static void discard_cmds(u16 n)
+{
+       u32 *pbt = (u32 *)g_pBTStartingCopy;
+       u8 ftl_cmd;
+       unsigned long k;
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       u8 cache_blks;
+       u16 id;
+#endif
+
+       if ((PendingCMD[n].CMD == WRITE_MAIN_CMD) ||
+               (PendingCMD[n].CMD == WRITE_MAIN_SPARE_CMD)) {
+               for (k = 0; k < DeviceInfo.wDataBlockNum; k++) {
+                       if (PendingCMD[n].Block == (pbt[k] & (~BAD_BLOCK)))
+                               MARK_BLK_AS_DISCARD(pbt[k]);
+               }
+       }
+
+       ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+       while (ftl_cmd <= PendingCMD[n].Tag) {
+               p_BTableChangesDelta += 1;
+               ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+       }
+
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       id = n - MAX_CHANS;
+
+       if (int_cache[id].item != -1) {
+               cache_blks = int_cache[id].item;
+               if (PendingCMD[n].CMD == MEMCOPY_CMD) {
+                       if ((cache_start_copy.array[cache_blks].buf <=
+                               PendingCMD[n].DataDestAddr) &&
+                               ((cache_start_copy.array[cache_blks].buf +
+                               Cache.cache_item_size) >
+                               PendingCMD[n].DataDestAddr)) {
+                               cache_start_copy.array[cache_blks].address =
+                                               NAND_CACHE_INIT_ADDR;
+                               cache_start_copy.array[cache_blks].use_cnt =
+                                                               0;
+                               cache_start_copy.array[cache_blks].changed =
+                                                               CLEAR;
+                       }
+               } else {
+                       cache_start_copy.array[cache_blks].address =
+                                       int_cache[id].cache.address;
+                       cache_start_copy.array[cache_blks].changed =
+                                       int_cache[id].cache.changed;
+               }
+       }
+#endif
+}
+
+static void process_cmd_pass(int *first_failed_cmd, u16 idx)
+{
+       if (0 == *first_failed_cmd)
+               save_blk_table_changes(idx);
+       else
+               discard_cmds(idx);
+}
+
+static void process_cmd_fail_abort(int *first_failed_cmd,
+                               u16 idx, int event)
+{
+       u32 *pbt = (u32 *)g_pBTStartingCopy;
+       u8 ftl_cmd;
+       unsigned long i;
+       int erase_fail, program_fail;
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       u8 cache_blks;
+       u16 id;
+#endif
+
+       if (0 == *first_failed_cmd)
+               *first_failed_cmd = PendingCMD[idx].SBDCmdIndex;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Uncorrectable error has occured "
+               "while executing %u Command %u accesing Block %u\n",
+               (unsigned int)p_BTableChangesDelta->ftl_cmd_cnt,
+               PendingCMD[idx].CMD,
+               (unsigned int)PendingCMD[idx].Block);
+
+       ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+       while (ftl_cmd <= PendingCMD[idx].Tag) {
+               p_BTableChangesDelta += 1;
+               ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+       }
+
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       id = idx - MAX_CHANS;
+
+       if (int_cache[id].item != -1) {
+               cache_blks = int_cache[id].item;
+               if ((PendingCMD[idx].CMD == WRITE_MAIN_CMD)) {
+                       cache_start_copy.array[cache_blks].address =
+                                       int_cache[id].cache.address;
+                       cache_start_copy.array[cache_blks].changed = SET;
+               } else if ((PendingCMD[idx].CMD == READ_MAIN_CMD)) {
+                       cache_start_copy.array[cache_blks].address =
+                               NAND_CACHE_INIT_ADDR;
+                       cache_start_copy.array[cache_blks].use_cnt = 0;
+                       cache_start_copy.array[cache_blks].changed =
+                                                       CLEAR;
+               } else if (PendingCMD[idx].CMD == ERASE_CMD) {
+                       /* ? */
+               } else if (PendingCMD[idx].CMD == MEMCOPY_CMD) {
+                       /* ? */
+               }
+       }
+#endif
+
+       erase_fail = (event == EVENT_ERASE_FAILURE) &&
+                       (PendingCMD[idx].CMD == ERASE_CMD);
+
+       program_fail = (event == EVENT_PROGRAM_FAILURE) &&
+                       ((PendingCMD[idx].CMD == WRITE_MAIN_CMD) ||
+                       (PendingCMD[idx].CMD == WRITE_MAIN_SPARE_CMD));
+
+       if (erase_fail || program_fail) {
+               for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+                       if (PendingCMD[idx].Block ==
+                               (pbt[i] & (~BAD_BLOCK)))
+                               MARK_BLOCK_AS_BAD(pbt[i]);
+               }
+       }
+}
+
+static void process_cmd(int *first_failed_cmd, u16 idx, int event)
+{
+       u8 ftl_cmd;
+       int cmd_match = 0;
+
+       if (p_BTableChangesDelta->ftl_cmd_cnt == PendingCMD[idx].Tag)
+               cmd_match = 1;
+
+       if (PendingCMD[idx].Status == CMD_PASS) {
+               process_cmd_pass(first_failed_cmd, idx);
+       } else if ((PendingCMD[idx].Status == CMD_FAIL) ||
+                       (PendingCMD[idx].Status == CMD_ABORT)) {
+               process_cmd_fail_abort(first_failed_cmd, idx, event);
+       } else if ((PendingCMD[idx].Status == CMD_NOT_DONE) &&
+                                       PendingCMD[idx].Tag) {
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       " Command no. %hu is not executed\n",
+                       (unsigned int)PendingCMD[idx].Tag);
+               ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+               while (ftl_cmd <= PendingCMD[idx].Tag) {
+                       p_BTableChangesDelta += 1;
+                       ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
+               }
+       }
+}
+#endif
+
+static void process_cmd(int *first_failed_cmd, u16 idx, int event)
+{
+       printk(KERN_ERR "temporary workaround function. "
+               "Should not be called! \n");
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:            GLOB_FTL_Event_Status
+* Inputs:       none
+* Outputs:      Event Code
+* Description: It is called by SBD after hardware interrupt signalling
+*               completion of commands chain
+*               It does following things
+*               get event status from LLD
+*               analyze command chain status
+*               determine last command executed
+*               analyze results
+*               rebuild the block table in case of uncorrectable error
+*               return event code
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Event_Status(int *first_failed_cmd)
+{
+       int event_code = PASS;
+       u16 i_P;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       *first_failed_cmd = 0;
+
+       event_code = GLOB_LLD_Event_Status();
+
+       switch (event_code) {
+       case EVENT_PASS:
+               nand_dbg_print(NAND_DBG_DEBUG, "Handling EVENT_PASS\n");
+               break;
+       case EVENT_UNCORRECTABLE_DATA_ERROR:
+               nand_dbg_print(NAND_DBG_DEBUG, "Handling Uncorrectable ECC!\n");
+               break;
+       case EVENT_PROGRAM_FAILURE:
+       case EVENT_ERASE_FAILURE:
+               nand_dbg_print(NAND_DBG_WARN, "Handling Ugly case. "
+                       "Event code: 0x%x\n", event_code);
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta;
+               for (i_P = MAX_CHANS; i_P < (ftl_cmd_cnt + MAX_CHANS);
+                               i_P++)
+                       process_cmd(first_failed_cmd, i_P, event_code);
+               memcpy(g_pBlockTable, g_pBTStartingCopy,
+                       DeviceInfo.wDataBlockNum * sizeof(u32));
+               memcpy(g_pWearCounter, g_pWearCounterCopy,
+                       DeviceInfo.wDataBlockNum * sizeof(u8));
+               if (DeviceInfo.MLCDevice)
+                       memcpy(g_pReadCounter, g_pReadCounterCopy,
+                               DeviceInfo.wDataBlockNum * sizeof(u16));
+
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+               memcpy((void *)&Cache, (void *)&cache_start_copy,
+                       sizeof(struct flash_cache_tag));
+               memset((void *)&int_cache, -1,
+                       sizeof(struct flash_cache_delta_list_tag) *
+                       (MAX_DESCS + MAX_CHANS));
+#endif
+               break;
+       default:
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Handling unexpected event code - 0x%x\n",
+                       event_code);
+               event_code = ERR;
+               break;
+       }
+
+       memcpy(g_pBTStartingCopy, g_pBlockTable,
+               DeviceInfo.wDataBlockNum * sizeof(u32));
+       memcpy(g_pWearCounterCopy, g_pWearCounter,
+               DeviceInfo.wDataBlockNum * sizeof(u8));
+       if (DeviceInfo.MLCDevice)
+               memcpy(g_pReadCounterCopy, g_pReadCounter,
+                       DeviceInfo.wDataBlockNum * sizeof(u16));
+
+       g_pBTDelta_Free = g_pBTDelta;
+       ftl_cmd_cnt = 0;
+       g_pNextBlockTable = g_pBlockTableCopies;
+       cp_back_buf_idx = 0;
+
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       memcpy((void *)&cache_start_copy, (void *)&Cache,
+               sizeof(struct flash_cache_tag));
+       memset((void *)&int_cache, -1,
+               sizeof(struct flash_cache_delta_list_tag) *
+               (MAX_DESCS + MAX_CHANS));
+#endif
+
+       return event_code;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     glob_ftl_execute_cmds
+* Inputs:       none
+* Outputs:      none
+* Description:  pass thru to LLD
+***************************************************************/
+u16 glob_ftl_execute_cmds(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE,
+               "glob_ftl_execute_cmds: ftl_cmd_cnt %u\n",
+               (unsigned int)ftl_cmd_cnt);
+       g_SBDCmdIndex = 0;
+       return glob_lld_execute_cmds();
+}
+
+#endif
+
+#if !CMD_DMA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Read Immediate
+* Inputs:         pointer to data
+*                     address of data
+* Outputs:      PASS / FAIL
+* Description:  Reads one page of data into RAM directly from flash without
+*       using or disturbing cache.It is assumed this function is called
+*       with CMD-DMA disabled.
+*****************************************************************/
+int GLOB_FTL_Read_Immediate(u8 *read_data, u64 addr)
+{
+       int wResult = FAIL;
+       u32 Block;
+       u16 Page;
+       u32 phy_blk;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       Block = BLK_FROM_ADDR(addr);
+       Page = PAGE_FROM_ADDR(addr, Block);
+
+       if (!IS_SPARE_BLOCK(Block))
+               return FAIL;
+
+       phy_blk = pbt[Block];
+       wResult = GLOB_LLD_Read_Page_Main(read_data, phy_blk, Page, 1);
+
+       if (DeviceInfo.MLCDevice) {
+               g_pReadCounter[phy_blk - DeviceInfo.wSpectraStartBlock]++;
+               if (g_pReadCounter[phy_blk - DeviceInfo.wSpectraStartBlock]
+                       >= MAX_READ_COUNTER)
+                       FTL_Read_Disturbance(phy_blk);
+               if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+                       g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                       FTL_Write_IN_Progress_Block_Table_Page();
+               }
+       }
+
+       return wResult;
+}
+#endif
+
+#ifdef SUPPORT_BIG_ENDIAN
+/*********************************************************************
+* Function:     FTL_Invert_Block_Table
+* Inputs:       none
+* Outputs:      none
+* Description:  Re-format the block table in ram based on BIG_ENDIAN and
+*                     LARGE_BLOCKNUM if necessary
+**********************************************************************/
+static void FTL_Invert_Block_Table(void)
+{
+       u32 i;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+#ifdef SUPPORT_LARGE_BLOCKNUM
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               pbt[i] = INVERTUINT32(pbt[i]);
+               g_pWearCounter[i] = INVERTUINT32(g_pWearCounter[i]);
+       }
+#else
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               pbt[i] = INVERTUINT16(pbt[i]);
+               g_pWearCounter[i] = INVERTUINT16(g_pWearCounter[i]);
+       }
+#endif
+}
+#endif
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Flash_Init
+* Inputs:       none
+* Outputs:      PASS=0 / FAIL=0x01 (based on read ID)
+* Description:  The flash controller is initialized
+*               The flash device is reset
+*               Perform a flash READ ID command to confirm that a
+*                   valid device is attached and active.
+*                   The DeviceInfo structure gets filled in
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Flash_Init(void)
+{
+       int status = FAIL;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       g_SBDCmdIndex = 0;
+
+       GLOB_LLD_Flash_Init();
+
+       status = GLOB_LLD_Read_Device_ID();
+
+       return status;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Inputs:       none
+* Outputs:      PASS=0 / FAIL=0x01 (based on read ID)
+* Description:  The flash controller is released
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Flash_Release(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       return GLOB_LLD_Flash_Release();
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Cache_Release
+* Inputs:       none
+* Outputs:      none
+* Description:  release all allocated memory in GLOB_FTL_Init
+*               (allocated in GLOB_FTL_Init)
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void GLOB_FTL_Cache_Release(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       free_memory();
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_If_Hit
+* Inputs:       Page Address
+* Outputs:      Block number/UNHIT BLOCK
+* Description:  Determines if the addressed page is in cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u16 FTL_Cache_If_Hit(u64 page_addr)
+{
+       u16 item;
+       u64 addr;
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       item = UNHIT_CACHE_ITEM;
+       for (i = 0; i < CACHE_ITEM_NUM; i++) {
+               addr = Cache.array[i].address;
+               if ((page_addr >= addr) &&
+                       (page_addr < (addr + Cache.cache_item_size))) {
+                       item = i;
+                       break;
+               }
+       }
+
+       return item;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Calculate_LRU
+* Inputs:       None
+* Outputs:      None
+* Description:  Calculate the least recently block in a cache and record its
+*               index in LRU field.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void FTL_Calculate_LRU(void)
+{
+       u16 i, bCurrentLRU, bTempCount;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       bCurrentLRU = 0;
+       bTempCount = MAX_WORD_VALUE;
+
+       for (i = 0; i < CACHE_ITEM_NUM; i++) {
+               if (Cache.array[i].use_cnt < bTempCount) {
+                       bCurrentLRU = i;
+                       bTempCount = Cache.array[i].use_cnt;
+               }
+       }
+
+       Cache.LRU = bCurrentLRU;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Read_Page
+* Inputs:       pointer to read buffer, logical address and cache item number
+* Outputs:      None
+* Description:  Read the page from the cached block addressed by blocknumber
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void FTL_Cache_Read_Page(u8 *data_buf, u64 logic_addr, u16 cache_item)
+{
+       u8 *start_addr;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       start_addr = Cache.array[cache_item].buf;
+       start_addr += (u32)(((logic_addr - Cache.array[cache_item].address) >>
+               DeviceInfo.nBitsInPageDataSize) * DeviceInfo.wPageDataSize);
+
+#if CMD_DMA
+       GLOB_LLD_MemCopy_CMD(data_buf, start_addr,
+                       DeviceInfo.wPageDataSize, 0);
+       ftl_cmd_cnt++;
+#else
+       memcpy(data_buf, start_addr, DeviceInfo.wPageDataSize);
+#endif
+
+       if (Cache.array[cache_item].use_cnt < MAX_WORD_VALUE)
+               Cache.array[cache_item].use_cnt++;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Read_All
+* Inputs:       pointer to read buffer,block address
+* Outputs:      PASS=0 / FAIL =1
+* Description:  It reads pages in cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Read_All(u8 *pData, u64 phy_addr)
+{
+       int wResult = PASS;
+       u32 Block;
+       u32 lba;
+       u16 Page;
+       u16 PageCount;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 i;
+
+       Block = BLK_FROM_ADDR(phy_addr);
+       Page = PAGE_FROM_ADDR(phy_addr, Block);
+       PageCount = Cache.pages_per_item;
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+                       "%s, Line %d, Function: %s, Block: 0x%x\n",
+                       __FILE__, __LINE__, __func__, Block);
+
+       lba = 0xffffffff;
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               if ((pbt[i] & (~BAD_BLOCK)) == Block) {
+                       lba = i;
+                       if (IS_SPARE_BLOCK(i) || IS_BAD_BLOCK(i) ||
+                               IS_DISCARDED_BLOCK(i)) {
+                               /* Add by yunpeng -2008.12.3 */
+#if CMD_DMA
+                               GLOB_LLD_MemCopy_CMD(pData, g_temp_buf,
+                               PageCount * DeviceInfo.wPageDataSize, 0);
+                               ftl_cmd_cnt++;
+#else
+                               memset(pData, 0xFF,
+                                       PageCount * DeviceInfo.wPageDataSize);
+#endif
+                               return wResult;
+                       } else {
+                               continue; /* break ?? */
+                       }
+               }
+       }
+
+       if (0xffffffff == lba)
+               printk(KERN_ERR "FTL_Cache_Read_All: Block is not found in BT\n");
+
+#if CMD_DMA
+       wResult = GLOB_LLD_Read_Page_Main_cdma(pData, Block, Page,
+                       PageCount, LLD_CMD_FLAG_MODE_CDMA);
+       if (DeviceInfo.MLCDevice) {
+               g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock]++;
+               nand_dbg_print(NAND_DBG_DEBUG,
+                              "Read Counter modified in ftl_cmd_cnt %u"
+                               " Block %u Counter%u\n",
+                              ftl_cmd_cnt, (unsigned int)Block,
+                              g_pReadCounter[Block -
+                              DeviceInfo.wSpectraStartBlock]);
+
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+               p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+               p_BTableChangesDelta->RC_Index =
+                       Block - DeviceInfo.wSpectraStartBlock;
+               p_BTableChangesDelta->RC_Entry_Value =
+                       g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock];
+               p_BTableChangesDelta->ValidFields = 0xC0;
+
+               ftl_cmd_cnt++;
+
+               if (g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock] >=
+                   MAX_READ_COUNTER)
+                       FTL_Read_Disturbance(Block);
+               if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+                       g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                       FTL_Write_IN_Progress_Block_Table_Page();
+               }
+       } else {
+               ftl_cmd_cnt++;
+       }
+#else
+       wResult = GLOB_LLD_Read_Page_Main(pData, Block, Page, PageCount);
+       if (wResult == FAIL)
+               return wResult;
+
+       if (DeviceInfo.MLCDevice) {
+               g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock]++;
+               if (g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock] >=
+                                               MAX_READ_COUNTER)
+                       FTL_Read_Disturbance(Block);
+               if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+                       g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                       FTL_Write_IN_Progress_Block_Table_Page();
+               }
+       }
+#endif
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Write_All
+* Inputs:       pointer to cache in sys memory
+*               address of free block in flash
+* Outputs:      PASS=0 / FAIL=1
+* Description:  writes all the pages of the block in cache to flash
+*
+*               NOTE:need to make sure this works ok when cache is limited
+*               to a partial block. This is where copy-back would be
+*               activated.  This would require knowing which pages in the
+*               cached block are clean/dirty.Right now we only know if
+*               the whole block is clean/dirty.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr)
+{
+       u16 wResult = PASS;
+       u32 Block;
+       u16 Page;
+       u16 PageCount;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       nand_dbg_print(NAND_DBG_DEBUG, "This block %d going to be written "
+               "on %d\n", cache_block_to_write,
+               (u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize));
+
+       Block = BLK_FROM_ADDR(blk_addr);
+       Page = PAGE_FROM_ADDR(blk_addr, Block);
+       PageCount = Cache.pages_per_item;
+
+#if CMD_DMA
+       if (FAIL == GLOB_LLD_Write_Page_Main_cdma(pData,
+                                       Block, Page, PageCount)) {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "NAND Program fail in %s, Line %d, "
+                       "Function: %s, new Bad Block %d generated! "
+                       "Need Bad Block replacing.\n",
+                       __FILE__, __LINE__, __func__, Block);
+               wResult = FAIL;
+       }
+       ftl_cmd_cnt++;
+#else
+       if (FAIL == GLOB_LLD_Write_Page_Main(pData, Block, Page, PageCount)) {
+               nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in %s,"
+                       " Line %d, Function %s, new Bad Block %d generated!"
+                       "Need Bad Block replacing.\n",
+                       __FILE__, __LINE__, __func__, Block);
+               wResult = FAIL;
+       }
+#endif
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Update_Block
+* Inputs:       pointer to buffer,page address,block address
+* Outputs:      PASS=0 / FAIL=1
+* Description:  It updates the cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Update_Block(u8 *pData,
+                       u64 old_page_addr, u64 blk_addr)
+{
+       int i, j;
+       u8 *buf = pData;
+       int wResult = PASS;
+       int wFoundInCache;
+       u64 page_addr;
+       u64 addr;
+       u64 old_blk_addr;
+       u16 page_offset;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                               __FILE__, __LINE__, __func__);
+
+       old_blk_addr = (u64)(old_page_addr >>
+               DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize;
+       page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >>
+               DeviceInfo.nBitsInPageDataSize);
+
+       for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) {
+               page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize;
+               if (i != page_offset) {
+                       wFoundInCache = FAIL;
+                       for (j = 0; j < CACHE_ITEM_NUM; j++) {
+                               addr = Cache.array[j].address;
+                               addr = FTL_Get_Physical_Block_Addr(addr) +
+                                       GLOB_u64_Remainder(addr, 2);
+                               if ((addr >= page_addr) && addr <
+                                       (page_addr + Cache.cache_item_size)) {
+                                       wFoundInCache = PASS;
+                                       buf = Cache.array[j].buf;
+                                       Cache.array[j].changed = SET;
+#if CMD_DMA
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+                                       int_cache[ftl_cmd_cnt].item = j;
+                                       int_cache[ftl_cmd_cnt].cache.address =
+                                               Cache.array[j].address;
+                                       int_cache[ftl_cmd_cnt].cache.changed =
+                                               Cache.array[j].changed;
+#endif
+#endif
+                                       break;
+                               }
+                       }
+                       if (FAIL == wFoundInCache) {
+                               if (ERR == FTL_Cache_Read_All(g_pTempBuf,
+                                       page_addr)) {
+                                       wResult = FAIL;
+                                       break;
+                               }
+                               buf = g_pTempBuf;
+                       }
+               } else {
+                       buf = pData;
+               }
+
+               if (FAIL == FTL_Cache_Write_All(buf,
+                       blk_addr + (page_addr - old_blk_addr))) {
+                       wResult = FAIL;
+                       break;
+               }
+       }
+
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Copy_Block
+* Inputs:       source block address
+*               Destination block address
+* Outputs:      PASS=0 / FAIL=1
+* Description:  used only for static wear leveling to move the block
+*               containing static data to new blocks(more worn)
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int FTL_Copy_Block(u64 old_blk_addr, u64 blk_addr)
+{
+       int i, r1, r2, wResult = PASS;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) {
+               r1 = FTL_Cache_Read_All(g_pTempBuf, old_blk_addr +
+                                       i * DeviceInfo.wPageDataSize);
+               r2 = FTL_Cache_Write_All(g_pTempBuf, blk_addr +
+                                       i * DeviceInfo.wPageDataSize);
+               if ((ERR == r1) || (FAIL == r2)) {
+                       wResult = FAIL;
+                       break;
+               }
+       }
+
+       return wResult;
+}
+
+/* Search the block table to find out the least wear block and then return it */
+static u32 find_least_worn_blk_for_l2_cache(void)
+{
+       int i;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u8 least_wear_cnt = MAX_BYTE_VALUE;
+       u32 least_wear_blk_idx = MAX_U32_VALUE;
+       u32 phy_idx;
+
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               if (IS_SPARE_BLOCK(i)) {
+                       phy_idx = (u32)((~BAD_BLOCK) & pbt[i]);
+                       if (phy_idx > DeviceInfo.wSpectraEndBlock)
+                               printk(KERN_ERR "find_least_worn_blk_for_l2_cache: "
+                                       "Too big phy block num (%d)\n", phy_idx);
+                       if (g_pWearCounter[phy_idx -DeviceInfo.wSpectraStartBlock] < least_wear_cnt) {
+                               least_wear_cnt = g_pWearCounter[phy_idx - DeviceInfo.wSpectraStartBlock];
+                               least_wear_blk_idx = i;
+                       }
+               }
+       }
+
+       nand_dbg_print(NAND_DBG_WARN,
+               "find_least_worn_blk_for_l2_cache: "
+               "find block %d with least worn counter (%d)\n",
+               least_wear_blk_idx, least_wear_cnt);
+
+       return least_wear_blk_idx;
+}
+
+
+
+/* Get blocks for Level2 Cache */
+static int get_l2_cache_blks(void)
+{
+       int n;
+       u32 blk;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       for (n = 0; n < BLK_NUM_FOR_L2_CACHE; n++) {
+               blk = find_least_worn_blk_for_l2_cache();
+               if (blk > DeviceInfo.wDataBlockNum) {
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "find_least_worn_blk_for_l2_cache: "
+                               "No enough free NAND blocks (n: %d) for L2 Cache!\n", n);
+                       return FAIL;
+               }
+               /* Tag the free block as discard in block table */
+               pbt[blk] = (pbt[blk] & (~BAD_BLOCK)) | DISCARD_BLOCK;
+               /* Add the free block to the L2 Cache block array */
+               cache_l2.blk_array[n] = pbt[blk] & (~BAD_BLOCK);
+       }
+
+       return PASS;
+}
+
+static int erase_l2_cache_blocks(void)
+{
+       int i, ret = PASS;
+       u32 pblk, lblk;
+       u64 addr;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < BLK_NUM_FOR_L2_CACHE; i++) {
+               pblk = cache_l2.blk_array[i];
+
+               /* If the L2 cache block is invalid, then just skip it */
+               if (MAX_U32_VALUE == pblk)
+                       continue;
+
+               BUG_ON(pblk > DeviceInfo.wSpectraEndBlock);
+
+               addr = (u64)pblk << DeviceInfo.nBitsInBlockDataSize;
+               if (PASS == GLOB_FTL_Block_Erase(addr)) {
+                       /* Get logical block number of the erased block */
+                       lblk = FTL_Get_Block_Index(pblk);
+                       BUG_ON(BAD_BLOCK == lblk);
+                       /* Tag it as free in the block table */
+                       pbt[lblk] &= (u32)(~DISCARD_BLOCK);
+                       pbt[lblk] |= (u32)(SPARE_BLOCK);
+               } else {
+                       MARK_BLOCK_AS_BAD(pbt[lblk]);
+                       ret = ERR;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * Merge the valid data page in the L2 cache blocks into NAND.
+*/
+static int flush_l2_cache(void)
+{
+       struct list_head *p;
+       struct spectra_l2_cache_list *pnd, *tmp_pnd;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 phy_blk, l2_blk;
+       u64 addr;
+       u16 l2_page;
+       int i, ret = PASS;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       if (list_empty(&cache_l2.table.list)) /* No data to flush */
+               return ret;
+
+       //dump_cache_l2_table();
+
+       if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+               g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+               FTL_Write_IN_Progress_Block_Table_Page();
+       }
+
+       list_for_each(p, &cache_l2.table.list) {
+               pnd = list_entry(p, struct spectra_l2_cache_list, list);
+               if (IS_SPARE_BLOCK(pnd->logical_blk_num) ||
+                       IS_BAD_BLOCK(pnd->logical_blk_num) ||
+                       IS_DISCARDED_BLOCK(pnd->logical_blk_num)) {
+                       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d\n", __FILE__, __LINE__);
+                       memset(cache_l2_blk_buf, 0xff, DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize);                   
+               } else {
+                       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d\n", __FILE__, __LINE__);
+                       phy_blk = pbt[pnd->logical_blk_num] & (~BAD_BLOCK);
+                       ret = GLOB_LLD_Read_Page_Main(cache_l2_blk_buf,
+                               phy_blk, 0, DeviceInfo.wPagesPerBlock);
+                       if (ret == FAIL) {
+                               printk(KERN_ERR "Read NAND page fail in %s, Line %d\n", __FILE__, __LINE__);
+                       }
+               }
+
+               for (i = 0; i < DeviceInfo.wPagesPerBlock; i++) {
+                       if (pnd->pages_array[i] != MAX_U32_VALUE) {
+                               l2_blk = cache_l2.blk_array[(pnd->pages_array[i] >> 16) & 0xffff];
+                               l2_page = pnd->pages_array[i] & 0xffff;
+                               ret = GLOB_LLD_Read_Page_Main(cache_l2_page_buf, l2_blk, l2_page, 1);
+                               if (ret == FAIL) {
+                                       printk(KERN_ERR "Read NAND page fail in %s, Line %d\n", __FILE__, __LINE__);
+                               }
+                               memcpy(cache_l2_blk_buf + i * DeviceInfo.wPageDataSize, cache_l2_page_buf, DeviceInfo.wPageDataSize);
+                       }
+               }
+
+               /* Find a free block and tag the original block as discarded */
+               addr = (u64)pnd->logical_blk_num << DeviceInfo.nBitsInBlockDataSize;
+               ret = FTL_Replace_Block(addr);
+               if (ret == FAIL) {
+                       printk(KERN_ERR "FTL_Replace_Block fail in %s, Line %d\n", __FILE__, __LINE__);
+               }
+
+               /* Write back the updated data into NAND */
+               phy_blk = pbt[pnd->logical_blk_num] & (~BAD_BLOCK);
+               if (FAIL == GLOB_LLD_Write_Page_Main(cache_l2_blk_buf, phy_blk, 0, DeviceInfo.wPagesPerBlock)) {
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "Program NAND block %d fail in %s, Line %d\n",
+                               phy_blk, __FILE__, __LINE__);
+                       /* This may not be really a bad block. So just tag it as discarded. */
+                       /* Then it has a chance to be erased when garbage collection. */
+                       /* If it is really bad, then the erase will fail and it will be marked */
+                       /* as bad then. Otherwise it will be marked as free and can be used again */
+                       MARK_BLK_AS_DISCARD(pbt[pnd->logical_blk_num]);
+                       /* Find another free block and write it again */
+                       FTL_Replace_Block(addr);
+                       phy_blk = pbt[pnd->logical_blk_num] & (~BAD_BLOCK);
+                       if (FAIL == GLOB_LLD_Write_Page_Main(cache_l2_blk_buf, phy_blk, 0, DeviceInfo.wPagesPerBlock)) {
+                               printk(KERN_ERR "Failed to write back block %d when flush L2 cache."
+                                       "Some data will be lost!\n", phy_blk);
+                               MARK_BLOCK_AS_BAD(pbt[pnd->logical_blk_num]);
+                       }
+               } else {
+                       /* tag the new free block as used block */
+                       pbt[pnd->logical_blk_num] &= (~SPARE_BLOCK);
+               }
+       }
+
+       /* Destroy the L2 Cache table and free the memory of all nodes */
+       list_for_each_entry_safe(pnd, tmp_pnd, &cache_l2.table.list, list) {
+               list_del(&pnd->list);
+               kfree(pnd);
+       }
+
+       /* Erase discard L2 cache blocks */
+       if (erase_l2_cache_blocks() != PASS)
+               nand_dbg_print(NAND_DBG_WARN,
+                       " Erase L2 cache blocks error in %s, Line %d\n",
+                       __FILE__, __LINE__);
+
+       /* Init the Level2 Cache data structure */
+       for (i = 0; i < BLK_NUM_FOR_L2_CACHE; i++)
+               cache_l2.blk_array[i] = MAX_U32_VALUE;
+       cache_l2.cur_blk_idx = 0;
+       cache_l2.cur_page_num = 0;
+       INIT_LIST_HEAD(&cache_l2.table.list);
+       cache_l2.table.logical_blk_num = MAX_U32_VALUE;
+
+       return ret;
+}
+
+/*
+ * Write back a changed victim cache item to the Level2 Cache
+ * and update the L2 Cache table to map the change.
+ * If the L2 Cache is full, then start to do the L2 Cache flush.
+*/
+static int write_back_to_l2_cache(u8 *buf, u64 logical_addr)
+{
+       u32 logical_blk_num;
+       u16 logical_page_num;
+       struct list_head *p;
+       struct spectra_l2_cache_list *pnd, *pnd_new;
+       u32 node_size;
+       int i, found;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       /*
+        * If Level2 Cache table is empty, then it means either:
+        * 1. This is the first time that the function called after FTL_init
+        * or
+        * 2. The Level2 Cache has just been flushed
+        *
+        * So, 'steal' some free blocks from NAND for L2 Cache using
+        * by just mask them as discard in the block table
+       */
+       if (list_empty(&cache_l2.table.list)) {
+               BUG_ON(cache_l2.cur_blk_idx != 0);
+               BUG_ON(cache_l2.cur_page_num!= 0);
+               BUG_ON(cache_l2.table.logical_blk_num != MAX_U32_VALUE);
+               if (FAIL == get_l2_cache_blks()) {
+                       GLOB_FTL_Garbage_Collection();
+                       if (FAIL == get_l2_cache_blks()) {
+                               printk(KERN_ALERT "Fail to get L2 cache blks!\n");
+                               return FAIL;
+                       }
+               }
+       }
+
+       logical_blk_num = BLK_FROM_ADDR(logical_addr);
+       logical_page_num = PAGE_FROM_ADDR(logical_addr, logical_blk_num);
+       BUG_ON(logical_blk_num == MAX_U32_VALUE);
+
+       /* Write the cache item data into the current position of L2 Cache */
+#if CMD_DMA
+       /*
+        * TODO
+        */
+#else
+       if (FAIL == GLOB_LLD_Write_Page_Main(buf,
+               cache_l2.blk_array[cache_l2.cur_blk_idx],
+               cache_l2.cur_page_num, 1)) {
+               nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in "
+                       "%s, Line %d, new Bad Block %d generated!\n",
+                       __FILE__, __LINE__,
+                       cache_l2.blk_array[cache_l2.cur_blk_idx]);
+
+               /* TODO: tag the current block as bad and try again */
+
+               return FAIL;
+       }
+#endif
+
+       /* 
+        * Update the L2 Cache table.
+        *
+        * First seaching in the table to see whether the logical block
+        * has been mapped. If not, then kmalloc a new node for the
+        * logical block, fill data, and then insert it to the list.
+        * Otherwise, just update the mapped node directly.
+        */
+       found = 0;
+       list_for_each(p, &cache_l2.table.list) {
+               pnd = list_entry(p, struct spectra_l2_cache_list, list);
+               if (pnd->logical_blk_num == logical_blk_num) {
+                       pnd->pages_array[logical_page_num] =
+                               (cache_l2.cur_blk_idx << 16) |
+                               cache_l2.cur_page_num;
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found) { /* Create new node for the logical block here */
+
+               /* The logical pages to physical pages map array is
+                * located at the end of struct spectra_l2_cache_list.
+                */ 
+               node_size = sizeof(struct spectra_l2_cache_list) +
+                       sizeof(u32) * DeviceInfo.wPagesPerBlock;
+               pnd_new = kmalloc(node_size, GFP_ATOMIC);
+               if (!pnd_new) {
+                       printk(KERN_ERR "Failed to kmalloc in %s Line %d\n",
+                               __FILE__, __LINE__);
+                       /* 
+                        * TODO: Need to flush all the L2 cache into NAND ASAP
+                        * since no memory available here
+                        */
+               }
+               pnd_new->logical_blk_num = logical_blk_num;
+               for (i = 0; i < DeviceInfo.wPagesPerBlock; i++)
+                       pnd_new->pages_array[i] = MAX_U32_VALUE;
+               pnd_new->pages_array[logical_page_num] =
+                       (cache_l2.cur_blk_idx << 16) | cache_l2.cur_page_num;
+               list_add(&pnd_new->list, &cache_l2.table.list);
+       }
+
+       /* Increasing the current position pointer of the L2 Cache */
+       cache_l2.cur_page_num++;
+       if (cache_l2.cur_page_num >= DeviceInfo.wPagesPerBlock) {
+               cache_l2.cur_blk_idx++;
+               if (cache_l2.cur_blk_idx >= BLK_NUM_FOR_L2_CACHE) {
+                       /* The L2 Cache is full. Need to flush it now */
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "L2 Cache is full, will start to flush it\n");
+                       flush_l2_cache();
+               } else {
+                       cache_l2.cur_page_num = 0;
+               }
+       }
+
+       return PASS;
+}
+
+/*
+ * Seach in the Level2 Cache table to find the cache item.
+ * If find, read the data from the NAND page of L2 Cache,
+ * Otherwise, return FAIL.
+ */
+static int search_l2_cache(u8 *buf, u64 logical_addr)
+{
+       u32 logical_blk_num;
+       u16 logical_page_num;
+       struct list_head *p;
+       struct spectra_l2_cache_list *pnd;
+       u32 tmp = MAX_U32_VALUE;
+       u32 phy_blk;
+       u16 phy_page;
+       int ret = FAIL;
+
+       logical_blk_num = BLK_FROM_ADDR(logical_addr);
+       logical_page_num = PAGE_FROM_ADDR(logical_addr, logical_blk_num);
+
+       list_for_each(p, &cache_l2.table.list) {
+               pnd = list_entry(p, struct spectra_l2_cache_list, list);
+               if (pnd->logical_blk_num == logical_blk_num) {
+                       tmp = pnd->pages_array[logical_page_num];
+                       break;
+               }
+       }
+
+       if (tmp != MAX_U32_VALUE) { /* Found valid map */
+               phy_blk = cache_l2.blk_array[(tmp >> 16) & 0xFFFF];
+               phy_page = tmp & 0xFFFF;
+#if CMD_DMA
+               /* TODO */
+#else
+               ret = GLOB_LLD_Read_Page_Main(buf, phy_blk, phy_page, 1);
+#endif
+       }
+
+       return ret;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Write_Back
+* Inputs:       pointer to data cached in sys memory
+*               address of free block in flash
+* Outputs:      PASS=0 / FAIL=1
+* Description:  writes all the pages of Cache Block to flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr)
+{
+       int i, j, iErase;
+       u64 old_page_addr, addr, phy_addr;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 lba;
+       
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) +
+               GLOB_u64_Remainder(blk_addr, 2);
+
+       iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL;
+
+       pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK);
+
+#if CMD_DMA
+       p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
+       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+       p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+       p_BTableChangesDelta->BT_Index = (u32)(blk_addr >>
+               DeviceInfo.nBitsInBlockDataSize);
+       p_BTableChangesDelta->BT_Entry_Value =
+               pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)];
+       p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+
+       if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+               g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+               FTL_Write_IN_Progress_Block_Table_Page();
+       }
+
+       for (i = 0; i < RETRY_TIMES; i++) {
+               if (PASS == iErase) {
+                       phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+                       if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
+                               lba = BLK_FROM_ADDR(blk_addr);
+                               MARK_BLOCK_AS_BAD(pbt[lba]);
+                               i = RETRY_TIMES;
+                               break;
+                       }
+               }
+
+               for (j = 0; j < CACHE_ITEM_NUM; j++) {
+                       addr = Cache.array[j].address;
+                       if ((addr <= blk_addr) &&
+                               ((addr + Cache.cache_item_size) > blk_addr))
+                               cache_block_to_write = j;
+               }
+
+               phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+               if (PASS == FTL_Cache_Update_Block(pData,
+                                       old_page_addr, phy_addr)) {
+                       cache_block_to_write = UNHIT_CACHE_ITEM;
+                       break;
+               } else {
+                       iErase = PASS;
+               }
+       }
+
+       if (i >= RETRY_TIMES) {
+               if (ERR == FTL_Flash_Error_Handle(pData,
+                                       old_page_addr, blk_addr))
+                       return ERR;
+               else
+                       return FAIL;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Write_Page
+* Inputs:       Pointer to buffer, page address, cache block number
+* Outputs:      PASS=0 / FAIL=1
+* Description:  It writes the data in Cache Block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void FTL_Cache_Write_Page(u8 *pData, u64 page_addr,
+                               u8 cache_blk, u16 flag)
+{
+       u8 *pDest;
+       u64 addr;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       addr = Cache.array[cache_blk].address;
+       pDest = Cache.array[cache_blk].buf;
+
+       pDest += (unsigned long)(page_addr - addr);
+       Cache.array[cache_blk].changed = SET;
+#if CMD_DMA
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       int_cache[ftl_cmd_cnt].item = cache_blk;
+       int_cache[ftl_cmd_cnt].cache.address =
+                       Cache.array[cache_blk].address;
+       int_cache[ftl_cmd_cnt].cache.changed =
+                       Cache.array[cache_blk].changed;
+#endif
+       GLOB_LLD_MemCopy_CMD(pDest, pData, DeviceInfo.wPageDataSize, flag);
+       ftl_cmd_cnt++;
+#else
+       memcpy(pDest, pData, DeviceInfo.wPageDataSize);
+#endif
+       if (Cache.array[cache_blk].use_cnt < MAX_WORD_VALUE)
+               Cache.array[cache_blk].use_cnt++;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Write
+* Inputs:       none
+* Outputs:      PASS=0 / FAIL=1
+* Description:  It writes least frequently used Cache block to flash if it
+*               has been changed
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Write(void)
+{
+       int i, bResult = PASS;
+       u16 bNO, least_count = 0xFFFF;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       FTL_Calculate_LRU();
+
+       bNO = Cache.LRU;
+       nand_dbg_print(NAND_DBG_DEBUG, "FTL_Cache_Write: "
+               "Least used cache block is %d\n", bNO);
+
+       if (Cache.array[bNO].changed != SET)
+               return bResult;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "FTL_Cache_Write: Cache"
+               " Block %d containing logical block %d is dirty\n",
+               bNO,
+               (u32)(Cache.array[bNO].address >>
+               DeviceInfo.nBitsInBlockDataSize));
+#if CMD_DMA
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       int_cache[ftl_cmd_cnt].item = bNO;
+       int_cache[ftl_cmd_cnt].cache.address =
+                               Cache.array[bNO].address;
+       int_cache[ftl_cmd_cnt].cache.changed = CLEAR;
+#endif
+#endif
+       bResult = write_back_to_l2_cache(Cache.array[bNO].buf,
+                       Cache.array[bNO].address);
+       if (bResult != ERR)
+               Cache.array[bNO].changed = CLEAR;
+
+       least_count = Cache.array[bNO].use_cnt;
+
+       for (i = 0; i < CACHE_ITEM_NUM; i++) {
+               if (i == bNO)
+                       continue;
+               if (Cache.array[i].use_cnt > 0)
+                       Cache.array[i].use_cnt -= least_count;
+       }
+
+       return bResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Cache_Read
+* Inputs:       Page address
+* Outputs:      PASS=0 / FAIL=1
+* Description:  It reads the block from device in Cache Block
+*               Set the LRU count to 1
+*               Mark the Cache Block as clean
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Read(u64 logical_addr)
+{
+       u64 item_addr, phy_addr;
+       u16 num;
+       int ret;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       num = Cache.LRU; /* The LRU cache item will be overwritten */
+
+       item_addr = (u64)GLOB_u64_Div(logical_addr, Cache.cache_item_size) *
+               Cache.cache_item_size;
+       Cache.array[num].address = item_addr;
+       Cache.array[num].use_cnt = 1;
+       Cache.array[num].changed = CLEAR;
+
+#if CMD_DMA
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+       int_cache[ftl_cmd_cnt].item = num;
+       int_cache[ftl_cmd_cnt].cache.address =
+                       Cache.array[num].address;
+       int_cache[ftl_cmd_cnt].cache.changed =
+                       Cache.array[num].changed;
+#endif
+#endif
+       /*
+        * Search in L2 Cache. If hit, fill data into L1 Cache item buffer,
+        * Otherwise, read it from NAND
+        */
+       ret = search_l2_cache(Cache.array[num].buf, logical_addr);
+       if (PASS == ret) /* Hit in L2 Cache */
+               return ret;
+
+       /* Compute the physical start address of NAND device according to */
+       /* the logical start address of the cache item (LRU cache item) */
+       phy_addr = FTL_Get_Physical_Block_Addr(item_addr) +
+               GLOB_u64_Remainder(item_addr, 2);
+
+       return FTL_Cache_Read_All(Cache.array[num].buf, phy_addr);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Check_Block_Table
+* Inputs:       ?
+* Outputs:      PASS=0 / FAIL=1
+* Description:  It checks the correctness of each block table entry
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Check_Block_Table(int wOldTable)
+{
+       u32 i;
+       int wResult = PASS;
+       u32 blk_idx;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u8 *pFlag = flag_check_blk_table;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (NULL != pFlag) {
+               memset(pFlag, FAIL, DeviceInfo.wDataBlockNum);
+               for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+                       blk_idx = (u32)(pbt[i] & (~BAD_BLOCK));
+
+                       /*
+                        * 20081006/KBV - Changed to pFlag[i] reference
+                        * to avoid buffer overflow
+                        */
+
+                       /*
+                        * 2008-10-20 Yunpeng Note: This change avoid
+                        * buffer overflow, but changed function of
+                        * the code, so it should be re-write later
+                        */
+                       if ((blk_idx > DeviceInfo.wSpectraEndBlock) ||
+                               PASS == pFlag[i]) {
+                               wResult = FAIL;
+                               break;
+                       } else {
+                               pFlag[i] = PASS;
+                       }
+               }
+       }
+
+       return wResult;
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Write_Block_Table
+* Inputs:       flasg
+* Outputs:      0=Block Table was updated. No write done. 1=Block write needs to
+* happen. -1 Error
+* Description:  It writes the block table
+*               Block table always mapped to LBA 0 which inturn mapped
+*               to any physical block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Write_Block_Table(int wForce)
+{
+       u32 *pbt = (u32 *)g_pBlockTable;
+       int wSuccess = PASS;
+       u32 wTempBlockTableIndex;
+       u16 bt_pages, new_bt_offset;
+       u8 blockchangeoccured = 0;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+       if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus)
+               return 0;
+
+       if (PASS == wForce) {
+               g_wBlockTableOffset =
+                       (u16)(DeviceInfo.wPagesPerBlock - bt_pages);
+#if CMD_DMA
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+               p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+               p_BTableChangesDelta->g_wBlockTableOffset =
+                       g_wBlockTableOffset;
+               p_BTableChangesDelta->ValidFields = 0x01;
+#endif
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+               "Inside FTL_Write_Block_Table: block %d Page:%d\n",
+               g_wBlockTableIndex, g_wBlockTableOffset);
+
+       do {
+               new_bt_offset = g_wBlockTableOffset + bt_pages + 1;
+               if ((0 == (new_bt_offset % DeviceInfo.wPagesPerBlock)) ||
+                       (new_bt_offset > DeviceInfo.wPagesPerBlock) ||
+                       (FAIL == wSuccess)) {
+                       wTempBlockTableIndex = FTL_Replace_Block_Table();
+                       if (BAD_BLOCK == wTempBlockTableIndex)
+                               return ERR;
+                       if (!blockchangeoccured) {
+                               bt_block_changed = 1;
+                               blockchangeoccured = 1;
+                       }
+
+                       g_wBlockTableIndex = wTempBlockTableIndex;
+                       g_wBlockTableOffset = 0;
+                       pbt[BLOCK_TABLE_INDEX] = g_wBlockTableIndex;
+#if CMD_DMA
+                       p_BTableChangesDelta =
+                               (struct BTableChangesDelta *)g_pBTDelta_Free;
+                       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+                       p_BTableChangesDelta->ftl_cmd_cnt =
+                                   ftl_cmd_cnt;
+                       p_BTableChangesDelta->g_wBlockTableOffset =
+                                   g_wBlockTableOffset;
+                       p_BTableChangesDelta->g_wBlockTableIndex =
+                                   g_wBlockTableIndex;
+                       p_BTableChangesDelta->ValidFields = 0x03;
+
+                       p_BTableChangesDelta =
+                               (struct BTableChangesDelta *)g_pBTDelta_Free;
+                       g_pBTDelta_Free +=
+                               sizeof(struct BTableChangesDelta);
+
+                       p_BTableChangesDelta->ftl_cmd_cnt =
+                                   ftl_cmd_cnt;
+                       p_BTableChangesDelta->BT_Index =
+                                   BLOCK_TABLE_INDEX;
+                       p_BTableChangesDelta->BT_Entry_Value =
+                                   pbt[BLOCK_TABLE_INDEX];
+                       p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+               }
+
+               wSuccess = FTL_Write_Block_Table_Data();
+               if (FAIL == wSuccess)
+                       MARK_BLOCK_AS_BAD(pbt[BLOCK_TABLE_INDEX]);
+       } while (FAIL == wSuccess);
+
+       g_cBlockTableStatus = CURRENT_BLOCK_TABLE;
+
+       return 1;
+}
+
+/******************************************************************
+* Function:     GLOB_FTL_Flash_Format
+* Inputs:       none
+* Outputs:      PASS
+* Description:  The block table stores bad block info, including MDF+
+*               blocks gone bad over the ages. Therefore, if we have a
+*               block table in place, then use it to scan for bad blocks
+*               If not, then scan for MDF.
+*               Now, a block table will only be found if spectra was already
+*               being used. For a fresh flash, we'll go thru scanning for
+*               MDF. If spectra was being used, then there is a chance that
+*               the MDF has been corrupted. Spectra avoids writing to the
+*               first 2 bytes of the spare area to all pages in a block. This
+*               covers all known flash devices. However, since flash
+*               manufacturers have no standard of where the MDF is stored,
+*               this cannot guarantee that the MDF is protected for future
+*               devices too. The initial scanning for the block table assures
+*               this. It is ok even if the block table is outdated, as all
+*               we're looking for are bad block markers.
+*               Use this when mounting a file system or starting a
+*               new flash.
+*
+*********************************************************************/
+static int  FTL_Format_Flash(u8 valid_block_table)
+{
+       u32 i, j;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 tempNode;
+       int ret;
+
+#if CMD_DMA
+       u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy;
+       if (ftl_cmd_cnt)
+               return FAIL;
+#endif
+
+       if (FAIL == FTL_Check_Block_Table(FAIL))
+               valid_block_table = 0;
+
+       if (valid_block_table) {
+               u8 switched = 1;
+               u32 block, k;
+
+               k = DeviceInfo.wSpectraStartBlock;
+               while (switched && (k < DeviceInfo.wSpectraEndBlock)) {
+                       switched = 0;
+                       k++;
+                       for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+                       j <= DeviceInfo.wSpectraEndBlock;
+                       j++, i++) {
+                               block = (pbt[i] & ~BAD_BLOCK) -
+                                       DeviceInfo.wSpectraStartBlock;
+                               if (block != i) {
+                                       switched = 1;
+                                       tempNode = pbt[i];
+                                       pbt[i] = pbt[block];
+                                       pbt[block] = tempNode;
+                               }
+                       }
+               }
+               if ((k == DeviceInfo.wSpectraEndBlock) && switched)
+                       valid_block_table = 0;
+       }
+
+       if (!valid_block_table) {
+               memset(g_pBlockTable, 0,
+                       DeviceInfo.wDataBlockNum * sizeof(u32));
+               memset(g_pWearCounter, 0,
+                       DeviceInfo.wDataBlockNum * sizeof(u8));
+               if (DeviceInfo.MLCDevice)
+                       memset(g_pReadCounter, 0,
+                               DeviceInfo.wDataBlockNum * sizeof(u16));
+#if CMD_DMA
+               memset(g_pBTStartingCopy, 0,
+                       DeviceInfo.wDataBlockNum * sizeof(u32));
+               memset(g_pWearCounterCopy, 0,
+                               DeviceInfo.wDataBlockNum * sizeof(u8));
+               if (DeviceInfo.MLCDevice)
+                       memset(g_pReadCounterCopy, 0,
+                               DeviceInfo.wDataBlockNum * sizeof(u16));
+#endif
+               for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+                       j <= DeviceInfo.wSpectraEndBlock;
+                       j++, i++) {
+                       if (GLOB_LLD_Get_Bad_Block((u32)j))
+                               pbt[i] = (u32)(BAD_BLOCK | j);
+               }
+       }
+
+       nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n");
+
+       for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+               j <= DeviceInfo.wSpectraEndBlock;
+               j++, i++) {
+               if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) {
+                       ret = GLOB_LLD_Erase_Block(j);
+                       if (FAIL == ret) {
+                               pbt[i] = (u32)(j);
+                               MARK_BLOCK_AS_BAD(pbt[i]);
+                               nand_dbg_print(NAND_DBG_WARN,
+                              "NAND Program fail in %s, Line %d, "
+                              "Function: %s, new Bad Block %d generated!\n",
+                              __FILE__, __LINE__, __func__, (int)j);
+                       } else {
+                               pbt[i] = (u32)(SPARE_BLOCK | j);
+                       }
+               }
+#if CMD_DMA
+               pbtStartingCopy[i] = pbt[i];
+#endif
+       }
+
+       g_wBlockTableOffset = 0;
+       for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock -
+                       DeviceInfo.wSpectraStartBlock))
+                       && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++)
+               ;
+       if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) {
+               printk(KERN_ERR "All blocks bad!\n");
+               return FAIL;
+       } else {
+               g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK;
+               if (i != BLOCK_TABLE_INDEX) {
+                       tempNode = pbt[i];
+                       pbt[i] = pbt[BLOCK_TABLE_INDEX];
+                       pbt[BLOCK_TABLE_INDEX] = tempNode;
+               }
+       }
+       pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
+
+#if CMD_DMA
+       pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
+#endif
+
+       g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+       memset(g_pBTBlocks, 0xFF,
+                       (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32));
+       g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex;
+       FTL_Write_Block_Table(FAIL);
+
+       for (i = 0; i < CACHE_ITEM_NUM; i++) {
+               Cache.array[i].address = NAND_CACHE_INIT_ADDR;
+               Cache.array[i].use_cnt = 0;
+               Cache.array[i].changed  = CLEAR;
+       }
+
+#if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA)
+       memcpy((void *)&cache_start_copy, (void *)&Cache,
+                       sizeof(struct flash_cache_tag));
+#endif
+       return PASS;
+}
+
+static int  force_format_nand(void)
+{
+       u32 i;
+
+       /* Force erase the whole unprotected physical partiton of NAND */
+       printk(KERN_ALERT "Start to force erase whole NAND device ...\n");
+       printk(KERN_ALERT "From phyical block %d to %d\n",
+               DeviceInfo.wSpectraStartBlock, DeviceInfo.wSpectraEndBlock);
+       for (i = DeviceInfo.wSpectraStartBlock; i <= DeviceInfo.wSpectraEndBlock; i++) {
+               if (GLOB_LLD_Erase_Block(i))
+                       printk(KERN_ERR "Failed to force erase NAND block %d\n", i);
+       }
+       printk(KERN_ALERT "Force Erase ends. Please reboot the system ...\n");
+       while(1);
+
+       return PASS;
+}
+
+int GLOB_FTL_Flash_Format(void)
+{
+       //return FTL_Format_Flash(1);
+       return force_format_nand();
+
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Search_Block_Table_IN_Block
+* Inputs:       Block Number
+*               Pointer to page
+* Outputs:      PASS / FAIL
+*               Page contatining the block table
+* Description:  It searches the block table in the block
+*               passed as an argument.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Search_Block_Table_IN_Block(u32 BT_Block,
+                                               u8 BT_Tag, u16 *Page)
+{
+       u16 i, j, k;
+       u16 Result = PASS;
+       u16 Last_IPF = 0;
+       u8  BT_Found = 0;
+       u8 *tagarray;
+       u8 *tempbuf = tmp_buf_search_bt_in_block;
+       u8 *pSpareBuf = spare_buf_search_bt_in_block;
+       u8 *pSpareBufBTLastPage = spare_buf_bt_search_bt_in_block;
+       u8 bt_flag_last_page = 0xFF;
+       u8 search_in_previous_pages = 0;
+       u16 bt_pages;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+                      "Searching block table in %u block\n",
+                      (unsigned int)BT_Block);
+
+       bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+       for (i = bt_pages; i < DeviceInfo.wPagesPerBlock;
+                               i += (bt_pages + 1)) {
+               nand_dbg_print(NAND_DBG_DEBUG,
+                              "Searching last IPF: %d\n", i);
+               Result = GLOB_LLD_Read_Page_Main_Polling(tempbuf,
+                                                       BT_Block, i, 1);
+
+               if (0 == memcmp(tempbuf, g_pIPF, DeviceInfo.wPageDataSize)) {
+                       if ((i + bt_pages + 1) < DeviceInfo.wPagesPerBlock) {
+                               continue;
+                       } else {
+                               search_in_previous_pages = 1;
+                               Last_IPF = i;
+                       }
+               }
+
+               if (!search_in_previous_pages) {
+                       if (i != bt_pages) {
+                               i -= (bt_pages + 1);
+                               Last_IPF = i;
+                       }
+               }
+
+               if (0 == Last_IPF)
+                       break;
+
+               if (!search_in_previous_pages) {
+                       i = i + 1;
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Reading the spare area of Block %u Page %u",
+                               (unsigned int)BT_Block, i);
+                       Result = GLOB_LLD_Read_Page_Spare(pSpareBuf,
+                                                       BT_Block, i, 1);
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Reading the spare area of Block %u Page %u",
+                               (unsigned int)BT_Block, i + bt_pages - 1);
+                       Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
+                               BT_Block, i + bt_pages - 1, 1);
+
+                       k = 0;
+                       j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
+                       if (j) {
+                               for (; k < j; k++) {
+                                       if (tagarray[k] == BT_Tag)
+                                               break;
+                               }
+                       }
+
+                       if (k < j)
+                               bt_flag = tagarray[k];
+                       else
+                               Result = FAIL;
+
+                       if (Result == PASS) {
+                               k = 0;
+                               j = FTL_Extract_Block_Table_Tag(
+                                       pSpareBufBTLastPage, &tagarray);
+                               if (j) {
+                                       for (; k < j; k++) {
+                                               if (tagarray[k] == BT_Tag)
+                                                       break;
+                                       }
+                               }
+
+                               if (k < j)
+                                       bt_flag_last_page = tagarray[k];
+                               else
+                                       Result = FAIL;
+
+                               if (Result == PASS) {
+                                       if (bt_flag == bt_flag_last_page) {
+                                               nand_dbg_print(NAND_DBG_DEBUG,
+                                                       "Block table is found"
+                                                       " in page after IPF "
+                                                       "at block %d "
+                                                       "page %d\n",
+                                                       (int)BT_Block, i);
+                                               BT_Found = 1;
+                                               *Page  = i;
+                                               g_cBlockTableStatus =
+                                                       CURRENT_BLOCK_TABLE;
+                                               break;
+                                       } else {
+                                               Result = FAIL;
+                                       }
+                               }
+                       }
+               }
+
+               if (search_in_previous_pages)
+                       i = i - bt_pages;
+               else
+                       i = i - (bt_pages + 1);
+
+               Result = PASS;
+
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Reading the spare area of Block %d Page %d",
+                       (int)BT_Block, i);
+
+               Result = GLOB_LLD_Read_Page_Spare(pSpareBuf, BT_Block, i, 1);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Reading the spare area of Block %u Page %u",
+                       (unsigned int)BT_Block, i + bt_pages - 1);
+
+               Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
+                                       BT_Block, i + bt_pages - 1, 1);
+
+               k = 0;
+               j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
+               if (j) {
+                       for (; k < j; k++) {
+                               if (tagarray[k] == BT_Tag)
+                                       break;
+                       }
+               }
+
+               if (k < j)
+                       bt_flag = tagarray[k];
+               else
+                       Result = FAIL;
+
+               if (Result == PASS) {
+                       k = 0;
+                       j = FTL_Extract_Block_Table_Tag(pSpareBufBTLastPage,
+                                               &tagarray);
+                       if (j) {
+                               for (; k < j; k++) {
+                                       if (tagarray[k] == BT_Tag)
+                                               break;
+                               }
+                       }
+
+                       if (k < j) {
+                               bt_flag_last_page = tagarray[k];
+                       } else {
+                               Result = FAIL;
+                               break;
+                       }
+
+                       if (Result == PASS) {
+                               if (bt_flag == bt_flag_last_page) {
+                                       nand_dbg_print(NAND_DBG_DEBUG,
+                                               "Block table is found "
+                                               "in page prior to IPF "
+                                               "at block %u page %d\n",
+                                               (unsigned int)BT_Block, i);
+                                       BT_Found = 1;
+                                       *Page  = i;
+                                       g_cBlockTableStatus =
+                                               IN_PROGRESS_BLOCK_TABLE;
+                                       break;
+                               } else {
+                                       Result = FAIL;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       if (Result == FAIL) {
+               if ((Last_IPF > bt_pages) && (i < Last_IPF) && (!BT_Found)) {
+                       BT_Found = 1;
+                       *Page = i - (bt_pages + 1);
+               }
+               if ((Last_IPF == bt_pages) && (i < Last_IPF) && (!BT_Found))
+                       goto func_return;
+       }
+
+       if (Last_IPF == 0) {
+               i = 0;
+               Result = PASS;
+               nand_dbg_print(NAND_DBG_DEBUG, "Reading the spare area of "
+                       "Block %u Page %u", (unsigned int)BT_Block, i);
+
+               Result = GLOB_LLD_Read_Page_Spare(pSpareBuf, BT_Block, i, 1);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Reading the spare area of Block %u Page %u",
+                       (unsigned int)BT_Block, i + bt_pages - 1);
+               Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
+                                       BT_Block, i + bt_pages - 1, 1);
+
+               k = 0;
+               j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
+               if (j) {
+                       for (; k < j; k++) {
+                               if (tagarray[k] == BT_Tag)
+                                       break;
+                       }
+               }
+
+               if (k < j)
+                       bt_flag = tagarray[k];
+               else
+                       Result = FAIL;
+
+               if (Result == PASS) {
+                       k = 0;
+                       j = FTL_Extract_Block_Table_Tag(pSpareBufBTLastPage,
+                                                       &tagarray);
+                       if (j) {
+                               for (; k < j; k++) {
+                                       if (tagarray[k] == BT_Tag)
+                                               break;
+                               }
+                       }
+
+                       if (k < j)
+                               bt_flag_last_page = tagarray[k];
+                       else
+                               Result = FAIL;
+
+                       if (Result == PASS) {
+                               if (bt_flag == bt_flag_last_page) {
+                                       nand_dbg_print(NAND_DBG_DEBUG,
+                                               "Block table is found "
+                                               "in page after IPF at "
+                                               "block %u page %u\n",
+                                               (unsigned int)BT_Block,
+                                               (unsigned int)i);
+                                       BT_Found = 1;
+                                       *Page  = i;
+                                       g_cBlockTableStatus =
+                                               CURRENT_BLOCK_TABLE;
+                                       goto func_return;
+                               } else {
+                                       Result = FAIL;
+                               }
+                       }
+               }
+
+               if (Result == FAIL)
+                       goto func_return;
+       }
+func_return:
+       return Result;
+}
+
+u8 *get_blk_table_start_addr(void)
+{
+       return g_pBlockTable;
+}
+
+unsigned long get_blk_table_len(void)
+{
+       return DeviceInfo.wDataBlockNum * sizeof(u32);
+}
+
+u8 *get_wear_leveling_table_start_addr(void)
+{
+       return g_pWearCounter;
+}
+
+unsigned long get_wear_leveling_table_len(void)
+{
+       return DeviceInfo.wDataBlockNum * sizeof(u8);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Read_Block_Table
+* Inputs:       none
+* Outputs:      PASS / FAIL
+* Description:  read the flash spare area and find a block containing the
+*               most recent block table(having largest block_table_counter).
+*               Find the last written Block table in this block.
+*               Check the correctness of Block Table
+*               If CDMA is enabled, this function is called in
+*               polling mode.
+*               We don't need to store changes in Block table in this
+*               function as it is called only at initialization
+*
+*               Note: Currently this function is called at initialization
+*               before any read/erase/write command issued to flash so,
+*               there is no need to wait for CDMA list to complete as of now
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Read_Block_Table(void)
+{
+       u16 i = 0;
+       int k, j;
+       u8 *tempBuf, *tagarray;
+       int wResult = FAIL;
+       int status = FAIL;
+       u8 block_table_found = 0;
+       int search_result;
+       u32 Block;
+       u16 Page = 0;
+       u16 PageCount;
+       u16 bt_pages;
+       int wBytesCopied = 0, tempvar;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       tempBuf = tmp_buf1_read_blk_table;
+       bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+       for (j = DeviceInfo.wSpectraStartBlock;
+               j <= (int)DeviceInfo.wSpectraEndBlock;
+                       j++) {
+               status = GLOB_LLD_Read_Page_Spare(tempBuf, j, 0, 1);
+               k = 0;
+               i = FTL_Extract_Block_Table_Tag(tempBuf, &tagarray);
+               if (i) {
+                       status  = GLOB_LLD_Read_Page_Main_Polling(tempBuf,
+                                                               j, 0, 1);
+                       for (; k < i; k++) {
+                               if (tagarray[k] == tempBuf[3])
+                                       break;
+                       }
+               }
+
+               if (k < i)
+                       k = tagarray[k];
+               else
+                       continue;
+
+               nand_dbg_print(NAND_DBG_DEBUG,
+                               "Block table is contained in Block %d %d\n",
+                                      (unsigned int)j, (unsigned int)k);
+
+               if (g_pBTBlocks[k-FIRST_BT_ID] == BTBLOCK_INVAL) {
+                       g_pBTBlocks[k-FIRST_BT_ID] = j;
+                       block_table_found = 1;
+               } else {
+                       printk(KERN_ERR "FTL_Read_Block_Table -"
+                               "This should never happens. "
+                               "Two block table have same counter %u!\n", k);
+               }
+       }
+
+       if (block_table_found) {
+               if (g_pBTBlocks[FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL &&
+               g_pBTBlocks[LAST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL) {
+                       j = LAST_BT_ID;
+                       while ((j > FIRST_BT_ID) &&
+                       (g_pBTBlocks[j - FIRST_BT_ID] != BTBLOCK_INVAL))
+                               j--;
+                       if (j == FIRST_BT_ID) {
+                               j = LAST_BT_ID;
+                               last_erased = LAST_BT_ID;
+                       } else {
+                               last_erased = (u8)j + 1;
+                               while ((j > FIRST_BT_ID) && (BTBLOCK_INVAL ==
+                                       g_pBTBlocks[j - FIRST_BT_ID]))
+                                       j--;
+                       }
+               } else {
+                       j = FIRST_BT_ID;
+                       while (g_pBTBlocks[j - FIRST_BT_ID] == BTBLOCK_INVAL)
+                               j++;
+                       last_erased = (u8)j;
+                       while ((j < LAST_BT_ID) && (BTBLOCK_INVAL !=
+                               g_pBTBlocks[j - FIRST_BT_ID]))
+                               j++;
+                       if (g_pBTBlocks[j-FIRST_BT_ID] == BTBLOCK_INVAL)
+                               j--;
+               }
+
+               if (last_erased > j)
+                       j += (1 + LAST_BT_ID - FIRST_BT_ID);
+
+               for (; (j >= last_erased) && (FAIL == wResult); j--) {
+                       i = (j - FIRST_BT_ID) %
+                               (1 + LAST_BT_ID - FIRST_BT_ID);
+                       search_result =
+                       FTL_Search_Block_Table_IN_Block(g_pBTBlocks[i],
+                                               i + FIRST_BT_ID, &Page);
+                       if (g_cBlockTableStatus == IN_PROGRESS_BLOCK_TABLE)
+                               block_table_found = 0;
+
+                       while ((search_result == PASS) && (FAIL == wResult)) {
+                               nand_dbg_print(NAND_DBG_DEBUG,
+                                       "FTL_Read_Block_Table:"
+                                       "Block: %u Page: %u "
+                                       "contains block table\n",
+                                       (unsigned int)g_pBTBlocks[i],
+                                       (unsigned int)Page);
+
+                               tempBuf = tmp_buf2_read_blk_table;
+
+                               for (k = 0; k < bt_pages; k++) {
+                                       Block = g_pBTBlocks[i];
+                                       PageCount = 1;
+
+                                       status  =
+                                       GLOB_LLD_Read_Page_Main_Polling(
+                                       tempBuf, Block, Page, PageCount);
+
+                                       tempvar = k ? 0 : 4;
+
+                                       wBytesCopied +=
+                                       FTL_Copy_Block_Table_From_Flash(
+                                       tempBuf + tempvar,
+                                       DeviceInfo.wPageDataSize - tempvar,
+                                       wBytesCopied);
+
+                                       Page++;
+                               }
+
+                               wResult = FTL_Check_Block_Table(FAIL);
+                               if (FAIL == wResult) {
+                                       block_table_found = 0;
+                                       if (Page > bt_pages)
+                                               Page -= ((bt_pages<<1) + 1);
+                                       else
+                                               search_result = FAIL;
+                               }
+                       }
+               }
+       }
+
+       if (PASS == wResult) {
+               if (!block_table_found)
+                       FTL_Execute_SPL_Recovery();
+
+               if (g_cBlockTableStatus == IN_PROGRESS_BLOCK_TABLE)
+                       g_wBlockTableOffset = (u16)Page + 1;
+               else
+                       g_wBlockTableOffset = (u16)Page - bt_pages;
+
+               g_wBlockTableIndex = (u32)g_pBTBlocks[i];
+
+#if CMD_DMA
+               if (DeviceInfo.MLCDevice)
+                       memcpy(g_pBTStartingCopy, g_pBlockTable,
+                               DeviceInfo.wDataBlockNum * sizeof(u32)
+                               + DeviceInfo.wDataBlockNum * sizeof(u8)
+                               + DeviceInfo.wDataBlockNum * sizeof(u16));
+               else
+                       memcpy(g_pBTStartingCopy, g_pBlockTable,
+                               DeviceInfo.wDataBlockNum * sizeof(u32)
+                               + DeviceInfo.wDataBlockNum * sizeof(u8));
+#endif
+       }
+
+       if (FAIL == wResult)
+               printk(KERN_ERR "Yunpeng - "
+               "Can not find valid spectra block table!\n");
+
+#if AUTO_FORMAT_FLASH
+       if (FAIL == wResult) {
+               nand_dbg_print(NAND_DBG_DEBUG, "doing auto-format\n");
+               wResult = FTL_Format_Flash(0);
+       }
+#endif
+
+       return wResult;
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Flash_Error_Handle
+* Inputs:       Pointer to data
+*               Page address
+*               Block address
+* Outputs:      PASS=0 / FAIL=1
+* Description:  It handles any error occured during Spectra operation
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr,
+                               u64 blk_addr)
+{
+       u32 i;
+       int j;
+       u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr);
+       u64 phy_addr;
+       int wErase = FAIL;
+       int wResult = FAIL;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (ERR == GLOB_FTL_Garbage_Collection())
+               return ERR;
+
+       do {
+               for (i = DeviceInfo.wSpectraEndBlock -
+                       DeviceInfo.wSpectraStartBlock;
+                                       i > 0; i--) {
+                       if (IS_SPARE_BLOCK(i)) {
+                               tmp_node = (u32)(BAD_BLOCK |
+                                       pbt[blk_node]);
+                               pbt[blk_node] = (u32)(pbt[i] &
+                                       (~SPARE_BLOCK));
+                               pbt[i] = tmp_node;
+#if CMD_DMA
+                               p_BTableChangesDelta =
+                                   (struct BTableChangesDelta *)
+                                   g_pBTDelta_Free;
+                               g_pBTDelta_Free +=
+                                   sizeof(struct BTableChangesDelta);
+
+                               p_BTableChangesDelta->ftl_cmd_cnt =
+                                   ftl_cmd_cnt;
+                               p_BTableChangesDelta->BT_Index =
+                                   blk_node;
+                               p_BTableChangesDelta->BT_Entry_Value =
+                                   pbt[blk_node];
+                               p_BTableChangesDelta->ValidFields = 0x0C;
+
+                               p_BTableChangesDelta =
+                                   (struct BTableChangesDelta *)
+                                   g_pBTDelta_Free;
+                               g_pBTDelta_Free +=
+                                   sizeof(struct BTableChangesDelta);
+
+                               p_BTableChangesDelta->ftl_cmd_cnt =
+                                   ftl_cmd_cnt;
+                               p_BTableChangesDelta->BT_Index = i;
+                               p_BTableChangesDelta->BT_Entry_Value = pbt[i];
+                               p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+                               wResult = PASS;
+                               break;
+                       }
+               }
+
+               if (FAIL == wResult) {
+                       if (FAIL == GLOB_FTL_Garbage_Collection())
+                               break;
+                       else
+                               continue;
+               }
+
+               if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+                       g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                       FTL_Write_IN_Progress_Block_Table_Page();
+               }
+
+               phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+
+               for (j = 0; j < RETRY_TIMES; j++) {
+                       if (PASS == wErase) {
+                               if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
+                                       MARK_BLOCK_AS_BAD(pbt[blk_node]);
+                                       break;
+                               }
+                       }
+                       if (PASS == FTL_Cache_Update_Block(pData,
+                                                          old_page_addr,
+                                                          phy_addr)) {
+                               wResult = PASS;
+                               break;
+                       } else {
+                               wResult = FAIL;
+                               wErase = PASS;
+                       }
+               }
+       } while (FAIL == wResult);
+
+       FTL_Write_Block_Table(FAIL);
+
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Get_Page_Num
+* Inputs:       Size in bytes
+* Outputs:      Size in pages
+* Description:  It calculates the pages required for the length passed
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Get_Page_Num(u64 length)
+{
+       return (u32)((length >> DeviceInfo.nBitsInPageDataSize) +
+               (GLOB_u64_Remainder(length , 1) > 0 ? 1 : 0));
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Get_Physical_Block_Addr
+* Inputs:       Block Address (byte format)
+* Outputs:      Physical address of the block.
+* Description:  It translates LBA to PBA by returning address stored
+*               at the LBA location in the block table
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u64 FTL_Get_Physical_Block_Addr(u64 logical_addr)
+{
+       u32 *pbt;
+       u64 physical_addr;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       pbt = (u32 *)g_pBlockTable;
+       physical_addr = (u64) DeviceInfo.wBlockDataSize *
+               (pbt[BLK_FROM_ADDR(logical_addr)] & (~BAD_BLOCK));
+
+       return physical_addr;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Get_Block_Index
+* Inputs:       Physical Block no.
+* Outputs:      Logical block no. /BAD_BLOCK
+* Description:  It returns the logical block no. for the PBA passed
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Get_Block_Index(u32 wBlockNum)
+{
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++)
+               if (wBlockNum == (pbt[i] & (~BAD_BLOCK)))
+                       return i;
+
+       return BAD_BLOCK;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Wear_Leveling
+* Inputs:       none
+* Outputs:      PASS=0
+* Description:  This is static wear leveling (done by explicit call)
+*               do complete static wear leveling
+*               do complete garbage collection
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Wear_Leveling(void)
+{
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       FTL_Static_Wear_Leveling();
+       GLOB_FTL_Garbage_Collection();
+
+       return PASS;
+}
+
+static void find_least_most_worn(u8 *chg,
+       u32 *least_idx, u8 *least_cnt,
+       u32 *most_idx, u8 *most_cnt)
+{
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 idx;
+       u8 cnt;
+       int i;
+
+       for (i = BLOCK_TABLE_INDEX + 1; i < DeviceInfo.wDataBlockNum; i++) {
+               if (IS_BAD_BLOCK(i) || PASS == chg[i])
+                       continue;
+
+               idx = (u32) ((~BAD_BLOCK) & pbt[i]);
+               cnt = g_pWearCounter[idx - DeviceInfo.wSpectraStartBlock];
+
+               if (IS_SPARE_BLOCK(i)) {
+                       if (cnt > *most_cnt) {
+                               *most_cnt = cnt;
+                               *most_idx = idx;
+                       }
+               }
+
+               if (IS_DATA_BLOCK(i)) {
+                       if (cnt < *least_cnt) {
+                               *least_cnt = cnt;
+                               *least_idx = idx;
+                       }
+               }
+
+               if (PASS == chg[*most_idx] || PASS == chg[*least_idx]) {
+                       debug_boundary_error(*most_idx,
+                               DeviceInfo.wDataBlockNum, 0);
+                       debug_boundary_error(*least_idx,
+                               DeviceInfo.wDataBlockNum, 0);
+                       continue;
+               }
+       }
+}
+
+static int move_blks_for_wear_leveling(u8 *chg,
+       u32 *least_idx, u32 *rep_blk_num, int *result)
+{
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 rep_blk;
+       int j, ret_cp_blk, ret_erase;
+       int ret = PASS;
+
+       chg[*least_idx] = PASS;
+       debug_boundary_error(*least_idx, DeviceInfo.wDataBlockNum, 0);
+
+       rep_blk = FTL_Replace_MWBlock();
+       if (rep_blk != BAD_BLOCK) {
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "More than two spare blocks exist so do it\n");
+               nand_dbg_print(NAND_DBG_DEBUG, "Block Replaced is %d\n",
+                               rep_blk);
+
+               chg[rep_blk] = PASS;
+
+               if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+                       g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                       FTL_Write_IN_Progress_Block_Table_Page();
+               }
+
+               for (j = 0; j < RETRY_TIMES; j++) {
+                       ret_cp_blk = FTL_Copy_Block((u64)(*least_idx) *
+                               DeviceInfo.wBlockDataSize,
+                               (u64)rep_blk * DeviceInfo.wBlockDataSize);
+                       if (FAIL == ret_cp_blk) {
+                               ret_erase = GLOB_FTL_Block_Erase((u64)rep_blk
+                                       * DeviceInfo.wBlockDataSize);
+                               if (FAIL == ret_erase)
+                                       MARK_BLOCK_AS_BAD(pbt[rep_blk]);
+                       } else {
+                               nand_dbg_print(NAND_DBG_DEBUG,
+                                       "FTL_Copy_Block == OK\n");
+                               break;
+                       }
+               }
+
+               if (j < RETRY_TIMES) {
+                       u32 tmp;
+                       u32 old_idx = FTL_Get_Block_Index(*least_idx);
+                       u32 rep_idx = FTL_Get_Block_Index(rep_blk);
+                       tmp = (u32)(DISCARD_BLOCK | pbt[old_idx]);
+                       pbt[old_idx] = (u32)((~SPARE_BLOCK) &
+                                                       pbt[rep_idx]);
+                       pbt[rep_idx] = tmp;
+#if CMD_DMA
+                       p_BTableChangesDelta = (struct BTableChangesDelta *)
+                                               g_pBTDelta_Free;
+                       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+                       p_BTableChangesDelta->ftl_cmd_cnt =
+                                               ftl_cmd_cnt;
+                       p_BTableChangesDelta->BT_Index = old_idx;
+                       p_BTableChangesDelta->BT_Entry_Value = pbt[old_idx];
+                       p_BTableChangesDelta->ValidFields = 0x0C;
+
+                       p_BTableChangesDelta = (struct BTableChangesDelta *)
+                                               g_pBTDelta_Free;
+                       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+                       p_BTableChangesDelta->ftl_cmd_cnt =
+                                               ftl_cmd_cnt;
+                       p_BTableChangesDelta->BT_Index = rep_idx;
+                       p_BTableChangesDelta->BT_Entry_Value = pbt[rep_idx];
+                       p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+               } else {
+                       pbt[FTL_Get_Block_Index(rep_blk)] |= BAD_BLOCK;
+#if CMD_DMA
+                       p_BTableChangesDelta = (struct BTableChangesDelta *)
+                                               g_pBTDelta_Free;
+                       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+                       p_BTableChangesDelta->ftl_cmd_cnt =
+                                               ftl_cmd_cnt;
+                       p_BTableChangesDelta->BT_Index =
+                                       FTL_Get_Block_Index(rep_blk);
+                       p_BTableChangesDelta->BT_Entry_Value =
+                                       pbt[FTL_Get_Block_Index(rep_blk)];
+                       p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+                       *result = FAIL;
+                       ret = FAIL;
+               }
+
+               if (((*rep_blk_num)++) > WEAR_LEVELING_BLOCK_NUM)
+                       ret = FAIL;
+       } else {
+               printk(KERN_ERR "Less than 3 spare blocks exist so quit\n");
+               ret = FAIL;
+       }
+
+       return ret;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Static_Wear_Leveling
+* Inputs:       none
+* Outputs:      PASS=0 / FAIL=1
+* Description:  This is static wear leveling (done by explicit call)
+*               search for most&least used
+*               if difference < GATE:
+*                   update the block table with exhange
+*                   mark block table in flash as IN_PROGRESS
+*                   copy flash block
+*               the caller should handle GC clean up after calling this function
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int FTL_Static_Wear_Leveling(void)
+{
+       u8 most_worn_cnt;
+       u8 least_worn_cnt;
+       u32 most_worn_idx;
+       u32 least_worn_idx;
+       int result = PASS;
+       int go_on = PASS;
+       u32 replaced_blks = 0;
+       u8 *chang_flag = flags_static_wear_leveling;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (!chang_flag)
+               return FAIL;
+
+       memset(chang_flag, FAIL, DeviceInfo.wDataBlockNum);
+       while (go_on == PASS) {
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "starting static wear leveling\n");
+               most_worn_cnt = 0;
+               least_worn_cnt = 0xFF;
+               least_worn_idx = BLOCK_TABLE_INDEX;
+               most_worn_idx = BLOCK_TABLE_INDEX;
+
+               find_least_most_worn(chang_flag, &least_worn_idx,
+                       &least_worn_cnt, &most_worn_idx, &most_worn_cnt);
+
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Used and least worn is block %u, whos count is %u\n",
+                       (unsigned int)least_worn_idx,
+                       (unsigned int)least_worn_cnt);
+
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Free and  most worn is block %u, whos count is %u\n",
+                       (unsigned int)most_worn_idx,
+                       (unsigned int)most_worn_cnt);
+
+               if ((most_worn_cnt > least_worn_cnt) &&
+                       (most_worn_cnt - least_worn_cnt > WEAR_LEVELING_GATE))
+                       go_on = move_blks_for_wear_leveling(chang_flag,
+                               &least_worn_idx, &replaced_blks, &result);
+               else
+                       go_on = FAIL;
+       }
+
+       return result;
+}
+
+#if CMD_DMA
+static int do_garbage_collection(u32 discard_cnt)
+{
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 pba;
+       u8 bt_block_erased = 0;
+       int i, cnt, ret = FAIL;
+       u64 addr;
+
+       i = 0;
+       while ((i < DeviceInfo.wDataBlockNum) && (discard_cnt > 0) &&
+                       ((ftl_cmd_cnt + 28) < 256)) {
+               if (((pbt[i] & BAD_BLOCK) != BAD_BLOCK) &&
+                               (pbt[i] & DISCARD_BLOCK)) {
+                       if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+                               g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                               FTL_Write_IN_Progress_Block_Table_Page();
+                       }
+
+                       addr = FTL_Get_Physical_Block_Addr((u64)i *
+                                               DeviceInfo.wBlockDataSize);
+                       pba = BLK_FROM_ADDR(addr);
+
+                       for (cnt = FIRST_BT_ID; cnt <= LAST_BT_ID; cnt++) {
+                               if (pba == g_pBTBlocks[cnt - FIRST_BT_ID]) {
+                                       nand_dbg_print(NAND_DBG_DEBUG,
+                                               "GC will erase BT block %u\n",
+                                               (unsigned int)pba);
+                                       discard_cnt--;
+                                       i++;
+                                       bt_block_erased = 1;
+                                       break;
+                               }
+                       }
+
+                       if (bt_block_erased) {
+                               bt_block_erased = 0;
+                               continue;
+                       }
+
+                       addr = FTL_Get_Physical_Block_Addr((u64)i *
+                                               DeviceInfo.wBlockDataSize);
+
+                       if (PASS == GLOB_FTL_Block_Erase(addr)) {
+                               pbt[i] &= (u32)(~DISCARD_BLOCK);
+                               pbt[i] |= (u32)(SPARE_BLOCK);
+                               p_BTableChangesDelta =
+                                       (struct BTableChangesDelta *)
+                                       g_pBTDelta_Free;
+                               g_pBTDelta_Free +=
+                                       sizeof(struct BTableChangesDelta);
+                               p_BTableChangesDelta->ftl_cmd_cnt =
+                                       ftl_cmd_cnt - 1;
+                               p_BTableChangesDelta->BT_Index = i;
+                               p_BTableChangesDelta->BT_Entry_Value = pbt[i];
+                               p_BTableChangesDelta->ValidFields = 0x0C;
+                               discard_cnt--;
+                               ret = PASS;
+                       } else {
+                               MARK_BLOCK_AS_BAD(pbt[i]);
+                       }
+               }
+
+               i++;
+       }
+
+       return ret;
+}
+
+#else
+static int do_garbage_collection(u32 discard_cnt)
+{
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 pba;
+       u8 bt_block_erased = 0;
+       int i, cnt, ret = FAIL;
+       u64 addr;
+
+       i = 0;
+       while ((i < DeviceInfo.wDataBlockNum) && (discard_cnt > 0)) {
+               if (((pbt[i] & BAD_BLOCK) != BAD_BLOCK) &&
+                               (pbt[i] & DISCARD_BLOCK)) {
+                       if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+                               g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                               FTL_Write_IN_Progress_Block_Table_Page();
+                       }
+
+                       addr = FTL_Get_Physical_Block_Addr((u64)i *
+                                               DeviceInfo.wBlockDataSize);
+                       pba = BLK_FROM_ADDR(addr);
+
+                       for (cnt = FIRST_BT_ID; cnt <= LAST_BT_ID; cnt++) {
+                               if (pba == g_pBTBlocks[cnt - FIRST_BT_ID]) {
+                                       nand_dbg_print(NAND_DBG_DEBUG,
+                                               "GC will erase BT block %d\n",
+                                               pba);
+                                       discard_cnt--;
+                                       i++;
+                                       bt_block_erased = 1;
+                                       break;
+                               }
+                       }
+
+                       if (bt_block_erased) {
+                               bt_block_erased = 0;
+                               continue;
+                       }
+
+                       /* If the discard block is L2 cache block, then just skip it */
+                       for (cnt = 0; cnt < BLK_NUM_FOR_L2_CACHE; cnt++) {
+                               if (cache_l2.blk_array[cnt] == pba) {
+                                       nand_dbg_print(NAND_DBG_DEBUG,
+                                               "GC will erase L2 cache blk %d\n",
+                                               pba);
+                                       break;
+                               }
+                       }
+                       if (cnt < BLK_NUM_FOR_L2_CACHE) { /* Skip it */
+                               discard_cnt--;
+                               i++;
+                               continue;
+                       }
+
+                       addr = FTL_Get_Physical_Block_Addr((u64)i *
+                                               DeviceInfo.wBlockDataSize);
+
+                       if (PASS == GLOB_FTL_Block_Erase(addr)) {
+                               pbt[i] &= (u32)(~DISCARD_BLOCK);
+                               pbt[i] |= (u32)(SPARE_BLOCK);
+                               discard_cnt--;
+                               ret = PASS;
+                       } else {
+                               MARK_BLOCK_AS_BAD(pbt[i]);
+                       }
+               }
+
+               i++;
+       }
+
+       return ret;
+}
+#endif
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Garbage_Collection
+* Inputs:       none
+* Outputs:      PASS / FAIL (returns the number of un-erased blocks
+* Description:  search the block table for all discarded blocks to erase
+*               for each discarded block:
+*                   set the flash block to IN_PROGRESS
+*                   erase the block
+*                   update the block table
+*                   write the block table to flash
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Garbage_Collection(void)
+{
+       u32 i;
+       u32 wDiscard = 0;
+       int wResult = FAIL;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       if (GC_Called) {
+               printk(KERN_ALERT "GLOB_FTL_Garbage_Collection() "
+                       "has been re-entered! Exit.\n");
+               return PASS;
+       }
+
+       GC_Called = 1;
+
+       GLOB_FTL_BT_Garbage_Collection();
+
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               if (IS_DISCARDED_BLOCK(i))
+                       wDiscard++;
+       }
+
+       if (wDiscard <= 0) {
+               GC_Called = 0;
+               return wResult;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+               "Found %d discarded blocks\n", wDiscard);
+
+       FTL_Write_Block_Table(FAIL);
+
+       wResult = do_garbage_collection(wDiscard);
+
+       FTL_Write_Block_Table(FAIL);
+
+       GC_Called = 0;
+
+       return wResult;
+}
+
+
+#if CMD_DMA
+static int do_bt_garbage_collection(void)
+{
+       u32 pba, lba;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 *pBTBlocksNode = (u32 *)g_pBTBlocks;
+       u64 addr;
+       int i, ret = FAIL;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       if (BT_GC_Called)
+               return PASS;
+
+       BT_GC_Called = 1;
+
+       for (i = last_erased; (i <= LAST_BT_ID) &&
+               (g_pBTBlocks[((i + 2) % (1 + LAST_BT_ID - FIRST_BT_ID)) +
+               FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL) &&
+               ((ftl_cmd_cnt + 28)) < 256; i++) {
+               pba = pBTBlocksNode[i - FIRST_BT_ID];
+               lba = FTL_Get_Block_Index(pba);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "do_bt_garbage_collection: pba %d, lba %d\n",
+                       pba, lba);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Block Table Entry: %d", pbt[lba]);
+
+               if (((pbt[lba] & BAD_BLOCK) != BAD_BLOCK) &&
+                       (pbt[lba] & DISCARD_BLOCK)) {
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "do_bt_garbage_collection_cdma: "
+                               "Erasing Block tables present in block %d\n",
+                               pba);
+                       addr = FTL_Get_Physical_Block_Addr((u64)lba *
+                                               DeviceInfo.wBlockDataSize);
+                       if (PASS == GLOB_FTL_Block_Erase(addr)) {
+                               pbt[lba] &= (u32)(~DISCARD_BLOCK);
+                               pbt[lba] |= (u32)(SPARE_BLOCK);
+
+                               p_BTableChangesDelta =
+                                       (struct BTableChangesDelta *)
+                                       g_pBTDelta_Free;
+                               g_pBTDelta_Free +=
+                                       sizeof(struct BTableChangesDelta);
+
+                               p_BTableChangesDelta->ftl_cmd_cnt =
+                                       ftl_cmd_cnt - 1;
+                               p_BTableChangesDelta->BT_Index = lba;
+                               p_BTableChangesDelta->BT_Entry_Value =
+                                                               pbt[lba];
+
+                               p_BTableChangesDelta->ValidFields = 0x0C;
+
+                               ret = PASS;
+                               pBTBlocksNode[last_erased - FIRST_BT_ID] =
+                                                       BTBLOCK_INVAL;
+                               nand_dbg_print(NAND_DBG_DEBUG,
+                                       "resetting bt entry at index %d "
+                                       "value %d\n", i,
+                                       pBTBlocksNode[i - FIRST_BT_ID]);
+                               if (last_erased == LAST_BT_ID)
+                                       last_erased = FIRST_BT_ID;
+                               else
+                                       last_erased++;
+                       } else {
+                               MARK_BLOCK_AS_BAD(pbt[lba]);
+                       }
+               }
+       }
+
+       BT_GC_Called = 0;
+
+       return ret;
+}
+
+#else
+static int do_bt_garbage_collection(void)
+{
+       u32 pba, lba;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 *pBTBlocksNode = (u32 *)g_pBTBlocks;
+       u64 addr;
+       int i, ret = FAIL;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       if (BT_GC_Called)
+               return PASS;
+
+       BT_GC_Called = 1;
+
+       for (i = last_erased; (i <= LAST_BT_ID) &&
+               (g_pBTBlocks[((i + 2) % (1 + LAST_BT_ID - FIRST_BT_ID)) +
+               FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL); i++) {
+               pba = pBTBlocksNode[i - FIRST_BT_ID];
+               lba = FTL_Get_Block_Index(pba);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "do_bt_garbage_collection_cdma: pba %d, lba %d\n",
+                       pba, lba);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Block Table Entry: %d", pbt[lba]);
+
+               if (((pbt[lba] & BAD_BLOCK) != BAD_BLOCK) &&
+                       (pbt[lba] & DISCARD_BLOCK)) {
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "do_bt_garbage_collection: "
+                               "Erasing Block tables present in block %d\n",
+                               pba);
+                       addr = FTL_Get_Physical_Block_Addr((u64)lba *
+                                               DeviceInfo.wBlockDataSize);
+                       if (PASS == GLOB_FTL_Block_Erase(addr)) {
+                               pbt[lba] &= (u32)(~DISCARD_BLOCK);
+                               pbt[lba] |= (u32)(SPARE_BLOCK);
+                               ret = PASS;
+                               pBTBlocksNode[last_erased - FIRST_BT_ID] =
+                                                       BTBLOCK_INVAL;
+                               nand_dbg_print(NAND_DBG_DEBUG,
+                                       "resetting bt entry at index %d "
+                                       "value %d\n", i,
+                                       pBTBlocksNode[i - FIRST_BT_ID]);
+                               if (last_erased == LAST_BT_ID)
+                                       last_erased = FIRST_BT_ID;
+                               else
+                                       last_erased++;
+                       } else {
+                               MARK_BLOCK_AS_BAD(pbt[lba]);
+                       }
+               }
+       }
+
+       BT_GC_Called = 0;
+
+       return ret;
+}
+
+#endif
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_BT_Garbage_Collection
+* Inputs:       none
+* Outputs:      PASS / FAIL (returns the number of un-erased blocks
+* Description:  Erases discarded blocks containing Block table
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_BT_Garbage_Collection(void)
+{
+       return do_bt_garbage_collection();
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Replace_OneBlock
+* Inputs:       Block number 1
+*               Block number 2
+* Outputs:      Replaced Block Number
+* Description:  Interchange block table entries at wBlockNum and wReplaceNum
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_OneBlock(u32 blk, u32 rep_blk)
+{
+       u32 tmp_blk;
+       u32 replace_node = BAD_BLOCK;
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       if (rep_blk != BAD_BLOCK) {
+               if (IS_BAD_BLOCK(blk))
+                       tmp_blk = pbt[blk];
+               else
+                       tmp_blk = DISCARD_BLOCK | (~SPARE_BLOCK & pbt[blk]);
+
+               replace_node = (u32) ((~SPARE_BLOCK) & pbt[rep_blk]);
+               pbt[blk] = replace_node;
+               pbt[rep_blk] = tmp_blk;
+
+#if CMD_DMA
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+               p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+               p_BTableChangesDelta->BT_Index = blk;
+               p_BTableChangesDelta->BT_Entry_Value = pbt[blk];
+
+               p_BTableChangesDelta->ValidFields = 0x0C;
+
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+               p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+               p_BTableChangesDelta->BT_Index = rep_blk;
+               p_BTableChangesDelta->BT_Entry_Value = pbt[rep_blk];
+               p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+       }
+
+       return replace_node;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Write_Block_Table_Data
+* Inputs:       Block table size in pages
+* Outputs:      PASS=0 / FAIL=1
+* Description:  Write block table data in flash
+*               If first page and last page
+*                  Write data+BT flag
+*               else
+*                  Write data
+*               BT flag is a counter. Its value is incremented for block table
+*               write in a new Block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Write_Block_Table_Data(void)
+{
+       u64 dwBlockTableAddr, pTempAddr;
+       u32 Block;
+       u16 Page, PageCount;
+       u8 *tempBuf = tmp_buf_write_blk_table_data;
+       int wBytesCopied;
+       u16 bt_pages;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       dwBlockTableAddr =
+               (u64)((u64)g_wBlockTableIndex * DeviceInfo.wBlockDataSize +
+               (u64)g_wBlockTableOffset * DeviceInfo.wPageDataSize);
+       pTempAddr = dwBlockTableAddr;
+
+       bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+       nand_dbg_print(NAND_DBG_DEBUG, "FTL_Write_Block_Table_Data: "
+                              "page= %d BlockTableIndex= %d "
+                              "BlockTableOffset=%d\n", bt_pages,
+                              g_wBlockTableIndex, g_wBlockTableOffset);
+
+       Block = BLK_FROM_ADDR(pTempAddr);
+       Page = PAGE_FROM_ADDR(pTempAddr, Block);
+       PageCount = 1;
+
+       if (bt_block_changed) {
+               if (bt_flag == LAST_BT_ID) {
+                       bt_flag = FIRST_BT_ID;
+                       g_pBTBlocks[bt_flag - FIRST_BT_ID] = Block;
+               } else if (bt_flag < LAST_BT_ID) {
+                       bt_flag++;
+                       g_pBTBlocks[bt_flag - FIRST_BT_ID] = Block;
+               }
+
+               if ((bt_flag > (LAST_BT_ID-4)) &&
+                       g_pBTBlocks[FIRST_BT_ID - FIRST_BT_ID] !=
+                                               BTBLOCK_INVAL) {
+                       bt_block_changed = 0;
+                       GLOB_FTL_BT_Garbage_Collection();
+               }
+
+               bt_block_changed = 0;
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Block Table Counter is %u Block %u\n",
+                       bt_flag, (unsigned int)Block);
+       }
+
+       memset(tempBuf, 0, 3);
+       tempBuf[3] = bt_flag;
+       wBytesCopied = FTL_Copy_Block_Table_To_Flash(tempBuf + 4,
+                       DeviceInfo.wPageDataSize - 4, 0);
+       memset(&tempBuf[wBytesCopied + 4], 0xff,
+               DeviceInfo.wPageSize - (wBytesCopied + 4));
+       FTL_Insert_Block_Table_Signature(&tempBuf[DeviceInfo.wPageDataSize],
+                                       bt_flag);
+
+#if CMD_DMA
+       memcpy(g_pNextBlockTable, tempBuf,
+               DeviceInfo.wPageSize * sizeof(u8));
+       nand_dbg_print(NAND_DBG_DEBUG, "Writing First Page of Block Table "
+               "Block %u Page %u\n", (unsigned int)Block, Page);
+       if (FAIL == GLOB_LLD_Write_Page_Main_Spare_cdma(g_pNextBlockTable,
+               Block, Page, 1,
+               LLD_CMD_FLAG_MODE_CDMA | LLD_CMD_FLAG_ORDER_BEFORE_REST)) {
+               nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in "
+                       "%s, Line %d, Function: %s, "
+                       "new Bad Block %d generated!\n",
+                       __FILE__, __LINE__, __func__, Block);
+               goto func_return;
+       }
+
+       ftl_cmd_cnt++;
+       g_pNextBlockTable += ((DeviceInfo.wPageSize * sizeof(u8)));
+#else
+       if (FAIL == GLOB_LLD_Write_Page_Main_Spare(tempBuf, Block, Page, 1)) {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "NAND Program fail in %s, Line %d, Function: %s, "
+                       "new Bad Block %d generated!\n",
+                       __FILE__, __LINE__, __func__, Block);
+               goto func_return;
+       }
+#endif
+
+       if (bt_pages > 1) {
+               PageCount = bt_pages - 1;
+               if (PageCount > 1) {
+                       wBytesCopied += FTL_Copy_Block_Table_To_Flash(tempBuf,
+                               DeviceInfo.wPageDataSize * (PageCount - 1),
+                               wBytesCopied);
+
+#if CMD_DMA
+                       memcpy(g_pNextBlockTable, tempBuf,
+                               (PageCount - 1) * DeviceInfo.wPageDataSize);
+                       if (FAIL == GLOB_LLD_Write_Page_Main_cdma(
+                               g_pNextBlockTable, Block, Page + 1,
+                               PageCount - 1)) {
+                               nand_dbg_print(NAND_DBG_WARN,
+                                       "NAND Program fail in %s, Line %d, "
+                                       "Function: %s, "
+                                       "new Bad Block %d generated!\n",
+                                       __FILE__, __LINE__, __func__,
+                                       (int)Block);
+                               goto func_return;
+                       }
+
+                       ftl_cmd_cnt++;
+                       g_pNextBlockTable += (PageCount - 1) *
+                               DeviceInfo.wPageDataSize * sizeof(u8);
+#else
+                       if (FAIL == GLOB_LLD_Write_Page_Main(tempBuf,
+                                       Block, Page + 1, PageCount - 1)) {
+                               nand_dbg_print(NAND_DBG_WARN,
+                                       "NAND Program fail in %s, Line %d, "
+                                       "Function: %s, "
+                                       "new Bad Block %d generated!\n",
+                                       __FILE__, __LINE__, __func__,
+                                       (int)Block);
+                               goto func_return;
+                       }
+#endif
+               }
+
+               wBytesCopied = FTL_Copy_Block_Table_To_Flash(tempBuf,
+                               DeviceInfo.wPageDataSize, wBytesCopied);
+               memset(&tempBuf[wBytesCopied], 0xff,
+                       DeviceInfo.wPageSize-wBytesCopied);
+               FTL_Insert_Block_Table_Signature(
+                       &tempBuf[DeviceInfo.wPageDataSize], bt_flag);
+#if CMD_DMA
+               memcpy(g_pNextBlockTable, tempBuf,
+                               DeviceInfo.wPageSize * sizeof(u8));
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Writing the last Page of Block Table "
+                       "Block %u Page %u\n",
+                       (unsigned int)Block, Page + bt_pages - 1);
+               if (FAIL == GLOB_LLD_Write_Page_Main_Spare_cdma(
+                       g_pNextBlockTable, Block, Page + bt_pages - 1, 1,
+                       LLD_CMD_FLAG_MODE_CDMA |
+                       LLD_CMD_FLAG_ORDER_BEFORE_REST)) {
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "NAND Program fail in %s, Line %d, "
+                               "Function: %s, new Bad Block %d generated!\n",
+                               __FILE__, __LINE__, __func__, Block);
+                       goto func_return;
+               }
+               ftl_cmd_cnt++;
+#else
+               if (FAIL == GLOB_LLD_Write_Page_Main_Spare(tempBuf,
+                                       Block, Page+bt_pages - 1, 1)) {
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "NAND Program fail in %s, Line %d, "
+                               "Function: %s, "
+                               "new Bad Block %d generated!\n",
+                               __FILE__, __LINE__, __func__, Block);
+                       goto func_return;
+               }
+#endif
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "FTL_Write_Block_Table_Data: done\n");
+
+func_return:
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Replace_Block_Table
+* Inputs:       None
+* Outputs:      PASS=0 / FAIL=1
+* Description:  Get a new block to write block table
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_Block_Table(void)
+{
+       u32 blk;
+       int gc;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       blk = FTL_Replace_LWBlock(BLOCK_TABLE_INDEX, &gc);
+
+       if ((BAD_BLOCK == blk) && (PASS == gc)) {
+               GLOB_FTL_Garbage_Collection();
+               blk = FTL_Replace_LWBlock(BLOCK_TABLE_INDEX, &gc);
+       }
+       if (BAD_BLOCK == blk)
+               printk(KERN_ERR "%s, %s: There is no spare block. "
+                       "It should never happen\n",
+                       __FILE__, __func__);
+
+       nand_dbg_print(NAND_DBG_DEBUG, "New Block table Block is %d\n", blk);
+
+       return blk;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Replace_LWBlock
+* Inputs:       Block number
+*               Pointer to Garbage Collect flag
+* Outputs:
+* Description:  Determine the least weared block by traversing
+*               block table
+*               Set Garbage collection to be called if number of spare
+*               block is less than Free Block Gate count
+*               Change Block table entry to map least worn block for current
+*               operation
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_LWBlock(u32 wBlockNum, int *pGarbageCollect)
+{
+       u32 i;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u8 wLeastWornCounter = 0xFF;
+       u32 wLeastWornIndex = BAD_BLOCK;
+       u32 wSpareBlockNum = 0;
+       u32 wDiscardBlockNum = 0;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       if (IS_SPARE_BLOCK(wBlockNum)) {
+               *pGarbageCollect = FAIL;
+               pbt[wBlockNum] = (u32)(pbt[wBlockNum] & (~SPARE_BLOCK));
+#if CMD_DMA
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+               p_BTableChangesDelta->ftl_cmd_cnt =
+                                               ftl_cmd_cnt;
+               p_BTableChangesDelta->BT_Index = (u32)(wBlockNum);
+               p_BTableChangesDelta->BT_Entry_Value = pbt[wBlockNum];
+               p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+               return pbt[wBlockNum];
+       }
+
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               if (IS_DISCARDED_BLOCK(i))
+                       wDiscardBlockNum++;
+
+               if (IS_SPARE_BLOCK(i)) {
+                       u32 wPhysicalIndex = (u32)((~BAD_BLOCK) & pbt[i]);
+                       if (wPhysicalIndex > DeviceInfo.wSpectraEndBlock)
+                               printk(KERN_ERR "FTL_Replace_LWBlock: "
+                                       "This should never occur!\n");
+                       if (g_pWearCounter[wPhysicalIndex -
+                               DeviceInfo.wSpectraStartBlock] <
+                               wLeastWornCounter) {
+                               wLeastWornCounter =
+                                       g_pWearCounter[wPhysicalIndex -
+                                       DeviceInfo.wSpectraStartBlock];
+                               wLeastWornIndex = i;
+                       }
+                       wSpareBlockNum++;
+               }
+       }
+
+       nand_dbg_print(NAND_DBG_WARN,
+               "FTL_Replace_LWBlock: Least Worn Counter %d\n",
+               (int)wLeastWornCounter);
+
+       if ((wDiscardBlockNum >= NUM_FREE_BLOCKS_GATE) ||
+               (wSpareBlockNum <= NUM_FREE_BLOCKS_GATE))
+               *pGarbageCollect = PASS;
+       else
+               *pGarbageCollect = FAIL;
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+               "FTL_Replace_LWBlock: Discarded Blocks %u Spare"
+               " Blocks %u\n",
+               (unsigned int)wDiscardBlockNum,
+               (unsigned int)wSpareBlockNum);
+
+       return FTL_Replace_OneBlock(wBlockNum, wLeastWornIndex);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Replace_MWBlock
+* Inputs:       None
+* Outputs:      most worn spare block no./BAD_BLOCK
+* Description:  It finds most worn spare block.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_MWBlock(void)
+{
+       u32 i;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u8 wMostWornCounter = 0;
+       u32 wMostWornIndex = BAD_BLOCK;
+       u32 wSpareBlockNum = 0;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               if (IS_SPARE_BLOCK(i)) {
+                       u32 wPhysicalIndex = (u32)((~SPARE_BLOCK) & pbt[i]);
+                       if (g_pWearCounter[wPhysicalIndex -
+                           DeviceInfo.wSpectraStartBlock] >
+                           wMostWornCounter) {
+                               wMostWornCounter =
+                                   g_pWearCounter[wPhysicalIndex -
+                                   DeviceInfo.wSpectraStartBlock];
+                               wMostWornIndex = wPhysicalIndex;
+                       }
+                       wSpareBlockNum++;
+               }
+       }
+
+       if (wSpareBlockNum <= 2)
+               return BAD_BLOCK;
+
+       return wMostWornIndex;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Replace_Block
+* Inputs:       Block Address
+* Outputs:      PASS=0 / FAIL=1
+* Description:  If block specified by blk_addr parameter is not free,
+*               replace it with the least worn block.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Replace_Block(u64 blk_addr)
+{
+       u32 current_blk = BLK_FROM_ADDR(blk_addr);
+       u32 *pbt = (u32 *)g_pBlockTable;
+       int wResult = PASS;
+       int GarbageCollect = FAIL;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       if (IS_SPARE_BLOCK(current_blk)) {
+               pbt[current_blk] = (~SPARE_BLOCK) & pbt[current_blk];
+#if CMD_DMA
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+               p_BTableChangesDelta->ftl_cmd_cnt =
+                       ftl_cmd_cnt;
+               p_BTableChangesDelta->BT_Index = current_blk;
+               p_BTableChangesDelta->BT_Entry_Value = pbt[current_blk];
+               p_BTableChangesDelta->ValidFields = 0x0C ;
+#endif
+               return wResult;
+       }
+
+       FTL_Replace_LWBlock(current_blk, &GarbageCollect);
+
+       if (PASS == GarbageCollect)
+               wResult = GLOB_FTL_Garbage_Collection();
+
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Is_BadBlock
+* Inputs:       block number to test
+* Outputs:      PASS (block is BAD) / FAIL (block is not bad)
+* Description:  test if this block number is flagged as bad
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Is_BadBlock(u32 wBlockNum)
+{
+       u32 *pbt = (u32 *)g_pBlockTable;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       if (wBlockNum >= DeviceInfo.wSpectraStartBlock
+               && BAD_BLOCK == (pbt[wBlockNum] & BAD_BLOCK))
+               return PASS;
+       else
+               return FAIL;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Flush_Cache
+* Inputs:       none
+* Outputs:      PASS=0 / FAIL=1
+* Description:  flush all the cache blocks to flash
+*               if a cache block is not dirty, don't do anything with it
+*               else, write the block and update the block table
+* Note:         This function should be called at shutdown/power down.
+*               to write important data into device
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Flush_Cache(void)
+{
+       int i, ret;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < CACHE_ITEM_NUM; i++) {
+               if (SET == Cache.array[i].changed) {
+#if CMD_DMA
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+                       int_cache[ftl_cmd_cnt].item = i;
+                       int_cache[ftl_cmd_cnt].cache.address =
+                                       Cache.array[i].address;
+                       int_cache[ftl_cmd_cnt].cache.changed = CLEAR;
+#endif
+#endif
+                       ret = write_back_to_l2_cache(Cache.array[i].buf, Cache.array[i].address);
+                       if (PASS == ret) {
+                               Cache.array[i].changed = CLEAR;
+                       } else {
+                               printk(KERN_ALERT "Failed when write back to L2 cache!\n");
+                               /* TODO - How to handle this? */
+                       }
+               }
+       }
+
+       flush_l2_cache();
+
+       return FTL_Write_Block_Table(FAIL);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Page_Read
+* Inputs:       pointer to data
+*                   logical address of data (u64 is LBA * Bytes/Page)
+* Outputs:      PASS=0 / FAIL=1
+* Description:  reads a page of data into RAM from the cache
+*               if the data is not already in cache, read from flash to cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Page_Read(u8 *data, u64 logical_addr)
+{
+       u16 cache_item;
+       int res = PASS;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "GLOB_FTL_Page_Read - "
+               "page_addr: %llu\n", logical_addr);
+
+       cache_item = FTL_Cache_If_Hit(logical_addr);
+
+       if (UNHIT_CACHE_ITEM == cache_item) {
+               nand_dbg_print(NAND_DBG_DEBUG,
+                              "GLOB_FTL_Page_Read: Cache not hit\n");
+               res = FTL_Cache_Write();
+               if (ERR == FTL_Cache_Read(logical_addr))
+                       res = ERR;
+               cache_item = Cache.LRU;
+       }
+
+       FTL_Cache_Read_Page(data, logical_addr, cache_item);
+
+       return res;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Page_Write
+* Inputs:       pointer to data
+*               address of data (ADDRESSTYPE is LBA * Bytes/Page)
+* Outputs:      PASS=0 / FAIL=1
+* Description:  writes a page of data from RAM to the cache
+*               if the data is not already in cache, write back the
+*               least recently used block and read the addressed block
+*               from flash to cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Page_Write(u8 *pData, u64 dwPageAddr)
+{
+       u16 cache_blk;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       int wResult = PASS;
+
+       nand_dbg_print(NAND_DBG_TRACE, "GLOB_FTL_Page_Write - "
+               "dwPageAddr: %llu\n", dwPageAddr);
+
+       cache_blk = FTL_Cache_If_Hit(dwPageAddr);
+
+       if (UNHIT_CACHE_ITEM == cache_blk) {
+               wResult = FTL_Cache_Write();
+               if (IS_BAD_BLOCK(BLK_FROM_ADDR(dwPageAddr))) {
+                       wResult = FTL_Replace_Block(dwPageAddr);
+                       pbt[BLK_FROM_ADDR(dwPageAddr)] |= SPARE_BLOCK;
+                       if (wResult == FAIL)
+                               return FAIL;
+               }
+               if (ERR == FTL_Cache_Read(dwPageAddr))
+                       wResult = ERR;
+               cache_blk = Cache.LRU;
+               FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk, 0);
+       } else {
+#if CMD_DMA
+               FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk,
+                               LLD_CMD_FLAG_ORDER_BEFORE_REST);
+#else
+               FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk, 0);
+#endif
+       }
+
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     GLOB_FTL_Block_Erase
+* Inputs:       address of block to erase (now in byte format, should change to
+* block format)
+* Outputs:      PASS=0 / FAIL=1
+* Description:  erases the specified block
+*               increments the erase count
+*               If erase count reaches its upper limit,call function to
+*               do the ajustment as per the relative erase count values
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Block_Erase(u64 blk_addr)
+{
+       int status;
+       u32 BlkIdx;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       BlkIdx = (u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize);
+
+       if (BlkIdx < DeviceInfo.wSpectraStartBlock) {
+               printk(KERN_ERR "GLOB_FTL_Block_Erase: "
+                       "This should never occur\n");
+               return FAIL;
+       }
+
+#if CMD_DMA
+       status = GLOB_LLD_Erase_Block_cdma(BlkIdx, LLD_CMD_FLAG_MODE_CDMA);
+       if (status == FAIL)
+               nand_dbg_print(NAND_DBG_WARN,
+                              "NAND Program fail in %s, Line %d, "
+                              "Function: %s, new Bad Block %d generated!\n",
+                              __FILE__, __LINE__, __func__, BlkIdx);
+#else
+       status = GLOB_LLD_Erase_Block(BlkIdx);
+       if (status == FAIL) {
+               nand_dbg_print(NAND_DBG_WARN,
+                              "NAND Program fail in %s, Line %d, "
+                              "Function: %s, new Bad Block %d generated!\n",
+                              __FILE__, __LINE__, __func__, BlkIdx);
+               return status;
+       }
+#endif
+
+       if (DeviceInfo.MLCDevice) {
+               g_pReadCounter[BlkIdx - DeviceInfo.wSpectraStartBlock] = 0;
+               if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+                       g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                       FTL_Write_IN_Progress_Block_Table_Page();
+               }
+       }
+
+       g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock]++;
+
+#if CMD_DMA
+       p_BTableChangesDelta =
+               (struct BTableChangesDelta *)g_pBTDelta_Free;
+       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+       p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+       p_BTableChangesDelta->WC_Index =
+               BlkIdx - DeviceInfo.wSpectraStartBlock;
+       p_BTableChangesDelta->WC_Entry_Value =
+               g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock];
+       p_BTableChangesDelta->ValidFields = 0x30;
+
+       if (DeviceInfo.MLCDevice) {
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+               p_BTableChangesDelta->ftl_cmd_cnt =
+                       ftl_cmd_cnt;
+               p_BTableChangesDelta->RC_Index =
+                       BlkIdx - DeviceInfo.wSpectraStartBlock;
+               p_BTableChangesDelta->RC_Entry_Value =
+                       g_pReadCounter[BlkIdx -
+                               DeviceInfo.wSpectraStartBlock];
+               p_BTableChangesDelta->ValidFields = 0xC0;
+       }
+
+       ftl_cmd_cnt++;
+#endif
+
+       if (g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock] == 0xFE)
+               FTL_Adjust_Relative_Erase_Count(BlkIdx);
+
+       return status;
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Adjust_Relative_Erase_Count
+* Inputs:       index to block that was just incremented and is at the max
+* Outputs:      PASS=0 / FAIL=1
+* Description:  If any erase counts at MAX, adjusts erase count of every
+*               block by substracting least worn
+*               counter from counter value of every entry in wear table
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX)
+{
+       u8 wLeastWornCounter = MAX_BYTE_VALUE;
+       u8 wWearCounter;
+       u32 i, wWearIndex;
+       u32 *pbt = (u32 *)g_pBlockTable;
+       int wResult = PASS;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+               __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+               if (IS_BAD_BLOCK(i))
+                       continue;
+               wWearIndex = (u32)(pbt[i] & (~BAD_BLOCK));
+
+               if ((wWearIndex - DeviceInfo.wSpectraStartBlock) < 0)
+                       printk(KERN_ERR "FTL_Adjust_Relative_Erase_Count:"
+                                       "This should never occur\n");
+               wWearCounter = g_pWearCounter[wWearIndex -
+                       DeviceInfo.wSpectraStartBlock];
+               if (wWearCounter < wLeastWornCounter)
+                       wLeastWornCounter = wWearCounter;
+       }
+
+       if (wLeastWornCounter == 0) {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Adjusting Wear Levelling Counters: Special Case\n");
+               g_pWearCounter[Index_of_MAX -
+                       DeviceInfo.wSpectraStartBlock]--;
+#if CMD_DMA
+               p_BTableChangesDelta =
+                       (struct BTableChangesDelta *)g_pBTDelta_Free;
+               g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+               p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+               p_BTableChangesDelta->WC_Index =
+                       Index_of_MAX - DeviceInfo.wSpectraStartBlock;
+               p_BTableChangesDelta->WC_Entry_Value =
+                       g_pWearCounter[Index_of_MAX -
+                               DeviceInfo.wSpectraStartBlock];
+               p_BTableChangesDelta->ValidFields = 0x30;
+#endif
+               FTL_Static_Wear_Leveling();
+       } else {
+               for (i = 0; i < DeviceInfo.wDataBlockNum; i++)
+                       if (!IS_BAD_BLOCK(i)) {
+                               wWearIndex = (u32)(pbt[i] & (~BAD_BLOCK));
+                               g_pWearCounter[wWearIndex -
+                                       DeviceInfo.wSpectraStartBlock] =
+                                       (u8)(g_pWearCounter
+                                       [wWearIndex -
+                                       DeviceInfo.wSpectraStartBlock] -
+                                       wLeastWornCounter);
+#if CMD_DMA
+                               p_BTableChangesDelta =
+                               (struct BTableChangesDelta *)g_pBTDelta_Free;
+                               g_pBTDelta_Free +=
+                                       sizeof(struct BTableChangesDelta);
+
+                               p_BTableChangesDelta->ftl_cmd_cnt =
+                                       ftl_cmd_cnt;
+                               p_BTableChangesDelta->WC_Index = wWearIndex -
+                                       DeviceInfo.wSpectraStartBlock;
+                               p_BTableChangesDelta->WC_Entry_Value =
+                                       g_pWearCounter[wWearIndex -
+                                       DeviceInfo.wSpectraStartBlock];
+                               p_BTableChangesDelta->ValidFields = 0x30;
+#endif
+                       }
+       }
+
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Write_IN_Progress_Block_Table_Page
+* Inputs:       None
+* Outputs:      None
+* Description:  It writes in-progress flag page to the page next to
+*               block table
+***********************************************************************/
+static int FTL_Write_IN_Progress_Block_Table_Page(void)
+{
+       int wResult = PASS;
+       u16 bt_pages;
+       u16 dwIPFPageAddr;
+#if CMD_DMA
+#else
+       u32 *pbt = (u32 *)g_pBlockTable;
+       u32 wTempBlockTableIndex;
+#endif
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+       bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+       dwIPFPageAddr = g_wBlockTableOffset + bt_pages;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Writing IPF at "
+                              "Block %d Page %d\n",
+                              g_wBlockTableIndex, dwIPFPageAddr);
+
+#if CMD_DMA
+       wResult = GLOB_LLD_Write_Page_Main_Spare_cdma(g_pIPF,
+               g_wBlockTableIndex, dwIPFPageAddr, 1,
+               LLD_CMD_FLAG_MODE_CDMA | LLD_CMD_FLAG_ORDER_BEFORE_REST);
+       if (wResult == FAIL) {
+               nand_dbg_print(NAND_DBG_WARN,
+                              "NAND Program fail in %s, Line %d, "
+                              "Function: %s, new Bad Block %d generated!\n",
+                              __FILE__, __LINE__, __func__,
+                              g_wBlockTableIndex);
+       }
+       g_wBlockTableOffset = dwIPFPageAddr + 1;
+       p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
+       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+       p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+       p_BTableChangesDelta->g_wBlockTableOffset = g_wBlockTableOffset;
+       p_BTableChangesDelta->ValidFields = 0x01;
+       ftl_cmd_cnt++;
+#else
+       wResult = GLOB_LLD_Write_Page_Main_Spare(g_pIPF,
+               g_wBlockTableIndex, dwIPFPageAddr, 1);
+       if (wResult == FAIL) {
+               nand_dbg_print(NAND_DBG_WARN,
+                              "NAND Program fail in %s, Line %d, "
+                              "Function: %s, new Bad Block %d generated!\n",
+                              __FILE__, __LINE__, __func__,
+                              (int)g_wBlockTableIndex);
+               MARK_BLOCK_AS_BAD(pbt[BLOCK_TABLE_INDEX]);
+               wTempBlockTableIndex = FTL_Replace_Block_Table();
+               bt_block_changed = 1;
+               if (BAD_BLOCK == wTempBlockTableIndex)
+                       return ERR;
+               g_wBlockTableIndex = wTempBlockTableIndex;
+               g_wBlockTableOffset = 0;
+               /* Block table tag is '00'. Means it's used one */
+               pbt[BLOCK_TABLE_INDEX] = g_wBlockTableIndex;
+               return FAIL;
+       }
+       g_wBlockTableOffset = dwIPFPageAddr + 1;
+#endif
+       return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     FTL_Read_Disturbance
+* Inputs:       block address
+* Outputs:      PASS=0 / FAIL=1
+* Description:  used to handle read disturbance. Data in block that
+*               reaches its read limit is moved to new block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int FTL_Read_Disturbance(u32 blk_addr)
+{
+       int wResult = FAIL;
+       u32 *pbt = (u32 *) g_pBlockTable;
+       u32 dwOldBlockAddr = blk_addr;
+       u32 wBlockNum;
+       u32 i;
+       u32 wLeastReadCounter = 0xFFFF;
+       u32 wLeastReadIndex = BAD_BLOCK;
+       u32 wSpareBlockNum = 0;
+       u32 wTempNode;
+       u32 wReplacedNode;
+       u8 *g_pTempBuf;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                              __FILE__, __LINE__, __func__);
+
+#if CMD_DMA
+       g_pTempBuf = cp_back_buf_copies[cp_back_buf_idx];
+       cp_back_buf_idx++;
+       if (cp_back_buf_idx > COPY_BACK_BUF_NUM) {
+               printk(KERN_ERR "cp_back_buf_copies overflow! Exit."
+               "Maybe too many pending commands in your CDMA chain.\n");
+               return FAIL;
+       }
+#else
+       g_pTempBuf = tmp_buf_read_disturbance;
+#endif
+
+       wBlockNum = FTL_Get_Block_Index(blk_addr);
+
+       do {
+               /* This is a bug.Here 'i' should be logical block number
+                * and start from 1 (0 is reserved for block table).
+                * Have fixed it.        - Yunpeng 2008. 12. 19
+                */
+               for (i = 1; i < DeviceInfo.wDataBlockNum; i++) {
+                       if (IS_SPARE_BLOCK(i)) {
+                               u32 wPhysicalIndex =
+                                       (u32)((~SPARE_BLOCK) & pbt[i]);
+                               if (g_pReadCounter[wPhysicalIndex -
+                                       DeviceInfo.wSpectraStartBlock] <
+                                       wLeastReadCounter) {
+                                       wLeastReadCounter =
+                                               g_pReadCounter[wPhysicalIndex -
+                                               DeviceInfo.wSpectraStartBlock];
+                                       wLeastReadIndex = i;
+                               }
+                               wSpareBlockNum++;
+                       }
+               }
+
+               if (wSpareBlockNum <= NUM_FREE_BLOCKS_GATE) {
+                       wResult = GLOB_FTL_Garbage_Collection();
+                       if (PASS == wResult)
+                               continue;
+                       else
+                               break;
+               } else {
+                       wTempNode = (u32)(DISCARD_BLOCK | pbt[wBlockNum]);
+                       wReplacedNode = (u32)((~SPARE_BLOCK) &
+                                       pbt[wLeastReadIndex]);
+#if CMD_DMA
+                       pbt[wBlockNum] = wReplacedNode;
+                       pbt[wLeastReadIndex] = wTempNode;
+                       p_BTableChangesDelta =
+                               (struct BTableChangesDelta *)g_pBTDelta_Free;
+                       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+                       p_BTableChangesDelta->ftl_cmd_cnt =
+                                       ftl_cmd_cnt;
+                       p_BTableChangesDelta->BT_Index = wBlockNum;
+                       p_BTableChangesDelta->BT_Entry_Value = pbt[wBlockNum];
+                       p_BTableChangesDelta->ValidFields = 0x0C;
+
+                       p_BTableChangesDelta =
+                               (struct BTableChangesDelta *)g_pBTDelta_Free;
+                       g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+                       p_BTableChangesDelta->ftl_cmd_cnt =
+                                       ftl_cmd_cnt;
+                       p_BTableChangesDelta->BT_Index = wLeastReadIndex;
+                       p_BTableChangesDelta->BT_Entry_Value =
+                                       pbt[wLeastReadIndex];
+                       p_BTableChangesDelta->ValidFields = 0x0C;
+
+                       wResult = GLOB_LLD_Read_Page_Main_cdma(g_pTempBuf,
+                               dwOldBlockAddr, 0, DeviceInfo.wPagesPerBlock,
+                               LLD_CMD_FLAG_MODE_CDMA);
+                       if (wResult == FAIL)
+                               return wResult;
+
+                       ftl_cmd_cnt++;
+
+                       if (wResult != FAIL) {
+                               if (FAIL == GLOB_LLD_Write_Page_Main_cdma(
+                                       g_pTempBuf, pbt[wBlockNum], 0,
+                                       DeviceInfo.wPagesPerBlock)) {
+                                       nand_dbg_print(NAND_DBG_WARN,
+                                               "NAND Program fail in "
+                                               "%s, Line %d, Function: %s, "
+                                               "new Bad Block %d "
+                                               "generated!\n",
+                                               __FILE__, __LINE__, __func__,
+                                               (int)pbt[wBlockNum]);
+                                       wResult = FAIL;
+                                       MARK_BLOCK_AS_BAD(pbt[wBlockNum]);
+                               }
+                               ftl_cmd_cnt++;
+                       }
+#else
+                       wResult = GLOB_LLD_Read_Page_Main(g_pTempBuf,
+                               dwOldBlockAddr, 0, DeviceInfo.wPagesPerBlock);
+                       if (wResult == FAIL)
+                               return wResult;
+
+                       if (wResult != FAIL) {
+                               /* This is a bug. At this time, pbt[wBlockNum]
+                               is still the physical address of
+                               discard block, and should not be write.
+                               Have fixed it as below.
+                                       -- Yunpeng 2008.12.19
+                               */
+                               wResult = GLOB_LLD_Write_Page_Main(g_pTempBuf,
+                                       wReplacedNode, 0,
+                                       DeviceInfo.wPagesPerBlock);
+                               if (wResult == FAIL) {
+                                       nand_dbg_print(NAND_DBG_WARN,
+                                               "NAND Program fail in "
+                                               "%s, Line %d, Function: %s, "
+                                               "new Bad Block %d "
+                                               "generated!\n",
+                                               __FILE__, __LINE__, __func__,
+                                               (int)wReplacedNode);
+                                       MARK_BLOCK_AS_BAD(wReplacedNode);
+                               } else {
+                                       pbt[wBlockNum] = wReplacedNode;
+                                       pbt[wLeastReadIndex] = wTempNode;
+                               }
+                       }
+
+                       if ((wResult == PASS) && (g_cBlockTableStatus !=
+                               IN_PROGRESS_BLOCK_TABLE)) {
+                               g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+                               FTL_Write_IN_Progress_Block_Table_Page();
+                       }
+#endif
+               }
+       } while (wResult != PASS)
+       ;
+
+#if CMD_DMA
+       /* ... */
+#endif
+
+       return wResult;
+}
+
diff --git a/drivers/staging/spectra/flash.h b/drivers/staging/spectra/flash.h
new file mode 100644 (file)
index 0000000..5ed0580
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _FLASH_INTERFACE_
+#define _FLASH_INTERFACE_
+
+#include "ffsport.h"
+#include "spectraswconfig.h"
+
+#define MAX_BYTE_VALUE        0xFF
+#define MAX_WORD_VALUE        0xFFFF
+#define MAX_U32_VALUE        0xFFFFFFFF
+
+#define MAX_BLOCKNODE_VALUE     0xFFFFFF
+#define DISCARD_BLOCK           0x800000
+#define SPARE_BLOCK             0x400000
+#define BAD_BLOCK               0xC00000
+
+#define UNHIT_CACHE_ITEM         0xFFFF
+
+#define NAND_CACHE_INIT_ADDR    0xffffffffffffffffULL
+
+#define IN_PROGRESS_BLOCK_TABLE   0x00
+#define CURRENT_BLOCK_TABLE       0x01
+
+#define BTSIG_OFFSET   (0)
+#define BTSIG_BYTES    (5)
+#define BTSIG_DELTA    (3)
+
+#define MAX_READ_COUNTER  0x2710
+
+#define FIRST_BT_ID            (1)
+#define LAST_BT_ID    (254)
+#define BTBLOCK_INVAL  (u32)(0xFFFFFFFF)
+
+struct device_info_tag {
+       u16 wDeviceMaker;
+       u16 wDeviceID;
+       u32 wDeviceType;
+       u32 wSpectraStartBlock;
+       u32 wSpectraEndBlock;
+       u32 wTotalBlocks;
+       u16 wPagesPerBlock;
+       u16 wPageSize;
+       u16 wPageDataSize;
+       u16 wPageSpareSize;
+       u16 wNumPageSpareFlag;
+       u16 wECCBytesPerSector;
+       u32 wBlockSize;
+       u32 wBlockDataSize;
+       u32 wDataBlockNum;
+       u8 bPlaneNum;
+       u16 wDeviceMainAreaSize;
+       u16 wDeviceSpareAreaSize;
+       u16 wDevicesConnected;
+       u16 wDeviceWidth;
+       u16 wHWRevision;
+       u16 wHWFeatures;
+
+       u16 wONFIDevFeatures;
+       u16 wONFIOptCommands;
+       u16 wONFITimingMode;
+       u16 wONFIPgmCacheTimingMode;
+
+       u16 MLCDevice;
+       u16 wSpareSkipBytes;
+
+       u8 nBitsInPageNumber;
+       u8 nBitsInPageDataSize;
+       u8 nBitsInBlockDataSize;
+};
+
+extern struct device_info_tag DeviceInfo;
+
+/* Cache item format */
+struct flash_cache_item_tag {
+       u64 address;
+       u16 use_cnt;
+       u16 changed;
+       u8 *buf;
+};
+
+struct flash_cache_tag {
+       u32 cache_item_size; /* Size in bytes of each cache item */
+       u16 pages_per_item; /* How many NAND pages in each cache item */
+       u16 LRU; /* No. of the least recently used cache item */
+       struct flash_cache_item_tag array[CACHE_ITEM_NUM];
+};
+
+/*
+ *Data structure for each list node of the managment table
+ * used for the Level 2 Cache. Each node maps one logical NAND block.
+ */
+struct spectra_l2_cache_list {
+       struct list_head list;
+       u32 logical_blk_num; /* Logical block number */
+       u32 pages_array[]; /* Page map array of this logical block.
+                          * Array index is the logical block number,
+                          * and for every item of this arry:
+                          * high 16 bit is index of the L2 cache block num,
+                          * low 16 bit is the phy page num
+                          * of the above L2 cache block.
+                          * This array will be kmalloc during run time.
+                          */
+};
+
+struct spectra_l2_cache_info {
+       u32 blk_array[BLK_NUM_FOR_L2_CACHE];
+       u16 cur_blk_idx; /* idx to the phy block number of current using */
+       u16 cur_page_num; /* pages number of current using */
+       struct spectra_l2_cache_list table; /* First node of the table */
+};
+
+#define RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE    1
+
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+struct flash_cache_mod_item_tag {
+       u64 address;
+       u8 changed;
+};
+
+struct flash_cache_delta_list_tag {
+       u8 item;  /* used cache item */
+       struct flash_cache_mod_item_tag cache;
+};
+#endif
+
+extern struct flash_cache_tag Cache;
+
+extern u8 *buf_read_page_main_spare;
+extern u8 *buf_write_page_main_spare;
+extern u8 *buf_read_page_spare;
+extern u8 *buf_get_bad_block;
+extern u8 *cdma_desc_buf;
+extern u8 *memcp_desc_buf;
+
+/* struture used for IndentfyDevice function */
+struct spectra_indentfy_dev_tag {
+       u32 NumBlocks;
+       u16 PagesPerBlock;
+       u16 PageDataSize;
+       u16 wECCBytesPerSector;
+       u32 wDataBlockNum;
+};
+
+int GLOB_FTL_Flash_Init(void);
+int GLOB_FTL_Flash_Release(void);
+/*void GLOB_FTL_Erase_Flash(void);*/
+int GLOB_FTL_Block_Erase(u64 block_addr);
+int GLOB_FTL_Is_BadBlock(u32 block_num);
+int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *dev_data);
+int GLOB_FTL_Event_Status(int *);
+u16 glob_ftl_execute_cmds(void);
+
+/*int FTL_Read_Disturbance(ADDRESSTYPE dwBlockAddr);*/
+int FTL_Read_Disturbance(u32 dwBlockAddr);
+
+/*Flash r/w based on cache*/
+int GLOB_FTL_Page_Read(u8 *read_data, u64 page_addr);
+int GLOB_FTL_Page_Write(u8 *write_data, u64 page_addr);
+int GLOB_FTL_Wear_Leveling(void);
+int GLOB_FTL_Flash_Format(void);
+int GLOB_FTL_Init(void);
+int GLOB_FTL_Flush_Cache(void);
+int GLOB_FTL_Garbage_Collection(void);
+int GLOB_FTL_BT_Garbage_Collection(void);
+void GLOB_FTL_Cache_Release(void);
+u8 *get_blk_table_start_addr(void);
+u8 *get_wear_leveling_table_start_addr(void);
+unsigned long get_blk_table_len(void);
+unsigned long get_wear_leveling_table_len(void);
+
+#if DEBUG_BNDRY
+void debug_boundary_lineno_error(int chnl, int limit, int no, int lineno,
+                               char *filename);
+#define debug_boundary_error(chnl, limit, no) debug_boundary_lineno_error(chnl,\
+                                               limit, no, __LINE__, __FILE__)
+#else
+#define debug_boundary_error(chnl, limit, no) ;
+#endif
+
+#endif /*_FLASH_INTERFACE_*/
diff --git a/drivers/staging/spectra/lld.c b/drivers/staging/spectra/lld.c
new file mode 100644 (file)
index 0000000..5c3b976
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "spectraswconfig.h"
+#include "ffsport.h"
+#include "ffsdefs.h"
+#include "lld.h"
+#include "lld_nand.h"
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+#if FLASH_EMU          /* vector all the LLD calls to the LLD_EMU code */
+#include "lld_emu.h"
+#include "lld_cdma.h"
+
+/* common functions: */
+u16 GLOB_LLD_Flash_Reset(void)
+{
+       return emu_Flash_Reset();
+}
+
+u16 GLOB_LLD_Read_Device_ID(void)
+{
+       return emu_Read_Device_ID();
+}
+
+int GLOB_LLD_Flash_Release(void)
+{
+       return emu_Flash_Release();
+}
+
+u16 GLOB_LLD_Flash_Init(void)
+{
+       return emu_Flash_Init();
+}
+
+u16 GLOB_LLD_Erase_Block(u32 block_add)
+{
+       return emu_Erase_Block(block_add);
+}
+
+u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
+                               u16 PageCount)
+{
+       return emu_Write_Page_Main(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 Page,
+                              u16 PageCount)
+{
+       return emu_Read_Page_Main(read_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
+                       u32 block, u16 page, u16 page_count)
+{
+       return emu_Read_Page_Main(read_data, block, page, page_count);
+}
+
+u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
+                                     u16 Page, u16 PageCount)
+{
+       return emu_Write_Page_Main_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
+                                    u16 Page, u16 PageCount)
+{
+       return emu_Read_Page_Main_Spare(read_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
+                                u16 PageCount)
+{
+       return emu_Write_Page_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
+                               u16 PageCount)
+{
+       return emu_Read_Page_Spare(read_data, block, Page, PageCount);
+}
+
+u16  GLOB_LLD_Get_Bad_Block(u32 block)
+{
+    return  emu_Get_Bad_Block(block);
+}
+
+#endif /* FLASH_EMU */
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+#if FLASH_MTD          /* vector all the LLD calls to the LLD_MTD code */
+#include "lld_mtd.h"
+#include "lld_cdma.h"
+
+/* common functions: */
+u16 GLOB_LLD_Flash_Reset(void)
+{
+       return mtd_Flash_Reset();
+}
+
+u16 GLOB_LLD_Read_Device_ID(void)
+{
+       return mtd_Read_Device_ID();
+}
+
+int GLOB_LLD_Flash_Release(void)
+{
+       return mtd_Flash_Release();
+}
+
+u16 GLOB_LLD_Flash_Init(void)
+{
+       return mtd_Flash_Init();
+}
+
+u16 GLOB_LLD_Erase_Block(u32 block_add)
+{
+       return mtd_Erase_Block(block_add);
+}
+
+u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
+                               u16 PageCount)
+{
+       return mtd_Write_Page_Main(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 Page,
+                              u16 PageCount)
+{
+       return mtd_Read_Page_Main(read_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
+                       u32 block, u16 page, u16 page_count)
+{
+       return mtd_Read_Page_Main(read_data, block, page, page_count);
+}
+
+u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
+                                     u16 Page, u16 PageCount)
+{
+       return mtd_Write_Page_Main_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
+                                    u16 Page, u16 PageCount)
+{
+       return mtd_Read_Page_Main_Spare(read_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
+                                u16 PageCount)
+{
+       return mtd_Write_Page_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
+                               u16 PageCount)
+{
+       return mtd_Read_Page_Spare(read_data, block, Page, PageCount);
+}
+
+u16  GLOB_LLD_Get_Bad_Block(u32 block)
+{
+    return  mtd_Get_Bad_Block(block);
+}
+
+#endif /* FLASH_MTD */
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+#if FLASH_NAND /* vector all the LLD calls to the NAND controller code */
+#include "lld_nand.h"
+#include "lld_cdma.h"
+#include "flash.h"
+
+/* common functions for LLD_NAND */
+void GLOB_LLD_ECC_Control(int enable)
+{
+       NAND_ECC_Ctrl(enable);
+}
+
+/* common functions for LLD_NAND */
+u16 GLOB_LLD_Flash_Reset(void)
+{
+       return NAND_Flash_Reset();
+}
+
+u16 GLOB_LLD_Read_Device_ID(void)
+{
+       return NAND_Read_Device_ID();
+}
+
+u16 GLOB_LLD_UnlockArrayAll(void)
+{
+       return NAND_UnlockArrayAll();
+}
+
+u16 GLOB_LLD_Flash_Init(void)
+{
+       return NAND_Flash_Init();
+}
+
+int GLOB_LLD_Flash_Release(void)
+{
+       return nand_release_spectra();
+}
+
+u16 GLOB_LLD_Erase_Block(u32 block_add)
+{
+       return NAND_Erase_Block(block_add);
+}
+
+
+u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
+                               u16 PageCount)
+{
+       return NAND_Write_Page_Main(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 page,
+                              u16 page_count)
+{
+       if (page_count == 1) /* Using polling to improve read speed */
+               return NAND_Read_Page_Main_Polling(read_data, block, page, 1);
+       else
+               return NAND_Read_Page_Main(read_data, block, page, page_count);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
+                       u32 block, u16 page, u16 page_count)
+{
+       return NAND_Read_Page_Main_Polling(read_data,
+                       block, page, page_count);
+}
+
+u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
+                                     u16 Page, u16 PageCount)
+{
+       return NAND_Write_Page_Main_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
+                                u16 PageCount)
+{
+       return NAND_Write_Page_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
+                                    u16 page, u16 page_count)
+{
+       return NAND_Read_Page_Main_Spare(read_data, block, page, page_count);
+}
+
+u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
+                               u16 PageCount)
+{
+       return NAND_Read_Page_Spare(read_data, block, Page, PageCount);
+}
+
+u16  GLOB_LLD_Get_Bad_Block(u32 block)
+{
+       return  NAND_Get_Bad_Block(block);
+}
+
+#if CMD_DMA
+u16 GLOB_LLD_Event_Status(void)
+{
+       return CDMA_Event_Status();
+}
+
+u16 glob_lld_execute_cmds(void)
+{
+       return CDMA_Execute_CMDs();
+}
+
+u16 GLOB_LLD_MemCopy_CMD(u8 *dest, u8 *src,
+                       u32 ByteCount, u16 flag)
+{
+       /* Replace the hardware memcopy with software memcpy function */
+       if (CDMA_Execute_CMDs())
+               return FAIL;
+       memcpy(dest, src, ByteCount);
+       return PASS;
+
+       /* return CDMA_MemCopy_CMD(dest, src, ByteCount, flag); */
+}
+
+u16 GLOB_LLD_Erase_Block_cdma(u32 block, u16 flags)
+{
+       return CDMA_Data_CMD(ERASE_CMD, 0, block, 0, 0, flags);
+}
+
+u16 GLOB_LLD_Write_Page_Main_cdma(u8 *data, u32 block, u16 page, u16 count)
+{
+       return CDMA_Data_CMD(WRITE_MAIN_CMD, data, block, page, count, 0);
+}
+
+u16 GLOB_LLD_Read_Page_Main_cdma(u8 *data, u32 block, u16 page,
+                               u16 count, u16 flags)
+{
+       return CDMA_Data_CMD(READ_MAIN_CMD, data, block, page, count, flags);
+}
+
+u16 GLOB_LLD_Write_Page_Main_Spare_cdma(u8 *data, u32 block, u16 page,
+                                       u16 count, u16 flags)
+{
+       return CDMA_Data_CMD(WRITE_MAIN_SPARE_CMD,
+                       data, block, page, count, flags);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare_cdma(u8 *data,
+                               u32 block, u16 page, u16 count)
+{
+       return CDMA_Data_CMD(READ_MAIN_SPARE_CMD, data, block, page, count,
+                       LLD_CMD_FLAG_MODE_CDMA);
+}
+
+#endif /* CMD_DMA */
+#endif /* FLASH_NAND */
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+/* end of LLD.c */
diff --git a/drivers/staging/spectra/lld.h b/drivers/staging/spectra/lld.h
new file mode 100644 (file)
index 0000000..d3738e0
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+
+#ifndef _LLD_
+#define _LLD_
+
+#include "ffsport.h"
+#include "spectraswconfig.h"
+#include "flash.h"
+
+#define GOOD_BLOCK 0
+#define DEFECTIVE_BLOCK 1
+#define READ_ERROR 2
+
+#define CLK_X  5
+#define CLK_MULTI 4
+
+/* Typedefs */
+
+/*  prototypes: API for LLD */
+/* Currently, Write_Page_Main
+ *                       MemCopy
+ *                       Read_Page_Main_Spare
+ * do not have flag because they were not implemented prior to this
+ * They are not being added to keep changes to a minimum for now.
+ * Currently, they are not required (only reqd for Wr_P_M_S.)
+ * Later on, these NEED to be changed.
+ */
+
+extern void GLOB_LLD_ECC_Control(int enable);
+
+extern u16 GLOB_LLD_Flash_Reset(void);
+
+extern u16 GLOB_LLD_Read_Device_ID(void);
+
+extern u16 GLOB_LLD_UnlockArrayAll(void);
+
+extern u16 GLOB_LLD_Flash_Init(void);
+
+extern int GLOB_LLD_Flash_Release(void);
+
+extern u16 GLOB_LLD_Erase_Block(u32 block_add);
+
+extern u16 GLOB_LLD_Write_Page_Main(u8 *write_data,
+       u32 block, u16 Page, u16 PageCount);
+
+extern u16 GLOB_LLD_Read_Page_Main(u8 *read_data,
+       u32 block, u16 page, u16 page_count);
+
+extern u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
+       u32 block, u16 page, u16 page_count);
+
+extern u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data,
+       u32 block, u16 Page, u16 PageCount);
+
+extern u16 GLOB_LLD_Write_Page_Spare(u8 *write_data,
+       u32 block, u16 Page, u16 PageCount);
+
+extern u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data,
+       u32 block, u16 page, u16 page_count);
+
+extern u16 GLOB_LLD_Read_Page_Spare(u8 *read_data,
+       u32 block, u16 Page, u16 PageCount);
+
+extern u16  GLOB_LLD_Get_Bad_Block(u32 block);
+
+extern u16 GLOB_LLD_Event_Status(void);
+
+extern u16 GLOB_LLD_MemCopy_CMD(u8 *dest, u8 *src, u32 ByteCount, u16 flag);
+
+extern u16 glob_lld_execute_cmds(void);
+
+extern u16 GLOB_LLD_Erase_Block_cdma(u32 block, u16 flags);
+
+extern u16 GLOB_LLD_Write_Page_Main_cdma(u8 *data,
+       u32 block, u16 page, u16 count);
+
+extern u16 GLOB_LLD_Read_Page_Main_cdma(u8 *data,
+       u32 block, u16 page, u16 count, u16 flags);
+
+extern u16 GLOB_LLD_Write_Page_Main_Spare_cdma(u8 *data,
+       u32 block, u16 page, u16 count, u16 flags);
+
+extern u16 GLOB_LLD_Read_Page_Main_Spare_cdma(u8 *data,
+       u32 block, u16 page, u16 count);
+
+#define LLD_CMD_FLAG_ORDER_BEFORE_REST         (0x1)
+#define LLD_CMD_FLAG_MODE_CDMA                 (0x8)
+
+
+#endif /*_LLD_ */
+
+
diff --git a/drivers/staging/spectra/lld_cdma.c b/drivers/staging/spectra/lld_cdma.c
new file mode 100644 (file)
index 0000000..c6e7610
--- /dev/null
@@ -0,0 +1,910 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+
+#include "spectraswconfig.h"
+#include "lld.h"
+#include "lld_nand.h"
+#include "lld_cdma.h"
+#include "lld_emu.h"
+#include "flash.h"
+#include "nand_regs.h"
+
+#define MAX_PENDING_CMDS    4
+#define MODE_02             (0x2 << 26)
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     CDMA_Data_Cmd
+* Inputs:   cmd code (aligned for hw)
+*               data: pointer to source or destination
+*               block: block address
+*               page: page address
+*               num: num pages to transfer
+* Outputs:      PASS
+* Description:  This function takes the parameters and puts them
+*                   into the "pending commands" array.
+*               It does not parse or validate the parameters.
+*               The array index is same as the tag.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_Data_CMD(u8 cmd, u8 *data, u32 block, u16 page, u16 num, u16 flags)
+{
+       u8 bank;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (0 == cmd)
+               nand_dbg_print(NAND_DBG_DEBUG,
+               "%s, Line %d, Illegal cmd (0)\n", __FILE__, __LINE__);
+
+       /* If a command of another bank comes, then first execute */
+       /* pending commands of the current bank, then set the new */
+       /* bank as current bank */
+       bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+       if (bank != info.flash_bank) {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Will access new bank. old bank: %d, new bank: %d\n",
+                       info.flash_bank, bank);
+               if (CDMA_Execute_CMDs()) {
+                       printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
+                       return FAIL;
+               }
+               info.flash_bank = bank;
+       }
+
+       info.pcmds[info.pcmds_num].CMD = cmd;
+       info.pcmds[info.pcmds_num].DataAddr = data;
+       info.pcmds[info.pcmds_num].Block = block;
+       info.pcmds[info.pcmds_num].Page = page;
+       info.pcmds[info.pcmds_num].PageCount = num;
+       info.pcmds[info.pcmds_num].DataDestAddr = 0;
+       info.pcmds[info.pcmds_num].DataSrcAddr = 0;
+       info.pcmds[info.pcmds_num].MemCopyByteCnt = 0;
+       info.pcmds[info.pcmds_num].Flags = flags;
+       info.pcmds[info.pcmds_num].Status = 0xB0B;
+
+       switch (cmd) {
+       case WRITE_MAIN_SPARE_CMD:
+               Conv_Main_Spare_Data_Log2Phy_Format(data, num);
+               break;
+       case WRITE_SPARE_CMD:
+               Conv_Spare_Data_Log2Phy_Format(data);
+               break;
+       default:
+               break;
+       }
+
+       info.pcmds_num++;
+
+       if (info.pcmds_num >= MAX_PENDING_CMDS) {
+               if (CDMA_Execute_CMDs()) {
+                       printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
+                       return FAIL;
+               }
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     CDMA_MemCopy_CMD
+* Inputs:       dest: pointer to destination
+*               src:  pointer to source
+*               count: num bytes to transfer
+* Outputs:      PASS
+* Description:  This function takes the parameters and puts them
+*                   into the "pending commands" array.
+*               It does not parse or validate the parameters.
+*               The array index is same as the tag.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_MemCopy_CMD(u8 *dest, u8 *src, u32 byte_cnt, u16 flags)
+{
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       info.pcmds[info.pcmds_num].CMD = MEMCOPY_CMD;
+       info.pcmds[info.pcmds_num].DataAddr = 0;
+       info.pcmds[info.pcmds_num].Block = 0;
+       info.pcmds[info.pcmds_num].Page = 0;
+       info.pcmds[info.pcmds_num].PageCount = 0;
+       info.pcmds[info.pcmds_num].DataDestAddr = dest;
+       info.pcmds[info.pcmds_num].DataSrcAddr = src;
+       info.pcmds[info.pcmds_num].MemCopyByteCnt = byte_cnt;
+       info.pcmds[info.pcmds_num].Flags = flags;
+       info.pcmds[info.pcmds_num].Status = 0xB0B;
+
+       info.pcmds_num++;
+
+       if (info.pcmds_num >= MAX_PENDING_CMDS) {
+               if (CDMA_Execute_CMDs()) {
+                       printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
+                       return FAIL;
+               }
+       }
+
+       return PASS;
+}
+
+#if 0
+/* Prints the PendingCMDs array */
+void print_pending_cmds(void)
+{
+       u16 i;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < info.pcmds_num; i++) {
+               nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
+               switch (info.pcmds[i].CMD) {
+               case ERASE_CMD:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Erase Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               case WRITE_MAIN_CMD:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Write Main Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               case WRITE_MAIN_SPARE_CMD:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Write Main Spare Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               case READ_MAIN_SPARE_CMD:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Read Main Spare Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               case READ_MAIN_CMD:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Read Main Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               case MEMCOPY_CMD:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Memcopy Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               case DUMMY_CMD:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Dummy Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               default:
+                       nand_dbg_print(NAND_DBG_DEBUG,
+                               "Illegal Command (0x%x)\n",
+                               info.pcmds[i].CMD);
+                       break;
+               }
+
+               nand_dbg_print(NAND_DBG_DEBUG, "DataAddr: 0x%x\n",
+                       (u32)info.pcmds[i].DataAddr);
+               nand_dbg_print(NAND_DBG_DEBUG, "Block: %d\n",
+                       info.pcmds[i].Block);
+               nand_dbg_print(NAND_DBG_DEBUG, "Page: %d\n",
+                       info.pcmds[i].Page);
+               nand_dbg_print(NAND_DBG_DEBUG, "PageCount: %d\n",
+                       info.pcmds[i].PageCount);
+               nand_dbg_print(NAND_DBG_DEBUG, "DataDestAddr: 0x%x\n",
+                       (u32)info.pcmds[i].DataDestAddr);
+               nand_dbg_print(NAND_DBG_DEBUG, "DataSrcAddr: 0x%x\n",
+                       (u32)info.pcmds[i].DataSrcAddr);
+               nand_dbg_print(NAND_DBG_DEBUG, "MemCopyByteCnt: %d\n",
+                       info.pcmds[i].MemCopyByteCnt);
+               nand_dbg_print(NAND_DBG_DEBUG, "Flags: 0x%x\n",
+                       info.pcmds[i].Flags);
+               nand_dbg_print(NAND_DBG_DEBUG, "Status: 0x%x\n",
+                       info.pcmds[i].Status);
+       }
+}
+
+/* Print the CDMA descriptors */
+void print_cdma_descriptors(void)
+{
+       struct cdma_descriptor *pc;
+       int i;
+
+       pc = (struct cdma_descriptor *)info.cdma_desc_buf;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump cdma descriptors:\n");
+
+       for (i = 0; i < info.cdma_num; i++) {
+               nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "NxtPointerHi: 0x%x, NxtPointerLo: 0x%x\n",
+                       pc[i].NxtPointerHi, pc[i].NxtPointerLo);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "FlashPointerHi: 0x%x, FlashPointerLo: 0x%x\n",
+                       pc[i].FlashPointerHi, pc[i].FlashPointerLo);
+               nand_dbg_print(NAND_DBG_DEBUG, "CommandType: 0x%x\n",
+                       pc[i].CommandType);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "MemAddrHi: 0x%x, MemAddrLo: 0x%x\n",
+                       pc[i].MemAddrHi, pc[i].MemAddrLo);
+               nand_dbg_print(NAND_DBG_DEBUG, "CommandFlags: 0x%x\n",
+                       pc[i].CommandFlags);
+               nand_dbg_print(NAND_DBG_DEBUG, "Channel: %d, Status: 0x%x\n",
+                       pc[i].Channel, pc[i].Status);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "MemCopyPointerHi: 0x%x, MemCopyPointerLo: 0x%x\n",
+                       pc[i].MemCopyPointerHi, pc[i].MemCopyPointerLo);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Reserved12: 0x%x, Reserved13: 0x%x, "
+                       "Reserved14: 0x%x, pcmd: %d\n",
+                       pc[i].Reserved12, pc[i].Reserved13,
+                       pc[i].Reserved14, pc[i].pcmd);
+       }
+}
+
+/* Print the Memory copy descriptors */
+static void print_memcp_descriptors(void)
+{
+       struct memcpy_descriptor *pm;
+       int i;
+
+       pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump mem_cpy descriptors:\n");
+
+       for (i = 0; i < info.cdma_num; i++) {
+               nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "NxtPointerHi: 0x%x, NxtPointerLo: 0x%x\n",
+                       pm[i].NxtPointerHi, pm[i].NxtPointerLo);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "SrcAddrHi: 0x%x, SrcAddrLo: 0x%x\n",
+                       pm[i].SrcAddrHi, pm[i].SrcAddrLo);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "DestAddrHi: 0x%x, DestAddrLo: 0x%x\n",
+                       pm[i].DestAddrHi, pm[i].DestAddrLo);
+               nand_dbg_print(NAND_DBG_DEBUG, "XferSize: %d\n",
+                       pm[i].XferSize);
+               nand_dbg_print(NAND_DBG_DEBUG, "MemCopyFlags: 0x%x\n",
+                       pm[i].MemCopyFlags);
+               nand_dbg_print(NAND_DBG_DEBUG, "MemCopyStatus: %d\n",
+                       pm[i].MemCopyStatus);
+               nand_dbg_print(NAND_DBG_DEBUG, "reserved9: 0x%x\n",
+                       pm[i].reserved9);
+               nand_dbg_print(NAND_DBG_DEBUG, "reserved10: 0x%x\n",
+                       pm[i].reserved10);
+               nand_dbg_print(NAND_DBG_DEBUG, "reserved11: 0x%x\n",
+                       pm[i].reserved11);
+               nand_dbg_print(NAND_DBG_DEBUG, "reserved12: 0x%x\n",
+                       pm[i].reserved12);
+               nand_dbg_print(NAND_DBG_DEBUG, "reserved13: 0x%x\n",
+                       pm[i].reserved13);
+               nand_dbg_print(NAND_DBG_DEBUG, "reserved14: 0x%x\n",
+                       pm[i].reserved14);
+               nand_dbg_print(NAND_DBG_DEBUG, "reserved15: 0x%x\n",
+                       pm[i].reserved15);
+       }
+}
+#endif
+
+/* Reset cdma_descriptor chain to 0 */
+static void reset_cdma_desc(int i)
+{
+       struct cdma_descriptor *ptr;
+
+       BUG_ON(i >= MAX_DESCS);
+
+       ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
+
+       ptr[i].NxtPointerHi = 0;
+       ptr[i].NxtPointerLo = 0;
+       ptr[i].FlashPointerHi = 0;
+       ptr[i].FlashPointerLo = 0;
+       ptr[i].CommandType = 0;
+       ptr[i].MemAddrHi = 0;
+       ptr[i].MemAddrLo = 0;
+       ptr[i].CommandFlags = 0;
+       ptr[i].Channel = 0;
+       ptr[i].Status = 0;
+       ptr[i].MemCopyPointerHi = 0;
+       ptr[i].MemCopyPointerLo = 0;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     CDMA_UpdateEventStatus
+* Inputs:       none
+* Outputs:      none
+* Description:  This function update the event status of all the channels
+*               when an error condition is reported.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void CDMA_UpdateEventStatus(void)
+{
+       int i, j, active_chan;
+       struct cdma_descriptor *ptr;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
+
+       for (j = 0; j < info.cdma_num; j++) {
+               /* Check for the descriptor with failure */
+               if ((ptr[j].Status & CMD_DMA_DESC_FAIL))
+                       break;
+
+       }
+
+       /* All the previous cmd's status for this channel must be good */
+       for (i = 0; i < j; i++) {
+               if (ptr[i].pcmd != 0xff)
+                       info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
+       }
+
+       /* Abort the channel with type 0 reset command. It resets the */
+       /* selected channel after the descriptor completes the flash */
+       /* operation and status has been updated for the descriptor. */
+       /* Memory Copy and Sync associated with this descriptor will */
+       /* not be executed */
+       active_chan = ioread32(FlashReg + CHNL_ACTIVE);
+       if ((active_chan & (1 << info.flash_bank)) == (1 << info.flash_bank)) {
+               iowrite32(MODE_02 | (0 << 4), FlashMem); /* Type 0 reset */
+               iowrite32((0xF << 4) | info.flash_bank, FlashMem + 0x10);
+       } else { /* Should not reached here */
+               printk(KERN_ERR "Error! Used bank is not set in"
+                       " reg CHNL_ACTIVE\n");
+       }
+}
+
+static void cdma_trans(u16 chan)
+{
+       u32 addr;
+
+       addr = info.cdma_desc;
+
+       iowrite32(MODE_10 | (chan << 24), FlashMem);
+       iowrite32((1 << 7) | chan, FlashMem + 0x10);
+
+       iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & (addr >> 16)) << 8),
+               FlashMem);
+       iowrite32((1 << 7) | (1 << 4) | 0, FlashMem + 0x10);
+
+       iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & addr) << 8), FlashMem);
+       iowrite32((1 << 7) | (1 << 5) | 0, FlashMem + 0x10);
+
+       iowrite32(MODE_10 | (chan << 24), FlashMem);
+       iowrite32((1 << 7) | (1 << 5) | (1 << 4) | 0, FlashMem + 0x10);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     CDMA_Execute_CMDs (for use with CMD_DMA)
+* Inputs:       tag_count:  the number of pending cmds to do
+* Outputs:      PASS/FAIL
+* Description:  Build the SDMA chain(s) by making one CMD-DMA descriptor
+*               for each pending command, start the CDMA engine, and return.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_Execute_CMDs(void)
+{
+       int i, ret;
+       u64 flash_add;
+       u32 ptr;
+       dma_addr_t map_addr, next_ptr;
+       u16 status = PASS;
+       u16 tmp_c;
+       struct cdma_descriptor *pc;
+       struct memcpy_descriptor *pm;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       /* No pending cmds to execute, just exit */
+       if (0 == info.pcmds_num) {
+               nand_dbg_print(NAND_DBG_TRACE,
+                       "No pending cmds to execute. Just exit.\n");
+               return PASS;
+       }
+
+       for (i = 0; i < MAX_DESCS; i++)
+               reset_cdma_desc(i);
+
+       pc = (struct cdma_descriptor *)info.cdma_desc_buf;
+       pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
+
+       info.cdma_desc = virt_to_bus(info.cdma_desc_buf);
+       info.memcp_desc = virt_to_bus(info.memcp_desc_buf);
+       next_ptr = info.cdma_desc;
+       info.cdma_num = 0;
+
+       for (i = 0; i < info.pcmds_num; i++) {
+               if (info.pcmds[i].Block >= DeviceInfo.wTotalBlocks) {
+                       info.pcmds[i].Status = CMD_NOT_DONE;
+                       continue;
+               }
+
+               next_ptr += sizeof(struct cdma_descriptor);
+               pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
+               pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
+
+               /* Use the Block offset within a bank */
+               tmp_c = info.pcmds[i].Block /
+                       (DeviceInfo.wTotalBlocks / totalUsedBanks);
+               flash_add = (u64)(info.pcmds[i].Block - tmp_c *
+                       (DeviceInfo.wTotalBlocks / totalUsedBanks)) *
+                       DeviceInfo.wBlockDataSize +
+                       (u64)(info.pcmds[i].Page) *
+                       DeviceInfo.wPageDataSize;
+
+               ptr = MODE_10 | (info.flash_bank << 24) |
+                       (u32)GLOB_u64_Div(flash_add,
+                               DeviceInfo.wPageDataSize);
+               pc[info.cdma_num].FlashPointerHi = ptr >> 16;
+               pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
+
+               if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
+                       (info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
+                       /* Descriptor to set Main+Spare Access Mode */
+                       pc[info.cdma_num].CommandType = 0x43;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       pc[info.cdma_num].MemAddrHi = 0;
+                       pc[info.cdma_num].MemAddrLo = 0;
+                       pc[info.cdma_num].Channel = 0;
+                       pc[info.cdma_num].Status = 0;
+                       pc[info.cdma_num].pcmd = i;
+
+                       info.cdma_num++;
+                       BUG_ON(info.cdma_num >= MAX_DESCS);
+
+                       reset_cdma_desc(info.cdma_num);
+                       next_ptr += sizeof(struct cdma_descriptor);
+                       pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
+                       pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
+                       pc[info.cdma_num].FlashPointerHi = ptr >> 16;
+                       pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
+               }
+
+               switch (info.pcmds[i].CMD) {
+               case ERASE_CMD:
+                       pc[info.cdma_num].CommandType = 1;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       pc[info.cdma_num].MemAddrHi = 0;
+                       pc[info.cdma_num].MemAddrLo = 0;
+                       break;
+
+               case WRITE_MAIN_CMD:
+                       pc[info.cdma_num].CommandType =
+                               0x2100 | info.pcmds[i].PageCount;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       map_addr = virt_to_bus(info.pcmds[i].DataAddr);
+                       pc[info.cdma_num].MemAddrHi = map_addr >> 16;
+                       pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
+                       break;
+
+               case READ_MAIN_CMD:
+                       pc[info.cdma_num].CommandType =
+                               0x2000 | info.pcmds[i].PageCount;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       map_addr = virt_to_bus(info.pcmds[i].DataAddr);
+                       pc[info.cdma_num].MemAddrHi = map_addr >> 16;
+                       pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
+                       break;
+
+               case WRITE_MAIN_SPARE_CMD:
+                       pc[info.cdma_num].CommandType =
+                               0x2100 | info.pcmds[i].PageCount;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       map_addr = virt_to_bus(info.pcmds[i].DataAddr);
+                       pc[info.cdma_num].MemAddrHi = map_addr >> 16;
+                       pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
+                       break;
+
+               case READ_MAIN_SPARE_CMD:
+                       pc[info.cdma_num].CommandType =
+                               0x2000 | info.pcmds[i].PageCount;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       map_addr = virt_to_bus(info.pcmds[i].DataAddr);
+                       pc[info.cdma_num].MemAddrHi = map_addr >> 16;
+                       pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
+                       break;
+
+               case MEMCOPY_CMD:
+                       pc[info.cdma_num].CommandType = 0xFFFF; /* NOP cmd */
+                       /* Set bit 11 to let the CDMA engine continue to */
+                       /* execute only after it has finished processing   */
+                       /* the memcopy descriptor.                        */
+                       /* Also set bit 10 and bit 9 to 1                  */
+                       pc[info.cdma_num].CommandFlags = 0x0E40;
+                       map_addr = info.memcp_desc + info.cdma_num *
+                                       sizeof(struct memcpy_descriptor);
+                       pc[info.cdma_num].MemCopyPointerHi = map_addr >> 16;
+                       pc[info.cdma_num].MemCopyPointerLo = map_addr & 0xffff;
+
+                       pm[info.cdma_num].NxtPointerHi = 0;
+                       pm[info.cdma_num].NxtPointerLo = 0;
+
+                       map_addr = virt_to_bus(info.pcmds[i].DataSrcAddr);
+                       pm[info.cdma_num].SrcAddrHi = map_addr >> 16;
+                       pm[info.cdma_num].SrcAddrLo = map_addr & 0xffff;
+                       map_addr = virt_to_bus(info.pcmds[i].DataDestAddr);
+                       pm[info.cdma_num].DestAddrHi = map_addr >> 16;
+                       pm[info.cdma_num].DestAddrLo = map_addr & 0xffff;
+
+                       pm[info.cdma_num].XferSize =
+                               info.pcmds[i].MemCopyByteCnt;
+                       pm[info.cdma_num].MemCopyFlags =
+                               (0 << 15 | 0 << 14 | 27 << 8 | 0x40);
+                       pm[info.cdma_num].MemCopyStatus = 0;
+                       break;
+
+               case DUMMY_CMD:
+               default:
+                       pc[info.cdma_num].CommandType = 0XFFFF;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       pc[info.cdma_num].MemAddrHi = 0;
+                       pc[info.cdma_num].MemAddrLo = 0;
+                       break;
+               }
+
+               pc[info.cdma_num].Channel = 0;
+               pc[info.cdma_num].Status = 0;
+               pc[info.cdma_num].pcmd = i;
+
+               info.cdma_num++;
+               BUG_ON(info.cdma_num >= MAX_DESCS);
+
+               if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
+                       (info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
+                       /* Descriptor to set back Main Area Access Mode */
+                       reset_cdma_desc(info.cdma_num);
+                       next_ptr += sizeof(struct cdma_descriptor);
+                       pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
+                       pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
+
+                       pc[info.cdma_num].FlashPointerHi = ptr >> 16;
+                       pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
+
+                       pc[info.cdma_num].CommandType = 0x42;
+                       pc[info.cdma_num].CommandFlags =
+                               (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
+                       pc[info.cdma_num].MemAddrHi = 0;
+                       pc[info.cdma_num].MemAddrLo = 0;
+
+                       pc[info.cdma_num].Channel = 0;
+                       pc[info.cdma_num].Status = 0;
+                       pc[info.cdma_num].pcmd = i;
+
+                       info.cdma_num++;
+                       BUG_ON(info.cdma_num >= MAX_DESCS);
+               }
+       }
+
+       /* Add a dummy descriptor at end of the CDMA chain */
+       reset_cdma_desc(info.cdma_num);
+       ptr = MODE_10 | (info.flash_bank << 24);
+       pc[info.cdma_num].FlashPointerHi = ptr >> 16;
+       pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
+       pc[info.cdma_num].CommandType = 0xFFFF; /* NOP command */
+       /* Set Command Flags for the last CDMA descriptor: */
+       /* set Continue bit (bit 9) to 0 and Interrupt bit (bit 8) to 1 */
+       pc[info.cdma_num].CommandFlags =
+               (0 << 10) | (0 << 9) | (1 << 8) | 0x40;
+       pc[info.cdma_num].pcmd = 0xff; /* Set it to an illegal value */
+       info.cdma_num++;
+       BUG_ON(info.cdma_num >= MAX_DESCS);
+
+       iowrite32(1, FlashReg + GLOBAL_INT_ENABLE);  /* Enable Interrupt */
+
+       iowrite32(1, FlashReg + DMA_ENABLE);
+       /* Wait for DMA to be enabled before issuing the next command */
+       while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+       cdma_trans(info.flash_bank);
+
+       ret = wait_for_completion_timeout(&info.complete, 50 * HZ);
+       if (!ret)
+               printk(KERN_ERR "Wait for completion timeout "
+                       "in %s, Line %d\n", __FILE__, __LINE__);
+       status = info.ret;
+
+       info.pcmds_num = 0; /* Clear the pending cmds number to 0 */
+
+       return status;
+}
+
+int is_cdma_interrupt(void)
+{
+       u32 ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma;
+       u32 int_en_mask;
+       u32 cdma_int_en_mask;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       /* Set the global Enable masks for only those interrupts
+        * that are supported */
+       cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+                       DMA_INTR__DESC_COMP_CHANNEL1 |
+                       DMA_INTR__DESC_COMP_CHANNEL2 |
+                       DMA_INTR__DESC_COMP_CHANNEL3 |
+                       DMA_INTR__MEMCOPY_DESC_COMP);
+
+       int_en_mask = (INTR_STATUS0__ECC_ERR |
+               INTR_STATUS0__PROGRAM_FAIL |
+               INTR_STATUS0__ERASE_FAIL);
+
+       ints_b0 = ioread32(FlashReg + INTR_STATUS0) & int_en_mask;
+       ints_b1 = ioread32(FlashReg + INTR_STATUS1) & int_en_mask;
+       ints_b2 = ioread32(FlashReg + INTR_STATUS2) & int_en_mask;
+       ints_b3 = ioread32(FlashReg + INTR_STATUS3) & int_en_mask;
+       ints_cdma = ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask;
+
+       nand_dbg_print(NAND_DBG_WARN, "ints_bank0 to ints_bank3: "
+                       "0x%x, 0x%x, 0x%x, 0x%x, ints_cdma: 0x%x\n",
+                       ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma);
+
+       if (ints_b0 || ints_b1 || ints_b2 || ints_b3 || ints_cdma) {
+               return 1;
+       } else {
+               iowrite32(ints_b0, FlashReg + INTR_STATUS0);
+               iowrite32(ints_b1, FlashReg + INTR_STATUS1);
+               iowrite32(ints_b2, FlashReg + INTR_STATUS2);
+               iowrite32(ints_b3, FlashReg + INTR_STATUS3);
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Not a NAND controller interrupt! Ignore it.\n");
+               return 0;
+       }
+}
+
+static void update_event_status(void)
+{
+       int i;
+       struct cdma_descriptor *ptr;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
+
+       for (i = 0; i < info.cdma_num; i++) {
+               if (ptr[i].pcmd != 0xff)
+                       info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
+               if ((ptr[i].CommandType == 0x41) ||
+                       (ptr[i].CommandType == 0x42) ||
+                       (ptr[i].CommandType == 0x43))
+                       continue;
+
+               switch (info.pcmds[ptr[i].pcmd].CMD) {
+               case READ_MAIN_SPARE_CMD:
+                       Conv_Main_Spare_Data_Phy2Log_Format(
+                               info.pcmds[ptr[i].pcmd].DataAddr,
+                               info.pcmds[ptr[i].pcmd].PageCount);
+                       break;
+               case READ_SPARE_CMD:
+                       Conv_Spare_Data_Phy2Log_Format(
+                               info.pcmds[ptr[i].pcmd].DataAddr);
+                       break;
+               }
+       }
+}
+
+static u16 do_ecc_for_desc(u32 ch, u8 *buf, u16 page)
+{
+       u16 event = EVENT_NONE;
+       u16 err_byte;
+       u16 err_page = 0;
+       u8 err_sector;
+       u8 err_device;
+       u16 ecc_correction_info;
+       u16 err_address;
+       u32 eccSectorSize;
+       u8 *err_pos;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+       do {
+               if (0 == ch)
+                       err_page = ioread32(FlashReg + ERR_PAGE_ADDR0);
+               else if (1 == ch)
+                       err_page = ioread32(FlashReg + ERR_PAGE_ADDR1);
+               else if (2 == ch)
+                       err_page = ioread32(FlashReg + ERR_PAGE_ADDR2);
+               else if (3 == ch)
+                       err_page = ioread32(FlashReg + ERR_PAGE_ADDR3);
+
+               err_address = ioread32(FlashReg + ECC_ERROR_ADDRESS);
+               err_byte = err_address & ECC_ERROR_ADDRESS__OFFSET;
+               err_sector = ((err_address &
+                       ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
+
+               ecc_correction_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
+               err_device = ((ecc_correction_info &
+                       ERR_CORRECTION_INFO__DEVICE_NR) >> 8);
+
+               if (ecc_correction_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
+                       event = EVENT_UNCORRECTABLE_DATA_ERROR;
+               } else {
+                       event = EVENT_CORRECTABLE_DATA_ERROR_FIXED;
+                       if (err_byte < ECC_SECTOR_SIZE) {
+                               err_pos = buf +
+                                       (err_page - page) *
+                                       DeviceInfo.wPageDataSize +
+                                       err_sector * eccSectorSize +
+                                       err_byte *
+                                       DeviceInfo.wDevicesConnected +
+                                       err_device;
+                               *err_pos ^= ecc_correction_info &
+                                       ERR_CORRECTION_INFO__BYTEMASK;
+                       }
+               }
+       } while (!(ecc_correction_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
+
+       return event;
+}
+
+static u16 process_ecc_int(u32 c, u16 *p_desc_num)
+{
+       struct cdma_descriptor *ptr;
+       u16 j;
+       int event = EVENT_PASS;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (c != info.flash_bank)
+               printk(KERN_ERR "Error!info.flash_bank is %d, while c is %d\n",
+                               info.flash_bank, c);
+
+       ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
+
+       for (j = 0; j < info.cdma_num; j++)
+               if ((ptr[j].Status & CMD_DMA_DESC_COMP) != CMD_DMA_DESC_COMP)
+                       break;
+
+       *p_desc_num = j; /* Pass the descripter number found here */
+
+       if (j >= info.cdma_num) {
+               printk(KERN_ERR "Can not find the correct descriptor number "
+                       "when ecc interrupt triggered!"
+                       "info.cdma_num: %d, j: %d\n", info.cdma_num, j);
+               return EVENT_UNCORRECTABLE_DATA_ERROR;
+       }
+
+       event = do_ecc_for_desc(c, info.pcmds[ptr[j].pcmd].DataAddr,
+               info.pcmds[ptr[j].pcmd].Page);
+
+       if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
+               printk(KERN_ERR "Uncorrectable ECC error!"
+                       "info.cdma_num: %d, j: %d, "
+                       "pending cmd CMD: 0x%x, "
+                       "Block: 0x%x, Page: 0x%x, PageCount: 0x%x\n",
+                       info.cdma_num, j,
+                       info.pcmds[ptr[j].pcmd].CMD,
+                       info.pcmds[ptr[j].pcmd].Block,
+                       info.pcmds[ptr[j].pcmd].Page,
+                       info.pcmds[ptr[j].pcmd].PageCount);
+
+               if (ptr[j].pcmd != 0xff)
+                       info.pcmds[ptr[j].pcmd].Status = CMD_FAIL;
+               CDMA_UpdateEventStatus();
+       }
+
+       return event;
+}
+
+static void process_prog_erase_fail_int(u16 desc_num)
+{
+       struct cdma_descriptor *ptr;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
+
+       if (ptr[desc_num].pcmd != 0xFF)
+               info.pcmds[ptr[desc_num].pcmd].Status = CMD_FAIL;
+
+       CDMA_UpdateEventStatus();
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     CDMA_Event_Status (for use with CMD_DMA)
+* Inputs:       none
+* Outputs:      Event_Status code
+* Description:  This function is called after an interrupt has happened
+*               It reads the HW status register and ...tbd
+*               It returns the appropriate event status
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16  CDMA_Event_Status(void)
+{
+       u32 ints_addr[4] = {INTR_STATUS0, INTR_STATUS1,
+               INTR_STATUS2, INTR_STATUS3};
+       u32 dma_intr_bit[4] = {DMA_INTR__DESC_COMP_CHANNEL0,
+               DMA_INTR__DESC_COMP_CHANNEL1,
+               DMA_INTR__DESC_COMP_CHANNEL2,
+               DMA_INTR__DESC_COMP_CHANNEL3};
+       u32 cdma_int_status, int_status;
+       u32 ecc_enable = 0;
+       u16 event = EVENT_PASS;
+       u16 cur_desc = 0;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       ecc_enable = ioread32(FlashReg + ECC_ENABLE);
+
+       while (1) {
+               int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
+               if (ecc_enable && (int_status & INTR_STATUS0__ECC_ERR)) {
+                       event = process_ecc_int(info.flash_bank, &cur_desc);
+                       iowrite32(INTR_STATUS0__ECC_ERR,
+                               FlashReg + ints_addr[info.flash_bank]);
+                       if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
+                               nand_dbg_print(NAND_DBG_WARN,
+                                       "ints_bank0 to ints_bank3: "
+                                       "0x%x, 0x%x, 0x%x, 0x%x, "
+                                       "ints_cdma: 0x%x\n",
+                                       ioread32(FlashReg + INTR_STATUS0),
+                                       ioread32(FlashReg + INTR_STATUS1),
+                                       ioread32(FlashReg + INTR_STATUS2),
+                                       ioread32(FlashReg + INTR_STATUS3),
+                                       ioread32(FlashReg + DMA_INTR));
+                               break;
+                       }
+               } else if (int_status & INTR_STATUS0__PROGRAM_FAIL) {
+                       printk(KERN_ERR "NAND program fail interrupt!\n");
+                       process_prog_erase_fail_int(cur_desc);
+                       event = EVENT_PROGRAM_FAILURE;
+                       break;
+               } else if (int_status & INTR_STATUS0__ERASE_FAIL) {
+                       printk(KERN_ERR "NAND erase fail interrupt!\n");
+                       process_prog_erase_fail_int(cur_desc);
+                       event = EVENT_ERASE_FAILURE;
+                       break;
+               } else {
+                       cdma_int_status = ioread32(FlashReg + DMA_INTR);
+                       if (cdma_int_status & dma_intr_bit[info.flash_bank]) {
+                               iowrite32(dma_intr_bit[info.flash_bank],
+                                       FlashReg + DMA_INTR);
+                               update_event_status();
+                               event = EVENT_PASS;
+                               break;
+                       }
+               }
+       }
+
+       int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
+       iowrite32(int_status, FlashReg + ints_addr[info.flash_bank]);
+       cdma_int_status = ioread32(FlashReg + DMA_INTR);
+       iowrite32(cdma_int_status, FlashReg + DMA_INTR);
+
+       iowrite32(0, FlashReg + DMA_ENABLE);
+       while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       return event;
+}
+
+
+
diff --git a/drivers/staging/spectra/lld_cdma.h b/drivers/staging/spectra/lld_cdma.h
new file mode 100644 (file)
index 0000000..854ea06
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/* header for LLD_CDMA.c module */
+
+#ifndef _LLD_CDMA_
+#define _LLD_CDMA_
+
+#include "flash.h"
+
+#define  DEBUG_SYNC    1
+
+/*///////////   CDMA specific MACRO definition */
+#define MAX_DESCS         (255)
+#define MAX_CHANS  (4)
+#define MAX_SYNC_POINTS         (16)
+#define MAX_DESC_PER_CHAN     (MAX_DESCS * 3 + MAX_SYNC_POINTS + 2)
+
+#define CHANNEL_SYNC_MASK       (0x000F)
+#define CHANNEL_DMA_MASK        (0x00F0)
+#define CHANNEL_ID_MASK         (0x0300)
+#define CHANNEL_CONT_MASK       (0x4000)
+#define CHANNEL_INTR_MASK       (0x8000)
+
+#define CHANNEL_SYNC_OFFSET     (0)
+#define CHANNEL_DMA_OFFSET      (4)
+#define CHANNEL_ID_OFFSET       (8)
+#define CHANNEL_CONT_OFFSET     (14)
+#define CHANNEL_INTR_OFFSET     (15)
+
+u16 CDMA_Data_CMD(u8 cmd, u8 *data, u32 block, u16 page, u16 num, u16 flags);
+u16 CDMA_MemCopy_CMD(u8 *dest, u8 *src, u32 byte_cnt, u16 flags);
+u16 CDMA_Execute_CMDs(void);
+void print_pending_cmds(void);
+void print_cdma_descriptors(void);
+
+extern u8 g_SBDCmdIndex;
+extern struct mrst_nand_info info;
+
+
+/*///////////   prototypes: APIs for LLD_CDMA */
+int is_cdma_interrupt(void);
+u16 CDMA_Event_Status(void);
+
+/* CMD-DMA Descriptor Struct.  These are defined by the CMD_DMA HW */
+struct cdma_descriptor {
+       u32 NxtPointerHi;
+       u32 NxtPointerLo;
+       u32 FlashPointerHi;
+       u32 FlashPointerLo;
+       u32 CommandType;
+       u32 MemAddrHi;
+       u32 MemAddrLo;
+       u32 CommandFlags;
+       u32 Channel;
+       u32 Status;
+       u32 MemCopyPointerHi;
+       u32 MemCopyPointerLo;
+       u32 Reserved12;
+       u32 Reserved13;
+       u32 Reserved14;
+       u32 pcmd; /* pending cmd num related to this descriptor */
+};
+
+/* This struct holds one MemCopy descriptor as defined by the HW */
+struct memcpy_descriptor {
+       u32 NxtPointerHi;
+       u32 NxtPointerLo;
+       u32 SrcAddrHi;
+       u32 SrcAddrLo;
+       u32 DestAddrHi;
+       u32 DestAddrLo;
+       u32 XferSize;
+       u32 MemCopyFlags;
+       u32 MemCopyStatus;
+       u32 reserved9;
+       u32 reserved10;
+       u32 reserved11;
+       u32 reserved12;
+       u32 reserved13;
+       u32 reserved14;
+       u32 reserved15;
+};
+
+/* Pending CMD table entries (includes MemCopy parameters */
+struct pending_cmd {
+       u8 CMD;
+       u8 *DataAddr;
+       u32 Block;
+       u16 Page;
+       u16 PageCount;
+       u8 *DataDestAddr;
+       u8 *DataSrcAddr;
+       u32 MemCopyByteCnt;
+       u16 Flags;
+       u16 Status;
+};
+
+#if DEBUG_SYNC
+extern u32 debug_sync_cnt;
+#endif
+
+/* Definitions for CMD DMA descriptor chain fields */
+#define     CMD_DMA_DESC_COMP   0x8000
+#define     CMD_DMA_DESC_FAIL   0x4000
+
+#endif /*_LLD_CDMA_*/
diff --git a/drivers/staging/spectra/lld_emu.c b/drivers/staging/spectra/lld_emu.c
new file mode 100644 (file)
index 0000000..60eb0f6
--- /dev/null
@@ -0,0 +1,780 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include "flash.h"
+#include "ffsdefs.h"
+#include "lld_emu.h"
+#include "lld.h"
+#if CMD_DMA
+#include "lld_cdma.h"
+#endif
+
+#define GLOB_LLD_PAGES           64
+#define GLOB_LLD_PAGE_SIZE       (512+16)
+#define GLOB_LLD_PAGE_DATA_SIZE  512
+#define GLOB_LLD_BLOCKS          2048
+
+#if (CMD_DMA  && FLASH_EMU)
+#include "lld_cdma.h"
+u32 totalUsedBanks;
+u32 valid_banks[MAX_CHANS];
+#endif
+
+#if FLASH_EMU                  /* This is for entire module */
+
+static u8 *flash_memory[GLOB_LLD_BLOCKS * GLOB_LLD_PAGES];
+
+/* Read nand emu file and then fill it's content to flash_memory */
+int emu_load_file_to_mem(void)
+{
+       mm_segment_t fs;
+       struct file *nef_filp = NULL;
+       struct inode *inode = NULL;
+       loff_t nef_size = 0;
+       loff_t tmp_file_offset, file_offset;
+       ssize_t nread;
+       int i, rc = -EINVAL;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       fs = get_fs();
+       set_fs(get_ds());
+
+       nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
+       if (IS_ERR(nef_filp)) {
+               printk(KERN_ERR "filp_open error: "
+                      "Unable to open nand emu file!\n");
+               return PTR_ERR(nef_filp);
+       }
+
+       if (nef_filp->f_path.dentry) {
+               inode = nef_filp->f_path.dentry->d_inode;
+       } else {
+               printk(KERN_ERR "Can not get valid inode!\n");
+               goto out;
+       }
+
+       nef_size = i_size_read(inode->i_mapping->host);
+       if (nef_size <= 0) {
+               printk(KERN_ERR "Invalid nand emu file size: "
+                      "0x%llx\n", nef_size);
+               goto out;
+       } else {
+               nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: %lld\n",
+                              nef_size);
+       }
+
+       file_offset = 0;
+       for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
+               tmp_file_offset = file_offset;
+               nread = vfs_read(nef_filp,
+                                (char __user *)flash_memory[i],
+                                GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
+               if (nread < GLOB_LLD_PAGE_SIZE) {
+                       printk(KERN_ERR "%s, Line %d - "
+                              "nand emu file partial read: "
+                              "%d bytes\n", __FILE__, __LINE__, (int)nread);
+                       goto out;
+               }
+               file_offset += GLOB_LLD_PAGE_SIZE;
+       }
+       rc = 0;
+
+out:
+       filp_close(nef_filp, current->files);
+       set_fs(fs);
+       return rc;
+}
+
+/* Write contents of flash_memory to nand emu file */
+int emu_write_mem_to_file(void)
+{
+       mm_segment_t fs;
+       struct file *nef_filp = NULL;
+       struct inode *inode = NULL;
+       loff_t nef_size = 0;
+       loff_t tmp_file_offset, file_offset;
+       ssize_t nwritten;
+       int i, rc = -EINVAL;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       fs = get_fs();
+       set_fs(get_ds());
+
+       nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
+       if (IS_ERR(nef_filp)) {
+               printk(KERN_ERR "filp_open error: "
+                      "Unable to open nand emu file!\n");
+               return PTR_ERR(nef_filp);
+       }
+
+       if (nef_filp->f_path.dentry) {
+               inode = nef_filp->f_path.dentry->d_inode;
+       } else {
+               printk(KERN_ERR "Invalid " "nef_filp->f_path.dentry value!\n");
+               goto out;
+       }
+
+       nef_size = i_size_read(inode->i_mapping->host);
+       if (nef_size <= 0) {
+               printk(KERN_ERR "Invalid "
+                      "nand emu file size: 0x%llx\n", nef_size);
+               goto out;
+       } else {
+               nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: "
+                              "%lld\n", nef_size);
+       }
+
+       file_offset = 0;
+       for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
+               tmp_file_offset = file_offset;
+               nwritten = vfs_write(nef_filp,
+                                    (char __user *)flash_memory[i],
+                                    GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
+               if (nwritten < GLOB_LLD_PAGE_SIZE) {
+                       printk(KERN_ERR "%s, Line %d - "
+                              "nand emu file partial write: "
+                              "%d bytes\n", __FILE__, __LINE__, (int)nwritten);
+                       goto out;
+               }
+               file_offset += GLOB_LLD_PAGE_SIZE;
+       }
+       rc = 0;
+
+out:
+       filp_close(nef_filp, current->files);
+       set_fs(fs);
+       return rc;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Flash_Init
+* Inputs:       none
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:  Creates & initializes the flash RAM array.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Flash_Init(void)
+{
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       flash_memory[0] = (u8 *)vmalloc(GLOB_LLD_PAGE_SIZE *
+                                                  GLOB_LLD_BLOCKS *
+                                                  GLOB_LLD_PAGES *
+                                                  sizeof(u8));
+       if (!flash_memory[0]) {
+               printk(KERN_ERR "Fail to allocate memory "
+                      "for nand emulator!\n");
+               return ERR;
+       }
+
+       memset((char *)(flash_memory[0]), 0xFF,
+              GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS * GLOB_LLD_PAGES *
+              sizeof(u8));
+
+       for (i = 1; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++)
+               flash_memory[i] = flash_memory[i - 1] + GLOB_LLD_PAGE_SIZE;
+
+       emu_load_file_to_mem(); /* Load nand emu file to mem */
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Flash_Release
+* Inputs:       none
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Releases the flash.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int emu_Flash_Release(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       emu_write_mem_to_file();  /* Write back mem to nand emu file */
+
+       vfree(flash_memory[0]);
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Read_Device_ID
+* Inputs:       none
+* Outputs:      PASS=1 FAIL=0
+* Description:  Reads the info from the controller registers.
+*               Sets up DeviceInfo structure with device parameters
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+u16 emu_Read_Device_ID(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       DeviceInfo.wDeviceMaker = 0;
+       DeviceInfo.wDeviceType = 8;
+       DeviceInfo.wSpectraStartBlock = 36;
+       DeviceInfo.wSpectraEndBlock = GLOB_LLD_BLOCKS - 1;
+       DeviceInfo.wTotalBlocks = GLOB_LLD_BLOCKS;
+       DeviceInfo.wPagesPerBlock = GLOB_LLD_PAGES;
+       DeviceInfo.wPageSize = GLOB_LLD_PAGE_SIZE;
+       DeviceInfo.wPageDataSize = GLOB_LLD_PAGE_DATA_SIZE;
+       DeviceInfo.wPageSpareSize = GLOB_LLD_PAGE_SIZE -
+           GLOB_LLD_PAGE_DATA_SIZE;
+       DeviceInfo.wBlockSize = DeviceInfo.wPageSize * GLOB_LLD_PAGES;
+       DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * GLOB_LLD_PAGES;
+       DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
+                                               DeviceInfo.wSpectraStartBlock
+                                               + 1);
+       DeviceInfo.MLCDevice = 1; /* Emulate MLC device */
+       DeviceInfo.nBitsInPageNumber =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
+       DeviceInfo.nBitsInPageDataSize =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
+       DeviceInfo.nBitsInBlockDataSize =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
+
+#if CMD_DMA
+       totalUsedBanks = 4;
+       valid_banks[0] = 1;
+       valid_banks[1] = 1;
+       valid_banks[2] = 1;
+       valid_banks[3] = 1;
+#endif
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Flash_Reset
+* Inputs:       none
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Reset the flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Flash_Reset(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Erase_Block
+* Inputs:       Address
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Erase a block
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Erase_Block(u32 block_add)
+{
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (block_add >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "emu_Erase_Block error! "
+                      "Too big block address: %d\n", block_add);
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
+               (int)block_add);
+
+       for (i = block_add * GLOB_LLD_PAGES;
+            i < ((block_add + 1) * GLOB_LLD_PAGES); i++) {
+               if (flash_memory[i]) {
+                       memset((u8 *)(flash_memory[i]), 0xFF,
+                              DeviceInfo.wPageSize * sizeof(u8));
+               }
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Write_Page_Main
+* Inputs:       Write buffer address pointer
+*               Block number
+*               Page  number
+*               Number of pages to process
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:  Write the data in the buffer to main area of flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
+                          u16 Page, u16 PageCount)
+{
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks)
+               return FAIL;
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock)
+               return FAIL;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "emu_Write_Page_Main: "
+                      "lba %u Page %u PageCount %u\n",
+                      (unsigned int)Block,
+                      (unsigned int)Page, (unsigned int)PageCount);
+
+       for (i = 0; i < PageCount; i++) {
+               if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+                       printk(KERN_ERR "Run out of memory\n");
+                       return FAIL;
+               }
+               memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
+                      write_data, DeviceInfo.wPageDataSize);
+               write_data += DeviceInfo.wPageDataSize;
+               Page++;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Read_Page_Main
+* Inputs:       Read buffer address pointer
+*               Block number
+*               Page  number
+*               Number of pages to process
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:  Read the data from the flash main area to the buffer
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Read_Page_Main(u8 *read_data, u32 Block,
+                         u16 Page, u16 PageCount)
+{
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks)
+               return FAIL;
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock)
+               return FAIL;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "emu_Read_Page_Main: "
+                      "lba %u Page %u PageCount %u\n",
+                      (unsigned int)Block,
+                      (unsigned int)Page, (unsigned int)PageCount);
+
+       for (i = 0; i < PageCount; i++) {
+               if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+                       memset(read_data, 0xFF, DeviceInfo.wPageDataSize);
+               } else {
+                       memcpy(read_data,
+                              (u8 *) (flash_memory[Block * GLOB_LLD_PAGES
+                                                     + Page]),
+                              DeviceInfo.wPageDataSize);
+               }
+               read_data += DeviceInfo.wPageDataSize;
+               Page++;
+       }
+
+       return PASS;
+}
+
+#ifndef ELDORA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Read_Page_Main_Spare
+* Inputs:       Write Buffer
+*                       Address
+*                       Buffer size
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Read from flash main+spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
+                               u16 Page, u16 PageCount)
+{
+       int i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "Read Page Main+Spare "
+                      "Error: Block Address too big\n");
+               return FAIL;
+       }
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "Read Page Main+Spare "
+                      "Error: Page number too big\n");
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
+                      "No. of pages %u block %u start page %u\n",
+                      (unsigned int)PageCount,
+                      (unsigned int)Block, (unsigned int)Page);
+
+       for (i = 0; i < PageCount; i++) {
+               if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+                       memset(read_data, 0xFF, DeviceInfo.wPageSize);
+               } else {
+                       memcpy(read_data, (u8 *) (flash_memory[Block *
+                                                                GLOB_LLD_PAGES
+                                                                + Page]),
+                              DeviceInfo.wPageSize);
+               }
+
+               read_data += DeviceInfo.wPageSize;
+               Page++;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Write_Page_Main_Spare
+* Inputs:       Write buffer
+*                       address
+*                       buffer length
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Write the buffer to main+spare area of flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
+                                u16 Page, u16 page_count)
+{
+       u16 i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "Write Page Main + Spare "
+                      "Error: Block Address too big\n");
+               return FAIL;
+       }
+
+       if (Page + page_count > DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "Write Page Main + Spare "
+                      "Error: Page number too big\n");
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
+                      "No. of pages %u block %u start page %u\n",
+                      (unsigned int)page_count,
+                      (unsigned int)Block, (unsigned int)Page);
+
+       for (i = 0; i < page_count; i++) {
+               if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+                       printk(KERN_ERR "Run out of memory!\n");
+                       return FAIL;
+               }
+               memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
+                      write_data, DeviceInfo.wPageSize);
+               write_data += DeviceInfo.wPageSize;
+               Page++;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Write_Page_Spare
+* Inputs:       Write buffer
+*                       Address
+*                       buffer size
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Write the buffer in the spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
+                           u16 Page, u16 PageCount)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "Read Page Spare Error: "
+                      "Block Address too big\n");
+               return FAIL;
+       }
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "Read Page Spare Error: "
+                      "Page number too big\n");
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Write Page Spare- "
+                      "block %u page %u\n",
+                      (unsigned int)Block, (unsigned int)Page);
+
+       if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+               printk(KERN_ERR "Run out of memory!\n");
+               return FAIL;
+       }
+
+       memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page] +
+                        DeviceInfo.wPageDataSize), write_data,
+              (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Read_Page_Spare
+* Inputs:       Write Buffer
+*                       Address
+*                       Buffer size
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Read data from the spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Read_Page_Spare(u8 *write_data, u32 Block,
+                          u16 Page, u16 PageCount)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "Read Page Spare "
+                      "Error: Block Address too big\n");
+               return FAIL;
+       }
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "Read Page Spare "
+                      "Error: Page number too big\n");
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
+                      "block %u page %u\n",
+                      (unsigned int)Block, (unsigned int)Page);
+
+       if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+               memset(write_data, 0xFF,
+                      (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
+       } else {
+               memcpy(write_data,
+                      (u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]
+                                + DeviceInfo.wPageDataSize),
+                      (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Enable_Disable_Interrupts
+* Inputs:       enable or disable
+* Outputs:      none
+* Description:  NOP
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void emu_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+}
+
+u16 emu_Get_Bad_Block(u32 block)
+{
+       return 0;
+}
+
+#if CMD_DMA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Support for CDMA functions
+************************************
+*       emu_CDMA_Flash_Init
+*           CDMA_process_data command   (use LLD_CDMA)
+*           CDMA_MemCopy_CMD            (use LLD_CDMA)
+*       emu_CDMA_execute all commands
+*       emu_CDMA_Event_Status
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_CDMA_Flash_Init(void)
+{
+       u16 i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
+               PendingCMD[i].CMD = 0;
+               PendingCMD[i].Tag = 0;
+               PendingCMD[i].DataAddr = 0;
+               PendingCMD[i].Block = 0;
+               PendingCMD[i].Page = 0;
+               PendingCMD[i].PageCount = 0;
+               PendingCMD[i].DataDestAddr = 0;
+               PendingCMD[i].DataSrcAddr = 0;
+               PendingCMD[i].MemCopyByteCnt = 0;
+               PendingCMD[i].ChanSync[0] = 0;
+               PendingCMD[i].ChanSync[1] = 0;
+               PendingCMD[i].ChanSync[2] = 0;
+               PendingCMD[i].ChanSync[3] = 0;
+               PendingCMD[i].ChanSync[4] = 0;
+               PendingCMD[i].Status = 3;
+       }
+
+       return PASS;
+}
+
+static void emu_isr(int irq, void *dev_id)
+{
+       /* TODO:  ... */
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     CDMA_Execute_CMDs
+* Inputs:       tag_count:  the number of pending cmds to do
+* Outputs:      PASS/FAIL
+* Description:  execute each command in the pending CMD array
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_CDMA_Execute_CMDs(u16 tag_count)
+{
+       u16 i, j;
+       u8 CMD;         /* cmd parameter */
+       u8 *data;
+       u32 block;
+       u16 page;
+       u16 count;
+       u16 status = PASS;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
+                      "Tag Count %u\n", tag_count);
+
+       for (i = 0; i < totalUsedBanks; i++) {
+               PendingCMD[i].CMD = DUMMY_CMD;
+               PendingCMD[i].Tag = 0xFF;
+               PendingCMD[i].Block =
+                   (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
+
+               for (j = 0; j <= MAX_CHANS; j++)
+                       PendingCMD[i].ChanSync[j] = 0;
+       }
+
+       CDMA_Execute_CMDs(tag_count);
+
+       print_pending_cmds(tag_count);
+
+#if DEBUG_SYNC
+       }
+       debug_sync_cnt++;
+#endif
+
+       for (i = MAX_CHANS;
+            i < tag_count + MAX_CHANS; i++) {
+               CMD = PendingCMD[i].CMD;
+               data = PendingCMD[i].DataAddr;
+               block = PendingCMD[i].Block;
+               page = PendingCMD[i].Page;
+               count = PendingCMD[i].PageCount;
+
+               switch (CMD) {
+               case ERASE_CMD:
+                       emu_Erase_Block(block);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case WRITE_MAIN_CMD:
+                       emu_Write_Page_Main(data, block, page, count);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case WRITE_MAIN_SPARE_CMD:
+                       emu_Write_Page_Main_Spare(data, block, page, count);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case READ_MAIN_CMD:
+                       emu_Read_Page_Main(data, block, page, count);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case MEMCOPY_CMD:
+                       memcpy(PendingCMD[i].DataDestAddr,
+                              PendingCMD[i].DataSrcAddr,
+                              PendingCMD[i].MemCopyByteCnt);
+               case DUMMY_CMD:
+                       PendingCMD[i].Status = PASS;
+                       break;
+               default:
+                       PendingCMD[i].Status = FAIL;
+                       break;
+               }
+       }
+
+       /*
+        * Temperory adding code to reset PendingCMD array for basic testing.
+        * It should be done at the end of  event status function.
+        */
+       for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
+               PendingCMD[i].CMD = 0;
+               PendingCMD[i].Tag = 0;
+               PendingCMD[i].DataAddr = 0;
+               PendingCMD[i].Block = 0;
+               PendingCMD[i].Page = 0;
+               PendingCMD[i].PageCount = 0;
+               PendingCMD[i].DataDestAddr = 0;
+               PendingCMD[i].DataSrcAddr = 0;
+               PendingCMD[i].MemCopyByteCnt = 0;
+               PendingCMD[i].ChanSync[0] = 0;
+               PendingCMD[i].ChanSync[1] = 0;
+               PendingCMD[i].ChanSync[2] = 0;
+               PendingCMD[i].ChanSync[3] = 0;
+               PendingCMD[i].ChanSync[4] = 0;
+               PendingCMD[i].Status = CMD_NOT_DONE;
+       }
+
+       nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
+
+       emu_isr(0, 0); /* This is a null isr now. Need fill it in future */
+
+       return status;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     emu_Event_Status
+* Inputs:       none
+* Outputs:      Event_Status code
+* Description:  This function can also be used to force errors
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_CDMA_Event_Status(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       return EVENT_PASS;
+}
+
+#endif /* CMD_DMA */
+#endif /* !ELDORA */
+#endif /* FLASH_EMU */
diff --git a/drivers/staging/spectra/lld_emu.h b/drivers/staging/spectra/lld_emu.h
new file mode 100644 (file)
index 0000000..63f84c3
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LLD_EMU_
+#define _LLD_EMU_
+
+#include "ffsport.h"
+#include "ffsdefs.h"
+
+/* prototypes: emulator API functions */
+extern u16 emu_Flash_Reset(void);
+extern u16 emu_Flash_Init(void);
+extern int emu_Flash_Release(void);
+extern u16 emu_Read_Device_ID(void);
+extern u16 emu_Erase_Block(u32 block_addr);
+extern u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
+                               u16 Page, u16 PageCount);
+extern u16 emu_Read_Page_Main(u8 *read_data, u32 Block, u16 Page,
+                                u16 PageCount);
+extern u16 emu_Event_Status(void);
+extern void emu_Enable_Disable_Interrupts(u16 INT_ENABLE);
+extern u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
+                                       u16 Page, u16 PageCount);
+extern u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
+                                       u16 Page, u16 PageCount);
+extern u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
+                                      u16 Page, u16 PageCount);
+extern u16 emu_Read_Page_Spare(u8 *read_data, u32 Block, u16 Page,
+                                 u16 PageCount);
+extern u16 emu_Get_Bad_Block(u32 block);
+
+u16 emu_CDMA_Flash_Init(void);
+u16 emu_CDMA_Execute_CMDs(u16 tag_count);
+u16 emu_CDMA_Event_Status(void);
+#endif /*_LLD_EMU_*/
diff --git a/drivers/staging/spectra/lld_mtd.c b/drivers/staging/spectra/lld_mtd.c
new file mode 100644 (file)
index 0000000..0de05b1
--- /dev/null
@@ -0,0 +1,687 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include "flash.h"
+#include "ffsdefs.h"
+#include "lld_emu.h"
+#include "lld.h"
+#if CMD_DMA
+#include "lld_cdma.h"
+#endif
+
+#define GLOB_LLD_PAGES           64
+#define GLOB_LLD_PAGE_SIZE       (512+16)
+#define GLOB_LLD_PAGE_DATA_SIZE  512
+#define GLOB_LLD_BLOCKS          2048
+
+#if CMD_DMA
+#include "lld_cdma.h"
+u32 totalUsedBanks;
+u32 valid_banks[MAX_CHANS];
+#endif
+
+static struct mtd_info *spectra_mtd;
+static int mtddev = -1;
+module_param(mtddev, int, 0);
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Flash_Init
+* Inputs:       none
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:  Creates & initializes the flash RAM array.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Flash_Init(void)
+{
+       if (mtddev == -1) {
+               printk(KERN_ERR "No MTD device specified. Give mtddev parameter\n");
+               return FAIL;
+       }
+
+       spectra_mtd = get_mtd_device(NULL, mtddev);
+       if (!spectra_mtd) {
+               printk(KERN_ERR "Failed to obtain MTD device #%d\n", mtddev);
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Flash_Release
+* Inputs:       none
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Releases the flash.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int mtd_Flash_Release(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+       if (!spectra_mtd)
+               return PASS;
+
+       put_mtd_device(spectra_mtd);
+       spectra_mtd = NULL;
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Read_Device_ID
+* Inputs:       none
+* Outputs:      PASS=1 FAIL=0
+* Description:  Reads the info from the controller registers.
+*               Sets up DeviceInfo structure with device parameters
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+u16 mtd_Read_Device_ID(void)
+{
+       uint64_t tmp;
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (!spectra_mtd)
+               return FAIL;
+
+       DeviceInfo.wDeviceMaker = 0;
+       DeviceInfo.wDeviceType = 8;
+       DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
+       tmp = spectra_mtd->size;
+       do_div(tmp, spectra_mtd->erasesize);
+       DeviceInfo.wTotalBlocks = tmp;
+       DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
+       DeviceInfo.wPagesPerBlock = spectra_mtd->erasesize / spectra_mtd->writesize;
+       DeviceInfo.wPageSize = spectra_mtd->writesize + spectra_mtd->oobsize;
+       DeviceInfo.wPageDataSize = spectra_mtd->writesize;
+       DeviceInfo.wPageSpareSize = spectra_mtd->oobsize;
+       DeviceInfo.wBlockSize = DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
+       DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * DeviceInfo.wPagesPerBlock;
+       DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
+                                               DeviceInfo.wSpectraStartBlock
+                                               + 1);
+       DeviceInfo.MLCDevice = 0;//spectra_mtd->celltype & NAND_CI_CELLTYPE_MSK;
+       DeviceInfo.nBitsInPageNumber =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
+       DeviceInfo.nBitsInPageDataSize =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
+       DeviceInfo.nBitsInBlockDataSize =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
+
+#if CMD_DMA
+       totalUsedBanks = 4;
+       valid_banks[0] = 1;
+       valid_banks[1] = 1;
+       valid_banks[2] = 1;
+       valid_banks[3] = 1;
+#endif
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Flash_Reset
+* Inputs:       none
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Reset the flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Flash_Reset(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       return PASS;
+}
+
+void erase_callback(struct erase_info *e)
+{
+       complete((void *)e->priv);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Erase_Block
+* Inputs:       Address
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Erase a block
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Erase_Block(u32 block_add)
+{
+       struct erase_info erase;
+       DECLARE_COMPLETION_ONSTACK(comp);
+       int ret;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (block_add >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "mtd_Erase_Block error! "
+                      "Too big block address: %d\n", block_add);
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
+               (int)block_add);
+
+       erase.mtd = spectra_mtd;
+       erase.callback = erase_callback;
+       erase.addr = block_add * spectra_mtd->erasesize;
+       erase.len = spectra_mtd->erasesize;
+       erase.priv = (unsigned long)&comp;
+
+       ret = spectra_mtd->erase(spectra_mtd, &erase);
+       if (!ret) {
+               wait_for_completion(&comp);
+               if (erase.state != MTD_ERASE_DONE)
+                       ret = -EIO;
+       }
+       if (ret) {
+               printk(KERN_WARNING "mtd_Erase_Block error! "
+                      "erase of region [0x%llx, 0x%llx] failed\n",
+                      erase.addr, erase.len);
+               return FAIL;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Write_Page_Main
+* Inputs:       Write buffer address pointer
+*               Block number
+*               Page  number
+*               Number of pages to process
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:  Write the data in the buffer to main area of flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Write_Page_Main(u8 *write_data, u32 Block,
+                          u16 Page, u16 PageCount)
+{
+       size_t retlen;
+       int ret = 0;
+
+       if (Block >= DeviceInfo.wTotalBlocks)
+               return FAIL;
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock)
+               return FAIL;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "mtd_Write_Page_Main: "
+                      "lba %u Page %u PageCount %u\n",
+                      (unsigned int)Block,
+                      (unsigned int)Page, (unsigned int)PageCount);
+
+
+       while (PageCount) {
+               ret = spectra_mtd->write(spectra_mtd,
+                                        (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
+                                        DeviceInfo.wPageDataSize, &retlen, write_data);
+               if (ret) {
+                       printk(KERN_ERR "%s failed %d\n", __func__, ret);
+                       return FAIL;
+               }
+               write_data += DeviceInfo.wPageDataSize;
+               Page++;
+               PageCount--;
+       }
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Read_Page_Main
+* Inputs:       Read buffer address pointer
+*               Block number
+*               Page  number
+*               Number of pages to process
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:  Read the data from the flash main area to the buffer
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Read_Page_Main(u8 *read_data, u32 Block,
+                         u16 Page, u16 PageCount)
+{
+       size_t retlen;
+       int ret = 0;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks)
+               return FAIL;
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock)
+               return FAIL;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "mtd_Read_Page_Main: "
+                      "lba %u Page %u PageCount %u\n",
+                      (unsigned int)Block,
+                      (unsigned int)Page, (unsigned int)PageCount);
+
+
+       while (PageCount) {
+               ret = spectra_mtd->read(spectra_mtd,
+                                       (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
+                                       DeviceInfo.wPageDataSize, &retlen, read_data);
+               if (ret) {
+                       printk(KERN_ERR "%s failed %d\n", __func__, ret);
+                       return FAIL;
+               }
+               read_data += DeviceInfo.wPageDataSize;
+               Page++;
+               PageCount--;
+       }
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       return PASS;
+}
+
+#ifndef ELDORA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Read_Page_Main_Spare
+* Inputs:       Write Buffer
+*                       Address
+*                       Buffer size
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Read from flash main+spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
+                               u16 Page, u16 PageCount)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "Read Page Main+Spare "
+                      "Error: Block Address too big\n");
+               return FAIL;
+       }
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "Read Page Main+Spare "
+                      "Error: Page number %d+%d too big in block %d\n",
+                      Page, PageCount, Block);
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
+                      "No. of pages %u block %u start page %u\n",
+                      (unsigned int)PageCount,
+                      (unsigned int)Block, (unsigned int)Page);
+
+
+       while (PageCount) {
+               struct mtd_oob_ops ops;
+               int ret;
+
+               ops.mode = MTD_OOB_AUTO;
+               ops.datbuf = read_data;
+               ops.len = DeviceInfo.wPageDataSize;
+               ops.oobbuf = read_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
+               ops.ooblen = BTSIG_BYTES;
+               ops.ooboffs = 0;
+
+               ret = spectra_mtd->read_oob(spectra_mtd,
+                                           (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
+                                           &ops);
+               if (ret) {
+                       printk(KERN_ERR "%s failed %d\n", __func__, ret);
+                       return FAIL;
+               }
+               read_data += DeviceInfo.wPageSize;
+               Page++;
+               PageCount--;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Write_Page_Main_Spare
+* Inputs:       Write buffer
+*                       address
+*                       buffer length
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Write the buffer to main+spare area of flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
+                                u16 Page, u16 page_count)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "Write Page Main + Spare "
+                      "Error: Block Address too big\n");
+               return FAIL;
+       }
+
+       if (Page + page_count > DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "Write Page Main + Spare "
+                      "Error: Page number %d+%d too big in block %d\n",
+                      Page, page_count, Block);
+               WARN_ON(1);
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
+                      "No. of pages %u block %u start page %u\n",
+                      (unsigned int)page_count,
+                      (unsigned int)Block, (unsigned int)Page);
+
+       while (page_count) {
+               struct mtd_oob_ops ops;
+               int ret;
+
+               ops.mode = MTD_OOB_AUTO;
+               ops.datbuf = write_data;
+               ops.len = DeviceInfo.wPageDataSize;
+               ops.oobbuf = write_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
+               ops.ooblen = BTSIG_BYTES;
+               ops.ooboffs = 0;
+
+               ret = spectra_mtd->write_oob(spectra_mtd,
+                                            (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
+                                            &ops);
+               if (ret) {
+                       printk(KERN_ERR "%s failed %d\n", __func__, ret);
+                       return FAIL;
+               }
+               write_data += DeviceInfo.wPageSize;
+               Page++;
+               page_count--;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Write_Page_Spare
+* Inputs:       Write buffer
+*                       Address
+*                       buffer size
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Write the buffer in the spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Write_Page_Spare(u8 *write_data, u32 Block,
+                           u16 Page, u16 PageCount)
+{
+       WARN_ON(1);
+       return FAIL;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Read_Page_Spare
+* Inputs:       Write Buffer
+*                       Address
+*                       Buffer size
+* Outputs:      PASS=0 (notice 0=ok here)
+* Description:          Read data from the spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block,
+                          u16 Page, u16 PageCount)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (Block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "Read Page Spare "
+                      "Error: Block Address too big\n");
+               return FAIL;
+       }
+
+       if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "Read Page Spare "
+                      "Error: Page number too big\n");
+               return FAIL;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
+                      "block %u page %u (%u pages)\n",
+                      (unsigned int)Block, (unsigned int)Page, PageCount);
+
+       while (PageCount) {
+               struct mtd_oob_ops ops;
+               int ret;
+
+               ops.mode = MTD_OOB_AUTO;
+               ops.datbuf = NULL;
+               ops.len = 0;
+               ops.oobbuf = read_data;
+               ops.ooblen = BTSIG_BYTES;
+               ops.ooboffs = 0;
+
+               ret = spectra_mtd->read_oob(spectra_mtd,
+                                           (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
+                                           &ops);
+               if (ret) {
+                       printk(KERN_ERR "%s failed %d\n", __func__, ret);
+                       return FAIL;
+               }
+
+               read_data += DeviceInfo.wPageSize;
+               Page++;
+               PageCount--;
+       }
+
+       return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Enable_Disable_Interrupts
+* Inputs:       enable or disable
+* Outputs:      none
+* Description:  NOP
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void mtd_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+}
+
+u16 mtd_Get_Bad_Block(u32 block)
+{
+       return 0;
+}
+
+#if CMD_DMA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Support for CDMA functions
+************************************
+*       mtd_CDMA_Flash_Init
+*           CDMA_process_data command   (use LLD_CDMA)
+*           CDMA_MemCopy_CMD            (use LLD_CDMA)
+*       mtd_CDMA_execute all commands
+*       mtd_CDMA_Event_Status
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_CDMA_Flash_Init(void)
+{
+       u16 i;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
+               PendingCMD[i].CMD = 0;
+               PendingCMD[i].Tag = 0;
+               PendingCMD[i].DataAddr = 0;
+               PendingCMD[i].Block = 0;
+               PendingCMD[i].Page = 0;
+               PendingCMD[i].PageCount = 0;
+               PendingCMD[i].DataDestAddr = 0;
+               PendingCMD[i].DataSrcAddr = 0;
+               PendingCMD[i].MemCopyByteCnt = 0;
+               PendingCMD[i].ChanSync[0] = 0;
+               PendingCMD[i].ChanSync[1] = 0;
+               PendingCMD[i].ChanSync[2] = 0;
+               PendingCMD[i].ChanSync[3] = 0;
+               PendingCMD[i].ChanSync[4] = 0;
+               PendingCMD[i].Status = 3;
+       }
+
+       return PASS;
+}
+
+static void mtd_isr(int irq, void *dev_id)
+{
+       /* TODO:  ... */
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     CDMA_Execute_CMDs
+* Inputs:       tag_count:  the number of pending cmds to do
+* Outputs:      PASS/FAIL
+* Description:  execute each command in the pending CMD array
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_CDMA_Execute_CMDs(u16 tag_count)
+{
+       u16 i, j;
+       u8 CMD;         /* cmd parameter */
+       u8 *data;
+       u32 block;
+       u16 page;
+       u16 count;
+       u16 status = PASS;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
+                      "Tag Count %u\n", tag_count);
+
+       for (i = 0; i < totalUsedBanks; i++) {
+               PendingCMD[i].CMD = DUMMY_CMD;
+               PendingCMD[i].Tag = 0xFF;
+               PendingCMD[i].Block =
+                   (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
+
+               for (j = 0; j <= MAX_CHANS; j++)
+                       PendingCMD[i].ChanSync[j] = 0;
+       }
+
+       CDMA_Execute_CMDs(tag_count);
+
+#ifdef VERBOSE
+               print_pending_cmds(tag_count);
+#endif
+#if DEBUG_SYNC
+       }
+       debug_sync_cnt++;
+#endif
+
+       for (i = MAX_CHANS;
+            i < tag_count + MAX_CHANS; i++) {
+               CMD = PendingCMD[i].CMD;
+               data = PendingCMD[i].DataAddr;
+               block = PendingCMD[i].Block;
+               page = PendingCMD[i].Page;
+               count = PendingCMD[i].PageCount;
+
+               switch (CMD) {
+               case ERASE_CMD:
+                       mtd_Erase_Block(block);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case WRITE_MAIN_CMD:
+                       mtd_Write_Page_Main(data, block, page, count);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case WRITE_MAIN_SPARE_CMD:
+                       mtd_Write_Page_Main_Spare(data, block, page, count);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case READ_MAIN_CMD:
+                       mtd_Read_Page_Main(data, block, page, count);
+                       PendingCMD[i].Status = PASS;
+                       break;
+               case MEMCOPY_CMD:
+                       memcpy(PendingCMD[i].DataDestAddr,
+                              PendingCMD[i].DataSrcAddr,
+                              PendingCMD[i].MemCopyByteCnt);
+               case DUMMY_CMD:
+                       PendingCMD[i].Status = PASS;
+                       break;
+               default:
+                       PendingCMD[i].Status = FAIL;
+                       break;
+               }
+       }
+
+       /*
+        * Temperory adding code to reset PendingCMD array for basic testing.
+        * It should be done at the end of  event status function.
+        */
+       for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
+               PendingCMD[i].CMD = 0;
+               PendingCMD[i].Tag = 0;
+               PendingCMD[i].DataAddr = 0;
+               PendingCMD[i].Block = 0;
+               PendingCMD[i].Page = 0;
+               PendingCMD[i].PageCount = 0;
+               PendingCMD[i].DataDestAddr = 0;
+               PendingCMD[i].DataSrcAddr = 0;
+               PendingCMD[i].MemCopyByteCnt = 0;
+               PendingCMD[i].ChanSync[0] = 0;
+               PendingCMD[i].ChanSync[1] = 0;
+               PendingCMD[i].ChanSync[2] = 0;
+               PendingCMD[i].ChanSync[3] = 0;
+               PendingCMD[i].ChanSync[4] = 0;
+               PendingCMD[i].Status = CMD_NOT_DONE;
+       }
+
+       nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
+
+       mtd_isr(0, 0); /* This is a null isr now. Need fill it in future */
+
+       return status;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function:     mtd_Event_Status
+* Inputs:       none
+* Outputs:      Event_Status code
+* Description:  This function can also be used to force errors
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 mtd_CDMA_Event_Status(void)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       return EVENT_PASS;
+}
+
+#endif /* CMD_DMA */
+#endif /* !ELDORA */
diff --git a/drivers/staging/spectra/lld_mtd.h b/drivers/staging/spectra/lld_mtd.h
new file mode 100644 (file)
index 0000000..4e81ee8
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LLD_MTD_
+#define _LLD_MTD_
+
+#include "ffsport.h"
+#include "ffsdefs.h"
+
+/* prototypes: MTD API functions */
+extern u16 mtd_Flash_Reset(void);
+extern u16 mtd_Flash_Init(void);
+extern int mtd_Flash_Release(void);
+extern u16 mtd_Read_Device_ID(void);
+extern u16 mtd_Erase_Block(u32 block_addr);
+extern u16 mtd_Write_Page_Main(u8 *write_data, u32 Block,
+                               u16 Page, u16 PageCount);
+extern u16 mtd_Read_Page_Main(u8 *read_data, u32 Block, u16 Page,
+                                u16 PageCount);
+extern u16 mtd_Event_Status(void);
+extern void mtd_Enable_Disable_Interrupts(u16 INT_ENABLE);
+extern u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
+                                       u16 Page, u16 PageCount);
+extern u16 mtd_Write_Page_Spare(u8 *write_data, u32 Block,
+                                       u16 Page, u16 PageCount);
+extern u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
+                                      u16 Page, u16 PageCount);
+extern u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block, u16 Page,
+                                 u16 PageCount);
+extern u16 mtd_Get_Bad_Block(u32 block);
+
+u16 mtd_CDMA_Flash_Init(void);
+u16 mtd_CDMA_Execute_CMDs(u16 tag_count);
+u16 mtd_CDMA_Event_Status(void);
+#endif /*_LLD_MTD_*/
diff --git a/drivers/staging/spectra/lld_nand.c b/drivers/staging/spectra/lld_nand.c
new file mode 100644 (file)
index 0000000..13c3ad2
--- /dev/null
@@ -0,0 +1,2601 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "lld.h"
+#include "lld_nand.h"
+#include "lld_cdma.h"
+
+#include "spectraswconfig.h"
+#include "flash.h"
+#include "ffsdefs.h"
+
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+
+#include "nand_regs.h"
+
+#define SPECTRA_NAND_NAME    "nd"
+
+#define CEIL_DIV(X, Y) (((X)%(Y)) ? ((X)/(Y)+1) : ((X)/(Y)))
+#define MAX_PAGES_PER_RW        128
+
+#define INT_IDLE_STATE                 0
+#define INT_READ_PAGE_MAIN    0x01
+#define INT_WRITE_PAGE_MAIN    0x02
+#define INT_PIPELINE_READ_AHEAD    0x04
+#define INT_PIPELINE_WRITE_AHEAD    0x08
+#define INT_MULTI_PLANE_READ    0x10
+#define INT_MULTI_PLANE_WRITE    0x11
+
+static u32 enable_ecc;
+
+struct mrst_nand_info info;
+
+int totalUsedBanks;
+u32 GLOB_valid_banks[LLD_MAX_FLASH_BANKS];
+
+void __iomem *FlashReg;
+void __iomem *FlashMem;
+
+u16 conf_parameters[] = {
+       0x0000,
+       0x0000,
+       0x01F4,
+       0x01F4,
+       0x01F4,
+       0x01F4,
+       0x0000,
+       0x0000,
+       0x0001,
+       0x0000,
+       0x0000,
+       0x0000,
+       0x0000,
+       0x0040,
+       0x0001,
+       0x000A,
+       0x000A,
+       0x000A,
+       0x0000,
+       0x0000,
+       0x0005,
+       0x0012,
+       0x000C
+};
+
+u16   NAND_Get_Bad_Block(u32 block)
+{
+       u32 status = PASS;
+       u32 flag_bytes  = 0;
+       u32 skip_bytes  = DeviceInfo.wSpareSkipBytes;
+       u32 page, i;
+       u8 *pReadSpareBuf = buf_get_bad_block;
+
+       if (enable_ecc)
+               flag_bytes = DeviceInfo.wNumPageSpareFlag;
+
+       for (page = 0; page < 2; page++) {
+               status = NAND_Read_Page_Spare(pReadSpareBuf, block, page, 1);
+               if (status != PASS)
+                       return READ_ERROR;
+               for (i = flag_bytes; i < (flag_bytes + skip_bytes); i++)
+                       if (pReadSpareBuf[i] != 0xff)
+                               return DEFECTIVE_BLOCK;
+       }
+
+       for (page = 1; page < 3; page++) {
+               status = NAND_Read_Page_Spare(pReadSpareBuf, block,
+                       DeviceInfo.wPagesPerBlock - page , 1);
+               if (status != PASS)
+                       return READ_ERROR;
+               for (i = flag_bytes; i < (flag_bytes + skip_bytes); i++)
+                       if (pReadSpareBuf[i] != 0xff)
+                               return DEFECTIVE_BLOCK;
+       }
+
+       return GOOD_BLOCK;
+}
+
+
+u16 NAND_Flash_Reset(void)
+{
+       u32 i;
+       u32 intr_status_rst_comp[4] = {INTR_STATUS0__RST_COMP,
+               INTR_STATUS1__RST_COMP,
+               INTR_STATUS2__RST_COMP,
+               INTR_STATUS3__RST_COMP};
+       u32 intr_status_time_out[4] = {INTR_STATUS0__TIME_OUT,
+               INTR_STATUS1__TIME_OUT,
+               INTR_STATUS2__TIME_OUT,
+               INTR_STATUS3__TIME_OUT};
+       u32 intr_status[4] = {INTR_STATUS0, INTR_STATUS1,
+               INTR_STATUS2, INTR_STATUS3};
+       u32 device_reset_banks[4] = {DEVICE_RESET__BANK0,
+               DEVICE_RESET__BANK1,
+               DEVICE_RESET__BANK2,
+               DEVICE_RESET__BANK3};
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++)
+               iowrite32(intr_status_rst_comp[i] | intr_status_time_out[i],
+               FlashReg + intr_status[i]);
+
+       for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) {
+               iowrite32(device_reset_banks[i], FlashReg + DEVICE_RESET);
+               while (!(ioread32(FlashReg + intr_status[i]) &
+                       (intr_status_rst_comp[i] | intr_status_time_out[i])))
+                       ;
+               if (ioread32(FlashReg + intr_status[i]) &
+                       intr_status_time_out[i])
+                       nand_dbg_print(NAND_DBG_WARN,
+                       "NAND Reset operation timed out on bank %d\n", i);
+       }
+
+       for (i = 0; i < LLD_MAX_FLASH_BANKS; i++)
+               iowrite32(intr_status_rst_comp[i] | intr_status_time_out[i],
+                       FlashReg + intr_status[i]);
+
+       return PASS;
+}
+
+static void NAND_ONFi_Timing_Mode(u16 mode)
+{
+       u16 Trea[6] = {40, 30, 25, 20, 20, 16};
+       u16 Trp[6] = {50, 25, 17, 15, 12, 10};
+       u16 Treh[6] = {30, 15, 15, 10, 10, 7};
+       u16 Trc[6] = {100, 50, 35, 30, 25, 20};
+       u16 Trhoh[6] = {0, 15, 15, 15, 15, 15};
+       u16 Trloh[6] = {0, 0, 0, 0, 5, 5};
+       u16 Tcea[6] = {100, 45, 30, 25, 25, 25};
+       u16 Tadl[6] = {200, 100, 100, 100, 70, 70};
+       u16 Trhw[6] = {200, 100, 100, 100, 100, 100};
+       u16 Trhz[6] = {200, 100, 100, 100, 100, 100};
+       u16 Twhr[6] = {120, 80, 80, 60, 60, 60};
+       u16 Tcs[6] = {70, 35, 25, 25, 20, 15};
+
+       u16 TclsRising = 1;
+       u16 data_invalid_rhoh, data_invalid_rloh, data_invalid;
+       u16 dv_window = 0;
+       u16 en_lo, en_hi;
+       u16 acc_clks;
+       u16 addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       en_lo = CEIL_DIV(Trp[mode], CLK_X);
+       en_hi = CEIL_DIV(Treh[mode], CLK_X);
+
+#if ONFI_BLOOM_TIME
+       if ((en_hi * CLK_X) < (Treh[mode] + 2))
+               en_hi++;
+#endif
+
+       if ((en_lo + en_hi) * CLK_X < Trc[mode])
+               en_lo += CEIL_DIV((Trc[mode] - (en_lo + en_hi) * CLK_X), CLK_X);
+
+       if ((en_lo + en_hi) < CLK_MULTI)
+               en_lo += CLK_MULTI - en_lo - en_hi;
+
+       while (dv_window < 8) {
+               data_invalid_rhoh = en_lo * CLK_X + Trhoh[mode];
+
+               data_invalid_rloh = (en_lo + en_hi) * CLK_X + Trloh[mode];
+
+               data_invalid =
+                   data_invalid_rhoh <
+                   data_invalid_rloh ? data_invalid_rhoh : data_invalid_rloh;
+
+               dv_window = data_invalid - Trea[mode];
+
+               if (dv_window < 8)
+                       en_lo++;
+       }
+
+       acc_clks = CEIL_DIV(Trea[mode], CLK_X);
+
+       while (((acc_clks * CLK_X) - Trea[mode]) < 3)
+               acc_clks++;
+
+       if ((data_invalid - acc_clks * CLK_X) < 2)
+               nand_dbg_print(NAND_DBG_WARN, "%s, Line %d: Warning!\n",
+                       __FILE__, __LINE__);
+
+       addr_2_data = CEIL_DIV(Tadl[mode], CLK_X);
+       re_2_we = CEIL_DIV(Trhw[mode], CLK_X);
+       re_2_re = CEIL_DIV(Trhz[mode], CLK_X);
+       we_2_re = CEIL_DIV(Twhr[mode], CLK_X);
+       cs_cnt = CEIL_DIV((Tcs[mode] - Trp[mode]), CLK_X);
+       if (!TclsRising)
+               cs_cnt = CEIL_DIV(Tcs[mode], CLK_X);
+       if (cs_cnt == 0)
+               cs_cnt = 1;
+
+       if (Tcea[mode]) {
+               while (((cs_cnt * CLK_X) + Trea[mode]) < Tcea[mode])
+                       cs_cnt++;
+       }
+
+#if MODE5_WORKAROUND
+       if (mode == 5)
+               acc_clks = 5;
+#endif
+
+       /* Sighting 3462430: Temporary hack for MT29F128G08CJABAWP:B */
+       if ((ioread32(FlashReg + MANUFACTURER_ID) == 0) &&
+               (ioread32(FlashReg + DEVICE_ID) == 0x88))
+               acc_clks = 6;
+
+       iowrite32(acc_clks, FlashReg + ACC_CLKS);
+       iowrite32(re_2_we, FlashReg + RE_2_WE);
+       iowrite32(re_2_re, FlashReg + RE_2_RE);
+       iowrite32(we_2_re, FlashReg + WE_2_RE);
+       iowrite32(addr_2_data, FlashReg + ADDR_2_DATA);
+       iowrite32(en_lo, FlashReg + RDWR_EN_LO_CNT);
+       iowrite32(en_hi, FlashReg + RDWR_EN_HI_CNT);
+       iowrite32(cs_cnt, FlashReg + CS_SETUP_CNT);
+}
+
+static void index_addr(u32 address, u32 data)
+{
+       iowrite32(address, FlashMem);
+       iowrite32(data, FlashMem + 0x10);
+}
+
+static void index_addr_read_data(u32 address, u32 *pdata)
+{
+       iowrite32(address, FlashMem);
+       *pdata = ioread32(FlashMem + 0x10);
+}
+
+static void set_ecc_config(void)
+{
+#if SUPPORT_8BITECC
+       if ((ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE) < 4096) ||
+               (ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE) <= 128))
+               iowrite32(8, FlashReg + ECC_CORRECTION);
+#endif
+
+       if ((ioread32(FlashReg + ECC_CORRECTION) & ECC_CORRECTION__VALUE)
+               == 1) {
+               DeviceInfo.wECCBytesPerSector = 4;
+               DeviceInfo.wECCBytesPerSector *= DeviceInfo.wDevicesConnected;
+               DeviceInfo.wNumPageSpareFlag =
+                       DeviceInfo.wPageSpareSize -
+                       DeviceInfo.wPageDataSize /
+                       (ECC_SECTOR_SIZE * DeviceInfo.wDevicesConnected) *
+                       DeviceInfo.wECCBytesPerSector
+                       - DeviceInfo.wSpareSkipBytes;
+       } else {
+               DeviceInfo.wECCBytesPerSector =
+                       (ioread32(FlashReg + ECC_CORRECTION) &
+                       ECC_CORRECTION__VALUE) * 13 / 8;
+               if ((DeviceInfo.wECCBytesPerSector) % 2 == 0)
+                       DeviceInfo.wECCBytesPerSector += 2;
+               else
+                       DeviceInfo.wECCBytesPerSector += 1;
+
+               DeviceInfo.wECCBytesPerSector *= DeviceInfo.wDevicesConnected;
+               DeviceInfo.wNumPageSpareFlag = DeviceInfo.wPageSpareSize -
+                       DeviceInfo.wPageDataSize /
+                       (ECC_SECTOR_SIZE * DeviceInfo.wDevicesConnected) *
+                       DeviceInfo.wECCBytesPerSector
+                       - DeviceInfo.wSpareSkipBytes;
+       }
+}
+
+static u16 get_onfi_nand_para(void)
+{
+       int i;
+       u16 blks_lun_l, blks_lun_h, n_of_luns;
+       u32 blockperlun, id;
+
+       iowrite32(DEVICE_RESET__BANK0, FlashReg + DEVICE_RESET);
+
+       while (!((ioread32(FlashReg + INTR_STATUS0) &
+               INTR_STATUS0__RST_COMP) |
+               (ioread32(FlashReg + INTR_STATUS0) &
+               INTR_STATUS0__TIME_OUT)))
+               ;
+
+       if (ioread32(FlashReg + INTR_STATUS0) & INTR_STATUS0__RST_COMP) {
+               iowrite32(DEVICE_RESET__BANK1, FlashReg + DEVICE_RESET);
+               while (!((ioread32(FlashReg + INTR_STATUS1) &
+                       INTR_STATUS1__RST_COMP) |
+                       (ioread32(FlashReg + INTR_STATUS1) &
+                       INTR_STATUS1__TIME_OUT)))
+                       ;
+
+               if (ioread32(FlashReg + INTR_STATUS1) &
+                       INTR_STATUS1__RST_COMP) {
+                       iowrite32(DEVICE_RESET__BANK2,
+                               FlashReg + DEVICE_RESET);
+                       while (!((ioread32(FlashReg + INTR_STATUS2) &
+                               INTR_STATUS2__RST_COMP) |
+                               (ioread32(FlashReg + INTR_STATUS2) &
+                               INTR_STATUS2__TIME_OUT)))
+                               ;
+
+                       if (ioread32(FlashReg + INTR_STATUS2) &
+                               INTR_STATUS2__RST_COMP) {
+                               iowrite32(DEVICE_RESET__BANK3,
+                                       FlashReg + DEVICE_RESET);
+                               while (!((ioread32(FlashReg + INTR_STATUS3) &
+                                       INTR_STATUS3__RST_COMP) |
+                                       (ioread32(FlashReg + INTR_STATUS3) &
+                                       INTR_STATUS3__TIME_OUT)))
+                                       ;
+                       } else {
+                               printk(KERN_ERR "Getting a time out for bank 2!\n");
+                       }
+               } else {
+                       printk(KERN_ERR "Getting a time out for bank 1!\n");
+               }
+       }
+
+       iowrite32(INTR_STATUS0__TIME_OUT, FlashReg + INTR_STATUS0);
+       iowrite32(INTR_STATUS1__TIME_OUT, FlashReg + INTR_STATUS1);
+       iowrite32(INTR_STATUS2__TIME_OUT, FlashReg + INTR_STATUS2);
+       iowrite32(INTR_STATUS3__TIME_OUT, FlashReg + INTR_STATUS3);
+
+       DeviceInfo.wONFIDevFeatures =
+               ioread32(FlashReg + ONFI_DEVICE_FEATURES);
+       DeviceInfo.wONFIOptCommands =
+               ioread32(FlashReg + ONFI_OPTIONAL_COMMANDS);
+       DeviceInfo.wONFITimingMode =
+               ioread32(FlashReg + ONFI_TIMING_MODE);
+       DeviceInfo.wONFIPgmCacheTimingMode =
+               ioread32(FlashReg + ONFI_PGM_CACHE_TIMING_MODE);
+
+       n_of_luns = ioread32(FlashReg + ONFI_DEVICE_NO_OF_LUNS) &
+               ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS;
+       blks_lun_l = ioread32(FlashReg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L);
+       blks_lun_h = ioread32(FlashReg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U);
+
+       blockperlun = (blks_lun_h << 16) | blks_lun_l;
+
+       DeviceInfo.wTotalBlocks = n_of_luns * blockperlun;
+
+       if (!(ioread32(FlashReg + ONFI_TIMING_MODE) &
+               ONFI_TIMING_MODE__VALUE))
+               return FAIL;
+
+       for (i = 5; i > 0; i--) {
+               if (ioread32(FlashReg + ONFI_TIMING_MODE) & (0x01 << i))
+                       break;
+       }
+
+       NAND_ONFi_Timing_Mode(i);
+
+       index_addr(MODE_11 | 0, 0x90);
+       index_addr(MODE_11 | 1, 0);
+
+       for (i = 0; i < 3; i++)
+               index_addr_read_data(MODE_11 | 2, &id);
+
+       nand_dbg_print(NAND_DBG_DEBUG, "3rd ID: 0x%x\n", id);
+
+       DeviceInfo.MLCDevice = id & 0x0C;
+
+       /* By now, all the ONFI devices we know support the page cache */
+       /* rw feature. So here we enable the pipeline_rw_ahead feature */
+       /* iowrite32(1, FlashReg + CACHE_WRITE_ENABLE); */
+       /* iowrite32(1, FlashReg + CACHE_READ_ENABLE);  */
+
+       return PASS;
+}
+
+static void get_samsung_nand_para(void)
+{
+       u8 no_of_planes;
+       u32 blk_size;
+       u64 plane_size, capacity;
+       u32 id_bytes[5];
+       int i;
+
+       index_addr((u32)(MODE_11 | 0), 0x90);
+       index_addr((u32)(MODE_11 | 1), 0);
+       for (i = 0; i < 5; i++)
+               index_addr_read_data((u32)(MODE_11 | 2), &id_bytes[i]);
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+               "ID bytes: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+               id_bytes[0], id_bytes[1], id_bytes[2],
+               id_bytes[3], id_bytes[4]);
+
+       if ((id_bytes[1] & 0xff) == 0xd3) { /* Samsung K9WAG08U1A */
+               /* Set timing register values according to datasheet */
+               iowrite32(5, FlashReg + ACC_CLKS);
+               iowrite32(20, FlashReg + RE_2_WE);
+               iowrite32(12, FlashReg + WE_2_RE);
+               iowrite32(14, FlashReg + ADDR_2_DATA);
+               iowrite32(3, FlashReg + RDWR_EN_LO_CNT);
+               iowrite32(2, FlashReg + RDWR_EN_HI_CNT);
+               iowrite32(2, FlashReg + CS_SETUP_CNT);
+       }
+
+       no_of_planes = 1 << ((id_bytes[4] & 0x0c) >> 2);
+       plane_size  = (u64)64 << ((id_bytes[4] & 0x70) >> 4);
+       blk_size = 64 << ((ioread32(FlashReg + DEVICE_PARAM_1) & 0x30) >> 4);
+       capacity = (u64)128 * plane_size * no_of_planes;
+
+       DeviceInfo.wTotalBlocks = (u32)GLOB_u64_Div(capacity, blk_size);
+}
+
+static void get_toshiba_nand_para(void)
+{
+       void __iomem *scratch_reg;
+       u32 tmp;
+
+       /* Workaround to fix a controller bug which reports a wrong */
+       /* spare area size for some kind of Toshiba NAND device */
+       if ((ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE) == 4096) &&
+               (ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE) == 64)) {
+               iowrite32(216, FlashReg + DEVICE_SPARE_AREA_SIZE);
+               tmp = ioread32(FlashReg + DEVICES_CONNECTED) *
+                       ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE);
+               iowrite32(tmp, FlashReg + LOGICAL_PAGE_SPARE_SIZE);
+#if SUPPORT_15BITECC
+               iowrite32(15, FlashReg + ECC_CORRECTION);
+#elif SUPPORT_8BITECC
+               iowrite32(8, FlashReg + ECC_CORRECTION);
+#endif
+       }
+
+       /* As Toshiba NAND can not provide it's block number, */
+       /* so here we need user to provide the correct block */
+       /* number in a scratch register before the Linux NAND */
+       /* driver is loaded. If no valid value found in the scratch */
+       /* register, then we use default block number value */
+       scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
+       if (!scratch_reg) {
+               printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
+                       __FILE__, __LINE__);
+               DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+       } else {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Spectra: ioremap reg address: 0x%p\n", scratch_reg);
+               DeviceInfo.wTotalBlocks = 1 << ioread8(scratch_reg);
+               if (DeviceInfo.wTotalBlocks < 512)
+                       DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+               iounmap(scratch_reg);
+       }
+}
+
+static void get_hynix_nand_para(void)
+{
+       void __iomem *scratch_reg;
+       u32 main_size, spare_size;
+
+       switch (DeviceInfo.wDeviceID) {
+       case 0xD5: /* Hynix H27UAG8T2A, H27UBG8U5A or H27UCG8VFA */
+       case 0xD7: /* Hynix H27UDG8VEM, H27UCG8UDM or H27UCG8V5A */
+               iowrite32(128, FlashReg + PAGES_PER_BLOCK);
+               iowrite32(4096, FlashReg + DEVICE_MAIN_AREA_SIZE);
+               iowrite32(224, FlashReg + DEVICE_SPARE_AREA_SIZE);
+               main_size = 4096 * ioread32(FlashReg + DEVICES_CONNECTED);
+               spare_size = 224 * ioread32(FlashReg + DEVICES_CONNECTED);
+               iowrite32(main_size, FlashReg + LOGICAL_PAGE_DATA_SIZE);
+               iowrite32(spare_size, FlashReg + LOGICAL_PAGE_SPARE_SIZE);
+               iowrite32(0, FlashReg + DEVICE_WIDTH);
+#if SUPPORT_15BITECC
+               iowrite32(15, FlashReg + ECC_CORRECTION);
+#elif SUPPORT_8BITECC
+               iowrite32(8, FlashReg + ECC_CORRECTION);
+#endif
+               DeviceInfo.MLCDevice  = 1;
+               break;
+       default:
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Spectra: Unknown Hynix NAND (Device ID: 0x%x)."
+                       "Will use default parameter values instead.\n",
+                       DeviceInfo.wDeviceID);
+       }
+
+       scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
+       if (!scratch_reg) {
+               printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
+                       __FILE__, __LINE__);
+               DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+       } else {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Spectra: ioremap reg address: 0x%p\n", scratch_reg);
+               DeviceInfo.wTotalBlocks = 1 << ioread8(scratch_reg);
+               if (DeviceInfo.wTotalBlocks < 512)
+                       DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+               iounmap(scratch_reg);
+       }
+}
+
+static void find_valid_banks(void)
+{
+       u32 id[LLD_MAX_FLASH_BANKS];
+       int i;
+
+       totalUsedBanks = 0;
+       for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) {
+               index_addr((u32)(MODE_11 | (i << 24) | 0), 0x90);
+               index_addr((u32)(MODE_11 | (i << 24) | 1), 0);
+               index_addr_read_data((u32)(MODE_11 | (i << 24) | 2), &id[i]);
+
+               nand_dbg_print(NAND_DBG_DEBUG,
+                       "Return 1st ID for bank[%d]: %x\n", i, id[i]);
+
+               if (i == 0) {
+                       if (id[i] & 0x0ff)
+                               GLOB_valid_banks[i] = 1;
+               } else {
+                       if ((id[i] & 0x0ff) == (id[0] & 0x0ff))
+                               GLOB_valid_banks[i] = 1;
+               }
+
+               totalUsedBanks += GLOB_valid_banks[i];
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+               "totalUsedBanks: %d\n", totalUsedBanks);
+}
+
+static void detect_partition_feature(void)
+{
+       if (ioread32(FlashReg + FEATURES) & FEATURES__PARTITION) {
+               if ((ioread32(FlashReg + PERM_SRC_ID_1) &
+                       PERM_SRC_ID_1__SRCID) == SPECTRA_PARTITION_ID) {
+                       DeviceInfo.wSpectraStartBlock =
+                           ((ioread32(FlashReg + MIN_MAX_BANK_1) &
+                             MIN_MAX_BANK_1__MIN_VALUE) *
+                            DeviceInfo.wTotalBlocks)
+                           +
+                           (ioread32(FlashReg + MIN_BLK_ADDR_1) &
+                           MIN_BLK_ADDR_1__VALUE);
+
+                       DeviceInfo.wSpectraEndBlock =
+                           (((ioread32(FlashReg + MIN_MAX_BANK_1) &
+                              MIN_MAX_BANK_1__MAX_VALUE) >> 2) *
+                            DeviceInfo.wTotalBlocks)
+                           +
+                           (ioread32(FlashReg + MAX_BLK_ADDR_1) &
+                           MAX_BLK_ADDR_1__VALUE);
+
+                       DeviceInfo.wTotalBlocks *= totalUsedBanks;
+
+                       if (DeviceInfo.wSpectraEndBlock >=
+                           DeviceInfo.wTotalBlocks) {
+                               DeviceInfo.wSpectraEndBlock =
+                                   DeviceInfo.wTotalBlocks - 1;
+                       }
+
+                       DeviceInfo.wDataBlockNum =
+                               DeviceInfo.wSpectraEndBlock -
+                               DeviceInfo.wSpectraStartBlock + 1;
+               } else {
+                       DeviceInfo.wTotalBlocks *= totalUsedBanks;
+                       DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
+                       DeviceInfo.wSpectraEndBlock =
+                               DeviceInfo.wTotalBlocks - 1;
+                       DeviceInfo.wDataBlockNum =
+                               DeviceInfo.wSpectraEndBlock -
+                               DeviceInfo.wSpectraStartBlock + 1;
+               }
+       } else {
+               DeviceInfo.wTotalBlocks *= totalUsedBanks;
+               DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
+               DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
+               DeviceInfo.wDataBlockNum =
+                       DeviceInfo.wSpectraEndBlock -
+                       DeviceInfo.wSpectraStartBlock + 1;
+       }
+}
+
+static void dump_device_info(void)
+{
+       nand_dbg_print(NAND_DBG_DEBUG, "DeviceInfo:\n");
+       nand_dbg_print(NAND_DBG_DEBUG, "DeviceMaker: 0x%x\n",
+               DeviceInfo.wDeviceMaker);
+       nand_dbg_print(NAND_DBG_DEBUG, "DeviceID: 0x%x\n",
+               DeviceInfo.wDeviceID);
+       nand_dbg_print(NAND_DBG_DEBUG, "DeviceType: 0x%x\n",
+               DeviceInfo.wDeviceType);
+       nand_dbg_print(NAND_DBG_DEBUG, "SpectraStartBlock: %d\n",
+               DeviceInfo.wSpectraStartBlock);
+       nand_dbg_print(NAND_DBG_DEBUG, "SpectraEndBlock: %d\n",
+               DeviceInfo.wSpectraEndBlock);
+       nand_dbg_print(NAND_DBG_DEBUG, "TotalBlocks: %d\n",
+               DeviceInfo.wTotalBlocks);
+       nand_dbg_print(NAND_DBG_DEBUG, "PagesPerBlock: %d\n",
+               DeviceInfo.wPagesPerBlock);
+       nand_dbg_print(NAND_DBG_DEBUG, "PageSize: %d\n",
+               DeviceInfo.wPageSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "PageDataSize: %d\n",
+               DeviceInfo.wPageDataSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "PageSpareSize: %d\n",
+               DeviceInfo.wPageSpareSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "NumPageSpareFlag: %d\n",
+               DeviceInfo.wNumPageSpareFlag);
+       nand_dbg_print(NAND_DBG_DEBUG, "ECCBytesPerSector: %d\n",
+               DeviceInfo.wECCBytesPerSector);
+       nand_dbg_print(NAND_DBG_DEBUG, "BlockSize: %d\n",
+               DeviceInfo.wBlockSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "BlockDataSize: %d\n",
+               DeviceInfo.wBlockDataSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "DataBlockNum: %d\n",
+               DeviceInfo.wDataBlockNum);
+       nand_dbg_print(NAND_DBG_DEBUG, "PlaneNum: %d\n",
+               DeviceInfo.bPlaneNum);
+       nand_dbg_print(NAND_DBG_DEBUG, "DeviceMainAreaSize: %d\n",
+               DeviceInfo.wDeviceMainAreaSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "DeviceSpareAreaSize: %d\n",
+               DeviceInfo.wDeviceSpareAreaSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "DevicesConnected: %d\n",
+               DeviceInfo.wDevicesConnected);
+       nand_dbg_print(NAND_DBG_DEBUG, "DeviceWidth: %d\n",
+               DeviceInfo.wDeviceWidth);
+       nand_dbg_print(NAND_DBG_DEBUG, "HWRevision: 0x%x\n",
+               DeviceInfo.wHWRevision);
+       nand_dbg_print(NAND_DBG_DEBUG, "HWFeatures: 0x%x\n",
+               DeviceInfo.wHWFeatures);
+       nand_dbg_print(NAND_DBG_DEBUG, "ONFIDevFeatures: 0x%x\n",
+               DeviceInfo.wONFIDevFeatures);
+       nand_dbg_print(NAND_DBG_DEBUG, "ONFIOptCommands: 0x%x\n",
+               DeviceInfo.wONFIOptCommands);
+       nand_dbg_print(NAND_DBG_DEBUG, "ONFITimingMode: 0x%x\n",
+               DeviceInfo.wONFITimingMode);
+       nand_dbg_print(NAND_DBG_DEBUG, "ONFIPgmCacheTimingMode: 0x%x\n",
+               DeviceInfo.wONFIPgmCacheTimingMode);
+       nand_dbg_print(NAND_DBG_DEBUG, "MLCDevice: %s\n",
+               DeviceInfo.MLCDevice ? "Yes" : "No");
+       nand_dbg_print(NAND_DBG_DEBUG, "SpareSkipBytes: %d\n",
+               DeviceInfo.wSpareSkipBytes);
+       nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageNumber: %d\n",
+               DeviceInfo.nBitsInPageNumber);
+       nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageDataSize: %d\n",
+               DeviceInfo.nBitsInPageDataSize);
+       nand_dbg_print(NAND_DBG_DEBUG, "BitsInBlockDataSize: %d\n",
+               DeviceInfo.nBitsInBlockDataSize);
+}
+
+u16 NAND_Read_Device_ID(void)
+{
+       u16 status = PASS;
+       u8 no_of_planes;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       iowrite32(0x02, FlashReg + SPARE_AREA_SKIP_BYTES);
+       iowrite32(0xffff, FlashReg + SPARE_AREA_MARKER);
+       DeviceInfo.wDeviceMaker = ioread32(FlashReg + MANUFACTURER_ID);
+       DeviceInfo.wDeviceID = ioread32(FlashReg + DEVICE_ID);
+       DeviceInfo.MLCDevice = ioread32(FlashReg + DEVICE_PARAM_0) & 0x0c;
+
+       if (ioread32(FlashReg + ONFI_DEVICE_NO_OF_LUNS) &
+               ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE) { /* ONFI 1.0 NAND */
+               if (FAIL == get_onfi_nand_para())
+                       return FAIL;
+       } else if (DeviceInfo.wDeviceMaker == 0xEC) { /* Samsung NAND */
+               get_samsung_nand_para();
+       } else if (DeviceInfo.wDeviceMaker == 0x98) { /* Toshiba NAND */
+               get_toshiba_nand_para();
+       } else if (DeviceInfo.wDeviceMaker == 0xAD) { /* Hynix NAND */
+               get_hynix_nand_para();
+       } else {
+               DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+       }
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
+                       "acc_clks: %d, re_2_we: %d, we_2_re: %d,"
+                       "addr_2_data: %d, rdwr_en_lo_cnt: %d, "
+                       "rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n",
+                       ioread32(FlashReg + ACC_CLKS),
+                       ioread32(FlashReg + RE_2_WE),
+                       ioread32(FlashReg + WE_2_RE),
+                       ioread32(FlashReg + ADDR_2_DATA),
+                       ioread32(FlashReg + RDWR_EN_LO_CNT),
+                       ioread32(FlashReg + RDWR_EN_HI_CNT),
+                       ioread32(FlashReg + CS_SETUP_CNT));
+
+       DeviceInfo.wHWRevision = ioread32(FlashReg + REVISION);
+       DeviceInfo.wHWFeatures = ioread32(FlashReg + FEATURES);
+
+       DeviceInfo.wDeviceMainAreaSize =
+               ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE);
+       DeviceInfo.wDeviceSpareAreaSize =
+               ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE);
+
+       DeviceInfo.wPageDataSize =
+               ioread32(FlashReg + LOGICAL_PAGE_DATA_SIZE);
+
+       /* Note: When using the Micon 4K NAND device, the controller will report
+        * Page Spare Size as 216 bytes. But Micron's Spec say it's 218 bytes.
+        * And if force set it to 218 bytes, the controller can not work
+        * correctly. So just let it be. But keep in mind that this bug may
+        * cause
+        * other problems in future.       - Yunpeng  2008-10-10
+        */
+       DeviceInfo.wPageSpareSize =
+               ioread32(FlashReg + LOGICAL_PAGE_SPARE_SIZE);
+
+       DeviceInfo.wPagesPerBlock = ioread32(FlashReg + PAGES_PER_BLOCK);
+
+       DeviceInfo.wPageSize =
+           DeviceInfo.wPageDataSize + DeviceInfo.wPageSpareSize;
+       DeviceInfo.wBlockSize =
+           DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
+       DeviceInfo.wBlockDataSize =
+           DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize;
+
+       DeviceInfo.wDeviceWidth = ioread32(FlashReg + DEVICE_WIDTH);
+       DeviceInfo.wDeviceType =
+               ((ioread32(FlashReg + DEVICE_WIDTH) > 0) ? 16 : 8);
+
+       DeviceInfo.wDevicesConnected = ioread32(FlashReg + DEVICES_CONNECTED);
+
+       DeviceInfo.wSpareSkipBytes =
+               ioread32(FlashReg + SPARE_AREA_SKIP_BYTES) *
+               DeviceInfo.wDevicesConnected;
+
+       DeviceInfo.nBitsInPageNumber =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
+       DeviceInfo.nBitsInPageDataSize =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
+       DeviceInfo.nBitsInBlockDataSize =
+               (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
+
+       set_ecc_config();
+
+       no_of_planes = ioread32(FlashReg + NUMBER_OF_PLANES) &
+               NUMBER_OF_PLANES__VALUE;
+
+       switch (no_of_planes) {
+       case 0:
+       case 1:
+       case 3:
+       case 7:
+               DeviceInfo.bPlaneNum = no_of_planes + 1;
+               break;
+       default:
+               status = FAIL;
+               break;
+       }
+
+       find_valid_banks();
+
+       detect_partition_feature();
+
+       dump_device_info();
+
+       return status;
+}
+
+u16 NAND_UnlockArrayAll(void)
+{
+       u64 start_addr, end_addr;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       start_addr = 0;
+       end_addr = ((u64)DeviceInfo.wBlockSize *
+               (DeviceInfo.wTotalBlocks - 1)) >>
+               DeviceInfo.nBitsInPageDataSize;
+
+       index_addr((u32)(MODE_10 | (u32)start_addr), 0x10);
+       index_addr((u32)(MODE_10 | (u32)end_addr), 0x11);
+
+       return PASS;
+}
+
+void NAND_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (INT_ENABLE)
+               iowrite32(1, FlashReg + GLOBAL_INT_ENABLE);
+       else
+               iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+}
+
+u16 NAND_Erase_Block(u32 block)
+{
+       u16 status = PASS;
+       u64 flash_add;
+       u16 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       if (block >= DeviceInfo.wTotalBlocks)
+               status = FAIL;
+
+       if (status == PASS) {
+               intr_status = intr_status_addresses[flash_bank];
+
+               iowrite32(INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL,
+                       FlashReg + intr_status);
+
+               index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                       (flash_add >> DeviceInfo.nBitsInPageDataSize)), 1);
+
+               while (!(ioread32(FlashReg + intr_status) &
+                       (INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL)))
+                       ;
+
+               if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__ERASE_FAIL)
+                       status = FAIL;
+
+               iowrite32(INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL,
+                       FlashReg + intr_status);
+       }
+
+       return status;
+}
+
+static u32 Boundary_Check_Block_Page(u32 block, u16 page,
+                                               u16 page_count)
+{
+       u32 status = PASS;
+
+       if (block >= DeviceInfo.wTotalBlocks)
+               status = FAIL;
+
+       if (page + page_count > DeviceInfo.wPagesPerBlock)
+               status = FAIL;
+
+       return status;
+}
+
+u16 NAND_Read_Page_Spare(u8 *read_data, u32 block, u16 page,
+                           u16 page_count)
+{
+       u32 status = PASS;
+       u32 i;
+       u64 flash_add;
+       u32 PageSpareSize = DeviceInfo.wPageSpareSize;
+       u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u8 *page_spare = buf_read_page_spare;
+
+       if (block >= DeviceInfo.wTotalBlocks) {
+               printk(KERN_ERR "block too big: %d\n", (int)block);
+               status = FAIL;
+       }
+
+       if (page >= DeviceInfo.wPagesPerBlock) {
+               printk(KERN_ERR "page too big: %d\n", page);
+               status = FAIL;
+       }
+
+       if (page_count > 1) {
+               printk(KERN_ERR "page count too big: %d\n", page_count);
+               status = FAIL;
+       }
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       if (status == PASS) {
+               intr_status = intr_status_addresses[flash_bank];
+               iowrite32(ioread32(FlashReg + intr_status),
+                       FlashReg + intr_status);
+
+               index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                       (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+                       0x41);
+               index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                       (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+                       0x2000 | page_count);
+               while (!(ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__LOAD_COMP))
+                       ;
+
+               iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+                       (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+                       FlashMem);
+
+               for (i = 0; i < (PageSpareSize / 4); i++)
+                       *((u32 *)page_spare + i) =
+                                       ioread32(FlashMem + 0x10);
+
+               if (enable_ecc) {
+                       for (i = 0; i < spareFlagBytes; i++)
+                               read_data[i] =
+                                       page_spare[PageSpareSize -
+                                               spareFlagBytes + i];
+                       for (i = 0; i < (PageSpareSize - spareFlagBytes); i++)
+                               read_data[spareFlagBytes + i] =
+                                                       page_spare[i];
+               } else {
+                       for (i = 0; i < PageSpareSize; i++)
+                               read_data[i] = page_spare[i];
+               }
+
+               index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                       (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+       }
+
+       return status;
+}
+
+/* No use function. Should be removed later */
+u16 NAND_Write_Page_Spare(u8 *write_data, u32 block, u16 page,
+                            u16 page_count)
+{
+       printk(KERN_ERR
+              "Error! This function (NAND_Write_Page_Spare) should never"
+               " be called!\n");
+       return ERR;
+}
+
+/* op value:  0 - DDMA read;  1 - DDMA write */
+static void ddma_trans(u8 *data, u64 flash_add,
+                       u32 flash_bank, int op, u32 numPages)
+{
+       u32 data_addr;
+
+       /* Map virtual address to bus address for DDMA */
+       data_addr = virt_to_bus(data);
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+               (u16)(2 << 12) | (op << 8) | numPages);
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               ((u16)(0x0FFFF & (data_addr >> 16)) << 8)),
+               (u16)(2 << 12) | (2 << 8) | 0);
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               ((u16)(0x0FFFF & data_addr) << 8)),
+               (u16)(2 << 12) | (3 << 8) | 0);
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               (1 << 16) | (0x40 << 8)),
+               (u16)(2 << 12) | (4 << 8) | 0);
+}
+
+/* If data in buf are all 0xff, then return 1; otherwise return 0 */
+static int check_all_1(u8 *buf)
+{
+       int i, j, cnt;
+
+       for (i = 0; i < DeviceInfo.wPageDataSize; i++) {
+               if (buf[i] != 0xff) {
+                       cnt = 0;
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "the first non-0xff data byte is: %d\n", i);
+                       for (j = i; j < DeviceInfo.wPageDataSize; j++) {
+                               nand_dbg_print(NAND_DBG_WARN, "0x%x ", buf[j]);
+                               cnt++;
+                               if (cnt > 8)
+                                       break;
+                       }
+                       nand_dbg_print(NAND_DBG_WARN, "\n");
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+static int do_ecc_new(unsigned long bank, u8 *buf,
+                               u32 block, u16 page)
+{
+       int status = PASS;
+       u16 err_page = 0;
+       u16 err_byte;
+       u8 err_sect;
+       u8 err_dev;
+       u16 err_fix_info;
+       u16 err_addr;
+       u32 ecc_sect_size;
+       u8 *err_pos;
+       u32 err_page_addr[4] = {ERR_PAGE_ADDR0,
+               ERR_PAGE_ADDR1, ERR_PAGE_ADDR2, ERR_PAGE_ADDR3};
+
+       ecc_sect_size = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+       do {
+               err_page = ioread32(FlashReg + err_page_addr[bank]);
+               err_addr = ioread32(FlashReg + ECC_ERROR_ADDRESS);
+               err_byte = err_addr & ECC_ERROR_ADDRESS__OFFSET;
+               err_sect = ((err_addr & ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
+               err_fix_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
+               err_dev = ((err_fix_info & ERR_CORRECTION_INFO__DEVICE_NR)
+                       >> 8);
+               if (err_fix_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "%s, Line %d Uncorrectable ECC error "
+                               "when read block %d page %d."
+                               "PTN_INTR register: 0x%x "
+                               "err_page: %d, err_sect: %d, err_byte: %d, "
+                               "err_dev: %d, ecc_sect_size: %d, "
+                               "err_fix_info: 0x%x\n",
+                               __FILE__, __LINE__, block, page,
+                               ioread32(FlashReg + PTN_INTR),
+                               err_page, err_sect, err_byte, err_dev,
+                               ecc_sect_size, (u32)err_fix_info);
+
+                       if (check_all_1(buf))
+                               nand_dbg_print(NAND_DBG_WARN, "%s, Line %d"
+                                              "All 0xff!\n",
+                                              __FILE__, __LINE__);
+                       else
+                               nand_dbg_print(NAND_DBG_WARN, "%s, Line %d"
+                                              "Not all 0xff!\n",
+                                              __FILE__, __LINE__);
+                       status = FAIL;
+               } else {
+                       nand_dbg_print(NAND_DBG_WARN,
+                               "%s, Line %d Found ECC error "
+                               "when read block %d page %d."
+                               "err_page: %d, err_sect: %d, err_byte: %d, "
+                               "err_dev: %d, ecc_sect_size: %d, "
+                               "err_fix_info: 0x%x\n",
+                               __FILE__, __LINE__, block, page,
+                               err_page, err_sect, err_byte, err_dev,
+                               ecc_sect_size, (u32)err_fix_info);
+                       if (err_byte < ECC_SECTOR_SIZE) {
+                               err_pos = buf +
+                                       (err_page - page) *
+                                       DeviceInfo.wPageDataSize +
+                                       err_sect * ecc_sect_size +
+                                       err_byte *
+                                       DeviceInfo.wDevicesConnected +
+                                       err_dev;
+
+                               *err_pos ^= err_fix_info &
+                                       ERR_CORRECTION_INFO__BYTEMASK;
+                       }
+               }
+       } while (!(err_fix_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
+
+       return status;
+}
+
+u16 NAND_Read_Page_Main_Polling(u8 *read_data,
+               u32 block, u16 page, u16 page_count)
+{
+       u32 status = PASS;
+       u64 flash_add;
+       u32 intr_status = 0;
+       u32 flash_bank;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u8 *read_data_l;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+       if (status != PASS)
+               return status;
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       intr_status = intr_status_addresses[flash_bank];
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       if (page_count > 1) {
+               read_data_l = read_data;
+               while (page_count > MAX_PAGES_PER_RW) {
+                       if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+                               status = NAND_Multiplane_Read(read_data_l,
+                                       block, page, MAX_PAGES_PER_RW);
+                       else
+                               status = NAND_Pipeline_Read_Ahead_Polling(
+                                       read_data_l, block, page,
+                                       MAX_PAGES_PER_RW);
+
+                       if (status == FAIL)
+                               return status;
+
+                       read_data_l += DeviceInfo.wPageDataSize *
+                                       MAX_PAGES_PER_RW;
+                       page_count -= MAX_PAGES_PER_RW;
+                       page += MAX_PAGES_PER_RW;
+               }
+               if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+                       status = NAND_Multiplane_Read(read_data_l,
+                                       block, page, page_count);
+               else
+                       status = NAND_Pipeline_Read_Ahead_Polling(
+                                       read_data_l, block, page, page_count);
+
+               return status;
+       }
+
+       iowrite32(1, FlashReg + DMA_ENABLE);
+       while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       ddma_trans(read_data, flash_add, flash_bank, 0, 1);
+
+       if (enable_ecc) {
+               while (!(ioread32(FlashReg + intr_status) &
+                       (INTR_STATUS0__ECC_TRANSACTION_DONE |
+                       INTR_STATUS0__ECC_ERR)))
+                       ;
+
+               if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__ECC_ERR) {
+                       iowrite32(INTR_STATUS0__ECC_ERR,
+                               FlashReg + intr_status);
+                       status = do_ecc_new(flash_bank, read_data,
+                                       block, page);
+               }
+
+               if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__ECC_TRANSACTION_DONE &
+                       INTR_STATUS0__ECC_ERR)
+                       iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE |
+                               INTR_STATUS0__ECC_ERR,
+                               FlashReg + intr_status);
+               else if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__ECC_TRANSACTION_DONE)
+                       iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+                               FlashReg + intr_status);
+               else if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__ECC_ERR)
+                       iowrite32(INTR_STATUS0__ECC_ERR,
+                               FlashReg + intr_status);
+       } else {
+               while (!(ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__DMA_CMD_COMP))
+                       ;
+               iowrite32(INTR_STATUS0__DMA_CMD_COMP, FlashReg + intr_status);
+       }
+
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(0, FlashReg + DMA_ENABLE);
+       while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       return status;
+}
+
+u16 NAND_Pipeline_Read_Ahead_Polling(u8 *read_data,
+                       u32 block, u16 page, u16 page_count)
+{
+       u32 status = PASS;
+       u32 NumPages = page_count;
+       u64 flash_add;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u32 ecc_done_OR_dma_comp;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+
+       if (page_count < 2)
+               status = FAIL;
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               *DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       if (status == PASS) {
+               intr_status = intr_status_addresses[flash_bank];
+               iowrite32(ioread32(FlashReg + intr_status),
+                       FlashReg + intr_status);
+
+               iowrite32(1, FlashReg + DMA_ENABLE);
+               while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+                       ;
+
+               iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+               index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                       (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+               ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
+
+               ecc_done_OR_dma_comp = 0;
+               while (1) {
+                       if (enable_ecc) {
+                               while (!ioread32(FlashReg + intr_status))
+                                       ;
+
+                               if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_ERR) {
+                                       iowrite32(INTR_STATUS0__ECC_ERR,
+                                               FlashReg + intr_status);
+                                       status = do_ecc_new(flash_bank,
+                                               read_data, block, page);
+                               } else if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__DMA_CMD_COMP) {
+                                       iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                                               FlashReg + intr_status);
+
+                                       if (1 == ecc_done_OR_dma_comp)
+                                               break;
+
+                                       ecc_done_OR_dma_comp = 1;
+                               } else if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE) {
+                                       iowrite32(
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE,
+                                       FlashReg + intr_status);
+
+                                       if (1 == ecc_done_OR_dma_comp)
+                                               break;
+
+                                       ecc_done_OR_dma_comp = 1;
+                               }
+                       } else {
+                               while (!(ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__DMA_CMD_COMP))
+                                       ;
+
+                               iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                                       FlashReg + intr_status);
+                               break;
+                       }
+
+                       iowrite32((~INTR_STATUS0__ECC_ERR) &
+                               (~INTR_STATUS0__ECC_TRANSACTION_DONE) &
+                               (~INTR_STATUS0__DMA_CMD_COMP),
+                               FlashReg + intr_status);
+
+               }
+
+               iowrite32(ioread32(FlashReg + intr_status),
+                       FlashReg + intr_status);
+
+               iowrite32(0, FlashReg + DMA_ENABLE);
+
+               while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+                       ;
+       }
+       return status;
+}
+
+u16 NAND_Read_Page_Main(u8 *read_data, u32 block, u16 page,
+                          u16 page_count)
+{
+       u32 status = PASS;
+       u64 flash_add;
+       u32 intr_status = 0;
+       u32 flash_bank;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       int ret;
+       u8 *read_data_l;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+       if (status != PASS)
+               return status;
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       intr_status = intr_status_addresses[flash_bank];
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       if (page_count > 1) {
+               read_data_l = read_data;
+               while (page_count > MAX_PAGES_PER_RW) {
+                       if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+                               status = NAND_Multiplane_Read(read_data_l,
+                                       block, page, MAX_PAGES_PER_RW);
+                       else
+                               status = NAND_Pipeline_Read_Ahead(
+                                       read_data_l, block, page,
+                                       MAX_PAGES_PER_RW);
+
+                       if (status == FAIL)
+                               return status;
+
+                       read_data_l += DeviceInfo.wPageDataSize *
+                                       MAX_PAGES_PER_RW;
+                       page_count -= MAX_PAGES_PER_RW;
+                       page += MAX_PAGES_PER_RW;
+               }
+               if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+                       status = NAND_Multiplane_Read(read_data_l,
+                                       block, page, page_count);
+               else
+                       status = NAND_Pipeline_Read_Ahead(
+                                       read_data_l, block, page, page_count);
+
+               return status;
+       }
+
+       iowrite32(1, FlashReg + DMA_ENABLE);
+       while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       /* Fill the mrst_nand_info structure */
+       info.state = INT_READ_PAGE_MAIN;
+       info.read_data = read_data;
+       info.flash_bank = flash_bank;
+       info.block = block;
+       info.page = page;
+       info.ret = PASS;
+
+       ddma_trans(read_data, flash_add, flash_bank, 0, 1);
+
+       iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable Interrupt */
+
+       ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+       if (!ret) {
+               printk(KERN_ERR "Wait for completion timeout "
+                       "in %s, Line %d\n", __FILE__, __LINE__);
+               status = ERR;
+       } else {
+               status = info.ret;
+       }
+
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(0, FlashReg + DMA_ENABLE);
+       while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       return status;
+}
+
+void Conv_Spare_Data_Log2Phy_Format(u8 *data)
+{
+       int i;
+       const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+       const u32 PageSpareSize  = DeviceInfo.wPageSpareSize;
+
+       if (enable_ecc) {
+               for (i = spareFlagBytes - 1; i >= 0; i++)
+                       data[PageSpareSize - spareFlagBytes + i] = data[i];
+       }
+}
+
+void Conv_Spare_Data_Phy2Log_Format(u8 *data)
+{
+       int i;
+       const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+       const u32 PageSpareSize = DeviceInfo.wPageSpareSize;
+
+       if (enable_ecc) {
+               for (i = 0; i < spareFlagBytes; i++)
+                       data[i] = data[PageSpareSize - spareFlagBytes + i];
+       }
+}
+
+
+void Conv_Main_Spare_Data_Log2Phy_Format(u8 *data, u16 page_count)
+{
+       const u32 PageSize = DeviceInfo.wPageSize;
+       const u32 PageDataSize = DeviceInfo.wPageDataSize;
+       const u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+       const u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
+       const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+       u32 eccSectorSize;
+       u32 page_offset;
+       int i, j;
+
+       eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+       if (enable_ecc) {
+               while (page_count > 0) {
+                       page_offset = (page_count - 1) * PageSize;
+                       j = (DeviceInfo.wPageDataSize / eccSectorSize);
+                       for (i = spareFlagBytes - 1; i >= 0; i--)
+                               data[page_offset +
+                                       (eccSectorSize + eccBytes) * j + i] =
+                                       data[page_offset + PageDataSize + i];
+                       for (j--; j >= 1; j--) {
+                               for (i = eccSectorSize - 1; i >= 0; i--)
+                                       data[page_offset +
+                                       (eccSectorSize + eccBytes) * j + i] =
+                                               data[page_offset +
+                                               eccSectorSize * j + i];
+                       }
+                       for (i = (PageSize - spareSkipBytes) - 1;
+                               i >= PageDataSize; i--)
+                               data[page_offset + i + spareSkipBytes] =
+                                       data[page_offset + i];
+                       page_count--;
+               }
+       }
+}
+
+void Conv_Main_Spare_Data_Phy2Log_Format(u8 *data, u16 page_count)
+{
+       const u32 PageSize = DeviceInfo.wPageSize;
+       const u32 PageDataSize = DeviceInfo.wPageDataSize;
+       const u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+       const u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
+       const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+       u32 eccSectorSize;
+       u32 page_offset;
+       int i, j;
+
+       eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+       if (enable_ecc) {
+               while (page_count > 0) {
+                       page_offset = (page_count - 1) * PageSize;
+                       for (i = PageDataSize;
+                               i < PageSize - spareSkipBytes;
+                               i++)
+                               data[page_offset + i] =
+                                       data[page_offset + i +
+                                       spareSkipBytes];
+                       for (j = 1;
+                       j < DeviceInfo.wPageDataSize / eccSectorSize;
+                       j++) {
+                               for (i = 0; i < eccSectorSize; i++)
+                                       data[page_offset +
+                                       eccSectorSize * j + i] =
+                                               data[page_offset +
+                                               (eccSectorSize + eccBytes) * j
+                                               + i];
+                       }
+                       for (i = 0; i < spareFlagBytes; i++)
+                               data[page_offset + PageDataSize + i] =
+                                       data[page_offset +
+                                       (eccSectorSize + eccBytes) * j + i];
+                       page_count--;
+               }
+       }
+}
+
+/* Un-tested function */
+u16 NAND_Multiplane_Read(u8 *read_data, u32 block, u16 page,
+                           u16 page_count)
+{
+       u32 status = PASS;
+       u32 NumPages = page_count;
+       u64 flash_add;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u32 ecc_done_OR_dma_comp;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       if (status == PASS) {
+               intr_status = intr_status_addresses[flash_bank];
+               iowrite32(ioread32(FlashReg + intr_status),
+                       FlashReg + intr_status);
+
+               iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+               iowrite32(0x01, FlashReg + MULTIPLANE_OPERATION);
+
+               iowrite32(1, FlashReg + DMA_ENABLE);
+               while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+                       ;
+               index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                       (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+               ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
+
+               ecc_done_OR_dma_comp = 0;
+               while (1) {
+                       if (enable_ecc) {
+                               while (!ioread32(FlashReg + intr_status))
+                                       ;
+
+                               if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_ERR) {
+                                       iowrite32(INTR_STATUS0__ECC_ERR,
+                                               FlashReg + intr_status);
+                                       status = do_ecc_new(flash_bank,
+                                               read_data, block, page);
+                               } else if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__DMA_CMD_COMP) {
+                                       iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                                               FlashReg + intr_status);
+
+                                       if (1 == ecc_done_OR_dma_comp)
+                                               break;
+
+                                       ecc_done_OR_dma_comp = 1;
+                               } else if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE) {
+                                       iowrite32(
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE,
+                                       FlashReg + intr_status);
+
+                                       if (1 == ecc_done_OR_dma_comp)
+                                               break;
+
+                                       ecc_done_OR_dma_comp = 1;
+                               }
+                       } else {
+                               while (!(ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__DMA_CMD_COMP))
+                                       ;
+                               iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                                       FlashReg + intr_status);
+                               break;
+                       }
+
+                       iowrite32((~INTR_STATUS0__ECC_ERR) &
+                               (~INTR_STATUS0__ECC_TRANSACTION_DONE) &
+                               (~INTR_STATUS0__DMA_CMD_COMP),
+                               FlashReg + intr_status);
+
+               }
+
+               iowrite32(ioread32(FlashReg + intr_status),
+                       FlashReg + intr_status);
+
+               iowrite32(0, FlashReg + DMA_ENABLE);
+
+               while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+                       ;
+
+               iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
+       }
+
+       return status;
+}
+
+u16 NAND_Pipeline_Read_Ahead(u8 *read_data, u32 block,
+                               u16 page, u16 page_count)
+{
+       u32 status = PASS;
+       u32 NumPages = page_count;
+       u64 flash_add;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       int ret;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+
+       if (page_count < 2)
+               status = FAIL;
+
+       if (status != PASS)
+               return status;
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               *DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       intr_status = intr_status_addresses[flash_bank];
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(1, FlashReg + DMA_ENABLE);
+       while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       /* Fill the mrst_nand_info structure */
+       info.state = INT_PIPELINE_READ_AHEAD;
+       info.read_data = read_data;
+       info.flash_bank = flash_bank;
+       info.block = block;
+       info.page = page;
+       info.ret = PASS;
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+       ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
+
+       iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable Interrupt */
+
+       ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+       if (!ret) {
+               printk(KERN_ERR "Wait for completion timeout "
+                       "in %s, Line %d\n", __FILE__, __LINE__);
+               status = ERR;
+       } else {
+               status = info.ret;
+       }
+
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(0, FlashReg + DMA_ENABLE);
+
+       while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       return status;
+}
+
+
+u16 NAND_Write_Page_Main(u8 *write_data, u32 block, u16 page,
+                           u16 page_count)
+{
+       u32 status = PASS;
+       u64 flash_add;
+       u32 intr_status = 0;
+       u32 flash_bank;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       int ret;
+       u8 *write_data_l;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+       if (status != PASS)
+               return status;
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       intr_status = intr_status_addresses[flash_bank];
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       iowrite32(INTR_STATUS0__PROGRAM_COMP |
+               INTR_STATUS0__PROGRAM_FAIL, FlashReg + intr_status);
+
+       if (page_count > 1) {
+               write_data_l = write_data;
+               while (page_count > MAX_PAGES_PER_RW) {
+                       if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+                               status = NAND_Multiplane_Write(write_data_l,
+                                       block, page, MAX_PAGES_PER_RW);
+                       else
+                               status = NAND_Pipeline_Write_Ahead(
+                                       write_data_l, block, page,
+                                       MAX_PAGES_PER_RW);
+                       if (status == FAIL)
+                               return status;
+
+                       write_data_l += DeviceInfo.wPageDataSize *
+                                       MAX_PAGES_PER_RW;
+                       page_count -= MAX_PAGES_PER_RW;
+                       page += MAX_PAGES_PER_RW;
+               }
+               if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+                       status = NAND_Multiplane_Write(write_data_l,
+                               block, page, page_count);
+               else
+                       status = NAND_Pipeline_Write_Ahead(write_data_l,
+                               block, page, page_count);
+
+               return status;
+       }
+
+       iowrite32(1, FlashReg + DMA_ENABLE);
+       while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       /* Fill the mrst_nand_info structure */
+       info.state = INT_WRITE_PAGE_MAIN;
+       info.write_data = write_data;
+       info.flash_bank = flash_bank;
+       info.block = block;
+       info.page = page;
+       info.ret = PASS;
+
+       ddma_trans(write_data, flash_add, flash_bank, 1, 1);
+
+       iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable interrupt */
+
+       ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+       if (!ret) {
+               printk(KERN_ERR "Wait for completion timeout "
+                       "in %s, Line %d\n", __FILE__, __LINE__);
+               status = ERR;
+       } else {
+               status = info.ret;
+       }
+
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(0, FlashReg + DMA_ENABLE);
+       while (ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG)
+               ;
+
+       return status;
+}
+
+void NAND_ECC_Ctrl(int enable)
+{
+       if (enable) {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Will enable ECC in %s, Line %d, Function: %s\n",
+                       __FILE__, __LINE__, __func__);
+               iowrite32(1, FlashReg + ECC_ENABLE);
+               enable_ecc = 1;
+       } else {
+               nand_dbg_print(NAND_DBG_WARN,
+                       "Will disable ECC in %s, Line %d, Function: %s\n",
+                       __FILE__, __LINE__, __func__);
+               iowrite32(0, FlashReg + ECC_ENABLE);
+               enable_ecc = 0;
+       }
+}
+
+u16 NAND_Write_Page_Main_Spare(u8 *write_data, u32 block,
+                                       u16 page, u16 page_count)
+{
+       u32 status = PASS;
+       u32 i, j, page_num = 0;
+       u32 PageSize = DeviceInfo.wPageSize;
+       u32 PageDataSize = DeviceInfo.wPageDataSize;
+       u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+       u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+       u32 spareSkipBytes  = DeviceInfo.wSpareSkipBytes;
+       u64 flash_add;
+       u32 eccSectorSize;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u8 *page_main_spare = buf_write_page_main_spare;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       if (status == PASS) {
+               intr_status = intr_status_addresses[flash_bank];
+
+               iowrite32(1, FlashReg + TRANSFER_SPARE_REG);
+
+               while ((status != FAIL) && (page_count > 0)) {
+                       flash_add = (u64)(block %
+                       (DeviceInfo.wTotalBlocks / totalUsedBanks)) *
+                       DeviceInfo.wBlockDataSize +
+                       (u64)page * DeviceInfo.wPageDataSize;
+
+                       iowrite32(ioread32(FlashReg + intr_status),
+                               FlashReg + intr_status);
+
+                       iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+                               (flash_add >>
+                               DeviceInfo.nBitsInPageDataSize)),
+                               FlashMem);
+
+                       if (enable_ecc) {
+                               for (j = 0;
+                                    j <
+                                    DeviceInfo.wPageDataSize / eccSectorSize;
+                                    j++) {
+                                       for (i = 0; i < eccSectorSize; i++)
+                                               page_main_spare[(eccSectorSize +
+                                                                eccBytes) * j +
+                                                               i] =
+                                                   write_data[eccSectorSize *
+                                                              j + i];
+
+                                       for (i = 0; i < eccBytes; i++)
+                                               page_main_spare[(eccSectorSize +
+                                                                eccBytes) * j +
+                                                               eccSectorSize +
+                                                               i] =
+                                                   write_data[PageDataSize +
+                                                              spareFlagBytes +
+                                                              eccBytes * j +
+                                                              i];
+                               }
+
+                               for (i = 0; i < spareFlagBytes; i++)
+                                       page_main_spare[(eccSectorSize +
+                                                        eccBytes) * j + i] =
+                                           write_data[PageDataSize + i];
+
+                               for (i = PageSize - 1; i >= PageDataSize +
+                                                       spareSkipBytes; i--)
+                                       page_main_spare[i] = page_main_spare[i -
+                                                               spareSkipBytes];
+
+                               for (i = PageDataSize; i < PageDataSize +
+                                                       spareSkipBytes; i++)
+                                       page_main_spare[i] = 0xff;
+
+                               for (i = 0; i < PageSize / 4; i++)
+                                       iowrite32(
+                                       *((u32 *)page_main_spare + i),
+                                       FlashMem + 0x10);
+                       } else {
+
+                               for (i = 0; i < PageSize / 4; i++)
+                                       iowrite32(*((u32 *)write_data + i),
+                                               FlashMem + 0x10);
+                       }
+
+                       while (!(ioread32(FlashReg + intr_status) &
+                               (INTR_STATUS0__PROGRAM_COMP |
+                               INTR_STATUS0__PROGRAM_FAIL)))
+                               ;
+
+                       if (ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__PROGRAM_FAIL)
+                               status = FAIL;
+
+                       iowrite32(ioread32(FlashReg + intr_status),
+                                       FlashReg + intr_status);
+
+                       page_num++;
+                       page_count--;
+                       write_data += PageSize;
+               }
+
+               iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+       }
+
+       return status;
+}
+
+u16 NAND_Read_Page_Main_Spare(u8 *read_data, u32 block, u16 page,
+                                u16 page_count)
+{
+       u32 status = PASS;
+       u32 i, j;
+       u64 flash_add = 0;
+       u32 PageSize = DeviceInfo.wPageSize;
+       u32 PageDataSize = DeviceInfo.wPageDataSize;
+       u32 PageSpareSize = DeviceInfo.wPageSpareSize;
+       u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+       u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+       u32 spareSkipBytes  = DeviceInfo.wSpareSkipBytes;
+       u32 eccSectorSize;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u8 *read_data_l = read_data;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u8 *page_main_spare = buf_read_page_main_spare;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       if (status == PASS) {
+               intr_status = intr_status_addresses[flash_bank];
+
+               iowrite32(1, FlashReg + TRANSFER_SPARE_REG);
+
+               iowrite32(ioread32(FlashReg + intr_status),
+                               FlashReg + intr_status);
+
+               while ((status != FAIL) && (page_count > 0)) {
+                       flash_add = (u64)(block %
+                               (DeviceInfo.wTotalBlocks / totalUsedBanks))
+                               * DeviceInfo.wBlockDataSize +
+                               (u64)page * DeviceInfo.wPageDataSize;
+
+                       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                               (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+                               0x43);
+                       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+                               (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+                               0x2000 | page_count);
+
+                       while (!(ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__LOAD_COMP))
+                               ;
+
+                       iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+                               (flash_add >>
+                               DeviceInfo.nBitsInPageDataSize)),
+                               FlashMem);
+
+                       for (i = 0; i < PageSize / 4; i++)
+                               *(((u32 *)page_main_spare) + i) =
+                                       ioread32(FlashMem + 0x10);
+
+                       if (enable_ecc) {
+                               for (i = PageDataSize;  i < PageSize -
+                                                       spareSkipBytes; i++)
+                                       page_main_spare[i] = page_main_spare[i +
+                                                               spareSkipBytes];
+
+                               for (j = 0;
+                               j < DeviceInfo.wPageDataSize / eccSectorSize;
+                               j++) {
+
+                                       for (i = 0; i < eccSectorSize; i++)
+                                               read_data_l[eccSectorSize * j +
+                                                           i] =
+                                                   page_main_spare[
+                                                       (eccSectorSize +
+                                                       eccBytes) * j + i];
+
+                                       for (i = 0; i < eccBytes; i++)
+                                               read_data_l[PageDataSize +
+                                                           spareFlagBytes +
+                                                           eccBytes * j + i] =
+                                                   page_main_spare[
+                                                       (eccSectorSize +
+                                                       eccBytes) * j +
+                                                       eccSectorSize + i];
+                               }
+
+                               for (i = 0; i < spareFlagBytes; i++)
+                                       read_data_l[PageDataSize + i] =
+                                           page_main_spare[(eccSectorSize +
+                                                            eccBytes) * j + i];
+                       } else {
+                               for (i = 0; i < (PageDataSize + PageSpareSize);
+                                    i++)
+                                       read_data_l[i] = page_main_spare[i];
+
+                       }
+
+                       if (enable_ecc) {
+                               while (!(ioread32(FlashReg + intr_status) &
+                                       (INTR_STATUS0__ECC_TRANSACTION_DONE |
+                                       INTR_STATUS0__ECC_ERR)))
+                                       ;
+
+                               if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_ERR) {
+                                       iowrite32(INTR_STATUS0__ECC_ERR,
+                                               FlashReg + intr_status);
+                                       status = do_ecc_new(flash_bank,
+                                               read_data, block, page);
+                               }
+
+                               if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE &
+                                       INTR_STATUS0__ECC_ERR) {
+                                       iowrite32(INTR_STATUS0__ECC_ERR |
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE,
+                                       FlashReg + intr_status);
+                               } else if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE) {
+                                       iowrite32(
+                                       INTR_STATUS0__ECC_TRANSACTION_DONE,
+                                       FlashReg + intr_status);
+                               } else if (ioread32(FlashReg + intr_status) &
+                                       INTR_STATUS0__ECC_ERR) {
+                                       iowrite32(INTR_STATUS0__ECC_ERR,
+                                               FlashReg + intr_status);
+                               }
+                       }
+
+                       page++;
+                       page_count--;
+                       read_data_l += PageSize;
+               }
+       }
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+       return status;
+}
+
+u16 NAND_Pipeline_Write_Ahead(u8 *write_data, u32 block,
+                       u16 page, u16 page_count)
+{
+       u16 status = PASS;
+       u32 NumPages = page_count;
+       u64 flash_add;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       int ret;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+
+       if (page_count < 2)
+               status = FAIL;
+
+       if (status != PASS)
+               return status;
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       intr_status = intr_status_addresses[flash_bank];
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(1, FlashReg + DMA_ENABLE);
+       while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       /* Fill the mrst_nand_info structure */
+       info.state = INT_PIPELINE_WRITE_AHEAD;
+       info.write_data = write_data;
+       info.flash_bank = flash_bank;
+       info.block = block;
+       info.page = page;
+       info.ret = PASS;
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+       ddma_trans(write_data, flash_add, flash_bank, 1, NumPages);
+
+       iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable interrupt */
+
+       ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+       if (!ret) {
+               printk(KERN_ERR "Wait for completion timeout "
+                       "in %s, Line %d\n", __FILE__, __LINE__);
+               status = ERR;
+       } else {
+               status = info.ret;
+       }
+
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(0, FlashReg + DMA_ENABLE);
+       while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       return status;
+}
+
+/* Un-tested function */
+u16 NAND_Multiplane_Write(u8 *write_data, u32 block, u16 page,
+                            u16 page_count)
+{
+       u16 status = PASS;
+       u32 NumPages = page_count;
+       u64 flash_add;
+       u32 flash_bank;
+       u32 intr_status = 0;
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u16 status2 = PASS;
+       u32 t;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       status = Boundary_Check_Block_Page(block, page, page_count);
+       if (status != PASS)
+               return status;
+
+       flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+               * DeviceInfo.wBlockDataSize +
+               (u64)page * DeviceInfo.wPageDataSize;
+
+       flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+       intr_status = intr_status_addresses[flash_bank];
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+       iowrite32(0x01, FlashReg + MULTIPLANE_OPERATION);
+
+       iowrite32(1, FlashReg + DMA_ENABLE);
+       while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+       index_addr((u32)(MODE_10 | (flash_bank << 24) |
+               (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+       ddma_trans(write_data, flash_add, flash_bank, 1, NumPages);
+
+       while (1) {
+               while (!ioread32(FlashReg + intr_status))
+                       ;
+
+               if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__DMA_CMD_COMP) {
+                       iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                               FlashReg + intr_status);
+                       status = PASS;
+                       if (status2 == FAIL)
+                               status = FAIL;
+                       break;
+               } else if (ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__PROGRAM_FAIL) {
+                       status2 = FAIL;
+                       status = FAIL;
+                       t = ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__PROGRAM_FAIL;
+                       iowrite32(t, FlashReg + intr_status);
+               } else {
+                       iowrite32((~INTR_STATUS0__PROGRAM_FAIL) &
+                               (~INTR_STATUS0__DMA_CMD_COMP),
+                               FlashReg + intr_status);
+               }
+       }
+
+       iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+       iowrite32(0, FlashReg + DMA_ENABLE);
+
+       while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+               ;
+
+       iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
+
+       return status;
+}
+
+
+#if CMD_DMA
+static irqreturn_t cdma_isr(int irq, void *dev_id)
+{
+       struct mrst_nand_info *dev = dev_id;
+       int first_failed_cmd;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       if (!is_cdma_interrupt())
+               return IRQ_NONE;
+
+       /* Disable controller interrupts */
+       iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+       GLOB_FTL_Event_Status(&first_failed_cmd);
+       complete(&dev->complete);
+
+       return IRQ_HANDLED;
+}
+#else
+static void handle_nand_int_read(struct mrst_nand_info *dev)
+{
+       u32 intr_status_addresses[4] = {INTR_STATUS0,
+               INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+       u32 intr_status;
+       u32 ecc_done_OR_dma_comp = 0;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       dev->ret = PASS;
+       intr_status = intr_status_addresses[dev->flash_bank];
+
+       while (1) {
+               if (enable_ecc) {
+                       if (ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__ECC_ERR) {
+                               iowrite32(INTR_STATUS0__ECC_ERR,
+                                       FlashReg + intr_status);
+                               dev->ret = do_ecc_new(dev->flash_bank,
+                                               dev->read_data,
+                                               dev->block, dev->page);
+                       } else if (ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__DMA_CMD_COMP) {
+                               iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                                       FlashReg + intr_status);
+                               if (1 == ecc_done_OR_dma_comp)
+                                       break;
+                               ecc_done_OR_dma_comp = 1;
+                       } else if (ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__ECC_TRANSACTION_DONE) {
+                               iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+                                       FlashReg + intr_status);
+                               if (1 == ecc_done_OR_dma_comp)
+                                       break;
+                               ecc_done_OR_dma_comp = 1;
+                       }
+               } else {
+                       if (ioread32(FlashReg + intr_status) &
+                               INTR_STATUS0__DMA_CMD_COMP) {
+                               iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                                       FlashReg + intr_status);
+                               break;
+                       } else {
+                               printk(KERN_ERR "Illegal INTS "
+                                       "(offset addr 0x%x) value: 0x%x\n",
+                                       intr_status,
+                                       ioread32(FlashReg + intr_status));
+                       }
+               }
+
+               iowrite32((~INTR_STATUS0__ECC_ERR) &
+               (~INTR_STATUS0__ECC_TRANSACTION_DONE) &
+               (~INTR_STATUS0__DMA_CMD_COMP),
+               FlashReg + intr_status);
+       }
+}
+
+static void handle_nand_int_write(struct mrst_nand_info *dev)
+{
+       u32 intr_status;
+       u32 intr[4] = {INTR_STATUS0, INTR_STATUS1,
+               INTR_STATUS2, INTR_STATUS3};
+       int status = PASS;
+
+       nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       dev->ret = PASS;
+       intr_status = intr[dev->flash_bank];
+
+       while (1) {
+               while (!ioread32(FlashReg + intr_status))
+                       ;
+
+               if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__DMA_CMD_COMP) {
+                       iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+                               FlashReg + intr_status);
+                       if (FAIL == status)
+                               dev->ret = FAIL;
+                       break;
+               } else if (ioread32(FlashReg + intr_status) &
+                       INTR_STATUS0__PROGRAM_FAIL) {
+                       status = FAIL;
+                       iowrite32(INTR_STATUS0__PROGRAM_FAIL,
+                               FlashReg + intr_status);
+               } else {
+                       iowrite32((~INTR_STATUS0__PROGRAM_FAIL) &
+                               (~INTR_STATUS0__DMA_CMD_COMP),
+                               FlashReg + intr_status);
+               }
+       }
+}
+
+static irqreturn_t ddma_isr(int irq, void *dev_id)
+{
+       struct mrst_nand_info *dev = dev_id;
+       u32 int_mask, ints0, ints1, ints2, ints3, ints_offset;
+       u32 intr[4] = {INTR_STATUS0, INTR_STATUS1,
+               INTR_STATUS2, INTR_STATUS3};
+
+       int_mask = INTR_STATUS0__DMA_CMD_COMP |
+               INTR_STATUS0__ECC_TRANSACTION_DONE |
+               INTR_STATUS0__ECC_ERR |
+               INTR_STATUS0__PROGRAM_FAIL |
+               INTR_STATUS0__ERASE_FAIL;
+
+       ints0 = ioread32(FlashReg + INTR_STATUS0);
+       ints1 = ioread32(FlashReg + INTR_STATUS1);
+       ints2 = ioread32(FlashReg + INTR_STATUS2);
+       ints3 = ioread32(FlashReg + INTR_STATUS3);
+
+       ints_offset = intr[dev->flash_bank];
+
+       nand_dbg_print(NAND_DBG_DEBUG,
+               "INTR0: 0x%x, INTR1: 0x%x, INTR2: 0x%x, INTR3: 0x%x, "
+               "DMA_INTR: 0x%x, "
+               "dev->state: 0x%x, dev->flash_bank: %d\n",
+               ints0, ints1, ints2, ints3,
+               ioread32(FlashReg + DMA_INTR),
+               dev->state, dev->flash_bank);
+
+       if (!(ioread32(FlashReg + ints_offset) & int_mask)) {
+               iowrite32(ints0, FlashReg + INTR_STATUS0);
+               iowrite32(ints1, FlashReg + INTR_STATUS1);
+               iowrite32(ints2, FlashReg + INTR_STATUS2);
+               iowrite32(ints3, FlashReg + INTR_STATUS3);
+               nand_dbg_print(NAND_DBG_WARN,
+                       "ddma_isr: Invalid interrupt for NAND controller. "
+                       "Ignore it\n");
+               return IRQ_NONE;
+       }
+
+       switch (dev->state) {
+       case INT_READ_PAGE_MAIN:
+       case INT_PIPELINE_READ_AHEAD:
+               /* Disable controller interrupts */
+               iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+               handle_nand_int_read(dev);
+               break;
+       case INT_WRITE_PAGE_MAIN:
+       case INT_PIPELINE_WRITE_AHEAD:
+               iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+               handle_nand_int_write(dev);
+               break;
+       default:
+               printk(KERN_ERR "ddma_isr - Illegal state: 0x%x\n",
+                       dev->state);
+               return IRQ_NONE;
+       }
+
+       dev->state = INT_IDLE_STATE;
+       complete(&dev->complete);
+       return IRQ_HANDLED;
+}
+#endif
+
+static const struct pci_device_id nand_pci_ids[] = {
+       {
+        .vendor = 0x8086,
+        .device = 0x0809,
+        .subvendor = PCI_ANY_ID,
+        .subdevice = PCI_ANY_ID,
+        },
+       { /* end: all zeroes */ }
+};
+
+static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+       int ret = -ENODEV;
+       unsigned long csr_base;
+       unsigned long csr_len;
+       struct mrst_nand_info *pndev = &info;
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       ret = pci_enable_device(dev);
+       if (ret) {
+               printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
+               return ret;
+       }
+
+       pci_set_master(dev);
+       pndev->dev = dev;
+
+       csr_base = pci_resource_start(dev, 0);
+       if (!csr_base) {
+               printk(KERN_ERR "Spectra: pci_resource_start failed!\n");
+               return -ENODEV;
+       }
+
+       csr_len = pci_resource_len(dev, 0);
+       if (!csr_len) {
+               printk(KERN_ERR "Spectra: pci_resource_len failed!\n");
+               return -ENODEV;
+       }
+
+       ret = pci_request_regions(dev, SPECTRA_NAND_NAME);
+       if (ret) {
+               printk(KERN_ERR "Spectra: Unable to request "
+                      "memory region\n");
+               goto failed_req_csr;
+       }
+
+       pndev->ioaddr = ioremap_nocache(csr_base, csr_len);
+       if (!pndev->ioaddr) {
+               printk(KERN_ERR "Spectra: Unable to remap memory region\n");
+               ret = -ENOMEM;
+               goto failed_remap_csr;
+       }
+       nand_dbg_print(NAND_DBG_DEBUG, "Spectra: CSR 0x%08lx -> 0x%p (0x%lx)\n",
+                      csr_base, pndev->ioaddr, csr_len);
+
+       init_completion(&pndev->complete);
+       nand_dbg_print(NAND_DBG_DEBUG, "Spectra: IRQ %d\n", dev->irq);
+
+#if CMD_DMA
+       if (request_irq(dev->irq, cdma_isr, IRQF_SHARED,
+                       SPECTRA_NAND_NAME, &info)) {
+               printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
+               ret = -ENODEV;
+               iounmap(pndev->ioaddr);
+               goto failed_remap_csr;
+       }
+#else
+       if (request_irq(dev->irq, ddma_isr, IRQF_SHARED,
+                       SPECTRA_NAND_NAME, &info)) {
+               printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
+               ret = -ENODEV;
+               iounmap(pndev->ioaddr);
+               goto failed_remap_csr;
+       }
+#endif
+
+       pci_set_drvdata(dev, pndev);
+
+       return 0;
+
+failed_remap_csr:
+       pci_release_regions(dev);
+failed_req_csr:
+
+       return ret;
+}
+
+static void nand_pci_remove(struct pci_dev *dev)
+{
+       struct mrst_nand_info *pndev = pci_get_drvdata(dev);
+
+       nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+#if CMD_DMA
+       free_irq(dev->irq, pndev);
+#endif
+       iounmap(pndev->ioaddr);
+       pci_release_regions(dev);
+       pci_disable_device(dev);
+}
+
+MODULE_DEVICE_TABLE(pci, nand_pci_ids);
+
+static struct pci_driver nand_pci_driver = {
+       .name = SPECTRA_NAND_NAME,
+       .id_table = nand_pci_ids,
+       .probe = nand_pci_probe,
+       .remove = nand_pci_remove,
+};
+
+int NAND_Flash_Init(void)
+{
+       int retval;
+       u32 int_mask;
+
+       nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+                      __FILE__, __LINE__, __func__);
+
+       FlashReg = ioremap_nocache(GLOB_HWCTL_REG_BASE,
+                       GLOB_HWCTL_REG_SIZE);
+       if (!FlashReg) {
+               printk(KERN_ERR "Spectra: ioremap_nocache failed!");
+               return -ENOMEM;
+       }
+       nand_dbg_print(NAND_DBG_WARN,
+               "Spectra: Remapped reg base address: "
+               "0x%p, len: %d\n",
+               FlashReg, GLOB_HWCTL_REG_SIZE);
+
+       FlashMem = ioremap_nocache(GLOB_HWCTL_MEM_BASE,
+                       GLOB_HWCTL_MEM_SIZE);
+       if (!FlashMem) {
+               printk(KERN_ERR "Spectra: ioremap_nocache failed!");
+               iounmap(FlashReg);
+               return -ENOMEM;
+       }
+       nand_dbg_print(NAND_DBG_WARN,
+               "Spectra: Remapped flash base address: "
+               "0x%p, len: %d\n",
+               (void *)FlashMem, GLOB_HWCTL_MEM_SIZE);
+
+       nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
+                       "acc_clks: %d, re_2_we: %d, we_2_re: %d,"
+                       "addr_2_data: %d, rdwr_en_lo_cnt: %d, "
+                       "rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n",
+                       ioread32(FlashReg + ACC_CLKS),
+                       ioread32(FlashReg + RE_2_WE),
+                       ioread32(FlashReg + WE_2_RE),
+                       ioread32(FlashReg + ADDR_2_DATA),
+                       ioread32(FlashReg + RDWR_EN_LO_CNT),
+                       ioread32(FlashReg + RDWR_EN_HI_CNT),
+                       ioread32(FlashReg + CS_SETUP_CNT));
+
+       NAND_Flash_Reset();
+
+       iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+
+#if CMD_DMA
+       info.pcmds_num = 0;
+       info.flash_bank = 0;
+       info.cdma_num = 0;
+       int_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+               DMA_INTR__DESC_COMP_CHANNEL1 |
+               DMA_INTR__DESC_COMP_CHANNEL2 |
+               DMA_INTR__DESC_COMP_CHANNEL3 |
+               DMA_INTR__MEMCOPY_DESC_COMP);
+       iowrite32(int_mask, FlashReg + DMA_INTR_EN);
+       iowrite32(0xFFFF, FlashReg + DMA_INTR);
+
+       int_mask = (INTR_STATUS0__ECC_ERR |
+               INTR_STATUS0__PROGRAM_FAIL |
+               INTR_STATUS0__ERASE_FAIL);
+#else
+       int_mask = INTR_STATUS0__DMA_CMD_COMP |
+               INTR_STATUS0__ECC_TRANSACTION_DONE |
+               INTR_STATUS0__ECC_ERR |
+               INTR_STATUS0__PROGRAM_FAIL |
+               INTR_STATUS0__ERASE_FAIL;
+#endif
+       iowrite32(int_mask, FlashReg + INTR_EN0);
+       iowrite32(int_mask, FlashReg + INTR_EN1);
+       iowrite32(int_mask, FlashReg + INTR_EN2);
+       iowrite32(int_mask, FlashReg + INTR_EN3);
+
+       /* Clear all status bits */
+       iowrite32(0xFFFF, FlashReg + INTR_STATUS0);
+       iowrite32(0xFFFF, FlashReg + INTR_STATUS1);
+       iowrite32(0xFFFF, FlashReg + INTR_STATUS2);
+       iowrite32(0xFFFF, FlashReg + INTR_STATUS3);
+
+       iowrite32(0x0F, FlashReg + RB_PIN_ENABLED);
+       iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE);
+
+       /* Should set value for these registers when init */
+       iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES);
+       iowrite32(1, FlashReg + ECC_ENABLE);
+       enable_ecc = 1;
+
+       retval = pci_register_driver(&nand_pci_driver);
+       if (retval)
+               return -ENOMEM;
+
+       return PASS;
+}
+
+/* Free memory */
+int nand_release_spectra(void)
+{
+       pci_unregister_driver(&nand_pci_driver);
+       iounmap(FlashMem);
+       iounmap(FlashReg);
+
+       return 0;
+}
+
+
+
diff --git a/drivers/staging/spectra/lld_nand.h b/drivers/staging/spectra/lld_nand.h
new file mode 100644 (file)
index 0000000..d083882
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LLD_NAND_
+#define _LLD_NAND_
+
+#ifdef ELDORA
+#include "defs.h"
+#else
+#include "flash.h"
+#include "ffsport.h"
+#endif
+
+#define MODE_00    0x00000000
+#define MODE_01    0x04000000
+#define MODE_10    0x08000000
+#define MODE_11    0x0C000000
+
+
+#define DATA_TRANSFER_MODE              0
+#define PROTECTION_PER_BLOCK            1
+#define LOAD_WAIT_COUNT                 2
+#define PROGRAM_WAIT_COUNT              3
+#define ERASE_WAIT_COUNT                4
+#define INT_MONITOR_CYCLE_COUNT         5
+#define READ_BUSY_PIN_ENABLED           6
+#define MULTIPLANE_OPERATION_SUPPORT    7
+#define PRE_FETCH_MODE                  8
+#define CE_DONT_CARE_SUPPORT            9
+#define COPYBACK_SUPPORT                10
+#define CACHE_WRITE_SUPPORT             11
+#define CACHE_READ_SUPPORT              12
+#define NUM_PAGES_IN_BLOCK              13
+#define ECC_ENABLE_SELECT               14
+#define WRITE_ENABLE_2_READ_ENABLE      15
+#define ADDRESS_2_DATA                  16
+#define READ_ENABLE_2_WRITE_ENABLE      17
+#define TWO_ROW_ADDRESS_CYCLES          18
+#define MULTIPLANE_ADDRESS_RESTRICT     19
+#define ACC_CLOCKS                      20
+#define READ_WRITE_ENABLE_LOW_COUNT     21
+#define READ_WRITE_ENABLE_HIGH_COUNT    22
+
+#define ECC_SECTOR_SIZE     512
+#define LLD_MAX_FLASH_BANKS     4
+
+struct mrst_nand_info {
+       struct pci_dev *dev;
+       u32 state;
+       u32 flash_bank;
+       u8 *read_data;
+       u8 *write_data;
+       u32 block;
+       u16 page;
+       u32 use_dma;
+       void __iomem *ioaddr;  /* Mapped io reg base address */
+       int ret;
+       u32 pcmds_num;
+       struct pending_cmd *pcmds;
+       int cdma_num;           /* CDMA descriptor number in this chan */
+       u8 *cdma_desc_buf;      /* CDMA descriptor table */
+       u8 *memcp_desc_buf;     /* Memory copy descriptor table */
+       dma_addr_t cdma_desc;   /* Mapped CDMA descriptor table */
+       dma_addr_t memcp_desc;  /* Mapped memory copy descriptor table */
+       struct completion complete;
+};
+
+int NAND_Flash_Init(void);
+int nand_release_spectra(void);
+u16  NAND_Flash_Reset(void);
+u16  NAND_Read_Device_ID(void);
+u16  NAND_Erase_Block(u32 flash_add);
+u16  NAND_Write_Page_Main(u8 *write_data, u32 block, u16 page,
+                               u16 page_count);
+u16  NAND_Read_Page_Main(u8 *read_data, u32 block, u16 page,
+                               u16 page_count);
+u16  NAND_UnlockArrayAll(void);
+u16  NAND_Write_Page_Main_Spare(u8 *write_data, u32 block,
+                               u16 page, u16 page_count);
+u16  NAND_Write_Page_Spare(u8 *read_data, u32 block, u16 page,
+                               u16 page_count);
+u16  NAND_Read_Page_Main_Spare(u8 *read_data, u32 block, u16 page,
+                               u16 page_count);
+u16  NAND_Read_Page_Spare(u8 *read_data, u32 block, u16 page,
+                               u16 page_count);
+void NAND_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE);
+u16  NAND_Get_Bad_Block(u32 block);
+u16  NAND_Pipeline_Read_Ahead(u8 *read_data, u32 block, u16 page,
+                               u16 page_count);
+u16  NAND_Pipeline_Write_Ahead(u8 *write_data, u32 block,
+                               u16 page, u16 page_count);
+u16  NAND_Multiplane_Read(u8 *read_data, u32 block, u16 page,
+                               u16 page_count);
+u16  NAND_Multiplane_Write(u8 *write_data, u32 block, u16 page,
+                               u16 page_count);
+void NAND_ECC_Ctrl(int enable);
+u16 NAND_Read_Page_Main_Polling(u8 *read_data,
+               u32 block, u16 page, u16 page_count);
+u16 NAND_Pipeline_Read_Ahead_Polling(u8 *read_data,
+                       u32 block, u16 page, u16 page_count);
+void Conv_Spare_Data_Log2Phy_Format(u8 *data);
+void Conv_Spare_Data_Phy2Log_Format(u8 *data);
+void Conv_Main_Spare_Data_Log2Phy_Format(u8 *data, u16 page_count);
+void Conv_Main_Spare_Data_Phy2Log_Format(u8 *data, u16 page_count);
+
+extern void __iomem *FlashReg;
+extern void __iomem *FlashMem;
+
+extern int totalUsedBanks;
+extern u32 GLOB_valid_banks[LLD_MAX_FLASH_BANKS];
+
+#endif /*_LLD_NAND_*/
+
+
+
diff --git a/drivers/staging/spectra/nand_regs.h b/drivers/staging/spectra/nand_regs.h
new file mode 100644 (file)
index 0000000..e192e4a
--- /dev/null
@@ -0,0 +1,619 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#define DEVICE_RESET                           0x0
+#define     DEVICE_RESET__BANK0                                0x0001
+#define     DEVICE_RESET__BANK1                                0x0002
+#define     DEVICE_RESET__BANK2                                0x0004
+#define     DEVICE_RESET__BANK3                                0x0008
+
+#define TRANSFER_SPARE_REG                     0x10
+#define     TRANSFER_SPARE_REG__FLAG                   0x0001
+
+#define LOAD_WAIT_CNT                          0x20
+#define     LOAD_WAIT_CNT__VALUE                               0xffff
+
+#define PROGRAM_WAIT_CNT                       0x30
+#define     PROGRAM_WAIT_CNT__VALUE                    0xffff
+
+#define ERASE_WAIT_CNT                         0x40
+#define     ERASE_WAIT_CNT__VALUE                      0xffff
+
+#define INT_MON_CYCCNT                         0x50
+#define     INT_MON_CYCCNT__VALUE                      0xffff
+
+#define RB_PIN_ENABLED                         0x60
+#define     RB_PIN_ENABLED__BANK0                      0x0001
+#define     RB_PIN_ENABLED__BANK1                      0x0002
+#define     RB_PIN_ENABLED__BANK2                      0x0004
+#define     RB_PIN_ENABLED__BANK3                      0x0008
+
+#define MULTIPLANE_OPERATION                   0x70
+#define     MULTIPLANE_OPERATION__FLAG                 0x0001
+
+#define MULTIPLANE_READ_ENABLE                 0x80
+#define     MULTIPLANE_READ_ENABLE__FLAG               0x0001
+
+#define COPYBACK_DISABLE                       0x90
+#define     COPYBACK_DISABLE__FLAG                     0x0001
+
+#define CACHE_WRITE_ENABLE                     0xa0
+#define     CACHE_WRITE_ENABLE__FLAG                   0x0001
+
+#define CACHE_READ_ENABLE                      0xb0
+#define     CACHE_READ_ENABLE__FLAG                    0x0001
+
+#define PREFETCH_MODE                          0xc0
+#define     PREFETCH_MODE__PREFETCH_EN                 0x0001
+#define     PREFETCH_MODE__PREFETCH_BURST_LENGTH       0xfff0
+
+#define CHIP_ENABLE_DONT_CARE                  0xd0
+#define     CHIP_EN_DONT_CARE__FLAG                    0x01
+
+#define ECC_ENABLE                             0xe0
+#define     ECC_ENABLE__FLAG                           0x0001
+
+#define GLOBAL_INT_ENABLE                      0xf0
+#define     GLOBAL_INT_EN_FLAG                         0x01
+
+#define WE_2_RE                                        0x100
+#define     WE_2_RE__VALUE                             0x003f
+
+#define ADDR_2_DATA                            0x110
+#define     ADDR_2_DATA__VALUE                         0x003f
+
+#define RE_2_WE                                        0x120
+#define     RE_2_WE__VALUE                             0x003f
+
+#define ACC_CLKS                               0x130
+#define     ACC_CLKS__VALUE                            0x000f
+
+#define NUMBER_OF_PLANES                       0x140
+#define     NUMBER_OF_PLANES__VALUE                    0x0007
+
+#define PAGES_PER_BLOCK                                0x150
+#define     PAGES_PER_BLOCK__VALUE                     0xffff
+
+#define DEVICE_WIDTH                           0x160
+#define     DEVICE_WIDTH__VALUE                                0x0003
+
+#define DEVICE_MAIN_AREA_SIZE                  0x170
+#define     DEVICE_MAIN_AREA_SIZE__VALUE               0xffff
+
+#define DEVICE_SPARE_AREA_SIZE                 0x180
+#define     DEVICE_SPARE_AREA_SIZE__VALUE              0xffff
+
+#define TWO_ROW_ADDR_CYCLES                    0x190
+#define     TWO_ROW_ADDR_CYCLES__FLAG                  0x0001
+
+#define MULTIPLANE_ADDR_RESTRICT               0x1a0
+#define     MULTIPLANE_ADDR_RESTRICT__FLAG             0x0001
+
+#define ECC_CORRECTION                         0x1b0
+#define     ECC_CORRECTION__VALUE                      0x001f
+
+#define READ_MODE                              0x1c0
+#define     READ_MODE__VALUE                           0x000f
+
+#define WRITE_MODE                             0x1d0
+#define     WRITE_MODE__VALUE                          0x000f
+
+#define COPYBACK_MODE                          0x1e0
+#define     COPYBACK_MODE__VALUE                       0x000f
+
+#define RDWR_EN_LO_CNT                         0x1f0
+#define     RDWR_EN_LO_CNT__VALUE                      0x001f
+
+#define RDWR_EN_HI_CNT                         0x200
+#define     RDWR_EN_HI_CNT__VALUE                      0x001f
+
+#define MAX_RD_DELAY                           0x210
+#define     MAX_RD_DELAY__VALUE                                0x000f
+
+#define CS_SETUP_CNT                           0x220
+#define     CS_SETUP_CNT__VALUE                                0x001f
+
+#define SPARE_AREA_SKIP_BYTES                  0x230
+#define     SPARE_AREA_SKIP_BYTES__VALUE               0x003f
+
+#define SPARE_AREA_MARKER                      0x240
+#define     SPARE_AREA_MARKER__VALUE                   0xffff
+
+#define DEVICES_CONNECTED                      0x250
+#define     DEVICES_CONNECTED__VALUE                   0x0007
+
+#define DIE_MASK                                       0x260
+#define     DIE_MASK__VALUE                            0x00ff
+
+#define FIRST_BLOCK_OF_NEXT_PLANE              0x270
+#define     FIRST_BLOCK_OF_NEXT_PLANE__VALUE           0xffff
+
+#define WRITE_PROTECT                          0x280
+#define     WRITE_PROTECT__FLAG                                0x0001
+
+#define RE_2_RE                                        0x290
+#define     RE_2_RE__VALUE                             0x003f
+
+#define MANUFACTURER_ID                        0x300
+#define     MANUFACTURER_ID__VALUE                     0x00ff
+
+#define DEVICE_ID                              0x310
+#define     DEVICE_ID__VALUE                           0x00ff
+
+#define DEVICE_PARAM_0                         0x320
+#define     DEVICE_PARAM_0__VALUE                      0x00ff
+
+#define DEVICE_PARAM_1                         0x330
+#define     DEVICE_PARAM_1__VALUE                      0x00ff
+
+#define DEVICE_PARAM_2                         0x340
+#define     DEVICE_PARAM_2__VALUE                      0x00ff
+
+#define LOGICAL_PAGE_DATA_SIZE                 0x350
+#define     LOGICAL_PAGE_DATA_SIZE__VALUE              0xffff
+
+#define LOGICAL_PAGE_SPARE_SIZE                        0x360
+#define     LOGICAL_PAGE_SPARE_SIZE__VALUE             0xffff
+
+#define REVISION                                       0x370
+#define     REVISION__VALUE                            0xffff
+
+#define ONFI_DEVICE_FEATURES                   0x380
+#define     ONFI_DEVICE_FEATURES__VALUE                        0x003f
+
+#define ONFI_OPTIONAL_COMMANDS         0x390
+#define     ONFI_OPTIONAL_COMMANDS__VALUE              0x003f
+
+#define ONFI_TIMING_MODE                       0x3a0
+#define     ONFI_TIMING_MODE__VALUE                    0x003f
+
+#define ONFI_PGM_CACHE_TIMING_MODE             0x3b0
+#define     ONFI_PGM_CACHE_TIMING_MODE__VALUE          0x003f
+
+#define ONFI_DEVICE_NO_OF_LUNS                 0x3c0
+#define     ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS         0x00ff
+#define     ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE                0x0100
+
+#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L     0x3d0
+#define     ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L__VALUE  0xffff
+
+#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U     0x3e0
+#define     ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U__VALUE  0xffff
+
+#define FEATURES                                       0x3f0
+#define     FEATURES__N_BANKS                          0x0003
+#define     FEATURES__ECC_MAX_ERR                      0x003c
+#define     FEATURES__DMA                                      0x0040
+#define     FEATURES__CMD_DMA                          0x0080
+#define     FEATURES__PARTITION                                0x0100
+#define     FEATURES__XDMA_SIDEBAND                    0x0200
+#define     FEATURES__GPREG                            0x0400
+#define     FEATURES__INDEX_ADDR                               0x0800
+
+#define TRANSFER_MODE                          0x400
+#define     TRANSFER_MODE__VALUE                       0x0003
+
+#define INTR_STATUS0                           0x410
+#define     INTR_STATUS0__ECC_TRANSACTION_DONE         0x0001
+#define     INTR_STATUS0__ECC_ERR                      0x0002
+#define     INTR_STATUS0__DMA_CMD_COMP                 0x0004
+#define     INTR_STATUS0__TIME_OUT                     0x0008
+#define     INTR_STATUS0__PROGRAM_FAIL                 0x0010
+#define     INTR_STATUS0__ERASE_FAIL                   0x0020
+#define     INTR_STATUS0__LOAD_COMP                    0x0040
+#define     INTR_STATUS0__PROGRAM_COMP                 0x0080
+#define     INTR_STATUS0__ERASE_COMP                   0x0100
+#define     INTR_STATUS0__PIPE_CPYBCK_CMD_COMP         0x0200
+#define     INTR_STATUS0__LOCKED_BLK                   0x0400
+#define     INTR_STATUS0__UNSUP_CMD                    0x0800
+#define     INTR_STATUS0__INT_ACT                      0x1000
+#define     INTR_STATUS0__RST_COMP                     0x2000
+#define     INTR_STATUS0__PIPE_CMD_ERR                 0x4000
+#define     INTR_STATUS0__PAGE_XFER_INC                        0x8000
+
+#define INTR_EN0                                       0x420
+#define     INTR_EN0__ECC_TRANSACTION_DONE             0x0001
+#define     INTR_EN0__ECC_ERR                          0x0002
+#define     INTR_EN0__DMA_CMD_COMP                     0x0004
+#define     INTR_EN0__TIME_OUT                         0x0008
+#define     INTR_EN0__PROGRAM_FAIL                     0x0010
+#define     INTR_EN0__ERASE_FAIL                               0x0020
+#define     INTR_EN0__LOAD_COMP                                0x0040
+#define     INTR_EN0__PROGRAM_COMP                     0x0080
+#define     INTR_EN0__ERASE_COMP                               0x0100
+#define     INTR_EN0__PIPE_CPYBCK_CMD_COMP             0x0200
+#define     INTR_EN0__LOCKED_BLK                               0x0400
+#define     INTR_EN0__UNSUP_CMD                                0x0800
+#define     INTR_EN0__INT_ACT                          0x1000
+#define     INTR_EN0__RST_COMP                         0x2000
+#define     INTR_EN0__PIPE_CMD_ERR                     0x4000
+#define     INTR_EN0__PAGE_XFER_INC                    0x8000
+
+#define PAGE_CNT0                              0x430
+#define     PAGE_CNT0__VALUE                           0x00ff
+
+#define ERR_PAGE_ADDR0                         0x440
+#define     ERR_PAGE_ADDR0__VALUE                      0xffff
+
+#define ERR_BLOCK_ADDR0                        0x450
+#define     ERR_BLOCK_ADDR0__VALUE                     0xffff
+
+#define INTR_STATUS1                           0x460
+#define     INTR_STATUS1__ECC_TRANSACTION_DONE         0x0001
+#define     INTR_STATUS1__ECC_ERR                      0x0002
+#define     INTR_STATUS1__DMA_CMD_COMP                 0x0004
+#define     INTR_STATUS1__TIME_OUT                     0x0008
+#define     INTR_STATUS1__PROGRAM_FAIL                 0x0010
+#define     INTR_STATUS1__ERASE_FAIL                   0x0020
+#define     INTR_STATUS1__LOAD_COMP                    0x0040
+#define     INTR_STATUS1__PROGRAM_COMP                 0x0080
+#define     INTR_STATUS1__ERASE_COMP                   0x0100
+#define     INTR_STATUS1__PIPE_CPYBCK_CMD_COMP         0x0200
+#define     INTR_STATUS1__LOCKED_BLK                   0x0400
+#define     INTR_STATUS1__UNSUP_CMD                    0x0800
+#define     INTR_STATUS1__INT_ACT                      0x1000
+#define     INTR_STATUS1__RST_COMP                     0x2000
+#define     INTR_STATUS1__PIPE_CMD_ERR                 0x4000
+#define     INTR_STATUS1__PAGE_XFER_INC                        0x8000
+
+#define INTR_EN1                                       0x470
+#define     INTR_EN1__ECC_TRANSACTION_DONE             0x0001
+#define     INTR_EN1__ECC_ERR                          0x0002
+#define     INTR_EN1__DMA_CMD_COMP                     0x0004
+#define     INTR_EN1__TIME_OUT                         0x0008
+#define     INTR_EN1__PROGRAM_FAIL                     0x0010
+#define     INTR_EN1__ERASE_FAIL                               0x0020
+#define     INTR_EN1__LOAD_COMP                                0x0040
+#define     INTR_EN1__PROGRAM_COMP                     0x0080
+#define     INTR_EN1__ERASE_COMP                               0x0100
+#define     INTR_EN1__PIPE_CPYBCK_CMD_COMP             0x0200
+#define     INTR_EN1__LOCKED_BLK                               0x0400
+#define     INTR_EN1__UNSUP_CMD                                0x0800
+#define     INTR_EN1__INT_ACT                          0x1000
+#define     INTR_EN1__RST_COMP                         0x2000
+#define     INTR_EN1__PIPE_CMD_ERR                     0x4000
+#define     INTR_EN1__PAGE_XFER_INC                    0x8000
+
+#define PAGE_CNT1                              0x480
+#define     PAGE_CNT1__VALUE                           0x00ff
+
+#define ERR_PAGE_ADDR1                         0x490
+#define     ERR_PAGE_ADDR1__VALUE                      0xffff
+
+#define ERR_BLOCK_ADDR1                        0x4a0
+#define     ERR_BLOCK_ADDR1__VALUE                     0xffff
+
+#define INTR_STATUS2                           0x4b0
+#define     INTR_STATUS2__ECC_TRANSACTION_DONE         0x0001
+#define     INTR_STATUS2__ECC_ERR                      0x0002
+#define     INTR_STATUS2__DMA_CMD_COMP                 0x0004
+#define     INTR_STATUS2__TIME_OUT                     0x0008
+#define     INTR_STATUS2__PROGRAM_FAIL                 0x0010
+#define     INTR_STATUS2__ERASE_FAIL                   0x0020
+#define     INTR_STATUS2__LOAD_COMP                    0x0040
+#define     INTR_STATUS2__PROGRAM_COMP                 0x0080
+#define     INTR_STATUS2__ERASE_COMP                   0x0100
+#define     INTR_STATUS2__PIPE_CPYBCK_CMD_COMP         0x0200
+#define     INTR_STATUS2__LOCKED_BLK                   0x0400
+#define     INTR_STATUS2__UNSUP_CMD                    0x0800
+#define     INTR_STATUS2__INT_ACT                      0x1000
+#define     INTR_STATUS2__RST_COMP                     0x2000
+#define     INTR_STATUS2__PIPE_CMD_ERR                 0x4000
+#define     INTR_STATUS2__PAGE_XFER_INC                        0x8000
+
+#define INTR_EN2                                       0x4c0
+#define     INTR_EN2__ECC_TRANSACTION_DONE             0x0001
+#define     INTR_EN2__ECC_ERR                          0x0002
+#define     INTR_EN2__DMA_CMD_COMP                     0x0004
+#define     INTR_EN2__TIME_OUT                         0x0008
+#define     INTR_EN2__PROGRAM_FAIL                     0x0010
+#define     INTR_EN2__ERASE_FAIL                               0x0020
+#define     INTR_EN2__LOAD_COMP                                0x0040
+#define     INTR_EN2__PROGRAM_COMP                     0x0080
+#define     INTR_EN2__ERASE_COMP                               0x0100
+#define     INTR_EN2__PIPE_CPYBCK_CMD_COMP             0x0200
+#define     INTR_EN2__LOCKED_BLK                               0x0400
+#define     INTR_EN2__UNSUP_CMD                                0x0800
+#define     INTR_EN2__INT_ACT                          0x1000
+#define     INTR_EN2__RST_COMP                         0x2000
+#define     INTR_EN2__PIPE_CMD_ERR                     0x4000
+#define     INTR_EN2__PAGE_XFER_INC                    0x8000
+
+#define PAGE_CNT2                              0x4d0
+#define     PAGE_CNT2__VALUE                           0x00ff
+
+#define ERR_PAGE_ADDR2                         0x4e0
+#define     ERR_PAGE_ADDR2__VALUE                      0xffff
+
+#define ERR_BLOCK_ADDR2                        0x4f0
+#define     ERR_BLOCK_ADDR2__VALUE                     0xffff
+
+#define INTR_STATUS3                           0x500
+#define     INTR_STATUS3__ECC_TRANSACTION_DONE         0x0001
+#define     INTR_STATUS3__ECC_ERR                      0x0002
+#define     INTR_STATUS3__DMA_CMD_COMP                 0x0004
+#define     INTR_STATUS3__TIME_OUT                     0x0008
+#define     INTR_STATUS3__PROGRAM_FAIL                 0x0010
+#define     INTR_STATUS3__ERASE_FAIL                   0x0020
+#define     INTR_STATUS3__LOAD_COMP                    0x0040
+#define     INTR_STATUS3__PROGRAM_COMP                 0x0080
+#define     INTR_STATUS3__ERASE_COMP                   0x0100
+#define     INTR_STATUS3__PIPE_CPYBCK_CMD_COMP         0x0200
+#define     INTR_STATUS3__LOCKED_BLK                   0x0400
+#define     INTR_STATUS3__UNSUP_CMD                    0x0800
+#define     INTR_STATUS3__INT_ACT                      0x1000
+#define     INTR_STATUS3__RST_COMP                     0x2000
+#define     INTR_STATUS3__PIPE_CMD_ERR                 0x4000
+#define     INTR_STATUS3__PAGE_XFER_INC                        0x8000
+
+#define INTR_EN3                                       0x510
+#define     INTR_EN3__ECC_TRANSACTION_DONE             0x0001
+#define     INTR_EN3__ECC_ERR                          0x0002
+#define     INTR_EN3__DMA_CMD_COMP                     0x0004
+#define     INTR_EN3__TIME_OUT                         0x0008
+#define     INTR_EN3__PROGRAM_FAIL                     0x0010
+#define     INTR_EN3__ERASE_FAIL                               0x0020
+#define     INTR_EN3__LOAD_COMP                                0x0040
+#define     INTR_EN3__PROGRAM_COMP                     0x0080
+#define     INTR_EN3__ERASE_COMP                               0x0100
+#define     INTR_EN3__PIPE_CPYBCK_CMD_COMP             0x0200
+#define     INTR_EN3__LOCKED_BLK                               0x0400
+#define     INTR_EN3__UNSUP_CMD                                0x0800
+#define     INTR_EN3__INT_ACT                          0x1000
+#define     INTR_EN3__RST_COMP                         0x2000
+#define     INTR_EN3__PIPE_CMD_ERR                     0x4000
+#define     INTR_EN3__PAGE_XFER_INC                    0x8000
+
+#define PAGE_CNT3                              0x520
+#define     PAGE_CNT3__VALUE                           0x00ff
+
+#define ERR_PAGE_ADDR3                         0x530
+#define     ERR_PAGE_ADDR3__VALUE                      0xffff
+
+#define ERR_BLOCK_ADDR3                        0x540
+#define     ERR_BLOCK_ADDR3__VALUE                     0xffff
+
+#define DATA_INTR                              0x550
+#define     DATA_INTR__WRITE_SPACE_AV                  0x0001
+#define     DATA_INTR__READ_DATA_AV                    0x0002
+
+#define DATA_INTR_EN                           0x560
+#define     DATA_INTR_EN__WRITE_SPACE_AV               0x0001
+#define     DATA_INTR_EN__READ_DATA_AV                 0x0002
+
+#define GPREG_0                                        0x570
+#define     GPREG_0__VALUE                             0xffff
+
+#define GPREG_1                                        0x580
+#define     GPREG_1__VALUE                             0xffff
+
+#define GPREG_2                                        0x590
+#define     GPREG_2__VALUE                             0xffff
+
+#define GPREG_3                                        0x5a0
+#define     GPREG_3__VALUE                             0xffff
+
+#define ECC_THRESHOLD                          0x600
+#define     ECC_THRESHOLD__VALUE                               0x03ff
+
+#define ECC_ERROR_BLOCK_ADDRESS                0x610
+#define     ECC_ERROR_BLOCK_ADDRESS__VALUE             0xffff
+
+#define ECC_ERROR_PAGE_ADDRESS                 0x620
+#define     ECC_ERROR_PAGE_ADDRESS__VALUE              0x0fff
+#define     ECC_ERROR_PAGE_ADDRESS__BANK               0xf000
+
+#define ECC_ERROR_ADDRESS                      0x630
+#define     ECC_ERROR_ADDRESS__OFFSET                  0x0fff
+#define     ECC_ERROR_ADDRESS__SECTOR_NR               0xf000
+
+#define ERR_CORRECTION_INFO                    0x640
+#define     ERR_CORRECTION_INFO__BYTEMASK              0x00ff
+#define     ERR_CORRECTION_INFO__DEVICE_NR             0x0f00
+#define     ERR_CORRECTION_INFO__ERROR_TYPE            0x4000
+#define     ERR_CORRECTION_INFO__LAST_ERR_INFO         0x8000
+
+#define DMA_ENABLE                             0x700
+#define     DMA_ENABLE__FLAG                           0x0001
+
+#define IGNORE_ECC_DONE                                0x710
+#define     IGNORE_ECC_DONE__FLAG                      0x0001
+
+#define DMA_INTR                               0x720
+#define     DMA_INTR__TARGET_ERROR                     0x0001
+#define     DMA_INTR__DESC_COMP_CHANNEL0               0x0002
+#define     DMA_INTR__DESC_COMP_CHANNEL1               0x0004
+#define     DMA_INTR__DESC_COMP_CHANNEL2               0x0008
+#define     DMA_INTR__DESC_COMP_CHANNEL3               0x0010
+#define     DMA_INTR__MEMCOPY_DESC_COMP                0x0020
+
+#define DMA_INTR_EN                            0x730
+#define     DMA_INTR_EN__TARGET_ERROR                  0x0001
+#define     DMA_INTR_EN__DESC_COMP_CHANNEL0            0x0002
+#define     DMA_INTR_EN__DESC_COMP_CHANNEL1            0x0004
+#define     DMA_INTR_EN__DESC_COMP_CHANNEL2            0x0008
+#define     DMA_INTR_EN__DESC_COMP_CHANNEL3            0x0010
+#define     DMA_INTR_EN__MEMCOPY_DESC_COMP             0x0020
+
+#define TARGET_ERR_ADDR_LO                     0x740
+#define     TARGET_ERR_ADDR_LO__VALUE                  0xffff
+
+#define TARGET_ERR_ADDR_HI                     0x750
+#define     TARGET_ERR_ADDR_HI__VALUE                  0xffff
+
+#define CHNL_ACTIVE                            0x760
+#define     CHNL_ACTIVE__CHANNEL0                      0x0001
+#define     CHNL_ACTIVE__CHANNEL1                      0x0002
+#define     CHNL_ACTIVE__CHANNEL2                      0x0004
+#define     CHNL_ACTIVE__CHANNEL3                      0x0008
+
+#define ACTIVE_SRC_ID                          0x800
+#define     ACTIVE_SRC_ID__VALUE                               0x00ff
+
+#define PTN_INTR                                       0x810
+#define     PTN_INTR__CONFIG_ERROR                     0x0001
+#define     PTN_INTR__ACCESS_ERROR_BANK0               0x0002
+#define     PTN_INTR__ACCESS_ERROR_BANK1               0x0004
+#define     PTN_INTR__ACCESS_ERROR_BANK2               0x0008
+#define     PTN_INTR__ACCESS_ERROR_BANK3               0x0010
+#define     PTN_INTR__REG_ACCESS_ERROR                 0x0020
+
+#define PTN_INTR_EN                            0x820
+#define     PTN_INTR_EN__CONFIG_ERROR                  0x0001
+#define     PTN_INTR_EN__ACCESS_ERROR_BANK0            0x0002
+#define     PTN_INTR_EN__ACCESS_ERROR_BANK1            0x0004
+#define     PTN_INTR_EN__ACCESS_ERROR_BANK2            0x0008
+#define     PTN_INTR_EN__ACCESS_ERROR_BANK3            0x0010
+#define     PTN_INTR_EN__REG_ACCESS_ERROR              0x0020
+
+#define PERM_SRC_ID_0                          0x830
+#define     PERM_SRC_ID_0__SRCID                               0x00ff
+#define     PERM_SRC_ID_0__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_0__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_0__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_0__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_0                         0x840
+#define     MIN_BLK_ADDR_0__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_0                         0x850
+#define     MAX_BLK_ADDR_0__VALUE                      0xffff
+
+#define MIN_MAX_BANK_0                         0x860
+#define     MIN_MAX_BANK_0__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_0__MAX_VALUE                  0x000c
+
+#define PERM_SRC_ID_1                          0x870
+#define     PERM_SRC_ID_1__SRCID                               0x00ff
+#define     PERM_SRC_ID_1__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_1__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_1__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_1__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_1                         0x880
+#define     MIN_BLK_ADDR_1__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_1                         0x890
+#define     MAX_BLK_ADDR_1__VALUE                      0xffff
+
+#define MIN_MAX_BANK_1                         0x8a0
+#define     MIN_MAX_BANK_1__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_1__MAX_VALUE                  0x000c
+
+#define PERM_SRC_ID_2                          0x8b0
+#define     PERM_SRC_ID_2__SRCID                               0x00ff
+#define     PERM_SRC_ID_2__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_2__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_2__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_2__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_2                         0x8c0
+#define     MIN_BLK_ADDR_2__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_2                         0x8d0
+#define     MAX_BLK_ADDR_2__VALUE                      0xffff
+
+#define MIN_MAX_BANK_2                         0x8e0
+#define     MIN_MAX_BANK_2__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_2__MAX_VALUE                  0x000c
+
+#define PERM_SRC_ID_3                          0x8f0
+#define     PERM_SRC_ID_3__SRCID                               0x00ff
+#define     PERM_SRC_ID_3__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_3__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_3__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_3__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_3                         0x900
+#define     MIN_BLK_ADDR_3__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_3                         0x910
+#define     MAX_BLK_ADDR_3__VALUE                      0xffff
+
+#define MIN_MAX_BANK_3                         0x920
+#define     MIN_MAX_BANK_3__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_3__MAX_VALUE                  0x000c
+
+#define PERM_SRC_ID_4                          0x930
+#define     PERM_SRC_ID_4__SRCID                               0x00ff
+#define     PERM_SRC_ID_4__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_4__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_4__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_4__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_4                         0x940
+#define     MIN_BLK_ADDR_4__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_4                         0x950
+#define     MAX_BLK_ADDR_4__VALUE                      0xffff
+
+#define MIN_MAX_BANK_4                         0x960
+#define     MIN_MAX_BANK_4__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_4__MAX_VALUE                  0x000c
+
+#define PERM_SRC_ID_5                          0x970
+#define     PERM_SRC_ID_5__SRCID                               0x00ff
+#define     PERM_SRC_ID_5__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_5__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_5__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_5__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_5                         0x980
+#define     MIN_BLK_ADDR_5__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_5                         0x990
+#define     MAX_BLK_ADDR_5__VALUE                      0xffff
+
+#define MIN_MAX_BANK_5                         0x9a0
+#define     MIN_MAX_BANK_5__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_5__MAX_VALUE                  0x000c
+
+#define PERM_SRC_ID_6                          0x9b0
+#define     PERM_SRC_ID_6__SRCID                               0x00ff
+#define     PERM_SRC_ID_6__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_6__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_6__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_6__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_6                         0x9c0
+#define     MIN_BLK_ADDR_6__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_6                         0x9d0
+#define     MAX_BLK_ADDR_6__VALUE                      0xffff
+
+#define MIN_MAX_BANK_6                         0x9e0
+#define     MIN_MAX_BANK_6__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_6__MAX_VALUE                  0x000c
+
+#define PERM_SRC_ID_7                          0x9f0
+#define     PERM_SRC_ID_7__SRCID                               0x00ff
+#define     PERM_SRC_ID_7__DIRECT_ACCESS_ACTIVE                0x0800
+#define     PERM_SRC_ID_7__WRITE_ACTIVE                        0x2000
+#define     PERM_SRC_ID_7__READ_ACTIVE                 0x4000
+#define     PERM_SRC_ID_7__PARTITION_VALID             0x8000
+
+#define MIN_BLK_ADDR_7                         0xa00
+#define     MIN_BLK_ADDR_7__VALUE                      0xffff
+
+#define MAX_BLK_ADDR_7                         0xa10
+#define     MAX_BLK_ADDR_7__VALUE                      0xffff
+
+#define MIN_MAX_BANK_7                         0xa20
+#define     MIN_MAX_BANK_7__MIN_VALUE                  0x0003
+#define     MIN_MAX_BANK_7__MAX_VALUE                  0x000c
diff --git a/drivers/staging/spectra/spectraswconfig.h b/drivers/staging/spectra/spectraswconfig.h
new file mode 100644 (file)
index 0000000..1725946
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _SPECTRASWCONFIG_
+#define _SPECTRASWCONFIG_
+
+/* NAND driver version */
+#define GLOB_VERSION          "driver version 20100311"
+
+
+/***** Common Parameters *****/
+#define RETRY_TIMES                   3
+
+#define READ_BADBLOCK_INFO            1
+#define READBACK_VERIFY               0
+#define AUTO_FORMAT_FLASH             0
+
+/***** Cache Parameters *****/
+#define CACHE_ITEM_NUM            128
+#define BLK_NUM_FOR_L2_CACHE        16
+
+/***** Block Table Parameters *****/
+#define BLOCK_TABLE_INDEX             0
+
+/***** Wear Leveling Parameters *****/
+#define WEAR_LEVELING_GATE         0x10
+#define WEAR_LEVELING_BLOCK_NUM      10
+
+#define DEBUG_BNDRY             0
+
+/***** Product Feature Support *****/
+#define FLASH_EMU               defined(CONFIG_SPECTRA_EMU)
+#define FLASH_NAND              defined(CONFIG_SPECTRA_MRST_HW)
+#define FLASH_MTD               defined(CONFIG_SPECTRA_MTD)
+#define CMD_DMA                 defined(CONFIG_SPECTRA_MRST_HW_DMA)
+
+#define SPECTRA_PARTITION_ID    0
+
+/* Enable this macro if the number of flash blocks is larger than 16K. */
+#define SUPPORT_LARGE_BLOCKNUM  1
+
+/**** Block Table and Reserved Block Parameters *****/
+#define SPECTRA_START_BLOCK     3
+//#define NUM_FREE_BLOCKS_GATE    30
+#define NUM_FREE_BLOCKS_GATE    60
+
+/**** Hardware Parameters ****/
+#define GLOB_HWCTL_REG_BASE     0xFFA40000
+#define GLOB_HWCTL_REG_SIZE     4096
+
+#define GLOB_HWCTL_MEM_BASE     0xFFA48000
+#define GLOB_HWCTL_MEM_SIZE     4096
+
+/* KBV - Updated to LNW scratch register address */
+#define SCRATCH_REG_ADDR    0xFF108018
+#define SCRATCH_REG_SIZE    64
+
+#define GLOB_HWCTL_DEFAULT_BLKS    2048
+
+#define SUPPORT_15BITECC        1
+#define SUPPORT_8BITECC         1
+
+#define ONFI_BLOOM_TIME         0
+#define MODE5_WORKAROUND        1
+
+#endif /*_SPECTRASWCONFIG_*/
index 3ab204ddc29df2ac58a4524adfe044f80f980def..68ad3d0b84a722b275ca76c89a524fd7eafedca1 100644 (file)
@@ -4,7 +4,7 @@
 #
 menu "Texas Instruments shared transport line discipline"
 config TI_ST
-       tristate "shared transport core driver"
+       tristate "Shared transport core driver"
        depends on RFKILL
        select FW_LOADER
        help
index 2c4fe583901dbdd29d36dcfd97423d9a91940fd7..ebfd6bb60176aa1b2d2db109a5983b928741e139 100644 (file)
@@ -1,17 +1,6 @@
 TODO:
 
-1. A per-device/tty port context required to support multiple devices
-on same platform.
-
-2. REMOVE the sysfs entry PID passing mechanism, since there should
-be a better way to request user-space to install line discipline.
-
-3. Re-view/Re-work on the locking.
-
-4. Re-structure to make the ldisc driver more generic for chipsets which mux
-multiple connectivity (BT, FM, GPS) upon 1 TTY port.
-
-5. Step up and maintain this driver to ensure that it continues
+1. Step up and maintain this driver to ensure that it continues
 to work.  Having the hardware for this is pretty much a
 requirement.  If this does not happen, the will be removed in
 the 2.6.35 kernel release.
index d8420b5c91fa030dcab382711ddf63574f2cd196..61ae98833b17af5dec882a9e8d18d6b41a232a91 100644 (file)
@@ -80,31 +80,33 @@ static inline void hci_st_tx_complete(struct hci_st *hst, int pkt_type)
  * status.hci_st_open() function will wait for signal from this
  * API when st_register() function returns ST_PENDING.
  */
-static void hci_st_registration_completion_cb(char data)
+static void hci_st_registration_completion_cb(void *priv_data, char data)
 {
+       struct hci_st *lhst = (struct hci_st *)priv_data;
        BTDRV_API_START();
 
        /* hci_st_open() function needs value of 'data' to know
         * the registration status(success/fail),So have a back
         * up of it.
         */
-       hst->streg_cbdata = data;
+       lhst->streg_cbdata = data;
 
        /* Got a feedback from ST for BT driver registration
         * request.Wackup hci_st_open() function to continue
         * it's open operation.
         */
-       complete(&hst->wait_for_btdrv_reg_completion);
+       complete(&lhst->wait_for_btdrv_reg_completion);
 
        BTDRV_API_EXIT(0);
 }
 
 /* Called by Shared Transport layer when receive data is
  * available */
-static long hci_st_receive(struct sk_buff *skb)
+static long hci_st_receive(void *priv_data, struct sk_buff *skb)
 {
        int err;
        int len;
+       struct hci_st *lhst = (struct hci_st *)priv_data;
 
        BTDRV_API_START();
 
@@ -116,13 +118,13 @@ static long hci_st_receive(struct sk_buff *skb)
                BTDRV_API_EXIT(-EFAULT);
                return -EFAULT;
        }
-       if (!hst) {
+       if (!lhst) {
                kfree_skb(skb);
                BT_DRV_ERR("Invalid hci_st memory,freeing SKB");
                BTDRV_API_EXIT(-EFAULT);
                return -EFAULT;
        }
-       if (!test_bit(BT_DRV_RUNNING, &hst->flags)) {
+       if (!test_bit(BT_DRV_RUNNING, &lhst->flags)) {
                kfree_skb(skb);
                BT_DRV_ERR("Device is not running,freeing SKB");
                BTDRV_API_EXIT(-EINVAL);
@@ -130,7 +132,7 @@ static long hci_st_receive(struct sk_buff *skb)
        }
 
        len = skb->len;
-       skb->dev = (struct net_device *)hst->hdev;
+       skb->dev = (struct net_device *)lhst->hdev;
 
        /* Forward skb to HCI CORE layer */
        err = hci_recv_frame(skb);
@@ -141,7 +143,7 @@ static long hci_st_receive(struct sk_buff *skb)
                BTDRV_API_EXIT(err);
                return err;
        }
-       hst->hdev->stat.byte_rx += len;
+       lhst->hdev->stat.byte_rx += len;
 
        BTDRV_API_EXIT(0);
        return 0;
@@ -189,9 +191,14 @@ static int hci_st_open(struct hci_dev *hdev)
         * make it as NULL */
        hci_st_proto.write = NULL;
 
+       /* send in the hst to be received at registration complete callback
+        * and during st's receive
+        */
+       hci_st_proto.priv_data = hst;
+
        /* Register with ST layer */
        err = st_register(&hci_st_proto);
-       if (err == ST_ERR_PENDING) {
+       if (err == -EINPROGRESS) {
                /* Prepare wait-for-completion handler data structures.
                 * Needed to syncronize this and st_registration_completion_cb()
                 * functions.
@@ -232,7 +239,7 @@ static int hci_st_open(struct hci_dev *hdev)
                        return -EAGAIN;
                }
                err = 0;
-       } else if (err == ST_ERR_FAILURE) {
+       } else if (err == -1) {
                BT_DRV_ERR("st_register failed %d", err);
                BTDRV_API_EXIT(-EAGAIN);
                return -EAGAIN;
@@ -280,7 +287,7 @@ static int hci_st_close(struct hci_dev *hdev)
        /* Unregister from ST layer */
        if (test_and_clear_bit(BT_ST_REGISTERED, &hst->flags)) {
                err = st_unregister(ST_BT);
-               if (err != ST_SUCCESS) {
+               if (err != 0) {
                        BT_DRV_ERR("st_unregister failed %d", err);
                        BTDRV_API_EXIT(-EBUSY);
                        return -EBUSY;
index e8fc97e32c940402e68420c0463dbae428d50b70..9952579425b99a477c29e488243337e9372b2200 100644 (file)
 #define ST_H
 
 #include <linux/skbuff.h>
-/*
- * st.h
- */
 
 /* TODO:
  * Move the following to tty.h upon acceptance
  */
 #define N_TI_WL        20      /* Ldisc for TI's WL BT, FM, GPS combo chips */
 
-/* some gpios have active high, others like fm have
- * active low
+/**
+ * enum kim_gpio_state - Few protocols such as FM have ACTIVE LOW
+ *     gpio states for their chip/core enable gpios
  */
 enum kim_gpio_state {
        KIM_GPIO_INACTIVE,
        KIM_GPIO_ACTIVE,
 };
-/*
- * the list of protocols on chip
+
+/**
+ * enum proto-type - The protocol on WiLink chips which share a
+ *     common physical interface like UART.
  */
 enum proto_type {
        ST_BT,
@@ -50,41 +50,35 @@ enum proto_type {
        ST_MAX,
 };
 
-enum {
-       ST_ERR_FAILURE = -1,    /* check struct */
-       ST_SUCCESS,
-       ST_ERR_PENDING = -5,    /* to call reg_complete_cb */
-       ST_ERR_ALREADY,         /* already registered */
-       ST_ERR_INPROGRESS,
-       ST_ERR_NOPROTO,         /* protocol not supported */
-};
-
-/* per protocol structure
- * for BT/FM and GPS
+/**
+ * struct st_proto_s - Per Protocol structure from BT/FM/GPS to ST
+ * @type: type of the protocol being registered among the
+ *     available proto_type(BT, FM, GPS the protocol which share TTY).
+ * @recv: the receiver callback pointing to a function in the
+ *     protocol drivers called by the ST driver upon receiving
+ *     relevant data.
+ * @match_packet: reserved for future use, to make ST more generic
+ * @reg_complete_cb: callback handler pointing to a function in protocol
+ *     handler called by ST when the pending registrations are complete.
+ *     The registrations are marked pending, in situations when fw
+ *     download is in progress.
+ * @write: pointer to function in ST provided to protocol drivers from ST,
+ *     to be made use when protocol drivers have data to send to TTY.
+ * @priv_data: privdate data holder for the protocol drivers, sent
+ *     from the protocol drivers during registration, and sent back on
+ *     reg_complete_cb and recv.
  */
 struct st_proto_s {
        enum proto_type type;
-/*
- * to be called by ST when data arrives
- */
-       long (*recv) (struct sk_buff *);
-/*
- * for future use, logic now to be in ST
- */
+       long (*recv) (void *, struct sk_buff *);
        unsigned char (*match_packet) (const unsigned char *data);
-/*
- * subsequent registration return PENDING,
- * signalled complete by this callback function
- */
-       void (*reg_complete_cb) (char data);
-/*
- * write function, sent in as NULL and to be returned to
- * protocol drivers
- */
+       void (*reg_complete_cb) (void *, char data);
        long (*write) (struct sk_buff *skb);
+       void *priv_data;
 };
 
-extern long st_register(struct st_proto_s *new_proto);
-extern long st_unregister(enum proto_type type);
+extern long st_register(struct st_proto_s *);
+extern long st_unregister(enum proto_type);
 
+extern struct platform_device *st_get_plat_device(void);
 #endif /* ST_H */
index 4e93694e1c2137bc7df74a4336e0aa54080af8e6..063c9b1db1ab655504f5908e7c4598418dafd0fd 100644 (file)
@@ -38,7 +38,7 @@
 #include "st_ll.h"
 #include "st.h"
 
-#ifdef DEBUG
+#define VERBOSE
 /* strings to be used for rfkill entries and by
  * ST Core to be used for sysfs debug entry
  */
@@ -48,7 +48,6 @@ const unsigned char *protocol_strngs[] = {
        PROTO_ENTRY(ST_FM, "FM"),
        PROTO_ENTRY(ST_GPS, "GPS"),
 };
-#endif
 /* function pointer pointing to either,
  * st_kim_recv during registration to receive fw download responses
  * st_int_recv after registration to receive proto stack responses
@@ -61,7 +60,7 @@ void (*st_recv) (void*, const unsigned char*, long);
 bool is_protocol_list_empty(void)
 {
        unsigned char i = 0;
-       pr_info(" %s ", __func__);
+       pr_debug(" %s ", __func__);
        for (i = 0; i < ST_MAX; i++) {
                if (st_gdata->list[i] != NULL)
                        return ST_NOTEMPTY;
@@ -71,6 +70,7 @@ bool is_protocol_list_empty(void)
        return ST_EMPTY;
 }
 #endif
+
 /* can be called in from
  * -- KIM (during fw download)
  * -- ST Core (during st_write)
@@ -81,20 +81,15 @@ bool is_protocol_list_empty(void)
 int st_int_write(struct st_data_s *st_gdata,
        const unsigned char *data, int count)
 {
-#ifdef VERBOSE                 /* for debug */
-       int i;
-#endif
        struct tty_struct *tty;
        if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) {
                pr_err("tty unavailable to perform write");
-               return ST_ERR_FAILURE;
+               return -1;
        }
        tty = st_gdata->tty;
 #ifdef VERBOSE
-       printk(KERN_ERR "start data..\n");
-       for (i = 0; i < count; i++)     /* no newlines for each datum */
-               printk(" %x", data[i]);
-       printk(KERN_ERR "\n ..end data\n");
+       print_hex_dump(KERN_DEBUG, "<out<", DUMP_PREFIX_NONE,
+               16, 1, data, count, 0);
 #endif
        return tty->ops->write(tty, data, count);
 
@@ -122,8 +117,10 @@ void st_send_frame(enum proto_type protoid, struct st_data_s *st_gdata)
         *   protocol stack driver
         */
        if (likely(st_gdata->list[protoid]->recv != NULL)) {
-               if (unlikely(st_gdata->list[protoid]->recv(st_gdata->rx_skb)
-                            != ST_SUCCESS)) {
+               if (unlikely
+                       (st_gdata->list[protoid]->recv
+                       (st_gdata->list[protoid]->priv_data, st_gdata->rx_skb)
+                            != 0)) {
                        pr_err(" proto stack %d's ->recv failed", protoid);
                        kfree_skb(st_gdata->rx_skb);
                        return;
@@ -132,11 +129,11 @@ void st_send_frame(enum proto_type protoid, struct st_data_s *st_gdata)
                pr_err(" proto stack %d's ->recv null", protoid);
                kfree_skb(st_gdata->rx_skb);
        }
-       pr_info(" done %s", __func__);
        return;
 }
 
-/*
+/**
+ * st_reg_complete -
  * to call registration complete callbacks
  * of all protocol stack drivers
  */
@@ -147,7 +144,8 @@ void st_reg_complete(struct st_data_s *st_gdata, char err)
        for (i = 0; i < ST_MAX; i++) {
                if (likely(st_gdata != NULL && st_gdata->list[i] != NULL &&
                           st_gdata->list[i]->reg_complete_cb != NULL))
-                       st_gdata->list[i]->reg_complete_cb(err);
+                       st_gdata->list[i]->reg_complete_cb
+                               (st_gdata->list[i]->priv_data, err);
        }
 }
 
@@ -156,7 +154,7 @@ static inline int st_check_data_len(struct st_data_s *st_gdata,
 {
        register int room = skb_tailroom(st_gdata->rx_skb);
 
-       pr_info("len %d room %d", len, room);
+       pr_debug("len %d room %d", len, room);
 
        if (!len) {
                /* Received packet has only packet header and
@@ -190,8 +188,9 @@ static inline int st_check_data_len(struct st_data_s *st_gdata,
        return 0;
 }
 
-/* internal function for action when wake-up ack
- * received
+/**
+ * st_wakeup_ack - internal function for action when wake-up ack
+ *     received
  */
 static inline void st_wakeup_ack(struct st_data_s *st_gdata,
        unsigned char cmd)
@@ -214,9 +213,13 @@ static inline void st_wakeup_ack(struct st_data_s *st_gdata,
        st_tx_wakeup(st_gdata);
 }
 
-/* Decodes received RAW data and forwards to corresponding
- * client drivers (Bluetooth,FM,GPS..etc).
- *
+/**
+ * st_int_recv - ST's internal receive function.
+ *     Decodes received RAW data and forwards to corresponding
+ *     client drivers (Bluetooth,FM,GPS..etc).
+ *     This can receive various types of packets,
+ *     HCI-Events, ACL, SCO, 4 types of HCI-LL PM packets
+ *     CH-8 packets from FM, CH-9 packets from GPS cores.
  */
 void st_int_recv(void *disc_data,
        const unsigned char *data, long count)
@@ -259,7 +262,7 @@ void st_int_recv(void *disc_data,
 
                                /* Waiting for complete packet ? */
                        case ST_BT_W4_DATA:
-                               pr_info("Complete pkt received");
+                               pr_debug("Complete pkt received");
 
                                /* Ask ST CORE to forward
                                 * the packet to protocol driver */
@@ -275,7 +278,7 @@ void st_int_recv(void *disc_data,
                                eh = (struct hci_event_hdr *)st_gdata->rx_skb->
                                    data;
 
-                               pr_info("Event header: evt 0x%2.2x"
+                               pr_debug("Event header: evt 0x%2.2x"
                                           "plen %d", eh->evt, eh->plen);
 
                                st_check_data_len(st_gdata, protoid, eh->plen);
@@ -439,45 +442,43 @@ void st_int_recv(void *disc_data,
                        break;
                }
        }
-       pr_info("done %s", __func__);
+       pr_debug("done %s", __func__);
        return;
 }
 
-/* internal de-Q function
- * -- return previous in-completely written skb
- *  or return the skb in the txQ
+/**
+ * st_int_dequeue - internal de-Q function.
+ *     If the previous data set was not written
+ *     completely, return that skb which has the pending data.
+ *     In normal cases, return top of txq.
  */
 struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
 {
        struct sk_buff *returning_skb;
 
-       pr_info("%s", __func__);
-       /* if the previous skb wasn't written completely
-        */
+       pr_debug("%s", __func__);
        if (st_gdata->tx_skb != NULL) {
                returning_skb = st_gdata->tx_skb;
                st_gdata->tx_skb = NULL;
                return returning_skb;
        }
-
-       /* de-Q from the txQ always if previous write is complete */
        return skb_dequeue(&st_gdata->txq);
 }
 
-/* internal Q-ing function
- * will either Q the skb to txq or the tx_waitq
- * depending on the ST LL state
- *
- * lock the whole func - since ll_getstate and Q-ing should happen
- * in one-shot
+/**
+ * st_int_enqueue - internal Q-ing function.
+ *     Will either Q the skb to txq or the tx_waitq
+ *     depending on the ST LL state.
+ *     If the chip is asleep, then Q it onto waitq and
+ *     wakeup the chip.
+ *     txq and waitq needs protection since the other contexts
+ *     may be sending data, waking up chip.
  */
 void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
 {
        unsigned long flags = 0;
 
-       pr_info("%s", __func__);
-       /* this function can be invoked in more then one context.
-        * so have a lock */
+       pr_debug("%s", __func__);
        spin_lock_irqsave(&st_gdata->lock, flags);
 
        switch (st_ll_getstate(st_gdata)) {
@@ -488,16 +489,12 @@ void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
        case ST_LL_ASLEEP_TO_AWAKE:
                skb_queue_tail(&st_gdata->tx_waitq, skb);
                break;
-       case ST_LL_AWAKE_TO_ASLEEP:     /* host cannot be in this state */
+       case ST_LL_AWAKE_TO_ASLEEP:
                pr_err("ST LL is illegal state(%ld),"
                           "purging received skb.", st_ll_getstate(st_gdata));
                kfree_skb(skb);
                break;
-
        case ST_LL_ASLEEP:
-               /* call a function of ST LL to put data
-                * in tx_waitQ and wake_ind in txQ
-                */
                skb_queue_tail(&st_gdata->tx_waitq, skb);
                st_ll_wakeup(st_gdata);
                break;
@@ -507,8 +504,9 @@ void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
                kfree_skb(skb);
                break;
        }
+
        spin_unlock_irqrestore(&st_gdata->lock, flags);
-       pr_info("done %s", __func__);
+       pr_debug("done %s", __func__);
        return;
 }
 
@@ -522,7 +520,7 @@ void st_tx_wakeup(struct st_data_s *st_data)
 {
        struct sk_buff *skb;
        unsigned long flags;    /* for irq save flags */
-       pr_info("%s", __func__);
+       pr_debug("%s", __func__);
        /* check for sending & set flag sending here */
        if (test_and_set_bit(ST_TX_SENDING, &st_data->tx_state)) {
                pr_info("ST already sending");
@@ -563,33 +561,13 @@ void st_tx_wakeup(struct st_data_s *st_data)
 /********************************************************************/
 /* functions called from ST KIM
 */
-void kim_st_list_protocols(struct st_data_s *st_gdata, char *buf)
+void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf)
 {
-       unsigned long flags = 0;
-#ifdef DEBUG
-       unsigned char i = ST_MAX;
-#endif
-       spin_lock_irqsave(&st_gdata->lock, flags);
-#ifdef DEBUG                   /* more detailed log */
-       for (i = 0; i < ST_MAX; i++) {
-               if (i == 0) {
-                       sprintf(buf, "%s is %s", protocol_strngs[i],
-                               st_gdata->list[i] !=
-                               NULL ? "Registered" : "Unregistered");
-               } else {
-                       sprintf(buf, "%s\n%s is %s", buf, protocol_strngs[i],
-                               st_gdata->list[i] !=
-                               NULL ? "Registered" : "Unregistered");
-               }
-       }
-       sprintf(buf, "%s\n", buf);
-#else /* limited info */
-       sprintf(buf, "BT=%c\nFM=%c\nGPS=%c\n",
-               st_gdata->list[ST_BT] != NULL ? 'R' : 'U',
-               st_gdata->list[ST_FM] != NULL ? 'R' : 'U',
-               st_gdata->list[ST_GPS] != NULL ? 'R' : 'U');
-#endif
-       spin_unlock_irqrestore(&st_gdata->lock, flags);
+       seq_printf(buf, "[%d]\nBT=%c\nFM=%c\nGPS=%c\n",
+                       st_gdata->protos_registered,
+                       st_gdata->list[ST_BT] != NULL ? 'R' : 'U',
+                       st_gdata->list[ST_FM] != NULL ? 'R' : 'U',
+                       st_gdata->list[ST_GPS] != NULL ? 'R' : 'U');
 }
 
 /********************************************************************/
@@ -600,7 +578,7 @@ void kim_st_list_protocols(struct st_data_s *st_gdata, char *buf)
 long st_register(struct st_proto_s *new_proto)
 {
        struct st_data_s        *st_gdata;
-       long err = ST_SUCCESS;
+       long err = 0;
        unsigned long flags = 0;
 
        st_kim_ref(&st_gdata);
@@ -608,17 +586,17 @@ long st_register(struct st_proto_s *new_proto)
        if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL
            || new_proto->reg_complete_cb == NULL) {
                pr_err("gdata/new_proto/recv or reg_complete_cb not ready");
-               return ST_ERR_FAILURE;
+               return -1;
        }
 
        if (new_proto->type < ST_BT || new_proto->type >= ST_MAX) {
                pr_err("protocol %d not supported", new_proto->type);
-               return ST_ERR_NOPROTO;
+               return -EPROTONOSUPPORT;
        }
 
        if (st_gdata->list[new_proto->type] != NULL) {
                pr_err("protocol %d already registered", new_proto->type);
-               return ST_ERR_ALREADY;
+               return -EALREADY;
        }
 
        /* can be from process context only */
@@ -630,11 +608,12 @@ long st_register(struct st_proto_s *new_proto)
                st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE);
 
                st_gdata->list[new_proto->type] = new_proto;
+               st_gdata->protos_registered++;
                new_proto->write = st_write;
 
                set_bit(ST_REG_PENDING, &st_gdata->st_state);
                spin_unlock_irqrestore(&st_gdata->lock, flags);
-               return ST_ERR_PENDING;
+               return -EINPROGRESS;
        } else if (st_gdata->protos_registered == ST_EMPTY) {
                pr_info(" protocol list empty :%d ", new_proto->type);
                set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
@@ -648,16 +627,16 @@ long st_register(struct st_proto_s *new_proto)
                /* this may take a while to complete
                 * since it involves BT fw download
                 */
-               err = st_kim_start();
-               if (err != ST_SUCCESS) {
+               err = st_kim_start(st_gdata->kim_data);
+               if (err != 0) {
                        clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
                        if ((st_gdata->protos_registered != ST_EMPTY) &&
                            (test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
                                pr_err(" KIM failure complete callback ");
-                               st_reg_complete(st_gdata, ST_ERR_FAILURE);
+                               st_reg_complete(st_gdata, -1);
                        }
 
-                       return ST_ERR_FAILURE;
+                       return -1;
                }
 
                /* the protocol might require other gpios to be toggled
@@ -672,9 +651,8 @@ long st_register(struct st_proto_s *new_proto)
                 */
                if ((st_gdata->protos_registered != ST_EMPTY) &&
                    (test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
-                       pr_info(" call reg complete callback ");
-                       st_gdata->protos_registered++;
-                       st_reg_complete(st_gdata, ST_SUCCESS);
+                       pr_debug(" call reg complete callback ");
+                       st_reg_complete(st_gdata, 0);
                }
                clear_bit(ST_REG_PENDING, &st_gdata->st_state);
 
@@ -684,11 +662,12 @@ long st_register(struct st_proto_s *new_proto)
                if (st_gdata->list[new_proto->type] != NULL) {
                        pr_err(" proto %d already registered ",
                                   new_proto->type);
-                       return ST_ERR_ALREADY;
+                       return -EALREADY;
                }
 
                spin_lock_irqsave(&st_gdata->lock, flags);
                st_gdata->list[new_proto->type] = new_proto;
+               st_gdata->protos_registered++;
                new_proto->write = st_write;
                spin_unlock_irqrestore(&st_gdata->lock, flags);
                return err;
@@ -707,18 +686,19 @@ long st_register(struct st_proto_s *new_proto)
                default:
                        pr_err("%d protocol not supported",
                                   new_proto->type);
-                       err = ST_ERR_NOPROTO;
+                       err = -EPROTONOSUPPORT;
                        /* something wrong */
                        break;
                }
                st_gdata->list[new_proto->type] = new_proto;
+               st_gdata->protos_registered++;
                new_proto->write = st_write;
 
                /* lock already held before entering else */
                spin_unlock_irqrestore(&st_gdata->lock, flags);
                return err;
        }
-       pr_info("done %s(%d) ", __func__, new_proto->type);
+       pr_debug("done %s(%d) ", __func__, new_proto->type);
 }
 EXPORT_SYMBOL_GPL(st_register);
 
@@ -727,16 +707,16 @@ EXPORT_SYMBOL_GPL(st_register);
  */
 long st_unregister(enum proto_type type)
 {
-       long err = ST_SUCCESS;
+       long err = 0;
        unsigned long flags = 0;
        struct st_data_s        *st_gdata;
 
-       pr_info("%s: %d ", __func__, type);
+       pr_debug("%s: %d ", __func__, type);
 
        st_kim_ref(&st_gdata);
        if (type < ST_BT || type >= ST_MAX) {
                pr_err(" protocol %d not supported", type);
-               return ST_ERR_NOPROTO;
+               return -EPROTONOSUPPORT;
        }
 
        spin_lock_irqsave(&st_gdata->lock, flags);
@@ -744,7 +724,7 @@ long st_unregister(enum proto_type type)
        if (st_gdata->list[type] == NULL) {
                pr_err(" protocol %d not registered", type);
                spin_unlock_irqrestore(&st_gdata->lock, flags);
-               return ST_ERR_NOPROTO;
+               return -EPROTONOSUPPORT;
        }
 
        st_gdata->protos_registered--;
@@ -768,7 +748,7 @@ long st_unregister(enum proto_type type)
                }
 
                /* all protocols now unregistered */
-               st_kim_stop();
+               st_kim_stop(st_gdata->kim_data);
                /* disable ST LL */
                st_ll_disable(st_gdata);
        }
@@ -791,7 +771,7 @@ long st_write(struct sk_buff *skb)
        if (unlikely(skb == NULL || st_gdata == NULL
                || st_gdata->tty == NULL)) {
                pr_err("data/tty unavailable to perform write");
-               return ST_ERR_FAILURE;
+               return -1;
        }
 #ifdef DEBUG                   /* open-up skb to read the 1st byte */
        switch (skb->data[0]) {
@@ -810,10 +790,10 @@ long st_write(struct sk_buff *skb)
        if (unlikely(st_gdata->list[protoid] == NULL)) {
                pr_err(" protocol %d not registered, and writing? ",
                           protoid);
-               return ST_ERR_FAILURE;
+               return -1;
        }
 #endif
-       pr_info("%d to be written", skb->len);
+       pr_debug("%d to be written", skb->len);
        len = skb->len;
 
        /* st_ll to decide where to enqueue the skb */
@@ -834,7 +814,7 @@ EXPORT_SYMBOL_GPL(st_unregister);
  */
 static int st_tty_open(struct tty_struct *tty)
 {
-       int err = ST_SUCCESS;
+       int err = 0;
        struct st_data_s *st_gdata;
        pr_info("%s ", __func__);
 
@@ -855,8 +835,8 @@ static int st_tty_open(struct tty_struct *tty)
         * signal to UIM via KIM that -
         * installation of N_TI_WL ldisc is complete
         */
-       st_kim_complete();
-       pr_info("done %s", __func__);
+       st_kim_complete(st_gdata->kim_data);
+       pr_debug("done %s", __func__);
        return err;
 }
 
@@ -878,12 +858,13 @@ static void st_tty_close(struct tty_struct *tty)
                        pr_err("%d not un-registered", i);
                st_gdata->list[i] = NULL;
        }
+       st_gdata->protos_registered = 0;
        spin_unlock_irqrestore(&st_gdata->lock, flags);
        /*
         * signal to UIM via KIM that -
         * N_TI_WL ldisc is un-installed
         */
-       st_kim_complete();
+       st_kim_complete(st_gdata->kim_data);
        st_gdata->tty = NULL;
        /* Flush any pending characters in the driver and discipline. */
        tty_ldisc_flush(tty);
@@ -900,7 +881,7 @@ static void st_tty_close(struct tty_struct *tty)
        st_gdata->rx_skb = NULL;
        spin_unlock_irqrestore(&st_gdata->lock, flags);
 
-       pr_info("%s: done ", __func__);
+       pr_debug("%s: done ", __func__);
 }
 
 static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
@@ -908,11 +889,8 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
 {
 
 #ifdef VERBOSE
-       long i;
-       printk(KERN_ERR "incoming data...\n");
-       for (i = 0; i < count; i++)
-               printk(" %x", data[i]);
-       printk(KERN_ERR "\n.. data end\n");
+       print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
+               16, 1, data, count, 0);
 #endif
 
        /*
@@ -920,7 +898,7 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
         * to KIM for validation
         */
        st_recv(tty->disc_data, data, count);
-       pr_info("done %s", __func__);
+       pr_debug("done %s", __func__);
 }
 
 /* wake-up function called in from the TTY layer
@@ -929,7 +907,7 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
 static void st_tty_wakeup(struct tty_struct *tty)
 {
        struct  st_data_s *st_gdata = tty->disc_data;
-       pr_info("%s ", __func__);
+       pr_debug("%s ", __func__);
        /* don't do an wakeup for now */
        clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 
@@ -940,7 +918,7 @@ static void st_tty_wakeup(struct tty_struct *tty)
 static void st_tty_flush_buffer(struct tty_struct *tty)
 {
        struct  st_data_s *st_gdata = tty->disc_data;
-       pr_info("%s ", __func__);
+       pr_debug("%s ", __func__);
 
        kfree_skb(st_gdata->tx_skb);
        st_gdata->tx_skb = NULL;
@@ -979,7 +957,7 @@ int st_core_init(struct st_data_s **core_data)
                kfree(st_ldisc_ops);
                return err;
        }
-       pr_info("registered n_shared line discipline");
+       pr_debug("registered n_shared line discipline");
 
        st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL);
        if (!st_gdata) {
index f271c88a8087a665b6db97fc582544d2c9c662ec..e0c32d149f5f294878d22597bec9c1bfc05660a4 100644 (file)
 #define ST_REG_PENDING         3
 #define ST_WAITING_FOR_RESP    4
 
-/*
- * local data required for ST/KIM/ST-HCI-LL
+/**
+ * struct st_data_s - ST core internal structure
+ * @st_state: different states of ST like initializing, registration
+ *     in progress, this is mainly used to return relevant err codes
+ *     when protocol drivers are registering. It is also used to track
+ *     the recv function, as in during fw download only HCI events
+ *     can occur , where as during other times other events CH8, CH9
+ *     can occur.
+ * @tty: tty provided by the TTY core for line disciplines.
+ * @ldisc_ops: the procedures that this line discipline registers with TTY.
+ * @tx_skb: If for some reason the tty's write returns lesser bytes written
+ *     then to maintain the rest of data to be written on next instance.
+ *     This needs to be protected, hence the lock inside wakeup func.
+ * @tx_state: if the data is being written onto the TTY and protocol driver
+ *     wants to send more, queue up data and mark that there is
+ *     more data to send.
+ * @list: the list of protocols registered, only MAX can exist, one protocol
+ *     can register only once.
+ * @rx_state: states to be maintained inside st's tty receive
+ * @rx_count: count to be maintained inside st's tty receieve
+ * @rx_skb: the skb where all data for a protocol gets accumulated,
+ *     since tty might not call receive when a complete event packet
+ *     is received, the states, count and the skb needs to be maintained.
+ * @txq: the list of skbs which needs to be sent onto the TTY.
+ * @tx_waitq: if the chip is not in AWAKE state, the skbs needs to be queued
+ *     up in here, PM(WAKEUP_IND) data needs to be sent and then the skbs
+ *     from waitq can be moved onto the txq.
+ *     Needs locking too.
+ * @lock: the lock to protect skbs, queues, and ST states.
+ * @protos_registered: count of the protocols registered, also when 0 the
+ *     chip enable gpio can be toggled, and when it changes to 1 the fw
+ *     needs to be downloaded to initialize chip side ST.
+ * @ll_state: the various PM states the chip can be, the states are notified
+ *     to us, when the chip sends relevant PM packets(SLEEP_IND, WAKE_IND).
+ * @kim_data: reference to the parent encapsulating structure.
+ *
  */
 struct st_data_s {
        unsigned long st_state;
-/*
- * an instance of tty_struct & ldisc ops to move around
- */
        struct tty_struct *tty;
        struct tty_ldisc_ops *ldisc_ops;
-/*
- * the tx skb -
- * if the skb is already dequeued and the tty failed to write the same
- * maintain the skb to write in the next transaction
- */
        struct sk_buff *tx_skb;
 #define ST_TX_SENDING  1
 #define ST_TX_WAKEUP   2
        unsigned long tx_state;
-/*
- * list of protocol registered
- */
        struct st_proto_s *list[ST_MAX];
-/*
- * lock
- */
        unsigned long rx_state;
        unsigned long rx_count;
        struct sk_buff *rx_skb;
        struct sk_buff_head txq, tx_waitq;
-       spinlock_t lock;        /* ST LL state lock  */
+       spinlock_t lock;
        unsigned char   protos_registered;
-       unsigned long ll_state; /* ST LL power state */
+       unsigned long ll_state;
+       void *kim_data;
 };
 
-/* point this to tty->driver->write or tty->ops->write
+/**
+ * st_int_write -
+ * point this to tty->driver->write or tty->ops->write
  * depending upon the kernel version
  */
 int st_int_write(struct st_data_s*, const unsigned char*, int);
-/* internal write function, passed onto protocol drivers
+
+/**
+ * st_write -
+ * internal write function, passed onto protocol drivers
  * via the write function ptr of protocol struct
  */
 long st_write(struct sk_buff *);
-/* function to be called from ST-LL
- */
+
+/* function to be called from ST-LL */
 void st_ll_send_frame(enum proto_type, struct sk_buff *);
+
 /* internal wake up function */
 void st_tx_wakeup(struct st_data_s *st_data);
 
+/* init, exit entry funcs called from KIM */
 int st_core_init(struct st_data_s **);
 void st_core_exit(struct st_data_s *);
+
+/* ask for reference from KIM */
 void st_kim_ref(struct st_data_s **);
 
 #define GPS_STUB_TEST
index 98cbabba38447012687baedfb804a786ad8442fc..b4a6c7fdc4e6ca59283dd3e64736c0efdfd97407 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/delay.h>
 #include <linux/wait.h>
 #include <linux/gpio.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #include <linux/sched.h>
 
@@ -55,37 +57,10 @@ static struct platform_driver kim_platform_driver = {
                   },
 };
 
-#ifndef LEGACY_RFKILL_SUPPORT
-static ssize_t show_pid(struct device *dev, struct device_attribute
-                       *attr, char *buf);
-static ssize_t store_pid(struct device *dev, struct device_attribute
-                        *devattr, char *buf, size_t count);
-static ssize_t show_list(struct device *dev, struct device_attribute
-                        *attr, char *buf);
-
-/* structures specific for sysfs entries */
-static struct kobj_attribute pid_attr =
-__ATTR(pid, 0644, (void *)show_pid, (void *)store_pid);
-
-static struct kobj_attribute list_protocols =
-__ATTR(protocols, 0444, (void *)show_list, NULL);
-
-static struct attribute *uim_attrs[] = {
-       &pid_attr.attr,
-       /* add more debug sysfs entries */
-       &list_protocols.attr,
-       NULL,
-};
-
-static struct attribute_group uim_attr_grp = {
-       .attrs = uim_attrs,
-};
-#else
 static int kim_toggle_radio(void*, bool);
 static const struct rfkill_ops kim_rfkill_ops = {
        .set_block = kim_toggle_radio,
 };
-#endif /* LEGACY_RFKILL_SUPPORT */
 
 /* strings to be used for rfkill entries and by
  * ST Core to be used for sysfs debug entry
@@ -97,18 +72,19 @@ const unsigned char *protocol_names[] = {
        PROTO_ENTRY(ST_GPS, "GPS"),
 };
 
-struct kim_data_s      *kim_gdata;
 
 /**********************************************************************/
 /* internal functions */
 
-/*
- * function to return whether the firmware response was proper
- * in case of error don't complete so that waiting for proper
- * response times out
+/**
+ * validate_firmware_response -
+ *     function to return whether the firmware response was proper
+ *     in case of error don't complete so that waiting for proper
+ *     response times out
  */
-void validate_firmware_response(struct sk_buff *skb)
+void validate_firmware_response(struct kim_data_s *kim_gdata)
 {
+       struct sk_buff *skb = kim_gdata->rx_skb;
        if (unlikely(skb->data[5] != 0)) {
                pr_err("no proper response during fw download");
                pr_err("data6 %x", skb->data[5]);
@@ -122,14 +98,14 @@ void validate_firmware_response(struct sk_buff *skb)
 /* check for data len received inside kim_int_recv
  * most often hit the last case to update state to waiting for data
  */
-static inline int kim_check_data_len(int len)
+static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len)
 {
        register int room = skb_tailroom(kim_gdata->rx_skb);
 
-       pr_info("len %d room %d", len, room);
+       pr_debug("len %d room %d", len, room);
 
        if (!len) {
-               validate_firmware_response(kim_gdata->rx_skb);
+               validate_firmware_response(kim_gdata);
        } else if (len > room) {
                /* Received packet's payload length is larger.
                 * We can't accommodate it in created skb.
@@ -155,18 +131,20 @@ static inline int kim_check_data_len(int len)
        return 0;
 }
 
-/* receive function called during firmware download
- * - firmware download responses on different UART drivers
- *   have been observed to come in bursts of different
- *   tty_receive and hence the logic
+/**
+ * kim_int_recv - receive function called during firmware download
+ *     firmware download responses on different UART drivers
+ *     have been observed to come in bursts of different
+ *     tty_receive and hence the logic
  */
-void kim_int_recv(const unsigned char *data, long count)
+void kim_int_recv(struct kim_data_s *kim_gdata,
+       const unsigned char *data, long count)
 {
        register char *ptr;
        struct hci_event_hdr *eh;
        register int len = 0, type = 0;
 
-       pr_info("%s", __func__);
+       pr_debug("%s", __func__);
        /* Decode received bytes here */
        ptr = (char *)data;
        if (unlikely(ptr == NULL)) {
@@ -188,8 +166,8 @@ void kim_int_recv(const unsigned char *data, long count)
                        switch (kim_gdata->rx_state) {
                                /* Waiting for complete packet ? */
                        case ST_BT_W4_DATA:
-                               pr_info("Complete pkt received");
-                               validate_firmware_response(kim_gdata->rx_skb);
+                               pr_debug("Complete pkt received");
+                               validate_firmware_response(kim_gdata);
                                kim_gdata->rx_state = ST_W4_PACKET_TYPE;
                                kim_gdata->rx_skb = NULL;
                                continue;
@@ -197,9 +175,9 @@ void kim_int_recv(const unsigned char *data, long count)
                        case ST_BT_W4_EVENT_HDR:
                                eh = (struct hci_event_hdr *)kim_gdata->
                                    rx_skb->data;
-                               pr_info("Event header: evt 0x%2.2x"
+                               pr_debug("Event header: evt 0x%2.2x"
                                           "plen %d", eh->evt, eh->plen);
-                               kim_check_data_len(eh->plen);
+                               kim_check_data_len(kim_gdata, eh->plen);
                                continue;
                        }       /* end of switch */
                }               /* end of if rx_state */
@@ -216,7 +194,7 @@ void kim_int_recv(const unsigned char *data, long count)
                        ptr++;
                        count--;
                        continue;
-               }               /* end of switch *ptr */
+               }
                ptr++;
                count--;
                kim_gdata->rx_skb =
@@ -226,34 +204,35 @@ void kim_int_recv(const unsigned char *data, long count)
                        kim_gdata->rx_state = ST_W4_PACKET_TYPE;
                        kim_gdata->rx_count = 0;
                        return;
-               } /* not necessary in this case */
+               }
                bt_cb(kim_gdata->rx_skb)->pkt_type = type;
-       }                       /* end of while count */
+       }
        pr_info("done %s", __func__);
        return;
 }
 
-static long read_local_version(char *bts_scr_name)
+static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
 {
        unsigned short version = 0, chip = 0, min_ver = 0, maj_ver = 0;
        char read_ver_cmd[] = { 0x01, 0x01, 0x10, 0x00 };
 
-       pr_info("%s", __func__);
+       pr_debug("%s", __func__);
 
        INIT_COMPLETION(kim_gdata->kim_rcvd);
        if (4 != st_int_write(kim_gdata->core_data, read_ver_cmd, 4)) {
                pr_err("kim: couldn't write 4 bytes");
-               return ST_ERR_FAILURE;
+               return -1;
        }
 
        if (!wait_for_completion_timeout
            (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
                pr_err(" waiting for ver info- timed out ");
-               return ST_ERR_FAILURE;
+               return -1;
        }
 
        version =
-           MAKEWORD(kim_gdata->resp_buffer[13], kim_gdata->resp_buffer[14]);
+               MAKEWORD(kim_gdata->resp_buffer[13],
+                               kim_gdata->resp_buffer[14]);
        chip = (version & 0x7C00) >> 10;
        min_ver = (version & 0x007F);
        maj_ver = (version & 0x0380) >> 7;
@@ -262,25 +241,32 @@ static long read_local_version(char *bts_scr_name)
                maj_ver |= 0x0008;
 
        sprintf(bts_scr_name, "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
+
+       /* to be accessed later via sysfs entry */
+       kim_gdata->version.full = version;
+       kim_gdata->version.chip = chip;
+       kim_gdata->version.maj_ver = maj_ver;
+       kim_gdata->version.min_ver = min_ver;
+
        pr_info("%s", bts_scr_name);
-       return ST_SUCCESS;
+       return 0;
 }
 
-/* internal function which parses through the .bts firmware script file
- * intreprets SEND, DELAY actions only as of now
+/**
+ * download_firmware -
+ *     internal function which parses through the .bts firmware
+ *     script file intreprets SEND, DELAY actions only as of now
  */
-static long download_firmware(void)
+static long download_firmware(struct kim_data_s *kim_gdata)
 {
-       long err = ST_SUCCESS;
+       long err = 0;
        long len = 0;
        register unsigned char *ptr = NULL;
        register unsigned char *action_ptr = NULL;
        unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */
 
-       pr_info("%s", __func__);
-
-       err = read_local_version(bts_scr_name);
-       if (err != ST_SUCCESS) {
+       err = read_local_version(kim_gdata, bts_scr_name);
+       if (err != 0) {
                pr_err("kim: failed to read local ver");
                return err;
        }
@@ -291,7 +277,7 @@ static long download_firmware(void)
                     (kim_gdata->fw_entry->size == 0))) {
                pr_err(" request_firmware failed(errno %ld) for %s", err,
                           bts_scr_name);
-               return ST_ERR_FAILURE;
+               return -1;
        }
        ptr = (void *)kim_gdata->fw_entry->data;
        len = kim_gdata->fw_entry->size;
@@ -302,7 +288,7 @@ static long download_firmware(void)
        len -= sizeof(struct bts_header);
 
        while (len > 0 && ptr) {
-               pr_info(" action size %d, type %d ",
+               pr_debug(" action size %d, type %d ",
                           ((struct bts_action *)ptr)->size,
                           ((struct bts_action *)ptr)->type);
 
@@ -315,8 +301,8 @@ static long download_firmware(void)
                                /* ignore remote change
                                 * baud rate HCI VS command */
                                pr_err
-                                   (" change remote baud\
-                                   rate command in firmware");
+                                   (" change remote baud"
+                                   rate command in firmware");
                                break;
                        }
 
@@ -326,7 +312,7 @@ static long download_firmware(void)
                                           ((struct bts_action *)ptr)->size);
                        if (unlikely(err < 0)) {
                                release_firmware(kim_gdata->fw_entry);
-                               return ST_ERR_FAILURE;
+                               return -1;
                        }
                        if (!wait_for_completion_timeout
                            (&kim_gdata->kim_rcvd,
@@ -335,7 +321,7 @@ static long download_firmware(void)
                                    (" response timeout during fw download ");
                                /* timed out */
                                release_firmware(kim_gdata->fw_entry);
-                               return ST_ERR_FAILURE;
+                               return -1;
                        }
                        break;
                case ACTION_DELAY:      /* sleep */
@@ -353,19 +339,23 @@ static long download_firmware(void)
        }
        /* fw download complete */
        release_firmware(kim_gdata->fw_entry);
-       return ST_SUCCESS;
+       return 0;
 }
 
 /**********************************************************************/
 /* functions called from ST core */
-
 /* function to toggle the GPIO
  * needs to know whether the GPIO is active high or active low
  */
 void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state)
 {
+       struct platform_device  *kim_pdev;
+       struct kim_data_s       *kim_gdata;
        pr_info(" %s ", __func__);
 
+       kim_pdev = st_get_plat_device();
+       kim_gdata = dev_get_drvdata(&kim_pdev->dev);
+
        if (kim_gdata->gpios[type] == -1) {
                pr_info(" gpio not requested for protocol %s",
                           protocol_names[type]);
@@ -405,6 +395,9 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state)
  */
 void st_kim_recv(void *disc_data, const unsigned char *data, long count)
 {
+       struct st_data_s        *st_gdata = (struct st_data_s *)disc_data;
+       struct kim_data_s       *kim_gdata = st_gdata->kim_data;
+
        pr_info(" %s ", __func__);
        /* copy to local buffer */
        if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
@@ -413,7 +406,7 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count)
                complete_all(&kim_gdata->kim_rcvd);
                return;
        } else {
-               kim_int_recv(data, count);
+               kim_int_recv(kim_gdata, data, count);
                /* either completes or times out */
        }
        return;
@@ -422,27 +415,33 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count)
 /* to signal completion of line discipline installation
  * called from ST Core, upon tty_open
  */
-void st_kim_complete(void)
+void st_kim_complete(void *kim_data)
 {
+       struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
        complete(&kim_gdata->ldisc_installed);
 }
 
-/* called from ST Core upon 1st registration
-*/
-long st_kim_start(void)
+/**
+ * st_kim_start - called from ST Core upon 1st registration
+ *     This involves toggling the chip enable gpio, reading
+ *     the firmware version from chip, forming the fw file name
+ *     based on the chip version, requesting the fw, parsing it
+ *     and perform download(send/recv).
+ */
+long st_kim_start(void *kim_data)
 {
-       long err = ST_SUCCESS;
+       long err = 0;
        long retry = POR_RETRY_COUNT;
+       struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
+
        pr_info(" %s", __func__);
 
        do {
-#ifdef LEGACY_RFKILL_SUPPORT
                /* TODO: this is only because rfkill sub-system
                 * doesn't send events to user-space if the state
                 * isn't changed
                 */
                rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1);
-#endif
                /* Configure BT nShutdown to HIGH state */
                gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW);
                mdelay(5);      /* FIXME: a proper toggle */
@@ -450,30 +449,29 @@ long st_kim_start(void)
                mdelay(100);
                /* re-initialize the completion */
                INIT_COMPLETION(kim_gdata->ldisc_installed);
-#ifndef LEGACY_RFKILL_SUPPORT
+#if 0 /* older way of signalling user-space UIM */
                /* send signal to UIM */
                err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 0);
                if (err != 0) {
                        pr_info(" sending SIGUSR2 to uim failed %ld", err);
-                       err = ST_ERR_FAILURE;
+                       err = -1;
                        continue;
                }
-#else
+#endif
                /* unblock and send event to UIM via /dev/rfkill */
                rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 0);
-#endif
                /* wait for ldisc to be installed */
                err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
                                msecs_to_jiffies(LDISC_TIME));
                if (!err) {     /* timeout */
                        pr_err("line disc installation timed out ");
-                       err = ST_ERR_FAILURE;
+                       err = -1;
                        continue;
                } else {
                        /* ldisc installed now */
                        pr_info(" line discipline installed ");
-                       err = download_firmware();
-                       if (err != ST_SUCCESS) {
+                       err = download_firmware(kim_gdata);
+                       if (err != 0) {
                                pr_err("download firmware failed");
                                continue;
                        } else {        /* on success don't retry */
@@ -484,31 +482,33 @@ long st_kim_start(void)
        return err;
 }
 
-/* called from ST Core, on the last un-registration
-*/
-long st_kim_stop(void)
+/**
+ * st_kim_stop - called from ST Core, on the last un-registration
+ *     toggle low the chip enable gpio
+ */
+long st_kim_stop(void *kim_data)
 {
-       long err = ST_SUCCESS;
+       long err = 0;
+       struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
 
        INIT_COMPLETION(kim_gdata->ldisc_installed);
-#ifndef LEGACY_RFKILL_SUPPORT
+#if 0 /* older way of signalling user-space UIM */
        /* send signal to UIM */
        err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 1);
        if (err != 0) {
                pr_err("sending SIGUSR2 to uim failed %ld", err);
-               return ST_ERR_FAILURE;
+               return -1;
        }
-#else
+#endif
        /* set BT rfkill to be blocked */
        err = rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1);
-#endif
 
        /* wait for ldisc to be un-installed */
        err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
                        msecs_to_jiffies(LDISC_TIME));
        if (!err) {             /* timeout */
                pr_err(" timed out waiting for ldisc to be un-installed");
-               return ST_ERR_FAILURE;
+               return -1;
        }
 
        /* By default configure BT nShutdown to LOW state */
@@ -522,37 +522,24 @@ long st_kim_stop(void)
 
 /**********************************************************************/
 /* functions called from subsystems */
+/* called when debugfs entry is read from */
 
-#ifndef LEGACY_RFKILL_SUPPORT
-/* called when sysfs entry is written to */
-static ssize_t store_pid(struct device *dev, struct device_attribute
-                        *devattr, char *buf, size_t count)
+static int show_version(struct seq_file *s, void *unused)
 {
-       pr_info("%s: pid %s ", __func__, buf);
-       sscanf(buf, "%ld", &kim_gdata->uim_pid);
-       /* to be made use by kim_start to signal SIGUSR2
-        */
-       return strlen(buf);
-}
-
-/* called when sysfs entry is read from */
-static ssize_t show_pid(struct device *dev, struct device_attribute
-                       *attr, char *buf)
-{
-       sprintf(buf, "%ld", kim_gdata->uim_pid);
-       return strlen(buf);
+       struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
+       seq_printf(s, "%04X %d.%d.%d\n", kim_gdata->version.full,
+                       kim_gdata->version.chip, kim_gdata->version.maj_ver,
+                       kim_gdata->version.min_ver);
+       return 0;
 }
 
-/* called when sysfs entry is read from */
-static ssize_t show_list(struct device *dev, struct device_attribute
-                        *attr, char *buf)
+static int show_list(struct seq_file *s, void *unused)
 {
-       kim_st_list_protocols(kim_gdata->core_data, buf);
-       return strlen(buf);
+       struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
+       kim_st_list_protocols(kim_gdata->core_data, s);
+       return 0;
 }
 
-#else /* LEGACY_RFKILL_SUPPORT */
-
 /* function called from rfkill subsystem, when someone from
  * user space would write 0/1 on the sysfs entry
  * /sys/class/rfkill/rfkill0,1,3/state
@@ -560,7 +547,7 @@ static ssize_t show_list(struct device *dev, struct device_attribute
 static int kim_toggle_radio(void *data, bool blocked)
 {
        enum proto_type type = *((enum proto_type *)data);
-       pr_info(" %s: %d ", __func__, type);
+       pr_debug(" %s: %d ", __func__, type);
 
        switch (type) {
        case ST_BT:
@@ -577,33 +564,79 @@ static int kim_toggle_radio(void *data, bool blocked)
                pr_err(" wrong proto type ");
        break;
        }
-       return ST_SUCCESS;
+       return 0;
 }
 
-#endif /* LEGACY_RFKILL_SUPPORT */
-
+/**
+ * st_kim_ref - reference the core's data
+ *     This references the per-ST platform device in the arch/xx/
+ *     board-xx.c file.
+ *     This would enable multiple such platform devices to exist
+ *     on a given platform
+ */
 void st_kim_ref(struct st_data_s **core_data)
 {
+       struct platform_device  *pdev;
+       struct kim_data_s       *kim_gdata;
+       /* get kim_gdata reference from platform device */
+       pdev = st_get_plat_device();
+       kim_gdata = dev_get_drvdata(&pdev->dev);
        *core_data = kim_gdata->core_data;
 }
 
+static int kim_version_open(struct inode *i, struct file *f)
+{
+       return single_open(f, show_version, i->i_private);
+}
+
+static int kim_list_open(struct inode *i, struct file *f)
+{
+       return single_open(f, show_list, i->i_private);
+}
+
+static const struct file_operations version_debugfs_fops = {
+       /* version info */
+       .open = kim_version_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+static const struct file_operations list_debugfs_fops = {
+       /* protocols info */
+       .open = kim_list_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
 /**********************************************************************/
 /* functions called from platform device driver subsystem
  * need to have a relevant platform device entry in the platform's
  * board-*.c file
  */
 
+struct dentry *kim_debugfs_dir;
 static int kim_probe(struct platform_device *pdev)
 {
        long status;
        long proto;
        long *gpios = pdev->dev.platform_data;
+       struct kim_data_s       *kim_gdata;
+
+       kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
+       if (!kim_gdata) {
+               pr_err("no mem to allocate");
+               return -ENOMEM;
+       }
+       dev_set_drvdata(&pdev->dev, kim_gdata);
 
        status = st_core_init(&kim_gdata->core_data);
        if (status != 0) {
                pr_err(" ST core init failed");
-               return ST_ERR_FAILURE;
+               return -1;
        }
+       /* refer to itself */
+       kim_gdata->core_data->kim_data = kim_gdata;
 
        for (proto = 0; proto < ST_MAX; proto++) {
                kim_gdata->gpios[proto] = gpios[proto];
@@ -639,30 +672,12 @@ static int kim_probe(struct platform_device *pdev)
                        return status;
                }
        }
-#ifndef LEGACY_RFKILL_SUPPORT
-       /* pdev to contain BT, FM and GPS enable/N-Shutdown GPIOs
-        * execute request_gpio, set output direction
-        */
-       kim_gdata->kim_kobj = kobject_create_and_add("uim", NULL);
-       /* create the sysfs entry for UIM to put in pid */
-       if (sysfs_create_group(kim_gdata->kim_kobj, &uim_attr_grp)) {
-               pr_err(" sysfs entry creation failed");
-               kobject_put(kim_gdata->kim_kobj);
-               /* free requested GPIOs and fail probe */
-               for (proto = ST_BT; proto < ST_MAX; proto++) {
-                       if (gpios[proto] != -1)
-                               gpio_free(gpios[proto]);
-               }
-               return -1;      /* fail insmod */
-       }
-       pr_info(" sysfs entry created ");
-#endif
        /* get reference of pdev for request_firmware
         */
        kim_gdata->kim_pdev = pdev;
        init_completion(&kim_gdata->kim_rcvd);
        init_completion(&kim_gdata->ldisc_installed);
-#ifdef LEGACY_RFKILL_SUPPORT
+
        for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
                /* TODO: should all types be rfkill_type_bt ? */
                kim_gdata->rf_protos[proto] = proto;
@@ -685,8 +700,20 @@ static int kim_probe(struct platform_device *pdev)
                }
                pr_info("rfkill entry created for %ld", gpios[proto]);
        }
-#endif
-       return ST_SUCCESS;
+
+       kim_debugfs_dir = debugfs_create_dir("ti-st", NULL);
+       if (IS_ERR(kim_debugfs_dir)) {
+               pr_err(" debugfs entries creation failed ");
+               kim_debugfs_dir = NULL;
+               return -1;
+       }
+
+       debugfs_create_file("version", S_IRUGO, kim_debugfs_dir,
+                               kim_gdata, &version_debugfs_fops);
+       debugfs_create_file("protocols", S_IRUGO, kim_debugfs_dir,
+                               kim_gdata, &list_debugfs_fops);
+       pr_info(" debugfs entries created ");
+       return 0;
 }
 
 static int kim_remove(struct platform_device *pdev)
@@ -695,27 +722,27 @@ static int kim_remove(struct platform_device *pdev)
         */
        long *gpios = pdev->dev.platform_data;
        long proto;
+       struct kim_data_s       *kim_gdata;
+
+       kim_gdata = dev_get_drvdata(&pdev->dev);
 
        for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
                /* Claim the Bluetooth/FM/GPIO
                 * nShutdown gpio from the system
                 */
                gpio_free(gpios[proto]);
-#ifdef LEGACY_RFKILL_SUPPORT
                rfkill_unregister(kim_gdata->rfkill[proto]);
                rfkill_destroy(kim_gdata->rfkill[proto]);
                kim_gdata->rfkill[proto] = NULL;
-#endif
        }
        pr_info("kim: GPIO Freed");
-#ifndef LEGACY_RFKILL_SUPPORT
-       /* delete the sysfs entries */
-       sysfs_remove_group(kim_gdata->kim_kobj, &uim_attr_grp);
-       kobject_put(kim_gdata->kim_kobj);
-#endif
+       debugfs_remove_recursive(kim_debugfs_dir);
        kim_gdata->kim_pdev = NULL;
        st_core_exit(kim_gdata->core_data);
-       return ST_SUCCESS;
+
+       kfree(kim_gdata);
+       kim_gdata = NULL;
+       return 0;
 }
 
 /**********************************************************************/
@@ -723,27 +750,19 @@ static int kim_remove(struct platform_device *pdev)
 
 static int __init st_kim_init(void)
 {
-       long ret = ST_SUCCESS;
-       kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
-       if (!kim_gdata) {
-               pr_err("no mem to allocate");
-               return -ENOMEM;
-       }
-
+       long ret = 0;
        ret = platform_driver_register(&kim_platform_driver);
        if (ret != 0) {
                pr_err("platform drv registration failed");
-               return ST_ERR_FAILURE;
+               return -1;
        }
-       return ST_SUCCESS;
+       return 0;
 }
 
 static void __exit st_kim_deinit(void)
 {
        /* the following returns void */
        platform_driver_unregister(&kim_platform_driver);
-       kfree(kim_gdata);
-       kim_gdata = NULL;
 }
 
 
index ff3270ec7847cc7c9a398d8d504802b15658a211..7de2541f2dea1fb5e9e3522c2cdbc15f29df0d31 100644 (file)
  * since the self-test for chip takes a while
  */
 #define POR_RETRY_COUNT 5
-/*
- * legacy rfkill support where-in 3 rfkill
- * devices are created for the 3 gpios
- * that ST has requested
+
+/**
+ * struct chip_version - save the chip version
  */
-#define LEGACY_RFKILL_SUPPORT
-/*
- * header file for ST provided by KIM
+struct chip_version {
+       unsigned short full;
+       unsigned short chip;
+       unsigned short min_ver;
+       unsigned short maj_ver;
+};
+
+/**
+ * struct kim_data_s - the KIM internal data, embedded as the
+ *     platform's drv data. One for each ST device in the system.
+ * @uim_pid: KIM needs to communicate with UIM to request to install
+ *     the ldisc by opening UART when protocol drivers register.
+ * @kim_pdev: the platform device added in one of the board-XX.c file
+ *     in arch/XX/ directory, 1 for each ST device.
+ * @kim_rcvd: completion handler to notify when data was received,
+ *     mainly used during fw download, which involves multiple send/wait
+ *     for each of the HCI-VS commands.
+ * @ldisc_installed: completion handler to notify that the UIM accepted
+ *     the request to install ldisc, notify from tty_open which suggests
+ *     the ldisc was properly installed.
+ * @resp_buffer: data buffer for the .bts fw file name.
+ * @fw_entry: firmware class struct to request/release the fw.
+ * @gpios: the list of core/chip enable gpios for BT, FM and GPS cores.
+ * @rx_state: the rx state for kim's receive func during fw download.
+ * @rx_count: the rx count for the kim's receive func during fw download.
+ * @rx_skb: all of fw data might not come at once, and hence data storage for
+ *     whole of the fw response, only HCI_EVENTs and hence diff from ST's
+ *     response.
+ * @rfkill: rfkill data for each of the cores to be registered with rfkill.
+ * @rf_protos: proto types of the data registered with rfkill sub-system.
+ * @core_data: ST core's data, which mainly is the tty's disc_data
+ * @version: chip version available via a sysfs entry.
+ *
  */
 struct kim_data_s {
        long uim_pid;
        struct platform_device *kim_pdev;
        struct completion kim_rcvd, ldisc_installed;
-       /* MAX len of the .bts firmware script name */
        char resp_buffer[30];
        const struct firmware *fw_entry;
        long gpios[ST_MAX];
-       struct kobject *kim_kobj;
-/* used by kim_int_recv to validate fw response */
        unsigned long rx_state;
        unsigned long rx_count;
        struct sk_buff *rx_skb;
-#ifdef LEGACY_RFKILL_SUPPORT
        struct rfkill *rfkill[ST_MAX];
        enum proto_type rf_protos[ST_MAX];
-#endif
        struct st_data_s *core_data;
+       struct chip_version version;
 };
 
-long st_kim_start(void);
-long st_kim_stop(void);
-/*
- * called from st_tty_receive to authenticate fw_download
+/**
+ * functions called when 1 of the protocol drivers gets
+ * registered, these need to communicate with UIM to request
+ * ldisc installed, read chip_version, download relevant fw
  */
-void st_kim_recv(void *, const unsigned char *, long count);
+long st_kim_start(void *);
+long st_kim_stop(void *);
 
+void st_kim_recv(void *, const unsigned char *, long count);
 void st_kim_chip_toggle(enum proto_type, enum kim_gpio_state);
-
-void st_kim_complete(void);
-
-/* function called from ST KIM to ST Core, to
- * list out the protocols registered
- */
-void kim_st_list_protocols(struct st_data_s *, char *);
+void st_kim_complete(void *);
+void kim_st_list_protocols(struct st_data_s *, void *);
 
 /*
  * BTS headers
@@ -98,9 +120,13 @@ void kim_st_list_protocols(struct st_data_s *, char *);
 #define ACTION_RUN_SCRIPT       5
 #define ACTION_REMARKS          6
 
-/*
- *  * BRF Firmware header
- *   */
+/**
+ * struct bts_header - the fw file is NOT binary which can
+ *     be sent onto TTY as is. The .bts is more a script
+ *     file which has different types of actions.
+ *     Each such action needs to be parsed by the KIM and
+ *     relevant procedure to be called.
+ */
 struct bts_header {
        uint32_t magic;
        uint32_t version;
@@ -108,9 +134,10 @@ struct bts_header {
        uint8_t actions[0];
 } __attribute__ ((packed));
 
-/*
- *  * BRF Actions structure
- *   */
+/**
+ * struct bts_action - Each .bts action has its own type of
+ *     data.
+ */
 struct bts_action {
        uint16_t type;
        uint16_t size;
@@ -136,8 +163,11 @@ struct bts_action_serial {
        uint32_t flow_control;
 } __attribute__ ((packed));
 
-/* for identifying the change speed HCI VS
- * command
+/**
+ * struct hci_command - the HCI-VS for intrepreting
+ *     the change baud rate of host-side UART, which
+ *     needs to be ignored, since UIM would do that
+ *     when it receives request from KIM for ldisc installation.
  */
 struct hci_command {
        uint8_t prefix;
index 0685a100db6a74eef203986975e5d278a80162cc..7a1fb6de830ddeab60dd5379db5684cf5a31a784 100644 (file)
@@ -34,7 +34,7 @@ static void send_ll_cmd(struct st_data_s *st_data,
 
 static void ll_device_want_to_sleep(struct st_data_s *st_data)
 {
-       pr_info("%s", __func__);
+       pr_debug("%s", __func__);
        /* sanity check */
        if (st_data->ll_state != ST_LL_AWAKE)
                pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND"
@@ -101,7 +101,7 @@ void st_ll_wakeup(struct st_data_s *ll)
 /* called when ST Core wants the state */
 unsigned long st_ll_getstate(struct st_data_s *ll)
 {
-       pr_info(" returning state %ld", ll->ll_state);
+       pr_debug(" returning state %ld", ll->ll_state);
        return ll->ll_state;
 }
 
@@ -127,9 +127,9 @@ unsigned long st_ll_sleep_state(struct st_data_s *st_data,
                break;
        default:
                pr_err(" unknown input/state ");
-               return ST_ERR_FAILURE;
+               return -1;
        }
-       return ST_SUCCESS;
+       return 0;
 }
 
 /* Called from ST CORE to initialize ST LL */
index 77dfbf07e7b8fc5e6c26df9b4654103aaaf0e6da..e4dfacd83d90de419187d0c2fe82e28b6607294c 100644 (file)
@@ -41,6 +41,7 @@
 #define ST_LL_AWAKE_TO_ASLEEP      3
 #define ST_LL_INVALID             4
 
+/* different PM notifications coming from chip */
 #define LL_SLEEP_IND   0x30
 #define LL_SLEEP_ACK   0x31
 #define LL_WAKE_UP_IND 0x32
 long st_ll_init(struct st_data_s *);
 long st_ll_deinit(struct st_data_s *);
 
-/* enable/disable ST LL along with KIM start/stop
+/**
+ * enable/disable ST LL along with KIM start/stop
  * called by ST Core
  */
 void st_ll_enable(struct st_data_s *);
 void st_ll_disable(struct st_data_s *);
 
+/**
+ * various funcs used by ST core to set/get the various PM states
+ * of the chip.
+ */
 unsigned long st_ll_getstate(struct st_data_s *);
 unsigned long st_ll_sleep_state(struct st_data_s *, unsigned char);
 void st_ll_wakeup(struct st_data_s *);
+
 #endif /* ST_LL_H */
index 10311afcbd450f264dd4720cdf2673515e8c4eaf..626bda51ee87e1be92c3252ababe29f4cd89a894 100644 (file)
@@ -14,3 +14,15 @@ Description:
                uninstallation would be ppolling on this device and listening
                on events which would suggest either to install or un-install
                line discipline
+
+What:           /sys/kernel/debug/ti-st/version
+Contact:        Pavan Savoy <pavan_savoy@ti.com>
+Description:
+               WiLink chip's ROM version exposed to user-space for some
+               proprietary protocol stacks to make use of.
+
+What:           /sys/kernel/debug/ti-st/protocols
+Contact:        Pavan Savoy <pavan_savoy@ti.com>
+Description:
+               The reason for chip being ON, the list of protocols registered.
+
diff --git a/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS b/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS
new file mode 100644 (file)
index 0000000..86f5787
--- /dev/null
@@ -0,0 +1,45 @@
+TI DSP/Bridge Driver - Contributors File
+
+The DSP/Bridge project wish to thank all of its contributors, current bridge
+driver is the result of the work of all of them. If any name is accidentally
+omitted, let us know by sending a mail to omar.ramirez@ti.com or
+x095840@ti.com.
+
+Please keep the following list in alphabetical order.
+
+       Suman Anna
+       Sripal Bagadia
+       Felipe Balbi
+       Ohad Ben-Cohen
+       Phil Carmody
+       Deepak Chitriki
+       Felipe Contreras
+       Hiroshi Doyu
+       Seth Forshee
+       Ivan Gomez Castellanos
+       Mark Grosen
+       Ramesh Gupta G
+       Fernando Guzman Lugo
+       Axel Haslam
+       Janet Head
+       Shivananda Hebbar
+       Hari Kanigeri
+       Tony Lindgren
+       Antonio Luna
+       Hari Nagalla
+       Nishanth Menon
+       Ameya Palande
+       Vijay Pasam
+       Gilbert Pitney
+       Omar Ramirez Luna
+       Ernesto Ramos
+       Chris Ring
+       Larry Schiefer
+       Rebecca Schultz Zavin
+       Bhavin Shah
+       Andy Shevchenko
+       Jeff Taylor
+       Roman Tereshonkov
+       Armando Uribe de Leon
+       Nischal Varide
+       Wenbiao Wang
diff --git a/drivers/staging/tidspbridge/Documentation/README b/drivers/staging/tidspbridge/Documentation/README
new file mode 100644 (file)
index 0000000..df6d371
--- /dev/null
@@ -0,0 +1,70 @@
+                        Linux DSP/BIOS Bridge release
+
+DSP/BIOS Bridge overview
+========================
+
+DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more
+attached DSPs.  The GPP is considered the master or "host" processor, and the
+attached DSPs are processing resources that can be utilized by applications
+and drivers running on the GPP.
+
+The abstraction that DSP/BIOS Bridge supplies, is a direct link between a GPP
+program and a DSP task.  This communication link is partitioned into two
+types of sub-links:  messaging (short, fixed-length packets) and data
+streaming (multiple, large buffers).  Each sub-link operates independently,
+and features in-order delivery of data, meaning that messages are delivered
+in the order they were submitted to the message link, and stream buffers are
+delivered in the order they were submitted to the stream link.
+
+In addition, a GPP client can specify what inputs and outputs a DSP task
+uses. DSP tasks typically use message objects for passing control and status
+information and stream objects for efficient streaming of real-time data.
+
+GPP Software Architecture
+=========================
+
+A GPP application communicates with its associated DSP task running on the
+DSP subsystem using the DSP/BIOS Bridge API. For example, a GPP audio
+application can use the API to pass messages to a DSP task that is managing
+data flowing from analog-to-digital converters (ADCs) to digital-to-analog
+converters (DACs).
+
+From the perspective of the GPP OS, the DSP is treated as just another
+peripheral device.   Most high level GPP OS typically support a device driver
+model, whereby applications can safely access and share a hardware peripheral
+through standard driver interfaces.  Therefore, to allow multiple GPP
+applications to share access to the DSP, the GPP side of DSP/BIOS Bridge
+implements a device driver for the DSP.
+
+Since driver interfaces are not always standard across GPP OS, and to provide
+some level of interoperability of application code using DSP/BIOS Bridge
+between GPP OS, DSP/BIOS Bridge provides a standard library of APIs which
+wrap calls into the device driver.   So, rather than calling GPP OS specific
+driver interfaces, applications (and even other device drivers) can use the
+standard API library directly.
+
+DSP Software Architecture
+=========================
+
+For DSP/BIOS, DSP/BIOS Bridge adds a device-independent streaming I/O (STRM)
+interface, a messaging interface (NODE), and a Resource Manager (RM) Server.
+The RM Server runs as a task of DSP/BIOS and is subservient to commands
+and queries from the GPP.  It executes commands to start and stop DSP signal
+processing nodes in response to GPP programs making requests through the
+(GPP-side) API.
+
+DSP tasks started by the RM Server are similar to any other DSP task with two
+important differences:  they must follow a specific task model consisting of
+three C-callable functions (node create, execute, and delete), with specific
+sets of arguments, and they have a pre-defined task environment established
+by the RM Server.
+
+Tasks started by the RM Server communicate using the STRM and NODE interfaces
+and act as servers for their corresponding GPP clients, performing signal
+processing functions as requested by messages sent by their GPP client.
+Typically, a DSP task moves data from source devices to sink devices using
+device independent I/O streams, performing application-specific processing
+and transformations on the data while it is moved.  For example, an audio
+task might perform audio decompression (ADPCM, MPEG, CELP) on data received
+from a GPP audio driver and then send the decompressed linear samples to a
+digital-to-analog converter.
diff --git a/drivers/staging/tidspbridge/Documentation/error-codes b/drivers/staging/tidspbridge/Documentation/error-codes
new file mode 100644 (file)
index 0000000..12826e2
--- /dev/null
@@ -0,0 +1,157 @@
+                       DSP/Bridge Error Code Guide
+
+
+Success code is always taken as 0, except for one case where a success status
+different than 0 can be possible, this is when enumerating a series of dsp
+objects, if the enumeration doesn't have any more objects it is considered as a
+successful case. In this case a positive ENODATA is returned (TODO: Change to
+avoid this case).
+
+Error codes are returned as a negative 1, if an specific code is expected, it
+can be propagated to user space by reading errno symbol defined in errno.h, for
+specific details on the implementation a copy of the standard used should be
+read first.
+
+The error codes used by this driver are:
+
+[EPERM]
+    General driver failure.
+
+    According to the use case the following might apply:
+    - Device is in 'sleep/suspend' mode due to DPM.
+    - User cannot mark end of stream on an input channel.
+    - Requested operation is invalid for the node type.
+    - Invalid alignment for the node messaging buffer.
+    - The specified direction is invalid for the stream.
+    - Invalid stream mode.
+
+[ENOENT]
+    The specified object or file was not found.
+
+[ESRCH]
+    A shared memory buffer contained in a message or stream could not be mapped
+    to the GPP client process's virtual space.
+
+[EIO]
+    Driver interface I/O error.
+
+    or:
+    - Unable to plug channel ISR for configured IRQ.
+    - No free I/O request packets are available.
+
+[ENXIO]
+    Unable to find a named section in DSP executable or a non-existent memory
+    segment identifier was specified.
+
+[EBADF]
+    General error for file handling:
+
+    - Unable to open file.
+    - Unable to read file.
+    - An error occurred while parsing the DSP executable file.
+
+[ENOMEM]
+    A memory allocation failure occurred.
+
+[EACCES]
+    - Unable to read content of DCD data section; this is typically caused by
+    improperly configured nodes.
+    - Unable to decode DCD data section content; this is typically caused by
+    changes to DSP/BIOS Bridge data structures.
+    - Unable to get pointer to DCD data section; this is typically caused by
+    improperly configured UUIDs.
+    - Unable to load file containing DCD data section; this is typically
+    caused by a missing COFF file.
+    - The specified COFF file does not contain a valid node registration
+    section.
+
+[EFAULT]
+    Invalid pointer or handler.
+
+[EEXIST]
+    Attempted to create a channel manager  when one already exists.
+
+[EINVAL]
+    Invalid argument.
+
+[ESPIPE]
+    Symbol not found in the COFF file.  DSPNode_Create will return this if
+    the iAlg function table for an xDAIS socket is not found in the COFF file.
+    In this case, force the symbol to be linked into the COFF file.
+    DSPNode_Create, DSPNode_Execute, and DSPNode_Delete will return this if
+    the create, execute, or delete phase function, respectively, could not be
+    found in the COFF file.
+
+    - No symbol table is loaded/found for this board.
+    - Unable to initialize the ZL COFF parsing module.
+
+[EPIPE]
+    I/O is currently pending.
+
+    - End of stream was already requested on this output channel.
+
+[EDOM]
+    A parameter is specified outside its valid range.
+
+[ENOSYS]
+    The indicated operation is not supported.
+
+[EIDRM]
+    During enumeration a change in the number or properties of the objects
+    has occurred.
+
+[ECHRNG]
+    Attempt to created channel manager with too many channels or channel ID out
+    of range.
+
+[EBADR]
+    The state of the specified object is incorrect for the requested operation.
+
+    - Invalid segment ID.
+
+[ENODATA]
+    Unable to retrieve resource information from the registry.
+
+    - No more registry values.
+
+[ETIME]
+    A timeout occurred before the requested operation could complete.
+
+[ENOSR]
+    A stream has been issued the maximum number of buffers allowed in the
+    stream at once; buffers must be reclaimed from the stream before any more
+    can be issued.
+
+    - No free channels are available.
+
+[EILSEQ]
+    Error occurred in a dynamic loader library function.
+
+[EISCONN]
+    The Specified Connection already exists.
+
+[ENOTCONN]
+    Nodes not connected.
+
+[ETIMEDOUT]
+    Timeout occurred waiting for a response from the hardware.
+
+    - Wait for flush operation on an output channel timed out.
+
+[ECONNREFUSED]
+    No more connections can be made for this node.
+
+[EALREADY]
+    Channel is already in use.
+
+[EREMOTEIO]
+    dwTimeOut parameter was CHNL_IOCNOWAIT, yet no I/O completions were
+    queued.
+
+[ECANCELED]
+    I/O has been cancelled on this channel.
+
+[ENOKEY]
+    Invalid subkey parameter.
+
+    - UUID not found in registry.
diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig
new file mode 100644 (file)
index 0000000..93de4f2
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# DSP Bridge Driver Support
+#
+
+menuconfig TIDSPBRIDGE
+       tristate "DSP Bridge driver"
+       depends on ARCH_OMAP3
+       select OMAP_MBOX_FWK
+       help
+         DSP/BIOS Bridge is designed for platforms that contain a GPP and
+         one or more attached DSPs.  The GPP is considered the master or
+         "host" processor, and the attached DSPs are processing resources
+         that can be utilized by applications and drivers running on the GPP.
+
+         This driver depends on OMAP Mailbox (OMAP_MBOX_FWK).
+
+config TIDSPBRIDGE_DVFS
+       bool "Enable Bridge Dynamic Voltage and Frequency Scaling (DVFS)"
+       depends on TIDSPBRIDGE && OMAP_PM_SRF && CPU_FREQ
+       help
+         DVFS allows DSP Bridge to initiate the operating point change to
+         scale the chip voltage and frequency in order to match the
+         performance and power consumption to the current processing
+         requirements.
+
+config TIDSPBRIDGE_MEMPOOL_SIZE
+       hex "Physical memory pool size (Byte)"
+       depends on TIDSPBRIDGE
+       default 0x600000
+       help
+         Allocate specified size of memory at booting time to avoid allocation
+         failure under heavy memory fragmentation after some use time.
+
+config TIDSPBRIDGE_DEBUG
+       bool "Debug Support"
+       depends on TIDSPBRIDGE
+       help
+         Say Y to enable Bridge debugging capabilities
+
+config TIDSPBRIDGE_RECOVERY
+       bool "Recovery Support"
+       depends on TIDSPBRIDGE
+       default y
+       help
+         In case of DSP fatal error, BRIDGE driver will try to
+         recover itself.
+
+config TIDSPBRIDGE_CACHE_LINE_CHECK
+       bool "Check buffers to be 128 byte aligned"
+       depends on TIDSPBRIDGE
+       help
+         When the DSP processes data, the DSP cache controller loads 128-Byte
+         chunks (lines) from SDRAM and writes the data back in 128-Byte chunks.
+         If a DMM buffer does not start and end on a 128-Byte boundary, the data
+         preceding the start address (SA) from the 128-Byte boundary to the SA
+         and the data at addresses trailing the end address (EA) from the EA to
+         the next 128-Byte boundary will be loaded and written back as well.
+         This can lead to heap corruption. Say Y, to enforce the check for 128
+         byte alignment, buffers failing this check will be rejected.
+
+config TIDSPBRIDGE_WDT3
+       bool "Enable watchdog timer"
+       depends on TIDSPBRIDGE
+       help
+         WTD3 is managed by DSP and once it is enabled, DSP side bridge is in
+         charge of refreshing the timer before overflow, if the DSP hangs MPU
+         will caught the interrupt and try to recover DSP.
+
+config TIDSPBRIDGE_WDT_TIMEOUT
+       int "Watchdog timer timeout (in secs)"
+       depends on TIDSPBRIDGE && TIDSPBRIDGE_WDT3
+       default 5
+       help
+          Watchdog timer timeout value, after that time if the watchdog timer
+          counter is not reset the wdt overflow interrupt will be triggered
+
+config TIDSPBRIDGE_NTFY_PWRERR
+       bool "Notify power errors"
+       depends on TIDSPBRIDGE
+       help
+         Enable notifications to registered clients on the event of power errror
+         trying to suspend bridge driver. Say Y, to signal this event as a fatal
+         error, this will require a bridge restart to recover.
+
+config TIDSPBRIDGE_BACKTRACE
+       bool "Dump backtraces on fatal errors"
+       depends on TIDSPBRIDGE
+       help
+         Enable useful information to backtrace fatal errors. Say Y if you
+         want to dump information for testing purposes.
diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile
new file mode 100644 (file)
index 0000000..6567172
--- /dev/null
@@ -0,0 +1,34 @@
+obj-$(CONFIG_TIDSPBRIDGE)      += bridgedriver.o
+
+libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o
+libservices = services/sync.o services/cfg.o \
+               services/ntfy.o services/services.o
+libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
+               core/tiomap3430_pwr.o core/tiomap_io.o \
+               core/ue_deh.o core/wdt.o core/dsp-clock.o
+libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \
+               pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o
+librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
+               rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \
+               rmgr/nldr.o rmgr/drv_interface.o
+libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \
+                dynload/tramp.o
+libhw = hw/hw_mmu.o
+
+bridgedriver-objs = $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \
+                       $(libdload) $(libhw)
+
+#Machine dependent
+ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \
+               -DTICFG_PROC_VER -DTICFG_EVM_TYPE -DCHNL_SMCLASS \
+               -DCHNL_MESSAGES -DUSE_LEVEL_1_MACROS
+
+ccflags-y += -Idrivers/staging/tidspbridge/include
+ccflags-y += -Idrivers/staging/tidspbridge/services
+ccflags-y += -Idrivers/staging/tidspbridge/core
+ccflags-y += -Idrivers/staging/tidspbridge/pmgr
+ccflags-y += -Idrivers/staging/tidspbridge/rmgr
+ccflags-y += -Idrivers/staging/tidspbridge/dynload
+ccflags-y += -Idrivers/staging/tidspbridge/hw
+ccflags-y += -Iarch/arm
+
diff --git a/drivers/staging/tidspbridge/TODO b/drivers/staging/tidspbridge/TODO
new file mode 100644 (file)
index 0000000..54f4a29
--- /dev/null
@@ -0,0 +1,18 @@
+* Migrate to (and if necessary, extend) existing upstream code such as 
+  iommu, wdt, mcbsp, gptimers
+* Decouple hardware-specific code (e.g. bridge_brd_start/stop/delete/monitor)
+* DOFF binary loader: consider pushing to user space. at the very least
+  eliminate the direct filesystem access
+* Eliminate general services and libraries - use or extend existing kernel
+  libraries instead (e.g. gcf/lcm in nldr.c, global helpers in gen/)
+* Eliminate direct manipulation of OMAP_SYSC_BASE
+* Eliminate list.h : seem like a redundant wrapper to existing kernel lists
+* Eliminate DSP_SUCCEEDED macros and their imposed redundant indentations
+  (adopt the kernel way of checking for return values)
+* Audit interfaces exposed to user space
+* Audit and clean up header files folder
+* Use kernel coding style
+* checkpatch.pl fixes
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Omar Ramirez Luna <omar.ramirez@ti.com>.
diff --git a/drivers/staging/tidspbridge/core/_cmm.h b/drivers/staging/tidspbridge/core/_cmm.h
new file mode 100644 (file)
index 0000000..7660bef
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * _cmm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Private header file defining CMM manager objects and defines needed
+ * by IO manager to register shared memory regions when DSP base image
+ * is loaded(bridge_io_on_loaded).
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _CMM_
+#define _CMM_
+
+/*
+ *  These target side symbols define the beginning and ending addresses
+ *  of the section of shared memory used for shared memory manager CMM.
+ *  They are defined in the *cfg.cmd file by cdb code.
+ */
+#define SHM0_SHARED_BASE_SYM             "_SHM0_BEG"
+#define SHM0_SHARED_END_SYM              "_SHM0_END"
+#define SHM0_SHARED_RESERVED_BASE_SYM    "_SHM0_RSVDSTRT"
+
+/*
+ *  Shared Memory Region #0(SHMSEG0) is used in the following way:
+ *
+ *  |(_SHM0_BEG)                  | (_SHM0_RSVDSTRT)           | (_SHM0_END)
+ *  V                             V                            V
+ *  ------------------------------------------------------------
+ *  |     DSP-side allocations    |    GPP-side allocations    |
+ *  ------------------------------------------------------------
+ *
+ *
+ */
+
+#endif /* _CMM_ */
diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h
new file mode 100644 (file)
index 0000000..16723cd
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * _deh.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Private header for DEH module.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ * Copyright (C) 2010 Felipe Contreras
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _DEH_
+#define _DEH_
+
+#include <dspbridge/ntfy.h>
+#include <dspbridge/dspdefs.h>
+
+/* DEH Manager: only one created per board: */
+struct deh_mgr {
+       struct bridge_dev_context *hbridge_context;     /* Bridge context. */
+       struct ntfy_object *ntfy_obj;   /* NTFY object */
+
+       /* MMU Fault DPC */
+       struct tasklet_struct dpc_tasklet;
+};
+
+#endif /* _DEH_ */
diff --git a/drivers/staging/tidspbridge/core/_msg_sm.h b/drivers/staging/tidspbridge/core/_msg_sm.h
new file mode 100644 (file)
index 0000000..556de5c
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * _msg_sm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Private header file defining msg_ctrl manager objects and defines needed
+ * by IO manager.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _MSG_SM_
+#define _MSG_SM_
+
+#include <dspbridge/list.h>
+#include <dspbridge/msgdefs.h>
+
+/*
+ *  These target side symbols define the beginning and ending addresses
+ *  of the section of shared memory used for messages. They are
+ *  defined in the *cfg.cmd file by cdb code.
+ */
+#define MSG_SHARED_BUFFER_BASE_SYM      "_MSG_BEG"
+#define MSG_SHARED_BUFFER_LIMIT_SYM     "_MSG_END"
+
+#ifndef _CHNL_WORDSIZE
+#define _CHNL_WORDSIZE 4       /* default _CHNL_WORDSIZE is 2 bytes/word */
+#endif
+
+/*
+ *  ======== msg_ctrl ========
+ *  There is a control structure for messages to the DSP, and a control
+ *  structure for messages from the DSP. The shared memory region for
+ *  transferring messages is partitioned as follows:
+ *
+ *  ----------------------------------------------------------
+ *  |Control | Messages from DSP | Control | Messages to DSP |
+ *  ----------------------------------------------------------
+ *
+ *  msg_ctrl control structure for messages to the DSP is used in the following
+ *  way:
+ *
+ *  buf_empty -      This flag is set to FALSE by the GPP after it has output
+ *                  messages for the DSP. The DSP host driver sets it to
+ *                  TRUE after it has copied the messages.
+ *  post_swi -       Set to 1 by the GPP after it has written the messages,
+ *                  set the size, and set buf_empty to FALSE.
+ *                  The DSP Host driver uses SWI_andn of the post_swi field
+ *                  when a host interrupt occurs. The host driver clears
+ *                  this after posting the SWI.
+ *  size -          Number of messages to be read by the DSP.
+ *
+ *  For messages from the DSP:
+ *  buf_empty -      This flag is set to FALSE by the DSP after it has output
+ *                  messages for the GPP. The DPC on the GPP sets it to
+ *                  TRUE after it has copied the messages.
+ *  post_swi -       Set to 1 the DPC on the GPP after copying the messages.
+ *  size -          Number of messages to be read by the GPP.
+ */
+struct msg_ctrl {
+       u32 buf_empty;          /* to/from DSP buffer is empty */
+       u32 post_swi;           /* Set to "1" to post msg_ctrl SWI */
+       u32 size;               /* Number of messages to/from the DSP */
+       u32 resvd;
+};
+
+/*
+ *  ======== msg_mgr ========
+ *  The msg_mgr maintains a list of all MSG_QUEUEs. Each NODE object can
+ *  have msg_queue to hold all messages that come up from the corresponding
+ *  node on the DSP. The msg_mgr also has a shared queue of messages
+ *  ready to go to the DSP.
+ */
+struct msg_mgr {
+       /* The first field must match that in msgobj.h */
+
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+
+       struct io_mgr *hio_mgr; /* IO manager */
+       struct lst_list *queue_list;    /* List of MSG_QUEUEs */
+       spinlock_t msg_mgr_lock;        /* For critical sections */
+       /* Signalled when MsgFrame is available */
+       struct sync_object *sync_event;
+       struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */
+       struct lst_list *msg_used_list; /* MsgFrames ready to go to DSP */
+       u32 msgs_pending;       /* # of queued messages to go to DSP */
+       u32 max_msgs;           /* Max # of msgs that fit in buffer */
+       msg_onexit on_exit;     /* called when RMS_EXIT is received */
+};
+
+/*
+ *  ======== msg_queue ========
+ *  Each NODE has a msg_queue for receiving messages from the
+ *  corresponding node on the DSP. The msg_queue object maintains a list
+ *  of messages that have been sent to the host, but not yet read (MSG_Get),
+ *  and a list of free frames that can be filled when new messages arrive
+ *  from the DSP.
+ *  The msg_queue's hSynEvent gets posted when a message is ready.
+ */
+struct msg_queue {
+       struct list_head list_elem;
+       struct msg_mgr *hmsg_mgr;
+       u32 max_msgs;           /* Node message depth */
+       u32 msgq_id;            /* Node environment pointer */
+       struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */
+       /* Filled MsgFramess waiting to be read */
+       struct lst_list *msg_used_list;
+       void *arg;              /* Handle passed to mgr on_exit callback */
+       struct sync_object *sync_event; /* Signalled when message is ready */
+       struct sync_object *sync_done;  /* For synchronizing cleanup */
+       struct sync_object *sync_done_ack;      /* For synchronizing cleanup */
+       struct ntfy_object *ntfy_obj;   /* For notification of message ready */
+       bool done;              /* TRUE <==> deleting the object */
+       u32 io_msg_pend;        /* Number of pending MSG_get/put calls */
+};
+
+/*
+ *  ======== msg_dspmsg ========
+ */
+struct msg_dspmsg {
+       struct dsp_msg msg;
+       u32 msgq_id;            /* Identifies the node the message goes to */
+};
+
+/*
+ *  ======== msg_frame ========
+ */
+struct msg_frame {
+       struct list_head list_elem;
+       struct msg_dspmsg msg_data;
+};
+
+#endif /* _MSG_SM_ */
diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h
new file mode 100644 (file)
index 0000000..1c1f157
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ * _tiomap.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Definitions and types private to this Bridge driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _TIOMAP_
+#define _TIOMAP_
+
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
+#include <mach-omap2/prm-regbits-34xx.h>
+#include <mach-omap2/cm-regbits-34xx.h>
+#include <dspbridge/devdefs.h>
+#include <hw_defs.h>
+#include <dspbridge/dspioctl.h>        /* for bridge_ioctl_extproc defn */
+#include <dspbridge/sync.h>
+#include <dspbridge/clk.h>
+
+struct map_l4_peripheral {
+       u32 phys_addr;
+       u32 dsp_virt_addr;
+};
+
+#define ARM_MAILBOX_START               0xfffcf000
+#define ARM_MAILBOX_LENGTH              0x800
+
+/* New Registers in OMAP3.1 */
+
+#define TESTBLOCK_ID_START              0xfffed400
+#define TESTBLOCK_ID_LENGTH             0xff
+
+/* ID Returned by OMAP1510 */
+#define TBC_ID_VALUE                    0xB47002F
+
+#define SPACE_LENGTH                    0x2000
+#define API_CLKM_DPLL_DMA               0xfffec000
+#define ARM_INTERRUPT_OFFSET            0xb00
+
+#define BIOS24XX
+
+#define L4_PERIPHERAL_NULL          0x0
+#define DSPVA_PERIPHERAL_NULL       0x0
+
+#define MAX_LOCK_TLB_ENTRIES 15
+
+#define L4_PERIPHERAL_PRM        0x48306000    /*PRM L4 Peripheral */
+#define DSPVA_PERIPHERAL_PRM     0x1181e000
+#define L4_PERIPHERAL_SCM        0x48002000    /*SCM L4 Peripheral */
+#define DSPVA_PERIPHERAL_SCM     0x1181f000
+#define L4_PERIPHERAL_MMU        0x5D000000    /*MMU L4 Peripheral */
+#define DSPVA_PERIPHERAL_MMU     0x11820000
+#define L4_PERIPHERAL_CM        0x48004000     /* Core L4, Clock Management */
+#define DSPVA_PERIPHERAL_CM     0x1181c000
+#define L4_PERIPHERAL_PER        0x48005000    /*  PER */
+#define DSPVA_PERIPHERAL_PER     0x1181d000
+
+#define L4_PERIPHERAL_GPIO1       0x48310000
+#define DSPVA_PERIPHERAL_GPIO1    0x11809000
+#define L4_PERIPHERAL_GPIO2       0x49050000
+#define DSPVA_PERIPHERAL_GPIO2    0x1180a000
+#define L4_PERIPHERAL_GPIO3       0x49052000
+#define DSPVA_PERIPHERAL_GPIO3    0x1180b000
+#define L4_PERIPHERAL_GPIO4       0x49054000
+#define DSPVA_PERIPHERAL_GPIO4    0x1180c000
+#define L4_PERIPHERAL_GPIO5       0x49056000
+#define DSPVA_PERIPHERAL_GPIO5    0x1180d000
+
+#define L4_PERIPHERAL_IVA2WDT      0x49030000
+#define DSPVA_PERIPHERAL_IVA2WDT   0x1180e000
+
+#define L4_PERIPHERAL_DISPLAY     0x48050000
+#define DSPVA_PERIPHERAL_DISPLAY  0x1180f000
+
+#define L4_PERIPHERAL_SSI         0x48058000
+#define DSPVA_PERIPHERAL_SSI      0x11804000
+#define L4_PERIPHERAL_GDD         0x48059000
+#define DSPVA_PERIPHERAL_GDD      0x11805000
+#define L4_PERIPHERAL_SS1         0x4805a000
+#define DSPVA_PERIPHERAL_SS1      0x11806000
+#define L4_PERIPHERAL_SS2         0x4805b000
+#define DSPVA_PERIPHERAL_SS2      0x11807000
+
+#define L4_PERIPHERAL_CAMERA      0x480BC000
+#define DSPVA_PERIPHERAL_CAMERA   0x11819000
+
+#define L4_PERIPHERAL_SDMA        0x48056000
+#define DSPVA_PERIPHERAL_SDMA     0x11810000   /* 0x1181d000 conflict w/ PER */
+
+#define L4_PERIPHERAL_UART1             0x4806a000
+#define DSPVA_PERIPHERAL_UART1          0x11811000
+#define L4_PERIPHERAL_UART2             0x4806c000
+#define DSPVA_PERIPHERAL_UART2          0x11812000
+#define L4_PERIPHERAL_UART3             0x49020000
+#define DSPVA_PERIPHERAL_UART3    0x11813000
+
+#define L4_PERIPHERAL_MCBSP1      0x48074000
+#define DSPVA_PERIPHERAL_MCBSP1   0x11814000
+#define L4_PERIPHERAL_MCBSP2      0x49022000
+#define DSPVA_PERIPHERAL_MCBSP2   0x11815000
+#define L4_PERIPHERAL_MCBSP3      0x49024000
+#define DSPVA_PERIPHERAL_MCBSP3   0x11816000
+#define L4_PERIPHERAL_MCBSP4      0x49026000
+#define DSPVA_PERIPHERAL_MCBSP4   0x11817000
+#define L4_PERIPHERAL_MCBSP5      0x48096000
+#define DSPVA_PERIPHERAL_MCBSP5   0x11818000
+
+#define L4_PERIPHERAL_GPTIMER5    0x49038000
+#define DSPVA_PERIPHERAL_GPTIMER5 0x11800000
+#define L4_PERIPHERAL_GPTIMER6    0x4903a000
+#define DSPVA_PERIPHERAL_GPTIMER6 0x11801000
+#define L4_PERIPHERAL_GPTIMER7    0x4903c000
+#define DSPVA_PERIPHERAL_GPTIMER7 0x11802000
+#define L4_PERIPHERAL_GPTIMER8    0x4903e000
+#define DSPVA_PERIPHERAL_GPTIMER8 0x11803000
+
+#define L4_PERIPHERAL_SPI1      0x48098000
+#define DSPVA_PERIPHERAL_SPI1   0x1181a000
+#define L4_PERIPHERAL_SPI2      0x4809a000
+#define DSPVA_PERIPHERAL_SPI2   0x1181b000
+
+#define L4_PERIPHERAL_MBOX        0x48094000
+#define DSPVA_PERIPHERAL_MBOX     0x11808000
+
+#define PM_GRPSEL_BASE                         0x48307000
+#define DSPVA_GRPSEL_BASE              0x11821000
+
+#define L4_PERIPHERAL_SIDETONE_MCBSP2        0x49028000
+#define DSPVA_PERIPHERAL_SIDETONE_MCBSP2 0x11824000
+#define L4_PERIPHERAL_SIDETONE_MCBSP3        0x4902a000
+#define DSPVA_PERIPHERAL_SIDETONE_MCBSP3 0x11825000
+
+/* define a static array with L4 mappings */
+static const struct map_l4_peripheral l4_peripheral_table[] = {
+       {L4_PERIPHERAL_MBOX, DSPVA_PERIPHERAL_MBOX},
+       {L4_PERIPHERAL_SCM, DSPVA_PERIPHERAL_SCM},
+       {L4_PERIPHERAL_MMU, DSPVA_PERIPHERAL_MMU},
+       {L4_PERIPHERAL_GPTIMER5, DSPVA_PERIPHERAL_GPTIMER5},
+       {L4_PERIPHERAL_GPTIMER6, DSPVA_PERIPHERAL_GPTIMER6},
+       {L4_PERIPHERAL_GPTIMER7, DSPVA_PERIPHERAL_GPTIMER7},
+       {L4_PERIPHERAL_GPTIMER8, DSPVA_PERIPHERAL_GPTIMER8},
+       {L4_PERIPHERAL_GPIO1, DSPVA_PERIPHERAL_GPIO1},
+       {L4_PERIPHERAL_GPIO2, DSPVA_PERIPHERAL_GPIO2},
+       {L4_PERIPHERAL_GPIO3, DSPVA_PERIPHERAL_GPIO3},
+       {L4_PERIPHERAL_GPIO4, DSPVA_PERIPHERAL_GPIO4},
+       {L4_PERIPHERAL_GPIO5, DSPVA_PERIPHERAL_GPIO5},
+       {L4_PERIPHERAL_IVA2WDT, DSPVA_PERIPHERAL_IVA2WDT},
+       {L4_PERIPHERAL_DISPLAY, DSPVA_PERIPHERAL_DISPLAY},
+       {L4_PERIPHERAL_SSI, DSPVA_PERIPHERAL_SSI},
+       {L4_PERIPHERAL_GDD, DSPVA_PERIPHERAL_GDD},
+       {L4_PERIPHERAL_SS1, DSPVA_PERIPHERAL_SS1},
+       {L4_PERIPHERAL_SS2, DSPVA_PERIPHERAL_SS2},
+       {L4_PERIPHERAL_UART1, DSPVA_PERIPHERAL_UART1},
+       {L4_PERIPHERAL_UART2, DSPVA_PERIPHERAL_UART2},
+       {L4_PERIPHERAL_UART3, DSPVA_PERIPHERAL_UART3},
+       {L4_PERIPHERAL_MCBSP1, DSPVA_PERIPHERAL_MCBSP1},
+       {L4_PERIPHERAL_MCBSP2, DSPVA_PERIPHERAL_MCBSP2},
+       {L4_PERIPHERAL_MCBSP3, DSPVA_PERIPHERAL_MCBSP3},
+       {L4_PERIPHERAL_MCBSP4, DSPVA_PERIPHERAL_MCBSP4},
+       {L4_PERIPHERAL_MCBSP5, DSPVA_PERIPHERAL_MCBSP5},
+       {L4_PERIPHERAL_CAMERA, DSPVA_PERIPHERAL_CAMERA},
+       {L4_PERIPHERAL_SPI1, DSPVA_PERIPHERAL_SPI1},
+       {L4_PERIPHERAL_SPI2, DSPVA_PERIPHERAL_SPI2},
+       {L4_PERIPHERAL_PRM, DSPVA_PERIPHERAL_PRM},
+       {L4_PERIPHERAL_CM, DSPVA_PERIPHERAL_CM},
+       {L4_PERIPHERAL_PER, DSPVA_PERIPHERAL_PER},
+       {PM_GRPSEL_BASE, DSPVA_GRPSEL_BASE},
+       {L4_PERIPHERAL_SIDETONE_MCBSP2, DSPVA_PERIPHERAL_SIDETONE_MCBSP2},
+       {L4_PERIPHERAL_SIDETONE_MCBSP3, DSPVA_PERIPHERAL_SIDETONE_MCBSP3},
+       {L4_PERIPHERAL_NULL, DSPVA_PERIPHERAL_NULL}
+};
+
+/*
+ *   15         10                  0
+ *   ---------------------------------
+ *  |0|0|1|0|0|0|c|c|c|i|i|i|i|i|i|i|
+ *  ---------------------------------
+ *  |  (class)  | (module specific) |
+ *
+ *  where  c -> Externel Clock Command: Clk & Autoidle Disable/Enable
+ *  i -> External Clock ID Timers 5,6,7,8, McBSP1,2 and WDT3
+ */
+
+/* MBX_PM_CLK_IDMASK: DSP External clock id mask. */
+#define MBX_PM_CLK_IDMASK   0x7F
+
+/* MBX_PM_CLK_CMDSHIFT: DSP External clock command shift. */
+#define MBX_PM_CLK_CMDSHIFT 7
+
+/* MBX_PM_CLK_CMDMASK: DSP External clock command mask. */
+#define MBX_PM_CLK_CMDMASK 7
+
+/* MBX_PM_MAX_RESOURCES: CORE 1 Clock resources. */
+#define MBX_CORE1_RESOURCES 7
+
+/* MBX_PM_MAX_RESOURCES: CORE 2 Clock Resources. */
+#define MBX_CORE2_RESOURCES 1
+
+/* MBX_PM_MAX_RESOURCES: TOTAL Clock Reosurces. */
+#define MBX_PM_MAX_RESOURCES 11
+
+/*  Power Management Commands */
+#define BPWR_DISABLE_CLOCK     0
+#define BPWR_ENABLE_CLOCK      1
+
+/* OMAP242x specific resources */
+enum bpwr_ext_clock_id {
+       BPWR_GP_TIMER5 = 0x10,
+       BPWR_GP_TIMER6,
+       BPWR_GP_TIMER7,
+       BPWR_GP_TIMER8,
+       BPWR_WD_TIMER3,
+       BPWR_MCBSP1,
+       BPWR_MCBSP2,
+       BPWR_MCBSP3,
+       BPWR_MCBSP4,
+       BPWR_MCBSP5,
+       BPWR_SSI = 0x20
+};
+
+static const u32 bpwr_clkid[] = {
+       (u32) BPWR_GP_TIMER5,
+       (u32) BPWR_GP_TIMER6,
+       (u32) BPWR_GP_TIMER7,
+       (u32) BPWR_GP_TIMER8,
+       (u32) BPWR_WD_TIMER3,
+       (u32) BPWR_MCBSP1,
+       (u32) BPWR_MCBSP2,
+       (u32) BPWR_MCBSP3,
+       (u32) BPWR_MCBSP4,
+       (u32) BPWR_MCBSP5,
+       (u32) BPWR_SSI
+};
+
+struct bpwr_clk_t {
+       u32 clk_id;
+       enum dsp_clk_id clk;
+};
+
+static const struct bpwr_clk_t bpwr_clks[] = {
+       {(u32) BPWR_GP_TIMER5, DSP_CLK_GPT5},
+       {(u32) BPWR_GP_TIMER6, DSP_CLK_GPT6},
+       {(u32) BPWR_GP_TIMER7, DSP_CLK_GPT7},
+       {(u32) BPWR_GP_TIMER8, DSP_CLK_GPT8},
+       {(u32) BPWR_WD_TIMER3, DSP_CLK_WDT3},
+       {(u32) BPWR_MCBSP1, DSP_CLK_MCBSP1},
+       {(u32) BPWR_MCBSP2, DSP_CLK_MCBSP2},
+       {(u32) BPWR_MCBSP3, DSP_CLK_MCBSP3},
+       {(u32) BPWR_MCBSP4, DSP_CLK_MCBSP4},
+       {(u32) BPWR_MCBSP5, DSP_CLK_MCBSP5},
+       {(u32) BPWR_SSI, DSP_CLK_SSI}
+};
+
+/* Interrupt Register Offsets */
+#define INTH_IT_REG_OFFSET              0x00   /* Interrupt register offset */
+#define INTH_MASK_IT_REG_OFFSET         0x04   /* Mask Interrupt reg offset */
+
+#define   DSP_MAILBOX1_INT              10
+/*
+ *  Bit definition of  Interrupt  Level  Registers
+ */
+
+/* Mail Box defines */
+#define MB_ARM2DSP1_REG_OFFSET          0x00
+
+#define MB_ARM2DSP1B_REG_OFFSET         0x04
+
+#define MB_DSP2ARM1B_REG_OFFSET         0x0C
+
+#define MB_ARM2DSP1_FLAG_REG_OFFSET     0x18
+
+#define MB_ARM2DSP_FLAG                 0x0001
+
+#define MBOX_ARM2DSP HW_MBOX_ID0
+#define MBOX_DSP2ARM HW_MBOX_ID1
+#define MBOX_ARM HW_MBOX_U0_ARM
+#define MBOX_DSP HW_MBOX_U1_DSP1
+
+#define ENABLE                          true
+#define DISABLE                         false
+
+#define HIGH_LEVEL                      true
+#define LOW_LEVEL                       false
+
+/* Macro's */
+#define CLEAR_BIT(reg, mask)             (reg &= ~mask)
+#define SET_BIT(reg, mask)               (reg |= mask)
+
+#define SET_GROUP_BITS16(reg, position, width, value) \
+       do {\
+               reg &= ~((0xFFFF >> (16 - (width))) << (position)) ; \
+               reg |= ((value & (0xFFFF >> (16 - (width)))) << (position)); \
+       } while (0);
+
+#define CLEAR_BIT_INDEX(reg, index)   (reg &= ~(1 << (index)))
+
+/* This Bridge driver's device context: */
+struct bridge_dev_context {
+       struct dev_object *hdev_obj;    /* Handle to Bridge device object. */
+       u32 dw_dsp_base_addr;   /* Arm's API to DSP virt base addr */
+       /*
+        * DSP External memory prog address as seen virtually by the OS on
+        * the host side.
+        */
+       u32 dw_dsp_ext_base_addr;       /* See the comment above */
+       u32 dw_api_reg_base;    /* API mem map'd registers */
+       void __iomem *dw_dsp_mmu_base;  /* DSP MMU Mapped registers */
+       u32 dw_api_clk_base;    /* CLK Registers */
+       u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */
+       u32 dw_public_rhea;     /* Pub Rhea */
+       u32 dw_int_addr;        /* MB INTR reg */
+       u32 dw_tc_endianism;    /* TC Endianism register */
+       u32 dw_test_base;       /* DSP MMU Mapped registers */
+       u32 dw_self_loop;       /* Pointer to the selfloop */
+       u32 dw_dsp_start_add;   /* API Boot vector */
+       u32 dw_internal_size;   /* Internal memory size */
+
+       struct omap_mbox *mbox;         /* Mail box handle */
+
+       struct cfg_hostres *resources;  /* Host Resources */
+
+       /*
+        * Processor specific info is set when prog loaded and read from DCD.
+        * [See bridge_dev_ctrl()]  PROC info contains DSP-MMU TLB entries.
+        */
+       /* DMMU TLB entries */
+       struct bridge_ioctl_extproc atlb_entry[BRDIOCTL_NUMOFMMUTLB];
+       u32 dw_brd_state;       /* Last known board state. */
+
+       /* TC Settings */
+       bool tc_word_swap_on;   /* Traffic Controller Word Swap */
+       struct pg_table_attrs *pt_attrs;
+       u32 dsp_per_clks;
+};
+
+/*
+ * If dsp_debug is true, do not branch to the DSP entry
+ * point and wait for DSP to boot.
+ */
+extern s32 dsp_debug;
+
+/*
+ *  ======== sm_interrupt_dsp ========
+ *  Purpose:
+ *      Set interrupt value & send an interrupt to the DSP processor(s).
+ *      This is typicaly used when mailbox interrupt mechanisms allow data
+ *      to be associated with interrupt such as for OMAP's CMD/DATA regs.
+ *  Parameters:
+ *      dev_context:    Handle to Bridge driver defined device info.
+ *      mb_val:         Value associated with interrupt(e.g. mailbox value).
+ *  Returns:
+ *      0:        Interrupt sent;
+ *      else:           Unable to send interrupt.
+ *  Requires:
+ *  Ensures:
+ */
+int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val);
+
+#endif /* _TIOMAP_ */
diff --git a/drivers/staging/tidspbridge/core/_tiomap_pwr.h b/drivers/staging/tidspbridge/core/_tiomap_pwr.h
new file mode 100644 (file)
index 0000000..bd0354d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * _tiomap_pwr.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Definitions and types for the DSP wake/sleep routines.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _TIOMAP_PWR_
+#define _TIOMAP_PWR_
+
+#ifdef CONFIG_PM
+extern s32 dsp_test_sleepstate;
+#endif
+
+extern struct mailbox_context mboxsetting;
+
+/*
+ * ======== wake_dsp =========
+ * Wakes up the DSP from DeepSleep
+ */
+extern int wake_dsp(struct bridge_dev_context *dev_context,
+                                                       void *pargs);
+
+/*
+ * ======== sleep_dsp =========
+ * Places the DSP in DeepSleep.
+ */
+extern int sleep_dsp(struct bridge_dev_context *dev_context,
+                           u32 dw_cmd, void *pargs);
+/*
+ *  ========interrupt_dsp========
+ *       Sends an interrupt to DSP unconditionally.
+ */
+extern void interrupt_dsp(struct bridge_dev_context *dev_context,
+                                                       u16 mb_val);
+
+/*
+ * ======== wake_dsp =========
+ * Wakes up the DSP from DeepSleep
+ */
+extern int dsp_peripheral_clk_ctrl(struct bridge_dev_context
+                                       *dev_context, void *pargs);
+/*
+ *  ======== handle_hibernation_from_dsp ========
+ *     Handle Hibernation requested from DSP
+ */
+int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context);
+/*
+ *  ======== post_scale_dsp ========
+ *     Handle Post Scale notification to DSP
+ */
+int post_scale_dsp(struct bridge_dev_context *dev_context,
+                                                       void *pargs);
+/*
+ *  ======== pre_scale_dsp ========
+ *     Handle Pre Scale notification to DSP
+ */
+int pre_scale_dsp(struct bridge_dev_context *dev_context,
+                                                       void *pargs);
+/*
+ *  ======== handle_constraints_set ========
+ *     Handle constraints request from DSP
+ */
+int handle_constraints_set(struct bridge_dev_context *dev_context,
+                                 void *pargs);
+
+/*
+ *  ======== dsp_clk_wakeup_event_ctrl ========
+ *     This function sets the group selction bits for while
+ *     enabling/disabling.
+ */
+void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable);
+
+#endif /* _TIOMAP_PWR_ */
diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c
new file mode 100644 (file)
index 0000000..bee2b23
--- /dev/null
@@ -0,0 +1,1014 @@
+/*
+ * chnl_sm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implements upper edge functions for Bridge driver channel module.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *      The lower edge functions must be implemented by the Bridge driver
+ *      writer, and are declared in chnl_sm.h.
+ *
+ *      Care is taken in this code to prevent simulataneous access to channel
+ *      queues from
+ *      1. Threads.
+ *      2. io_dpc(), scheduled from the io_isr() as an event.
+ *
+ *      This is done primarily by:
+ *      - Semaphores.
+ *      - state flags in the channel object; and
+ *      - ensuring the IO_Dispatch() routine, which is called from both
+ *        CHNL_AddIOReq() and the DPC(if implemented), is not re-entered.
+ *
+ *  Channel Invariant:
+ *      There is an important invariant condition which must be maintained per
+ *      channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of
+ *      which may cause timeouts and/or failure offunction sync_wait_on_event.
+ *      This invariant condition is:
+ *
+ *          LST_Empty(pchnl->pio_completions) ==> pchnl->sync_event is reset
+ *      and
+ *          !LST_Empty(pchnl->pio_completions) ==> pchnl->sync_event is set.
+ */
+
+#include <linux/types.h>
+
+/*  ----------------------------------- OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Bridge Driver */
+#include <dspbridge/dspdefs.h>
+#include <dspbridge/dspchnl.h>
+#include "_tiomap.h"
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/io_sm.h>
+
+/*  ----------------------------------- Define for This */
+#define USERMODE_ADDR   PAGE_OFFSET
+
+#define MAILBOX_IRQ INT_MAIL_MPU_IRQ
+
+/*  ----------------------------------- Function Prototypes */
+static struct lst_list *create_chirp_list(u32 chirps);
+
+static void free_chirp_list(struct lst_list *chirp_list);
+
+static struct chnl_irp *make_new_chirp(void);
+
+static int search_free_channel(struct chnl_mgr *chnl_mgr_obj,
+                                     u32 *chnl);
+
+/*
+ *  ======== bridge_chnl_add_io_req ========
+ *      Enqueue an I/O request for data transfer on a channel to the DSP.
+ *      The direction (mode) is specified in the channel object. Note the DSP
+ *      address is specified for channels opened in direct I/O mode.
+ */
+int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf,
+                              u32 byte_size, u32 buf_size,
+                              u32 dw_dsp_addr, u32 dw_arg)
+{
+       int status = 0;
+       struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
+       struct chnl_irp *chnl_packet_obj = NULL;
+       struct bridge_dev_context *dev_ctxt;
+       struct dev_object *dev_obj;
+       u8 dw_state;
+       bool is_eos;
+       struct chnl_mgr *chnl_mgr_obj = pchnl->chnl_mgr_obj;
+       u8 *host_sys_buf = NULL;
+       bool sched_dpc = false;
+       u16 mb_val = 0;
+
+       is_eos = (byte_size == 0);
+
+       /* Validate args */
+       if (!host_buf || !pchnl) {
+               status = -EFAULT;
+       } else if (is_eos && CHNL_IS_INPUT(pchnl->chnl_mode)) {
+               status = -EPERM;
+       } else {
+               /*
+                * Check the channel state: only queue chirp if channel state
+                * allows it.
+                */
+               dw_state = pchnl->dw_state;
+               if (dw_state != CHNL_STATEREADY) {
+                       if (dw_state & CHNL_STATECANCEL)
+                               status = -ECANCELED;
+                       else if ((dw_state & CHNL_STATEEOS) &&
+                                CHNL_IS_OUTPUT(pchnl->chnl_mode))
+                               status = -EPIPE;
+                       else
+                               /* No other possible states left */
+                               DBC_ASSERT(0);
+               }
+       }
+
+       dev_obj = dev_get_first();
+       dev_get_bridge_context(dev_obj, &dev_ctxt);
+       if (!dev_ctxt)
+               status = -EFAULT;
+
+       if (status)
+               goto func_end;
+
+       if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1 && host_buf) {
+               if (!(host_buf < (void *)USERMODE_ADDR)) {
+                       host_sys_buf = host_buf;
+                       goto func_cont;
+               }
+               /* if addr in user mode, then copy to kernel space */
+               host_sys_buf = kmalloc(buf_size, GFP_KERNEL);
+               if (host_sys_buf == NULL) {
+                       status = -ENOMEM;
+                       goto func_end;
+               }
+               if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) {
+                       status = copy_from_user(host_sys_buf, host_buf,
+                                               buf_size);
+                       if (status) {
+                               kfree(host_sys_buf);
+                               host_sys_buf = NULL;
+                               status = -EFAULT;
+                               goto func_end;
+                       }
+               }
+       }
+func_cont:
+       /* Mailbox IRQ is disabled to avoid race condition with DMA/ZCPY
+        * channels. DPCCS is held to avoid race conditions with PCPY channels.
+        * If DPC is scheduled in process context (iosm_schedule) and any
+        * non-mailbox interrupt occurs, that DPC will run and break CS. Hence
+        * we disable ALL DPCs. We will try to disable ONLY IO DPC later. */
+       spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock);
+       omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX);
+       if (pchnl->chnl_type == CHNL_PCPY) {
+               /* This is a processor-copy channel. */
+               if (!status && CHNL_IS_OUTPUT(pchnl->chnl_mode)) {
+                       /* Check buffer size on output channels for fit. */
+                       if (byte_size >
+                           io_buf_size(pchnl->chnl_mgr_obj->hio_mgr))
+                               status = -EINVAL;
+
+               }
+       }
+       if (!status) {
+               /* Get a free chirp: */
+               chnl_packet_obj =
+                   (struct chnl_irp *)lst_get_head(pchnl->free_packets_list);
+               if (chnl_packet_obj == NULL)
+                       status = -EIO;
+
+       }
+       if (!status) {
+               /* Enqueue the chirp on the chnl's IORequest queue: */
+               chnl_packet_obj->host_user_buf = chnl_packet_obj->host_sys_buf =
+                   host_buf;
+               if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1)
+                       chnl_packet_obj->host_sys_buf = host_sys_buf;
+
+               /*
+                * Note: for dma chans dw_dsp_addr contains dsp address
+                * of SM buffer.
+                */
+               DBC_ASSERT(chnl_mgr_obj->word_size != 0);
+               /* DSP address */
+               chnl_packet_obj->dsp_tx_addr =
+                   dw_dsp_addr / chnl_mgr_obj->word_size;
+               chnl_packet_obj->byte_size = byte_size;
+               chnl_packet_obj->buf_size = buf_size;
+               /* Only valid for output channel */
+               chnl_packet_obj->dw_arg = dw_arg;
+               chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS :
+                                          CHNL_IOCSTATCOMPLETE);
+               lst_put_tail(pchnl->pio_requests,
+                            (struct list_head *)chnl_packet_obj);
+               pchnl->cio_reqs++;
+               DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets);
+               /*
+                * If end of stream, update the channel state to prevent
+                * more IOR's.
+                */
+               if (is_eos)
+                       pchnl->dw_state |= CHNL_STATEEOS;
+
+               /* Legacy DSM Processor-Copy */
+               DBC_ASSERT(pchnl->chnl_type == CHNL_PCPY);
+               /* Request IO from the DSP */
+               io_request_chnl(chnl_mgr_obj->hio_mgr, pchnl,
+                               (CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT :
+                                IO_OUTPUT), &mb_val);
+               sched_dpc = true;
+
+       }
+       omap_mbox_enable_irq(dev_ctxt->mbox, IRQ_RX);
+       spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
+       if (mb_val != 0)
+               sm_interrupt_dsp(dev_ctxt, mb_val);
+
+       /* Schedule a DPC, to do the actual data transfer */
+       if (sched_dpc)
+               iosm_schedule(chnl_mgr_obj->hio_mgr);
+
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_cancel_io ========
+ *      Return all I/O requests to the client which have not yet been
+ *      transferred.  The channel's I/O completion object is
+ *      signalled, and all the I/O requests are queued as IOC's, with the
+ *      status field set to CHNL_IOCSTATCANCEL.
+ *      This call is typically used in abort situations, and is a prelude to
+ *      chnl_close();
+ */
+int bridge_chnl_cancel_io(struct chnl_object *chnl_obj)
+{
+       int status = 0;
+       struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
+       u32 chnl_id = -1;
+       s8 chnl_mode;
+       struct chnl_irp *chnl_packet_obj;
+       struct chnl_mgr *chnl_mgr_obj = NULL;
+
+       /* Check args: */
+       if (pchnl && pchnl->chnl_mgr_obj) {
+               chnl_id = pchnl->chnl_id;
+               chnl_mode = pchnl->chnl_mode;
+               chnl_mgr_obj = pchnl->chnl_mgr_obj;
+       } else {
+               status = -EFAULT;
+       }
+       if (status)
+               goto func_end;
+
+       /*  Mark this channel as cancelled, to prevent further IORequests or
+        *  IORequests or dispatching. */
+       spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock);
+       pchnl->dw_state |= CHNL_STATECANCEL;
+       if (LST_IS_EMPTY(pchnl->pio_requests))
+               goto func_cont;
+
+       if (pchnl->chnl_type == CHNL_PCPY) {
+               /* Indicate we have no more buffers available for transfer: */
+               if (CHNL_IS_INPUT(pchnl->chnl_mode)) {
+                       io_cancel_chnl(chnl_mgr_obj->hio_mgr, chnl_id);
+               } else {
+                       /* Record that we no longer have output buffers
+                        * available: */
+                       chnl_mgr_obj->dw_output_mask &= ~(1 << chnl_id);
+               }
+       }
+       /* Move all IOR's to IOC queue: */
+       while (!LST_IS_EMPTY(pchnl->pio_requests)) {
+               chnl_packet_obj =
+                   (struct chnl_irp *)lst_get_head(pchnl->pio_requests);
+               if (chnl_packet_obj) {
+                       chnl_packet_obj->byte_size = 0;
+                       chnl_packet_obj->status |= CHNL_IOCSTATCANCEL;
+                       lst_put_tail(pchnl->pio_completions,
+                                    (struct list_head *)chnl_packet_obj);
+                       pchnl->cio_cs++;
+                       pchnl->cio_reqs--;
+                       DBC_ASSERT(pchnl->cio_reqs >= 0);
+               }
+       }
+func_cont:
+       spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_close ========
+ *  Purpose:
+ *      Ensures all pending I/O on this channel is cancelled, discards all
+ *      queued I/O completion notifications, then frees the resources allocated
+ *      for this channel, and makes the corresponding logical channel id
+ *      available for subsequent use.
+ */
+int bridge_chnl_close(struct chnl_object *chnl_obj)
+{
+       int status;
+       struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
+
+       /* Check args: */
+       if (!pchnl) {
+               status = -EFAULT;
+               goto func_cont;
+       }
+       {
+               /* Cancel IO: this ensures no further IO requests or
+                * notifications. */
+               status = bridge_chnl_cancel_io(chnl_obj);
+       }
+func_cont:
+       if (!status) {
+               /* Assert I/O on this channel is now cancelled: Protects
+                * from io_dpc. */
+               DBC_ASSERT((pchnl->dw_state & CHNL_STATECANCEL));
+               /* Invalidate channel object: Protects from
+                * CHNL_GetIOCompletion(). */
+               /* Free the slot in the channel manager: */
+               pchnl->chnl_mgr_obj->ap_channel[pchnl->chnl_id] = NULL;
+               spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
+               pchnl->chnl_mgr_obj->open_channels -= 1;
+               spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
+               if (pchnl->ntfy_obj) {
+                       ntfy_delete(pchnl->ntfy_obj);
+                       kfree(pchnl->ntfy_obj);
+                       pchnl->ntfy_obj = NULL;
+               }
+               /* Reset channel event: (NOTE: user_event freed in user
+                * context.). */
+               if (pchnl->sync_event) {
+                       sync_reset_event(pchnl->sync_event);
+                       kfree(pchnl->sync_event);
+                       pchnl->sync_event = NULL;
+               }
+               /* Free I/O request and I/O completion queues: */
+               if (pchnl->pio_completions) {
+                       free_chirp_list(pchnl->pio_completions);
+                       pchnl->pio_completions = NULL;
+                       pchnl->cio_cs = 0;
+               }
+               if (pchnl->pio_requests) {
+                       free_chirp_list(pchnl->pio_requests);
+                       pchnl->pio_requests = NULL;
+                       pchnl->cio_reqs = 0;
+               }
+               if (pchnl->free_packets_list) {
+                       free_chirp_list(pchnl->free_packets_list);
+                       pchnl->free_packets_list = NULL;
+               }
+               /* Release channel object. */
+               kfree(pchnl);
+               pchnl = NULL;
+       }
+       DBC_ENSURE(status || !pchnl);
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_create ========
+ *      Create a channel manager object, responsible for opening new channels
+ *      and closing old ones for a given board.
+ */
+int bridge_chnl_create(struct chnl_mgr **channel_mgr,
+                             struct dev_object *hdev_obj,
+                             const struct chnl_mgrattrs *mgr_attrts)
+{
+       int status = 0;
+       struct chnl_mgr *chnl_mgr_obj = NULL;
+       u8 max_channels;
+
+       /* Check DBC requirements: */
+       DBC_REQUIRE(channel_mgr != NULL);
+       DBC_REQUIRE(mgr_attrts != NULL);
+       DBC_REQUIRE(mgr_attrts->max_channels > 0);
+       DBC_REQUIRE(mgr_attrts->max_channels <= CHNL_MAXCHANNELS);
+       DBC_REQUIRE(mgr_attrts->word_size != 0);
+
+       /* Allocate channel manager object */
+       chnl_mgr_obj = kzalloc(sizeof(struct chnl_mgr), GFP_KERNEL);
+       if (chnl_mgr_obj) {
+               /*
+                * The max_channels attr must equal the # of supported chnls for
+                * each transport(# chnls for PCPY = DDMA = ZCPY): i.e.
+                *      mgr_attrts->max_channels = CHNL_MAXCHANNELS =
+                *                       DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS.
+                */
+               DBC_ASSERT(mgr_attrts->max_channels == CHNL_MAXCHANNELS);
+               max_channels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY;
+               /* Create array of channels */
+               chnl_mgr_obj->ap_channel = kzalloc(sizeof(struct chnl_object *)
+                                               * max_channels, GFP_KERNEL);
+               if (chnl_mgr_obj->ap_channel) {
+                       /* Initialize chnl_mgr object */
+                       chnl_mgr_obj->dw_type = CHNL_TYPESM;
+                       chnl_mgr_obj->word_size = mgr_attrts->word_size;
+                       /* Total # chnls supported */
+                       chnl_mgr_obj->max_channels = max_channels;
+                       chnl_mgr_obj->open_channels = 0;
+                       chnl_mgr_obj->dw_output_mask = 0;
+                       chnl_mgr_obj->dw_last_output = 0;
+                       chnl_mgr_obj->hdev_obj = hdev_obj;
+                       spin_lock_init(&chnl_mgr_obj->chnl_mgr_lock);
+               } else {
+                       status = -ENOMEM;
+               }
+       } else {
+               status = -ENOMEM;
+       }
+
+       if (status) {
+               bridge_chnl_destroy(chnl_mgr_obj);
+               *channel_mgr = NULL;
+       } else {
+               /* Return channel manager object to caller... */
+               *channel_mgr = chnl_mgr_obj;
+       }
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_destroy ========
+ *  Purpose:
+ *      Close all open channels, and destroy the channel manager.
+ */
+int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr)
+{
+       int status = 0;
+       struct chnl_mgr *chnl_mgr_obj = hchnl_mgr;
+       u32 chnl_id;
+
+       if (hchnl_mgr) {
+               /* Close all open channels: */
+               for (chnl_id = 0; chnl_id < chnl_mgr_obj->max_channels;
+                    chnl_id++) {
+                       status =
+                           bridge_chnl_close(chnl_mgr_obj->ap_channel
+                                             [chnl_id]);
+                       if (status)
+                               dev_dbg(bridge, "%s: Error status 0x%x\n",
+                                       __func__, status);
+               }
+
+               /* Free channel manager object: */
+               kfree(chnl_mgr_obj->ap_channel);
+
+               /* Set hchnl_mgr to NULL in device object. */
+               dev_set_chnl_mgr(chnl_mgr_obj->hdev_obj, NULL);
+               /* Free this Chnl Mgr object: */
+               kfree(hchnl_mgr);
+       } else {
+               status = -EFAULT;
+       }
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_flush_io ========
+ *  purpose:
+ *      Flushes all the outstanding data requests on a channel.
+ */
+int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout)
+{
+       int status = 0;
+       struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
+       s8 chnl_mode = -1;
+       struct chnl_mgr *chnl_mgr_obj;
+       struct chnl_ioc chnl_ioc_obj;
+       /* Check args: */
+       if (pchnl) {
+               if ((timeout == CHNL_IOCNOWAIT)
+                   && CHNL_IS_OUTPUT(pchnl->chnl_mode)) {
+                       status = -EINVAL;
+               } else {
+                       chnl_mode = pchnl->chnl_mode;
+                       chnl_mgr_obj = pchnl->chnl_mgr_obj;
+               }
+       } else {
+               status = -EFAULT;
+       }
+       if (!status) {
+               /* Note: Currently, if another thread continues to add IO
+                * requests to this channel, this function will continue to
+                * flush all such queued IO requests. */
+               if (CHNL_IS_OUTPUT(chnl_mode)
+                   && (pchnl->chnl_type == CHNL_PCPY)) {
+                       /* Wait for IO completions, up to the specified
+                        * timeout: */
+                       while (!LST_IS_EMPTY(pchnl->pio_requests) && !status) {
+                               status = bridge_chnl_get_ioc(chnl_obj,
+                                               timeout, &chnl_ioc_obj);
+                               if (status)
+                                       continue;
+
+                               if (chnl_ioc_obj.status & CHNL_IOCSTATTIMEOUT)
+                                       status = -ETIMEDOUT;
+
+                       }
+               } else {
+                       status = bridge_chnl_cancel_io(chnl_obj);
+                       /* Now, leave the channel in the ready state: */
+                       pchnl->dw_state &= ~CHNL_STATECANCEL;
+               }
+       }
+       DBC_ENSURE(status || LST_IS_EMPTY(pchnl->pio_requests));
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_get_info ========
+ *  Purpose:
+ *      Retrieve information related to a channel.
+ */
+int bridge_chnl_get_info(struct chnl_object *chnl_obj,
+                            struct chnl_info *channel_info)
+{
+       int status = 0;
+       struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
+       if (channel_info != NULL) {
+               if (pchnl) {
+                       /* Return the requested information: */
+                       channel_info->hchnl_mgr = pchnl->chnl_mgr_obj;
+                       channel_info->event_obj = pchnl->user_event;
+                       channel_info->cnhl_id = pchnl->chnl_id;
+                       channel_info->dw_mode = pchnl->chnl_mode;
+                       channel_info->bytes_tx = pchnl->bytes_moved;
+                       channel_info->process = pchnl->process;
+                       channel_info->sync_event = pchnl->sync_event;
+                       channel_info->cio_cs = pchnl->cio_cs;
+                       channel_info->cio_reqs = pchnl->cio_reqs;
+                       channel_info->dw_state = pchnl->dw_state;
+               } else {
+                       status = -EFAULT;
+               }
+       } else {
+               status = -EFAULT;
+       }
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_get_ioc ========
+ *      Optionally wait for I/O completion on a channel.  Dequeue an I/O
+ *      completion record, which contains information about the completed
+ *      I/O request.
+ *      Note: Ensures Channel Invariant (see notes above).
+ */
+int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
+                           struct chnl_ioc *chan_ioc)
+{
+       int status = 0;
+       struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
+       struct chnl_irp *chnl_packet_obj;
+       int stat_sync;
+       bool dequeue_ioc = true;
+       struct chnl_ioc ioc = { NULL, 0, 0, 0, 0 };
+       u8 *host_sys_buf = NULL;
+       struct bridge_dev_context *dev_ctxt;
+       struct dev_object *dev_obj;
+
+       /* Check args: */
+       if (!chan_ioc || !pchnl) {
+               status = -EFAULT;
+       } else if (timeout == CHNL_IOCNOWAIT) {
+               if (LST_IS_EMPTY(pchnl->pio_completions))
+                       status = -EREMOTEIO;
+
+       }
+
+       dev_obj = dev_get_first();
+       dev_get_bridge_context(dev_obj, &dev_ctxt);
+       if (!dev_ctxt)
+               status = -EFAULT;
+
+       if (status)
+               goto func_end;
+
+       ioc.status = CHNL_IOCSTATCOMPLETE;
+       if (timeout !=
+           CHNL_IOCNOWAIT && LST_IS_EMPTY(pchnl->pio_completions)) {
+               if (timeout == CHNL_IOCINFINITE)
+                       timeout = SYNC_INFINITE;
+
+               stat_sync = sync_wait_on_event(pchnl->sync_event, timeout);
+               if (stat_sync == -ETIME) {
+                       /* No response from DSP */
+                       ioc.status |= CHNL_IOCSTATTIMEOUT;
+                       dequeue_ioc = false;
+               } else if (stat_sync == -EPERM) {
+                       /* This can occur when the user mode thread is
+                        * aborted (^C), or when _VWIN32_WaitSingleObject()
+                        * fails due to unkown causes. */
+                       /* Even though Wait failed, there may be something in
+                        * the Q: */
+                       if (LST_IS_EMPTY(pchnl->pio_completions)) {
+                               ioc.status |= CHNL_IOCSTATCANCEL;
+                               dequeue_ioc = false;
+                       }
+               }
+       }
+       /* See comment in AddIOReq */
+       spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
+       omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX);
+       if (dequeue_ioc) {
+               /* Dequeue IOC and set chan_ioc; */
+               DBC_ASSERT(!LST_IS_EMPTY(pchnl->pio_completions));
+               chnl_packet_obj =
+                   (struct chnl_irp *)lst_get_head(pchnl->pio_completions);
+               /* Update chan_ioc from channel state and chirp: */
+               if (chnl_packet_obj) {
+                       pchnl->cio_cs--;
+                       /*  If this is a zero-copy channel, then set IOC's pbuf
+                        *  to the DSP's address. This DSP address will get
+                        *  translated to user's virtual addr later. */
+                       {
+                               host_sys_buf = chnl_packet_obj->host_sys_buf;
+                               ioc.pbuf = chnl_packet_obj->host_user_buf;
+                       }
+                       ioc.byte_size = chnl_packet_obj->byte_size;
+                       ioc.buf_size = chnl_packet_obj->buf_size;
+                       ioc.dw_arg = chnl_packet_obj->dw_arg;
+                       ioc.status |= chnl_packet_obj->status;
+                       /* Place the used chirp on the free list: */
+                       lst_put_tail(pchnl->free_packets_list,
+                                    (struct list_head *)chnl_packet_obj);
+               } else {
+                       ioc.pbuf = NULL;
+                       ioc.byte_size = 0;
+               }
+       } else {
+               ioc.pbuf = NULL;
+               ioc.byte_size = 0;
+               ioc.dw_arg = 0;
+               ioc.buf_size = 0;
+       }
+       /* Ensure invariant: If any IOC's are queued for this channel... */
+       if (!LST_IS_EMPTY(pchnl->pio_completions)) {
+               /*  Since DSPStream_Reclaim() does not take a timeout
+                *  parameter, we pass the stream's timeout value to
+                *  bridge_chnl_get_ioc. We cannot determine whether or not
+                *  we have waited in User mode. Since the stream's timeout
+                *  value may be non-zero, we still have to set the event.
+                *  Therefore, this optimization is taken out.
+                *
+                *  if (timeout == CHNL_IOCNOWAIT) {
+                *    ... ensure event is set..
+                *      sync_set_event(pchnl->sync_event);
+                *  } */
+               sync_set_event(pchnl->sync_event);
+       } else {
+               /* else, if list is empty, ensure event is reset. */
+               sync_reset_event(pchnl->sync_event);
+       }
+       omap_mbox_enable_irq(dev_ctxt->mbox, IRQ_RX);
+       spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
+       if (dequeue_ioc
+           && (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1)) {
+               if (!(ioc.pbuf < (void *)USERMODE_ADDR))
+                       goto func_cont;
+
+               /* If the addr is in user mode, then copy it */
+               if (!host_sys_buf || !ioc.pbuf) {
+                       status = -EFAULT;
+                       goto func_cont;
+               }
+               if (!CHNL_IS_INPUT(pchnl->chnl_mode))
+                       goto func_cont1;
+
+               /*host_user_buf */
+               status = copy_to_user(ioc.pbuf, host_sys_buf, ioc.byte_size);
+               if (status) {
+                       if (current->flags & PF_EXITING)
+                               status = 0;
+               }
+               if (status)
+                       status = -EFAULT;
+func_cont1:
+               kfree(host_sys_buf);
+       }
+func_cont:
+       /* Update User's IOC block: */
+       *chan_ioc = ioc;
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_get_mgr_info ========
+ *      Retrieve information related to the channel manager.
+ */
+int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr, u32 ch_id,
+                                struct chnl_mgrinfo *mgr_info)
+{
+       int status = 0;
+       struct chnl_mgr *chnl_mgr_obj = (struct chnl_mgr *)hchnl_mgr;
+
+       if (mgr_info != NULL) {
+               if (ch_id <= CHNL_MAXCHANNELS) {
+                       if (hchnl_mgr) {
+                               /* Return the requested information: */
+                               mgr_info->chnl_obj =
+                                   chnl_mgr_obj->ap_channel[ch_id];
+                               mgr_info->open_channels =
+                                   chnl_mgr_obj->open_channels;
+                               mgr_info->dw_type = chnl_mgr_obj->dw_type;
+                               /* total # of chnls */
+                               mgr_info->max_channels =
+                                   chnl_mgr_obj->max_channels;
+                       } else {
+                               status = -EFAULT;
+                       }
+               } else {
+                       status = -ECHRNG;
+               }
+       } else {
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_idle ========
+ *      Idles a particular channel.
+ */
+int bridge_chnl_idle(struct chnl_object *chnl_obj, u32 timeout,
+                           bool flush_data)
+{
+       s8 chnl_mode;
+       struct chnl_mgr *chnl_mgr_obj;
+       int status = 0;
+
+       DBC_REQUIRE(chnl_obj);
+
+       chnl_mode = chnl_obj->chnl_mode;
+       chnl_mgr_obj = chnl_obj->chnl_mgr_obj;
+
+       if (CHNL_IS_OUTPUT(chnl_mode) && !flush_data) {
+               /* Wait for IO completions, up to the specified timeout: */
+               status = bridge_chnl_flush_io(chnl_obj, timeout);
+       } else {
+               status = bridge_chnl_cancel_io(chnl_obj);
+
+               /* Reset the byte count and put channel back in ready state. */
+               chnl_obj->bytes_moved = 0;
+               chnl_obj->dw_state &= ~CHNL_STATECANCEL;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_open ========
+ *      Open a new half-duplex channel to the DSP board.
+ */
+int bridge_chnl_open(struct chnl_object **chnl,
+                           struct chnl_mgr *hchnl_mgr, s8 chnl_mode,
+                           u32 ch_id, const struct chnl_attr *pattrs)
+{
+       int status = 0;
+       struct chnl_mgr *chnl_mgr_obj = hchnl_mgr;
+       struct chnl_object *pchnl = NULL;
+       struct sync_object *sync_event = NULL;
+       /* Ensure DBC requirements: */
+       DBC_REQUIRE(chnl != NULL);
+       DBC_REQUIRE(pattrs != NULL);
+       DBC_REQUIRE(hchnl_mgr != NULL);
+       *chnl = NULL;
+       /* Validate Args: */
+       if (pattrs->uio_reqs == 0) {
+               status = -EINVAL;
+       } else {
+               if (!hchnl_mgr) {
+                       status = -EFAULT;
+               } else {
+                       if (ch_id != CHNL_PICKFREE) {
+                               if (ch_id >= chnl_mgr_obj->max_channels)
+                                       status = -ECHRNG;
+                               else if (chnl_mgr_obj->ap_channel[ch_id] !=
+                                        NULL)
+                                       status = -EALREADY;
+                       } else {
+                               /* Check for free channel */
+                               status =
+                                   search_free_channel(chnl_mgr_obj, &ch_id);
+                       }
+               }
+       }
+       if (status)
+               goto func_end;
+
+       DBC_ASSERT(ch_id < chnl_mgr_obj->max_channels);
+       /* Create channel object: */
+       pchnl = kzalloc(sizeof(struct chnl_object), GFP_KERNEL);
+       if (!pchnl) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       /* Protect queues from io_dpc: */
+       pchnl->dw_state = CHNL_STATECANCEL;
+       /* Allocate initial IOR and IOC queues: */
+       pchnl->free_packets_list = create_chirp_list(pattrs->uio_reqs);
+       pchnl->pio_requests = create_chirp_list(0);
+       pchnl->pio_completions = create_chirp_list(0);
+       pchnl->chnl_packets = pattrs->uio_reqs;
+       pchnl->cio_cs = 0;
+       pchnl->cio_reqs = 0;
+       sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
+       if (sync_event)
+               sync_init_event(sync_event);
+       else
+               status = -ENOMEM;
+
+       if (!status) {
+               pchnl->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
+                                                       GFP_KERNEL);
+               if (pchnl->ntfy_obj)
+                       ntfy_init(pchnl->ntfy_obj);
+               else
+                       status = -ENOMEM;
+       }
+
+       if (!status) {
+               if (pchnl->pio_completions && pchnl->pio_requests &&
+                   pchnl->free_packets_list) {
+                       /* Initialize CHNL object fields: */
+                       pchnl->chnl_mgr_obj = chnl_mgr_obj;
+                       pchnl->chnl_id = ch_id;
+                       pchnl->chnl_mode = chnl_mode;
+                       pchnl->user_event = sync_event;
+                       pchnl->sync_event = sync_event;
+                       /* Get the process handle */
+                       pchnl->process = current->tgid;
+                       pchnl->pcb_arg = 0;
+                       pchnl->bytes_moved = 0;
+                       /* Default to proc-copy */
+                       pchnl->chnl_type = CHNL_PCPY;
+               } else {
+                       status = -ENOMEM;
+               }
+       }
+
+       if (status) {
+               /* Free memory */
+               if (pchnl->pio_completions) {
+                       free_chirp_list(pchnl->pio_completions);
+                       pchnl->pio_completions = NULL;
+                       pchnl->cio_cs = 0;
+               }
+               if (pchnl->pio_requests) {
+                       free_chirp_list(pchnl->pio_requests);
+                       pchnl->pio_requests = NULL;
+               }
+               if (pchnl->free_packets_list) {
+                       free_chirp_list(pchnl->free_packets_list);
+                       pchnl->free_packets_list = NULL;
+               }
+               kfree(sync_event);
+               sync_event = NULL;
+
+               if (pchnl->ntfy_obj) {
+                       ntfy_delete(pchnl->ntfy_obj);
+                       kfree(pchnl->ntfy_obj);
+                       pchnl->ntfy_obj = NULL;
+               }
+               kfree(pchnl);
+       } else {
+               /* Insert channel object in channel manager: */
+               chnl_mgr_obj->ap_channel[pchnl->chnl_id] = pchnl;
+               spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock);
+               chnl_mgr_obj->open_channels++;
+               spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
+               /* Return result... */
+               pchnl->dw_state = CHNL_STATEREADY;
+               *chnl = pchnl;
+       }
+func_end:
+       DBC_ENSURE((!status && pchnl) || (*chnl == NULL));
+       return status;
+}
+
+/*
+ *  ======== bridge_chnl_register_notify ========
+ *      Registers for events on a particular channel.
+ */
+int bridge_chnl_register_notify(struct chnl_object *chnl_obj,
+                                   u32 event_mask, u32 notify_type,
+                                   struct dsp_notification *hnotification)
+{
+       int status = 0;
+
+       DBC_ASSERT(!(event_mask & ~(DSP_STREAMDONE | DSP_STREAMIOCOMPLETION)));
+
+       if (event_mask)
+               status = ntfy_register(chnl_obj->ntfy_obj, hnotification,
+                                               event_mask, notify_type);
+       else
+               status = ntfy_unregister(chnl_obj->ntfy_obj, hnotification);
+
+       return status;
+}
+
+/*
+ *  ======== create_chirp_list ========
+ *  Purpose:
+ *      Initialize a queue of channel I/O Request/Completion packets.
+ *  Parameters:
+ *      chirps:     Number of Chirps to allocate.
+ *  Returns:
+ *      Pointer to queue of IRPs, or NULL.
+ *  Requires:
+ *  Ensures:
+ */
+static struct lst_list *create_chirp_list(u32 chirps)
+{
+       struct lst_list *chirp_list;
+       struct chnl_irp *chnl_packet_obj;
+       u32 i;
+
+       chirp_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL);
+
+       if (chirp_list) {
+               INIT_LIST_HEAD(&chirp_list->head);
+               /* Make N chirps and place on queue. */
+               for (i = 0; (i < chirps)
+                    && ((chnl_packet_obj = make_new_chirp()) != NULL); i++) {
+                       lst_put_tail(chirp_list,
+                                    (struct list_head *)chnl_packet_obj);
+               }
+
+               /* If we couldn't allocate all chirps, free those allocated: */
+               if (i != chirps) {
+                       free_chirp_list(chirp_list);
+                       chirp_list = NULL;
+               }
+       }
+
+       return chirp_list;
+}
+
+/*
+ *  ======== free_chirp_list ========
+ *  Purpose:
+ *      Free the queue of Chirps.
+ */
+static void free_chirp_list(struct lst_list *chirp_list)
+{
+       DBC_REQUIRE(chirp_list != NULL);
+
+       while (!LST_IS_EMPTY(chirp_list))
+               kfree(lst_get_head(chirp_list));
+
+       kfree(chirp_list);
+}
+
+/*
+ *  ======== make_new_chirp ========
+ *      Allocate the memory for a new channel IRP.
+ */
+static struct chnl_irp *make_new_chirp(void)
+{
+       struct chnl_irp *chnl_packet_obj;
+
+       chnl_packet_obj = kzalloc(sizeof(struct chnl_irp), GFP_KERNEL);
+       if (chnl_packet_obj != NULL) {
+               /* lst_init_elem only resets the list's member values. */
+               lst_init_elem(&chnl_packet_obj->link);
+       }
+
+       return chnl_packet_obj;
+}
+
+/*
+ *  ======== search_free_channel ========
+ *      Search for a free channel slot in the array of channel pointers.
+ */
+static int search_free_channel(struct chnl_mgr *chnl_mgr_obj,
+                                     u32 *chnl)
+{
+       int status = -ENOSR;
+       u32 i;
+
+       DBC_REQUIRE(chnl_mgr_obj);
+
+       for (i = 0; i < chnl_mgr_obj->max_channels; i++) {
+               if (chnl_mgr_obj->ap_channel[i] == NULL) {
+                       status = 0;
+                       *chnl = i;
+                       break;
+               }
+       }
+
+       return status;
+}
diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c
new file mode 100644 (file)
index 0000000..5b1a0c5
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * clk.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Clock and Timer services.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+#include <plat/dmtimer.h>
+#include <plat/mcbsp.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/cfg.h>
+#include <dspbridge/drv.h>
+#include <dspbridge/dev.h>
+#include "_tiomap.h"
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/clk.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+
+#define OMAP_SSI_OFFSET                        0x58000
+#define OMAP_SSI_SIZE                  0x1000
+#define OMAP_SSI_SYSCONFIG_OFFSET      0x10
+
+#define SSI_AUTOIDLE                   (1 << 0)
+#define SSI_SIDLE_SMARTIDLE            (2 << 3)
+#define SSI_MIDLE_NOIDLE               (1 << 12)
+
+/* Clk types requested by the dsp */
+#define IVA2_CLK       0
+#define GPT_CLK                1
+#define WDT_CLK                2
+#define MCBSP_CLK      3
+#define SSI_CLK                4
+
+/* Bridge GPT id (1 - 4), DM Timer id (5 - 8) */
+#define DMT_ID(id) ((id) + 4)
+
+/* Bridge MCBSP id (6 - 10), OMAP Mcbsp id (0 - 4) */
+#define MCBSP_ID(id) ((id) - 6)
+
+static struct omap_dm_timer *timer[4];
+
+struct clk *iva2_clk;
+
+struct dsp_ssi {
+       struct clk *sst_fck;
+       struct clk *ssr_fck;
+       struct clk *ick;
+};
+
+static struct dsp_ssi ssi;
+
+static u32 dsp_clocks;
+
+static inline u32 is_dsp_clk_active(u32 clk, u8 id)
+{
+       return clk & (1 << id);
+}
+
+static inline void set_dsp_clk_active(u32 *clk, u8 id)
+{
+       *clk |= (1 << id);
+}
+
+static inline void set_dsp_clk_inactive(u32 *clk, u8 id)
+{
+       *clk &= ~(1 << id);
+}
+
+static s8 get_clk_type(u8 id)
+{
+       s8 type;
+
+       if (id == DSP_CLK_IVA2)
+               type = IVA2_CLK;
+       else if (id <= DSP_CLK_GPT8)
+               type = GPT_CLK;
+       else if (id == DSP_CLK_WDT3)
+               type = WDT_CLK;
+       else if (id <= DSP_CLK_MCBSP5)
+               type = MCBSP_CLK;
+       else if (id == DSP_CLK_SSI)
+               type = SSI_CLK;
+       else
+               type = -1;
+
+       return type;
+}
+
+/*
+ *  ======== dsp_clk_exit ========
+ *  Purpose:
+ *      Cleanup CLK module.
+ */
+void dsp_clk_exit(void)
+{
+       dsp_clock_disable_all(dsp_clocks);
+
+       clk_put(iva2_clk);
+       clk_put(ssi.sst_fck);
+       clk_put(ssi.ssr_fck);
+       clk_put(ssi.ick);
+}
+
+/*
+ *  ======== dsp_clk_init ========
+ *  Purpose:
+ *      Initialize CLK module.
+ */
+void dsp_clk_init(void)
+{
+       static struct platform_device dspbridge_device;
+
+       dspbridge_device.dev.bus = &platform_bus_type;
+
+       iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck");
+       if (IS_ERR(iva2_clk))
+               dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk);
+
+       ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck");
+       ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck");
+       ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick");
+
+       if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick))
+               dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n",
+                                       ssi.sst_fck, ssi.ssr_fck, ssi.ick);
+}
+
+#ifdef CONFIG_OMAP_MCBSP
+static void mcbsp_clk_prepare(bool flag, u8 id)
+{
+       struct cfg_hostres *resources;
+       struct dev_object *hdev_object = NULL;
+       struct bridge_dev_context *bridge_context = NULL;
+       u32 val;
+
+       hdev_object = (struct dev_object *)drv_get_first_dev_object();
+       if (!hdev_object)
+               return;
+
+       dev_get_bridge_context(hdev_object, &bridge_context);
+       if (!bridge_context)
+               return;
+
+       resources = bridge_context->resources;
+       if (!resources)
+               return;
+
+       if (flag) {
+               if (id == DSP_CLK_MCBSP1) {
+                       /* set MCBSP1_CLKS, on McBSP1 ON */
+                       val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
+                       val |= 1 << 2;
+                       __raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
+               } else if (id == DSP_CLK_MCBSP2) {
+                       /* set MCBSP2_CLKS, on McBSP2 ON */
+                       val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
+                       val |= 1 << 6;
+                       __raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
+               }
+       } else {
+               if (id == DSP_CLK_MCBSP1) {
+                       /* clear MCBSP1_CLKS, on McBSP1 OFF */
+                       val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
+                       val &= ~(1 << 2);
+                       __raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
+               } else if (id == DSP_CLK_MCBSP2) {
+                       /* clear MCBSP2_CLKS, on McBSP2 OFF */
+                       val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
+                       val &= ~(1 << 6);
+                       __raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
+               }
+       }
+}
+#endif
+
+/**
+ * dsp_gpt_wait_overflow - set gpt overflow and wait for fixed timeout
+ * @clk_id:      GP Timer clock id.
+ * @load:        Overflow value.
+ *
+ * Sets an overflow interrupt for the desired GPT waiting for a timeout
+ * of 5 msecs for the interrupt to occur.
+ */
+void dsp_gpt_wait_overflow(short int clk_id, unsigned int load)
+{
+       struct omap_dm_timer *gpt = timer[clk_id - 1];
+       unsigned long timeout;
+
+       if (!gpt)
+               return;
+
+       /* Enable overflow interrupt */
+       omap_dm_timer_set_int_enable(gpt, OMAP_TIMER_INT_OVERFLOW);
+
+       /*
+        * Set counter value to overflow counter after
+        * one tick and start timer.
+        */
+       omap_dm_timer_set_load_start(gpt, 0, load);
+
+       /* Wait 80us for timer to overflow */
+       udelay(80);
+
+       timeout = msecs_to_jiffies(5);
+       /* Check interrupt status and wait for interrupt */
+       while (!(omap_dm_timer_read_status(gpt) & OMAP_TIMER_INT_OVERFLOW)) {
+               if (time_is_after_jiffies(timeout)) {
+                       pr_err("%s: GPTimer interrupt failed\n", __func__);
+                       break;
+               }
+       }
+}
+
+/*
+ *  ======== dsp_clk_enable ========
+ *  Purpose:
+ *      Enable Clock .
+ *
+ */
+int dsp_clk_enable(enum dsp_clk_id clk_id)
+{
+       int status = 0;
+
+       if (is_dsp_clk_active(dsp_clocks, clk_id)) {
+               dev_err(bridge, "WARN: clock id %d already enabled\n", clk_id);
+               goto out;
+       }
+
+       switch (get_clk_type(clk_id)) {
+       case IVA2_CLK:
+               clk_enable(iva2_clk);
+               break;
+       case GPT_CLK:
+               timer[clk_id - 1] =
+                               omap_dm_timer_request_specific(DMT_ID(clk_id));
+               break;
+#ifdef CONFIG_OMAP_MCBSP
+       case MCBSP_CLK:
+               mcbsp_clk_prepare(true, clk_id);
+               omap_mcbsp_set_io_type(MCBSP_ID(clk_id), OMAP_MCBSP_POLL_IO);
+               omap_mcbsp_request(MCBSP_ID(clk_id));
+               break;
+#endif
+       case WDT_CLK:
+               dev_err(bridge, "ERROR: DSP requested to enable WDT3 clk\n");
+               break;
+       case SSI_CLK:
+               clk_enable(ssi.sst_fck);
+               clk_enable(ssi.ssr_fck);
+               clk_enable(ssi.ick);
+
+               /*
+                * The SSI module need to configured not to have the Forced
+                * idle for master interface. If it is set to forced idle,
+                * the SSI module is transitioning to standby thereby causing
+                * the client in the DSP hang waiting for the SSI module to
+                * be active after enabling the clocks
+                */
+               ssi_clk_prepare(true);
+               break;
+       default:
+               dev_err(bridge, "Invalid clock id for enable\n");
+               status = -EPERM;
+       }
+
+       if (!status)
+               set_dsp_clk_active(&dsp_clocks, clk_id);
+
+out:
+       return status;
+}
+
+/**
+ * dsp_clock_enable_all - Enable clocks used by the DSP
+ * @dev_context                Driver's device context strucure
+ *
+ * This function enables all the peripheral clocks that were requested by DSP.
+ */
+u32 dsp_clock_enable_all(u32 dsp_per_clocks)
+{
+       u32 clk_id;
+       u32 status = -EPERM;
+
+       for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) {
+               if (is_dsp_clk_active(dsp_per_clocks, clk_id))
+                       status = dsp_clk_enable(clk_id);
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dsp_clk_disable ========
+ *  Purpose:
+ *      Disable the clock.
+ *
+ */
+int dsp_clk_disable(enum dsp_clk_id clk_id)
+{
+       int status = 0;
+
+       if (!is_dsp_clk_active(dsp_clocks, clk_id)) {
+               dev_err(bridge, "ERR: clock id %d already disabled\n", clk_id);
+               goto out;
+       }
+
+       switch (get_clk_type(clk_id)) {
+       case IVA2_CLK:
+               clk_disable(iva2_clk);
+               break;
+       case GPT_CLK:
+               omap_dm_timer_free(timer[clk_id - 1]);
+               break;
+#ifdef CONFIG_OMAP_MCBSP
+       case MCBSP_CLK:
+               mcbsp_clk_prepare(false, clk_id);
+               omap_mcbsp_free(MCBSP_ID(clk_id));
+               break;
+#endif
+       case WDT_CLK:
+               dev_err(bridge, "ERROR: DSP requested to disable WDT3 clk\n");
+               break;
+       case SSI_CLK:
+               ssi_clk_prepare(false);
+               ssi_clk_prepare(false);
+               clk_disable(ssi.sst_fck);
+               clk_disable(ssi.ssr_fck);
+               clk_disable(ssi.ick);
+               break;
+       default:
+               dev_err(bridge, "Invalid clock id for disable\n");
+               status = -EPERM;
+       }
+
+       if (!status)
+               set_dsp_clk_inactive(&dsp_clocks, clk_id);
+
+out:
+       return status;
+}
+
+/**
+ * dsp_clock_disable_all - Disable all active clocks
+ * @dev_context                Driver's device context structure
+ *
+ * This function disables all the peripheral clocks that were enabled by DSP.
+ * It is meant to be called only when DSP is entering hibernation or when DSP
+ * is in error state.
+ */
+u32 dsp_clock_disable_all(u32 dsp_per_clocks)
+{
+       u32 clk_id;
+       u32 status = -EPERM;
+
+       for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) {
+               if (is_dsp_clk_active(dsp_per_clocks, clk_id))
+                       status = dsp_clk_disable(clk_id);
+       }
+
+       return status;
+}
+
+u32 dsp_clk_get_iva2_rate(void)
+{
+       u32 clk_speed_khz;
+
+       clk_speed_khz = clk_get_rate(iva2_clk);
+       clk_speed_khz /= 1000;
+       dev_dbg(bridge, "%s: clk speed Khz = %d\n", __func__, clk_speed_khz);
+
+       return clk_speed_khz;
+}
+
+void ssi_clk_prepare(bool FLAG)
+{
+       void __iomem *ssi_base;
+       unsigned int value;
+
+       ssi_base = ioremap(L4_34XX_BASE + OMAP_SSI_OFFSET, OMAP_SSI_SIZE);
+       if (!ssi_base) {
+               pr_err("%s: error, SSI not configured\n", __func__);
+               return;
+       }
+
+       if (FLAG) {
+               /* Set Autoidle, SIDLEMode to smart idle, and MIDLEmode to
+                * no idle
+                */
+               value = SSI_AUTOIDLE | SSI_SIDLE_SMARTIDLE | SSI_MIDLE_NOIDLE;
+       } else {
+               /* Set Autoidle, SIDLEMode to forced idle, and MIDLEmode to
+                * forced idle
+                */
+               value = SSI_AUTOIDLE;
+       }
+
+       __raw_writel(value, ssi_base + OMAP_SSI_SYSCONFIG_OFFSET);
+       iounmap(ssi_base);
+}
+
diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
new file mode 100644 (file)
index 0000000..02c660d
--- /dev/null
@@ -0,0 +1,2333 @@
+/*
+ * io_sm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * IO dispatcher for a shared memory channel driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * Channel Invariant:
+ * There is an important invariant condition which must be maintained per
+ * channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of
+ * which may cause timeouts and/or failure of the sync_wait_on_event
+ * function.
+ */
+#include <linux/types.h>
+
+/* Host OS */
+#include <dspbridge/host_os.h>
+#include <linux/workqueue.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/* Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/* Services Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/ntfy.h>
+#include <dspbridge/sync.h>
+
+/* Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
+/* Bridge Driver */
+#include <dspbridge/dspdeh.h>
+#include <dspbridge/dspio.h>
+#include <dspbridge/dspioctl.h>
+#include <dspbridge/wdt.h>
+#include <_tiomap.h>
+#include <tiomap_io.h>
+#include <_tiomap_pwr.h>
+
+/* Platform Manager */
+#include <dspbridge/cod.h>
+#include <dspbridge/node.h>
+#include <dspbridge/dev.h>
+
+/* Others */
+#include <dspbridge/rms_sh.h>
+#include <dspbridge/mgr.h>
+#include <dspbridge/drv.h>
+#include "_cmm.h"
+#include "module_list.h"
+
+/* This */
+#include <dspbridge/io_sm.h>
+#include "_msg_sm.h"
+
+/* Defines, Data Structures, Typedefs */
+#define OUTPUTNOTREADY  0xffff
+#define NOTENABLED      0xffff /* Channel(s) not enabled */
+
+#define EXTEND      "_EXT_END"
+
+#define SWAP_WORD(x)     (x)
+#define UL_PAGE_ALIGN_SIZE 0x10000     /* Page Align Size */
+
+#define MAX_PM_REQS 32
+
+#define MMU_FAULT_HEAD1 0xa5a5a5a5
+#define MMU_FAULT_HEAD2 0x96969696
+#define POLL_MAX 1000
+#define MAX_MMU_DBGBUFF 10240
+
+/* IO Manager: only one created per board */
+struct io_mgr {
+       /* These four fields must be the first fields in a io_mgr_ struct */
+       /* Bridge device context */
+       struct bridge_dev_context *hbridge_context;
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+       struct dev_object *hdev_obj;    /* Device this board represents */
+
+       /* These fields initialized in bridge_io_create() */
+       struct chnl_mgr *hchnl_mgr;
+       struct shm *shared_mem; /* Shared Memory control */
+       u8 *input;              /* Address of input channel */
+       u8 *output;             /* Address of output channel */
+       struct msg_mgr *hmsg_mgr;       /* Message manager */
+       /* Msg control for from DSP messages */
+       struct msg_ctrl *msg_input_ctrl;
+       /* Msg control for to DSP messages */
+       struct msg_ctrl *msg_output_ctrl;
+       u8 *msg_input;          /* Address of input messages */
+       u8 *msg_output;         /* Address of output messages */
+       u32 usm_buf_size;       /* Size of a shared memory I/O channel */
+       bool shared_irq;        /* Is this IRQ shared? */
+       u32 word_size;          /* Size in bytes of DSP word */
+       u16 intr_val;           /* Interrupt value */
+       /* Private extnd proc info; mmu setup */
+       struct mgr_processorextinfo ext_proc_info;
+       struct cmm_object *hcmm_mgr;    /* Shared Mem Mngr */
+       struct work_struct io_workq;    /* workqueue */
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+       u32 ul_trace_buffer_begin;      /* Trace message start address */
+       u32 ul_trace_buffer_end;        /* Trace message end address */
+       u32 ul_trace_buffer_current;    /* Trace message current address */
+       u32 ul_gpp_read_pointer;        /* GPP Read pointer to Trace buffer */
+       u8 *pmsg;
+       u32 ul_gpp_va;
+       u32 ul_dsp_va;
+#endif
+       /* IO Dpc */
+       u32 dpc_req;            /* Number of requested DPC's. */
+       u32 dpc_sched;          /* Number of executed DPC's. */
+       struct tasklet_struct dpc_tasklet;
+       spinlock_t dpc_lock;
+
+};
+
+/* Function Prototypes */
+static void io_dispatch_pm(struct io_mgr *pio_mgr);
+static void notify_chnl_complete(struct chnl_object *pchnl,
+                                struct chnl_irp *chnl_packet_obj);
+static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
+                       u8 io_mode);
+static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
+                       u8 io_mode);
+static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr);
+static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr);
+static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj,
+                            struct chnl_object *pchnl, u32 mask);
+
+/* Bus Addr (cached kernel) */
+static int register_shm_segs(struct io_mgr *hio_mgr,
+                                   struct cod_manager *cod_man,
+                                   u32 dw_gpp_base_pa);
+
+static inline void set_chnl_free(struct shm *sm, u32 chnl)
+{
+       sm->host_free_mask &= ~(1 << chnl);
+}
+
+static inline void set_chnl_busy(struct shm *sm, u32 chnl)
+{
+       sm->host_free_mask |= 1 << chnl;
+}
+
+
+/*
+ *  ======== bridge_io_create ========
+ *      Create an IO manager object.
+ */
+int bridge_io_create(struct io_mgr **io_man,
+                           struct dev_object *hdev_obj,
+                           const struct io_attrs *mgr_attrts)
+{
+       int status = 0;
+       struct io_mgr *pio_mgr = NULL;
+       struct shm *shared_mem = NULL;
+       struct bridge_dev_context *hbridge_context = NULL;
+       struct cfg_devnode *dev_node_obj;
+       struct chnl_mgr *hchnl_mgr;
+       u8 dev_type;
+
+       /* Check requirements */
+       if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
+       if (!hchnl_mgr || hchnl_mgr->hio_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       /*
+        * Message manager will be created when a file is loaded, since
+        * size of message buffer in shared memory is configurable in
+        * the base image.
+        */
+       dev_get_bridge_context(hdev_obj, &hbridge_context);
+       if (!hbridge_context) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       dev_get_dev_type(hdev_obj, &dev_type);
+       /*
+        * DSP shared memory area will get set properly when
+        * a program is loaded. They are unknown until a COFF file is
+        * loaded. I chose the value -1 because it was less likely to be
+        * a valid address than 0.
+        */
+       shared_mem = (struct shm *)-1;
+
+       /* Allocate IO manager object */
+       pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL);
+       if (pio_mgr == NULL) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+
+       /* Initialize chnl_mgr object */
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+       pio_mgr->pmsg = NULL;
+#endif
+       pio_mgr->hchnl_mgr = hchnl_mgr;
+       pio_mgr->word_size = mgr_attrts->word_size;
+       pio_mgr->shared_mem = shared_mem;
+
+       if (dev_type == DSP_UNIT) {
+               /* Create an IO DPC */
+               tasklet_init(&pio_mgr->dpc_tasklet, io_dpc, (u32) pio_mgr);
+
+               /* Initialize DPC counters */
+               pio_mgr->dpc_req = 0;
+               pio_mgr->dpc_sched = 0;
+
+               spin_lock_init(&pio_mgr->dpc_lock);
+
+               status = dev_get_dev_node(hdev_obj, &dev_node_obj);
+       }
+
+       if (!status) {
+               pio_mgr->hbridge_context = hbridge_context;
+               pio_mgr->shared_irq = mgr_attrts->irq_shared;
+               if (dsp_wdt_init())
+                       status = -EPERM;
+       } else {
+               status = -EIO;
+       }
+func_end:
+       if (status) {
+               /* Cleanup */
+               bridge_io_destroy(pio_mgr);
+               if (io_man)
+                       *io_man = NULL;
+       } else {
+               /* Return IO manager object to caller... */
+               hchnl_mgr->hio_mgr = pio_mgr;
+               *io_man = pio_mgr;
+       }
+       return status;
+}
+
+/*
+ *  ======== bridge_io_destroy ========
+ *  Purpose:
+ *      Disable interrupts, destroy the IO manager.
+ */
+int bridge_io_destroy(struct io_mgr *hio_mgr)
+{
+       int status = 0;
+       if (hio_mgr) {
+               /* Free IO DPC object */
+               tasklet_kill(&hio_mgr->dpc_tasklet);
+
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+               kfree(hio_mgr->pmsg);
+#endif
+               dsp_wdt_exit();
+               /* Free this IO manager object */
+               kfree(hio_mgr);
+       } else {
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== bridge_io_on_loaded ========
+ *  Purpose:
+ *      Called when a new program is loaded to get shared memory buffer
+ *      parameters from COFF file. ulSharedBufferBase and ulSharedBufferLimit
+ *      are in DSP address units.
+ */
+int bridge_io_on_loaded(struct io_mgr *hio_mgr)
+{
+       struct cod_manager *cod_man;
+       struct chnl_mgr *hchnl_mgr;
+       struct msg_mgr *hmsg_mgr;
+       u32 ul_shm_base;
+       u32 ul_shm_base_offset;
+       u32 ul_shm_limit;
+       u32 ul_shm_length = -1;
+       u32 ul_mem_length = -1;
+       u32 ul_msg_base;
+       u32 ul_msg_limit;
+       u32 ul_msg_length = -1;
+       u32 ul_ext_end;
+       u32 ul_gpp_pa = 0;
+       u32 ul_gpp_va = 0;
+       u32 ul_dsp_va = 0;
+       u32 ul_seg_size = 0;
+       u32 ul_pad_size = 0;
+       u32 i;
+       int status = 0;
+       u8 num_procs = 0;
+       s32 ndx = 0;
+       /* DSP MMU setup table */
+       struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB];
+       struct cfg_hostres *host_res;
+       struct bridge_dev_context *pbridge_context;
+       u32 map_attrs;
+       u32 shm0_end;
+       u32 ul_dyn_ext_base;
+       u32 ul_seg1_size = 0;
+       u32 pa_curr = 0;
+       u32 va_curr = 0;
+       u32 gpp_va_curr = 0;
+       u32 num_bytes = 0;
+       u32 all_bits = 0;
+       u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
+               HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
+       };
+
+       status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context);
+       if (!pbridge_context) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       host_res = pbridge_context->resources;
+       if (!host_res) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man);
+       if (!cod_man) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       hchnl_mgr = hio_mgr->hchnl_mgr;
+       /* The message manager is destroyed when the board is stopped. */
+       dev_get_msg_mgr(hio_mgr->hdev_obj, &hio_mgr->hmsg_mgr);
+       hmsg_mgr = hio_mgr->hmsg_mgr;
+       if (!hchnl_mgr || !hmsg_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       if (hio_mgr->shared_mem)
+               hio_mgr->shared_mem = NULL;
+
+       /* Get start and length of channel part of shared memory */
+       status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_BASE_SYM,
+                                  &ul_shm_base);
+       if (status) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_LIMIT_SYM,
+                                  &ul_shm_limit);
+       if (status) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       if (ul_shm_limit <= ul_shm_base) {
+               status = -EINVAL;
+               goto func_end;
+       }
+       /* Get total length in bytes */
+       ul_shm_length = (ul_shm_limit - ul_shm_base + 1) * hio_mgr->word_size;
+       /* Calculate size of a PROCCOPY shared memory region */
+       dev_dbg(bridge, "%s: (proc)proccopy shmmem size: 0x%x bytes\n",
+               __func__, (ul_shm_length - sizeof(struct shm)));
+
+       /* Get start and length of message part of shared memory */
+       status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_BASE_SYM,
+                                          &ul_msg_base);
+       if (!status) {
+               status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_LIMIT_SYM,
+                                          &ul_msg_limit);
+               if (!status) {
+                       if (ul_msg_limit <= ul_msg_base) {
+                               status = -EINVAL;
+                       } else {
+                               /*
+                                * Length (bytes) of messaging part of shared
+                                * memory.
+                                */
+                               ul_msg_length =
+                                   (ul_msg_limit - ul_msg_base +
+                                    1) * hio_mgr->word_size;
+                               /*
+                                * Total length (bytes) of shared memory:
+                                * chnl + msg.
+                                */
+                               ul_mem_length = ul_shm_length + ul_msg_length;
+                       }
+               } else {
+                       status = -EFAULT;
+               }
+       } else {
+               status = -EFAULT;
+       }
+       if (!status) {
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+               status =
+                   cod_get_sym_value(cod_man, DSP_TRACESEC_END, &shm0_end);
+#else
+               status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM,
+                                          &shm0_end);
+#endif
+               if (status)
+                       status = -EFAULT;
+       }
+       if (!status) {
+               status =
+                   cod_get_sym_value(cod_man, DYNEXTBASE, &ul_dyn_ext_base);
+               if (status)
+                       status = -EFAULT;
+       }
+       if (!status) {
+               status = cod_get_sym_value(cod_man, EXTEND, &ul_ext_end);
+               if (status)
+                       status = -EFAULT;
+       }
+       if (!status) {
+               /* Get memory reserved in host resources */
+               (void)mgr_enum_processor_info(0, (struct dsp_processorinfo *)
+                                             &hio_mgr->ext_proc_info,
+                                             sizeof(struct
+                                                    mgr_processorextinfo),
+                                             &num_procs);
+
+               /* The first MMU TLB entry(TLB_0) in DCD is ShmBase. */
+               ndx = 0;
+               ul_gpp_pa = host_res->dw_mem_phys[1];
+               ul_gpp_va = host_res->dw_mem_base[1];
+               /* This is the virtual uncached ioremapped address!!! */
+               /* Why can't we directly take the DSPVA from the symbols? */
+               ul_dsp_va = hio_mgr->ext_proc_info.ty_tlb[0].ul_dsp_virt;
+               ul_seg_size = (shm0_end - ul_dsp_va) * hio_mgr->word_size;
+               ul_seg1_size =
+                   (ul_ext_end - ul_dyn_ext_base) * hio_mgr->word_size;
+               /* 4K align */
+               ul_seg1_size = (ul_seg1_size + 0xFFF) & (~0xFFFUL);
+               /* 64K align */
+               ul_seg_size = (ul_seg_size + 0xFFFF) & (~0xFFFFUL);
+               ul_pad_size = UL_PAGE_ALIGN_SIZE - ((ul_gpp_pa + ul_seg1_size) %
+                                                   UL_PAGE_ALIGN_SIZE);
+               if (ul_pad_size == UL_PAGE_ALIGN_SIZE)
+                       ul_pad_size = 0x0;
+
+               dev_dbg(bridge, "%s: ul_gpp_pa %x, ul_gpp_va %x, ul_dsp_va %x, "
+                       "shm0_end %x, ul_dyn_ext_base %x, ul_ext_end %x, "
+                       "ul_seg_size %x ul_seg1_size %x \n", __func__,
+                       ul_gpp_pa, ul_gpp_va, ul_dsp_va, shm0_end,
+                       ul_dyn_ext_base, ul_ext_end, ul_seg_size, ul_seg1_size);
+
+               if ((ul_seg_size + ul_seg1_size + ul_pad_size) >
+                   host_res->dw_mem_length[1]) {
+                       pr_err("%s: shm Error, reserved 0x%x required 0x%x\n",
+                              __func__, host_res->dw_mem_length[1],
+                              ul_seg_size + ul_seg1_size + ul_pad_size);
+                       status = -ENOMEM;
+               }
+       }
+       if (status)
+               goto func_end;
+
+       pa_curr = ul_gpp_pa;
+       va_curr = ul_dyn_ext_base * hio_mgr->word_size;
+       gpp_va_curr = ul_gpp_va;
+       num_bytes = ul_seg1_size;
+
+       /*
+        * Try to fit into TLB entries. If not possible, push them to page
+        * tables. It is quite possible that if sections are not on
+        * bigger page boundary, we may end up making several small pages.
+        * So, push them onto page tables, if that is the case.
+        */
+       map_attrs = 0x00000000;
+       map_attrs = DSP_MAPLITTLEENDIAN;
+       map_attrs |= DSP_MAPPHYSICALADDR;
+       map_attrs |= DSP_MAPELEMSIZE32;
+       map_attrs |= DSP_MAPDONOTLOCK;
+
+       while (num_bytes) {
+               /*
+                * To find the max. page size with which both PA & VA are
+                * aligned.
+                */
+               all_bits = pa_curr | va_curr;
+               dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, "
+                       "num_bytes %x\n", all_bits, pa_curr, va_curr,
+                       num_bytes);
+               for (i = 0; i < 4; i++) {
+                       if ((num_bytes >= page_size[i]) && ((all_bits &
+                                                            (page_size[i] -
+                                                             1)) == 0)) {
+                               status =
+                                   hio_mgr->intf_fxns->
+                                   pfn_brd_mem_map(hio_mgr->hbridge_context,
+                                                   pa_curr, va_curr,
+                                                   page_size[i], map_attrs,
+                                                   NULL);
+                               if (status)
+                                       goto func_end;
+                               pa_curr += page_size[i];
+                               va_curr += page_size[i];
+                               gpp_va_curr += page_size[i];
+                               num_bytes -= page_size[i];
+                               /*
+                                * Don't try smaller sizes. Hopefully we have
+                                * reached an address aligned to a bigger page
+                                * size.
+                                */
+                               break;
+                       }
+               }
+       }
+       pa_curr += ul_pad_size;
+       va_curr += ul_pad_size;
+       gpp_va_curr += ul_pad_size;
+
+       /* Configure the TLB entries for the next cacheable segment */
+       num_bytes = ul_seg_size;
+       va_curr = ul_dsp_va * hio_mgr->word_size;
+       while (num_bytes) {
+               /*
+                * To find the max. page size with which both PA & VA are
+                * aligned.
+                */
+               all_bits = pa_curr | va_curr;
+               dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, "
+                       "va_curr %x, num_bytes %x\n", all_bits, pa_curr,
+                       va_curr, num_bytes);
+               for (i = 0; i < 4; i++) {
+                       if (!(num_bytes >= page_size[i]) ||
+                           !((all_bits & (page_size[i] - 1)) == 0))
+                               continue;
+                       if (ndx < MAX_LOCK_TLB_ENTRIES) {
+                               /*
+                                * This is the physical address written to
+                                * DSP MMU.
+                                */
+                               ae_proc[ndx].ul_gpp_pa = pa_curr;
+                               /*
+                                * This is the virtual uncached ioremapped
+                                * address!!!
+                                */
+                               ae_proc[ndx].ul_gpp_va = gpp_va_curr;
+                               ae_proc[ndx].ul_dsp_va =
+                                   va_curr / hio_mgr->word_size;
+                               ae_proc[ndx].ul_size = page_size[i];
+                               ae_proc[ndx].endianism = HW_LITTLE_ENDIAN;
+                               ae_proc[ndx].elem_size = HW_ELEM_SIZE16BIT;
+                               ae_proc[ndx].mixed_mode = HW_MMU_CPUES;
+                               dev_dbg(bridge, "shm MMU TLB entry PA %x"
+                                       " VA %x DSP_VA %x Size %x\n",
+                                       ae_proc[ndx].ul_gpp_pa,
+                                       ae_proc[ndx].ul_gpp_va,
+                                       ae_proc[ndx].ul_dsp_va *
+                                       hio_mgr->word_size, page_size[i]);
+                               ndx++;
+                       } else {
+                               status =
+                                   hio_mgr->intf_fxns->
+                                   pfn_brd_mem_map(hio_mgr->hbridge_context,
+                                                   pa_curr, va_curr,
+                                                   page_size[i], map_attrs,
+                                                   NULL);
+                               dev_dbg(bridge,
+                                       "shm MMU PTE entry PA %x"
+                                       " VA %x DSP_VA %x Size %x\n",
+                                       ae_proc[ndx].ul_gpp_pa,
+                                       ae_proc[ndx].ul_gpp_va,
+                                       ae_proc[ndx].ul_dsp_va *
+                                       hio_mgr->word_size, page_size[i]);
+                               if (status)
+                                       goto func_end;
+                       }
+                       pa_curr += page_size[i];
+                       va_curr += page_size[i];
+                       gpp_va_curr += page_size[i];
+                       num_bytes -= page_size[i];
+                       /*
+                        * Don't try smaller sizes. Hopefully we have reached
+                        * an address aligned to a bigger page size.
+                        */
+                       break;
+               }
+       }
+
+       /*
+        * Copy remaining entries from CDB. All entries are 1 MB and
+        * should not conflict with shm entries on MPU or DSP side.
+        */
+       for (i = 3; i < 7 && ndx < BRDIOCTL_NUMOFMMUTLB; i++) {
+               if (hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys == 0)
+                       continue;
+
+               if ((hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys >
+                    ul_gpp_pa - 0x100000
+                    && hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys <=
+                    ul_gpp_pa + ul_seg_size)
+                   || (hio_mgr->ext_proc_info.ty_tlb[i].ul_dsp_virt >
+                       ul_dsp_va - 0x100000 / hio_mgr->word_size
+                       && hio_mgr->ext_proc_info.ty_tlb[i].ul_dsp_virt <=
+                       ul_dsp_va + ul_seg_size / hio_mgr->word_size)) {
+                       dev_dbg(bridge,
+                               "CDB MMU entry %d conflicts with "
+                               "shm.\n\tCDB: GppPa %x, DspVa %x.\n\tSHM: "
+                               "GppPa %x, DspVa %x, Bytes %x.\n", i,
+                               hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys,
+                               hio_mgr->ext_proc_info.ty_tlb[i].ul_dsp_virt,
+                               ul_gpp_pa, ul_dsp_va, ul_seg_size);
+                       status = -EPERM;
+               } else {
+                       if (ndx < MAX_LOCK_TLB_ENTRIES) {
+                               ae_proc[ndx].ul_dsp_va =
+                                   hio_mgr->ext_proc_info.ty_tlb[i].
+                                   ul_dsp_virt;
+                               ae_proc[ndx].ul_gpp_pa =
+                                   hio_mgr->ext_proc_info.ty_tlb[i].
+                                   ul_gpp_phys;
+                               ae_proc[ndx].ul_gpp_va = 0;
+                               /* 1 MB */
+                               ae_proc[ndx].ul_size = 0x100000;
+                               dev_dbg(bridge, "shm MMU entry PA %x "
+                                       "DSP_VA 0x%x\n", ae_proc[ndx].ul_gpp_pa,
+                                       ae_proc[ndx].ul_dsp_va);
+                               ndx++;
+                       } else {
+                               status = hio_mgr->intf_fxns->pfn_brd_mem_map
+                                   (hio_mgr->hbridge_context,
+                                    hio_mgr->ext_proc_info.ty_tlb[i].
+                                    ul_gpp_phys,
+                                    hio_mgr->ext_proc_info.ty_tlb[i].
+                                    ul_dsp_virt, 0x100000, map_attrs,
+                                    NULL);
+                       }
+               }
+               if (status)
+                       goto func_end;
+       }
+
+       map_attrs = 0x00000000;
+       map_attrs = DSP_MAPLITTLEENDIAN;
+       map_attrs |= DSP_MAPPHYSICALADDR;
+       map_attrs |= DSP_MAPELEMSIZE32;
+       map_attrs |= DSP_MAPDONOTLOCK;
+
+       /* Map the L4 peripherals */
+       i = 0;
+       while (l4_peripheral_table[i].phys_addr) {
+               status = hio_mgr->intf_fxns->pfn_brd_mem_map
+                   (hio_mgr->hbridge_context, l4_peripheral_table[i].phys_addr,
+                    l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB,
+                    map_attrs, NULL);
+               if (status)
+                       goto func_end;
+               i++;
+       }
+
+       for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) {
+               ae_proc[i].ul_dsp_va = 0;
+               ae_proc[i].ul_gpp_pa = 0;
+               ae_proc[i].ul_gpp_va = 0;
+               ae_proc[i].ul_size = 0;
+       }
+       /*
+        * Set the shm physical address entry (grayed out in CDB file)
+        * to the virtual uncached ioremapped address of shm reserved
+        * on MPU.
+        */
+       hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys =
+           (ul_gpp_va + ul_seg1_size + ul_pad_size);
+
+       /*
+        * Need shm Phys addr. IO supports only one DSP for now:
+        * num_procs = 1.
+        */
+       if (!hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys || num_procs != 1) {
+               status = -EFAULT;
+               goto func_end;
+       } else {
+               if (ae_proc[0].ul_dsp_va > ul_shm_base) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+               /* ul_shm_base may not be at ul_dsp_va address */
+               ul_shm_base_offset = (ul_shm_base - ae_proc[0].ul_dsp_va) *
+                   hio_mgr->word_size;
+               /*
+                * bridge_dev_ctrl() will set dev context dsp-mmu info. In
+                * bridge_brd_start() the MMU will be re-programed with MMU
+                * DSPVa-GPPPa pair info while DSP is in a known
+                * (reset) state.
+                */
+
+               status =
+                   hio_mgr->intf_fxns->pfn_dev_cntrl(hio_mgr->hbridge_context,
+                                                     BRDIOCTL_SETMMUCONFIG,
+                                                     ae_proc);
+               if (status)
+                       goto func_end;
+               ul_shm_base = hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys;
+               ul_shm_base += ul_shm_base_offset;
+               ul_shm_base = (u32) MEM_LINEAR_ADDRESS((void *)ul_shm_base,
+                                                      ul_mem_length);
+               if (ul_shm_base == 0) {
+                       status = -EFAULT;
+                       goto func_end;
+               }
+               /* Register SM */
+               status =
+                   register_shm_segs(hio_mgr, cod_man, ae_proc[0].ul_gpp_pa);
+       }
+
+       hio_mgr->shared_mem = (struct shm *)ul_shm_base;
+       hio_mgr->input = (u8 *) hio_mgr->shared_mem + sizeof(struct shm);
+       hio_mgr->output = hio_mgr->input + (ul_shm_length -
+                                           sizeof(struct shm)) / 2;
+       hio_mgr->usm_buf_size = hio_mgr->output - hio_mgr->input;
+
+       /*  Set up Shared memory addresses for messaging. */
+       hio_mgr->msg_input_ctrl = (struct msg_ctrl *)((u8 *) hio_mgr->shared_mem
+                                                     + ul_shm_length);
+       hio_mgr->msg_input =
+           (u8 *) hio_mgr->msg_input_ctrl + sizeof(struct msg_ctrl);
+       hio_mgr->msg_output_ctrl =
+           (struct msg_ctrl *)((u8 *) hio_mgr->msg_input_ctrl +
+                               ul_msg_length / 2);
+       hio_mgr->msg_output =
+           (u8 *) hio_mgr->msg_output_ctrl + sizeof(struct msg_ctrl);
+       hmsg_mgr->max_msgs =
+           ((u8 *) hio_mgr->msg_output_ctrl - hio_mgr->msg_input)
+           / sizeof(struct msg_dspmsg);
+       dev_dbg(bridge, "IO MGR shm details: shared_mem %p, input %p, "
+               "output %p, msg_input_ctrl %p, msg_input %p, "
+               "msg_output_ctrl %p, msg_output %p\n",
+               (u8 *) hio_mgr->shared_mem, hio_mgr->input,
+               hio_mgr->output, (u8 *) hio_mgr->msg_input_ctrl,
+               hio_mgr->msg_input, (u8 *) hio_mgr->msg_output_ctrl,
+               hio_mgr->msg_output);
+       dev_dbg(bridge, "(proc) Mas msgs in shared memory: 0x%x\n",
+               hmsg_mgr->max_msgs);
+       memset((void *)hio_mgr->shared_mem, 0, sizeof(struct shm));
+
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+       /* Get the start address of trace buffer */
+       status = cod_get_sym_value(cod_man, SYS_PUTCBEG,
+                                  &hio_mgr->ul_trace_buffer_begin);
+       if (status) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       hio_mgr->ul_gpp_read_pointer = hio_mgr->ul_trace_buffer_begin =
+           (ul_gpp_va + ul_seg1_size + ul_pad_size) +
+           (hio_mgr->ul_trace_buffer_begin - ul_dsp_va);
+       /* Get the end address of trace buffer */
+       status = cod_get_sym_value(cod_man, SYS_PUTCEND,
+                                  &hio_mgr->ul_trace_buffer_end);
+       if (status) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       hio_mgr->ul_trace_buffer_end =
+           (ul_gpp_va + ul_seg1_size + ul_pad_size) +
+           (hio_mgr->ul_trace_buffer_end - ul_dsp_va);
+       /* Get the current address of DSP write pointer */
+       status = cod_get_sym_value(cod_man, BRIDGE_SYS_PUTC_CURRENT,
+                                  &hio_mgr->ul_trace_buffer_current);
+       if (status) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       hio_mgr->ul_trace_buffer_current =
+           (ul_gpp_va + ul_seg1_size + ul_pad_size) +
+           (hio_mgr->ul_trace_buffer_current - ul_dsp_va);
+       /* Calculate the size of trace buffer */
+       kfree(hio_mgr->pmsg);
+       hio_mgr->pmsg = kmalloc(((hio_mgr->ul_trace_buffer_end -
+                               hio_mgr->ul_trace_buffer_begin) *
+                               hio_mgr->word_size) + 2, GFP_KERNEL);
+       if (!hio_mgr->pmsg)
+               status = -ENOMEM;
+
+       hio_mgr->ul_dsp_va = ul_dsp_va;
+       hio_mgr->ul_gpp_va = (ul_gpp_va + ul_seg1_size + ul_pad_size);
+
+#endif
+func_end:
+       return status;
+}
+
+/*
+ *  ======== io_buf_size ========
+ *      Size of shared memory I/O channel.
+ */
+u32 io_buf_size(struct io_mgr *hio_mgr)
+{
+       if (hio_mgr)
+               return hio_mgr->usm_buf_size;
+       else
+               return 0;
+}
+
+/*
+ *  ======== io_cancel_chnl ========
+ *      Cancel IO on a given PCPY channel.
+ */
+void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl)
+{
+       struct io_mgr *pio_mgr = (struct io_mgr *)hio_mgr;
+       struct shm *sm;
+
+       if (!hio_mgr)
+               goto func_end;
+       sm = hio_mgr->shared_mem;
+
+       /* Inform DSP that we have no more buffers on this channel */
+       set_chnl_free(sm, chnl);
+
+       sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS);
+func_end:
+       return;
+}
+
+
+/*
+ *  ======== io_dispatch_pm ========
+ *      Performs I/O dispatch on PM related messages from DSP
+ */
+static void io_dispatch_pm(struct io_mgr *pio_mgr)
+{
+       int status;
+       u32 parg[2];
+
+       /* Perform Power message processing here */
+       parg[0] = pio_mgr->intr_val;
+
+       /* Send the command to the Bridge clk/pwr manager to handle */
+       if (parg[0] == MBX_PM_HIBERNATE_EN) {
+               dev_dbg(bridge, "PM: Hibernate command\n");
+               status = pio_mgr->intf_fxns->
+                               pfn_dev_cntrl(pio_mgr->hbridge_context,
+                                             BRDIOCTL_PWR_HIBERNATE, parg);
+               if (status)
+                       pr_err("%s: hibernate cmd failed 0x%x\n",
+                                      __func__, status);
+       } else if (parg[0] == MBX_PM_OPP_REQ) {
+               parg[1] = pio_mgr->shared_mem->opp_request.rqst_opp_pt;
+               dev_dbg(bridge, "PM: Requested OPP = 0x%x\n", parg[1]);
+               status = pio_mgr->intf_fxns->
+                               pfn_dev_cntrl(pio_mgr->hbridge_context,
+                                       BRDIOCTL_CONSTRAINT_REQUEST, parg);
+               if (status)
+                       dev_dbg(bridge, "PM: Failed to set constraint "
+                               "= 0x%x\n", parg[1]);
+       } else {
+               dev_dbg(bridge, "PM: clk control value of msg = 0x%x\n",
+                       parg[0]);
+               status = pio_mgr->intf_fxns->
+                               pfn_dev_cntrl(pio_mgr->hbridge_context,
+                                             BRDIOCTL_CLK_CTRL, parg);
+               if (status)
+                       dev_dbg(bridge, "PM: Failed to ctrl the DSP clk"
+                               "= 0x%x\n", *parg);
+       }
+}
+
+/*
+ *  ======== io_dpc ========
+ *      Deferred procedure call for shared memory channel driver ISR.  Carries
+ *      out the dispatch of I/O as a non-preemptible event.It can only be
+ *      pre-empted      by an ISR.
+ */
+void io_dpc(unsigned long ref_data)
+{
+       struct io_mgr *pio_mgr = (struct io_mgr *)ref_data;
+       struct chnl_mgr *chnl_mgr_obj;
+       struct msg_mgr *msg_mgr_obj;
+       struct deh_mgr *hdeh_mgr;
+       u32 requested;
+       u32 serviced;
+
+       if (!pio_mgr)
+               goto func_end;
+       chnl_mgr_obj = pio_mgr->hchnl_mgr;
+       dev_get_msg_mgr(pio_mgr->hdev_obj, &msg_mgr_obj);
+       dev_get_deh_mgr(pio_mgr->hdev_obj, &hdeh_mgr);
+       if (!chnl_mgr_obj)
+               goto func_end;
+
+       requested = pio_mgr->dpc_req;
+       serviced = pio_mgr->dpc_sched;
+
+       if (serviced == requested)
+               goto func_end;
+
+       /* Process pending DPC's */
+       do {
+               /* Check value of interrupt reg to ensure it's a valid error */
+               if ((pio_mgr->intr_val > DEH_BASE) &&
+                   (pio_mgr->intr_val < DEH_LIMIT)) {
+                       /* Notify DSP/BIOS exception */
+                       if (hdeh_mgr) {
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+                               print_dsp_debug_trace(pio_mgr);
+#endif
+                               bridge_deh_notify(hdeh_mgr, DSP_SYSERROR,
+                                                 pio_mgr->intr_val);
+                       }
+               }
+               /* Proc-copy chanel dispatch */
+               input_chnl(pio_mgr, NULL, IO_SERVICE);
+               output_chnl(pio_mgr, NULL, IO_SERVICE);
+
+#ifdef CHNL_MESSAGES
+               if (msg_mgr_obj) {
+                       /* Perform I/O dispatch on message queues */
+                       input_msg(pio_mgr, msg_mgr_obj);
+                       output_msg(pio_mgr, msg_mgr_obj);
+               }
+
+#endif
+#ifdef CONFIG_TIDSPBRIDGE_DEBUG
+               if (pio_mgr->intr_val & MBX_DBG_SYSPRINTF) {
+                       /* Notify DSP Trace message */
+                       print_dsp_debug_trace(pio_mgr);
+               }
+#endif
+               serviced++;
+       } while (serviced != requested);
+       pio_mgr->dpc_sched = requested;
+func_end:
+       return;
+}
+
+/*
+ *  ======== io_mbox_msg ========
+ *      Main interrupt handler for the shared memory IO manager.
+ *      Calls the Bridge's CHNL_ISR to determine if this interrupt is ours, then
+ *      schedules a DPC to dispatch I/O.
+ */
+void io_mbox_msg(u32 msg)
+{
+       struct io_mgr *pio_mgr;
+       struct dev_object *dev_obj;
+       unsigned long flags;
+
+       dev_obj = dev_get_first();
+       dev_get_io_mgr(dev_obj, &pio_mgr);
+
+       if (!pio_mgr)
+               return;
+
+       pio_mgr->intr_val = (u16)msg;
+       if (pio_mgr->intr_val & MBX_PM_CLASS)
+               io_dispatch_pm(pio_mgr);
+
+       if (pio_mgr->intr_val == MBX_DEH_RESET) {
+               pio_mgr->intr_val = 0;
+       } else {
+               spin_lock_irqsave(&pio_mgr->dpc_lock, flags);
+               pio_mgr->dpc_req++;
+               spin_unlock_irqrestore(&pio_mgr->dpc_lock, flags);
+               tasklet_schedule(&pio_mgr->dpc_tasklet);
+       }
+       return;
+}
+
+/*
+ *  ======== io_request_chnl ========
+ *  Purpose:
+ *      Request chanenel I/O from the DSP. Sets flags in shared memory, then
+ *      interrupts the DSP.
+ */
+void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl,
+                       u8 io_mode, u16 *mbx_val)
+{
+       struct chnl_mgr *chnl_mgr_obj;
+       struct shm *sm;
+
+       if (!pchnl || !mbx_val)
+               goto func_end;
+       chnl_mgr_obj = io_manager->hchnl_mgr;
+       sm = io_manager->shared_mem;
+       if (io_mode == IO_INPUT) {
+               /*
+                * Assertion fires if CHNL_AddIOReq() called on a stream
+                * which was cancelled, or attached to a dead board.
+                */
+               DBC_ASSERT((pchnl->dw_state == CHNL_STATEREADY) ||
+                          (pchnl->dw_state == CHNL_STATEEOS));
+               /* Indicate to the DSP we have a buffer available for input */
+               set_chnl_busy(sm, pchnl->chnl_id);
+               *mbx_val = MBX_PCPY_CLASS;
+       } else if (io_mode == IO_OUTPUT) {
+               /*
+                * This assertion fails if CHNL_AddIOReq() was called on a
+                * stream which was cancelled, or attached to a dead board.
+                */
+               DBC_ASSERT((pchnl->dw_state & ~CHNL_STATEEOS) ==
+                          CHNL_STATEREADY);
+               /*
+                * Record the fact that we have a buffer available for
+                * output.
+                */
+               chnl_mgr_obj->dw_output_mask |= (1 << pchnl->chnl_id);
+       } else {
+               DBC_ASSERT(io_mode);    /* Shouldn't get here. */
+       }
+func_end:
+       return;
+}
+
+/*
+ *  ======== iosm_schedule ========
+ *      Schedule DPC for IO.
+ */
+void iosm_schedule(struct io_mgr *io_manager)
+{
+       unsigned long flags;
+
+       if (!io_manager)
+               return;
+
+       /* Increment count of DPC's pending. */
+       spin_lock_irqsave(&io_manager->dpc_lock, flags);
+       io_manager->dpc_req++;
+       spin_unlock_irqrestore(&io_manager->dpc_lock, flags);
+
+       /* Schedule DPC */
+       tasklet_schedule(&io_manager->dpc_tasklet);
+}
+
+/*
+ *  ======== find_ready_output ========
+ *      Search for a host output channel which is ready to send.  If this is
+ *      called as a result of servicing the DPC, then implement a round
+ *      robin search; otherwise, this was called by a client thread (via
+ *      IO_Dispatch()), so just start searching from the current channel id.
+ */
+static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj,
+                            struct chnl_object *pchnl, u32 mask)
+{
+       u32 ret = OUTPUTNOTREADY;
+       u32 id, start_id;
+       u32 shift;
+
+       id = (pchnl !=
+             NULL ? pchnl->chnl_id : (chnl_mgr_obj->dw_last_output + 1));
+       id = ((id == CHNL_MAXCHANNELS) ? 0 : id);
+       if (id >= CHNL_MAXCHANNELS)
+               goto func_end;
+       if (mask) {
+               shift = (1 << id);
+               start_id = id;
+               do {
+                       if (mask & shift) {
+                               ret = id;
+                               if (pchnl == NULL)
+                                       chnl_mgr_obj->dw_last_output = id;
+                               break;
+                       }
+                       id = id + 1;
+                       id = ((id == CHNL_MAXCHANNELS) ? 0 : id);
+                       shift = (1 << id);
+               } while (id != start_id);
+       }
+func_end:
+       return ret;
+}
+
+/*
+ *  ======== input_chnl ========
+ *      Dispatch a buffer on an input channel.
+ */
+static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
+                       u8 io_mode)
+{
+       struct chnl_mgr *chnl_mgr_obj;
+       struct shm *sm;
+       u32 chnl_id;
+       u32 bytes;
+       struct chnl_irp *chnl_packet_obj = NULL;
+       u32 dw_arg;
+       bool clear_chnl = false;
+       bool notify_client = false;
+
+       sm = pio_mgr->shared_mem;
+       chnl_mgr_obj = pio_mgr->hchnl_mgr;
+
+       /* Attempt to perform input */
+       if (!sm->input_full)
+               goto func_end;
+
+       bytes = sm->input_size * chnl_mgr_obj->word_size;
+       chnl_id = sm->input_id;
+       dw_arg = sm->arg;
+       if (chnl_id >= CHNL_MAXCHANNELS) {
+               /* Shouldn't be here: would indicate corrupted shm. */
+               DBC_ASSERT(chnl_id);
+               goto func_end;
+       }
+       pchnl = chnl_mgr_obj->ap_channel[chnl_id];
+       if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) {
+               if ((pchnl->dw_state & ~CHNL_STATEEOS) == CHNL_STATEREADY) {
+                       if (!pchnl->pio_requests)
+                               goto func_end;
+                       /* Get the I/O request, and attempt a transfer */
+                       chnl_packet_obj = (struct chnl_irp *)
+                           lst_get_head(pchnl->pio_requests);
+                       if (chnl_packet_obj) {
+                               pchnl->cio_reqs--;
+                               if (pchnl->cio_reqs < 0)
+                                       goto func_end;
+                               /*
+                                * Ensure we don't overflow the client's
+                                * buffer.
+                                */
+                               bytes = min(bytes, chnl_packet_obj->byte_size);
+                               memcpy(chnl_packet_obj->host_sys_buf,
+                                               pio_mgr->input, bytes);
+                               pchnl->bytes_moved += bytes;
+                               chnl_packet_obj->byte_size = bytes;
+                               chnl_packet_obj->dw_arg = dw_arg;
+                               chnl_packet_obj->status = CHNL_IOCSTATCOMPLETE;
+
+                               if (bytes == 0) {
+                                       /*
+                                        * This assertion fails if the DSP
+                                        * sends EOS more than once on this
+                                        * channel.
+                                        */
+                                       if (pchnl->dw_state & CHNL_STATEEOS)
+                                               goto func_end;
+                                       /*
+                                        * Zero bytes indicates EOS. Update
+                                        * IOC status for this chirp, and also
+                                        * the channel state.
+                                        */
+                                       chnl_packet_obj->status |=
+                                           CHNL_IOCSTATEOS;
+                                       pchnl->dw_state |= CHNL_STATEEOS;
+                                       /*
+                                        * Notify that end of stream has
+                                        * occurred.
+                                        */
+                                       ntfy_notify(pchnl->ntfy_obj,
+                                                   DSP_STREAMDONE);
+                               }
+                               /* Tell DSP if no more I/O buffers available */
+                               if (!pchnl->pio_requests)
+                                       goto func_end;
+                               if (LST_IS_EMPTY(pchnl->pio_requests)) {
+                                       set_chnl_free(sm, pchnl->chnl_id);
+                               }
+                               clear_chnl = true;
+                               notify_client = true;
+                       } else {
+                               /*
+                                * Input full for this channel, but we have no
+                                * buffers available.  The channel must be
+                                * "idling". Clear out the physical input
+                                * channel.
+                                */
+                               clear_chnl = true;
+                       }
+               } else {
+                       /* Input channel cancelled: clear input channel */
+                       clear_chnl = true;
+               }
+       } else {
+               /* DPC fired after host closed channel: clear input channel */
+               clear_chnl = true;
+       }
+       if (clear_chnl) {
+               /* Indicate to the DSP we have read the input */
+               sm->input_full = 0;
+               sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS);
+       }
+       if (notify_client) {
+               /* Notify client with IO completion record */
+               notify_chnl_complete(pchnl, chnl_packet_obj);
+       }
+func_end:
+       return;
+}
+
+/*
+ *  ======== input_msg ========
+ *      Copies messages from shared memory to the message queues.
+ */
+static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
+{
+       u32 num_msgs;
+       u32 i;
+       u8 *msg_input;
+       struct msg_queue *msg_queue_obj;
+       struct msg_frame *pmsg;
+       struct msg_dspmsg msg;
+       struct msg_ctrl *msg_ctr_obj;
+       u32 input_empty;
+       u32 addr;
+
+       msg_ctr_obj = pio_mgr->msg_input_ctrl;
+       /* Get the number of input messages to be read */
+       input_empty = msg_ctr_obj->buf_empty;
+       num_msgs = msg_ctr_obj->size;
+       if (input_empty)
+               goto func_end;
+
+       msg_input = pio_mgr->msg_input;
+       for (i = 0; i < num_msgs; i++) {
+               /* Read the next message */
+               addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_cmd);
+               msg.msg.dw_cmd =
+                   read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr);
+               addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_arg1);
+               msg.msg.dw_arg1 =
+                   read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr);
+               addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_arg2);
+               msg.msg.dw_arg2 =
+                   read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr);
+               addr = (u32) &(((struct msg_dspmsg *)msg_input)->msgq_id);
+               msg.msgq_id =
+                   read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr);
+               msg_input += sizeof(struct msg_dspmsg);
+               if (!hmsg_mgr->queue_list)
+                       goto func_end;
+
+               /* Determine which queue to put the message in */
+               msg_queue_obj =
+                   (struct msg_queue *)lst_first(hmsg_mgr->queue_list);
+               dev_dbg(bridge, "input msg: dw_cmd=0x%x dw_arg1=0x%x "
+                       "dw_arg2=0x%x msgq_id=0x%x \n", msg.msg.dw_cmd,
+                       msg.msg.dw_arg1, msg.msg.dw_arg2, msg.msgq_id);
+               /*
+                * Interrupt may occur before shared memory and message
+                * input locations have been set up. If all nodes were
+                * cleaned up, hmsg_mgr->max_msgs should be 0.
+                */
+               while (msg_queue_obj != NULL) {
+                       if (msg.msgq_id == msg_queue_obj->msgq_id) {
+                               /* Found it */
+                               if (msg.msg.dw_cmd == RMS_EXITACK) {
+                                       /*
+                                        * Call the node exit notification.
+                                        * The exit message does not get
+                                        * queued.
+                                        */
+                                       (*hmsg_mgr->on_exit) ((void *)
+                                                          msg_queue_obj->arg,
+                                                          msg.msg.dw_arg1);
+                               } else {
+                                       /*
+                                        * Not an exit acknowledgement, queue
+                                        * the message.
+                                        */
+                                       if (!msg_queue_obj->msg_free_list)
+                                               goto func_end;
+                                       pmsg = (struct msg_frame *)lst_get_head
+                                           (msg_queue_obj->msg_free_list);
+                                       if (msg_queue_obj->msg_used_list
+                                           && pmsg) {
+                                               pmsg->msg_data = msg;
+                                               lst_put_tail
+                                                (msg_queue_obj->msg_used_list,
+                                                    (struct list_head *)pmsg);
+                                               ntfy_notify
+                                                   (msg_queue_obj->ntfy_obj,
+                                                    DSP_NODEMESSAGEREADY);
+                                               sync_set_event
+                                                   (msg_queue_obj->sync_event);
+                                       } else {
+                                               /*
+                                                * No free frame to copy the
+                                                * message into.
+                                                */
+                                               pr_err("%s: no free msg frames,"
+                                                      " discarding msg\n",
+                                                      __func__);
+                                       }
+                               }
+                               break;
+                       }
+
+                       if (!hmsg_mgr->queue_list || !msg_queue_obj)
+                               goto func_end;
+                       msg_queue_obj =
+                           (struct msg_queue *)lst_next(hmsg_mgr->queue_list,
+                                                        (struct list_head *)
+                                                        msg_queue_obj);
+               }
+       }
+       /* Set the post SWI flag */
+       if (num_msgs > 0) {
+               /* Tell the DSP we've read the messages */
+               msg_ctr_obj->buf_empty = true;
+               msg_ctr_obj->post_swi = true;
+               sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS);
+       }
+func_end:
+       return;
+}
+
+/*
+ *  ======== notify_chnl_complete ========
+ *  Purpose:
+ *      Signal the channel event, notifying the client that I/O has completed.
+ */
+static void notify_chnl_complete(struct chnl_object *pchnl,
+                                struct chnl_irp *chnl_packet_obj)
+{
+       bool signal_event;
+
+       if (!pchnl || !pchnl->sync_event ||
+           !pchnl->pio_completions || !chnl_packet_obj)
+               goto func_end;
+
+       /*
+        * Note: we signal the channel event only if the queue of IO
+        * completions is empty.  If it is not empty, the event is sure to be
+        * signalled by the only IO completion list consumer:
+        * bridge_chnl_get_ioc().
+        */
+       signal_event = LST_IS_EMPTY(pchnl->pio_completions);
+       /* Enqueue the IO completion info for the client */
+       lst_put_tail(pchnl->pio_completions,
+                    (struct list_head *)chnl_packet_obj);
+       pchnl->cio_cs++;
+
+       if (pchnl->cio_cs > pchnl->chnl_packets)
+               goto func_end;
+       /* Signal the channel event (if not already set) that IO is complete */
+       if (signal_event)
+               sync_set_event(pchnl->sync_event);
+
+       /* Notify that IO is complete */
+       ntfy_notify(pchnl->ntfy_obj, DSP_STREAMIOCOMPLETION);
+func_end:
+       return;
+}
+
+/*
+ *  ======== output_chnl ========
+ *  Purpose:
+ *      Dispatch a buffer on an output channel.
+ */
+static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
+                       u8 io_mode)
+{
+       struct chnl_mgr *chnl_mgr_obj;
+       struct shm *sm;
+       u32 chnl_id;
+       struct chnl_irp *chnl_packet_obj;
+       u32 dw_dsp_f_mask;
+
+       chnl_mgr_obj = pio_mgr->hchnl_mgr;
+       sm = pio_mgr->shared_mem;
+       /* Attempt to perform output */
+       if (sm->output_full)
+               goto func_end;
+
+       if (pchnl && !((pchnl->dw_state & ~CHNL_STATEEOS) == CHNL_STATEREADY))
+               goto func_end;
+
+       /* Look to see if both a PC and DSP output channel are ready */
+       dw_dsp_f_mask = sm->dsp_free_mask;
+       chnl_id =
+           find_ready_output(chnl_mgr_obj, pchnl,
+                             (chnl_mgr_obj->dw_output_mask & dw_dsp_f_mask));
+       if (chnl_id == OUTPUTNOTREADY)
+               goto func_end;
+
+       pchnl = chnl_mgr_obj->ap_channel[chnl_id];
+       if (!pchnl || !pchnl->pio_requests) {
+               /* Shouldn't get here */
+               goto func_end;
+       }
+       /* Get the I/O request, and attempt a transfer */
+       chnl_packet_obj = (struct chnl_irp *)lst_get_head(pchnl->pio_requests);
+       if (!chnl_packet_obj)
+               goto func_end;
+
+       pchnl->cio_reqs--;
+       if (pchnl->cio_reqs < 0 || !pchnl->pio_requests)
+               goto func_end;
+
+       /* Record fact that no more I/O buffers available */
+       if (LST_IS_EMPTY(pchnl->pio_requests))
+               chnl_mgr_obj->dw_output_mask &= ~(1 << chnl_id);
+
+       /* Transfer buffer to DSP side */
+       chnl_packet_obj->byte_size = min(pio_mgr->usm_buf_size,
+                                       chnl_packet_obj->byte_size);
+       memcpy(pio_mgr->output, chnl_packet_obj->host_sys_buf,
+                                       chnl_packet_obj->byte_size);
+       pchnl->bytes_moved += chnl_packet_obj->byte_size;
+       /* Write all 32 bits of arg */
+       sm->arg = chnl_packet_obj->dw_arg;
+#if _CHNL_WORDSIZE == 2
+       /* Access can be different SM access word size (e.g. 16/32 bit words) */
+       sm->output_id = (u16) chnl_id;
+       sm->output_size = (u16) (chnl_packet_obj->byte_size +
+                               chnl_mgr_obj->word_size - 1) /
+                               (u16) chnl_mgr_obj->word_size;
+#else
+       sm->output_id = chnl_id;
+       sm->output_size = (chnl_packet_obj->byte_size +
+                       chnl_mgr_obj->word_size - 1) / chnl_mgr_obj->word_size;
+#endif
+       sm->output_full =  1;
+       /* Indicate to the DSP we have written the output */
+       sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS);
+       /* Notify client with IO completion record (keep EOS) */
+       chnl_packet_obj->status &= CHNL_IOCSTATEOS;
+       notify_chnl_complete(pchnl, chnl_packet_obj);
+       /* Notify if stream is done. */
+       if (chnl_packet_obj->status & CHNL_IOCSTATEOS)
+               ntfy_notify(pchnl->ntfy_obj, DSP_STREAMDONE);
+
+func_end:
+       return;
+}
+
+/*
+ *  ======== output_msg ========
+ *      Copies messages from the message queues to the shared memory.
+ */
+static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
+{
+       u32 num_msgs = 0;
+       u32 i;
+       u8 *msg_output;
+       struct msg_frame *pmsg;
+       struct msg_ctrl *msg_ctr_obj;
+       u32 output_empty;
+       u32 val;
+       u32 addr;
+
+       msg_ctr_obj = pio_mgr->msg_output_ctrl;
+
+       /* Check if output has been cleared */
+       output_empty = msg_ctr_obj->buf_empty;
+       if (output_empty) {
+               num_msgs = (hmsg_mgr->msgs_pending > hmsg_mgr->max_msgs) ?
+                   hmsg_mgr->max_msgs : hmsg_mgr->msgs_pending;
+               msg_output = pio_mgr->msg_output;
+               /* Copy num_msgs messages into shared memory */
+               for (i = 0; i < num_msgs; i++) {
+                       if (!hmsg_mgr->msg_used_list) {
+                               pmsg = NULL;
+                               goto func_end;
+                       } else {
+                               pmsg = (struct msg_frame *)
+                                   lst_get_head(hmsg_mgr->msg_used_list);
+                       }
+                       if (pmsg != NULL) {
+                               val = (pmsg->msg_data).msgq_id;
+                               addr = (u32) &(((struct msg_dspmsg *)
+                                                msg_output)->msgq_id);
+                               write_ext32_bit_dsp_data(
+                                       pio_mgr->hbridge_context, addr, val);
+                               val = (pmsg->msg_data).msg.dw_cmd;
+                               addr = (u32) &((((struct msg_dspmsg *)
+                                                 msg_output)->msg).dw_cmd);
+                               write_ext32_bit_dsp_data(
+                                       pio_mgr->hbridge_context, addr, val);
+                               val = (pmsg->msg_data).msg.dw_arg1;
+                               addr = (u32) &((((struct msg_dspmsg *)
+                                                 msg_output)->msg).dw_arg1);
+                               write_ext32_bit_dsp_data(
+                                       pio_mgr->hbridge_context, addr, val);
+                               val = (pmsg->msg_data).msg.dw_arg2;
+                               addr = (u32) &((((struct msg_dspmsg *)
+                                                 msg_output)->msg).dw_arg2);
+                               write_ext32_bit_dsp_data(
+                                       pio_mgr->hbridge_context, addr, val);
+                               msg_output += sizeof(struct msg_dspmsg);
+                               if (!hmsg_mgr->msg_free_list)
+                                       goto func_end;
+                               lst_put_tail(hmsg_mgr->msg_free_list,
+                                            (struct list_head *)pmsg);
+                               sync_set_event(hmsg_mgr->sync_event);
+                       }
+               }
+
+               if (num_msgs > 0) {
+                       hmsg_mgr->msgs_pending -= num_msgs;
+#if _CHNL_WORDSIZE == 2
+                       /*
+                        * Access can be different SM access word size
+                        * (e.g. 16/32 bit words)
+                        */
+                       msg_ctr_obj->size = (u16) num_msgs;
+#else
+                       msg_ctr_obj->size = num_msgs;
+#endif
+                       msg_ctr_obj->buf_empty = false;
+                       /* Set the post SWI flag */
+                       msg_ctr_obj->post_swi = true;
+                       /* Tell the DSP we have written the output. */
+                       sm_interrupt_dsp(pio_mgr->hbridge_context,
+                                               MBX_PCPY_CLASS);
+               }
+       }
+func_end:
+       return;
+}
+
+/*
+ *  ======== register_shm_segs ========
+ *  purpose:
+ *      Registers GPP SM segment with CMM.
+ */
+static int register_shm_segs(struct io_mgr *hio_mgr,
+                                   struct cod_manager *cod_man,
+                                   u32 dw_gpp_base_pa)
+{
+       int status = 0;
+       u32 ul_shm0_base = 0;
+       u32 shm0_end = 0;
+       u32 ul_shm0_rsrvd_start = 0;
+       u32 ul_rsrvd_size = 0;
+       u32 ul_gpp_phys;
+       u32 ul_dsp_virt;
+       u32 ul_shm_seg_id0 = 0;
+       u32 dw_offset, dw_gpp_base_va, ul_dsp_size;
+
+       /*
+        * Read address and size info for first SM region.
+        * Get start of 1st SM Heap region.
+        */
+       status =
+           cod_get_sym_value(cod_man, SHM0_SHARED_BASE_SYM, &ul_shm0_base);
+       if (ul_shm0_base == 0) {
+               status = -EPERM;
+               goto func_end;
+       }
+       /* Get end of 1st SM Heap region */
+       if (!status) {
+               /* Get start and length of message part of shared memory */
+               status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM,
+                                          &shm0_end);
+               if (shm0_end == 0) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+       }
+       /* Start of Gpp reserved region */
+       if (!status) {
+               /* Get start and length of message part of shared memory */
+               status =
+                   cod_get_sym_value(cod_man, SHM0_SHARED_RESERVED_BASE_SYM,
+                                     &ul_shm0_rsrvd_start);
+               if (ul_shm0_rsrvd_start == 0) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+       }
+       /* Register with CMM */
+       if (!status) {
+               status = dev_get_cmm_mgr(hio_mgr->hdev_obj, &hio_mgr->hcmm_mgr);
+               if (!status) {
+                       status = cmm_un_register_gppsm_seg(hio_mgr->hcmm_mgr,
+                                                          CMM_ALLSEGMENTS);
+               }
+       }
+       /* Register new SM region(s) */
+       if (!status && (shm0_end - ul_shm0_base) > 0) {
+               /* Calc size (bytes) of SM the GPP can alloc from */
+               ul_rsrvd_size =
+                   (shm0_end - ul_shm0_rsrvd_start + 1) * hio_mgr->word_size;
+               if (ul_rsrvd_size <= 0) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+               /* Calc size of SM DSP can alloc from */
+               ul_dsp_size =
+                   (ul_shm0_rsrvd_start - ul_shm0_base) * hio_mgr->word_size;
+               if (ul_dsp_size <= 0) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+               /* First TLB entry reserved for Bridge SM use. */
+               ul_gpp_phys = hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys;
+               /* Get size in bytes */
+               ul_dsp_virt =
+                   hio_mgr->ext_proc_info.ty_tlb[0].ul_dsp_virt *
+                   hio_mgr->word_size;
+               /*
+                * Calc byte offset used to convert GPP phys <-> DSP byte
+                * address.
+                */
+               if (dw_gpp_base_pa > ul_dsp_virt)
+                       dw_offset = dw_gpp_base_pa - ul_dsp_virt;
+               else
+                       dw_offset = ul_dsp_virt - dw_gpp_base_pa;
+
+               if (ul_shm0_rsrvd_start * hio_mgr->word_size < ul_dsp_virt) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+               /*
+                * Calc Gpp phys base of SM region.
+                * This is actually uncached kernel virtual address.
+                */
+               dw_gpp_base_va =
+                   ul_gpp_phys + ul_shm0_rsrvd_start * hio_mgr->word_size -
+                   ul_dsp_virt;
+               /*
+                * Calc Gpp phys base of SM region.
+                * This is the physical address.
+                */
+               dw_gpp_base_pa =
+                   dw_gpp_base_pa + ul_shm0_rsrvd_start * hio_mgr->word_size -
+                   ul_dsp_virt;
+               /* Register SM Segment 0. */
+               status =
+                   cmm_register_gppsm_seg(hio_mgr->hcmm_mgr, dw_gpp_base_pa,
+                                          ul_rsrvd_size, dw_offset,
+                                          (dw_gpp_base_pa >
+                                           ul_dsp_virt) ? CMM_ADDTODSPPA :
+                                          CMM_SUBFROMDSPPA,
+                                          (u32) (ul_shm0_base *
+                                                 hio_mgr->word_size),
+                                          ul_dsp_size, &ul_shm_seg_id0,
+                                          dw_gpp_base_va);
+               /* First SM region is seg_id = 1 */
+               if (ul_shm_seg_id0 != 1)
+                       status = -EPERM;
+       }
+func_end:
+       return status;
+}
+
+/* ZCPY IO routines. */
+/*
+ *  ======== IO_SHMcontrol ========
+ *      Sets the requested shm setting.
+ */
+int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs)
+{
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       u32 i;
+       struct dspbridge_platform_data *pdata =
+           omap_dspbridge_dev->dev.platform_data;
+
+       switch (desc) {
+       case SHM_CURROPP:
+               /* Update the shared memory with requested OPP information */
+               if (pargs != NULL)
+                       hio_mgr->shared_mem->opp_table_struct.curr_opp_pt =
+                           *(u32 *) pargs;
+               else
+                       return -EPERM;
+               break;
+       case SHM_OPPINFO:
+               /*
+                * Update the shared memory with the voltage, frequency,
+                * min and max frequency values for an OPP.
+                */
+               for (i = 0; i <= dsp_max_opps; i++) {
+                       hio_mgr->shared_mem->opp_table_struct.opp_point[i].
+                           voltage = vdd1_dsp_freq[i][0];
+                       dev_dbg(bridge, "OPP-shm: voltage: %d\n",
+                               vdd1_dsp_freq[i][0]);
+                       hio_mgr->shared_mem->opp_table_struct.
+                           opp_point[i].frequency = vdd1_dsp_freq[i][1];
+                       dev_dbg(bridge, "OPP-shm: frequency: %d\n",
+                               vdd1_dsp_freq[i][1]);
+                       hio_mgr->shared_mem->opp_table_struct.opp_point[i].
+                           min_freq = vdd1_dsp_freq[i][2];
+                       dev_dbg(bridge, "OPP-shm: min freq: %d\n",
+                               vdd1_dsp_freq[i][2]);
+                       hio_mgr->shared_mem->opp_table_struct.opp_point[i].
+                           max_freq = vdd1_dsp_freq[i][3];
+                       dev_dbg(bridge, "OPP-shm: max freq: %d\n",
+                               vdd1_dsp_freq[i][3]);
+               }
+               hio_mgr->shared_mem->opp_table_struct.num_opp_pts =
+                   dsp_max_opps;
+               dev_dbg(bridge, "OPP-shm: max OPP number: %d\n", dsp_max_opps);
+               /* Update the current OPP number */
+               if (pdata->dsp_get_opp)
+                       i = (*pdata->dsp_get_opp) ();
+               hio_mgr->shared_mem->opp_table_struct.curr_opp_pt = i;
+               dev_dbg(bridge, "OPP-shm: value programmed = %d\n", i);
+               break;
+       case SHM_GETOPP:
+               /* Get the OPP that DSP has requested */
+               *(u32 *) pargs = hio_mgr->shared_mem->opp_request.rqst_opp_pt;
+               break;
+       default:
+               break;
+       }
+#endif
+       return 0;
+}
+
+/*
+ *  ======== bridge_io_get_proc_load ========
+ *      Gets the Processor's Load information
+ */
+int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
+                               struct dsp_procloadstat *proc_lstat)
+{
+       proc_lstat->curr_load =
+                       hio_mgr->shared_mem->load_mon_info.curr_dsp_load;
+       proc_lstat->predicted_load =
+           hio_mgr->shared_mem->load_mon_info.pred_dsp_load;
+       proc_lstat->curr_dsp_freq =
+           hio_mgr->shared_mem->load_mon_info.curr_dsp_freq;
+       proc_lstat->predicted_freq =
+           hio_mgr->shared_mem->load_mon_info.pred_dsp_freq;
+
+       dev_dbg(bridge, "Curr Load = %d, Pred Load = %d, Curr Freq = %d, "
+               "Pred Freq = %d\n", proc_lstat->curr_load,
+               proc_lstat->predicted_load, proc_lstat->curr_dsp_freq,
+               proc_lstat->predicted_freq);
+       return 0;
+}
+
+void io_sm_init(void)
+{
+       /* Do nothing */
+}
+
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+void print_dsp_debug_trace(struct io_mgr *hio_mgr)
+{
+       u32 ul_new_message_length = 0, ul_gpp_cur_pointer;
+
+       while (true) {
+               /* Get the DSP current pointer */
+               ul_gpp_cur_pointer =
+                   *(u32 *) (hio_mgr->ul_trace_buffer_current);
+               ul_gpp_cur_pointer =
+                   hio_mgr->ul_gpp_va + (ul_gpp_cur_pointer -
+                                         hio_mgr->ul_dsp_va);
+
+               /* No new debug messages available yet */
+               if (ul_gpp_cur_pointer == hio_mgr->ul_gpp_read_pointer) {
+                       break;
+               } else if (ul_gpp_cur_pointer > hio_mgr->ul_gpp_read_pointer) {
+                       /* Continuous data */
+                       ul_new_message_length =
+                           ul_gpp_cur_pointer - hio_mgr->ul_gpp_read_pointer;
+
+                       memcpy(hio_mgr->pmsg,
+                              (char *)hio_mgr->ul_gpp_read_pointer,
+                              ul_new_message_length);
+                       hio_mgr->pmsg[ul_new_message_length] = '\0';
+                       /*
+                        * Advance the GPP trace pointer to DSP current
+                        * pointer.
+                        */
+                       hio_mgr->ul_gpp_read_pointer += ul_new_message_length;
+                       /* Print the trace messages */
+                       pr_info("DSPTrace: %s\n", hio_mgr->pmsg);
+               } else if (ul_gpp_cur_pointer < hio_mgr->ul_gpp_read_pointer) {
+                       /* Handle trace buffer wraparound */
+                       memcpy(hio_mgr->pmsg,
+                              (char *)hio_mgr->ul_gpp_read_pointer,
+                              hio_mgr->ul_trace_buffer_end -
+                              hio_mgr->ul_gpp_read_pointer);
+                       ul_new_message_length =
+                           ul_gpp_cur_pointer - hio_mgr->ul_trace_buffer_begin;
+                       memcpy(&hio_mgr->pmsg[hio_mgr->ul_trace_buffer_end -
+                                             hio_mgr->ul_gpp_read_pointer],
+                              (char *)hio_mgr->ul_trace_buffer_begin,
+                              ul_new_message_length);
+                       hio_mgr->pmsg[hio_mgr->ul_trace_buffer_end -
+                                     hio_mgr->ul_gpp_read_pointer +
+                                     ul_new_message_length] = '\0';
+                       /*
+                        * Advance the GPP trace pointer to DSP current
+                        * pointer.
+                        */
+                       hio_mgr->ul_gpp_read_pointer =
+                           hio_mgr->ul_trace_buffer_begin +
+                           ul_new_message_length;
+                       /* Print the trace messages */
+                       pr_info("DSPTrace: %s\n", hio_mgr->pmsg);
+               }
+       }
+}
+#endif
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+/*
+ *  ======== print_dsp_trace_buffer ========
+ *      Prints the trace buffer returned from the DSP (if DBG_Trace is enabled).
+ *  Parameters:
+ *    hdeh_mgr:          Handle to DEH manager object
+ *                      number of extra carriage returns to generate.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Unable to allocate memory.
+ *  Requires:
+ *      hdeh_mgr muse be valid. Checked in bridge_deh_notify.
+ */
+int print_dsp_trace_buffer(struct bridge_dev_context *hbridge_context)
+{
+       int status = 0;
+       struct cod_manager *cod_mgr;
+       u32 ul_trace_end;
+       u32 ul_trace_begin;
+       u32 trace_cur_pos;
+       u32 ul_num_bytes = 0;
+       u32 ul_num_words = 0;
+       u32 ul_word_size = 2;
+       char *psz_buf;
+       char *str_beg;
+       char *trace_end;
+       char *buf_end;
+       char *new_line;
+
+       struct bridge_dev_context *pbridge_context = hbridge_context;
+       struct bridge_drv_interface *intf_fxns;
+       struct dev_object *dev_obj = (struct dev_object *)
+           pbridge_context->hdev_obj;
+
+       status = dev_get_cod_mgr(dev_obj, &cod_mgr);
+
+       if (cod_mgr) {
+               /* Look for SYS_PUTCBEG/SYS_PUTCEND */
+               status =
+                   cod_get_sym_value(cod_mgr, COD_TRACEBEG, &ul_trace_begin);
+       } else {
+               status = -EFAULT;
+       }
+       if (!status)
+               status =
+                   cod_get_sym_value(cod_mgr, COD_TRACEEND, &ul_trace_end);
+
+       if (!status)
+               /* trace_cur_pos will hold the address of a DSP pointer */
+               status = cod_get_sym_value(cod_mgr, COD_TRACECURPOS,
+                                                       &trace_cur_pos);
+
+       if (status)
+               goto func_end;
+
+       ul_num_bytes = (ul_trace_end - ul_trace_begin);
+
+       ul_num_words = ul_num_bytes * ul_word_size;
+       status = dev_get_intf_fxns(dev_obj, &intf_fxns);
+
+       if (status)
+               goto func_end;
+
+       psz_buf = kzalloc(ul_num_bytes + 2, GFP_ATOMIC);
+       if (psz_buf != NULL) {
+               /* Read trace buffer data */
+               status = (*intf_fxns->pfn_brd_read)(pbridge_context,
+                       (u8 *)psz_buf, (u32)ul_trace_begin,
+                       ul_num_bytes, 0);
+
+               if (status)
+                       goto func_end;
+
+               /* Pack and do newline conversion */
+               pr_debug("PrintDspTraceBuffer: "
+                       "before pack and unpack.\n");
+               pr_debug("%s: DSP Trace Buffer Begin:\n"
+                       "=======================\n%s\n",
+                       __func__, psz_buf);
+
+               /* Read the value at the DSP address in trace_cur_pos. */
+               status = (*intf_fxns->pfn_brd_read)(pbridge_context,
+                               (u8 *)&trace_cur_pos, (u32)trace_cur_pos,
+                               4, 0);
+               if (status)
+                       goto func_end;
+               /* Pack and do newline conversion */
+               pr_info("DSP Trace Buffer Begin:\n"
+                       "=======================\n%s\n",
+                       psz_buf);
+
+
+               /* convert to offset */
+               trace_cur_pos = trace_cur_pos - ul_trace_begin;
+
+               if (ul_num_bytes) {
+                       /*
+                        * The buffer is not full, find the end of the
+                        * data -- buf_end will be >= pszBuf after
+                        * while.
+                        */
+                       buf_end = &psz_buf[ul_num_bytes+1];
+                       /* DSP print position */
+                       trace_end = &psz_buf[trace_cur_pos];
+
+                       /*
+                        * Search buffer for a new_line and replace it
+                        * with '\0', then print as string.
+                        * Continue until end of buffer is reached.
+                        */
+                       str_beg = trace_end;
+                       ul_num_bytes = buf_end - str_beg;
+
+                       while (str_beg < buf_end) {
+                               new_line = strnchr(str_beg, ul_num_bytes,
+                                                               '\n');
+                               if (new_line && new_line < buf_end) {
+                                       *new_line = 0;
+                                       pr_debug("%s\n", str_beg);
+                                       str_beg = ++new_line;
+                                       ul_num_bytes = buf_end - str_beg;
+                               } else {
+                                       /*
+                                        * Assume buffer empty if it contains
+                                        * a zero
+                                        */
+                                       if (*str_beg != '\0') {
+                                               str_beg[ul_num_bytes] = 0;
+                                               pr_debug("%s\n", str_beg);
+                                       }
+                                       str_beg = buf_end;
+                                       ul_num_bytes = 0;
+                               }
+                       }
+                       /*
+                        * Search buffer for a nNewLine and replace it
+                        * with '\0', then print as string.
+                        * Continue until buffer is exhausted.
+                        */
+                       str_beg = psz_buf;
+                       ul_num_bytes = trace_end - str_beg;
+
+                       while (str_beg < trace_end) {
+                               new_line = strnchr(str_beg, ul_num_bytes, '\n');
+                               if (new_line != NULL && new_line < trace_end) {
+                                       *new_line = 0;
+                                       pr_debug("%s\n", str_beg);
+                                       str_beg = ++new_line;
+                                       ul_num_bytes = trace_end - str_beg;
+                               } else {
+                                       /*
+                                        * Assume buffer empty if it contains
+                                        * a zero
+                                        */
+                                       if (*str_beg != '\0') {
+                                               str_beg[ul_num_bytes] = 0;
+                                               pr_debug("%s\n", str_beg);
+                                       }
+                                       str_beg = trace_end;
+                                       ul_num_bytes = 0;
+                               }
+                       }
+               }
+               pr_info("\n=======================\n"
+                       "DSP Trace Buffer End:\n");
+               kfree(psz_buf);
+       } else {
+               status = -ENOMEM;
+       }
+func_end:
+       if (status)
+               dev_dbg(bridge, "%s Failed, status 0x%x\n", __func__, status);
+       return status;
+}
+
+/**
+ * dump_dsp_stack() - This function dumps the data on the DSP stack.
+ * @bridge_context:    Bridge driver's device context pointer.
+ *
+ */
+int dump_dsp_stack(struct bridge_dev_context *bridge_context)
+{
+       int status = 0;
+       struct cod_manager *code_mgr;
+       struct node_mgr *node_mgr;
+       u32 trace_begin;
+       char name[256];
+       struct {
+               u32 head[2];
+               u32 size;
+       } mmu_fault_dbg_info;
+       u32 *buffer;
+       u32 *buffer_beg;
+       u32 *buffer_end;
+       u32 exc_type;
+       u32 dyn_ext_base;
+       u32 i;
+       u32 offset_output;
+       u32 total_size;
+       u32 poll_cnt;
+       const char *dsp_regs[] = {"EFR", "IERR", "ITSR", "NTSR",
+                               "IRP", "NRP", "AMR", "SSR",
+                               "ILC", "RILC", "IER", "CSR"};
+       const char *exec_ctxt[] = {"Task", "SWI", "HWI", "Unknown"};
+       struct bridge_drv_interface *intf_fxns;
+       struct dev_object *dev_object = bridge_context->hdev_obj;
+
+       status = dev_get_cod_mgr(dev_object, &code_mgr);
+       if (!code_mgr) {
+               pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__);
+               status = -EFAULT;
+       }
+
+       if (!status) {
+               status = dev_get_node_manager(dev_object, &node_mgr);
+               if (!node_mgr) {
+                       pr_debug("%s: Failed on dev_get_node_manager.\n",
+                                                               __func__);
+                       status = -EFAULT;
+               }
+       }
+
+       if (!status) {
+               /* Look for SYS_PUTCBEG/SYS_PUTCEND: */
+               status =
+                       cod_get_sym_value(code_mgr, COD_TRACEBEG, &trace_begin);
+               pr_debug("%s: trace_begin Value 0x%x\n",
+                       __func__, trace_begin);
+               if (status)
+                       pr_debug("%s: Failed on cod_get_sym_value.\n",
+                                                               __func__);
+       }
+       if (!status)
+               status = dev_get_intf_fxns(dev_object, &intf_fxns);
+       /*
+        * Check for the "magic number" in the trace buffer.  If it has
+        * yet to appear then poll the trace buffer to wait for it.  Its
+        * appearance signals that the DSP has finished dumping its state.
+        */
+       mmu_fault_dbg_info.head[0] = 0;
+       mmu_fault_dbg_info.head[1] = 0;
+       if (!status) {
+               poll_cnt = 0;
+               while ((mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 ||
+                       mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) &&
+                       poll_cnt < POLL_MAX) {
+
+                       /* Read DSP dump size from the DSP trace buffer... */
+                       status = (*intf_fxns->pfn_brd_read)(bridge_context,
+                               (u8 *)&mmu_fault_dbg_info, (u32)trace_begin,
+                               sizeof(mmu_fault_dbg_info), 0);
+
+                       if (status)
+                               break;
+
+                       poll_cnt++;
+               }
+
+               if (mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 &&
+                       mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) {
+                       status = -ETIME;
+                       pr_err("%s:No DSP MMU-Fault information available.\n",
+                                                       __func__);
+               }
+       }
+
+       if (!status) {
+               total_size = mmu_fault_dbg_info.size;
+               /* Limit the size in case DSP went crazy */
+               if (total_size > MAX_MMU_DBGBUFF)
+                       total_size = MAX_MMU_DBGBUFF;
+
+               buffer = kzalloc(total_size, GFP_ATOMIC);
+               if (!buffer) {
+                       status = -ENOMEM;
+                       pr_debug("%s: Failed to "
+                               "allocate stack dump buffer.\n", __func__);
+                       goto func_end;
+               }
+
+               buffer_beg = buffer;
+               buffer_end =  buffer + total_size / 4;
+
+               /* Read bytes from the DSP trace buffer... */
+               status = (*intf_fxns->pfn_brd_read)(bridge_context,
+                               (u8 *)buffer, (u32)trace_begin,
+                               total_size, 0);
+               if (status) {
+                       pr_debug("%s: Failed to Read Trace Buffer.\n",
+                                                               __func__);
+                       goto func_end;
+               }
+
+               pr_err("\nAproximate Crash Position:\n"
+                       "--------------------------\n");
+
+               exc_type = buffer[3];
+               if (!exc_type)
+                       i = buffer[79];         /* IRP */
+               else
+                       i = buffer[80];         /* NRP */
+
+               status =
+                   cod_get_sym_value(code_mgr, DYNEXTBASE, &dyn_ext_base);
+               if (status) {
+                       status = -EFAULT;
+                       goto func_end;
+               }
+
+               if ((i > dyn_ext_base) && (node_find_addr(node_mgr, i,
+                       0x1000, &offset_output, name) == 0))
+                       pr_err("0x%-8x [\"%s\" + 0x%x]\n", i, name,
+                                                       i - offset_output);
+               else
+                       pr_err("0x%-8x [Unable to match to a symbol.]\n", i);
+
+               buffer += 4;
+
+               pr_err("\nExecution Info:\n"
+                       "---------------\n");
+
+               if (*buffer < ARRAY_SIZE(exec_ctxt)) {
+                       pr_err("Execution context \t%s\n",
+                               exec_ctxt[*buffer++]);
+               } else {
+                       pr_err("Execution context corrupt\n");
+                       kfree(buffer_beg);
+                       return -EFAULT;
+               }
+               pr_err("Task Handle\t\t0x%x\n", *buffer++);
+               pr_err("Stack Pointer\t\t0x%x\n", *buffer++);
+               pr_err("Stack Top\t\t0x%x\n", *buffer++);
+               pr_err("Stack Bottom\t\t0x%x\n", *buffer++);
+               pr_err("Stack Size\t\t0x%x\n", *buffer++);
+               pr_err("Stack Size In Use\t0x%x\n", *buffer++);
+
+               pr_err("\nCPU Registers\n"
+                       "---------------\n");
+
+               for (i = 0; i < 32; i++) {
+                       if (i == 4 || i == 6 || i == 8)
+                               pr_err("A%d 0x%-8x [Function Argument %d]\n",
+                                                       i, *buffer++, i-3);
+                       else if (i == 15)
+                               pr_err("A15 0x%-8x [Frame Pointer]\n",
+                                                               *buffer++);
+                       else
+                               pr_err("A%d 0x%x\n", i, *buffer++);
+               }
+
+               pr_err("\nB0 0x%x\n", *buffer++);
+               pr_err("B1 0x%x\n", *buffer++);
+               pr_err("B2 0x%x\n", *buffer++);
+
+               if ((*buffer > dyn_ext_base) && (node_find_addr(node_mgr,
+                       *buffer, 0x1000, &offset_output, name) == 0))
+
+                       pr_err("B3 0x%-8x [Function Return Pointer:"
+                               " \"%s\" + 0x%x]\n", *buffer, name,
+                               *buffer - offset_output);
+               else
+                       pr_err("B3 0x%-8x [Function Return Pointer:"
+                               "Unable to match to a symbol.]\n", *buffer);
+
+               buffer++;
+
+               for (i = 4; i < 32; i++) {
+                       if (i == 4 || i == 6 || i == 8)
+                               pr_err("B%d 0x%-8x [Function Argument %d]\n",
+                                                       i, *buffer++, i-2);
+                       else if (i == 14)
+                               pr_err("B14 0x%-8x [Data Page Pointer]\n",
+                                                               *buffer++);
+                       else
+                               pr_err("B%d 0x%x\n", i, *buffer++);
+               }
+
+               pr_err("\n");
+
+               for (i = 0; i < ARRAY_SIZE(dsp_regs); i++)
+                       pr_err("%s 0x%x\n", dsp_regs[i], *buffer++);
+
+               pr_err("\nStack:\n"
+                       "------\n");
+
+               for (i = 0; buffer < buffer_end; i++, buffer++) {
+                       if ((*buffer > dyn_ext_base) && (
+                               node_find_addr(node_mgr, *buffer , 0x600,
+                               &offset_output, name) == 0))
+                               pr_err("[%d] 0x%-8x [\"%s\" + 0x%x]\n",
+                                       i, *buffer, name,
+                                       *buffer - offset_output);
+                       else
+                               pr_err("[%d] 0x%x\n", i, *buffer);
+               }
+               kfree(buffer_beg);
+       }
+func_end:
+       return status;
+}
+
+/**
+ * dump_dl_modules() - This functions dumps the _DLModules loaded in DSP side
+ * @bridge_context:            Bridge driver's device context pointer.
+ *
+ */
+void dump_dl_modules(struct bridge_dev_context *bridge_context)
+{
+       struct cod_manager *code_mgr;
+       struct bridge_drv_interface *intf_fxns;
+       struct bridge_dev_context *bridge_ctxt = bridge_context;
+       struct dev_object *dev_object = bridge_ctxt->hdev_obj;
+       struct modules_header modules_hdr;
+       struct dll_module *module_struct = NULL;
+       u32 module_dsp_addr;
+       u32 module_size;
+       u32 module_struct_size = 0;
+       u32 sect_ndx;
+       char *sect_str ;
+       int status = 0;
+
+       status = dev_get_intf_fxns(dev_object, &intf_fxns);
+       if (status) {
+               pr_debug("%s: Failed on dev_get_intf_fxns.\n", __func__);
+               goto func_end;
+       }
+
+       status = dev_get_cod_mgr(dev_object, &code_mgr);
+       if (!code_mgr) {
+               pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__);
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       /* Lookup  the address of the modules_header structure */
+       status = cod_get_sym_value(code_mgr, "_DLModules", &module_dsp_addr);
+       if (status) {
+               pr_debug("%s: Failed on cod_get_sym_value for _DLModules.\n",
+                       __func__);
+               goto func_end;
+       }
+
+       pr_debug("%s: _DLModules at 0x%x\n", __func__, module_dsp_addr);
+
+       /* Copy the modules_header structure from DSP memory. */
+       status = (*intf_fxns->pfn_brd_read)(bridge_context, (u8 *) &modules_hdr,
+                               (u32) module_dsp_addr, sizeof(modules_hdr), 0);
+
+       if (status) {
+               pr_debug("%s: Failed failed to read modules header.\n",
+                                                               __func__);
+               goto func_end;
+       }
+
+       module_dsp_addr = modules_hdr.first_module;
+       module_size = modules_hdr.first_module_size;
+
+       pr_debug("%s: dll_module_header 0x%x %d\n", __func__, module_dsp_addr,
+                                                               module_size);
+
+       pr_err("\nDynamically Loaded Modules:\n"
+               "---------------------------\n");
+
+       /* For each dll_module structure in the list... */
+       while (module_size) {
+               /*
+                * Allocate/re-allocate memory to hold the dll_module
+                * structure. The memory is re-allocated only if the existing
+                * allocation is too small.
+                */
+               if (module_size > module_struct_size) {
+                       kfree(module_struct);
+                       module_struct = kzalloc(module_size+128, GFP_ATOMIC);
+                       module_struct_size = module_size+128;
+                       pr_debug("%s: allocated module struct %p %d\n",
+                               __func__, module_struct, module_struct_size);
+                       if (!module_struct)
+                               goto func_end;
+               }
+               /* Copy the dll_module structure from DSP memory */
+               status = (*intf_fxns->pfn_brd_read)(bridge_context,
+                       (u8 *)module_struct, module_dsp_addr, module_size, 0);
+
+               if (status) {
+                       pr_debug(
+                       "%s: Failed to read dll_module stuct for 0x%x.\n",
+                       __func__, module_dsp_addr);
+                       break;
+               }
+
+               /* Update info regarding the _next_ module in the list. */
+               module_dsp_addr = module_struct->next_module;
+               module_size = module_struct->next_module_size;
+
+               pr_debug("%s: next module 0x%x %d, this module num sects %d\n",
+                       __func__, module_dsp_addr, module_size,
+                       module_struct->num_sects);
+
+               /*
+                * The section name strings start immedialty following
+                * the array of dll_sect structures.
+                */
+               sect_str = (char *) &module_struct->
+                                       sects[module_struct->num_sects];
+               pr_err("%s\n", sect_str);
+
+               /*
+                * Advance to the first section name string.
+                * Each string follows the one before.
+                */
+               sect_str += strlen(sect_str) + 1;
+
+               /* Access each dll_sect structure and its name string. */
+               for (sect_ndx = 0;
+                       sect_ndx < module_struct->num_sects; sect_ndx++) {
+                       pr_err("    Section: 0x%x ",
+                               module_struct->sects[sect_ndx].sect_load_adr);
+
+                       if (((u32) sect_str - (u32) module_struct) <
+                               module_struct_size) {
+                               pr_err("%s\n", sect_str);
+                               /* Each string follows the one before. */
+                               sect_str += strlen(sect_str)+1;
+                       } else {
+                               pr_err("<string error>\n");
+                               pr_debug("%s: section name sting address "
+                                       "is invalid %p\n", __func__, sect_str);
+                       }
+               }
+       }
+func_end:
+       kfree(module_struct);
+}
+#endif
diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c
new file mode 100644 (file)
index 0000000..87712e2
--- /dev/null
@@ -0,0 +1,673 @@
+/*
+ * msg_sm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implements upper edge functions for Bridge message module.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/list.h>
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/io_sm.h>
+
+/*  ----------------------------------- This */
+#include <_msg_sm.h>
+#include <dspbridge/dspmsg.h>
+
+/*  ----------------------------------- Function Prototypes */
+static int add_new_msg(struct lst_list *msg_list);
+static void delete_msg_mgr(struct msg_mgr *hmsg_mgr);
+static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp);
+static void free_msg_list(struct lst_list *msg_list);
+
+/*
+ *  ======== bridge_msg_create ========
+ *      Create an object to manage message queues. Only one of these objects
+ *      can exist per device object.
+ */
+int bridge_msg_create(struct msg_mgr **msg_man,
+                            struct dev_object *hdev_obj,
+                            msg_onexit msg_callback)
+{
+       struct msg_mgr *msg_mgr_obj;
+       struct io_mgr *hio_mgr;
+       int status = 0;
+
+       if (!msg_man || !msg_callback || !hdev_obj) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       dev_get_io_mgr(hdev_obj, &hio_mgr);
+       if (!hio_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       *msg_man = NULL;
+       /* Allocate msg_ctrl manager object */
+       msg_mgr_obj = kzalloc(sizeof(struct msg_mgr), GFP_KERNEL);
+
+       if (msg_mgr_obj) {
+               msg_mgr_obj->on_exit = msg_callback;
+               msg_mgr_obj->hio_mgr = hio_mgr;
+               /* List of MSG_QUEUEs */
+               msg_mgr_obj->queue_list = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               /*  Queues of message frames for messages to the DSP. Message
+                * frames will only be added to the free queue when a
+                * msg_queue object is created. */
+               msg_mgr_obj->msg_free_list = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               msg_mgr_obj->msg_used_list = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               if (msg_mgr_obj->queue_list == NULL ||
+                   msg_mgr_obj->msg_free_list == NULL ||
+                   msg_mgr_obj->msg_used_list == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       INIT_LIST_HEAD(&msg_mgr_obj->queue_list->head);
+                       INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list->head);
+                       INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list->head);
+                       spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
+               }
+
+               /*  Create an event to be used by bridge_msg_put() in waiting
+                *  for an available free frame from the message manager. */
+               msg_mgr_obj->sync_event =
+                               kzalloc(sizeof(struct sync_object), GFP_KERNEL);
+               if (!msg_mgr_obj->sync_event)
+                       status = -ENOMEM;
+               else
+                       sync_init_event(msg_mgr_obj->sync_event);
+
+               if (!status)
+                       *msg_man = msg_mgr_obj;
+               else
+                       delete_msg_mgr(msg_mgr_obj);
+
+       } else {
+               status = -ENOMEM;
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_msg_create_queue ========
+ *      Create a msg_queue for sending/receiving messages to/from a node
+ *      on the DSP.
+ */
+int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
+                               struct msg_queue **msgq,
+                               u32 msgq_id, u32 max_msgs, void *arg)
+{
+       u32 i;
+       u32 num_allocated = 0;
+       struct msg_queue *msg_q;
+       int status = 0;
+
+       if (!hmsg_mgr || msgq == NULL || !hmsg_mgr->msg_free_list) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       *msgq = NULL;
+       /* Allocate msg_queue object */
+       msg_q = kzalloc(sizeof(struct msg_queue), GFP_KERNEL);
+       if (!msg_q) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       lst_init_elem((struct list_head *)msg_q);
+       msg_q->max_msgs = max_msgs;
+       msg_q->hmsg_mgr = hmsg_mgr;
+       msg_q->arg = arg;       /* Node handle */
+       msg_q->msgq_id = msgq_id;       /* Node env (not valid yet) */
+       /* Queues of Message frames for messages from the DSP */
+       msg_q->msg_free_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL);
+       msg_q->msg_used_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL);
+       if (msg_q->msg_free_list == NULL || msg_q->msg_used_list == NULL)
+               status = -ENOMEM;
+       else {
+               INIT_LIST_HEAD(&msg_q->msg_free_list->head);
+               INIT_LIST_HEAD(&msg_q->msg_used_list->head);
+       }
+
+       /*  Create event that will be signalled when a message from
+        *  the DSP is available. */
+       if (!status) {
+               msg_q->sync_event = kzalloc(sizeof(struct sync_object),
+                                                       GFP_KERNEL);
+               if (msg_q->sync_event)
+                       sync_init_event(msg_q->sync_event);
+               else
+                       status = -ENOMEM;
+       }
+
+       /* Create a notification list for message ready notification. */
+       if (!status) {
+               msg_q->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
+                                                       GFP_KERNEL);
+               if (msg_q->ntfy_obj)
+                       ntfy_init(msg_q->ntfy_obj);
+               else
+                       status = -ENOMEM;
+       }
+
+       /*  Create events that will be used to synchronize cleanup
+        *  when the object is deleted. sync_done will be set to
+        *  unblock threads in MSG_Put() or MSG_Get(). sync_done_ack
+        *  will be set by the unblocked thread to signal that it
+        *  is unblocked and will no longer reference the object. */
+       if (!status) {
+               msg_q->sync_done = kzalloc(sizeof(struct sync_object),
+                                                       GFP_KERNEL);
+               if (msg_q->sync_done)
+                       sync_init_event(msg_q->sync_done);
+               else
+                       status = -ENOMEM;
+       }
+
+       if (!status) {
+               msg_q->sync_done_ack = kzalloc(sizeof(struct sync_object),
+                                                       GFP_KERNEL);
+               if (msg_q->sync_done_ack)
+                       sync_init_event(msg_q->sync_done_ack);
+               else
+                       status = -ENOMEM;
+       }
+
+       if (!status) {
+               /* Enter critical section */
+               spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
+               /* Initialize message frames and put in appropriate queues */
+               for (i = 0; i < max_msgs && !status; i++) {
+                       status = add_new_msg(hmsg_mgr->msg_free_list);
+                       if (!status) {
+                               num_allocated++;
+                               status = add_new_msg(msg_q->msg_free_list);
+                       }
+               }
+               if (status) {
+                       /*  Stay inside CS to prevent others from taking any
+                        *  of the newly allocated message frames. */
+                       delete_msg_queue(msg_q, num_allocated);
+               } else {
+                       lst_put_tail(hmsg_mgr->queue_list,
+                                    (struct list_head *)msg_q);
+                       *msgq = msg_q;
+                       /* Signal that free frames are now available */
+                       if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list))
+                               sync_set_event(hmsg_mgr->sync_event);
+
+               }
+               /* Exit critical section */
+               spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+       } else {
+               delete_msg_queue(msg_q, 0);
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_msg_delete ========
+ *      Delete a msg_ctrl manager allocated in bridge_msg_create().
+ */
+void bridge_msg_delete(struct msg_mgr *hmsg_mgr)
+{
+       if (hmsg_mgr)
+               delete_msg_mgr(hmsg_mgr);
+}
+
+/*
+ *  ======== bridge_msg_delete_queue ========
+ *      Delete a msg_ctrl queue allocated in bridge_msg_create_queue.
+ */
+void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj)
+{
+       struct msg_mgr *hmsg_mgr;
+       u32 io_msg_pend;
+
+       if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr)
+               goto func_end;
+
+       hmsg_mgr = msg_queue_obj->hmsg_mgr;
+       msg_queue_obj->done = true;
+       /*  Unblock all threads blocked in MSG_Get() or MSG_Put(). */
+       io_msg_pend = msg_queue_obj->io_msg_pend;
+       while (io_msg_pend) {
+               /* Unblock thread */
+               sync_set_event(msg_queue_obj->sync_done);
+               /* Wait for acknowledgement */
+               sync_wait_on_event(msg_queue_obj->sync_done_ack, SYNC_INFINITE);
+               io_msg_pend = msg_queue_obj->io_msg_pend;
+       }
+       /* Remove message queue from hmsg_mgr->queue_list */
+       spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
+       lst_remove_elem(hmsg_mgr->queue_list,
+                       (struct list_head *)msg_queue_obj);
+       /* Free the message queue object */
+       delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs);
+       if (!hmsg_mgr->msg_free_list)
+               goto func_cont;
+       if (LST_IS_EMPTY(hmsg_mgr->msg_free_list))
+               sync_reset_event(hmsg_mgr->sync_event);
+func_cont:
+       spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+func_end:
+       return;
+}
+
+/*
+ *  ======== bridge_msg_get ========
+ *      Get a message from a msg_ctrl queue.
+ */
+int bridge_msg_get(struct msg_queue *msg_queue_obj,
+                         struct dsp_msg *pmsg, u32 utimeout)
+{
+       struct msg_frame *msg_frame_obj;
+       struct msg_mgr *hmsg_mgr;
+       bool got_msg = false;
+       struct sync_object *syncs[2];
+       u32 index;
+       int status = 0;
+
+       if (!msg_queue_obj || pmsg == NULL) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+
+       hmsg_mgr = msg_queue_obj->hmsg_mgr;
+       if (!msg_queue_obj->msg_used_list) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       /* Enter critical section */
+       spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
+       /* If a message is already there, get it */
+       if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list)) {
+               msg_frame_obj = (struct msg_frame *)
+                   lst_get_head(msg_queue_obj->msg_used_list);
+               if (msg_frame_obj != NULL) {
+                       *pmsg = msg_frame_obj->msg_data.msg;
+                       lst_put_tail(msg_queue_obj->msg_free_list,
+                                    (struct list_head *)msg_frame_obj);
+                       if (LST_IS_EMPTY(msg_queue_obj->msg_used_list))
+                               sync_reset_event(msg_queue_obj->sync_event);
+
+                       got_msg = true;
+               }
+       } else {
+               if (msg_queue_obj->done)
+                       status = -EPERM;
+               else
+                       msg_queue_obj->io_msg_pend++;
+
+       }
+       /* Exit critical section */
+       spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+       if (!status && !got_msg) {
+               /*  Wait til message is available, timeout, or done. We don't
+                *  have to schedule the DPC, since the DSP will send messages
+                *  when they are available. */
+               syncs[0] = msg_queue_obj->sync_event;
+               syncs[1] = msg_queue_obj->sync_done;
+               status = sync_wait_on_multiple_events(syncs, 2, utimeout,
+                                                     &index);
+               /* Enter critical section */
+               spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
+               if (msg_queue_obj->done) {
+                       msg_queue_obj->io_msg_pend--;
+                       /* Exit critical section */
+                       spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+                       /*  Signal that we're not going to access msg_queue_obj
+                        *  anymore, so it can be deleted. */
+                       (void)sync_set_event(msg_queue_obj->sync_done_ack);
+                       status = -EPERM;
+               } else {
+                       if (!status) {
+                               DBC_ASSERT(!LST_IS_EMPTY
+                                          (msg_queue_obj->msg_used_list));
+                               /* Get msg from used list */
+                               msg_frame_obj = (struct msg_frame *)
+                                   lst_get_head(msg_queue_obj->msg_used_list);
+                               /* Copy message into pmsg and put frame on the
+                                * free list */
+                               if (msg_frame_obj != NULL) {
+                                       *pmsg = msg_frame_obj->msg_data.msg;
+                                       lst_put_tail
+                                           (msg_queue_obj->msg_free_list,
+                                            (struct list_head *)
+                                            msg_frame_obj);
+                               }
+                       }
+                       msg_queue_obj->io_msg_pend--;
+                       /* Reset the event if there are still queued messages */
+                       if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list))
+                               sync_set_event(msg_queue_obj->sync_event);
+
+                       /* Exit critical section */
+                       spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+               }
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_msg_put ========
+ *      Put a message onto a msg_ctrl queue.
+ */
+int bridge_msg_put(struct msg_queue *msg_queue_obj,
+                         const struct dsp_msg *pmsg, u32 utimeout)
+{
+       struct msg_frame *msg_frame_obj;
+       struct msg_mgr *hmsg_mgr;
+       bool put_msg = false;
+       struct sync_object *syncs[2];
+       u32 index;
+       int status = 0;
+
+       if (!msg_queue_obj || !pmsg || !msg_queue_obj->hmsg_mgr) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       hmsg_mgr = msg_queue_obj->hmsg_mgr;
+       if (!hmsg_mgr->msg_free_list) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
+
+       /* If a message frame is available, use it */
+       if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
+               msg_frame_obj =
+                   (struct msg_frame *)lst_get_head(hmsg_mgr->msg_free_list);
+               if (msg_frame_obj != NULL) {
+                       msg_frame_obj->msg_data.msg = *pmsg;
+                       msg_frame_obj->msg_data.msgq_id =
+                           msg_queue_obj->msgq_id;
+                       lst_put_tail(hmsg_mgr->msg_used_list,
+                                    (struct list_head *)msg_frame_obj);
+                       hmsg_mgr->msgs_pending++;
+                       put_msg = true;
+               }
+               if (LST_IS_EMPTY(hmsg_mgr->msg_free_list))
+                       sync_reset_event(hmsg_mgr->sync_event);
+
+               /* Release critical section before scheduling DPC */
+               spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+               /* Schedule a DPC, to do the actual data transfer: */
+               iosm_schedule(hmsg_mgr->hio_mgr);
+       } else {
+               if (msg_queue_obj->done)
+                       status = -EPERM;
+               else
+                       msg_queue_obj->io_msg_pend++;
+
+               spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+       }
+       if (!status && !put_msg) {
+               /* Wait til a free message frame is available, timeout,
+                * or done */
+               syncs[0] = hmsg_mgr->sync_event;
+               syncs[1] = msg_queue_obj->sync_done;
+               status = sync_wait_on_multiple_events(syncs, 2, utimeout,
+                                                     &index);
+               if (status)
+                       goto func_end;
+               /* Enter critical section */
+               spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
+               if (msg_queue_obj->done) {
+                       msg_queue_obj->io_msg_pend--;
+                       /* Exit critical section */
+                       spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+                       /*  Signal that we're not going to access msg_queue_obj
+                        *  anymore, so it can be deleted. */
+                       (void)sync_set_event(msg_queue_obj->sync_done_ack);
+                       status = -EPERM;
+               } else {
+                       if (LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
+                               status = -EFAULT;
+                               goto func_cont;
+                       }
+                       /* Get msg from free list */
+                       msg_frame_obj = (struct msg_frame *)
+                           lst_get_head(hmsg_mgr->msg_free_list);
+                       /*
+                        * Copy message into pmsg and put frame on the
+                        * used list.
+                        */
+                       if (msg_frame_obj) {
+                               msg_frame_obj->msg_data.msg = *pmsg;
+                               msg_frame_obj->msg_data.msgq_id =
+                                   msg_queue_obj->msgq_id;
+                               lst_put_tail(hmsg_mgr->msg_used_list,
+                                            (struct list_head *)msg_frame_obj);
+                               hmsg_mgr->msgs_pending++;
+                               /*
+                                * Schedule a DPC, to do the actual
+                                * data transfer.
+                                */
+                               iosm_schedule(hmsg_mgr->hio_mgr);
+                       }
+
+                       msg_queue_obj->io_msg_pend--;
+                       /* Reset event if there are still frames available */
+                       if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list))
+                               sync_set_event(hmsg_mgr->sync_event);
+func_cont:
+                       /* Exit critical section */
+                       spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
+               }
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_msg_register_notify ========
+ */
+int bridge_msg_register_notify(struct msg_queue *msg_queue_obj,
+                                  u32 event_mask, u32 notify_type,
+                                  struct dsp_notification *hnotification)
+{
+       int status = 0;
+
+       if (!msg_queue_obj || !hnotification) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+
+       if (!(event_mask == DSP_NODEMESSAGEREADY || event_mask == 0)) {
+               status = -EPERM;
+               goto func_end;
+       }
+
+       if (notify_type != DSP_SIGNALEVENT) {
+               status = -EBADR;
+               goto func_end;
+       }
+
+       if (event_mask)
+               status = ntfy_register(msg_queue_obj->ntfy_obj, hnotification,
+                                               event_mask, notify_type);
+       else
+               status = ntfy_unregister(msg_queue_obj->ntfy_obj,
+                                                       hnotification);
+
+       if (status == -EINVAL) {
+               /*  Not registered. Ok, since we couldn't have known. Node
+                *  notifications are split between node state change handled
+                *  by NODE, and message ready handled by msg_ctrl. */
+               status = 0;
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_msg_set_queue_id ========
+ */
+void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, u32 msgq_id)
+{
+       /*
+        *  A message queue must be created when a node is allocated,
+        *  so that node_register_notify() can be called before the node
+        *  is created. Since we don't know the node environment until the
+        *  node is created, we need this function to set msg_queue_obj->msgq_id
+        *  to the node environment, after the node is created.
+        */
+       if (msg_queue_obj)
+               msg_queue_obj->msgq_id = msgq_id;
+}
+
+/*
+ *  ======== add_new_msg ========
+ *      Must be called in message manager critical section.
+ */
+static int add_new_msg(struct lst_list *msg_list)
+{
+       struct msg_frame *pmsg;
+       int status = 0;
+
+       pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC);
+       if (pmsg != NULL) {
+               lst_init_elem((struct list_head *)pmsg);
+               lst_put_tail(msg_list, (struct list_head *)pmsg);
+       } else {
+               status = -ENOMEM;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== delete_msg_mgr ========
+ */
+static void delete_msg_mgr(struct msg_mgr *hmsg_mgr)
+{
+       if (!hmsg_mgr)
+               goto func_end;
+
+       if (hmsg_mgr->queue_list) {
+               if (LST_IS_EMPTY(hmsg_mgr->queue_list)) {
+                       kfree(hmsg_mgr->queue_list);
+                       hmsg_mgr->queue_list = NULL;
+               }
+       }
+
+       if (hmsg_mgr->msg_free_list) {
+               free_msg_list(hmsg_mgr->msg_free_list);
+               hmsg_mgr->msg_free_list = NULL;
+       }
+
+       if (hmsg_mgr->msg_used_list) {
+               free_msg_list(hmsg_mgr->msg_used_list);
+               hmsg_mgr->msg_used_list = NULL;
+       }
+
+       kfree(hmsg_mgr->sync_event);
+
+       kfree(hmsg_mgr);
+func_end:
+       return;
+}
+
+/*
+ *  ======== delete_msg_queue ========
+ */
+static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp)
+{
+       struct msg_mgr *hmsg_mgr;
+       struct msg_frame *pmsg;
+       u32 i;
+
+       if (!msg_queue_obj ||
+           !msg_queue_obj->hmsg_mgr || !msg_queue_obj->hmsg_mgr->msg_free_list)
+               goto func_end;
+
+       hmsg_mgr = msg_queue_obj->hmsg_mgr;
+
+       /* Pull off num_to_dsp message frames from Msg manager and free */
+       for (i = 0; i < num_to_dsp; i++) {
+
+               if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
+                       pmsg = (struct msg_frame *)
+                           lst_get_head(hmsg_mgr->msg_free_list);
+                       kfree(pmsg);
+               } else {
+                       /* Cannot free all of the message frames */
+                       break;
+               }
+       }
+
+       if (msg_queue_obj->msg_free_list) {
+               free_msg_list(msg_queue_obj->msg_free_list);
+               msg_queue_obj->msg_free_list = NULL;
+       }
+
+       if (msg_queue_obj->msg_used_list) {
+               free_msg_list(msg_queue_obj->msg_used_list);
+               msg_queue_obj->msg_used_list = NULL;
+       }
+
+       if (msg_queue_obj->ntfy_obj) {
+               ntfy_delete(msg_queue_obj->ntfy_obj);
+               kfree(msg_queue_obj->ntfy_obj);
+       }
+
+       kfree(msg_queue_obj->sync_event);
+       kfree(msg_queue_obj->sync_done);
+       kfree(msg_queue_obj->sync_done_ack);
+
+       kfree(msg_queue_obj);
+func_end:
+       return;
+
+}
+
+/*
+ *  ======== free_msg_list ========
+ */
+static void free_msg_list(struct lst_list *msg_list)
+{
+       struct msg_frame *pmsg;
+
+       if (!msg_list)
+               goto func_end;
+
+       while ((pmsg = (struct msg_frame *)lst_get_head(msg_list)) != NULL)
+               kfree(pmsg);
+
+       DBC_ASSERT(LST_IS_EMPTY(msg_list));
+
+       kfree(msg_list);
+func_end:
+       return;
+}
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
new file mode 100644 (file)
index 0000000..f914829
--- /dev/null
@@ -0,0 +1,1802 @@
+/*
+ * tiomap.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Processor Manager Driver for TI OMAP3430 EVM.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <plat/control.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/drv.h>
+#include <dspbridge/sync.h>
+
+/* ------------------------------------ Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
+/*  ----------------------------------- Link Driver */
+#include <dspbridge/dspdefs.h>
+#include <dspbridge/dspchnl.h>
+#include <dspbridge/dspdeh.h>
+#include <dspbridge/dspio.h>
+#include <dspbridge/dspmsg.h>
+#include <dspbridge/pwr.h>
+#include <dspbridge/io_sm.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+#include <dspbridge/dspapi.h>
+#include <dspbridge/dmm.h>
+#include <dspbridge/wdt.h>
+
+/*  ----------------------------------- Local */
+#include "_tiomap.h"
+#include "_tiomap_pwr.h"
+#include "tiomap_io.h"
+
+/* Offset in shared mem to write to in order to synchronize start with DSP */
+#define SHMSYNCOFFSET 4                /* GPP byte offset */
+
+#define BUFFERSIZE 1024
+
+#define TIHELEN_ACKTIMEOUT  10000
+
+#define MMU_SECTION_ADDR_MASK    0xFFF00000
+#define MMU_SSECTION_ADDR_MASK   0xFF000000
+#define MMU_LARGE_PAGE_MASK      0xFFFF0000
+#define MMU_SMALL_PAGE_MASK      0xFFFFF000
+#define OMAP3_IVA2_BOOTADDR_MASK 0xFFFFFC00
+#define PAGES_II_LVL_TABLE   512
+#define PHYS_TO_PAGE(phys)      pfn_to_page((phys) >> PAGE_SHIFT)
+
+/* Forward Declarations: */
+static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt);
+static int bridge_brd_read(struct bridge_dev_context *dev_ctxt,
+                                 u8 *host_buff,
+                                 u32 dsp_addr, u32 ul_num_bytes,
+                                 u32 mem_type);
+static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
+                                  u32 dsp_addr);
+static int bridge_brd_status(struct bridge_dev_context *dev_ctxt,
+                                   int *board_state);
+static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt);
+static int bridge_brd_write(struct bridge_dev_context *dev_ctxt,
+                                  u8 *host_buff,
+                                  u32 dsp_addr, u32 ul_num_bytes,
+                                  u32 mem_type);
+static int bridge_brd_set_state(struct bridge_dev_context *dev_ctxt,
+                                   u32 brd_state);
+static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
+                                  u32 dsp_dest_addr, u32 dsp_src_addr,
+                                  u32 ul_num_bytes, u32 mem_type);
+static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
+                                   u8 *host_buff, u32 dsp_addr,
+                                   u32 ul_num_bytes, u32 mem_type);
+static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes, u32 ul_map_attr,
+                                 struct page **mapped_pages);
+static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
+                                    u32 virt_addr, u32 ul_num_bytes);
+static int bridge_dev_create(struct bridge_dev_context
+                                       **dev_cntxt,
+                                       struct dev_object *hdev_obj,
+                                       struct cfg_hostres *config_param);
+static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
+                                 u32 dw_cmd, void *pargs);
+static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
+static u32 user_va2_pa(struct mm_struct *mm, u32 address);
+static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
+                            u32 va, u32 size,
+                            struct hw_mmu_map_attrs_t *map_attrs);
+static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va,
+                         u32 size, struct hw_mmu_map_attrs_t *attrs);
+static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes,
+                                 struct hw_mmu_map_attrs_t *hw_attrs);
+
+bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr);
+
+/*  ----------------------------------- Globals */
+
+/* Attributes of L2 page tables for DSP MMU */
+struct page_info {
+       u32 num_entries;        /* Number of valid PTEs in the L2 PT */
+};
+
+/* Attributes used to manage the DSP MMU page tables */
+struct pg_table_attrs {
+       spinlock_t pg_lock;     /* Critical section object handle */
+
+       u32 l1_base_pa;         /* Physical address of the L1 PT */
+       u32 l1_base_va;         /* Virtual  address of the L1 PT */
+       u32 l1_size;            /* Size of the L1 PT */
+       u32 l1_tbl_alloc_pa;
+       /* Physical address of Allocated mem for L1 table. May not be aligned */
+       u32 l1_tbl_alloc_va;
+       /* Virtual address of Allocated mem for L1 table. May not be aligned */
+       u32 l1_tbl_alloc_sz;
+       /* Size of consistent memory allocated for L1 table.
+        * May not be aligned */
+
+       u32 l2_base_pa;         /* Physical address of the L2 PT */
+       u32 l2_base_va;         /* Virtual  address of the L2 PT */
+       u32 l2_size;            /* Size of the L2 PT */
+       u32 l2_tbl_alloc_pa;
+       /* Physical address of Allocated mem for L2 table. May not be aligned */
+       u32 l2_tbl_alloc_va;
+       /* Virtual address of Allocated mem for L2 table. May not be aligned */
+       u32 l2_tbl_alloc_sz;
+       /* Size of consistent memory allocated for L2 table.
+        * May not be aligned */
+
+       u32 l2_num_pages;       /* Number of allocated L2 PT */
+       /* Array [l2_num_pages] of L2 PT info structs */
+       struct page_info *pg_info;
+};
+
+/*
+ *  This Bridge driver's function interface table.
+ */
+static struct bridge_drv_interface drv_interface_fxns = {
+       /* Bridge API ver. for which this bridge driver is built. */
+       BRD_API_MAJOR_VERSION,
+       BRD_API_MINOR_VERSION,
+       bridge_dev_create,
+       bridge_dev_destroy,
+       bridge_dev_ctrl,
+       bridge_brd_monitor,
+       bridge_brd_start,
+       bridge_brd_stop,
+       bridge_brd_status,
+       bridge_brd_read,
+       bridge_brd_write,
+       bridge_brd_set_state,
+       bridge_brd_mem_copy,
+       bridge_brd_mem_write,
+       bridge_brd_mem_map,
+       bridge_brd_mem_un_map,
+       /* The following CHNL functions are provided by chnl_io.lib: */
+       bridge_chnl_create,
+       bridge_chnl_destroy,
+       bridge_chnl_open,
+       bridge_chnl_close,
+       bridge_chnl_add_io_req,
+       bridge_chnl_get_ioc,
+       bridge_chnl_cancel_io,
+       bridge_chnl_flush_io,
+       bridge_chnl_get_info,
+       bridge_chnl_get_mgr_info,
+       bridge_chnl_idle,
+       bridge_chnl_register_notify,
+       /* The following IO functions are provided by chnl_io.lib: */
+       bridge_io_create,
+       bridge_io_destroy,
+       bridge_io_on_loaded,
+       bridge_io_get_proc_load,
+       /* The following msg_ctrl functions are provided by chnl_io.lib: */
+       bridge_msg_create,
+       bridge_msg_create_queue,
+       bridge_msg_delete,
+       bridge_msg_delete_queue,
+       bridge_msg_get,
+       bridge_msg_put,
+       bridge_msg_register_notify,
+       bridge_msg_set_queue_id,
+};
+
+static inline void flush_all(struct bridge_dev_context *dev_context)
+{
+       if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION ||
+           dev_context->dw_brd_state == BRD_HIBERNATION)
+               wake_dsp(dev_context, NULL);
+
+       hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base);
+}
+
+static void bad_page_dump(u32 pa, struct page *pg)
+{
+       pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa);
+       pr_emerg("Bad page state in process '%s'\n"
+                "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n"
+                "Backtrace:\n",
+                current->comm, pg, (int)(2 * sizeof(unsigned long)),
+                (unsigned long)pg->flags, pg->mapping,
+                page_mapcount(pg), page_count(pg));
+       dump_stack();
+}
+
+/*
+ *  ======== bridge_drv_entry ========
+ *  purpose:
+ *      Bridge Driver entry point.
+ */
+void bridge_drv_entry(struct bridge_drv_interface **drv_intf,
+                  const char *driver_file_name)
+{
+
+       DBC_REQUIRE(driver_file_name != NULL);
+
+       io_sm_init();           /* Initialization of io_sm module */
+
+       if (strcmp(driver_file_name, "UMA") == 0)
+               *drv_intf = &drv_interface_fxns;
+       else
+               dev_dbg(bridge, "%s Unknown Bridge file name", __func__);
+
+}
+
+/*
+ *  ======== bridge_brd_monitor ========
+ *  purpose:
+ *      This bridge_brd_monitor puts DSP into a Loadable state.
+ *      i.e Application can load and start the device.
+ *
+ *  Preconditions:
+ *      Device in 'OFF' state.
+ */
+static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt)
+{
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       u32 temp;
+       struct dspbridge_platform_data *pdata =
+                                   omap_dspbridge_dev->dev.platform_data;
+
+       temp = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
+                                       OMAP_POWERSTATEST_MASK;
+       if (!(temp & 0x02)) {
+               /* IVA2 is not in ON state */
+               /* Read and set PM_PWSTCTRL_IVA2  to ON */
+               (*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK,
+                       PWRDM_POWER_ON, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL);
+               /* Set the SW supervised state transition */
+               (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP,
+                                       OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+
+               /* Wait until the state has moved to ON */
+               while ((*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
+                                               OMAP_INTRANSITION_MASK)
+                       ;
+               /* Disable Automatic transition */
+               (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO,
+                                       OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+       }
+       (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
+                                       OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+       dsp_clk_enable(DSP_CLK_IVA2);
+
+       /* set the device state to IDLE */
+       dev_context->dw_brd_state = BRD_IDLE;
+
+       return 0;
+}
+
+/*
+ *  ======== bridge_brd_read ========
+ *  purpose:
+ *      Reads buffers for DSP memory.
+ */
+static int bridge_brd_read(struct bridge_dev_context *dev_ctxt,
+                                 u8 *host_buff, u32 dsp_addr,
+                                 u32 ul_num_bytes, u32 mem_type)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       u32 offset;
+       u32 dsp_base_addr = dev_ctxt->dw_dsp_base_addr;
+
+       if (dsp_addr < dev_context->dw_dsp_start_add) {
+               status = -EPERM;
+               return status;
+       }
+       /* change here to account for the 3 bands of the DSP internal memory */
+       if ((dsp_addr - dev_context->dw_dsp_start_add) <
+           dev_context->dw_internal_size) {
+               offset = dsp_addr - dev_context->dw_dsp_start_add;
+       } else {
+               status = read_ext_dsp_data(dev_context, host_buff, dsp_addr,
+                                          ul_num_bytes, mem_type);
+               return status;
+       }
+       /* copy the data from  DSP memory, */
+       memcpy(host_buff, (void *)(dsp_base_addr + offset), ul_num_bytes);
+       return status;
+}
+
+/*
+ *  ======== bridge_brd_set_state ========
+ *  purpose:
+ *      This routine updates the Board status.
+ */
+static int bridge_brd_set_state(struct bridge_dev_context *dev_ctxt,
+                                   u32 brd_state)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+
+       dev_context->dw_brd_state = brd_state;
+       return status;
+}
+
+/*
+ *  ======== bridge_brd_start ========
+ *  purpose:
+ *      Initializes DSP MMU and Starts DSP.
+ *
+ *  Preconditions:
+ *  a) DSP domain is 'ACTIVE'.
+ *  b) DSP_RST1 is asserted.
+ *  b) DSP_RST2 is released.
+ */
+static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
+                                  u32 dsp_addr)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       u32 dw_sync_addr = 0;
+       u32 ul_shm_base;        /* Gpp Phys SM base addr(byte) */
+       u32 ul_shm_base_virt;   /* Dsp Virt SM base addr */
+       u32 ul_tlb_base_virt;   /* Base of MMU TLB entry */
+       /* Offset of shm_base_virt from tlb_base_virt */
+       u32 ul_shm_offset_virt;
+       s32 entry_ndx;
+       s32 itmp_entry_ndx = 0; /* DSP-MMU TLB entry base address */
+       struct cfg_hostres *resources = NULL;
+       u32 temp;
+       u32 ul_dsp_clk_rate;
+       u32 ul_dsp_clk_addr;
+       u32 ul_bios_gp_timer;
+       u32 clk_cmd;
+       struct io_mgr *hio_mgr;
+       u32 ul_load_monitor_timer;
+       struct dspbridge_platform_data *pdata =
+                               omap_dspbridge_dev->dev.platform_data;
+
+       /* The device context contains all the mmu setup info from when the
+        * last dsp base image was loaded. The first entry is always
+        * SHMMEM base. */
+       /* Get SHM_BEG - convert to byte address */
+       (void)dev_get_symbol(dev_context->hdev_obj, SHMBASENAME,
+                            &ul_shm_base_virt);
+       ul_shm_base_virt *= DSPWORDSIZE;
+       DBC_ASSERT(ul_shm_base_virt != 0);
+       /* DSP Virtual address */
+       ul_tlb_base_virt = dev_context->atlb_entry[0].ul_dsp_va;
+       DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
+       ul_shm_offset_virt =
+           ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE);
+       /* Kernel logical address */
+       ul_shm_base = dev_context->atlb_entry[0].ul_gpp_va + ul_shm_offset_virt;
+
+       DBC_ASSERT(ul_shm_base != 0);
+       /* 2nd wd is used as sync field */
+       dw_sync_addr = ul_shm_base + SHMSYNCOFFSET;
+       /* Write a signature into the shm base + offset; this will
+        * get cleared when the DSP program starts. */
+       if ((ul_shm_base_virt == 0) || (ul_shm_base == 0)) {
+               pr_err("%s: Illegal SM base\n", __func__);
+               status = -EPERM;
+       } else
+               __raw_writel(0xffffffff, dw_sync_addr);
+
+       if (!status) {
+               resources = dev_context->resources;
+               if (!resources)
+                       status = -EPERM;
+
+               /* Assert RST1 i.e only the RST only for DSP megacell */
+               if (!status) {
+                       (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,
+                                       OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD,
+                                       OMAP2_RM_RSTCTRL);
+                       /* Mask address with 1K for compatibility */
+                       __raw_writel(dsp_addr & OMAP3_IVA2_BOOTADDR_MASK,
+                                       OMAP343X_CTRL_REGADDR(
+                                       OMAP343X_CONTROL_IVA2_BOOTADDR));
+                       /*
+                        * Set bootmode to self loop if dsp_debug flag is true
+                        */
+                       __raw_writel((dsp_debug) ? OMAP3_IVA2_BOOTMOD_IDLE : 0,
+                                       OMAP343X_CTRL_REGADDR(
+                                       OMAP343X_CONTROL_IVA2_BOOTMOD));
+               }
+       }
+       if (!status) {
+               /* Reset and Unreset the RST2, so that BOOTADDR is copied to
+                * IVA2 SYSC register */
+               (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK,
+                       OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+               udelay(100);
+               (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
+                                       OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+               udelay(100);
+
+               /* Disbale the DSP MMU */
+               hw_mmu_disable(resources->dw_dmmu_base);
+               /* Disable TWL */
+               hw_mmu_twl_disable(resources->dw_dmmu_base);
+
+               /* Only make TLB entry if both addresses are non-zero */
+               for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB;
+                    entry_ndx++) {
+                       struct bridge_ioctl_extproc *e = &dev_context->atlb_entry[entry_ndx];
+                       struct hw_mmu_map_attrs_t map_attrs = {
+                               .endianism = e->endianism,
+                               .element_size = e->elem_size,
+                               .mixed_size = e->mixed_mode,
+                       };
+
+                       if (!e->ul_gpp_pa || !e->ul_dsp_va)
+                               continue;
+
+                       dev_dbg(bridge,
+                                       "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x",
+                                       itmp_entry_ndx,
+                                       e->ul_gpp_pa,
+                                       e->ul_dsp_va,
+                                       e->ul_size);
+
+                       hw_mmu_tlb_add(dev_context->dw_dsp_mmu_base,
+                                       e->ul_gpp_pa,
+                                       e->ul_dsp_va,
+                                       e->ul_size,
+                                       itmp_entry_ndx,
+                                       &map_attrs, 1, 1);
+
+                       itmp_entry_ndx++;
+               }
+       }
+
+       /* Lock the above TLB entries and get the BIOS and load monitor timer
+        * information */
+       if (!status) {
+               hw_mmu_num_locked_set(resources->dw_dmmu_base, itmp_entry_ndx);
+               hw_mmu_victim_num_set(resources->dw_dmmu_base, itmp_entry_ndx);
+               hw_mmu_ttb_set(resources->dw_dmmu_base,
+                              dev_context->pt_attrs->l1_base_pa);
+               hw_mmu_twl_enable(resources->dw_dmmu_base);
+               /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */
+
+               temp = __raw_readl((resources->dw_dmmu_base) + 0x10);
+               temp = (temp & 0xFFFFFFEF) | 0x11;
+               __raw_writel(temp, (resources->dw_dmmu_base) + 0x10);
+
+               /* Let the DSP MMU run */
+               hw_mmu_enable(resources->dw_dmmu_base);
+
+               /* Enable the BIOS clock */
+               (void)dev_get_symbol(dev_context->hdev_obj,
+                                    BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer);
+               (void)dev_get_symbol(dev_context->hdev_obj,
+                                    BRIDGEINIT_LOADMON_GPTIMER,
+                                    &ul_load_monitor_timer);
+       }
+
+       if (!status) {
+               if (ul_load_monitor_timer != 0xFFFF) {
+                       clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
+                           ul_load_monitor_timer;
+                       dsp_peripheral_clk_ctrl(dev_context, &clk_cmd);
+               } else {
+                       dev_dbg(bridge, "Not able to get the symbol for Load "
+                               "Monitor Timer\n");
+               }
+       }
+
+       if (!status) {
+               if (ul_bios_gp_timer != 0xFFFF) {
+                       clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
+                           ul_bios_gp_timer;
+                       dsp_peripheral_clk_ctrl(dev_context, &clk_cmd);
+               } else {
+                       dev_dbg(bridge,
+                               "Not able to get the symbol for BIOS Timer\n");
+               }
+       }
+
+       if (!status) {
+               /* Set the DSP clock rate */
+               (void)dev_get_symbol(dev_context->hdev_obj,
+                                    "_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr);
+               /*Set Autoidle Mode for IVA2 PLL */
+               (*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
+                               OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+
+               if ((unsigned int *)ul_dsp_clk_addr != NULL) {
+                       /* Get the clock rate */
+                       ul_dsp_clk_rate = dsp_clk_get_iva2_rate();
+                       dev_dbg(bridge, "%s: DSP clock rate (KHZ): 0x%x \n",
+                               __func__, ul_dsp_clk_rate);
+                       (void)bridge_brd_write(dev_context,
+                                              (u8 *) &ul_dsp_clk_rate,
+                                              ul_dsp_clk_addr, sizeof(u32), 0);
+               }
+               /*
+                * Enable Mailbox events and also drain any pending
+                * stale messages.
+                */
+               dev_context->mbox = omap_mbox_get("dsp");
+               if (IS_ERR(dev_context->mbox)) {
+                       dev_context->mbox = NULL;
+                       pr_err("%s: Failed to get dsp mailbox handle\n",
+                                                               __func__);
+                       status = -EPERM;
+               }
+
+       }
+       if (!status) {
+               dev_context->mbox->rxq->callback = (int (*)(void *))io_mbox_msg;
+
+/*PM_IVA2GRPSEL_PER = 0xC0;*/
+               temp = readl(resources->dw_per_pm_base + 0xA8);
+               temp = (temp & 0xFFFFFF30) | 0xC0;
+               writel(temp, resources->dw_per_pm_base + 0xA8);
+
+/*PM_MPUGRPSEL_PER &= 0xFFFFFF3F; */
+               temp = readl(resources->dw_per_pm_base + 0xA4);
+               temp = (temp & 0xFFFFFF3F);
+               writel(temp, resources->dw_per_pm_base + 0xA4);
+/*CM_SLEEPDEP_PER |= 0x04; */
+               temp = readl(resources->dw_per_base + 0x44);
+               temp = (temp & 0xFFFFFFFB) | 0x04;
+               writel(temp, resources->dw_per_base + 0x44);
+
+/*CM_CLKSTCTRL_IVA2 = 0x00000003 -To Allow automatic transitions */
+               (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_ENABLE_AUTO,
+                                       OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+
+               /* Let DSP go */
+               dev_dbg(bridge, "%s Unreset\n", __func__);
+               /* Enable DSP MMU Interrupts */
+               hw_mmu_event_enable(resources->dw_dmmu_base,
+                                   HW_MMU_ALL_INTERRUPTS);
+               /* release the RST1, DSP starts executing now .. */
+               (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0,
+                                       OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+
+               dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", dw_sync_addr);
+               dev_dbg(bridge, "DSP c_int00 Address =  0x%x\n", dsp_addr);
+               if (dsp_debug)
+                       while (__raw_readw(dw_sync_addr))
+                               ;;
+
+               /* Wait for DSP to clear word in shared memory */
+               /* Read the Location */
+               if (!wait_for_start(dev_context, dw_sync_addr))
+                       status = -ETIMEDOUT;
+
+               /* Start wdt */
+               dsp_wdt_sm_set((void *)ul_shm_base);
+               dsp_wdt_enable(true);
+
+               status = dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr);
+               if (hio_mgr) {
+                       io_sh_msetting(hio_mgr, SHM_OPPINFO, NULL);
+                       /* Write the synchronization bit to indicate the
+                        * completion of OPP table update to DSP
+                        */
+                       __raw_writel(0XCAFECAFE, dw_sync_addr);
+
+                       /* update board state */
+                       dev_context->dw_brd_state = BRD_RUNNING;
+                       /* (void)chnlsm_enable_interrupt(dev_context); */
+               } else {
+                       dev_context->dw_brd_state = BRD_UNKNOWN;
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== bridge_brd_stop ========
+ *  purpose:
+ *      Puts DSP in self loop.
+ *
+ *  Preconditions :
+ *  a) None
+ */
+static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       struct pg_table_attrs *pt_attrs;
+       u32 dsp_pwr_state;
+       int clk_status;
+       struct dspbridge_platform_data *pdata =
+                               omap_dspbridge_dev->dev.platform_data;
+
+       if (dev_context->dw_brd_state == BRD_STOPPED)
+               return status;
+
+       /* as per TRM, it is advised to first drive the IVA2 to 'Standby' mode,
+        * before turning off the clocks.. This is to ensure that there are no
+        * pending L3 or other transactons from IVA2 */
+       dsp_pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
+                                       OMAP_POWERSTATEST_MASK;
+       if (dsp_pwr_state != PWRDM_POWER_OFF) {
+               (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
+                                       OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+               sm_interrupt_dsp(dev_context, MBX_PM_DSPIDLE);
+               mdelay(10);
+
+               /* IVA2 is not in OFF state */
+               /* Set PM_PWSTCTRL_IVA2  to OFF */
+               (*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK,
+                       PWRDM_POWER_OFF, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL);
+               /* Set the SW supervised state transition for Sleep */
+               (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_SLEEP,
+                                       OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+       }
+       udelay(10);
+       /* Release the Ext Base virtual Address as the next DSP Program
+        * may have a different load address */
+       if (dev_context->dw_dsp_ext_base_addr)
+               dev_context->dw_dsp_ext_base_addr = 0;
+
+       dev_context->dw_brd_state = BRD_STOPPED;        /* update board state */
+
+       dsp_wdt_enable(false);
+
+       /* This is a good place to clear the MMU page tables as well */
+       if (dev_context->pt_attrs) {
+               pt_attrs = dev_context->pt_attrs;
+               memset((u8 *) pt_attrs->l1_base_va, 0x00, pt_attrs->l1_size);
+               memset((u8 *) pt_attrs->l2_base_va, 0x00, pt_attrs->l2_size);
+               memset((u8 *) pt_attrs->pg_info, 0x00,
+                      (pt_attrs->l2_num_pages * sizeof(struct page_info)));
+       }
+       /* Disable the mailbox interrupts */
+       if (dev_context->mbox) {
+               omap_mbox_disable_irq(dev_context->mbox, IRQ_RX);
+               omap_mbox_put(dev_context->mbox);
+               dev_context->mbox = NULL;
+       }
+       /* Reset IVA2 clocks*/
+       (*pdata->dsp_prm_write)(OMAP3430_RST1_IVA2_MASK | OMAP3430_RST2_IVA2_MASK |
+                       OMAP3430_RST3_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+
+       clk_status = dsp_clk_disable(DSP_CLK_IVA2);
+
+       return status;
+}
+
+/*
+ *  ======== bridge_brd_status ========
+ *      Returns the board status.
+ */
+static int bridge_brd_status(struct bridge_dev_context *dev_ctxt,
+                                   int *board_state)
+{
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       *board_state = dev_context->dw_brd_state;
+       return 0;
+}
+
+/*
+ *  ======== bridge_brd_write ========
+ *      Copies the buffers to DSP internal or external memory.
+ */
+static int bridge_brd_write(struct bridge_dev_context *dev_ctxt,
+                                  u8 *host_buff, u32 dsp_addr,
+                                  u32 ul_num_bytes, u32 mem_type)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+
+       if (dsp_addr < dev_context->dw_dsp_start_add) {
+               status = -EPERM;
+               return status;
+       }
+       if ((dsp_addr - dev_context->dw_dsp_start_add) <
+           dev_context->dw_internal_size) {
+               status = write_dsp_data(dev_ctxt, host_buff, dsp_addr,
+                                       ul_num_bytes, mem_type);
+       } else {
+               status = write_ext_dsp_data(dev_context, host_buff, dsp_addr,
+                                           ul_num_bytes, mem_type, false);
+       }
+
+       return status;
+}
+
+/*
+ *  ======== bridge_dev_create ========
+ *      Creates a driver object. Puts DSP in self loop.
+ */
+static int bridge_dev_create(struct bridge_dev_context
+                                       **dev_cntxt,
+                                       struct dev_object *hdev_obj,
+                                       struct cfg_hostres *config_param)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = NULL;
+       s32 entry_ndx;
+       struct cfg_hostres *resources = config_param;
+       struct pg_table_attrs *pt_attrs;
+       u32 pg_tbl_pa;
+       u32 pg_tbl_va;
+       u32 align_size;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       /* Allocate and initialize a data structure to contain the bridge driver
+        *  state, which becomes the context for later calls into this driver */
+       dev_context = kzalloc(sizeof(struct bridge_dev_context), GFP_KERNEL);
+       if (!dev_context) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+
+       dev_context->dw_dsp_start_add = (u32) OMAP_GEM_BASE;
+       dev_context->dw_self_loop = (u32) NULL;
+       dev_context->dsp_per_clks = 0;
+       dev_context->dw_internal_size = OMAP_DSP_SIZE;
+       /*  Clear dev context MMU table entries.
+        *  These get set on bridge_io_on_loaded() call after program loaded. */
+       for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; entry_ndx++) {
+               dev_context->atlb_entry[entry_ndx].ul_gpp_pa =
+                   dev_context->atlb_entry[entry_ndx].ul_dsp_va = 0;
+       }
+       dev_context->dw_dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *)
+                                                                (config_param->
+                                                                 dw_mem_base
+                                                                 [3]),
+                                                                config_param->
+                                                                dw_mem_length
+                                                                [3]);
+       if (!dev_context->dw_dsp_base_addr)
+               status = -EPERM;
+
+       pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL);
+       if (pt_attrs != NULL) {
+               /* Assuming that we use only DSP's memory map
+                * until 0x4000:0000 , we would need only 1024
+                * L1 enties i.e L1 size = 4K */
+               pt_attrs->l1_size = 0x1000;
+               align_size = pt_attrs->l1_size;
+               /* Align sizes are expected to be power of 2 */
+               /* we like to get aligned on L1 table size */
+               pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l1_size,
+                                                    align_size, &pg_tbl_pa);
+
+               /* Check if the PA is aligned for us */
+               if ((pg_tbl_pa) & (align_size - 1)) {
+                       /* PA not aligned to page table size ,
+                        * try with more allocation and align */
+                       mem_free_phys_mem((void *)pg_tbl_va, pg_tbl_pa,
+                                         pt_attrs->l1_size);
+                       /* we like to get aligned on L1 table size */
+                       pg_tbl_va =
+                           (u32) mem_alloc_phys_mem((pt_attrs->l1_size) * 2,
+                                                    align_size, &pg_tbl_pa);
+                       /* We should be able to get aligned table now */
+                       pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
+                       pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
+                       pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size * 2;
+                       /* Align the PA to the next 'align'  boundary */
+                       pt_attrs->l1_base_pa =
+                           ((pg_tbl_pa) +
+                            (align_size - 1)) & (~(align_size - 1));
+                       pt_attrs->l1_base_va =
+                           pg_tbl_va + (pt_attrs->l1_base_pa - pg_tbl_pa);
+               } else {
+                       /* We got aligned PA, cool */
+                       pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
+                       pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
+                       pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size;
+                       pt_attrs->l1_base_pa = pg_tbl_pa;
+                       pt_attrs->l1_base_va = pg_tbl_va;
+               }
+               if (pt_attrs->l1_base_va)
+                       memset((u8 *) pt_attrs->l1_base_va, 0x00,
+                              pt_attrs->l1_size);
+
+               /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM +
+                * L4 pages */
+               pt_attrs->l2_num_pages = ((DMMPOOLSIZE >> 20) + 6);
+               pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE *
+                   pt_attrs->l2_num_pages;
+               align_size = 4; /* Make it u32 aligned */
+               /* we like to get aligned on L1 table size */
+               pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l2_size,
+                                                    align_size, &pg_tbl_pa);
+               pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa;
+               pt_attrs->l2_tbl_alloc_va = pg_tbl_va;
+               pt_attrs->l2_tbl_alloc_sz = pt_attrs->l2_size;
+               pt_attrs->l2_base_pa = pg_tbl_pa;
+               pt_attrs->l2_base_va = pg_tbl_va;
+
+               if (pt_attrs->l2_base_va)
+                       memset((u8 *) pt_attrs->l2_base_va, 0x00,
+                              pt_attrs->l2_size);
+
+               pt_attrs->pg_info = kzalloc(pt_attrs->l2_num_pages *
+                                       sizeof(struct page_info), GFP_KERNEL);
+               dev_dbg(bridge,
+                       "L1 pa %x, va %x, size %x\n L2 pa %x, va "
+                       "%x, size %x\n", pt_attrs->l1_base_pa,
+                       pt_attrs->l1_base_va, pt_attrs->l1_size,
+                       pt_attrs->l2_base_pa, pt_attrs->l2_base_va,
+                       pt_attrs->l2_size);
+               dev_dbg(bridge, "pt_attrs %p L2 NumPages %x pg_info %p\n",
+                       pt_attrs, pt_attrs->l2_num_pages, pt_attrs->pg_info);
+       }
+       if ((pt_attrs != NULL) && (pt_attrs->l1_base_va != 0) &&
+           (pt_attrs->l2_base_va != 0) && (pt_attrs->pg_info != NULL))
+               dev_context->pt_attrs = pt_attrs;
+       else
+               status = -ENOMEM;
+
+       if (!status) {
+               spin_lock_init(&pt_attrs->pg_lock);
+               dev_context->tc_word_swap_on = drv_datap->tc_wordswapon;
+
+               /* Set the Clock Divisor for the DSP module */
+               udelay(5);
+               /* MMU address is obtained from the host
+                * resources struct */
+               dev_context->dw_dsp_mmu_base = resources->dw_dmmu_base;
+       }
+       if (!status) {
+               dev_context->hdev_obj = hdev_obj;
+               /* Store current board state. */
+               dev_context->dw_brd_state = BRD_UNKNOWN;
+               dev_context->resources = resources;
+               dsp_clk_enable(DSP_CLK_IVA2);
+               bridge_brd_stop(dev_context);
+               /* Return ptr to our device state to the DSP API for storage */
+               *dev_cntxt = dev_context;
+       } else {
+               if (pt_attrs != NULL) {
+                       kfree(pt_attrs->pg_info);
+
+                       if (pt_attrs->l2_tbl_alloc_va) {
+                               mem_free_phys_mem((void *)
+                                                 pt_attrs->l2_tbl_alloc_va,
+                                                 pt_attrs->l2_tbl_alloc_pa,
+                                                 pt_attrs->l2_tbl_alloc_sz);
+                       }
+                       if (pt_attrs->l1_tbl_alloc_va) {
+                               mem_free_phys_mem((void *)
+                                                 pt_attrs->l1_tbl_alloc_va,
+                                                 pt_attrs->l1_tbl_alloc_pa,
+                                                 pt_attrs->l1_tbl_alloc_sz);
+                       }
+               }
+               kfree(pt_attrs);
+               kfree(dev_context);
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== bridge_dev_ctrl ========
+ *      Receives device specific commands.
+ */
+static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
+                                 u32 dw_cmd, void *pargs)
+{
+       int status = 0;
+       struct bridge_ioctl_extproc *pa_ext_proc =
+                                       (struct bridge_ioctl_extproc *)pargs;
+       s32 ndx;
+
+       switch (dw_cmd) {
+       case BRDIOCTL_CHNLREAD:
+               break;
+       case BRDIOCTL_CHNLWRITE:
+               break;
+       case BRDIOCTL_SETMMUCONFIG:
+               /* store away dsp-mmu setup values for later use */
+               for (ndx = 0; ndx < BRDIOCTL_NUMOFMMUTLB; ndx++, pa_ext_proc++)
+                       dev_context->atlb_entry[ndx] = *pa_ext_proc;
+               break;
+       case BRDIOCTL_DEEPSLEEP:
+       case BRDIOCTL_EMERGENCYSLEEP:
+               /* Currently only DSP Idle is supported Need to update for
+                * later releases */
+               status = sleep_dsp(dev_context, PWR_DEEPSLEEP, pargs);
+               break;
+       case BRDIOCTL_WAKEUP:
+               status = wake_dsp(dev_context, pargs);
+               break;
+       case BRDIOCTL_CLK_CTRL:
+               status = 0;
+               /* Looking For Baseport Fix for Clocks */
+               status = dsp_peripheral_clk_ctrl(dev_context, pargs);
+               break;
+       case BRDIOCTL_PWR_HIBERNATE:
+               status = handle_hibernation_from_dsp(dev_context);
+               break;
+       case BRDIOCTL_PRESCALE_NOTIFY:
+               status = pre_scale_dsp(dev_context, pargs);
+               break;
+       case BRDIOCTL_POSTSCALE_NOTIFY:
+               status = post_scale_dsp(dev_context, pargs);
+               break;
+       case BRDIOCTL_CONSTRAINT_REQUEST:
+               status = handle_constraints_set(dev_context, pargs);
+               break;
+       default:
+               status = -EPERM;
+               break;
+       }
+       return status;
+}
+
+/*
+ *  ======== bridge_dev_destroy ========
+ *      Destroys the driver object.
+ */
+static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
+{
+       struct pg_table_attrs *pt_attrs;
+       int status = 0;
+       struct bridge_dev_context *dev_context = (struct bridge_dev_context *)
+           dev_ctxt;
+       struct cfg_hostres *host_res;
+       u32 shm_size;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       /* It should never happen */
+       if (!dev_ctxt)
+               return -EFAULT;
+
+       /* first put the device to stop state */
+       bridge_brd_stop(dev_context);
+       if (dev_context->pt_attrs) {
+               pt_attrs = dev_context->pt_attrs;
+               kfree(pt_attrs->pg_info);
+
+               if (pt_attrs->l2_tbl_alloc_va) {
+                       mem_free_phys_mem((void *)pt_attrs->l2_tbl_alloc_va,
+                                         pt_attrs->l2_tbl_alloc_pa,
+                                         pt_attrs->l2_tbl_alloc_sz);
+               }
+               if (pt_attrs->l1_tbl_alloc_va) {
+                       mem_free_phys_mem((void *)pt_attrs->l1_tbl_alloc_va,
+                                         pt_attrs->l1_tbl_alloc_pa,
+                                         pt_attrs->l1_tbl_alloc_sz);
+               }
+               kfree(pt_attrs);
+
+       }
+
+       if (dev_context->resources) {
+               host_res = dev_context->resources;
+               shm_size = drv_datap->shm_size;
+               if (shm_size >= 0x10000) {
+                       if ((host_res->dw_mem_base[1]) &&
+                           (host_res->dw_mem_phys[1])) {
+                               mem_free_phys_mem((void *)
+                                                 host_res->dw_mem_base
+                                                 [1],
+                                                 host_res->dw_mem_phys
+                                                 [1], shm_size);
+                       }
+               } else {
+                       dev_dbg(bridge, "%s: Error getting shm size "
+                               "from registry: %x. Not calling "
+                               "mem_free_phys_mem\n", __func__,
+                               status);
+               }
+               host_res->dw_mem_base[1] = 0;
+               host_res->dw_mem_phys[1] = 0;
+
+               if (host_res->dw_mem_base[0])
+                       iounmap((void *)host_res->dw_mem_base[0]);
+               if (host_res->dw_mem_base[2])
+                       iounmap((void *)host_res->dw_mem_base[2]);
+               if (host_res->dw_mem_base[3])
+                       iounmap((void *)host_res->dw_mem_base[3]);
+               if (host_res->dw_mem_base[4])
+                       iounmap((void *)host_res->dw_mem_base[4]);
+               if (host_res->dw_dmmu_base)
+                       iounmap(host_res->dw_dmmu_base);
+               if (host_res->dw_per_base)
+                       iounmap(host_res->dw_per_base);
+               if (host_res->dw_per_pm_base)
+                       iounmap((void *)host_res->dw_per_pm_base);
+               if (host_res->dw_core_pm_base)
+                       iounmap((void *)host_res->dw_core_pm_base);
+               if (host_res->dw_sys_ctrl_base)
+                       iounmap(host_res->dw_sys_ctrl_base);
+
+               host_res->dw_mem_base[0] = (u32) NULL;
+               host_res->dw_mem_base[2] = (u32) NULL;
+               host_res->dw_mem_base[3] = (u32) NULL;
+               host_res->dw_mem_base[4] = (u32) NULL;
+               host_res->dw_dmmu_base = NULL;
+               host_res->dw_sys_ctrl_base = NULL;
+
+               kfree(host_res);
+       }
+
+       /* Free the driver's device context: */
+       kfree(drv_datap->base_img);
+       kfree(drv_datap);
+       dev_set_drvdata(bridge, NULL);
+       kfree((void *)dev_ctxt);
+       return status;
+}
+
+static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
+                                  u32 dsp_dest_addr, u32 dsp_src_addr,
+                                  u32 ul_num_bytes, u32 mem_type)
+{
+       int status = 0;
+       u32 src_addr = dsp_src_addr;
+       u32 dest_addr = dsp_dest_addr;
+       u32 copy_bytes = 0;
+       u32 total_bytes = ul_num_bytes;
+       u8 host_buf[BUFFERSIZE];
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       while (total_bytes > 0 && !status) {
+               copy_bytes =
+                   total_bytes > BUFFERSIZE ? BUFFERSIZE : total_bytes;
+               /* Read from External memory */
+               status = read_ext_dsp_data(dev_ctxt, host_buf, src_addr,
+                                          copy_bytes, mem_type);
+               if (!status) {
+                       if (dest_addr < (dev_context->dw_dsp_start_add +
+                                        dev_context->dw_internal_size)) {
+                               /* Write to Internal memory */
+                               status = write_dsp_data(dev_ctxt, host_buf,
+                                                       dest_addr, copy_bytes,
+                                                       mem_type);
+                       } else {
+                               /* Write to External memory */
+                               status =
+                                   write_ext_dsp_data(dev_ctxt, host_buf,
+                                                      dest_addr, copy_bytes,
+                                                      mem_type, false);
+                       }
+               }
+               total_bytes -= copy_bytes;
+               src_addr += copy_bytes;
+               dest_addr += copy_bytes;
+       }
+       return status;
+}
+
+/* Mem Write does not halt the DSP to write unlike bridge_brd_write */
+static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
+                                   u8 *host_buff, u32 dsp_addr,
+                                   u32 ul_num_bytes, u32 mem_type)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       u32 ul_remain_bytes = 0;
+       u32 ul_bytes = 0;
+       ul_remain_bytes = ul_num_bytes;
+       while (ul_remain_bytes > 0 && !status) {
+               ul_bytes =
+                   ul_remain_bytes > BUFFERSIZE ? BUFFERSIZE : ul_remain_bytes;
+               if (dsp_addr < (dev_context->dw_dsp_start_add +
+                                dev_context->dw_internal_size)) {
+                       status =
+                           write_dsp_data(dev_ctxt, host_buff, dsp_addr,
+                                          ul_bytes, mem_type);
+               } else {
+                       status = write_ext_dsp_data(dev_ctxt, host_buff,
+                                                   dsp_addr, ul_bytes,
+                                                   mem_type, true);
+               }
+               ul_remain_bytes -= ul_bytes;
+               dsp_addr += ul_bytes;
+               host_buff = host_buff + ul_bytes;
+       }
+       return status;
+}
+
+/*
+ *  ======== bridge_brd_mem_map ========
+ *      This function maps MPU buffer to the DSP address space. It performs
+ *  linear to physical address translation if required. It translates each
+ *  page since linear addresses can be physically non-contiguous
+ *  All address & size arguments are assumed to be page aligned (in proc.c)
+ *
+ *  TODO: Disable MMU while updating the page tables (but that'll stall DSP)
+ */
+static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes, u32 ul_map_attr,
+                                 struct page **mapped_pages)
+{
+       u32 attrs;
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       struct hw_mmu_map_attrs_t hw_attrs;
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = current->mm;
+       u32 write = 0;
+       u32 num_usr_pgs = 0;
+       struct page *mapped_page, *pg;
+       s32 pg_num;
+       u32 va = virt_addr;
+       struct task_struct *curr_task = current;
+       u32 pg_i = 0;
+       u32 mpu_addr, pa;
+
+       dev_dbg(bridge,
+               "%s hDevCtxt %p, pa %x, va %x, size %x, ul_map_attr %x\n",
+               __func__, dev_ctxt, ul_mpu_addr, virt_addr, ul_num_bytes,
+               ul_map_attr);
+       if (ul_num_bytes == 0)
+               return -EINVAL;
+
+       if (ul_map_attr & DSP_MAP_DIR_MASK) {
+               attrs = ul_map_attr;
+       } else {
+               /* Assign default attributes */
+               attrs = ul_map_attr | (DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16);
+       }
+       /* Take mapping properties */
+       if (attrs & DSP_MAPBIGENDIAN)
+               hw_attrs.endianism = HW_BIG_ENDIAN;
+       else
+               hw_attrs.endianism = HW_LITTLE_ENDIAN;
+
+       hw_attrs.mixed_size = (enum hw_mmu_mixed_size_t)
+           ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2);
+       /* Ignore element_size if mixed_size is enabled */
+       if (hw_attrs.mixed_size == 0) {
+               if (attrs & DSP_MAPELEMSIZE8) {
+                       /* Size is 8 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE8BIT;
+               } else if (attrs & DSP_MAPELEMSIZE16) {
+                       /* Size is 16 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE16BIT;
+               } else if (attrs & DSP_MAPELEMSIZE32) {
+                       /* Size is 32 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE32BIT;
+               } else if (attrs & DSP_MAPELEMSIZE64) {
+                       /* Size is 64 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE64BIT;
+               } else {
+                       /*
+                        * Mixedsize isn't enabled, so size can't be
+                        * zero here
+                        */
+                       return -EINVAL;
+               }
+       }
+       if (attrs & DSP_MAPDONOTLOCK)
+               hw_attrs.donotlockmpupage = 1;
+       else
+               hw_attrs.donotlockmpupage = 0;
+
+       if (attrs & DSP_MAPVMALLOCADDR) {
+               return mem_map_vmalloc(dev_ctxt, ul_mpu_addr, virt_addr,
+                                      ul_num_bytes, &hw_attrs);
+       }
+       /*
+        * Do OS-specific user-va to pa translation.
+        * Combine physically contiguous regions to reduce TLBs.
+        * Pass the translated pa to pte_update.
+        */
+       if ((attrs & DSP_MAPPHYSICALADDR)) {
+               status = pte_update(dev_context, ul_mpu_addr, virt_addr,
+                                   ul_num_bytes, &hw_attrs);
+               goto func_cont;
+       }
+
+       /*
+        * Important Note: ul_mpu_addr is mapped from user application process
+        * to current process - it must lie completely within the current
+        * virtual memory address space in order to be of use to us here!
+        */
+       down_read(&mm->mmap_sem);
+       vma = find_vma(mm, ul_mpu_addr);
+       if (vma)
+               dev_dbg(bridge,
+                       "VMAfor UserBuf: ul_mpu_addr=%x, ul_num_bytes=%x, "
+                       "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
+                       ul_num_bytes, vma->vm_start, vma->vm_end,
+                       vma->vm_flags);
+
+       /*
+        * It is observed that under some circumstances, the user buffer is
+        * spread across several VMAs. So loop through and check if the entire
+        * user buffer is covered
+        */
+       while ((vma) && (ul_mpu_addr + ul_num_bytes > vma->vm_end)) {
+               /* jump to the next VMA region */
+               vma = find_vma(mm, vma->vm_end + 1);
+               dev_dbg(bridge,
+                       "VMA for UserBuf ul_mpu_addr=%x ul_num_bytes=%x, "
+                       "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
+                       ul_num_bytes, vma->vm_start, vma->vm_end,
+                       vma->vm_flags);
+       }
+       if (!vma) {
+               pr_err("%s: Failed to get VMA region for 0x%x (%d)\n",
+                      __func__, ul_mpu_addr, ul_num_bytes);
+               status = -EINVAL;
+               up_read(&mm->mmap_sem);
+               goto func_cont;
+       }
+
+       if (vma->vm_flags & VM_IO) {
+               num_usr_pgs = ul_num_bytes / PG_SIZE4K;
+               mpu_addr = ul_mpu_addr;
+
+               /* Get the physical addresses for user buffer */
+               for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
+                       pa = user_va2_pa(mm, mpu_addr);
+                       if (!pa) {
+                               status = -EPERM;
+                               pr_err("DSPBRIDGE: VM_IO mapping physical"
+                                      "address is invalid\n");
+                               break;
+                       }
+                       if (pfn_valid(__phys_to_pfn(pa))) {
+                               pg = PHYS_TO_PAGE(pa);
+                               get_page(pg);
+                               if (page_count(pg) < 1) {
+                                       pr_err("Bad page in VM_IO buffer\n");
+                                       bad_page_dump(pa, pg);
+                               }
+                       }
+                       status = pte_set(dev_context->pt_attrs, pa,
+                                        va, HW_PAGE_SIZE4KB, &hw_attrs);
+                       if (status)
+                               break;
+
+                       va += HW_PAGE_SIZE4KB;
+                       mpu_addr += HW_PAGE_SIZE4KB;
+                       pa += HW_PAGE_SIZE4KB;
+               }
+       } else {
+               num_usr_pgs = ul_num_bytes / PG_SIZE4K;
+               if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
+                       write = 1;
+
+               for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
+                       pg_num = get_user_pages(curr_task, mm, ul_mpu_addr, 1,
+                                               write, 1, &mapped_page, NULL);
+                       if (pg_num > 0) {
+                               if (page_count(mapped_page) < 1) {
+                                       pr_err("Bad page count after doing"
+                                              "get_user_pages on"
+                                              "user buffer\n");
+                                       bad_page_dump(page_to_phys(mapped_page),
+                                                     mapped_page);
+                               }
+                               status = pte_set(dev_context->pt_attrs,
+                                                page_to_phys(mapped_page), va,
+                                                HW_PAGE_SIZE4KB, &hw_attrs);
+                               if (status)
+                                       break;
+
+                               if (mapped_pages)
+                                       mapped_pages[pg_i] = mapped_page;
+
+                               va += HW_PAGE_SIZE4KB;
+                               ul_mpu_addr += HW_PAGE_SIZE4KB;
+                       } else {
+                               pr_err("DSPBRIDGE: get_user_pages FAILED,"
+                                      "MPU addr = 0x%x,"
+                                      "vma->vm_flags = 0x%lx,"
+                                      "get_user_pages Err"
+                                      "Value = %d, Buffer"
+                                      "size=0x%x\n", ul_mpu_addr,
+                                      vma->vm_flags, pg_num, ul_num_bytes);
+                               status = -EPERM;
+                               break;
+                       }
+               }
+       }
+       up_read(&mm->mmap_sem);
+func_cont:
+       if (status) {
+               /*
+                * Roll out the mapped pages incase it failed in middle of
+                * mapping
+                */
+               if (pg_i) {
+                       bridge_brd_mem_un_map(dev_context, virt_addr,
+                                          (pg_i * PG_SIZE4K));
+               }
+               status = -EPERM;
+       }
+       /*
+        * In any case, flush the TLB
+        * This is called from here instead from pte_update to avoid unnecessary
+        * repetition while mapping non-contiguous physical regions of a virtual
+        * region
+        */
+       flush_all(dev_context);
+       dev_dbg(bridge, "%s status %x\n", __func__, status);
+       return status;
+}
+
+/*
+ *  ======== bridge_brd_mem_un_map ========
+ *      Invalidate the PTEs for the DSP VA block to be unmapped.
+ *
+ *      PTEs of a mapped memory block are contiguous in any page table
+ *      So, instead of looking up the PTE address for every 4K block,
+ *      we clear consecutive PTEs until we unmap all the bytes
+ */
+static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
+                                    u32 virt_addr, u32 ul_num_bytes)
+{
+       u32 l1_base_va;
+       u32 l2_base_va;
+       u32 l2_base_pa;
+       u32 l2_page_num;
+       u32 pte_val;
+       u32 pte_size;
+       u32 pte_count;
+       u32 pte_addr_l1;
+       u32 pte_addr_l2 = 0;
+       u32 rem_bytes;
+       u32 rem_bytes_l2;
+       u32 va_curr;
+       struct page *pg = NULL;
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       struct pg_table_attrs *pt = dev_context->pt_attrs;
+       u32 temp;
+       u32 paddr;
+       u32 numof4k_pages = 0;
+
+       va_curr = virt_addr;
+       rem_bytes = ul_num_bytes;
+       rem_bytes_l2 = 0;
+       l1_base_va = pt->l1_base_va;
+       pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
+       dev_dbg(bridge, "%s dev_ctxt %p, va %x, NumBytes %x l1_base_va %x, "
+               "pte_addr_l1 %x\n", __func__, dev_ctxt, virt_addr,
+               ul_num_bytes, l1_base_va, pte_addr_l1);
+
+       while (rem_bytes && !status) {
+               u32 va_curr_orig = va_curr;
+               /* Find whether the L1 PTE points to a valid L2 PT */
+               pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
+               pte_val = *(u32 *) pte_addr_l1;
+               pte_size = hw_mmu_pte_size_l1(pte_val);
+
+               if (pte_size != HW_MMU_COARSE_PAGE_SIZE)
+                       goto skip_coarse_page;
+
+               /*
+                * Get the L2 PA from the L1 PTE, and find
+                * corresponding L2 VA
+                */
+               l2_base_pa = hw_mmu_pte_coarse_l1(pte_val);
+               l2_base_va = l2_base_pa - pt->l2_base_pa + pt->l2_base_va;
+               l2_page_num =
+                   (l2_base_pa - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE;
+               /*
+                * Find the L2 PTE address from which we will start
+                * clearing, the number of PTEs to be cleared on this
+                * page, and the size of VA space that needs to be
+                * cleared on this L2 page
+                */
+               pte_addr_l2 = hw_mmu_pte_addr_l2(l2_base_va, va_curr);
+               pte_count = pte_addr_l2 & (HW_MMU_COARSE_PAGE_SIZE - 1);
+               pte_count = (HW_MMU_COARSE_PAGE_SIZE - pte_count) / sizeof(u32);
+               if (rem_bytes < (pte_count * PG_SIZE4K))
+                       pte_count = rem_bytes / PG_SIZE4K;
+               rem_bytes_l2 = pte_count * PG_SIZE4K;
+
+               /*
+                * Unmap the VA space on this L2 PT. A quicker way
+                * would be to clear pte_count entries starting from
+                * pte_addr_l2. However, below code checks that we don't
+                * clear invalid entries or less than 64KB for a 64KB
+                * entry. Similar checking is done for L1 PTEs too
+                * below
+                */
+               while (rem_bytes_l2 && !status) {
+                       pte_val = *(u32 *) pte_addr_l2;
+                       pte_size = hw_mmu_pte_size_l2(pte_val);
+                       /* va_curr aligned to pte_size? */
+                       if (pte_size == 0 || rem_bytes_l2 < pte_size ||
+                           va_curr & (pte_size - 1)) {
+                               status = -EPERM;
+                               break;
+                       }
+
+                       /* Collect Physical addresses from VA */
+                       paddr = (pte_val & ~(pte_size - 1));
+                       if (pte_size == HW_PAGE_SIZE64KB)
+                               numof4k_pages = 16;
+                       else
+                               numof4k_pages = 1;
+                       temp = 0;
+                       while (temp++ < numof4k_pages) {
+                               if (!pfn_valid(__phys_to_pfn(paddr))) {
+                                       paddr += HW_PAGE_SIZE4KB;
+                                       continue;
+                               }
+                               pg = PHYS_TO_PAGE(paddr);
+                               if (page_count(pg) < 1) {
+                                       pr_info("DSPBRIDGE: UNMAP function: "
+                                               "COUNT 0 FOR PA 0x%x, size = "
+                                               "0x%x\n", paddr, ul_num_bytes);
+                                       bad_page_dump(paddr, pg);
+                               } else {
+                                       set_page_dirty(pg);
+                                       page_cache_release(pg);
+                               }
+                               paddr += HW_PAGE_SIZE4KB;
+                       }
+                       if (hw_mmu_pte_clear(pte_addr_l2, va_curr, pte_size)) {
+                               status = -EPERM;
+                               goto EXIT_LOOP;
+                       }
+
+                       status = 0;
+                       rem_bytes_l2 -= pte_size;
+                       va_curr += pte_size;
+                       pte_addr_l2 += (pte_size >> 12) * sizeof(u32);
+               }
+               spin_lock(&pt->pg_lock);
+               if (rem_bytes_l2 == 0) {
+                       pt->pg_info[l2_page_num].num_entries -= pte_count;
+                       if (pt->pg_info[l2_page_num].num_entries == 0) {
+                               /*
+                                * Clear the L1 PTE pointing to the L2 PT
+                                */
+                               if (!hw_mmu_pte_clear(l1_base_va, va_curr_orig,
+                                                    HW_MMU_COARSE_PAGE_SIZE))
+                                       status = 0;
+                               else {
+                                       status = -EPERM;
+                                       spin_unlock(&pt->pg_lock);
+                                       goto EXIT_LOOP;
+                               }
+                       }
+                       rem_bytes -= pte_count * PG_SIZE4K;
+               } else
+                       status = -EPERM;
+
+               spin_unlock(&pt->pg_lock);
+               continue;
+skip_coarse_page:
+               /* va_curr aligned to pte_size? */
+               /* pte_size = 1 MB or 16 MB */
+               if (pte_size == 0 || rem_bytes < pte_size ||
+                   va_curr & (pte_size - 1)) {
+                       status = -EPERM;
+                       break;
+               }
+
+               if (pte_size == HW_PAGE_SIZE1MB)
+                       numof4k_pages = 256;
+               else
+                       numof4k_pages = 4096;
+               temp = 0;
+               /* Collect Physical addresses from VA */
+               paddr = (pte_val & ~(pte_size - 1));
+               while (temp++ < numof4k_pages) {
+                       if (pfn_valid(__phys_to_pfn(paddr))) {
+                               pg = PHYS_TO_PAGE(paddr);
+                               if (page_count(pg) < 1) {
+                                       pr_info("DSPBRIDGE: UNMAP function: "
+                                               "COUNT 0 FOR PA 0x%x, size = "
+                                               "0x%x\n", paddr, ul_num_bytes);
+                                       bad_page_dump(paddr, pg);
+                               } else {
+                                       set_page_dirty(pg);
+                                       page_cache_release(pg);
+                               }
+                       }
+                       paddr += HW_PAGE_SIZE4KB;
+               }
+               if (!hw_mmu_pte_clear(l1_base_va, va_curr, pte_size)) {
+                       status = 0;
+                       rem_bytes -= pte_size;
+                       va_curr += pte_size;
+               } else {
+                       status = -EPERM;
+                       goto EXIT_LOOP;
+               }
+       }
+       /*
+        * It is better to flush the TLB here, so that any stale old entries
+        * get flushed
+        */
+EXIT_LOOP:
+       flush_all(dev_context);
+       dev_dbg(bridge,
+               "%s: va_curr %x, pte_addr_l1 %x pte_addr_l2 %x rem_bytes %x,"
+               " rem_bytes_l2 %x status %x\n", __func__, va_curr, pte_addr_l1,
+               pte_addr_l2, rem_bytes, rem_bytes_l2, status);
+       return status;
+}
+
+/*
+ *  ======== user_va2_pa ========
+ *  Purpose:
+ *      This function walks through the page tables to convert a userland
+ *      virtual address to physical address
+ */
+static u32 user_va2_pa(struct mm_struct *mm, u32 address)
+{
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *ptep, pte;
+
+       pgd = pgd_offset(mm, address);
+       if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
+               pmd = pmd_offset(pgd, address);
+               if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
+                       ptep = pte_offset_map(pmd, address);
+                       if (ptep) {
+                               pte = *ptep;
+                               if (pte_present(pte))
+                                       return pte & PAGE_MASK;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/*
+ *  ======== pte_update ========
+ *      This function calculates the optimum page-aligned addresses and sizes
+ *      Caller must pass page-aligned values
+ */
+static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
+                            u32 va, u32 size,
+                            struct hw_mmu_map_attrs_t *map_attrs)
+{
+       u32 i;
+       u32 all_bits;
+       u32 pa_curr = pa;
+       u32 va_curr = va;
+       u32 num_bytes = size;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       int status = 0;
+       u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
+               HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
+       };
+
+       while (num_bytes && !status) {
+               /* To find the max. page size with which both PA & VA are
+                * aligned */
+               all_bits = pa_curr | va_curr;
+
+               for (i = 0; i < 4; i++) {
+                       if ((num_bytes >= page_size[i]) && ((all_bits &
+                                                            (page_size[i] -
+                                                             1)) == 0)) {
+                               status =
+                                   pte_set(dev_context->pt_attrs, pa_curr,
+                                           va_curr, page_size[i], map_attrs);
+                               pa_curr += page_size[i];
+                               va_curr += page_size[i];
+                               num_bytes -= page_size[i];
+                               /* Don't try smaller sizes. Hopefully we have
+                                * reached an address aligned to a bigger page
+                                * size */
+                               break;
+                       }
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== pte_set ========
+ *      This function calculates PTE address (MPU virtual) to be updated
+ *      It also manages the L2 page tables
+ */
+static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va,
+                         u32 size, struct hw_mmu_map_attrs_t *attrs)
+{
+       u32 i;
+       u32 pte_val;
+       u32 pte_addr_l1;
+       u32 pte_size;
+       /* Base address of the PT that will be updated */
+       u32 pg_tbl_va;
+       u32 l1_base_va;
+       /* Compiler warns that the next three variables might be used
+        * uninitialized in this function. Doesn't seem so. Working around,
+        * anyways. */
+       u32 l2_base_va = 0;
+       u32 l2_base_pa = 0;
+       u32 l2_page_num = 0;
+       int status = 0;
+
+       l1_base_va = pt->l1_base_va;
+       pg_tbl_va = l1_base_va;
+       if ((size == HW_PAGE_SIZE64KB) || (size == HW_PAGE_SIZE4KB)) {
+               /* Find whether the L1 PTE points to a valid L2 PT */
+               pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va);
+               if (pte_addr_l1 <= (pt->l1_base_va + pt->l1_size)) {
+                       pte_val = *(u32 *) pte_addr_l1;
+                       pte_size = hw_mmu_pte_size_l1(pte_val);
+               } else {
+                       return -EPERM;
+               }
+               spin_lock(&pt->pg_lock);
+               if (pte_size == HW_MMU_COARSE_PAGE_SIZE) {
+                       /* Get the L2 PA from the L1 PTE, and find
+                        * corresponding L2 VA */
+                       l2_base_pa = hw_mmu_pte_coarse_l1(pte_val);
+                       l2_base_va =
+                           l2_base_pa - pt->l2_base_pa + pt->l2_base_va;
+                       l2_page_num =
+                           (l2_base_pa -
+                            pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE;
+               } else if (pte_size == 0) {
+                       /* L1 PTE is invalid. Allocate a L2 PT and
+                        * point the L1 PTE to it */
+                       /* Find a free L2 PT. */
+                       for (i = 0; (i < pt->l2_num_pages) &&
+                            (pt->pg_info[i].num_entries != 0); i++)
+                               ;;
+                       if (i < pt->l2_num_pages) {
+                               l2_page_num = i;
+                               l2_base_pa = pt->l2_base_pa + (l2_page_num *
+                                               HW_MMU_COARSE_PAGE_SIZE);
+                               l2_base_va = pt->l2_base_va + (l2_page_num *
+                                               HW_MMU_COARSE_PAGE_SIZE);
+                               /* Endianness attributes are ignored for
+                                * HW_MMU_COARSE_PAGE_SIZE */
+                               status =
+                                   hw_mmu_pte_set(l1_base_va, l2_base_pa, va,
+                                                  HW_MMU_COARSE_PAGE_SIZE,
+                                                  attrs);
+                       } else {
+                               status = -ENOMEM;
+                       }
+               } else {
+                       /* Found valid L1 PTE of another size.
+                        * Should not overwrite it. */
+                       status = -EPERM;
+               }
+               if (!status) {
+                       pg_tbl_va = l2_base_va;
+                       if (size == HW_PAGE_SIZE64KB)
+                               pt->pg_info[l2_page_num].num_entries += 16;
+                       else
+                               pt->pg_info[l2_page_num].num_entries++;
+                       dev_dbg(bridge, "PTE: L2 BaseVa %x, BasePa %x, PageNum "
+                               "%x, num_entries %x\n", l2_base_va,
+                               l2_base_pa, l2_page_num,
+                               pt->pg_info[l2_page_num].num_entries);
+               }
+               spin_unlock(&pt->pg_lock);
+       }
+       if (!status) {
+               dev_dbg(bridge, "PTE: pg_tbl_va %x, pa %x, va %x, size %x\n",
+                       pg_tbl_va, pa, va, size);
+               dev_dbg(bridge, "PTE: endianism %x, element_size %x, "
+                       "mixed_size %x\n", attrs->endianism,
+                       attrs->element_size, attrs->mixed_size);
+               status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs);
+       }
+
+       return status;
+}
+
+/* Memory map kernel VA -- memory allocated with vmalloc */
+static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes,
+                                 struct hw_mmu_map_attrs_t *hw_attrs)
+{
+       int status = 0;
+       struct page *page[1];
+       u32 i;
+       u32 pa_curr;
+       u32 pa_next;
+       u32 va_curr;
+       u32 size_curr;
+       u32 num_pages;
+       u32 pa;
+       u32 num_of4k_pages;
+       u32 temp = 0;
+
+       /*
+        * Do Kernel va to pa translation.
+        * Combine physically contiguous regions to reduce TLBs.
+        * Pass the translated pa to pte_update.
+        */
+       num_pages = ul_num_bytes / PAGE_SIZE;   /* PAGE_SIZE = OS page size */
+       i = 0;
+       va_curr = ul_mpu_addr;
+       page[0] = vmalloc_to_page((void *)va_curr);
+       pa_next = page_to_phys(page[0]);
+       while (!status && (i < num_pages)) {
+               /*
+                * Reuse pa_next from the previous iteraion to avoid
+                * an extra va2pa call
+                */
+               pa_curr = pa_next;
+               size_curr = PAGE_SIZE;
+               /*
+                * If the next page is physically contiguous,
+                * map it with the current one by increasing
+                * the size of the region to be mapped
+                */
+               while (++i < num_pages) {
+                       page[0] =
+                           vmalloc_to_page((void *)(va_curr + size_curr));
+                       pa_next = page_to_phys(page[0]);
+
+                       if (pa_next == (pa_curr + size_curr))
+                               size_curr += PAGE_SIZE;
+                       else
+                               break;
+
+               }
+               if (pa_next == 0) {
+                       status = -ENOMEM;
+                       break;
+               }
+               pa = pa_curr;
+               num_of4k_pages = size_curr / HW_PAGE_SIZE4KB;
+               while (temp++ < num_of4k_pages) {
+                       get_page(PHYS_TO_PAGE(pa));
+                       pa += HW_PAGE_SIZE4KB;
+               }
+               status = pte_update(dev_context, pa_curr, virt_addr +
+                                   (va_curr - ul_mpu_addr), size_curr,
+                                   hw_attrs);
+               va_curr += size_curr;
+       }
+       /*
+        * In any case, flush the TLB
+        * This is called from here instead from pte_update to avoid unnecessary
+        * repetition while mapping non-contiguous physical regions of a virtual
+        * region
+        */
+       flush_all(dev_context);
+       dev_dbg(bridge, "%s status %x\n", __func__, status);
+       return status;
+}
+
+/*
+ *  ======== wait_for_start ========
+ *      Wait for the singal from DSP that it has started, or time out.
+ */
+bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr)
+{
+       u16 timeout = TIHELEN_ACKTIMEOUT;
+
+       /*  Wait for response from board */
+       while (__raw_readw(dw_sync_addr) && --timeout)
+               udelay(10);
+
+       /*  If timed out: return false */
+       if (!timeout) {
+               pr_err("%s: Timed out waiting DSP to Start\n", __func__);
+               return false;
+       }
+       return true;
+}
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
new file mode 100644 (file)
index 0000000..b789f8f
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * tiomap_pwr.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implementation of DSP wake/sleep routines.
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/cfg.h>
+#include <dspbridge/drv.h>
+#include <dspbridge/io_sm.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/brddefs.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/iodefs.h>
+
+/* ------------------------------------ Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
+#include <dspbridge/pwr_sh.h>
+
+/*  ----------------------------------- Bridge Driver */
+#include <dspbridge/dspdeh.h>
+#include <dspbridge/wdt.h>
+
+/*  ----------------------------------- specific to this file */
+#include "_tiomap.h"
+#include "_tiomap_pwr.h"
+#include <mach-omap2/prm-regbits-34xx.h>
+#include <mach-omap2/cm-regbits-34xx.h>
+
+#define PWRSTST_TIMEOUT          200
+
+/*
+ *  ======== handle_constraints_set ========
+ *     Sets new DSP constraint
+ */
+int handle_constraints_set(struct bridge_dev_context *dev_context,
+                                 void *pargs)
+{
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       u32 *constraint_val;
+       struct dspbridge_platform_data *pdata =
+           omap_dspbridge_dev->dev.platform_data;
+
+       constraint_val = (u32 *) (pargs);
+       /* Read the target value requested by DSP */
+       dev_dbg(bridge, "OPP: %s opp requested = 0x%x\n", __func__,
+               (u32) *(constraint_val + 1));
+
+       /* Set the new opp value */
+       if (pdata->dsp_set_min_opp)
+               (*pdata->dsp_set_min_opp) ((u32) *(constraint_val + 1));
+#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
+       return 0;
+}
+
+/*
+ *  ======== handle_hibernation_from_dsp ========
+ *     Handle Hibernation requested from DSP
+ */
+int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context)
+{
+       int status = 0;
+#ifdef CONFIG_PM
+       u16 timeout = PWRSTST_TIMEOUT / 10;
+       u32 pwr_state;
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       u32 opplevel;
+       struct io_mgr *hio_mgr;
+#endif
+       struct dspbridge_platform_data *pdata =
+           omap_dspbridge_dev->dev.platform_data;
+
+       pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
+                                               OMAP_POWERSTATEST_MASK;
+       /* Wait for DSP to move into OFF state */
+       while ((pwr_state != PWRDM_POWER_OFF) && --timeout) {
+               if (msleep_interruptible(10)) {
+                       pr_err("Waiting for DSP OFF mode interrupted\n");
+                       return -EPERM;
+               }
+               pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
+                                       OMAP2_PM_PWSTST) & OMAP_POWERSTATEST_MASK;
+       }
+       if (timeout == 0) {
+               pr_err("%s: Timed out waiting for DSP off mode\n", __func__);
+               status = -ETIMEDOUT;
+               return status;
+       } else {
+
+               /* Save mailbox settings */
+               omap_mbox_save_ctx(dev_context->mbox);
+
+               /* Turn off DSP Peripheral clocks and DSP Load monitor timer */
+               status = dsp_clock_disable_all(dev_context->dsp_per_clks);
+
+               /* Disable wdt on hibernation. */
+               dsp_wdt_enable(false);
+
+               if (!status) {
+                       /* Update the Bridger Driver state */
+                       dev_context->dw_brd_state = BRD_DSP_HIBERNATION;
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+                       status =
+                           dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr);
+                       if (!hio_mgr) {
+                               status = DSP_EHANDLE;
+                               return status;
+                       }
+                       io_sh_msetting(hio_mgr, SHM_GETOPP, &opplevel);
+
+                       /*
+                        * Set the OPP to low level before moving to OFF
+                        * mode
+                        */
+                       if (pdata->dsp_set_min_opp)
+                               (*pdata->dsp_set_min_opp) (VDD1_OPP1);
+                       status = 0;
+#endif /* CONFIG_TIDSPBRIDGE_DVFS */
+               }
+       }
+#endif
+       return status;
+}
+
+/*
+ *  ======== sleep_dsp ========
+ *     Put DSP in low power consuming state.
+ */
+int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
+                    void *pargs)
+{
+       int status = 0;
+#ifdef CONFIG_PM
+#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
+       struct deh_mgr *hdeh_mgr;
+#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
+       u16 timeout = PWRSTST_TIMEOUT / 10;
+       u32 pwr_state, target_pwr_state;
+       struct dspbridge_platform_data *pdata =
+                               omap_dspbridge_dev->dev.platform_data;
+
+       /* Check if sleep code is valid */
+       if ((dw_cmd != PWR_DEEPSLEEP) && (dw_cmd != PWR_EMERGENCYDEEPSLEEP))
+               return -EINVAL;
+
+       switch (dev_context->dw_brd_state) {
+       case BRD_RUNNING:
+               omap_mbox_save_ctx(dev_context->mbox);
+               if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
+                       sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
+                       dev_dbg(bridge, "PM: %s - sent hibernate cmd to DSP\n",
+                               __func__);
+                       target_pwr_state = PWRDM_POWER_OFF;
+               } else {
+                       sm_interrupt_dsp(dev_context, MBX_PM_DSPRETENTION);
+                       target_pwr_state = PWRDM_POWER_RET;
+               }
+               break;
+       case BRD_RETENTION:
+               omap_mbox_save_ctx(dev_context->mbox);
+               if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
+                       sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
+                       target_pwr_state = PWRDM_POWER_OFF;
+               } else
+                       return 0;
+               break;
+       case BRD_HIBERNATION:
+       case BRD_DSP_HIBERNATION:
+               /* Already in Hibernation, so just return */
+               dev_dbg(bridge, "PM: %s - DSP already in hibernation\n",
+                       __func__);
+               return 0;
+       case BRD_STOPPED:
+               dev_dbg(bridge, "PM: %s - Board in STOP state\n", __func__);
+               return 0;
+       default:
+               dev_dbg(bridge, "PM: %s - Bridge in Illegal state\n", __func__);
+               return -EPERM;
+       }
+
+       /* Get the PRCM DSP power domain status */
+       pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
+                                               OMAP_POWERSTATEST_MASK;
+
+       /* Wait for DSP to move into target power state */
+       while ((pwr_state != target_pwr_state) && --timeout) {
+               if (msleep_interruptible(10)) {
+                       pr_err("Waiting for DSP to Suspend interrupted\n");
+                       return -EPERM;
+               }
+               pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
+                                       OMAP2_PM_PWSTST) & OMAP_POWERSTATEST_MASK;
+       }
+
+       if (!timeout) {
+               pr_err("%s: Timed out waiting for DSP off mode, state %x\n",
+                      __func__, pwr_state);
+#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
+               dev_get_deh_mgr(dev_context->hdev_obj, &hdeh_mgr);
+               bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0);
+#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
+               return -ETIMEDOUT;
+       } else {
+               /* Update the Bridger Driver state */
+               if (dsp_test_sleepstate == PWRDM_POWER_OFF)
+                       dev_context->dw_brd_state = BRD_HIBERNATION;
+               else
+                       dev_context->dw_brd_state = BRD_RETENTION;
+
+               /* Disable wdt on hibernation. */
+               dsp_wdt_enable(false);
+
+               /* Turn off DSP Peripheral clocks */
+               status = dsp_clock_disable_all(dev_context->dsp_per_clks);
+               if (status)
+                       return status;
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+               else if (target_pwr_state == PWRDM_POWER_OFF) {
+                       /*
+                        * Set the OPP to low level before moving to OFF mode
+                        */
+                       if (pdata->dsp_set_min_opp)
+                               (*pdata->dsp_set_min_opp) (VDD1_OPP1);
+               }
+#endif /* CONFIG_TIDSPBRIDGE_DVFS */
+       }
+#endif /* CONFIG_PM */
+       return status;
+}
+
+/*
+ *  ======== wake_dsp ========
+ *     Wake up DSP from sleep.
+ */
+int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
+{
+       int status = 0;
+#ifdef CONFIG_PM
+
+       /* Check the board state, if it is not 'SLEEP' then return */
+       if (dev_context->dw_brd_state == BRD_RUNNING ||
+           dev_context->dw_brd_state == BRD_STOPPED) {
+               /* The Device is in 'RET' or 'OFF' state and Bridge state is not
+                * 'SLEEP', this means state inconsistency, so return */
+               return 0;
+       }
+
+       /* Send a wakeup message to DSP */
+       sm_interrupt_dsp(dev_context, MBX_PM_DSPWAKEUP);
+
+       /* Set the device state to RUNNIG */
+       dev_context->dw_brd_state = BRD_RUNNING;
+#endif /* CONFIG_PM */
+       return status;
+}
+
+/*
+ *  ======== dsp_peripheral_clk_ctrl ========
+ *     Enable/Disable the DSP peripheral clocks as needed..
+ */
+int dsp_peripheral_clk_ctrl(struct bridge_dev_context *dev_context,
+                                  void *pargs)
+{
+       u32 ext_clk = 0;
+       u32 ext_clk_id = 0;
+       u32 ext_clk_cmd = 0;
+       u32 clk_id_index = MBX_PM_MAX_RESOURCES;
+       u32 tmp_index;
+       u32 dsp_per_clks_before;
+       int status = 0;
+
+       dsp_per_clks_before = dev_context->dsp_per_clks;
+
+       ext_clk = (u32) *((u32 *) pargs);
+       ext_clk_id = ext_clk & MBX_PM_CLK_IDMASK;
+
+       /* process the power message -- TODO, keep it in a separate function */
+       for (tmp_index = 0; tmp_index < MBX_PM_MAX_RESOURCES; tmp_index++) {
+               if (ext_clk_id == bpwr_clkid[tmp_index]) {
+                       clk_id_index = tmp_index;
+                       break;
+               }
+       }
+       /* TODO -- Assert may be a too hard restriction here.. May be we should
+        * just return with failure when the CLK ID does not match */
+       /* DBC_ASSERT(clk_id_index < MBX_PM_MAX_RESOURCES); */
+       if (clk_id_index == MBX_PM_MAX_RESOURCES) {
+               /* return with a more meaningfull error code */
+               return -EPERM;
+       }
+       ext_clk_cmd = (ext_clk >> MBX_PM_CLK_CMDSHIFT) & MBX_PM_CLK_CMDMASK;
+       switch (ext_clk_cmd) {
+       case BPWR_DISABLE_CLOCK:
+               status = dsp_clk_disable(bpwr_clks[clk_id_index].clk);
+               dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id,
+                                         false);
+               if (!status) {
+                       (dev_context->dsp_per_clks) &=
+                               (~((u32) (1 << bpwr_clks[clk_id_index].clk)));
+               }
+               break;
+       case BPWR_ENABLE_CLOCK:
+               status = dsp_clk_enable(bpwr_clks[clk_id_index].clk);
+               dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id, true);
+               if (!status)
+                       (dev_context->dsp_per_clks) |=
+                               (1 << bpwr_clks[clk_id_index].clk);
+               break;
+       default:
+               dev_dbg(bridge, "%s: Unsupported CMD\n", __func__);
+               /* unsupported cmd */
+               /* TODO -- provide support for AUTOIDLE Enable/Disable
+                * commands */
+       }
+       return status;
+}
+
+/*
+ *  ========pre_scale_dsp========
+ *  Sends prescale notification to DSP
+ *
+ */
+int pre_scale_dsp(struct bridge_dev_context *dev_context, void *pargs)
+{
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       u32 level;
+       u32 voltage_domain;
+
+       voltage_domain = *((u32 *) pargs);
+       level = *((u32 *) pargs + 1);
+
+       dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
+               __func__, voltage_domain, level);
+       if ((dev_context->dw_brd_state == BRD_HIBERNATION) ||
+           (dev_context->dw_brd_state == BRD_RETENTION) ||
+           (dev_context->dw_brd_state == BRD_DSP_HIBERNATION)) {
+               dev_dbg(bridge, "OPP: %s IVA in sleep. No message to DSP\n");
+               return 0;
+       } else if ((dev_context->dw_brd_state == BRD_RUNNING)) {
+               /* Send a prenotificatio to DSP */
+               dev_dbg(bridge, "OPP: %s sent notification to DSP\n", __func__);
+               sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_PRENOTIFY);
+               return 0;
+       } else {
+               return -EPERM;
+       }
+#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
+       return 0;
+}
+
+/*
+ *  ========post_scale_dsp========
+ *  Sends postscale notification to DSP
+ *
+ */
+int post_scale_dsp(struct bridge_dev_context *dev_context,
+                                                       void *pargs)
+{
+       int status = 0;
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       u32 level;
+       u32 voltage_domain;
+       struct io_mgr *hio_mgr;
+
+       status = dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr);
+       if (!hio_mgr)
+               return -EFAULT;
+
+       voltage_domain = *((u32 *) pargs);
+       level = *((u32 *) pargs + 1);
+       dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
+               __func__, voltage_domain, level);
+       if ((dev_context->dw_brd_state == BRD_HIBERNATION) ||
+           (dev_context->dw_brd_state == BRD_RETENTION) ||
+           (dev_context->dw_brd_state == BRD_DSP_HIBERNATION)) {
+               /* Update the OPP value in shared memory */
+               io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
+               dev_dbg(bridge, "OPP: %s IVA in sleep. Wrote to shm\n",
+                       __func__);
+       } else if ((dev_context->dw_brd_state == BRD_RUNNING)) {
+               /* Update the OPP value in shared memory */
+               io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
+               /* Send a post notification to DSP */
+               sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_POSTNOTIFY);
+               dev_dbg(bridge, "OPP: %s wrote to shm. Sent post notification "
+                       "to DSP\n", __func__);
+       } else {
+               status = -EPERM;
+       }
+#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
+       return status;
+}
+
+void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable)
+{
+       struct cfg_hostres *resources;
+       int status = 0;
+       u32 iva2_grpsel;
+       u32 mpu_grpsel;
+       struct dev_object *hdev_object = NULL;
+       struct bridge_dev_context *bridge_context = NULL;
+
+       hdev_object = (struct dev_object *)drv_get_first_dev_object();
+       if (!hdev_object)
+               return;
+
+       status = dev_get_bridge_context(hdev_object, &bridge_context);
+       if (!bridge_context)
+               return;
+
+       resources = bridge_context->resources;
+       if (!resources)
+               return;
+
+       switch (clock_id) {
+       case BPWR_GP_TIMER5:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       case BPWR_GP_TIMER6:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       case BPWR_GP_TIMER7:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       case BPWR_GP_TIMER8:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       case BPWR_MCBSP1:
+               iva2_grpsel = readl(resources->dw_core_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_core_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_core_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_core_pm_base + 0xA4);
+               break;
+       case BPWR_MCBSP2:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       case BPWR_MCBSP3:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       case BPWR_MCBSP4:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       case BPWR_MCBSP5:
+               iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
+               mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4);
+               if (enable) {
+                       iva2_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
+                       mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
+               } else {
+                       mpu_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
+                       iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
+               }
+               writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8);
+               writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
+               break;
+       }
+}
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c
new file mode 100644 (file)
index 0000000..190c028
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * tiomap_io.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implementation for the io read/write routines.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+#include <dspbridge/drv.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/wdt.h>
+
+/*  ----------------------------------- specific to this file */
+#include "_tiomap.h"
+#include "_tiomap_pwr.h"
+#include "tiomap_io.h"
+
+static u32 ul_ext_base;
+static u32 ul_ext_end;
+
+static u32 shm0_end;
+static u32 ul_dyn_ext_base;
+static u32 ul_trace_sec_beg;
+static u32 ul_trace_sec_end;
+static u32 ul_shm_base_virt;
+
+bool symbols_reloaded = true;
+
+/*
+ *  ======== read_ext_dsp_data ========
+ *      Copies DSP external memory buffers to the host side buffers.
+ */
+int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
+                            u8 *host_buff, u32 dsp_addr,
+                            u32 ul_num_bytes, u32 mem_type)
+{
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       u32 offset;
+       u32 ul_tlb_base_virt = 0;
+       u32 ul_shm_offset_virt = 0;
+       u32 dw_ext_prog_virt_mem;
+       u32 dw_base_addr = dev_context->dw_dsp_ext_base_addr;
+       bool trace_read = false;
+
+       if (!ul_shm_base_virt) {
+               status = dev_get_symbol(dev_context->hdev_obj,
+                                       SHMBASENAME, &ul_shm_base_virt);
+       }
+       DBC_ASSERT(ul_shm_base_virt != 0);
+
+       /* Check if it is a read of Trace section */
+       if (!status && !ul_trace_sec_beg) {
+               status = dev_get_symbol(dev_context->hdev_obj,
+                                       DSP_TRACESEC_BEG, &ul_trace_sec_beg);
+       }
+       DBC_ASSERT(ul_trace_sec_beg != 0);
+
+       if (!status && !ul_trace_sec_end) {
+               status = dev_get_symbol(dev_context->hdev_obj,
+                                       DSP_TRACESEC_END, &ul_trace_sec_end);
+       }
+       DBC_ASSERT(ul_trace_sec_end != 0);
+
+       if (!status) {
+               if ((dsp_addr <= ul_trace_sec_end) &&
+                   (dsp_addr >= ul_trace_sec_beg))
+                       trace_read = true;
+       }
+
+       /* If reading from TRACE, force remap/unmap */
+       if (trace_read && dw_base_addr) {
+               dw_base_addr = 0;
+               dev_context->dw_dsp_ext_base_addr = 0;
+       }
+
+       if (!dw_base_addr) {
+               /* Initialize ul_ext_base and ul_ext_end */
+               ul_ext_base = 0;
+               ul_ext_end = 0;
+
+               /* Get DYNEXT_BEG, EXT_BEG and EXT_END. */
+               if (!status && !ul_dyn_ext_base) {
+                       status = dev_get_symbol(dev_context->hdev_obj,
+                                               DYNEXTBASE, &ul_dyn_ext_base);
+               }
+               DBC_ASSERT(ul_dyn_ext_base != 0);
+
+               if (!status) {
+                       status = dev_get_symbol(dev_context->hdev_obj,
+                                               EXTBASE, &ul_ext_base);
+               }
+               DBC_ASSERT(ul_ext_base != 0);
+
+               if (!status) {
+                       status = dev_get_symbol(dev_context->hdev_obj,
+                                               EXTEND, &ul_ext_end);
+               }
+               DBC_ASSERT(ul_ext_end != 0);
+
+               /* Trace buffer is right after the shm SEG0,
+                *  so set the base address to SHMBASE */
+               if (trace_read) {
+                       ul_ext_base = ul_shm_base_virt;
+                       ul_ext_end = ul_trace_sec_end;
+               }
+
+               DBC_ASSERT(ul_ext_end != 0);
+               DBC_ASSERT(ul_ext_end > ul_ext_base);
+
+               if (ul_ext_end < ul_ext_base)
+                       status = -EPERM;
+
+               if (!status) {
+                       ul_tlb_base_virt =
+                           dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE;
+                       DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
+                       dw_ext_prog_virt_mem =
+                           dev_context->atlb_entry[0].ul_gpp_va;
+
+                       if (!trace_read) {
+                               ul_shm_offset_virt =
+                                   ul_shm_base_virt - ul_tlb_base_virt;
+                               ul_shm_offset_virt +=
+                                   PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base +
+                                                 1, HW_PAGE_SIZE64KB);
+                               dw_ext_prog_virt_mem -= ul_shm_offset_virt;
+                               dw_ext_prog_virt_mem +=
+                                   (ul_ext_base - ul_dyn_ext_base);
+                               dev_context->dw_dsp_ext_base_addr =
+                                   dw_ext_prog_virt_mem;
+
+                               /*
+                                * This dw_dsp_ext_base_addr will get cleared
+                                * only when the board is stopped.
+                               */
+                               if (!dev_context->dw_dsp_ext_base_addr)
+                                       status = -EPERM;
+                       }
+
+                       dw_base_addr = dw_ext_prog_virt_mem;
+               }
+       }
+
+       if (!dw_base_addr || !ul_ext_base || !ul_ext_end)
+               status = -EPERM;
+
+       offset = dsp_addr - ul_ext_base;
+
+       if (!status)
+               memcpy(host_buff, (u8 *) dw_base_addr + offset, ul_num_bytes);
+
+       return status;
+}
+
+/*
+ *  ======== write_dsp_data ========
+ *  purpose:
+ *      Copies buffers to the DSP internal/external memory.
+ */
+int write_dsp_data(struct bridge_dev_context *dev_context,
+                         u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes,
+                         u32 mem_type)
+{
+       u32 offset;
+       u32 dw_base_addr = dev_context->dw_dsp_base_addr;
+       struct cfg_hostres *resources = dev_context->resources;
+       int status = 0;
+       u32 base1, base2, base3;
+       base1 = OMAP_DSP_MEM1_SIZE;
+       base2 = OMAP_DSP_MEM2_BASE - OMAP_DSP_MEM1_BASE;
+       base3 = OMAP_DSP_MEM3_BASE - OMAP_DSP_MEM1_BASE;
+
+       if (!resources)
+               return -EPERM;
+
+       offset = dsp_addr - dev_context->dw_dsp_start_add;
+       if (offset < base1) {
+               dw_base_addr = MEM_LINEAR_ADDRESS(resources->dw_mem_base[2],
+                                                 resources->dw_mem_length[2]);
+       } else if (offset > base1 && offset < base2 + OMAP_DSP_MEM2_SIZE) {
+               dw_base_addr = MEM_LINEAR_ADDRESS(resources->dw_mem_base[3],
+                                                 resources->dw_mem_length[3]);
+               offset = offset - base2;
+       } else if (offset >= base2 + OMAP_DSP_MEM2_SIZE &&
+                  offset < base3 + OMAP_DSP_MEM3_SIZE) {
+               dw_base_addr = MEM_LINEAR_ADDRESS(resources->dw_mem_base[4],
+                                                 resources->dw_mem_length[4]);
+               offset = offset - base3;
+       } else {
+               return -EPERM;
+       }
+       if (ul_num_bytes)
+               memcpy((u8 *) (dw_base_addr + offset), host_buff, ul_num_bytes);
+       else
+               *((u32 *) host_buff) = dw_base_addr + offset;
+
+       return status;
+}
+
+/*
+ *  ======== write_ext_dsp_data ========
+ *  purpose:
+ *      Copies buffers to the external memory.
+ *
+ */
+int write_ext_dsp_data(struct bridge_dev_context *dev_context,
+                             u8 *host_buff, u32 dsp_addr,
+                             u32 ul_num_bytes, u32 mem_type,
+                             bool dynamic_load)
+{
+       u32 dw_base_addr = dev_context->dw_dsp_ext_base_addr;
+       u32 dw_offset = 0;
+       u8 temp_byte1, temp_byte2;
+       u8 remain_byte[4];
+       s32 i;
+       int ret = 0;
+       u32 dw_ext_prog_virt_mem;
+       u32 ul_tlb_base_virt = 0;
+       u32 ul_shm_offset_virt = 0;
+       struct cfg_hostres *host_res = dev_context->resources;
+       bool trace_load = false;
+       temp_byte1 = 0x0;
+       temp_byte2 = 0x0;
+
+       if (symbols_reloaded) {
+               /* Check if it is a load to Trace section */
+               ret = dev_get_symbol(dev_context->hdev_obj,
+                                    DSP_TRACESEC_BEG, &ul_trace_sec_beg);
+               if (!ret)
+                       ret = dev_get_symbol(dev_context->hdev_obj,
+                                            DSP_TRACESEC_END,
+                                            &ul_trace_sec_end);
+       }
+       if (!ret) {
+               if ((dsp_addr <= ul_trace_sec_end) &&
+                   (dsp_addr >= ul_trace_sec_beg))
+                       trace_load = true;
+       }
+
+       /* If dynamic, force remap/unmap */
+       if ((dynamic_load || trace_load) && dw_base_addr) {
+               dw_base_addr = 0;
+               MEM_UNMAP_LINEAR_ADDRESS((void *)
+                                        dev_context->dw_dsp_ext_base_addr);
+               dev_context->dw_dsp_ext_base_addr = 0x0;
+       }
+       if (!dw_base_addr) {
+               if (symbols_reloaded)
+                       /* Get SHM_BEG  EXT_BEG and EXT_END. */
+                       ret = dev_get_symbol(dev_context->hdev_obj,
+                                            SHMBASENAME, &ul_shm_base_virt);
+               DBC_ASSERT(ul_shm_base_virt != 0);
+               if (dynamic_load) {
+                       if (!ret) {
+                               if (symbols_reloaded)
+                                       ret =
+                                           dev_get_symbol
+                                           (dev_context->hdev_obj, DYNEXTBASE,
+                                            &ul_ext_base);
+                       }
+                       DBC_ASSERT(ul_ext_base != 0);
+                       if (!ret) {
+                               /* DR  OMAPS00013235 : DLModules array may be
+                                * in EXTMEM. It is expected that DYNEXTMEM and
+                                * EXTMEM are contiguous, so checking for the
+                                * upper bound at EXTEND should be Ok. */
+                               if (symbols_reloaded)
+                                       ret =
+                                           dev_get_symbol
+                                           (dev_context->hdev_obj, EXTEND,
+                                            &ul_ext_end);
+                       }
+               } else {
+                       if (symbols_reloaded) {
+                               if (!ret)
+                                       ret =
+                                           dev_get_symbol
+                                           (dev_context->hdev_obj, EXTBASE,
+                                            &ul_ext_base);
+                               DBC_ASSERT(ul_ext_base != 0);
+                               if (!ret)
+                                       ret =
+                                           dev_get_symbol
+                                           (dev_context->hdev_obj, EXTEND,
+                                            &ul_ext_end);
+                       }
+               }
+               /* Trace buffer it right after the shm SEG0, so set the
+                *      base address to SHMBASE */
+               if (trace_load)
+                       ul_ext_base = ul_shm_base_virt;
+
+               DBC_ASSERT(ul_ext_end != 0);
+               DBC_ASSERT(ul_ext_end > ul_ext_base);
+               if (ul_ext_end < ul_ext_base)
+                       ret = -EPERM;
+
+               if (!ret) {
+                       ul_tlb_base_virt =
+                           dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE;
+                       DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
+
+                       if (symbols_reloaded) {
+                               ret = dev_get_symbol
+                                           (dev_context->hdev_obj,
+                                            DSP_TRACESEC_END, &shm0_end);
+                               if (!ret) {
+                                       ret =
+                                           dev_get_symbol
+                                           (dev_context->hdev_obj, DYNEXTBASE,
+                                            &ul_dyn_ext_base);
+                               }
+                       }
+                       ul_shm_offset_virt =
+                           ul_shm_base_virt - ul_tlb_base_virt;
+                       if (trace_load) {
+                               dw_ext_prog_virt_mem =
+                                   dev_context->atlb_entry[0].ul_gpp_va;
+                       } else {
+                               dw_ext_prog_virt_mem = host_res->dw_mem_base[1];
+                               dw_ext_prog_virt_mem +=
+                                   (ul_ext_base - ul_dyn_ext_base);
+                       }
+
+                       dev_context->dw_dsp_ext_base_addr =
+                           (u32) MEM_LINEAR_ADDRESS((void *)
+                                                    dw_ext_prog_virt_mem,
+                                                    ul_ext_end - ul_ext_base);
+                       dw_base_addr += dev_context->dw_dsp_ext_base_addr;
+                       /* This dw_dsp_ext_base_addr will get cleared only when
+                        * the board is stopped. */
+                       if (!dev_context->dw_dsp_ext_base_addr)
+                               ret = -EPERM;
+               }
+       }
+       if (!dw_base_addr || !ul_ext_base || !ul_ext_end)
+               ret = -EPERM;
+
+       if (!ret) {
+               for (i = 0; i < 4; i++)
+                       remain_byte[i] = 0x0;
+
+               dw_offset = dsp_addr - ul_ext_base;
+               /* Also make sure the dsp_addr is < ul_ext_end */
+               if (dsp_addr > ul_ext_end || dw_offset > dsp_addr)
+                       ret = -EPERM;
+       }
+       if (!ret) {
+               if (ul_num_bytes)
+                       memcpy((u8 *) dw_base_addr + dw_offset, host_buff,
+                              ul_num_bytes);
+               else
+                       *((u32 *) host_buff) = dw_base_addr + dw_offset;
+       }
+       /* Unmap here to force remap for other Ext loads */
+       if ((dynamic_load || trace_load) && dev_context->dw_dsp_ext_base_addr) {
+               MEM_UNMAP_LINEAR_ADDRESS((void *)
+                                        dev_context->dw_dsp_ext_base_addr);
+               dev_context->dw_dsp_ext_base_addr = 0x0;
+       }
+       symbols_reloaded = false;
+       return ret;
+}
+
+int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val)
+{
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       u32 opplevel = 0;
+#endif
+       struct dspbridge_platform_data *pdata =
+               omap_dspbridge_dev->dev.platform_data;
+       struct cfg_hostres *resources = dev_context->resources;
+       int status = 0;
+       u32 temp;
+
+       if (!dev_context->mbox)
+               return 0;
+
+       if (!resources)
+               return -EPERM;
+
+       if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION ||
+           dev_context->dw_brd_state == BRD_HIBERNATION) {
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+               if (pdata->dsp_get_opp)
+                       opplevel = (*pdata->dsp_get_opp) ();
+               if (opplevel == VDD1_OPP1) {
+                       if (pdata->dsp_set_min_opp)
+                               (*pdata->dsp_set_min_opp) (VDD1_OPP2);
+               }
+#endif
+               /* Restart the peripheral clocks */
+               dsp_clock_enable_all(dev_context->dsp_per_clks);
+               dsp_wdt_enable(true);
+
+               /*
+                * 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control
+                *     in CM_AUTOIDLE_PLL_IVA2 register
+                */
+               (*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
+                               OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+
+               /*
+                * 7:4 IVA2_DPLL_FREQSEL - IVA2 internal frq set to
+                *     0.75 MHz - 1.0 MHz
+                * 2:0 EN_IVA2_DPLL - Enable IVA2 DPLL in lock mode
+                */
+               (*pdata->dsp_cm_rmw_bits)(OMAP3430_IVA2_DPLL_FREQSEL_MASK |
+                               OMAP3430_EN_IVA2_DPLL_MASK,
+                               0x3 << OMAP3430_IVA2_DPLL_FREQSEL_SHIFT |
+                               0x7 << OMAP3430_EN_IVA2_DPLL_SHIFT,
+                               OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
+
+               /* Restore mailbox settings */
+               omap_mbox_restore_ctx(dev_context->mbox);
+
+               /* Access MMU SYS CONFIG register to generate a short wakeup */
+               temp = readl(resources->dw_dmmu_base + 0x10);
+
+               dev_context->dw_brd_state = BRD_RUNNING;
+       } else if (dev_context->dw_brd_state == BRD_RETENTION) {
+               /* Restart the peripheral clocks */
+               dsp_clock_enable_all(dev_context->dsp_per_clks);
+       }
+
+       status = omap_mbox_msg_send(dev_context->mbox, mb_val);
+
+       if (status) {
+               pr_err("omap_mbox_msg_send Fail and status = %d\n", status);
+               status = -EPERM;
+       }
+
+       return 0;
+}
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.h b/drivers/staging/tidspbridge/core/tiomap_io.h
new file mode 100644 (file)
index 0000000..a3f19c7
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * tiomap_io.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Definitions, types and function prototypes for the io (r/w external mem).
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _TIOMAP_IO_
+#define _TIOMAP_IO_
+
+/*
+ * Symbol that defines beginning of shared memory.
+ * For OMAP (Helen) this is the DSP Virtual base address of SDRAM.
+ * This will be used to program DSP MMU to map DSP Virt to GPP phys.
+ * (see dspMmuTlbEntry()).
+ */
+#define SHMBASENAME "SHM_BEG"
+#define EXTBASE     "EXT_BEG"
+#define EXTEND      "_EXT_END"
+#define DYNEXTBASE  "_DYNEXT_BEG"
+#define DYNEXTEND   "_DYNEXT_END"
+#define IVAEXTMEMBASE   "_IVAEXTMEM_BEG"
+#define IVAEXTMEMEND   "_IVAEXTMEM_END"
+
+#define DSP_TRACESEC_BEG  "_BRIDGE_TRACE_BEG"
+#define DSP_TRACESEC_END  "_BRIDGE_TRACE_END"
+
+#define SYS_PUTCBEG               "_SYS_PUTCBEG"
+#define SYS_PUTCEND               "_SYS_PUTCEND"
+#define BRIDGE_SYS_PUTC_CURRENT   "_BRIDGE_SYS_PUTC_current"
+
+#define WORDSWAP_ENABLE 0x3    /* Enable word swap */
+
+/*
+ *  ======== read_ext_dsp_data ========
+ *  Reads it from DSP External memory. The external memory for the DSP
+ * is configured by the combination of DSP MMU and shm Memory manager in the CDB
+ */
+extern int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
+                                   u8 *host_buff, u32 dsp_addr,
+                                   u32 ul_num_bytes, u32 mem_type);
+
+/*
+ *  ======== write_dsp_data ========
+ */
+extern int write_dsp_data(struct bridge_dev_context *dev_context,
+                                u8 *host_buff, u32 dsp_addr,
+                                u32 ul_num_bytes, u32 mem_type);
+
+/*
+ *  ======== write_ext_dsp_data ========
+ *  Writes to the DSP External memory for external program.
+ *  The ext mem for progra is configured by the combination of DSP MMU and
+ *  shm Memory manager in the CDB
+ */
+extern int write_ext_dsp_data(struct bridge_dev_context *dev_context,
+                                    u8 *host_buff, u32 dsp_addr,
+                                    u32 ul_num_bytes, u32 mem_type,
+                                    bool dynamic_load);
+
+/*
+ * ======== write_ext32_bit_dsp_data ========
+ * Writes 32 bit data to the external memory
+ */
+extern inline void write_ext32_bit_dsp_data(const
+                                       struct bridge_dev_context *dev_context,
+                                       u32 dsp_addr, u32 val)
+{
+       *(u32 *) dsp_addr = ((dev_context->tc_word_swap_on) ? (((val << 16) &
+                                                                0xFFFF0000) |
+                                                               ((val >> 16) &
+                                                                0x0000FFFF)) :
+                             val);
+}
+
+/*
+ * ======== read_ext32_bit_dsp_data ========
+ * Reads 32 bit data from the external memory
+ */
+extern inline u32 read_ext32_bit_dsp_data(const struct bridge_dev_context
+                                         *dev_context, u32 dsp_addr)
+{
+       u32 ret;
+       ret = *(u32 *) dsp_addr;
+
+       ret = ((dev_context->tc_word_swap_on) ? (((ret << 16)
+                                                 & 0xFFFF0000) | ((ret >> 16) &
+                                                                  0x0000FFFF))
+              : ret);
+       return ret;
+}
+
+#endif /* _TIOMAP_IO_ */
diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c
new file mode 100644 (file)
index 0000000..3430418
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * ue_deh.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implements upper edge DSP exception handling (DEH) functions.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ * Copyright (C) 2010 Felipe Contreras
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <plat/dmtimer.h>
+
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/dspdeh.h>
+#include <dspbridge/dev.h>
+#include "_tiomap.h"
+#include "_deh.h"
+
+#include <dspbridge/io_sm.h>
+#include <dspbridge/drv.h>
+#include <dspbridge/wdt.h>
+
+static u32 fault_addr;
+
+static void mmu_fault_dpc(unsigned long data)
+{
+       struct deh_mgr *deh = (void *)data;
+
+       if (!deh)
+               return;
+
+       bridge_deh_notify(deh, DSP_MMUFAULT, 0);
+}
+
+static irqreturn_t mmu_fault_isr(int irq, void *data)
+{
+       struct deh_mgr *deh = data;
+       struct cfg_hostres *resources;
+       u32 event;
+
+       if (!deh)
+               return IRQ_HANDLED;
+
+       resources = deh->hbridge_context->resources;
+       if (!resources) {
+               dev_dbg(bridge, "%s: Failed to get Host Resources\n",
+                               __func__);
+               return IRQ_HANDLED;
+       }
+
+       hw_mmu_event_status(resources->dw_dmmu_base, &event);
+       if (event == HW_MMU_TRANSLATION_FAULT) {
+               hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr);
+               dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__,
+                               event, fault_addr);
+               /*
+                * Schedule a DPC directly. In the future, it may be
+                * necessary to check if DSP MMU fault is intended for
+                * Bridge.
+                */
+               tasklet_schedule(&deh->dpc_tasklet);
+
+               /* Disable the MMU events, else once we clear it will
+                * start to raise INTs again */
+               hw_mmu_event_disable(resources->dw_dmmu_base,
+                               HW_MMU_TRANSLATION_FAULT);
+       } else {
+               hw_mmu_event_disable(resources->dw_dmmu_base,
+                               HW_MMU_ALL_INTERRUPTS);
+       }
+       return IRQ_HANDLED;
+}
+
+int bridge_deh_create(struct deh_mgr **ret_deh,
+               struct dev_object *hdev_obj)
+{
+       int status;
+       struct deh_mgr *deh;
+       struct bridge_dev_context *hbridge_context = NULL;
+
+       /*  Message manager will be created when a file is loaded, since
+        *  size of message buffer in shared memory is configurable in
+        *  the base image. */
+       /* Get Bridge context info. */
+       dev_get_bridge_context(hdev_obj, &hbridge_context);
+       /* Allocate IO manager object: */
+       deh = kzalloc(sizeof(*deh), GFP_KERNEL);
+       if (!deh) {
+               status = -ENOMEM;
+               goto err;
+       }
+
+       /* Create an NTFY object to manage notifications */
+       deh->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL);
+       if (!deh->ntfy_obj) {
+               status = -ENOMEM;
+               goto err;
+       }
+       ntfy_init(deh->ntfy_obj);
+
+       /* Create a MMUfault DPC */
+       tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh);
+
+       /* Fill in context structure */
+       deh->hbridge_context = hbridge_context;
+
+       /* Install ISR function for DSP MMU fault */
+       status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0,
+                       "DspBridge\tiommu fault", deh);
+       if (status < 0)
+               goto err;
+
+       *ret_deh = deh;
+       return 0;
+
+err:
+       bridge_deh_destroy(deh);
+       *ret_deh = NULL;
+       return status;
+}
+
+int bridge_deh_destroy(struct deh_mgr *deh)
+{
+       if (!deh)
+               return -EFAULT;
+
+       /* If notification object exists, delete it */
+       if (deh->ntfy_obj) {
+               ntfy_delete(deh->ntfy_obj);
+               kfree(deh->ntfy_obj);
+       }
+       /* Disable DSP MMU fault */
+       free_irq(INT_DSP_MMU_IRQ, deh);
+
+       /* Free DPC object */
+       tasklet_kill(&deh->dpc_tasklet);
+
+       /* Deallocate the DEH manager object */
+       kfree(deh);
+
+       return 0;
+}
+
+int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask,
+               u32 notify_type,
+               struct dsp_notification *hnotification)
+{
+       if (!deh)
+               return -EFAULT;
+
+       if (event_mask)
+               return ntfy_register(deh->ntfy_obj, hnotification,
+                               event_mask, notify_type);
+       else
+               return ntfy_unregister(deh->ntfy_obj, hnotification);
+}
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
+{
+       struct cfg_hostres *resources;
+       struct hw_mmu_map_attrs_t map_attrs = {
+               .endianism = HW_LITTLE_ENDIAN,
+               .element_size = HW_ELEM_SIZE16BIT,
+               .mixed_size = HW_MMU_CPUES,
+       };
+       void *dummy_va_addr;
+
+       resources = dev_context->resources;
+       dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC);
+
+       /*
+        * Before acking the MMU fault, let's make sure MMU can only
+        * access entry #0. Then add a new entry so that the DSP OS
+        * can continue in order to dump the stack.
+        */
+       hw_mmu_twl_disable(resources->dw_dmmu_base);
+       hw_mmu_tlb_flush_all(resources->dw_dmmu_base);
+
+       hw_mmu_tlb_add(resources->dw_dmmu_base,
+                       virt_to_phys(dummy_va_addr), fault_addr,
+                       HW_PAGE_SIZE4KB, 1,
+                       &map_attrs, HW_SET, HW_SET);
+
+       dsp_clk_enable(DSP_CLK_GPT8);
+
+       dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);
+
+       /* Clear MMU interrupt */
+       hw_mmu_event_ack(resources->dw_dmmu_base,
+                       HW_MMU_TRANSLATION_FAULT);
+       dump_dsp_stack(dev_context);
+       dsp_clk_disable(DSP_CLK_GPT8);
+
+       hw_mmu_disable(resources->dw_dmmu_base);
+       free_page((unsigned long)dummy_va_addr);
+}
+#endif
+
+static inline const char *event_to_string(int event)
+{
+       switch (event) {
+       case DSP_SYSERROR: return "DSP_SYSERROR"; break;
+       case DSP_MMUFAULT: return "DSP_MMUFAULT"; break;
+       case DSP_PWRERROR: return "DSP_PWRERROR"; break;
+       case DSP_WDTOVERFLOW: return "DSP_WDTOVERFLOW"; break;
+       default: return "unkown event"; break;
+       }
+}
+
+void bridge_deh_notify(struct deh_mgr *deh, int event, int info)
+{
+       struct bridge_dev_context *dev_context;
+       const char *str = event_to_string(event);
+
+       if (!deh)
+               return;
+
+       dev_dbg(bridge, "%s: device exception", __func__);
+       dev_context = deh->hbridge_context;
+
+       switch (event) {
+       case DSP_SYSERROR:
+               dev_err(bridge, "%s: %s, info=0x%x", __func__,
+                               str, info);
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+               dump_dl_modules(dev_context);
+               dump_dsp_stack(dev_context);
+#endif
+               break;
+       case DSP_MMUFAULT:
+               dev_err(bridge, "%s: %s, addr=0x%x", __func__,
+                               str, fault_addr);
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+               print_dsp_trace_buffer(dev_context);
+               dump_dl_modules(dev_context);
+               mmu_fault_print_stack(dev_context);
+#endif
+               break;
+       default:
+               dev_err(bridge, "%s: %s", __func__, str);
+               break;
+       }
+
+       /* Filter subsequent notifications when an error occurs */
+       if (dev_context->dw_brd_state != BRD_ERROR) {
+               ntfy_notify(deh->ntfy_obj, event);
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+               bridge_recover_schedule();
+#endif
+       }
+
+       /* Set the Board state as ERROR */
+       dev_context->dw_brd_state = BRD_ERROR;
+       /* Disable all the clocks that were enabled by DSP */
+       dsp_clock_disable_all(dev_context->dsp_per_clks);
+       /*
+        * Avoid the subsequent WDT if it happens once,
+        * also if fatal error occurs.
+        */
+       dsp_wdt_enable(false);
+}
diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c
new file mode 100644 (file)
index 0000000..2126f59
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * wdt.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * IO dispatcher for a shared memory channel driver.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/dspdeh.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/_chnl_sm.h>
+#include <dspbridge/wdt.h>
+#include <dspbridge/host_os.h>
+
+
+#ifdef CONFIG_TIDSPBRIDGE_WDT3
+
+#define OMAP34XX_WDT3_BASE             (L4_PER_34XX_BASE + 0x30000)
+
+static struct dsp_wdt_setting dsp_wdt;
+
+void dsp_wdt_dpc(unsigned long data)
+{
+       struct deh_mgr *deh_mgr;
+       dev_get_deh_mgr(dev_get_first(), &deh_mgr);
+       if (deh_mgr)
+               bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
+}
+
+irqreturn_t dsp_wdt_isr(int irq, void *data)
+{
+       u32 value;
+       /* ack wdt3 interrupt */
+       value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
+       __raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
+
+       tasklet_schedule(&dsp_wdt.wdt3_tasklet);
+       return IRQ_HANDLED;
+}
+
+int dsp_wdt_init(void)
+{
+       int ret = 0;
+
+       dsp_wdt.sm_wdt = NULL;
+       dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE);
+       tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);
+
+       dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
+
+       if (dsp_wdt.fclk) {
+               dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
+               if (!dsp_wdt.iclk) {
+                       clk_put(dsp_wdt.fclk);
+                       dsp_wdt.fclk = NULL;
+                       ret = -EFAULT;
+               }
+       } else
+               ret = -EFAULT;
+
+       if (!ret)
+               ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0,
+                                                       "dsp_wdt", &dsp_wdt);
+
+       /* Disable at this moment, it will be enabled when DSP starts */
+       if (!ret)
+               disable_irq(INT_34XX_WDT3_IRQ);
+
+       return ret;
+}
+
+void dsp_wdt_sm_set(void *data)
+{
+       dsp_wdt.sm_wdt = data;
+       dsp_wdt.sm_wdt->wdt_overflow = CONFIG_TIDSPBRIDGE_WDT_TIMEOUT;
+}
+
+
+void dsp_wdt_exit(void)
+{
+       free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
+       tasklet_kill(&dsp_wdt.wdt3_tasklet);
+
+       if (dsp_wdt.fclk)
+               clk_put(dsp_wdt.fclk);
+       if (dsp_wdt.iclk)
+               clk_put(dsp_wdt.iclk);
+
+       dsp_wdt.fclk = NULL;
+       dsp_wdt.iclk = NULL;
+       dsp_wdt.sm_wdt = NULL;
+       dsp_wdt.reg_base = NULL;
+}
+
+void dsp_wdt_enable(bool enable)
+{
+       u32 tmp;
+       static bool wdt_enable;
+
+       if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk)
+               return;
+
+       wdt_enable = enable;
+
+       if (enable) {
+               clk_enable(dsp_wdt.fclk);
+               clk_enable(dsp_wdt.iclk);
+               dsp_wdt.sm_wdt->wdt_setclocks = 1;
+               tmp = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
+               __raw_writel(tmp, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
+               enable_irq(INT_34XX_WDT3_IRQ);
+       } else {
+               disable_irq(INT_34XX_WDT3_IRQ);
+               dsp_wdt.sm_wdt->wdt_setclocks = 0;
+               clk_disable(dsp_wdt.iclk);
+               clk_disable(dsp_wdt.fclk);
+       }
+}
+
+#else
+void dsp_wdt_enable(bool enable)
+{
+}
+
+void dsp_wdt_sm_set(void *data)
+{
+}
+
+int dsp_wdt_init(void)
+{
+       return 0;
+}
+
+void dsp_wdt_exit(void)
+{
+}
+#endif
+
diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c
new file mode 100644 (file)
index 0000000..c85a5e8
--- /dev/null
@@ -0,0 +1,1953 @@
+/*
+ * cload.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "header.h"
+
+#include "module_list.h"
+#define LINKER_MODULES_HEADER ("_" MODULES_HEADER)
+
+/*
+ * forward references
+ */
+static void dload_symbols(struct dload_state *dlthis);
+static void dload_data(struct dload_state *dlthis);
+static void allocate_sections(struct dload_state *dlthis);
+static void string_table_free(struct dload_state *dlthis);
+static void symbol_table_free(struct dload_state *dlthis);
+static void section_table_free(struct dload_state *dlthis);
+static void init_module_handle(struct dload_state *dlthis);
+#if BITS_PER_AU > BITS_PER_BYTE
+static char *unpack_name(struct dload_state *dlthis, u32 soffset);
+#endif
+
+static const char cinitname[] = { ".cinit" };
+static const char loader_dllview_root[] = { "?DLModules?" };
+
+/*
+ * Error strings
+ */
+static const char readstrm[] = { "Error reading %s from input stream" };
+static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" };
+static const char tgtalloc[] = {
+       "Target memory allocate failed, section %s size " FMT_UI32 };
+static const char initfail[] = { "%s to target address " FMT_UI32 " failed" };
+static const char dlvwrite[] = { "Write to DLLview list failed" };
+static const char iconnect[] = { "Connect call to init interface failed" };
+static const char err_checksum[] = { "Checksum failed on %s" };
+
+/*************************************************************************
+ * Procedure dload_error
+ *
+ * Parameters:
+ *     errtxt  description of the error, printf style
+ *     ...             additional information
+ *
+ * Effect:
+ *     Reports or records the error as appropriate.
+ *********************************************************************** */
+void dload_error(struct dload_state *dlthis, const char *errtxt, ...)
+{
+       va_list args;
+
+       va_start(args, errtxt);
+       dlthis->mysym->error_report(dlthis->mysym, errtxt, args);
+       va_end(args);
+       dlthis->dload_errcount += 1;
+
+}                              /* dload_error */
+
+#define DL_ERROR(zza, zzb) dload_error(dlthis, zza, zzb)
+
+/*************************************************************************
+ * Procedure dload_syms_error
+ *
+ * Parameters:
+ *     errtxt  description of the error, printf style
+ *     ...             additional information
+ *
+ * Effect:
+ *     Reports or records the error as appropriate.
+ *********************************************************************** */
+void dload_syms_error(struct dynamic_loader_sym *syms, const char *errtxt, ...)
+{
+       va_list args;
+
+       va_start(args, errtxt);
+       syms->error_report(syms, errtxt, args);
+       va_end(args);
+}
+
+/*************************************************************************
+ * Procedure dynamic_load_module
+ *
+ * Parameters:
+ *     module  The input stream that supplies the module image
+ *     syms    Host-side symbol table and malloc/free functions
+ *     alloc   Target-side memory allocation
+ *     init    Target-side memory initialization
+ *     options Option flags DLOAD_*
+ *     mhandle A module handle for use with Dynamic_Unload
+ *
+ * Effect:
+ *     The module image is read using *module.  Target storage for the new
+ *     image is
+ * obtained from *alloc.  Symbols defined and referenced by the module are
+ * managed using *syms.  The image is then relocated and references
+ *     resolved as necessary, and the resulting executable bits are placed
+ *     into target memory using *init.
+ *
+ * Returns:
+ *     On a successful load, a module handle is placed in *mhandle,
+ *     and zero is returned.  On error, the number of errors detected is
+ *     returned.  Individual errors are reported during the load process
+ *     using syms->error_report().
+ ********************************************************************** */
+int dynamic_load_module(struct dynamic_loader_stream *module,
+                       struct dynamic_loader_sym *syms,
+                       struct dynamic_loader_allocate *alloc,
+                       struct dynamic_loader_initialize *init,
+                       unsigned options, void **mhandle)
+{
+       register unsigned *dp, sz;
+       struct dload_state dl_state;    /* internal state for this call */
+
+       /* blast our internal state */
+       dp = (unsigned *)&dl_state;
+       for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1)
+               *dp++ = 0;
+
+       /* Enable _only_ BSS initialization if enabled by user */
+       if ((options & DLOAD_INITBSS) == DLOAD_INITBSS)
+               dl_state.myoptions = DLOAD_INITBSS;
+
+       /* Check that mandatory arguments are present */
+       if (!module || !syms) {
+               dload_error(&dl_state, "Required parameter is NULL");
+       } else {
+               dl_state.strm = module;
+               dl_state.mysym = syms;
+               dload_headers(&dl_state);
+               if (!dl_state.dload_errcount)
+                       dload_strings(&dl_state, false);
+               if (!dl_state.dload_errcount)
+                       dload_sections(&dl_state);
+
+               if (init && !dl_state.dload_errcount) {
+                       if (init->connect(init)) {
+                               dl_state.myio = init;
+                               dl_state.myalloc = alloc;
+                               /* do now, before reducing symbols */
+                               allocate_sections(&dl_state);
+                       } else
+                               dload_error(&dl_state, iconnect);
+               }
+
+               if (!dl_state.dload_errcount) {
+                       /* fix up entry point address */
+                       unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1;
+                       if (sref < dl_state.allocated_secn_count)
+                               dl_state.dfile_hdr.df_entrypt +=
+                                   dl_state.ldr_sections[sref].run_addr;
+
+                       dload_symbols(&dl_state);
+               }
+
+               if (init && !dl_state.dload_errcount)
+                       dload_data(&dl_state);
+
+               init_module_handle(&dl_state);
+
+               /* dl_state.myio is init or 0 at this point. */
+               if (dl_state.myio) {
+                       if ((!dl_state.dload_errcount) &&
+                           (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) &&
+                           (!init->execute(init,
+                                           dl_state.dfile_hdr.df_entrypt)))
+                               dload_error(&dl_state, "Init->Execute Failed");
+                       init->release(init);
+               }
+
+               symbol_table_free(&dl_state);
+               section_table_free(&dl_state);
+               string_table_free(&dl_state);
+               dload_tramp_cleanup(&dl_state);
+
+               if (dl_state.dload_errcount) {
+                       dynamic_unload_module(dl_state.myhandle, syms, alloc,
+                                             init);
+                       dl_state.myhandle = NULL;
+               }
+       }
+
+       if (mhandle)
+               *mhandle = dl_state.myhandle;   /* give back the handle */
+
+       return dl_state.dload_errcount;
+}                              /* DLOAD_File */
+
+/*************************************************************************
+ * Procedure dynamic_open_module
+ *
+ * Parameters:
+ *      module  The input stream that supplies the module image
+ *      syms    Host-side symbol table and malloc/free functions
+ *      alloc   Target-side memory allocation
+ *      init    Target-side memory initialization
+ *      options Option flags DLOAD_*
+ *      mhandle A module handle for use with Dynamic_Unload
+ *
+ * Effect:
+ *      The module image is read using *module.  Target storage for the new
+ *      image is
+ *     obtained from *alloc.  Symbols defined and referenced by the module are
+ *     managed using *syms.  The image is then relocated and references
+ *      resolved as necessary, and the resulting executable bits are placed
+ *      into target memory using *init.
+ *
+ * Returns:
+ *      On a successful load, a module handle is placed in *mhandle,
+ *      and zero is returned.  On error, the number of errors detected is
+ *      returned.  Individual errors are reported during the load process
+ *      using syms->error_report().
+ ********************************************************************** */
+int
+dynamic_open_module(struct dynamic_loader_stream *module,
+                   struct dynamic_loader_sym *syms,
+                   struct dynamic_loader_allocate *alloc,
+                   struct dynamic_loader_initialize *init,
+                   unsigned options, void **mhandle)
+{
+       register unsigned *dp, sz;
+       struct dload_state dl_state;    /* internal state for this call */
+
+       /* blast our internal state */
+       dp = (unsigned *)&dl_state;
+       for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1)
+               *dp++ = 0;
+
+       /* Enable _only_ BSS initialization if enabled by user */
+       if ((options & DLOAD_INITBSS) == DLOAD_INITBSS)
+               dl_state.myoptions = DLOAD_INITBSS;
+
+       /* Check that mandatory arguments are present */
+       if (!module || !syms) {
+               dload_error(&dl_state, "Required parameter is NULL");
+       } else {
+               dl_state.strm = module;
+               dl_state.mysym = syms;
+               dload_headers(&dl_state);
+               if (!dl_state.dload_errcount)
+                       dload_strings(&dl_state, false);
+               if (!dl_state.dload_errcount)
+                       dload_sections(&dl_state);
+
+               if (init && !dl_state.dload_errcount) {
+                       if (init->connect(init)) {
+                               dl_state.myio = init;
+                               dl_state.myalloc = alloc;
+                               /* do now, before reducing symbols */
+                               allocate_sections(&dl_state);
+                       } else
+                               dload_error(&dl_state, iconnect);
+               }
+
+               if (!dl_state.dload_errcount) {
+                       /* fix up entry point address */
+                       unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1;
+                       if (sref < dl_state.allocated_secn_count)
+                               dl_state.dfile_hdr.df_entrypt +=
+                                   dl_state.ldr_sections[sref].run_addr;
+
+                       dload_symbols(&dl_state);
+               }
+
+               init_module_handle(&dl_state);
+
+               /* dl_state.myio is either 0 or init at this point. */
+               if (dl_state.myio) {
+                       if ((!dl_state.dload_errcount) &&
+                           (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) &&
+                           (!init->execute(init,
+                                           dl_state.dfile_hdr.df_entrypt)))
+                               dload_error(&dl_state, "Init->Execute Failed");
+                       init->release(init);
+               }
+
+               symbol_table_free(&dl_state);
+               section_table_free(&dl_state);
+               string_table_free(&dl_state);
+
+               if (dl_state.dload_errcount) {
+                       dynamic_unload_module(dl_state.myhandle, syms, alloc,
+                                             init);
+                       dl_state.myhandle = NULL;
+               }
+       }
+
+       if (mhandle)
+               *mhandle = dl_state.myhandle;   /* give back the handle */
+
+       return dl_state.dload_errcount;
+}                              /* DLOAD_File */
+
+/*************************************************************************
+ * Procedure dload_headers
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Loads the DOFF header and verify record.  Deals with any byte-order
+ * issues and checks them for validity.
+ *********************************************************************** */
+#define COMBINED_HEADER_SIZE (sizeof(struct doff_filehdr_t)+ \
+                            sizeof(struct doff_verify_rec_t))
+
+void dload_headers(struct dload_state *dlthis)
+{
+       u32 map;
+
+       /* Read the header and the verify record as one.  If we don't get it
+          all, we're done */
+       if (dlthis->strm->read_buffer(dlthis->strm, &dlthis->dfile_hdr,
+                                     COMBINED_HEADER_SIZE) !=
+           COMBINED_HEADER_SIZE) {
+               DL_ERROR(readstrm, "File Headers");
+               return;
+       }
+       /*
+        * Verify that we have the byte order of the file correct.
+        * If not, must fix it before we can continue
+        */
+       map = REORDER_MAP(dlthis->dfile_hdr.df_byte_reshuffle);
+       if (map != REORDER_MAP(BYTE_RESHUFFLE_VALUE)) {
+               /* input is either byte-shuffled or bad */
+               if ((map & 0xFCFCFCFC) == 0) {  /* no obviously bogus bits */
+                       dload_reorder(&dlthis->dfile_hdr, COMBINED_HEADER_SIZE,
+                                     map);
+               }
+               if (dlthis->dfile_hdr.df_byte_reshuffle !=
+                   BYTE_RESHUFFLE_VALUE) {
+                       /* didn't fix the problem, the byte swap map is bad */
+                       dload_error(dlthis,
+                                   "Bad byte swap map " FMT_UI32 " in header",
+                                   dlthis->dfile_hdr.df_byte_reshuffle);
+                       return;
+               }
+               dlthis->reorder_map = map;      /* keep map for future use */
+       }
+
+       /*
+        * Verify checksum of header and verify record
+        */
+       if (~dload_checksum(&dlthis->dfile_hdr,
+                           sizeof(struct doff_filehdr_t)) ||
+           ~dload_checksum(&dlthis->verify,
+                           sizeof(struct doff_verify_rec_t))) {
+               DL_ERROR(err_checksum, "header or verify record");
+               return;
+       }
+#if HOST_ENDIANNESS
+       dlthis->dfile_hdr.df_byte_reshuffle = map;      /* put back for later */
+#endif
+
+       /* Check for valid target ID */
+       if ((dlthis->dfile_hdr.df_target_id != TARGET_ID) &&
+           -(dlthis->dfile_hdr.df_target_id != TMS470_ID)) {
+               dload_error(dlthis, "Bad target ID 0x%x and TARGET_ID 0x%x",
+                           dlthis->dfile_hdr.df_target_id, TARGET_ID);
+               return;
+       }
+       /* Check for valid file format */
+       if ((dlthis->dfile_hdr.df_doff_version != DOFF0)) {
+               dload_error(dlthis, "Bad DOFF version 0x%x",
+                           dlthis->dfile_hdr.df_doff_version);
+               return;
+       }
+
+       /*
+        * Apply reasonableness checks to count fields
+        */
+       if (dlthis->dfile_hdr.df_strtab_size > MAX_REASONABLE_STRINGTAB) {
+               dload_error(dlthis, "Excessive string table size " FMT_UI32,
+                           dlthis->dfile_hdr.df_strtab_size);
+               return;
+       }
+       if (dlthis->dfile_hdr.df_no_scns > MAX_REASONABLE_SECTIONS) {
+               dload_error(dlthis, "Excessive section count 0x%x",
+                           dlthis->dfile_hdr.df_no_scns);
+               return;
+       }
+#ifndef TARGET_ENDIANNESS
+       /*
+        * Check that endianness does not disagree with explicit specification
+        */
+       if ((dlthis->dfile_hdr.df_flags >> ALIGN_COFF_ENDIANNESS) &
+           dlthis->myoptions & ENDIANNESS_MASK) {
+               dload_error(dlthis,
+                           "Input endianness disagrees with specified option");
+               return;
+       }
+       dlthis->big_e_target = dlthis->dfile_hdr.df_flags & DF_BIG;
+#endif
+
+}                              /* dload_headers */
+
+/*     COFF Section Processing
+ *
+ *     COFF sections are read in and retained intact.  Each record is embedded
+ *     in a new structure that records the updated load and
+ *     run addresses of the section */
+
+static const char secn_errid[] = { "section" };
+
+/*************************************************************************
+ * Procedure dload_sections
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Loads the section records into an internal table.
+ *********************************************************************** */
+void dload_sections(struct dload_state *dlthis)
+{
+       s16 siz;
+       struct doff_scnhdr_t *shp;
+       unsigned nsecs = dlthis->dfile_hdr.df_no_scns;
+
+       /* allocate space for the DOFF section records */
+       siz = nsecs * sizeof(struct doff_scnhdr_t);
+       shp =
+           (struct doff_scnhdr_t *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                                                 siz);
+       if (!shp) {             /* not enough storage */
+               DL_ERROR(err_alloc, siz);
+               return;
+       }
+       dlthis->sect_hdrs = shp;
+
+       /* read in the section records */
+       if (dlthis->strm->read_buffer(dlthis->strm, shp, siz) != siz) {
+               DL_ERROR(readstrm, secn_errid);
+               return;
+       }
+
+       /* if we need to fix up byte order, do it now */
+       if (dlthis->reorder_map)
+               dload_reorder(shp, siz, dlthis->reorder_map);
+
+       /* check for validity */
+       if (~dload_checksum(dlthis->sect_hdrs, siz) !=
+           dlthis->verify.dv_scn_rec_checksum) {
+               DL_ERROR(err_checksum, secn_errid);
+               return;
+       }
+
+}                              /* dload_sections */
+
+/*****************************************************************************
+ * Procedure allocate_sections
+ *
+ * Parameters:
+ *     alloc   target memory allocator class
+ *
+ * Effect:
+ *     Assigns new (target) addresses for sections
+ **************************************************************************** */
+static void allocate_sections(struct dload_state *dlthis)
+{
+       u16 curr_sect, nsecs, siz;
+       struct doff_scnhdr_t *shp;
+       struct ldr_section_info *asecs;
+       struct my_handle *hndl;
+       nsecs = dlthis->dfile_hdr.df_no_scns;
+       if (!nsecs)
+               return;
+       if ((dlthis->myalloc == NULL) &&
+           (dlthis->dfile_hdr.df_target_scns > 0)) {
+               DL_ERROR("Arg 3 (alloc) required but NULL", 0);
+               return;
+       }
+       /*
+        * allocate space for the module handle, which we will keep for unload
+        * purposes include an additional section store for an auto-generated
+        * trampoline section in case we need it.
+        */
+       siz = (dlthis->dfile_hdr.df_target_scns + 1) *
+           sizeof(struct ldr_section_info) + MY_HANDLE_SIZE;
+
+       hndl =
+           (struct my_handle *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                                             siz);
+       if (!hndl) {            /* not enough storage */
+               DL_ERROR(err_alloc, siz);
+               return;
+       }
+       /* initialize the handle header */
+       hndl->dm.hnext = hndl->dm.hprev = hndl; /* circular list */
+       hndl->dm.hroot = NULL;
+       hndl->dm.dbthis = 0;
+       dlthis->myhandle = hndl;        /* save away for return */
+       /* pointer to the section list of allocated sections */
+       dlthis->ldr_sections = asecs = hndl->secns;
+       /* * Insert names into all sections, make copies of
+          the sections we allocate */
+       shp = dlthis->sect_hdrs;
+       for (curr_sect = 0; curr_sect < nsecs; curr_sect++) {
+               u32 soffset = shp->ds_offset;
+#if BITS_PER_AU <= BITS_PER_BYTE
+               /* attempt to insert the name of this section */
+               if (soffset < dlthis->dfile_hdr.df_strtab_size)
+                       ((struct ldr_section_info *)shp)->name =
+                               dlthis->str_head + soffset;
+               else {
+                       dload_error(dlthis, "Bad name offset in section %d",
+                                   curr_sect);
+                       ((struct ldr_section_info *)shp)->name = NULL;
+               }
+#endif
+               /* allocate target storage for sections that require it */
+               if (ds_needs_allocation(shp)) {
+                       *asecs = *(struct ldr_section_info *)shp;
+                       asecs->context = 0;     /* zero the context field */
+#if BITS_PER_AU > BITS_PER_BYTE
+                       asecs->name = unpack_name(dlthis, soffset);
+                       dlthis->debug_string_size = soffset + dlthis->temp_len;
+#else
+                       dlthis->debug_string_size = soffset;
+#endif
+                       if (dlthis->myalloc != NULL) {
+                               if (!dlthis->myalloc->
+                                   dload_allocate(dlthis->myalloc, asecs,
+                                                  ds_alignment(asecs->type))) {
+                                       dload_error(dlthis, tgtalloc,
+                                                   asecs->name, asecs->size);
+                                       return;
+                               }
+                       }
+                       /* keep address deltas in original section table */
+                       shp->ds_vaddr = asecs->load_addr - shp->ds_vaddr;
+                       shp->ds_paddr = asecs->run_addr - shp->ds_paddr;
+                       dlthis->allocated_secn_count += 1;
+               }               /* allocate target storage */
+               shp += 1;
+               asecs += 1;
+       }
+#if BITS_PER_AU <= BITS_PER_BYTE
+       dlthis->debug_string_size +=
+           strlen(dlthis->str_head + dlthis->debug_string_size) + 1;
+#endif
+}                              /* allocate sections */
+
+/*************************************************************************
+ * Procedure section_table_free
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Frees any state used by the symbol table.
+ *
+ * WARNING:
+ *     This routine is not allowed to declare errors!
+ *********************************************************************** */
+static void section_table_free(struct dload_state *dlthis)
+{
+       struct doff_scnhdr_t *shp;
+
+       shp = dlthis->sect_hdrs;
+       if (shp)
+               dlthis->mysym->dload_deallocate(dlthis->mysym, shp);
+
+}                              /* section_table_free */
+
+/*************************************************************************
+ * Procedure dload_strings
+ *
+ * Parameters:
+ *  sec_names_only   If true only read in the "section names"
+ *                  portion of the string table
+ *
+ * Effect:
+ *     Loads the DOFF string table into memory. DOFF keeps all strings in a
+ * big unsorted array.  We just read that array into memory in bulk.
+ *********************************************************************** */
+static const char stringtbl[] = { "string table" };
+
+void dload_strings(struct dload_state *dlthis, bool sec_names_only)
+{
+       u32 ssiz;
+       char *strbuf;
+
+       if (sec_names_only) {
+               ssiz = BYTE_TO_HOST(DOFF_ALIGN
+                                   (dlthis->dfile_hdr.df_scn_name_size));
+       } else {
+               ssiz = BYTE_TO_HOST(DOFF_ALIGN
+                                   (dlthis->dfile_hdr.df_strtab_size));
+       }
+       if (ssiz == 0)
+               return;
+
+       /* get some memory for the string table */
+#if BITS_PER_AU > BITS_PER_BYTE
+       strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz +
+                                                      dlthis->dfile_hdr.
+                                                      df_max_str_len);
+#else
+       strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz);
+#endif
+       if (strbuf == NULL) {
+               DL_ERROR(err_alloc, ssiz);
+               return;
+       }
+       dlthis->str_head = strbuf;
+#if BITS_PER_AU > BITS_PER_BYTE
+       dlthis->str_temp = strbuf + ssiz;
+#endif
+       /* read in the strings and verify them */
+       if ((unsigned)(dlthis->strm->read_buffer(dlthis->strm, strbuf,
+                                                ssiz)) != ssiz) {
+               DL_ERROR(readstrm, stringtbl);
+       }
+       /* if we need to fix up byte order, do it now */
+#ifndef _BIG_ENDIAN
+       if (dlthis->reorder_map)
+               dload_reorder(strbuf, ssiz, dlthis->reorder_map);
+
+       if ((!sec_names_only) && (~dload_checksum(strbuf, ssiz) !=
+                                 dlthis->verify.dv_str_tab_checksum)) {
+               DL_ERROR(err_checksum, stringtbl);
+       }
+#else
+       if (dlthis->dfile_hdr.df_byte_reshuffle !=
+           HOST_BYTE_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) {
+               /* put strings in big-endian order, not in PC order */
+               dload_reorder(strbuf, ssiz,
+                             HOST_BYTE_ORDER(dlthis->
+                                             dfile_hdr.df_byte_reshuffle));
+       }
+       if ((!sec_names_only) && (~dload_reverse_checksum(strbuf, ssiz) !=
+                                 dlthis->verify.dv_str_tab_checksum)) {
+               DL_ERROR(err_checksum, stringtbl);
+       }
+#endif
+}                              /* dload_strings */
+
+/*************************************************************************
+ * Procedure string_table_free
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Frees any state used by the string table.
+ *
+ * WARNING:
+ *     This routine is not allowed to declare errors!
+ ************************************************************************ */
+static void string_table_free(struct dload_state *dlthis)
+{
+       if (dlthis->str_head)
+               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               dlthis->str_head);
+
+}                              /* string_table_free */
+
+/*
+ * Symbol Table Maintenance Functions
+ *
+ * COFF symbols are read by dload_symbols(), which is called after
+ * sections have been allocated.  Symbols which might be used in
+ * relocation (ie, not debug info) are retained in an internal temporary
+ * compressed table (type local_symbol). A particular symbol is recovered
+ * by index by calling dload_find_symbol().  dload_find_symbol
+ * reconstructs a more explicit representation (type SLOTVEC) which is
+ * used by reloc.c
+ */
+/* real size of debug header */
+#define DBG_HDR_SIZE (sizeof(struct dll_module) - sizeof(struct dll_sect))
+
+static const char sym_errid[] = { "symbol" };
+
+/**************************************************************************
+ * Procedure dload_symbols
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Reads in symbols and retains ones that might be needed for relocation
+ * purposes.
+ *********************************************************************** */
+/* size of symbol buffer no bigger than target data buffer, to limit stack
+ * usage */
+#define MY_SYM_BUF_SIZ (BYTE_TO_HOST(IMAGE_PACKET_SIZE)/\
+                       sizeof(struct doff_syment_t))
+
+static void dload_symbols(struct dload_state *dlthis)
+{
+       u32 sym_count, siz, dsiz, symbols_left;
+       u32 checks;
+       struct local_symbol *sp;
+       struct dynload_symbol *symp;
+       struct dynload_symbol *newsym;
+
+       sym_count = dlthis->dfile_hdr.df_no_syms;
+       if (sym_count == 0)
+               return;
+
+       /*
+        * We keep a local symbol table for all of the symbols in the input.
+        * This table contains only section & value info, as we do not have
+        * to do any name processing for locals.  We reuse this storage
+        * as a temporary for .dllview record construction.
+        * Allocate storage for the whole table.  Add 1 to the section count
+        * in case a trampoline section is auto-generated as well as the
+        * size of the trampoline section name so DLLView doens't get lost.
+        */
+
+       siz = sym_count * sizeof(struct local_symbol);
+       dsiz = DBG_HDR_SIZE +
+           (sizeof(struct dll_sect) * dlthis->allocated_secn_count) +
+           BYTE_TO_HOST_ROUND(dlthis->debug_string_size + 1);
+       if (dsiz > siz)
+               siz = dsiz;     /* larger of symbols and .dllview temp */
+       sp = (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                                                 siz);
+       if (!sp) {
+               DL_ERROR(err_alloc, siz);
+               return;
+       }
+       dlthis->local_symtab = sp;
+       /* Read the symbols in the input, store them in the table, and post any
+        * globals to the global symbol table.  In the process, externals
+        become defined from the global symbol table */
+       checks = dlthis->verify.dv_sym_tab_checksum;
+       symbols_left = sym_count;
+       do {                    /* read all symbols */
+               char *sname;
+               u32 val;
+               s32 delta;
+               struct doff_syment_t *input_sym;
+               unsigned syms_in_buf;
+               struct doff_syment_t my_sym_buf[MY_SYM_BUF_SIZ];
+               input_sym = my_sym_buf;
+               syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ?
+                   MY_SYM_BUF_SIZ : symbols_left;
+               siz = syms_in_buf * sizeof(struct doff_syment_t);
+               if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) !=
+                   siz) {
+                       DL_ERROR(readstrm, sym_errid);
+                       return;
+               }
+               if (dlthis->reorder_map)
+                       dload_reorder(input_sym, siz, dlthis->reorder_map);
+
+               checks += dload_checksum(input_sym, siz);
+               do {            /* process symbols in buffer */
+                       symbols_left -= 1;
+                       /* attempt to derive the name of this symbol */
+                       sname = NULL;
+                       if (input_sym->dn_offset > 0) {
+#if BITS_PER_AU <= BITS_PER_BYTE
+                               if ((u32) input_sym->dn_offset <
+                                   dlthis->dfile_hdr.df_strtab_size)
+                                       sname = dlthis->str_head +
+                                           BYTE_TO_HOST(input_sym->dn_offset);
+                               else
+                                       dload_error(dlthis,
+                                                   "Bad name offset in symbol "
+                                                   " %d", symbols_left);
+#else
+                               sname = unpack_name(dlthis,
+                                                   input_sym->dn_offset);
+#endif
+                       }
+                       val = input_sym->dn_value;
+                       delta = 0;
+                       sp->sclass = input_sym->dn_sclass;
+                       sp->secnn = input_sym->dn_scnum;
+                       /* if this is an undefined symbol,
+                        * define it (or fail) now */
+                       if (sp->secnn == DN_UNDEF) {
+                               /* pointless for static undefined */
+                               if (input_sym->dn_sclass != DN_EXT)
+                                       goto loop_cont;
+
+                               /* try to define symbol from previously
+                                * loaded images */
+                               symp = dlthis->mysym->find_matching_symbol
+                                   (dlthis->mysym, sname);
+                               if (!symp) {
+                                       DL_ERROR
+                                           ("Undefined external symbol %s",
+                                            sname);
+                                       goto loop_cont;
+                               }
+                               val = delta = symp->value;
+#ifdef ENABLE_TRAMP_DEBUG
+                               dload_syms_error(dlthis->mysym,
+                                                "===> ext sym [%s] at %x",
+                                                sname, val);
+#endif
+
+                               goto loop_cont;
+                       }
+                       /* symbol defined by this module */
+                       if (sp->secnn > 0) {
+                               /* symbol references a section */
+                               if ((unsigned)sp->secnn <=
+                                   dlthis->allocated_secn_count) {
+                                       /* section was allocated */
+                                       struct doff_scnhdr_t *srefp =
+                                           &dlthis->sect_hdrs[sp->secnn - 1];
+
+                                       if (input_sym->dn_sclass ==
+                                           DN_STATLAB ||
+                                           input_sym->dn_sclass == DN_EXTLAB) {
+                                               /* load */
+                                               delta = srefp->ds_vaddr;
+                                       } else {
+                                               /* run */
+                                               delta = srefp->ds_paddr;
+                                       }
+                                       val += delta;
+                               }
+                               goto loop_itr;
+                       }
+                       /* This symbol is an absolute symbol */
+                       if (sp->secnn == DN_ABS && ((sp->sclass == DN_EXT) ||
+                                                   (sp->sclass ==
+                                                    DN_EXTLAB))) {
+                               symp =
+                                   dlthis->mysym->find_matching_symbol(dlthis->
+                                                                       mysym,
+                                                                       sname);
+                               if (!symp)
+                                       goto loop_itr;
+                               /* This absolute symbol is already defined. */
+                               if (symp->value == input_sym->dn_value) {
+                                       /* If symbol values are equal, continue
+                                        * but don't add to the global symbol
+                                        * table */
+                                       sp->value = val;
+                                       sp->delta = delta;
+                                       sp += 1;
+                                       input_sym += 1;
+                                       continue;
+                               } else {
+                                       /* If symbol values are not equal,
+                                        * return with redefinition error */
+                                       DL_ERROR("Absolute symbol %s is "
+                                                "defined multiple times with "
+                                                "different values", sname);
+                                       return;
+                               }
+                       }
+loop_itr:
+                       /* if this is a global symbol, post it to the
+                        * global table */
+                       if (input_sym->dn_sclass == DN_EXT ||
+                           input_sym->dn_sclass == DN_EXTLAB) {
+                               /* Keep this global symbol for subsequent
+                                * modules. Don't complain on error, to allow
+                                * symbol API to suppress global symbols */
+                               if (!sname)
+                                       goto loop_cont;
+
+                               newsym = dlthis->mysym->add_to_symbol_table
+                                   (dlthis->mysym, sname,
+                                    (unsigned)dlthis->myhandle);
+                               if (newsym)
+                                       newsym->value = val;
+
+                       }       /* global */
+loop_cont:
+                       sp->value = val;
+                       sp->delta = delta;
+                       sp += 1;
+                       input_sym += 1;
+               } while ((syms_in_buf -= 1) > 0);       /* process sym in buf */
+       } while (symbols_left > 0);     /* read all symbols */
+       if (~checks)
+               dload_error(dlthis, "Checksum of symbols failed");
+
+}                              /* dload_symbols */
+
+/*****************************************************************************
+ * Procedure symbol_table_free
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Frees any state used by the symbol table.
+ *
+ * WARNING:
+ *     This routine is not allowed to declare errors!
+ **************************************************************************** */
+static void symbol_table_free(struct dload_state *dlthis)
+{
+       if (dlthis->local_symtab) {
+               if (dlthis->dload_errcount) {   /* blow off our symbols */
+                       dlthis->mysym->purge_symbol_table(dlthis->mysym,
+                                                         (unsigned)
+                                                         dlthis->myhandle);
+               }
+               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               dlthis->local_symtab);
+       }
+}                              /* symbol_table_free */
+
+/* .cinit Processing
+ *
+ * The dynamic loader does .cinit interpretation.  cload_cinit()
+ * acts as a special write-to-target function, in that it takes relocated
+ * data from the normal data flow, and interprets it as .cinit actions.
+ * Because the normal data flow does not  necessarily process the whole
+ * .cinit section in one buffer, cload_cinit() must be prepared to
+ * interpret the data piecemeal.  A state machine is used for this
+ * purpose.
+ */
+
+/* The following are only for use by reloc.c and things it calls */
+static const struct ldr_section_info cinit_info_init = { cinitname, 0, 0,
+       (ldr_addr)-1, 0, DLOAD_BSS, 0
+};
+
+/*************************************************************************
+ * Procedure cload_cinit
+ *
+ * Parameters:
+ *     ipacket         Pointer to data packet to be loaded
+ *
+ * Effect:
+ *     Interprets the data in the buffer as .cinit data, and performs the
+ * appropriate initializations.
+ *********************************************************************** */
+static void cload_cinit(struct dload_state *dlthis,
+                       struct image_packet_t *ipacket)
+{
+#if TDATA_TO_HOST(CINIT_COUNT)*BITS_PER_AU > 16
+       s32 init_count, left;
+#else
+       s16 init_count, left;
+#endif
+       unsigned char *pktp = ipacket->img_data;
+       unsigned char *pktend = pktp + BYTE_TO_HOST_ROUND(ipacket->packet_size);
+       int temp;
+       ldr_addr atmp;
+       struct ldr_section_info cinit_info;
+
+       /*  PROCESS ALL THE INITIALIZATION RECORDS THE BUFFER. */
+       while (true) {
+               left = pktend - pktp;
+               switch (dlthis->cinit_state) {
+               case CI_COUNT:  /* count field */
+                       if (left < TDATA_TO_HOST(CINIT_COUNT))
+                               goto loopexit;
+                       temp = dload_unpack(dlthis, (tgt_au_t *) pktp,
+                                           CINIT_COUNT * TDATA_AU_BITS, 0,
+                                           ROP_SGN);
+                       pktp += TDATA_TO_HOST(CINIT_COUNT);
+                       /* negative signifies BSS table, zero means done */
+                       if (temp <= 0) {
+                               dlthis->cinit_state = CI_DONE;
+                               break;
+                       }
+                       dlthis->cinit_count = temp;
+                       dlthis->cinit_state = CI_ADDRESS;
+                       break;
+#if CINIT_ALIGN < CINIT_ADDRESS
+               case CI_PARTADDRESS:
+                       pktp -= TDATA_TO_HOST(CINIT_ALIGN);
+                       /* back up pointer into space courtesy of caller */
+                       *(uint16_t *) pktp = dlthis->cinit_addr;
+                       /* stuff in saved bits  !! FALL THRU !! */
+#endif
+               case CI_ADDRESS:        /* Address field for a copy packet */
+                       if (left < TDATA_TO_HOST(CINIT_ADDRESS)) {
+#if CINIT_ALIGN < CINIT_ADDRESS
+                               if (left == TDATA_TO_HOST(CINIT_ALIGN)) {
+                                       /* address broken into halves */
+                                       dlthis->cinit_addr = *(uint16_t *) pktp;
+                                       /* remember 1st half */
+                                       dlthis->cinit_state = CI_PARTADDRESS;
+                                       left = 0;
+                               }
+#endif
+                               goto loopexit;
+                       }
+                       atmp = dload_unpack(dlthis, (tgt_au_t *) pktp,
+                                           CINIT_ADDRESS * TDATA_AU_BITS, 0,
+                                           ROP_UNS);
+                       pktp += TDATA_TO_HOST(CINIT_ADDRESS);
+#if CINIT_PAGE_BITS > 0
+                       dlthis->cinit_page = atmp &
+                           ((1 << CINIT_PAGE_BITS) - 1);
+                       atmp >>= CINIT_PAGE_BITS;
+#else
+                       dlthis->cinit_page = CINIT_DEFAULT_PAGE;
+#endif
+                       dlthis->cinit_addr = atmp;
+                       dlthis->cinit_state = CI_COPY;
+                       break;
+               case CI_COPY:   /* copy bits to the target */
+                       init_count = HOST_TO_TDATA(left);
+                       if (init_count > dlthis->cinit_count)
+                               init_count = dlthis->cinit_count;
+                       if (init_count == 0)
+                               goto loopexit;  /* get more bits */
+                       cinit_info = cinit_info_init;
+                       cinit_info.page = dlthis->cinit_page;
+                       if (!dlthis->myio->writemem(dlthis->myio, pktp,
+                                                  TDATA_TO_TADDR
+                                                  (dlthis->cinit_addr),
+                                                  &cinit_info,
+                                                  TDATA_TO_HOST(init_count))) {
+                               dload_error(dlthis, initfail, "write",
+                                           dlthis->cinit_addr);
+                       }
+                       dlthis->cinit_count -= init_count;
+                       if (dlthis->cinit_count <= 0) {
+                               dlthis->cinit_state = CI_COUNT;
+                               init_count = (init_count + CINIT_ALIGN - 1) &
+                                   -CINIT_ALIGN;
+                               /* align to next init */
+                       }
+                       pktp += TDATA_TO_HOST(init_count);
+                       dlthis->cinit_addr += init_count;
+                       break;
+               case CI_DONE:   /* no more .cinit to do */
+                       return;
+               }               /* switch (cinit_state) */
+       }                       /* while */
+
+loopexit:
+       if (left > 0) {
+               dload_error(dlthis, "%d bytes left over in cinit packet", left);
+               dlthis->cinit_state = CI_DONE;  /* left over bytes are bad */
+       }
+}                              /* cload_cinit */
+
+/*     Functions to interface to reloc.c
+ *
+ * reloc.c is the relocation module borrowed from the linker, with
+ * minimal (we hope) changes for our purposes.  cload_sect_data() invokes
+ * this module on a section to relocate and load the image data for that
+ * section.  The actual read and write actions are supplied by the global
+ * routines below.
+ */
+
+/************************************************************************
+ * Procedure relocate_packet
+ *
+ * Parameters:
+ *     ipacket         Pointer to an image packet to relocate
+ *
+ * Effect:
+ *     Performs the required relocations on the packet.  Returns a checksum
+ * of the relocation operations.
+ *********************************************************************** */
+#define MY_RELOC_BUF_SIZ 8
+/* careful! exists at the same time as the image buffer */
+static int relocate_packet(struct dload_state *dlthis,
+                          struct image_packet_t *ipacket,
+                          u32 *checks, bool *tramps_generated)
+{
+       u32 rnum;
+       *tramps_generated = false;
+
+       rnum = ipacket->num_relocs;
+       do {                    /* all relocs */
+               unsigned rinbuf;
+               int siz;
+               struct reloc_record_t *rp, rrec[MY_RELOC_BUF_SIZ];
+               rp = rrec;
+               rinbuf = rnum > MY_RELOC_BUF_SIZ ? MY_RELOC_BUF_SIZ : rnum;
+               siz = rinbuf * sizeof(struct reloc_record_t);
+               if (dlthis->strm->read_buffer(dlthis->strm, rp, siz) != siz) {
+                       DL_ERROR(readstrm, "relocation");
+                       return 0;
+               }
+               /* reorder the bytes if need be */
+               if (dlthis->reorder_map)
+                       dload_reorder(rp, siz, dlthis->reorder_map);
+
+               *checks += dload_checksum(rp, siz);
+               do {
+                       /* perform the relocation operation */
+                       dload_relocate(dlthis, (tgt_au_t *) ipacket->img_data,
+                                      rp, tramps_generated, false);
+                       rp += 1;
+                       rnum -= 1;
+               } while ((rinbuf -= 1) > 0);
+       } while (rnum > 0);     /* all relocs */
+       /* If trampoline(s) were generated, we need to do an update of the
+        * trampoline copy of the packet since a 2nd phase relo will be done
+        * later. */
+       if (*tramps_generated == true) {
+               dload_tramp_pkt_udpate(dlthis,
+                                      (dlthis->image_secn -
+                                       dlthis->ldr_sections),
+                                      dlthis->image_offset, ipacket);
+       }
+
+       return 1;
+}                              /* dload_read_reloc */
+
+#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32))
+
+/* VERY dangerous */
+static const char imagepak[] = { "image packet" };
+
+/*************************************************************************
+ * Procedure dload_data
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Read image data from input file, relocate it, and download it to the
+ *     target.
+ *********************************************************************** */
+static void dload_data(struct dload_state *dlthis)
+{
+       u16 curr_sect;
+       struct doff_scnhdr_t *sptr = dlthis->sect_hdrs;
+       struct ldr_section_info *lptr = dlthis->ldr_sections;
+#ifdef OPT_ZERO_COPY_LOADER
+       bool zero_copy = false;
+#endif
+       u8 *dest;
+
+       struct {
+               struct image_packet_t ipacket;
+               u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)];
+       } ibuf;
+
+       /* Indicates whether CINIT processing has occurred */
+       bool cinit_processed = false;
+
+       /* Loop through the sections and load them one at a time.
+        */
+       for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns;
+            curr_sect += 1) {
+               if (ds_needs_download(sptr)) {
+                       s32 nip;
+                       ldr_addr image_offset = 0;
+                       /* set relocation info for this section */
+                       if (curr_sect < dlthis->allocated_secn_count)
+                               dlthis->delta_runaddr = sptr->ds_paddr;
+                       else {
+                               lptr = (struct ldr_section_info *)sptr;
+                               dlthis->delta_runaddr = 0;
+                       }
+                       dlthis->image_secn = lptr;
+#if BITS_PER_AU > BITS_PER_BYTE
+                       lptr->name = unpack_name(dlthis, sptr->ds_offset);
+#endif
+                       nip = sptr->ds_nipacks;
+                       while ((nip -= 1) >= 0) {       /* process packets */
+
+                               s32 ipsize;
+                               u32 checks;
+                               bool tramp_generated = false;
+
+                               /* get the fixed header bits */
+                               if (dlthis->strm->read_buffer(dlthis->strm,
+                                                             &ibuf.ipacket,
+                                                             IPH_SIZE) !=
+                                   IPH_SIZE) {
+                                       DL_ERROR(readstrm, imagepak);
+                                       return;
+                               }
+                               /* reorder the header if need be */
+                               if (dlthis->reorder_map) {
+                                       dload_reorder(&ibuf.ipacket, IPH_SIZE,
+                                                     dlthis->reorder_map);
+                               }
+                               /* now read the rest of the packet */
+                               ipsize =
+                                   BYTE_TO_HOST(DOFF_ALIGN
+                                                (ibuf.ipacket.packet_size));
+                               if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
+                                       DL_ERROR("Bad image packet size %d",
+                                                ipsize);
+                                       return;
+                               }
+                               dest = ibuf.bufr;
+#ifdef OPT_ZERO_COPY_LOADER
+                               zero_copy = false;
+                               if (!dload_check_type(sptr, DLOAD_CINIT) {
+                                       dlthis->myio->writemem(dlthis->myio,
+                                                              &dest,
+                                                              lptr->load_addr +
+                                                              image_offset,
+                                                              lptr, 0);
+                                       zero_copy = (dest != ibuf.bufr);
+                               }
+#endif
+                               /* End of determination */
+
+                               if (dlthis->strm->read_buffer(dlthis->strm,
+                                                             ibuf.bufr,
+                                                             ipsize) !=
+                                   ipsize) {
+                                       DL_ERROR(readstrm, imagepak);
+                                       return;
+                               }
+                               ibuf.ipacket.img_data = dest;
+
+                               /* reorder the bytes if need be */
+#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
+                               if (dlthis->reorder_map) {
+                                       dload_reorder(dest, ipsize,
+                                                     dlthis->reorder_map);
+                               }
+                               checks = dload_checksum(dest, ipsize);
+#else
+                               if (dlthis->dfile_hdr.df_byte_reshuffle !=
+                                   TARGET_ORDER(REORDER_MAP
+                                                (BYTE_RESHUFFLE_VALUE))) {
+                                       /* put image bytes in big-endian order,
+                                        * not PC order */
+                                       dload_reorder(dest, ipsize,
+                                                     TARGET_ORDER
+                                                     (dlthis->dfile_hdr.
+                                                      df_byte_reshuffle));
+                               }
+#if TARGET_AU_BITS > 8
+                               checks = dload_reverse_checksum16(dest, ipsize);
+#else
+                               checks = dload_reverse_checksum(dest, ipsize);
+#endif
+#endif
+
+                               checks += dload_checksum(&ibuf.ipacket,
+                                                        IPH_SIZE);
+                               /* relocate the image bits as needed */
+                               if (ibuf.ipacket.num_relocs) {
+                                       dlthis->image_offset = image_offset;
+                                       if (!relocate_packet(dlthis,
+                                                            &ibuf.ipacket,
+                                                            &checks,
+                                                            &tramp_generated))
+                                               return; /* serious error */
+                               }
+                               if (~checks)
+                                       DL_ERROR(err_checksum, imagepak);
+                               /* Only write the result to the target if no
+                                * trampoline was generated.  Otherwise it
+                                *will be done during trampoline finalize. */
+
+                               if (tramp_generated == false) {
+
+                                       /* stuff the result into target
+                                        * memory */
+                                       if (dload_check_type(sptr,
+                                               DLOAD_CINIT)) {
+                                               cload_cinit(dlthis,
+                                                           &ibuf.ipacket);
+                                               cinit_processed = true;
+                                       } else {
+#ifdef OPT_ZERO_COPY_LOADER
+                                               if (!zero_copy) {
+#endif
+                                                       /* FIXME */
+                                                       if (!dlthis->myio->
+                                                           writemem(dlthis->
+                                                               myio,
+                                                               ibuf.bufr,
+                                                               lptr->
+                                                               load_addr +
+                                                               image_offset,
+                                                               lptr,
+                                                               BYTE_TO_HOST
+                                                               (ibuf.
+                                                               ipacket.
+                                                               packet_size))) {
+                                                               DL_ERROR
+                                                                 ("Write to "
+                                                                 FMT_UI32
+                                                                 " failed",
+                                                                 lptr->
+                                                                 load_addr +
+                                                                 image_offset);
+                                                       }
+#ifdef OPT_ZERO_COPY_LOADER
+                                               }
+#endif
+                                       }
+                               }
+                               image_offset +=
+                                   BYTE_TO_TADDR(ibuf.ipacket.packet_size);
+                       }       /* process packets */
+                       /* if this is a BSS section, we may want to fill it */
+                       if (!dload_check_type(sptr, DLOAD_BSS))
+                               goto loop_cont;
+
+                       if (!(dlthis->myoptions & DLOAD_INITBSS))
+                               goto loop_cont;
+
+                       if (cinit_processed) {
+                               /* Don't clear BSS after load-time
+                                * initialization */
+                               DL_ERROR
+                                   ("Zero-initialization at " FMT_UI32
+                                    " after " "load-time initialization!",
+                                    lptr->load_addr);
+                               goto loop_cont;
+                       }
+                       /* fill the .bss area */
+                       dlthis->myio->fillmem(dlthis->myio,
+                                             TADDR_TO_HOST(lptr->load_addr),
+                                             lptr, TADDR_TO_HOST(lptr->size),
+                                             DLOAD_FILL_BSS);
+                       goto loop_cont;
+               }
+               /* if DS_DOWNLOAD_MASK */
+               /* If not loading, but BSS, zero initialize */
+               if (!dload_check_type(sptr, DLOAD_BSS))
+                       goto loop_cont;
+
+               if (!(dlthis->myoptions & DLOAD_INITBSS))
+                       goto loop_cont;
+
+               if (curr_sect >= dlthis->allocated_secn_count)
+                       lptr = (struct ldr_section_info *)sptr;
+
+               if (cinit_processed) {
+                       /*Don't clear BSS after load-time initialization */
+                       DL_ERROR("Zero-initialization at " FMT_UI32
+                                " attempted after "
+                                "load-time initialization!", lptr->load_addr);
+                       goto loop_cont;
+               }
+               /* fill the .bss area */
+               dlthis->myio->fillmem(dlthis->myio,
+                                     TADDR_TO_HOST(lptr->load_addr), lptr,
+                                     TADDR_TO_HOST(lptr->size),
+                                     DLOAD_FILL_BSS);
+loop_cont:
+               sptr += 1;
+               lptr += 1;
+       }                       /* load sections */
+
+       /*  Finalize any trampolines that were created during the load */
+       if (dload_tramp_finalize(dlthis) == 0) {
+               DL_ERROR("Finalization of auto-trampolines (size = " FMT_UI32
+                        ") failed", dlthis->tramp.tramp_sect_next_addr);
+       }
+}                              /* dload_data */
+
+/*************************************************************************
+ * Procedure dload_reorder
+ *
+ * Parameters:
+ *     data    32-bit aligned pointer to data to be byte-swapped
+ *     dsiz    size of the data to be reordered in sizeof() units.
+ *     map             32-bit map defining how to reorder the data.  Value
+ *                     must be REORDER_MAP() of some permutation
+ *                     of 0x00 01 02 03
+ *
+ * Effect:
+ *     Re-arranges the bytes in each word according to the map specified.
+ *
+ *********************************************************************** */
+/* mask for byte shift count */
+#define SHIFT_COUNT_MASK (3 << LOG_BITS_PER_BYTE)
+
+void dload_reorder(void *data, int dsiz, unsigned int map)
+{
+       register u32 tmp, tmap, datv;
+       u32 *dp = (u32 *) data;
+
+       map <<= LOG_BITS_PER_BYTE;      /* align map with SHIFT_COUNT_MASK */
+       do {
+               tmp = 0;
+               datv = *dp;
+               tmap = map;
+               do {
+                       tmp |= (datv & BYTE_MASK) << (tmap & SHIFT_COUNT_MASK);
+                       tmap >>= BITS_PER_BYTE;
+               } while (datv >>= BITS_PER_BYTE);
+               *dp++ = tmp;
+       } while ((dsiz -= sizeof(u32)) > 0);
+}                              /* dload_reorder */
+
+/*************************************************************************
+ * Procedure dload_checksum
+ *
+ * Parameters:
+ *     data    32-bit aligned pointer to data to be checksummed
+ *     siz             size of the data to be checksummed in sizeof() units.
+ *
+ * Effect:
+ *     Returns a checksum of the specified block
+ *
+ *********************************************************************** */
+u32 dload_checksum(void *data, unsigned siz)
+{
+       u32 sum;
+       u32 *dp;
+       int left;
+
+       sum = 0;
+       dp = (u32 *) data;
+       for (left = siz; left > 0; left -= sizeof(u32))
+               sum += *dp++;
+       return sum;
+}                              /* dload_checksum */
+
+#if HOST_ENDIANNESS
+/*************************************************************************
+ * Procedure dload_reverse_checksum
+ *
+ * Parameters:
+ *     data    32-bit aligned pointer to data to be checksummed
+ *     siz             size of the data to be checksummed in sizeof() units.
+ *
+ * Effect:
+ *     Returns a checksum of the specified block, which is assumed to be bytes
+ * in big-endian order.
+ *
+ * Notes:
+ *     In a big-endian host, things like the string table are stored as bytes
+ * in host order. But dllcreate always checksums in little-endian order.
+ * It is most efficient to just handle the difference a word at a time.
+ *
+ ********************************************************************** */
+u32 dload_reverse_checksum(void *data, unsigned siz)
+{
+       u32 sum, temp;
+       u32 *dp;
+       int left;
+
+       sum = 0;
+       dp = (u32 *) data;
+
+       for (left = siz; left > 0; left -= sizeof(u32)) {
+               temp = *dp++;
+               sum += temp << BITS_PER_BYTE * 3;
+               sum += temp >> BITS_PER_BYTE * 3;
+               sum += (temp >> BITS_PER_BYTE) & (BYTE_MASK << BITS_PER_BYTE);
+               sum += (temp & (BYTE_MASK << BITS_PER_BYTE)) << BITS_PER_BYTE;
+       }
+
+       return sum;
+}                              /* dload_reverse_checksum */
+
+#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
+u32 dload_reverse_checksum16(void *data, unsigned siz)
+{
+       uint_fast32_t sum, temp;
+       u32 *dp;
+       int left;
+
+       sum = 0;
+       dp = (u32 *) data;
+
+       for (left = siz; left > 0; left -= sizeof(u32)) {
+               temp = *dp++;
+               sum += temp << BITS_PER_BYTE * 2;
+               sum += temp >> BITS_PER_BYTE * 2;
+       }
+
+       return sum;
+}                              /* dload_reverse_checksum16 */
+#endif
+#endif
+
+/*************************************************************************
+ * Procedure swap_words
+ *
+ * Parameters:
+ *     data    32-bit aligned pointer to data to be swapped
+ *     siz     size of the data to be swapped.
+ *     bitmap  Bit map of how to swap each 32-bit word; 1 => 2 shorts,
+ *             0 => 1 long
+ *
+ * Effect:
+ *     Swaps the specified data according to the specified map
+ *
+ *********************************************************************** */
+static void swap_words(void *data, unsigned siz, unsigned bitmap)
+{
+       register int i;
+#if TARGET_AU_BITS < 16
+       register u16 *sp;
+#endif
+       register u32 *lp;
+
+       siz /= sizeof(u16);
+
+#if TARGET_AU_BITS < 16
+       /* pass 1: do all the bytes */
+       i = siz;
+       sp = (u16 *) data;
+       do {
+               register u16 tmp;
+               tmp = *sp;
+               *sp++ = SWAP16BY8(tmp);
+       } while ((i -= 1) > 0);
+#endif
+
+#if TARGET_AU_BITS < 32
+       /* pass 2: fixup the 32-bit words */
+       i = siz >> 1;
+       lp = (u32 *) data;
+       do {
+               if ((bitmap & 1) == 0) {
+                       register u32 tmp;
+                       tmp = *lp;
+                       *lp = SWAP32BY16(tmp);
+               }
+               lp += 1;
+               bitmap >>= 1;
+       } while ((i -= 1) > 0);
+#endif
+}                              /* swap_words */
+
+/*************************************************************************
+ * Procedure copy_tgt_strings
+ *
+ * Parameters:
+ *     dstp            Destination address.  Assumed to be 32-bit aligned
+ *     srcp            Source address.  Assumed to be 32-bit aligned
+ *     charcount       Number of characters to copy.
+ *
+ * Effect:
+ *     Copies strings from the source (which is in usual .dof file order on
+ * the loading processor) to the destination buffer (which should be in proper
+ * target addressable unit order).  Makes sure the last string in the
+ * buffer is NULL terminated (for safety).
+ * Returns the first unused destination address.
+ *********************************************************************** */
+static char *copy_tgt_strings(void *dstp, void *srcp, unsigned charcount)
+{
+       register tgt_au_t *src = (tgt_au_t *) srcp;
+       register tgt_au_t *dst = (tgt_au_t *) dstp;
+       register int cnt = charcount;
+       do {
+#if TARGET_AU_BITS <= BITS_PER_AU
+               /* byte-swapping issues may exist for strings on target */
+               *dst++ = *src++;
+#else
+               *dst++ = *src++;
+#endif
+       } while ((cnt -= (sizeof(tgt_au_t) * BITS_PER_AU / BITS_PER_BYTE)) > 0);
+       /*apply force to make sure that the string table has null terminator */
+#if (BITS_PER_AU == BITS_PER_BYTE) && (TARGET_AU_BITS == BITS_PER_BYTE)
+       dst[-1] = 0;
+#else
+       /* little endian */
+       dst[-1] &= (1 << (BITS_PER_AU - BITS_PER_BYTE)) - 1;
+#endif
+       return (char *)dst;
+}                              /* copy_tgt_strings */
+
+/*************************************************************************
+ * Procedure init_module_handle
+ *
+ * Parameters:
+ *     none
+ *
+ * Effect:
+ *     Initializes the module handle we use to enable unloading, and installs
+ * the debug information required by the target.
+ *
+ * Notes:
+ * The handle returned from dynamic_load_module needs to encapsulate all the
+ * allocations done for the module, and enable them plus the modules symbols to
+ * be deallocated.
+ *
+ *********************************************************************** */
+#ifndef _BIG_ENDIAN
+static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0,
+       (ldr_addr)-1, DBG_LIST_PAGE, DLOAD_DATA, 0
+};
+#else
+static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0,
+       (ldr_addr)-1, DLOAD_DATA, DBG_LIST_PAGE, 0
+};
+#endif
+static void init_module_handle(struct dload_state *dlthis)
+{
+       struct my_handle *hndl;
+       u16 curr_sect;
+       struct ldr_section_info *asecs;
+       struct dll_module *dbmod;
+       struct dll_sect *dbsec;
+       struct dbg_mirror_root *mlist;
+       register char *cp;
+       struct modules_header mhdr;
+       struct ldr_section_info dllview_info;
+       struct dynload_symbol *debug_mirror_sym;
+       hndl = dlthis->myhandle;
+       if (!hndl)
+               return;         /* must be errors detected, so forget it */
+
+       /*  Store the section count */
+       hndl->secn_count = dlthis->allocated_secn_count;
+
+       /*  If a trampoline section was created, add it in */
+       if (dlthis->tramp.tramp_sect_next_addr != 0)
+               hndl->secn_count += 1;
+
+       hndl->secn_count = hndl->secn_count << 1;
+
+       hndl->secn_count = dlthis->allocated_secn_count << 1;
+#ifndef TARGET_ENDIANNESS
+       if (dlthis->big_e_target)
+               hndl->secn_count += 1;  /* flag for big-endian */
+#endif
+       if (dlthis->dload_errcount)
+               return;         /* abandon if errors detected */
+       /* Locate the symbol that names the header for the CCS debug list
+          of modules. If not found, we just don't generate the debug record.
+          If found, we create our modules list.  We make sure to create the
+          loader_dllview_root even if there is no relocation info to record,
+          just to try to put both symbols in the same symbol table and
+          module. */
+       debug_mirror_sym = dlthis->mysym->find_matching_symbol(dlthis->mysym,
+                                                       loader_dllview_root);
+       if (!debug_mirror_sym) {
+               struct dynload_symbol *dlmodsym;
+               struct dbg_mirror_root *mlst;
+
+               /* our root symbol is not yet present;
+                  check if we have DLModules defined */
+               dlmodsym = dlthis->mysym->find_matching_symbol(dlthis->mysym,
+                                                       LINKER_MODULES_HEADER);
+               if (!dlmodsym)
+                       return; /* no DLModules list so no debug info */
+               /* if we have DLModules defined, construct our header */
+               mlst = (struct dbg_mirror_root *)
+                   dlthis->mysym->dload_allocate(dlthis->mysym,
+                                                 sizeof(struct
+                                                        dbg_mirror_root));
+               if (!mlst) {
+                       DL_ERROR(err_alloc, sizeof(struct dbg_mirror_root));
+                       return;
+               }
+               mlst->hnext = NULL;
+               mlst->changes = 0;
+               mlst->refcount = 0;
+               mlst->dbthis = TDATA_TO_TADDR(dlmodsym->value);
+               /* add our root symbol */
+               debug_mirror_sym = dlthis->mysym->add_to_symbol_table
+                   (dlthis->mysym, loader_dllview_root,
+                    (unsigned)dlthis->myhandle);
+               if (!debug_mirror_sym) {
+                       /* failed, recover memory */
+                       dlthis->mysym->dload_deallocate(dlthis->mysym, mlst);
+                       return;
+               }
+               debug_mirror_sym->value = (u32) mlst;
+       }
+       /* First create the DLLview record and stuff it into the buffer.
+          Then write it to the DSP.  Record pertinent locations in our hndl,
+          and add it to the per-processor list of handles with debug info. */
+#ifndef DEBUG_HEADER_IN_LOADER
+       mlist = (struct dbg_mirror_root *)debug_mirror_sym->value;
+       if (!mlist)
+               return;
+#else
+       mlist = (struct dbg_mirror_root *)&debug_list_header;
+#endif
+       hndl->dm.hroot = mlist; /* set pointer to root into our handle */
+       if (!dlthis->allocated_secn_count)
+               return;         /* no load addresses to be recorded */
+       /* reuse temporary symbol storage */
+       dbmod = (struct dll_module *)dlthis->local_symtab;
+       /* Create the DLLview record in the memory we retain for our handle */
+       dbmod->num_sects = dlthis->allocated_secn_count;
+       dbmod->timestamp = dlthis->verify.dv_timdat;
+       dbmod->version = INIT_VERSION;
+       dbmod->verification = VERIFICATION;
+       asecs = dlthis->ldr_sections;
+       dbsec = dbmod->sects;
+       for (curr_sect = dlthis->allocated_secn_count;
+            curr_sect > 0; curr_sect -= 1) {
+               dbsec->sect_load_adr = asecs->load_addr;
+               dbsec->sect_run_adr = asecs->run_addr;
+               dbsec += 1;
+               asecs += 1;
+       }
+
+       /*  If a trampoline section was created go ahead and add its info */
+       if (dlthis->tramp.tramp_sect_next_addr != 0) {
+               dbmod->num_sects++;
+               dbsec->sect_load_adr = asecs->load_addr;
+               dbsec->sect_run_adr = asecs->run_addr;
+               dbsec++;
+               asecs++;
+       }
+
+       /* now cram in the names */
+       cp = copy_tgt_strings(dbsec, dlthis->str_head,
+                             dlthis->debug_string_size);
+
+       /* If a trampoline section was created, add its name so DLLView
+        * can show the user the section info. */
+       if (dlthis->tramp.tramp_sect_next_addr != 0) {
+               cp = copy_tgt_strings(cp,
+                                     dlthis->tramp.final_string_table,
+                                     strlen(dlthis->tramp.final_string_table) +
+                                     1);
+       }
+
+       /* round off the size of the debug record, and remember same */
+       hndl->dm.dbsiz = HOST_TO_TDATA_ROUND(cp - (char *)dbmod);
+       *cp = 0;                /* strictly to make our test harness happy */
+       dllview_info = dllview_info_init;
+       dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz);
+       /* Initialize memory context to default heap */
+       dllview_info.context = 0;
+       hndl->dm.context = 0;
+       /* fill in next pointer and size */
+       if (mlist->hnext) {
+               dbmod->next_module = TADDR_TO_TDATA(mlist->hnext->dm.dbthis);
+               dbmod->next_module_size = mlist->hnext->dm.dbsiz;
+       } else {
+               dbmod->next_module_size = 0;
+               dbmod->next_module = 0;
+       }
+       /* allocate memory for on-DSP DLLview debug record */
+       if (!dlthis->myalloc)
+               return;
+       if (!dlthis->myalloc->dload_allocate(dlthis->myalloc, &dllview_info,
+                                            HOST_TO_TADDR(sizeof(u32)))) {
+               return;
+       }
+       /* Store load address of .dllview section */
+       hndl->dm.dbthis = dllview_info.load_addr;
+       /* Store memory context (segid) in which .dllview section
+        * was  allocated */
+       hndl->dm.context = dllview_info.context;
+       mlist->refcount += 1;
+       /* swap bytes in the entire debug record, but not the string table */
+       if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) {
+               swap_words(dbmod, (char *)dbsec - (char *)dbmod,
+                          DLL_MODULE_BITMAP);
+       }
+       /* Update the DLLview list on the DSP write new record */
+       if (!dlthis->myio->writemem(dlthis->myio, dbmod,
+                                   dllview_info.load_addr, &dllview_info,
+                                   TADDR_TO_HOST(dllview_info.size))) {
+               return;
+       }
+       /* write new header */
+       mhdr.first_module_size = hndl->dm.dbsiz;
+       mhdr.first_module = TADDR_TO_TDATA(dllview_info.load_addr);
+       /* swap bytes in the module header, if needed */
+       if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) {
+               swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16),
+                          MODULES_HEADER_BITMAP);
+       }
+       dllview_info = dllview_info_init;
+       if (!dlthis->myio->writemem(dlthis->myio, &mhdr, mlist->dbthis,
+                                   &dllview_info,
+                                   sizeof(struct modules_header) -
+                                   sizeof(u16))) {
+               return;
+       }
+       /* Add the module handle to this processor's list
+          of handles with debug info */
+       hndl->dm.hnext = mlist->hnext;
+       if (hndl->dm.hnext)
+               hndl->dm.hnext->dm.hprev = hndl;
+       hndl->dm.hprev = (struct my_handle *)mlist;
+       mlist->hnext = hndl;    /* insert after root */
+}                              /* init_module_handle */
+
+/*************************************************************************
+ * Procedure dynamic_unload_module
+ *
+ * Parameters:
+ *     mhandle A module handle from dynamic_load_module
+ *     syms    Host-side symbol table and malloc/free functions
+ *     alloc   Target-side memory allocation
+ *
+ * Effect:
+ *     The module specified by mhandle is unloaded.  Unloading causes all
+ * target memory to be deallocated, all symbols defined by the module to
+ * be purged, and any host-side storage used by the dynamic loader for
+ * this module to be released.
+ *
+ * Returns:
+ *     Zero for success. On error, the number of errors detected is returned.
+ * Individual errors are reported using syms->error_report().
+ *********************************************************************** */
+int dynamic_unload_module(void *mhandle,
+                         struct dynamic_loader_sym *syms,
+                         struct dynamic_loader_allocate *alloc,
+                         struct dynamic_loader_initialize *init)
+{
+       s16 curr_sect;
+       struct ldr_section_info *asecs;
+       struct my_handle *hndl;
+       struct dbg_mirror_root *root;
+       unsigned errcount = 0;
+       struct ldr_section_info dllview_info = dllview_info_init;
+       struct modules_header mhdr;
+
+       hndl = (struct my_handle *)mhandle;
+       if (!hndl)
+               return 0;       /* if handle is null, nothing to do */
+       /* Clear out the module symbols
+        * Note that if this is the module that defined MODULES_HEADER
+        (the head of the target debug list)
+        * then this operation will blow away that symbol.
+        It will therefore be impossible for subsequent
+        * operations to add entries to this un-referenceable list. */
+       if (!syms)
+               return 1;
+       syms->purge_symbol_table(syms, (unsigned)hndl);
+       /* Deallocate target memory for sections
+        * NOTE: The trampoline section, if created, gets deleted here, too */
+
+       asecs = hndl->secns;
+       if (alloc)
+               for (curr_sect = (hndl->secn_count >> 1); curr_sect > 0;
+                    curr_sect -= 1) {
+                       asecs->name = NULL;
+                       alloc->dload_deallocate(alloc, asecs++);
+               }
+       root = hndl->dm.hroot;
+       if (!root) {
+               /* there is a debug list containing this module */
+               goto func_end;
+       }
+       if (!hndl->dm.dbthis) { /* target-side dllview record exists */
+               goto loop_end;
+       }
+       /* Retrieve memory context in which .dllview was allocated */
+       dllview_info.context = hndl->dm.context;
+       if (hndl->dm.hprev == hndl)
+               goto exitunltgt;
+
+       /* target-side dllview record is in list */
+       /* dequeue this record from our GPP-side mirror list */
+       hndl->dm.hprev->dm.hnext = hndl->dm.hnext;
+       if (hndl->dm.hnext)
+               hndl->dm.hnext->dm.hprev = hndl->dm.hprev;
+       /* Update next_module of previous entry in target list
+        * We are using mhdr here as a surrogate for either a
+        struct modules_header or a dll_module */
+       if (hndl->dm.hnext) {
+               mhdr.first_module = TADDR_TO_TDATA(hndl->dm.hnext->dm.dbthis);
+               mhdr.first_module_size = hndl->dm.hnext->dm.dbsiz;
+       } else {
+               mhdr.first_module = 0;
+               mhdr.first_module_size = 0;
+       }
+       if (!init)
+               goto exitunltgt;
+
+       if (!init->connect(init)) {
+               dload_syms_error(syms, iconnect);
+               errcount += 1;
+               goto exitunltgt;
+       }
+       /* swap bytes in the module header, if needed */
+       if (TARGET_ENDIANNESS_DIFFERS(hndl->secn_count & 0x1)) {
+               swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16),
+                          MODULES_HEADER_BITMAP);
+       }
+       if (!init->writemem(init, &mhdr, hndl->dm.hprev->dm.dbthis,
+                           &dllview_info, sizeof(struct modules_header) -
+                           sizeof(mhdr.update_flag))) {
+               dload_syms_error(syms, dlvwrite);
+               errcount += 1;
+       }
+       /* update change counter */
+       root->changes += 1;
+       if (!init->writemem(init, &(root->changes),
+                           root->dbthis + HOST_TO_TADDR
+                           (sizeof(mhdr.first_module) +
+                            sizeof(mhdr.first_module_size)),
+                           &dllview_info, sizeof(mhdr.update_flag))) {
+               dload_syms_error(syms, dlvwrite);
+               errcount += 1;
+       }
+       init->release(init);
+exitunltgt:
+       /* release target storage */
+       dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz);
+       dllview_info.load_addr = hndl->dm.dbthis;
+       if (alloc)
+               alloc->dload_deallocate(alloc, &dllview_info);
+       root->refcount -= 1;
+       /* target-side dllview record exists */
+loop_end:
+#ifndef DEBUG_HEADER_IN_LOADER
+       if (root->refcount <= 0) {
+               /* if all references gone, blow off the header */
+               /* our root symbol may be gone due to the Purge above,
+                  but if not, do not destroy the root */
+               if (syms->find_matching_symbol
+                   (syms, loader_dllview_root) == NULL)
+                       syms->dload_deallocate(syms, root);
+       }
+#endif
+func_end:
+       /* there is a debug list containing this module */
+       syms->dload_deallocate(syms, mhandle);  /* release our storage */
+       return errcount;
+}                              /* dynamic_unload_module */
+
+#if BITS_PER_AU > BITS_PER_BYTE
+/*************************************************************************
+ * Procedure unpack_name
+ *
+ * Parameters:
+ *     soffset Byte offset into the string table
+ *
+ * Effect:
+ *     Returns a pointer to the string specified by the offset supplied, or
+ * NULL for error.
+ *
+ *********************************************************************** */
+static char *unpack_name(struct dload_state *dlthis, u32 soffset)
+{
+       u8 tmp, *src;
+       char *dst;
+
+       if (soffset >= dlthis->dfile_hdr.df_strtab_size) {
+               dload_error(dlthis, "Bad string table offset " FMT_UI32,
+                           soffset);
+               return NULL;
+       }
+       src = (uint_least8_t *) dlthis->str_head +
+           (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE));
+       dst = dlthis->str_temp;
+       if (soffset & 1)
+               *dst++ = *src++;        /* only 1 character in first word */
+       do {
+               tmp = *src++;
+               *dst = (tmp >> BITS_PER_BYTE);
+               if (!(*dst++))
+                       break;
+       } while ((*dst++ = tmp & BYTE_MASK));
+       dlthis->temp_len = dst - dlthis->str_temp;
+       /* squirrel away length including terminating null */
+       return dlthis->str_temp;
+}                              /* unpack_name */
+#endif
diff --git a/drivers/staging/tidspbridge/dynload/dload_internal.h b/drivers/staging/tidspbridge/dynload/dload_internal.h
new file mode 100644 (file)
index 0000000..302a7c5
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * dload_internal.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _DLOAD_INTERNAL_
+#define _DLOAD_INTERNAL_
+
+#include <linux/types.h>
+
+/*
+ * Internal state definitions for the dynamic loader
+ */
+
+/* type used for relocation intermediate results */
+typedef s32 rvalue;
+
+/* unsigned version of same; must have at least as many bits */
+typedef u32 urvalue;
+
+/*
+ * Dynamic loader configuration constants
+ */
+/* error issued if input has more sections than this limit */
+#define REASONABLE_SECTION_LIMIT 100
+
+/* (Addressable unit) value used to clear BSS section */
+#define DLOAD_FILL_BSS 0
+
+/*
+ * Reorder maps explained (?)
+ *
+ * The doff file format defines a 32-bit pattern used to determine the
+ * byte order of an image being read.  That value is
+ * BYTE_RESHUFFLE_VALUE == 0x00010203
+ * For purposes of the reorder routine, we would rather have the all-is-OK
+ * for 32-bits pattern be 0x03020100.  This first macro makes the
+ * translation from doff file header value to MAP value: */
+#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303)
+/* This translation is made in dload_headers.  Thereafter, the all-is-OK
+ * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE).
+ * But sadly, not all bits of the doff file are 32-bit integers.
+ * The notable exceptions are strings and image bits.
+ * Strings obey host byte order: */
+#if defined(_BIG_ENDIAN)
+#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
+#else
+#define HOST_BYTE_ORDER(cookedmap) (cookedmap)
+#endif
+/* Target bits consist of target AUs (could be bytes, or 16-bits,
+ * or 32-bits) stored as an array in host order.  A target order
+ * map is defined by: */
+#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16
+#define TARGET_ORDER(cookedmap) (cookedmap)
+#elif TARGET_AU_BITS > 8
+#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202)
+#else
+#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
+#endif
+
+/* forward declaration for handle returned by dynamic loader */
+struct my_handle;
+
+/*
+ * a list of module handles, which mirrors the debug list on the target
+ */
+struct dbg_mirror_root {
+       /* must be same as dbg_mirror_list; __DLModules address on target */
+       u32 dbthis;
+       struct my_handle *hnext;        /* must be same as dbg_mirror_list */
+       u16 changes;            /* change counter */
+       u16 refcount;           /* number of modules referencing this root */
+};
+
+struct dbg_mirror_list {
+       u32 dbthis;
+       struct my_handle *hnext, *hprev;
+       struct dbg_mirror_root *hroot;
+       u16 dbsiz;
+       u32 context;    /* Save context for .dllview memory allocation */
+};
+
+#define VARIABLE_SIZE 1
+/*
+ * the structure we actually return as an opaque module handle
+ */
+struct my_handle {
+       struct dbg_mirror_list dm;      /* !!! must be first !!! */
+       /* sections following << 1, LSB is set for big-endian target */
+       u16 secn_count;
+       struct ldr_section_info secns[VARIABLE_SIZE];
+};
+#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\
+                       sizeof(struct ldr_section_info))
+/* real size of my_handle */
+
+/*
+ * reduced symbol structure used for symbols during relocation
+ */
+struct local_symbol {
+       s32 value;              /* Relocated symbol value */
+       s32 delta;              /* Original value in input file */
+       s16 secnn;              /* section number */
+       s16 sclass;             /* symbol class */
+};
+
+/*
+ * Trampoline data structures
+ */
+#define TRAMP_NO_GEN_AVAIL              65535
+#define TRAMP_SYM_PREFIX                "__$dbTR__"
+#define TRAMP_SECT_NAME                 ".dbTR"
+/* MUST MATCH THE LENGTH ABOVE!! */
+#define TRAMP_SYM_PREFIX_LEN            9
+/* Includes NULL termination */
+#define TRAMP_SYM_HEX_ASCII_LEN         9
+
+#define GET_CONTAINER(ptr, type, field) ((type *)((unsigned long)ptr -\
+                               (unsigned long)(&((type *)0)->field)))
+#ifndef FIELD_OFFSET
+#define FIELD_OFFSET(type, field)       ((unsigned long)(&((type *)0)->field))
+#endif
+
+/*
+    The trampoline code for the target is located in a table called
+    "tramp_gen_info" with is indexed by looking up the index in the table
+    "tramp_map".  The tramp_map index is acquired using the target
+    HASH_FUNC on the relocation type that caused the trampoline.  Each
+    trampoline code table entry MUST follow this format:
+
+    |----------------------------------------------|
+    |  tramp_gen_code_hdr                          |
+    |----------------------------------------------|
+    |  Trampoline image code                       |
+    |  (the raw instruction code for the target)   |
+    |----------------------------------------------|
+    |  Relocation entries for the image code       |
+    |----------------------------------------------|
+
+    This is very similar to how image data is laid out in the DOFF file
+    itself.
+ */
+struct tramp_gen_code_hdr {
+       u32 tramp_code_size;    /*  in BYTES */
+       u32 num_relos;
+       u32 relo_offset;        /*  in BYTES */
+};
+
+struct tramp_img_pkt {
+       struct tramp_img_pkt *next;     /*  MUST BE FIRST */
+       u32 base;
+       struct tramp_gen_code_hdr hdr;
+       u8 payload[VARIABLE_SIZE];
+};
+
+struct tramp_img_dup_relo {
+       struct tramp_img_dup_relo *next;
+       struct reloc_record_t relo;
+};
+
+struct tramp_img_dup_pkt {
+       struct tramp_img_dup_pkt *next; /*  MUST BE FIRST */
+       s16 secnn;
+       u32 offset;
+       struct image_packet_t img_pkt;
+       struct tramp_img_dup_relo *relo_chain;
+
+       /*  PAYLOAD OF IMG PKT FOLLOWS */
+};
+
+struct tramp_sym {
+       struct tramp_sym *next; /*  MUST BE FIRST */
+       u32 index;
+       u32 str_index;
+       struct local_symbol sym_info;
+};
+
+struct tramp_string {
+       struct tramp_string *next;      /*  MUST BE FIRST */
+       u32 index;
+       char str[VARIABLE_SIZE];        /*  NULL terminated */
+};
+
+struct tramp_info {
+       u32 tramp_sect_next_addr;
+       struct ldr_section_info sect_info;
+
+       struct tramp_sym *symbol_head;
+       struct tramp_sym *symbol_tail;
+       u32 tramp_sym_next_index;
+       struct local_symbol *final_sym_table;
+
+       struct tramp_string *string_head;
+       struct tramp_string *string_tail;
+       u32 tramp_string_next_index;
+       u32 tramp_string_size;
+       char *final_string_table;
+
+       struct tramp_img_pkt *tramp_pkts;
+       struct tramp_img_dup_pkt *dup_pkts;
+};
+
+/*
+ * States of the .cinit state machine
+ */
+enum cinit_mode {
+       CI_COUNT = 0,           /* expecting a count */
+       CI_ADDRESS,             /* expecting an address */
+#if CINIT_ALIGN < CINIT_ADDRESS        /* handle case of partial address field */
+       CI_PARTADDRESS,         /* have only part of the address */
+#endif
+       CI_COPY,                /* in the middle of copying data */
+       CI_DONE                 /* end of .cinit table */
+};
+
+/*
+ * The internal state of the dynamic loader, which is passed around as
+ * an object
+ */
+struct dload_state {
+       struct dynamic_loader_stream *strm;     /* The module input stream */
+       struct dynamic_loader_sym *mysym;       /* Symbols for this session */
+       /* target memory allocator */
+       struct dynamic_loader_allocate *myalloc;
+       struct dynamic_loader_initialize *myio; /* target memory initializer */
+       unsigned myoptions;     /* Options parameter dynamic_load_module */
+
+       char *str_head;         /* Pointer to string table */
+#if BITS_PER_AU > BITS_PER_BYTE
+       char *str_temp;         /* Pointer to temporary buffer for strings */
+       /* big enough to hold longest string */
+       unsigned temp_len;      /* length of last temporary string */
+       char *xstrings;         /* Pointer to buffer for expanded */
+       /* strings for sec names */
+#endif
+       /* Total size of strings for DLLView section names */
+       unsigned debug_string_size;
+       /* Pointer to parallel section info for allocated sections only */
+       struct doff_scnhdr_t *sect_hdrs;        /* Pointer to section table */
+       struct ldr_section_info *ldr_sections;
+#if TMS32060
+       /* The address of the start of the .bss section */
+       ldr_addr bss_run_base;
+#endif
+       struct local_symbol *local_symtab;      /* Relocation symbol table */
+
+       /* pointer to DL section info for the section being relocated */
+       struct ldr_section_info *image_secn;
+       /* change in run address for current section during relocation */
+       ldr_addr delta_runaddr;
+       ldr_addr image_offset;  /* offset of current packet in section */
+       enum cinit_mode cinit_state;    /* current state of cload_cinit() */
+       int cinit_count;        /* the current count */
+       ldr_addr cinit_addr;    /* the current address */
+       s16 cinit_page;         /* the current page */
+       /* Handle to be returned by dynamic_load_module */
+       struct my_handle *myhandle;
+       unsigned dload_errcount;        /* Total # of errors reported so far */
+       /* Number of target sections that require allocation and relocation */
+       unsigned allocated_secn_count;
+#ifndef TARGET_ENDIANNESS
+       int big_e_target;       /* Target data in big-endian format */
+#endif
+       /* map for reordering bytes, 0 if not needed */
+       u32 reorder_map;
+       struct doff_filehdr_t dfile_hdr;        /* DOFF file header structure */
+       struct doff_verify_rec_t verify;        /* Verify record */
+
+       struct tramp_info tramp;        /* Trampoline data, if needed */
+
+       int relstkidx;          /* index into relocation value stack */
+       /* relocation value stack used in relexp.c */
+       rvalue relstk[STATIC_EXPR_STK_SIZE];
+
+};
+
+#ifdef TARGET_ENDIANNESS
+#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS
+#else
+#define TARGET_BIG_ENDIAN (dlthis->big_e_target)
+#endif
+
+/*
+ * Exports from cload.c to rest of the world
+ */
+extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...);
+extern void dload_syms_error(struct dynamic_loader_sym *syms,
+                            const char *errtxt, ...);
+extern void dload_headers(struct dload_state *dlthis);
+extern void dload_strings(struct dload_state *dlthis, bool sec_names_only);
+extern void dload_sections(struct dload_state *dlthis);
+extern void dload_reorder(void *data, int dsiz, u32 map);
+extern u32 dload_checksum(void *data, unsigned siz);
+
+#if HOST_ENDIANNESS
+extern uint32_t dload_reverse_checksum(void *data, unsigned siz);
+#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
+extern uint32_t dload_reverse_checksum16(void *data, unsigned siz);
+#endif
+#endif
+
+/*
+ * exported by reloc.c
+ */
+extern void dload_relocate(struct dload_state *dlthis, tgt_au_t * data,
+                          struct reloc_record_t *rp, bool * tramps_generated,
+                          bool second_pass);
+
+extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data,
+                          int fieldsz, int offset, unsigned sgn);
+
+extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data,
+                       int fieldsz, int offset, unsigned sgn);
+
+/*
+ * exported by tramp.c
+ */
+extern bool dload_tramp_avail(struct dload_state *dlthis,
+                             struct reloc_record_t *rp);
+
+int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
+                        u32 image_offset, struct image_packet_t *ipacket,
+                        struct reloc_record_t *rp);
+
+extern int dload_tramp_pkt_udpate(struct dload_state *dlthis,
+                                 s16 secnn, u32 image_offset,
+                                 struct image_packet_t *ipacket);
+
+extern int dload_tramp_finalize(struct dload_state *dlthis);
+
+extern void dload_tramp_cleanup(struct dload_state *dlthis);
+
+#endif /* _DLOAD_INTERNAL_ */
diff --git a/drivers/staging/tidspbridge/dynload/doff.h b/drivers/staging/tidspbridge/dynload/doff.h
new file mode 100644 (file)
index 0000000..a7c3145
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * doff.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Structures & definitions used for dynamically loaded modules file format.
+ * This format is a reformatted version of COFF. It optimizes the layout for
+ * the dynamic loader.
+ *
+ * .dof files, when viewed as a sequence of 32-bit integers, look the same
+ * on big-endian and little-endian machines.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _DOFF_H
+#define _DOFF_H
+
+
+#define BYTE_RESHUFFLE_VALUE 0x00010203
+
+/* DOFF file header containing fields categorizing the remainder of the file */
+struct doff_filehdr_t {
+
+       /* string table size, including filename, in bytes */
+       u32 df_strtab_size;
+
+       /* entry point if one exists */
+       u32 df_entrypt;
+
+       /* identifies byte ordering of file;
+        * always set to BYTE_RESHUFFLE_VALUE */
+       u32 df_byte_reshuffle;
+
+       /* Size of the string table up to and including the last section name */
+       /* Size includes the name of the COFF file also */
+       u32 df_scn_name_size;
+
+#ifndef _BIG_ENDIAN
+       /* number of symbols */
+       u16 df_no_syms;
+
+       /* length in bytes of the longest string, including terminating NULL */
+       /* excludes the name of the file */
+       u16 df_max_str_len;
+
+       /* total number of sections including no-load ones */
+       u16 df_no_scns;
+
+       /* number of sections containing target code allocated or downloaded */
+       u16 df_target_scns;
+
+       /* unique id for dll file format & version */
+       u16 df_doff_version;
+
+       /* identifies ISA */
+       u16 df_target_id;
+
+       /* useful file flags */
+       u16 df_flags;
+
+       /* section reference for entry point, N_UNDEF for none, */
+       /* N_ABS for absolute address */
+       s16 df_entry_secn;
+#else
+       /* length of the longest string, including terminating NULL */
+       u16 df_max_str_len;
+
+       /* number of symbols */
+       u16 df_no_syms;
+
+       /* number of sections containing target code allocated or downloaded */
+       u16 df_target_scns;
+
+       /* total number of sections including no-load ones */
+       u16 df_no_scns;
+
+       /* identifies ISA */
+       u16 df_target_id;
+
+       /* unique id for dll file format & version */
+       u16 df_doff_version;
+
+       /* section reference for entry point, N_UNDEF for none, */
+       /* N_ABS for absolute address */
+       s16 df_entry_secn;
+
+       /* useful file flags */
+       u16 df_flags;
+#endif
+       /* checksum for file header record */
+       u32 df_checksum;
+
+};
+
+/* flags in the df_flags field */
+#define  DF_LITTLE   0x100
+#define  DF_BIG      0x200
+#define  DF_BYTE_ORDER (DF_LITTLE | DF_BIG)
+
+/* Supported processors */
+#define TMS470_ID   0x97
+#define LEAD_ID     0x98
+#define TMS32060_ID 0x99
+#define LEAD3_ID    0x9c
+
+/* Primary processor for loading */
+#if TMS32060
+#define TARGET_ID   TMS32060_ID
+#endif
+
+/* Verification record containing values used to test integrity of the bits */
+struct doff_verify_rec_t {
+
+       /* time and date stamp */
+       u32 dv_timdat;
+
+       /* checksum for all section records */
+       u32 dv_scn_rec_checksum;
+
+       /* checksum for string table */
+       u32 dv_str_tab_checksum;
+
+       /* checksum for symbol table */
+       u32 dv_sym_tab_checksum;
+
+       /* checksum for verification record */
+       u32 dv_verify_rec_checksum;
+
+};
+
+/* String table is an array of null-terminated strings.  The first entry is
+ * the filename, which is added by DLLcreate.  No new structure definitions
+ * are required.
+ */
+
+/* Section Records including information on the corresponding image packets */
+/*
+ *      !!WARNING!!
+ *
+ * This structure is expected to match in form ldr_section_info in
+ * dynamic_loader.h
+ */
+
+struct doff_scnhdr_t {
+
+       s32 ds_offset;          /* offset into string table of name */
+       s32 ds_paddr;           /* RUN address, in target AU */
+       s32 ds_vaddr;           /* LOAD address, in target AU */
+       s32 ds_size;            /* section size, in target AU */
+#ifndef _BIG_ENDIAN
+       u16 ds_page;            /* memory page id */
+       u16 ds_flags;           /* section flags */
+#else
+       u16 ds_flags;           /* section flags */
+       u16 ds_page;            /* memory page id */
+#endif
+       u32 ds_first_pkt_offset;
+       /* Absolute byte offset into the file */
+       /* where the first image record resides */
+
+       s32 ds_nipacks;         /* number of image packets */
+
+};
+
+/* Symbol table entry */
+struct doff_syment_t {
+
+       s32 dn_offset;          /* offset into string table of name */
+       s32 dn_value;           /* value of symbol */
+#ifndef _BIG_ENDIAN
+       s16 dn_scnum;           /* section number */
+       s16 dn_sclass;          /* storage class */
+#else
+       s16 dn_sclass;          /* storage class */
+       s16 dn_scnum;           /* section number, 1-based */
+#endif
+
+};
+
+/* special values for dn_scnum */
+#define  DN_UNDEF  0           /* undefined symbol */
+#define  DN_ABS    (-1)                /* value of symbol is absolute */
+/* special values for dn_sclass */
+#define DN_EXT     2
+#define DN_STATLAB 20
+#define DN_EXTLAB  21
+
+/* Default value of image bits in packet */
+/* Configurable by user on the command line */
+#define IMAGE_PACKET_SIZE 1024
+
+/* An image packet contains a chunk of data from a section along with */
+/* information necessary for its processing. */
+struct image_packet_t {
+
+       s32 num_relocs;         /* number of relocations for */
+       /* this packet */
+
+       s32 packet_size;        /* number of bytes in array */
+       /* "bits" occupied  by */
+       /* valid data.  Could be */
+       /* < IMAGE_PACKET_SIZE to */
+       /* prevent splitting a */
+       /* relocation across packets. */
+       /* Last packet of a section */
+       /* will most likely contain */
+       /* < IMAGE_PACKET_SIZE bytes */
+       /* of valid data */
+
+       s32 img_chksum;         /* Checksum for image packet */
+       /* and the corresponding */
+       /* relocation records */
+
+       u8 *img_data;           /* Actual data in section */
+
+};
+
+/* The relocation structure definition matches the COFF version.  Offsets */
+/* however are relative to the image packet base not the section base. */
+struct reloc_record_t {
+
+       s32 vaddr;
+
+       /* expressed in target AUs */
+
+       union {
+               struct {
+#ifndef _BIG_ENDIAN
+                       u8 _offset;     /* bit offset of rel fld */
+                       u8 _fieldsz;    /* size of rel fld */
+                       u8 _wordsz;     /* # bytes containing rel fld */
+                       u8 _dum1;
+                       u16 _dum2;
+                       u16 _type;
+#else
+                       unsigned _dum1:8;
+                       unsigned _wordsz:8;     /* # bytes containing rel fld */
+                       unsigned _fieldsz:8;    /* size of rel fld */
+                       unsigned _offset:8;     /* bit offset of rel fld */
+                       u16 _type;
+                       u16 _dum2;
+#endif
+               } _r_field;
+
+               struct {
+                       u32 _spc;       /* image packet relative PC */
+#ifndef _BIG_ENDIAN
+                       u16 _dum;
+                       u16 _type;      /* relocation type */
+#else
+                       u16 _type;      /* relocation type */
+                       u16 _dum;
+#endif
+               } _r_spc;
+
+               struct {
+                       u32 _uval;      /* constant value */
+#ifndef _BIG_ENDIAN
+                       u16 _dum;
+                       u16 _type;      /* relocation type */
+#else
+                       u16 _type;      /* relocation type */
+                       u16 _dum;
+#endif
+               } _r_uval;
+
+               struct {
+                       s32 _symndx;    /* 32-bit sym tbl index */
+#ifndef _BIG_ENDIAN
+                       u16 _disp;      /* extra addr encode data */
+                       u16 _type;      /* relocation type */
+#else
+                       u16 _type;      /* relocation type */
+                       u16 _disp;      /* extra addr encode data */
+#endif
+               } _r_sym;
+       } _u_reloc;
+
+};
+
+/* abbreviations for convenience */
+#ifndef TYPE
+#define TYPE      _u_reloc._r_sym._type
+#define UVAL      _u_reloc._r_uval._uval
+#define SYMNDX    _u_reloc._r_sym._symndx
+#define OFFSET    _u_reloc._r_field._offset
+#define FIELDSZ   _u_reloc._r_field._fieldsz
+#define WORDSZ    _u_reloc._r_field._wordsz
+#define R_DISP      _u_reloc._r_sym._disp
+#endif
+
+/**************************************************************************** */
+/* */
+/* Important DOFF macros used for file processing */
+/* */
+/**************************************************************************** */
+
+/* DOFF Versions */
+#define         DOFF0                       0
+
+/* Return the address/size >= to addr that is at a 32-bit boundary */
+/* This assumes that a byte is 8 bits */
+#define         DOFF_ALIGN(addr)            (((addr) + 3) & ~3UL)
+
+/**************************************************************************** */
+/* */
+/* The DOFF section header flags field is laid out as follows: */
+/* */
+/*  Bits 0-3 : Section Type */
+/*  Bit    4 : Set when section requires target memory to be allocated by DL */
+/*  Bit    5 : Set when section requires downloading */
+/*  Bits 8-11: Alignment, same as COFF */
+/* */
+/**************************************************************************** */
+
+/* Enum for DOFF section types (bits 0-3 of flag): See dynamic_loader.h */
+#define DS_SECTION_TYPE_MASK   0xF
+/* DS_ALLOCATE indicates whether a section needs space on the target */
+#define DS_ALLOCATE_MASK            0x10
+/* DS_DOWNLOAD indicates that the loader needs to copy bits */
+#define DS_DOWNLOAD_MASK            0x20
+/* Section alignment requirement in AUs */
+#define DS_ALIGNMENT_SHIFT     8
+
+static inline bool dload_check_type(struct doff_scnhdr_t *sptr, u32 flag)
+{
+       return (sptr->ds_flags & DS_SECTION_TYPE_MASK) == flag;
+}
+static inline bool ds_needs_allocation(struct doff_scnhdr_t *sptr)
+{
+       return sptr->ds_flags & DS_ALLOCATE_MASK;
+}
+
+static inline bool ds_needs_download(struct doff_scnhdr_t *sptr)
+{
+       return sptr->ds_flags & DS_DOWNLOAD_MASK;
+}
+
+static inline int ds_alignment(u16 ds_flags)
+{
+       return 1 << ((ds_flags >> DS_ALIGNMENT_SHIFT) & DS_SECTION_TYPE_MASK);
+}
+
+
+#endif /* _DOFF_H */
diff --git a/drivers/staging/tidspbridge/dynload/getsection.c b/drivers/staging/tidspbridge/dynload/getsection.c
new file mode 100644 (file)
index 0000000..e0b3771
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * getsection.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <dspbridge/getsection.h>
+#include "header.h"
+
+/*
+ * Error strings
+ */
+static const char readstrm[] = { "Error reading %s from input stream" };
+static const char seek[] = { "Set file position to %d failed" };
+static const char isiz[] = { "Bad image packet size %d" };
+static const char err_checksum[] = { "Checksum failed on %s" };
+
+static const char err_reloc[] = { "dload_get_section unable to read"
+           "sections containing relocation entries"
+};
+
+#if BITS_PER_AU > BITS_PER_BYTE
+static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" };
+static const char stbl[] = { "Bad string table offset " FMT_UI32 };
+#endif
+
+/************************************************************** */
+/********************* SUPPORT FUNCTIONS ********************** */
+/************************************************************** */
+
+#if BITS_PER_AU > BITS_PER_BYTE
+/**************************************************************************
+ * Procedure unpack_sec_name
+ *
+ * Parameters:
+ *  dlthis             Handle from dload_module_open for this module
+ *     soffset     Byte offset into the string table
+ *  dst         Place to store the expanded string
+ *
+ * Effect:
+ *     Stores a string from the string table into the destination, expanding
+ * it in the process.  Returns a pointer just past the end of the stored
+ * string on success, or NULL on failure.
+ *
+ ************************************************************************ */
+static char *unpack_sec_name(struct dload_state *dlthis, u32 soffset, char *dst)
+{
+       u8 tmp, *src;
+
+       if (soffset >= dlthis->dfile_hdr.df_scn_name_size) {
+               dload_error(dlthis, stbl, soffset);
+               return NULL;
+       }
+       src = (u8 *) dlthis->str_head +
+           (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE));
+       if (soffset & 1)
+               *dst++ = *src++;        /* only 1 character in first word */
+       do {
+               tmp = *src++;
+               *dst = (tmp >> BITS_PER_BYTE)
+                   if (!(*dst++))
+                       break;
+       } while ((*dst++ = tmp & BYTE_MASK));
+
+       return dst;
+}
+
+/**************************************************************************
+ * Procedure expand_sec_names
+ *
+ * Parameters:
+ *  dlthis             Handle from dload_module_open for this module
+ *
+ * Effect:
+ *    Allocates a buffer, unpacks and copies strings from string table into it.
+ * Stores a pointer to the buffer into a state variable.
+ ************************************************************************* */
+static void expand_sec_names(struct dload_state *dlthis)
+{
+       char *xstrings, *curr, *next;
+       u32 xsize;
+       u16 sec;
+       struct ldr_section_info *shp;
+       /* assume worst-case size requirement */
+       xsize = dlthis->dfile_hdr.df_max_str_len * dlthis->dfile_hdr.df_no_scns;
+       xstrings = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, xsize);
+       if (xstrings == NULL) {
+               dload_error(dlthis, err_alloc, xsize);
+               return;
+       }
+       dlthis->xstrings = xstrings;
+       /* For each sec, copy and expand its name */
+       curr = xstrings;
+       for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
+               shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec];
+               next = unpack_sec_name(dlthis, *(u32 *) &shp->name, curr);
+               if (next == NULL)
+                       break;  /* error */
+               shp->name = curr;
+               curr = next;
+       }
+}
+
+#endif
+
+/************************************************************** */
+/********************* EXPORTED FUNCTIONS ********************* */
+/************************************************************** */
+
+/**************************************************************************
+ * Procedure dload_module_open
+ *
+ * Parameters:
+ *     module  The input stream that supplies the module image
+ *     syms    Host-side malloc/free and error reporting functions.
+ *                     Other methods are unused.
+ *
+ * Effect:
+ *     Reads header information from a dynamic loader module using the
+    specified
+ * stream object, and returns a handle for the module information.  This
+ * handle may be used in subsequent query calls to obtain information
+ * contained in the module.
+ *
+ * Returns:
+ *     NULL if an error is encountered, otherwise a module handle for use
+ * in subsequent operations.
+ ************************************************************************* */
+void *dload_module_open(struct dynamic_loader_stream *module,
+                                   struct dynamic_loader_sym *syms)
+{
+       struct dload_state *dlthis;     /* internal state for this call */
+       unsigned *dp, sz;
+       u32 sec_start;
+#if BITS_PER_AU <= BITS_PER_BYTE
+       u16 sec;
+#endif
+
+       /* Check that mandatory arguments are present */
+       if (!module || !syms) {
+               if (syms != NULL)
+                       dload_syms_error(syms, "Required parameter is NULL");
+
+               return NULL;
+       }
+
+       dlthis = (struct dload_state *)
+           syms->dload_allocate(syms, sizeof(struct dload_state));
+       if (!dlthis) {
+               /* not enough storage */
+               dload_syms_error(syms, "Can't allocate module info");
+               return NULL;
+       }
+
+       /* clear our internal state */
+       dp = (unsigned *)dlthis;
+       for (sz = sizeof(struct dload_state) / sizeof(unsigned);
+            sz > 0; sz -= 1)
+               *dp++ = 0;
+
+       dlthis->strm = module;
+       dlthis->mysym = syms;
+
+       /* read in the doff image and store in our state variable */
+       dload_headers(dlthis);
+
+       if (!dlthis->dload_errcount)
+               dload_strings(dlthis, true);
+
+       /* skip ahead past the unread portion of the string table */
+       sec_start = sizeof(struct doff_filehdr_t) +
+           sizeof(struct doff_verify_rec_t) +
+           BYTE_TO_HOST(DOFF_ALIGN(dlthis->dfile_hdr.df_strtab_size));
+
+       if (dlthis->strm->set_file_posn(dlthis->strm, sec_start) != 0) {
+               dload_error(dlthis, seek, sec_start);
+               return NULL;
+       }
+
+       if (!dlthis->dload_errcount)
+               dload_sections(dlthis);
+
+       if (dlthis->dload_errcount) {
+               dload_module_close(dlthis);     /* errors, blow off our state */
+               dlthis = NULL;
+               return NULL;
+       }
+#if BITS_PER_AU > BITS_PER_BYTE
+       /* Expand all section names from the string table into the */
+       /* state variable, and convert section names from a relative */
+       /* string table offset to a pointers to the expanded string. */
+       expand_sec_names(dlthis);
+#else
+       /* Convert section names from a relative string table offset */
+       /* to a pointer into the string table. */
+       for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
+               struct ldr_section_info *shp =
+                   (struct ldr_section_info *)&dlthis->sect_hdrs[sec];
+               shp->name = dlthis->str_head + *(u32 *) &shp->name;
+       }
+#endif
+
+       return dlthis;
+}
+
+/***************************************************************************
+ * Procedure dload_get_section_info
+ *
+ * Parameters:
+ *  minfo              Handle from dload_module_open for this module
+ *     section_name    Pointer to the string name of the section desired
+ *     section_info    Address of a section info structure pointer to be
+ *                     initialized
+ *
+ * Effect:
+ *     Finds the specified section in the module information, and initializes
+ * the provided struct ldr_section_info pointer.
+ *
+ * Returns:
+ *     true for success, false for section not found
+ ************************************************************************* */
+int dload_get_section_info(void *minfo, const char *section_name,
+                          const struct ldr_section_info **const section_info)
+{
+       struct dload_state *dlthis;
+       struct ldr_section_info *shp;
+       u16 sec;
+
+       dlthis = (struct dload_state *)minfo;
+       if (!dlthis)
+               return false;
+
+       for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
+               shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec];
+               if (strcmp(section_name, shp->name) == 0) {
+                       *section_info = shp;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32))
+
+/**************************************************************************
+ * Procedure dload_get_section
+ *
+ * Parameters:
+ *  minfo              Handle from dload_module_open for this module
+ *     section_info    Pointer to a section info structure for the desired
+ *                     section
+ *     section_data    Buffer to contain the section initialized data
+ *
+ * Effect:
+ *     Copies the initialized data for the specified section into the
+ * supplied buffer.
+ *
+ * Returns:
+ *     true for success, false for section not found
+ ************************************************************************* */
+int dload_get_section(void *minfo,
+                     const struct ldr_section_info *section_info,
+                     void *section_data)
+{
+       struct dload_state *dlthis;
+       u32 pos;
+       struct doff_scnhdr_t *sptr = NULL;
+       s32 nip;
+       struct image_packet_t ipacket;
+       s32 ipsize;
+       u32 checks;
+       s8 *dest = (s8 *) section_data;
+
+       dlthis = (struct dload_state *)minfo;
+       if (!dlthis)
+               return false;
+       sptr = (struct doff_scnhdr_t *)section_info;
+       if (sptr == NULL)
+               return false;
+
+       /* skip ahead to the start of the first packet */
+       pos = BYTE_TO_HOST(DOFF_ALIGN((u32) sptr->ds_first_pkt_offset));
+       if (dlthis->strm->set_file_posn(dlthis->strm, pos) != 0) {
+               dload_error(dlthis, seek, pos);
+               return false;
+       }
+
+       nip = sptr->ds_nipacks;
+       while ((nip -= 1) >= 0) {       /* for each packet */
+               /* get the fixed header bits */
+               if (dlthis->strm->read_buffer(dlthis->strm, &ipacket,
+                                             IPH_SIZE) != IPH_SIZE) {
+                       dload_error(dlthis, readstrm, "image packet");
+                       return false;
+               }
+               /* reorder the header if need be */
+               if (dlthis->reorder_map)
+                       dload_reorder(&ipacket, IPH_SIZE, dlthis->reorder_map);
+
+               /* Now read the packet image bits. Note: round the size up to
+                * the next multiple of 4 bytes; this is what checksum
+                * routines want. */
+               ipsize = BYTE_TO_HOST(DOFF_ALIGN(ipacket.packet_size));
+               if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
+                       dload_error(dlthis, isiz, ipsize);
+                       return false;
+               }
+               if (dlthis->strm->read_buffer
+                   (dlthis->strm, dest, ipsize) != ipsize) {
+                       dload_error(dlthis, readstrm, "image packet");
+                       return false;
+               }
+               /* reorder the bytes if need be */
+#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
+               if (dlthis->reorder_map)
+                       dload_reorder(dest, ipsize, dlthis->reorder_map);
+
+               checks = dload_checksum(dest, ipsize);
+#else
+               if (dlthis->dfile_hdr.df_byte_reshuffle !=
+                   TARGET_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) {
+                       /* put image bytes in big-endian order, not PC order */
+                       dload_reorder(dest, ipsize,
+                                     TARGET_ORDER(dlthis->
+                                               dfile_hdr.df_byte_reshuffle));
+               }
+#if TARGET_AU_BITS > 8
+               checks = dload_reverse_checksum16(dest, ipsize);
+#else
+               checks = dload_reverse_checksum(dest, ipsize);
+#endif
+#endif
+               checks += dload_checksum(&ipacket, IPH_SIZE);
+
+               /* NYI: unable to handle relocation entries here.  Reloc
+                * entries referring to fields that span the packet boundaries
+                * may result in packets of sizes that are not multiple of
+                * 4 bytes. Our checksum implementation works on 32-bit words
+                * only. */
+               if (ipacket.num_relocs != 0) {
+                       dload_error(dlthis, err_reloc, ipsize);
+                       return false;
+               }
+
+               if (~checks) {
+                       dload_error(dlthis, err_checksum, "image packet");
+                       return false;
+               }
+
+               /*Advance destination ptr by the size of the just-read packet */
+               dest += ipsize;
+       }
+
+       return true;
+}
+
+/***************************************************************************
+ * Procedure dload_module_close
+ *
+ * Parameters:
+ *  minfo              Handle from dload_module_open for this module
+ *
+ * Effect:
+ *     Releases any storage associated with the module handle.  On return,
+ * the module handle is invalid.
+ *
+ * Returns:
+ *     Zero for success. On error, the number of errors detected is returned.
+ * Individual errors are reported using syms->error_report(), where syms was
+ * an argument to dload_module_open
+ ************************************************************************* */
+void dload_module_close(void *minfo)
+{
+       struct dload_state *dlthis;
+
+       dlthis = (struct dload_state *)minfo;
+       if (!dlthis)
+               return;
+
+       if (dlthis->str_head)
+               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               dlthis->str_head);
+
+       if (dlthis->sect_hdrs)
+               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               dlthis->sect_hdrs);
+
+#if BITS_PER_AU > BITS_PER_BYTE
+       if (dlthis->xstrings)
+               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               dlthis->xstrings);
+
+#endif
+
+       dlthis->mysym->dload_deallocate(dlthis->mysym, dlthis);
+}
diff --git a/drivers/staging/tidspbridge/dynload/header.h b/drivers/staging/tidspbridge/dynload/header.h
new file mode 100644 (file)
index 0000000..5b50a15
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * header.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/string.h>
+#define DL_STRCMP  strcmp
+
+/* maximum parenthesis nesting in relocation stack expressions */
+#define STATIC_EXPR_STK_SIZE 10
+
+#include <linux/types.h>
+
+#include "doff.h"
+#include <dspbridge/dynamic_loader.h>
+#include "params.h"
+#include "dload_internal.h"
+#include "reloc_table.h"
+
+/*
+ * Plausibility limits
+ *
+ * These limits are imposed upon the input DOFF file as a check for validity.
+ * They are hard limits, in that the load will fail if they are exceeded.
+ * The numbers selected are arbitrary, in that the loader implementation does
+ * not require these limits.
+ */
+
+/* maximum number of bytes in string table */
+#define MAX_REASONABLE_STRINGTAB (0x100000)
+/* maximum number of code,data,etc. sections */
+#define MAX_REASONABLE_SECTIONS (200)
+/* maximum number of linker symbols */
+#define MAX_REASONABLE_SYMBOLS (100000)
+
+/* shift count to align F_BIG with DLOAD_LITTLE */
+#define ALIGN_COFF_ENDIANNESS 7
+#define ENDIANNESS_MASK (DF_BYTE_ORDER >> ALIGN_COFF_ENDIANNESS)
diff --git a/drivers/staging/tidspbridge/dynload/module_list.h b/drivers/staging/tidspbridge/dynload/module_list.h
new file mode 100644 (file)
index 0000000..a216bb1
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * dspbridge/mpu_driver/src/dynload/module_list.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This C header file gives the layout of the data structure created by the
+ * dynamic loader to describe the set of modules loaded into the DSP.
+ *
+ * Linked List Structure:
+ * ----------------------
+ * The data structure defined here is a singly-linked list.  The list
+ * represents the set of modules which are currently loaded in the DSP memory.
+ * The first entry in the list is a header record which contains a flag
+ * representing the state of the list.  The rest of the entries in the list
+ * are module records.
+ *
+ * Global symbol  _DLModules designates the first record in the list (i.e. the
+ * header record).  This symbol must be defined in any program that wishes to
+ * use DLLview plug-in.
+ *
+ * String Representation:
+ * ----------------------
+ * The string names of the module and its sections are stored in a block of
+ * memory which follows the module record itself.  The strings are ordered:
+ * module name first, followed by section names in order from the first
+ * section to the last.  String names are tightly packed arrays of 8-bit
+ * characters (two characters per 16-bit word on the C55x).  Strings are
+ * zero-byte-terminated.
+ *
+ * Creating and updating the list:
+ * -------------------------------
+ * Upon loading a new module into the DSP memory the dynamic loader inserts a
+ * new module record as the first module record in the list.  The fields of
+ * this module record are initialized to reflect the properties of the module.
+ * The dynamic loader does NOT increment the flag/counter in the list's header
+ * record.
+ *
+ * Upon unloading a module from the DSP memory the dynamic loader removes the
+ * module's record from this list.  The dynamic loader also increments the
+ * flag/counter in the list's header record to indicate that the list has been
+ * changed.
+ */
+
+#ifndef _MODULE_LIST_H_
+#define _MODULE_LIST_H_
+
+#include <linux/types.h>
+
+/* Global pointer to the modules_header structure */
+#define MODULES_HEADER "_DLModules"
+#define MODULES_HEADER_NO_UNDERSCORE "DLModules"
+
+/* Initial version number */
+#define INIT_VERSION 1
+
+/* Verification number -- to be recorded in each module record */
+#define VERIFICATION 0x79
+
+/* forward declarations */
+struct dll_module;
+struct dll_sect;
+
+/* the first entry in the list is the modules_header record;
+ * its address is contained in the global _DLModules pointer */
+struct modules_header {
+
+       /*
+        * Address of the first dll_module record in the list or NULL.
+        * Note: for C55x this is a word address (C55x data is
+        * word-addressable)
+        */
+       u32 first_module;
+
+       /* Combined storage size (in target addressable units) of the
+        * dll_module record which follows this header record, or zero
+        * if the list is empty.  This size includes the module's string table.
+        * Note: for C55x the unit is a 16-bit word */
+       u16 first_module_size;
+
+       /* Counter is incremented whenever a module record is removed from
+        * the list */
+       u16 update_flag;
+
+};
+
+/* for each 32-bits in above structure, a bitmap, LSB first, whose bits are:
+ * 0 => a 32-bit value, 1 => 2 16-bit values */
+/* swapping bitmap for type modules_header */
+#define MODULES_HEADER_BITMAP 0x2
+
+/* information recorded about each section in a module */
+struct dll_sect {
+
+       /* Load-time address of the section.
+        * Note: for C55x this is a byte address for program sections, and
+        * a word address for data sections.  C55x program memory is
+        * byte-addressable, while data memory is word-addressable. */
+       u32 sect_load_adr;
+
+       /* Run-time address of the section.
+        * Note 1: for C55x this is a byte address for program sections, and
+        * a word address for data sections.
+        * Note 2: for C55x two most significant bits of this field indicate
+        * the section type: '00' for a code section, '11' for a data section
+        * (C55 addresses are really only 24-bits wide). */
+       u32 sect_run_adr;
+
+};
+
+/* the rest of the entries in the list are module records */
+struct dll_module {
+
+       /* Address of the next dll_module record in the list, or 0 if this is
+        * the last record in the list.
+        * Note: for C55x this is a word address (C55x data is
+        * word-addressable) */
+       u32 next_module;
+
+       /* Combined storage size (in target addressable units) of the
+        * dll_module record which follows this one, or zero if this is the
+        * last record in the list.  This size includes the module's string
+        * table.
+        * Note: for C55x the unit is a 16-bit word. */
+       u16 next_module_size;
+
+       /* version number of the tooling; set to INIT_VERSION for Phase 1 */
+       u16 version;
+
+       /* the verification word; set to VERIFICATION */
+       u16 verification;
+
+       /* Number of sections in the sects array */
+       u16 num_sects;
+
+       /* Module's "unique" id; copy of the timestamp from the host
+        * COFF file */
+       u32 timestamp;
+
+       /* Array of num_sects elements of the module's section records */
+       struct dll_sect sects[1];
+};
+
+/* for each 32 bits in above structure, a bitmap, LSB first, whose bits are:
+ * 0 => a 32-bit value, 1 => 2 16-bit values */
+#define DLL_MODULE_BITMAP 0x6  /* swapping bitmap for type dll_module */
+
+#endif /* _MODULE_LIST_H_ */
diff --git a/drivers/staging/tidspbridge/dynload/params.h b/drivers/staging/tidspbridge/dynload/params.h
new file mode 100644 (file)
index 0000000..d797fcd
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * params.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This file defines host and target properties for all machines
+ * supported by the dynamic loader.  To be tedious...
+ *
+ * host: the machine on which the dynamic loader runs
+ * target: the machine that the dynamic loader is loading
+ *
+ * Host and target may or may not be the same, depending upon the particular
+ * use.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/******************************************************************************
+ *
+ *                                                     Host Properties
+ *
+ **************************************************************************** */
+
+#define BITS_PER_BYTE 8                /* bits in the standard PC/SUN byte */
+#define LOG_BITS_PER_BYTE 3    /* log base 2 of same */
+#define BYTE_MASK ((1U<<BITS_PER_BYTE)-1)
+
+#if defined(__TMS320C55X__) || defined(_TMS320C5XX)
+#define BITS_PER_AU 16
+#define LOG_BITS_PER_AU 4
+ /* use this print string in error messages for uint32_t */
+#define FMT_UI32 "0x%lx"
+#define FMT8_UI32 "%08lx"      /* same but no 0x, fixed width field */
+#else
+/* bits in the smallest addressable data storage unit */
+#define BITS_PER_AU 8
+/* log base 2 of the same; useful for shift counts */
+#define LOG_BITS_PER_AU 3
+#define FMT_UI32 "0x%x"
+#define FMT8_UI32 "%08x"
+#endif
+
+/* generic fastest method for swapping bytes and shorts */
+#define SWAP32BY16(zz) (((zz) << 16) | ((zz) >> 16))
+#define SWAP16BY8(zz) (((zz) << 8) | ((zz) >> 8))
+
+/* !! don't be tempted to insert type definitions here; use <stdint.h> !! */
+
+/******************************************************************************
+ *
+ *                                                     Target Properties
+ *
+ **************************************************************************** */
+
+/*-------------------------------------------------------------------------- */
+/* TMS320C6x Target Specific Parameters (byte-addressable) */
+/*-------------------------------------------------------------------------- */
+#if TMS32060
+#define MEMORG          0x0L   /* Size of configured memory */
+#define MEMSIZE         0x0L   /* (full address space) */
+
+#define CINIT_ALIGN     8      /* alignment of cinit record in TDATA AUs */
+#define CINIT_COUNT    4       /* width of count field in TDATA AUs */
+#define CINIT_ADDRESS  4       /* width of address field in TDATA AUs */
+#define CINIT_PAGE_BITS        0       /* Number of LSBs of address that
+                                * are page number */
+
+#define LENIENT_SIGNED_RELEXPS 0       /* DOES SIGNED ALLOW MAX UNSIGNED */
+
+#undef TARGET_ENDIANNESS       /* may be big or little endian */
+
+/* align a target address to a word boundary */
+#define TARGET_WORD_ALIGN(zz) (((zz) + 0x3) & -0x4)
+#endif
+
+/*--------------------------------------------------------------------------
+ *
+ *                     DEFAULT SETTINGS and DERIVED PROPERTIES
+ *
+ * This section establishes defaults for values not specified above
+ *-------------------------------------------------------------------------- */
+#ifndef TARGET_AU_BITS
+#define TARGET_AU_BITS 8       /* width of the target addressable unit */
+#define LOG_TARGET_AU_BITS 3   /* log2 of same */
+#endif
+
+#ifndef CINIT_DEFAULT_PAGE
+#define CINIT_DEFAULT_PAGE 0   /* default .cinit page number */
+#endif
+
+#ifndef DATA_RUN2LOAD
+#define DATA_RUN2LOAD(zz) (zz) /* translate data run address to load address */
+#endif
+
+#ifndef DBG_LIST_PAGE
+#define DBG_LIST_PAGE 0                /* page number for .dllview section */
+#endif
+
+#ifndef TARGET_WORD_ALIGN
+/* align a target address to a word boundary */
+#define TARGET_WORD_ALIGN(zz) (zz)
+#endif
+
+#ifndef TDATA_TO_TADDR
+#define TDATA_TO_TADDR(zz) (zz)        /* target data address to target AU address */
+#define TADDR_TO_TDATA(zz) (zz)        /* target AU address to target data address */
+#define TDATA_AU_BITS  TARGET_AU_BITS  /* bits per data AU */
+#define LOG_TDATA_AU_BITS      LOG_TARGET_AU_BITS
+#endif
+
+/*
+ *
+ * Useful properties and conversions derived from the above
+ *
+ */
+
+/*
+ * Conversions between host and target addresses
+ */
+#if LOG_BITS_PER_AU == LOG_TARGET_AU_BITS
+/* translate target addressable unit to host address */
+#define TADDR_TO_HOST(x) (x)
+/* translate host address to target addressable unit */
+#define HOST_TO_TADDR(x) (x)
+#elif LOG_BITS_PER_AU > LOG_TARGET_AU_BITS
+#define TADDR_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS))
+#define HOST_TO_TADDR(x) ((x) << (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS))
+#else
+#define TADDR_TO_HOST(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU))
+#define HOST_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU))
+#endif
+
+#if LOG_BITS_PER_AU == LOG_TDATA_AU_BITS
+/* translate target addressable unit to host address */
+#define TDATA_TO_HOST(x) (x)
+/* translate host address to target addressable unit */
+#define HOST_TO_TDATA(x) (x)
+/* translate host address to target addressable unit, round up */
+#define HOST_TO_TDATA_ROUND(x) (x)
+/* byte offset to host offset, rounded up for TDATA size */
+#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x)
+#elif LOG_BITS_PER_AU > LOG_TDATA_AU_BITS
+#define TDATA_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
+#define HOST_TO_TDATA(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
+#define HOST_TO_TDATA_ROUND(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
+#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x)
+#else
+#define TDATA_TO_HOST(x) ((x) << (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
+#define HOST_TO_TDATA(x) ((x) >> (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
+#define HOST_TO_TDATA_ROUND(x) (((x) +\
+                               (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))-1) >>\
+                               (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
+#define BYTE_TO_HOST_TDATA_ROUND(x) (BYTE_TO_HOST((x) +\
+       (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_BYTE))-1) &\
+       -(TDATA_AU_BITS/BITS_PER_AU))
+#endif
+
+/*
+ * Input in DOFF format is always expresed in bytes, regardless of loading host
+ * so we wind up converting from bytes to target and host units even when the
+ * host is not a byte machine.
+ */
+#if LOG_BITS_PER_AU == LOG_BITS_PER_BYTE
+#define BYTE_TO_HOST(x) (x)
+#define BYTE_TO_HOST_ROUND(x) (x)
+#define HOST_TO_BYTE(x) (x)
+#elif LOG_BITS_PER_AU >= LOG_BITS_PER_BYTE
+#define BYTE_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
+#define BYTE_TO_HOST_ROUND(x) ((x + (BITS_PER_AU/BITS_PER_BYTE-1)) >>\
+                             (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
+#define HOST_TO_BYTE(x) ((x) << (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
+#else
+/* lets not try to deal with sub-8-bit byte machines */
+#endif
+
+#if LOG_TARGET_AU_BITS == LOG_BITS_PER_BYTE
+/* translate target addressable unit to byte address */
+#define TADDR_TO_BYTE(x) (x)
+/* translate byte address to target addressable unit */
+#define BYTE_TO_TADDR(x) (x)
+#elif LOG_TARGET_AU_BITS > LOG_BITS_PER_BYTE
+#define TADDR_TO_BYTE(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE))
+#define BYTE_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE))
+#else
+/* lets not try to deal with sub-8-bit byte machines */
+#endif
+
+#ifdef _BIG_ENDIAN
+#define HOST_ENDIANNESS 1
+#else
+#define HOST_ENDIANNESS 0
+#endif
+
+#ifdef TARGET_ENDIANNESS
+#define TARGET_ENDIANNESS_DIFFERS(rtend) (HOST_ENDIANNESS^TARGET_ENDIANNESS)
+#elif HOST_ENDIANNESS
+#define TARGET_ENDIANNESS_DIFFERS(rtend) (!(rtend))
+#else
+#define TARGET_ENDIANNESS_DIFFERS(rtend) (rtend)
+#endif
+
+/* the unit in which we process target image data */
+#if TARGET_AU_BITS <= 8
+typedef u8 tgt_au_t;
+#elif TARGET_AU_BITS <= 16
+typedef u16 tgt_au_t;
+#else
+typedef u32 tgt_au_t;
+#endif
+
+/* size of that unit */
+#if TARGET_AU_BITS < BITS_PER_AU
+#define TGTAU_BITS BITS_PER_AU
+#define LOG_TGTAU_BITS LOG_BITS_PER_AU
+#else
+#define TGTAU_BITS TARGET_AU_BITS
+#define LOG_TGTAU_BITS LOG_TARGET_AU_BITS
+#endif
diff --git a/drivers/staging/tidspbridge/dynload/reloc.c b/drivers/staging/tidspbridge/dynload/reloc.c
new file mode 100644 (file)
index 0000000..7b28c07
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+ * reloc.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "header.h"
+
+#if TMS32060
+/* the magic symbol for the start of BSS */
+static const char bsssymbol[] = { ".bss" };
+#endif
+
+#if TMS32060
+#include "reloc_table_c6000.c"
+#endif
+
+#if TMS32060
+/* From coff.h - ignore these relocation operations */
+#define R_C60ALIGN     0x76    /* C60: Alignment info for compressor */
+#define R_C60FPHEAD    0x77    /* C60: Explicit assembly directive */
+#define R_C60NOCMP    0x100    /* C60: Don't compress this code scn */
+#endif
+
+/**************************************************************************
+ * Procedure dload_unpack
+ *
+ * Parameters:
+ *     data    pointer to storage unit containing lowest host address of
+ *             image data
+ *     fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU
+ *     offset  Offset from LSB, 0 <= offset < BITS_PER_AU
+ *     sgn     Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY)
+ *
+ * Effect:
+ *     Extracts the specified field and returns it.
+ ************************************************************************* */
+rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data, int fieldsz,
+                   int offset, unsigned sgn)
+{
+       register rvalue objval;
+       register int shift, direction;
+       register tgt_au_t *dp = data;
+
+       fieldsz -= 1;   /* avoid nastiness with 32-bit shift of 32-bit value */
+       /* * collect up enough bits to contain the desired field */
+       if (TARGET_BIG_ENDIAN) {
+               dp += (fieldsz + offset) >> LOG_TGTAU_BITS;
+               direction = -1;
+       } else
+               direction = 1;
+       objval = *dp >> offset;
+       shift = TGTAU_BITS - offset;
+       while (shift <= fieldsz) {
+               dp += direction;
+               objval += (rvalue) *dp << shift;
+               shift += TGTAU_BITS;
+       }
+
+       /* * sign or zero extend the value appropriately */
+       if (sgn == ROP_UNS)
+               objval &= (2 << fieldsz) - 1;
+       else {
+               shift = sizeof(rvalue) * BITS_PER_AU - 1 - fieldsz;
+               objval = (objval << shift) >> shift;
+       }
+
+       return objval;
+
+}                              /* dload_unpack */
+
+/**************************************************************************
+ * Procedure dload_repack
+ *
+ * Parameters:
+ *     val             Value to insert
+ *     data    Pointer to storage unit containing lowest host address of
+ *             image data
+ *     fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU
+ *     offset  Offset from LSB, 0 <= offset < BITS_PER_AU
+ *     sgn     Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY)
+ *
+ * Effect:
+ *     Stuffs the specified value in the specified field.  Returns 0 for
+ *     success
+ * or 1 if the value will not fit in the specified field according to the
+ * specified signedness rule.
+ ************************************************************************* */
+static const unsigned char ovf_limit[] = { 1, 2, 2 };
+
+int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data,
+                int fieldsz, int offset, unsigned sgn)
+{
+       register urvalue objval, mask;
+       register int shift, direction;
+       register tgt_au_t *dp = data;
+
+       fieldsz -= 1;   /* avoid nastiness with 32-bit shift of 32-bit value */
+       /* clip the bits */
+       mask = (2UL << fieldsz) - 1;
+       objval = (val & mask);
+       /* * store the bits through the specified mask */
+       if (TARGET_BIG_ENDIAN) {
+               dp += (fieldsz + offset) >> LOG_TGTAU_BITS;
+               direction = -1;
+       } else
+               direction = 1;
+
+       /* insert LSBs */
+       *dp = (*dp & ~(mask << offset)) + (objval << offset);
+       shift = TGTAU_BITS - offset;
+       /* align mask and objval with AU boundary */
+       objval >>= shift;
+       mask >>= shift;
+
+       while (mask) {
+               dp += direction;
+               *dp = (*dp & ~mask) + objval;
+               objval >>= TGTAU_BITS;
+               mask >>= TGTAU_BITS;
+       }
+
+       /*
+        * check for overflow
+        */
+       if (sgn) {
+               unsigned tmp = (val >> fieldsz) + (sgn & 0x1);
+               if (tmp > ovf_limit[sgn - 1])
+                       return 1;
+       }
+       return 0;
+
+}                              /* dload_repack */
+
+/* lookup table for the scaling amount in a C6x instruction */
+#if TMS32060
+#define SCALE_BITS 4           /* there are 4 bits in the scale field */
+#define SCALE_MASK 0x7         /* we really only use the bottom 3 bits */
+static const u8 c60_scale[SCALE_MASK + 1] = {
+       1, 0, 0, 0, 1, 1, 2, 2
+};
+#endif
+
+/**************************************************************************
+ * Procedure dload_relocate
+ *
+ * Parameters:
+ *     data    Pointer to base of image data
+ *     rp              Pointer to relocation operation
+ *
+ * Effect:
+ *     Performs the specified relocation operation
+ ************************************************************************* */
+void dload_relocate(struct dload_state *dlthis, tgt_au_t * data,
+                   struct reloc_record_t *rp, bool *tramps_generated,
+                   bool second_pass)
+{
+       rvalue val, reloc_amt, orig_val = 0;
+       unsigned int fieldsz = 0;
+       unsigned int offset = 0;
+       unsigned int reloc_info = 0;
+       unsigned int reloc_action = 0;
+       register int rx = 0;
+       rvalue *stackp = NULL;
+       int top;
+       struct local_symbol *svp = NULL;
+#ifdef RFV_SCALE
+       unsigned int scale = 0;
+#endif
+       struct image_packet_t *img_pkt = NULL;
+
+       /* The image packet data struct is only used during first pass
+        * relocation in the event that a trampoline is needed.  2nd pass
+        * relocation doesn't guarantee that data is coming from an
+        * image_packet_t structure. See cload.c, dload_data for how img_data is
+        * set. If that changes this needs to be updated!!! */
+       if (second_pass == false)
+               img_pkt = (struct image_packet_t *)((u8 *) data -
+                                                   sizeof(struct
+                                                          image_packet_t));
+
+       rx = HASH_FUNC(rp->TYPE);
+       while (rop_map1[rx] != rp->TYPE) {
+               rx = HASH_L(rop_map2[rx]);
+               if (rx < 0) {
+#if TMS32060
+                       switch (rp->TYPE) {
+                       case R_C60ALIGN:
+                       case R_C60NOCMP:
+                       case R_C60FPHEAD:
+                               /* Ignore these reloc types and return */
+                               break;
+                       default:
+                               /* Unknown reloc type, print error and return */
+                               dload_error(dlthis, "Bad coff operator 0x%x",
+                                           rp->TYPE);
+                       }
+#else
+                       dload_error(dlthis, "Bad coff operator 0x%x", rp->TYPE);
+#endif
+                       return;
+               }
+       }
+       rx = HASH_I(rop_map2[rx]);
+       if ((rx < (sizeof(rop_action) / sizeof(u16)))
+           && (rx < (sizeof(rop_info) / sizeof(u16))) && (rx > 0)) {
+               reloc_action = rop_action[rx];
+               reloc_info = rop_info[rx];
+       } else {
+               dload_error(dlthis, "Buffer Overflow - Array Index Out "
+                           "of Bounds");
+       }
+
+       /* Compute the relocation amount for the referenced symbol, if any */
+       reloc_amt = rp->UVAL;
+       if (RFV_SYM(reloc_info)) {      /* relocation uses a symbol reference */
+               /* If this is first pass, use the module local symbol table,
+                * else use the trampoline symbol table. */
+               if (second_pass == false) {
+                       if ((u32) rp->SYMNDX < dlthis->dfile_hdr.df_no_syms) {
+                               /* real symbol reference */
+                               svp = &dlthis->local_symtab[rp->SYMNDX];
+                               reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ?
+                                   svp->delta : svp->value;
+                       }
+                       /* reloc references current section */
+                       else if (rp->SYMNDX == -1) {
+                               reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ?
+                                   dlthis->delta_runaddr :
+                                   dlthis->image_secn->run_addr;
+                       }
+               }
+       }
+       /* relocation uses a symbol reference */
+       /* Handle stack adjustment */
+       val = 0;
+       top = RFV_STK(reloc_info);
+       if (top) {
+               top += dlthis->relstkidx - RSTK_UOP;
+               if (top >= STATIC_EXPR_STK_SIZE) {
+                       dload_error(dlthis,
+                                   "Expression stack overflow in %s at offset "
+                                   FMT_UI32, dlthis->image_secn->name,
+                                   rp->vaddr + dlthis->image_offset);
+                       return;
+               }
+               val = dlthis->relstk[dlthis->relstkidx];
+               dlthis->relstkidx = top;
+               stackp = &dlthis->relstk[top];
+       }
+       /* Derive field position and size, if we need them */
+       if (reloc_info & ROP_RW) {      /* read or write action in our future */
+               fieldsz = RFV_WIDTH(reloc_action);
+               if (fieldsz) {  /* field info from table */
+                       offset = RFV_POSN(reloc_action);
+                       if (TARGET_BIG_ENDIAN)
+                               /* make sure vaddr is the lowest target
+                                * address containing bits */
+                               rp->vaddr += RFV_BIGOFF(reloc_info);
+               } else {        /* field info from relocation op */
+                       fieldsz = rp->FIELDSZ;
+                       offset = rp->OFFSET;
+                       if (TARGET_BIG_ENDIAN)
+                               /* make sure vaddr is the lowest target
+                                  address containing bits */
+                               rp->vaddr += (rp->WORDSZ - offset - fieldsz)
+                                   >> LOG_TARGET_AU_BITS;
+               }
+               data = (tgt_au_t *) ((char *)data + TADDR_TO_HOST(rp->vaddr));
+               /* compute lowest host location of referenced data */
+#if BITS_PER_AU > TARGET_AU_BITS
+               /* conversion from target address to host address may lose
+                  address bits; add loss to offset */
+               if (TARGET_BIG_ENDIAN) {
+                       offset += -((rp->vaddr << LOG_TARGET_AU_BITS) +
+                                   offset + fieldsz) &
+                           (BITS_PER_AU - TARGET_AU_BITS);
+               } else {
+                       offset += (rp->vaddr << LOG_TARGET_AU_BITS) &
+                           (BITS_PER_AU - 1);
+               }
+#endif
+#ifdef RFV_SCALE
+               scale = RFV_SCALE(reloc_info);
+#endif
+       }
+       /* read the object value from the current image, if so ordered */
+       if (reloc_info & ROP_R) {
+               /* relocation reads current image value */
+               val = dload_unpack(dlthis, data, fieldsz, offset,
+                                  RFV_SIGN(reloc_info));
+               /* Save off the original value in case the relo overflows and
+                * we can trampoline it. */
+               orig_val = val;
+
+#ifdef RFV_SCALE
+               val <<= scale;
+#endif
+       }
+       /* perform the necessary arithmetic */
+       switch (RFV_ACTION(reloc_action)) {     /* relocation actions */
+       case RACT_VAL:
+               break;
+       case RACT_ASGN:
+               val = reloc_amt;
+               break;
+       case RACT_ADD:
+               val += reloc_amt;
+               break;
+       case RACT_PCR:
+               /*-----------------------------------------------------------
+                * Handle special cases of jumping from absolute sections
+                * (special reloc type) or to absolute destination
+                * (symndx == -1).  In either case, set the appropriate
+                * relocation amount to 0.
+                *----------------------------------------------------------- */
+               if (rp->SYMNDX == -1)
+                       reloc_amt = 0;
+               val += reloc_amt - dlthis->delta_runaddr;
+               break;
+       case RACT_ADDISP:
+               val += rp->R_DISP + reloc_amt;
+               break;
+       case RACT_ASGPC:
+               val = dlthis->image_secn->run_addr + reloc_amt;
+               break;
+       case RACT_PLUS:
+               if (stackp != NULL)
+                       val += *stackp;
+               break;
+       case RACT_SUB:
+               if (stackp != NULL)
+                       val = *stackp - val;
+               break;
+       case RACT_NEG:
+               val = -val;
+               break;
+       case RACT_MPY:
+               if (stackp != NULL)
+                       val *= *stackp;
+               break;
+       case RACT_DIV:
+               if (stackp != NULL)
+                       val = *stackp / val;
+               break;
+       case RACT_MOD:
+               if (stackp != NULL)
+                       val = *stackp % val;
+               break;
+       case RACT_SR:
+               if (val >= sizeof(rvalue) * BITS_PER_AU)
+                       val = 0;
+               else if (stackp != NULL)
+                       val = (urvalue) *stackp >> val;
+               break;
+       case RACT_ASR:
+               if (val >= sizeof(rvalue) * BITS_PER_AU)
+                       val = sizeof(rvalue) * BITS_PER_AU - 1;
+               else if (stackp != NULL)
+                       val = *stackp >> val;
+               break;
+       case RACT_SL:
+               if (val >= sizeof(rvalue) * BITS_PER_AU)
+                       val = 0;
+               else if (stackp != NULL)
+                       val = *stackp << val;
+               break;
+       case RACT_AND:
+               if (stackp != NULL)
+                       val &= *stackp;
+               break;
+       case RACT_OR:
+               if (stackp != NULL)
+                       val |= *stackp;
+               break;
+       case RACT_XOR:
+               if (stackp != NULL)
+                       val ^= *stackp;
+               break;
+       case RACT_NOT:
+               val = ~val;
+               break;
+#if TMS32060
+       case RACT_C6SECT:
+               /* actually needed address of secn containing symbol */
+               if (svp != NULL) {
+                       if (rp->SYMNDX >= 0)
+                               if (svp->secnn > 0)
+                                       reloc_amt = dlthis->ldr_sections
+                                           [svp->secnn - 1].run_addr;
+               }
+               /* !!! FALL THRU !!! */
+       case RACT_C6BASE:
+               if (dlthis->bss_run_base == 0) {
+                       struct dynload_symbol *symp;
+                       symp = dlthis->mysym->find_matching_symbol
+                           (dlthis->mysym, bsssymbol);
+                       /* lookup value of global BSS base */
+                       if (symp)
+                               dlthis->bss_run_base = symp->value;
+                       else
+                               dload_error(dlthis,
+                                           "Global BSS base referenced in %s "
+                                           "offset" FMT_UI32 " but not "
+                                           "defined",
+                                           dlthis->image_secn->name,
+                                           rp->vaddr + dlthis->image_offset);
+               }
+               reloc_amt -= dlthis->bss_run_base;
+               /* !!! FALL THRU !!! */
+       case RACT_C6DSPL:
+               /* scale factor determined by 3 LSBs of field */
+               scale = c60_scale[val & SCALE_MASK];
+               offset += SCALE_BITS;
+               fieldsz -= SCALE_BITS;
+               val >>= SCALE_BITS;     /* ignore the scale field hereafter */
+               val <<= scale;
+               val += reloc_amt;       /* do the usual relocation */
+               if (((1 << scale) - 1) & val)
+                       dload_error(dlthis,
+                                   "Unaligned reference in %s offset "
+                                   FMT_UI32, dlthis->image_secn->name,
+                                   rp->vaddr + dlthis->image_offset);
+               break;
+#endif
+       }                       /* relocation actions */
+       /* * Put back result as required */
+       if (reloc_info & ROP_W) {       /* relocation writes image value */
+#ifdef RFV_SCALE
+               val >>= scale;
+#endif
+               if (dload_repack(dlthis, val, data, fieldsz, offset,
+                                RFV_SIGN(reloc_info))) {
+                       /* Check to see if this relo can be trampolined,
+                        * but only in first phase relocation.  2nd phase
+                        * relocation cannot trampoline. */
+                       if ((second_pass == false) &&
+                           (dload_tramp_avail(dlthis, rp) == true)) {
+
+                               /* Before generating the trampoline, restore
+                                * the value to its original so the 2nd pass
+                                *  relo will work. */
+                               dload_repack(dlthis, orig_val, data, fieldsz,
+                                            offset, RFV_SIGN(reloc_info));
+                               if (!dload_tramp_generate(dlthis,
+                                                       (dlthis->image_secn -
+                                                        dlthis->ldr_sections),
+                                                        dlthis->image_offset,
+                                                        img_pkt, rp)) {
+                                       dload_error(dlthis,
+                                                   "Failed to "
+                                                   "generate trampoline for "
+                                                   "bit overflow");
+                                       dload_error(dlthis,
+                                                   "Relocation val " FMT_UI32
+                                                   " overflows %d bits in %s "
+                                                   "offset " FMT_UI32, val,
+                                                   fieldsz,
+                                                   dlthis->image_secn->name,
+                                                   dlthis->image_offset +
+                                                   rp->vaddr);
+                               } else
+                                       *tramps_generated = true;
+                       } else {
+                               dload_error(dlthis, "Relocation value "
+                                           FMT_UI32 " overflows %d bits in %s"
+                                           " offset " FMT_UI32, val, fieldsz,
+                                           dlthis->image_secn->name,
+                                           dlthis->image_offset + rp->vaddr);
+                       }
+               }
+       } else if (top)
+               *stackp = val;
+}                              /* reloc_value */
diff --git a/drivers/staging/tidspbridge/dynload/reloc_table.h b/drivers/staging/tidspbridge/dynload/reloc_table.h
new file mode 100644 (file)
index 0000000..6aab03d
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * reloc_table.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _RELOC_TABLE_H_
+#define _RELOC_TABLE_H_
+/*
+ * Table of relocation operator properties
+ */
+#include <linux/types.h>
+
+/* How does this relocation operation access the program image? */
+#define ROP_N  0               /* does not access image */
+#define ROP_R  1               /* read from image */
+#define ROP_W  2               /* write to image */
+#define ROP_RW 3               /* read from and write to image */
+
+/* For program image access, what are the overflow rules for the bit field? */
+/* Beware! Procedure repack depends on this encoding */
+#define ROP_ANY        0               /* no overflow ever, just truncate the value */
+#define ROP_SGN        1               /* signed field */
+#define ROP_UNS        2               /* unsigned field */
+#define ROP_MAX 3      /* allow maximum range of either signed or unsigned */
+
+/* How does the relocation operation use the symbol reference */
+#define ROP_IGN        0               /* no symbol is referenced */
+#define ROP_LIT 0              /* use rp->UVAL literal field */
+#define ROP_SYM        1               /* symbol value is used in relocation */
+#define ROP_SYMD 2             /* delta value vs last link is used */
+
+/* How does the reloc op use the stack? */
+#define RSTK_N 0               /* Does not use */
+#define RSTK_POP 1             /* Does a POP */
+#define RSTK_UOP 2             /* Unary op, stack position unaffected */
+#define RSTK_PSH 3             /* Does a push */
+
+/*
+ * Computational actions performed by the dynamic loader
+ */
+enum dload_actions {
+       /* don't alter the current val (from stack or mem fetch) */
+       RACT_VAL,
+       /* set value to reference amount (from symbol reference) */
+       RACT_ASGN,
+       RACT_ADD,               /* add reference to value */
+       RACT_PCR,               /* add reference minus PC delta to value */
+       RACT_ADDISP,            /* add reference plus R_DISP */
+       RACT_ASGPC,             /* set value to section addr plus reference */
+
+       RACT_PLUS,              /* stack + */
+       RACT_SUB,               /* stack - */
+       RACT_NEG,               /* stack unary - */
+
+       RACT_MPY,               /* stack * */
+       RACT_DIV,               /* stack / */
+       RACT_MOD,               /* stack % */
+
+       RACT_SR,                /* stack unsigned >> */
+       RACT_ASR,               /* stack signed >> */
+       RACT_SL,                /* stack << */
+       RACT_AND,               /* stack & */
+       RACT_OR,                /* stack | */
+       RACT_XOR,               /* stack ^ */
+       RACT_NOT,               /* stack ~ */
+       RACT_C6SECT,            /* for C60 R_SECT op */
+       RACT_C6BASE,            /* for C60 R_BASE op */
+       RACT_C6DSPL,            /* for C60 scaled 15-bit displacement */
+       RACT_PCR23T             /* for ARM Thumb long branch */
+};
+
+/*
+ * macros used to extract values
+ */
+#define RFV_POSN(aaa) ((aaa) & 0xF)
+#define RFV_WIDTH(aaa) (((aaa) >> 4) & 0x3F)
+#define RFV_ACTION(aaa) ((aaa) >> 10)
+
+#define RFV_SIGN(iii) (((iii) >> 2) & 0x3)
+#define RFV_SYM(iii) (((iii) >> 4) & 0x3)
+#define RFV_STK(iii) (((iii) >> 6) & 0x3)
+#define RFV_ACCS(iii) ((iii) & 0x3)
+
+#if (TMS32060)
+#define RFV_SCALE(iii) ((iii) >> 11)
+#define RFV_BIGOFF(iii) (((iii) >> 8) & 0x7)
+#else
+#define RFV_BIGOFF(iii) ((iii) >> 8)
+#endif
+
+#endif /* _RELOC_TABLE_H_ */
diff --git a/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c b/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c
new file mode 100644 (file)
index 0000000..a28bc04
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * reloc_table_c6000.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Tables generated for c6000 */
+
+#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63)
+#define HASH_L(zz) ((zz) >> 8)
+#define HASH_I(zz) ((zz) & 0xFF)
+
+static const u16 rop_map1[] = {
+       0,
+       1,
+       2,
+       20,
+       4,
+       5,
+       6,
+       15,
+       80,
+       81,
+       82,
+       83,
+       84,
+       85,
+       86,
+       87,
+       17,
+       18,
+       19,
+       21,
+       16,
+       16394,
+       16404,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       32,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       40,
+       112,
+       113,
+       65535,
+       16384,
+       16385,
+       16386,
+       16387,
+       16388,
+       16389,
+       16390,
+       16391,
+       16392,
+       16393,
+       16395,
+       16396,
+       16397,
+       16398,
+       16399,
+       16400,
+       16401,
+       16402,
+       16403,
+       16405,
+       16406,
+       65535,
+       65535,
+       65535
+};
+
+static const s16 rop_map2[] = {
+       -256,
+       -255,
+       -254,
+       -245,
+       -253,
+       -252,
+       -251,
+       -250,
+       -241,
+       -240,
+       -239,
+       -238,
+       -237,
+       -236,
+       1813,
+       5142,
+       -248,
+       -247,
+       778,
+       -244,
+       -249,
+       -221,
+       -211,
+       -1,
+       -1,
+       -1,
+       -1,
+       -1,
+       -1,
+       -243,
+       -1,
+       -1,
+       -1,
+       -1,
+       -1,
+       -1,
+       -242,
+       -233,
+       -232,
+       -1,
+       -231,
+       -230,
+       -229,
+       -228,
+       -227,
+       -226,
+       -225,
+       -224,
+       -223,
+       5410,
+       -220,
+       -219,
+       -218,
+       -217,
+       -216,
+       -215,
+       -214,
+       -213,
+       5676,
+       -210,
+       -209,
+       -1,
+       -1,
+       -1
+};
+
+static const u16 rop_action[] = {
+       2560,
+       2304,
+       2304,
+       2432,
+       2432,
+       2560,
+       2176,
+       2304,
+       2560,
+       3200,
+       3328,
+       3584,
+       3456,
+       2304,
+       4208,
+       20788,
+       21812,
+       3415,
+       3245,
+       2311,
+       4359,
+       19764,
+       2311,
+       3191,
+       3280,
+       6656,
+       7680,
+       8704,
+       9728,
+       10752,
+       11776,
+       12800,
+       13824,
+       14848,
+       15872,
+       16896,
+       17920,
+       18944,
+       0,
+       0,
+       0,
+       0,
+       1536,
+       1536,
+       1536,
+       5632,
+       512,
+       0
+};
+
+static const u16 rop_info[] = {
+       0,
+       35,
+       35,
+       35,
+       35,
+       35,
+       35,
+       35,
+       35,
+       39,
+       39,
+       39,
+       39,
+       35,
+       34,
+       283,
+       299,
+       4135,
+       4391,
+       291,
+       33059,
+       283,
+       295,
+       4647,
+       4135,
+       64,
+       64,
+       128,
+       64,
+       64,
+       64,
+       64,
+       64,
+       64,
+       64,
+       64,
+       64,
+       128,
+       201,
+       197,
+       74,
+       70,
+       208,
+       196,
+       200,
+       192,
+       192,
+       66
+};
diff --git a/drivers/staging/tidspbridge/dynload/tramp.c b/drivers/staging/tidspbridge/dynload/tramp.c
new file mode 100644 (file)
index 0000000..60d22ea
--- /dev/null
@@ -0,0 +1,1143 @@
+/*
+ * tramp.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "header.h"
+
+#if TMS32060
+#include "tramp_table_c6000.c"
+#endif
+
+#define MAX_RELOS_PER_PASS     4
+
+/*
+ * Function:   priv_tramp_sect_tgt_alloc
+ * Description: Allocate target memory for the trampoline section.  The
+ *       target mem size is easily obtained as the next available address.
+ */
+static int priv_tramp_sect_tgt_alloc(struct dload_state *dlthis)
+{
+       int ret_val = 0;
+       struct ldr_section_info *sect_info;
+
+       /*  Populate the trampoline loader section and allocate it on the
+        * target.  The section name is ALWAYS the first string in the final
+        * string table for trampolines.  The trampoline section is always
+        * 1 beyond the total number of allocated sections. */
+       sect_info = &dlthis->ldr_sections[dlthis->allocated_secn_count];
+
+       sect_info->name = dlthis->tramp.final_string_table;
+       sect_info->size = dlthis->tramp.tramp_sect_next_addr;
+       sect_info->context = 0;
+       sect_info->type =
+           (4 << 8) | DLOAD_TEXT | DS_ALLOCATE_MASK | DS_DOWNLOAD_MASK;
+       sect_info->page = 0;
+       sect_info->run_addr = 0;
+       sect_info->load_addr = 0;
+       ret_val = dlthis->myalloc->dload_allocate(dlthis->myalloc,
+                                                 sect_info,
+                                                 ds_alignment
+                                                 (sect_info->type));
+
+       if (ret_val == 0)
+               dload_error(dlthis, "Failed to allocate target memory for"
+                           " trampoline");
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_h2a
+ * Description: Helper function to convert a hex value to its ASCII
+ *       representation.  Used for trampoline symbol name generation.
+ */
+static u8 priv_h2a(u8 value)
+{
+       if (value > 0xF)
+               return 0xFF;
+
+       if (value <= 9)
+               value += 0x30;
+       else
+               value += 0x37;
+
+       return value;
+}
+
+/*
+ * Function:   priv_tramp_sym_gen_name
+ * Description: Generate a trampoline symbol name (ASCII) using the value
+ *       of the symbol.  This places the new name into the user buffer.
+ *       The name is fixed in length and of the form: __$dbTR__xxxxxxxx
+ *       (where "xxxxxxxx" is the hex value.
+ */
+static void priv_tramp_sym_gen_name(u32 value, char *dst)
+{
+       u32 i;
+       char *prefix = TRAMP_SYM_PREFIX;
+       char *dst_local = dst;
+       u8 tmp;
+
+       /*  Clear out the destination, including the ending NULL */
+       for (i = 0; i < (TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN); i++)
+               *(dst_local + i) = 0;
+
+       /*  Copy the prefix to start */
+       for (i = 0; i < strlen(TRAMP_SYM_PREFIX); i++) {
+               *dst_local = *(prefix + i);
+               dst_local++;
+       }
+
+       /*  Now convert the value passed in to a string equiv of the hex */
+       for (i = 0; i < sizeof(value); i++) {
+#ifndef _BIG_ENDIAN
+               tmp = *(((u8 *) &value) + (sizeof(value) - 1) - i);
+               *dst_local = priv_h2a((tmp & 0xF0) >> 4);
+               dst_local++;
+               *dst_local = priv_h2a(tmp & 0x0F);
+               dst_local++;
+#else
+               tmp = *(((u8 *) &value) + i);
+               *dst_local = priv_h2a((tmp & 0xF0) >> 4);
+               dst_local++;
+               *dst_local = priv_h2a(tmp & 0x0F);
+               dst_local++;
+#endif
+       }
+
+       /*  NULL terminate */
+       *dst_local = 0;
+}
+
+/*
+ * Function:   priv_tramp_string_create
+ * Description: Create a new string specific to the trampoline loading and add
+ *       it to the trampoline string list.  This list contains the
+ *       trampoline section name and trampoline point symbols.
+ */
+static struct tramp_string *priv_tramp_string_create(struct dload_state *dlthis,
+                                                    u32 str_len, char *str)
+{
+       struct tramp_string *new_string = NULL;
+       u32 i;
+
+       /*  Create a new string object with the specified size. */
+       new_string =
+           (struct tramp_string *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                                                (sizeof
+                                                                 (struct
+                                                                  tramp_string)
+                                                                 + str_len +
+                                                                 1));
+       if (new_string != NULL) {
+               /*  Clear the string first.  This ensures the ending NULL is
+                * present and the optimizer won't touch it. */
+               for (i = 0; i < (sizeof(struct tramp_string) + str_len + 1);
+                    i++)
+                       *((u8 *) new_string + i) = 0;
+
+               /*  Add this string to our virtual table by assigning it the
+                * next index and pushing it to the tail of the list. */
+               new_string->index = dlthis->tramp.tramp_string_next_index;
+               dlthis->tramp.tramp_string_next_index++;
+               dlthis->tramp.tramp_string_size += str_len + 1;
+
+               new_string->next = NULL;
+               if (dlthis->tramp.string_head == NULL)
+                       dlthis->tramp.string_head = new_string;
+               else
+                       dlthis->tramp.string_tail->next = new_string;
+
+               dlthis->tramp.string_tail = new_string;
+
+               /*  Copy the string over to the new object */
+               for (i = 0; i < str_len; i++)
+                       new_string->str[i] = str[i];
+       }
+
+       return new_string;
+}
+
+/*
+ * Function:   priv_tramp_string_find
+ * Description: Walk the trampoline string list and find a match for the
+ *       provided string.  If not match is found, NULL is returned.
+ */
+static struct tramp_string *priv_tramp_string_find(struct dload_state *dlthis,
+                                                  char *str)
+{
+       struct tramp_string *cur_str = NULL;
+       struct tramp_string *ret_val = NULL;
+       u32 i;
+       u32 str_len = strlen(str);
+
+       for (cur_str = dlthis->tramp.string_head;
+            (ret_val == NULL) && (cur_str != NULL); cur_str = cur_str->next) {
+               /*  If the string lengths aren't equal, don't bother
+                * comparing */
+               if (str_len != strlen(cur_str->str))
+                       continue;
+
+               /*  Walk the strings until one of them ends */
+               for (i = 0; i < str_len; i++) {
+                       /*  If they don't match in the current position then
+                        * break out now, no sense in continuing to look at
+                        * this string. */
+                       if (str[i] != cur_str->str[i])
+                               break;
+               }
+
+               if (i == str_len)
+                       ret_val = cur_str;
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_string_tbl_finalize
+ * Description: Flatten the trampoline string list into a table of NULL
+ *       terminated strings.  This is the same format of string table
+ *       as used by the COFF/DOFF file.
+ */
+static int priv_string_tbl_finalize(struct dload_state *dlthis)
+{
+       int ret_val = 0;
+       struct tramp_string *cur_string;
+       char *cur_loc;
+       char *tmp;
+
+       /*  Allocate enough space for all strings that have been created.  The
+        * table is simply all strings concatenated together will NULL
+        * endings. */
+       dlthis->tramp.final_string_table =
+           (char *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                                 dlthis->tramp.
+                                                 tramp_string_size);
+       if (dlthis->tramp.final_string_table != NULL) {
+               /*  We got our buffer, walk the list and release the nodes as*
+                * we go */
+               cur_loc = dlthis->tramp.final_string_table;
+               cur_string = dlthis->tramp.string_head;
+               while (cur_string != NULL) {
+                       /*  Move the head/tail pointers */
+                       dlthis->tramp.string_head = cur_string->next;
+                       if (dlthis->tramp.string_tail == cur_string)
+                               dlthis->tramp.string_tail = NULL;
+
+                       /*  Copy the string contents */
+                       for (tmp = cur_string->str;
+                            *tmp != '\0'; tmp++, cur_loc++)
+                               *cur_loc = *tmp;
+
+                       /*  Pick up the NULL termination since it was missed by
+                        * breaking using it to end the above loop. */
+                       *cur_loc = '\0';
+                       cur_loc++;
+
+                       /*  Free the string node, we don't need it any more. */
+                       dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                                       cur_string);
+
+                       /*  Move our pointer to the next one */
+                       cur_string = dlthis->tramp.string_head;
+               }
+
+               /*  Update our return value to success */
+               ret_val = 1;
+       } else
+               dload_error(dlthis, "Failed to allocate trampoline "
+                           "string table");
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_tramp_sect_alloc
+ * Description: Virtually allocate space from the trampoline section.  This
+ *       function returns the next offset within the trampoline section
+ *       that is available and moved the next available offset by the
+ *       requested size.  NO TARGET ALLOCATION IS DONE AT THIS TIME.
+ */
+static u32 priv_tramp_sect_alloc(struct dload_state *dlthis, u32 tramp_size)
+{
+       u32 ret_val;
+
+       /*  If the next available address is 0, this is our first allocation.
+        * Create a section name string to go into the string table . */
+       if (dlthis->tramp.tramp_sect_next_addr == 0) {
+               dload_syms_error(dlthis->mysym, "*** WARNING ***  created "
+                                "dynamic TRAMPOLINE section for module %s",
+                                dlthis->str_head);
+       }
+
+       /*  Reserve space for the new trampoline */
+       ret_val = dlthis->tramp.tramp_sect_next_addr;
+       dlthis->tramp.tramp_sect_next_addr += tramp_size;
+       return ret_val;
+}
+
+/*
+ * Function:   priv_tramp_sym_create
+ * Description: Allocate and create a new trampoline specific symbol and add
+ *       it to the trampoline symbol list.  These symbols will include
+ *       trampoline points as well as the external symbols they
+ *       reference.
+ */
+static struct tramp_sym *priv_tramp_sym_create(struct dload_state *dlthis,
+                                              u32 str_index,
+                                              struct local_symbol *tmp_sym)
+{
+       struct tramp_sym *new_sym = NULL;
+       u32 i;
+
+       /*  Allocate new space for the symbol in the symbol table. */
+       new_sym =
+           (struct tramp_sym *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                             sizeof(struct tramp_sym));
+       if (new_sym != NULL) {
+               for (i = 0; i != sizeof(struct tramp_sym); i++)
+                       *((char *)new_sym + i) = 0;
+
+               /*  Assign this symbol the next symbol index for easier
+                * reference later during relocation. */
+               new_sym->index = dlthis->tramp.tramp_sym_next_index;
+               dlthis->tramp.tramp_sym_next_index++;
+
+               /*  Populate the symbol information.  At this point any
+                * trampoline symbols will be the offset location, not the
+                * final.  Copy over the symbol info to start, then be sure to
+                * get the string index from the trampoline string table. */
+               new_sym->sym_info = *tmp_sym;
+               new_sym->str_index = str_index;
+
+               /*  Push the new symbol to the tail of the symbol table list */
+               new_sym->next = NULL;
+               if (dlthis->tramp.symbol_head == NULL)
+                       dlthis->tramp.symbol_head = new_sym;
+               else
+                       dlthis->tramp.symbol_tail->next = new_sym;
+
+               dlthis->tramp.symbol_tail = new_sym;
+       }
+
+       return new_sym;
+}
+
+/*
+ * Function:   priv_tramp_sym_get
+ * Description: Search for the symbol with the matching string index (from
+ *       the trampoline string table) and return the trampoline
+ *       symbol object, if found.  Otherwise return NULL.
+ */
+static struct tramp_sym *priv_tramp_sym_get(struct dload_state *dlthis,
+                                           u32 string_index)
+{
+       struct tramp_sym *sym_found = NULL;
+
+       /*  Walk the symbol table list and search vs. the string index */
+       for (sym_found = dlthis->tramp.symbol_head;
+            sym_found != NULL; sym_found = sym_found->next) {
+               if (sym_found->str_index == string_index)
+                       break;
+       }
+
+       return sym_found;
+}
+
+/*
+ * Function:   priv_tramp_sym_find
+ * Description: Search for a trampoline symbol based on the string name of
+ *       the symbol.  Return the symbol object, if found, otherwise
+ *       return NULL.
+ */
+static struct tramp_sym *priv_tramp_sym_find(struct dload_state *dlthis,
+                                            char *string)
+{
+       struct tramp_sym *sym_found = NULL;
+       struct tramp_string *str_found = NULL;
+
+       /*  First, search for the string, then search for the sym based on the
+          string index. */
+       str_found = priv_tramp_string_find(dlthis, string);
+       if (str_found != NULL)
+               sym_found = priv_tramp_sym_get(dlthis, str_found->index);
+
+       return sym_found;
+}
+
+/*
+ * Function:   priv_tramp_sym_finalize
+ * Description: Allocate a flat symbol table for the trampoline section,
+ *       put each trampoline symbol into the table, adjust the
+ *       symbol value based on the section address on the target and
+ *       free the trampoline symbol list nodes.
+ */
+static int priv_tramp_sym_finalize(struct dload_state *dlthis)
+{
+       int ret_val = 0;
+       struct tramp_sym *cur_sym;
+       struct ldr_section_info *tramp_sect =
+           &dlthis->ldr_sections[dlthis->allocated_secn_count];
+       struct local_symbol *new_sym;
+
+       /*  Allocate a table to hold a flattened version of all symbols
+        * created. */
+       dlthis->tramp.final_sym_table =
+           (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                (sizeof(struct local_symbol) * dlthis->tramp.
+                                                 tramp_sym_next_index));
+       if (dlthis->tramp.final_sym_table != NULL) {
+               /*  Walk the list of all symbols, copy it over to the flattened
+                * table. After it has been copied, the node can be freed as
+                * it is no longer needed. */
+               new_sym = dlthis->tramp.final_sym_table;
+               cur_sym = dlthis->tramp.symbol_head;
+               while (cur_sym != NULL) {
+                       /*  Pop it off the list */
+                       dlthis->tramp.symbol_head = cur_sym->next;
+                       if (cur_sym == dlthis->tramp.symbol_tail)
+                               dlthis->tramp.symbol_tail = NULL;
+
+                       /*  Copy the symbol contents into the flat table */
+                       *new_sym = cur_sym->sym_info;
+
+                       /*  Now finaize the symbol.  If it is in the tramp
+                        * section, we need to adjust for the section start.
+                        * If it is external then we don't need to adjust at
+                        * all.
+                        * NOTE: THIS CODE ASSUMES THAT THE TRAMPOLINE IS
+                        * REFERENCED LIKE A CALL TO AN EXTERNAL SO VALUE AND
+                        * DELTA ARE THE SAME.  SEE THE FUNCTION dload_symbols
+                        * WHERE DN_UNDEF IS HANDLED FOR MORE REFERENCE. */
+                       if (new_sym->secnn < 0) {
+                               new_sym->value += tramp_sect->load_addr;
+                               new_sym->delta = new_sym->value;
+                       }
+
+                       /*  Let go of the symbol node */
+                       dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);
+
+                       /*  Move to the next node */
+                       cur_sym = dlthis->tramp.symbol_head;
+                       new_sym++;
+               }
+
+               ret_val = 1;
+       } else
+               dload_error(dlthis, "Failed to alloc trampoline sym table");
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_tgt_img_gen
+ * Description: Allocate storage for and copy the target specific image data
+ *     and fix up its relocations for the new external symbol.  If
+ *     a trampoline image packet was successfully created it is added
+ *     to the trampoline list.
+ */
+static int priv_tgt_img_gen(struct dload_state *dlthis, u32 base,
+                           u32 gen_index, struct tramp_sym *new_ext_sym)
+{
+       struct tramp_img_pkt *new_img_pkt = NULL;
+       u32 i;
+       u32 pkt_size = tramp_img_pkt_size_get();
+       u8 *gen_tbl_entry;
+       u8 *pkt_data;
+       struct reloc_record_t *cur_relo;
+       int ret_val = 0;
+
+       /*  Allocate a new image packet and set it up. */
+       new_img_pkt =
+           (struct tramp_img_pkt *)dlthis->mysym->dload_allocate(dlthis->mysym,
+                                                                 pkt_size);
+       if (new_img_pkt != NULL) {
+               /*  Save the base, this is where it goes in the section */
+               new_img_pkt->base = base;
+
+               /*  Copy over the image data and relos from the target table */
+               pkt_data = (u8 *) &new_img_pkt->hdr;
+               gen_tbl_entry = (u8 *) &tramp_gen_info[gen_index];
+               for (i = 0; i < pkt_size; i++) {
+                       *pkt_data = *gen_tbl_entry;
+                       pkt_data++;
+                       gen_tbl_entry++;
+               }
+
+               /*  Update the relocations to point to the external symbol */
+               cur_relo =
+                   (struct reloc_record_t *)((u8 *) &new_img_pkt->hdr +
+                                             new_img_pkt->hdr.relo_offset);
+               for (i = 0; i < new_img_pkt->hdr.num_relos; i++)
+                       cur_relo[i].SYMNDX = new_ext_sym->index;
+
+               /*  Add it to the trampoline list. */
+               new_img_pkt->next = dlthis->tramp.tramp_pkts;
+               dlthis->tramp.tramp_pkts = new_img_pkt;
+
+               ret_val = 1;
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_pkt_relo
+ * Description: Take the provided image data and the collection of relocations
+ *       for it and perform the relocations.  Note that all relocations
+ *       at this stage are considered SECOND PASS since the original
+ *       image has already been processed in the first pass.  This means
+ *       TRAMPOLINES ARE TREATED AS 2ND PASS even though this is really
+ *       the first (and only) relocation that will be performed on them.
+ */
+static int priv_pkt_relo(struct dload_state *dlthis, tgt_au_t * data,
+                        struct reloc_record_t *rp[], u32 relo_count)
+{
+       int ret_val = 1;
+       u32 i;
+       bool tmp;
+
+       /*  Walk through all of the relos and process them.  This function is
+        * the equivalent of relocate_packet() from cload.c, but specialized
+        * for trampolines and 2nd phase relocations. */
+       for (i = 0; i < relo_count; i++)
+               dload_relocate(dlthis, data, rp[i], &tmp, true);
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_tramp_pkt_finalize
+ * Description: Walk the list of all trampoline packets and finalize them.
+ *       Each trampoline image packet will be relocated now that the
+ *       trampoline section has been allocated on the target.  Once
+ *       all of the relocations are done the trampoline image data
+ *       is written into target memory and the trampoline packet
+ *       is freed: it is no longer needed after this point.
+ */
+static int priv_tramp_pkt_finalize(struct dload_state *dlthis)
+{
+       int ret_val = 1;
+       struct tramp_img_pkt *cur_pkt = NULL;
+       struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
+       u32 relos_done;
+       u32 i;
+       struct reloc_record_t *cur_relo;
+       struct ldr_section_info *sect_info =
+           &dlthis->ldr_sections[dlthis->allocated_secn_count];
+
+       /*  Walk the list of trampoline packets and relocate each packet.  This
+        * function is the trampoline equivalent of dload_data() from
+        * cload.c. */
+       cur_pkt = dlthis->tramp.tramp_pkts;
+       while ((ret_val != 0) && (cur_pkt != NULL)) {
+               /*  Remove the pkt from the list */
+               dlthis->tramp.tramp_pkts = cur_pkt->next;
+
+               /*  Setup section and image offset information for the relo */
+               dlthis->image_secn = sect_info;
+               dlthis->image_offset = cur_pkt->base;
+               dlthis->delta_runaddr = sect_info->run_addr;
+
+               /*  Walk through all relos for the packet */
+               relos_done = 0;
+               cur_relo = (struct reloc_record_t *)((u8 *) &cur_pkt->hdr +
+                                                    cur_pkt->hdr.relo_offset);
+               while (relos_done < cur_pkt->hdr.num_relos) {
+#ifdef ENABLE_TRAMP_DEBUG
+                       dload_syms_error(dlthis->mysym,
+                                        "===> Trampoline %x branches to %x",
+                                        sect_info->run_addr +
+                                        dlthis->image_offset,
+                                        dlthis->
+                                        tramp.final_sym_table[cur_relo->
+                                                              SYMNDX].value);
+#endif
+
+                       for (i = 0;
+                            ((i < MAX_RELOS_PER_PASS) &&
+                             ((i + relos_done) < cur_pkt->hdr.num_relos)); i++)
+                               relos[i] = cur_relo + i;
+
+                       /*  Do the actual relo */
+                       ret_val = priv_pkt_relo(dlthis,
+                                               (tgt_au_t *) &cur_pkt->payload,
+                                               relos, i);
+                       if (ret_val == 0) {
+                               dload_error(dlthis,
+                                           "Relocation of trampoline pkt at %x"
+                                           " failed", cur_pkt->base +
+                                           sect_info->run_addr);
+                               break;
+                       }
+
+                       relos_done += i;
+                       cur_relo += i;
+               }
+
+               /*  Make sure we didn't hit a problem */
+               if (ret_val != 0) {
+                       /*  Relos are done for the packet, write it to the
+                        * target */
+                       ret_val = dlthis->myio->writemem(dlthis->myio,
+                                                        &cur_pkt->payload,
+                                                        sect_info->load_addr +
+                                                        cur_pkt->base,
+                                                        sect_info,
+                                                        BYTE_TO_HOST
+                                                        (cur_pkt->hdr.
+                                                         tramp_code_size));
+                       if (ret_val == 0) {
+                               dload_error(dlthis,
+                                           "Write to " FMT_UI32 " failed",
+                                           sect_info->load_addr +
+                                           cur_pkt->base);
+                       }
+
+                       /*  Done with the pkt, let it go */
+                       dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);
+
+                       /*  Get the next packet to process */
+                       cur_pkt = dlthis->tramp.tramp_pkts;
+               }
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_dup_pkt_finalize
+ * Description: Walk the list of duplicate image packets and finalize them.
+ *       Each duplicate packet will be relocated again for the
+ *       relocations that previously failed and have been adjusted
+ *       to point at a trampoline.  Once all relocations for a packet
+ *       have been done, write the packet into target memory.  The
+ *       duplicate packet and its relocation chain are all freed
+ *       after use here as they are no longer needed after this.
+ */
+static int priv_dup_pkt_finalize(struct dload_state *dlthis)
+{
+       int ret_val = 1;
+       struct tramp_img_dup_pkt *cur_pkt;
+       struct tramp_img_dup_relo *cur_relo;
+       struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
+       struct doff_scnhdr_t *sect_hdr = NULL;
+       s32 i;
+
+       /* Similar to the trampoline pkt finalize, this function walks each dup
+        * pkt that was generated and performs all relocations that were
+        * deferred to a 2nd pass.  This is the equivalent of dload_data() from
+        * cload.c, but does not need the additional reorder and checksum
+        * processing as it has already been done. */
+       cur_pkt = dlthis->tramp.dup_pkts;
+       while ((ret_val != 0) && (cur_pkt != NULL)) {
+               /*  Remove the node from the list, we'll be freeing it
+                * shortly */
+               dlthis->tramp.dup_pkts = cur_pkt->next;
+
+               /*  Setup the section and image offset for relocation */
+               dlthis->image_secn = &dlthis->ldr_sections[cur_pkt->secnn];
+               dlthis->image_offset = cur_pkt->offset;
+
+               /*  In order to get the delta run address, we need to reference
+                * the original section header.  It's a bit ugly, but needed
+                * for relo. */
+               i = (s32) (dlthis->image_secn - dlthis->ldr_sections);
+               sect_hdr = dlthis->sect_hdrs + i;
+               dlthis->delta_runaddr = sect_hdr->ds_paddr;
+
+               /*  Walk all relos in the chain and process each. */
+               cur_relo = cur_pkt->relo_chain;
+               while (cur_relo != NULL) {
+                       /*  Process them a chunk at a time to be efficient */
+                       for (i = 0; (i < MAX_RELOS_PER_PASS)
+                            && (cur_relo != NULL);
+                            i++, cur_relo = cur_relo->next) {
+                               relos[i] = &cur_relo->relo;
+                               cur_pkt->relo_chain = cur_relo->next;
+                       }
+
+                       /*  Do the actual relo */
+                       ret_val = priv_pkt_relo(dlthis,
+                                               cur_pkt->img_pkt.img_data,
+                                               relos, i);
+                       if (ret_val == 0) {
+                               dload_error(dlthis,
+                                           "Relocation of dup pkt at %x"
+                                           " failed", cur_pkt->offset +
+                                           dlthis->image_secn->run_addr);
+                               break;
+                       }
+
+                       /*  Release all of these relos, we're done with them */
+                       while (i > 0) {
+                               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               GET_CONTAINER
+                                               (relos[i - 1],
+                                                struct tramp_img_dup_relo,
+                                                relo));
+                               i--;
+                       }
+
+                       /*  DO NOT ADVANCE cur_relo, IT IS ALREADY READY TO
+                        * GO! */
+               }
+
+               /* Done with all relos.  Make sure we didn't have a problem and
+                * write it out to the target */
+               if (ret_val != 0) {
+                       ret_val = dlthis->myio->writemem(dlthis->myio,
+                                                        cur_pkt->img_pkt.
+                                                        img_data,
+                                                        dlthis->image_secn->
+                                                        load_addr +
+                                                        cur_pkt->offset,
+                                                        dlthis->image_secn,
+                                                        BYTE_TO_HOST
+                                                        (cur_pkt->img_pkt.
+                                                         packet_size));
+                       if (ret_val == 0) {
+                               dload_error(dlthis,
+                                           "Write to " FMT_UI32 " failed",
+                                           dlthis->image_secn->load_addr +
+                                           cur_pkt->offset);
+                       }
+
+                       dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);
+
+                       /*  Advance to the next packet */
+                       cur_pkt = dlthis->tramp.dup_pkts;
+               }
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   priv_dup_find
+ * Description: Walk the list of existing duplicate packets and find a
+ *       match based on the section number and image offset.  Return
+ *       the duplicate packet if found, otherwise NULL.
+ */
+static struct tramp_img_dup_pkt *priv_dup_find(struct dload_state *dlthis,
+                                              s16 secnn, u32 image_offset)
+{
+       struct tramp_img_dup_pkt *cur_pkt = NULL;
+
+       for (cur_pkt = dlthis->tramp.dup_pkts;
+            cur_pkt != NULL; cur_pkt = cur_pkt->next) {
+               if ((cur_pkt->secnn == secnn) &&
+                   (cur_pkt->offset == image_offset)) {
+                       /*  Found a match, break out */
+                       break;
+               }
+       }
+
+       return cur_pkt;
+}
+
+/*
+ * Function:   priv_img_pkt_dup
+ * Description: Duplicate the original image packet.  If this is the first
+ *       time this image packet has been seen (based on section number
+ *       and image offset), create a new duplicate packet and add it
+ *       to the dup packet list.  If not, just get the existing one and
+ *       update it with the current packet contents (since relocation
+ *       on the packet is still ongoing in first pass.)  Create a
+ *       duplicate of the provided relocation, but update it to point
+ *       to the new trampoline symbol.  Add the new relocation dup to
+ *       the dup packet's relo chain for 2nd pass relocation later.
+ */
+static int priv_img_pkt_dup(struct dload_state *dlthis,
+                           s16 secnn, u32 image_offset,
+                           struct image_packet_t *ipacket,
+                           struct reloc_record_t *rp,
+                           struct tramp_sym *new_tramp_sym)
+{
+       struct tramp_img_dup_pkt *dup_pkt = NULL;
+       u32 new_dup_size;
+       s32 i;
+       int ret_val = 0;
+       struct tramp_img_dup_relo *dup_relo = NULL;
+
+       /*  Determinne if this image packet is already being tracked in the
+          dup list for other trampolines. */
+       dup_pkt = priv_dup_find(dlthis, secnn, image_offset);
+
+       if (dup_pkt == NULL) {
+               /*  This image packet does not exist in our tracking, so create
+                * a new one and add it to the head of the list. */
+               new_dup_size = sizeof(struct tramp_img_dup_pkt) +
+                   ipacket->packet_size;
+
+               dup_pkt = (struct tramp_img_dup_pkt *)
+                   dlthis->mysym->dload_allocate(dlthis->mysym, new_dup_size);
+               if (dup_pkt != NULL) {
+                       /*  Save off the section and offset information */
+                       dup_pkt->secnn = secnn;
+                       dup_pkt->offset = image_offset;
+                       dup_pkt->relo_chain = NULL;
+
+                       /*  Copy the original packet content */
+                       dup_pkt->img_pkt = *ipacket;
+                       dup_pkt->img_pkt.img_data = (u8 *) (dup_pkt + 1);
+                       for (i = 0; i < ipacket->packet_size; i++)
+                               *(dup_pkt->img_pkt.img_data + i) =
+                                   *(ipacket->img_data + i);
+
+                       /*  Add the packet to the dup list */
+                       dup_pkt->next = dlthis->tramp.dup_pkts;
+                       dlthis->tramp.dup_pkts = dup_pkt;
+               } else
+                       dload_error(dlthis, "Failed to create dup packet!");
+       } else {
+               /*  The image packet contents could have changed since
+                * trampoline detection happens during relocation of the image
+                * packets.  So, we need to update the image packet contents
+                * before adding relo information. */
+               for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
+                       *(dup_pkt->img_pkt.img_data + i) =
+                           *(ipacket->img_data + i);
+       }
+
+       /*  Since the previous code may have allocated a new dup packet for us,
+          double check that we actually have one. */
+       if (dup_pkt != NULL) {
+               /*  Allocate a new node for the relo chain.  Each image packet
+                * can potentially have multiple relocations that cause a
+                * trampoline to be generated.  So, we keep them in a chain,
+                * order is not important. */
+               dup_relo = dlthis->mysym->dload_allocate(dlthis->mysym,
+                                        sizeof(struct tramp_img_dup_relo));
+               if (dup_relo != NULL) {
+                       /*  Copy the relo contents, adjust for the new
+                        * trampoline and add it to the list. */
+                       dup_relo->relo = *rp;
+                       dup_relo->relo.SYMNDX = new_tramp_sym->index;
+
+                       dup_relo->next = dup_pkt->relo_chain;
+                       dup_pkt->relo_chain = dup_relo;
+
+                       /*  That's it, we're done.  Make sure we update our
+                        * return value to be success since everything finished
+                        * ok */
+                       ret_val = 1;
+               } else
+                       dload_error(dlthis, "Unable to alloc dup relo");
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   dload_tramp_avail
+ * Description: Check to see if the target supports a trampoline for this type
+ *       of relocation.  Return true if it does, otherwise false.
+ */
+bool dload_tramp_avail(struct dload_state *dlthis, struct reloc_record_t *rp)
+{
+       bool ret_val = false;
+       u16 map_index;
+       u16 gen_index;
+
+       /*  Check type hash vs. target tramp table */
+       map_index = HASH_FUNC(rp->TYPE);
+       gen_index = tramp_map[map_index];
+       if (gen_index != TRAMP_NO_GEN_AVAIL)
+               ret_val = true;
+
+       return ret_val;
+}
+
+/*
+ * Function:   dload_tramp_generate
+ * Description: Create a new trampoline for the provided image packet and
+ *       relocation causing problems.  This will create the trampoline
+ *       as well as duplicate/update the image packet and relocation
+ *       causing the problem, which will be relo'd again during
+ *       finalization.
+ */
+int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
+                        u32 image_offset, struct image_packet_t *ipacket,
+                        struct reloc_record_t *rp)
+{
+       u16 map_index;
+       u16 gen_index;
+       int ret_val = 1;
+       char tramp_sym_str[TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN];
+       struct local_symbol *ref_sym;
+       struct tramp_sym *new_tramp_sym;
+       struct tramp_sym *new_ext_sym;
+       struct tramp_string *new_tramp_str;
+       u32 new_tramp_base;
+       struct local_symbol tmp_sym;
+       struct local_symbol ext_tmp_sym;
+
+       /*  Hash the relo type to get our generator information */
+       map_index = HASH_FUNC(rp->TYPE);
+       gen_index = tramp_map[map_index];
+       if (gen_index != TRAMP_NO_GEN_AVAIL) {
+               /*  If this is the first trampoline, create the section name in
+                * our string table for debug help later. */
+               if (dlthis->tramp.string_head == NULL) {
+                       priv_tramp_string_create(dlthis,
+                                                strlen(TRAMP_SECT_NAME),
+                                                TRAMP_SECT_NAME);
+               }
+#ifdef ENABLE_TRAMP_DEBUG
+               dload_syms_error(dlthis->mysym,
+                                "Trampoline at img loc %x, references %x",
+                                dlthis->ldr_sections[secnn].run_addr +
+                                image_offset + rp->vaddr,
+                                dlthis->local_symtab[rp->SYMNDX].value);
+#endif
+
+               /*  Generate the trampoline string, check if already defined.
+                * If the relo symbol index is -1, it means we need the section
+                * info for relo later.  To do this we'll dummy up a symbol
+                * with the section delta and run addresses. */
+               if (rp->SYMNDX == -1) {
+                       ext_tmp_sym.value =
+                           dlthis->ldr_sections[secnn].run_addr;
+                       ext_tmp_sym.delta = dlthis->sect_hdrs[secnn].ds_paddr;
+                       ref_sym = &ext_tmp_sym;
+               } else
+                       ref_sym = &(dlthis->local_symtab[rp->SYMNDX]);
+
+               priv_tramp_sym_gen_name(ref_sym->value, tramp_sym_str);
+               new_tramp_sym = priv_tramp_sym_find(dlthis, tramp_sym_str);
+               if (new_tramp_sym == NULL) {
+                       /*  If tramp string not defined, create it and a new
+                        * string, and symbol for it as well as the original
+                        * symbol which caused the trampoline. */
+                       new_tramp_str = priv_tramp_string_create(dlthis,
+                                                               strlen
+                                                               (tramp_sym_str),
+                                                                tramp_sym_str);
+                       if (new_tramp_str == NULL) {
+                               dload_error(dlthis, "Failed to create new "
+                                           "trampoline string\n");
+                               ret_val = 0;
+                       } else {
+                               /*  Allocate tramp section space for the new
+                                * tramp from the target */
+                               new_tramp_base = priv_tramp_sect_alloc(dlthis,
+                                                      tramp_size_get());
+
+                               /*  We have a string, create the new symbol and
+                                * duplicate the external. */
+                               tmp_sym.value = new_tramp_base;
+                               tmp_sym.delta = 0;
+                               tmp_sym.secnn = -1;
+                               tmp_sym.sclass = 0;
+                               new_tramp_sym = priv_tramp_sym_create(dlthis,
+                                                             new_tramp_str->
+                                                             index,
+                                                             &tmp_sym);
+
+                               new_ext_sym = priv_tramp_sym_create(dlthis, -1,
+                                                                   ref_sym);
+
+                               if ((new_tramp_sym != NULL) &&
+                                   (new_ext_sym != NULL)) {
+                                       /*  Call the image generator to get the
+                                        * new image data and fix up its
+                                        * relocations for the external
+                                        * symbol. */
+                                       ret_val = priv_tgt_img_gen(dlthis,
+                                                                new_tramp_base,
+                                                                gen_index,
+                                                                new_ext_sym);
+
+                                       /*  Add generated image data to tramp
+                                        * image list */
+                                       if (ret_val != 1) {
+                                               dload_error(dlthis, "Failed to "
+                                                           "create img pkt for"
+                                                           " trampoline\n");
+                                       }
+                               } else {
+                                       dload_error(dlthis, "Failed to create "
+                                                   "new tramp syms "
+                                                   "(%8.8X, %8.8X)\n",
+                                                   new_tramp_sym, new_ext_sym);
+                                       ret_val = 0;
+                               }
+                       }
+               }
+
+               /*  Duplicate the image data and relo record that caused the
+                * tramp, including update the relo data to point to the tramp
+                * symbol. */
+               if (ret_val == 1) {
+                       ret_val = priv_img_pkt_dup(dlthis, secnn, image_offset,
+                                                  ipacket, rp, new_tramp_sym);
+                       if (ret_val != 1) {
+                               dload_error(dlthis, "Failed to create dup of "
+                                           "original img pkt\n");
+                       }
+               }
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   dload_tramp_pkt_update
+ * Description: Update the duplicate copy of this image packet, which the
+ *       trampoline layer is already tracking.  This is call is critical
+ *       to make if trampolines were generated anywhere within the
+ *       packet and first pass relo continued on the remainder.  The
+ *       trampoline layer needs the updates image data so when 2nd
+ *       pass relo is done during finalize the image packet can be
+ *       written to the target since all relo is done.
+ */
+int dload_tramp_pkt_udpate(struct dload_state *dlthis, s16 secnn,
+                          u32 image_offset, struct image_packet_t *ipacket)
+{
+       struct tramp_img_dup_pkt *dup_pkt = NULL;
+       s32 i;
+       int ret_val = 0;
+
+       /*  Find the image packet in question, the caller needs us to update it
+          since a trampoline was previously generated. */
+       dup_pkt = priv_dup_find(dlthis, secnn, image_offset);
+       if (dup_pkt != NULL) {
+               for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
+                       *(dup_pkt->img_pkt.img_data + i) =
+                           *(ipacket->img_data + i);
+
+               ret_val = 1;
+       } else {
+               dload_error(dlthis,
+                           "Unable to find existing DUP pkt for %x, offset %x",
+                           secnn, image_offset);
+
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   dload_tramp_finalize
+ * Description: If any trampolines were created, finalize everything on the
+ *       target by allocating the trampoline section on the target,
+ *       finalizing the trampoline symbols, finalizing the trampoline
+ *       packets (write the new section to target memory) and finalize
+ *       the duplicate packets by doing 2nd pass relo over them.
+ */
+int dload_tramp_finalize(struct dload_state *dlthis)
+{
+       int ret_val = 1;
+
+       if (dlthis->tramp.tramp_sect_next_addr != 0) {
+               /*  Finalize strings into a flat table.  This is needed so it
+                * can be added to the debug string table later. */
+               ret_val = priv_string_tbl_finalize(dlthis);
+
+               /*  Do target allocation for section BEFORE finalizing
+                * symbols. */
+               if (ret_val != 0)
+                       ret_val = priv_tramp_sect_tgt_alloc(dlthis);
+
+               /*  Finalize symbols with their correct target information and
+                * flatten */
+               if (ret_val != 0)
+                       ret_val = priv_tramp_sym_finalize(dlthis);
+
+               /*  Finalize all trampoline packets.  This performs the
+                * relocation on the packets as well as writing them to target
+                * memory. */
+               if (ret_val != 0)
+                       ret_val = priv_tramp_pkt_finalize(dlthis);
+
+               /*  Perform a 2nd pass relocation on the dup list. */
+               if (ret_val != 0)
+                       ret_val = priv_dup_pkt_finalize(dlthis);
+       }
+
+       return ret_val;
+}
+
+/*
+ * Function:   dload_tramp_cleanup
+ * Description: Release all temporary resources used in the trampoline layer.
+ *       Note that the target memory which may have been allocated and
+ *       written to store the trampolines is NOT RELEASED HERE since it
+ *       is potentially still in use.  It is automatically released
+ *       when the module is unloaded.
+ */
+void dload_tramp_cleanup(struct dload_state *dlthis)
+{
+       struct tramp_info *tramp = &dlthis->tramp;
+       struct tramp_sym *cur_sym;
+       struct tramp_string *cur_string;
+       struct tramp_img_pkt *cur_tramp_pkt;
+       struct tramp_img_dup_pkt *cur_dup_pkt;
+       struct tramp_img_dup_relo *cur_dup_relo;
+
+       /*  If there were no tramps generated, just return */
+       if (tramp->tramp_sect_next_addr == 0)
+               return;
+
+       /*  Destroy all tramp information */
+       for (cur_sym = tramp->symbol_head;
+            cur_sym != NULL; cur_sym = tramp->symbol_head) {
+               tramp->symbol_head = cur_sym->next;
+               if (tramp->symbol_tail == cur_sym)
+                       tramp->symbol_tail = NULL;
+
+               dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);
+       }
+
+       if (tramp->final_sym_table != NULL)
+               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               tramp->final_sym_table);
+
+       for (cur_string = tramp->string_head;
+            cur_string != NULL; cur_string = tramp->string_head) {
+               tramp->string_head = cur_string->next;
+               if (tramp->string_tail == cur_string)
+                       tramp->string_tail = NULL;
+
+               dlthis->mysym->dload_deallocate(dlthis->mysym, cur_string);
+       }
+
+       if (tramp->final_string_table != NULL)
+               dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                               tramp->final_string_table);
+
+       for (cur_tramp_pkt = tramp->tramp_pkts;
+            cur_tramp_pkt != NULL; cur_tramp_pkt = tramp->tramp_pkts) {
+               tramp->tramp_pkts = cur_tramp_pkt->next;
+               dlthis->mysym->dload_deallocate(dlthis->mysym, cur_tramp_pkt);
+       }
+
+       for (cur_dup_pkt = tramp->dup_pkts;
+            cur_dup_pkt != NULL; cur_dup_pkt = tramp->dup_pkts) {
+               tramp->dup_pkts = cur_dup_pkt->next;
+
+               for (cur_dup_relo = cur_dup_pkt->relo_chain;
+                    cur_dup_relo != NULL;
+                    cur_dup_relo = cur_dup_pkt->relo_chain) {
+                       cur_dup_pkt->relo_chain = cur_dup_relo->next;
+                       dlthis->mysym->dload_deallocate(dlthis->mysym,
+                                                       cur_dup_relo);
+               }
+
+               dlthis->mysym->dload_deallocate(dlthis->mysym, cur_dup_pkt);
+       }
+}
diff --git a/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c b/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c
new file mode 100644 (file)
index 0000000..09cc64f
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * tramp_table_c6000.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "dload_internal.h"
+
+/*  These are defined in coff.h, but may not be available on all platforms
+       so we'll go ahead and define them here. */
+#ifndef R_C60LO16
+#define R_C60LO16        0x54  /* C60: MVK Low Half Register */
+#define R_C60HI16        0x55  /* C60: MVKH/MVKLH High Half Register */
+#endif
+
+#define C6X_TRAMP_WORD_COUNT                   8
+#define C6X_TRAMP_MAX_RELOS                     8
+
+/*  THIS HASH FUNCTION MUST MATCH THE ONE reloc_table_c6000.c */
+#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63)
+
+/*  THIS MUST MATCH reloc_record_t FOR A SYMBOL BASED RELO */
+struct c6000_relo_record {
+       s32 vaddr;
+       s32 symndx;
+#ifndef _BIG_ENDIAN
+       u16 disp;
+       u16 type;
+#else
+       u16 type;
+       u16 disp;
+#endif
+};
+
+struct c6000_gen_code {
+       struct tramp_gen_code_hdr hdr;
+       u32 tramp_instrs[C6X_TRAMP_WORD_COUNT];
+       struct c6000_relo_record relos[C6X_TRAMP_MAX_RELOS];
+};
+
+/*  Hash mapping for relos that can cause trampolines. */
+static const u16 tramp_map[] = {
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       0,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535,
+       65535
+};
+
+static const struct c6000_gen_code tramp_gen_info[] = {
+       /*  Tramp caused by R_C60PCR21 */
+       {
+        /*  Header - 8 instructions, 2 relos */
+        {
+         sizeof(u32) * C6X_TRAMP_WORD_COUNT,
+         2,
+         FIELD_OFFSET(struct c6000_gen_code, relos)
+         },
+
+        /*  Trampoline instructions */
+        {
+         0x053C54F7,           /*       STW.D2T2  B10, *sp--[2] */
+         0x0500002A,           /*  || MVK.S2   <blank>, B10 */
+         0x0500006A,           /*       MVKH.S2   <blank>, B10 */
+         0x00280362,           /*       B.S2     B10 */
+         0x053C52E6,           /*       LDW.D2T2  *++sp[2], B10 */
+         0x00006000,           /*       NOP       4 */
+         0x00000000,           /*       NOP */
+         0x00000000            /*       NOP */
+         },
+
+        /*  Relocations */
+        {
+         {4, 0, 0, R_C60LO16},
+         {8, 0, 0, R_C60HI16},
+         {0, 0, 0, 0x0000},
+         {0, 0, 0, 0x0000},
+         {0, 0, 0, 0x0000},
+         {0, 0, 0, 0x0000},
+         {0, 0, 0, 0x0000},
+         {0, 0, 0, 0x0000}
+         }
+        }
+};
+
+/*  TARGET SPECIFIC FUNCTIONS THAT MUST BE DEFINED */
+static u32 tramp_size_get(void)
+{
+       return sizeof(u32) * C6X_TRAMP_WORD_COUNT;
+}
+
+static u32 tramp_img_pkt_size_get(void)
+{
+       return sizeof(struct c6000_gen_code);
+}
diff --git a/drivers/staging/tidspbridge/gen/gb.c b/drivers/staging/tidspbridge/gen/gb.c
new file mode 100644 (file)
index 0000000..06eb3d3
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * gb.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Generic bitmap operations.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <linux/types.h>
+/*  ----------------------------------- This */
+#include <dspbridge/gs.h>
+#include <dspbridge/gb.h>
+
+struct gb_t_map {
+       u32 len;
+       u32 wcnt;
+       u32 *words;
+};
+
+/*
+ *  ======== gb_clear ========
+ *  purpose:
+ *      Clears a bit in the bit map.
+ */
+
+void gb_clear(struct gb_t_map *map, u32 bitn)
+{
+       u32 mask;
+
+       mask = 1L << (bitn % BITS_PER_LONG);
+       map->words[bitn / BITS_PER_LONG] &= ~mask;
+}
+
+/*
+ *  ======== gb_create ========
+ *  purpose:
+ *      Creates a bit map.
+ */
+
+struct gb_t_map *gb_create(u32 len)
+{
+       struct gb_t_map *map;
+       u32 i;
+       map = (struct gb_t_map *)gs_alloc(sizeof(struct gb_t_map));
+       if (map != NULL) {
+               map->len = len;
+               map->wcnt = len / BITS_PER_LONG + 1;
+               map->words = (u32 *) gs_alloc(map->wcnt * sizeof(u32));
+               if (map->words != NULL) {
+                       for (i = 0; i < map->wcnt; i++)
+                               map->words[i] = 0L;
+
+               } else {
+                       gs_frees(map, sizeof(struct gb_t_map));
+                       map = NULL;
+               }
+       }
+
+       return map;
+}
+
+/*
+ *  ======== gb_delete ========
+ *  purpose:
+ *      Frees a bit map.
+ */
+
+void gb_delete(struct gb_t_map *map)
+{
+       gs_frees(map->words, map->wcnt * sizeof(u32));
+       gs_frees(map, sizeof(struct gb_t_map));
+}
+
+/*
+ *  ======== gb_findandset ========
+ *  purpose:
+ *      Finds a free bit and sets it.
+ */
+u32 gb_findandset(struct gb_t_map *map)
+{
+       u32 bitn;
+
+       bitn = gb_minclear(map);
+
+       if (bitn != GB_NOBITS)
+               gb_set(map, bitn);
+
+       return bitn;
+}
+
+/*
+ *  ======== gb_minclear ========
+ *  purpose:
+ *      returns the location of the first unset bit in the bit map.
+ */
+u32 gb_minclear(struct gb_t_map *map)
+{
+       u32 bit_location = 0;
+       u32 bit_acc = 0;
+       u32 i;
+       u32 bit;
+       u32 *word;
+
+       for (word = map->words, i = 0; i < map->wcnt; word++, i++) {
+               if (~*word) {
+                       for (bit = 0; bit < BITS_PER_LONG; bit++, bit_acc++) {
+                               if (bit_acc == map->len)
+                                       return GB_NOBITS;
+
+                               if (~*word & (1L << bit)) {
+                                       bit_location = i * BITS_PER_LONG + bit;
+                                       return bit_location;
+                               }
+
+                       }
+               } else {
+                       bit_acc += BITS_PER_LONG;
+               }
+       }
+
+       return GB_NOBITS;
+}
+
+/*
+ *  ======== gb_set ========
+ *  purpose:
+ *      Sets a bit in the bit map.
+ */
+
+void gb_set(struct gb_t_map *map, u32 bitn)
+{
+       u32 mask;
+
+       mask = 1L << (bitn % BITS_PER_LONG);
+       map->words[bitn / BITS_PER_LONG] |= mask;
+}
+
+/*
+ *  ======== gb_test ========
+ *  purpose:
+ *      Returns true if the bit is set in the specified location.
+ */
+
+bool gb_test(struct gb_t_map *map, u32 bitn)
+{
+       bool state;
+       u32 mask;
+       u32 word;
+
+       mask = 1L << (bitn % BITS_PER_LONG);
+       word = map->words[bitn / BITS_PER_LONG];
+       state = word & mask ? true : false;
+
+       return state;
+}
diff --git a/drivers/staging/tidspbridge/gen/gh.c b/drivers/staging/tidspbridge/gen/gh.c
new file mode 100644 (file)
index 0000000..f72d943
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * gh.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+#include <dspbridge/host_os.h>
+
+#include <dspbridge/gs.h>
+
+#include <dspbridge/gh.h>
+
+struct element {
+       struct element *next;
+       u8 data[1];
+};
+
+struct gh_t_hash_tab {
+       u16 max_bucket;
+       u16 val_size;
+       struct element **buckets;
+        u16(*hash) (void *, u16);
+        bool(*match) (void *, void *);
+       void (*delete) (void *);
+};
+
+static void noop(void *p);
+static s32 cur_init;
+static void myfree(void *ptr, s32 size);
+
+/*
+ *  ======== gh_create ========
+ */
+
+struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
+                               u16(*hash) (void *, u16), bool(*match) (void *,
+                                                                       void *),
+                               void (*delete) (void *))
+{
+       struct gh_t_hash_tab *hash_tab;
+       u16 i;
+       hash_tab =
+           (struct gh_t_hash_tab *)gs_alloc(sizeof(struct gh_t_hash_tab));
+       if (hash_tab == NULL)
+               return NULL;
+       hash_tab->max_bucket = max_bucket;
+       hash_tab->val_size = val_size;
+       hash_tab->hash = hash;
+       hash_tab->match = match;
+       hash_tab->delete = delete == NULL ? noop : delete;
+
+       hash_tab->buckets = (struct element **)
+           gs_alloc(sizeof(struct element *) * max_bucket);
+       if (hash_tab->buckets == NULL) {
+               gh_delete(hash_tab);
+               return NULL;
+       }
+
+       for (i = 0; i < max_bucket; i++)
+               hash_tab->buckets[i] = NULL;
+
+       return hash_tab;
+}
+
+/*
+ *  ======== gh_delete ========
+ */
+void gh_delete(struct gh_t_hash_tab *hash_tab)
+{
+       struct element *elem, *next;
+       u16 i;
+
+       if (hash_tab != NULL) {
+               if (hash_tab->buckets != NULL) {
+                       for (i = 0; i < hash_tab->max_bucket; i++) {
+                               for (elem = hash_tab->buckets[i]; elem != NULL;
+                                    elem = next) {
+                                       next = elem->next;
+                                       (*hash_tab->delete) (elem->data);
+                                       myfree(elem,
+                                              sizeof(struct element) - 1 +
+                                              hash_tab->val_size);
+                               }
+                       }
+
+                       myfree(hash_tab->buckets, sizeof(struct element *)
+                              * hash_tab->max_bucket);
+               }
+
+               myfree(hash_tab, sizeof(struct gh_t_hash_tab));
+       }
+}
+
+/*
+ *  ======== gh_exit ========
+ */
+
+void gh_exit(void)
+{
+       if (cur_init-- == 1)
+               gs_exit();
+
+}
+
+/*
+ *  ======== gh_find ========
+ */
+
+void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
+{
+       struct element *elem;
+
+       elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];
+
+       for (; elem; elem = elem->next) {
+               if ((*hash_tab->match) (key, elem->data))
+                       return elem->data;
+       }
+
+       return NULL;
+}
+
+/*
+ *  ======== gh_init ========
+ */
+
+void gh_init(void)
+{
+       if (cur_init++ == 0)
+               gs_init();
+}
+
+/*
+ *  ======== gh_insert ========
+ */
+
+void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
+{
+       struct element *elem;
+       u16 i;
+       char *src, *dst;
+
+       elem = (struct element *)gs_alloc(sizeof(struct element) - 1 +
+                                         hash_tab->val_size);
+       if (elem != NULL) {
+
+               dst = (char *)elem->data;
+               src = (char *)value;
+               for (i = 0; i < hash_tab->val_size; i++)
+                       *dst++ = *src++;
+
+               i = (*hash_tab->hash) (key, hash_tab->max_bucket);
+               elem->next = hash_tab->buckets[i];
+               hash_tab->buckets[i] = elem;
+
+               return elem->data;
+       }
+
+       return NULL;
+}
+
+/*
+ *  ======== noop ========
+ */
+/* ARGSUSED */
+static void noop(void *p)
+{
+       p = p;                  /* stifle compiler warning */
+}
+
+/*
+ *  ======== myfree ========
+ */
+static void myfree(void *ptr, s32 size)
+{
+       gs_free(ptr);
+}
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+/**
+ * gh_iterate() - This function goes through all the elements in the hash table
+ *             looking for the dsp symbols.
+ * @hash_tab:  Hash table
+ * @callback:  pointer to callback function
+ * @user_data: User data, contains the find_symbol_context pointer
+ *
+ */
+void gh_iterate(struct gh_t_hash_tab *hash_tab,
+               void (*callback)(void *, void *), void *user_data)
+{
+       struct element *elem;
+       u32 i;
+
+       if (hash_tab && hash_tab->buckets)
+               for (i = 0; i < hash_tab->max_bucket; i++) {
+                       elem = hash_tab->buckets[i];
+                       while (elem) {
+                               callback(&elem->data, user_data);
+                               elem = elem->next;
+                       }
+               }
+}
+#endif
diff --git a/drivers/staging/tidspbridge/gen/gs.c b/drivers/staging/tidspbridge/gen/gs.c
new file mode 100644 (file)
index 0000000..9fc6144
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * gs.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * General storage memory allocator services.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+#include <linux/types.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/gs.h>
+
+#include <linux/slab.h>
+
+/*  ----------------------------------- Globals */
+static u32 cumsize;
+
+/*
+ *  ======== gs_alloc ========
+ *  purpose:
+ *      Allocates memory of the specified size.
+ */
+void *gs_alloc(u32 size)
+{
+       void *p;
+
+       p = kzalloc(size, GFP_KERNEL);
+       if (p == NULL)
+               return NULL;
+       cumsize += size;
+       return p;
+}
+
+/*
+ *  ======== gs_exit ========
+ *  purpose:
+ *      Discontinue the usage of the GS module.
+ */
+void gs_exit(void)
+{
+       /* Do nothing */
+}
+
+/*
+ *  ======== gs_free ========
+ *  purpose:
+ *      Frees the memory.
+ */
+void gs_free(void *ptr)
+{
+       kfree(ptr);
+       /* ack! no size info */
+       /* cumsize -= size; */
+}
+
+/*
+ *  ======== gs_frees ========
+ *  purpose:
+ *      Frees the memory.
+ */
+void gs_frees(void *ptr, u32 size)
+{
+       kfree(ptr);
+       cumsize -= size;
+}
+
+/*
+ *  ======== gs_init ========
+ *  purpose:
+ *      Initializes the GS module.
+ */
+void gs_init(void)
+{
+       /* Do nothing */
+}
diff --git a/drivers/staging/tidspbridge/gen/uuidutil.c b/drivers/staging/tidspbridge/gen/uuidutil.c
new file mode 100644 (file)
index 0000000..da39c4f
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * uuidutil.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This file contains the implementation of UUID helper functions.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/uuidutil.h>
+
+/*
+ *  ======== uuid_uuid_to_string ========
+ *  Purpose:
+ *      Converts a struct dsp_uuid to a string.
+ *      Note: snprintf format specifier is:
+ *      %[flags] [width] [.precision] [{h | l | I64 | L}]type
+ */
+void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid,
+                        s32 size)
+{
+       s32 i;                  /* return result from snprintf. */
+
+       DBC_REQUIRE(uuid_obj && sz_uuid);
+
+       i = snprintf(sz_uuid, size,
+                    "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X",
+                    uuid_obj->ul_data1, uuid_obj->us_data2, uuid_obj->us_data3,
+                    uuid_obj->uc_data4, uuid_obj->uc_data5,
+                    uuid_obj->uc_data6[0], uuid_obj->uc_data6[1],
+                    uuid_obj->uc_data6[2], uuid_obj->uc_data6[3],
+                    uuid_obj->uc_data6[4], uuid_obj->uc_data6[5]);
+
+       DBC_ENSURE(i != -1);
+}
+
+static s32 uuid_hex_to_bin(char *buf, s32 len)
+{
+       s32 i;
+       s32 result = 0;
+       int value;
+
+       for (i = 0; i < len; i++) {
+               value = hex_to_bin(*buf++);
+               result *= 16;
+               if (value > 0)
+                       result += value;
+       }
+
+       return result;
+}
+
+/*
+ *  ======== uuid_uuid_from_string ========
+ *  Purpose:
+ *      Converts a string to a struct dsp_uuid.
+ */
+void uuid_uuid_from_string(char *sz_uuid, struct dsp_uuid *uuid_obj)
+{
+       s32 j;
+
+       uuid_obj->ul_data1 = uuid_hex_to_bin(sz_uuid, 8);
+       sz_uuid += 8;
+
+       /* Step over underscore */
+       sz_uuid++;
+
+       uuid_obj->us_data2 = (u16) uuid_hex_to_bin(sz_uuid, 4);
+       sz_uuid += 4;
+
+       /* Step over underscore */
+       sz_uuid++;
+
+       uuid_obj->us_data3 = (u16) uuid_hex_to_bin(sz_uuid, 4);
+       sz_uuid += 4;
+
+       /* Step over underscore */
+       sz_uuid++;
+
+       uuid_obj->uc_data4 = (u8) uuid_hex_to_bin(sz_uuid, 2);
+       sz_uuid += 2;
+
+       uuid_obj->uc_data5 = (u8) uuid_hex_to_bin(sz_uuid, 2);
+       sz_uuid += 2;
+
+       /* Step over underscore */
+       sz_uuid++;
+
+       for (j = 0; j < 6; j++) {
+               uuid_obj->uc_data6[j] = (u8) uuid_hex_to_bin(sz_uuid, 2);
+               sz_uuid += 2;
+       }
+}
diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h
new file mode 100644 (file)
index 0000000..e48d7f6
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * EasiGlobal.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _EASIGLOBAL_H
+#define _EASIGLOBAL_H
+#include <linux/types.h>
+
+/*
+ * DEFINE:        READ_ONLY, WRITE_ONLY &  READ_WRITE
+ *
+ * DESCRIPTION: Defines used to describe register types for EASI-checker tests.
+ */
+
+#define READ_ONLY    1
+#define WRITE_ONLY   2
+#define READ_WRITE   3
+
+/*
+ * MACRO:        _DEBUG_LEVEL1_EASI
+ *
+ * DESCRIPTION:  A MACRO which can be used to indicate that a particular beach
+ *               register access function was called.
+ *
+ * NOTE:         We currently dont use this functionality.
+ */
+#define _DEBUG_LEVEL1_EASI(easi_num)     ((void)0)
+
+#endif /* _EASIGLOBAL_H */
diff --git a/drivers/staging/tidspbridge/hw/MMUAccInt.h b/drivers/staging/tidspbridge/hw/MMUAccInt.h
new file mode 100644 (file)
index 0000000..1cefca3
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * MMUAccInt.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _MMU_ACC_INT_H
+#define _MMU_ACC_INT_H
+
+/* Mappings of level 1 EASI function numbers to function names */
+
+#define EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32 (MMU_BASE_EASIL1 + 3)
+#define EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32  (MMU_BASE_EASIL1 + 17)
+#define EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32    (MMU_BASE_EASIL1 + 39)
+#define EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32   (MMU_BASE_EASIL1 + 51)
+#define EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32 (MMU_BASE_EASIL1 + 102)
+#define EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 103)
+#define EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32 (MMU_BASE_EASIL1 + 156)
+#define EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32 (MMU_BASE_EASIL1 + 174)
+#define EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32   (MMU_BASE_EASIL1 + 180)
+#define EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32     (MMU_BASE_EASIL1 + 190)
+#define EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32   (MMU_BASE_EASIL1 + 194)
+#define EASIL1_MMUMMU_TTB_WRITE_REGISTER32  (MMU_BASE_EASIL1 + 198)
+#define EASIL1_MMUMMU_LOCK_READ_REGISTER32   (MMU_BASE_EASIL1 + 203)
+#define EASIL1_MMUMMU_LOCK_WRITE_REGISTER32  (MMU_BASE_EASIL1 + 204)
+#define EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32  (MMU_BASE_EASIL1 + 205)
+#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32 (MMU_BASE_EASIL1 + 209)
+#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32 (MMU_BASE_EASIL1 + 211)
+#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32  (MMU_BASE_EASIL1 + 212)
+#define EASIL1_MMUMMU_LD_TLB_READ_REGISTER32    (MMU_BASE_EASIL1 + 213)
+#define EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32   (MMU_BASE_EASIL1 + 214)
+#define EASIL1_MMUMMU_CAM_WRITE_REGISTER32   (MMU_BASE_EASIL1 + 226)
+#define EASIL1_MMUMMU_RAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 268)
+#define EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32  (MMU_BASE_EASIL1 + 322)
+
+/* Register offset address definitions */
+#define MMU_MMU_SYSCONFIG_OFFSET   0x10
+#define MMU_MMU_IRQSTATUS_OFFSET  0x18
+#define MMU_MMU_IRQENABLE_OFFSET    0x1c
+#define MMU_MMU_WALKING_ST_OFFSET 0x40
+#define MMU_MMU_CNTL_OFFSET   0x44
+#define MMU_MMU_FAULT_AD_OFFSET  0x48
+#define MMU_MMU_TTB_OFFSET  0x4c
+#define MMU_MMU_LOCK_OFFSET   0x50
+#define MMU_MMU_LD_TLB_OFFSET  0x54
+#define MMU_MMU_CAM_OFFSET   0x58
+#define MMU_MMU_RAM_OFFSET   0x5c
+#define MMU_MMU_GFLUSH_OFFSET  0x60
+#define MMU_MMU_FLUSH_ENTRY_OFFSET  0x64
+/* Bitfield mask and offset declarations */
+#define MMU_MMU_SYSCONFIG_IDLE_MODE_MASK  0x18
+#define MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET  3
+#define MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK  0x1
+#define MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET   0
+#define MMU_MMU_WALKING_ST_TWL_RUNNING_MASK 0x1
+#define MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET  0
+#define MMU_MMU_CNTL_TWL_ENABLE_MASK 0x4
+#define MMU_MMU_CNTL_TWL_ENABLE_OFFSET 2
+#define MMU_MMU_CNTL_MMU_ENABLE_MASK    0x2
+#define MMU_MMU_CNTL_MMU_ENABLE_OFFSET   1
+#define MMU_MMU_LOCK_BASE_VALUE_MASK 0xfc00
+#define MMU_MMU_LOCK_BASE_VALUE_OFFSET   10
+#define MMU_MMU_LOCK_CURRENT_VICTIM_MASK   0x3f0
+#define MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET    4
+
+#endif /* _MMU_ACC_INT_H */
diff --git a/drivers/staging/tidspbridge/hw/MMURegAcM.h b/drivers/staging/tidspbridge/hw/MMURegAcM.h
new file mode 100644 (file)
index 0000000..ab1a16d
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * MMURegAcM.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _MMU_REG_ACM_H
+#define _MMU_REG_ACM_H
+
+#include <linux/io.h>
+#include <EasiGlobal.h>
+
+#include "MMUAccInt.h"
+
+#if defined(USE_LEVEL_1_MACROS)
+
+#define MMUMMU_SYSCONFIG_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_SYSCONFIG_OFFSET))
+
+#define MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32);\
+    data &= ~(MMU_MMU_SYSCONFIG_IDLE_MODE_MASK);\
+    new_value <<= MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET;\
+    new_value &= MMU_MMU_SYSCONFIG_IDLE_MODE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32);\
+    data &= ~(MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK);\
+    new_value <<= MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET;\
+    new_value &= MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_IRQSTATUS_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(easil1_mmummu_irqstatus_read_register32),\
+      __raw_readl((base_address)+MMU_MMU_IRQSTATUS_OFFSET))
+
+#define MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_IRQENABLE_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_IRQENABLE_OFFSET))
+
+#define MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_WALKING_STTWL_RUNNING_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_WALKING_ST_OFFSET))))\
+      & MMU_MMU_WALKING_ST_TWL_RUNNING_MASK) >>\
+      MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET))
+
+#define MMUMMU_CNTLTWL_ENABLE_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\
+      MMU_MMU_CNTL_TWL_ENABLE_MASK) >>\
+      MMU_MMU_CNTL_TWL_ENABLE_OFFSET))
+
+#define MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_CNTL_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32);\
+    data &= ~(MMU_MMU_CNTL_TWL_ENABLE_MASK);\
+    new_value <<= MMU_MMU_CNTL_TWL_ENABLE_OFFSET;\
+    new_value &= MMU_MMU_CNTL_TWL_ENABLE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_CNTL_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32);\
+    data &= ~(MMU_MMU_CNTL_MMU_ENABLE_MASK);\
+    new_value <<= MMU_MMU_CNTL_MMU_ENABLE_OFFSET;\
+    new_value &= MMU_MMU_CNTL_MMU_ENABLE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_FAULT_AD_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_FAULT_AD_OFFSET))
+
+#define MMUMMU_TTB_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_TTB_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_TTB_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_LOCK_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_LOCK_OFFSET))
+
+#define MMUMMU_LOCK_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LOCK_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_LOCK_BASE_VALUE_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
+      MMU_MMU_LOCK_BASE_VALUE_MASK) >>\
+      MMU_MMU_LOCK_BASE_VALUE_OFFSET))
+
+#define MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LOCK_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(easil1_mmummu_lock_base_value_write32);\
+    data &= ~(MMU_MMU_LOCK_BASE_VALUE_MASK);\
+    new_value <<= MMU_MMU_LOCK_BASE_VALUE_OFFSET;\
+    new_value &= MMU_MMU_LOCK_BASE_VALUE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_LOCK_CURRENT_VICTIM_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
+      MMU_MMU_LOCK_CURRENT_VICTIM_MASK) >>\
+      MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET))
+
+#define MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LOCK_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32);\
+    data &= ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK);\
+    new_value <<= MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET;\
+    new_value &= MMU_MMU_LOCK_CURRENT_VICTIM_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_LOCK_CURRENT_VICTIM_SET32(var, value)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32),\
+      (((var) & ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK)) |\
+      (((value) << MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET) &\
+      MMU_MMU_LOCK_CURRENT_VICTIM_MASK)))
+
+#define MMUMMU_LD_TLB_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_LD_TLB_OFFSET))
+
+#define MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LD_TLB_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_CAM_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_CAM_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CAM_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_RAM_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_RAM_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_RAM_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#endif /* USE_LEVEL_1_MACROS */
+
+#endif /* _MMU_REG_ACM_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_defs.h b/drivers/staging/tidspbridge/hw/hw_defs.h
new file mode 100644 (file)
index 0000000..d5266d4
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * hw_defs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global HW definitions
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _HW_DEFS_H
+#define _HW_DEFS_H
+
+/* Page size */
+#define HW_PAGE_SIZE4KB   0x1000
+#define HW_PAGE_SIZE64KB  0x10000
+#define HW_PAGE_SIZE1MB   0x100000
+#define HW_PAGE_SIZE16MB  0x1000000
+
+/* hw_status:  return type for HW API */
+typedef long hw_status;
+
+/*  Macro used to set and clear any bit */
+#define HW_CLEAR       0
+#define HW_SET         1
+
+/* hw_endianism_t:  Enumerated Type used to specify the endianism
+ *             Do NOT change these values. They are used as bit fields. */
+enum hw_endianism_t {
+       HW_LITTLE_ENDIAN,
+       HW_BIG_ENDIAN
+};
+
+/* hw_element_size_t:  Enumerated Type used to specify the element size
+ *             Do NOT change these values. They are used as bit fields. */
+enum hw_element_size_t {
+       HW_ELEM_SIZE8BIT,
+       HW_ELEM_SIZE16BIT,
+       HW_ELEM_SIZE32BIT,
+       HW_ELEM_SIZE64BIT
+};
+
+/* hw_idle_mode_t:  Enumerated Type used to specify Idle modes */
+enum hw_idle_mode_t {
+       HW_FORCE_IDLE,
+       HW_NO_IDLE,
+       HW_SMART_IDLE
+};
+
+#endif /* _HW_DEFS_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c
new file mode 100644 (file)
index 0000000..014f5d5
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * hw_mmu.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * API definitions to setup MMU TLB and PTE
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/io.h>
+#include "MMURegAcM.h"
+#include <hw_defs.h>
+#include <hw_mmu.h>
+#include <linux/types.h>
+#include <linux/err.h>
+
+#define MMU_BASE_VAL_MASK      0xFC00
+#define MMU_PAGE_MAX        3
+#define MMU_ELEMENTSIZE_MAX      3
+#define MMU_ADDR_MASK      0xFFFFF000
+#define MMU_TTB_MASK        0xFFFFC000
+#define MMU_SECTION_ADDR_MASK    0xFFF00000
+#define MMU_SSECTION_ADDR_MASK   0xFF000000
+#define MMU_PAGE_TABLE_MASK      0xFFFFFC00
+#define MMU_LARGE_PAGE_MASK      0xFFFF0000
+#define MMU_SMALL_PAGE_MASK      0xFFFFF000
+
+#define MMU_LOAD_TLB   0x00000001
+#define MMU_GFLUSH     0x60
+
+/*
+ * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS)
+ */
+enum hw_mmu_page_size_t {
+       HW_MMU_SECTION,
+       HW_MMU_LARGE_PAGE,
+       HW_MMU_SMALL_PAGE,
+       HW_MMU_SUPERSECTION
+};
+
+/*
+ * FUNCTION          : mmu_flush_entry
+ *
+ * INPUTS:
+ *
+ *       Identifier      : base_address
+ *       Type          : const u32
+ *       Description     : Base Address of instance of MMU module
+ *
+ * RETURNS:
+ *
+ *       Type          : hw_status
+ *       Description     : 0            -- No errors occured
+ *                      RET_BAD_NULL_PARAM     -- A Pointer
+ *                                             Paramater was set to NULL
+ *
+ * PURPOSE:          : Flush the TLB entry pointed by the
+ *                     lock counter register
+ *                     even if this entry is set protected
+ *
+ * METHOD:            : Check the Input parameter and Flush a
+ *                      single entry in the TLB.
+ */
+static hw_status mmu_flush_entry(const void __iomem *base_address);
+
+/*
+ * FUNCTION          : mmu_set_cam_entry
+ *
+ * INPUTS:
+ *
+ *       Identifier      : base_address
+ *       TypE          : const u32
+ *       Description     : Base Address of instance of MMU module
+ *
+ *       Identifier      : page_sz
+ *       TypE          : const u32
+ *       Description     : It indicates the page size
+ *
+ *       Identifier      : preserved_bit
+ *       Type          : const u32
+ *       Description     : It indicates the TLB entry is preserved entry
+ *                                                     or not
+ *
+ *       Identifier      : valid_bit
+ *       Type          : const u32
+ *       Description     : It indicates the TLB entry is valid entry or not
+ *
+ *
+ *       Identifier      : virtual_addr_tag
+ *       Type          : const u32
+ *       Description     : virtual Address
+ *
+ * RETURNS:
+ *
+ *       Type          : hw_status
+ *       Description     : 0            -- No errors occured
+ *                      RET_BAD_NULL_PARAM     -- A Pointer Paramater
+ *                                                was set to NULL
+ *                      RET_PARAM_OUT_OF_RANGE -- Input Parameter out
+ *                                                of Range
+ *
+ * PURPOSE:            : Set MMU_CAM reg
+ *
+ * METHOD:             : Check the Input parameters and set the CAM entry.
+ */
+static hw_status mmu_set_cam_entry(const void __iomem *base_address,
+                                  const u32 page_sz,
+                                  const u32 preserved_bit,
+                                  const u32 valid_bit,
+                                  const u32 virtual_addr_tag);
+
+/*
+ * FUNCTION          : mmu_set_ram_entry
+ *
+ * INPUTS:
+ *
+ *       Identifier      : base_address
+ *       Type          : const u32
+ *       Description     : Base Address of instance of MMU module
+ *
+ *       Identifier      : physical_addr
+ *       Type          : const u32
+ *       Description     : Physical Address to which the corresponding
+ *                      virtual   Address shouldpoint
+ *
+ *       Identifier      : endianism
+ *       Type          : hw_endianism_t
+ *       Description     : endianism for the given page
+ *
+ *       Identifier      : element_size
+ *       Type          : hw_element_size_t
+ *       Description     : The element size ( 8,16, 32 or 64 bit)
+ *
+ *       Identifier      : mixed_size
+ *       Type          : hw_mmu_mixed_size_t
+ *       Description     : Element Size to follow CPU or TLB
+ *
+ * RETURNS:
+ *
+ *       Type          : hw_status
+ *       Description     : 0            -- No errors occured
+ *                      RET_BAD_NULL_PARAM     -- A Pointer Paramater
+ *                                                     was set to NULL
+ *                      RET_PARAM_OUT_OF_RANGE -- Input Parameter
+ *                                                     out of Range
+ *
+ * PURPOSE:          : Set MMU_CAM reg
+ *
+ * METHOD:            : Check the Input parameters and set the RAM entry.
+ */
+static hw_status mmu_set_ram_entry(const void __iomem *base_address,
+                                  const u32 physical_addr,
+                                  enum hw_endianism_t endianism,
+                                  enum hw_element_size_t element_size,
+                                  enum hw_mmu_mixed_size_t mixed_size);
+
+/* HW FUNCTIONS */
+
+hw_status hw_mmu_enable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET);
+
+       return status;
+}
+
+hw_status hw_mmu_disable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR);
+
+       return status;
+}
+
+hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
+                               u32 num_locked_entries)
+{
+       hw_status status = 0;
+
+       MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, num_locked_entries);
+
+       return status;
+}
+
+hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
+                               u32 victim_entry_num)
+{
+       hw_status status = 0;
+
+       MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victim_entry_num);
+
+       return status;
+}
+
+hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask)
+{
+       hw_status status = 0;
+
+       MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irq_mask);
+
+       return status;
+}
+
+hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask)
+{
+       hw_status status = 0;
+       u32 irq_reg;
+
+       irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
+
+       MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irq_mask);
+
+       return status;
+}
+
+hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask)
+{
+       hw_status status = 0;
+       u32 irq_reg;
+
+       irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
+
+       MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irq_mask);
+
+       return status;
+}
+
+hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask)
+{
+       hw_status status = 0;
+
+       *irq_mask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address);
+
+       return status;
+}
+
+hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr)
+{
+       hw_status status = 0;
+
+       /* read values from register */
+       *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address);
+
+       return status;
+}
+
+hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr)
+{
+       hw_status status = 0;
+       u32 load_ttb;
+
+       load_ttb = ttb_phys_addr & ~0x7FUL;
+       /* write values to register */
+       MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb);
+
+       return status;
+}
+
+hw_status hw_mmu_twl_enable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET);
+
+       return status;
+}
+
+hw_status hw_mmu_twl_disable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR);
+
+       return status;
+}
+
+hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr,
+                          u32 page_sz)
+{
+       hw_status status = 0;
+       u32 virtual_addr_tag;
+       enum hw_mmu_page_size_t pg_size_bits;
+
+       switch (page_sz) {
+       case HW_PAGE_SIZE4KB:
+               pg_size_bits = HW_MMU_SMALL_PAGE;
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               pg_size_bits = HW_MMU_LARGE_PAGE;
+               break;
+
+       case HW_PAGE_SIZE1MB:
+               pg_size_bits = HW_MMU_SECTION;
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               pg_size_bits = HW_MMU_SUPERSECTION;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       /* Generate the 20-bit tag from virtual address */
+       virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
+
+       mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag);
+
+       mmu_flush_entry(base_address);
+
+       return status;
+}
+
+hw_status hw_mmu_tlb_add(const void __iomem *base_address,
+                        u32 physical_addr,
+                        u32 virtual_addr,
+                        u32 page_sz,
+                        u32 entry_num,
+                        struct hw_mmu_map_attrs_t *map_attrs,
+                        s8 preserved_bit, s8 valid_bit)
+{
+       hw_status status = 0;
+       u32 lock_reg;
+       u32 virtual_addr_tag;
+       enum hw_mmu_page_size_t mmu_pg_size;
+
+       /*Check the input Parameters */
+       switch (page_sz) {
+       case HW_PAGE_SIZE4KB:
+               mmu_pg_size = HW_MMU_SMALL_PAGE;
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               mmu_pg_size = HW_MMU_LARGE_PAGE;
+               break;
+
+       case HW_PAGE_SIZE1MB:
+               mmu_pg_size = HW_MMU_SECTION;
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               mmu_pg_size = HW_MMU_SUPERSECTION;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address);
+
+       /* Generate the 20-bit tag from virtual address */
+       virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
+
+       /* Write the fields in the CAM Entry Register */
+       mmu_set_cam_entry(base_address, mmu_pg_size, preserved_bit, valid_bit,
+                         virtual_addr_tag);
+
+       /* Write the different fields of the RAM Entry Register */
+       /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */
+       mmu_set_ram_entry(base_address, physical_addr, map_attrs->endianism,
+                         map_attrs->element_size, map_attrs->mixed_size);
+
+       /* Update the MMU Lock Register */
+       /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */
+       MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entry_num);
+
+       /* Enable loading of an entry in TLB by writing 1
+          into LD_TLB_REG register */
+       MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB);
+
+       MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg);
+
+       return status;
+}
+
+hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
+                        u32 physical_addr,
+                        u32 virtual_addr,
+                        u32 page_sz, struct hw_mmu_map_attrs_t *map_attrs)
+{
+       hw_status status = 0;
+       u32 pte_addr, pte_val;
+       s32 num_entries = 1;
+
+       switch (page_sz) {
+       case HW_PAGE_SIZE4KB:
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SMALL_PAGE_MASK);
+               pte_val =
+                   ((physical_addr & MMU_SMALL_PAGE_MASK) |
+                    (map_attrs->endianism << 9) | (map_attrs->
+                                                   element_size << 4) |
+                    (map_attrs->mixed_size << 11) | 2);
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_LARGE_PAGE_MASK);
+               pte_val =
+                   ((physical_addr & MMU_LARGE_PAGE_MASK) |
+                    (map_attrs->endianism << 9) | (map_attrs->
+                                                   element_size << 4) |
+                    (map_attrs->mixed_size << 11) | 1);
+               break;
+
+       case HW_PAGE_SIZE1MB:
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SECTION_ADDR_MASK);
+               pte_val =
+                   ((((physical_addr & MMU_SECTION_ADDR_MASK) |
+                      (map_attrs->endianism << 15) | (map_attrs->
+                                                      element_size << 10) |
+                      (map_attrs->mixed_size << 17)) & ~0x40000) | 0x2);
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SSECTION_ADDR_MASK);
+               pte_val =
+                   (((physical_addr & MMU_SSECTION_ADDR_MASK) |
+                     (map_attrs->endianism << 15) | (map_attrs->
+                                                     element_size << 10) |
+                     (map_attrs->mixed_size << 17)
+                    ) | 0x40000 | 0x2);
+               break;
+
+       case HW_MMU_COARSE_PAGE_SIZE:
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SECTION_ADDR_MASK);
+               pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       while (--num_entries >= 0)
+               ((u32 *) pte_addr)[num_entries] = pte_val;
+
+       return status;
+}
+
+hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size)
+{
+       hw_status status = 0;
+       u32 pte_addr;
+       s32 num_entries = 1;
+
+       switch (page_size) {
+       case HW_PAGE_SIZE4KB:
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SMALL_PAGE_MASK);
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_LARGE_PAGE_MASK);
+               break;
+
+       case HW_PAGE_SIZE1MB:
+       case HW_MMU_COARSE_PAGE_SIZE:
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SECTION_ADDR_MASK);
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SSECTION_ADDR_MASK);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       while (--num_entries >= 0)
+               ((u32 *) pte_addr)[num_entries] = 0;
+
+       return status;
+}
+
+/* mmu_flush_entry */
+static hw_status mmu_flush_entry(const void __iomem *base_address)
+{
+       hw_status status = 0;
+       u32 flush_entry_data = 0x1;
+
+       /* write values to register */
+       MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data);
+
+       return status;
+}
+
+/* mmu_set_cam_entry */
+static hw_status mmu_set_cam_entry(const void __iomem *base_address,
+                                  const u32 page_sz,
+                                  const u32 preserved_bit,
+                                  const u32 valid_bit,
+                                  const u32 virtual_addr_tag)
+{
+       hw_status status = 0;
+       u32 mmu_cam_reg;
+
+       mmu_cam_reg = (virtual_addr_tag << 12);
+       mmu_cam_reg = (mmu_cam_reg) | (page_sz) | (valid_bit << 2) |
+           (preserved_bit << 3);
+
+       /* write values to register */
+       MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg);
+
+       return status;
+}
+
+/* mmu_set_ram_entry */
+static hw_status mmu_set_ram_entry(const void __iomem *base_address,
+                                  const u32 physical_addr,
+                                  enum hw_endianism_t endianism,
+                                  enum hw_element_size_t element_size,
+                                  enum hw_mmu_mixed_size_t mixed_size)
+{
+       hw_status status = 0;
+       u32 mmu_ram_reg;
+
+       mmu_ram_reg = (physical_addr & MMU_ADDR_MASK);
+       mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) |
+                                      (mixed_size << 6));
+
+       /* write values to register */
+       MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg);
+
+       return status;
+
+}
+
+void hw_mmu_tlb_flush_all(const void __iomem *base)
+{
+       __raw_writeb(1, base + MMU_GFLUSH);
+}
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h
new file mode 100644 (file)
index 0000000..1458a2c
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * hw_mmu.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * MMU types and API declarations
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _HW_MMU_H
+#define _HW_MMU_H
+
+#include <linux/types.h>
+
+/* Bitmasks for interrupt sources */
+#define HW_MMU_TRANSLATION_FAULT   0x2
+#define HW_MMU_ALL_INTERRUPTS      0x1F
+
+#define HW_MMU_COARSE_PAGE_SIZE 0x400
+
+/* hw_mmu_mixed_size_t:  Enumerated Type used to specify whether to follow
+                       CPU/TLB Element size */
+enum hw_mmu_mixed_size_t {
+       HW_MMU_TLBES,
+       HW_MMU_CPUES
+};
+
+/* hw_mmu_map_attrs_t:  Struct containing MMU mapping attributes */
+struct hw_mmu_map_attrs_t {
+       enum hw_endianism_t endianism;
+       enum hw_element_size_t element_size;
+       enum hw_mmu_mixed_size_t mixed_size;
+       bool donotlockmpupage;
+};
+
+extern hw_status hw_mmu_enable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_disable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
+                                      u32 num_locked_entries);
+
+extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
+                                      u32 victim_entry_num);
+
+/* For MMU faults */
+extern hw_status hw_mmu_event_ack(const void __iomem *base_address,
+                                 u32 irq_mask);
+
+extern hw_status hw_mmu_event_disable(const void __iomem *base_address,
+                                     u32 irq_mask);
+
+extern hw_status hw_mmu_event_enable(const void __iomem *base_address,
+                                    u32 irq_mask);
+
+extern hw_status hw_mmu_event_status(const void __iomem *base_address,
+                                    u32 *irq_mask);
+
+extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address,
+                                       u32 *addr);
+
+/* Set the TT base address */
+extern hw_status hw_mmu_ttb_set(const void __iomem *base_address,
+                               u32 ttb_phys_addr);
+
+extern hw_status hw_mmu_twl_enable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_twl_disable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address,
+                                 u32 virtual_addr, u32 page_sz);
+
+extern hw_status hw_mmu_tlb_add(const void __iomem *base_address,
+                               u32 physical_addr,
+                               u32 virtual_addr,
+                               u32 page_sz,
+                               u32 entry_num,
+                               struct hw_mmu_map_attrs_t *map_attrs,
+                               s8 preserved_bit, s8 valid_bit);
+
+/* For PTEs */
+extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
+                               u32 physical_addr,
+                               u32 virtual_addr,
+                               u32 page_sz,
+                               struct hw_mmu_map_attrs_t *map_attrs);
+
+extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va,
+                                 u32 virtual_addr, u32 page_size);
+
+void hw_mmu_tlb_flush_all(const void __iomem *base);
+
+static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va)
+{
+       u32 pte_addr;
+       u32 va31_to20;
+
+       va31_to20 = va >> (20 - 2);     /* Left-shift by 2 here itself */
+       va31_to20 &= 0xFFFFFFFCUL;
+       pte_addr = l1_base + va31_to20;
+
+       return pte_addr;
+}
+
+static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va)
+{
+       u32 pte_addr;
+
+       pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC);
+
+       return pte_addr;
+}
+
+static inline u32 hw_mmu_pte_coarse_l1(u32 pte_val)
+{
+       u32 pte_coarse;
+
+       pte_coarse = pte_val & 0xFFFFFC00;
+
+       return pte_coarse;
+}
+
+static inline u32 hw_mmu_pte_size_l1(u32 pte_val)
+{
+       u32 pte_size = 0;
+
+       if ((pte_val & 0x3) == 0x1) {
+               /* Points to L2 PT */
+               pte_size = HW_MMU_COARSE_PAGE_SIZE;
+       }
+
+       if ((pte_val & 0x3) == 0x2) {
+               if (pte_val & (1 << 18))
+                       pte_size = HW_PAGE_SIZE16MB;
+               else
+                       pte_size = HW_PAGE_SIZE1MB;
+       }
+
+       return pte_size;
+}
+
+static inline u32 hw_mmu_pte_size_l2(u32 pte_val)
+{
+       u32 pte_size = 0;
+
+       if (pte_val & 0x2)
+               pte_size = HW_PAGE_SIZE4KB;
+       else if (pte_val & 0x1)
+               pte_size = HW_PAGE_SIZE64KB;
+
+       return pte_size;
+}
+
+#endif /* _HW_MMU_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h
new file mode 100644 (file)
index 0000000..8efd1fb
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * _chnl_sm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Private header file defining channel manager and channel objects for
+ * a shared memory channel driver.
+ *
+ * Shared between the modules implementing the shared memory channel class
+ * library.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _CHNL_SM_
+#define _CHNL_SM_
+
+#include <dspbridge/dspapi.h>
+#include <dspbridge/dspdefs.h>
+
+#include <dspbridge/list.h>
+#include <dspbridge/ntfy.h>
+
+/*
+ *  These target side symbols define the beginning and ending addresses
+ *  of shared memory buffer. They are defined in the *cfg.cmd file by
+ *  cdb code.
+ */
+#define CHNL_SHARED_BUFFER_BASE_SYM "_SHM_BEG"
+#define CHNL_SHARED_BUFFER_LIMIT_SYM "_SHM_END"
+#define BRIDGEINIT_BIOSGPTIMER "_BRIDGEINIT_BIOSGPTIMER"
+#define BRIDGEINIT_LOADMON_GPTIMER "_BRIDGEINIT_LOADMON_GPTIMER"
+
+#ifndef _CHNL_WORDSIZE
+#define _CHNL_WORDSIZE 4       /* default _CHNL_WORDSIZE is 2 bytes/word */
+#endif
+
+#define MAXOPPS 16
+
+/* Shared memory config options */
+#define SHM_CURROPP    0       /* Set current OPP in shm */
+#define SHM_OPPINFO    1       /* Set dsp voltage and freq table values */
+#define SHM_GETOPP     2       /* Get opp requested by DSP */
+
+struct opp_table_entry {
+       u32 voltage;
+       u32 frequency;
+       u32 min_freq;
+       u32 max_freq;
+};
+
+struct opp_struct {
+       u32 curr_opp_pt;
+       u32 num_opp_pts;
+       struct opp_table_entry opp_point[MAXOPPS];
+};
+
+/* Request to MPU */
+struct opp_rqst_struct {
+       u32 rqst_dsp_freq;
+       u32 rqst_opp_pt;
+};
+
+/* Info to MPU */
+struct load_mon_struct {
+       u32 curr_dsp_load;
+       u32 curr_dsp_freq;
+       u32 pred_dsp_load;
+       u32 pred_dsp_freq;
+};
+
+/* Structure in shared between DSP and PC for communication. */
+struct shm {
+       u32 dsp_free_mask;      /* Written by DSP, read by PC. */
+       u32 host_free_mask;     /* Written by PC, read by DSP */
+
+       u32 input_full;         /* Input channel has unread data. */
+       u32 input_id;           /* Channel for which input is available. */
+       u32 input_size;         /* Size of data block (in DSP words). */
+
+       u32 output_full;        /* Output channel has unread data. */
+       u32 output_id;          /* Channel for which output is available. */
+       u32 output_size;        /* Size of data block (in DSP words). */
+
+       u32 arg;                /* Arg for Issue/Reclaim (23 bits for 55x). */
+       u32 resvd;              /* Keep structure size even for 32-bit DSPs */
+
+       /* Operating Point structure */
+       struct opp_struct opp_table_struct;
+       /* Operating Point Request structure */
+       struct opp_rqst_struct opp_request;
+       /* load monitor information structure */
+       struct load_mon_struct load_mon_info;
+#ifdef CONFIG_TIDSPBRIDGE_WDT3
+       /* Flag for WDT enable/disable F/I clocks */
+       u32 wdt_setclocks;
+       u32 wdt_overflow;       /* WDT overflow time */
+       char dummy[176];        /* padding to 256 byte boundary */
+#else
+       char dummy[184];        /* padding to 256 byte boundary */
+#endif
+       u32 shm_dbg_var[64];    /* shared memory debug variables */
+};
+
+       /* Channel Manager: only one created per board: */
+struct chnl_mgr {
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+       struct io_mgr *hio_mgr; /* IO manager */
+       /* Device this board represents */
+       struct dev_object *hdev_obj;
+
+       /* These fields initialized in bridge_chnl_create(): */
+       u32 dw_output_mask;     /* Host output channels w/ full buffers */
+       u32 dw_last_output;     /* Last output channel fired from DPC */
+       /* Critical section object handle */
+       spinlock_t chnl_mgr_lock;
+       u32 word_size;          /* Size in bytes of DSP word */
+       u8 max_channels;        /* Total number of channels */
+       u8 open_channels;       /* Total number of open channels */
+       struct chnl_object **ap_channel;        /* Array of channels */
+       u8 dw_type;             /* Type of channel class library */
+       /* If no shm syms, return for CHNL_Open */
+       int chnl_open_status;
+};
+
+/*
+ *  Channel: up to CHNL_MAXCHANNELS per board or if DSP-DMA supported then
+ *     up to CHNL_MAXCHANNELS + CHNL_MAXDDMACHNLS per board.
+ */
+struct chnl_object {
+       /* Pointer back to channel manager */
+       struct chnl_mgr *chnl_mgr_obj;
+       u32 chnl_id;            /* Channel id */
+       u8 dw_state;            /* Current channel state */
+       s8 chnl_mode;           /* Chnl mode and attributes */
+       /* Chnl I/O completion event (user mode) */
+       void *user_event;
+       /* Abstract syncronization object */
+       struct sync_object *sync_event;
+       u32 process;            /* Process which created this channel */
+       u32 pcb_arg;            /* Argument to use with callback */
+       struct lst_list *pio_requests;  /* List of IOR's to driver */
+       s32 cio_cs;             /* Number of IOC's in queue */
+       s32 cio_reqs;           /* Number of IORequests in queue */
+       s32 chnl_packets;       /* Initial number of free Irps */
+       /* List of IOC's from driver */
+       struct lst_list *pio_completions;
+       struct lst_list *free_packets_list;     /* List of free Irps */
+       struct ntfy_object *ntfy_obj;
+       u32 bytes_moved;        /* Total number of bytes transfered */
+
+       /* For DSP-DMA */
+
+       /* Type of chnl transport:CHNL_[PCPY][DDMA] */
+       u32 chnl_type;
+};
+
+/* I/O Request/completion packet: */
+struct chnl_irp {
+       struct list_head link;  /* Link to next CHIRP in queue. */
+       /* Buffer to be filled/emptied. (User) */
+       u8 *host_user_buf;
+       /* Buffer to be filled/emptied. (System) */
+       u8 *host_sys_buf;
+       u32 dw_arg;             /* Issue/Reclaim argument. */
+       u32 dsp_tx_addr;        /* Transfer address on DSP side. */
+       u32 byte_size;          /* Bytes transferred. */
+       u32 buf_size;           /* Actual buffer size when allocated. */
+       u32 status;             /* Status of IO completion. */
+};
+
+#endif /* _CHNL_SM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/brddefs.h b/drivers/staging/tidspbridge/include/dspbridge/brddefs.h
new file mode 100644 (file)
index 0000000..f80d9a5
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * brddefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global BRD constants and types, shared between DSP API and Bridge driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef BRDDEFS_
+#define BRDDEFS_
+
+/* platform status values */
+#define BRD_STOPPED     0x0    /* No Monitor Loaded, Not running. */
+#define BRD_IDLE        0x1    /* Monitor Loaded, but suspended. */
+#define BRD_RUNNING     0x2    /* Monitor loaded, and executing. */
+#define BRD_UNKNOWN     0x3    /* Board state is indeterminate. */
+#define BRD_SYNCINIT    0x4
+#define BRD_LOADED      0x5
+#define BRD_LASTSTATE   BRD_LOADED     /* Set to highest legal board state. */
+#define BRD_SLEEP_TRANSITION 0x6       /* Sleep transition in progress */
+#define BRD_HIBERNATION 0x7    /* MPU initiated hibernation */
+#define BRD_RETENTION     0x8  /* Retention mode */
+#define BRD_DSP_HIBERNATION     0x9    /* DSP initiated hibernation */
+#define BRD_ERROR              0xA     /* Board state is Error */
+
+/* BRD Object */
+struct brd_object;
+
+#endif /* BRDDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfg.h b/drivers/staging/tidspbridge/include/dspbridge/cfg.h
new file mode 100644 (file)
index 0000000..05a8999
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * cfg.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * PM Configuration module.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CFG_
+#define CFG_
+#include <dspbridge/host_os.h>
+#include <dspbridge/cfgdefs.h>
+
+/*
+ *  ======== cfg_exit ========
+ *  Purpose:
+ *      Discontinue usage of the CFG module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      cfg_init(void) was previously called.
+ *  Ensures:
+ *      Resources acquired in cfg_init(void) are freed.
+ */
+extern void cfg_exit(void);
+
+/*
+ *  ======== cfg_get_auto_start ========
+ *  Purpose:
+ *      Retreive the autostart mask, if any, for this board.
+ *  Parameters:
+ *      dev_node_obj:  Handle to the dev_node who's driver we are querying.
+ *      auto_start:   Ptr to location for 32 bit autostart mask.
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT:  dev_node_obj is invalid.
+ *      -ENODATA: Unable to retreive resource.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:        *auto_start contains autostart mask for this devnode.
+ */
+extern int cfg_get_auto_start(struct cfg_devnode *dev_node_obj,
+                                    u32 *auto_start);
+
+/*
+ *  ======== cfg_get_cd_version ========
+ *  Purpose:
+ *      Retrieves the version of the PM Class Driver.
+ *  Parameters:
+ *      version:    Ptr to u32 to contain version number upon return.
+ *  Returns:
+ *      0:    Success.  version contains Class Driver version in
+ *                  the form: 0xAABBCCDD where AABB is Major version and
+ *                  CCDD is Minor.
+ *      -EPERM:  Failure.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:    Success.
+ *      else:       *version is NULL.
+ */
+extern int cfg_get_cd_version(u32 *version);
+
+/*
+ *  ======== cfg_get_dev_object ========
+ *  Purpose:
+ *      Retrieve the Device Object handle for a given devnode.
+ *  Parameters:
+ *      dev_node_obj:  Platform's dev_node handle from which to retrieve
+ *                     value.
+ *      value:          Ptr to location to store the value.
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT: dev_node_obj is invalid or device_obj is invalid.
+ *      -ENODATA: The resource is not available.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:    *value is set to the retrieved u32.
+ *      else:       *value is set to 0L.
+ */
+extern int cfg_get_dev_object(struct cfg_devnode *dev_node_obj,
+                                    u32 *value);
+
+/*
+ *  ======== cfg_get_exec_file ========
+ *  Purpose:
+ *      Retreive the default executable, if any, for this board.
+ *  Parameters:
+ *      dev_node_obj: Handle to the dev_node who's driver we are querying.
+ *      buf_size:       Size of buffer.
+ *      str_exec_file:  Ptr to character buf to hold ExecFile.
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT:  dev_node_obj is invalid or str_exec_file is invalid.
+ *      -ENODATA: The resource is not available.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:    Not more than buf_size bytes were copied into str_exec_file,
+ *                  and *str_exec_file contains default executable for this
+ *                  devnode.
+ */
+extern int cfg_get_exec_file(struct cfg_devnode *dev_node_obj,
+                                   u32 buf_size, char *str_exec_file);
+
+/*
+ *  ======== cfg_get_object ========
+ *  Purpose:
+ *      Retrieve the Driver Object handle From the Registry
+ *  Parameters:
+ *      value:      Ptr to location to store the value.
+ *      dw_type      Type of Object to Get
+ *  Returns:
+ *      0:    Success.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:    *value is set to the retrieved u32(non-Zero).
+ *      else:       *value is set to 0L.
+ */
+extern int cfg_get_object(u32 *value, u8 dw_type);
+
+/*
+ *  ======== cfg_get_perf_value ========
+ *  Purpose:
+ *      Retrieve a flag indicating whether PERF should log statistics for the
+ *      PM class driver.
+ *  Parameters:
+ *      enable_perf:    Location to store flag.  0 indicates the key was
+ *                      not found, or had a zero value.  A nonzero value
+ *                      means the key was found and had a nonzero value.
+ *  Returns:
+ *  Requires:
+ *      enable_perf != NULL;
+ *  Ensures:
+ */
+extern void cfg_get_perf_value(bool *enable_perf);
+
+/*
+ *  ======== cfg_get_zl_file ========
+ *  Purpose:
+ *      Retreive the ZLFile, if any, for this board.
+ *  Parameters:
+ *      dev_node_obj: Handle to the dev_node who's driver we are querying.
+ *      buf_size:       Size of buffer.
+ *      str_zl_file_name: Ptr to character buf to hold ZLFileName.
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT: str_zl_file_name is invalid or dev_node_obj is invalid.
+ *      -ENODATA: couldn't find the ZLFileName.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:    Not more than buf_size bytes were copied into
+ *                  str_zl_file_name, and *str_zl_file_name contains ZLFileName
+ *                  for this devnode.
+ */
+extern int cfg_get_zl_file(struct cfg_devnode *dev_node_obj,
+                                 u32 buf_size, char *str_zl_file_name);
+
+/*
+ *  ======== cfg_init ========
+ *  Purpose:
+ *      Initialize the CFG module's private state.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occured.
+ *  Requires:
+ *  Ensures:
+ *      A requirement for each of the other public CFG functions.
+ */
+extern bool cfg_init(void);
+
+/*
+ *  ======== cfg_set_dev_object ========
+ *  Purpose:
+ *      Store the Device Object handle for a given devnode.
+ *  Parameters:
+ *      dev_node_obj:   Platform's dev_node handle we are storing value with.
+ *      value:    Arbitrary value to store.
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT:  dev_node_obj is invalid.
+ *      -EPERM:              Internal Error.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:    The Private u32 was successfully set.
+ */
+extern int cfg_set_dev_object(struct cfg_devnode *dev_node_obj,
+                                    u32 value);
+
+/*
+ *  ======== CFG_SetDrvObject ========
+ *  Purpose:
+ *      Store the Driver Object handle.
+ *  Parameters:
+ *      value:          Arbitrary value to store.
+ *      dw_type          Type of Object to Store
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Internal Error.
+ *  Requires:
+ *      CFG initialized.
+ *  Ensures:
+ *      0:        The Private u32 was successfully set.
+ */
+extern int cfg_set_object(u32 value, u8 dw_type);
+
+#endif /* CFG_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
new file mode 100644 (file)
index 0000000..38122db
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * cfgdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global CFG constants and types, shared between DSP API and Bridge driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CFGDEFS_
+#define CFGDEFS_
+
+/* Maximum length of module search path. */
+#define CFG_MAXSEARCHPATHLEN    255
+
+/* Maximum length of general paths. */
+#define CFG_MAXPATH             255
+
+/* Host Resources: */
+#define CFG_MAXMEMREGISTERS     9
+#define CFG_MAXIOPORTS          20
+#define CFG_MAXIRQS             7
+#define CFG_MAXDMACHANNELS      7
+
+/* IRQ flag */
+#define CFG_IRQSHARED           0x01   /* IRQ can be shared */
+
+/* DSP Resources: */
+#define CFG_DSPMAXMEMTYPES      10
+#define CFG_DEFAULT_NUM_WINDOWS 1      /* We support only one window. */
+
+/* A platform-related device handle: */
+struct cfg_devnode;
+
+/*
+ *  Host resource structure.
+ */
+struct cfg_hostres {
+       u32 num_mem_windows;    /* Set to default */
+       /* This is the base.memory */
+       u32 dw_mem_base[CFG_MAXMEMREGISTERS];   /* shm virtual address */
+       u32 dw_mem_length[CFG_MAXMEMREGISTERS]; /* Length of the Base */
+       u32 dw_mem_phys[CFG_MAXMEMREGISTERS];   /* shm Physical address */
+       u8 birq_registers;      /* IRQ Number */
+       u8 birq_attrib;         /* IRQ Attribute */
+       u32 dw_offset_for_monitor;      /* The Shared memory starts from
+                                        * dw_mem_base + this offset */
+       /*
+        *  Info needed by NODE for allocating channels to communicate with RMS:
+        *      dw_chnl_offset:       Offset of RMS channels. Lower channels are
+        *                          reserved.
+        *      dw_chnl_buf_size:      Size of channel buffer to send to RMS
+        *      dw_num_chnls:           Total number of channels
+        *                              (including reserved).
+        */
+       u32 dw_chnl_offset;
+       u32 dw_chnl_buf_size;
+       u32 dw_num_chnls;
+       void __iomem *dw_per_base;
+       u32 dw_per_pm_base;
+       u32 dw_core_pm_base;
+       void __iomem *dw_dmmu_base;
+       void __iomem *dw_sys_ctrl_base;
+};
+
+struct cfg_dspmemdesc {
+       u32 mem_type;           /* Type of memory. */
+       u32 ul_min;             /* Minimum amount of memory of this type. */
+       u32 ul_max;             /* Maximum amount of memory of this type. */
+};
+
+#endif /* CFGDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnl.h b/drivers/staging/tidspbridge/include/dspbridge/chnl.h
new file mode 100644 (file)
index 0000000..8733b3b
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * chnl.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP API channel interface: multiplexes data streams through the single
+ * physical link managed by a Bridge driver.
+ *
+ * See DSP API chnl.h for more details.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CHNL_
+#define CHNL_
+
+#include <dspbridge/chnlpriv.h>
+
+/*
+ *  ======== chnl_close ========
+ *  Purpose:
+ *      Ensures all pending I/O on this channel is cancelled, discards all
+ *      queued I/O completion notifications, then frees the resources allocated
+ *      for this channel, and makes the corresponding logical channel id
+ *      available for subsequent use.
+ *  Parameters:
+ *      chnl_obj:          Channel object handle.
+ *  Returns:
+ *      0:        Success;
+ *      -EFAULT:    Invalid chnl_obj.
+ *  Requires:
+ *      chnl_init(void) called.
+ *      No thread must be blocked on this channel's I/O completion event.
+ *  Ensures:
+ *      0:        The I/O completion event for this channel is freed.
+ *                      chnl_obj is no longer valid.
+ */
+extern int chnl_close(struct chnl_object *chnl_obj);
+
+/*
+ *  ======== chnl_create ========
+ *  Purpose:
+ *      Create a channel manager object, responsible for opening new channels
+ *      and closing old ones for a given board.
+ *  Parameters:
+ *      channel_mgr:    Location to store a channel manager object on output.
+ *      hdev_obj:     Handle to a device object.
+ *      mgr_attrts:      Channel manager attributes.
+ *      mgr_attrts->max_channels:   Max channels
+ *      mgr_attrts->birq:        Channel's I/O IRQ number.
+ *      mgr_attrts->irq_shared:     TRUE if the IRQ is shareable.
+ *      mgr_attrts->word_size:   DSP Word size in equivalent PC bytes..
+ *  Returns:
+ *      0:                Success;
+ *      -EFAULT:            hdev_obj is invalid.
+ *      -EINVAL: max_channels is 0.
+ *               Invalid DSP word size (must be > 0).
+ *               Invalid base address for DSP communications.
+ *      -ENOMEM:            Insufficient memory for requested resources.
+ *      -EIO:             Unable to plug channel ISR for configured IRQ.
+ *      -ECHRNG:     This manager cannot handle this many channels.
+ *      -EEXIST:       Channel manager already exists for this device.
+ *  Requires:
+ *      chnl_init(void) called.
+ *      channel_mgr != NULL.
+ *      mgr_attrts != NULL.
+ *  Ensures:
+ *      0:                Subsequent calls to chnl_create() for the same
+ *                              board without an intervening call to
+ *                              chnl_destroy() will fail.
+ */
+extern int chnl_create(struct chnl_mgr **channel_mgr,
+                             struct dev_object *hdev_obj,
+                             const struct chnl_mgrattrs *mgr_attrts);
+
+/*
+ *  ======== chnl_destroy ========
+ *  Purpose:
+ *      Close all open channels, and destroy the channel manager.
+ *  Parameters:
+ *      hchnl_mgr:           Channel manager object.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        hchnl_mgr was invalid.
+ *  Requires:
+ *      chnl_init(void) called.
+ *  Ensures:
+ *      0:            Cancels I/O on each open channel.
+ *                          Closes each open channel.
+ *                          chnl_create may subsequently be called for the
+ *                          same board.
+ */
+extern int chnl_destroy(struct chnl_mgr *hchnl_mgr);
+
+/*
+ *  ======== chnl_exit ========
+ *  Purpose:
+ *      Discontinue usage of the CHNL module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      chnl_init(void) previously called.
+ *  Ensures:
+ *      Resources, if any acquired in chnl_init(void), are freed when the last
+ *      client of CHNL calls chnl_exit(void).
+ */
+extern void chnl_exit(void);
+
+/*
+ *  ======== chnl_init ========
+ *  Purpose:
+ *      Initialize the CHNL module's private state.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occurred.
+ *  Requires:
+ *  Ensures:
+ *      A requirement for each of the other public CHNL functions.
+ */
+extern bool chnl_init(void);
+
+#endif /* CHNL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h
new file mode 100644 (file)
index 0000000..5bf5f6b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * chnldefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * System-wide channel objects and constants.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CHNLDEFS_
+#define CHNLDEFS_
+
+/* Channel id option. */
+#define CHNL_PICKFREE       (~0UL)     /* Let manager pick a free channel. */
+
+/* Channel manager limits: */
+#define CHNL_INITIOREQS      4 /* Default # of I/O requests. */
+
+/* Channel modes */
+#define CHNL_MODETODSP         0       /* Data streaming to the DSP. */
+#define CHNL_MODEFROMDSP       1       /* Data streaming from the DSP. */
+
+/* GetIOCompletion flags */
+#define CHNL_IOCINFINITE     0xffffffff        /* Wait forever for IO completion. */
+#define CHNL_IOCNOWAIT       0x0       /* Dequeue an IOC, if available. */
+
+/* IO Completion Record status: */
+#define CHNL_IOCSTATCOMPLETE 0x0000    /* IO Completed. */
+#define CHNL_IOCSTATCANCEL   0x0002    /* IO was cancelled */
+#define CHNL_IOCSTATTIMEOUT  0x0008    /* Wait for IOC timed out. */
+#define CHNL_IOCSTATEOS      0x8000    /* End Of Stream reached. */
+
+/* Macros for checking I/O Completion status: */
+#define CHNL_IS_IO_COMPLETE(ioc)  (!(ioc.status & ~CHNL_IOCSTATEOS))
+#define CHNL_IS_IO_CANCELLED(ioc) (ioc.status & CHNL_IOCSTATCANCEL)
+#define CHNL_IS_TIMED_OUT(ioc)    (ioc.status & CHNL_IOCSTATTIMEOUT)
+
+/* Channel attributes: */
+struct chnl_attr {
+       u32 uio_reqs;           /* Max # of preallocated I/O requests. */
+       void *event_obj;        /* User supplied auto-reset event object. */
+       char *pstr_event_name;  /* Ptr to name of user event object. */
+       void *reserved1;        /* Reserved for future use. */
+       u32 reserved2;          /* Reserved for future use. */
+
+};
+
+/* I/O completion record: */
+struct chnl_ioc {
+       void *pbuf;             /* Buffer to be filled/emptied. */
+       u32 byte_size;          /* Bytes transferred. */
+       u32 buf_size;           /* Actual buffer size in bytes */
+       u32 status;             /* Status of IO completion. */
+       u32 dw_arg;             /* User argument associated with pbuf. */
+};
+
+#endif /* CHNLDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h
new file mode 100644 (file)
index 0000000..9292100
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * chnlpriv.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Private channel header shared between DSPSYS, DSPAPI and
+ * Bridge driver modules.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CHNLPRIV_
+#define CHNLPRIV_
+
+#include <dspbridge/chnldefs.h>
+#include <dspbridge/devdefs.h>
+#include <dspbridge/sync.h>
+
+/* Channel manager limits: */
+#define CHNL_MAXCHANNELS    32 /* Max channels available per transport */
+
+/*
+ *  Trans port channel Id definitions:(must match dsp-side).
+ *
+ *  For CHNL_MAXCHANNELS = 16:
+ *
+ *  ChnlIds:
+ *      0-15  (PCPY) - transport 0)
+ *      16-31 (DDMA) - transport 1)
+ *      32-47 (ZCPY) - transport 2)
+ */
+#define CHNL_PCPY       0      /* Proc-copy transport 0 */
+
+#define CHNL_MAXIRQ     0xff   /* Arbitrarily large number. */
+
+/* The following modes are private: */
+#define CHNL_MODEUSEREVENT  0x1000     /* User provided the channel event. */
+#define CHNL_MODEMASK       0x1001
+
+/* Higher level channel states: */
+#define CHNL_STATEREADY                0       /* Channel ready for I/O. */
+#define CHNL_STATECANCEL       1       /* I/O was cancelled. */
+#define CHNL_STATEEOS          2       /* End Of Stream reached. */
+
+/* Macros for checking mode: */
+#define CHNL_IS_INPUT(mode)      (mode & CHNL_MODEFROMDSP)
+#define CHNL_IS_OUTPUT(mode)     (!CHNL_IS_INPUT(mode))
+
+/* Types of channel class libraries: */
+#define CHNL_TYPESM         1  /* Shared memory driver. */
+#define CHNL_TYPEBM         2  /* Bus Mastering driver. */
+
+/* Max string length of channel I/O completion event name - change if needed */
+#define CHNL_MAXEVTNAMELEN  32
+
+/* Max memory pages lockable in CHNL_PrepareBuffer() - change if needed */
+#define CHNL_MAXLOCKPAGES   64
+
+/* Channel info. */
+struct chnl_info {
+       struct chnl_mgr *hchnl_mgr;     /* Owning channel manager. */
+       u32 cnhl_id;            /* Channel ID. */
+       void *event_obj;        /* Channel I/O completion event. */
+       /*Abstraction of I/O completion event. */
+       struct sync_object *sync_event;
+       s8 dw_mode;             /* Channel mode. */
+       u8 dw_state;            /* Current channel state. */
+       u32 bytes_tx;           /* Total bytes transferred. */
+       u32 cio_cs;             /* Number of IOCs in queue. */
+       u32 cio_reqs;           /* Number of IO Requests in queue. */
+       u32 process;            /* Process owning this channel. */
+};
+
+/* Channel manager info: */
+struct chnl_mgrinfo {
+       u8 dw_type;             /* Type of channel class library. */
+       /* Channel handle, given the channel id. */
+       struct chnl_object *chnl_obj;
+       u8 open_channels;       /* Number of open channels. */
+       u8 max_channels;        /* total # of chnls supported */
+};
+
+/* Channel Manager Attrs: */
+struct chnl_mgrattrs {
+       /* Max number of channels this manager can use. */
+       u8 max_channels;
+       u32 word_size;          /* DSP Word size. */
+};
+
+#endif /* CHNLPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/clk.h b/drivers/staging/tidspbridge/include/dspbridge/clk.h
new file mode 100644 (file)
index 0000000..b239503
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * clk.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Provides Clock functions.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _CLK_H
+#define _CLK_H
+
+enum dsp_clk_id {
+       DSP_CLK_IVA2 = 0,
+       DSP_CLK_GPT5,
+       DSP_CLK_GPT6,
+       DSP_CLK_GPT7,
+       DSP_CLK_GPT8,
+       DSP_CLK_WDT3,
+       DSP_CLK_MCBSP1,
+       DSP_CLK_MCBSP2,
+       DSP_CLK_MCBSP3,
+       DSP_CLK_MCBSP4,
+       DSP_CLK_MCBSP5,
+       DSP_CLK_SSI,
+       DSP_CLK_NOT_DEFINED
+};
+
+/*
+ *  ======== dsp_clk_exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      CLK initialized.
+ *  Ensures:
+ *      Resources used by module are freed when cRef reaches zero.
+ */
+extern void dsp_clk_exit(void);
+
+/*
+ *  ======== dsp_clk_init ========
+ *  Purpose:
+ *      Initializes private state of CLK module.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occured.
+ *  Requires:
+ *  Ensures:
+ *      CLK initialized.
+ */
+extern void dsp_clk_init(void);
+
+void dsp_gpt_wait_overflow(short int clk_id, unsigned int load);
+
+/*
+ *  ======== dsp_clk_enable ========
+ *  Purpose:
+ *      Enables the clock requested.
+ *  Parameters:
+ *  Returns:
+ *      0:     Success.
+ *     -EPERM: Error occured while enabling the clock.
+ *  Requires:
+ *  Ensures:
+ */
+extern int dsp_clk_enable(enum dsp_clk_id clk_id);
+
+u32 dsp_clock_enable_all(u32 dsp_per_clocks);
+
+/*
+ *  ======== dsp_clk_disable ========
+ *  Purpose:
+ *      Disables the clock requested.
+ *  Parameters:
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Error occured while disabling the clock.
+ *  Requires:
+ *  Ensures:
+ */
+extern int dsp_clk_disable(enum dsp_clk_id clk_id);
+
+extern u32 dsp_clk_get_iva2_rate(void);
+
+u32 dsp_clock_disable_all(u32 dsp_per_clocks);
+
+extern void ssi_clk_prepare(bool FLAG);
+
+#endif /* _SYNC_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmm.h b/drivers/staging/tidspbridge/include/dspbridge/cmm.h
new file mode 100644 (file)
index 0000000..a921f1b
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * cmm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * The Communication Memory Management(CMM) module provides shared memory
+ * management services for DSP/BIOS Bridge data streaming and messaging.
+ * Multiple shared memory segments can be registered with CMM. Memory is
+ * coelesced back to the appropriate pool when a buffer is freed.
+ *
+ * The CMM_Xlator[xxx] functions are used for node messaging and data
+ * streaming address translation to perform zero-copy inter-processor
+ * data transfer(GPP<->DSP). A "translator" object is created for a node or
+ * stream object that contains per thread virtual address information. This
+ * translator info is used at runtime to perform SM address translation
+ * to/from the DSP address space.
+ *
+ * Notes:
+ *   cmm_xlator_alloc_buf - Used by Node and Stream modules for SM address
+ *                       translation.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CMM_
+#define CMM_
+
+#include <dspbridge/devdefs.h>
+
+#include <dspbridge/cmmdefs.h>
+#include <dspbridge/host_os.h>
+
+/*
+ *  ======== cmm_calloc_buf ========
+ *  Purpose:
+ *      Allocate memory buffers that can be used for data streaming or
+ *      messaging.
+ *  Parameters:
+ *      hcmm_mgr:   Cmm Mgr handle.
+ *      usize:     Number of bytes to allocate.
+ *      pattr:     Attributes of memory to allocate.
+ *      pp_buf_va:   Address of where to place VA.
+ *  Returns:
+ *      Pointer to a zero'd block of SM memory;
+ *      NULL if memory couldn't be allocated,
+ *      or if byte_size == 0,
+ *  Requires:
+ *      Valid hcmm_mgr.
+ *      CMM initialized.
+ *  Ensures:
+ *      The returned pointer, if not NULL, points to a valid memory block of
+ *      the size requested.
+ *
+ */
+extern void *cmm_calloc_buf(struct cmm_object *hcmm_mgr,
+                           u32 usize, struct cmm_attrs *pattrs,
+                           void **pp_buf_va);
+
+/*
+ *  ======== cmm_create ========
+ *  Purpose:
+ *      Create a communication memory manager object.
+ *  Parameters:
+ *      ph_cmm_mgr:    Location to store a communication manager handle on
+ *                     output.
+ *      hdev_obj: Handle to a device object.
+ *      mgr_attrts: Comm mem manager attributes.
+ *  Returns:
+ *      0:        Success;
+ *      -ENOMEM:    Insufficient memory for requested resources.
+ *      -EPERM:      Failed to initialize critical sect sync object.
+ *
+ *  Requires:
+ *      cmm_init(void) called.
+ *      ph_cmm_mgr != NULL.
+ *      mgr_attrts->ul_min_block_size >= 4 bytes.
+ *  Ensures:
+ *
+ */
+extern int cmm_create(struct cmm_object **ph_cmm_mgr,
+                            struct dev_object *hdev_obj,
+                            const struct cmm_mgrattrs *mgr_attrts);
+
+/*
+ *  ======== cmm_destroy ========
+ *  Purpose:
+ *      Destroy the communication memory manager object.
+ *  Parameters:
+ *      hcmm_mgr:   Cmm Mgr handle.
+ *      force:     Force deallocation of all cmm memory immediately if set TRUE.
+ *                 If FALSE, and outstanding allocations will return -EPERM
+ *                 status.
+ *  Returns:
+ *      0:        CMM object & resources deleted.
+ *      -EPERM:      Unable to free CMM object due to outstanding allocation.
+ *      -EFAULT:    Unable to free CMM due to bad handle.
+ *  Requires:
+ *      CMM is initialized.
+ *      hcmm_mgr != NULL.
+ *  Ensures:
+ *      Memory resources used by Cmm Mgr are freed.
+ */
+extern int cmm_destroy(struct cmm_object *hcmm_mgr, bool force);
+
+/*
+ *  ======== cmm_exit ========
+ *  Purpose:
+ *     Discontinue usage of module. Cleanup CMM module if CMM cRef reaches zero.
+ *  Parameters:
+ *     n/a
+ *  Returns:
+ *     n/a
+ *  Requires:
+ *     CMM is initialized.
+ *  Ensures:
+ */
+extern void cmm_exit(void);
+
+/*
+ *  ======== cmm_free_buf ========
+ *  Purpose:
+ *      Free the given buffer.
+ *  Parameters:
+ *      hcmm_mgr:    Cmm Mgr handle.
+ *      pbuf:       Pointer to memory allocated by cmm_calloc_buf().
+ *      ul_seg_id:    SM segment Id used in CMM_Calloc() attrs.
+ *                  Set to 0 to use default segment.
+ *  Returns:
+ *      0
+ *      -EPERM
+ *  Requires:
+ *      CMM initialized.
+ *      buf_pa != NULL
+ *  Ensures:
+ *
+ */
+extern int cmm_free_buf(struct cmm_object *hcmm_mgr,
+                              void *buf_pa, u32 ul_seg_id);
+
+/*
+ *  ======== cmm_get_handle ========
+ *  Purpose:
+ *      Return the handle to the cmm mgr for the given device obj.
+ *  Parameters:
+ *      hprocessor:   Handle to a Processor.
+ *      ph_cmm_mgr:    Location to store the shared memory mgr handle on
+ *                     output.
+ *
+ *  Returns:
+ *      0:        Cmm Mgr opaque handle returned.
+ *      -EFAULT:    Invalid handle.
+ *  Requires:
+ *      ph_cmm_mgr != NULL
+ *      hdev_obj != NULL
+ *  Ensures:
+ */
+extern int cmm_get_handle(void *hprocessor,
+                                struct cmm_object **ph_cmm_mgr);
+
+/*
+ *  ======== cmm_get_info ========
+ *  Purpose:
+ *      Return the current SM and VM utilization information.
+ *  Parameters:
+ *      hcmm_mgr:     Handle to a Cmm Mgr.
+ *      cmm_info_obj:    Location to store the Cmm information on output.
+ *
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid handle.
+ *      -EINVAL Invalid input argument.
+ *  Requires:
+ *  Ensures:
+ *
+ */
+extern int cmm_get_info(struct cmm_object *hcmm_mgr,
+                              struct cmm_info *cmm_info_obj);
+
+/*
+ *  ======== cmm_init ========
+ *  Purpose:
+ *      Initializes private state of CMM module.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occured.
+ *  Requires:
+ *  Ensures:
+ *      CMM initialized.
+ */
+extern bool cmm_init(void);
+
+/*
+ *  ======== cmm_register_gppsm_seg ========
+ *  Purpose:
+ *      Register a block of SM with the CMM.
+ *  Parameters:
+ *      hcmm_mgr:         Handle to a Cmm Mgr.
+ *      lpGPPBasePA:     GPP Base Physical address.
+ *      ul_size:          Size in GPP bytes.
+ *      dsp_addr_offset  GPP PA to DSP PA Offset.
+ *      c_factor:         Add offset if CMM_ADDTODSPPA, sub if CMM_SUBFROMDSPPA.
+ *      dw_dsp_base:       DSP virtual base byte address.
+ *      ul_dsp_size:       Size of DSP segment in bytes.
+ *      sgmt_id:         Address to store segment Id.
+ *
+ *  Returns:
+ *      0:         Success.
+ *      -EFAULT:     Invalid hcmm_mgr handle.
+ *      -EINVAL: Invalid input argument.
+ *      -EPERM:       Unable to register.
+ *      - On success *sgmt_id is a valid SM segment ID.
+ *  Requires:
+ *      ul_size > 0
+ *      sgmt_id != NULL
+ *      dw_gpp_base_pa != 0
+ *      c_factor = CMM_ADDTODSPPA || c_factor = CMM_SUBFROMDSPPA
+ *  Ensures:
+ *
+ */
+extern int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr,
+                                        unsigned int dw_gpp_base_pa,
+                                        u32 ul_size,
+                                        u32 dsp_addr_offset,
+                                        s8 c_factor,
+                                        unsigned int dw_dsp_base,
+                                        u32 ul_dsp_size,
+                                        u32 *sgmt_id, u32 gpp_base_va);
+
+/*
+ *  ======== cmm_un_register_gppsm_seg ========
+ *  Purpose:
+ *      Unregister the given memory segment that was previously registered
+ *      by cmm_register_gppsm_seg.
+ *  Parameters:
+ *      hcmm_mgr:    Handle to a Cmm Mgr.
+ *      ul_seg_id     Segment identifier returned by cmm_register_gppsm_seg.
+ *  Returns:
+ *       0:         Success.
+ *       -EFAULT:     Invalid handle.
+ *       -EINVAL: Invalid ul_seg_id.
+ *       -EPERM:       Unable to unregister for unknown reason.
+ *  Requires:
+ *  Ensures:
+ *
+ */
+extern int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr,
+                                           u32 ul_seg_id);
+
+/*
+ *  ======== cmm_xlator_alloc_buf ========
+ *  Purpose:
+ *      Allocate the specified SM buffer and create a local memory descriptor.
+ *      Place on the descriptor on the translator's HaQ (Host Alloc'd Queue).
+ *  Parameters:
+ *      xlator:    Handle to a Xlator object.
+ *      va_buf:     Virtual address ptr(client context)
+ *      pa_size:    Size of SM memory to allocate.
+ *  Returns:
+ *      Ptr to valid physical address(Pa) of pa_size bytes, NULL if failed.
+ *  Requires:
+ *      va_buf != 0.
+ *      pa_size != 0.
+ *  Ensures:
+ *
+ */
+extern void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator,
+                                 void *va_buf, u32 pa_size);
+
+/*
+ *  ======== cmm_xlator_create ========
+ *  Purpose:
+ *     Create a translator(xlator) object used for process specific Va<->Pa
+ *     address translation. Node messaging and streams use this to perform
+ *     inter-processor(GPP<->DSP) zero-copy data transfer.
+ *  Parameters:
+ *     xlator:         Address to place handle to a new Xlator handle.
+ *     hcmm_mgr:        Handle to Cmm Mgr associated with this translator.
+ *     xlator_attrs:   Translator attributes used for the client NODE or STREAM.
+ *  Returns:
+ *     0:            Success.
+ *     -EINVAL:    Bad input Attrs.
+ *     -ENOMEM:   Insufficient memory(local) for requested resources.
+ *  Requires:
+ *     xlator != NULL
+ *     hcmm_mgr != NULL
+ *     xlator_attrs != NULL
+ *  Ensures:
+ *
+ */
+extern int cmm_xlator_create(struct cmm_xlatorobject **xlator,
+                                   struct cmm_object *hcmm_mgr,
+                                   struct cmm_xlatorattrs *xlator_attrs);
+
+/*
+ *  ======== cmm_xlator_delete ========
+ *  Purpose:
+ *      Delete translator resources
+ *  Parameters:
+ *      xlator:    handle to translator.
+ *      force:     force = TRUE will free XLators SM buffers/dscriptrs.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Bad translator handle.
+ *      -EPERM:      Unable to free translator resources.
+ *  Requires:
+ *      refs > 0
+ *  Ensures:
+ *
+ */
+extern int cmm_xlator_delete(struct cmm_xlatorobject *xlator,
+                                   bool force);
+
+/*
+ *  ======== cmm_xlator_free_buf ========
+ *  Purpose:
+ *      Free SM buffer and descriptor.
+ *      Does not free client process VM.
+ *  Parameters:
+ *      xlator:    handle to translator.
+ *      buf_va      Virtual address of PA to free.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Bad translator handle.
+ *  Requires:
+ *  Ensures:
+ *
+ */
+extern int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator,
+                                     void *buf_va);
+
+/*
+ *  ======== cmm_xlator_info ========
+ *  Purpose:
+ *      Set/Get process specific "translator" address info.
+ *      This is used to perform fast virtaul address translation
+ *      for shared memory buffers between the GPP and DSP.
+ *  Parameters:
+ *     xlator:     handle to translator.
+ *     paddr:       Virtual base address of segment.
+ *     ul_size:      Size in bytes.
+ *     segm_id:     Segment identifier of SM segment(s)
+ *     set_info     Set xlator fields if TRUE, else return base addr
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Bad translator handle.
+ *  Requires:
+ *      (refs > 0)
+ *      (paddr != NULL)
+ *      (ul_size > 0)
+ *  Ensures:
+ *
+ */
+extern int cmm_xlator_info(struct cmm_xlatorobject *xlator,
+                                 u8 **paddr,
+                                 u32 ul_size, u32 segm_id, bool set_info);
+
+/*
+ *  ======== cmm_xlator_translate ========
+ *  Purpose:
+ *      Perform address translation VA<->PA for the specified stream or
+ *      message shared memory buffer.
+ *  Parameters:
+ *     xlator: handle to translator.
+ *     paddr    address of buffer to translate.
+ *     xtype    Type of address xlation. CMM_PA2VA or CMM_VA2PA.
+ *  Returns:
+ *     Valid address on success, else NULL.
+ *  Requires:
+ *      refs > 0
+ *      paddr != NULL
+ *      xtype >= CMM_VA2PA) && (xtype <= CMM_DSPPA2PA)
+ *  Ensures:
+ *
+ */
+extern void *cmm_xlator_translate(struct cmm_xlatorobject *xlator,
+                                 void *paddr, enum cmm_xlatetype xtype);
+
+#endif /* CMM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h
new file mode 100644 (file)
index 0000000..fbff372
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * cmmdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global MEM constants and types.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CMMDEFS_
+#define CMMDEFS_
+
+#include <dspbridge/list.h>
+
+/* Cmm attributes used in cmm_create() */
+struct cmm_mgrattrs {
+       /* Minimum SM allocation; default 32 bytes. */
+       u32 ul_min_block_size;
+};
+
+/* Attributes for CMM_AllocBuf() & CMM_AllocDesc() */
+struct cmm_attrs {
+       u32 ul_seg_id;          /*  1,2... are SM segments. 0 is not. */
+       u32 ul_alignment;       /*  0,1,2,4....ul_min_block_size */
+};
+
+/*
+ *  DSPPa to GPPPa Conversion Factor.
+ *
+ *  For typical platforms:
+ *      converted Address = PaDSP + ( c_factor * addressToConvert).
+ */
+#define CMM_SUBFROMDSPPA       -1
+#define CMM_ADDTODSPPA         1
+
+#define CMM_ALLSEGMENTS         0xFFFFFF       /* All SegIds */
+#define CMM_MAXGPPSEGS          1      /* Maximum # of SM segs */
+
+/*
+ *  SMSEGs are SM segments the DSP allocates from.
+ *
+ *  This info is used by the GPP to xlate DSP allocated PAs.
+ */
+
+struct cmm_seginfo {
+       u32 dw_seg_base_pa;     /* Start Phys address of SM segment */
+       /* Total size in bytes of segment: DSP+GPP */
+       u32 ul_total_seg_size;
+       u32 dw_gpp_base_pa;     /* Start Phys addr of Gpp SM seg */
+       u32 ul_gpp_size;        /* Size of Gpp SM seg in bytes */
+       u32 dw_dsp_base_va;     /* DSP virt base byte address */
+       u32 ul_dsp_size;        /* DSP seg size in bytes */
+       /* # of current GPP allocations from this segment */
+       u32 ul_in_use_cnt;
+       u32 dw_seg_base_va;     /* Start Virt address of SM seg */
+
+};
+
+/* CMM useful information */
+struct cmm_info {
+       /* # of SM segments registered with this Cmm. */
+       u32 ul_num_gppsm_segs;
+       /* Total # of allocations outstanding for CMM */
+       u32 ul_total_in_use_cnt;
+       /* Min SM block size allocation from cmm_create() */
+       u32 ul_min_block_size;
+       /* Info per registered SM segment. */
+       struct cmm_seginfo seg_info[CMM_MAXGPPSEGS];
+};
+
+/* XlatorCreate attributes */
+struct cmm_xlatorattrs {
+       u32 ul_seg_id;          /* segment Id used for SM allocations */
+       u32 dw_dsp_bufs;        /* # of DSP-side bufs */
+       u32 dw_dsp_buf_size;    /* size of DSP-side bufs in GPP bytes */
+       /* Vm base address alloc'd in client process context */
+       void *vm_base;
+       /* dw_vm_size must be >= (dwMaxNumBufs * dwMaxSize) */
+       u32 dw_vm_size;
+};
+
+/*
+ * Cmm translation types. Use to map SM addresses to process context.
+ */
+enum cmm_xlatetype {
+       CMM_VA2PA = 0,          /* Virtual to GPP physical address xlation */
+       CMM_PA2VA = 1,          /* GPP Physical to virtual */
+       CMM_VA2DSPPA = 2,       /* Va to DSP Pa */
+       CMM_PA2DSPPA = 3,       /* GPP Pa to DSP Pa */
+       CMM_DSPPA2PA = 4,       /* DSP Pa to GPP Pa */
+};
+
+struct cmm_object;
+struct cmm_xlatorobject;
+
+#endif /* CMMDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cod.h b/drivers/staging/tidspbridge/include/dspbridge/cod.h
new file mode 100644 (file)
index 0000000..42bce2e
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * cod.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Code management module for DSPs. This module provides an interface
+ * interface for loading both static and dynamic code objects onto DSP
+ * systems.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef COD_
+#define COD_
+
+#include <dspbridge/dblldefs.h>
+
+#define COD_MAXPATHLENGTH       255
+#define COD_TRACEBEG            "SYS_PUTCBEG"
+#define COD_TRACEEND            "SYS_PUTCEND"
+#define COD_TRACECURPOS        "BRIDGE_SYS_PUTC_current"
+#define COD_TRACESECT           "trace"
+#define COD_TRACEBEGOLD         "PUTCBEG"
+#define COD_TRACEENDOLD         "PUTCEND"
+
+#define COD_NOLOAD              DBLL_NOLOAD
+#define COD_SYMB                DBLL_SYMB
+
+/* COD code manager handle */
+struct cod_manager;
+
+/* COD library handle */
+struct cod_libraryobj;
+
+/* COD attributes */
+struct cod_attrs {
+       u32 ul_reserved;
+};
+
+/*
+ *  Function prototypes for writing memory to a DSP system, allocating
+ *  and freeing DSP memory.
+ */
+typedef u32(*cod_writefxn) (void *priv_ref, u32 dsp_add,
+                           void *pbuf, u32 ul_num_bytes, u32 mem_space);
+
+/*
+ *  ======== cod_close ========
+ *  Purpose:
+ *      Close a library opened with cod_open().
+ *  Parameters:
+ *      lib             - Library handle returned by cod_open().
+ *  Returns:
+ *      None.
+ *  Requires:
+ *      COD module initialized.
+ *      valid lib.
+ *  Ensures:
+ *
+ */
+extern void cod_close(struct cod_libraryobj *lib);
+
+/*
+ *  ======== cod_create ========
+ *  Purpose:
+ *      Create an object to manage code on a DSP system. This object can be
+ *      used to load an initial program image with arguments that can later
+ *      be expanded with dynamically loaded object files.
+ *      Symbol table information is managed by this object and can be retrieved
+ *      using the cod_get_sym_value() function.
+ *  Parameters:
+ *      manager:        created manager object
+ *      str_zl_file:    ZL DLL filename, of length < COD_MAXPATHLENGTH.
+ *      attrs:          attributes to be used by this object. A NULL value
+ *                      will cause default attrs to be used.
+ *  Returns:
+ *      0:                Success.
+ *      -ESPIPE:   ZL_Create failed.
+ *      -ENOSYS:           attrs was not NULL.  We don't yet support
+ *                              non default values of attrs.
+ *  Requires:
+ *      COD module initialized.
+ *      str_zl_file != NULL
+ *  Ensures:
+ */
+extern int cod_create(struct cod_manager **mgr,
+                            char *str_zl_file,
+                            const struct cod_attrs *attrs);
+
+/*
+ *  ======== cod_delete ========
+ *  Purpose:
+ *      Delete a code manager object.
+ *  Parameters:
+ *      cod_mgr_obj:   handle of manager to be deleted
+ *  Returns:
+ *      None.
+ *  Requires:
+ *      COD module initialized.
+ *      valid cod_mgr_obj.
+ *  Ensures:
+ */
+extern void cod_delete(struct cod_manager *cod_mgr_obj);
+
+/*
+ *  ======== cod_exit ========
+ *  Purpose:
+ *      Discontinue usage of the COD module.
+ *  Parameters:
+ *      None.
+ *  Returns:
+ *      None.
+ *  Requires:
+ *      COD initialized.
+ *  Ensures:
+ *      Resources acquired in cod_init(void) are freed.
+ */
+extern void cod_exit(void);
+
+/*
+ *  ======== cod_get_base_lib ========
+ *  Purpose:
+ *      Get handle to the base image DBL library.
+ *  Parameters:
+ *      cod_mgr_obj:   handle of manager to be deleted
+ *      plib:       location to store library handle on output.
+ *  Returns:
+ *      0:    Success.
+ *  Requires:
+ *      COD module initialized.
+ *      valid cod_mgr_obj.
+ *      plib != NULL.
+ *  Ensures:
+ */
+extern int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
+                                  struct dbll_library_obj **plib);
+
+/*
+ *  ======== cod_get_base_name ========
+ *  Purpose:
+ *      Get the name of the base image DBL library.
+ *  Parameters:
+ *      cod_mgr_obj:   handle of manager to be deleted
+ *      sz_name:    location to store library name on output.
+ *      usize:       size of name buffer.
+ *  Returns:
+ *      0:    Success.
+ *      -EPERM:  Buffer too small.
+ *  Requires:
+ *      COD module initialized.
+ *      valid cod_mgr_obj.
+ *      sz_name != NULL.
+ *  Ensures:
+ */
+extern int cod_get_base_name(struct cod_manager *cod_mgr_obj,
+                                   char *sz_name, u32 usize);
+
+/*
+ *  ======== cod_get_entry ========
+ *  Purpose:
+ *      Retrieve the entry point of a loaded DSP program image
+ *  Parameters:
+ *      cod_mgr_obj:   handle of manager to be deleted
+ *      entry_pt:   pointer to location for entry point
+ *  Returns:
+ *      0:       Success.
+ *  Requires:
+ *      COD module initialized.
+ *      valid cod_mgr_obj.
+ *      entry_pt != NULL.
+ *  Ensures:
+ */
+extern int cod_get_entry(struct cod_manager *cod_mgr_obj,
+                               u32 *entry_pt);
+
+/*
+ *  ======== cod_get_loader ========
+ *  Purpose:
+ *      Get handle to the DBL loader.
+ *  Parameters:
+ *      cod_mgr_obj:   handle of manager to be deleted
+ *      loader:     location to store loader handle on output.
+ *  Returns:
+ *      0:    Success.
+ *  Requires:
+ *      COD module initialized.
+ *      valid cod_mgr_obj.
+ *      loader != NULL.
+ *  Ensures:
+ */
+extern int cod_get_loader(struct cod_manager *cod_mgr_obj,
+                                struct dbll_tar_obj **loader);
+
+/*
+ *  ======== cod_get_section ========
+ *  Purpose:
+ *      Retrieve the starting address and length of a section in the COFF file
+ *      given the section name.
+ *  Parameters:
+ *      lib         Library handle returned from cod_open().
+ *      str_sect:   name of the section, with or without leading "."
+ *      addr:       Location to store address.
+ *      len:        Location to store length.
+ *  Returns:
+ *      0:                Success
+ *      -ESPIPE:  Symbols could not be found or have not been loaded onto
+ *                the board.
+ *  Requires:
+ *      COD module initialized.
+ *      valid cod_mgr_obj.
+ *      str_sect != NULL;
+ *      addr != NULL;
+ *      len != NULL;
+ *  Ensures:
+ *      0:  *addr and *len contain the address and length of the
+ *                 section.
+ *      else:  *addr == 0 and *len == 0;
+ *
+ */
+extern int cod_get_section(struct cod_libraryobj *lib,
+                                 char *str_sect,
+                                 u32 *addr, u32 *len);
+
+/*
+ *  ======== cod_get_sym_value ========
+ *  Purpose:
+ *      Retrieve the value for the specified symbol. The symbol is first
+ *      searched for literally and then, if not found, searched for as a
+ *      C symbol.
+ *  Parameters:
+ *      lib:        library handle returned from cod_open().
+ *      pstrSymbol: name of the symbol
+ *      value:      value of the symbol
+ *  Returns:
+ *      0:                Success.
+ *      -ESPIPE:  Symbols could not be found or have not been loaded onto
+ *                the board.
+ *  Requires:
+ *      COD module initialized.
+ *      Valid cod_mgr_obj.
+ *      str_sym != NULL.
+ *      pul_value != NULL.
+ *  Ensures:
+ */
+extern int cod_get_sym_value(struct cod_manager *cod_mgr_obj,
+                                   char *str_sym, u32 * pul_value);
+
+/*
+ *  ======== cod_init ========
+ *  Purpose:
+ *      Initialize the COD module's private state.
+ *  Parameters:
+ *      None.
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occured.
+ *  Requires:
+ *  Ensures:
+ *      A requirement for each of the other public COD functions.
+ */
+extern bool cod_init(void);
+
+/*
+ *  ======== cod_load_base ========
+ *  Purpose:
+ *      Load the initial program image, optionally with command-line arguments,
+ *      on the DSP system managed by the supplied handle. The program to be
+ *      loaded must be the first element of the args array and must be a fully
+ *      qualified pathname.
+ *  Parameters:
+ *      hmgr:       manager to load the code with
+ *      num_argc:   number of arguments in the args array
+ *      args:       array of strings for arguments to DSP program
+ *      write_fxn:   board-specific function to write data to DSP system
+ *      arb:       arbitrary pointer to be passed as first arg to write_fxn
+ *      envp:       array of environment strings for DSP exec.
+ *  Returns:
+ *      0:                   Success.
+ *      -EBADF:       Failed to open target code.
+ *  Requires:
+ *      COD module initialized.
+ *      hmgr is valid.
+ *      num_argc > 0.
+ *      args != NULL.
+ *      args[0] != NULL.
+ *      pfn_write != NULL.
+ *  Ensures:
+ */
+extern int cod_load_base(struct cod_manager *cod_mgr_obj,
+                               u32 num_argc, char *args[],
+                               cod_writefxn pfn_write, void *arb,
+                               char *envp[]);
+
+/*
+ *  ======== cod_open ========
+ *  Purpose:
+ *      Open a library for reading sections. Does not load or set the base.
+ *  Parameters:
+ *      hmgr:           manager to load the code with
+ *      sz_coff_path:   Coff file to open.
+ *      flags:          COD_NOLOAD (don't load symbols) or COD_SYMB (load
+ *                      symbols).
+ *      lib_obj:        Handle returned that can be used in calls to cod_close
+ *                      and cod_get_section.
+ *  Returns:
+ *      S_OK:                   Success.
+ *      -EBADF:       Failed to open target code.
+ *  Requires:
+ *      COD module initialized.
+ *      hmgr is valid.
+ *      flags == COD_NOLOAD || flags == COD_SYMB.
+ *      sz_coff_path != NULL.
+ *  Ensures:
+ */
+extern int cod_open(struct cod_manager *hmgr,
+                          char *sz_coff_path,
+                          u32 flags, struct cod_libraryobj **lib_obj);
+
+/*
+ *  ======== cod_open_base ========
+ *  Purpose:
+ *      Open base image for reading sections. Does not load the base.
+ *  Parameters:
+ *      hmgr:           manager to load the code with
+ *      sz_coff_path:   Coff file to open.
+ *      flags:          Specifies whether to load symbols.
+ *  Returns:
+ *      0:            Success.
+ *      -EBADF:   Failed to open target code.
+ *  Requires:
+ *      COD module initialized.
+ *      hmgr is valid.
+ *      sz_coff_path != NULL.
+ *  Ensures:
+ */
+extern int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
+                               dbll_flags flags);
+
+/*
+ *  ======== cod_read_section ========
+ *  Purpose:
+ *      Retrieve the content of a code section given the section name.
+ *  Parameters:
+ *      cod_mgr_obj    - manager in which to search for the symbol
+ *      str_sect    - name of the section, with or without leading "."
+ *      str_content - buffer to store content of the section.
+ *  Returns:
+ *      0: on success, error code on failure
+ *      -ESPIPE:  Symbols have not been loaded onto the board.
+ *  Requires:
+ *      COD module initialized.
+ *      valid cod_mgr_obj.
+ *      str_sect != NULL;
+ *      str_content != NULL;
+ *  Ensures:
+ *      0:  *str_content stores the content of the named section.
+ */
+extern int cod_read_section(struct cod_libraryobj *lib,
+                                  char *str_sect,
+                                  char *str_content, u32 content_size);
+
+#endif /* COD_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbc.h b/drivers/staging/tidspbridge/include/dspbridge/dbc.h
new file mode 100644 (file)
index 0000000..463760f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * dbc.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * "Design by Contract" programming macros.
+ *
+ * Notes:
+ *   Requires that the GT->ERROR function has been defaulted to a valid
+ *   error handler for the given execution environment.
+ *
+ *   Does not require that GT_init() be called.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DBC_
+#define DBC_
+
+/* Assertion Macros: */
+#ifdef CONFIG_TIDSPBRIDGE_DEBUG
+
+#define DBC_ASSERT(exp) \
+    if (!(exp)) \
+       pr_err("%s, line %d: Assertion (" #exp ") failed.\n", \
+       __FILE__, __LINE__)
+#define DBC_REQUIRE DBC_ASSERT /* Function Precondition. */
+#define DBC_ENSURE  DBC_ASSERT /* Function Postcondition. */
+
+#else
+
+#define DBC_ASSERT(exp) {}
+#define DBC_REQUIRE(exp) {}
+#define DBC_ENSURE(exp) {}
+
+#endif /* DEBUG */
+
+#endif /* DBC_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h
new file mode 100644 (file)
index 0000000..7cc3e12
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * dbdcd.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Defines the DSP/BIOS Bridge Configuration Database (DCD) API.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DBDCD_
+#define DBDCD_
+
+#include <dspbridge/dbdcddef.h>
+#include <dspbridge/host_os.h>
+#include <dspbridge/nldrdefs.h>
+
+/*
+ *  ======== dcd_auto_register ========
+ *  Purpose:
+ *      This function automatically registers DCD objects specified in a
+ *      special COFF section called ".dcd_register"
+ *  Parameters:
+ *      hdcd_mgr:                A DCD manager handle.
+ *      sz_coff_path:           Pointer to name of COFF file containing DCD
+ *                              objects to be registered.
+ *  Returns:
+ *      0:                Success.
+ *      -EACCES: Unable to find auto-registration/read/load section.
+ *      -EFAULT:            Invalid DCD_HMANAGER handle..
+ *  Requires:
+ *      DCD initialized.
+ *  Ensures:
+ *  Note:
+ *      Due to the DCD database construction, it is essential for a DCD-enabled
+ *      COFF file to contain the right COFF sections, especially
+ *      ".dcd_register", which is used for auto registration.
+ */
+extern int dcd_auto_register(struct dcd_manager *hdcd_mgr,
+                                   char *sz_coff_path);
+
+/*
+ *  ======== dcd_auto_unregister ========
+ *  Purpose:
+ *      This function automatically unregisters DCD objects specified in a
+ *      special COFF section called ".dcd_register"
+ *  Parameters:
+ *      hdcd_mgr:                A DCD manager handle.
+ *      sz_coff_path:           Pointer to name of COFF file containing
+ *                              DCD objects to be unregistered.
+ *  Returns:
+ *      0:                Success.
+ *      -EACCES: Unable to find auto-registration/read/load section.
+ *      -EFAULT:            Invalid DCD_HMANAGER handle..
+ *  Requires:
+ *      DCD initialized.
+ *  Ensures:
+ *  Note:
+ *      Due to the DCD database construction, it is essential for a DCD-enabled
+ *      COFF file to contain the right COFF sections, especially
+ *      ".dcd_register", which is used for auto unregistration.
+ */
+extern int dcd_auto_unregister(struct dcd_manager *hdcd_mgr,
+                                     char *sz_coff_path);
+
+/*
+ *  ======== dcd_create_manager ========
+ *  Purpose:
+ *      This function creates a DCD module manager.
+ *  Parameters:
+ *      sz_zl_dll_name: Pointer to a DLL name string.
+ *      dcd_mgr:        A pointer to a DCD manager handle.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Unable to allocate memory for DCD manager handle.
+ *      -EPERM:      General failure.
+ *  Requires:
+ *      DCD initialized.
+ *      sz_zl_dll_name is non-NULL.
+ *      dcd_mgr is non-NULL.
+ *  Ensures:
+ *      A DCD manager handle is created.
+ */
+extern int dcd_create_manager(char *sz_zl_dll_name,
+                                    struct dcd_manager **dcd_mgr);
+
+/*
+ *  ======== dcd_destroy_manager ========
+ *  Purpose:
+ *      This function destroys a DCD module manager.
+ *  Parameters:
+ *      hdcd_mgr:        A DCD manager handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid DCD manager handle.
+ *  Requires:
+ *      DCD initialized.
+ *  Ensures:
+ */
+extern int dcd_destroy_manager(struct dcd_manager *hdcd_mgr);
+
+/*
+ *  ======== dcd_enumerate_object ========
+ *  Purpose:
+ *      This function enumerates currently visible DSP/BIOS Bridge objects
+ *      and returns the UUID and type of each enumerated object.
+ *  Parameters:
+ *      index:              The object enumeration index.
+ *      obj_type:            Type of object to enumerate.
+ *      uuid_obj:              Pointer to a dsp_uuid object.
+ *  Returns:
+ *      0:            Success.
+ *      -EPERM:          Unable to enumerate through the DCD database.
+ *      ENODATA:  Enumeration completed. This is not an error code.
+ *  Requires:
+ *      DCD initialized.
+ *      uuid_obj is a valid pointer.
+ *  Ensures:
+ *  Details:
+ *      This function can be used in conjunction with dcd_get_object_def to
+ *      retrieve object properties.
+ */
+extern int dcd_enumerate_object(s32 index,
+                                      enum dsp_dcdobjtype obj_type,
+                                      struct dsp_uuid *uuid_obj);
+
+/*
+ *  ======== dcd_exit ========
+ *  Purpose:
+ *      This function cleans up the DCD module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      DCD initialized.
+ *  Ensures:
+ */
+extern void dcd_exit(void);
+
+/*
+ *  ======== dcd_get_dep_libs ========
+ *  Purpose:
+ *      Given the uuid of a library and size of array of uuids, this function
+ *      fills the array with the uuids of all dependent libraries of the input
+ *      library.
+ *  Parameters:
+ *      hdcd_mgr: A DCD manager handle.
+ *      uuid_obj: Pointer to a dsp_uuid for a library.
+ *      num_libs: Size of uuid array (number of library uuids).
+ *      dep_lib_uuids: Array of dependent library uuids to be filled in.
+ *      prstnt_dep_libs:    Array indicating if corresponding lib is persistent.
+ *      phase: phase to obtain correct input library
+ *  Returns:
+ *      0: Success.
+ *      -ENOMEM: Memory allocation failure.
+ *      -EACCES: Failure to read section containing library info.
+ *      -EPERM: General failure.
+ *  Requires:
+ *      DCD initialized.
+ *      Valid hdcd_mgr.
+ *      uuid_obj != NULL
+ *      dep_lib_uuids != NULL.
+ *  Ensures:
+ */
+extern int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr,
+                                  struct dsp_uuid *uuid_obj,
+                                  u16 num_libs,
+                                  struct dsp_uuid *dep_lib_uuids,
+                                  bool *prstnt_dep_libs,
+                                  enum nldr_phase phase);
+
+/*
+ *  ======== dcd_get_num_dep_libs ========
+ *  Purpose:
+ *      Given the uuid of a library, determine its number of dependent
+ *      libraries.
+ *  Parameters:
+ *      hdcd_mgr:        A DCD manager handle.
+ *      uuid_obj:          Pointer to a dsp_uuid for a library.
+ *      num_libs:       Size of uuid array (number of library uuids).
+ *      num_pers_libs:  number of persistent dependent library.
+ *      phase:          Phase to obtain correct input library
+ *  Returns:
+ *      0: Success.
+ *      -ENOMEM: Memory allocation failure.
+ *      -EACCES: Failure to read section containing library info.
+ *      -EPERM: General failure.
+ *  Requires:
+ *      DCD initialized.
+ *      Valid hdcd_mgr.
+ *      uuid_obj != NULL
+ *      num_libs != NULL.
+ *  Ensures:
+ */
+extern int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr,
+                                      struct dsp_uuid *uuid_obj,
+                                      u16 *num_libs,
+                                      u16 *num_pers_libs,
+                                      enum nldr_phase phase);
+
+/*
+ *  ======== dcd_get_library_name ========
+ *  Purpose:
+ *      This function returns the name of a (dynamic) library for a given
+ *      UUID.
+ *  Parameters:
+ *      hdcd_mgr: A DCD manager handle.
+ *      uuid_obj:      Pointer to a dsp_uuid that represents a unique DSP/BIOS
+ *                      Bridge object.
+ *      str_lib_name: Buffer to hold library name.
+ *      buff_size: Contains buffer size. Set to string size on output.
+ *      phase:          Which phase to load
+ *      phase_split:    Are phases in multiple libraries
+ *  Returns:
+ *      0: Success.
+ *      -EPERM: General failure.
+ *  Requires:
+ *      DCD initialized.
+ *      Valid hdcd_mgr.
+ *      str_lib_name != NULL.
+ *      uuid_obj != NULL
+ *      buff_size != NULL.
+ *  Ensures:
+ */
+extern int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
+                                      struct dsp_uuid *uuid_obj,
+                                      char *str_lib_name,
+                                      u32 *buff_size,
+                                      enum nldr_phase phase,
+                                      bool *phase_split);
+
+/*
+ *  ======== dcd_get_object_def ========
+ *  Purpose:
+ *      This function returns the properties/attributes of a DSP/BIOS Bridge
+ *      object.
+ *  Parameters:
+ *      hdcd_mgr:            A DCD manager handle.
+ *      uuid_obj:              Pointer to a dsp_uuid that represents a unique
+ *                          DSP/BIOS Bridge object.
+ *      obj_type:            The type of DSP/BIOS Bridge object to be
+ *                          referenced (node, processor, etc).
+ *      obj_def:            Pointer to an object definition structure. A
+ *                          union of various possible DCD object types.
+ *  Returns:
+ *      0: Success.
+ *      -EACCES: Unable to access/read/parse/load content of object code
+ *               section.
+ *      -EPERM:          General failure.
+ *      -EFAULT:        Invalid DCD_HMANAGER handle.
+ *  Requires:
+ *      DCD initialized.
+ *      obj_uuid is non-NULL.
+ *      obj_def is non-NULL.
+ *  Ensures:
+ */
+extern int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
+                                    struct dsp_uuid *obj_uuid,
+                                    enum dsp_dcdobjtype obj_type,
+                                    struct dcd_genericobj *obj_def);
+
+/*
+ *  ======== dcd_get_objects ========
+ *  Purpose:
+ *      This function finds all DCD objects specified in a special
+ *      COFF section called ".dcd_register", and for each object,
+ *      call a "register" function.  The "register" function may perform
+ *      various actions, such as 1) register nodes in the node database, 2)
+ *      unregister nodes from the node database, and 3) add overlay nodes.
+ *  Parameters:
+ *      hdcd_mgr:                A DCD manager handle.
+ *      sz_coff_path:           Pointer to name of COFF file containing DCD
+ *                              objects.
+ *      register_fxn:           Callback fxn to be applied on each located
+ *                              DCD object.
+ *      handle:                 Handle to pass to callback.
+ *  Returns:
+ *      0:                Success.
+ *      -EACCES: Unable to access/read/parse/load content of object code
+ *               section.
+ *      -EFAULT:            Invalid DCD_HMANAGER handle..
+ *  Requires:
+ *      DCD initialized.
+ *  Ensures:
+ *  Note:
+ *      Due to the DCD database construction, it is essential for a DCD-enabled
+ *      COFF file to contain the right COFF sections, especially
+ *      ".dcd_register", which is used for auto registration.
+ */
+extern int dcd_get_objects(struct dcd_manager *hdcd_mgr,
+                                 char *sz_coff_path,
+                                 dcd_registerfxn register_fxn, void *handle);
+
+/*
+ *  ======== dcd_init ========
+ *  Purpose:
+ *      This function initializes DCD.
+ *  Parameters:
+ *  Returns:
+ *      FALSE:  Initialization failed.
+ *      TRUE:   Initialization succeeded.
+ *  Requires:
+ *  Ensures:
+ *      DCD initialized.
+ */
+extern bool dcd_init(void);
+
+/*
+ *  ======== dcd_register_object ========
+ *  Purpose:
+ *      This function registers a DSP/BIOS Bridge object in the DCD database.
+ *  Parameters:
+ *      uuid_obj:          Pointer to a dsp_uuid that identifies a DSP/BIOS
+ *                      Bridge object.
+ *      obj_type:        Type of object.
+ *      psz_path_name:    Path to the object's COFF file.
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Failed to register object.
+ *  Requires:
+ *      DCD initialized.
+ *      uuid_obj and szPathName are non-NULL values.
+ *      obj_type is a valid type value.
+ *  Ensures:
+ */
+extern int dcd_register_object(struct dsp_uuid *uuid_obj,
+                                     enum dsp_dcdobjtype obj_type,
+                                     char *psz_path_name);
+
+/*
+ *  ======== dcd_unregister_object ========
+ *  Purpose:
+ *      This function de-registers a valid DSP/BIOS Bridge object from the DCD
+ *      database.
+ *  Parameters:
+ *      uuid_obj:      Pointer to a dsp_uuid that identifies a DSP/BIOS Bridge
+ *                  object.
+ *      obj_type:    Type of object.
+ *  Returns:
+ *      0:    Success.
+ *      -EPERM:  Unable to de-register the specified object.
+ *  Requires:
+ *      DCD initialized.
+ *      uuid_obj is a non-NULL value.
+ *      obj_type is a valid type value.
+ *  Ensures:
+ */
+extern int dcd_unregister_object(struct dsp_uuid *uuid_obj,
+                                       enum dsp_dcdobjtype obj_type);
+
+#endif /* _DBDCD_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h
new file mode 100644 (file)
index 0000000..1daa4b5
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * dbdcddef.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DCD (DSP/BIOS Bridge Configuration Database) constants and types.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DBDCDDEF_
+#define DBDCDDEF_
+
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/mgrpriv.h> /* for mgr_processorextinfo */
+
+/*
+ *  The following defines are critical elements for the DCD module:
+ *
+ * - DCD_REGKEY enables DCD functions to locate registered DCD objects.
+ * - DCD_REGISTER_SECTION identifies the COFF section where the UUID of
+ *   registered DCD objects are stored.
+ */
+#define DCD_REGKEY              "Software\\TexasInstruments\\DspBridge\\DCD"
+#define DCD_REGISTER_SECTION    ".dcd_register"
+
+#define DCD_MAXPATHLENGTH    255
+
+/* DCD Manager Object */
+struct dcd_manager;
+
+struct dcd_key_elem {
+       struct list_head link;  /* Make it linked to a list */
+       char name[DCD_MAXPATHLENGTH];   /*  Name of a given value entry */
+       char *path;             /*  Pointer to the actual data */
+};
+
+/* DCD Node Properties */
+struct dcd_nodeprops {
+       struct dsp_ndbprops ndb_props;
+       u32 msg_segid;
+       u32 msg_notify_type;
+       char *pstr_create_phase_fxn;
+       char *pstr_delete_phase_fxn;
+       char *pstr_execute_phase_fxn;
+       char *pstr_i_alg_name;
+
+       /* Dynamic load properties */
+       u16 us_load_type;       /* Static, dynamic, overlay */
+       u32 ul_data_mem_seg_mask;       /* Data memory requirements */
+       u32 ul_code_mem_seg_mask;       /* Code memory requirements */
+};
+
+/* DCD Generic Object Type */
+struct dcd_genericobj {
+       union dcd_obj {
+               struct dcd_nodeprops node_obj;  /* node object. */
+               /* processor object. */
+               struct dsp_processorinfo proc_info;
+               /* extended proc object (private) */
+               struct mgr_processorextinfo ext_proc_obj;
+       } obj_data;
+};
+
+/* DCD Internal Callback Type */
+typedef int(*dcd_registerfxn) (struct dsp_uuid *uuid_obj,
+                                     enum dsp_dcdobjtype obj_type,
+                                     void *handle);
+
+#endif /* DBDCDDEF_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h
new file mode 100644 (file)
index 0000000..5af075d
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ * dbdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global definitions and constants for DSP/BIOS Bridge.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DBDEFS_
+#define DBDEFS_
+
+#include <linux/types.h>
+
+#include <dspbridge/rms_sh.h>  /* Types shared between GPP and DSP */
+
+#define PG_SIZE4K 4096
+#define PG_MASK(pg_size) (~((pg_size)-1))
+#define PG_ALIGN_LOW(addr, pg_size) ((addr) & PG_MASK(pg_size))
+#define PG_ALIGN_HIGH(addr, pg_size) (((addr)+(pg_size)-1) & PG_MASK(pg_size))
+
+/* API return value and calling convention */
+#define DBAPI                       int
+
+/* Infinite time value for the utimeout parameter to DSPStream_Select() */
+#define DSP_FOREVER                 (-1)
+
+/* Maximum length of node name, used in dsp_ndbprops */
+#define DSP_MAXNAMELEN              32
+
+/* notify_type values for the RegisterNotify() functions. */
+#define DSP_SIGNALEVENT             0x00000001
+
+/* Types of events for processors */
+#define DSP_PROCESSORSTATECHANGE    0x00000001
+#define DSP_PROCESSORATTACH         0x00000002
+#define DSP_PROCESSORDETACH         0x00000004
+#define DSP_PROCESSORRESTART        0x00000008
+
+/* DSP exception events (DSP/BIOS and DSP MMU fault) */
+#define DSP_MMUFAULT                0x00000010
+#define DSP_SYSERROR                0x00000020
+#define DSP_EXCEPTIONABORT          0x00000300
+#define DSP_PWRERROR                0x00000080
+#define DSP_WDTOVERFLOW        0x00000040
+
+/* IVA exception events (IVA MMU fault) */
+#define IVA_MMUFAULT                0x00000040
+/* Types of events for nodes */
+#define DSP_NODESTATECHANGE         0x00000100
+#define DSP_NODEMESSAGEREADY        0x00000200
+
+/* Types of events for streams */
+#define DSP_STREAMDONE              0x00001000
+#define DSP_STREAMIOCOMPLETION      0x00002000
+
+/* Handle definition representing the GPP node in DSPNode_Connect() calls */
+#define DSP_HGPPNODE                0xFFFFFFFF
+
+/* Node directions used in DSPNode_Connect() */
+#define DSP_TONODE                  1
+#define DSP_FROMNODE                2
+
+/* Define Node Minimum and Maximum Priorities */
+#define DSP_NODE_MIN_PRIORITY       1
+#define DSP_NODE_MAX_PRIORITY       15
+
+/* Pre-Defined Message Command Codes available to user: */
+#define DSP_RMSUSERCODESTART RMS_USER  /* Start of RMS user cmd codes */
+/* end of user codes */
+#define DSP_RMSUSERCODEEND (RMS_USER + RMS_MAXUSERCODES);
+/* msg_ctrl contains SM buffer description */
+#define DSP_RMSBUFDESC RMS_BUFDESC
+
+/* Shared memory identifier for MEM segment named "SHMSEG0" */
+#define DSP_SHMSEG0     (u32)(-1)
+
+/* Processor ID numbers */
+#define DSP_UNIT    0
+#define IVA_UNIT    1
+
+#define DSPWORD       unsigned char
+#define DSPWORDSIZE     sizeof(DSPWORD)
+
+/* Power control enumerations */
+#define PROC_PWRCONTROL             0x8070
+
+#define PROC_PWRMGT_ENABLE          (PROC_PWRCONTROL + 0x3)
+#define PROC_PWRMGT_DISABLE         (PROC_PWRCONTROL + 0x4)
+
+/* Bridge Code Version */
+#define BRIDGE_VERSION_CODE         333
+
+#define    MAX_PROFILES     16
+
+/* DSP chip type */
+#define DSPTYPE64      0x99
+
+/* Handy Macros */
+#define VALID_PROC_EVENT (DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH | \
+       DSP_PROCESSORDETACH | DSP_PROCESSORRESTART | DSP_NODESTATECHANGE | \
+       DSP_STREAMDONE | DSP_STREAMIOCOMPLETION | DSP_MMUFAULT | \
+       DSP_SYSERROR | DSP_WDTOVERFLOW | DSP_PWRERROR)
+
+static inline bool is_valid_proc_event(u32 x)
+{
+       return (x == 0 || (x & VALID_PROC_EVENT && !(x & ~VALID_PROC_EVENT)));
+}
+
+/* The Node UUID structure */
+struct dsp_uuid {
+       u32 ul_data1;
+       u16 us_data2;
+       u16 us_data3;
+       u8 uc_data4;
+       u8 uc_data5;
+       u8 uc_data6[6];
+};
+
+/* DCD types */
+enum dsp_dcdobjtype {
+       DSP_DCDNODETYPE,
+       DSP_DCDPROCESSORTYPE,
+       DSP_DCDLIBRARYTYPE,
+       DSP_DCDCREATELIBTYPE,
+       DSP_DCDEXECUTELIBTYPE,
+       DSP_DCDDELETELIBTYPE,
+       /* DSP_DCDMAXOBJTYPE is meant to be the last DCD object type */
+       DSP_DCDMAXOBJTYPE
+};
+
+/* Processor states */
+enum dsp_procstate {
+       PROC_STOPPED,
+       PROC_LOADED,
+       PROC_RUNNING,
+       PROC_ERROR
+};
+
+/*
+ *  Node types: Message node, task node, xDAIS socket node, and
+ *  device node. _NODE_GPP is used when defining a stream connection
+ *  between a task or socket node and the GPP.
+ *
+ */
+enum node_type {
+       NODE_DEVICE,
+       NODE_TASK,
+       NODE_DAISSOCKET,
+       NODE_MESSAGE,
+       NODE_GPP
+};
+
+/*
+ *  ======== node_state ========
+ *  Internal node states.
+ */
+enum node_state {
+       NODE_ALLOCATED,
+       NODE_CREATED,
+       NODE_RUNNING,
+       NODE_PAUSED,
+       NODE_DONE,
+       NODE_CREATING,
+       NODE_STARTING,
+       NODE_PAUSING,
+       NODE_TERMINATING,
+       NODE_DELETING,
+};
+
+/* Stream states */
+enum dsp_streamstate {
+       STREAM_IDLE,
+       STREAM_READY,
+       STREAM_PENDING,
+       STREAM_DONE
+};
+
+/* Stream connect types */
+enum dsp_connecttype {
+       CONNECTTYPE_NODEOUTPUT,
+       CONNECTTYPE_GPPOUTPUT,
+       CONNECTTYPE_NODEINPUT,
+       CONNECTTYPE_GPPINPUT
+};
+
+/* Stream mode types */
+enum dsp_strmmode {
+       STRMMODE_PROCCOPY,      /* Processor(s) copy stream data payloads */
+       STRMMODE_ZEROCOPY,      /* Strm buffer ptrs swapped no data copied */
+       STRMMODE_LDMA,          /* Local DMA : OMAP's System-DMA device */
+       STRMMODE_RDMA           /* Remote DMA: OMAP's DSP-DMA device */
+};
+
+/* Resource Types */
+enum dsp_resourceinfotype {
+       DSP_RESOURCE_DYNDARAM = 0,
+       DSP_RESOURCE_DYNSARAM,
+       DSP_RESOURCE_DYNEXTERNAL,
+       DSP_RESOURCE_DYNSRAM,
+       DSP_RESOURCE_PROCLOAD
+};
+
+/* Memory Segment Types */
+enum dsp_memtype {
+       DSP_DYNDARAM = 0,
+       DSP_DYNSARAM,
+       DSP_DYNEXTERNAL,
+       DSP_DYNSRAM
+};
+
+/* Memory Flush Types */
+enum dsp_flushtype {
+       PROC_INVALIDATE_MEM = 0,
+       PROC_WRITEBACK_MEM,
+       PROC_WRITEBACK_INVALIDATE_MEM,
+};
+
+/* Memory Segment Status Values */
+struct dsp_memstat {
+       u32 ul_size;
+       u32 ul_total_free_size;
+       u32 ul_len_max_free_block;
+       u32 ul_num_free_blocks;
+       u32 ul_num_alloc_blocks;
+};
+
+/* Processor Load information Values */
+struct dsp_procloadstat {
+       u32 curr_load;
+       u32 predicted_load;
+       u32 curr_dsp_freq;
+       u32 predicted_freq;
+};
+
+/* Attributes for STRM connections between nodes */
+struct dsp_strmattr {
+       u32 seg_id;             /* Memory segment on DSP to allocate buffers */
+       u32 buf_size;           /* Buffer size (DSP words) */
+       u32 num_bufs;           /* Number of buffers */
+       u32 buf_alignment;      /* Buffer alignment */
+       u32 utimeout;           /* Timeout for blocking STRM calls */
+       enum dsp_strmmode strm_mode;    /* mode of stream when opened */
+       /* DMA chnl id if dsp_strmmode is LDMA or RDMA */
+       u32 udma_chnl_id;
+       u32 udma_priority;      /* DMA channel priority 0=lowest, >0=high */
+};
+
+/* The dsp_cbdata structure */
+struct dsp_cbdata {
+       u32 cb_data;
+       u8 node_data[1];
+};
+
+/* The dsp_msg structure */
+struct dsp_msg {
+       u32 dw_cmd;
+       u32 dw_arg1;
+       u32 dw_arg2;
+};
+
+/* The dsp_resourcereqmts structure for node's resource requirements */
+struct dsp_resourcereqmts {
+       u32 cb_struct;
+       u32 static_data_size;
+       u32 global_data_size;
+       u32 program_mem_size;
+       u32 uwc_execution_time;
+       u32 uwc_period;
+       u32 uwc_deadline;
+       u32 avg_exection_time;
+       u32 minimum_period;
+};
+
+/*
+ * The dsp_streamconnect structure describes a stream connection
+ * between two nodes, or between a node and the GPP
+ */
+struct dsp_streamconnect {
+       u32 cb_struct;
+       enum dsp_connecttype connect_type;
+       u32 this_node_stream_index;
+       void *connected_node;
+       struct dsp_uuid ui_connected_node_id;
+       u32 connected_node_stream_index;
+};
+
+struct dsp_nodeprofs {
+       u32 ul_heap_size;
+};
+
+/* The dsp_ndbprops structure reports the attributes of a node */
+struct dsp_ndbprops {
+       u32 cb_struct;
+       struct dsp_uuid ui_node_id;
+       char ac_name[DSP_MAXNAMELEN];
+       enum node_type ntype;
+       u32 cache_on_gpp;
+       struct dsp_resourcereqmts dsp_resource_reqmts;
+       s32 prio;
+       u32 stack_size;
+       u32 sys_stack_size;
+       u32 stack_seg;
+       u32 message_depth;
+       u32 num_input_streams;
+       u32 num_output_streams;
+       u32 utimeout;
+       u32 count_profiles;     /* Number of supported profiles */
+       /* Array of profiles */
+       struct dsp_nodeprofs node_profiles[MAX_PROFILES];
+       u32 stack_seg_name;     /* Stack Segment Name */
+};
+
+       /* The dsp_nodeattrin structure describes the attributes of a
+        * node client */
+struct dsp_nodeattrin {
+       u32 cb_struct;
+       s32 prio;
+       u32 utimeout;
+       u32 profile_id;
+       /* Reserved, for Bridge Internal use only */
+       u32 heap_size;
+       void *pgpp_virt_addr;   /* Reserved, for Bridge Internal use only */
+};
+
+       /* The dsp_nodeinfo structure is used to retrieve information
+        * about a node */
+struct dsp_nodeinfo {
+       u32 cb_struct;
+       struct dsp_ndbprops nb_node_database_props;
+       u32 execution_priority;
+       enum node_state ns_execution_state;
+       void *device_owner;
+       u32 number_streams;
+       struct dsp_streamconnect sc_stream_connection[16];
+       u32 node_env;
+};
+
+       /* The dsp_nodeattr structure describes the attributes of a node */
+struct dsp_nodeattr {
+       u32 cb_struct;
+       struct dsp_nodeattrin in_node_attr_in;
+       u32 node_attr_inputs;
+       u32 node_attr_outputs;
+       struct dsp_nodeinfo node_info;
+};
+
+/*
+ *  Notification type: either the name of an opened event, or an event or
+ *  window handle.
+ */
+struct dsp_notification {
+       char *ps_name;
+       void *handle;
+};
+
+/* The dsp_processorattrin structure describes the attributes of a processor */
+struct dsp_processorattrin {
+       u32 cb_struct;
+       u32 utimeout;
+};
+/*
+ * The dsp_processorinfo structure describes basic capabilities of a
+ * DSP processor
+ */
+struct dsp_processorinfo {
+       u32 cb_struct;
+       int processor_family;
+       int processor_type;
+       u32 clock_rate;
+       u32 ul_internal_mem_size;
+       u32 ul_external_mem_size;
+       u32 processor_id;
+       int ty_running_rtos;
+       s32 node_min_priority;
+       s32 node_max_priority;
+};
+
+/* Error information of last DSP exception signalled to the GPP */
+struct dsp_errorinfo {
+       u32 dw_err_mask;
+       u32 dw_val1;
+       u32 dw_val2;
+       u32 dw_val3;
+};
+
+/* The dsp_processorstate structure describes the state of a DSP processor */
+struct dsp_processorstate {
+       u32 cb_struct;
+       enum dsp_procstate proc_state;
+};
+
+/*
+ * The dsp_resourceinfo structure is used to retrieve information about a
+ * processor's resources
+ */
+struct dsp_resourceinfo {
+       u32 cb_struct;
+       enum dsp_resourceinfotype resource_type;
+       union {
+               u32 ul_resource;
+               struct dsp_memstat mem_stat;
+               struct dsp_procloadstat proc_load_stat;
+       } result;
+};
+
+/*
+ * The dsp_streamattrin structure describes the attributes of a stream,
+ * including segment and alignment of data buffers allocated with
+ * DSPStream_AllocateBuffers(), if applicable
+ */
+struct dsp_streamattrin {
+       u32 cb_struct;
+       u32 utimeout;
+       u32 segment_id;
+       u32 buf_alignment;
+       u32 num_bufs;
+       enum dsp_strmmode strm_mode;
+       u32 udma_chnl_id;
+       u32 udma_priority;
+};
+
+/* The dsp_bufferattr structure describes the attributes of a data buffer */
+struct dsp_bufferattr {
+       u32 cb_struct;
+       u32 segment_id;
+       u32 buf_alignment;
+};
+
+/*
+ *  The dsp_streaminfo structure is used to retrieve information
+ *  about a stream.
+ */
+struct dsp_streaminfo {
+       u32 cb_struct;
+       u32 number_bufs_allowed;
+       u32 number_bufs_in_stream;
+       u32 ul_number_bytes;
+       void *sync_object_handle;
+       enum dsp_streamstate ss_stream_state;
+};
+
+/* DMM MAP attributes
+It is a bit mask with each bit value indicating a specific attribute
+bit 0 - GPP address type (user virtual=0, physical=1)
+bit 1 - MMU Endianism (Big Endian=1, Little Endian=0)
+bit 2 - MMU mixed page attribute (Mixed/ CPUES=1, TLBES =0)
+bit 3 - MMU element size = 8bit (valid only for non mixed page entries)
+bit 4 - MMU element size = 16bit (valid only for non mixed page entries)
+bit 5 - MMU element size = 32bit (valid only for non mixed page entries)
+bit 6 - MMU element size = 64bit (valid only for non mixed page entries)
+
+bit 14 - Input (read only) buffer
+bit 15 - Output (writeable) buffer
+*/
+
+/* Types of mapping attributes */
+
+/* MPU address is virtual and needs to be translated to physical addr */
+#define DSP_MAPVIRTUALADDR          0x00000000
+#define DSP_MAPPHYSICALADDR         0x00000001
+
+/* Mapped data is big endian */
+#define DSP_MAPBIGENDIAN            0x00000002
+#define DSP_MAPLITTLEENDIAN         0x00000000
+
+/* Element size is based on DSP r/w access size */
+#define DSP_MAPMIXEDELEMSIZE        0x00000004
+
+/*
+ * Element size for MMU mapping (8, 16, 32, or 64 bit)
+ * Ignored if DSP_MAPMIXEDELEMSIZE enabled
+ */
+#define DSP_MAPELEMSIZE8            0x00000008
+#define DSP_MAPELEMSIZE16           0x00000010
+#define DSP_MAPELEMSIZE32           0x00000020
+#define DSP_MAPELEMSIZE64           0x00000040
+
+#define DSP_MAPVMALLOCADDR         0x00000080
+
+#define DSP_MAPDONOTLOCK          0x00000100
+
+#define DSP_MAP_DIR_MASK               0x3FFF
+
+#define GEM_CACHE_LINE_SIZE     128
+#define GEM_L1P_PREFETCH_SIZE   128
+
+/*
+ * Definitions from dbreg.h
+ */
+
+#define DSPPROCTYPE_C64                6410
+#define IVAPROCTYPE_ARM7       470
+
+#define REG_MGR_OBJECT 1
+#define REG_DRV_OBJECT 2
+
+/* registry */
+#define DRVOBJECT      "DrvObject"
+#define MGROBJECT      "MgrObject"
+
+/* Max registry path length. Also the max registry value length. */
+#define MAXREGPATHLENGTH       255
+
+#endif /* DBDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h
new file mode 100644 (file)
index 0000000..bf4fb99
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * dbldefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DBLDEFS_
+#define DBLDEFS_
+
+/*
+ *  Bit masks for dbl_flags.
+ */
+#define DBL_NOLOAD   0x0       /* Don't load symbols, code, or data */
+#define DBL_SYMB     0x1       /* load symbols */
+#define DBL_CODE     0x2       /* load code */
+#define DBL_DATA     0x4       /* load data */
+#define DBL_DYNAMIC  0x8       /* dynamic load */
+#define DBL_BSS      0x20      /* Unitialized section */
+
+#define DBL_MAXPATHLENGTH       255
+
+/*
+ *  ======== dbl_flags ========
+ *  Specifies whether to load code, data, or symbols
+ */
+typedef s32 dbl_flags;
+
+/*
+ *  ======== dbl_sect_info ========
+ *  For collecting info on overlay sections
+ */
+struct dbl_sect_info {
+       const char *name;       /* name of section */
+       u32 sect_run_addr;      /* run address of section */
+       u32 sect_load_addr;     /* load address of section */
+       u32 size;               /* size of section (target MAUs) */
+       dbl_flags type;         /* Code, data, or BSS */
+};
+
+/*
+ *  ======== dbl_symbol ========
+ *  (Needed for dynamic load library)
+ */
+struct dbl_symbol {
+       u32 value;
+};
+
+/*
+ *  ======== dbl_alloc_fxn ========
+ *  Allocate memory function.  Allocate or reserve (if reserved == TRUE)
+ *  "size" bytes of memory from segment "space" and return the address in
+ *  *dsp_address (or starting at *dsp_address if reserve == TRUE). Returns 0 on
+ *  success, or an error code on failure.
+ */
+typedef s32(*dbl_alloc_fxn) (void *hdl, s32 space, u32 size, u32 align,
+                            u32 *dsp_address, s32 seg_id, s32 req,
+                            bool reserved);
+
+/*
+ *  ======== dbl_free_fxn ========
+ *  Free memory function.  Free, or unreserve (if reserved == TRUE) "size"
+ *  bytes of memory from segment "space"
+ */
+typedef bool(*dbl_free_fxn) (void *hdl, u32 addr, s32 space, u32 size,
+                            bool reserved);
+
+/*
+ *  ======== dbl_log_write_fxn ========
+ *  Function to call when writing data from a section, to log the info.
+ *  Can be NULL if no logging is required.
+ */
+typedef int(*dbl_log_write_fxn) (void *handle,
+                                       struct dbl_sect_info *sect, u32 addr,
+                                       u32 bytes);
+
+/*
+ *  ======== dbl_sym_lookup ========
+ *  Symbol lookup function - Find the symbol name and return its value.
+ *
+ *  Parameters:
+ *      handle          - Opaque handle
+ *      parg            - Opaque argument.
+ *      name            - Name of symbol to lookup.
+ *      sym             - Location to store address of symbol structure.
+ *
+ *  Returns:
+ *      TRUE:           Success (symbol was found).
+ *      FALSE:          Failed to find symbol.
+ */
+typedef bool(*dbl_sym_lookup) (void *handle, void *parg, void *rmm_handle,
+                              const char *name, struct dbl_symbol ** sym);
+
+/*
+ *  ======== dbl_write_fxn ========
+ *  Write memory function.  Write "n" HOST bytes of memory to segment "mtype"
+ *  starting at address "dsp_address" from the buffer "buf".  The buffer is
+ *  formatted as an array of words appropriate for the DSP.
+ */
+typedef s32(*dbl_write_fxn) (void *hdl, u32 dsp_address, void *buf,
+                            u32 n, s32 mtype);
+
+/*
+ *  ======== dbl_attrs ========
+ */
+struct dbl_attrs {
+       dbl_alloc_fxn alloc;
+       dbl_free_fxn free;
+       void *rmm_handle;       /* Handle to pass to alloc, free functions */
+       dbl_write_fxn write;
+       void *input_params;     /* Handle to pass to write, cinit function */
+
+       dbl_log_write_fxn log_write;
+       void *log_write_handle;
+
+       /* Symbol matching function and handle to pass to it */
+       dbl_sym_lookup sym_lookup;
+       void *sym_handle;
+       void *sym_arg;
+
+       /*
+        *  These file manipulation functions should be compatible with the
+        *  "C" run time library functions of the same name.
+        */
+        s32(*fread) (void *, size_t, size_t, void *);
+        s32(*fseek) (void *, long, int);
+        s32(*ftell) (void *);
+        s32(*fclose) (void *);
+       void *(*fopen) (const char *, const char *);
+};
+
+#endif /* DBLDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbll.h b/drivers/staging/tidspbridge/include/dspbridge/dbll.h
new file mode 100644 (file)
index 0000000..b018676
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * dbll.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ *  DSP/BIOS Bridge Dynamic load library module interface. Function header
+ *  comments are in the file dblldefs.h.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DBLL_
+#define DBLL_
+
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/dblldefs.h>
+
+extern bool symbols_reloaded;
+
+extern void dbll_close(struct dbll_library_obj *zl_lib);
+extern int dbll_create(struct dbll_tar_obj **target_obj,
+                             struct dbll_attrs *pattrs);
+extern void dbll_delete(struct dbll_tar_obj *target);
+extern void dbll_exit(void);
+extern bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name,
+                         struct dbll_sym_val **sym_val);
+extern void dbll_get_attrs(struct dbll_tar_obj *target,
+                          struct dbll_attrs *pattrs);
+extern bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name,
+                           struct dbll_sym_val **sym_val);
+extern int dbll_get_sect(struct dbll_library_obj *lib, char *name,
+                               u32 *paddr, u32 *psize);
+extern bool dbll_init(void);
+extern int dbll_load(struct dbll_library_obj *lib,
+                           dbll_flags flags,
+                           struct dbll_attrs *attrs, u32 * entry);
+extern int dbll_load_sect(struct dbll_library_obj *zl_lib,
+                                char *sec_name, struct dbll_attrs *attrs);
+extern int dbll_open(struct dbll_tar_obj *target, char *file,
+                           dbll_flags flags,
+                      struct dbll_library_obj **lib_obj);
+extern int dbll_read_sect(struct dbll_library_obj *lib,
+                                char *name, char *buf, u32 size);
+extern void dbll_set_attrs(struct dbll_tar_obj *target,
+                          struct dbll_attrs *pattrs);
+extern void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs);
+extern int dbll_unload_sect(struct dbll_library_obj *lib,
+                                  char *sect_name, struct dbll_attrs *attrs);
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address,
+               u32 offset_range, u32 *sym_addr_output, char *name_output);
+#endif
+
+#endif /* DBLL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h
new file mode 100644 (file)
index 0000000..d2b4fda
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ * dblldefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DBLLDEFS_
+#define DBLLDEFS_
+
+/*
+ *  Bit masks for dbl_flags.
+ */
+#define DBLL_NOLOAD   0x0      /* Don't load symbols, code, or data */
+#define DBLL_SYMB     0x1      /* load symbols */
+#define DBLL_CODE     0x2      /* load code */
+#define DBLL_DATA     0x4      /* load data */
+#define DBLL_DYNAMIC  0x8      /* dynamic load */
+#define DBLL_BSS      0x20     /* Unitialized section */
+
+#define DBLL_MAXPATHLENGTH       255
+
+/*
+ *  ======== DBLL_Target ========
+ *
+ */
+struct dbll_tar_obj;
+
+/*
+ *  ======== dbll_flags ========
+ *  Specifies whether to load code, data, or symbols
+ */
+typedef s32 dbll_flags;
+
+/*
+ *  ======== DBLL_Library ========
+ *
+ */
+struct dbll_library_obj;
+
+/*
+ *  ======== dbll_sect_info ========
+ *  For collecting info on overlay sections
+ */
+struct dbll_sect_info {
+       const char *name;       /* name of section */
+       u32 sect_run_addr;      /* run address of section */
+       u32 sect_load_addr;     /* load address of section */
+       u32 size;               /* size of section (target MAUs) */
+       dbll_flags type;        /* Code, data, or BSS */
+};
+
+/*
+ *  ======== dbll_sym_val ========
+ *  (Needed for dynamic load library)
+ */
+struct dbll_sym_val {
+       u32 value;
+};
+
+/*
+ *  ======== dbll_alloc_fxn ========
+ *  Allocate memory function.  Allocate or reserve (if reserved == TRUE)
+ *  "size" bytes of memory from segment "space" and return the address in
+ *  *dsp_address (or starting at *dsp_address if reserve == TRUE). Returns 0 on
+ *  success, or an error code on failure.
+ */
+typedef s32(*dbll_alloc_fxn) (void *hdl, s32 space, u32 size, u32 align,
+                             u32 *dsp_address, s32 seg_id, s32 req,
+                             bool reserved);
+
+/*
+ *  ======== dbll_close_fxn ========
+ */
+typedef s32(*dbll_f_close_fxn) (void *);
+
+/*
+ *  ======== dbll_free_fxn ========
+ *  Free memory function.  Free, or unreserve (if reserved == TRUE) "size"
+ *  bytes of memory from segment "space"
+ */
+typedef bool(*dbll_free_fxn) (void *hdl, u32 addr, s32 space, u32 size,
+                             bool reserved);
+
+/*
+ *  ======== dbll_f_open_fxn ========
+ */
+typedef void *(*dbll_f_open_fxn) (const char *, const char *);
+
+/*
+ *  ======== dbll_log_write_fxn ========
+ *  Function to call when writing data from a section, to log the info.
+ *  Can be NULL if no logging is required.
+ */
+typedef int(*dbll_log_write_fxn) (void *handle,
+                                        struct dbll_sect_info *sect, u32 addr,
+                                        u32 bytes);
+
+/*
+ *  ======== dbll_read_fxn ========
+ */
+typedef s32(*dbll_read_fxn) (void *, size_t, size_t, void *);
+
+/*
+ *  ======== dbll_seek_fxn ========
+ */
+typedef s32(*dbll_seek_fxn) (void *, long, int);
+
+/*
+ *  ======== dbll_sym_lookup ========
+ *  Symbol lookup function - Find the symbol name and return its value.
+ *
+ *  Parameters:
+ *      handle          - Opaque handle
+ *      parg            - Opaque argument.
+ *      name            - Name of symbol to lookup.
+ *      sym             - Location to store address of symbol structure.
+ *
+ *  Returns:
+ *      TRUE:           Success (symbol was found).
+ *      FALSE:          Failed to find symbol.
+ */
+typedef bool(*dbll_sym_lookup) (void *handle, void *parg, void *rmm_handle,
+                               const char *name, struct dbll_sym_val ** sym);
+
+/*
+ *  ======== dbll_tell_fxn ========
+ */
+typedef s32(*dbll_tell_fxn) (void *);
+
+/*
+ *  ======== dbll_write_fxn ========
+ *  Write memory function.  Write "n" HOST bytes of memory to segment "mtype"
+ *  starting at address "dsp_address" from the buffer "buf".  The buffer is
+ *  formatted as an array of words appropriate for the DSP.
+ */
+typedef s32(*dbll_write_fxn) (void *hdl, u32 dsp_address, void *buf,
+                             u32 n, s32 mtype);
+
+/*
+ *  ======== dbll_attrs ========
+ */
+struct dbll_attrs {
+       dbll_alloc_fxn alloc;
+       dbll_free_fxn free;
+       void *rmm_handle;       /* Handle to pass to alloc, free functions */
+       dbll_write_fxn write;
+       void *input_params;     /* Handle to pass to write, cinit function */
+       bool base_image;
+       dbll_log_write_fxn log_write;
+       void *log_write_handle;
+
+       /* Symbol matching function and handle to pass to it */
+       dbll_sym_lookup sym_lookup;
+       void *sym_handle;
+       void *sym_arg;
+
+       /*
+        *  These file manipulation functions should be compatible with the
+        *  "C" run time library functions of the same name.
+        */
+        s32(*fread) (void *, size_t, size_t, void *);
+        s32(*fseek) (void *, long, int);
+        s32(*ftell) (void *);
+        s32(*fclose) (void *);
+       void *(*fopen) (const char *, const char *);
+};
+
+/*
+ *  ======== dbll_close ========
+ *  Close library opened with dbll_open.
+ *  Parameters:
+ *      lib             - Handle returned from dbll_open().
+ *  Returns:
+ *  Requires:
+ *      DBL initialized.
+ *      Valid lib.
+ *  Ensures:
+ */
+typedef void (*dbll_close_fxn) (struct dbll_library_obj *library);
+
+/*
+ *  ======== dbll_create ========
+ *  Create a target object, specifying the alloc, free, and write functions.
+ *  Parameters:
+ *      target_obj         - Location to store target handle on output.
+ *      pattrs          - Attributes.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Memory allocation failed.
+ *  Requires:
+ *      DBL initialized.
+ *      pattrs != NULL.
+ *      target_obj != NULL;
+ *  Ensures:
+ *      Success:        *target_obj != NULL.
+ *      Failure:        *target_obj == NULL.
+ */
+typedef int(*dbll_create_fxn) (struct dbll_tar_obj **target_obj,
+                                     struct dbll_attrs *attrs);
+
+/*
+ *  ======== dbll_delete ========
+ *  Delete target object and free resources for any loaded libraries.
+ *  Parameters:
+ *      target          - Handle returned from DBLL_Create().
+ *  Returns:
+ *  Requires:
+ *      DBL initialized.
+ *      Valid target.
+ *  Ensures:
+ */
+typedef void (*dbll_delete_fxn) (struct dbll_tar_obj *target);
+
+/*
+ *  ======== dbll_exit ========
+ *  Discontinue use of DBL module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      refs > 0.
+ *  Ensures:
+ *      refs >= 0.
+ */
+typedef void (*dbll_exit_fxn) (void);
+
+/*
+ *  ======== dbll_get_addr ========
+ *  Get address of name in the specified library.
+ *  Parameters:
+ *      lib             - Handle returned from dbll_open().
+ *      name            - Name of symbol
+ *      sym_val         - Location to store symbol address on output.
+ *  Returns:
+ *      TRUE:           Success.
+ *      FALSE:          Symbol not found.
+ *  Requires:
+ *      DBL initialized.
+ *      Valid library.
+ *      name != NULL.
+ *      sym_val != NULL.
+ *  Ensures:
+ */
+typedef bool(*dbll_get_addr_fxn) (struct dbll_library_obj *lib, char *name,
+                                 struct dbll_sym_val **sym_val);
+
+/*
+ *  ======== dbll_get_attrs ========
+ *  Retrieve the attributes of the target.
+ *  Parameters:
+ *      target          - Handle returned from DBLL_Create().
+ *      pattrs          - Location to store attributes on output.
+ *  Returns:
+ *  Requires:
+ *      DBL initialized.
+ *      Valid target.
+ *      pattrs != NULL.
+ *  Ensures:
+ */
+typedef void (*dbll_get_attrs_fxn) (struct dbll_tar_obj *target,
+                                   struct dbll_attrs *attrs);
+
+/*
+ *  ======== dbll_get_c_addr ========
+ *  Get address of "C" name on the specified library.
+ *  Parameters:
+ *      lib             - Handle returned from dbll_open().
+ *      name            - Name of symbol
+ *      sym_val         - Location to store symbol address on output.
+ *  Returns:
+ *      TRUE:           Success.
+ *      FALSE:          Symbol not found.
+ *  Requires:
+ *      DBL initialized.
+ *      Valid target.
+ *      name != NULL.
+ *      sym_val != NULL.
+ *  Ensures:
+ */
+typedef bool(*dbll_get_c_addr_fxn) (struct dbll_library_obj *lib, char *name,
+                                   struct dbll_sym_val **sym_val);
+
+/*
+ *  ======== dbll_get_sect ========
+ *  Get address and size of a named section.
+ *  Parameters:
+ *      lib             - Library handle returned from dbll_open().
+ *      name            - Name of section.
+ *      paddr           - Location to store section address on output.
+ *      psize           - Location to store section size on output.
+ *  Returns:
+ *      0:        Success.
+ *      -ENXIO:    Section not found.
+ *  Requires:
+ *      DBL initialized.
+ *      Valid lib.
+ *      name != NULL.
+ *      paddr != NULL;
+ *      psize != NULL.
+ *  Ensures:
+ */
+typedef int(*dbll_get_sect_fxn) (struct dbll_library_obj *lib,
+                                       char *name, u32 * addr, u32 * size);
+
+/*
+ *  ======== dbll_init ========
+ *  Initialize DBL module.
+ *  Parameters:
+ *  Returns:
+ *      TRUE:           Success.
+ *      FALSE:          Failure.
+ *  Requires:
+ *      refs >= 0.
+ *  Ensures:
+ *      Success:        refs > 0.
+ *      Failure:        refs >= 0.
+ */
+typedef bool(*dbll_init_fxn) (void);
+
+/*
+ *  ======== dbll_load ========
+ *  Load library onto the target.
+ *
+ *  Parameters:
+ *      lib             - Library handle returned from dbll_open().
+ *      flags           - Load code, data and/or symbols.
+ *      attrs           - May contain alloc, free, and write function.
+ *      entry_pt        - Location to store program entry on output.
+ *  Returns:
+ *      0:        Success.
+ *      -EBADF:     File read failed.
+ *      -EILSEQ:   Failure in dynamic loader library.
+ *  Requires:
+ *      DBL initialized.
+ *      Valid lib.
+ *      entry != NULL.
+ *  Ensures:
+ */
+typedef int(*dbll_load_fxn) (struct dbll_library_obj *lib,
+                                   dbll_flags flags,
+                                   struct dbll_attrs *attrs, u32 *entry);
+
+/*
+ *  ======== dbll_load_sect ========
+ *  Load a named section from an library (for overlay support).
+ *  Parameters:
+ *      lib             - Handle returned from dbll_open().
+ *      sec_name        - Name of section to load.
+ *      attrs           - Contains write function and handle to pass to it.
+ *  Returns:
+ *      0:        Success.
+ *      -ENXIO:    Section not found.
+ *      -ENOSYS:   Function not implemented.
+ *  Requires:
+ *      Valid lib.
+ *      sec_name != NULL.
+ *      attrs != NULL.
+ *      attrs->write != NULL.
+ *  Ensures:
+ */
+typedef int(*dbll_load_sect_fxn) (struct dbll_library_obj *lib,
+                                        char *sz_sect_name,
+                                        struct dbll_attrs *attrs);
+
+/*
+ *  ======== dbll_open ========
+ *  dbll_open() returns a library handle that can be used to load/unload
+ *  the symbols/code/data via dbll_load()/dbll_unload().
+ *  Parameters:
+ *      target          - Handle returned from dbll_create().
+ *      file            - Name of file to open.
+ *      flags           - If flags & DBLL_SYMB, load symbols.
+ *      lib_obj         - Location to store library handle on output.
+ *  Returns:
+ *      0:            Success.
+ *      -ENOMEM:        Memory allocation failure.
+ *      -EBADF:         File open/read failure.
+ *                      Unable to determine target type.
+ *  Requires:
+ *      DBL initialized.
+ *      Valid target.
+ *      file != NULL.
+ *      lib_obj != NULL.
+ *      dbll_attrs fopen function non-NULL.
+ *  Ensures:
+ *      Success:        Valid *lib_obj.
+ *      Failure:        *lib_obj == NULL.
+ */
+typedef int(*dbll_open_fxn) (struct dbll_tar_obj *target, char *file,
+                                   dbll_flags flags,
+                                   struct dbll_library_obj **lib_obj);
+
+/*
+ *  ======== dbll_read_sect ========
+ *  Read COFF section into a character buffer.
+ *  Parameters:
+ *      lib             - Library handle returned from dbll_open().
+ *      name            - Name of section.
+ *      pbuf            - Buffer to write section contents into.
+ *      size            - Buffer size
+ *  Returns:
+ *      0:        Success.
+ *      -ENXIO:    Named section does not exists.
+ *  Requires:
+ *      DBL initialized.
+ *      Valid lib.
+ *      name != NULL.
+ *      pbuf != NULL.
+ *      size != 0.
+ *  Ensures:
+ */
+typedef int(*dbll_read_sect_fxn) (struct dbll_library_obj *lib,
+                                        char *name, char *content,
+                                        u32 cont_size);
+
+/*
+ *  ======== dbll_set_attrs ========
+ *  Set the attributes of the target.
+ *  Parameters:
+ *      target          - Handle returned from dbll_create().
+ *      pattrs          - New attributes.
+ *  Returns:
+ *  Requires:
+ *      DBL initialized.
+ *      Valid target.
+ *      pattrs != NULL.
+ *  Ensures:
+ */
+typedef void (*dbll_set_attrs_fxn) (struct dbll_tar_obj *target,
+                                   struct dbll_attrs *attrs);
+
+/*
+ *  ======== dbll_unload ========
+ *  Unload library loaded with dbll_load().
+ *  Parameters:
+ *      lib             - Handle returned from dbll_open().
+ *      attrs           - Contains free() function and handle to pass to it.
+ *  Returns:
+ *  Requires:
+ *      DBL initialized.
+ *      Valid lib.
+ *  Ensures:
+ */
+typedef void (*dbll_unload_fxn) (struct dbll_library_obj *library,
+                                struct dbll_attrs *attrs);
+
+/*
+ *  ======== dbll_unload_sect ========
+ *  Unload a named section from an library (for overlay support).
+ *  Parameters:
+ *      lib             - Handle returned from dbll_open().
+ *      sec_name        - Name of section to load.
+ *      attrs           - Contains free() function and handle to pass to it.
+ *  Returns:
+ *      0:        Success.
+ *      -ENXIO:    Named section not found.
+ *      -ENOSYS
+ *  Requires:
+ *      DBL initialized.
+ *      Valid lib.
+ *      sec_name != NULL.
+ *  Ensures:
+ */
+typedef int(*dbll_unload_sect_fxn) (struct dbll_library_obj *lib,
+                                          char *sz_sect_name,
+                                          struct dbll_attrs *attrs);
+
+struct dbll_fxns {
+       dbll_close_fxn close_fxn;
+       dbll_create_fxn create_fxn;
+       dbll_delete_fxn delete_fxn;
+       dbll_exit_fxn exit_fxn;
+       dbll_get_attrs_fxn get_attrs_fxn;
+       dbll_get_addr_fxn get_addr_fxn;
+       dbll_get_c_addr_fxn get_c_addr_fxn;
+       dbll_get_sect_fxn get_sect_fxn;
+       dbll_init_fxn init_fxn;
+       dbll_load_fxn load_fxn;
+       dbll_load_sect_fxn load_sect_fxn;
+       dbll_open_fxn open_fxn;
+       dbll_read_sect_fxn read_sect_fxn;
+       dbll_set_attrs_fxn set_attrs_fxn;
+       dbll_unload_fxn unload_fxn;
+       dbll_unload_sect_fxn unload_sect_fxn;
+};
+
+#endif /* DBLDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h
new file mode 100644 (file)
index 0000000..09f8bf8
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * dehdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Definition for Bridge driver module DEH.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DEHDEFS_
+#define DEHDEFS_
+
+#include <dspbridge/mbx_sh.h>  /* shared mailbox codes */
+
+/* DEH object manager */
+struct deh_mgr;
+
+/* Magic code used to determine if DSP signaled exception. */
+#define DEH_BASE        MBX_DEH_BASE
+#define DEH_USERS_BASE  MBX_DEH_USERS_BASE
+#define DEH_LIMIT       MBX_DEH_LIMIT
+
+#endif /* _DEHDEFS_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h
new file mode 100644 (file)
index 0000000..357458f
--- /dev/null
@@ -0,0 +1,702 @@
+/*
+ * dev.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Bridge Bridge driver device operations.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DEV_
+#define DEV_
+
+/*  ----------------------------------- Module Dependent Headers */
+#include <dspbridge/chnldefs.h>
+#include <dspbridge/cmm.h>
+#include <dspbridge/cod.h>
+#include <dspbridge/dehdefs.h>
+#include <dspbridge/nodedefs.h>
+#include <dspbridge/dispdefs.h>
+#include <dspbridge/dspdefs.h>
+#include <dspbridge/dmm.h>
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/devdefs.h>
+
+/*
+ *  ======== dev_brd_write_fxn ========
+ *  Purpose:
+ *      Exported function to be used as the COD write function.  This function
+ *      is passed a handle to a DEV_hObject by ZL in arb, then calls the
+ *      device's bridge_brd_write() function.
+ *  Parameters:
+ *      arb:           Handle to a Device Object.
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      dsp_addr:       Address on DSP board (Destination).
+ *      host_buf:       Pointer to host buffer (Source).
+ *      ul_num_bytes:     Number of bytes to transfer.
+ *      mem_type:       Memory space on DSP to which to transfer.
+ *  Returns:
+ *      Number of bytes written.  Returns 0 if the DEV_hObject passed in via
+ *      arb is invalid.
+ *  Requires:
+ *      DEV Initialized.
+ *      host_buf != NULL
+ *  Ensures:
+ */
+extern u32 dev_brd_write_fxn(void *arb,
+                            u32 dsp_add,
+                            void *host_buf, u32 ul_num_bytes, u32 mem_space);
+
+/*
+ *  ======== dev_create_device ========
+ *  Purpose:
+ *      Called by the operating system to load the Bridge Driver for a
+ *      'Bridge device.
+ *  Parameters:
+ *      device_obj:     Ptr to location to receive the device object handle.
+ *      driver_file_name: Name of Bridge driver PE DLL file to load.  If the
+ *                      absolute path is not provided, the file is loaded
+ *                      through 'Bridge's module search path.
+ *      host_config:    Host configuration information, to be passed down
+ *                      to the Bridge driver when bridge_dev_create() is called.
+ *      pDspConfig:     DSP resources, to be passed down to the Bridge driver
+ *                      when bridge_dev_create() is called.
+ *      dev_node_obj:       Platform specific device node.
+ *  Returns:
+ *      0:            Module is loaded, device object has been created
+ *      -ENOMEM:        Insufficient memory to create needed resources.
+ *      -EPERM:              Unable to find Bridge driver entry point function.
+ *      -ESPIPE:   Unable to load ZL DLL.
+ *  Requires:
+ *      DEV Initialized.
+ *      device_obj != NULL.
+ *      driver_file_name != NULL.
+ *      host_config != NULL.
+ *      pDspConfig != NULL.
+ *  Ensures:
+ *      0:  *device_obj will contain handle to the new device object.
+ *      Otherwise, does not create the device object, ensures the Bridge driver
+ *      module is unloaded, and sets *device_obj to NULL.
+ */
+extern int dev_create_device(struct dev_object
+                                   **device_obj,
+                                   const char *driver_file_name,
+                                   struct cfg_devnode *dev_node_obj);
+
+/*
+ *  ======== dev_create_iva_device ========
+ *  Purpose:
+ *      Called by the operating system to load the Bridge Driver for IVA.
+ *  Parameters:
+ *      device_obj:     Ptr to location to receive the device object handle.
+ *      driver_file_name: Name of Bridge driver PE DLL file to load.  If the
+ *                      absolute path is not provided, the file is loaded
+ *                      through 'Bridge's module search path.
+ *      host_config:    Host configuration information, to be passed down
+ *                      to the Bridge driver when bridge_dev_create() is called.
+ *      pDspConfig:     DSP resources, to be passed down to the Bridge driver
+ *                      when bridge_dev_create() is called.
+ *      dev_node_obj:       Platform specific device node.
+ *  Returns:
+ *      0:            Module is loaded, device object has been created
+ *      -ENOMEM:        Insufficient memory to create needed resources.
+ *      -EPERM:              Unable to find Bridge driver entry point function.
+ *      -ESPIPE:   Unable to load ZL DLL.
+ *  Requires:
+ *      DEV Initialized.
+ *      device_obj != NULL.
+ *      driver_file_name != NULL.
+ *      host_config != NULL.
+ *      pDspConfig != NULL.
+ *  Ensures:
+ *      0:  *device_obj will contain handle to the new device object.
+ *      Otherwise, does not create the device object, ensures the Bridge driver
+ *      module is unloaded, and sets *device_obj to NULL.
+ */
+extern int dev_create_iva_device(struct dev_object
+                                       **device_obj,
+                                       const char *driver_file_name,
+                                       const struct cfg_hostres
+                                       *host_config,
+                                       struct cfg_devnode *dev_node_obj);
+
+/*
+ *  ======== dev_create2 ========
+ *  Purpose:
+ *      After successful loading of the image from api_init_complete2
+ *      (PROC Auto_Start) or proc_load this fxn is called. This creates
+ *      the Node Manager and updates the DEV Object.
+ *  Parameters:
+ *      hdev_obj: Handle to device object created with dev_create_device().
+ *  Returns:
+ *      0:    Successful Creation of Node Manager
+ *      -EPERM:  Some Error Occurred.
+ *  Requires:
+ *      DEV Initialized
+ *      Valid hdev_obj
+ *  Ensures:
+ *      0 and hdev_obj->hnode_mgr != NULL
+ *      else    hdev_obj->hnode_mgr == NULL
+ */
+extern int dev_create2(struct dev_object *hdev_obj);
+
+/*
+ *  ======== dev_destroy2 ========
+ *  Purpose:
+ *      Destroys the Node manager for this device.
+ *  Parameters:
+ *      hdev_obj: Handle to device object created with dev_create_device().
+ *  Returns:
+ *      0:    Successful Creation of Node Manager
+ *      -EPERM:  Some Error Occurred.
+ *  Requires:
+ *      DEV Initialized
+ *      Valid hdev_obj
+ *  Ensures:
+ *      0 and hdev_obj->hnode_mgr == NULL
+ *      else    -EPERM.
+ */
+extern int dev_destroy2(struct dev_object *hdev_obj);
+
+/*
+ *  ======== dev_destroy_device ========
+ *  Purpose:
+ *      Destroys the channel manager for this device, if any, calls
+ *      bridge_dev_destroy(), and then attempts to unload the Bridge module.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *      -EPERM:     The Bridge driver failed it's bridge_dev_destroy() function.
+ *  Requires:
+ *      DEV Initialized.
+ *  Ensures:
+ */
+extern int dev_destroy_device(struct dev_object
+                                    *hdev_obj);
+
+/*
+ *  ======== dev_get_chnl_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the channel manager created for this device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      *mgr:           Ptr to location to store handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      mgr != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *mgr contains a handle to a channel manager object,
+ *                      or NULL.
+ *      else:           *mgr is NULL.
+ */
+extern int dev_get_chnl_mgr(struct dev_object *hdev_obj,
+                                  struct chnl_mgr **mgr);
+
+/*
+ *  ======== dev_get_cmm_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the shared memory manager created for this
+ *      device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      *mgr:           Ptr to location to store handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      mgr != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *mgr contains a handle to a channel manager object,
+ *                      or NULL.
+ *      else:           *mgr is NULL.
+ */
+extern int dev_get_cmm_mgr(struct dev_object *hdev_obj,
+                                 struct cmm_object **mgr);
+
+/*
+ *  ======== dev_get_dmm_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the dynamic memory manager created for this
+ *      device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      *mgr:           Ptr to location to store handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      mgr != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *mgr contains a handle to a channel manager object,
+ *                      or NULL.
+ *      else:           *mgr is NULL.
+ */
+extern int dev_get_dmm_mgr(struct dev_object *hdev_obj,
+                                 struct dmm_object **mgr);
+
+/*
+ *  ======== dev_get_cod_mgr ========
+ *  Purpose:
+ *      Retrieve the COD manager create for this device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      *cod_mgr:       Ptr to location to store handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      cod_mgr != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *cod_mgr contains a handle to a COD manager object.
+ *      else:           *cod_mgr is NULL.
+ */
+extern int dev_get_cod_mgr(struct dev_object *hdev_obj,
+                                 struct cod_manager **cod_mgr);
+
+/*
+ *  ======== dev_get_deh_mgr ========
+ *  Purpose:
+ *      Retrieve the DEH manager created for this device.
+ *  Parameters:
+ *      hdev_obj: Handle to device object created with dev_create_device().
+ *      *deh_manager:  Ptr to location to store handle.
+ *  Returns:
+ *      0:    Success.
+ *      -EFAULT:   Invalid hdev_obj.
+ *  Requires:
+ *      deh_manager != NULL.
+ *      DEH Initialized.
+ *  Ensures:
+ *      0:    *deh_manager contains a handle to a DEH manager object.
+ *      else:       *deh_manager is NULL.
+ */
+extern int dev_get_deh_mgr(struct dev_object *hdev_obj,
+                                 struct deh_mgr **deh_manager);
+
+/*
+ *  ======== dev_get_dev_node ========
+ *  Purpose:
+ *      Retrieve the platform specific device ID for this device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      dev_nde:        Ptr to location to get the device node handle.
+ *  Returns:
+ *      0:        Returns a DEVNODE in *dev_node_obj.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      dev_nde != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *dev_nde contains a platform specific device ID;
+ *      else:           *dev_nde is NULL.
+ */
+extern int dev_get_dev_node(struct dev_object *hdev_obj,
+                                  struct cfg_devnode **dev_nde);
+
+/*
+ *  ======== dev_get_dev_type ========
+ *  Purpose:
+ *      Retrieve the platform specific device ID for this device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      dev_nde:        Ptr to location to get the device node handle.
+ *  Returns:
+ *      0:        Success
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      dev_nde != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *dev_nde contains a platform specific device ID;
+ *      else:           *dev_nde is NULL.
+ */
+extern int dev_get_dev_type(struct dev_object *device_obj,
+                                       u8 *dev_type);
+
+/*
+ *  ======== dev_get_first ========
+ *  Purpose:
+ *      Retrieve the first Device Object handle from an internal linked list of
+ *      of DEV_OBJECTs maintained by DEV.
+ *  Parameters:
+ *  Returns:
+ *      NULL if there are no device objects stored; else
+ *      a valid DEV_HOBJECT.
+ *  Requires:
+ *      No calls to dev_create_device or dev_destroy_device (which my modify the
+ *      internal device object list) may occur between calls to dev_get_first
+ *      and dev_get_next.
+ *  Ensures:
+ *      The DEV_HOBJECT returned is valid.
+ *      A subsequent call to dev_get_next will return the next device object in
+ *      the list.
+ */
+extern struct dev_object *dev_get_first(void);
+
+/*
+ *  ======== dev_get_intf_fxns ========
+ *  Purpose:
+ *      Retrieve the Bridge driver interface function structure for the
+ *      loaded Bridge driver.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      *if_fxns:       Ptr to location to store fxn interface.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      if_fxns != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *if_fxns contains a pointer to the Bridge
+ *                      driver interface;
+ *      else:           *if_fxns is NULL.
+ */
+extern int dev_get_intf_fxns(struct dev_object *hdev_obj,
+                           struct bridge_drv_interface **if_fxns);
+
+/*
+ *  ======== dev_get_io_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the IO manager created for this device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      *mgr:           Ptr to location to store handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      mgr != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *mgr contains a handle to an IO manager object.
+ *      else:           *mgr is NULL.
+ */
+extern int dev_get_io_mgr(struct dev_object *hdev_obj,
+                                struct io_mgr **mgr);
+
+/*
+ *  ======== dev_get_next ========
+ *  Purpose:
+ *      Retrieve the next Device Object handle from an internal linked list of
+ *      of DEV_OBJECTs maintained by DEV, after having previously called
+ *      dev_get_first() and zero or more dev_get_next
+ *  Parameters:
+ *      hdev_obj: Handle to the device object returned from a previous
+ *                  call to dev_get_first() or dev_get_next().
+ *  Returns:
+ *      NULL if there are no further device objects on the list or hdev_obj
+ *      was invalid;
+ *      else the next valid DEV_HOBJECT in the list.
+ *  Requires:
+ *      No calls to dev_create_device or dev_destroy_device (which my modify the
+ *      internal device object list) may occur between calls to dev_get_first
+ *      and dev_get_next.
+ *  Ensures:
+ *      The DEV_HOBJECT returned is valid.
+ *      A subsequent call to dev_get_next will return the next device object in
+ *      the list.
+ */
+extern struct dev_object *dev_get_next(struct dev_object
+                                      *hdev_obj);
+
+/*
+ *  ========= dev_get_msg_mgr ========
+ *  Purpose:
+ *      Retrieve the msg_ctrl Manager Handle from the DevObject.
+ *  Parameters:
+ *      hdev_obj: Handle to the Dev Object
+ *      msg_man:    Location where msg_ctrl Manager handle will be returned.
+ *  Returns:
+ *  Requires:
+ *      DEV Initialized.
+ *      Valid hdev_obj.
+ *      node_man != NULL.
+ *  Ensures:
+ */
+extern void dev_get_msg_mgr(struct dev_object *hdev_obj,
+                           struct msg_mgr **msg_man);
+
+/*
+ *  ========= dev_get_node_manager ========
+ *  Purpose:
+ *      Retrieve the Node Manager Handle from the DevObject. It is an
+ *      accessor function
+ *  Parameters:
+ *      hdev_obj:     Handle to the Dev Object
+ *      node_man:       Location where Handle to the Node Manager will be
+ *                      returned..
+ *  Returns:
+ *      0:        Success
+ *      -EFAULT:    Invalid Dev Object handle.
+ *  Requires:
+ *      DEV Initialized.
+ *      node_man is not null
+ *  Ensures:
+ *      0:        *node_man contains a handle to a Node manager object.
+ *      else:           *node_man is NULL.
+ */
+extern int dev_get_node_manager(struct dev_object
+                                      *hdev_obj,
+                                      struct node_mgr **node_man);
+
+/*
+ *  ======== dev_get_symbol ========
+ *  Purpose:
+ *      Get the value of a symbol in the currently loaded program.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      str_sym:        Name of symbol to look up.
+ *      pul_value:       Ptr to symbol value.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *      -ESPIPE: Symbols couldn not be found or have not been loaded onto
+ *               the board.
+ *  Requires:
+ *      str_sym != NULL.
+ *      pul_value != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *pul_value contains the symbol value;
+ */
+extern int dev_get_symbol(struct dev_object *hdev_obj,
+                                const char *str_sym, u32 * pul_value);
+
+/*
+ *  ======== dev_get_bridge_context ========
+ *  Purpose:
+ *      Retrieve the Bridge Context handle, as returned by the
+ *      bridge_dev_create fxn.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with dev_create_device()
+ *      *phbridge_context:  Ptr to location to store context handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      phbridge_context != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *phbridge_context contains context handle;
+ *      else:           *phbridge_context is NULL;
+ */
+extern int dev_get_bridge_context(struct dev_object *hdev_obj,
+                                     struct bridge_dev_context
+                                     **phbridge_context);
+
+/*
+ *  ======== dev_exit ========
+ *  Purpose:
+ *      Decrement reference count, and free resources when reference count is
+ *      0.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      DEV is initialized.
+ *  Ensures:
+ *      When reference count == 0, DEV's private resources are freed.
+ */
+extern void dev_exit(void);
+
+/*
+ *  ======== dev_init ========
+ *  Purpose:
+ *      Initialize DEV's private state, keeping a reference count on each call.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occured.
+ *  Requires:
+ *  Ensures:
+ *      TRUE: A requirement for the other public DEV functions.
+ */
+extern bool dev_init(void);
+
+/*
+ *  ======== dev_is_locked ========
+ *  Purpose:
+ *      Predicate function to determine if the device has been
+ *      locked by a client for exclusive access.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *  Returns:
+ *      0:        TRUE: device has been locked.
+ *      0:     FALSE: device not locked.
+ *      -EFAULT:    hdev_obj was invalid.
+ *  Requires:
+ *      DEV Initialized.
+ *  Ensures:
+ */
+extern int dev_is_locked(struct dev_object *hdev_obj);
+
+/*
+ *  ======== dev_insert_proc_object ========
+ *  Purpose:
+ *      Inserts the Processor Object into the List of PROC Objects
+ *      kept in the DEV Object
+ *  Parameters:
+ *      proc_obj:    Handle to the Proc Object
+ *      hdev_obj      Handle to the Dev Object
+ *      bAttachedNew    Specifies if there are already processors attached
+ *  Returns:
+ *      0:        Successfully inserted into the list
+ *  Requires:
+ *      proc_obj is not NULL
+ *      hdev_obj is a valid handle to the DEV.
+ *      DEV Initialized.
+ *      List(of Proc object in Dev) Exists.
+ *  Ensures:
+ *      0 & the PROC Object is inserted and the list is not empty
+ *  Details:
+ *      If the List of Proc Object is empty bAttachedNew is TRUE, it indicated
+ *      this is the first Processor attaching.
+ *      If it is False, there are already processors attached.
+ */
+extern int dev_insert_proc_object(struct dev_object
+                                        *hdev_obj,
+                                        u32 proc_obj,
+                                        bool *already_attached);
+
+/*
+ *  ======== dev_remove_proc_object ========
+ *  Purpose:
+ *      Search for and remove a Proc object from the given list maintained
+ *      by the DEV
+ *  Parameters:
+ *      p_proc_object:        Ptr to ProcObject to insert.
+ *      dev_obj:         Ptr to Dev Object where the list is.
+ *      already_attached:  Ptr to return the bool
+ *  Returns:
+ *      0:            If successful.
+ *      -EPERM           Failure to Remove the PROC Object from the list
+ *  Requires:
+ *      DevObject is Valid
+ *      proc_obj != 0
+ *      dev_obj->proc_list != NULL
+ *      !LST_IS_EMPTY(dev_obj->proc_list)
+ *      already_attached !=NULL
+ *  Ensures:
+ *  Details:
+ *      List will be deleted when the DEV is destroyed.
+ *
+ */
+extern int dev_remove_proc_object(struct dev_object
+                                        *hdev_obj, u32 proc_obj);
+
+/*
+ *  ======== dev_notify_clients ========
+ *  Purpose:
+ *      Notify all clients of this device of a change in device status.
+ *      Clients may include multiple users of BRD, as well as CHNL.
+ *      This function is asychronous, and may be called by a timer event
+ *      set up by a watchdog timer.
+ *  Parameters:
+ *      hdev_obj:  Handle to device object created with dev_create_device().
+ *      ret:         A status word, most likely a BRD_STATUS.
+ *  Returns:
+ *      0:     All registered clients were asynchronously notified.
+ *      -EINVAL:   Invalid hdev_obj.
+ *  Requires:
+ *      DEV Initialized.
+ *  Ensures:
+ *      0: Notifications are queued by the operating system to be
+ *      delivered to clients.  This function does not ensure that
+ *      the notifications will ever be delivered.
+ */
+extern int dev_notify_clients(struct dev_object *hdev_obj, u32 ret);
+
+/*
+ *  ======== dev_remove_device ========
+ *  Purpose:
+ *      Destroys the Device Object created by dev_start_device.
+ *  Parameters:
+ *      dev_node_obj:       Device node as it is know to OS.
+ *  Returns:
+ *      0:        If success;
+ *      <error code>    Otherwise.
+ *  Requires:
+ *  Ensures:
+ */
+extern int dev_remove_device(struct cfg_devnode *dev_node_obj);
+
+/*
+ *  ======== dev_set_chnl_mgr ========
+ *  Purpose:
+ *      Set the channel manager for this device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      hmgr:           Handle to a channel manager, or NULL.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      DEV Initialized.
+ *  Ensures:
+ */
+extern int dev_set_chnl_mgr(struct dev_object *hdev_obj,
+                                  struct chnl_mgr *hmgr);
+
+/*
+ *  ======== dev_set_msg_mgr ========
+ *  Purpose:
+ *      Set the Message manager for this device.
+ *  Parameters:
+ *      hdev_obj: Handle to device object created with dev_create_device().
+ *      hmgr:       Handle to a message manager, or NULL.
+ *  Returns:
+ *  Requires:
+ *      DEV Initialized.
+ *  Ensures:
+ */
+extern void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr);
+
+/*
+ *  ======== dev_start_device ========
+ *  Purpose:
+ *      Initializes the new device with bridge environment.  This involves
+ *      querying CM for allocated resources, querying the registry for
+ *      necessary dsp resources (requested in the INF file), and using this
+ *      information to create a bridge device object.
+ *  Parameters:
+ *      dev_node_obj:       Device node as it is know to OS.
+ *  Returns:
+ *      0:        If success;
+ *      <error code>    Otherwise.
+ *  Requires:
+ *      DEV initialized.
+ *  Ensures:
+ */
+extern int dev_start_device(struct cfg_devnode *dev_node_obj);
+
+#endif /* DEV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/devdefs.h b/drivers/staging/tidspbridge/include/dspbridge/devdefs.h
new file mode 100644 (file)
index 0000000..a2f9241
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * devdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Definition of common include typedef between dspdefs.h and dev.h. Required
+ * to break circular dependency between Bridge driver and DEV include files.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DEVDEFS_
+#define DEVDEFS_
+
+/* Bridge Device Object */
+struct dev_object;
+
+#endif /* DEVDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/disp.h b/drivers/staging/tidspbridge/include/dspbridge/disp.h
new file mode 100644 (file)
index 0000000..82bf721
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * disp.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge Node Dispatcher.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DISP_
+#define DISP_
+
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/nodedefs.h>
+#include <dspbridge/nodepriv.h>
+#include <dspbridge/dispdefs.h>
+
+/*
+ *  ======== disp_create ========
+ *  Create a NODE Dispatcher object. This object handles the creation,
+ *  deletion, and execution of nodes on the DSP target, through communication
+ *  with the Resource Manager Server running on the target. Each NODE
+ *  Manager object should have exactly one NODE Dispatcher.
+ *
+ *  Parameters:
+ *      dispatch_obj:   Location to store node dispatcher object on output.
+ *      hdev_obj:     Device for this processor.
+ *      disp_attrs:     Node dispatcher attributes.
+ *  Returns:
+ *      0:                Success;
+ *      -ENOMEM:            Insufficient memory for requested resources.
+ *      -EPERM:              Unable to create dispatcher.
+ *  Requires:
+ *      disp_init(void) called.
+ *      disp_attrs != NULL.
+ *      hdev_obj != NULL.
+ *      dispatch_obj != NULL.
+ *  Ensures:
+ *      0:        IS_VALID(*dispatch_obj).
+ *      error:          *dispatch_obj == NULL.
+ */
+extern int disp_create(struct disp_object **dispatch_obj,
+                             struct dev_object *hdev_obj,
+                             const struct disp_attr *disp_attrs);
+
+/*
+ *  ======== disp_delete ========
+ *  Delete the NODE Dispatcher.
+ *
+ *  Parameters:
+ *      disp_obj:  Node Dispatcher object.
+ *  Returns:
+ *  Requires:
+ *      disp_init(void) called.
+ *      Valid disp_obj.
+ *  Ensures:
+ *      disp_obj is invalid.
+ */
+extern void disp_delete(struct disp_object *disp_obj);
+
+/*
+ *  ======== disp_exit ========
+ *  Discontinue usage of DISP module.
+ *
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      disp_init(void) previously called.
+ *  Ensures:
+ *      Any resources acquired in disp_init(void) will be freed when last DISP
+ *      client calls disp_exit(void).
+ */
+extern void disp_exit(void);
+
+/*
+ *  ======== disp_init ========
+ *  Initialize the DISP module.
+ *
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialization succeeded, FALSE otherwise.
+ *  Ensures:
+ */
+extern bool disp_init(void);
+
+/*
+ *  ======== disp_node_change_priority ========
+ *  Change the priority of a node currently running on the target.
+ *
+ *  Parameters:
+ *      disp_obj:            Node Dispatcher object.
+ *      hnode:                  Node object representing a node currently
+ *                              allocated or running on the DSP.
+ *      ulFxnAddress:           Address of RMS function for changing priority.
+ *      node_env:                Address of node's environment structure.
+ *      prio:              New priority level to set node's priority to.
+ *  Returns:
+ *      0:                Success.
+ *      -ETIME:           A timeout occurred before the DSP responded.
+ *  Requires:
+ *      disp_init(void) called.
+ *      Valid disp_obj.
+ *      hnode != NULL.
+ *  Ensures:
+ */
+extern int disp_node_change_priority(struct disp_object
+                                           *disp_obj,
+                                           struct node_object *hnode,
+                                           u32 rms_fxn,
+                                           nodeenv node_env, s32 prio);
+
+/*
+ *  ======== disp_node_create ========
+ *  Create a node on the DSP by remotely calling the node's create function.
+ *
+ *  Parameters:
+ *      disp_obj:    Node Dispatcher object.
+ *      hnode:          Node handle obtained from node_allocate().
+ *      ul_fxn_addr:      Address or RMS create node function.
+ *      ul_create_fxn:    Address of node's create function.
+ *      pargs:          Arguments to pass to RMS node create function.
+ *      node_env:       Location to store node environment pointer on
+ *                      output.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIME:   A timeout occurred before the DSP responded.
+ *      -EPERM:      A failure occurred, unable to create node.
+ *  Requires:
+ *      disp_init(void) called.
+ *      Valid disp_obj.
+ *      pargs != NULL.
+ *      hnode != NULL.
+ *      node_env != NULL.
+ *      node_get_type(hnode) != NODE_DEVICE.
+ *  Ensures:
+ */
+extern int disp_node_create(struct disp_object *disp_obj,
+                                  struct node_object *hnode,
+                                  u32 rms_fxn,
+                                  u32 ul_create_fxn,
+                                  const struct node_createargs
+                                  *pargs, nodeenv *node_env);
+
+/*
+ *  ======== disp_node_delete ========
+ *  Delete a node on the DSP by remotely calling the node's delete function.
+ *
+ *  Parameters:
+ *      disp_obj:    Node Dispatcher object.
+ *      hnode:          Node object representing a node currently
+ *                      loaded on the DSP.
+ *      ul_fxn_addr:      Address or RMS delete node function.
+ *      ul_delete_fxn:    Address of node's delete function.
+ *      node_env:        Address of node's environment structure.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIME:   A timeout occurred before the DSP responded.
+ *  Requires:
+ *      disp_init(void) called.
+ *      Valid disp_obj.
+ *      hnode != NULL.
+ *  Ensures:
+ */
+extern int disp_node_delete(struct disp_object *disp_obj,
+                                  struct node_object *hnode,
+                                  u32 rms_fxn,
+                                  u32 ul_delete_fxn, nodeenv node_env);
+
+/*
+ *  ======== disp_node_run ========
+ *  Start execution of a node's execute phase, or resume execution of a node
+ *  that has been suspended (via DISP_NodePause()) on the DSP.
+ *
+ *  Parameters:
+ *      disp_obj:    Node Dispatcher object.
+ *      hnode:          Node object representing a node to be executed
+ *                      on the DSP.
+ *      ul_fxn_addr:      Address or RMS node execute function.
+ *      ul_execute_fxn:   Address of node's execute function.
+ *      node_env:        Address of node's environment structure.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIME:   A timeout occurred before the DSP responded.
+ *  Requires:
+ *      disp_init(void) called.
+ *      Valid disp_obj.
+ *      hnode != NULL.
+ *  Ensures:
+ */
+extern int disp_node_run(struct disp_object *disp_obj,
+                               struct node_object *hnode,
+                               u32 rms_fxn,
+                               u32 ul_execute_fxn, nodeenv node_env);
+
+#endif /* DISP_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dispdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dispdefs.h
new file mode 100644 (file)
index 0000000..946551a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * dispdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global DISP constants and types, shared by PROCESSOR, NODE, and DISP.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DISPDEFS_
+#define DISPDEFS_
+
+struct disp_object;
+
+/* Node Dispatcher attributes */
+struct disp_attr {
+       u32 ul_chnl_offset;     /* Offset of channel ids reserved for RMS */
+       /* Size of buffer for sending data to RMS */
+       u32 ul_chnl_buf_size;
+       int proc_family;        /* eg, 5000 */
+       int proc_type;          /* eg, 5510 */
+       void *reserved1;        /* Reserved for future use. */
+       u32 reserved2;          /* Reserved for future use. */
+};
+
+#endif /* DISPDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h
new file mode 100644 (file)
index 0000000..6c58335
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * dmm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address
+ * space that can be directly mapped to any MPU buffer or memory region.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DMM_
+#define DMM_
+
+#include <dspbridge/dbdefs.h>
+
+struct dmm_object;
+
+/* DMM attributes used in dmm_create() */
+struct dmm_mgrattrs {
+       u32 reserved;
+};
+
+#define DMMPOOLSIZE      0x4000000
+
+/*
+ *  ======== dmm_get_handle ========
+ *  Purpose:
+ *      Return the dynamic memory manager object for this device.
+ *      This is typically called from the client process.
+ */
+
+extern int dmm_get_handle(void *hprocessor,
+                                struct dmm_object **dmm_manager);
+
+extern int dmm_reserve_memory(struct dmm_object *dmm_mgr,
+                                    u32 size, u32 *prsv_addr);
+
+extern int dmm_un_reserve_memory(struct dmm_object *dmm_mgr,
+                                       u32 rsv_addr);
+
+extern int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr,
+                                u32 size);
+
+extern int dmm_un_map_memory(struct dmm_object *dmm_mgr,
+                                   u32 addr, u32 *psize);
+
+extern int dmm_destroy(struct dmm_object *dmm_mgr);
+
+extern int dmm_delete_tables(struct dmm_object *dmm_mgr);
+
+extern int dmm_create(struct dmm_object **dmm_manager,
+                            struct dev_object *hdev_obj,
+                            const struct dmm_mgrattrs *mgr_attrts);
+
+extern bool dmm_init(void);
+
+extern void dmm_exit(void);
+
+extern int dmm_create_tables(struct dmm_object *dmm_mgr,
+                                   u32 addr, u32 size);
+
+#ifdef DSP_DMM_DEBUG
+u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr);
+#endif
+
+#endif /* DMM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h
new file mode 100644 (file)
index 0000000..f365015
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * drv.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DRV Resource allocation module. Driver Object gets Created
+ * at the time of Loading. It holds the List of Device Objects
+ * in the system.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DRV_
+#define DRV_
+
+#include <dspbridge/devdefs.h>
+
+#include <dspbridge/drvdefs.h>
+#include <linux/idr.h>
+
+#define DRV_ASSIGN     1
+#define DRV_RELEASE    0
+
+/* Provide the DSP Internal memory windows that can be accessed from L3 address
+ * space */
+
+#define OMAP_GEM_BASE   0x107F8000
+#define OMAP_DSP_SIZE   0x00720000
+
+/* MEM1 is L2 RAM + L2 Cache space */
+#define OMAP_DSP_MEM1_BASE 0x5C7F8000
+#define OMAP_DSP_MEM1_SIZE 0x18000
+#define OMAP_DSP_GEM1_BASE 0x107F8000
+
+/* MEM2 is L1P RAM/CACHE space */
+#define OMAP_DSP_MEM2_BASE 0x5CE00000
+#define OMAP_DSP_MEM2_SIZE 0x8000
+#define OMAP_DSP_GEM2_BASE 0x10E00000
+
+/* MEM3 is L1D RAM/CACHE space */
+#define OMAP_DSP_MEM3_BASE 0x5CF04000
+#define OMAP_DSP_MEM3_SIZE 0x14000
+#define OMAP_DSP_GEM3_BASE 0x10F04000
+
+#define OMAP_IVA2_PRM_BASE 0x48306000
+#define OMAP_IVA2_PRM_SIZE 0x1000
+
+#define OMAP_IVA2_CM_BASE 0x48004000
+#define OMAP_IVA2_CM_SIZE 0x1000
+
+#define OMAP_PER_CM_BASE 0x48005000
+#define OMAP_PER_CM_SIZE 0x1000
+
+#define OMAP_PER_PRM_BASE 0x48307000
+#define OMAP_PER_PRM_SIZE 0x1000
+
+#define OMAP_CORE_PRM_BASE 0x48306A00
+#define OMAP_CORE_PRM_SIZE 0x1000
+
+#define OMAP_SYSC_BASE 0x48002000
+#define OMAP_SYSC_SIZE 0x1000
+
+#define OMAP_DMMU_BASE 0x5D000000
+#define OMAP_DMMU_SIZE 0x1000
+
+#define OMAP_PRCM_VDD1_DOMAIN 1
+#define OMAP_PRCM_VDD2_DOMAIN 2
+
+/* GPP PROCESS CLEANUP Data structures */
+
+/* New structure (member of process context) abstracts NODE resource info */
+struct node_res_object {
+       void *hnode;
+       s32 node_allocated;     /* Node status */
+       s32 heap_allocated;     /* Heap status */
+       s32 streams_allocated;  /* Streams status */
+       int id;
+};
+
+/* used to cache dma mapping information */
+struct bridge_dma_map_info {
+       /* direction of DMA in action, or DMA_NONE */
+       enum dma_data_direction dir;
+       /* number of elements requested by us */
+       int num_pages;
+       /* number of elements returned from dma_map_sg */
+       int sg_num;
+       /* list of buffers used in this DMA action */
+       struct scatterlist *sg;
+};
+
+/* Used for DMM mapped memory accounting */
+struct dmm_map_object {
+       struct list_head link;
+       u32 dsp_addr;
+       u32 mpu_addr;
+       u32 size;
+       u32 num_usr_pgs;
+       struct page **pages;
+       struct bridge_dma_map_info dma_info;
+};
+
+/* Used for DMM reserved memory accounting */
+struct dmm_rsv_object {
+       struct list_head link;
+       u32 dsp_reserved_addr;
+};
+
+/* New structure (member of process context) abstracts DMM resource info */
+struct dspheap_res_object {
+       s32 heap_allocated;     /* DMM status */
+       u32 ul_mpu_addr;
+       u32 ul_dsp_addr;
+       u32 ul_dsp_res_addr;
+       u32 heap_size;
+       void *hprocessor;
+       struct dspheap_res_object *next;
+};
+
+/* New structure (member of process context) abstracts stream resource info */
+struct strm_res_object {
+       s32 stream_allocated;   /* Stream status */
+       void *hstream;
+       u32 num_bufs;
+       u32 dir;
+       int id;
+};
+
+/* Overall Bridge process resource usage state */
+enum gpp_proc_res_state {
+       PROC_RES_ALLOCATED,
+       PROC_RES_FREED
+};
+
+/* Bridge Data */
+struct drv_data {
+       char *base_img;
+       s32 shm_size;
+       int tc_wordswapon;
+       void *drv_object;
+       void *dev_object;
+       void *mgr_object;
+};
+
+/* Process Context */
+struct process_context {
+       /* Process State */
+       enum gpp_proc_res_state res_state;
+
+       /* Handle to Processor */
+       void *hprocessor;
+
+       /* DSP Node resources */
+       struct idr *node_id;
+
+       /* DMM mapped memory resources */
+       struct list_head dmm_map_list;
+       spinlock_t dmm_map_lock;
+
+       /* DMM reserved memory resources */
+       struct list_head dmm_rsv_list;
+       spinlock_t dmm_rsv_lock;
+
+       /* DSP Heap resources */
+       struct dspheap_res_object *pdspheap_list;
+
+       /* Stream resources */
+       struct idr *stream_id;
+};
+
+/*
+ *  ======== drv_create ========
+ *  Purpose:
+ *      Creates the Driver Object. This is done during the driver loading.
+ *      There is only one Driver Object in the DSP/BIOS Bridge.
+ *  Parameters:
+ *      drv_obj:        Location to store created DRV Object handle.
+ *  Returns:
+ *      0:        Sucess
+ *      -ENOMEM:    Failed in Memory allocation
+ *      -EPERM:      General Failure
+ *  Requires:
+ *      DRV Initialized (refs > 0 )
+ *      drv_obj != NULL.
+ *  Ensures:
+ *      0:        - *drv_obj is a valid DRV interface to the device.
+ *                      - List of DevObject Created and Initialized.
+ *                      - List of dev_node String created and intialized.
+ *                      - Registry is updated with the DRV Object.
+ *      !0:       DRV Object not created
+ *  Details:
+ *      There is one Driver Object for the Driver representing
+ *      the driver itself. It contains the list of device
+ *      Objects and the list of Device Extensions in the system.
+ *      Also it can hold other neccessary
+ *      information in its storage area.
+ */
+extern int drv_create(struct drv_object **drv_obj);
+
+/*
+ *  ======== drv_destroy ========
+ *  Purpose:
+ *      destroys the Dev Object list, DrvExt list
+ *      and destroy the DRV object
+ *      Called upon driver unLoading.or unsuccesful loading of the driver.
+ *  Parameters:
+ *      driver_obj:     Handle to Driver object .
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Failed to destroy DRV Object
+ *  Requires:
+ *      DRV Initialized (cRegs > 0 )
+ *      hdrv_obj is not NULL and a valid DRV handle .
+ *      List of DevObject is Empty.
+ *      List of DrvExt is Empty
+ *  Ensures:
+ *      0:        - DRV Object destroyed and hdrv_obj is not a valid
+ *                        DRV handle.
+ *                      - Registry is updated with "0" as the DRV Object.
+ */
+extern int drv_destroy(struct drv_object *driver_obj);
+
+/*
+ *  ======== drv_exit ========
+ *  Purpose:
+ *      Exit the DRV module, freeing any modules initialized in drv_init.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *  Ensures:
+ */
+extern void drv_exit(void);
+
+/*
+ *  ======== drv_get_first_dev_object ========
+ *  Purpose:
+ *      Returns the Ptr to the FirstDev Object in the List
+ *  Parameters:
+ *  Requires:
+ *      DRV Initialized
+ *  Returns:
+ *      dw_dev_object:  Ptr to the First Dev Object as a u32
+ *      0 if it fails to retrieve the First Dev Object
+ *  Ensures:
+ */
+extern u32 drv_get_first_dev_object(void);
+
+/*
+ *  ======== drv_get_first_dev_extension ========
+ *  Purpose:
+ *      Returns the Ptr to the First Device Extension in the List
+ *  Parameters:
+ *  Requires:
+ *      DRV Initialized
+ *  Returns:
+ *      dw_dev_extension:     Ptr to the First Device Extension as a u32
+ *      0:                  Failed to Get the Device Extension
+ *  Ensures:
+ */
+extern u32 drv_get_first_dev_extension(void);
+
+/*
+ *  ======== drv_get_dev_object ========
+ *  Purpose:
+ *      Given a index, returns a handle to DevObject from the list
+ *  Parameters:
+ *      hdrv_obj:     Handle to the Manager
+ *      device_obj:     Location to store the Dev Handle
+ *  Requires:
+ *      DRV Initialized
+ *      index >= 0
+ *      hdrv_obj is not NULL and Valid DRV Object
+ *      device_obj is not NULL
+ *      Device Object List not Empty
+ *  Returns:
+ *      0:        Success
+ *      -EPERM:      Failed to Get the Dev Object
+ *  Ensures:
+ *      0:        *device_obj != NULL
+ *      -EPERM:      *device_obj = NULL
+ */
+extern int drv_get_dev_object(u32 index,
+                                    struct drv_object *hdrv_obj,
+                                    struct dev_object **device_obj);
+
+/*
+ *  ======== drv_get_next_dev_object ========
+ *  Purpose:
+ *      Returns the Ptr to the Next Device Object from the the List
+ *  Parameters:
+ *      hdev_obj:     Handle to the Device Object
+ *  Requires:
+ *      DRV Initialized
+ *      hdev_obj != 0
+ *  Returns:
+ *      dw_dev_object:    Ptr to the Next Dev Object as a u32
+ *      0:              If it fail to get the next Dev Object.
+ *  Ensures:
+ */
+extern u32 drv_get_next_dev_object(u32 hdev_obj);
+
+/*
+ *  ======== drv_get_next_dev_extension ========
+ *  Purpose:
+ *      Returns the Ptr to the Next Device Extension from the the List
+ *  Parameters:
+ *      dev_extension:      Handle to the Device Extension
+ *  Requires:
+ *      DRV Initialized
+ *      dev_extension != 0.
+ *  Returns:
+ *      dw_dev_extension:     Ptr to the Next Dev Extension
+ *      0:                  If it fail to Get the next Dev Extension
+ *  Ensures:
+ */
+extern u32 drv_get_next_dev_extension(u32 dev_extension);
+
+/*
+ *  ======== drv_init ========
+ *  Purpose:
+ *      Initialize the DRV module.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if success; FALSE otherwise.
+ *  Requires:
+ *  Ensures:
+ */
+extern int drv_init(void);
+
+/*
+ *  ======== drv_insert_dev_object ========
+ *  Purpose:
+ *      Insert a DeviceObject into the list of Driver object.
+ *  Parameters:
+ *      driver_obj:     Handle to DrvObject
+ *      hdev_obj:     Handle to DeviceObject to insert.
+ *  Returns:
+ *      0:        If successful.
+ *      -EPERM:      General Failure:
+ *  Requires:
+ *      hdrv_obj != NULL and Valid DRV Handle.
+ *      hdev_obj != NULL.
+ *  Ensures:
+ *      0:        Device Object is inserted and the List is not empty.
+ */
+extern int drv_insert_dev_object(struct drv_object *driver_obj,
+                                       struct dev_object *hdev_obj);
+
+/*
+ *  ======== drv_remove_dev_object ========
+ *  Purpose:
+ *      Search for and remove a Device object from the given list of Device Obj
+ *      objects.
+ *  Parameters:
+ *      driver_obj:     Handle to DrvObject
+ *      hdev_obj:     Handle to DevObject to Remove
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Unable to find dev_obj.
+ *  Requires:
+ *      hdrv_obj != NULL and a Valid DRV Handle.
+ *      hdev_obj != NULL.
+ *      List exists and is not empty.
+ *  Ensures:
+ *      List either does not exist (NULL), or is not empty if it does exist.
+ */
+extern int drv_remove_dev_object(struct drv_object *driver_obj,
+                                       struct dev_object *hdev_obj);
+
+/*
+ *  ======== drv_request_resources ========
+ *  Purpose:
+ *      Assigns the Resources or Releases them.
+ *  Parameters:
+ *      dw_context:          Path to the driver Registry Key.
+ *      dev_node_strg:     Ptr to dev_node String stored in the Device Ext.
+ *  Returns:
+ *      TRUE if success; FALSE otherwise.
+ *  Requires:
+ *  Ensures:
+ *      The Resources are assigned based on Bus type.
+ *      The hardware is initialized. Resource information is
+ *      gathered from the Registry(ISA, PCMCIA)or scanned(PCI)
+ *      Resource structure is stored in the registry which will be
+ *      later used by the CFG module.
+ */
+extern int drv_request_resources(u32 dw_context,
+                                       u32 *dev_node_strg);
+
+/*
+ *  ======== drv_release_resources ========
+ *  Purpose:
+ *      Assigns the Resources or Releases them.
+ *  Parameters:
+ *      dw_context:      Path to the driver Registry Key.
+ *      hdrv_obj:     Handle to the Driver Object.
+ *  Returns:
+ *      TRUE if success; FALSE otherwise.
+ *  Requires:
+ *  Ensures:
+ *      The Resources are released based on Bus type.
+ *      Resource structure is deleted from the registry
+ */
+extern int drv_release_resources(u32 dw_context,
+                                       struct drv_object *hdrv_obj);
+
+/**
+ * drv_request_bridge_res_dsp() - Reserves shared memory for bridge.
+ * @phost_resources:  pointer to host resources.
+ */
+int drv_request_bridge_res_dsp(void **phost_resources);
+
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+void bridge_recover_schedule(void);
+#endif
+
+/*
+ *  ======== mem_ext_phys_pool_init ========
+ *  Purpose:
+ *      Uses the physical memory chunk passed for internal consitent memory
+ *      allocations.
+ *      physical address based on the page frame address.
+ *  Parameters:
+ *      pool_phys_base  starting address of the physical memory pool.
+ *      pool_size      size of the physical memory pool.
+ *  Returns:
+ *      none.
+ *  Requires:
+ *      - MEM initialized.
+ *      - valid physical address for the base and size > 0
+ */
+extern void mem_ext_phys_pool_init(u32 pool_phys_base, u32 pool_size);
+
+/*
+ *  ======== mem_ext_phys_pool_release ========
+ */
+extern void mem_ext_phys_pool_release(void);
+
+/*  ======== mem_alloc_phys_mem ========
+ *  Purpose:
+ *      Allocate physically contiguous, uncached memory
+ *  Parameters:
+ *      byte_size:     Number of bytes to allocate.
+ *      align_mask:    Alignment Mask.
+ *      physical_address: Physical address of allocated memory.
+ *  Returns:
+ *      Pointer to a block of memory;
+ *      NULL if memory couldn't be allocated, or if byte_size == 0.
+ *  Requires:
+ *      MEM initialized.
+ *  Ensures:
+ *      The returned pointer, if not NULL, points to a valid memory block of
+ *      the size requested.  Returned physical address refers to physical
+ *      location of memory.
+ */
+extern void *mem_alloc_phys_mem(u32 byte_size,
+                               u32 align_mask, u32 *physical_address);
+
+/*
+ *  ======== mem_free_phys_mem ========
+ *  Purpose:
+ *      Free the given block of physically contiguous memory.
+ *  Parameters:
+ *      virtual_address:  Pointer to virtual memory region allocated
+ *      by mem_alloc_phys_mem().
+ *      physical_address:  Pointer to physical memory region  allocated
+ *      by mem_alloc_phys_mem().
+ *      byte_size:  Size of the memory region allocated by mem_alloc_phys_mem().
+ *  Returns:
+ *  Requires:
+ *      MEM initialized.
+ *      virtual_address is a valid memory address returned by
+ *          mem_alloc_phys_mem()
+ *  Ensures:
+ *      virtual_address is no longer a valid pointer to memory.
+ */
+extern void mem_free_phys_mem(void *virtual_address,
+                             u32 physical_address, u32 byte_size);
+
+/*
+ *  ======== MEM_LINEAR_ADDRESS ========
+ *  Purpose:
+ *      Get the linear address corresponding to the given physical address.
+ *  Parameters:
+ *      phys_addr:  Physical address to be mapped.
+ *      byte_size:     Number of bytes in physical range to map.
+ *  Returns:
+ *      The corresponding linear address, or NULL if unsuccessful.
+ *  Requires:
+ *      MEM initialized.
+ *  Ensures:
+ *  Notes:
+ *      If valid linear address is returned, be sure to call
+ *      MEM_UNMAP_LINEAR_ADDRESS().
+ */
+#define MEM_LINEAR_ADDRESS(phy_addr, byte_size) phy_addr
+
+/*
+ *  ======== MEM_UNMAP_LINEAR_ADDRESS ========
+ *  Purpose:
+ *      Unmap the linear address mapped in MEM_LINEAR_ADDRESS.
+ *  Parameters:
+ *      base_addr: Ptr to mapped memory (as returned by MEM_LINEAR_ADDRESS()).
+ *  Returns:
+ *  Requires:
+ *      - MEM initialized.
+ *      - base_addr is a valid linear address mapped in MEM_LINEAR_ADDRESS.
+ *  Ensures:
+ *      - base_addr no longer points to a valid linear address.
+ */
+#define MEM_UNMAP_LINEAR_ADDRESS(base_addr) {}
+
+#endif /* DRV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/drvdefs.h b/drivers/staging/tidspbridge/include/dspbridge/drvdefs.h
new file mode 100644 (file)
index 0000000..2920917
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * drvdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Definition of common struct between dspdefs.h and drv.h.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DRVDEFS_
+#define DRVDEFS_
+
+/* Bridge Driver Object */
+struct drv_object;
+
+#endif /* DRVDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h
new file mode 100644 (file)
index 0000000..8da5bd8
--- /dev/null
@@ -0,0 +1,475 @@
+/*
+ * dspapi-ioctl.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Contains structures and commands that are used for interaction
+ * between the DDSP API and Bridge driver.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPAPIIOCTL_
+#define DSPAPIIOCTL_
+
+#include <dspbridge/cmm.h>
+#include <dspbridge/strmdefs.h>
+#include <dspbridge/dbdcd.h>
+
+union trapped_args {
+
+       /* MGR Module */
+       struct {
+               u32 node_id;
+               struct dsp_ndbprops __user *pndb_props;
+               u32 undb_props_size;
+               u32 __user *pu_num_nodes;
+       } args_mgr_enumnode_info;
+
+       struct {
+               u32 processor_id;
+               struct dsp_processorinfo __user *processor_info;
+               u32 processor_info_size;
+               u32 __user *pu_num_procs;
+       } args_mgr_enumproc_info;
+
+       struct {
+               struct dsp_uuid *uuid_obj;
+               enum dsp_dcdobjtype obj_type;
+               char *psz_path_name;
+       } args_mgr_registerobject;
+
+       struct {
+               struct dsp_uuid *uuid_obj;
+               enum dsp_dcdobjtype obj_type;
+       } args_mgr_unregisterobject;
+
+       struct {
+               struct dsp_notification __user *__user *anotifications;
+               u32 count;
+               u32 __user *pu_index;
+               u32 utimeout;
+       } args_mgr_wait;
+
+       /* PROC Module */
+       struct {
+               u32 processor_id;
+               struct dsp_processorattrin __user *attr_in;
+               void *__user *ph_processor;
+       } args_proc_attach;
+
+       struct {
+               void *hprocessor;
+               u32 dw_cmd;
+               struct dsp_cbdata __user *pargs;
+       } args_proc_ctrl;
+
+       struct {
+               void *hprocessor;
+       } args_proc_detach;
+
+       struct {
+               void *hprocessor;
+               void *__user *node_tab;
+               u32 node_tab_size;
+               u32 __user *pu_num_nodes;
+               u32 __user *pu_allocated;
+       } args_proc_enumnode_info;
+
+       struct {
+               void *hprocessor;
+               u32 resource_type;
+               struct dsp_resourceinfo *resource_info;
+               u32 resource_info_size;
+       } args_proc_enumresources;
+
+       struct {
+               void *hprocessor;
+               struct dsp_processorstate __user *proc_state_obj;
+               u32 state_info_size;
+       } args_proc_getstate;
+
+       struct {
+               void *hprocessor;
+               u8 __user *pbuf;
+               u8 __user *psize;
+               u32 max_size;
+       } args_proc_gettrace;
+
+       struct {
+               void *hprocessor;
+               s32 argc_index;
+               char __user *__user *user_args;
+               char *__user *user_envp;
+       } args_proc_load;
+
+       struct {
+               void *hprocessor;
+               u32 event_mask;
+               u32 notify_type;
+               struct dsp_notification __user *hnotification;
+       } args_proc_register_notify;
+
+       struct {
+               void *hprocessor;
+       } args_proc_start;
+
+       struct {
+               void *hprocessor;
+               u32 ul_size;
+               void *__user *pp_rsv_addr;
+       } args_proc_rsvmem;
+
+       struct {
+               void *hprocessor;
+               u32 ul_size;
+               void *prsv_addr;
+       } args_proc_unrsvmem;
+
+       struct {
+               void *hprocessor;
+               void *pmpu_addr;
+               u32 ul_size;
+               void *req_addr;
+               void *__user *pp_map_addr;
+               u32 ul_map_attr;
+       } args_proc_mapmem;
+
+       struct {
+               void *hprocessor;
+               u32 ul_size;
+               void *map_addr;
+       } args_proc_unmapmem;
+
+       struct {
+               void *hprocessor;
+               void *pmpu_addr;
+               u32 ul_size;
+               u32 dir;
+       } args_proc_dma;
+
+       struct {
+               void *hprocessor;
+               void *pmpu_addr;
+               u32 ul_size;
+               u32 ul_flags;
+       } args_proc_flushmemory;
+
+       struct {
+               void *hprocessor;
+       } args_proc_stop;
+
+       struct {
+               void *hprocessor;
+               void *pmpu_addr;
+               u32 ul_size;
+       } args_proc_invalidatememory;
+
+       /* NODE Module */
+       struct {
+               void *hprocessor;
+               struct dsp_uuid __user *node_id_ptr;
+               struct dsp_cbdata __user *pargs;
+               struct dsp_nodeattrin __user *attr_in;
+               void *__user *ph_node;
+       } args_node_allocate;
+
+       struct {
+               void *hnode;
+               u32 usize;
+               struct dsp_bufferattr __user *pattr;
+               u8 *__user *pbuffer;
+       } args_node_allocmsgbuf;
+
+       struct {
+               void *hnode;
+               s32 prio;
+       } args_node_changepriority;
+
+       struct {
+               void *hnode;
+               u32 stream_id;
+               void *other_node;
+               u32 other_stream;
+               struct dsp_strmattr __user *pattrs;
+               struct dsp_cbdata __user *conn_param;
+       } args_node_connect;
+
+       struct {
+               void *hnode;
+       } args_node_create;
+
+       struct {
+               void *hnode;
+       } args_node_delete;
+
+       struct {
+               void *hnode;
+               struct dsp_bufferattr __user *pattr;
+               u8 *pbuffer;
+       } args_node_freemsgbuf;
+
+       struct {
+               void *hnode;
+               struct dsp_nodeattr __user *pattr;
+               u32 attr_size;
+       } args_node_getattr;
+
+       struct {
+               void *hnode;
+               struct dsp_msg __user *message;
+               u32 utimeout;
+       } args_node_getmessage;
+
+       struct {
+               void *hnode;
+       } args_node_pause;
+
+       struct {
+               void *hnode;
+               struct dsp_msg __user *message;
+               u32 utimeout;
+       } args_node_putmessage;
+
+       struct {
+               void *hnode;
+               u32 event_mask;
+               u32 notify_type;
+               struct dsp_notification __user *hnotification;
+       } args_node_registernotify;
+
+       struct {
+               void *hnode;
+       } args_node_run;
+
+       struct {
+               void *hnode;
+               int __user *pstatus;
+       } args_node_terminate;
+
+       struct {
+               void *hprocessor;
+               struct dsp_uuid __user *node_id_ptr;
+               struct dsp_ndbprops __user *node_props;
+       } args_node_getuuidprops;
+
+       /* STRM module */
+
+       struct {
+               void *hstream;
+               u32 usize;
+               u8 *__user *ap_buffer;
+               u32 num_bufs;
+       } args_strm_allocatebuffer;
+
+       struct {
+               void *hstream;
+       } args_strm_close;
+
+       struct {
+               void *hstream;
+               u8 *__user *ap_buffer;
+               u32 num_bufs;
+       } args_strm_freebuffer;
+
+       struct {
+               void *hstream;
+               void **ph_event;
+       } args_strm_geteventhandle;
+
+       struct {
+               void *hstream;
+               struct stream_info __user *stream_info;
+               u32 stream_info_size;
+       } args_strm_getinfo;
+
+       struct {
+               void *hstream;
+               bool flush_flag;
+       } args_strm_idle;
+
+       struct {
+               void *hstream;
+               u8 *pbuffer;
+               u32 dw_bytes;
+               u32 dw_buf_size;
+               u32 dw_arg;
+       } args_strm_issue;
+
+       struct {
+               void *hnode;
+               u32 direction;
+               u32 index;
+               struct strm_attr __user *attr_in;
+               void *__user *ph_stream;
+       } args_strm_open;
+
+       struct {
+               void *hstream;
+               u8 *__user *buf_ptr;
+               u32 __user *bytes;
+               u32 __user *buf_size_ptr;
+               u32 __user *pdw_arg;
+       } args_strm_reclaim;
+
+       struct {
+               void *hstream;
+               u32 event_mask;
+               u32 notify_type;
+               struct dsp_notification __user *hnotification;
+       } args_strm_registernotify;
+
+       struct {
+               void *__user *stream_tab;
+               u32 strm_num;
+               u32 __user *pmask;
+               u32 utimeout;
+       } args_strm_select;
+
+       /* CMM Module */
+       struct {
+               struct cmm_object *hcmm_mgr;
+               u32 usize;
+               struct cmm_attrs *pattrs;
+               void **pp_buf_va;
+       } args_cmm_allocbuf;
+
+       struct {
+               struct cmm_object *hcmm_mgr;
+               void *buf_pa;
+               u32 ul_seg_id;
+       } args_cmm_freebuf;
+
+       struct {
+               void *hprocessor;
+               struct cmm_object *__user *ph_cmm_mgr;
+       } args_cmm_gethandle;
+
+       struct {
+               struct cmm_object *hcmm_mgr;
+               struct cmm_info __user *cmm_info_obj;
+       } args_cmm_getinfo;
+
+       /* UTIL module */
+       struct {
+               s32 util_argc;
+               char **pp_argv;
+       } args_util_testdll;
+};
+
+/*
+ * Dspbridge Ioctl numbering scheme
+ *
+ *    7                           0
+ *  ---------------------------------
+ *  |  Module   |   Ioctl Number    |
+ *  ---------------------------------
+ *  | x | x | x | 0 | 0 | 0 | 0 | 0 |
+ *  ---------------------------------
+ */
+
+/* Ioctl driver identifier */
+#define DB             0xDB
+
+/*
+ * Following are used to distinguish between module ioctls, this is needed
+ * in case new ioctls are introduced.
+ */
+#define DB_MODULE_MASK         0xE0
+#define DB_IOC_MASK            0x1F
+
+/* Ioctl module masks */
+#define DB_MGR         0x0
+#define DB_PROC                0x20
+#define DB_NODE                0x40
+#define DB_STRM                0x60
+#define DB_CMM         0x80
+
+#define DB_MODULE_SHIFT                5
+
+/* Used to calculate the ioctl per dspbridge module */
+#define DB_IOC(module, num) \
+                       (((module) & DB_MODULE_MASK) | ((num) & DB_IOC_MASK))
+/* Used to get dspbridge ioctl module */
+#define DB_GET_MODULE(cmd)     ((cmd) & DB_MODULE_MASK)
+/* Used to get dspbridge ioctl number */
+#define DB_GET_IOC(cmd)                ((cmd) & DB_IOC_MASK)
+
+/* TODO: Remove deprecated and not implemented */
+
+/* MGR Module */
+#define MGR_ENUMNODE_INFO      _IOWR(DB, DB_IOC(DB_MGR, 0), unsigned long)
+#define MGR_ENUMPROC_INFO      _IOWR(DB, DB_IOC(DB_MGR, 1), unsigned long)
+#define MGR_REGISTEROBJECT     _IOWR(DB, DB_IOC(DB_MGR, 2), unsigned long)
+#define MGR_UNREGISTEROBJECT   _IOWR(DB, DB_IOC(DB_MGR, 3), unsigned long)
+#define MGR_WAIT               _IOWR(DB, DB_IOC(DB_MGR, 4), unsigned long)
+/* MGR_GET_PROC_RES Deprecated */
+#define MGR_GET_PROC_RES       _IOR(DB, DB_IOC(DB_MGR, 5), unsigned long)
+
+/* PROC Module */
+#define PROC_ATTACH            _IOWR(DB, DB_IOC(DB_PROC, 0), unsigned long)
+#define PROC_CTRL              _IOR(DB, DB_IOC(DB_PROC, 1), unsigned long)
+/* PROC_DETACH Deprecated */
+#define PROC_DETACH            _IOR(DB, DB_IOC(DB_PROC, 2), unsigned long)
+#define PROC_ENUMNODE          _IOWR(DB, DB_IOC(DB_PROC, 3), unsigned long)
+#define PROC_ENUMRESOURCES     _IOWR(DB, DB_IOC(DB_PROC, 4), unsigned long)
+#define PROC_GET_STATE         _IOWR(DB, DB_IOC(DB_PROC, 5), unsigned long)
+#define PROC_GET_TRACE         _IOWR(DB, DB_IOC(DB_PROC, 6), unsigned long)
+#define PROC_LOAD              _IOW(DB, DB_IOC(DB_PROC, 7), unsigned long)
+#define PROC_REGISTERNOTIFY    _IOWR(DB, DB_IOC(DB_PROC, 8), unsigned long)
+#define PROC_START             _IOW(DB, DB_IOC(DB_PROC, 9), unsigned long)
+#define PROC_RSVMEM            _IOWR(DB, DB_IOC(DB_PROC, 10), unsigned long)
+#define PROC_UNRSVMEM          _IOW(DB, DB_IOC(DB_PROC, 11), unsigned long)
+#define PROC_MAPMEM            _IOWR(DB, DB_IOC(DB_PROC, 12), unsigned long)
+#define PROC_UNMAPMEM          _IOR(DB, DB_IOC(DB_PROC, 13), unsigned long)
+#define PROC_FLUSHMEMORY       _IOW(DB, DB_IOC(DB_PROC, 14), unsigned long)
+#define PROC_STOP              _IOWR(DB, DB_IOC(DB_PROC, 15), unsigned long)
+#define PROC_INVALIDATEMEMORY  _IOW(DB, DB_IOC(DB_PROC, 16), unsigned long)
+#define PROC_BEGINDMA          _IOW(DB, DB_IOC(DB_PROC, 17), unsigned long)
+#define PROC_ENDDMA            _IOW(DB, DB_IOC(DB_PROC, 18), unsigned long)
+
+/* NODE Module */
+#define NODE_ALLOCATE          _IOWR(DB, DB_IOC(DB_NODE, 0), unsigned long)
+#define NODE_ALLOCMSGBUF       _IOWR(DB, DB_IOC(DB_NODE, 1), unsigned long)
+#define NODE_CHANGEPRIORITY    _IOW(DB, DB_IOC(DB_NODE, 2), unsigned long)
+#define NODE_CONNECT           _IOW(DB, DB_IOC(DB_NODE, 3), unsigned long)
+#define NODE_CREATE            _IOW(DB, DB_IOC(DB_NODE, 4), unsigned long)
+#define NODE_DELETE            _IOW(DB, DB_IOC(DB_NODE, 5), unsigned long)
+#define NODE_FREEMSGBUF                _IOW(DB, DB_IOC(DB_NODE, 6), unsigned long)
+#define NODE_GETATTR           _IOWR(DB, DB_IOC(DB_NODE, 7), unsigned long)
+#define NODE_GETMESSAGE                _IOWR(DB, DB_IOC(DB_NODE, 8), unsigned long)
+#define NODE_PAUSE             _IOW(DB, DB_IOC(DB_NODE, 9), unsigned long)
+#define NODE_PUTMESSAGE                _IOW(DB, DB_IOC(DB_NODE, 10), unsigned long)
+#define NODE_REGISTERNOTIFY    _IOWR(DB, DB_IOC(DB_NODE, 11), unsigned long)
+#define NODE_RUN               _IOW(DB, DB_IOC(DB_NODE, 12), unsigned long)
+#define NODE_TERMINATE         _IOWR(DB, DB_IOC(DB_NODE, 13), unsigned long)
+#define NODE_GETUUIDPROPS      _IOWR(DB, DB_IOC(DB_NODE, 14), unsigned long)
+
+/* STRM Module */
+#define STRM_ALLOCATEBUFFER    _IOWR(DB, DB_IOC(DB_STRM, 0), unsigned long)
+#define STRM_CLOSE             _IOW(DB, DB_IOC(DB_STRM, 1), unsigned long)
+#define STRM_FREEBUFFER                _IOWR(DB, DB_IOC(DB_STRM, 2), unsigned long)
+#define STRM_GETEVENTHANDLE    _IO(DB, DB_IOC(DB_STRM, 3))     /* Not Impl'd */
+#define STRM_GETINFO           _IOWR(DB, DB_IOC(DB_STRM, 4), unsigned long)
+#define STRM_IDLE              _IOW(DB, DB_IOC(DB_STRM, 5), unsigned long)
+#define STRM_ISSUE             _IOW(DB, DB_IOC(DB_STRM, 6), unsigned long)
+#define STRM_OPEN              _IOWR(DB, DB_IOC(DB_STRM, 7), unsigned long)
+#define STRM_RECLAIM           _IOWR(DB, DB_IOC(DB_STRM, 8), unsigned long)
+#define STRM_REGISTERNOTIFY    _IOWR(DB, DB_IOC(DB_STRM, 9), unsigned long)
+#define STRM_SELECT            _IOWR(DB, DB_IOC(DB_STRM, 10), unsigned long)
+
+/* CMM Module */
+#define CMM_ALLOCBUF           _IO(DB, DB_IOC(DB_CMM, 0))      /* Not Impl'd */
+#define CMM_FREEBUF            _IO(DB, DB_IOC(DB_CMM, 1))      /* Not Impl'd */
+#define CMM_GETHANDLE          _IOR(DB, DB_IOC(DB_CMM, 2), unsigned long)
+#define CMM_GETINFO            _IOR(DB, DB_IOC(DB_CMM, 3), unsigned long)
+
+#endif /* DSPAPIIOCTL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi.h
new file mode 100644 (file)
index 0000000..c99c687
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * dspapi.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Includes the wrapper functions called directly by the
+ * DeviceIOControl interface.
+ *
+ * Notes:
+ *   Bridge services exported to Bridge driver are initialized by the DSPAPI on
+ *   behalf of the Bridge driver. Bridge driver must not call module Init/Exit
+ *   functions.
+ *
+ *   To ensure Bridge driver binary compatibility across different platforms,
+ *   for the same processor, a Bridge driver must restrict its usage of system
+ *   services to those exported by the DSPAPI library.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPAPI_
+#define DSPAPI_
+
+#include <dspbridge/dspapi-ioctl.h>
+
+/* This BRD API Library Version: */
+#define BRD_API_MAJOR_VERSION   (u32)8 /* .8x - Alpha, .9x - Beta, 1.x FCS */
+#define BRD_API_MINOR_VERSION   (u32)0
+
+/*
+ *  ======== api_call_dev_ioctl ========
+ *  Purpose:
+ *      Call the (wrapper) function for the corresponding API IOCTL.
+ *  Parameters:
+ *      cmd:        IOCTL id, base 0.
+ *      args:       Argument structure.
+ *      result:
+ *  Returns:
+ *      0 if command called; -EINVAL if command not in IOCTL
+ *      table.
+ *  Requires:
+ *  Ensures:
+ */
+extern int api_call_dev_ioctl(unsigned int cmd,
+                                     union trapped_args *args,
+                                     u32 *result, void *pr_ctxt);
+
+/*
+ *  ======== api_init ========
+ *  Purpose:
+ *      Initialize modules used by Bridge API.
+ *      This procedure is called when the driver is loaded.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if success; FALSE otherwise.
+ *  Requires:
+ *  Ensures:
+ */
+extern bool api_init(void);
+
+/*
+ *  ======== api_init_complete2 ========
+ *  Purpose:
+ *      Perform any required bridge initialization which cannot
+ *      be performed in api_init() or dev_start_device() due
+ *      to the fact that some services are not yet
+ *      completely initialized.
+ *  Parameters:
+ *  Returns:
+ *      0:        Allow this device to load
+ *      -EPERM:      Failure.
+ *  Requires:
+ *      Bridge API initialized.
+ *  Ensures:
+ */
+extern int api_init_complete2(void);
+
+/*
+ *  ======== api_exit ========
+ *  Purpose:
+ *      Exit all modules initialized in api_init(void).
+ *      This procedure is called when the driver is unloaded.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      api_init(void) was previously called.
+ *  Ensures:
+ *      Resources acquired in api_init(void) are freed.
+ */
+extern void api_exit(void);
+
+/* MGR wrapper functions */
+extern u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt);
+extern u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt);
+extern u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt);
+extern u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt);
+extern u32 mgrwrap_wait_for_bridge_events(union trapped_args *args,
+                                         void *pr_ctxt);
+
+extern u32 mgrwrap_get_process_resources_info(union trapped_args *args,
+                                             void *pr_ctxt);
+
+/* CPRC (Processor) wrapper Functions */
+extern u32 procwrap_attach(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_detach(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_load(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_start(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_map(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_stop(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt);
+extern u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt);
+
+/* NODE wrapper functions */
+extern u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_create(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_run(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt);
+extern u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt);
+
+/* STRM wrapper functions */
+extern u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_close(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_get_event_handle(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_open(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt);
+extern u32 strmwrap_select(union trapped_args *args, void *pr_ctxt);
+
+extern u32 cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt);
+extern u32 cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt);
+extern u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt);
+extern u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt);
+
+#endif /* DSPAPI_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h b/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h
new file mode 100644 (file)
index 0000000..7146a50
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * dspchnl.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Declares the upper edge channel class library functions required by
+ * all Bridge driver / DSP API driver interface tables. These functions are
+ * implemented by every class of Bridge channel library.
+ *
+ * Notes:
+ *   The function comment headers reside in dspdefs.h.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPCHNL_
+#define DSPCHNL_
+
+extern int bridge_chnl_create(struct chnl_mgr **channel_mgr,
+                                    struct dev_object *hdev_obj,
+                                    const struct chnl_mgrattrs
+                                    *mgr_attrts);
+
+extern int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr);
+
+extern int bridge_chnl_open(struct chnl_object **chnl,
+                                  struct chnl_mgr *hchnl_mgr,
+                                  s8 chnl_mode,
+                                  u32 ch_id,
+                                  const struct chnl_attr
+                                  *pattrs);
+
+extern int bridge_chnl_close(struct chnl_object *chnl_obj);
+
+extern int bridge_chnl_add_io_req(struct chnl_object *chnl_obj,
+                                     void *host_buf,
+                                     u32 byte_size, u32 buf_size,
+                                     u32 dw_dsp_addr, u32 dw_arg);
+
+extern int bridge_chnl_get_ioc(struct chnl_object *chnl_obj,
+                                  u32 timeout, struct chnl_ioc *chan_ioc);
+
+extern int bridge_chnl_cancel_io(struct chnl_object *chnl_obj);
+
+extern int bridge_chnl_flush_io(struct chnl_object *chnl_obj,
+                                   u32 timeout);
+
+extern int bridge_chnl_get_info(struct chnl_object *chnl_obj,
+                                   struct chnl_info *channel_info);
+
+extern int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr,
+                                       u32 ch_id, struct chnl_mgrinfo
+                                       *mgr_info);
+
+extern int bridge_chnl_idle(struct chnl_object *chnl_obj,
+                                  u32 timeout, bool flush_data);
+
+extern int bridge_chnl_register_notify(struct chnl_object *chnl_obj,
+                                          u32 event_mask,
+                                          u32 notify_type,
+                                          struct dsp_notification
+                                          *hnotification);
+
+#endif /* DSPCHNL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
new file mode 100644 (file)
index 0000000..0ae7d16
--- /dev/null
@@ -0,0 +1,1054 @@
+/*
+ * dspdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Bridge driver entry point and interface function declarations.
+ *
+ * Notes:
+ *   The DSP API obtains it's function interface to
+ *   the Bridge driver via a call to bridge_drv_entry().
+ *
+ *   Bridge services exported to Bridge drivers are initialized by the
+ *   DSP API on behalf of the Bridge driver.
+ *
+ *   Bridge function DBC Requires and Ensures are also made by the DSP API on
+ *   behalf of the Bridge driver, to simplify the Bridge driver code.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPDEFS_
+#define DSPDEFS_
+
+#include <dspbridge/brddefs.h>
+#include <dspbridge/cfgdefs.h>
+#include <dspbridge/chnlpriv.h>
+#include <dspbridge/dehdefs.h>
+#include <dspbridge/devdefs.h>
+#include <dspbridge/iodefs.h>
+#include <dspbridge/msgdefs.h>
+
+/*
+ *  Any IOCTLS at or above this value are reserved for standard Bridge driver
+ *  interfaces.
+ */
+#define BRD_RESERVEDIOCTLBASE   0x8000
+
+/* Handle to Bridge driver's private device context. */
+struct bridge_dev_context;
+
+/*--------------------------------------------------------------------------- */
+/* BRIDGE DRIVER FUNCTION TYPES */
+/*--------------------------------------------------------------------------- */
+
+/*
+ *  ======== bridge_brd_monitor ========
+ *  Purpose:
+ *      Bring the board to the BRD_IDLE (monitor) state.
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device context.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIMEDOUT:  Timeout occured waiting for a response from hardware.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL
+ *  Ensures:
+ *      0:        Board is in BRD_IDLE state;
+ *      else:           Board state is indeterminate.
+ */
+typedef int(*fxn_brd_monitor) (struct bridge_dev_context *dev_ctxt);
+
+/*
+ *  ======== fxn_brd_setstate ========
+ *  Purpose:
+ *      Sets the Bridge driver state
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      brd_state:      Board state
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *      brd_state  <= BRD_LASTSTATE.
+ *  Ensures:
+ *      brd_state  <= BRD_LASTSTATE.
+ *  Update the Board state to the specified state.
+ */
+typedef int(*fxn_brd_setstate) (struct bridge_dev_context
+                                      * dev_ctxt, u32 brd_state);
+
+/*
+ *  ======== bridge_brd_start ========
+ *  Purpose:
+ *      Bring board to the BRD_RUNNING (start) state.
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device context.
+ *      dsp_addr:       DSP address at which to start execution.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIMEDOUT:  Timeout occured waiting for a response from hardware.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL
+ *      Board is in monitor (BRD_IDLE) state.
+ *  Ensures:
+ *      0:        Board is in BRD_RUNNING state.
+ *                      Interrupts to the PC are enabled.
+ *      else:           Board state is indeterminate.
+ */
+typedef int(*fxn_brd_start) (struct bridge_dev_context
+                                   * dev_ctxt, u32 dsp_addr);
+
+/*
+ *  ======== bridge_brd_mem_copy ========
+ *  Purpose:
+ *  Copy memory from one DSP address to another
+ *  Parameters:
+ *      dev_context:    Pointer to context handle
+ *  dsp_dest_addr:  DSP address to copy to
+ *  dsp_src_addr:   DSP address to copy from
+ *  ul_num_bytes: Number of bytes to copy
+ *  mem_type:   What section of memory to copy to
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_context != NULL
+ *  Ensures:
+ *      0:        Board is in BRD_RUNNING state.
+ *                      Interrupts to the PC are enabled.
+ *      else:           Board state is indeterminate.
+ */
+typedef int(*fxn_brd_memcopy) (struct bridge_dev_context
+                                     * dev_ctxt,
+                                     u32 dsp_dest_addr,
+                                     u32 dsp_src_addr,
+                                     u32 ul_num_bytes, u32 mem_type);
+/*
+ *  ======== bridge_brd_mem_write ========
+ *  Purpose:
+ *      Write a block of host memory into a DSP address, into a given memory
+ *      space.  Unlike bridge_brd_write, this API does reset the DSP
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      dsp_addr:       Address on DSP board (Destination).
+ *      host_buf:       Pointer to host buffer (Source).
+ *      ul_num_bytes:     Number of bytes to transfer.
+ *      mem_type:       Memory space on DSP to which to transfer.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIMEDOUT:  Timeout occured waiting for a response from hardware.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *      host_buf != NULL.
+ *  Ensures:
+ */
+typedef int(*fxn_brd_memwrite) (struct bridge_dev_context
+                                      * dev_ctxt,
+                                      u8 *host_buf,
+                                      u32 dsp_addr, u32 ul_num_bytes,
+                                      u32 mem_type);
+
+/*
+ *  ======== bridge_brd_mem_map ========
+ *  Purpose:
+ *      Map a MPU memory region to a DSP/IVA memory space
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      ul_mpu_addr:      MPU memory region start address.
+ *      virt_addr:      DSP/IVA memory region u8 address.
+ *      ul_num_bytes:     Number of bytes to map.
+ *      map_attrs:       Mapping attributes (e.g. endianness).
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *  Ensures:
+ */
+typedef int(*fxn_brd_memmap) (struct bridge_dev_context
+                                    * dev_ctxt, u32 ul_mpu_addr,
+                                    u32 virt_addr, u32 ul_num_bytes,
+                                    u32 map_attr,
+                                    struct page **mapped_pages);
+
+/*
+ *  ======== bridge_brd_mem_un_map ========
+ *  Purpose:
+ *      UnMap an MPU memory region from DSP/IVA memory space
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      virt_addr:      DSP/IVA memory region u8 address.
+ *      ul_num_bytes:     Number of bytes to unmap.
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *  Ensures:
+ */
+typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
+                                      * dev_ctxt,
+                                      u32 virt_addr, u32 ul_num_bytes);
+
+/*
+ *  ======== bridge_brd_stop ========
+ *  Purpose:
+ *      Bring board to the BRD_STOPPED state.
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device context.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIMEDOUT:  Timeout occured waiting for a response from hardware.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL
+ *  Ensures:
+ *      0:        Board is in BRD_STOPPED (stop) state;
+ *                      Interrupts to the PC are disabled.
+ *      else:           Board state is indeterminate.
+ */
+typedef int(*fxn_brd_stop) (struct bridge_dev_context *dev_ctxt);
+
+/*
+ *  ======== bridge_brd_status ========
+ *  Purpose:
+ *      Report the current state of the board.
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device context.
+ *      board_state:    Ptr to BRD status variable.
+ *  Returns:
+ *      0:
+ *  Requires:
+ *      board_state != NULL;
+ *      dev_ctxt != NULL
+ *  Ensures:
+ *      *board_state is one of
+ *       {BRD_STOPPED, BRD_IDLE, BRD_RUNNING, BRD_UNKNOWN};
+ */
+typedef int(*fxn_brd_status) (struct bridge_dev_context *dev_ctxt,
+                                    int *board_state);
+
+/*
+ *  ======== bridge_brd_read ========
+ *  Purpose:
+ *      Read a block of DSP memory, from a given memory space, into a host
+ *      buffer.
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      host_buf:       Pointer to host buffer (Destination).
+ *      dsp_addr:       Address on DSP board (Source).
+ *      ul_num_bytes:     Number of bytes to transfer.
+ *      mem_type:       Memory space on DSP from which to transfer.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIMEDOUT:  Timeout occured waiting for a response from hardware.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *      host_buf != NULL.
+ *  Ensures:
+ *  Will not write more than ul_num_bytes bytes into host_buf.
+ */
+typedef int(*fxn_brd_read) (struct bridge_dev_context *dev_ctxt,
+                                  u8 *host_buf,
+                                  u32 dsp_addr,
+                                  u32 ul_num_bytes, u32 mem_type);
+
+/*
+ *  ======== bridge_brd_write ========
+ *  Purpose:
+ *      Write a block of host memory into a DSP address, into a given memory
+ *      space.
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      dsp_addr:       Address on DSP board (Destination).
+ *      host_buf:       Pointer to host buffer (Source).
+ *      ul_num_bytes:     Number of bytes to transfer.
+ *      mem_type:       Memory space on DSP to which to transfer.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIMEDOUT:  Timeout occured waiting for a response from hardware.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *      host_buf != NULL.
+ *  Ensures:
+ */
+typedef int(*fxn_brd_write) (struct bridge_dev_context *dev_ctxt,
+                                   u8 *host_buf,
+                                   u32 dsp_addr,
+                                   u32 ul_num_bytes, u32 mem_type);
+
+/*
+ *  ======== bridge_chnl_create ========
+ *  Purpose:
+ *      Create a channel manager object, responsible for opening new channels
+ *      and closing old ones for a given 'Bridge board.
+ *  Parameters:
+ *      channel_mgr:    Location to store a channel manager object on output.
+ *      hdev_obj:     Handle to a device object.
+ *      mgr_attrts:      Channel manager attributes.
+ *      mgr_attrts->max_channels: Max channels
+ *      mgr_attrts->birq:      Channel's I/O IRQ number.
+ *      mgr_attrts->irq_shared:   TRUE if the IRQ is shareable.
+ *      mgr_attrts->word_size: DSP Word size in equivalent PC bytes..
+ *      mgr_attrts->shm_base:  Base physical address of shared memory, if any.
+ *      mgr_attrts->usm_length: Bytes of shared memory block.
+ *  Returns:
+ *      0:            Success;
+ *      -ENOMEM:        Insufficient memory for requested resources.
+ *      -EIO:         Unable to plug ISR for given IRQ.
+ *      -EFAULT:    Couldn't map physical address to a virtual one.
+ *  Requires:
+ *      channel_mgr != NULL.
+ *      mgr_attrts != NULL
+ *      mgr_attrts field are all valid:
+ *          0 < max_channels <= CHNL_MAXCHANNELS.
+ *          birq <= 15.
+ *          word_size > 0.
+ *      hdev_obj != NULL
+ *      No channel manager exists for this board.
+ *  Ensures:
+ */
+typedef int(*fxn_chnl_create) (struct chnl_mgr
+                                     **channel_mgr,
+                                     struct dev_object
+                                     * hdev_obj,
+                                     const struct
+                                     chnl_mgrattrs * mgr_attrts);
+
+/*
+ *  ======== bridge_chnl_destroy ========
+ *  Purpose:
+ *      Close all open channels, and destroy the channel manager.
+ *  Parameters:
+ *      hchnl_mgr:       Channel manager object.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    hchnl_mgr was invalid.
+ *  Requires:
+ *  Ensures:
+ *      0: Cancels I/O on each open channel. Closes each open channel.
+ *          chnl_create may subsequently be called for the same device.
+ */
+typedef int(*fxn_chnl_destroy) (struct chnl_mgr *hchnl_mgr);
+/*
+ *  ======== bridge_deh_notify ========
+ *  Purpose:
+ *      When notified of DSP error, take appropriate action.
+ *  Parameters:
+ *      hdeh_mgr:        Handle to DEH manager object.
+ *      evnt_mask:    Indicate the type of exception
+ *      error_info:    Error information
+ *  Returns:
+ *
+ *  Requires:
+ *      hdeh_mgr != NULL;
+ *     evnt_mask with a valid exception
+ *  Ensures:
+ */
+typedef void (*fxn_deh_notify) (struct deh_mgr *hdeh_mgr,
+                               u32 evnt_mask, u32 error_info);
+
+/*
+ *  ======== bridge_chnl_open ========
+ *  Purpose:
+ *      Open a new half-duplex channel to the DSP board.
+ *  Parameters:
+ *      chnl:           Location to store a channel object handle.
+ *      hchnl_mgr:     Handle to channel manager, as returned by
+ *                     CHNL_GetMgr().
+ *      chnl_mode:          One of {CHNL_MODETODSP, CHNL_MODEFROMDSP} specifies
+ *                      direction of data transfer.
+ *      ch_id:        If CHNL_PICKFREE is specified, the channel manager will
+ *                      select a free channel id (default);
+ *                      otherwise this field specifies the id of the channel.
+ *      pattrs:         Channel attributes.  Attribute fields are as follows:
+ *      pattrs->uio_reqs: Specifies the maximum number of I/O requests which can
+ *                      be pending at any given time. All request packets are
+ *                      preallocated when the channel is opened.
+ *      pattrs->event_obj: This field allows the user to supply an auto reset
+ *                      event object for channel I/O completion notifications.
+ *                      It is the responsibility of the user to destroy this
+ *                      object AFTER closing the channel.
+ *                      This channel event object can be retrieved using
+ *                      CHNL_GetEventHandle().
+ *      pattrs->hReserved: The kernel mode handle of this event object.
+ *
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT:            hchnl_mgr is invalid.
+ *      -ENOMEM:            Insufficient memory for requested resources.
+ *      -EINVAL:        Invalid number of IOReqs.
+ *      -ENOSR:    No free channels available.
+ *      -ECHRNG:       Channel ID is out of range.
+ *      -EALREADY:        Channel is in use.
+ *      -EIO:         No free IO request packets available for
+ *                              queuing.
+ *  Requires:
+ *      chnl != NULL.
+ *      pattrs != NULL.
+ *      pattrs->event_obj is a valid event handle.
+ *      pattrs->hReserved is the kernel mode handle for pattrs->event_obj.
+ *  Ensures:
+ *      0:                *chnl is a valid channel.
+ *      else:                   *chnl is set to NULL if (chnl != NULL);
+ */
+typedef int(*fxn_chnl_open) (struct chnl_object
+                                   **chnl,
+                                   struct chnl_mgr *hchnl_mgr,
+                                   s8 chnl_mode,
+                                   u32 ch_id,
+                                   const struct
+                                   chnl_attr * pattrs);
+
+/*
+ *  ======== bridge_chnl_close ========
+ *  Purpose:
+ *      Ensures all pending I/O on this channel is cancelled, discards all
+ *      queued I/O completion notifications, then frees the resources allocated
+ *      for this channel, and makes the corresponding logical channel id
+ *      available for subsequent use.
+ *  Parameters:
+ *      chnl_obj:          Handle to a channel object.
+ *  Returns:
+ *      0:        Success;
+ *      -EFAULT:    Invalid chnl_obj.
+ *  Requires:
+ *      No thread must be blocked on this channel's I/O completion event.
+ *  Ensures:
+ *      0:        chnl_obj is no longer valid.
+ */
+typedef int(*fxn_chnl_close) (struct chnl_object *chnl_obj);
+
+/*
+ *  ======== bridge_chnl_add_io_req ========
+ *  Purpose:
+ *      Enqueue an I/O request for data transfer on a channel to the DSP.
+ *      The direction (mode) is specified in the channel object. Note the DSP
+ *      address is specified for channels opened in direct I/O mode.
+ *  Parameters:
+ *      chnl_obj:          Channel object handle.
+ *      host_buf:       Host buffer address source.
+ *      byte_size:     Number of PC bytes to transfer. A zero value indicates
+ *                      that this buffer is the last in the output channel.
+ *                      A zero value is invalid for an input channel.
+ *!     buf_size:       Actual buffer size in host bytes.
+ *      dw_dsp_addr:      DSP address for transfer.  (Currently ignored).
+ *      dw_arg:          A user argument that travels with the buffer.
+ *  Returns:
+ *      0:        Success;
+ *      -EFAULT: Invalid chnl_obj or host_buf.
+ *      -EPERM:   User cannot mark EOS on an input channel.
+ *      -ECANCELED: I/O has been cancelled on this channel.  No further
+ *                      I/O is allowed.
+ *      -EPIPE:     End of stream was already marked on a previous
+ *                      IORequest on this channel.  No further I/O is expected.
+ *      -EINVAL: Buffer submitted to this output channel is larger than
+ *                      the size of the physical shared memory output window.
+ *  Requires:
+ *  Ensures:
+ *      0: The buffer will be transferred if the channel is ready;
+ *          otherwise, will be queued for transfer when the channel becomes
+ *          ready.  In any case, notifications of I/O completion are
+ *          asynchronous.
+ *          If byte_size is 0 for an output channel, subsequent CHNL_AddIOReq's
+ *          on this channel will fail with error code -EPIPE.  The
+ *          corresponding IOC for this I/O request will have its status flag
+ *          set to CHNL_IOCSTATEOS.
+ */
+typedef int(*fxn_chnl_addioreq) (struct chnl_object
+                                       * chnl_obj,
+                                       void *host_buf,
+                                       u32 byte_size,
+                                       u32 buf_size,
+                                       u32 dw_dsp_addr, u32 dw_arg);
+
+/*
+ *  ======== bridge_chnl_get_ioc ========
+ *  Purpose:
+ *      Dequeue an I/O completion record, which contains information about the
+ *      completed I/O request.
+ *  Parameters:
+ *      chnl_obj:          Channel object handle.
+ *      timeout:        A value of CHNL_IOCNOWAIT will simply dequeue the
+ *                      first available IOC.
+ *      chan_ioc:       On output, contains host buffer address, bytes
+ *                      transferred, and status of I/O completion.
+ *      chan_ioc->status:   See chnldefs.h.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT: Invalid chnl_obj or chan_ioc.
+ *      -EREMOTEIO:   CHNL_IOCNOWAIT was specified as the timeout parameter
+ *                      yet no I/O completions were queued.
+ *  Requires:
+ *      timeout == CHNL_IOCNOWAIT.
+ *  Ensures:
+ *      0: if there are any remaining IOC's queued before this call
+ *          returns, the channel event object will be left in a signalled
+ *          state.
+ */
+typedef int(*fxn_chnl_getioc) (struct chnl_object *chnl_obj,
+                                     u32 timeout,
+                                     struct chnl_ioc *chan_ioc);
+
+/*
+ *  ======== bridge_chnl_cancel_io ========
+ *  Purpose:
+ *      Return all I/O requests to the client which have not yet been
+ *      transferred.  The channel's I/O completion object is
+ *      signalled, and all the I/O requests are queued as IOC's, with the
+ *      status field set to CHNL_IOCSTATCANCEL.
+ *      This call is typically used in abort situations, and is a prelude to
+ *      chnl_close();
+ *  Parameters:
+ *      chnl_obj:          Channel object handle.
+ *  Returns:
+ *      0:        Success;
+ *      -EFAULT:    Invalid chnl_obj.
+ *  Requires:
+ *  Ensures:
+ *      Subsequent I/O requests to this channel will not be accepted.
+ */
+typedef int(*fxn_chnl_cancelio) (struct chnl_object *chnl_obj);
+
+/*
+ *  ======== bridge_chnl_flush_io ========
+ *  Purpose:
+ *      For an output stream (to the DSP), indicates if any IO requests are in
+ *      the output request queue.  For input streams (from the DSP), will
+ *      cancel all pending IO requests.
+ *  Parameters:
+ *      chnl_obj:              Channel object handle.
+ *      timeout:            Timeout value for flush operation.
+ *  Returns:
+ *      0:            Success;
+ *      S_CHNLIOREQUEST:    Returned if any IORequests are in the output queue.
+ *      -EFAULT:        Invalid chnl_obj.
+ *  Requires:
+ *  Ensures:
+ *      0:            No I/O requests will be pending on this channel.
+ */
+typedef int(*fxn_chnl_flushio) (struct chnl_object *chnl_obj,
+                                      u32 timeout);
+
+/*
+ *  ======== bridge_chnl_get_info ========
+ *  Purpose:
+ *      Retrieve information related to a channel.
+ *  Parameters:
+ *      chnl_obj:          Handle to a valid channel object, or NULL.
+ *      channel_info:   Location to store channel info.
+ *  Returns:
+ *      0:        Success;
+ *      -EFAULT: Invalid chnl_obj or channel_info.
+ *  Requires:
+ *  Ensures:
+ *      0:        channel_info points to a filled in chnl_info struct,
+ *                      if (channel_info != NULL).
+ */
+typedef int(*fxn_chnl_getinfo) (struct chnl_object *chnl_obj,
+                                      struct chnl_info *channel_info);
+
+/*
+ *  ======== bridge_chnl_get_mgr_info ========
+ *  Purpose:
+ *      Retrieve information related to the channel manager.
+ *  Parameters:
+ *      hchnl_mgr:           Handle to a valid channel manager, or NULL.
+ *      ch_id:            Channel ID.
+ *      mgr_info:           Location to store channel manager info.
+ *  Returns:
+ *      0:            Success;
+ *      -EFAULT: Invalid hchnl_mgr or mgr_info.
+ *      -ECHRNG:   Invalid channel ID.
+ *  Requires:
+ *  Ensures:
+ *      0:            mgr_info points to a filled in chnl_mgrinfo
+ *                          struct, if (mgr_info != NULL).
+ */
+typedef int(*fxn_chnl_getmgrinfo) (struct chnl_mgr
+                                         * hchnl_mgr,
+                                         u32 ch_id,
+                                         struct chnl_mgrinfo *mgr_info);
+
+/*
+ *  ======== bridge_chnl_idle ========
+ *  Purpose:
+ *      Idle a channel. If this is an input channel, or if this is an output
+ *      channel and flush_data is TRUE, all currently enqueued buffers will be
+ *      dequeued (data discarded for output channel).
+ *      If this is an output channel and flush_data is FALSE, this function
+ *      will block until all currently buffered data is output, or the timeout
+ *      specified has been reached.
+ *
+ *  Parameters:
+ *      chnl_obj:          Channel object handle.
+ *      timeout:        If output channel and flush_data is FALSE, timeout value
+ *                      to wait for buffers to be output. (Not used for
+ *                      input channel).
+ *      flush_data:     If output channel and flush_data is TRUE, discard any
+ *                      currently buffered data. If FALSE, wait for currently
+ *                      buffered data to be output, or timeout, whichever
+ *                      occurs first. flush_data is ignored for input channel.
+ *  Returns:
+ *      0:            Success;
+ *      -EFAULT:        Invalid chnl_obj.
+ *      -ETIMEDOUT: Timeout occured before channel could be idled.
+ *  Requires:
+ *  Ensures:
+ */
+typedef int(*fxn_chnl_idle) (struct chnl_object *chnl_obj,
+                                   u32 timeout, bool flush_data);
+
+/*
+ *  ======== bridge_chnl_register_notify ========
+ *  Purpose:
+ *      Register for notification of events on a channel.
+ *  Parameters:
+ *      chnl_obj:          Channel object handle.
+ *      event_mask:     Type of events to be notified about: IO completion
+ *                      (DSP_STREAMIOCOMPLETION) or end of stream
+ *                      (DSP_STREAMDONE).
+ *      notify_type:    DSP_SIGNALEVENT.
+ *      hnotification:  Handle of a dsp_notification object.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Insufficient memory.
+ *      -EINVAL:     event_mask is 0 and hnotification was not
+ *                      previously registered.
+ *      -EFAULT:    NULL hnotification, hnotification event name
+ *                      too long, or hnotification event name NULL.
+ *  Requires:
+ *      Valid chnl_obj.
+ *      hnotification != NULL.
+ *      (event_mask & ~(DSP_STREAMIOCOMPLETION | DSP_STREAMDONE)) == 0.
+ *      notify_type == DSP_SIGNALEVENT.
+ *  Ensures:
+ */
+typedef int(*fxn_chnl_registernotify)
+ (struct chnl_object *chnl_obj,
+  u32 event_mask, u32 notify_type, struct dsp_notification *hnotification);
+
+/*
+ *  ======== bridge_dev_create ========
+ *  Purpose:
+ *      Complete creation of the device object for this board.
+ *  Parameters:
+ *      device_ctx:     Ptr to location to store a Bridge device context.
+ *      hdev_obj:     Handle to a Device Object, created and managed by DSP API.
+ *      config_param:        Ptr to configuration parameters provided by the
+ *                      Configuration Manager during device loading.
+ *      pDspConfig:     DSP resources, as specified in the registry key for this
+ *                      device.
+ *  Returns:
+ *      0:            Success.
+ *      -ENOMEM:        Unable to allocate memory for device context.
+ *  Requires:
+ *      device_ctx != NULL;
+ *      hdev_obj != NULL;
+ *      config_param != NULL;
+ *      pDspConfig != NULL;
+ *      Fields in config_param and pDspConfig contain valid values.
+ *  Ensures:
+ *      0:        All Bridge driver specific DSP resource and other
+ *                      board context has been allocated.
+ *      -ENOMEM:    Bridge failed to allocate resources.
+ *                      Any acquired resources have been freed.  The DSP API
+ *                      will not call bridge_dev_destroy() if
+ *                      bridge_dev_create() fails.
+ *  Details:
+ *      Called during the CONFIGMG's Device_Init phase. Based on host and
+ *      DSP configuration information, create a board context, a handle to
+ *      which is passed into other Bridge BRD and CHNL functions.  The
+ *      board context contains state information for the device. Since the
+ *      addresses of all pointer parameters may be invalid when this
+ *      function returns, they must not be stored into the device context
+ *      structure.
+ */
+typedef int(*fxn_dev_create) (struct bridge_dev_context
+                                    **device_ctx,
+                                    struct dev_object
+                                    * hdev_obj,
+                                    struct cfg_hostres
+                                    * config_param);
+
+/*
+ *  ======== bridge_dev_ctrl ========
+ *  Purpose:
+ *      Bridge driver specific interface.
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      dw_cmd:          Bridge driver defined command code.
+ *      pargs:          Pointer to an arbitrary argument structure.
+ *  Returns:
+ *      0 or -EPERM. Actual command error codes should be passed back in
+ *      the pargs structure, and are defined by the Bridge driver implementor.
+ *  Requires:
+ *      All calls are currently assumed to be synchronous.  There are no
+ *      IOCTL completion routines provided.
+ *  Ensures:
+ */
+typedef int(*fxn_dev_ctrl) (struct bridge_dev_context *dev_ctxt,
+                                  u32 dw_cmd, void *pargs);
+
+/*
+ *  ======== bridge_dev_destroy ========
+ *  Purpose:
+ *      Deallocate Bridge device extension structures and all other resources
+ *      acquired by the Bridge driver.
+ *      No calls to other Bridge driver functions may subsequently
+ *      occur, except for bridge_dev_create().
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device information.
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Failed to release a resource previously acquired.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *  Ensures:
+ *      0: Device context is freed.
+ */
+typedef int(*fxn_dev_destroy) (struct bridge_dev_context *dev_ctxt);
+
+/*
+ *  ======== bridge_io_create ========
+ *  Purpose:
+ *      Create an object that manages I/O between CHNL and msg_ctrl.
+ *  Parameters:
+ *      io_man:         Location to store IO manager on output.
+ *      hchnl_mgr:       Handle to channel manager.
+ *      hmsg_mgr:        Handle to message manager.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Memory allocation failure.
+ *      -EPERM:      Creation failed.
+ *  Requires:
+ *      hdev_obj != NULL;
+ *      Channel manager already created;
+ *      Message manager already created;
+ *      mgr_attrts != NULL;
+ *      io_man != NULL;
+ *  Ensures:
+ */
+typedef int(*fxn_io_create) (struct io_mgr **io_man,
+                                   struct dev_object *hdev_obj,
+                                   const struct io_attrs *mgr_attrts);
+
+/*
+ *  ======== bridge_io_destroy ========
+ *  Purpose:
+ *      Destroy object created in bridge_io_create.
+ *  Parameters:
+ *      hio_mgr:         IO Manager.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Memory allocation failure.
+ *      -EPERM:      Creation failed.
+ *  Requires:
+ *      Valid hio_mgr;
+ *  Ensures:
+ */
+typedef int(*fxn_io_destroy) (struct io_mgr *hio_mgr);
+
+/*
+ *  ======== bridge_io_on_loaded ========
+ *  Purpose:
+ *      Called whenever a program is loaded to update internal data. For
+ *      example, if shared memory is used, this function would update the
+ *      shared memory location and address.
+ *  Parameters:
+ *      hio_mgr:     IO Manager.
+ *  Returns:
+ *      0:    Success.
+ *      -EPERM:  Internal failure occurred.
+ *  Requires:
+ *      Valid hio_mgr;
+ *  Ensures:
+ */
+typedef int(*fxn_io_onloaded) (struct io_mgr *hio_mgr);
+
+/*
+ *  ======== fxn_io_getprocload ========
+ *  Purpose:
+ *      Called to get the Processor's current and predicted load
+ *  Parameters:
+ *      hio_mgr:     IO Manager.
+ *      proc_load_stat   Processor Load statistics
+ *  Returns:
+ *      0:    Success.
+ *      -EPERM:  Internal failure occurred.
+ *  Requires:
+ *      Valid hio_mgr;
+ *  Ensures:
+ */
+typedef int(*fxn_io_getprocload) (struct io_mgr *hio_mgr,
+                                        struct dsp_procloadstat *
+                                        proc_load_stat);
+
+/*
+ *  ======== bridge_msg_create ========
+ *  Purpose:
+ *      Create an object to manage message queues. Only one of these objects
+ *      can exist per device object.
+ *  Parameters:
+ *      msg_man:            Location to store msg_ctrl manager on output.
+ *      hdev_obj:         Handle to a device object.
+ *      msg_callback:        Called whenever an RMS_EXIT message is received.
+ *  Returns:
+ *      0:            Success.
+ *      -ENOMEM:        Insufficient memory.
+ *  Requires:
+ *      msg_man != NULL.
+ *      msg_callback != NULL.
+ *      hdev_obj != NULL.
+ *  Ensures:
+ */
+typedef int(*fxn_msg_create)
+ (struct msg_mgr **msg_man,
+  struct dev_object *hdev_obj, msg_onexit msg_callback);
+
+/*
+ *  ======== bridge_msg_create_queue ========
+ *  Purpose:
+ *      Create a msg_ctrl queue for sending or receiving messages from a Message
+ *      node on the DSP.
+ *  Parameters:
+ *      hmsg_mgr:            msg_ctrl queue manager handle returned from
+ *                          bridge_msg_create.
+ *      msgq:               Location to store msg_ctrl queue on output.
+ *      msgq_id:           Identifier for messages (node environment pointer).
+ *      max_msgs:           Max number of simultaneous messages for the node.
+ *      h:                  Handle passed to hmsg_mgr->msg_callback().
+ *  Returns:
+ *      0:            Success.
+ *      -ENOMEM:        Insufficient memory.
+ *  Requires:
+ *      msgq != NULL.
+ *      h != NULL.
+ *      max_msgs > 0.
+ *  Ensures:
+ *      msgq !=NULL <==> 0.
+ */
+typedef int(*fxn_msg_createqueue)
+ (struct msg_mgr *hmsg_mgr,
+  struct msg_queue **msgq, u32 msgq_id, u32 max_msgs, void *h);
+
+/*
+ *  ======== bridge_msg_delete ========
+ *  Purpose:
+ *      Delete a msg_ctrl manager allocated in bridge_msg_create().
+ *  Parameters:
+ *      hmsg_mgr:    Handle returned from bridge_msg_create().
+ *  Returns:
+ *  Requires:
+ *      Valid hmsg_mgr.
+ *  Ensures:
+ */
+typedef void (*fxn_msg_delete) (struct msg_mgr *hmsg_mgr);
+
+/*
+ *  ======== bridge_msg_delete_queue ========
+ *  Purpose:
+ *      Delete a msg_ctrl queue allocated in bridge_msg_create_queue.
+ *  Parameters:
+ *      msg_queue_obj:  Handle to msg_ctrl queue returned from
+ *                  bridge_msg_create_queue.
+ *  Returns:
+ *  Requires:
+ *      Valid msg_queue_obj.
+ *  Ensures:
+ */
+typedef void (*fxn_msg_deletequeue) (struct msg_queue *msg_queue_obj);
+
+/*
+ *  ======== bridge_msg_get ========
+ *  Purpose:
+ *      Get a message from a msg_ctrl queue.
+ *  Parameters:
+ *      msg_queue_obj:     Handle to msg_ctrl queue returned from
+ *                     bridge_msg_create_queue.
+ *      pmsg:          Location to copy message into.
+ *      utimeout:      Timeout to wait for a message.
+ *  Returns:
+ *      0:       Success.
+ *      -ETIME:  Timeout occurred.
+ *      -EPERM:     No frames available for message (max_msgs too
+ *                     small).
+ *  Requires:
+ *      Valid msg_queue_obj.
+ *      pmsg != NULL.
+ *  Ensures:
+ */
+typedef int(*fxn_msg_get) (struct msg_queue *msg_queue_obj,
+                                 struct dsp_msg *pmsg, u32 utimeout);
+
+/*
+ *  ======== bridge_msg_put ========
+ *  Purpose:
+ *      Put a message onto a msg_ctrl queue.
+ *  Parameters:
+ *      msg_queue_obj:      Handle to msg_ctrl queue returned from
+ *                      bridge_msg_create_queue.
+ *      pmsg:           Pointer to message.
+ *      utimeout:       Timeout to wait for a message.
+ *  Returns:
+ *      0:        Success.
+ *      -ETIME:   Timeout occurred.
+ *      -EPERM:      No frames available for message (max_msgs too
+ *                      small).
+ *  Requires:
+ *      Valid msg_queue_obj.
+ *      pmsg != NULL.
+ *  Ensures:
+ */
+typedef int(*fxn_msg_put) (struct msg_queue *msg_queue_obj,
+                                 const struct dsp_msg *pmsg, u32 utimeout);
+
+/*
+ *  ======== bridge_msg_register_notify ========
+ *  Purpose:
+ *      Register notification for when a message is ready.
+ *  Parameters:
+ *      msg_queue_obj:      Handle to msg_ctrl queue returned from
+ *                      bridge_msg_create_queue.
+ *      event_mask:     Type of events to be notified about: Must be
+ *                      DSP_NODEMESSAGEREADY, or 0 to unregister.
+ *      notify_type:    DSP_SIGNALEVENT.
+ *      hnotification:  Handle of notification object.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Insufficient memory.
+ *  Requires:
+ *      Valid msg_queue_obj.
+ *      hnotification != NULL.
+ *      notify_type == DSP_SIGNALEVENT.
+ *      event_mask == DSP_NODEMESSAGEREADY || event_mask == 0.
+ *  Ensures:
+ */
+typedef int(*fxn_msg_registernotify)
+ (struct msg_queue *msg_queue_obj,
+  u32 event_mask, u32 notify_type, struct dsp_notification *hnotification);
+
+/*
+ *  ======== bridge_msg_set_queue_id ========
+ *  Purpose:
+ *      Set message queue id to node environment. Allows bridge_msg_create_queue
+ *      to be called in node_allocate, before the node environment is known.
+ *  Parameters:
+ *      msg_queue_obj:  Handle to msg_ctrl queue returned from
+ *                  bridge_msg_create_queue.
+ *      msgq_id:       Node environment pointer.
+ *  Returns:
+ *  Requires:
+ *      Valid msg_queue_obj.
+ *      msgq_id != 0.
+ *  Ensures:
+ */
+typedef void (*fxn_msg_setqueueid) (struct msg_queue *msg_queue_obj,
+                                   u32 msgq_id);
+
+/*
+ *  Bridge Driver interface function table.
+ *
+ *  The information in this table is filled in by the specific Bridge driver,
+ *  and copied into the DSP API's own space.  If any interface
+ *  function field is set to a value of NULL, then the DSP API will
+ *  consider that function not implemented, and return the error code
+ *  -ENOSYS when a Bridge driver client attempts to call that function.
+ *
+ *  This function table contains DSP API version numbers, which are used by the
+ *  Bridge driver loader to help ensure backwards compatility between older
+ *  Bridge drivers and newer DSP API.  These must be set to
+ *  BRD_API_MAJOR_VERSION and BRD_API_MINOR_VERSION, respectively.
+ *
+ *  A Bridge driver need not export a CHNL interface.  In this case, *all* of
+ *  the bridge_chnl_* entries must be set to NULL.
+ */
+struct bridge_drv_interface {
+       u32 brd_api_major_version;      /* Set to BRD_API_MAJOR_VERSION. */
+       u32 brd_api_minor_version;      /* Set to BRD_API_MINOR_VERSION. */
+       fxn_dev_create pfn_dev_create;  /* Create device context */
+       fxn_dev_destroy pfn_dev_destroy;        /* Destroy device context */
+       fxn_dev_ctrl pfn_dev_cntrl;     /* Optional vendor interface */
+       fxn_brd_monitor pfn_brd_monitor;        /* Load and/or start monitor */
+       fxn_brd_start pfn_brd_start;    /* Start DSP program. */
+       fxn_brd_stop pfn_brd_stop;      /* Stop/reset board. */
+       fxn_brd_status pfn_brd_status;  /* Get current board status. */
+       fxn_brd_read pfn_brd_read;      /* Read board memory */
+       fxn_brd_write pfn_brd_write;    /* Write board memory. */
+       fxn_brd_setstate pfn_brd_set_state;     /* Sets the Board State */
+       fxn_brd_memcopy pfn_brd_mem_copy;       /* Copies DSP Memory */
+       fxn_brd_memwrite pfn_brd_mem_write;     /* Write DSP Memory w/o halt */
+       fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */
+       fxn_brd_memunmap pfn_brd_mem_un_map;    /* Unmaps MPU mem to DSP mem */
+       fxn_chnl_create pfn_chnl_create;        /* Create channel manager. */
+       fxn_chnl_destroy pfn_chnl_destroy;      /* Destroy channel manager. */
+       fxn_chnl_open pfn_chnl_open;    /* Create a new channel. */
+       fxn_chnl_close pfn_chnl_close;  /* Close a channel. */
+       fxn_chnl_addioreq pfn_chnl_add_io_req;  /* Req I/O on a channel. */
+       fxn_chnl_getioc pfn_chnl_get_ioc;       /* Wait for I/O completion. */
+       fxn_chnl_cancelio pfn_chnl_cancel_io;   /* Cancl I/O on a channel. */
+       fxn_chnl_flushio pfn_chnl_flush_io;     /* Flush I/O. */
+       fxn_chnl_getinfo pfn_chnl_get_info;     /* Get channel specific info */
+       /* Get channel manager info. */
+       fxn_chnl_getmgrinfo pfn_chnl_get_mgr_info;
+       fxn_chnl_idle pfn_chnl_idle;    /* Idle the channel */
+       /* Register for notif. */
+       fxn_chnl_registernotify pfn_chnl_register_notify;
+       fxn_io_create pfn_io_create;    /* Create IO manager */
+       fxn_io_destroy pfn_io_destroy;  /* Destroy IO manager */
+       fxn_io_onloaded pfn_io_on_loaded;       /* Notify of program loaded */
+       /* Get Processor's current and predicted load */
+       fxn_io_getprocload pfn_io_get_proc_load;
+       fxn_msg_create pfn_msg_create;  /* Create message manager */
+       /* Create message queue */
+       fxn_msg_createqueue pfn_msg_create_queue;
+       fxn_msg_delete pfn_msg_delete;  /* Delete message manager */
+       /* Delete message queue */
+       fxn_msg_deletequeue pfn_msg_delete_queue;
+       fxn_msg_get pfn_msg_get;        /* Get a message */
+       fxn_msg_put pfn_msg_put;        /* Send a message */
+       /* Register for notif. */
+       fxn_msg_registernotify pfn_msg_register_notify;
+       /* Set message queue id */
+       fxn_msg_setqueueid pfn_msg_set_queue_id;
+};
+
+/*
+ *  ======== bridge_drv_entry ========
+ *  Purpose:
+ *      Registers Bridge driver functions with the DSP API. Called only once
+ *      by the DSP API.  The caller will first check DSP API version
+ *      compatibility, and then copy the interface functions into its own
+ *      memory space.
+ *  Parameters:
+ *      drv_intf  Pointer to a location to receive a pointer to the
+ *                      Bridge driver interface.
+ *  Returns:
+ *  Requires:
+ *      The code segment this function resides in must expect to be discarded
+ *      after completion.
+ *  Ensures:
+ *      drv_intf pointer initialized to Bridge driver's function
+ *      interface. No system resources are acquired by this function.
+ *  Details:
+ *      Called during the Device_Init phase.
+ */
+void bridge_drv_entry(struct bridge_drv_interface **drv_intf,
+                  const char *driver_file_name);
+
+#endif /* DSPDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h b/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h
new file mode 100644 (file)
index 0000000..d258ab6
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * dspdeh.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Defines upper edge DEH functions required by all Bridge driver/DSP API
+ * interface tables.
+ *
+ * Notes:
+ *   Function comment headers reside with the function typedefs in dspdefs.h.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ * Copyright (C) 2010 Felipe Contreras
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPDEH_
+#define DSPDEH_
+
+struct deh_mgr;
+struct dev_object;
+struct dsp_notification;
+
+int bridge_deh_create(struct deh_mgr **ret_deh,
+               struct dev_object *hdev_obj);
+
+int bridge_deh_destroy(struct deh_mgr *deh);
+
+int bridge_deh_register_notify(struct deh_mgr *deh,
+               u32 event_mask,
+               u32 notify_type,
+               struct dsp_notification *hnotification);
+
+void bridge_deh_notify(struct deh_mgr *deh, int event, int info);
+
+#endif /* DSPDEH_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h b/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h
new file mode 100644 (file)
index 0000000..0bb250f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * dspdrv.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This is the Stream Interface for the DSp API.
+ * All Device operations are performed via DeviceIOControl.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if !defined _DSPDRV_H_
+#define _DSPDRV_H_
+
+#define MAX_DEV     10         /* Max support of 10 devices */
+
+/*
+ *  ======== dsp_deinit ========
+ *  Purpose:
+ *      This function is called by Device Manager to de-initialize a device.
+ *      This function is not called by applications.
+ *  Parameters:
+ *      device_context:Handle to the device context. The XXX_Init function
+ *      creates and returns this identifier.
+ *  Returns:
+ *      TRUE indicates the device successfully de-initialized. Otherwise it
+ *      returns FALSE.
+ *  Requires:
+ *      device_context!= NULL. For a built in device this should never
+ *      get called.
+ *  Ensures:
+ */
+extern bool dsp_deinit(u32 device_context);
+
+/*
+ *  ======== dsp_init ========
+ *  Purpose:
+ *      This function is called by Device Manager to initialize a device.
+ *      This function is not called by applications
+ *  Parameters:
+ *      dw_context:  Specifies a pointer to a string containing the registry
+ *                  path to the active key for the stream interface driver.
+ *                  HKEY_LOCAL_MACHINE\Drivers\Active
+ *  Returns:
+ *      Returns a handle to the device context created. This is the our actual
+ *      Device Object representing the DSP Device instance.
+ *  Requires:
+ *  Ensures:
+ *      Succeeded:  device context > 0
+ *      Failed:     device Context = 0
+ */
+extern u32 dsp_init(u32 *init_status);
+
+#endif
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspio.h b/drivers/staging/tidspbridge/include/dspbridge/dspio.h
new file mode 100644 (file)
index 0000000..88f5f90
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * dspio.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Declares the upper edge IO functions required by all Bridge driver /DSP API
+ * interface tables.
+ *
+ * Notes:
+ *   Function comment headers reside in dspdefs.h.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPIO_
+#define DSPIO_
+
+#include <dspbridge/devdefs.h>
+#include <dspbridge/iodefs.h>
+
+extern int bridge_io_create(struct io_mgr **io_man,
+                                  struct dev_object *hdev_obj,
+                                  const struct io_attrs *mgr_attrts);
+
+extern int bridge_io_destroy(struct io_mgr *hio_mgr);
+
+extern int bridge_io_on_loaded(struct io_mgr *hio_mgr);
+
+extern int iva_io_on_loaded(struct io_mgr *hio_mgr);
+extern int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
+                                      struct dsp_procloadstat *proc_lstat);
+
+#endif /* DSPIO_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h
new file mode 100644 (file)
index 0000000..41e0594
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * dspioctl.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Bridge driver BRD_IOCtl reserved command definitions.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPIOCTL_
+#define DSPIOCTL_
+
+/* ------------------------------------ Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
+/*
+ * Any IOCTLS at or above this value are reserved for standard Bridge driver
+ * interfaces.
+ */
+#define BRDIOCTL_RESERVEDBASE       0x8000
+
+#define BRDIOCTL_CHNLREAD           (BRDIOCTL_RESERVEDBASE + 0x10)
+#define BRDIOCTL_CHNLWRITE          (BRDIOCTL_RESERVEDBASE + 0x20)
+#define BRDIOCTL_GETINTRCOUNT       (BRDIOCTL_RESERVEDBASE + 0x30)
+#define BRDIOCTL_RESETINTRCOUNT     (BRDIOCTL_RESERVEDBASE + 0x40)
+#define BRDIOCTL_INTERRUPTDSP       (BRDIOCTL_RESERVEDBASE + 0x50)
+/* DMMU */
+#define BRDIOCTL_SETMMUCONFIG       (BRDIOCTL_RESERVEDBASE + 0x60)
+/* PWR */
+#define BRDIOCTL_PWRCONTROL         (BRDIOCTL_RESERVEDBASE + 0x70)
+
+/* attention, modifiers:
+ * Some of these control enumerations are made visible to user for power
+ * control, so any changes to this list, should also be updated in the user
+ * header file 'dbdefs.h' ***/
+/* These ioctls are reserved for PWR power commands for the DSP */
+#define BRDIOCTL_DEEPSLEEP          (BRDIOCTL_PWRCONTROL + 0x0)
+#define BRDIOCTL_EMERGENCYSLEEP     (BRDIOCTL_PWRCONTROL + 0x1)
+#define BRDIOCTL_WAKEUP             (BRDIOCTL_PWRCONTROL + 0x2)
+#define BRDIOCTL_PWRENABLE          (BRDIOCTL_PWRCONTROL + 0x3)
+#define BRDIOCTL_PWRDISABLE         (BRDIOCTL_PWRCONTROL + 0x4)
+#define BRDIOCTL_CLK_CTRL                  (BRDIOCTL_PWRCONTROL + 0x7)
+/* DSP Initiated Hibernate */
+#define BRDIOCTL_PWR_HIBERNATE (BRDIOCTL_PWRCONTROL + 0x8)
+#define BRDIOCTL_PRESCALE_NOTIFY (BRDIOCTL_PWRCONTROL + 0x9)
+#define BRDIOCTL_POSTSCALE_NOTIFY (BRDIOCTL_PWRCONTROL + 0xA)
+#define BRDIOCTL_CONSTRAINT_REQUEST (BRDIOCTL_PWRCONTROL + 0xB)
+
+/* Number of actual DSP-MMU TLB entrries */
+#define BRDIOCTL_NUMOFMMUTLB        32
+
+struct bridge_ioctl_extproc {
+       u32 ul_dsp_va;          /* DSP virtual address */
+       u32 ul_gpp_pa;          /* GPP physical address */
+       /* GPP virtual address. __va does not work for ioremapped addresses */
+       u32 ul_gpp_va;
+       u32 ul_size;            /* Size of the mapped memory in bytes */
+       enum hw_endianism_t endianism;
+       enum hw_mmu_mixed_size_t mixed_mode;
+       enum hw_element_size_t elem_size;
+};
+
+#endif /* DSPIOCTL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h b/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h
new file mode 100644 (file)
index 0000000..d4bd458
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * dspmsg.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Declares the upper edge message class library functions required by
+ * all Bridge driver / DSP API interface tables.  These functions are
+ * implemented by every class of Bridge driver channel library.
+ *
+ * Notes:
+ *   Function comment headers reside in dspdefs.h.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DSPMSG_
+#define DSPMSG_
+
+#include <dspbridge/msgdefs.h>
+
+extern int bridge_msg_create(struct msg_mgr **msg_man,
+                                   struct dev_object *hdev_obj,
+                                   msg_onexit msg_callback);
+
+extern int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
+                                      struct msg_queue **msgq,
+                                      u32 msgq_id, u32 max_msgs, void *arg);
+
+extern void bridge_msg_delete(struct msg_mgr *hmsg_mgr);
+
+extern void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj);
+
+extern int bridge_msg_get(struct msg_queue *msg_queue_obj,
+                                struct dsp_msg *pmsg, u32 utimeout);
+
+extern int bridge_msg_put(struct msg_queue *msg_queue_obj,
+                                const struct dsp_msg *pmsg, u32 utimeout);
+
+extern int bridge_msg_register_notify(struct msg_queue *msg_queue_obj,
+                                         u32 event_mask,
+                                         u32 notify_type,
+                                         struct dsp_notification
+                                         *hnotification);
+
+extern void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj,
+                                       u32 msgq_id);
+
+#endif /* DSPMSG_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h b/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h
new file mode 100644 (file)
index 0000000..4b109d1
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * dynamic_loader.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _DYNAMIC_LOADER_H_
+#define _DYNAMIC_LOADER_H_
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+/*
+ * Dynamic Loader
+ *
+ * The function of the dynamic loader is to load a "module" containing
+ * instructions for a "target" processor into that processor.  In the process
+ * it assigns memory for the module, resolves symbol references made by the
+ * module, and remembers symbols defined by the module.
+ *
+ * The dynamic loader is parameterized for a particular system by 4 classes
+ * that supply the module and system specific functions it requires
+ */
+       /* The read functions for the module image to be loaded */
+struct dynamic_loader_stream;
+
+       /* This class defines "host" symbol and support functions */
+struct dynamic_loader_sym;
+
+       /* This class defines the allocator for "target" memory */
+struct dynamic_loader_allocate;
+
+       /* This class defines the copy-into-target-memory functions */
+struct dynamic_loader_initialize;
+
+/*
+ * Option flags to modify the behavior of module loading
+ */
+#define DLOAD_INITBSS 0x1      /* initialize BSS sections to zero */
+#define DLOAD_BIGEND 0x2       /* require big-endian load module */
+#define DLOAD_LITTLE 0x4       /* require little-endian load module */
+
+/*****************************************************************************
+ * Procedure dynamic_load_module
+ *
+ * Parameters:
+ *  module  The input stream that supplies the module image
+ *  syms    Host-side symbol table and malloc/free functions
+ *  alloc   Target-side memory allocation
+ *  init    Target-side memory initialization, or NULL for symbol read only
+ *  options Option flags DLOAD_*
+ *  mhandle A module handle for use with Dynamic_Unload
+ *
+ * Effect:
+ *  The module image is read using *module.  Target storage for the new image is
+ * obtained from *alloc.  Symbols defined and referenced by the module are
+ * managed using *syms.  The image is then relocated and references resolved
+ * as necessary, and the resulting executable bits are placed into target memory
+ * using *init.
+ *
+ * Returns:
+ *  On a successful load, a module handle is placed in *mhandle, and zero is
+ * returned.  On error, the number of errors detected is returned.  Individual
+ * errors are reported during the load process using syms->error_report().
+ **************************************************************************** */
+extern int dynamic_load_module(
+                                     /* the source for the module image */
+                                     struct dynamic_loader_stream *module,
+                                     /* host support for symbols and storage */
+                                     struct dynamic_loader_sym *syms,
+                                     /* the target memory allocator */
+                                     struct dynamic_loader_allocate *alloc,
+                                     /* the target memory initializer */
+                                     struct dynamic_loader_initialize *init,
+                                     unsigned options, /* option flags */
+                                     /* the returned module handle */
+                                     void **mhandle);
+
+/*****************************************************************************
+ * Procedure dynamic_open_module
+ *
+ * Parameters:
+ *  module  The input stream that supplies the module image
+ *  syms    Host-side symbol table and malloc/free functions
+ *  alloc   Target-side memory allocation
+ *  init    Target-side memory initialization, or NULL for symbol read only
+ *  options Option flags DLOAD_*
+ *  mhandle A module handle for use with Dynamic_Unload
+ *
+ * Effect:
+ *  The module image is read using *module.  Target storage for the new image is
+ * obtained from *alloc.  Symbols defined and referenced by the module are
+ * managed using *syms.  The image is then relocated and references resolved
+ * as necessary, and the resulting executable bits are placed into target memory
+ * using *init.
+ *
+ * Returns:
+ *  On a successful load, a module handle is placed in *mhandle, and zero is
+ * returned.  On error, the number of errors detected is returned.  Individual
+ * errors are reported during the load process using syms->error_report().
+ **************************************************************************** */
+extern int dynamic_open_module(
+                                     /* the source for the module image */
+                                     struct dynamic_loader_stream *module,
+                                     /* host support for symbols and storage */
+                                     struct dynamic_loader_sym *syms,
+                                     /* the target memory allocator */
+                                     struct dynamic_loader_allocate *alloc,
+                                     /* the target memory initializer */
+                                     struct dynamic_loader_initialize *init,
+                                     unsigned options, /* option flags */
+                                     /* the returned module handle */
+                                     void **mhandle);
+
+/*****************************************************************************
+ * Procedure dynamic_unload_module
+ *
+ * Parameters:
+ *  mhandle A module handle from dynamic_load_module
+ *  syms    Host-side symbol table and malloc/free functions
+ *  alloc   Target-side memory allocation
+ *
+ * Effect:
+ *  The module specified by mhandle is unloaded.  Unloading causes all
+ * target memory to be deallocated, all symbols defined by the module to
+ * be purged, and any host-side storage used by the dynamic loader for
+ * this module to be released.
+ *
+ * Returns:
+ *  Zero for success. On error, the number of errors detected is returned.
+ * Individual errors are reported using syms->error_report().
+ **************************************************************************** */
+extern int dynamic_unload_module(void *mhandle,        /* the module
+                                                        * handle */
+                                /* host support for symbols and
+                                 * storage */
+                                struct dynamic_loader_sym *syms,
+                                /* the target memory allocator */
+                                struct dynamic_loader_allocate *alloc,
+                                /* the target memory initializer */
+                                struct dynamic_loader_initialize *init);
+
+/*****************************************************************************
+ *****************************************************************************
+ * A class used by the dynamic loader for input of the module image
+ *****************************************************************************
+ **************************************************************************** */
+struct dynamic_loader_stream {
+/* public: */
+    /*************************************************************************
+     * read_buffer
+     *
+     * PARAMETERS :
+     *  buffer  Pointer to the buffer to fill
+     *  bufsiz  Amount of data desired in sizeof() units
+     *
+     * EFFECT :
+     *  Reads the specified amount of data from the module input stream
+     * into the specified buffer.  Returns the amount of data read in sizeof()
+     * units (which if less than the specification, represents an error).
+     *
+     * NOTES:
+     *  In release 1 increments the file position by the number of bytes read
+     *
+     ************************************************************************ */
+       int (*read_buffer) (struct dynamic_loader_stream *thisptr,
+                           void *buffer, unsigned bufsiz);
+
+    /*************************************************************************
+     * set_file_posn (release 1 only)
+     *
+     * PARAMETERS :
+     *  posn  Desired file position relative to start of file in sizeof() units.
+     *
+     * EFFECT :
+     *  Adjusts the internal state of the stream object so that the next
+     * read_buffer call will begin to read at the specified offset from
+     * the beginning of the input module.  Returns 0 for success, non-zero
+     * for failure.
+     *
+     ************************************************************************ */
+       int (*set_file_posn) (struct dynamic_loader_stream *thisptr,
+                             /* to be eliminated in release 2 */
+                             unsigned int posn);
+
+};
+
+/*****************************************************************************
+ *****************************************************************************
+ * A class used by the dynamic loader for symbol table support and
+ * miscellaneous host-side functions
+ *****************************************************************************
+ **************************************************************************** */
+
+typedef u32 ldr_addr;
+
+/*
+ * the structure of a symbol known to the dynamic loader
+ */
+struct dynload_symbol {
+       ldr_addr value;
+};
+
+struct dynamic_loader_sym {
+/* public: */
+    /*************************************************************************
+     * find_matching_symbol
+     *
+     * PARAMETERS :
+     *  name    The name of the desired symbol
+     *
+     * EFFECT :
+     *  Locates a symbol matching the name specified.  A pointer to the
+     * symbol is returned if it exists; 0 is returned if no such symbol is
+     * found.
+     *
+     ************************************************************************ */
+       struct dynload_symbol *(*find_matching_symbol)
+        (struct dynamic_loader_sym *thisptr, const char *name);
+
+    /*************************************************************************
+     * add_to_symbol_table
+     *
+     * PARAMETERS :
+     *  nname       Pointer to the name of the new symbol
+     *  moduleid    An opaque module id assigned by the dynamic loader
+     *
+     * EFFECT :
+     *  The new symbol is added to the table.  A pointer to the symbol is
+     * returned, or NULL is returned for failure.
+     *
+     * NOTES:
+     *  It is permissible for this function to return NULL; the effect is that
+     * the named symbol will not be available to resolve references in
+     * subsequent loads.  Returning NULL will not cause the current load
+     * to fail.
+     ************************************************************************ */
+       struct dynload_symbol *(*add_to_symbol_table)
+        (struct dynamic_loader_sym *
+         thisptr, const char *nname, unsigned moduleid);
+
+    /*************************************************************************
+     * purge_symbol_table
+     *
+     * PARAMETERS :
+     *  moduleid    An opaque module id assigned by the dynamic loader
+     *
+     * EFFECT :
+     *  Each symbol in the symbol table whose moduleid matches the argument
+     * is removed from the table.
+     ************************************************************************ */
+       void (*purge_symbol_table) (struct dynamic_loader_sym *thisptr,
+                                   unsigned moduleid);
+
+    /*************************************************************************
+     * dload_allocate
+     *
+     * PARAMETERS :
+     *  memsiz  size of desired memory in sizeof() units
+     *
+     * EFFECT :
+     *  Returns a pointer to some "host" memory for use by the dynamic
+     * loader, or NULL for failure.
+     * This function is serves as a replaceable form of "malloc" to
+     * allow the user to configure the memory usage of the dynamic loader.
+     ************************************************************************ */
+       void *(*dload_allocate) (struct dynamic_loader_sym *thisptr,
+                                unsigned memsiz);
+
+    /*************************************************************************
+     * dload_deallocate
+     *
+     * PARAMETERS :
+     *  memptr  pointer to previously allocated memory
+     *
+     * EFFECT :
+     *  Releases the previously allocated "host" memory.
+     ************************************************************************ */
+       void (*dload_deallocate) (struct dynamic_loader_sym *thisptr,
+                                 void *memptr);
+
+    /*************************************************************************
+     * error_report
+     *
+     * PARAMETERS :
+     *  errstr  pointer to an error string
+     *  args    additional arguments
+     *
+     * EFFECT :
+     *  This function provides an error reporting interface for the dynamic
+     * loader.  The error string and arguments are designed as for the
+     * library function vprintf.
+     ************************************************************************ */
+       void (*error_report) (struct dynamic_loader_sym *thisptr,
+                             const char *errstr, va_list args);
+
+};                             /* class dynamic_loader_sym */
+
+/*****************************************************************************
+ *****************************************************************************
+ * A class used by the dynamic loader to allocate and deallocate target memory.
+ *****************************************************************************
+ **************************************************************************** */
+
+struct ldr_section_info {
+       /* Name of the memory section assigned at build time */
+       const char *name;
+       ldr_addr run_addr;      /* execution address of the section */
+       ldr_addr load_addr;     /* load address of the section */
+       ldr_addr size;          /* size of the section in addressable units */
+#ifndef _BIG_ENDIAN
+       u16 page;               /* memory page or view */
+       u16 type;               /* one of the section types below */
+#else
+       u16 type;               /* one of the section types below */
+       u16 page;               /* memory page or view */
+#endif
+       /* a context field for use by dynamic_loader_allocate;
+        *   ignored but maintained by the dynamic loader */
+       u32 context;
+};
+
+/* use this macro to extract type of section from ldr_section_info.type field */
+#define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF)
+
+/* type of section to be allocated */
+#define DLOAD_TEXT 0
+#define DLOAD_DATA 1
+#define DLOAD_BSS 2
+       /* internal use only, run-time cinit will be of type DLOAD_DATA */
+#define DLOAD_CINIT 3
+
+struct dynamic_loader_allocate {
+/* public: */
+
+    /*************************************************************************
+    * Function allocate
+    *
+    * Parameters:
+    *   info        A pointer to an information block for the section
+    *   align       The alignment of the storage in target AUs
+    *
+    * Effect:
+    *   Allocates target memory for the specified section and fills in the
+    * load_addr and run_addr fields of the section info structure. Returns TRUE
+    * for success, FALSE for failure.
+    *
+    * Notes:
+    *   Frequently load_addr and run_addr are the same, but if they are not
+    * load_addr is used with dynamic_loader_initialize, and run_addr is
+    * used for almost all relocations.  This function should always initialize
+    * both fields.
+    ************************************************************************ */
+       int (*dload_allocate) (struct dynamic_loader_allocate *thisptr,
+                              struct ldr_section_info *info, unsigned align);
+
+    /*************************************************************************
+    * Function deallocate
+    *
+    * Parameters:
+    *   info        A pointer to an information block for the section
+    *
+    * Effect:
+    *   Releases the target memory previously allocated.
+    *
+    * Notes:
+    * The content of the info->name field is undefined on call to this function.
+    ************************************************************************ */
+       void (*dload_deallocate) (struct dynamic_loader_allocate *thisptr,
+                                 struct ldr_section_info *info);
+
+};                             /* class dynamic_loader_allocate */
+
+/*****************************************************************************
+ *****************************************************************************
+ * A class used by the dynamic loader to load data into a target.  This class
+ * provides the interface-specific functions needed to load data.
+ *****************************************************************************
+ **************************************************************************** */
+
+struct dynamic_loader_initialize {
+/* public: */
+    /*************************************************************************
+    * Function connect
+    *
+    * Parameters:
+    *   none
+    *
+    * Effect:
+    *   Connect to the initialization interface. Returns TRUE for success,
+    * FALSE for failure.
+    *
+    * Notes:
+    *   This function is called prior to use of any other functions in
+    * this interface.
+    ************************************************************************ */
+       int (*connect) (struct dynamic_loader_initialize *thisptr);
+
+    /*************************************************************************
+    * Function readmem
+    *
+    * Parameters:
+    *   bufr        Pointer to a word-aligned buffer for the result
+    *   locn        Target address of first data element
+    *   info        Section info for the section in which the address resides
+    *   bytsiz      Size of the data to be read in sizeof() units
+    *
+    * Effect:
+    *   Fills the specified buffer with data from the target.  Returns TRUE for
+    * success, FALSE for failure.
+    ************************************************************************ */
+       int (*readmem) (struct dynamic_loader_initialize *thisptr,
+                       void *bufr,
+                       ldr_addr locn,
+                       struct ldr_section_info *info, unsigned bytsiz);
+
+    /*************************************************************************
+    * Function writemem
+    *
+    * Parameters:
+    *   bufr        Pointer to a word-aligned buffer of data
+    *   locn        Target address of first data element to be written
+    *   info        Section info for the section in which the address resides
+    *   bytsiz      Size of the data to be written in sizeof() units
+    *
+    * Effect:
+    *   Writes the specified buffer to the target.  Returns TRUE for success,
+    * FALSE for failure.
+    ************************************************************************ */
+       int (*writemem) (struct dynamic_loader_initialize *thisptr,
+                        void *bufr,
+                        ldr_addr locn,
+                        struct ldr_section_info *info, unsigned bytsiz);
+
+    /*************************************************************************
+    * Function fillmem
+    *
+    * Parameters:
+    *   locn        Target address of first data element to be written
+    *   info        Section info for the section in which the address resides
+    *   bytsiz      Size of the data to be written in sizeof() units
+    *   val         Value to be written in each byte
+    * Effect:
+    *   Fills the specified area of target memory.  Returns TRUE for success,
+    * FALSE for failure.
+    ************************************************************************ */
+       int (*fillmem) (struct dynamic_loader_initialize *thisptr,
+                       ldr_addr locn, struct ldr_section_info *info,
+                       unsigned bytsiz, unsigned val);
+
+    /*************************************************************************
+    * Function execute
+    *
+    * Parameters:
+    *   start       Starting address
+    *
+    * Effect:
+    *   The target code at the specified starting address is executed.
+    *
+    * Notes:
+    *   This function is called at the end of the dynamic load process
+    * if the input module has specified a starting address.
+    ************************************************************************ */
+       int (*execute) (struct dynamic_loader_initialize *thisptr,
+                       ldr_addr start);
+
+    /*************************************************************************
+    * Function release
+    *
+    * Parameters:
+    *   none
+    *
+    * Effect:
+    *   Releases the connection to the load interface.
+    *
+    * Notes:
+    *   This function is called at the end of the dynamic load process.
+    ************************************************************************ */
+       void (*release) (struct dynamic_loader_initialize *thisptr);
+
+};                             /* class dynamic_loader_initialize */
+
+#endif /* _DYNAMIC_LOADER_H_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/gb.h b/drivers/staging/tidspbridge/include/dspbridge/gb.h
new file mode 100644 (file)
index 0000000..fda783a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * gb.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Generic bitmap manager.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef GB_
+#define GB_
+
+#define GB_NOBITS (~0)
+#include <dspbridge/host_os.h>
+
+struct gb_t_map;
+
+/*
+ *  ======== gb_clear ========
+ *  Clear the bit in position bitn in the bitmap map.  Bit positions are
+ *  zero based.
+ */
+
+extern void gb_clear(struct gb_t_map *map, u32 bitn);
+
+/*
+ *  ======== gb_create ========
+ *  Create a bit map with len bits.  Initially all bits are cleared.
+ */
+
+extern struct gb_t_map *gb_create(u32 len);
+
+/*
+ *  ======== gb_delete ========
+ *  Delete previously created bit map
+ */
+
+extern void gb_delete(struct gb_t_map *map);
+
+/*
+ *  ======== gb_findandset ========
+ *  Finds a clear bit, sets it, and returns the position
+ */
+
+extern u32 gb_findandset(struct gb_t_map *map);
+
+/*
+ *  ======== gb_minclear ========
+ *  gb_minclear returns the minimum clear bit position.  If no bit is
+ *  clear, gb_minclear returns -1.
+ */
+extern u32 gb_minclear(struct gb_t_map *map);
+
+/*
+ *  ======== gb_set ========
+ *  Set the bit in position bitn in the bitmap map.  Bit positions are
+ *  zero based.
+ */
+
+extern void gb_set(struct gb_t_map *map, u32 bitn);
+
+/*
+ *  ======== gb_test ========
+ *  Returns TRUE if the bit in position bitn is set in map; otherwise
+ *  gb_test returns FALSE.  Bit positions are zero based.
+ */
+
+extern bool gb_test(struct gb_t_map *map, u32 bitn);
+
+#endif /*GB_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/getsection.h b/drivers/staging/tidspbridge/include/dspbridge/getsection.h
new file mode 100644 (file)
index 0000000..626063d
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * getsection.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This file provides an API add-on to the dynamic loader that allows the user
+ * to query section information and extract section data from dynamic load
+ * modules.
+ *
+ * Notes:
+ *   Functions in this API assume that the supplied dynamic_loader_stream
+ *   object supports the set_file_posn method.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _GETSECTION_H_
+#define _GETSECTION_H_
+
+#include "dynamic_loader.h"
+
+/*
+ * Procedure dload_module_open
+ *
+ * Parameters:
+ *  module  The input stream that supplies the module image
+ *  syms    Host-side malloc/free and error reporting functions.
+ *          Other methods are unused.
+ *
+ * Effect:
+ *  Reads header information from a dynamic loader module using the specified
+ * stream object, and returns a handle for the module information.  This
+ * handle may be used in subsequent query calls to obtain information
+ * contained in the module.
+ *
+ * Returns:
+ *  NULL if an error is encountered, otherwise a module handle for use
+ * in subsequent operations.
+ */
+extern void *dload_module_open(struct dynamic_loader_stream
+                                          *module, struct dynamic_loader_sym
+                                          *syms);
+
+/*
+ * Procedure dload_get_section_info
+ *
+ * Parameters:
+ *  minfo       Handle from dload_module_open for this module
+ *  section_name Pointer to the string name of the section desired
+ *  section_info Address of a section info structure pointer to be initialized
+ *
+ * Effect:
+ *  Finds the specified section in the module information, and fills in
+ * the provided ldr_section_info structure.
+ *
+ * Returns:
+ *  TRUE for success, FALSE for section not found
+ */
+extern int dload_get_section_info(void *minfo,
+                                 const char *section_name,
+                                 const struct ldr_section_info
+                                 **const section_info);
+
+/*
+ * Procedure dload_get_section
+ *
+ * Parameters:
+ *  minfo       Handle from dload_module_open for this module
+ *  section_info Pointer to a section info structure for the desired section
+ *  section_data Buffer to contain the section initialized data
+ *
+ * Effect:
+ *  Copies the initialized data for the specified section into the
+ * supplied buffer.
+ *
+ * Returns:
+ *  TRUE for success, FALSE for section not found
+ */
+extern int dload_get_section(void *minfo,
+                            const struct ldr_section_info *section_info,
+                            void *section_data);
+
+/*
+ * Procedure dload_module_close
+ *
+ * Parameters:
+ *  minfo       Handle from dload_module_open for this module
+ *
+ * Effect:
+ *  Releases any storage associated with the module handle.  On return,
+ * the module handle is invalid.
+ *
+ * Returns:
+ *  Zero for success. On error, the number of errors detected is returned.
+ * Individual errors are reported using syms->error_report(), where syms was
+ * an argument to dload_module_open
+ */
+extern void dload_module_close(void *minfo);
+
+#endif /* _GETSECTION_H_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/gh.h b/drivers/staging/tidspbridge/include/dspbridge/gh.h
new file mode 100644 (file)
index 0000000..9de291d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * gh.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef GH_
+#define GH_
+#include <dspbridge/host_os.h>
+
+extern struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
+                                      u16(*hash) (void *, u16),
+                                      bool(*match) (void *, void *),
+                                      void (*delete) (void *));
+extern void gh_delete(struct gh_t_hash_tab *hash_tab);
+extern void gh_exit(void);
+extern void *gh_find(struct gh_t_hash_tab *hash_tab, void *key);
+extern void gh_init(void);
+extern void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value);
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+void gh_iterate(struct gh_t_hash_tab *hash_tab,
+       void (*callback)(void *, void *), void *user_data);
+#endif
+#endif /* GH_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/gs.h b/drivers/staging/tidspbridge/include/dspbridge/gs.h
new file mode 100644 (file)
index 0000000..f32d8d9
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * gs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Memory allocation/release wrappers.  This module allows clients to
+ * avoid OS spacific issues related to memory allocation.  It also provides
+ * simple diagnostic capabilities to assist in the detection of memory
+ * leaks.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef GS_
+#define GS_
+
+/*
+ *  ======== gs_alloc ========
+ *  Alloc size bytes of space.  Returns pointer to space
+ *  allocated, otherwise NULL.
+ */
+extern void *gs_alloc(u32 size);
+
+/*
+ *  ======== gs_exit ========
+ *  Module exit.  Do not change to "#define gs_init()"; in
+ *  some environments this operation must actually do some work!
+ */
+extern void gs_exit(void);
+
+/*
+ *  ======== gs_free ========
+ *  Free space allocated by gs_alloc() or GS_calloc().
+ */
+extern void gs_free(void *ptr);
+
+/*
+ *  ======== gs_frees ========
+ *  Free space allocated by gs_alloc() or GS_calloc() and assert that
+ *  the size of the allocation is size bytes.
+ */
+extern void gs_frees(void *ptr, u32 size);
+
+/*
+ *  ======== gs_init ========
+ *  Module initialization.  Do not change to "#define gs_init()"; in
+ *  some environments this operation must actually do some work!
+ */
+extern void gs_init(void);
+
+#endif /*GS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h
new file mode 100644 (file)
index 0000000..6b4feb4
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * host_os.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _HOST_OS_H_
+#define _HOST_OS_H_
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/syscalls.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/vmalloc.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <plat/clock.h>
+#include <linux/clk.h>
+#include <plat/mailbox.h>
+#include <linux/pagemap.h>
+#include <asm/cacheflush.h>
+#include <linux/dma-mapping.h>
+
+/* TODO -- Remove, once BP defines them */
+#define INT_DSP_MMU_IRQ        28
+
+struct dspbridge_platform_data {
+       void (*dsp_set_min_opp) (u8 opp_id);
+        u8(*dsp_get_opp) (void);
+       void (*cpu_set_freq) (unsigned long f);
+       unsigned long (*cpu_get_freq) (void);
+       unsigned long mpu_speed[6];
+
+       /* functions to write and read PRCM registers */
+       void (*dsp_prm_write)(u32, s16 , u16);
+       u32 (*dsp_prm_read)(s16 , u16);
+       u32 (*dsp_prm_rmw_bits)(u32, u32, s16, s16);
+       void (*dsp_cm_write)(u32, s16 , u16);
+       u32 (*dsp_cm_read)(s16 , u16);
+       u32 (*dsp_cm_rmw_bits)(u32, u32, s16, s16);
+
+       u32 phys_mempool_base;
+       u32 phys_mempool_size;
+};
+
+#define PRCM_VDD1 1
+
+extern struct platform_device *omap_dspbridge_dev;
+extern struct device *bridge;
+
+#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
+extern void dspbridge_reserve_sdram(void);
+#else
+static inline void dspbridge_reserve_sdram(void)
+{
+}
+#endif
+
+extern unsigned long dspbridge_get_mempool_base(void);
+#endif
diff --git a/drivers/staging/tidspbridge/include/dspbridge/io.h b/drivers/staging/tidspbridge/include/dspbridge/io.h
new file mode 100644 (file)
index 0000000..bc346f9
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * io.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * The io module manages IO between CHNL and msg_ctrl.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef IO_
+#define IO_
+
+#include <dspbridge/cfgdefs.h>
+#include <dspbridge/devdefs.h>
+
+#include <dspbridge/iodefs.h>
+
+/*
+ *  ======== io_create ========
+ *  Purpose:
+ *      Create an IO manager object, responsible for managing IO between
+ *      CHNL and msg_ctrl.
+ *  Parameters:
+ *      channel_mgr:            Location to store a channel manager object on
+ *                              output.
+ *      hdev_obj:             Handle to a device object.
+ *      mgr_attrts:              IO manager attributes.
+ *      mgr_attrts->birq:        I/O IRQ number.
+ *      mgr_attrts->irq_shared:     TRUE if the IRQ is shareable.
+ *      mgr_attrts->word_size:   DSP Word size in equivalent PC bytes..
+ *  Returns:
+ *      0:                Success;
+ *      -ENOMEM:            Insufficient memory for requested resources.
+ *      -EIO:             Unable to plug channel ISR for configured IRQ.
+ *      -EINVAL: Invalid DSP word size (must be > 0).
+ *               Invalid base address for DSP communications.
+ *  Requires:
+ *      io_init(void) called.
+ *      io_man != NULL.
+ *      mgr_attrts != NULL.
+ *  Ensures:
+ */
+extern int io_create(struct io_mgr **io_man,
+                           struct dev_object *hdev_obj,
+                           const struct io_attrs *mgr_attrts);
+
+/*
+ *  ======== io_destroy ========
+ *  Purpose:
+ *      Destroy the IO manager.
+ *  Parameters:
+ *      hio_mgr:         IOmanager object.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    hio_mgr was invalid.
+ *  Requires:
+ *      io_init(void) called.
+ *  Ensures:
+ */
+extern int io_destroy(struct io_mgr *hio_mgr);
+
+/*
+ *  ======== io_exit ========
+ *  Purpose:
+ *      Discontinue usage of the IO module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      io_init(void) previously called.
+ *  Ensures:
+ *      Resources, if any acquired in io_init(void), are freed when the last
+ *      client of IO calls io_exit(void).
+ */
+extern void io_exit(void);
+
+/*
+ *  ======== io_init ========
+ *  Purpose:
+ *      Initialize the IO module's private state.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occurred.
+ *  Requires:
+ *  Ensures:
+ *      A requirement for each of the other public CHNL functions.
+ */
+extern bool io_init(void);
+
+/*
+ *  ======== io_on_loaded ========
+ *  Purpose:
+ *      Called when a program is loaded so IO manager can update its
+ *      internal state.
+ *  Parameters:
+ *      hio_mgr:         IOmanager object.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    hio_mgr was invalid.
+ *  Requires:
+ *      io_init(void) called.
+ *  Ensures:
+ */
+extern int io_on_loaded(struct io_mgr *hio_mgr);
+
+#endif /* CHNL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h
new file mode 100644 (file)
index 0000000..18aec55
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * io_sm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * IO dispatcher for a shared memory channel driver.
+ * Also, includes macros to simulate shm via port io calls.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef IOSM_
+#define IOSM_
+
+#include <dspbridge/_chnl_sm.h>
+#include <dspbridge/host_os.h>
+
+#include <dspbridge/iodefs.h>
+
+#define IO_INPUT            0
+#define IO_OUTPUT           1
+#define IO_SERVICE          2
+#define IO_MAXSERVICE       IO_SERVICE
+
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+/* The maximum number of OPPs that are supported */
+extern s32 dsp_max_opps;
+/* The Vdd1 opp table information */
+extern u32 vdd1_dsp_freq[6][4];
+#endif
+
+/*
+ *  ======== io_cancel_chnl ========
+ *  Purpose:
+ *      Cancel IO on a given channel.
+ *  Parameters:
+ *      hio_mgr:     IO Manager.
+ *      chnl:       Index of channel to cancel IO on.
+ *  Returns:
+ *  Requires:
+ *      Valid hio_mgr.
+ *  Ensures:
+ */
+extern void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl);
+
+/*
+ *  ======== io_dpc ========
+ *  Purpose:
+ *      Deferred procedure call for shared memory channel driver ISR.  Carries
+ *      out the dispatch of I/O.
+ *  Parameters:
+ *      ref_data:   Pointer to reference data registered via a call to
+ *                  DPC_Create().
+ *  Returns:
+ *  Requires:
+ *      Must not block.
+ *      Must not acquire resources.
+ *      All data touched must be locked in memory if running in kernel mode.
+ *  Ensures:
+ *      Non-preemptible (but interruptible).
+ */
+extern void io_dpc(unsigned long ref_data);
+
+/*
+ *  ======== io_mbox_msg ========
+ *  Purpose:
+ *      Main interrupt handler for the shared memory Bridge channel manager.
+ *      Calls the Bridge's chnlsm_isr to determine if this interrupt is ours,
+ *      then schedules a DPC to dispatch I/O.
+ *  Parameters:
+ *      ref_data:   Pointer to the channel manager object for this board.
+ *                  Set in an initial call to ISR_Install().
+ *  Returns:
+ *      TRUE if interrupt handled; FALSE otherwise.
+ *  Requires:
+ *      Must be in locked memory if executing in kernel mode.
+ *      Must only call functions which are in locked memory if Kernel mode.
+ *      Must only call asynchronous services.
+ *      Interrupts are disabled and EOI for this interrupt has been sent.
+ *  Ensures:
+ */
+void io_mbox_msg(u32 msg);
+
+/*
+ *  ======== io_request_chnl ========
+ *  Purpose:
+ *      Request I/O from the DSP. Sets flags in shared memory, then interrupts
+ *      the DSP.
+ *  Parameters:
+ *      hio_mgr:     IO manager handle.
+ *      pchnl:      Ptr to the channel requesting I/O.
+ *      io_mode:      Mode of channel: {IO_INPUT | IO_OUTPUT}.
+ *  Returns:
+ *  Requires:
+ *      pchnl != NULL
+ *  Ensures:
+ */
+extern void io_request_chnl(struct io_mgr *io_manager,
+                           struct chnl_object *pchnl,
+                           u8 io_mode, u16 *mbx_val);
+
+/*
+ *  ======== iosm_schedule ========
+ *  Purpose:
+ *      Schedule DPC for IO.
+ *  Parameters:
+ *      pio_mgr:     Ptr to a I/O manager.
+ *  Returns:
+ *  Requires:
+ *      pchnl != NULL
+ *  Ensures:
+ */
+extern void iosm_schedule(struct io_mgr *io_manager);
+
+/*
+ * DSP-DMA IO functions
+ */
+
+/*
+ *  ======== io_ddma_init_chnl_desc ========
+ *  Purpose:
+ *      Initialize DSP DMA channel descriptor.
+ *  Parameters:
+ *      hio_mgr:         Handle to a I/O manager.
+ *      ddma_chnl_id:    DDMA channel identifier.
+ *      num_desc:       Number of buffer descriptors(equals # of IOReqs &
+ *                      Chirps)
+ *      dsp:           Dsp address;
+ *  Returns:
+ *  Requires:
+ *     ddma_chnl_id < DDMA_MAXDDMACHNLS
+ *     num_desc > 0
+ *     pVa != NULL
+ *     pDspPa != NULL
+ *
+ *  Ensures:
+ */
+extern void io_ddma_init_chnl_desc(struct io_mgr *hio_mgr, u32 ddma_chnl_id,
+                                  u32 num_desc, void *dsp);
+
+/*
+ *  ======== io_ddma_clear_chnl_desc ========
+ *  Purpose:
+ *      Clear DSP DMA channel descriptor.
+ *  Parameters:
+ *      hio_mgr:         Handle to a I/O manager.
+ *      ddma_chnl_id:    DDMA channel identifier.
+ *  Returns:
+ *  Requires:
+ *     ddma_chnl_id < DDMA_MAXDDMACHNLS
+ *  Ensures:
+ */
+extern void io_ddma_clear_chnl_desc(struct io_mgr *hio_mgr, u32 ddma_chnl_id);
+
+/*
+ *  ======== io_ddma_request_chnl ========
+ *  Purpose:
+ *      Request channel DSP-DMA from the DSP. Sets up SM descriptors and
+ *      control fields in shared memory.
+ *  Parameters:
+ *      hio_mgr:     Handle to a I/O manager.
+ *      pchnl:      Ptr to channel object
+ *      chnl_packet_obj:     Ptr to channel i/o request packet.
+ *  Returns:
+ *  Requires:
+ *      pchnl != NULL
+ *      pchnl->cio_reqs > 0
+ *      chnl_packet_obj != NULL
+ *  Ensures:
+ */
+extern void io_ddma_request_chnl(struct io_mgr *hio_mgr,
+                                struct chnl_object *pchnl,
+                                struct chnl_irp *chnl_packet_obj,
+                                u16 *mbx_val);
+
+/*
+ * Zero-copy IO functions
+ */
+
+/*
+ *  ======== io_ddzc_init_chnl_desc ========
+ *  Purpose:
+ *      Initialize ZCPY channel descriptor.
+ *  Parameters:
+ *      hio_mgr:     Handle to a I/O manager.
+ *      zid:        zero-copy channel identifier.
+ *  Returns:
+ *  Requires:
+ *     ddma_chnl_id < DDMA_MAXZCPYCHNLS
+ *     hio_mgr != Null
+ *  Ensures:
+ */
+extern void io_ddzc_init_chnl_desc(struct io_mgr *hio_mgr, u32 zid);
+
+/*
+ *  ======== io_ddzc_clear_chnl_desc ========
+ *  Purpose:
+ *      Clear DSP ZC channel descriptor.
+ *  Parameters:
+ *      hio_mgr:         Handle to a I/O manager.
+ *      ch_id:        ZC channel identifier.
+ *  Returns:
+ *  Requires:
+ *      hio_mgr is valid
+ *      ch_id < DDMA_MAXZCPYCHNLS
+ *  Ensures:
+ */
+extern void io_ddzc_clear_chnl_desc(struct io_mgr *hio_mgr, u32 ch_id);
+
+/*
+ *  ======== io_ddzc_request_chnl ========
+ *  Purpose:
+ *      Request zero-copy channel transfer. Sets up SM descriptors and
+ *      control fields in shared memory.
+ *  Parameters:
+ *      hio_mgr:         Handle to a I/O manager.
+ *      pchnl:          Ptr to channel object
+ *      chnl_packet_obj:         Ptr to channel i/o request packet.
+ *  Returns:
+ *  Requires:
+ *      pchnl != NULL
+ *      pchnl->cio_reqs > 0
+ *      chnl_packet_obj != NULL
+ *  Ensures:
+ */
+extern void io_ddzc_request_chnl(struct io_mgr *hio_mgr,
+                                struct chnl_object *pchnl,
+                                struct chnl_irp *chnl_packet_obj,
+                                u16 *mbx_val);
+
+/*
+ *  ======== io_sh_msetting ========
+ *  Purpose:
+ *      Sets the shared memory setting
+ *  Parameters:
+ *      hio_mgr:         Handle to a I/O manager.
+ *      desc:             Shared memory type
+ *      pargs:          Ptr to shm setting
+ *  Returns:
+ *  Requires:
+ *      hio_mgr != NULL
+ *      pargs != NULL
+ *  Ensures:
+ */
+extern int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs);
+
+/*
+ *  Misc functions for the CHNL_IO shared memory library:
+ */
+
+/* Maximum channel bufsize that can be used. */
+extern u32 io_buf_size(struct io_mgr *hio_mgr);
+
+extern u32 io_read_value(struct bridge_dev_context *dev_ctxt, u32 dsp_addr);
+
+extern void io_write_value(struct bridge_dev_context *dev_ctxt,
+                          u32 dsp_addr, u32 value);
+
+extern u32 io_read_value_long(struct bridge_dev_context *dev_ctxt,
+                             u32 dsp_addr);
+
+extern void io_write_value_long(struct bridge_dev_context *dev_ctxt,
+                               u32 dsp_addr, u32 value);
+
+extern void io_or_set_value(struct bridge_dev_context *dev_ctxt,
+                           u32 dsp_addr, u32 value);
+
+extern void io_and_set_value(struct bridge_dev_context *dev_ctxt,
+                            u32 dsp_addr, u32 value);
+
+extern void io_sm_init(void);
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+/*
+ *  ========print_dsp_trace_buffer ========
+ *      Print DSP tracebuffer.
+ */
+extern int print_dsp_trace_buffer(struct bridge_dev_context
+                                        *hbridge_context);
+
+int dump_dsp_stack(struct bridge_dev_context *bridge_context);
+
+void dump_dl_modules(struct bridge_dev_context *bridge_context);
+
+#endif
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+void print_dsp_debug_trace(struct io_mgr *hio_mgr);
+#endif
+
+#endif /* IOSM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/iodefs.h b/drivers/staging/tidspbridge/include/dspbridge/iodefs.h
new file mode 100644 (file)
index 0000000..8bd10a0
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * iodefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * System-wide channel objects and constants.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef IODEFS_
+#define IODEFS_
+
+#define IO_MAXIRQ   0xff       /* Arbitrarily large number. */
+
+/* IO Objects: */
+struct io_mgr;
+
+/* IO manager attributes: */
+struct io_attrs {
+       u8 birq;                /* Channel's I/O IRQ number. */
+       bool irq_shared;        /* TRUE if the IRQ is shareable. */
+       u32 word_size;          /* DSP Word size. */
+       u32 shm_base;           /* Physical base address of shared memory. */
+       u32 usm_length;         /* Size (in bytes) of shared memory. */
+};
+
+#endif /* IODEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/ldr.h b/drivers/staging/tidspbridge/include/dspbridge/ldr.h
new file mode 100644 (file)
index 0000000..6a0269c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * ldr.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Provide module loading services and symbol export services.
+ *
+ * Notes:
+ *   This service is meant to be used by modules of the DSP/BIOS Bridge
+ *   driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef LDR_
+#define LDR_
+
+/* Loader objects: */
+struct ldr_module;
+
+#endif /* LDR_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/list.h b/drivers/staging/tidspbridge/include/dspbridge/list.h
new file mode 100644 (file)
index 0000000..6837b61
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * list.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Declarations of list management control structures and definitions
+ * of inline list management functions.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef LIST_
+#define LIST_
+
+#include <dspbridge/host_os.h>
+#include <linux/list.h>
+
+#define LST_IS_EMPTY(l)      list_empty(&(l)->head)
+
+struct lst_list {
+       struct list_head head;
+};
+
+/*
+ *  ======== lst_first ========
+ *  Purpose:
+ *      Returns a pointer to the first element of the list, or NULL if the list
+ *      is empty.
+ *  Parameters:
+ *      lst:  Pointer to list control structure.
+ *  Returns:
+ *      Pointer to first list element, or NULL.
+ *  Requires:
+ *      - LST initialized.
+ *      - lst != NULL.
+ *  Ensures:
+ */
+static inline struct list_head *lst_first(struct lst_list *lst)
+{
+       if (lst && !list_empty(&lst->head))
+               return lst->head.next;
+       return NULL;
+}
+
+/*
+ *  ======== lst_get_head ========
+ *  Purpose:
+ *      Pops the head off the list and returns a pointer to it.
+ *  Details:
+ *      If the list is empty, returns NULL.
+ *      Else, removes the element at the head of the list, making the next
+ *      element the head of the list.
+ *      The head is removed by making the tail element of the list point its
+ *      "next" pointer at the next element after the head, and by making the
+ *      "prev" pointer of the next element after the head point at the tail
+ *      element.  So the next element after the head becomes the new head of
+ *      the list.
+ *  Parameters:
+ *      lst:    Pointer to list control structure of list whose head
+ *              element is to be removed
+ *  Returns:
+ *      Pointer to element that was at the head of the list (success)
+ *      NULL          No elements in list
+ *  Requires:
+ *      - LST initialized.
+ *      - lst != NULL.
+ *  Ensures:
+ *  Notes:
+ *      Because the tail of the list points forward (its "next" pointer) to
+ *      the head of the list, and the head of the list points backward (its
+ *      "prev" pointer) to the tail of the list, this list is circular.
+ */
+static inline struct list_head *lst_get_head(struct lst_list *lst)
+{
+       struct list_head *elem_list;
+
+       if (!lst || list_empty(&lst->head))
+               return NULL;
+
+       elem_list = lst->head.next;
+       lst->head.next = elem_list->next;
+       elem_list->next->prev = &lst->head;
+
+       return elem_list;
+}
+
+/*
+ *  ======== lst_init_elem ========
+ *  Purpose:
+ *      Initializes a list element to default (cleared) values
+ *  Details:
+ *  Parameters:
+ *      elem_list:  Pointer to list element to be reset
+ *  Returns:
+ *  Requires:
+ *      LST initialized.
+ *  Ensures:
+ *  Notes:
+ *      This function must not be called to "reset" an element in the middle
+ *      of a list chain -- that would break the chain.
+ *
+ */
+static inline void lst_init_elem(struct list_head *elem_list)
+{
+       if (elem_list) {
+               elem_list->next = NULL;
+               elem_list->prev = NULL;
+       }
+}
+
+/*
+ *  ======== lst_insert_before ========
+ *  Purpose:
+ *     Insert the element before the existing element.
+ *  Parameters:
+ *      lst:            Pointer to list control structure.
+ *      elem_list:          Pointer to element in list to insert.
+ *      elem_existing:  Pointer to existing list element.
+ *  Returns:
+ *  Requires:
+ *      - LST initialized.
+ *      - lst != NULL.
+ *      - elem_list != NULL.
+ *      - elem_existing != NULL.
+ *  Ensures:
+ */
+static inline void lst_insert_before(struct lst_list *lst,
+                                    struct list_head *elem_list,
+                                    struct list_head *elem_existing)
+{
+       if (lst && elem_list && elem_existing)
+               list_add_tail(elem_list, elem_existing);
+}
+
+/*
+ *  ======== lst_next ========
+ *  Purpose:
+ *      Returns a pointer to the next element of the list, or NULL if the next
+ *      element is the head of the list or the list is empty.
+ *  Parameters:
+ *      lst:        Pointer to list control structure.
+ *      cur_elem:   Pointer to element in list to remove.
+ *  Returns:
+ *      Pointer to list element, or NULL.
+ *  Requires:
+ *      - LST initialized.
+ *      - lst != NULL.
+ *      - cur_elem != NULL.
+ *  Ensures:
+ */
+static inline struct list_head *lst_next(struct lst_list *lst,
+                                        struct list_head *cur_elem)
+{
+       if (lst && !list_empty(&lst->head) && cur_elem &&
+           (cur_elem->next != &lst->head))
+               return cur_elem->next;
+       return NULL;
+}
+
+/*
+ *  ======== lst_put_tail ========
+ *  Purpose:
+ *      Adds the specified element to the tail of the list
+ *  Details:
+ *      Sets new element's "prev" pointer to the address previously held by
+ *      the head element's prev pointer.  This is the previous tail member of
+ *      the list.
+ *      Sets the new head's prev pointer to the address of the element.
+ *      Sets next pointer of the previous tail member of the list to point to
+ *      the new element (rather than the head, which it had been pointing at).
+ *      Sets new element's next pointer to the address of the head element.
+ *      Sets head's prev pointer to the address of the new element.
+ *  Parameters:
+ *      lst:    Pointer to list control structure to which *elem_list will be
+ *              added
+ *      elem_list:  Pointer to list element to be added
+ *  Returns:
+ *      Void
+ *  Requires:
+ *      *elem_list and *lst must both exist.
+ *      LST initialized.
+ *  Ensures:
+ *  Notes:
+ *      Because the tail is always "just before" the head of the list (the
+ *      tail's "next" pointer points at the head of the list, and the head's
+ *      "prev" pointer points at the tail of the list), the list is circular.
+ */
+static inline void lst_put_tail(struct lst_list *lst,
+                               struct list_head *elem_list)
+{
+       if (lst && elem_list)
+               list_add_tail(elem_list, &lst->head);
+}
+
+/*
+ *  ======== lst_remove_elem ========
+ *  Purpose:
+ *      Removes (unlinks) the given element from the list, if the list is not
+ *      empty.  Does not free the list element.
+ *  Parameters:
+ *      lst:        Pointer to list control structure.
+ *      cur_elem:   Pointer to element in list to remove.
+ *  Returns:
+ *  Requires:
+ *      - LST initialized.
+ *      - lst != NULL.
+ *      - cur_elem != NULL.
+ *  Ensures:
+ */
+static inline void lst_remove_elem(struct lst_list *lst,
+                                  struct list_head *cur_elem)
+{
+       if (lst && !list_empty(&lst->head) && cur_elem)
+               list_del_init(cur_elem);
+}
+
+#endif /* LIST_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h b/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h
new file mode 100644 (file)
index 0000000..5d165cd
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * mbx_sh.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Definitions for shared mailbox cmd/data values.(used on both
+ * the GPP and DSP sides).
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *  Bridge usage of OMAP mailbox 1 is determined by the "class" of the
+ *  mailbox interrupt's cmd value received. The class value are defined
+ *  as a bit (10 thru 15) being set.
+ *
+ *  Note: Only 16 bits of each  is used. Other 16 bit data reg available.
+ *
+ *   16 bit Mbx bit defns:
+ *
+ * A). Exception/Error handling (Module DEH) : class = 0.
+ *
+ *    15         10                  0
+ *   ---------------------------------
+ *   |0|0|0|0|0|0|x|x|x|x|x|x|x|x|x|x|
+ *   ---------------------------------
+ *   |  (class)  | (module specific) |
+ *
+ *
+ * B: DSP-DMA link driver channels (DDMA) : class = 1.
+ *
+ *    15         10                  0
+ *   ---------------------------------
+ *   |0|0|0|0|0|1|b|b|b|b|b|c|c|c|c|c|
+ *   ---------------------------------
+ *   |  (class)  | (module specific) |
+ *
+ *   where b -> buffer index  (32 DDMA buffers/chnl max)
+ *         c -> channel Id    (32 DDMA chnls max)
+ *
+ *
+ * C: Proc-copy link driver channels (PCPY) : class = 2.
+ *
+ *    15         10                  0
+ *   ---------------------------------
+ *   |0|0|0|0|1|0|x|x|x|x|x|x|x|x|x|x|
+ *   ---------------------------------
+ *   |  (class)  | (module specific) |
+ *
+ *
+ * D: Zero-copy link driver channels (DDZC) : class = 4.
+ *
+ *    15         10                  0
+ *   ---------------------------------
+ *   |0|0|0|1|0|0|x|x|x|x|x|c|c|c|c|c|
+ *   ---------------------------------
+ *   |  (class)  | (module specific) |
+ *
+ *   where x -> not used
+ *         c -> channel Id    (32 ZCPY chnls max)
+ *
+ *
+ * E: Power management : class = 8.
+ *
+ *    15         10                  0
+ *   ---------------------------------
+ *   |0|0|1|0|0|0|x|x|x|x|x|c|c|c|c|c|
+
+ *     0010 00xx xxxc cccc
+ *     0010 00nn pppp qqqq
+ *     nn:
+ *     00 = reserved
+ *     01 = pwr state change
+ *     10 = opp pre-change
+ *     11 = opp post-change
+ *
+ *     if nn = pwr state change:
+ *     pppp = don't care
+ *     qqqq:
+ *     0010 = hibernate
+ *     0010 0001 0000 0010
+ *     0110 = retention
+ *     0010 0001 0000 0110
+ *     others reserved
+ *
+ *     if nn = opp pre-change:
+ *     pppp = current opp
+ *     qqqq = next opp
+ *
+ *     if nn = opp post-change:
+ *     pppp = prev opp
+ *     qqqq = current opp
+ *
+ *   ---------------------------------
+ *   |  (class)  | (module specific) |
+ *
+ *   where x -> not used
+ *         c -> Power management command
+ *
+ */
+
+#ifndef _MBX_SH_H
+#define _MBX_SH_H
+
+#define MBX_CLASS_MSK      0xFC00      /* Class bits are 10 thru 15 */
+#define MBX_VALUE_MSK      0x03FF      /* Value is 0 thru 9 */
+
+#define MBX_DEH_CLASS      0x0000      /* DEH owns Mbx INTR */
+#define MBX_DDMA_CLASS     0x0400      /* DSP-DMA link drvr chnls owns INTR */
+#define MBX_PCPY_CLASS     0x0800      /* PROC-COPY  " */
+#define MBX_ZCPY_CLASS     0x1000      /* ZERO-COPY  " */
+#define MBX_PM_CLASS       0x2000      /* Power Management */
+#define MBX_DBG_CLASS      0x4000      /* For debugging purpose */
+
+/*
+ * Exception Handler codes
+ * Magic code used to determine if DSP signaled exception.
+ */
+#define MBX_DEH_BASE        0x0
+#define MBX_DEH_USERS_BASE  0x100      /* 256 */
+#define MBX_DEH_LIMIT       0x3FF      /* 1023 */
+#define MBX_DEH_RESET       0x101      /* DSP RESET (DEH) */
+#define MBX_DEH_EMMU        0X103      /*DSP MMU FAULT RECOVERY */
+
+/*
+ *  Link driver command/status codes.
+ */
+/* DSP-DMA */
+#define MBX_DDMA_NUMCHNLBITS 5 /* # chnl Id: # bits available */
+#define MBX_DDMA_CHNLSHIFT   0 /* # of bits to shift */
+#define MBX_DDMA_CHNLMSK     0x01F     /* bits 0 thru 4 */
+
+#define MBX_DDMA_NUMBUFBITS  5 /* buffer index: # of bits avail */
+#define MBX_DDMA_BUFSHIFT    (MBX_DDMA_NUMCHNLBITS + MBX_DDMA_CHNLSHIFT)
+#define MBX_DDMA_BUFMSK      0x3E0     /* bits 5 thru 9 */
+
+/* Zero-Copy */
+#define MBX_ZCPY_NUMCHNLBITS 5 /* # chnl Id: # bits available */
+#define MBX_ZCPY_CHNLSHIFT   0 /* # of bits to shift */
+#define MBX_ZCPY_CHNLMSK     0x01F     /* bits 0 thru 4 */
+
+/*  Power Management Commands */
+#define MBX_PM_DSPIDLE                  (MBX_PM_CLASS + 0x0)
+#define MBX_PM_DSPWAKEUP                (MBX_PM_CLASS + 0x1)
+#define MBX_PM_EMERGENCYSLEEP           (MBX_PM_CLASS + 0x2)
+#define MBX_PM_SLEEPUNTILRESTART        (MBX_PM_CLASS + 0x3)
+#define MBX_PM_DSPGLOBALIDLE_OFF        (MBX_PM_CLASS + 0x4)
+#define MBX_PM_DSPGLOBALIDLE_ON         (MBX_PM_CLASS + 0x5)
+#define MBX_PM_SETPOINT_PRENOTIFY       (MBX_PM_CLASS + 0x6)
+#define MBX_PM_SETPOINT_POSTNOTIFY      (MBX_PM_CLASS + 0x7)
+#define MBX_PM_DSPRETN                  (MBX_PM_CLASS + 0x8)
+#define MBX_PM_DSPRETENTION        (MBX_PM_CLASS + 0x8)
+#define MBX_PM_DSPHIBERNATE        (MBX_PM_CLASS + 0x9)
+#define MBX_PM_HIBERNATE_EN        (MBX_PM_CLASS + 0xA)
+#define MBX_PM_OPP_REQ                  (MBX_PM_CLASS + 0xB)
+#define MBX_PM_OPP_CHG                  (MBX_PM_CLASS + 0xC)
+
+#define MBX_PM_TYPE_MASK 0x0300
+#define MBX_PM_TYPE_PWR_CHNG 0x0100
+#define MBX_PM_TYPE_OPP_PRECHNG 0x0200
+#define MBX_PM_TYPE_OPP_POSTCHNG 0x0300
+#define MBX_PM_TYPE_OPP_MASK 0x0300
+#define MBX_PM_OPP_PRECHNG (MBX_PM_CLASS | MBX_PM_TYPE_OPP_PRECHNG)
+/* DSP to MPU */
+#define MBX_PM_OPP_CHNG(OPP) (MBX_PM_CLASS | MBX_PM_TYPE_OPP_PRECHNG | (OPP))
+#define MBX_PM_RET (MBX_PM_CLASS | MBX_PM_TYPE_PWR_CHNG | 0x0006)
+#define MBX_PM_HIB (MBX_PM_CLASS | MBX_PM_TYPE_PWR_CHNG | 0x0002)
+#define MBX_PM_OPP1 0
+#define MBX_PM_OPP2 1
+#define MBX_PM_OPP3 2
+#define MBX_PM_OPP4 3
+
+/* Bridge Debug Commands */
+#define MBX_DBG_SYSPRINTF       (MBX_DBG_CLASS + 0x0)
+
+#endif /* _MBX_SH_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/memdefs.h b/drivers/staging/tidspbridge/include/dspbridge/memdefs.h
new file mode 100644 (file)
index 0000000..78d2c5d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * memdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global MEM constants and types, shared between Bridge driver and DSP API.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef MEMDEFS_
+#define MEMDEFS_
+
+/*
+ *  MEM_VIRTUALSEGID is used by Node & Strm to access virtual address space in
+ *  the correct client process context.
+ */
+#define MEM_SETVIRTUALSEGID     0x10000000
+#define MEM_GETVIRTUALSEGID     0x20000000
+#define MEM_MASKVIRTUALSEGID    (MEM_SETVIRTUALSEGID | MEM_GETVIRTUALSEGID)
+
+#endif /* MEMDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgr.h b/drivers/staging/tidspbridge/include/dspbridge/mgr.h
new file mode 100644 (file)
index 0000000..99f7dc0
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * mgr.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This is the DSP API RM module interface.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef MGR_
+#define MGR_
+
+#include <dspbridge/mgrpriv.h>
+
+#define MAX_EVENTS 32
+
+/*
+ *  ======== mgr_wait_for_bridge_events ========
+ *  Purpose:
+ *      Block on any Bridge event(s)
+ *  Parameters:
+ *      anotifications  : array of pointers to notification objects.
+ *      count          : number of elements in above array
+ *      pu_index         : index of signaled event object
+ *      utimeout        : timeout interval in milliseocnds
+ *  Returns:
+ *      0         : Success.
+ *      -ETIME    : Wait timed out. *pu_index is undetermined.
+ *  Details:
+ */
+
+int mgr_wait_for_bridge_events(struct dsp_notification
+                                     **anotifications,
+                                     u32 count, u32 *pu_index,
+                                     u32 utimeout);
+
+/*
+ *  ======== mgr_create ========
+ *  Purpose:
+ *      Creates the Manager Object. This is done during the driver loading.
+ *      There is only one Manager Object in the DSP/BIOS Bridge.
+ *  Parameters:
+ *      mgr_obj:        Location to store created MGR Object handle.
+ *      dev_node_obj:       Device object as known to the system.
+ *  Returns:
+ *      0:        Success
+ *      -ENOMEM:    Failed to Create the Object
+ *      -EPERM:      General Failure
+ *  Requires:
+ *      MGR Initialized (refs > 0 )
+ *      mgr_obj != NULL.
+ *  Ensures:
+ *      0:        *mgr_obj is a valid MGR interface to the device.
+ *                      MGR Object stores the DCD Manager Handle.
+ *                      MGR Object stored in the Regsitry.
+ *      !0:       MGR Object not created
+ *  Details:
+ *      DCD Dll is loaded and MGR Object stores the handle of the DLL.
+ */
+extern int mgr_create(struct mgr_object **mgr_obj,
+                            struct cfg_devnode *dev_node_obj);
+
+/*
+ *  ======== mgr_destroy ========
+ *  Purpose:
+ *      Destroys the MGR object. Called upon driver unloading.
+ *  Parameters:
+ *      hmgr_obj:     Handle to Manager object .
+ *  Returns:
+ *      0:        Success.
+ *                      DCD Manager freed; MGR Object destroyed;
+ *                      MGR Object deleted from the Registry.
+ *      -EPERM:      Failed to destroy MGR Object
+ *  Requires:
+ *      MGR Initialized (refs > 0 )
+ *      hmgr_obj is a valid MGR handle .
+ *  Ensures:
+ *      0:        MGR Object destroyed and hmgr_obj is Invalid MGR
+ *                      Handle.
+ */
+extern int mgr_destroy(struct mgr_object *hmgr_obj);
+
+/*
+ *  ======== mgr_enum_node_info ========
+ *  Purpose:
+ *      Enumerate and get configuration information about nodes configured
+ *      in the node database.
+ *  Parameters:
+ *      node_id:              The node index (base 0).
+ *      pndb_props:          Ptr to the dsp_ndbprops structure for output.
+ *      undb_props_size:      Size of the dsp_ndbprops structure.
+ *      pu_num_nodes:         Location where the number of nodes configured
+ *                          in the database will be returned.
+ *  Returns:
+ *      0:            Success.
+ *      -EINVAL:    Parameter node_id is > than the number of nodes.
+ *                          configutred in the system
+ *      -EIDRM:  During Enumeration there has been a change in
+ *                              the number of nodes configured or in the
+ *                              the properties of the enumerated nodes.
+ *      -EPERM:          Failed to querry the Node Data Base
+ *  Requires:
+ *      pNDBPROPS is not null
+ *      undb_props_size >= sizeof(dsp_ndbprops)
+ *      pu_num_nodes is not null
+ *      MGR Initialized (refs > 0 )
+ *  Ensures:
+ *      SUCCESS on successful retreival of data and *pu_num_nodes > 0 OR
+ *      DSP_FAILED  && *pu_num_nodes == 0.
+ *  Details:
+ */
+extern int mgr_enum_node_info(u32 node_id,
+                                    struct dsp_ndbprops *pndb_props,
+                                    u32 undb_props_size,
+                                    u32 *pu_num_nodes);
+
+/*
+ *  ======== mgr_enum_processor_info ========
+ *  Purpose:
+ *      Enumerate and get configuration information about available DSP
+ *      processors
+ *  Parameters:
+ *      processor_id:         The processor index (zero-based).
+ *      processor_info:     Ptr to the dsp_processorinfo structure .
+ *      processor_info_size: Size of dsp_processorinfo structure.
+ *      pu_num_procs:         Location where the number of DSPs configured
+ *                          in the database will be returned
+ *  Returns:
+ *      0:            Success.
+ *      -EINVAL:    Parameter processor_id is > than the number of
+ *                          DSP Processors in the system.
+ *      -EPERM:          Failed to querry the Node Data Base
+ *  Requires:
+ *      processor_info is not null
+ *      pu_num_procs is not null
+ *      processor_info_size >= sizeof(dsp_processorinfo)
+ *      MGR Initialized (refs > 0 )
+ *  Ensures:
+ *      SUCCESS on successful retreival of data and *pu_num_procs > 0 OR
+ *      DSP_FAILED && *pu_num_procs == 0.
+ *  Details:
+ */
+extern int mgr_enum_processor_info(u32 processor_id,
+                                         struct dsp_processorinfo
+                                         *processor_info,
+                                         u32 processor_info_size,
+                                         u8 *pu_num_procs);
+/*
+ *  ======== mgr_exit ========
+ *  Purpose:
+ *      Decrement reference count, and free resources when reference count is
+ *      0.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      MGR is initialized.
+ *  Ensures:
+ *      When reference count == 0, MGR's private resources are freed.
+ */
+extern void mgr_exit(void);
+
+/*
+ *  ======== mgr_get_dcd_handle ========
+ *  Purpose:
+ *      Retrieves the MGR handle. Accessor Function
+ *  Parameters:
+ *      mgr_handle:     Handle to the Manager Object
+ *      dcd_handle:     Ptr to receive the DCD Handle.
+ *  Returns:
+ *      0:        Sucess
+ *      -EPERM:      Failure to get the Handle
+ *  Requires:
+ *      MGR is initialized.
+ *      dcd_handle != NULL
+ *  Ensures:
+ *      0 and *dcd_handle != NULL ||
+ *      -EPERM and *dcd_handle == NULL
+ */
+extern int mgr_get_dcd_handle(struct mgr_object
+                                    *mgr_handle, u32 *dcd_handle);
+
+/*
+ *  ======== mgr_init ========
+ *  Purpose:
+ *      Initialize MGR's private state, keeping a reference count on each
+ *      call. Intializes the DCD.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occured.
+ *  Requires:
+ *  Ensures:
+ *      TRUE: A requirement for the other public MGR functions.
+ */
+extern bool mgr_init(void);
+
+#endif /* MGR_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h b/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h
new file mode 100644 (file)
index 0000000..bca4e10
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * mgrpriv.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global MGR constants and types, shared by PROC, MGR, and DSP API.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef MGRPRIV_
+#define MGRPRIV_
+
+/*
+ * OMAP1510 specific
+ */
+#define MGR_MAXTLBENTRIES  32
+
+/* RM MGR Object */
+struct mgr_object;
+
+struct mgr_tlbentry {
+       u32 ul_dsp_virt;        /* DSP virtual address */
+       u32 ul_gpp_phys;        /* GPP physical address */
+};
+
+/*
+ *  The DSP_PROCESSOREXTINFO structure describes additional extended
+ *  capabilities of a DSP processor not exposed to user.
+ */
+struct mgr_processorextinfo {
+       struct dsp_processorinfo ty_basic;      /* user processor info */
+       /* private dsp mmu entries */
+       struct mgr_tlbentry ty_tlb[MGR_MAXTLBENTRIES];
+};
+
+#endif /* MGRPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/msg.h b/drivers/staging/tidspbridge/include/dspbridge/msg.h
new file mode 100644 (file)
index 0000000..95778bc
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * msg.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge msg_ctrl Module.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef MSG_
+#define MSG_
+
+#include <dspbridge/devdefs.h>
+#include <dspbridge/msgdefs.h>
+
+/*
+ *  ======== msg_create ========
+ *  Purpose:
+ *      Create an object to manage message queues. Only one of these objects
+ *      can exist per device object. The msg_ctrl manager must be created before
+ *      the IO Manager.
+ *  Parameters:
+ *      msg_man:            Location to store msg_ctrl manager handle on output.
+ *      hdev_obj:         The device object.
+ *      msg_callback:        Called whenever an RMS_EXIT message is received.
+ *  Returns:
+ *  Requires:
+ *      msg_mod_init(void) called.
+ *      msg_man != NULL.
+ *      hdev_obj != NULL.
+ *      msg_callback != NULL.
+ *  Ensures:
+ */
+extern int msg_create(struct msg_mgr **msg_man,
+                            struct dev_object *hdev_obj,
+                            msg_onexit msg_callback);
+
+/*
+ *  ======== msg_delete ========
+ *  Purpose:
+ *      Delete a msg_ctrl manager allocated in msg_create().
+ *  Parameters:
+ *      hmsg_mgr:            Handle returned from msg_create().
+ *  Returns:
+ *  Requires:
+ *      msg_mod_init(void) called.
+ *      Valid hmsg_mgr.
+ *  Ensures:
+ */
+extern void msg_delete(struct msg_mgr *hmsg_mgr);
+
+/*
+ *  ======== msg_exit ========
+ *  Purpose:
+ *      Discontinue usage of msg_ctrl module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      msg_mod_init(void) successfully called before.
+ *  Ensures:
+ *      Any resources acquired in msg_mod_init(void) will be freed when last
+ *      msg_ctrl client calls msg_exit(void).
+ */
+extern void msg_exit(void);
+
+/*
+ *  ======== msg_mod_init ========
+ *  Purpose:
+ *      Initialize the msg_ctrl module.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialization succeeded, FALSE otherwise.
+ *  Ensures:
+ */
+extern bool msg_mod_init(void);
+
+#endif /* MSG_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h
new file mode 100644 (file)
index 0000000..80a3fa1
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * msgdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global msg_ctrl constants and types.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef MSGDEFS_
+#define MSGDEFS_
+
+/* msg_ctrl Objects: */
+struct msg_mgr;
+struct msg_queue;
+
+/* Function prototype for callback to be called on RMS_EXIT message received */
+typedef void (*msg_onexit) (void *h, s32 node_status);
+
+#endif /* MSGDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldr.h b/drivers/staging/tidspbridge/include/dspbridge/nldr.h
new file mode 100644 (file)
index 0000000..d9653ee
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * nldr.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge dynamic loader interface.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/dbdcddef.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/rmm.h>
+#include <dspbridge/nldrdefs.h>
+
+#ifndef NLDR_
+#define NLDR_
+
+extern int nldr_allocate(struct nldr_object *nldr_obj,
+                               void *priv_ref, const struct dcd_nodeprops
+                               *node_props,
+                               struct nldr_nodeobject **nldr_nodeobj,
+                               bool *pf_phase_split);
+
+extern int nldr_create(struct nldr_object **nldr,
+                             struct dev_object *hdev_obj,
+                             const struct nldr_attrs *pattrs);
+
+extern void nldr_delete(struct nldr_object *nldr_obj);
+extern void nldr_exit(void);
+
+extern int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj,
+                                   char *str_fxn, u32 * addr);
+
+extern int nldr_get_rmm_manager(struct nldr_object *nldr,
+                                      struct rmm_target_obj **rmm_mgr);
+
+extern bool nldr_init(void);
+extern int nldr_load(struct nldr_nodeobject *nldr_node_obj,
+                           enum nldr_phase phase);
+extern int nldr_unload(struct nldr_nodeobject *nldr_node_obj,
+                             enum nldr_phase phase);
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr,
+       u32 offset_range, void *offset_output, char *sym_name);
+#endif
+
+#endif /* NLDR_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h
new file mode 100644 (file)
index 0000000..c85d3da
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * nldrdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global Dynamic + static/overlay Node loader (NLDR) constants and types.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef NLDRDEFS_
+#define NLDRDEFS_
+
+#include <dspbridge/dbdcddef.h>
+#include <dspbridge/devdefs.h>
+
+#define NLDR_MAXPATHLENGTH       255
+/* NLDR Objects: */
+struct nldr_object;
+struct nldr_nodeobject;
+
+/*
+ *  ======== nldr_loadtype ========
+ *  Load types for a node. Must match values in node.h55.
+ */
+enum nldr_loadtype {
+       NLDR_STATICLOAD,        /* Linked in base image, not overlay */
+       NLDR_DYNAMICLOAD,       /* Dynamically loaded node */
+       NLDR_OVLYLOAD           /* Linked in base image, overlay node */
+};
+
+/*
+ *  ======== nldr_ovlyfxn ========
+ *  Causes code or data to be copied from load address to run address. This
+ *  is the "cod_writefxn" that gets passed to the DBLL_Library and is used as
+ *  the ZL write function.
+ *
+ *  Parameters:
+ *      priv_ref:       Handle to identify the node.
+ *      dsp_run_addr:   Run address of code or data.
+ *      dsp_load_addr:  Load address of code or data.
+ *      ul_num_bytes:     Number of (GPP) bytes to copy.
+ *      mem_space:      RMS_CODE or RMS_DATA.
+ *  Returns:
+ *      ul_num_bytes:     Success.
+ *      0:              Failure.
+ *  Requires:
+ *  Ensures:
+ */
+typedef u32(*nldr_ovlyfxn) (void *priv_ref, u32 dsp_run_addr,
+                           u32 dsp_load_addr, u32 ul_num_bytes, u32 mem_space);
+
+/*
+ *  ======== nldr_writefxn ========
+ *  Write memory function. Used for dynamic load writes.
+ *  Parameters:
+ *      priv_ref:       Handle to identify the node.
+ *      dsp_add:        Address of code or data.
+ *      pbuf:           Code or data to be written
+ *      ul_num_bytes:     Number of (GPP) bytes to write.
+ *      mem_space:      DBLL_DATA or DBLL_CODE.
+ *  Returns:
+ *      ul_num_bytes:     Success.
+ *      0:              Failure.
+ *  Requires:
+ *  Ensures:
+ */
+typedef u32(*nldr_writefxn) (void *priv_ref,
+                            u32 dsp_add, void *pbuf,
+                            u32 ul_num_bytes, u32 mem_space);
+
+/*
+ *  ======== nldr_attrs ========
+ *  Attributes passed to nldr_create function.
+ */
+struct nldr_attrs {
+       nldr_ovlyfxn pfn_ovly;
+       nldr_writefxn pfn_write;
+       u16 us_dsp_word_size;
+       u16 us_dsp_mau_size;
+};
+
+/*
+ *  ======== nldr_phase ========
+ *  Indicates node create, delete, or execute phase function.
+ */
+enum nldr_phase {
+       NLDR_CREATE,
+       NLDR_DELETE,
+       NLDR_EXECUTE,
+       NLDR_NOPHASE
+};
+
+/*
+ *  Typedefs of loader functions imported from a DLL, or defined in a
+ *  function table.
+ */
+
+/*
+ *  ======== nldr_allocate ========
+ *  Allocate resources to manage the loading of a node on the DSP.
+ *
+ *  Parameters:
+ *      nldr_obj:          Handle of loader that will load the node.
+ *      priv_ref:       Handle to identify the node.
+ *      node_props:     Pointer to a dcd_nodeprops for the node.
+ *      nldr_nodeobj:   Location to store node handle on output. This handle
+ *                      will be passed to nldr_load/nldr_unload.
+ *      pf_phase_split:   pointer to int variable referenced in node.c
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Insufficient memory on GPP.
+ *  Requires:
+ *      nldr_init(void) called.
+ *      Valid nldr_obj.
+ *      node_props != NULL.
+ *      nldr_nodeobj != NULL.
+ *  Ensures:
+ *      0:        IsValidNode(*nldr_nodeobj).
+ *      error:          *nldr_nodeobj == NULL.
+ */
+typedef int(*nldr_allocatefxn) (struct nldr_object *nldr_obj,
+                                      void *priv_ref,
+                                      const struct dcd_nodeprops
+                                      * node_props,
+                                      struct nldr_nodeobject
+                                      **nldr_nodeobj,
+                                      bool *pf_phase_split);
+
+/*
+ *  ======== nldr_create ========
+ *  Create a loader object. This object handles the loading and unloading of
+ *  create, delete, and execute phase functions of nodes on the DSP target.
+ *
+ *  Parameters:
+ *      nldr:           Location to store loader handle on output.
+ *      hdev_obj:     Device for this processor.
+ *      pattrs:         Loader attributes.
+ *  Returns:
+ *      0:        Success;
+ *      -ENOMEM:    Insufficient memory for requested resources.
+ *  Requires:
+ *      nldr_init(void) called.
+ *      nldr != NULL.
+ *      hdev_obj != NULL.
+ *     pattrs != NULL.
+ *  Ensures:
+ *      0:        Valid *nldr.
+ *      error:          *nldr == NULL.
+ */
+typedef int(*nldr_createfxn) (struct nldr_object **nldr,
+                                    struct dev_object *hdev_obj,
+                                    const struct nldr_attrs *pattrs);
+
+/*
+ *  ======== nldr_delete ========
+ *  Delete the NLDR loader.
+ *
+ *  Parameters:
+ *      nldr_obj:          Node manager object.
+ *  Returns:
+ *  Requires:
+ *      nldr_init(void) called.
+ *      Valid nldr_obj.
+ *  Ensures:
+ *     nldr_obj invalid
+ */
+typedef void (*nldr_deletefxn) (struct nldr_object *nldr_obj);
+
+/*
+ *  ======== nldr_exit ========
+ *  Discontinue usage of NLDR module.
+ *
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      nldr_init(void) successfully called before.
+ *  Ensures:
+ *      Any resources acquired in nldr_init(void) will be freed when last NLDR
+ *      client calls nldr_exit(void).
+ */
+typedef void (*nldr_exitfxn) (void);
+
+/*
+ *  ======== NLDR_Free ========
+ *  Free resources allocated in nldr_allocate.
+ *
+ *  Parameters:
+ *      nldr_node_obj:      Handle returned from nldr_allocate().
+ *  Returns:
+ *  Requires:
+ *      nldr_init(void) called.
+ *      Valid nldr_node_obj.
+ *  Ensures:
+ */
+typedef void (*nldr_freefxn) (struct nldr_nodeobject *nldr_node_obj);
+
+/*
+ *  ======== nldr_get_fxn_addr ========
+ *  Get address of create, delete, or execute phase function of a node on
+ *  the DSP.
+ *
+ *  Parameters:
+ *      nldr_node_obj:      Handle returned from nldr_allocate().
+ *      str_fxn:        Name of function.
+ *      addr:           Location to store function address.
+ *  Returns:
+ *      0:        Success.
+ *      -ESPIPE:    Address of function not found.
+ *  Requires:
+ *      nldr_init(void) called.
+ *      Valid nldr_node_obj.
+ *      addr != NULL;
+ *      str_fxn != NULL;
+ *  Ensures:
+ */
+typedef int(*nldr_getfxnaddrfxn) (struct nldr_nodeobject
+                                        * nldr_node_obj,
+                                        char *str_fxn, u32 * addr);
+
+/*
+ *  ======== nldr_init ========
+ *  Initialize the NLDR module.
+ *
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialization succeeded, FALSE otherwise.
+ *  Ensures:
+ */
+typedef bool(*nldr_initfxn) (void);
+
+/*
+ *  ======== nldr_load ========
+ *  Load create, delete, or execute phase function of a node on the DSP.
+ *
+ *  Parameters:
+ *      nldr_node_obj:      Handle returned from nldr_allocate().
+ *      phase:          Type of function to load (create, delete, or execute).
+ *  Returns:
+ *      0:                Success.
+ *      -ENOMEM:            Insufficient memory on GPP.
+ *      -ENXIO:     Can't overlay phase because overlay memory
+ *                              is already in use.
+ *      -EILSEQ:           Failure in dynamic loader library.
+ *  Requires:
+ *      nldr_init(void) called.
+ *      Valid nldr_node_obj.
+ *  Ensures:
+ */
+typedef int(*nldr_loadfxn) (struct nldr_nodeobject *nldr_node_obj,
+                                  enum nldr_phase phase);
+
+/*
+ *  ======== nldr_unload ========
+ *  Unload create, delete, or execute phase function of a node on the DSP.
+ *
+ *  Parameters:
+ *      nldr_node_obj:      Handle returned from nldr_allocate().
+ *      phase:          Node function to unload (create, delete, or execute).
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Insufficient memory on GPP.
+ *  Requires:
+ *      nldr_init(void) called.
+ *      Valid nldr_node_obj.
+ *  Ensures:
+ */
+typedef int(*nldr_unloadfxn) (struct nldr_nodeobject *nldr_node_obj,
+                                    enum nldr_phase phase);
+
+/*
+ *  ======== node_ldr_fxns ========
+ */
+struct node_ldr_fxns {
+       nldr_allocatefxn pfn_allocate;
+       nldr_createfxn pfn_create;
+       nldr_deletefxn pfn_delete;
+       nldr_exitfxn pfn_exit;
+       nldr_getfxnaddrfxn pfn_get_fxn_addr;
+       nldr_initfxn pfn_init;
+       nldr_loadfxn pfn_load;
+       nldr_unloadfxn pfn_unload;
+};
+
+#endif /* NLDRDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h
new file mode 100644 (file)
index 0000000..49ed5c1
--- /dev/null
@@ -0,0 +1,583 @@
+/*
+ * node.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge Node Manager.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef NODE_
+#define NODE_
+
+#include <dspbridge/procpriv.h>
+
+#include <dspbridge/nodedefs.h>
+#include <dspbridge/dispdefs.h>
+#include <dspbridge/nldrdefs.h>
+#include <dspbridge/drv.h>
+
+/*
+ *  ======== node_allocate ========
+ *  Purpose:
+ *      Allocate GPP resources to manage a node on the DSP.
+ *  Parameters:
+ *      hprocessor:         Handle of processor that is allocating the node.
+ *      node_uuid:          Pointer to a dsp_uuid for the node.
+ *      pargs:              Optional arguments to be passed to the node.
+ *      attr_in:            Optional pointer to node attributes (priority,
+ *                          timeout...)
+ *      noderes:             Location to store node resource info.
+ *  Returns:
+ *      0:            Success.
+ *      -ENOMEM:        Insufficient memory on GPP.
+ *      -ENOKEY:          Node UUID has not been registered.
+ *      -ESPIPE:        iAlg functions not found for a DAIS node.
+ *      -EDOM:         attr_in != NULL and attr_in->prio out of
+ *                          range.
+ *      -EPERM:          A failure occured, unable to allocate node.
+ *      -EBADR:    Proccessor is not in the running state.
+ *  Requires:
+ *      node_init(void) called.
+ *      hprocessor != NULL.
+ *      node_uuid != NULL.
+ *      noderes != NULL.
+ *  Ensures:
+ *      0:            IsValidNode(*ph_node).
+ *      error:              *noderes == NULL.
+ */
+extern int node_allocate(struct proc_object *hprocessor,
+                               const struct dsp_uuid *node_uuid,
+                               const struct dsp_cbdata
+                               *pargs, const struct dsp_nodeattrin
+                               *attr_in,
+                               struct node_res_object **noderes,
+                               struct process_context *pr_ctxt);
+
+/*
+ *  ======== node_alloc_msg_buf ========
+ *  Purpose:
+ *      Allocate and Prepare a buffer whose descriptor will be passed to a
+ *      Node within a (dsp_msg)message
+ *  Parameters:
+ *      hnode:          The node handle.
+ *      usize:          The size of the buffer to be allocated.
+ *      pattr:          Pointer to a dsp_bufferattr structure.
+ *      pbuffer:        Location to store the address of the allocated
+ *                      buffer on output.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid node handle.
+ *      -ENOMEM:    Insufficent memory.
+ *      -EPERM:      General Failure.
+ *      -EINVAL:      Invalid Size.
+ *  Requires:
+ *      node_init(void) called.
+ *      pbuffer != NULL.
+ *  Ensures:
+ */
+extern int node_alloc_msg_buf(struct node_object *hnode,
+                                    u32 usize, struct dsp_bufferattr
+                                    *pattr, u8 **pbuffer);
+
+/*
+ *  ======== node_change_priority ========
+ *  Purpose:
+ *      Change the priority of an allocated node.
+ *  Parameters:
+ *      hnode:              Node handle returned from node_allocate.
+ *      prio:          New priority level to set node's priority to.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid hnode.
+ *      -EDOM:         prio is out of range.
+ *      -EPERM: The specified node is not a task node.
+ *              Unable to change node's runtime priority level.
+ *      -EBADR:    Node is not in the NODE_ALLOCATED, NODE_PAUSED,
+ *                          or NODE_RUNNING state.
+ *      -ETIME:       A timeout occurred before the DSP responded.
+ *  Requires:
+ *      node_init(void) called.
+ *  Ensures:
+ *      0 && (Node's current priority == prio)
+ */
+extern int node_change_priority(struct node_object *hnode, s32 prio);
+
+/*
+ *  ======== node_close_orphans ========
+ *  Purpose:
+ *      Delete all nodes whose owning processor is being destroyed.
+ *  Parameters:
+ *      hnode_mgr:       Node manager object.
+ *      proc:          Handle to processor object being destroyed.
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Unable to delete all nodes belonging to proc.
+ *  Requires:
+ *      Valid hnode_mgr.
+ *      proc != NULL.
+ *  Ensures:
+ */
+extern int node_close_orphans(struct node_mgr *hnode_mgr,
+                                    struct proc_object *proc);
+
+/*
+ *  ======== node_connect ========
+ *  Purpose:
+ *      Connect two nodes on the DSP, or a node on the DSP to the GPP. In the
+ *      case that the connnection is being made between a node on the DSP and
+ *      the GPP, one of the node handles (either node1 or node2) must be
+ *      the constant NODE_HGPPNODE.
+ *  Parameters:
+ *      node1:         Handle of first node to connect to second node. If
+ *                      this is a connection from the GPP to node2, node1
+ *                      must be the constant NODE_HGPPNODE. Otherwise, node1
+ *                      must be a node handle returned from a successful call
+ *                      to Node_Allocate().
+ *      node2:         Handle of second node. Must be either NODE_HGPPNODE
+ *                      if this is a connection from DSP node to GPP, or a
+ *                      node handle returned from a successful call to
+ *                      node_allocate().
+ *      stream1:        Output stream index on first node, to be connected
+ *                      to second node's input stream. Value must range from
+ *                      0 <= stream1 < number of output streams.
+ *      stream2:        Input stream index on second node. Value must range
+ *                      from 0 <= stream2 < number of input streams.
+ *      pattrs:         Stream attributes (NULL ==> use defaults).
+ *      conn_param:     A pointer to a dsp_cbdata structure that defines
+ *                      connection parameter for device nodes to pass to DSP
+ *                      side.
+ *                      If the value of this parameter is NULL, then this API
+ *                      behaves like DSPNode_Connect. This parameter will have
+ *                      length of the string and the null terminated string in
+ *                      dsp_cbdata struct. This can be extended in future tp
+ *                      pass binary data.
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT:            Invalid node1 or node2.
+ *      -ENOMEM:            Insufficient host memory.
+ *      -EINVAL:             A stream index parameter is invalid.
+ *      -EISCONN:  A connection already exists for one of the
+ *                              indices stream1 or stream2.
+ *      -EBADR:        Either node1 or node2 is not in the
+ *                              NODE_ALLOCATED state.
+ *      -ECONNREFUSED: No more connections available.
+ *      -EPERM:              Attempt to make an illegal connection (eg,
+ *                              Device node to device node, or device node to
+ *                              GPP), the two nodes are on different DSPs.
+ *  Requires:
+ *      node_init(void) called.
+ *  Ensures:
+ */
+extern int node_connect(struct node_object *node1,
+                              u32 stream1,
+                              struct node_object *node2,
+                              u32 stream2,
+                              struct dsp_strmattr *pattrs,
+                              struct dsp_cbdata
+                              *conn_param);
+
+/*
+ *  ======== node_create ========
+ *  Purpose:
+ *      Create a node on the DSP by remotely calling the node's create
+ *      function. If necessary, load code that contains the node's create
+ *      function.
+ *  Parameters:
+ *      hnode:              Node handle returned from node_allocate().
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid hnode.
+ *      -ESPIPE:        Create function not found in the COFF file.
+ *      -EBADR:    Node is not in the NODE_ALLOCATED state.
+ *      -ENOMEM:        Memory allocation failure on the DSP.
+ *      -ETIME:       A timeout occurred before the DSP responded.
+ *      -EPERM:          A failure occurred, unable to create node.
+ *  Requires:
+ *      node_init(void) called.
+ *  Ensures:
+ */
+extern int node_create(struct node_object *hnode);
+
+/*
+ *  ======== node_create_mgr ========
+ *  Purpose:
+ *      Create a NODE Manager object. This object handles the creation,
+ *      deletion, and execution of nodes on the DSP target. The NODE Manager
+ *      also maintains a pipe map of used and available node connections.
+ *      Each DEV object should have exactly one NODE Manager object.
+ *
+ *  Parameters:
+ *      node_man:       Location to store node manager handle on output.
+ *      hdev_obj:     Device for this processor.
+ *  Returns:
+ *      0:        Success;
+ *      -ENOMEM:    Insufficient memory for requested resources.
+ *      -EPERM:      General failure.
+ *  Requires:
+ *      node_init(void) called.
+ *      node_man != NULL.
+ *      hdev_obj != NULL.
+ *  Ensures:
+ *      0:        Valide *node_man.
+ *      error:          *node_man == NULL.
+ */
+extern int node_create_mgr(struct node_mgr **node_man,
+                                 struct dev_object *hdev_obj);
+
+/*
+ *  ======== node_delete ========
+ *  Purpose:
+ *      Delete resources allocated in node_allocate(). If the node was
+ *      created, delete the node on the DSP by remotely calling the node's
+ *      delete function. Loads the node's delete function if necessary.
+ *      GPP side resources are freed after node's delete function returns.
+ *  Parameters:
+ *      noderes:              Node resource info handle returned from
+ *                                 node_allocate().
+ *      pr_ctxt:                Poninter to process context data.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid hnode.
+ *      -ETIME:       A timeout occurred before the DSP responded.
+ *      -EPERM:          A failure occurred in deleting the node.
+ *      -ESPIPE:        Delete function not found in the COFF file.
+ *  Requires:
+ *      node_init(void) called.
+ *  Ensures:
+ *      0:            hnode is invalid.
+ */
+extern int node_delete(struct node_res_object *noderes,
+                             struct process_context *pr_ctxt);
+
+/*
+ *  ======== node_delete_mgr ========
+ *  Purpose:
+ *      Delete the NODE Manager.
+ *  Parameters:
+ *      hnode_mgr:       Node manager object.
+ *  Returns:
+ *      0:        Success.
+ *  Requires:
+ *      node_init(void) called.
+ *      Valid hnode_mgr.
+ *  Ensures:
+ */
+extern int node_delete_mgr(struct node_mgr *hnode_mgr);
+
+/*
+ *  ======== node_enum_nodes ========
+ *  Purpose:
+ *      Enumerate the nodes currently allocated for the DSP.
+ *  Parameters:
+ *      hnode_mgr:       Node manager returned from node_create_mgr().
+ *      node_tab:       Array to copy node handles into.
+ *      node_tab_size:   Number of handles that can be written to node_tab.
+ *      pu_num_nodes:     Location where number of node handles written to
+ *                      node_tab will be written.
+ *      pu_allocated:    Location to write total number of allocated nodes.
+ *  Returns:
+ *      0:        Success.
+ *      -EINVAL:      node_tab is too small to hold all node handles.
+ *  Requires:
+ *      Valid hnode_mgr.
+ *      node_tab != NULL || node_tab_size == 0.
+ *      pu_num_nodes != NULL.
+ *      pu_allocated != NULL.
+ *  Ensures:
+ *      - (-EINVAL && *pu_num_nodes == 0)
+ *      - || (0 && *pu_num_nodes <= node_tab_size)  &&
+ *        (*pu_allocated == *pu_num_nodes)
+ */
+extern int node_enum_nodes(struct node_mgr *hnode_mgr,
+                                 void **node_tab,
+                                 u32 node_tab_size,
+                                 u32 *pu_num_nodes,
+                                 u32 *pu_allocated);
+
+/*
+ *  ======== node_exit ========
+ *  Purpose:
+ *      Discontinue usage of NODE module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      node_init(void) successfully called before.
+ *  Ensures:
+ *      Any resources acquired in node_init(void) will be freed when last NODE
+ *      client calls node_exit(void).
+ */
+extern void node_exit(void);
+
+/*
+ *  ======== node_free_msg_buf ========
+ *  Purpose:
+ *      Free a message buffer previously allocated with node_alloc_msg_buf.
+ *  Parameters:
+ *      hnode:          The node handle.
+ *      pbuffer:        (Address) Buffer allocated by node_alloc_msg_buf.
+ *      pattr:          Same buffer attributes passed to node_alloc_msg_buf.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid node handle.
+ *      -EPERM:      Failure to free the buffer.
+ *  Requires:
+ *      node_init(void) called.
+ *      pbuffer != NULL.
+ *  Ensures:
+ */
+extern int node_free_msg_buf(struct node_object *hnode,
+                                   u8 *pbuffer,
+                                   struct dsp_bufferattr
+                                   *pattr);
+
+/*
+ *  ======== node_get_attr ========
+ *  Purpose:
+ *      Copy the current attributes of the specified node into a dsp_nodeattr
+ *      structure.
+ *  Parameters:
+ *      hnode:          Node object allocated from node_allocate().
+ *      pattr:          Pointer to dsp_nodeattr structure to copy node's
+ *                      attributes.
+ *      attr_size:      Size of pattr.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hnode.
+ *  Requires:
+ *      node_init(void) called.
+ *      pattr != NULL.
+ *  Ensures:
+ *      0:        *pattrs contains the node's current attributes.
+ */
+extern int node_get_attr(struct node_object *hnode,
+                               struct dsp_nodeattr *pattr, u32 attr_size);
+
+/*
+ *  ======== node_get_message ========
+ *  Purpose:
+ *      Retrieve a message from a node on the DSP. The node must be either a
+ *      message node, task node, or XDAIS socket node.
+ *      If a message is not available, this function will block until a
+ *      message is available, or the node's timeout value is reached.
+ *  Parameters:
+ *      hnode:          Node handle returned from node_allocate().
+ *      message:       Pointer to dsp_msg structure to copy the
+ *                      message into.
+ *      utimeout:       Timeout in milliseconds to wait for message.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hnode.
+ *      -EPERM: Cannot retrieve messages from this type of node.
+ *              Error occurred while trying to retrieve a message.
+ *      -ETIME:   Timeout occurred and no message is available.
+ *  Requires:
+ *      node_init(void) called.
+ *      message != NULL.
+ *  Ensures:
+ */
+extern int node_get_message(struct node_object *hnode,
+                                  struct dsp_msg *message, u32 utimeout);
+
+/*
+ *  ======== node_get_nldr_obj ========
+ *  Purpose:
+ *      Retrieve the Nldr manager
+ *  Parameters:
+ *      hnode_mgr:       Node Manager
+ *      nldr_ovlyobj:   Pointer to a Nldr manager handle
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hnode.
+ *  Ensures:
+ */
+extern int node_get_nldr_obj(struct node_mgr *hnode_mgr,
+                                   struct nldr_object **nldr_ovlyobj);
+
+/*
+ *  ======== node_init ========
+ *  Purpose:
+ *      Initialize the NODE module.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialization succeeded, FALSE otherwise.
+ *  Ensures:
+ */
+extern bool node_init(void);
+
+/*
+ *  ======== node_on_exit ========
+ *  Purpose:
+ *      Gets called when RMS_EXIT is received for a node. PROC needs to pass
+ *      this function as a parameter to msg_create(). This function then gets
+ *      called by the Bridge driver when an exit message for a node is received.
+ *  Parameters:
+ *      hnode:      Handle of the node that the exit message is for.
+ *      node_status:    Return status of the node's execute phase.
+ *  Returns:
+ *  Ensures:
+ */
+void node_on_exit(struct node_object *hnode, s32 node_status);
+
+/*
+ *  ======== node_pause ========
+ *  Purpose:
+ *      Suspend execution of a node currently running on the DSP.
+ *  Parameters:
+ *      hnode:              Node object representing a node currently
+ *                          running on the DSP.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid hnode.
+ *      -EPERM: Node is not a task or socket node.
+ *              Failed to pause node.
+ *      -ETIME:       A timeout occurred before the DSP responded.
+ *      DSP_EWRONGSTSATE:   Node is not in NODE_RUNNING state.
+ *  Requires:
+ *      node_init(void) called.
+ *  Ensures:
+ */
+extern int node_pause(struct node_object *hnode);
+
+/*
+ *  ======== node_put_message ========
+ *  Purpose:
+ *      Send a message to a message node, task node, or XDAIS socket node.
+ *      This function will block until the message stream can accommodate
+ *      the message, or a timeout occurs. The message will be copied, so Msg
+ *      can be re-used immediately after return.
+ *  Parameters:
+ *      hnode:              Node handle returned by node_allocate().
+ *      pmsg:               Location of message to be sent to the node.
+ *      utimeout:           Timeout in msecs to wait.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid hnode.
+ *      -EPERM: Messages can't be sent to this type of node.
+ *              Unable to send message.
+ *      -ETIME:       Timeout occurred before message could be set.
+ *      -EBADR:    Node is in invalid state for sending messages.
+ *  Requires:
+ *      node_init(void) called.
+ *      pmsg != NULL.
+ *  Ensures:
+ */
+extern int node_put_message(struct node_object *hnode,
+                                  const struct dsp_msg *pmsg, u32 utimeout);
+
+/*
+ *  ======== node_register_notify ========
+ *  Purpose:
+ *      Register to be notified on specific events for this node.
+ *  Parameters:
+ *      hnode:          Node handle returned by node_allocate().
+ *      event_mask:     Mask of types of events to be notified about.
+ *      notify_type:    Type of notification to be sent.
+ *      hnotification:  Handle to be used for notification.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hnode.
+ *      -ENOMEM:    Insufficient memory on GPP.
+ *      -EINVAL:     event_mask is invalid.
+ *      -ENOSYS:   Notification type specified by notify_type is not
+ *                      supported.
+ *  Requires:
+ *      node_init(void) called.
+ *      hnotification != NULL.
+ *  Ensures:
+ */
+extern int node_register_notify(struct node_object *hnode,
+                                      u32 event_mask, u32 notify_type,
+                                      struct dsp_notification
+                                      *hnotification);
+
+/*
+ *  ======== node_run ========
+ *  Purpose:
+ *      Start execution of a node's execute phase, or resume execution of
+ *      a node that has been suspended (via node_pause()) on the DSP. Load
+ *      the node's execute function if necessary.
+ *  Parameters:
+ *      hnode:              Node object representing a node currently
+ *                          running on the DSP.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid hnode.
+ *      -EPERM: hnode doesn't represent a message, task or dais socket node.
+ *              Unable to start or resume execution.
+ *      -ETIME:       A timeout occurred before the DSP responded.
+ *      DSP_EWRONGSTSATE:   Node is not in NODE_PAUSED or NODE_CREATED state.
+ *      -ESPIPE:        Execute function not found in the COFF file.
+ *  Requires:
+ *      node_init(void) called.
+ *  Ensures:
+ */
+extern int node_run(struct node_object *hnode);
+
+/*
+ *  ======== node_terminate ========
+ *  Purpose:
+ *      Signal a node running on the DSP that it should exit its execute
+ *      phase function.
+ *  Parameters:
+ *      hnode:              Node object representing a node currently
+ *                          running on the DSP.
+ *      pstatus:            Location to store execute-phase function return
+ *                          value.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid hnode.
+ *      -ETIME:       A timeout occurred before the DSP responded.
+ *      -EPERM: Type of node specified cannot be terminated.
+ *              Unable to terminate the node.
+ *      -EBADR:    Operation not valid for the current node state.
+ *  Requires:
+ *      node_init(void) called.
+ *      pstatus != NULL.
+ *  Ensures:
+ */
+extern int node_terminate(struct node_object *hnode,
+                                int *pstatus);
+
+/*
+ *  ======== node_get_uuid_props ========
+ *  Purpose:
+ *      Fetch Node properties given the UUID
+ *  Parameters:
+ *
+ */
+extern int node_get_uuid_props(void *hprocessor,
+                                     const struct dsp_uuid *node_uuid,
+                                     struct dsp_ndbprops
+                                     *node_props);
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+/**
+ * node_find_addr() - Find the closest symbol to the given address.
+ *
+ * @node_mgr:          Node manager handle
+ * @sym_addr:          Given address to find the closest symbol
+ * @offset_range:              offset range to look fo the closest symbol
+ * @sym_addr_output:   Symbol Output address
+ * @sym_name:          String with the symbol name of the closest symbol
+ *
+ *     This function finds the closest symbol to the address where a MMU
+ *     Fault occurred on the DSP side.
+ */
+int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
+                               u32 offset_range, void *sym_addr_output,
+                               char *sym_name);
+
+enum node_state node_get_state(void *hnode);
+#endif
+
+#endif /* NODE_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h b/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h
new file mode 100644 (file)
index 0000000..fb9623d
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * nodedefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global NODE constants and types, shared by PROCESSOR, NODE, and DISP.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef NODEDEFS_
+#define NODEDEFS_
+
+#define NODE_SUSPENDEDPRI -1
+
+/* NODE Objects: */
+struct node_mgr;
+struct node_object;
+
+#endif /* NODEDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h b/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h
new file mode 100644 (file)
index 0000000..16b0233
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * nodepriv.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Private node header shared by NODE and DISP.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef NODEPRIV_
+#define NODEPRIV_
+
+#include <dspbridge/strmdefs.h>
+#include <dspbridge/nodedefs.h>
+#include <dspbridge/nldrdefs.h>
+
+/* DSP address of node environment structure */
+typedef u32 nodeenv;
+
+/*
+ *  Node create structures
+ */
+
+/* Message node */
+struct node_msgargs {
+       u32 max_msgs;           /* Max # of simultaneous messages for node */
+       u32 seg_id;             /* Segment for allocating message buffers */
+       u32 notify_type;        /* Notify type (SEM_post, SWI_post, etc.) */
+       u32 arg_length;         /* Length in 32-bit words of arg data block */
+       u8 *pdata;              /* Argument data for node */
+};
+
+struct node_strmdef {
+       u32 buf_size;           /* Size of buffers for SIO stream */
+       u32 num_bufs;           /* max # of buffers in SIO stream at once */
+       u32 seg_id;             /* Memory segment id to allocate buffers */
+       u32 utimeout;           /* Timeout for blocking SIO calls */
+       u32 buf_alignment;      /* Buffer alignment */
+       char *sz_device;        /* Device name for stream */
+};
+
+/* Task node */
+struct node_taskargs {
+       struct node_msgargs node_msg_args;
+       s32 prio;
+       u32 stack_size;
+       u32 sys_stack_size;
+       u32 stack_seg;
+       u32 udsp_heap_res_addr; /* DSP virtual heap address */
+       u32 udsp_heap_addr;     /* DSP virtual heap address */
+       u32 heap_size;          /* Heap size */
+       u32 ugpp_heap_addr;     /* GPP virtual heap address */
+       u32 profile_id;         /* Profile ID */
+       u32 num_inputs;
+       u32 num_outputs;
+       u32 ul_dais_arg;        /* Address of iAlg object */
+       struct node_strmdef *strm_in_def;
+       struct node_strmdef *strm_out_def;
+};
+
+/*
+ *  ======== node_createargs ========
+ */
+struct node_createargs {
+       union {
+               struct node_msgargs node_msg_args;
+               struct node_taskargs task_arg_obj;
+       } asa;
+};
+
+/*
+ *  ======== node_get_channel_id ========
+ *  Purpose:
+ *      Get the channel index reserved for a stream connection between the
+ *      host and a node. This index is reserved when node_connect() is called
+ *      to connect the node with the host. This index should be passed to
+ *      the CHNL_Open function when the stream is actually opened.
+ *  Parameters:
+ *      hnode:          Node object allocated from node_allocate().
+ *      dir:           Input (DSP_TONODE) or output (DSP_FROMNODE).
+ *      index:         Stream index.
+ *      chan_id:        Location to store channel index.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hnode.
+ *      -EPERM:  Not a task or DAIS socket node.
+ *      -EINVAL:     The node's stream corresponding to index and dir
+ *                      is not a stream to or from the host.
+ *  Requires:
+ *      node_init(void) called.
+ *      Valid dir.
+ *      chan_id != NULL.
+ *  Ensures:
+ */
+extern int node_get_channel_id(struct node_object *hnode,
+                                     u32 dir, u32 index, u32 *chan_id);
+
+/*
+ *  ======== node_get_strm_mgr ========
+ *  Purpose:
+ *      Get the STRM manager for a node.
+ *  Parameters:
+ *      hnode:          Node allocated with node_allocate().
+ *      strm_man:       Location to store STRM manager on output.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hnode.
+ *  Requires:
+ *      strm_man != NULL.
+ *  Ensures:
+ */
+extern int node_get_strm_mgr(struct node_object *hnode,
+                                   struct strm_mgr **strm_man);
+
+/*
+ *  ======== node_get_timeout ========
+ *  Purpose:
+ *      Get the timeout value of a node.
+ *  Parameters:
+ *      hnode:      Node allocated with node_allocate(), or DSP_HGPPNODE.
+ *  Returns:
+ *      Node's timeout value.
+ *  Requires:
+ *      Valid hnode.
+ *  Ensures:
+ */
+extern u32 node_get_timeout(struct node_object *hnode);
+
+/*
+ *  ======== node_get_type ========
+ *  Purpose:
+ *      Get the type (device, message, task, or XDAIS socket) of a node.
+ *  Parameters:
+ *      hnode:      Node allocated with node_allocate(), or DSP_HGPPNODE.
+ *  Returns:
+ *      Node type:  NODE_DEVICE, NODE_TASK, NODE_XDAIS, or NODE_GPP.
+ *  Requires:
+ *      Valid hnode.
+ *  Ensures:
+ */
+extern enum node_type node_get_type(struct node_object *hnode);
+
+/*
+ *  ======== get_node_info ========
+ *  Purpose:
+ *      Get node information without holding semaphore.
+ *  Parameters:
+ *      hnode:      Node allocated with node_allocate(), or DSP_HGPPNODE.
+ *  Returns:
+ *      Node info:  priority, device owner, no. of streams, execution state
+ *                  NDB properties.
+ *  Requires:
+ *      Valid hnode.
+ *  Ensures:
+ */
+extern void get_node_info(struct node_object *hnode,
+                         struct dsp_nodeinfo *node_info);
+
+/*
+ *  ======== node_get_load_type ========
+ *  Purpose:
+ *      Get the load type (dynamic, overlay, static) of a node.
+ *  Parameters:
+ *      hnode:      Node allocated with node_allocate(), or DSP_HGPPNODE.
+ *  Returns:
+ *      Node type:  NLDR_DYNAMICLOAD, NLDR_OVLYLOAD, NLDR_STATICLOAD
+ *  Requires:
+ *      Valid hnode.
+ *  Ensures:
+ */
+extern enum nldr_loadtype node_get_load_type(struct node_object *hnode);
+
+#endif /* NODEPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/ntfy.h b/drivers/staging/tidspbridge/include/dspbridge/ntfy.h
new file mode 100644 (file)
index 0000000..cbc8819
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * ntfy.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Manage lists of notification events.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef NTFY_
+#define NTFY_
+
+#include <dspbridge/host_os.h>
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/sync.h>
+
+/**
+ * ntfy_object - head structure to nofify dspbridge events
+ * @head:      List of notify objects
+ * @ntfy_lock: lock for list access.
+ *
+ */
+struct ntfy_object {
+       struct raw_notifier_head head;/* List of notifier objects */
+       spinlock_t ntfy_lock;   /* For critical sections */
+};
+
+/**
+ * ntfy_event - structure store specify event to be notified
+ * @noti_block:        List of notify objects
+ * @event:     event that it respond
+ * @type:      event type (only DSP_SIGNALEVENT supported)
+ * @sync_obj:  sync_event used to set the event
+ *
+ */
+struct ntfy_event {
+       struct notifier_block noti_block;
+       u32 event;      /* Events to be notified about */
+       u32 type;       /* Type of notification to be sent */
+       struct sync_object sync_obj;
+};
+
+
+/**
+ * dsp_notifier_event() - callback function to nofity events
+ * @this:              pointer to itself struct notifier_block
+ * @event:     event to be notified.
+ * @data:              Currently not used.
+ *
+ */
+int dsp_notifier_event(struct notifier_block *this, unsigned long event,
+                          void *data);
+
+/**
+ * ntfy_init() - Set the initial state of the ntfy_object structure.
+ * @no:                pointer to ntfy_object structure.
+ *
+ * This function sets the initial state of the ntfy_object in order it
+ * can be used by the other ntfy functions.
+ */
+
+static inline void ntfy_init(struct ntfy_object *no)
+{
+       spin_lock_init(&no->ntfy_lock);
+       RAW_INIT_NOTIFIER_HEAD(&no->head);
+}
+
+/**
+ * ntfy_delete() - delete list of nofy events registered.
+ * @ntfy_obj:  Pointer to the ntfy object structure.
+ *
+ * This function is used to remove all the notify events  registered.
+ * unregister function is not needed in this function, to unregister
+ * a ntfy_event please look at ntfy_register function.
+ *
+ */
+static inline void ntfy_delete(struct ntfy_object *ntfy_obj)
+{
+       struct ntfy_event *ne;
+       struct notifier_block *nb;
+
+       spin_lock_bh(&ntfy_obj->ntfy_lock);
+       nb = ntfy_obj->head.head;
+       while (nb) {
+               ne = container_of(nb, struct ntfy_event, noti_block);
+               nb = nb->next;
+               kfree(ne);
+       }
+       spin_unlock_bh(&ntfy_obj->ntfy_lock);
+}
+
+/**
+ * ntfy_notify() - nofity all event register for an specific event.
+ * @ntfy_obj:  Pointer to the ntfy_object structure.
+ * @event:     event to be notified.
+ *
+ * This function traverses all the ntfy events registers and
+ * set the event with mach with @event.
+ */
+static inline void ntfy_notify(struct ntfy_object *ntfy_obj, u32 event)
+{
+       spin_lock_bh(&ntfy_obj->ntfy_lock);
+       raw_notifier_call_chain(&ntfy_obj->head, event, NULL);
+       spin_unlock_bh(&ntfy_obj->ntfy_lock);
+}
+
+
+
+/**
+ * ntfy_init() - Create and initialize a ntfy_event structure.
+ * @event:     event that the ntfy event will respond
+ * @type               event type (only DSP_SIGNALEVENT supported)
+ *
+ * This function create a ntfy_event element and sets the event it will
+ * respond the ntfy_event in order it can be used by the other ntfy functions.
+ * In case of success it will return a pointer to the ntfy_event struct
+ * created. Otherwise it will return NULL;
+ */
+
+static inline struct ntfy_event *ntfy_event_create(u32 event, u32 type)
+{
+       struct ntfy_event *ne;
+       ne = kmalloc(sizeof(struct ntfy_event), GFP_KERNEL);
+       if (ne) {
+               sync_init_event(&ne->sync_obj);
+               ne->noti_block.notifier_call = dsp_notifier_event;
+               ne->event = event;
+               ne->type = type;
+       }
+       return ne;
+}
+
+/**
+ * ntfy_register() - register new ntfy_event into a given ntfy_object
+ * @ntfy_obj:  Pointer to the ntfy_object structure.
+ * @noti:              Pointer to the handle to be returned to the user space.
+ * @event      event that the ntfy event will respond
+ * @type               event type (only DSP_SIGNALEVENT supported)
+ *
+ * This function register a new ntfy_event into the ntfy_object list,
+ * which will respond to the @event passed.
+ * This function will return 0 in case of error.
+ * -EFAULT in case of bad pointers and
+ * DSP_EMemory in case of no memory to create ntfy_event.
+ */
+static  inline int ntfy_register(struct ntfy_object *ntfy_obj,
+                        struct dsp_notification *noti,
+                        u32 event, u32 type)
+{
+       struct ntfy_event *ne;
+       int status = 0;
+
+       if (!noti || !ntfy_obj) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       if (!event) {
+               status = -EINVAL;
+               goto func_end;
+       }
+       ne = ntfy_event_create(event, type);
+       if (!ne) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       noti->handle = &ne->sync_obj;
+
+       spin_lock_bh(&ntfy_obj->ntfy_lock);
+       raw_notifier_chain_register(&ntfy_obj->head, &ne->noti_block);
+       spin_unlock_bh(&ntfy_obj->ntfy_lock);
+func_end:
+       return status;
+}
+
+/**
+ * ntfy_unregister() - unregister a ntfy_event from a given ntfy_object
+ * @ntfy_obj:  Pointer to the ntfy_object structure.
+ * @noti:              Pointer to the event that will be removed.
+ *
+ * This function unregister a ntfy_event from the ntfy_object list,
+ * @noti contains the event which is wanted to be removed.
+ * This function will return 0 in case of error.
+ * -EFAULT in case of bad pointers and
+ * DSP_EMemory in case of no memory to create ntfy_event.
+ */
+static  inline int ntfy_unregister(struct ntfy_object *ntfy_obj,
+                        struct dsp_notification *noti)
+{
+       int status = 0;
+       struct ntfy_event *ne;
+
+       if (!noti || !ntfy_obj) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       ne = container_of((struct sync_object *)noti, struct ntfy_event,
+                                                               sync_obj);
+       spin_lock_bh(&ntfy_obj->ntfy_lock);
+       raw_notifier_chain_unregister(&ntfy_obj->head,
+                                               &ne->noti_block);
+       kfree(ne);
+       spin_unlock_bh(&ntfy_obj->ntfy_lock);
+func_end:
+       return status;
+}
+
+#endif                         /* NTFY_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h
new file mode 100644 (file)
index 0000000..5e09fd1
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * proc.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This is the DSP API RM module interface.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef PROC_
+#define PROC_
+
+#include <dspbridge/cfgdefs.h>
+#include <dspbridge/devdefs.h>
+#include <dspbridge/drv.h>
+
+extern char *iva_img;
+
+/*
+ *  ======== proc_attach ========
+ *  Purpose:
+ *      Prepare for communication with a particular DSP processor, and return
+ *      a handle to the processor object. The PROC Object gets created
+ *  Parameters:
+ *      processor_id  :           The processor index (zero-based).
+ *      hmgr_obj  :       Handle to the Manager Object
+ *      attr_in     :     Ptr to the dsp_processorattrin structure.
+ *                           A NULL value means use default values.
+ *      ph_processor :    Ptr to location to store processor handle.
+ *  Returns:
+ *      0     :           Success.
+ *      -EPERM   :        General failure.
+ *      -EFAULT :         Invalid processor handle.
+ *      0:   Success; Processor already attached.
+ *  Requires:
+ *      ph_processor != NULL.
+ *      PROC Initialized.
+ *  Ensures:
+ *      -EPERM, and *ph_processor == NULL, OR
+ *      Success and *ph_processor is a Valid Processor handle OR
+ *      0 and *ph_processor is a Valid Processor.
+ *  Details:
+ *      When attr_in is NULL, the default timeout value is 10 seconds.
+ */
+extern int proc_attach(u32 processor_id,
+                             const struct dsp_processorattrin
+                             *attr_in, void **ph_processor,
+                             struct process_context *pr_ctxt);
+
+/*
+ *  ======== proc_auto_start =========
+ *  Purpose:
+ *      A Particular device gets loaded with the default image
+ *      if the AutoStart flag is set.
+ *  Parameters:
+ *      hdev_obj  :   Handle to the Device
+ *  Returns:
+ *      0     :   On Successful Loading
+ *      -ENOENT   :   No DSP exec file found.
+ *      -EPERM   :   General Failure
+ *  Requires:
+ *      hdev_obj != NULL.
+ *      dev_node_obj != NULL.
+ *      PROC Initialized.
+ *  Ensures:
+ */
+extern int proc_auto_start(struct cfg_devnode *dev_node_obj,
+                                 struct dev_object *hdev_obj);
+
+/*
+ *  ======== proc_ctrl ========
+ *  Purpose:
+ *      Pass control information to the GPP device driver managing the DSP
+ *      processor. This will be an OEM-only function, and not part of the
+ *      'Bridge application developer's API.
+ *  Parameters:
+ *      hprocessor  :       The processor handle.
+ *      dw_cmd       :       Private driver IOCTL cmd ID.
+ *      pargs       :       Ptr to an driver defined argument structure.
+ *  Returns:
+ *      0     :       SUCCESS
+ *      -EFAULT :       Invalid processor handle.
+ *      -ETIME:       A Timeout Occured before the Control information
+ *                       could be sent.
+ *      -EPERM   :       General Failure.
+ *  Requires:
+ *      PROC Initialized.
+ *  Ensures
+ *  Details:
+ *      This function Calls bridge_dev_ctrl.
+ */
+extern int proc_ctrl(void *hprocessor,
+                           u32 dw_cmd, struct dsp_cbdata *arg);
+
+/*
+ *  ======== proc_detach ========
+ *  Purpose:
+ *      Close a DSP processor and de-allocate all (GPP) resources reserved
+ *      for it. The Processor Object is deleted.
+ *  Parameters:
+ *      pr_ctxt     :   The processor handle.
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   InValid Handle.
+ *      -EPERM   :   General failure.
+ *  Requires:
+ *      PROC Initialized.
+ *  Ensures:
+ *      PROC Object is destroyed.
+ */
+extern int proc_detach(struct process_context *pr_ctxt);
+
+/*
+ *  ======== proc_enum_nodes ========
+ *  Purpose:
+ *      Enumerate the nodes currently allocated on a processor.
+ *  Parameters:
+ *      hprocessor  :   The processor handle.
+ *      node_tab    :   The first Location of an array allocated for node
+ *                   handles.
+ *      node_tab_size:   The number of (DSP_HNODE) handles that can be held
+ *                   to the memory the client has allocated for node_tab
+ *      pu_num_nodes  :   Location where DSPProcessor_EnumNodes will return
+ *                   the number of valid handles written to node_tab
+ *      pu_allocated :   Location where DSPProcessor_EnumNodes will return
+ *                   the number of nodes that are allocated on the DSP.
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   Invalid processor handle.
+ *      -EINVAL   :   The amount of memory allocated for node_tab is
+ *                   insufficent. That is the number of nodes actually
+ *                   allocated on the DSP is greater than the value
+ *                   specified for node_tab_size.
+ *      -EPERM   :   Unable to get Resource Information.
+ *  Details:
+ *  Requires
+ *      pu_num_nodes is not NULL.
+ *      pu_allocated is not NULL.
+ *      node_tab is not NULL.
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_enum_nodes(void *hprocessor,
+                                 void **node_tab,
+                                 u32 node_tab_size,
+                                 u32 *pu_num_nodes,
+                                 u32 *pu_allocated);
+
+/*
+ *  ======== proc_get_resource_info ========
+ *  Purpose:
+ *      Enumerate the resources currently available on a processor.
+ *  Parameters:
+ *      hprocessor  :       The processor handle.
+ *      resource_type:      Type of resource .
+ *      resource_info:      Ptr to the dsp_resourceinfo structure.
+ *      resource_info_size:  Size of the structure.
+ *  Returns:
+ *      0     :       Success.
+ *      -EFAULT :       Invalid processor handle.
+ *      -EBADR:    The processor is not in the PROC_RUNNING state.
+ *      -ETIME:       A timeout occured before the DSP responded to the
+ *                       querry.
+ *      -EPERM   :       Unable to get Resource Information
+ *  Requires:
+ *      resource_info is not NULL.
+ *      Parameter resource_type is Valid.[TBD]
+ *      resource_info_size is >= sizeof dsp_resourceinfo struct.
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ *      This function currently returns
+ *      -ENOSYS, and does not write any data to the resource_info struct.
+ */
+extern int proc_get_resource_info(void *hprocessor,
+                                        u32 resource_type,
+                                        struct dsp_resourceinfo
+                                        *resource_info,
+                                        u32 resource_info_size);
+
+/*
+ *  ======== proc_exit ========
+ *  Purpose:
+ *      Decrement reference count, and free resources when reference count is
+ *      0.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      PROC is initialized.
+ *  Ensures:
+ *      When reference count == 0, PROC's private resources are freed.
+ */
+extern void proc_exit(void);
+
+/*
+ * ======== proc_get_dev_object =========
+ *  Purpose:
+ *      Returns the DEV Hanlde for a given Processor handle
+ *  Parameters:
+ *      hprocessor  :   Processor Handle
+ *      device_obj :    Location to store the DEV Handle.
+ *  Returns:
+ *      0     :   Success; *device_obj has Dev handle
+ *      -EPERM   :   Failure; *device_obj is zero.
+ *  Requires:
+ *      device_obj is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *      0     :   *device_obj is not NULL
+ *      -EPERM   :   *device_obj is NULL.
+ */
+extern int proc_get_dev_object(void *hprocessor,
+                                     struct dev_object **device_obj);
+
+/*
+ *  ======== proc_init ========
+ *  Purpose:
+ *      Initialize PROC's private state, keeping a reference count on each
+ *      call.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialized; FALSE if error occured.
+ *  Requires:
+ *  Ensures:
+ *      TRUE: A requirement for the other public PROC functions.
+ */
+extern bool proc_init(void);
+
+/*
+ *  ======== proc_get_state ========
+ *  Purpose:
+ *      Report the state of the specified DSP processor.
+ *  Parameters:
+ *      hprocessor  :   The processor handle.
+ *      proc_state_obj :   Ptr to location to store the dsp_processorstate
+ *                   structure.
+ *      state_info_size: Size of dsp_processorstate.
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   Invalid processor handle.
+ *      -EPERM   :   General failure while querying processor state.
+ *  Requires:
+ *      proc_state_obj is not NULL
+ *      state_info_size is >= than the size of dsp_processorstate structure.
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_get_state(void *hprocessor, struct dsp_processorstate
+                                *proc_state_obj, u32 state_info_size);
+
+/*
+ *  ======== PROC_GetProcessorID ========
+ *  Purpose:
+ *      Report the state of the specified DSP processor.
+ *  Parameters:
+ *      hprocessor  :   The processor handle.
+ *      proc_id      :   Processor ID
+ *
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   Invalid processor handle.
+ *      -EPERM   :   General failure while querying processor state.
+ *  Requires:
+ *      proc_state_obj is not NULL
+ *      state_info_size is >= than the size of dsp_processorstate structure.
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_get_processor_id(void *proc, u32 * proc_id);
+
+/*
+ *  ======== proc_get_trace ========
+ *  Purpose:
+ *      Retrieve the trace buffer from the specified DSP processor.
+ *  Parameters:
+ *      hprocessor  :   The processor handle.
+ *      pbuf   :   Ptr to buffer to hold trace output.
+ *      max_size    :   Maximum size of the output buffer.
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   Invalid processor handle.
+ *      -EPERM   :   General failure while retireving processor trace
+ *                   Buffer.
+ *  Requires:
+ *      pbuf is not NULL
+ *      max_size is > 0.
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_get_trace(void *hprocessor, u8 * pbuf, u32 max_size);
+
+/*
+ *  ======== proc_load ========
+ *  Purpose:
+ *      Reset a processor and load a new base program image.
+ *      This will be an OEM-only function.
+ *  Parameters:
+ *      hprocessor:       The processor handle.
+ *      argc_index:       The number of Arguments(strings)in the aArgV[]
+ *      user_args:       An Array of Arguments(Unicode Strings)
+ *      user_envp:       An Array of Environment settings(Unicode Strings)
+ *  Returns:
+ *      0:       Success.
+ *      -ENOENT:       The DSP Execuetable was not found.
+ *      -EFAULT:       Invalid processor handle.
+ *      -EPERM   :       Unable to Load the Processor
+ *  Requires:
+ *      user_args is not NULL
+ *      argc_index is > 0
+ *      PROC Initialized.
+ *  Ensures:
+ *      Success and ProcState == PROC_LOADED
+ *      or DSP_FAILED status.
+ *  Details:
+ *      Does not implement access rights to control which GPP application
+ *      can load the processor.
+ */
+extern int proc_load(void *hprocessor,
+                           const s32 argc_index, const char **user_args,
+                           const char **user_envp);
+
+/*
+ *  ======== proc_register_notify ========
+ *  Purpose:
+ *      Register to be notified of specific processor events
+ *  Parameters:
+ *      hprocessor  :   The processor handle.
+ *      event_mask  :   Mask of types of events to be notified about.
+ *      notify_type :   Type of notification to be sent.
+ *      hnotification:  Handle to be used for notification.
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   Invalid processor handle or hnotification.
+ *      -EINVAL  :   Parameter event_mask is Invalid
+ *      DSP_ENOTIMP :   The notification type specified in uNotifyMask
+ *                   is not supported.
+ *      -EPERM   :   Unable to register for notification.
+ *  Requires:
+ *      hnotification is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_register_notify(void *hprocessor,
+                                      u32 event_mask, u32 notify_type,
+                                      struct dsp_notification
+                                      *hnotification);
+
+/*
+ *  ======== proc_notify_clients ========
+ *  Purpose:
+ *      Notify the Processor Clients
+ *  Parameters:
+ *      proc       :   The processor handle.
+ *      events     :   Event to be notified about.
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   Invalid processor handle.
+ *      -EPERM   :   Failure to Set or Reset the Event
+ *  Requires:
+ *      events is Supported or Valid type of Event
+ *      proc is a valid handle
+ *      PROC Initialized.
+ *  Ensures:
+ */
+extern int proc_notify_clients(void *proc, u32 events);
+
+/*
+ *  ======== proc_notify_all_clients ========
+ *  Purpose:
+ *      Notify the Processor Clients
+ *  Parameters:
+ *      proc       :   The processor handle.
+ *      events     :   Event to be notified about.
+ *  Returns:
+ *      0     :   Success.
+ *      -EFAULT :   Invalid processor handle.
+ *      -EPERM   :   Failure to Set or Reset the Event
+ *  Requires:
+ *      events is Supported or Valid type of Event
+ *      proc is a valid handle
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ *      NODE And STRM would use this function to notify their clients
+ *      about the state changes in NODE or STRM.
+ */
+extern int proc_notify_all_clients(void *proc, u32 events);
+
+/*
+ *  ======== proc_start ========
+ *  Purpose:
+ *      Start a processor running.
+ *      Processor must be in PROC_LOADED state.
+ *      This will be an OEM-only function, and not part of the 'Bridge
+ *      application developer's API.
+ *  Parameters:
+ *      hprocessor  :       The processor handle.
+ *  Returns:
+ *      0     :       Success.
+ *      -EFAULT :       Invalid processor handle.
+ *      -EBADR:    Processor is not in PROC_LOADED state.
+ *      -EPERM   :       Unable to start the processor.
+ *  Requires:
+ *      PROC Initialized.
+ *  Ensures:
+ *      Success and ProcState == PROC_RUNNING or DSP_FAILED status.
+ *  Details:
+ */
+extern int proc_start(void *hprocessor);
+
+/*
+ *  ======== proc_stop ========
+ *  Purpose:
+ *      Start a processor running.
+ *      Processor must be in PROC_LOADED state.
+ *      This will be an OEM-only function, and not part of the 'Bridge
+ *      application developer's API.
+ *  Parameters:
+ *      hprocessor  :       The processor handle.
+ *  Returns:
+ *      0     :       Success.
+ *      -EFAULT :       Invalid processor handle.
+ *      -EBADR:    Processor is not in PROC_LOADED state.
+ *      -EPERM   :       Unable to start the processor.
+ *  Requires:
+ *      PROC Initialized.
+ *  Ensures:
+ *      Success and ProcState == PROC_RUNNING or DSP_FAILED status.
+ *  Details:
+ */
+extern int proc_stop(void *hprocessor);
+
+/*
+ *  ======== proc_end_dma ========
+ *  Purpose:
+ *      Begin a DMA transfer
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      pmpu_addr      :   Buffer start address
+ *      ul_size                :   Buffer size
+ *      dir            :   The direction of the transfer
+ *  Requires:
+ *      Memory was previously mapped.
+ */
+extern int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
+                                               enum dma_data_direction dir);
+/*
+ *  ======== proc_begin_dma ========
+ *  Purpose:
+ *      Begin a DMA transfer
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      pmpu_addr      :   Buffer start address
+ *      ul_size                :   Buffer size
+ *      dir            :   The direction of the transfer
+ *  Requires:
+ *      Memory was previously mapped.
+ */
+extern int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
+                                               enum dma_data_direction dir);
+
+/*
+ *  ======== proc_flush_memory ========
+ *  Purpose:
+ *      Flushes a buffer from the MPU data cache.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      pmpu_addr      :   Buffer start address
+ *      ul_size          :   Buffer size
+ *      ul_flags        :   Reserved.
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *  Requires:
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ *      All the arguments are currently ignored.
+ */
+extern int proc_flush_memory(void *hprocessor,
+                                   void *pmpu_addr, u32 ul_size, u32 ul_flags);
+
+/*
+ *  ======== proc_invalidate_memory ========
+ *  Purpose:
+ *      Invalidates a buffer from the MPU data cache.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      pmpu_addr      :   Buffer start address
+ *      ul_size          :   Buffer size
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *  Requires:
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ *      All the arguments are currently ignored.
+ */
+extern int proc_invalidate_memory(void *hprocessor,
+                                        void *pmpu_addr, u32 ul_size);
+
+/*
+ *  ======== proc_map ========
+ *  Purpose:
+ *      Maps a MPU buffer to DSP address space.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      pmpu_addr      :   Starting address of the memory region to map.
+ *      ul_size          :   Size of the memory region to map.
+ *      req_addr       :   Requested DSP start address. Offset-adjusted actual
+ *                       mapped address is in the last argument.
+ *      pp_map_addr       :   Ptr to DSP side mapped u8 address.
+ *      ul_map_attr       :   Optional endianness attributes, virt to phys flag.
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *      -ENOMEM     :   MPU side memory allocation error.
+ *      -ENOENT   :   Cannot find a reserved region starting with this
+ *                   :   address.
+ *  Requires:
+ *      pmpu_addr is not NULL
+ *      ul_size is not zero
+ *      pp_map_addr is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_map(void *hprocessor,
+                          void *pmpu_addr,
+                          u32 ul_size,
+                          void *req_addr,
+                          void **pp_map_addr, u32 ul_map_attr,
+                          struct process_context *pr_ctxt);
+
+/*
+ *  ======== proc_reserve_memory ========
+ *  Purpose:
+ *      Reserve a virtually contiguous region of DSP address space.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      ul_size          :   Size of the address space to reserve.
+ *      pp_rsv_addr       :   Ptr to DSP side reserved u8 address.
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *      -ENOMEM     :   Cannot reserve chunk of this size.
+ *  Requires:
+ *      pp_rsv_addr is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_reserve_memory(void *hprocessor,
+                                     u32 ul_size, void **pp_rsv_addr,
+                                     struct process_context *pr_ctxt);
+
+/*
+ *  ======== proc_un_map ========
+ *  Purpose:
+ *      Removes a MPU buffer mapping from the DSP address space.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      map_addr       :   Starting address of the mapped memory region.
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *      -ENOENT   :   Cannot find a mapped region starting with this
+ *                   :   address.
+ *  Requires:
+ *      map_addr is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_un_map(void *hprocessor, void *map_addr,
+                             struct process_context *pr_ctxt);
+
+/*
+ *  ======== proc_un_reserve_memory ========
+ *  Purpose:
+ *      Frees a previously reserved region of DSP address space.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      prsv_addr      :   Ptr to DSP side reservedBYTE address.
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *      -ENOENT   :   Cannot find a reserved region starting with this
+ *                   :   address.
+ *  Requires:
+ *      prsv_addr is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_un_reserve_memory(void *hprocessor,
+                                        void *prsv_addr,
+                                        struct process_context *pr_ctxt);
+
+#endif /* PROC_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/procpriv.h b/drivers/staging/tidspbridge/include/dspbridge/procpriv.h
new file mode 100644 (file)
index 0000000..77d1f0e
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * procpriv.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global PROC constants and types, shared by PROC, MGR and DSP API.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef PROCPRIV_
+#define PROCPRIV_
+
+/* RM PROC Object */
+struct proc_object;
+
+#endif /* PROCPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr.h b/drivers/staging/tidspbridge/include/dspbridge/pwr.h
new file mode 100644 (file)
index 0000000..a6dc783
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * pwr.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef PWR_
+#define PWR_
+
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/pwr_sh.h>
+
+/*
+ *  ======== pwr_sleep_dsp ========
+ *      Signal the DSP to go to sleep.
+ *
+ *  Parameters:
+ *      sleep_code:          New sleep state for DSP.  (Initially, valid codes
+ *                          are PWR_DEEPSLEEP or PWR_EMERGENCYDEEPSLEEP; both of
+ *                          these codes will simply put the DSP in deep sleep.)
+ *
+ *     timeout:            Maximum time (msec) that PWR should wait for
+ *                          confirmation that the DSP sleep state has been
+ *                          reached.  If PWR should simply send the command to
+ *                          the DSP to go to sleep and then return (i.e.,
+ *                          asynchrounous sleep), the timeout should be
+ *                          specified as zero.
+ *
+ *  Returns:
+ *      0:            Success.
+ *      0: Success, but the DSP was already asleep.
+ *      -EINVAL:    The specified sleep_code is not supported.
+ *      -ETIME:       A timeout occured while waiting for DSP sleep
+ *                          confirmation.
+ *      -EPERM:          General failure, unable to send sleep command to
+ *                          the DSP.
+ */
+extern int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout);
+
+/*
+ *  ======== pwr_wake_dsp ========
+ *    Signal the DSP to wake from sleep.
+ *
+ *  Parameters:
+ *     timeout:            Maximum time (msec) that PWR should wait for
+ *                          confirmation that the DSP is awake.  If PWR should
+ *                          simply send a command to the DSP to wake and then
+ *                          return (i.e., asynchrounous wake), timeout should
+ *                          be specified as zero.
+ *
+ *  Returns:
+ *      0:            Success.
+ *      0:  Success, but the DSP was already awake.
+ *      -ETIME:       A timeout occured while waiting for wake
+ *                          confirmation.
+ *      -EPERM:          General failure, unable to send wake command to
+ *                          the DSP.
+ */
+extern int pwr_wake_dsp(const u32 timeout);
+
+/*
+ *  ======== pwr_pm_pre_scale ========
+ *    Prescale notification to DSP.
+ *
+ *  Parameters:
+ *     voltage_domain:   The voltage domain for which notification is sent
+ *    level:                   The level of voltage domain
+ *
+ *  Returns:
+ *      0:            Success.
+ *      0:  Success, but the DSP was already awake.
+ *      -ETIME:       A timeout occured while waiting for wake
+ *                          confirmation.
+ *      -EPERM:          General failure, unable to send wake command to
+ *                          the DSP.
+ */
+extern int pwr_pm_pre_scale(u16 voltage_domain, u32 level);
+
+/*
+ *  ======== pwr_pm_post_scale ========
+ *    PostScale notification to DSP.
+ *
+ *  Parameters:
+ *     voltage_domain:   The voltage domain for which notification is sent
+ *    level:                   The level of voltage domain
+ *
+ *  Returns:
+ *      0:            Success.
+ *      0:  Success, but the DSP was already awake.
+ *      -ETIME:       A timeout occured while waiting for wake
+ *                          confirmation.
+ *      -EPERM:          General failure, unable to send wake command to
+ *                          the DSP.
+ */
+extern int pwr_pm_post_scale(u16 voltage_domain, u32 level);
+
+#endif /* PWR_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h b/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h
new file mode 100644 (file)
index 0000000..1b4a090
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * pwr_sh.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Power Manager shared definitions (used on both GPP and DSP sides).
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef PWR_SH_
+#define PWR_SH_
+
+#include <dspbridge/mbx_sh.h>
+
+/* valid sleep command codes that can be sent by GPP via mailbox: */
+#define PWR_DEEPSLEEP           MBX_PM_DSPIDLE
+#define PWR_EMERGENCYDEEPSLEEP  MBX_PM_EMERGENCYSLEEP
+#define PWR_SLEEPUNTILRESTART   MBX_PM_SLEEPUNTILRESTART
+#define PWR_WAKEUP              MBX_PM_DSPWAKEUP
+#define PWR_AUTOENABLE          MBX_PM_PWRENABLE
+#define PWR_AUTODISABLE         MBX_PM_PWRDISABLE
+#define PWR_RETENTION             MBX_PM_DSPRETN
+
+#endif /* PWR_SH_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h
new file mode 100644 (file)
index 0000000..dfaf0c6
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * resourcecleanup.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <dspbridge/nodepriv.h>
+#include <dspbridge/drv.h>
+
+extern int drv_get_proc_ctxt_list(struct process_context **pctxt,
+                                        struct drv_object *hdrv_obj);
+
+extern int drv_insert_proc_context(struct drv_object *driver_obj,
+                                         void *process_ctxt);
+
+extern int drv_remove_all_dmm_res_elements(void *process_ctxt);
+
+extern int drv_remove_all_node_res_elements(void *process_ctxt);
+
+extern int drv_proc_set_pid(void *ctxt, s32 process);
+
+extern int drv_remove_all_resources(void *process_ctxt);
+
+extern int drv_remove_proc_context(struct drv_object *driver_obj,
+                                         void *pr_ctxt);
+
+extern int drv_insert_node_res_element(void *hnode, void *node_resource,
+                                             void *process_ctxt);
+
+extern void drv_proc_node_update_heap_status(void *node_resource, s32 status);
+
+extern void drv_proc_node_update_status(void *node_resource, s32 status);
+
+extern int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources);
+
+extern int drv_proc_insert_strm_res_element(void *stream_obj,
+                                                  void *strm_res,
+                                                  void *process_ctxt);
+
+extern int drv_remove_all_strm_res_elements(void *process_ctxt);
+
+extern enum node_state node_get_state(void *hnode);
diff --git a/drivers/staging/tidspbridge/include/dspbridge/rmm.h b/drivers/staging/tidspbridge/include/dspbridge/rmm.h
new file mode 100644 (file)
index 0000000..baea536
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * rmm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This memory manager provides general heap management and arbitrary
+ * alignment for any number of memory segments, and management of overlay
+ * memory.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef RMM_
+#define RMM_
+
+/*
+ *  ======== rmm_addr ========
+ *  DSP address + segid
+ */
+struct rmm_addr {
+       u32 addr;
+       s32 segid;
+};
+
+/*
+ *  ======== rmm_segment ========
+ *  Memory segment on the DSP available for remote allocations.
+ */
+struct rmm_segment {
+       u32 base;               /* Base of the segment */
+       u32 length;             /* Size of the segment (target MAUs) */
+       s32 space;              /* Code or data */
+       u32 number;             /* Number of Allocated Blocks */
+};
+
+/*
+ *  ======== RMM_Target ========
+ */
+struct rmm_target_obj;
+
+/*
+ *  ======== rmm_alloc ========
+ *
+ *  rmm_alloc is used to remotely allocate or reserve memory on the DSP.
+ *
+ *  Parameters:
+ *      target          - Target returned from rmm_create().
+ *      segid           - Memory segment to allocate from.
+ *      size            - Size (target MAUS) to allocate.
+ *      align           - alignment.
+ *      dsp_address     - If reserve is FALSE, the location to store allocated
+ *                        address on output, otherwise, the DSP address to
+ *                        reserve.
+ *      reserve         - If TRUE, reserve the memory specified by dsp_address.
+ *  Returns:
+ *      0:                Success.
+ *      -ENOMEM:            Memory allocation on GPP failed.
+ *      -ENXIO:     Cannot "allocate" overlay memory because it's
+ *                              already in use.
+ *  Requires:
+ *      RMM initialized.
+ *      Valid target.
+ *      dsp_address != NULL.
+ *      size > 0
+ *      reserve || target->num_segs > 0.
+ *  Ensures:
+ */
+extern int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size,
+                       u32 align, u32 *dsp_address, bool reserve);
+
+/*
+ *  ======== rmm_create ========
+ *  Create a target object with memory segments for remote allocation. If
+ *  seg_tab == NULL or num_segs == 0, memory can only be reserved through
+ *  rmm_alloc().
+ *
+ *  Parameters:
+ *      target_obj:        - Location to store target on output.
+ *      seg_tab:         - Table of memory segments.
+ *      num_segs:        - Number of memory segments.
+ *  Returns:
+ *      0:        Success.
+ *      -ENOMEM:    Memory allocation failed.
+ *  Requires:
+ *      RMM initialized.
+ *      target_obj != NULL.
+ *      num_segs == 0 || seg_tab != NULL.
+ *  Ensures:
+ *      Success:        Valid *target_obj.
+ *      Failure:        *target_obj == NULL.
+ */
+extern int rmm_create(struct rmm_target_obj **target_obj,
+                            struct rmm_segment seg_tab[], u32 num_segs);
+
+/*
+ *  ======== rmm_delete ========
+ *  Delete target allocated in rmm_create().
+ *
+ *  Parameters:
+ *      target          - Target returned from rmm_create().
+ *  Returns:
+ *  Requires:
+ *      RMM initialized.
+ *      Valid target.
+ *  Ensures:
+ */
+extern void rmm_delete(struct rmm_target_obj *target);
+
+/*
+ *  ======== rmm_exit ========
+ *  Exit the RMM module
+ *
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      rmm_init successfully called.
+ *  Ensures:
+ */
+extern void rmm_exit(void);
+
+/*
+ *  ======== rmm_free ========
+ *  Free or unreserve memory allocated through rmm_alloc().
+ *
+ *  Parameters:
+ *      target:         - Target returned from rmm_create().
+ *      segid:          - Segment of memory to free.
+ *      dsp_address:    - Address to free or unreserve.
+ *      size:           - Size of memory to free or unreserve.
+ *      reserved:       - TRUE if memory was reserved only, otherwise FALSE.
+ *  Returns:
+ *  Requires:
+ *      RMM initialized.
+ *      Valid target.
+ *      reserved || segid < target->num_segs.
+ *      reserve || [dsp_address, dsp_address + size] is a valid memory range.
+ *  Ensures:
+ */
+extern bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr,
+                    u32 size, bool reserved);
+
+/*
+ *  ======== rmm_init ========
+ *  Initialize the RMM module
+ *
+ *  Parameters:
+ *  Returns:
+ *      TRUE:   Success.
+ *      FALSE:  Failure.
+ *  Requires:
+ *  Ensures:
+ */
+extern bool rmm_init(void);
+
+/*
+ *  ======== rmm_stat ========
+ *  Obtain  memory segment status
+ *
+ *  Parameters:
+ *      segid:       Segment ID of the dynamic loading segment.
+ *      mem_stat_buf: Pointer to allocated buffer into which memory stats are
+ *                   placed.
+ *  Returns:
+ *      TRUE:   Success.
+ *      FALSE:  Failure.
+ *  Requires:
+ *      segid < target->num_segs
+ *  Ensures:
+ */
+extern bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid,
+                    struct dsp_memstat *mem_stat_buf);
+
+#endif /* RMM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h b/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h
new file mode 100644 (file)
index 0000000..7bc5574
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * rms_sh.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge Resource Manager Server shared definitions (used on both
+ * GPP and DSP sides).
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef RMS_SH_
+#define RMS_SH_
+
+#include <dspbridge/rmstypes.h>
+
+/* Node Types: */
+#define RMS_TASK                1      /* Task node */
+#define RMS_DAIS                2      /* xDAIS socket node */
+#define RMS_MSG                 3      /* Message node */
+
+/* Memory Types: */
+#define RMS_CODE                0      /* Program space */
+#define RMS_DATA                1      /* Data space */
+#define RMS_IO                 2       /* I/O space */
+
+/* RM Server Command and Response Buffer Sizes: */
+#define RMS_COMMANDBUFSIZE     256     /* Size of command buffer */
+#define RMS_RESPONSEBUFSIZE    16      /* Size of response buffer */
+
+/* Pre-Defined Command/Response Codes: */
+#define RMS_EXIT                0x80000000     /* GPP->Node: shutdown */
+#define RMS_EXITACK             0x40000000     /* Node->GPP: ack shutdown */
+#define RMS_BUFDESC             0x20000000     /* Arg1 SM buf, Arg2 SM size */
+#define RMS_KILLTASK            0x10000000     /* GPP->Node: Kill Task */
+#define RMS_USER                0x0    /* Start of user-defined msg codes */
+#define RMS_MAXUSERCODES        0xfff  /* Maximum user defined C/R Codes */
+
+/* RM Server RPC Command Structure: */
+struct rms_command {
+       rms_word fxn;           /* Server function address */
+       rms_word arg1;          /* First argument */
+       rms_word arg2;          /* Second argument */
+       rms_word data;          /* Function-specific data array */
+};
+
+/*
+ *  The rms_strm_def structure defines the parameters for both input and output
+ *  streams, and is passed to a node's create function.
+ */
+struct rms_strm_def {
+       rms_word bufsize;       /* Buffer size (in DSP words) */
+       rms_word nbufs;         /* Max number of bufs in stream */
+       rms_word segid;         /* Segment to allocate buffers */
+       rms_word align;         /* Alignment for allocated buffers */
+       rms_word timeout;       /* Timeout (msec) for blocking calls */
+       char name[1];   /* Device Name (terminated by '\0') */
+};
+
+/* Message node create args structure: */
+struct rms_msg_args {
+       rms_word max_msgs;      /* Max # simultaneous msgs to node */
+       rms_word segid;         /* Mem segment for NODE_allocMsgBuf */
+       rms_word notify_type;   /* Type of message notification */
+       rms_word arg_length;    /* Length (in DSP chars) of arg data */
+       rms_word arg_data;      /* Arg data for node */
+};
+
+/* Partial task create args structure */
+struct rms_more_task_args {
+       rms_word priority;      /* Task's runtime priority level */
+       rms_word stack_size;    /* Task's stack size */
+       rms_word sysstack_size; /* Task's system stack size (55x) */
+       rms_word stack_seg;     /* Memory segment for task's stack */
+       rms_word heap_addr;     /* base address of the node memory heap in
+                                * external memory (DSP virtual address) */
+       rms_word heap_size;     /* size in MAUs of the node memory heap in
+                                * external memory */
+       rms_word misc;          /* Misc field.  Not used for 'normal'
+                                * task nodes; for xDAIS socket nodes
+                                * specifies the IALG_Fxn pointer.
+                                */
+       /* # input STRM definition structures */
+       rms_word num_input_streams;
+};
+
+#endif /* RMS_SH_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h b/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h
new file mode 100644 (file)
index 0000000..83c0f1d
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * rmstypes.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge Resource Manager Server shared data type definitions.
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef RMSTYPES_
+#define RMSTYPES_
+#include <linux/types.h>
+typedef u32 rms_word;
+
+#endif /* RMSTYPES_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/services.h b/drivers/staging/tidspbridge/include/dspbridge/services.h
new file mode 100644 (file)
index 0000000..eb26c86
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * services.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Provide loading and unloading of SERVICES modules.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef SERVICES_
+#define SERVICES_
+
+#include <dspbridge/host_os.h>
+/*
+ *  ======== services_exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      SERVICES initialized.
+ *  Ensures:
+ *      Resources used by module are freed when cRef reaches zero.
+ */
+extern void services_exit(void);
+
+/*
+ *  ======== services_init ========
+ *  Purpose:
+ *      Initializes SERVICES modules.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if all modules initialized; otherwise FALSE.
+ *  Requires:
+ *  Ensures:
+ *      SERVICES modules initialized.
+ */
+extern bool services_init(void);
+
+#endif /* SERVICES_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/strm.h b/drivers/staging/tidspbridge/include/dspbridge/strm.h
new file mode 100644 (file)
index 0000000..3e4671e
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * strm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSPBridge Stream Manager.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef STRM_
+#define STRM_
+
+#include <dspbridge/dev.h>
+
+#include <dspbridge/strmdefs.h>
+#include <dspbridge/proc.h>
+
+/*
+ *  ======== strm_allocate_buffer ========
+ *  Purpose:
+ *      Allocate data buffer(s) for use with a stream.
+ *  Parameter:
+ *      strmres:     Stream resource info handle returned from strm_open().
+ *      usize:          Size (GPP bytes) of the buffer(s).
+ *      num_bufs:       Number of buffers to allocate.
+ *      ap_buffer:       Array to hold buffer addresses.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *      -ENOMEM:    Insufficient memory.
+ *      -EPERM:      Failure occurred, unable to allocate buffers.
+ *      -EINVAL:      usize must be > 0 bytes.
+ *  Requires:
+ *      strm_init(void) called.
+ *      ap_buffer != NULL.
+ *  Ensures:
+ */
+extern int strm_allocate_buffer(struct strm_res_object *strmres,
+                                      u32 usize,
+                                      u8 **ap_buffer,
+                                      u32 num_bufs,
+                                      struct process_context *pr_ctxt);
+
+/*
+ *  ======== strm_close ========
+ *  Purpose:
+ *      Close a stream opened with strm_open().
+ *  Parameter:
+ *      strmres:          Stream resource info handle returned from strm_open().
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *      -EPIPE:   Some data buffers issued to the stream have not
+ *                      been reclaimed.
+ *      -EPERM:      Failure to close stream.
+ *  Requires:
+ *      strm_init(void) called.
+ *  Ensures:
+ */
+extern int strm_close(struct strm_res_object *strmres,
+                            struct process_context *pr_ctxt);
+
+/*
+ *  ======== strm_create ========
+ *  Purpose:
+ *      Create a STRM manager object. This object holds information about the
+ *      device needed to open streams.
+ *  Parameters:
+ *      strm_man:       Location to store handle to STRM manager object on
+ *                      output.
+ *      dev_obj:           Device for this processor.
+ *  Returns:
+ *      0:        Success;
+ *      -ENOMEM:    Insufficient memory for requested resources.
+ *      -EPERM:      General failure.
+ *  Requires:
+ *      strm_init(void) called.
+ *      strm_man != NULL.
+ *      dev_obj != NULL.
+ *  Ensures:
+ *      0:        Valid *strm_man.
+ *      error:          *strm_man == NULL.
+ */
+extern int strm_create(struct strm_mgr **strm_man,
+                             struct dev_object *dev_obj);
+
+/*
+ *  ======== strm_delete ========
+ *  Purpose:
+ *      Delete the STRM Object.
+ *  Parameters:
+ *      strm_mgr_obj:       Handle to STRM manager object from strm_create.
+ *  Returns:
+ *  Requires:
+ *      strm_init(void) called.
+ *      Valid strm_mgr_obj.
+ *  Ensures:
+ *      strm_mgr_obj is not valid.
+ */
+extern void strm_delete(struct strm_mgr *strm_mgr_obj);
+
+/*
+ *  ======== strm_exit ========
+ *  Purpose:
+ *      Discontinue usage of STRM module.
+ *  Parameters:
+ *  Returns:
+ *  Requires:
+ *      strm_init(void) successfully called before.
+ *  Ensures:
+ */
+extern void strm_exit(void);
+
+/*
+ *  ======== strm_free_buffer ========
+ *  Purpose:
+ *      Free buffer(s) allocated with strm_allocate_buffer.
+ *  Parameter:
+ *      strmres:     Stream resource info handle returned from strm_open().
+ *      ap_buffer:       Array containing buffer addresses.
+ *      num_bufs:       Number of buffers to be freed.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream handle.
+ *      -EPERM:      Failure occurred, unable to free buffers.
+ *  Requires:
+ *      strm_init(void) called.
+ *      ap_buffer != NULL.
+ *  Ensures:
+ */
+extern int strm_free_buffer(struct strm_res_object *strmres,
+                                  u8 **ap_buffer, u32 num_bufs,
+                                  struct process_context *pr_ctxt);
+
+/*
+ *  ======== strm_get_event_handle ========
+ *  Purpose:
+ *      Get stream's user event handle. This function is used when closing
+ *      a stream, so the event can be closed.
+ *  Parameter:
+ *      stream_obj:      Stream handle returned from strm_open().
+ *      ph_event:        Location to store event handle on output.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *  Requires:
+ *      strm_init(void) called.
+ *      ph_event != NULL.
+ *  Ensures:
+ */
+extern int strm_get_event_handle(struct strm_object *stream_obj,
+                                       void **ph_event);
+
+/*
+ *  ======== strm_get_info ========
+ *  Purpose:
+ *      Get information about a stream. User's dsp_streaminfo is contained
+ *      in stream_info struct. stream_info also contains Bridge private info.
+ *  Parameters:
+ *      stream_obj:         Stream handle returned from strm_open().
+ *      stream_info:        Location to store stream info on output.
+ *      uSteamInfoSize:     Size of user's dsp_streaminfo structure.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid stream_obj.
+ *      -EINVAL:          stream_info_size < sizeof(dsp_streaminfo).
+ *      -EPERM:          Unable to get stream info.
+ *  Requires:
+ *      strm_init(void) called.
+ *      stream_info != NULL.
+ *  Ensures:
+ */
+extern int strm_get_info(struct strm_object *stream_obj,
+                               struct stream_info *stream_info,
+                               u32 stream_info_size);
+
+/*
+ *  ======== strm_idle ========
+ *  Purpose:
+ *      Idle a stream and optionally flush output data buffers.
+ *      If this is an output stream and flush_data is TRUE, all data currently
+ *      enqueued will be discarded.
+ *      If this is an output stream and flush_data is FALSE, this function
+ *      will block until all currently buffered data is output, or the timeout
+ *      specified has been reached.
+ *      After a successful call to strm_idle(), all buffers can immediately
+ *      be reclaimed.
+ *  Parameters:
+ *      stream_obj:     Stream handle returned from strm_open().
+ *      flush_data:     If TRUE, discard output buffers.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *      -ETIME:   A timeout occurred before the stream could be idled.
+ *      -EPERM:      Unable to idle stream.
+ *  Requires:
+ *      strm_init(void) called.
+ *  Ensures:
+ */
+extern int strm_idle(struct strm_object *stream_obj, bool flush_data);
+
+/*
+ *  ======== strm_init ========
+ *  Purpose:
+ *      Initialize the STRM module.
+ *  Parameters:
+ *  Returns:
+ *      TRUE if initialization succeeded, FALSE otherwise.
+ *  Requires:
+ *  Ensures:
+ */
+extern bool strm_init(void);
+
+/*
+ *  ======== strm_issue ========
+ *  Purpose:
+ *      Send a buffer of data to a stream.
+ *  Parameters:
+ *      stream_obj:         Stream handle returned from strm_open().
+ *      pbuf:               Pointer to buffer of data to be sent to the stream.
+ *      ul_bytes:            Number of bytes of data in the buffer.
+ *      ul_buf_size:          Actual buffer size in bytes.
+ *      dw_arg:              A user argument that travels with the buffer.
+ *  Returns:
+ *      0:            Success.
+ *      -EFAULT:        Invalid stream_obj.
+ *      -ENOSR:    The stream is full.
+ *      -EPERM:          Failure occurred, unable to issue buffer.
+ *  Requires:
+ *      strm_init(void) called.
+ *      pbuf != NULL.
+ *  Ensures:
+ */
+extern int strm_issue(struct strm_object *stream_obj, u8 * pbuf,
+                            u32 ul_bytes, u32 ul_buf_size, u32 dw_arg);
+
+/*
+ *  ======== strm_open ========
+ *  Purpose:
+ *      Open a stream for sending/receiving data buffers to/from a task of
+ *      DAIS socket node on the DSP.
+ *  Parameters:
+ *      hnode:          Node handle returned from node_allocate().
+ *      dir:           DSP_TONODE or DSP_FROMNODE.
+ *      index:         Stream index.
+ *      pattr:          Pointer to structure containing attributes to be
+ *                      applied to stream. Cannot be NULL.
+ *      strmres:     Location to store stream resuorce info handle on output.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hnode.
+ *      -EPERM: Invalid direction.
+ *              hnode is not a task or DAIS socket node.
+ *              Unable to open stream.
+ *      -EINVAL:     Invalid index.
+ *  Requires:
+ *      strm_init(void) called.
+ *      strmres != NULL.
+ *      pattr != NULL.
+ *  Ensures:
+ *      0:        *strmres is valid.
+ *      error:          *strmres == NULL.
+ */
+extern int strm_open(struct node_object *hnode, u32 dir,
+                           u32 index, struct strm_attr *pattr,
+                           struct strm_res_object **strmres,
+                           struct process_context *pr_ctxt);
+
+/*
+ *  ======== strm_prepare_buffer ========
+ *  Purpose:
+ *      Prepare a data buffer not allocated by DSPStream_AllocateBuffers()
+ *      for use with a stream.
+ *  Parameter:
+ *      stream_obj:     Stream handle returned from strm_open().
+ *      usize:          Size (GPP bytes) of the buffer.
+ *      pbuffer:        Buffer address.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *      -EPERM:      Failure occurred, unable to prepare buffer.
+ *  Requires:
+ *      strm_init(void) called.
+ *      pbuffer != NULL.
+ *  Ensures:
+ */
+extern int strm_prepare_buffer(struct strm_object *stream_obj,
+                                     u32 usize, u8 *pbuffer);
+
+/*
+ *  ======== strm_reclaim ========
+ *  Purpose:
+ *      Request a buffer back from a stream.
+ *  Parameters:
+ *      stream_obj:          Stream handle returned from strm_open().
+ *      buf_ptr:        Location to store pointer to reclaimed buffer.
+ *      nbytes:         Location where number of bytes of data in the
+ *                      buffer will be written.
+ *      buff_size:      Location where actual buffer size will be written.
+ *      pdw_arg:         Location where user argument that travels with
+ *                      the buffer will be written.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *      -ETIME:   A timeout occurred before a buffer could be
+ *                      retrieved.
+ *      -EPERM:      Failure occurred, unable to reclaim buffer.
+ *  Requires:
+ *      strm_init(void) called.
+ *      buf_ptr != NULL.
+ *      nbytes != NULL.
+ *      pdw_arg != NULL.
+ *  Ensures:
+ */
+extern int strm_reclaim(struct strm_object *stream_obj,
+                              u8 **buf_ptr, u32 * nbytes,
+                              u32 *buff_size, u32 *pdw_arg);
+
+/*
+ *  ======== strm_register_notify ========
+ *  Purpose:
+ *      Register to be notified on specific events for this stream.
+ *  Parameters:
+ *      stream_obj:     Stream handle returned by strm_open().
+ *      event_mask:     Mask of types of events to be notified about.
+ *      notify_type:    Type of notification to be sent.
+ *      hnotification:  Handle to be used for notification.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *      -ENOMEM:    Insufficient memory on GPP.
+ *      -EINVAL:     event_mask is invalid.
+ *      -ENOSYS:   Notification type specified by notify_type is not
+ *                      supported.
+ *  Requires:
+ *      strm_init(void) called.
+ *      hnotification != NULL.
+ *  Ensures:
+ */
+extern int strm_register_notify(struct strm_object *stream_obj,
+                                      u32 event_mask, u32 notify_type,
+                                      struct dsp_notification
+                                      *hnotification);
+
+/*
+ *  ======== strm_select ========
+ *  Purpose:
+ *      Select a ready stream.
+ *  Parameters:
+ *      strm_tab:       Array of stream handles returned from strm_open().
+ *      strms:          Number of stream handles in array.
+ *      pmask:          Location to store mask of ready streams on output.
+ *      utimeout:       Timeout value (milliseconds).
+ *  Returns:
+ *      0:        Success.
+ *      -EDOM:     strms out of range.
+
+ *      -EFAULT:    Invalid stream handle in array.
+ *      -ETIME:   A timeout occurred before a stream became ready.
+ *      -EPERM:      Failure occurred, unable to select a stream.
+ *  Requires:
+ *      strm_init(void) called.
+ *      strm_tab != NULL.
+ *      strms > 0.
+ *      pmask != NULL.
+ *  Ensures:
+ *      0:        *pmask != 0 || utimeout == 0.
+ *      Error:          *pmask == 0.
+ */
+extern int strm_select(struct strm_object **strm_tab,
+                             u32 strms, u32 *pmask, u32 utimeout);
+
+/*
+ *  ======== strm_unprepare_buffer ========
+ *  Purpose:
+ *      Unprepare a data buffer that was previously prepared for a stream
+ *      with DSPStream_PrepareBuffer(), and that will no longer be used with
+ *      the stream.
+ *  Parameter:
+ *      stream_obj:     Stream handle returned from strm_open().
+ *      usize:          Size (GPP bytes) of the buffer.
+ *      pbuffer:        Buffer address.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid stream_obj.
+ *      -EPERM:      Failure occurred, unable to unprepare buffer.
+ *  Requires:
+ *      strm_init(void) called.
+ *      pbuffer != NULL.
+ *  Ensures:
+ */
+extern int strm_unprepare_buffer(struct strm_object *stream_obj,
+                                       u32 usize, u8 *pbuffer);
+
+#endif /* STRM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h
new file mode 100644 (file)
index 0000000..b363f79
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * strmdefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global STRM constants and types.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef STRMDEFS_
+#define STRMDEFS_
+
+#define STRM_MAXEVTNAMELEN      32
+
+struct strm_mgr;
+
+struct strm_object;
+
+struct strm_attr {
+       void *user_event;
+       char *pstr_event_name;
+       void *virt_base;        /* Process virtual base address of
+                                * mapped SM */
+       u32 ul_virt_size;       /* Size of virtual space in bytes */
+       struct dsp_streamattrin *stream_attr_in;
+};
+
+struct stream_info {
+       enum dsp_strmmode strm_mode;    /* transport mode of
+                                        * stream(DMA, ZEROCOPY..) */
+       u32 segment_id;         /* Segment strm allocs from. 0 is local mem */
+       void *virt_base;        /* "      " Stream'process virt base */
+       struct dsp_streaminfo *user_strm;       /* User's stream information
+                                                * returned */
+};
+
+#endif /* STRMDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/sync.h b/drivers/staging/tidspbridge/include/dspbridge/sync.h
new file mode 100644 (file)
index 0000000..e2651e7
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * sync.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Provide synchronization services.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _SYNC_H
+#define _SYNC_H
+
+#include <dspbridge/dbdefs.h>
+
+
+/* Special timeout value indicating an infinite wait: */
+#define SYNC_INFINITE  0xffffffff
+
+/**
+ * struct sync_object - the basic sync_object structure
+ * @comp:      use to signal events
+ * @multi_comp:        use to signal multiple events.
+ *
+ */
+struct sync_object{
+       struct completion comp;
+       struct completion *multi_comp;
+};
+
+/**
+ * sync_init_event() - set initial state for a sync_event element
+ * @event:     event to be initialized.
+ *
+ * Set the initial state for a sync_event element.
+ */
+
+static inline void sync_init_event(struct sync_object *event)
+{
+       init_completion(&event->comp);
+       event->multi_comp = NULL;
+}
+
+/**
+ * sync_reset_event() - reset a sync_event element
+ * @event:     event to be reset.
+ *
+ * This function reset to the initial state to @event.
+ */
+
+static inline void sync_reset_event(struct sync_object *event)
+{
+       INIT_COMPLETION(event->comp);
+       event->multi_comp = NULL;
+}
+
+/**
+ * sync_set_event() - set or signal and specified event
+ * @event:     Event to be set..
+ *
+ * set the @event, if there is an thread waiting for the event
+ * it will be waken up, this function only wakes one thread.
+ */
+
+void sync_set_event(struct sync_object *event);
+
+/**
+ * sync_wait_on_event() - waits for a event to be set.
+ * @event:     events to wait for it.
+ * @timeout    timeout on waiting for the evetn.
+ *
+ * This functios will wait until @event is set or until timeout. In case of
+ * success the function will return 0 and
+ * in case of timeout the function will return -ETIME
+ */
+
+static inline int sync_wait_on_event(struct sync_object *event,
+                                                       unsigned timeout)
+{
+       return wait_for_completion_timeout(&event->comp,
+               msecs_to_jiffies(timeout)) ? 0 : -ETIME;
+}
+
+/**
+ * sync_wait_on_multiple_events() - waits for multiple events to be set.
+ * @events:    Array of events to wait for them.
+ * @count:     number of elements of the array.
+ * @timeout    timeout on waiting for the evetns.
+ * @pu_index   index of the event set.
+ *
+ * This functios will wait until any of the array element is set or until
+ * timeout. In case of success the function will return 0 and
+ * @pu_index will store the index of the array element set and in case
+ * of timeout the function will return -ETIME.
+ */
+
+int sync_wait_on_multiple_events(struct sync_object **events,
+                                    unsigned count, unsigned timeout,
+                                    unsigned *index);
+
+#endif /* _SYNC_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/utildefs.h b/drivers/staging/tidspbridge/include/dspbridge/utildefs.h
new file mode 100644 (file)
index 0000000..8fe5414
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * utildefs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global UTIL constants and types, shared between DSP API and DSPSYS.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef UTILDEFS_
+#define UTILDEFS_
+
+/* constants taken from configmg.h */
+#define UTIL_MAXMEMREGS     9
+#define UTIL_MAXIOPORTS     20
+#define UTIL_MAXIRQS        7
+#define UTIL_MAXDMACHNLS    7
+
+/* misc. constants */
+#define UTIL_MAXARGVS       10
+
+/* Platform specific important info */
+struct util_sysinfo {
+       /* Granularity of page protection; usually 1k or 4k */
+       u32 dw_page_size;
+       u32 dw_allocation_granularity;  /* VM granularity, usually 64K */
+       u32 dw_number_of_processors;    /* Used as sanity check */
+};
+
+#endif /* UTILDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h b/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h
new file mode 100644 (file)
index 0000000..9a99475
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * uuidutil.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This file contains the specification of UUID helper functions.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef UUIDUTIL_
+#define UUIDUTIL_
+
+#define MAXUUIDLEN  37
+
+/*
+ *  ======== uuid_uuid_to_string ========
+ *  Purpose:
+ *      Converts a dsp_uuid to an ANSI string.
+ *  Parameters:
+ *      uuid_obj:      Pointer to a dsp_uuid object.
+ *      sz_uuid:    Pointer to a buffer to receive a NULL-terminated UUID
+ *                  string.
+ *      size:      Maximum size of the sz_uuid string.
+ *  Returns:
+ *  Requires:
+ *      uuid_obj & sz_uuid are non-NULL values.
+ *  Ensures:
+ *      Lenghth of sz_uuid is less than MAXUUIDLEN.
+ *  Details:
+ *      UUID string limit currently set at MAXUUIDLEN.
+ */
+void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid,
+                        s32 size);
+
+/*
+ *  ======== uuid_uuid_from_string ========
+ *  Purpose:
+ *      Converts an ANSI string to a dsp_uuid.
+ *  Parameters:
+ *      sz_uuid:    Pointer to a string that represents a dsp_uuid object.
+ *      uuid_obj:      Pointer to a dsp_uuid object.
+ *  Returns:
+ *  Requires:
+ *      uuid_obj & sz_uuid are non-NULL values.
+ *  Ensures:
+ *  Details:
+ *      We assume the string representation of a UUID has the following format:
+ *      "12345678_1234_1234_1234_123456789abc".
+ */
+extern void uuid_uuid_from_string(char *sz_uuid,
+                                 struct dsp_uuid *uuid_obj);
+
+#endif /* UUIDUTIL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/wdt.h b/drivers/staging/tidspbridge/include/dspbridge/wdt.h
new file mode 100644 (file)
index 0000000..4c00ba5
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * wdt.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * IO dispatcher for a shared memory channel driver.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef __DSP_WDT3_H_
+#define __DSP_WDT3_H_
+
+/* WDT defines */
+#define OMAP3_WDT3_ISR_OFFSET  0x0018
+
+
+/**
+ * struct dsp_wdt_setting - the basic dsp_wdt_setting structure
+ * @reg_base:  pointer to the base of the wdt registers
+ * @sm_wdt:    pointer to flags in shared memory
+ * @wdt3_tasklet       tasklet to manage wdt event
+ * @fclk               handle to wdt3 functional clock
+ * @iclk               handle to wdt3 interface clock
+ *
+ * This struct is used in the function to manage wdt3.
+ */
+
+struct dsp_wdt_setting {
+       void __iomem *reg_base;
+       struct shm *sm_wdt;
+       struct tasklet_struct wdt3_tasklet;
+       struct clk *fclk;
+       struct clk *iclk;
+};
+
+/**
+ * dsp_wdt_init() - initialize wdt3 module.
+ *
+ * This function initilize to wdt3 module, so that
+ * other wdt3 function can be used.
+ */
+int dsp_wdt_init(void);
+
+/**
+ * dsp_wdt_exit() - initialize wdt3 module.
+ *
+ * This function frees all resources allocated for wdt3 module.
+ */
+void dsp_wdt_exit(void);
+
+/**
+ * dsp_wdt_enable() - enable/disable wdt3
+ * @enable:    bool value to enable/disable wdt3
+ *
+ * This function enables or disables wdt3 base on @enable value.
+ *
+ */
+void dsp_wdt_enable(bool enable);
+
+/**
+ * dsp_wdt_sm_set() - store pointer to the share memory
+ * @data:              pointer to dspbridge share memory
+ *
+ * This function is used to pass a valid pointer to share memory,
+ * so that the flags can be set in order DSP side can read them.
+ *
+ */
+void dsp_wdt_sm_set(void *data);
+
+#endif
+
diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c
new file mode 100644 (file)
index 0000000..90317b5
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * chnl.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP API channel interface: multiplexes data streams through the single
+ * physical link managed by a Bridge Bridge driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/proc.h>
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/chnlpriv.h>
+#include <chnlobj.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/chnl.h>
+
+/*  ----------------------------------- Globals */
+static u32 refs;
+
+/*
+ *  ======== chnl_create ========
+ *  Purpose:
+ *      Create a channel manager object, responsible for opening new channels
+ *      and closing old ones for a given 'Bridge board.
+ */
+int chnl_create(struct chnl_mgr **channel_mgr,
+                      struct dev_object *hdev_obj,
+                      const struct chnl_mgrattrs *mgr_attrts)
+{
+       int status;
+       struct chnl_mgr *hchnl_mgr;
+       struct chnl_mgr_ *chnl_mgr_obj = NULL;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(channel_mgr != NULL);
+       DBC_REQUIRE(mgr_attrts != NULL);
+
+       *channel_mgr = NULL;
+
+       /* Validate args: */
+       if ((0 < mgr_attrts->max_channels) &&
+           (mgr_attrts->max_channels <= CHNL_MAXCHANNELS))
+               status = 0;
+       else if (mgr_attrts->max_channels == 0)
+               status = -EINVAL;
+       else
+               status = -ECHRNG;
+
+       if (mgr_attrts->word_size == 0)
+               status = -EINVAL;
+
+       if (!status) {
+               status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
+               if (!status && hchnl_mgr != NULL)
+                       status = -EEXIST;
+
+       }
+
+       if (!status) {
+               struct bridge_drv_interface *intf_fxns;
+               dev_get_intf_fxns(hdev_obj, &intf_fxns);
+               /* Let Bridge channel module finish the create: */
+               status = (*intf_fxns->pfn_chnl_create) (&hchnl_mgr, hdev_obj,
+                                                       mgr_attrts);
+               if (!status) {
+                       /* Fill in DSP API channel module's fields of the
+                        * chnl_mgr structure */
+                       chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
+                       chnl_mgr_obj->intf_fxns = intf_fxns;
+                       /* Finally, return the new channel manager handle: */
+                       *channel_mgr = hchnl_mgr;
+               }
+       }
+
+       DBC_ENSURE(status || chnl_mgr_obj);
+
+       return status;
+}
+
+/*
+ *  ======== chnl_destroy ========
+ *  Purpose:
+ *      Close all open channels, and destroy the channel manager.
+ */
+int chnl_destroy(struct chnl_mgr *hchnl_mgr)
+{
+       struct chnl_mgr_ *chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
+       struct bridge_drv_interface *intf_fxns;
+       int status;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (chnl_mgr_obj) {
+               intf_fxns = chnl_mgr_obj->intf_fxns;
+               /* Let Bridge channel module destroy the chnl_mgr: */
+               status = (*intf_fxns->pfn_chnl_destroy) (hchnl_mgr);
+       } else {
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== chnl_exit ========
+ *  Purpose:
+ *      Discontinue usage of the CHNL module.
+ */
+void chnl_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== chnl_init ========
+ *  Purpose:
+ *      Initialize the CHNL module's private state.
+ */
+bool chnl_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
diff --git a/drivers/staging/tidspbridge/pmgr/chnlobj.h b/drivers/staging/tidspbridge/pmgr/chnlobj.h
new file mode 100644 (file)
index 0000000..6795e0a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * chnlobj.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Structure subcomponents of channel class library channel objects which
+ * are exposed to DSP API from Bridge driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CHNLOBJ_
+#define CHNLOBJ_
+
+#include <dspbridge/chnldefs.h>
+#include <dspbridge/dspdefs.h>
+
+/*
+ *  This struct is the first field in a chnl_mgr struct. Other. implementation
+ *  specific fields follow this structure in memory.
+ */
+struct chnl_mgr_ {
+       /* These must be the first fields in a chnl_mgr struct: */
+
+       /* Function interface to Bridge driver. */
+       struct bridge_drv_interface *intf_fxns;
+};
+
+/*
+ *  This struct is the first field in a chnl_object struct. Other,
+ *  implementation specific fields follow this structure in memory.
+ */
+struct chnl_object_ {
+       /* These must be the first fields in a chnl_object struct: */
+       struct chnl_mgr_ *chnl_mgr_obj; /* Pointer back to channel manager. */
+};
+
+#endif /* CHNLOBJ_ */
diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c
new file mode 100644 (file)
index 0000000..ce3dc88
--- /dev/null
@@ -0,0 +1,1154 @@
+/*
+ * cmm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * The Communication(Shared) Memory Management(CMM) module provides
+ * shared memory management services for DSP/BIOS Bridge data streaming
+ * and messaging.
+ *
+ * Multiple shared memory segments can be registered with CMM.
+ * Each registered SM segment is represented by a SM "allocator" that
+ * describes a block of physically contiguous shared memory used for
+ * future allocations by CMM.
+ *
+ * Memory is coelesced back to the appropriate heap when a buffer is
+ * freed.
+ *
+ * Notes:
+ *   Va: Virtual address.
+ *   Pa: Physical or kernel system address.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/list.h>
+#include <dspbridge/sync.h>
+#include <dspbridge/utildefs.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+#include <dspbridge/proc.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/cmm.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define NEXT_PA(pnode)   (pnode->dw_pa + pnode->ul_size)
+
+/* Other bus/platform translations */
+#define DSPPA2GPPPA(base, x, y)  ((x)+(y))
+#define GPPPA2DSPPA(base, x, y)  ((x)-(y))
+
+/*
+ *  Allocators define a block of contiguous memory used for future allocations.
+ *
+ *      sma - shared memory allocator.
+ *      vma - virtual memory allocator.(not used).
+ */
+struct cmm_allocator {         /* sma */
+       unsigned int shm_base;  /* Start of physical SM block */
+       u32 ul_sm_size;         /* Size of SM block in bytes */
+       unsigned int dw_vm_base;        /* Start of VM block. (Dev driver
+                                        * context for 'sma') */
+       u32 dw_dsp_phys_addr_offset;    /* DSP PA to GPP PA offset for this
+                                        * SM space */
+       s8 c_factor;            /* DSPPa to GPPPa Conversion Factor */
+       unsigned int dw_dsp_base;       /* DSP virt base byte address */
+       u32 ul_dsp_size;        /* DSP seg size in bytes */
+       struct cmm_object *hcmm_mgr;    /* back ref to parent mgr */
+       /* node list of available memory */
+       struct lst_list *free_list_head;
+       /* node list of memory in use */
+       struct lst_list *in_use_list_head;
+};
+
+struct cmm_xlator {            /* Pa<->Va translator object */
+       /* CMM object this translator associated */
+       struct cmm_object *hcmm_mgr;
+       /*
+        *  Client process virtual base address that corresponds to phys SM
+        *  base address for translator's ul_seg_id.
+        *  Only 1 segment ID currently supported.
+        */
+       unsigned int dw_virt_base;      /* virtual base address */
+       u32 ul_virt_size;       /* size of virt space in bytes */
+       u32 ul_seg_id;          /* Segment Id */
+};
+
+/* CMM Mgr */
+struct cmm_object {
+       /*
+        * Cmm Lock is used to serialize access mem manager for multi-threads.
+        */
+       struct mutex cmm_lock;  /* Lock to access cmm mgr */
+       struct lst_list *node_free_list_head;   /* Free list of memory nodes */
+       u32 ul_min_block_size;  /* Min SM block; default 16 bytes */
+       u32 dw_page_size;       /* Memory Page size (1k/4k) */
+       /* GPP SM segment ptrs */
+       struct cmm_allocator *pa_gppsm_seg_tab[CMM_MAXGPPSEGS];
+};
+
+/* Default CMM Mgr attributes */
+static struct cmm_mgrattrs cmm_dfltmgrattrs = {
+       /* ul_min_block_size, min block size(bytes) allocated by cmm mgr */
+       16
+};
+
+/* Default allocation attributes */
+static struct cmm_attrs cmm_dfltalctattrs = {
+       1               /* ul_seg_id, default segment Id for allocator */
+};
+
+/* Address translator default attrs */
+static struct cmm_xlatorattrs cmm_dfltxlatorattrs = {
+       /* ul_seg_id, does not have to match cmm_dfltalctattrs ul_seg_id */
+       1,
+       0,                      /* dw_dsp_bufs */
+       0,                      /* dw_dsp_buf_size */
+       NULL,                   /* vm_base */
+       0,                      /* dw_vm_size */
+};
+
+/* SM node representing a block of memory. */
+struct cmm_mnode {
+       struct list_head link;  /* must be 1st element */
+       u32 dw_pa;              /* Phys addr */
+       u32 dw_va;              /* Virtual address in device process context */
+       u32 ul_size;            /* SM block size in bytes */
+       u32 client_proc;        /* Process that allocated this mem block */
+};
+
+/*  ----------------------------------- Globals */
+static u32 refs;               /* module reference count */
+
+/*  ----------------------------------- Function Prototypes */
+static void add_to_free_list(struct cmm_allocator *allocator,
+                            struct cmm_mnode *pnode);
+static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj,
+                                          u32 ul_seg_id);
+static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator,
+                                       u32 usize);
+static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa,
+                                 u32 dw_va, u32 ul_size);
+/* get available slot for new allocator */
+static s32 get_slot(struct cmm_object *cmm_mgr_obj);
+static void un_register_gppsm_seg(struct cmm_allocator *psma);
+
+/*
+ *  ======== cmm_calloc_buf ========
+ *  Purpose:
+ *      Allocate a SM buffer, zero contents, and return the physical address
+ *      and optional driver context virtual address(pp_buf_va).
+ *
+ *      The freelist is sorted in increasing size order. Get the first
+ *      block that satifies the request and sort the remaining back on
+ *      the freelist; if large enough. The kept block is placed on the
+ *      inUseList.
+ */
+void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize,
+                    struct cmm_attrs *pattrs, void **pp_buf_va)
+{
+       struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
+       void *buf_pa = NULL;
+       struct cmm_mnode *pnode = NULL;
+       struct cmm_mnode *new_node = NULL;
+       struct cmm_allocator *allocator = NULL;
+       u32 delta_size;
+       u8 *pbyte = NULL;
+       s32 cnt;
+
+       if (pattrs == NULL)
+               pattrs = &cmm_dfltalctattrs;
+
+       if (pp_buf_va != NULL)
+               *pp_buf_va = NULL;
+
+       if (cmm_mgr_obj && (usize != 0)) {
+               if (pattrs->ul_seg_id > 0) {
+                       /* SegId > 0 is SM */
+                       /* get the allocator object for this segment id */
+                       allocator =
+                           get_allocator(cmm_mgr_obj, pattrs->ul_seg_id);
+                       /* keep block size a multiple of ul_min_block_size */
+                       usize =
+                           ((usize - 1) & ~(cmm_mgr_obj->ul_min_block_size -
+                                            1))
+                           + cmm_mgr_obj->ul_min_block_size;
+                       mutex_lock(&cmm_mgr_obj->cmm_lock);
+                       pnode = get_free_block(allocator, usize);
+               }
+               if (pnode) {
+                       delta_size = (pnode->ul_size - usize);
+                       if (delta_size >= cmm_mgr_obj->ul_min_block_size) {
+                               /* create a new block with the leftovers and
+                                * add to freelist */
+                               new_node =
+                                   get_node(cmm_mgr_obj, pnode->dw_pa + usize,
+                                            pnode->dw_va + usize,
+                                            (u32) delta_size);
+                               /* leftovers go free */
+                               add_to_free_list(allocator, new_node);
+                               /* adjust our node's size */
+                               pnode->ul_size = usize;
+                       }
+                       /* Tag node with client process requesting allocation
+                        * We'll need to free up a process's alloc'd SM if the
+                        * client process goes away.
+                        */
+                       /* Return TGID instead of process handle */
+                       pnode->client_proc = current->tgid;
+
+                       /* put our node on InUse list */
+                       lst_put_tail(allocator->in_use_list_head,
+                                    (struct list_head *)pnode);
+                       buf_pa = (void *)pnode->dw_pa;  /* physical address */
+                       /* clear mem */
+                       pbyte = (u8 *) pnode->dw_va;
+                       for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++)
+                               *pbyte = 0;
+
+                       if (pp_buf_va != NULL) {
+                               /* Virtual address */
+                               *pp_buf_va = (void *)pnode->dw_va;
+                       }
+               }
+               mutex_unlock(&cmm_mgr_obj->cmm_lock);
+       }
+       return buf_pa;
+}
+
+/*
+ *  ======== cmm_create ========
+ *  Purpose:
+ *      Create a communication memory manager object.
+ */
+int cmm_create(struct cmm_object **ph_cmm_mgr,
+                     struct dev_object *hdev_obj,
+                     const struct cmm_mgrattrs *mgr_attrts)
+{
+       struct cmm_object *cmm_obj = NULL;
+       int status = 0;
+       struct util_sysinfo sys_info;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(ph_cmm_mgr != NULL);
+
+       *ph_cmm_mgr = NULL;
+       /* create, zero, and tag a cmm mgr object */
+       cmm_obj = kzalloc(sizeof(struct cmm_object), GFP_KERNEL);
+       if (cmm_obj != NULL) {
+               if (mgr_attrts == NULL)
+                       mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */
+
+               /* 4 bytes minimum */
+               DBC_ASSERT(mgr_attrts->ul_min_block_size >= 4);
+               /* save away smallest block allocation for this cmm mgr */
+               cmm_obj->ul_min_block_size = mgr_attrts->ul_min_block_size;
+               /* save away the systems memory page size */
+               sys_info.dw_page_size = PAGE_SIZE;
+               sys_info.dw_allocation_granularity = PAGE_SIZE;
+               sys_info.dw_number_of_processors = 1;
+
+               cmm_obj->dw_page_size = sys_info.dw_page_size;
+
+               /* Note: DSP SM seg table(aDSPSMSegTab[]) zero'd by
+                * MEM_ALLOC_OBJECT */
+
+               /* create node free list */
+               cmm_obj->node_free_list_head =
+                               kzalloc(sizeof(struct lst_list),
+                                               GFP_KERNEL);
+               if (cmm_obj->node_free_list_head == NULL) {
+                       status = -ENOMEM;
+                       cmm_destroy(cmm_obj, true);
+               } else {
+                       INIT_LIST_HEAD(&cmm_obj->
+                                      node_free_list_head->head);
+                       mutex_init(&cmm_obj->cmm_lock);
+                       *ph_cmm_mgr = cmm_obj;
+               }
+       } else {
+               status = -ENOMEM;
+       }
+       return status;
+}
+
+/*
+ *  ======== cmm_destroy ========
+ *  Purpose:
+ *      Release the communication memory manager resources.
+ */
+int cmm_destroy(struct cmm_object *hcmm_mgr, bool force)
+{
+       struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
+       struct cmm_info temp_info;
+       int status = 0;
+       s32 slot_seg;
+       struct cmm_mnode *pnode;
+
+       DBC_REQUIRE(refs > 0);
+       if (!hcmm_mgr) {
+               status = -EFAULT;
+               return status;
+       }
+       mutex_lock(&cmm_mgr_obj->cmm_lock);
+       /* If not force then fail if outstanding allocations exist */
+       if (!force) {
+               /* Check for outstanding memory allocations */
+               status = cmm_get_info(hcmm_mgr, &temp_info);
+               if (!status) {
+                       if (temp_info.ul_total_in_use_cnt > 0) {
+                               /* outstanding allocations */
+                               status = -EPERM;
+                       }
+               }
+       }
+       if (!status) {
+               /* UnRegister SM allocator */
+               for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) {
+                       if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] != NULL) {
+                               un_register_gppsm_seg
+                                   (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg]);
+                               /* Set slot to NULL for future reuse */
+                               cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = NULL;
+                       }
+               }
+       }
+       if (cmm_mgr_obj->node_free_list_head != NULL) {
+               /* Free the free nodes */
+               while (!LST_IS_EMPTY(cmm_mgr_obj->node_free_list_head)) {
+                       pnode = (struct cmm_mnode *)
+                           lst_get_head(cmm_mgr_obj->node_free_list_head);
+                       kfree(pnode);
+               }
+               /* delete NodeFreeList list */
+               kfree(cmm_mgr_obj->node_free_list_head);
+       }
+       mutex_unlock(&cmm_mgr_obj->cmm_lock);
+       if (!status) {
+               /* delete CS & cmm mgr object */
+               mutex_destroy(&cmm_mgr_obj->cmm_lock);
+               kfree(cmm_mgr_obj);
+       }
+       return status;
+}
+
+/*
+ *  ======== cmm_exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ */
+void cmm_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+}
+
+/*
+ *  ======== cmm_free_buf ========
+ *  Purpose:
+ *      Free the given buffer.
+ */
+int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa,
+                       u32 ul_seg_id)
+{
+       struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
+       int status = -EFAULT;
+       struct cmm_mnode *mnode_obj = NULL;
+       struct cmm_allocator *allocator = NULL;
+       struct cmm_attrs *pattrs;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(buf_pa != NULL);
+
+       if (ul_seg_id == 0) {
+               pattrs = &cmm_dfltalctattrs;
+               ul_seg_id = pattrs->ul_seg_id;
+       }
+       if (!hcmm_mgr || !(ul_seg_id > 0)) {
+               status = -EFAULT;
+               return status;
+       }
+       /* get the allocator for this segment id */
+       allocator = get_allocator(cmm_mgr_obj, ul_seg_id);
+       if (allocator != NULL) {
+               mutex_lock(&cmm_mgr_obj->cmm_lock);
+               mnode_obj =
+                   (struct cmm_mnode *)lst_first(allocator->in_use_list_head);
+               while (mnode_obj) {
+                       if ((u32) buf_pa == mnode_obj->dw_pa) {
+                               /* Found it */
+                               lst_remove_elem(allocator->in_use_list_head,
+                                               (struct list_head *)mnode_obj);
+                               /* back to freelist */
+                               add_to_free_list(allocator, mnode_obj);
+                               status = 0;     /* all right! */
+                               break;
+                       }
+                       /* next node. */
+                       mnode_obj = (struct cmm_mnode *)
+                           lst_next(allocator->in_use_list_head,
+                                    (struct list_head *)mnode_obj);
+               }
+               mutex_unlock(&cmm_mgr_obj->cmm_lock);
+       }
+       return status;
+}
+
+/*
+ *  ======== cmm_get_handle ========
+ *  Purpose:
+ *      Return the communication memory manager object for this device.
+ *      This is typically called from the client process.
+ */
+int cmm_get_handle(void *hprocessor, struct cmm_object ** ph_cmm_mgr)
+{
+       int status = 0;
+       struct dev_object *hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(ph_cmm_mgr != NULL);
+       if (hprocessor != NULL)
+               status = proc_get_dev_object(hprocessor, &hdev_obj);
+       else
+               hdev_obj = dev_get_first();     /* default */
+
+       if (!status)
+               status = dev_get_cmm_mgr(hdev_obj, ph_cmm_mgr);
+
+       return status;
+}
+
+/*
+ *  ======== cmm_get_info ========
+ *  Purpose:
+ *      Return the current memory utilization information.
+ */
+int cmm_get_info(struct cmm_object *hcmm_mgr,
+                       struct cmm_info *cmm_info_obj)
+{
+       struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
+       u32 ul_seg;
+       int status = 0;
+       struct cmm_allocator *altr;
+       struct cmm_mnode *mnode_obj = NULL;
+
+       DBC_REQUIRE(cmm_info_obj != NULL);
+
+       if (!hcmm_mgr) {
+               status = -EFAULT;
+               return status;
+       }
+       mutex_lock(&cmm_mgr_obj->cmm_lock);
+       cmm_info_obj->ul_num_gppsm_segs = 0;    /* # of SM segments */
+       /* Total # of outstanding alloc */
+       cmm_info_obj->ul_total_in_use_cnt = 0;
+       /* min block size */
+       cmm_info_obj->ul_min_block_size = cmm_mgr_obj->ul_min_block_size;
+       /* check SM memory segments */
+       for (ul_seg = 1; ul_seg <= CMM_MAXGPPSEGS; ul_seg++) {
+               /* get the allocator object for this segment id */
+               altr = get_allocator(cmm_mgr_obj, ul_seg);
+               if (altr != NULL) {
+                       cmm_info_obj->ul_num_gppsm_segs++;
+                       cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_pa =
+                           altr->shm_base - altr->ul_dsp_size;
+                       cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size =
+                           altr->ul_dsp_size + altr->ul_sm_size;
+                       cmm_info_obj->seg_info[ul_seg - 1].dw_gpp_base_pa =
+                           altr->shm_base;
+                       cmm_info_obj->seg_info[ul_seg - 1].ul_gpp_size =
+                           altr->ul_sm_size;
+                       cmm_info_obj->seg_info[ul_seg - 1].dw_dsp_base_va =
+                           altr->dw_dsp_base;
+                       cmm_info_obj->seg_info[ul_seg - 1].ul_dsp_size =
+                           altr->ul_dsp_size;
+                       cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_va =
+                           altr->dw_vm_base - altr->ul_dsp_size;
+                       cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0;
+                       mnode_obj = (struct cmm_mnode *)
+                           lst_first(altr->in_use_list_head);
+                       /* Count inUse blocks */
+                       while (mnode_obj) {
+                               cmm_info_obj->ul_total_in_use_cnt++;
+                               cmm_info_obj->seg_info[ul_seg -
+                                                      1].ul_in_use_cnt++;
+                               /* next node. */
+                               mnode_obj = (struct cmm_mnode *)
+                                   lst_next(altr->in_use_list_head,
+                                            (struct list_head *)mnode_obj);
+                       }
+               }
+       }                       /* end for */
+       mutex_unlock(&cmm_mgr_obj->cmm_lock);
+       return status;
+}
+
+/*
+ *  ======== cmm_init ========
+ *  Purpose:
+ *      Initializes private state of CMM module.
+ */
+bool cmm_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
+
+/*
+ *  ======== cmm_register_gppsm_seg ========
+ *  Purpose:
+ *      Register a block of SM with the CMM to be used for later GPP SM
+ *      allocations.
+ */
+int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr,
+                                 u32 dw_gpp_base_pa, u32 ul_size,
+                                 u32 dsp_addr_offset, s8 c_factor,
+                                 u32 dw_dsp_base, u32 ul_dsp_size,
+                                 u32 *sgmt_id, u32 gpp_base_va)
+{
+       struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
+       struct cmm_allocator *psma = NULL;
+       int status = 0;
+       struct cmm_mnode *new_node;
+       s32 slot_seg;
+
+       DBC_REQUIRE(ul_size > 0);
+       DBC_REQUIRE(sgmt_id != NULL);
+       DBC_REQUIRE(dw_gpp_base_pa != 0);
+       DBC_REQUIRE(gpp_base_va != 0);
+       DBC_REQUIRE((c_factor <= CMM_ADDTODSPPA) &&
+                   (c_factor >= CMM_SUBFROMDSPPA));
+       dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x "
+               "dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", __func__,
+               dw_gpp_base_pa, ul_size, dsp_addr_offset, dw_dsp_base,
+               ul_dsp_size, gpp_base_va);
+       if (!hcmm_mgr) {
+               status = -EFAULT;
+               return status;
+       }
+       /* make sure we have room for another allocator */
+       mutex_lock(&cmm_mgr_obj->cmm_lock);
+       slot_seg = get_slot(cmm_mgr_obj);
+       if (slot_seg < 0) {
+               /* get a slot number */
+               status = -EPERM;
+               goto func_end;
+       }
+       /* Check if input ul_size is big enough to alloc at least one block */
+       if (ul_size < cmm_mgr_obj->ul_min_block_size) {
+               status = -EINVAL;
+               goto func_end;
+       }
+
+       /* create, zero, and tag an SM allocator object */
+       psma = kzalloc(sizeof(struct cmm_allocator), GFP_KERNEL);
+       if (psma != NULL) {
+               psma->hcmm_mgr = hcmm_mgr;      /* ref to parent */
+               psma->shm_base = dw_gpp_base_pa;        /* SM Base phys */
+               psma->ul_sm_size = ul_size;     /* SM segment size in bytes */
+               psma->dw_vm_base = gpp_base_va;
+               psma->dw_dsp_phys_addr_offset = dsp_addr_offset;
+               psma->c_factor = c_factor;
+               psma->dw_dsp_base = dw_dsp_base;
+               psma->ul_dsp_size = ul_dsp_size;
+               if (psma->dw_vm_base == 0) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+               /* return the actual segment identifier */
+               *sgmt_id = (u32) slot_seg + 1;
+               /* create memory free list */
+               psma->free_list_head = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               if (psma->free_list_head == NULL) {
+                       status = -ENOMEM;
+                       goto func_end;
+               }
+               INIT_LIST_HEAD(&psma->free_list_head->head);
+
+               /* create memory in-use list */
+               psma->in_use_list_head = kzalloc(sizeof(struct
+                                               lst_list), GFP_KERNEL);
+               if (psma->in_use_list_head == NULL) {
+                       status = -ENOMEM;
+                       goto func_end;
+               }
+               INIT_LIST_HEAD(&psma->in_use_list_head->head);
+
+               /* Get a mem node for this hunk-o-memory */
+               new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa,
+                                   psma->dw_vm_base, ul_size);
+               /* Place node on the SM allocator's free list */
+               if (new_node) {
+                       lst_put_tail(psma->free_list_head,
+                                    (struct list_head *)new_node);
+               } else {
+                       status = -ENOMEM;
+                       goto func_end;
+               }
+       } else {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       /* make entry */
+       cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = psma;
+
+func_end:
+       if (status && psma) {
+               /* Cleanup allocator */
+               un_register_gppsm_seg(psma);
+       }
+
+       mutex_unlock(&cmm_mgr_obj->cmm_lock);
+       return status;
+}
+
+/*
+ *  ======== cmm_un_register_gppsm_seg ========
+ *  Purpose:
+ *      UnRegister GPP SM segments with the CMM.
+ */
+int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr,
+                                    u32 ul_seg_id)
+{
+       struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
+       int status = 0;
+       struct cmm_allocator *psma;
+       u32 ul_id = ul_seg_id;
+
+       DBC_REQUIRE(ul_seg_id > 0);
+       if (hcmm_mgr) {
+               if (ul_seg_id == CMM_ALLSEGMENTS)
+                       ul_id = 1;
+
+               if ((ul_id > 0) && (ul_id <= CMM_MAXGPPSEGS)) {
+                       while (ul_id <= CMM_MAXGPPSEGS) {
+                               mutex_lock(&cmm_mgr_obj->cmm_lock);
+                               /* slot = seg_id-1 */
+                               psma = cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1];
+                               if (psma != NULL) {
+                                       un_register_gppsm_seg(psma);
+                                       /* Set alctr ptr to NULL for future
+                                        * reuse */
+                                       cmm_mgr_obj->pa_gppsm_seg_tab[ul_id -
+                                                                     1] = NULL;
+                               } else if (ul_seg_id != CMM_ALLSEGMENTS) {
+                                       status = -EPERM;
+                               }
+                               mutex_unlock(&cmm_mgr_obj->cmm_lock);
+                               if (ul_seg_id != CMM_ALLSEGMENTS)
+                                       break;
+
+                               ul_id++;
+                       }       /* end while */
+               } else {
+                       status = -EINVAL;
+               }
+       } else {
+               status = -EFAULT;
+       }
+       return status;
+}
+
+/*
+ *  ======== un_register_gppsm_seg ========
+ *  Purpose:
+ *      UnRegister the SM allocator by freeing all its resources and
+ *      nulling cmm mgr table entry.
+ *  Note:
+ *      This routine is always called within cmm lock crit sect.
+ */
+static void un_register_gppsm_seg(struct cmm_allocator *psma)
+{
+       struct cmm_mnode *mnode_obj = NULL;
+       struct cmm_mnode *next_node = NULL;
+
+       DBC_REQUIRE(psma != NULL);
+       if (psma->free_list_head != NULL) {
+               /* free nodes on free list */
+               mnode_obj = (struct cmm_mnode *)lst_first(psma->free_list_head);
+               while (mnode_obj) {
+                       next_node =
+                           (struct cmm_mnode *)lst_next(psma->free_list_head,
+                                                        (struct list_head *)
+                                                        mnode_obj);
+                       lst_remove_elem(psma->free_list_head,
+                                       (struct list_head *)mnode_obj);
+                       kfree((void *)mnode_obj);
+                       /* next node. */
+                       mnode_obj = next_node;
+               }
+               kfree(psma->free_list_head);    /* delete freelist */
+               /* free nodes on InUse list */
+               mnode_obj =
+                   (struct cmm_mnode *)lst_first(psma->in_use_list_head);
+               while (mnode_obj) {
+                       next_node =
+                           (struct cmm_mnode *)lst_next(psma->in_use_list_head,
+                                                        (struct list_head *)
+                                                        mnode_obj);
+                       lst_remove_elem(psma->in_use_list_head,
+                                       (struct list_head *)mnode_obj);
+                       kfree((void *)mnode_obj);
+                       /* next node. */
+                       mnode_obj = next_node;
+               }
+               kfree(psma->in_use_list_head);  /* delete InUse list */
+       }
+       if ((void *)psma->dw_vm_base != NULL)
+               MEM_UNMAP_LINEAR_ADDRESS((void *)psma->dw_vm_base);
+
+       /* Free allocator itself */
+       kfree(psma);
+}
+
+/*
+ *  ======== get_slot ========
+ *  Purpose:
+ *      An available slot # is returned. Returns negative on failure.
+ */
+static s32 get_slot(struct cmm_object *cmm_mgr_obj)
+{
+       s32 slot_seg = -1;      /* neg on failure */
+       DBC_REQUIRE(cmm_mgr_obj != NULL);
+       /* get first available slot in cmm mgr SMSegTab[] */
+       for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) {
+               if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] == NULL)
+                       break;
+
+       }
+       if (slot_seg == CMM_MAXGPPSEGS)
+               slot_seg = -1;  /* failed */
+
+       return slot_seg;
+}
+
+/*
+ *  ======== get_node ========
+ *  Purpose:
+ *      Get a memory node from freelist or create a new one.
+ */
+static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa,
+                                 u32 dw_va, u32 ul_size)
+{
+       struct cmm_mnode *pnode = NULL;
+
+       DBC_REQUIRE(cmm_mgr_obj != NULL);
+       DBC_REQUIRE(dw_pa != 0);
+       DBC_REQUIRE(dw_va != 0);
+       DBC_REQUIRE(ul_size != 0);
+       /* Check cmm mgr's node freelist */
+       if (LST_IS_EMPTY(cmm_mgr_obj->node_free_list_head)) {
+               pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL);
+       } else {
+               /* surely a valid element */
+               pnode = (struct cmm_mnode *)
+                   lst_get_head(cmm_mgr_obj->node_free_list_head);
+       }
+       if (pnode) {
+               lst_init_elem((struct list_head *)pnode);       /* set self */
+               pnode->dw_pa = dw_pa;   /* Physical addr of start of block */
+               pnode->dw_va = dw_va;   /* Virtual   "            " */
+               pnode->ul_size = ul_size;       /* Size of block */
+       }
+       return pnode;
+}
+
+/*
+ *  ======== delete_node ========
+ *  Purpose:
+ *      Put a memory node on the cmm nodelist for later use.
+ *      Doesn't actually delete the node. Heap thrashing friendly.
+ */
+static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode)
+{
+       DBC_REQUIRE(pnode != NULL);
+       lst_init_elem((struct list_head *)pnode);       /* init .self ptr */
+       lst_put_tail(cmm_mgr_obj->node_free_list_head,
+                    (struct list_head *)pnode);
+}
+
+/*
+ * ====== get_free_block ========
+ *  Purpose:
+ *      Scan the free block list and return the first block that satisfies
+ *      the size.
+ */
+static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator,
+                                       u32 usize)
+{
+       if (allocator) {
+               struct cmm_mnode *mnode_obj = (struct cmm_mnode *)
+                   lst_first(allocator->free_list_head);
+               while (mnode_obj) {
+                       if (usize <= (u32) mnode_obj->ul_size) {
+                               lst_remove_elem(allocator->free_list_head,
+                                               (struct list_head *)mnode_obj);
+                               return mnode_obj;
+                       }
+                       /* next node. */
+                       mnode_obj = (struct cmm_mnode *)
+                           lst_next(allocator->free_list_head,
+                                    (struct list_head *)mnode_obj);
+               }
+       }
+       return NULL;
+}
+
+/*
+ *  ======== add_to_free_list ========
+ *  Purpose:
+ *      Coelesce node into the freelist in ascending size order.
+ */
+static void add_to_free_list(struct cmm_allocator *allocator,
+                            struct cmm_mnode *pnode)
+{
+       struct cmm_mnode *node_prev = NULL;
+       struct cmm_mnode *node_next = NULL;
+       struct cmm_mnode *mnode_obj;
+       u32 dw_this_pa;
+       u32 dw_next_pa;
+
+       DBC_REQUIRE(pnode != NULL);
+       DBC_REQUIRE(allocator != NULL);
+       dw_this_pa = pnode->dw_pa;
+       dw_next_pa = NEXT_PA(pnode);
+       mnode_obj = (struct cmm_mnode *)lst_first(allocator->free_list_head);
+       while (mnode_obj) {
+               if (dw_this_pa == NEXT_PA(mnode_obj)) {
+                       /* found the block ahead of this one */
+                       node_prev = mnode_obj;
+               } else if (dw_next_pa == mnode_obj->dw_pa) {
+                       node_next = mnode_obj;
+               }
+               if ((node_prev == NULL) || (node_next == NULL)) {
+                       /* next node. */
+                       mnode_obj = (struct cmm_mnode *)
+                           lst_next(allocator->free_list_head,
+                                    (struct list_head *)mnode_obj);
+               } else {
+                       /* got 'em */
+                       break;
+               }
+       }                       /* while */
+       if (node_prev != NULL) {
+               /* combine with previous block */
+               lst_remove_elem(allocator->free_list_head,
+                               (struct list_head *)node_prev);
+               /* grow node to hold both */
+               pnode->ul_size += node_prev->ul_size;
+               pnode->dw_pa = node_prev->dw_pa;
+               pnode->dw_va = node_prev->dw_va;
+               /* place node on mgr nodeFreeList */
+               delete_node((struct cmm_object *)allocator->hcmm_mgr,
+                           node_prev);
+       }
+       if (node_next != NULL) {
+               /* combine with next block */
+               lst_remove_elem(allocator->free_list_head,
+                               (struct list_head *)node_next);
+               /* grow da node */
+               pnode->ul_size += node_next->ul_size;
+               /* place node on mgr nodeFreeList */
+               delete_node((struct cmm_object *)allocator->hcmm_mgr,
+                           node_next);
+       }
+       /* Now, let's add to freelist in increasing size order */
+       mnode_obj = (struct cmm_mnode *)lst_first(allocator->free_list_head);
+       while (mnode_obj) {
+               if (pnode->ul_size <= mnode_obj->ul_size)
+                       break;
+
+               /* next node. */
+               mnode_obj =
+                   (struct cmm_mnode *)lst_next(allocator->free_list_head,
+                                                (struct list_head *)mnode_obj);
+       }
+       /* if mnode_obj is NULL then add our pnode to the end of the freelist */
+       if (mnode_obj == NULL) {
+               lst_put_tail(allocator->free_list_head,
+                            (struct list_head *)pnode);
+       } else {
+               /* insert our node before the current traversed node */
+               lst_insert_before(allocator->free_list_head,
+                                 (struct list_head *)pnode,
+                                 (struct list_head *)mnode_obj);
+       }
+}
+
+/*
+ * ======== get_allocator ========
+ *  Purpose:
+ *      Return the allocator for the given SM Segid.
+ *      SegIds:  1,2,3..max.
+ */
+static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj,
+                                          u32 ul_seg_id)
+{
+       struct cmm_allocator *allocator = NULL;
+
+       DBC_REQUIRE(cmm_mgr_obj != NULL);
+       DBC_REQUIRE((ul_seg_id > 0) && (ul_seg_id <= CMM_MAXGPPSEGS));
+       allocator = cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1];
+       if (allocator != NULL) {
+               /* make sure it's for real */
+               if (!allocator) {
+                       allocator = NULL;
+                       DBC_ASSERT(false);
+               }
+       }
+       return allocator;
+}
+
+/*
+ *  The CMM_Xlator[xxx] routines below are used by Node and Stream
+ *  to perform SM address translation to the client process address space.
+ *  A "translator" object is created by a node/stream for each SM seg used.
+ */
+
+/*
+ *  ======== cmm_xlator_create ========
+ *  Purpose:
+ *      Create an address translator object.
+ */
+int cmm_xlator_create(struct cmm_xlatorobject **xlator,
+                            struct cmm_object *hcmm_mgr,
+                            struct cmm_xlatorattrs *xlator_attrs)
+{
+       struct cmm_xlator *xlator_object = NULL;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(xlator != NULL);
+       DBC_REQUIRE(hcmm_mgr != NULL);
+
+       *xlator = NULL;
+       if (xlator_attrs == NULL)
+               xlator_attrs = &cmm_dfltxlatorattrs;    /* set defaults */
+
+       xlator_object = kzalloc(sizeof(struct cmm_xlator), GFP_KERNEL);
+       if (xlator_object != NULL) {
+               xlator_object->hcmm_mgr = hcmm_mgr;     /* ref back to CMM */
+               /* SM seg_id */
+               xlator_object->ul_seg_id = xlator_attrs->ul_seg_id;
+       } else {
+               status = -ENOMEM;
+       }
+       if (!status)
+               *xlator = (struct cmm_xlatorobject *)xlator_object;
+
+       return status;
+}
+
+/*
+ *  ======== cmm_xlator_delete ========
+ *  Purpose:
+ *      Free the Xlator resources.
+ *      VM gets freed later.
+ */
+int cmm_xlator_delete(struct cmm_xlatorobject *xlator, bool force)
+{
+       struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
+
+       DBC_REQUIRE(refs > 0);
+
+       kfree(xlator_obj);
+
+       return 0;
+}
+
+/*
+ *  ======== cmm_xlator_alloc_buf ========
+ */
+void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *va_buf,
+                          u32 pa_size)
+{
+       struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
+       void *pbuf = NULL;
+       void *tmp_va_buff;
+       struct cmm_attrs attrs;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(xlator != NULL);
+       DBC_REQUIRE(xlator_obj->hcmm_mgr != NULL);
+       DBC_REQUIRE(va_buf != NULL);
+       DBC_REQUIRE(pa_size > 0);
+       DBC_REQUIRE(xlator_obj->ul_seg_id > 0);
+
+       if (xlator_obj) {
+               attrs.ul_seg_id = xlator_obj->ul_seg_id;
+               __raw_writel(0, va_buf);
+               /* Alloc SM */
+               pbuf =
+                   cmm_calloc_buf(xlator_obj->hcmm_mgr, pa_size, &attrs, NULL);
+               if (pbuf) {
+                       /* convert to translator(node/strm) process Virtual
+                        * address */
+                        tmp_va_buff = cmm_xlator_translate(xlator,
+                                                        pbuf, CMM_PA2VA);
+                       __raw_writel((u32)tmp_va_buff, va_buf);
+               }
+       }
+       return pbuf;
+}
+
+/*
+ *  ======== cmm_xlator_free_buf ========
+ *  Purpose:
+ *      Free the given SM buffer and descriptor.
+ *      Does not free virtual memory.
+ */
+int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va)
+{
+       struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
+       int status = -EPERM;
+       void *buf_pa = NULL;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(buf_va != NULL);
+       DBC_REQUIRE(xlator_obj->ul_seg_id > 0);
+
+       if (xlator_obj) {
+               /* convert Va to Pa so we can free it. */
+               buf_pa = cmm_xlator_translate(xlator, buf_va, CMM_VA2PA);
+               if (buf_pa) {
+                       status = cmm_free_buf(xlator_obj->hcmm_mgr, buf_pa,
+                                             xlator_obj->ul_seg_id);
+                       if (status) {
+                               /* Uh oh, this shouldn't happen. Descriptor
+                                * gone! */
+                               DBC_ASSERT(false);      /* CMM is leaking mem */
+                       }
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== cmm_xlator_info ========
+ *  Purpose:
+ *      Set/Get translator info.
+ */
+int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 ** paddr,
+                          u32 ul_size, u32 segm_id, bool set_info)
+{
+       struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(paddr != NULL);
+       DBC_REQUIRE((segm_id > 0) && (segm_id <= CMM_MAXGPPSEGS));
+
+       if (xlator_obj) {
+               if (set_info) {
+                       /* set translators virtual address range */
+                       xlator_obj->dw_virt_base = (u32) *paddr;
+                       xlator_obj->ul_virt_size = ul_size;
+               } else {        /* return virt base address */
+                       *paddr = (u8 *) xlator_obj->dw_virt_base;
+               }
+       } else {
+               status = -EFAULT;
+       }
+       return status;
+}
+
+/*
+ *  ======== cmm_xlator_translate ========
+ */
+void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr,
+                          enum cmm_xlatetype xtype)
+{
+       u32 dw_addr_xlate = 0;
+       struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
+       struct cmm_object *cmm_mgr_obj = NULL;
+       struct cmm_allocator *allocator = NULL;
+       u32 dw_offset = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(paddr != NULL);
+       DBC_REQUIRE((xtype >= CMM_VA2PA) && (xtype <= CMM_DSPPA2PA));
+
+       if (!xlator_obj)
+               goto loop_cont;
+
+       cmm_mgr_obj = (struct cmm_object *)xlator_obj->hcmm_mgr;
+       /* get this translator's default SM allocator */
+       DBC_ASSERT(xlator_obj->ul_seg_id > 0);
+       allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->ul_seg_id - 1];
+       if (!allocator)
+               goto loop_cont;
+
+       if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_VA2PA) ||
+           (xtype == CMM_PA2VA)) {
+               if (xtype == CMM_PA2VA) {
+                       /* Gpp Va = Va Base + offset */
+                       dw_offset = (u8 *) paddr - (u8 *) (allocator->shm_base -
+                                                          allocator->
+                                                          ul_dsp_size);
+                       dw_addr_xlate = xlator_obj->dw_virt_base + dw_offset;
+                       /* Check if translated Va base is in range */
+                       if ((dw_addr_xlate < xlator_obj->dw_virt_base) ||
+                           (dw_addr_xlate >=
+                            (xlator_obj->dw_virt_base +
+                             xlator_obj->ul_virt_size))) {
+                               dw_addr_xlate = 0;      /* bad address */
+                       }
+               } else {
+                       /* Gpp PA =  Gpp Base + offset */
+                       dw_offset =
+                           (u8 *) paddr - (u8 *) xlator_obj->dw_virt_base;
+                       dw_addr_xlate =
+                           allocator->shm_base - allocator->ul_dsp_size +
+                           dw_offset;
+               }
+       } else {
+               dw_addr_xlate = (u32) paddr;
+       }
+       /*Now convert address to proper target physical address if needed */
+       if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_PA2DSPPA)) {
+               /* Got Gpp Pa now, convert to DSP Pa */
+               dw_addr_xlate =
+                   GPPPA2DSPPA((allocator->shm_base - allocator->ul_dsp_size),
+                               dw_addr_xlate,
+                               allocator->dw_dsp_phys_addr_offset *
+                               allocator->c_factor);
+       } else if (xtype == CMM_DSPPA2PA) {
+               /* Got DSP Pa, convert to GPP Pa */
+               dw_addr_xlate =
+                   DSPPA2GPPPA(allocator->shm_base - allocator->ul_dsp_size,
+                               dw_addr_xlate,
+                               allocator->dw_dsp_phys_addr_offset *
+                               allocator->c_factor);
+       }
+loop_cont:
+       return (void *)dw_addr_xlate;
+}
diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c
new file mode 100644 (file)
index 0000000..52989ab
--- /dev/null
@@ -0,0 +1,652 @@
+/*
+ * cod.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This module implements DSP code management for the DSP/BIOS Bridge
+ * environment. It is mostly a thin wrapper.
+ *
+ * This module provides an interface for loading both static and
+ * dynamic code objects onto DSP systems.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/ldr.h>
+
+/*  ----------------------------------- Platform Manager */
+/* Include appropriate loader header file */
+#include <dspbridge/dbll.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/cod.h>
+
+/*
+ *  ======== cod_manager ========
+ */
+struct cod_manager {
+       struct dbll_tar_obj *target;
+       struct dbll_library_obj *base_lib;
+       bool loaded;            /* Base library loaded? */
+       u32 ul_entry;
+       struct ldr_module *dll_obj;
+       struct dbll_fxns fxns;
+       struct dbll_attrs attrs;
+       char sz_zl_file[COD_MAXPATHLENGTH];
+};
+
+/*
+ *  ======== cod_libraryobj ========
+ */
+struct cod_libraryobj {
+       struct dbll_library_obj *dbll_lib;
+       struct cod_manager *cod_mgr;
+};
+
+static u32 refs = 0L;
+
+static struct dbll_fxns ldr_fxns = {
+       (dbll_close_fxn) dbll_close,
+       (dbll_create_fxn) dbll_create,
+       (dbll_delete_fxn) dbll_delete,
+       (dbll_exit_fxn) dbll_exit,
+       (dbll_get_attrs_fxn) dbll_get_attrs,
+       (dbll_get_addr_fxn) dbll_get_addr,
+       (dbll_get_c_addr_fxn) dbll_get_c_addr,
+       (dbll_get_sect_fxn) dbll_get_sect,
+       (dbll_init_fxn) dbll_init,
+       (dbll_load_fxn) dbll_load,
+       (dbll_load_sect_fxn) dbll_load_sect,
+       (dbll_open_fxn) dbll_open,
+       (dbll_read_sect_fxn) dbll_read_sect,
+       (dbll_set_attrs_fxn) dbll_set_attrs,
+       (dbll_unload_fxn) dbll_unload,
+       (dbll_unload_sect_fxn) dbll_unload_sect,
+};
+
+static bool no_op(void);
+
+/*
+ * File operations (originally were under kfile.c)
+ */
+static s32 cod_f_close(struct file *filp)
+{
+       /* Check for valid handle */
+       if (!filp)
+               return -EFAULT;
+
+       filp_close(filp, NULL);
+
+       /* we can't use 0 here */
+       return 0;
+}
+
+static struct file *cod_f_open(const char *psz_file_name, const char *sz_mode)
+{
+       mm_segment_t fs;
+       struct file *filp;
+
+       fs = get_fs();
+       set_fs(get_ds());
+
+       /* ignore given mode and open file as read-only */
+       filp = filp_open(psz_file_name, O_RDONLY, 0);
+
+       if (IS_ERR(filp))
+               filp = NULL;
+
+       set_fs(fs);
+
+       return filp;
+}
+
+static s32 cod_f_read(void __user *pbuffer, s32 size, s32 count,
+                     struct file *filp)
+{
+       /* check for valid file handle */
+       if (!filp)
+               return -EFAULT;
+
+       if ((size > 0) && (count > 0) && pbuffer) {
+               u32 dw_bytes_read;
+               mm_segment_t fs;
+
+               /* read from file */
+               fs = get_fs();
+               set_fs(get_ds());
+               dw_bytes_read = filp->f_op->read(filp, pbuffer, size * count,
+                                                &(filp->f_pos));
+               set_fs(fs);
+
+               if (!dw_bytes_read)
+                       return -EBADF;
+
+               return dw_bytes_read / size;
+       }
+
+       return -EINVAL;
+}
+
+static s32 cod_f_seek(struct file *filp, s32 offset, s32 origin)
+{
+       loff_t dw_cur_pos;
+
+       /* check for valid file handle */
+       if (!filp)
+               return -EFAULT;
+
+       /* based on the origin flag, move the internal pointer */
+       dw_cur_pos = filp->f_op->llseek(filp, offset, origin);
+
+       if ((s32) dw_cur_pos < 0)
+               return -EPERM;
+
+       /* we can't use 0 here */
+       return 0;
+}
+
+static s32 cod_f_tell(struct file *filp)
+{
+       loff_t dw_cur_pos;
+
+       if (!filp)
+               return -EFAULT;
+
+       /* Get current position */
+       dw_cur_pos = filp->f_op->llseek(filp, 0, SEEK_CUR);
+
+       if ((s32) dw_cur_pos < 0)
+               return -EPERM;
+
+       return dw_cur_pos;
+}
+
+/*
+ *  ======== cod_close ========
+ */
+void cod_close(struct cod_libraryobj *lib)
+{
+       struct cod_manager *hmgr;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(lib != NULL);
+       DBC_REQUIRE(lib->cod_mgr);
+
+       hmgr = lib->cod_mgr;
+       hmgr->fxns.close_fxn(lib->dbll_lib);
+
+       kfree(lib);
+}
+
+/*
+ *  ======== cod_create ========
+ *  Purpose:
+ *      Create an object to manage code on a DSP system.
+ *      This object can be used to load an initial program image with
+ *      arguments that can later be expanded with
+ *      dynamically loaded object files.
+ *
+ */
+int cod_create(struct cod_manager **mgr, char *str_zl_file,
+                     const struct cod_attrs *attrs)
+{
+       struct cod_manager *mgr_new;
+       struct dbll_attrs zl_attrs;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(mgr != NULL);
+
+       /* assume failure */
+       *mgr = NULL;
+
+       /* we don't support non-default attrs yet */
+       if (attrs != NULL)
+               return -ENOSYS;
+
+       mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL);
+       if (mgr_new == NULL)
+               return -ENOMEM;
+
+       /* Set up loader functions */
+       mgr_new->fxns = ldr_fxns;
+
+       /* initialize the ZL module */
+       mgr_new->fxns.init_fxn();
+
+       zl_attrs.alloc = (dbll_alloc_fxn) no_op;
+       zl_attrs.free = (dbll_free_fxn) no_op;
+       zl_attrs.fread = (dbll_read_fxn) cod_f_read;
+       zl_attrs.fseek = (dbll_seek_fxn) cod_f_seek;
+       zl_attrs.ftell = (dbll_tell_fxn) cod_f_tell;
+       zl_attrs.fclose = (dbll_f_close_fxn) cod_f_close;
+       zl_attrs.fopen = (dbll_f_open_fxn) cod_f_open;
+       zl_attrs.sym_lookup = NULL;
+       zl_attrs.base_image = true;
+       zl_attrs.log_write = NULL;
+       zl_attrs.log_write_handle = NULL;
+       zl_attrs.write = NULL;
+       zl_attrs.rmm_handle = NULL;
+       zl_attrs.input_params = NULL;
+       zl_attrs.sym_handle = NULL;
+       zl_attrs.sym_arg = NULL;
+
+       mgr_new->attrs = zl_attrs;
+
+       status = mgr_new->fxns.create_fxn(&mgr_new->target, &zl_attrs);
+
+       if (status) {
+               cod_delete(mgr_new);
+               return -ESPIPE;
+       }
+
+       /* return the new manager */
+       *mgr = mgr_new;
+
+       return 0;
+}
+
+/*
+ *  ======== cod_delete ========
+ *  Purpose:
+ *      Delete a code manager object.
+ */
+void cod_delete(struct cod_manager *cod_mgr_obj)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr_obj);
+
+       if (cod_mgr_obj->base_lib) {
+               if (cod_mgr_obj->loaded)
+                       cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib,
+                                                       &cod_mgr_obj->attrs);
+
+               cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
+       }
+       if (cod_mgr_obj->target) {
+               cod_mgr_obj->fxns.delete_fxn(cod_mgr_obj->target);
+               cod_mgr_obj->fxns.exit_fxn();
+       }
+       kfree(cod_mgr_obj);
+}
+
+/*
+ *  ======== cod_exit ========
+ *  Purpose:
+ *      Discontinue usage of the COD module.
+ *
+ */
+void cod_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== cod_get_base_lib ========
+ *  Purpose:
+ *      Get handle to the base image DBL library.
+ */
+int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
+                           struct dbll_library_obj **plib)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr_obj);
+       DBC_REQUIRE(plib != NULL);
+
+       *plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib;
+
+       return status;
+}
+
+/*
+ *  ======== cod_get_base_name ========
+ */
+int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name,
+                            u32 usize)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr_obj);
+       DBC_REQUIRE(sz_name != NULL);
+
+       if (usize <= COD_MAXPATHLENGTH)
+               strncpy(sz_name, cod_mgr_obj->sz_zl_file, usize);
+       else
+               status = -EPERM;
+
+       return status;
+}
+
+/*
+ *  ======== cod_get_entry ========
+ *  Purpose:
+ *      Retrieve the entry point of a loaded DSP program image
+ *
+ */
+int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr_obj);
+       DBC_REQUIRE(entry_pt != NULL);
+
+       *entry_pt = cod_mgr_obj->ul_entry;
+
+       return 0;
+}
+
+/*
+ *  ======== cod_get_loader ========
+ *  Purpose:
+ *      Get handle to the DBLL loader.
+ */
+int cod_get_loader(struct cod_manager *cod_mgr_obj,
+                         struct dbll_tar_obj **loader)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr_obj);
+       DBC_REQUIRE(loader != NULL);
+
+       *loader = (struct dbll_tar_obj *)cod_mgr_obj->target;
+
+       return status;
+}
+
+/*
+ *  ======== cod_get_section ========
+ *  Purpose:
+ *      Retrieve the starting address and length of a section in the COFF file
+ *      given the section name.
+ */
+int cod_get_section(struct cod_libraryobj *lib, char *str_sect,
+                          u32 *addr, u32 *len)
+{
+       struct cod_manager *cod_mgr_obj;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(lib != NULL);
+       DBC_REQUIRE(lib->cod_mgr);
+       DBC_REQUIRE(str_sect != NULL);
+       DBC_REQUIRE(addr != NULL);
+       DBC_REQUIRE(len != NULL);
+
+       *addr = 0;
+       *len = 0;
+       if (lib != NULL) {
+               cod_mgr_obj = lib->cod_mgr;
+               status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, str_sect,
+                                                       addr, len);
+       } else {
+               status = -ESPIPE;
+       }
+
+       DBC_ENSURE(!status || ((*addr == 0) && (*len == 0)));
+
+       return status;
+}
+
+/*
+ *  ======== cod_get_sym_value ========
+ *  Purpose:
+ *      Retrieve the value for the specified symbol. The symbol is first
+ *      searched for literally and then, if not found, searched for as a
+ *      C symbol.
+ *
+ */
+int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym,
+                            u32 *pul_value)
+{
+       struct dbll_sym_val *dbll_sym;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr_obj);
+       DBC_REQUIRE(str_sym != NULL);
+       DBC_REQUIRE(pul_value != NULL);
+
+       dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n",
+               __func__, cod_mgr_obj, str_sym, pul_value);
+       if (cod_mgr_obj->base_lib) {
+               if (!cod_mgr_obj->fxns.
+                   get_addr_fxn(cod_mgr_obj->base_lib, str_sym, &dbll_sym)) {
+                       if (!cod_mgr_obj->fxns.
+                           get_c_addr_fxn(cod_mgr_obj->base_lib, str_sym,
+                                               &dbll_sym))
+                               return -ESPIPE;
+               }
+       } else {
+               return -ESPIPE;
+       }
+
+       *pul_value = dbll_sym->value;
+
+       return 0;
+}
+
+/*
+ *  ======== cod_init ========
+ *  Purpose:
+ *      Initialize the COD module's private state.
+ *
+ */
+bool cod_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && refs > 0) || (!ret && refs >= 0));
+       return ret;
+}
+
+/*
+ *  ======== cod_load_base ========
+ *  Purpose:
+ *      Load the initial program image, optionally with command-line arguments,
+ *      on the DSP system managed by the supplied handle. The program to be
+ *      loaded must be the first element of the args array and must be a fully
+ *      qualified pathname.
+ *  Details:
+ *      if num_argc doesn't match the number of arguments in the args array, the
+ *      args array is searched for a NULL terminating entry, and argc is
+ *      recalculated to reflect this.  In this way, we can support NULL
+ *      terminating args arrays, if num_argc is very large.
+ */
+int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[],
+                        cod_writefxn pfn_write, void *arb, char *envp[])
+{
+       dbll_flags flags;
+       struct dbll_attrs save_attrs;
+       struct dbll_attrs new_attrs;
+       int status;
+       u32 i;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr_obj);
+       DBC_REQUIRE(num_argc > 0);
+       DBC_REQUIRE(args != NULL);
+       DBC_REQUIRE(args[0] != NULL);
+       DBC_REQUIRE(pfn_write != NULL);
+       DBC_REQUIRE(cod_mgr_obj->base_lib != NULL);
+
+       /*
+        *  Make sure every argv[] stated in argc has a value, or change argc to
+        *  reflect true number in NULL terminated argv array.
+        */
+       for (i = 0; i < num_argc; i++) {
+               if (args[i] == NULL) {
+                       num_argc = i;
+                       break;
+               }
+       }
+
+       /* set the write function for this operation */
+       cod_mgr_obj->fxns.get_attrs_fxn(cod_mgr_obj->target, &save_attrs);
+
+       new_attrs = save_attrs;
+       new_attrs.write = (dbll_write_fxn) pfn_write;
+       new_attrs.input_params = arb;
+       new_attrs.alloc = (dbll_alloc_fxn) no_op;
+       new_attrs.free = (dbll_free_fxn) no_op;
+       new_attrs.log_write = NULL;
+       new_attrs.log_write_handle = NULL;
+
+       /* Load the image */
+       flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
+       status = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags,
+                                           &new_attrs,
+                                           &cod_mgr_obj->ul_entry);
+       if (status)
+               cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
+
+       if (!status)
+               cod_mgr_obj->loaded = true;
+       else
+               cod_mgr_obj->base_lib = NULL;
+
+       return status;
+}
+
+/*
+ *  ======== cod_open ========
+ *      Open library for reading sections.
+ */
+int cod_open(struct cod_manager *hmgr, char *sz_coff_path,
+                   u32 flags, struct cod_libraryobj **lib_obj)
+{
+       int status = 0;
+       struct cod_libraryobj *lib = NULL;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hmgr);
+       DBC_REQUIRE(sz_coff_path != NULL);
+       DBC_REQUIRE(flags == COD_NOLOAD || flags == COD_SYMB);
+       DBC_REQUIRE(lib_obj != NULL);
+
+       *lib_obj = NULL;
+
+       lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL);
+       if (lib == NULL)
+               status = -ENOMEM;
+
+       if (!status) {
+               lib->cod_mgr = hmgr;
+               status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags,
+                                            &lib->dbll_lib);
+               if (!status)
+                       *lib_obj = lib;
+       }
+
+       if (status)
+               pr_err("%s: error status 0x%x, sz_coff_path: %s flags: 0x%x\n",
+                      __func__, status, sz_coff_path, flags);
+       return status;
+}
+
+/*
+ *  ======== cod_open_base ========
+ *  Purpose:
+ *      Open base image for reading sections.
+ */
+int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
+                        dbll_flags flags)
+{
+       int status = 0;
+       struct dbll_library_obj *lib;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hmgr);
+       DBC_REQUIRE(sz_coff_path != NULL);
+
+       /* if we previously opened a base image, close it now */
+       if (hmgr->base_lib) {
+               if (hmgr->loaded) {
+                       hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs);
+                       hmgr->loaded = false;
+               }
+               hmgr->fxns.close_fxn(hmgr->base_lib);
+               hmgr->base_lib = NULL;
+       }
+       status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, &lib);
+       if (!status) {
+               /* hang onto the library for subsequent sym table usage */
+               hmgr->base_lib = lib;
+               strncpy(hmgr->sz_zl_file, sz_coff_path, COD_MAXPATHLENGTH - 1);
+               hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0';
+       }
+
+       if (status)
+               pr_err("%s: error status 0x%x sz_coff_path: %s\n", __func__,
+                      status, sz_coff_path);
+       return status;
+}
+
+/*
+ *  ======== cod_read_section ========
+ *  Purpose:
+ *      Retrieve the content of a code section given the section name.
+ */
+int cod_read_section(struct cod_libraryobj *lib, char *str_sect,
+                           char *str_content, u32 content_size)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(lib != NULL);
+       DBC_REQUIRE(lib->cod_mgr);
+       DBC_REQUIRE(str_sect != NULL);
+       DBC_REQUIRE(str_content != NULL);
+
+       if (lib != NULL)
+               status =
+                   lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect,
+                                                    str_content, content_size);
+       else
+               status = -ESPIPE;
+
+       return status;
+}
+
+/*
+ *  ======== no_op ========
+ *  Purpose:
+ *      No Operation.
+ *
+ */
+static bool no_op(void)
+{
+       return true;
+}
diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c
new file mode 100644 (file)
index 0000000..2340638
--- /dev/null
@@ -0,0 +1,1585 @@
+/*
+ * dbll.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+#include <dspbridge/gh.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+
+/* Dynamic loader library interface */
+#include <dspbridge/dynamic_loader.h>
+#include <dspbridge/getsection.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/dbll.h>
+#include <dspbridge/rmm.h>
+
+/* Number of buckets for symbol hash table */
+#define MAXBUCKETS 211
+
+/* Max buffer length */
+#define MAXEXPR 128
+
+#define DOFF_ALIGN(x) (((x) + 3) & ~3UL)
+
+/*
+ *  ======== struct dbll_tar_obj* ========
+ *  A target may have one or more libraries of symbols/code/data loaded
+ *  onto it, where a library is simply the symbols/code/data contained
+ *  in a DOFF file.
+ */
+/*
+ *  ======== dbll_tar_obj ========
+ */
+struct dbll_tar_obj {
+       struct dbll_attrs attrs;
+       struct dbll_library_obj *head;  /* List of all opened libraries */
+};
+
+/*
+ *  The following 4 typedefs are "super classes" of the dynamic loader
+ *  library types used in dynamic loader functions (dynamic_loader.h).
+ */
+/*
+ *  ======== dbll_stream ========
+ *  Contains dynamic_loader_stream
+ */
+struct dbll_stream {
+       struct dynamic_loader_stream dl_stream;
+       struct dbll_library_obj *lib;
+};
+
+/*
+ *  ======== ldr_symbol ========
+ */
+struct ldr_symbol {
+       struct dynamic_loader_sym dl_symbol;
+       struct dbll_library_obj *lib;
+};
+
+/*
+ *  ======== dbll_alloc ========
+ */
+struct dbll_alloc {
+       struct dynamic_loader_allocate dl_alloc;
+       struct dbll_library_obj *lib;
+};
+
+/*
+ *  ======== dbll_init_obj ========
+ */
+struct dbll_init_obj {
+       struct dynamic_loader_initialize dl_init;
+       struct dbll_library_obj *lib;
+};
+
+/*
+ *  ======== DBLL_Library ========
+ *  A library handle is returned by DBLL_Open() and is passed to dbll_load()
+ *  to load symbols/code/data, and to dbll_unload(), to remove the
+ *  symbols/code/data loaded by dbll_load().
+ */
+
+/*
+ *  ======== dbll_library_obj ========
+ */
+struct dbll_library_obj {
+       struct dbll_library_obj *next;  /* Next library in target's list */
+       struct dbll_library_obj *prev;  /* Previous in the list */
+       struct dbll_tar_obj *target_obj;        /* target for this library */
+
+       /* Objects needed by dynamic loader */
+       struct dbll_stream stream;
+       struct ldr_symbol symbol;
+       struct dbll_alloc allocate;
+       struct dbll_init_obj init;
+       void *dload_mod_obj;
+
+       char *file_name;        /* COFF file name */
+       void *fp;               /* Opaque file handle */
+       u32 entry;              /* Entry point */
+       void *desc;     /* desc of DOFF file loaded */
+       u32 open_ref;           /* Number of times opened */
+       u32 load_ref;           /* Number of times loaded */
+       struct gh_t_hash_tab *sym_tab;  /* Hash table of symbols */
+       u32 ul_pos;
+};
+
+/*
+ *  ======== dbll_symbol ========
+ */
+struct dbll_symbol {
+       struct dbll_sym_val value;
+       char *name;
+};
+
+static void dof_close(struct dbll_library_obj *zl_lib);
+static int dof_open(struct dbll_library_obj *zl_lib);
+static s32 no_op(struct dynamic_loader_initialize *thisptr, void *bufr,
+                ldr_addr locn, struct ldr_section_info *info,
+                unsigned bytsize);
+
+/*
+ *  Functions called by dynamic loader
+ *
+ */
+/* dynamic_loader_stream */
+static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer,
+                           unsigned bufsize);
+static int dbll_set_file_posn(struct dynamic_loader_stream *this,
+                             unsigned int pos);
+/* dynamic_loader_sym */
+static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
+                                              const char *name);
+static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym
+                                                      *this, const char *name,
+                                                      unsigned module_id);
+static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym
+                                                  *this, const char *name,
+                                                  unsigned moduleid);
+static void dbll_purge_symbol_table(struct dynamic_loader_sym *this,
+                                   unsigned module_id);
+static void *allocate(struct dynamic_loader_sym *this, unsigned memsize);
+static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr);
+static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr,
+                           va_list args);
+/* dynamic_loader_allocate */
+static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
+                         struct ldr_section_info *info, unsigned align);
+static void rmm_dealloc(struct dynamic_loader_allocate *this,
+                       struct ldr_section_info *info);
+
+/* dynamic_loader_initialize */
+static int connect(struct dynamic_loader_initialize *this);
+static int read_mem(struct dynamic_loader_initialize *this, void *buf,
+                   ldr_addr addr, struct ldr_section_info *info,
+                   unsigned bytes);
+static int write_mem(struct dynamic_loader_initialize *this, void *buf,
+                    ldr_addr addr, struct ldr_section_info *info,
+                    unsigned nbytes);
+static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr,
+                   struct ldr_section_info *info, unsigned bytes,
+                   unsigned val);
+static int execute(struct dynamic_loader_initialize *this, ldr_addr start);
+static void release(struct dynamic_loader_initialize *this);
+
+/* symbol table hash functions */
+static u16 name_hash(void *key, u16 max_bucket);
+static bool name_match(void *key, void *sp);
+static void sym_delete(void *value);
+
+static u32 refs;               /* module reference count */
+
+/* Symbol Redefinition */
+static int redefined_symbol;
+static int gbl_search = 1;
+
+/*
+ *  ======== dbll_close ========
+ */
+void dbll_close(struct dbll_library_obj *zl_lib)
+{
+       struct dbll_tar_obj *zl_target;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_lib);
+       DBC_REQUIRE(zl_lib->open_ref > 0);
+       zl_target = zl_lib->target_obj;
+       zl_lib->open_ref--;
+       if (zl_lib->open_ref == 0) {
+               /* Remove library from list */
+               if (zl_target->head == zl_lib)
+                       zl_target->head = zl_lib->next;
+
+               if (zl_lib->prev)
+                       (zl_lib->prev)->next = zl_lib->next;
+
+               if (zl_lib->next)
+                       (zl_lib->next)->prev = zl_lib->prev;
+
+               /* Free DOF resources */
+               dof_close(zl_lib);
+               kfree(zl_lib->file_name);
+
+               /* remove symbols from symbol table */
+               if (zl_lib->sym_tab)
+                       gh_delete(zl_lib->sym_tab);
+
+               /* remove the library object itself */
+               kfree(zl_lib);
+               zl_lib = NULL;
+       }
+}
+
+/*
+ *  ======== dbll_create ========
+ */
+int dbll_create(struct dbll_tar_obj **target_obj,
+                      struct dbll_attrs *pattrs)
+{
+       struct dbll_tar_obj *pzl_target;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pattrs != NULL);
+       DBC_REQUIRE(target_obj != NULL);
+
+       /* Allocate DBL target object */
+       pzl_target = kzalloc(sizeof(struct dbll_tar_obj), GFP_KERNEL);
+       if (target_obj != NULL) {
+               if (pzl_target == NULL) {
+                       *target_obj = NULL;
+                       status = -ENOMEM;
+               } else {
+                       pzl_target->attrs = *pattrs;
+                       *target_obj = (struct dbll_tar_obj *)pzl_target;
+               }
+               DBC_ENSURE((!status && *target_obj) ||
+                               (status && *target_obj == NULL));
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dbll_delete ========
+ */
+void dbll_delete(struct dbll_tar_obj *target)
+{
+       struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_target);
+
+       if (zl_target != NULL)
+               kfree(zl_target);
+
+}
+
+/*
+ *  ======== dbll_exit ========
+ *  Discontinue usage of DBL module.
+ */
+void dbll_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       if (refs == 0)
+               gh_exit();
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== dbll_get_addr ========
+ *  Get address of name in the specified library.
+ */
+bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name,
+                  struct dbll_sym_val **sym_val)
+{
+       struct dbll_symbol *sym;
+       bool status = false;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_lib);
+       DBC_REQUIRE(name != NULL);
+       DBC_REQUIRE(sym_val != NULL);
+       DBC_REQUIRE(zl_lib->sym_tab != NULL);
+
+       sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, name);
+       if (sym != NULL) {
+               *sym_val = &sym->value;
+               status = true;
+       }
+
+       dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p, status 0x%x\n",
+               __func__, zl_lib, name, sym_val, status);
+       return status;
+}
+
+/*
+ *  ======== dbll_get_attrs ========
+ *  Retrieve the attributes of the target.
+ */
+void dbll_get_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs)
+{
+       struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_target);
+       DBC_REQUIRE(pattrs != NULL);
+
+       if ((pattrs != NULL) && (zl_target != NULL))
+               *pattrs = zl_target->attrs;
+
+}
+
+/*
+ *  ======== dbll_get_c_addr ========
+ *  Get address of a "C" name in the specified library.
+ */
+bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name,
+                    struct dbll_sym_val **sym_val)
+{
+       struct dbll_symbol *sym;
+       char cname[MAXEXPR + 1];
+       bool status = false;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_lib);
+       DBC_REQUIRE(sym_val != NULL);
+       DBC_REQUIRE(zl_lib->sym_tab != NULL);
+       DBC_REQUIRE(name != NULL);
+
+       cname[0] = '_';
+
+       strncpy(cname + 1, name, sizeof(cname) - 2);
+       cname[MAXEXPR] = '\0';  /* insure '\0' string termination */
+
+       /* Check for C name, if not found */
+       sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, cname);
+
+       if (sym != NULL) {
+               *sym_val = &sym->value;
+               status = true;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dbll_get_sect ========
+ *  Get the base address and size (in bytes) of a COFF section.
+ */
+int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr,
+                        u32 *psize)
+{
+       u32 byte_size;
+       bool opened_doff = false;
+       const struct ldr_section_info *sect = NULL;
+       struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(name != NULL);
+       DBC_REQUIRE(paddr != NULL);
+       DBC_REQUIRE(psize != NULL);
+       DBC_REQUIRE(zl_lib);
+
+       /* If DOFF file is not open, we open it. */
+       if (zl_lib != NULL) {
+               if (zl_lib->fp == NULL) {
+                       status = dof_open(zl_lib);
+                       if (!status)
+                               opened_doff = true;
+
+               } else {
+                       (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
+                                                             zl_lib->ul_pos,
+                                                             SEEK_SET);
+               }
+       } else {
+               status = -EFAULT;
+       }
+       if (!status) {
+               byte_size = 1;
+               if (dload_get_section_info(zl_lib->desc, name, &sect)) {
+                       *paddr = sect->load_addr;
+                       *psize = sect->size * byte_size;
+                       /* Make sure size is even for good swap */
+                       if (*psize % 2)
+                               (*psize)++;
+
+                       /* Align size */
+                       *psize = DOFF_ALIGN(*psize);
+               } else {
+                       status = -ENXIO;
+               }
+       }
+       if (opened_doff) {
+               dof_close(zl_lib);
+               opened_doff = false;
+       }
+
+       dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, "
+               "status 0x%x\n", __func__, lib, name, paddr, psize, status);
+
+       return status;
+}
+
+/*
+ *  ======== dbll_init ========
+ */
+bool dbll_init(void)
+{
+       DBC_REQUIRE(refs >= 0);
+
+       if (refs == 0)
+               gh_init();
+
+       refs++;
+
+       return true;
+}
+
+/*
+ *  ======== dbll_load ========
+ */
+int dbll_load(struct dbll_library_obj *lib, dbll_flags flags,
+                    struct dbll_attrs *attrs, u32 *entry)
+{
+       struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
+       struct dbll_tar_obj *dbzl;
+       bool got_symbols = true;
+       s32 err;
+       int status = 0;
+       bool opened_doff = false;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_lib);
+       DBC_REQUIRE(entry != NULL);
+       DBC_REQUIRE(attrs != NULL);
+
+       /*
+        *  Load if not already loaded.
+        */
+       if (zl_lib->load_ref == 0 || !(flags & DBLL_DYNAMIC)) {
+               dbzl = zl_lib->target_obj;
+               dbzl->attrs = *attrs;
+               /* Create a hash table for symbols if not already created */
+               if (zl_lib->sym_tab == NULL) {
+                       got_symbols = false;
+                       zl_lib->sym_tab = gh_create(MAXBUCKETS,
+                                                   sizeof(struct dbll_symbol),
+                                                   name_hash,
+                                                   name_match, sym_delete);
+                       if (zl_lib->sym_tab == NULL)
+                               status = -ENOMEM;
+
+               }
+               /*
+                *  Set up objects needed by the dynamic loader
+                */
+               /* Stream */
+               zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer;
+               zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn;
+               zl_lib->stream.lib = zl_lib;
+               /* Symbol */
+               zl_lib->symbol.dl_symbol.find_matching_symbol =
+                   dbll_find_symbol;
+               if (got_symbols) {
+                       zl_lib->symbol.dl_symbol.add_to_symbol_table =
+                           find_in_symbol_table;
+               } else {
+                       zl_lib->symbol.dl_symbol.add_to_symbol_table =
+                           dbll_add_to_symbol_table;
+               }
+               zl_lib->symbol.dl_symbol.purge_symbol_table =
+                   dbll_purge_symbol_table;
+               zl_lib->symbol.dl_symbol.dload_allocate = allocate;
+               zl_lib->symbol.dl_symbol.dload_deallocate = deallocate;
+               zl_lib->symbol.dl_symbol.error_report = dbll_err_report;
+               zl_lib->symbol.lib = zl_lib;
+               /* Allocate */
+               zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc;
+               zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc;
+               zl_lib->allocate.lib = zl_lib;
+               /* Init */
+               zl_lib->init.dl_init.connect = connect;
+               zl_lib->init.dl_init.readmem = read_mem;
+               zl_lib->init.dl_init.writemem = write_mem;
+               zl_lib->init.dl_init.fillmem = fill_mem;
+               zl_lib->init.dl_init.execute = execute;
+               zl_lib->init.dl_init.release = release;
+               zl_lib->init.lib = zl_lib;
+               /* If COFF file is not open, we open it. */
+               if (zl_lib->fp == NULL) {
+                       status = dof_open(zl_lib);
+                       if (!status)
+                               opened_doff = true;
+
+               }
+               if (!status) {
+                       zl_lib->ul_pos = (*(zl_lib->target_obj->attrs.ftell))
+                           (zl_lib->fp);
+                       /* Reset file cursor */
+                       (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
+                                                             (long)0,
+                                                             SEEK_SET);
+                       symbols_reloaded = true;
+                       /* The 5th argument, DLOAD_INITBSS, tells the DLL
+                        * module to zero-init all BSS sections.  In general,
+                        * this is not necessary and also increases load time.
+                        * We may want to make this configurable by the user */
+                       err = dynamic_load_module(&zl_lib->stream.dl_stream,
+                                                 &zl_lib->symbol.dl_symbol,
+                                                 &zl_lib->allocate.dl_alloc,
+                                                 &zl_lib->init.dl_init,
+                                                 DLOAD_INITBSS,
+                                                 &zl_lib->dload_mod_obj);
+
+                       if (err != 0) {
+                               status = -EILSEQ;
+                       } else if (redefined_symbol) {
+                               zl_lib->load_ref++;
+                               dbll_unload(zl_lib, (struct dbll_attrs *)attrs);
+                               redefined_symbol = false;
+                               status = -EILSEQ;
+                       } else {
+                               *entry = zl_lib->entry;
+                       }
+               }
+       }
+       if (!status)
+               zl_lib->load_ref++;
+
+       /* Clean up DOFF resources */
+       if (opened_doff)
+               dof_close(zl_lib);
+
+       DBC_ENSURE(status || zl_lib->load_ref > 0);
+
+       dev_dbg(bridge, "%s: lib: %p flags: 0x%x entry: %p, status 0x%x\n",
+               __func__, lib, flags, entry, status);
+
+       return status;
+}
+
+/*
+ *  ======== dbll_load_sect ========
+ *  Not supported for COFF.
+ */
+int dbll_load_sect(struct dbll_library_obj *zl_lib, char *sec_name,
+                         struct dbll_attrs *attrs)
+{
+       DBC_REQUIRE(zl_lib);
+
+       return -ENOSYS;
+}
+
+/*
+ *  ======== dbll_open ========
+ */
+int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags,
+                    struct dbll_library_obj **lib_obj)
+{
+       struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
+       struct dbll_library_obj *zl_lib = NULL;
+       s32 err;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_target);
+       DBC_REQUIRE(zl_target->attrs.fopen != NULL);
+       DBC_REQUIRE(file != NULL);
+       DBC_REQUIRE(lib_obj != NULL);
+
+       zl_lib = zl_target->head;
+       while (zl_lib != NULL) {
+               if (strcmp(zl_lib->file_name, file) == 0) {
+                       /* Library is already opened */
+                       zl_lib->open_ref++;
+                       break;
+               }
+               zl_lib = zl_lib->next;
+       }
+       if (zl_lib == NULL) {
+               /* Allocate DBL library object */
+               zl_lib = kzalloc(sizeof(struct dbll_library_obj), GFP_KERNEL);
+               if (zl_lib == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       zl_lib->ul_pos = 0;
+                       /* Increment ref count to allow close on failure
+                        * later on */
+                       zl_lib->open_ref++;
+                       zl_lib->target_obj = zl_target;
+                       /* Keep a copy of the file name */
+                       zl_lib->file_name = kzalloc(strlen(file) + 1,
+                                                       GFP_KERNEL);
+                       if (zl_lib->file_name == NULL) {
+                               status = -ENOMEM;
+                       } else {
+                               strncpy(zl_lib->file_name, file,
+                                       strlen(file) + 1);
+                       }
+                       zl_lib->sym_tab = NULL;
+               }
+       }
+       /*
+        *  Set up objects needed by the dynamic loader
+        */
+       if (status)
+               goto func_cont;
+
+       /* Stream */
+       zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer;
+       zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn;
+       zl_lib->stream.lib = zl_lib;
+       /* Symbol */
+       zl_lib->symbol.dl_symbol.add_to_symbol_table = dbll_add_to_symbol_table;
+       zl_lib->symbol.dl_symbol.find_matching_symbol = dbll_find_symbol;
+       zl_lib->symbol.dl_symbol.purge_symbol_table = dbll_purge_symbol_table;
+       zl_lib->symbol.dl_symbol.dload_allocate = allocate;
+       zl_lib->symbol.dl_symbol.dload_deallocate = deallocate;
+       zl_lib->symbol.dl_symbol.error_report = dbll_err_report;
+       zl_lib->symbol.lib = zl_lib;
+       /* Allocate */
+       zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc;
+       zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc;
+       zl_lib->allocate.lib = zl_lib;
+       /* Init */
+       zl_lib->init.dl_init.connect = connect;
+       zl_lib->init.dl_init.readmem = read_mem;
+       zl_lib->init.dl_init.writemem = write_mem;
+       zl_lib->init.dl_init.fillmem = fill_mem;
+       zl_lib->init.dl_init.execute = execute;
+       zl_lib->init.dl_init.release = release;
+       zl_lib->init.lib = zl_lib;
+       if (!status && zl_lib->fp == NULL)
+               status = dof_open(zl_lib);
+
+       zl_lib->ul_pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp);
+       (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, SEEK_SET);
+       /* Create a hash table for symbols if flag is set */
+       if (zl_lib->sym_tab != NULL || !(flags & DBLL_SYMB))
+               goto func_cont;
+
+       zl_lib->sym_tab =
+           gh_create(MAXBUCKETS, sizeof(struct dbll_symbol), name_hash,
+                     name_match, sym_delete);
+       if (zl_lib->sym_tab == NULL) {
+               status = -ENOMEM;
+       } else {
+               /* Do a fake load to get symbols - set write func to no_op */
+               zl_lib->init.dl_init.writemem = no_op;
+               err = dynamic_open_module(&zl_lib->stream.dl_stream,
+                                         &zl_lib->symbol.dl_symbol,
+                                         &zl_lib->allocate.dl_alloc,
+                                         &zl_lib->init.dl_init, 0,
+                                         &zl_lib->dload_mod_obj);
+               if (err != 0) {
+                       status = -EILSEQ;
+               } else {
+                       /* Now that we have the symbol table, we can unload */
+                       err = dynamic_unload_module(zl_lib->dload_mod_obj,
+                                                   &zl_lib->symbol.dl_symbol,
+                                                   &zl_lib->allocate.dl_alloc,
+                                                   &zl_lib->init.dl_init);
+                       if (err != 0)
+                               status = -EILSEQ;
+
+                       zl_lib->dload_mod_obj = NULL;
+               }
+       }
+func_cont:
+       if (!status) {
+               if (zl_lib->open_ref == 1) {
+                       /* First time opened - insert in list */
+                       if (zl_target->head)
+                               (zl_target->head)->prev = zl_lib;
+
+                       zl_lib->prev = NULL;
+                       zl_lib->next = zl_target->head;
+                       zl_target->head = zl_lib;
+               }
+               *lib_obj = (struct dbll_library_obj *)zl_lib;
+       } else {
+               *lib_obj = NULL;
+               if (zl_lib != NULL)
+                       dbll_close((struct dbll_library_obj *)zl_lib);
+
+       }
+       DBC_ENSURE((!status && (zl_lib->open_ref > 0) && *lib_obj)
+                               || (status && *lib_obj == NULL));
+
+       dev_dbg(bridge, "%s: target: %p file: %s lib_obj: %p, status 0x%x\n",
+               __func__, target, file, lib_obj, status);
+
+       return status;
+}
+
+/*
+ *  ======== dbll_read_sect ========
+ *  Get the content of a COFF section.
+ */
+int dbll_read_sect(struct dbll_library_obj *lib, char *name,
+                         char *buf, u32 size)
+{
+       struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
+       bool opened_doff = false;
+       u32 byte_size;          /* size of bytes */
+       u32 ul_sect_size;       /* size of section */
+       const struct ldr_section_info *sect = NULL;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_lib);
+       DBC_REQUIRE(name != NULL);
+       DBC_REQUIRE(buf != NULL);
+       DBC_REQUIRE(size != 0);
+
+       /* If DOFF file is not open, we open it. */
+       if (zl_lib != NULL) {
+               if (zl_lib->fp == NULL) {
+                       status = dof_open(zl_lib);
+                       if (!status)
+                               opened_doff = true;
+
+               } else {
+                       (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
+                                                             zl_lib->ul_pos,
+                                                             SEEK_SET);
+               }
+       } else {
+               status = -EFAULT;
+       }
+       if (status)
+               goto func_cont;
+
+       byte_size = 1;
+       if (!dload_get_section_info(zl_lib->desc, name, &sect)) {
+               status = -ENXIO;
+               goto func_cont;
+       }
+       /*
+        * Ensure the supplied buffer size is sufficient to store
+        * the section buf to be read.
+        */
+       ul_sect_size = sect->size * byte_size;
+       /* Make sure size is even for good swap */
+       if (ul_sect_size % 2)
+               ul_sect_size++;
+
+       /* Align size */
+       ul_sect_size = DOFF_ALIGN(ul_sect_size);
+       if (ul_sect_size > size) {
+               status = -EPERM;
+       } else {
+               if (!dload_get_section(zl_lib->desc, sect, buf))
+                       status = -EBADF;
+
+       }
+func_cont:
+       if (opened_doff) {
+               dof_close(zl_lib);
+               opened_doff = false;
+       }
+
+       dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, "
+               "status 0x%x\n", __func__, lib, name, buf, size, status);
+       return status;
+}
+
+/*
+ *  ======== dbll_set_attrs ========
+ *  Set the attributes of the target.
+ */
+void dbll_set_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs)
+{
+       struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_target);
+       DBC_REQUIRE(pattrs != NULL);
+
+       if ((pattrs != NULL) && (zl_target != NULL))
+               zl_target->attrs = *pattrs;
+
+}
+
+/*
+ *  ======== dbll_unload ========
+ */
+void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs)
+{
+       struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
+       s32 err = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(zl_lib);
+       DBC_REQUIRE(zl_lib->load_ref > 0);
+       dev_dbg(bridge, "%s: lib: %p\n", __func__, lib);
+       zl_lib->load_ref--;
+       /* Unload only if reference count is 0 */
+       if (zl_lib->load_ref != 0)
+               goto func_end;
+
+       zl_lib->target_obj->attrs = *attrs;
+       if (zl_lib->dload_mod_obj) {
+               err = dynamic_unload_module(zl_lib->dload_mod_obj,
+                                           &zl_lib->symbol.dl_symbol,
+                                           &zl_lib->allocate.dl_alloc,
+                                           &zl_lib->init.dl_init);
+               if (err != 0)
+                       dev_dbg(bridge, "%s: failed: 0x%x\n", __func__, err);
+       }
+       /* remove symbols from symbol table */
+       if (zl_lib->sym_tab != NULL) {
+               gh_delete(zl_lib->sym_tab);
+               zl_lib->sym_tab = NULL;
+       }
+       /* delete DOFF desc since it holds *lots* of host OS
+        * resources */
+       dof_close(zl_lib);
+func_end:
+       DBC_ENSURE(zl_lib->load_ref >= 0);
+}
+
+/*
+ *  ======== dbll_unload_sect ========
+ *  Not supported for COFF.
+ */
+int dbll_unload_sect(struct dbll_library_obj *lib, char *sec_name,
+                           struct dbll_attrs *attrs)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(sec_name != NULL);
+
+       return -ENOSYS;
+}
+
+/*
+ *  ======== dof_close ========
+ */
+static void dof_close(struct dbll_library_obj *zl_lib)
+{
+       if (zl_lib->desc) {
+               dload_module_close(zl_lib->desc);
+               zl_lib->desc = NULL;
+       }
+       /* close file */
+       if (zl_lib->fp) {
+               (zl_lib->target_obj->attrs.fclose) (zl_lib->fp);
+               zl_lib->fp = NULL;
+       }
+}
+
+/*
+ *  ======== dof_open ========
+ */
+static int dof_open(struct dbll_library_obj *zl_lib)
+{
+       void *open = *(zl_lib->target_obj->attrs.fopen);
+       int status = 0;
+
+       /* First open the file for the dynamic loader, then open COF */
+       zl_lib->fp =
+           (void *)((dbll_f_open_fxn) (open)) (zl_lib->file_name, "rb");
+
+       /* Open DOFF module */
+       if (zl_lib->fp && zl_lib->desc == NULL) {
+               (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0,
+                                                     SEEK_SET);
+               zl_lib->desc =
+                   dload_module_open(&zl_lib->stream.dl_stream,
+                                     &zl_lib->symbol.dl_symbol);
+               if (zl_lib->desc == NULL) {
+                       (zl_lib->target_obj->attrs.fclose) (zl_lib->fp);
+                       zl_lib->fp = NULL;
+                       status = -EBADF;
+               }
+       } else {
+               status = -EBADF;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== name_hash ========
+ */
+static u16 name_hash(void *key, u16 max_bucket)
+{
+       u16 ret;
+       u16 hash;
+       char *name = (char *)key;
+
+       DBC_REQUIRE(name != NULL);
+
+       hash = 0;
+
+       while (*name) {
+               hash <<= 1;
+               hash ^= *name++;
+       }
+
+       ret = hash % max_bucket;
+
+       return ret;
+}
+
+/*
+ *  ======== name_match ========
+ */
+static bool name_match(void *key, void *sp)
+{
+       DBC_REQUIRE(key != NULL);
+       DBC_REQUIRE(sp != NULL);
+
+       if ((key != NULL) && (sp != NULL)) {
+               if (strcmp((char *)key, ((struct dbll_symbol *)sp)->name) ==
+                   0)
+                       return true;
+       }
+       return false;
+}
+
+/*
+ *  ======== no_op ========
+ */
+static int no_op(struct dynamic_loader_initialize *thisptr, void *bufr,
+                ldr_addr locn, struct ldr_section_info *info, unsigned bytsize)
+{
+       return 1;
+}
+
+/*
+ *  ======== sym_delete ========
+ */
+static void sym_delete(void *value)
+{
+       struct dbll_symbol *sp = (struct dbll_symbol *)value;
+
+       kfree(sp->name);
+}
+
+/*
+ *  Dynamic Loader Functions
+ */
+
+/* dynamic_loader_stream */
+/*
+ *  ======== dbll_read_buffer ========
+ */
+static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer,
+                           unsigned bufsize)
+{
+       struct dbll_stream *pstream = (struct dbll_stream *)this;
+       struct dbll_library_obj *lib;
+       int bytes_read = 0;
+
+       DBC_REQUIRE(this != NULL);
+       lib = pstream->lib;
+       DBC_REQUIRE(lib);
+
+       if (lib != NULL) {
+               bytes_read =
+                   (*(lib->target_obj->attrs.fread)) (buffer, 1, bufsize,
+                                                      lib->fp);
+       }
+       return bytes_read;
+}
+
+/*
+ *  ======== dbll_set_file_posn ========
+ */
+static int dbll_set_file_posn(struct dynamic_loader_stream *this,
+                             unsigned int pos)
+{
+       struct dbll_stream *pstream = (struct dbll_stream *)this;
+       struct dbll_library_obj *lib;
+       int status = 0;         /* Success */
+
+       DBC_REQUIRE(this != NULL);
+       lib = pstream->lib;
+       DBC_REQUIRE(lib);
+
+       if (lib != NULL) {
+               status = (*(lib->target_obj->attrs.fseek)) (lib->fp, (long)pos,
+                                                           SEEK_SET);
+       }
+
+       return status;
+}
+
+/* dynamic_loader_sym */
+
+/*
+ *  ======== dbll_find_symbol ========
+ */
+static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
+                                              const char *name)
+{
+       struct dynload_symbol *ret_sym;
+       struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
+       struct dbll_library_obj *lib;
+       struct dbll_sym_val *dbll_sym = NULL;
+       bool status = false;    /* Symbol not found yet */
+
+       DBC_REQUIRE(this != NULL);
+       lib = ldr_sym->lib;
+       DBC_REQUIRE(lib);
+
+       if (lib != NULL) {
+               if (lib->target_obj->attrs.sym_lookup) {
+                       /* Check current lib + base lib + dep lib +
+                        * persistent lib */
+                       status = (*(lib->target_obj->attrs.sym_lookup))
+                           (lib->target_obj->attrs.sym_handle,
+                            lib->target_obj->attrs.sym_arg,
+                            lib->target_obj->attrs.rmm_handle, name,
+                            &dbll_sym);
+               } else {
+                       /* Just check current lib for symbol */
+                       status = dbll_get_addr((struct dbll_library_obj *)lib,
+                                              (char *)name, &dbll_sym);
+                       if (!status) {
+                               status =
+                                   dbll_get_c_addr((struct dbll_library_obj *)
+                                                   lib, (char *)name,
+                                                   &dbll_sym);
+                       }
+               }
+       }
+
+       if (!status && gbl_search)
+               dev_dbg(bridge, "%s: Symbol not found: %s\n", __func__, name);
+
+       DBC_ASSERT((status && (dbll_sym != NULL))
+                  || (!status && (dbll_sym == NULL)));
+
+       ret_sym = (struct dynload_symbol *)dbll_sym;
+       return ret_sym;
+}
+
+/*
+ *  ======== find_in_symbol_table ========
+ */
+static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym
+                                                  *this, const char *name,
+                                                  unsigned moduleid)
+{
+       struct dynload_symbol *ret_sym;
+       struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
+       struct dbll_library_obj *lib;
+       struct dbll_symbol *sym;
+
+       DBC_REQUIRE(this != NULL);
+       lib = ldr_sym->lib;
+       DBC_REQUIRE(lib);
+       DBC_REQUIRE(lib->sym_tab != NULL);
+
+       sym = (struct dbll_symbol *)gh_find(lib->sym_tab, (char *)name);
+
+       ret_sym = (struct dynload_symbol *)&sym->value;
+       return ret_sym;
+}
+
+/*
+ *  ======== dbll_add_to_symbol_table ========
+ */
+static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym
+                                                      *this, const char *name,
+                                                      unsigned module_id)
+{
+       struct dbll_symbol *sym_ptr = NULL;
+       struct dbll_symbol symbol;
+       struct dynload_symbol *dbll_sym = NULL;
+       struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
+       struct dbll_library_obj *lib;
+       struct dynload_symbol *ret;
+
+       DBC_REQUIRE(this != NULL);
+       DBC_REQUIRE(name);
+       lib = ldr_sym->lib;
+       DBC_REQUIRE(lib);
+
+       /* Check to see if symbol is already defined in symbol table */
+       if (!(lib->target_obj->attrs.base_image)) {
+               gbl_search = false;
+               dbll_sym = dbll_find_symbol(this, name);
+               gbl_search = true;
+               if (dbll_sym) {
+                       redefined_symbol = true;
+                       dev_dbg(bridge, "%s already defined in symbol table\n",
+                               name);
+                       return NULL;
+               }
+       }
+       /* Allocate string to copy symbol name */
+       symbol.name = kzalloc(strlen((char *const)name) + 1, GFP_KERNEL);
+       if (symbol.name == NULL)
+               return NULL;
+
+       if (symbol.name != NULL) {
+               /* Just copy name (value will be filled in by dynamic loader) */
+               strncpy(symbol.name, (char *const)name,
+                       strlen((char *const)name) + 1);
+
+               /* Add symbol to symbol table */
+               sym_ptr =
+                   (struct dbll_symbol *)gh_insert(lib->sym_tab, (void *)name,
+                                                   (void *)&symbol);
+               if (sym_ptr == NULL)
+                       kfree(symbol.name);
+
+       }
+       if (sym_ptr != NULL)
+               ret = (struct dynload_symbol *)&sym_ptr->value;
+       else
+               ret = NULL;
+
+       return ret;
+}
+
+/*
+ *  ======== dbll_purge_symbol_table ========
+ */
+static void dbll_purge_symbol_table(struct dynamic_loader_sym *this,
+                                   unsigned module_id)
+{
+       struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
+       struct dbll_library_obj *lib;
+
+       DBC_REQUIRE(this != NULL);
+       lib = ldr_sym->lib;
+       DBC_REQUIRE(lib);
+
+       /* May not need to do anything */
+}
+
+/*
+ *  ======== allocate ========
+ */
+static void *allocate(struct dynamic_loader_sym *this, unsigned memsize)
+{
+       struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
+       struct dbll_library_obj *lib;
+       void *buf;
+
+       DBC_REQUIRE(this != NULL);
+       lib = ldr_sym->lib;
+       DBC_REQUIRE(lib);
+
+       buf = kzalloc(memsize, GFP_KERNEL);
+
+       return buf;
+}
+
+/*
+ *  ======== deallocate ========
+ */
+static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr)
+{
+       struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
+       struct dbll_library_obj *lib;
+
+       DBC_REQUIRE(this != NULL);
+       lib = ldr_sym->lib;
+       DBC_REQUIRE(lib);
+
+       kfree(mem_ptr);
+}
+
+/*
+ *  ======== dbll_err_report ========
+ */
+static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr,
+                           va_list args)
+{
+       struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
+       struct dbll_library_obj *lib;
+       char temp_buf[MAXEXPR];
+
+       DBC_REQUIRE(this != NULL);
+       lib = ldr_sym->lib;
+       DBC_REQUIRE(lib);
+       vsnprintf((char *)temp_buf, MAXEXPR, (char *)errstr, args);
+       dev_dbg(bridge, "%s\n", temp_buf);
+}
+
+/* dynamic_loader_allocate */
+
+/*
+ *  ======== dbll_rmm_alloc ========
+ */
+static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
+                         struct ldr_section_info *info, unsigned align)
+{
+       struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this;
+       struct dbll_library_obj *lib;
+       int status = 0;
+       u32 mem_sect_type;
+       struct rmm_addr rmm_addr_obj;
+       s32 ret = true;
+       unsigned stype = DLOAD_SECTION_TYPE(info->type);
+       char *token = NULL;
+       char *sz_sec_last_token = NULL;
+       char *sz_last_token = NULL;
+       char *sz_sect_name = NULL;
+       char *psz_cur;
+       s32 token_len = 0;
+       s32 seg_id = -1;
+       s32 req = -1;
+       s32 count = 0;
+       u32 alloc_size = 0;
+       u32 run_addr_flag = 0;
+
+       DBC_REQUIRE(this != NULL);
+       lib = dbll_alloc_obj->lib;
+       DBC_REQUIRE(lib);
+
+       mem_sect_type =
+           (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
+                                                DLOAD_BSS) ? DBLL_BSS :
+           DBLL_DATA;
+
+       /* Attempt to extract the segment ID and requirement information from
+          the name of the section */
+       DBC_REQUIRE(info->name);
+       token_len = strlen((char *)(info->name)) + 1;
+
+       sz_sect_name = kzalloc(token_len, GFP_KERNEL);
+       sz_last_token = kzalloc(token_len, GFP_KERNEL);
+       sz_sec_last_token = kzalloc(token_len, GFP_KERNEL);
+
+       if (sz_sect_name == NULL || sz_sec_last_token == NULL ||
+           sz_last_token == NULL) {
+               status = -ENOMEM;
+               goto func_cont;
+       }
+       strncpy(sz_sect_name, (char *)(info->name), token_len);
+       psz_cur = sz_sect_name;
+       while ((token = strsep(&psz_cur, ":")) && *token != '\0') {
+               strncpy(sz_sec_last_token, sz_last_token,
+                       strlen(sz_last_token) + 1);
+               strncpy(sz_last_token, token, strlen(token) + 1);
+               token = strsep(&psz_cur, ":");
+               count++;        /* optimizes processing */
+       }
+       /* If token is 0 or 1, and sz_sec_last_token is DYN_DARAM or DYN_SARAM,
+          or DYN_EXTERNAL, then mem granularity information is present
+          within the section name - only process if there are at least three
+          tokens within the section name (just a minor optimization) */
+       if (count >= 3)
+               strict_strtol(sz_last_token, 10, (long *)&req);
+
+       if ((req == 0) || (req == 1)) {
+               if (strcmp(sz_sec_last_token, "DYN_DARAM") == 0) {
+                       seg_id = 0;
+               } else {
+                       if (strcmp(sz_sec_last_token, "DYN_SARAM") == 0) {
+                               seg_id = 1;
+                       } else {
+                               if (strcmp(sz_sec_last_token,
+                                          "DYN_EXTERNAL") == 0)
+                                       seg_id = 2;
+                       }
+               }
+       }
+func_cont:
+       kfree(sz_sect_name);
+       sz_sect_name = NULL;
+       kfree(sz_last_token);
+       sz_last_token = NULL;
+       kfree(sz_sec_last_token);
+       sz_sec_last_token = NULL;
+
+       if (mem_sect_type == DBLL_CODE)
+               alloc_size = info->size + GEM_L1P_PREFETCH_SIZE;
+       else
+               alloc_size = info->size;
+
+       if (info->load_addr != info->run_addr)
+               run_addr_flag = 1;
+       /* TODO - ideally, we can pass the alignment requirement also
+        * from here */
+       if (lib != NULL) {
+               status =
+                   (lib->target_obj->attrs.alloc) (lib->target_obj->attrs.
+                                                   rmm_handle, mem_sect_type,
+                                                   alloc_size, align,
+                                                   (u32 *) &rmm_addr_obj,
+                                                   seg_id, req, false);
+       }
+       if (status) {
+               ret = false;
+       } else {
+               /* RMM gives word address. Need to convert to byte address */
+               info->load_addr = rmm_addr_obj.addr * DSPWORDSIZE;
+               if (!run_addr_flag)
+                       info->run_addr = info->load_addr;
+               info->context = (u32) rmm_addr_obj.segid;
+               dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, "
+                       "info->run_addr 0x%x, info->load_addr 0x%x\n",
+                       __func__, info->name, info->load_addr / DSPWORDSIZE,
+                       info->size / DSPWORDSIZE, info->run_addr,
+                       info->load_addr);
+       }
+       return ret;
+}
+
+/*
+ *  ======== rmm_dealloc ========
+ */
+static void rmm_dealloc(struct dynamic_loader_allocate *this,
+                       struct ldr_section_info *info)
+{
+       struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this;
+       struct dbll_library_obj *lib;
+       u32 segid;
+       int status = 0;
+       unsigned stype = DLOAD_SECTION_TYPE(info->type);
+       u32 mem_sect_type;
+       u32 free_size = 0;
+
+       mem_sect_type =
+           (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
+                                                DLOAD_BSS) ? DBLL_BSS :
+           DBLL_DATA;
+       DBC_REQUIRE(this != NULL);
+       lib = dbll_alloc_obj->lib;
+       DBC_REQUIRE(lib);
+       /* segid was set by alloc function */
+       segid = (u32) info->context;
+       if (mem_sect_type == DBLL_CODE)
+               free_size = info->size + GEM_L1P_PREFETCH_SIZE;
+       else
+               free_size = info->size;
+       if (lib != NULL) {
+               status =
+                   (lib->target_obj->attrs.free) (lib->target_obj->attrs.
+                                                  sym_handle, segid,
+                                                  info->load_addr /
+                                                  DSPWORDSIZE, free_size,
+                                                  false);
+       }
+}
+
+/* dynamic_loader_initialize */
+/*
+ *  ======== connect ========
+ */
+static int connect(struct dynamic_loader_initialize *this)
+{
+       return true;
+}
+
+/*
+ *  ======== read_mem ========
+ *  This function does not need to be implemented.
+ */
+static int read_mem(struct dynamic_loader_initialize *this, void *buf,
+                   ldr_addr addr, struct ldr_section_info *info,
+                   unsigned nbytes)
+{
+       struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
+       struct dbll_library_obj *lib;
+       int bytes_read = 0;
+
+       DBC_REQUIRE(this != NULL);
+       lib = init_obj->lib;
+       DBC_REQUIRE(lib);
+       /* Need bridge_brd_read function */
+       return bytes_read;
+}
+
+/*
+ *  ======== write_mem ========
+ */
+static int write_mem(struct dynamic_loader_initialize *this, void *buf,
+                    ldr_addr addr, struct ldr_section_info *info,
+                    unsigned bytes)
+{
+       struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
+       struct dbll_library_obj *lib;
+       struct dbll_tar_obj *target_obj;
+       struct dbll_sect_info sect_info;
+       u32 mem_sect_type;
+       bool ret = true;
+
+       DBC_REQUIRE(this != NULL);
+       lib = init_obj->lib;
+       if (!lib)
+               return false;
+
+       target_obj = lib->target_obj;
+
+       mem_sect_type =
+           (DLOAD_SECTION_TYPE(info->type) ==
+            DLOAD_TEXT) ? DBLL_CODE : DBLL_DATA;
+       if (target_obj && target_obj->attrs.write) {
+               ret =
+                   (*target_obj->attrs.write) (target_obj->attrs.input_params,
+                                               addr, buf, bytes,
+                                               mem_sect_type);
+
+               if (target_obj->attrs.log_write) {
+                       sect_info.name = info->name;
+                       sect_info.sect_run_addr = info->run_addr;
+                       sect_info.sect_load_addr = info->load_addr;
+                       sect_info.size = info->size;
+                       sect_info.type = mem_sect_type;
+                       /* Pass the information about what we've written to
+                        * another module */
+                       (*target_obj->attrs.log_write) (target_obj->attrs.
+                                                       log_write_handle,
+                                                       &sect_info, addr,
+                                                       bytes);
+               }
+       }
+       return ret;
+}
+
+/*
+ *  ======== fill_mem ========
+ *  Fill bytes of memory at a given address with a given value by
+ *  writing from a buffer containing the given value.  Write in
+ *  sets of MAXEXPR (128) bytes to avoid large stack buffer issues.
+ */
+static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr,
+                   struct ldr_section_info *info, unsigned bytes, unsigned val)
+{
+       bool ret = true;
+       char *pbuf;
+       struct dbll_library_obj *lib;
+       struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
+
+       DBC_REQUIRE(this != NULL);
+       lib = init_obj->lib;
+       pbuf = NULL;
+       /* Pass the NULL pointer to write_mem to get the start address of Shared
+          memory. This is a trick to just get the start address, there is no
+          writing taking place with this Writemem
+        */
+       if ((lib->target_obj->attrs.write) != (dbll_write_fxn) no_op)
+               write_mem(this, &pbuf, addr, info, 0);
+       if (pbuf)
+               memset(pbuf, val, bytes);
+
+       return ret;
+}
+
+/*
+ *  ======== execute ========
+ */
+static int execute(struct dynamic_loader_initialize *this, ldr_addr start)
+{
+       struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
+       struct dbll_library_obj *lib;
+       bool ret = true;
+
+       DBC_REQUIRE(this != NULL);
+       lib = init_obj->lib;
+       DBC_REQUIRE(lib);
+       /* Save entry point */
+       if (lib != NULL)
+               lib->entry = (u32) start;
+
+       return ret;
+}
+
+/*
+ *  ======== release ========
+ */
+static void release(struct dynamic_loader_initialize *this)
+{
+}
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+/**
+ *  find_symbol_context - Basic symbol context structure
+ * @address:           Symbol Adress
+ * @offset_range:              Offset range where the search for the DSP symbol
+ *                     started.
+ * @cur_best_offset:   Best offset to start looking for the DSP symbol
+ * @sym_addr:          Address of the DSP symbol
+ * @name:              Symbol name
+ *
+ */
+struct find_symbol_context {
+       /* input */
+       u32 address;
+       u32 offset_range;
+       /* state */
+       u32 cur_best_offset;
+       /* output */
+       u32 sym_addr;
+       char name[120];
+};
+
+/**
+ * find_symbol_callback() - Validates symbol address and copies the symbol name
+ *                     to the user data.
+ * @elem:              dsp library context
+ * @user_data:         Find symbol context
+ *
+ */
+void find_symbol_callback(void *elem, void *user_data)
+{
+       struct dbll_symbol *symbol = elem;
+       struct find_symbol_context *context = user_data;
+       u32 symbol_addr = symbol->value.value;
+       u32 offset = context->address - symbol_addr;
+
+       /*
+        * Address given should be greater than symbol address,
+        * symbol address should be  within specified range
+        * and the offset should be better than previous one
+        */
+       if (context->address >= symbol_addr && symbol_addr < (u32)-1 &&
+               offset < context->cur_best_offset) {
+               context->cur_best_offset = offset;
+               context->sym_addr = symbol_addr;
+               strncpy(context->name, symbol->name, sizeof(context->name));
+       }
+
+       return;
+}
+
+/**
+ * dbll_find_dsp_symbol() - This function retrieves the dsp symbol from the dsp binary.
+ * @zl_lib:            DSP binary obj library pointer
+ * @address:           Given address to find the dsp symbol
+ * @offset_range:              offset range to look for dsp symbol
+ * @sym_addr_output:   Symbol Output address
+ * @name_output:               String with the dsp symbol
+ *
+ *     This function retrieves the dsp symbol from the dsp binary.
+ */
+bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address,
+                               u32 offset_range, u32 *sym_addr_output,
+                               char *name_output)
+{
+       bool status = false;
+       struct find_symbol_context context;
+
+       context.address = address;
+       context.offset_range = offset_range;
+       context.cur_best_offset = offset_range;
+       context.sym_addr = 0;
+       context.name[0] = '\0';
+
+       gh_iterate(zl_lib->sym_tab, find_symbol_callback, &context);
+
+       if (context.name[0]) {
+               status = true;
+               strcpy(name_output, context.name);
+               *sym_addr_output = context.sym_addr;
+       }
+
+       return status;
+}
+#endif
diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c
new file mode 100644 (file)
index 0000000..4ddf03d
--- /dev/null
@@ -0,0 +1,1151 @@
+/*
+ * dev.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implementation of Bridge Bridge driver device operations.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/ldr.h>
+#include <dspbridge/list.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/cod.h>
+#include <dspbridge/drv.h>
+#include <dspbridge/proc.h>
+#include <dspbridge/dmm.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/mgr.h>
+#include <dspbridge/node.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/dspapi.h>  /* DSP API version info. */
+
+#include <dspbridge/chnl.h>
+#include <dspbridge/io.h>
+#include <dspbridge/msg.h>
+#include <dspbridge/cmm.h>
+#include <dspbridge/dspdeh.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+
+#define MAKEVERSION(major, minor)   (major * 10 + minor)
+#define BRD_API_VERSION                MAKEVERSION(BRD_API_MAJOR_VERSION,      \
+                               BRD_API_MINOR_VERSION)
+
+/* The Bridge device object: */
+struct dev_object {
+       /* LST requires "link" to be first field! */
+       struct list_head link;  /* Link to next dev_object. */
+       u8 dev_type;            /* Device Type */
+       struct cfg_devnode *dev_node_obj;       /* Platform specific dev id */
+       /* Bridge Context Handle */
+       struct bridge_dev_context *hbridge_context;
+       /* Function interface to Bridge driver. */
+       struct bridge_drv_interface bridge_interface;
+       struct brd_object *lock_owner;  /* Client with exclusive access. */
+       struct cod_manager *cod_mgr;    /* Code manager handle. */
+       struct chnl_mgr *hchnl_mgr;     /* Channel manager. */
+       struct deh_mgr *hdeh_mgr;       /* DEH manager. */
+       struct msg_mgr *hmsg_mgr;       /* Message manager. */
+       struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */
+       struct cmm_object *hcmm_mgr;    /* SM memory manager. */
+       struct dmm_object *dmm_mgr;     /* Dynamic memory manager. */
+       struct ldr_module *module_obj;  /* Bridge Module handle. */
+       u32 word_size;          /* DSP word size: quick access. */
+       struct drv_object *hdrv_obj;    /* Driver Object */
+       struct lst_list *proc_list;     /* List of Proceeosr attached to
+                                        * this device */
+       struct node_mgr *hnode_mgr;
+};
+
+/*  ----------------------------------- Globals */
+static u32 refs;               /* Module reference count */
+
+/*  ----------------------------------- Function Prototypes */
+static int fxn_not_implemented(int arg, ...);
+static int init_cod_mgr(struct dev_object *dev_obj);
+static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
+                                struct bridge_drv_interface *intf_fxns);
+/*
+ *  ======== dev_brd_write_fxn ========
+ *  Purpose:
+ *      Exported function to be used as the COD write function.  This function
+ *      is passed a handle to a DEV_hObject, then calls the
+ *      device's bridge_brd_write() function.
+ */
+u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf,
+                     u32 ul_num_bytes, u32 mem_space)
+{
+       struct dev_object *dev_obj = (struct dev_object *)arb;
+       u32 ul_written = 0;
+       int status;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(host_buf != NULL);  /* Required of BrdWrite(). */
+       if (dev_obj) {
+               /* Require of BrdWrite() */
+               DBC_ASSERT(dev_obj->hbridge_context != NULL);
+               status = (*dev_obj->bridge_interface.pfn_brd_write) (
+                                       dev_obj->hbridge_context, host_buf,
+                                       dsp_add, ul_num_bytes, mem_space);
+               /* Special case of getting the address only */
+               if (ul_num_bytes == 0)
+                       ul_num_bytes = 1;
+               if (!status)
+                       ul_written = ul_num_bytes;
+
+       }
+       return ul_written;
+}
+
+/*
+ *  ======== dev_create_device ========
+ *  Purpose:
+ *      Called by the operating system to load the PM Bridge Driver for a
+ *      PM board (device).
+ */
+int dev_create_device(struct dev_object **device_obj,
+                            const char *driver_file_name,
+                            struct cfg_devnode *dev_node_obj)
+{
+       struct cfg_hostres *host_res;
+       struct ldr_module *module_obj = NULL;
+       struct bridge_drv_interface *drv_fxns = NULL;
+       struct dev_object *dev_obj = NULL;
+       struct chnl_mgrattrs mgr_attrs;
+       struct io_attrs io_mgr_attrs;
+       u32 num_windows;
+       struct drv_object *hdrv_obj = NULL;
+       int status = 0;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(device_obj != NULL);
+       DBC_REQUIRE(driver_file_name != NULL);
+
+       status = drv_request_bridge_res_dsp((void *)&host_res);
+
+       if (status) {
+               dev_dbg(bridge, "%s: Failed to reserve bridge resources\n",
+                       __func__);
+               goto leave;
+       }
+
+       /*  Get the Bridge driver interface functions */
+       bridge_drv_entry(&drv_fxns, driver_file_name);
+       if (cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT)) {
+               /* don't propogate CFG errors from this PROC function */
+               status = -EPERM;
+       }
+       /* Create the device object, and pass a handle to the Bridge driver for
+        * storage. */
+       if (!status) {
+               DBC_ASSERT(drv_fxns);
+               dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL);
+               if (dev_obj) {
+                       /* Fill out the rest of the Dev Object structure: */
+                       dev_obj->dev_node_obj = dev_node_obj;
+                       dev_obj->module_obj = module_obj;
+                       dev_obj->cod_mgr = NULL;
+                       dev_obj->hchnl_mgr = NULL;
+                       dev_obj->hdeh_mgr = NULL;
+                       dev_obj->lock_owner = NULL;
+                       dev_obj->word_size = DSPWORDSIZE;
+                       dev_obj->hdrv_obj = hdrv_obj;
+                       dev_obj->dev_type = DSP_UNIT;
+                       /* Store this Bridge's interface functions, based on its
+                        * version. */
+                       store_interface_fxns(drv_fxns,
+                                               &dev_obj->bridge_interface);
+
+                       /* Call fxn_dev_create() to get the Bridge's device
+                        * context handle. */
+                       status = (dev_obj->bridge_interface.pfn_dev_create)
+                           (&dev_obj->hbridge_context, dev_obj,
+                            host_res);
+                       /* Assert bridge_dev_create()'s ensure clause: */
+                       DBC_ASSERT(status
+                                  || (dev_obj->hbridge_context != NULL));
+               } else {
+                       status = -ENOMEM;
+               }
+       }
+       /* Attempt to create the COD manager for this device: */
+       if (!status)
+               status = init_cod_mgr(dev_obj);
+
+       /* Attempt to create the channel manager for this device: */
+       if (!status) {
+               mgr_attrs.max_channels = CHNL_MAXCHANNELS;
+               io_mgr_attrs.birq = host_res->birq_registers;
+               io_mgr_attrs.irq_shared =
+                   (host_res->birq_attrib & CFG_IRQSHARED);
+               io_mgr_attrs.word_size = DSPWORDSIZE;
+               mgr_attrs.word_size = DSPWORDSIZE;
+               num_windows = host_res->num_mem_windows;
+               if (num_windows) {
+                       /* Assume last memory window is for CHNL */
+                       io_mgr_attrs.shm_base = host_res->dw_mem_base[1] +
+                           host_res->dw_offset_for_monitor;
+                       io_mgr_attrs.usm_length =
+                           host_res->dw_mem_length[1] -
+                           host_res->dw_offset_for_monitor;
+               } else {
+                       io_mgr_attrs.shm_base = 0;
+                       io_mgr_attrs.usm_length = 0;
+                       pr_err("%s: No memory reserved for shared structures\n",
+                              __func__);
+               }
+               status = chnl_create(&dev_obj->hchnl_mgr, dev_obj, &mgr_attrs);
+               if (status == -ENOSYS) {
+                       /* It's OK for a device not to have a channel
+                        * manager: */
+                       status = 0;
+               }
+               /* Create CMM mgr even if Msg Mgr not impl. */
+               status = cmm_create(&dev_obj->hcmm_mgr,
+                                   (struct dev_object *)dev_obj, NULL);
+               /* Only create IO manager if we have a channel manager */
+               if (!status && dev_obj->hchnl_mgr) {
+                       status = io_create(&dev_obj->hio_mgr, dev_obj,
+                                          &io_mgr_attrs);
+               }
+               /* Only create DEH manager if we have an IO manager */
+               if (!status) {
+                       /* Instantiate the DEH module */
+                       status = bridge_deh_create(&dev_obj->hdeh_mgr, dev_obj);
+               }
+               /* Create DMM mgr . */
+               status = dmm_create(&dev_obj->dmm_mgr,
+                                   (struct dev_object *)dev_obj, NULL);
+       }
+       /* Add the new DEV_Object to the global list: */
+       if (!status) {
+               lst_init_elem(&dev_obj->link);
+               status = drv_insert_dev_object(hdrv_obj, dev_obj);
+       }
+       /* Create the Processor List */
+       if (!status) {
+               dev_obj->proc_list = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               if (!(dev_obj->proc_list))
+                       status = -EPERM;
+               else
+                       INIT_LIST_HEAD(&dev_obj->proc_list->head);
+       }
+leave:
+       /*  If all went well, return a handle to the dev object;
+        *  else, cleanup and return NULL in the OUT parameter. */
+       if (!status) {
+               *device_obj = dev_obj;
+       } else {
+               if (dev_obj) {
+                       kfree(dev_obj->proc_list);
+                       if (dev_obj->cod_mgr)
+                               cod_delete(dev_obj->cod_mgr);
+                       if (dev_obj->dmm_mgr)
+                               dmm_destroy(dev_obj->dmm_mgr);
+                       kfree(dev_obj);
+               }
+
+               *device_obj = NULL;
+       }
+
+       DBC_ENSURE((!status && *device_obj) || (status && !*device_obj));
+       return status;
+}
+
+/*
+ *  ======== dev_create2 ========
+ *  Purpose:
+ *      After successful loading of the image from api_init_complete2
+ *      (PROC Auto_Start) or proc_load this fxn is called. This creates
+ *      the Node Manager and updates the DEV Object.
+ */
+int dev_create2(struct dev_object *hdev_obj)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hdev_obj);
+
+       /* There can be only one Node Manager per DEV object */
+       DBC_ASSERT(!dev_obj->hnode_mgr);
+       status = node_create_mgr(&dev_obj->hnode_mgr, hdev_obj);
+       if (status)
+               dev_obj->hnode_mgr = NULL;
+
+       DBC_ENSURE((!status && dev_obj->hnode_mgr != NULL)
+                  || (status && dev_obj->hnode_mgr == NULL));
+       return status;
+}
+
+/*
+ *  ======== dev_destroy2 ========
+ *  Purpose:
+ *      Destroys the Node manager for this device.
+ */
+int dev_destroy2(struct dev_object *hdev_obj)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hdev_obj);
+
+       if (dev_obj->hnode_mgr) {
+               if (node_delete_mgr(dev_obj->hnode_mgr))
+                       status = -EPERM;
+               else
+                       dev_obj->hnode_mgr = NULL;
+
+       }
+
+       DBC_ENSURE((!status && dev_obj->hnode_mgr == NULL) || status);
+       return status;
+}
+
+/*
+ *  ======== dev_destroy_device ========
+ *  Purpose:
+ *      Destroys the channel manager for this device, if any, calls
+ *      bridge_dev_destroy(), and then attempts to unload the Bridge module.
+ */
+int dev_destroy_device(struct dev_object *hdev_obj)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (hdev_obj) {
+               if (dev_obj->cod_mgr) {
+                       cod_delete(dev_obj->cod_mgr);
+                       dev_obj->cod_mgr = NULL;
+               }
+
+               if (dev_obj->hnode_mgr) {
+                       node_delete_mgr(dev_obj->hnode_mgr);
+                       dev_obj->hnode_mgr = NULL;
+               }
+
+               /* Free the io, channel, and message managers for this board: */
+               if (dev_obj->hio_mgr) {
+                       io_destroy(dev_obj->hio_mgr);
+                       dev_obj->hio_mgr = NULL;
+               }
+               if (dev_obj->hchnl_mgr) {
+                       chnl_destroy(dev_obj->hchnl_mgr);
+                       dev_obj->hchnl_mgr = NULL;
+               }
+               if (dev_obj->hmsg_mgr) {
+                       msg_delete(dev_obj->hmsg_mgr);
+                       dev_obj->hmsg_mgr = NULL;
+               }
+
+               if (dev_obj->hdeh_mgr) {
+                       /* Uninitialize DEH module. */
+                       bridge_deh_destroy(dev_obj->hdeh_mgr);
+                       dev_obj->hdeh_mgr = NULL;
+               }
+               if (dev_obj->hcmm_mgr) {
+                       cmm_destroy(dev_obj->hcmm_mgr, true);
+                       dev_obj->hcmm_mgr = NULL;
+               }
+
+               if (dev_obj->dmm_mgr) {
+                       dmm_destroy(dev_obj->dmm_mgr);
+                       dev_obj->dmm_mgr = NULL;
+               }
+
+               /* Call the driver's bridge_dev_destroy() function: */
+               /* Require of DevDestroy */
+               if (dev_obj->hbridge_context) {
+                       status = (*dev_obj->bridge_interface.pfn_dev_destroy)
+                           (dev_obj->hbridge_context);
+                       dev_obj->hbridge_context = NULL;
+               } else
+                       status = -EPERM;
+               if (!status) {
+                       kfree(dev_obj->proc_list);
+                       dev_obj->proc_list = NULL;
+
+                       /* Remove this DEV_Object from the global list: */
+                       drv_remove_dev_object(dev_obj->hdrv_obj, dev_obj);
+                       /* Free The library * LDR_FreeModule
+                        * (dev_obj->module_obj); */
+                       /* Free this dev object: */
+                       kfree(dev_obj);
+                       dev_obj = NULL;
+               }
+       } else {
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dev_get_chnl_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the channel manager handle created for this
+ *      device.
+ */
+int dev_get_chnl_mgr(struct dev_object *hdev_obj,
+                           struct chnl_mgr **mgr)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(mgr != NULL);
+
+       if (hdev_obj) {
+               *mgr = dev_obj->hchnl_mgr;
+       } else {
+               *mgr = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
+       return status;
+}
+
+/*
+ *  ======== dev_get_cmm_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the shared memory manager created for this
+ *      device.
+ */
+int dev_get_cmm_mgr(struct dev_object *hdev_obj,
+                          struct cmm_object **mgr)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(mgr != NULL);
+
+       if (hdev_obj) {
+               *mgr = dev_obj->hcmm_mgr;
+       } else {
+               *mgr = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
+       return status;
+}
+
+/*
+ *  ======== dev_get_dmm_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the dynamic memory manager created for this
+ *      device.
+ */
+int dev_get_dmm_mgr(struct dev_object *hdev_obj,
+                          struct dmm_object **mgr)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(mgr != NULL);
+
+       if (hdev_obj) {
+               *mgr = dev_obj->dmm_mgr;
+       } else {
+               *mgr = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
+       return status;
+}
+
+/*
+ *  ======== dev_get_cod_mgr ========
+ *  Purpose:
+ *      Retrieve the COD manager create for this device.
+ */
+int dev_get_cod_mgr(struct dev_object *hdev_obj,
+                          struct cod_manager **cod_mgr)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(cod_mgr != NULL);
+
+       if (hdev_obj) {
+               *cod_mgr = dev_obj->cod_mgr;
+       } else {
+               *cod_mgr = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (cod_mgr != NULL && *cod_mgr == NULL));
+       return status;
+}
+
+/*
+ *  ========= dev_get_deh_mgr ========
+ */
+int dev_get_deh_mgr(struct dev_object *hdev_obj,
+                          struct deh_mgr **deh_manager)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(deh_manager != NULL);
+       DBC_REQUIRE(hdev_obj);
+       if (hdev_obj) {
+               *deh_manager = hdev_obj->hdeh_mgr;
+       } else {
+               *deh_manager = NULL;
+               status = -EFAULT;
+       }
+       return status;
+}
+
+/*
+ *  ======== dev_get_dev_node ========
+ *  Purpose:
+ *      Retrieve the platform specific device ID for this device.
+ */
+int dev_get_dev_node(struct dev_object *hdev_obj,
+                           struct cfg_devnode **dev_nde)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dev_nde != NULL);
+
+       if (hdev_obj) {
+               *dev_nde = dev_obj->dev_node_obj;
+       } else {
+               *dev_nde = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (dev_nde != NULL && *dev_nde == NULL));
+       return status;
+}
+
+/*
+ *  ======== dev_get_first ========
+ *  Purpose:
+ *      Retrieve the first Device Object handle from an internal linked list
+ *      DEV_OBJECTs maintained by DEV.
+ */
+struct dev_object *dev_get_first(void)
+{
+       struct dev_object *dev_obj = NULL;
+
+       dev_obj = (struct dev_object *)drv_get_first_dev_object();
+
+       return dev_obj;
+}
+
+/*
+ *  ======== dev_get_intf_fxns ========
+ *  Purpose:
+ *      Retrieve the Bridge interface function structure for the loaded driver.
+ *      if_fxns != NULL.
+ */
+int dev_get_intf_fxns(struct dev_object *hdev_obj,
+                            struct bridge_drv_interface **if_fxns)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(if_fxns != NULL);
+
+       if (hdev_obj) {
+               *if_fxns = &dev_obj->bridge_interface;
+       } else {
+               *if_fxns = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || ((if_fxns != NULL) && (*if_fxns == NULL)));
+       return status;
+}
+
+/*
+ *  ========= dev_get_io_mgr ========
+ */
+int dev_get_io_mgr(struct dev_object *hdev_obj,
+                         struct io_mgr **io_man)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(io_man != NULL);
+       DBC_REQUIRE(hdev_obj);
+
+       if (hdev_obj) {
+               *io_man = hdev_obj->hio_mgr;
+       } else {
+               *io_man = NULL;
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dev_get_next ========
+ *  Purpose:
+ *      Retrieve the next Device Object handle from an internal linked list
+ *      of DEV_OBJECTs maintained by DEV, after having previously called
+ *      dev_get_first() and zero or more dev_get_next
+ */
+struct dev_object *dev_get_next(struct dev_object *hdev_obj)
+{
+       struct dev_object *next_dev_object = NULL;
+
+       if (hdev_obj) {
+               next_dev_object = (struct dev_object *)
+                   drv_get_next_dev_object((u32) hdev_obj);
+       }
+
+       return next_dev_object;
+}
+
+/*
+ *  ========= dev_get_msg_mgr ========
+ */
+void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(msg_man != NULL);
+       DBC_REQUIRE(hdev_obj);
+
+       *msg_man = hdev_obj->hmsg_mgr;
+}
+
+/*
+ *  ======== dev_get_node_manager ========
+ *  Purpose:
+ *      Retrieve the Node Manager Handle
+ */
+int dev_get_node_manager(struct dev_object *hdev_obj,
+                               struct node_mgr **node_man)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(node_man != NULL);
+
+       if (hdev_obj) {
+               *node_man = dev_obj->hnode_mgr;
+       } else {
+               *node_man = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (node_man != NULL && *node_man == NULL));
+       return status;
+}
+
+/*
+ *  ======== dev_get_symbol ========
+ */
+int dev_get_symbol(struct dev_object *hdev_obj,
+                         const char *str_sym, u32 * pul_value)
+{
+       int status = 0;
+       struct cod_manager *cod_mgr;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(str_sym != NULL && pul_value != NULL);
+
+       if (hdev_obj) {
+               status = dev_get_cod_mgr(hdev_obj, &cod_mgr);
+               if (cod_mgr)
+                       status = cod_get_sym_value(cod_mgr, (char *)str_sym,
+                                                  pul_value);
+               else
+                       status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dev_get_bridge_context ========
+ *  Purpose:
+ *      Retrieve the Bridge Context handle, as returned by the
+ *      bridge_dev_create fxn.
+ */
+int dev_get_bridge_context(struct dev_object *hdev_obj,
+                              struct bridge_dev_context **phbridge_context)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(phbridge_context != NULL);
+
+       if (hdev_obj) {
+               *phbridge_context = dev_obj->hbridge_context;
+       } else {
+               *phbridge_context = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || ((phbridge_context != NULL) &&
+                                            (*phbridge_context == NULL)));
+       return status;
+}
+
+/*
+ *  ======== dev_exit ========
+ *  Purpose:
+ *      Decrement reference count, and free resources when reference count is
+ *      0.
+ */
+void dev_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       if (refs == 0) {
+               cmm_exit();
+               dmm_exit();
+       }
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== dev_init ========
+ *  Purpose:
+ *      Initialize DEV's private state, keeping a reference count on each call.
+ */
+bool dev_init(void)
+{
+       bool cmm_ret, dmm_ret, ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (refs == 0) {
+               cmm_ret = cmm_init();
+               dmm_ret = dmm_init();
+
+               ret = cmm_ret && dmm_ret;
+
+               if (!ret) {
+                       if (cmm_ret)
+                               cmm_exit();
+
+                       if (dmm_ret)
+                               dmm_exit();
+
+               }
+       }
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
+
+/*
+ *  ======== dev_notify_clients ========
+ *  Purpose:
+ *      Notify all clients of this device of a change in device status.
+ */
+int dev_notify_clients(struct dev_object *hdev_obj, u32 ret)
+{
+       int status = 0;
+
+       struct dev_object *dev_obj = hdev_obj;
+       void *proc_obj;
+
+       for (proc_obj = (void *)lst_first(dev_obj->proc_list);
+            proc_obj != NULL;
+            proc_obj = (void *)lst_next(dev_obj->proc_list,
+                                        (struct list_head *)proc_obj))
+               proc_notify_clients(proc_obj, (u32) ret);
+
+       return status;
+}
+
+/*
+ *  ======== dev_remove_device ========
+ */
+int dev_remove_device(struct cfg_devnode *dev_node_obj)
+{
+       struct dev_object *hdev_obj;    /* handle to device object */
+       int status = 0;
+       struct dev_object *dev_obj;
+
+       /* Retrieve the device object handle originaly stored with
+        * the dev_node: */
+       status = cfg_get_dev_object(dev_node_obj, (u32 *) &hdev_obj);
+       if (!status) {
+               /* Remove the Processor List */
+               dev_obj = (struct dev_object *)hdev_obj;
+               /* Destroy the device object. */
+               status = dev_destroy_device(hdev_obj);
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dev_set_chnl_mgr ========
+ *  Purpose:
+ *      Set the channel manager for this device.
+ */
+int dev_set_chnl_mgr(struct dev_object *hdev_obj,
+                           struct chnl_mgr *hmgr)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (hdev_obj)
+               dev_obj->hchnl_mgr = hmgr;
+       else
+               status = -EFAULT;
+
+       DBC_ENSURE(status || (dev_obj->hchnl_mgr == hmgr));
+       return status;
+}
+
+/*
+ *  ======== dev_set_msg_mgr ========
+ *  Purpose:
+ *      Set the message manager for this device.
+ */
+void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hdev_obj);
+
+       hdev_obj->hmsg_mgr = hmgr;
+}
+
+/*
+ *  ======== dev_start_device ========
+ *  Purpose:
+ *      Initializes the new device with the BRIDGE environment.
+ */
+int dev_start_device(struct cfg_devnode *dev_node_obj)
+{
+       struct dev_object *hdev_obj = NULL;     /* handle to 'Bridge Device */
+       /* Bridge driver filename */
+       char bridge_file_name[CFG_MAXSEARCHPATHLEN] = "UMA";
+       int status;
+       struct mgr_object *hmgr_obj = NULL;
+
+       DBC_REQUIRE(refs > 0);
+
+       /* Given all resources, create a device object. */
+       status = dev_create_device(&hdev_obj, bridge_file_name,
+                                  dev_node_obj);
+       if (!status) {
+               /* Store away the hdev_obj with the DEVNODE */
+               status = cfg_set_dev_object(dev_node_obj, (u32) hdev_obj);
+               if (status) {
+                       /* Clean up */
+                       dev_destroy_device(hdev_obj);
+                       hdev_obj = NULL;
+               }
+       }
+       if (!status) {
+               /* Create the Manager Object */
+               status = mgr_create(&hmgr_obj, dev_node_obj);
+       }
+       if (status) {
+               if (hdev_obj)
+                       dev_destroy_device(hdev_obj);
+
+               /* Ensure the device extension is NULL */
+               cfg_set_dev_object(dev_node_obj, 0L);
+       }
+
+       return status;
+}
+
+/*
+ *  ======== fxn_not_implemented ========
+ *  Purpose:
+ *      Takes the place of a Bridge Null Function.
+ *  Parameters:
+ *      Multiple, optional.
+ *  Returns:
+ *      -ENOSYS:   Always.
+ */
+static int fxn_not_implemented(int arg, ...)
+{
+       return -ENOSYS;
+}
+
+/*
+ *  ======== init_cod_mgr ========
+ *  Purpose:
+ *      Create a COD manager for this device.
+ *  Parameters:
+ *      dev_obj:             Pointer to device object created with
+ *                              dev_create_device()
+ *  Returns:
+ *      0:                Success.
+ *      -EFAULT:            Invalid hdev_obj.
+ *  Requires:
+ *      Should only be called once by dev_create_device() for a given DevObject.
+ *  Ensures:
+ */
+static int init_cod_mgr(struct dev_object *dev_obj)
+{
+       int status = 0;
+       char *sz_dummy_file = "dummy";
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(!dev_obj || (dev_obj->cod_mgr == NULL));
+
+       status = cod_create(&dev_obj->cod_mgr, sz_dummy_file, NULL);
+
+       return status;
+}
+
+/*
+ *  ======== dev_insert_proc_object ========
+ *  Purpose:
+ *      Insert a ProcObject into the list maintained by DEV.
+ *  Parameters:
+ *      p_proc_object:        Ptr to ProcObject to insert.
+ *      dev_obj:         Ptr to Dev Object where the list is.
+  *     already_attached:  Ptr to return the bool
+ *  Returns:
+ *      0:           If successful.
+ *  Requires:
+ *      List Exists
+ *      hdev_obj is Valid handle
+ *      DEV Initialized
+ *      already_attached != NULL
+ *      proc_obj != 0
+ *  Ensures:
+ *      0 and List is not Empty.
+ */
+int dev_insert_proc_object(struct dev_object *hdev_obj,
+                                 u32 proc_obj, bool *already_attached)
+{
+       int status = 0;
+       struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dev_obj);
+       DBC_REQUIRE(proc_obj != 0);
+       DBC_REQUIRE(dev_obj->proc_list != NULL);
+       DBC_REQUIRE(already_attached != NULL);
+       if (!LST_IS_EMPTY(dev_obj->proc_list))
+               *already_attached = true;
+
+       /* Add DevObject to tail. */
+       lst_put_tail(dev_obj->proc_list, (struct list_head *)proc_obj);
+
+       DBC_ENSURE(!status && !LST_IS_EMPTY(dev_obj->proc_list));
+
+       return status;
+}
+
+/*
+ *  ======== dev_remove_proc_object ========
+ *  Purpose:
+ *      Search for and remove a Proc object from the given list maintained
+ *      by the DEV
+ *  Parameters:
+ *      p_proc_object:        Ptr to ProcObject to insert.
+ *      dev_obj          Ptr to Dev Object where the list is.
+ *  Returns:
+ *      0:            If successful.
+ *  Requires:
+ *      List exists and is not empty
+ *      proc_obj != 0
+ *      hdev_obj is a valid Dev handle.
+ *  Ensures:
+ *  Details:
+ *      List will be deleted when the DEV is destroyed.
+ */
+int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj)
+{
+       int status = -EPERM;
+       struct list_head *cur_elem;
+       struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
+
+       DBC_REQUIRE(dev_obj);
+       DBC_REQUIRE(proc_obj != 0);
+       DBC_REQUIRE(dev_obj->proc_list != NULL);
+       DBC_REQUIRE(!LST_IS_EMPTY(dev_obj->proc_list));
+
+       /* Search list for dev_obj: */
+       for (cur_elem = lst_first(dev_obj->proc_list); cur_elem != NULL;
+            cur_elem = lst_next(dev_obj->proc_list, cur_elem)) {
+               /* If found, remove it. */
+               if ((u32) cur_elem == proc_obj) {
+                       lst_remove_elem(dev_obj->proc_list, cur_elem);
+                       status = 0;
+                       break;
+               }
+       }
+
+       return status;
+}
+
+int dev_get_dev_type(struct dev_object *device_obj, u8 *dev_type)
+{
+       int status = 0;
+       struct dev_object *dev_obj = (struct dev_object *)device_obj;
+
+       *dev_type = dev_obj->dev_type;
+
+       return status;
+}
+
+/*
+ *  ======== store_interface_fxns ========
+ *  Purpose:
+ *      Copy the Bridge's interface functions into the device object,
+ *      ensuring that fxn_not_implemented() is set for:
+ *
+ *      1. All Bridge function pointers which are NULL; and
+ *      2. All function slots in the struct dev_object structure which have no
+ *         corresponding slots in the the Bridge's interface, because the Bridge
+ *         is of an *older* version.
+ *  Parameters:
+ *      intf_fxns:      Interface fxn Structure of the Bridge's Dev Object.
+ *      drv_fxns:      Interface Fxns offered by the Bridge during DEV_Create().
+ *  Returns:
+ *  Requires:
+ *      Input pointers are valid.
+ *      Bridge driver is *not* written for a newer DSP API.
+ *  Ensures:
+ *      All function pointers in the dev object's fxn interface are not NULL.
+ */
+static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
+                                struct bridge_drv_interface *intf_fxns)
+{
+       u32 bridge_version;
+
+       /* Local helper macro: */
+#define  STORE_FXN(cast, pfn) \
+    (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \
+    (cast)fxn_not_implemented))
+
+       DBC_REQUIRE(intf_fxns != NULL);
+       DBC_REQUIRE(drv_fxns != NULL);
+       DBC_REQUIRE(MAKEVERSION(drv_fxns->brd_api_major_version,
+                       drv_fxns->brd_api_minor_version) <= BRD_API_VERSION);
+       bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version,
+                                    drv_fxns->brd_api_minor_version);
+       intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version;
+       intf_fxns->brd_api_minor_version = drv_fxns->brd_api_minor_version;
+       /* Install functions up to DSP API version .80 (first alpha): */
+       if (bridge_version > 0) {
+               STORE_FXN(fxn_dev_create, pfn_dev_create);
+               STORE_FXN(fxn_dev_destroy, pfn_dev_destroy);
+               STORE_FXN(fxn_dev_ctrl, pfn_dev_cntrl);
+               STORE_FXN(fxn_brd_monitor, pfn_brd_monitor);
+               STORE_FXN(fxn_brd_start, pfn_brd_start);
+               STORE_FXN(fxn_brd_stop, pfn_brd_stop);
+               STORE_FXN(fxn_brd_status, pfn_brd_status);
+               STORE_FXN(fxn_brd_read, pfn_brd_read);
+               STORE_FXN(fxn_brd_write, pfn_brd_write);
+               STORE_FXN(fxn_brd_setstate, pfn_brd_set_state);
+               STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy);
+               STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write);
+               STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map);
+               STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map);
+               STORE_FXN(fxn_chnl_create, pfn_chnl_create);
+               STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy);
+               STORE_FXN(fxn_chnl_open, pfn_chnl_open);
+               STORE_FXN(fxn_chnl_close, pfn_chnl_close);
+               STORE_FXN(fxn_chnl_addioreq, pfn_chnl_add_io_req);
+               STORE_FXN(fxn_chnl_getioc, pfn_chnl_get_ioc);
+               STORE_FXN(fxn_chnl_cancelio, pfn_chnl_cancel_io);
+               STORE_FXN(fxn_chnl_flushio, pfn_chnl_flush_io);
+               STORE_FXN(fxn_chnl_getinfo, pfn_chnl_get_info);
+               STORE_FXN(fxn_chnl_getmgrinfo, pfn_chnl_get_mgr_info);
+               STORE_FXN(fxn_chnl_idle, pfn_chnl_idle);
+               STORE_FXN(fxn_chnl_registernotify, pfn_chnl_register_notify);
+               STORE_FXN(fxn_io_create, pfn_io_create);
+               STORE_FXN(fxn_io_destroy, pfn_io_destroy);
+               STORE_FXN(fxn_io_onloaded, pfn_io_on_loaded);
+               STORE_FXN(fxn_io_getprocload, pfn_io_get_proc_load);
+               STORE_FXN(fxn_msg_create, pfn_msg_create);
+               STORE_FXN(fxn_msg_createqueue, pfn_msg_create_queue);
+               STORE_FXN(fxn_msg_delete, pfn_msg_delete);
+               STORE_FXN(fxn_msg_deletequeue, pfn_msg_delete_queue);
+               STORE_FXN(fxn_msg_get, pfn_msg_get);
+               STORE_FXN(fxn_msg_put, pfn_msg_put);
+               STORE_FXN(fxn_msg_registernotify, pfn_msg_register_notify);
+               STORE_FXN(fxn_msg_setqueueid, pfn_msg_set_queue_id);
+       }
+       /* Add code for any additional functions in newerBridge versions here */
+       /* Ensure postcondition: */
+       DBC_ENSURE(intf_fxns->pfn_dev_create != NULL);
+       DBC_ENSURE(intf_fxns->pfn_dev_destroy != NULL);
+       DBC_ENSURE(intf_fxns->pfn_dev_cntrl != NULL);
+       DBC_ENSURE(intf_fxns->pfn_brd_monitor != NULL);
+       DBC_ENSURE(intf_fxns->pfn_brd_start != NULL);
+       DBC_ENSURE(intf_fxns->pfn_brd_stop != NULL);
+       DBC_ENSURE(intf_fxns->pfn_brd_status != NULL);
+       DBC_ENSURE(intf_fxns->pfn_brd_read != NULL);
+       DBC_ENSURE(intf_fxns->pfn_brd_write != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_create != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_destroy != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_open != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_close != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_add_io_req != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_get_ioc != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_cancel_io != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_flush_io != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_get_info != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_get_mgr_info != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_idle != NULL);
+       DBC_ENSURE(intf_fxns->pfn_chnl_register_notify != NULL);
+       DBC_ENSURE(intf_fxns->pfn_io_create != NULL);
+       DBC_ENSURE(intf_fxns->pfn_io_destroy != NULL);
+       DBC_ENSURE(intf_fxns->pfn_io_on_loaded != NULL);
+       DBC_ENSURE(intf_fxns->pfn_io_get_proc_load != NULL);
+       DBC_ENSURE(intf_fxns->pfn_msg_set_queue_id != NULL);
+
+#undef  STORE_FXN
+}
diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c
new file mode 100644 (file)
index 0000000..8685233
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * dmm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
+ * space that can be directly mapped to any MPU buffer or memory region
+ *
+ * Notes:
+ *   Region: Generic memory entitiy having a start address and a size
+ *   Chunk:  Reserved region
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+#include <dspbridge/proc.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/dmm.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define DMM_ADDR_VIRTUAL(a) \
+       (((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\
+       dyn_mem_map_beg)
+#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K)
+
+/* DMM Mgr */
+struct dmm_object {
+       /* Dmm Lock is used to serialize access mem manager for
+        * multi-threads. */
+       spinlock_t dmm_lock;    /* Lock to access dmm mgr */
+};
+
+/*  ----------------------------------- Globals */
+static u32 refs;               /* module reference count */
+struct map_page {
+       u32 region_size:15;
+       u32 mapped_size:15;
+       u32 reserved:1;
+       u32 mapped:1;
+};
+
+/*  Create the free list */
+static struct map_page *virtual_mapping_table;
+static u32 free_region;                /* The index of free region */
+static u32 free_size;
+static u32 dyn_mem_map_beg;    /* The Beginning of dynamic memory mapping */
+static u32 table_size;         /* The size of virt and phys pages tables */
+
+/*  ----------------------------------- Function Prototypes */
+static struct map_page *get_region(u32 addr);
+static struct map_page *get_free_region(u32 len);
+static struct map_page *get_mapped_region(u32 addrs);
+
+/*  ======== dmm_create_tables ========
+ *  Purpose:
+ *      Create table to hold the information of physical address
+ *      the buffer pages that is passed by the user, and the table
+ *      to hold the information of the virtual memory that is reserved
+ *      for DSP.
+ */
+int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       int status = 0;
+
+       status = dmm_delete_tables(dmm_obj);
+       if (!status) {
+               dyn_mem_map_beg = addr;
+               table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K;
+               /*  Create the free list */
+               virtual_mapping_table = __vmalloc(table_size *
+                               sizeof(struct map_page), GFP_KERNEL |
+                               __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
+               if (virtual_mapping_table == NULL)
+                       status = -ENOMEM;
+               else {
+                       /* On successful allocation,
+                        * all entries are zero ('free') */
+                       free_region = 0;
+                       free_size = table_size * PG_SIZE4K;
+                       virtual_mapping_table[0].region_size = table_size;
+               }
+       }
+
+       if (status)
+               pr_err("%s: failure, status 0x%x\n", __func__, status);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_create ========
+ *  Purpose:
+ *      Create a dynamic memory manager object.
+ */
+int dmm_create(struct dmm_object **dmm_manager,
+                     struct dev_object *hdev_obj,
+                     const struct dmm_mgrattrs *mgr_attrts)
+{
+       struct dmm_object *dmm_obj = NULL;
+       int status = 0;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dmm_manager != NULL);
+
+       *dmm_manager = NULL;
+       /* create, zero, and tag a cmm mgr object */
+       dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL);
+       if (dmm_obj != NULL) {
+               spin_lock_init(&dmm_obj->dmm_lock);
+               *dmm_manager = dmm_obj;
+       } else {
+               status = -ENOMEM;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dmm_destroy ========
+ *  Purpose:
+ *      Release the communication memory manager resources.
+ */
+int dmm_destroy(struct dmm_object *dmm_mgr)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       if (dmm_mgr) {
+               status = dmm_delete_tables(dmm_obj);
+               if (!status)
+                       kfree(dmm_obj);
+       } else
+               status = -EFAULT;
+
+       return status;
+}
+
+/*
+ *  ======== dmm_delete_tables ========
+ *  Purpose:
+ *      Delete DMM Tables.
+ */
+int dmm_delete_tables(struct dmm_object *dmm_mgr)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       /* Delete all DMM tables */
+       if (dmm_mgr)
+               vfree(virtual_mapping_table);
+       else
+               status = -EFAULT;
+       return status;
+}
+
+/*
+ *  ======== dmm_exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ */
+void dmm_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+}
+
+/*
+ *  ======== dmm_get_handle ========
+ *  Purpose:
+ *      Return the dynamic memory manager object for this device.
+ *      This is typically called from the client process.
+ */
+int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager)
+{
+       int status = 0;
+       struct dev_object *hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dmm_manager != NULL);
+       if (hprocessor != NULL)
+               status = proc_get_dev_object(hprocessor, &hdev_obj);
+       else
+               hdev_obj = dev_get_first();     /* default */
+
+       if (!status)
+               status = dev_get_dmm_mgr(hdev_obj, dmm_manager);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_init ========
+ *  Purpose:
+ *      Initializes private state of DMM module.
+ */
+bool dmm_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       virtual_mapping_table = NULL;
+       table_size = 0;
+
+       return ret;
+}
+
+/*
+ *  ======== dmm_map_memory ========
+ *  Purpose:
+ *      Add a mapping block to the reserved chunk. DMM assumes that this block
+ *  will be mapped in the DSP/IVA's address space. DMM returns an error if a
+ *  mapping overlaps another one. This function stores the info that will be
+ *  required later while unmapping the block.
+ */
+int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *chunk;
+       int status = 0;
+
+       spin_lock(&dmm_obj->dmm_lock);
+       /* Find the Reserved memory chunk containing the DSP block to
+        * be mapped */
+       chunk = (struct map_page *)get_region(addr);
+       if (chunk != NULL) {
+               /* Mark the region 'mapped', leave the 'reserved' info as-is */
+               chunk->mapped = true;
+               chunk->mapped_size = (size / PG_SIZE4K);
+       } else
+               status = -ENOENT;
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, "
+               "chunk %p", __func__, dmm_mgr, addr, size, status, chunk);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_reserve_memory ========
+ *  Purpose:
+ *      Reserve a chunk of virtually contiguous DSP/IVA address space.
+ */
+int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size,
+                             u32 *prsv_addr)
+{
+       int status = 0;
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *node;
+       u32 rsv_addr = 0;
+       u32 rsv_size = 0;
+
+       spin_lock(&dmm_obj->dmm_lock);
+
+       /* Try to get a DSP chunk from the free list */
+       node = get_free_region(size);
+       if (node != NULL) {
+               /*  DSP chunk of given size is available. */
+               rsv_addr = DMM_ADDR_VIRTUAL(node);
+               /* Calculate the number entries to use */
+               rsv_size = size / PG_SIZE4K;
+               if (rsv_size < node->region_size) {
+                       /* Mark remainder of free region */
+                       node[rsv_size].mapped = false;
+                       node[rsv_size].reserved = false;
+                       node[rsv_size].region_size =
+                           node->region_size - rsv_size;
+                       node[rsv_size].mapped_size = 0;
+               }
+               /*  get_region will return first fit chunk. But we only use what
+                  is requested. */
+               node->mapped = false;
+               node->reserved = true;
+               node->region_size = rsv_size;
+               node->mapped_size = 0;
+               /* Return the chunk's starting address */
+               *prsv_addr = rsv_addr;
+       } else
+               /*dSP chunk of given size is not available */
+               status = -ENOMEM;
+
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, "
+               "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size,
+               prsv_addr, status, rsv_addr, rsv_size);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_un_map_memory ========
+ *  Purpose:
+ *      Remove the mapped block from the reserved chunk.
+ */
+int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *chunk;
+       int status = 0;
+
+       spin_lock(&dmm_obj->dmm_lock);
+       chunk = get_mapped_region(addr);
+       if (chunk == NULL)
+               status = -ENOENT;
+
+       if (!status) {
+               /* Unmap the region */
+               *psize = chunk->mapped_size * PG_SIZE4K;
+               chunk->mapped = false;
+               chunk->mapped_size = 0;
+       }
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, "
+               "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_un_reserve_memory ========
+ *  Purpose:
+ *      Free a chunk of reserved DSP/IVA address space.
+ */
+int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *chunk;
+       u32 i;
+       int status = 0;
+       u32 chunk_size;
+
+       spin_lock(&dmm_obj->dmm_lock);
+
+       /* Find the chunk containing the reserved address */
+       chunk = get_mapped_region(rsv_addr);
+       if (chunk == NULL)
+               status = -ENOENT;
+
+       if (!status) {
+               /* Free all the mapped pages for this reserved region */
+               i = 0;
+               while (i < chunk->region_size) {
+                       if (chunk[i].mapped) {
+                               /* Remove mapping from the page tables. */
+                               chunk_size = chunk[i].mapped_size;
+                               /* Clear the mapping flags */
+                               chunk[i].mapped = false;
+                               chunk[i].mapped_size = 0;
+                               i += chunk_size;
+                       } else
+                               i++;
+               }
+               /* Clear the flags (mark the region 'free') */
+               chunk->reserved = false;
+               /* NOTE: We do NOT coalesce free regions here.
+                * Free regions are coalesced in get_region(), as it traverses
+                *the whole mapping table
+                */
+       }
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p",
+               __func__, dmm_mgr, rsv_addr, status, chunk);
+
+       return status;
+}
+
+/*
+ *  ======== get_region ========
+ *  Purpose:
+ *      Returns a region containing the specified memory region
+ */
+static struct map_page *get_region(u32 addr)
+{
+       struct map_page *curr_region = NULL;
+       u32 i = 0;
+
+       if (virtual_mapping_table != NULL) {
+               /* find page mapped by this address */
+               i = DMM_ADDR_TO_INDEX(addr);
+               if (i < table_size)
+                       curr_region = virtual_mapping_table + i;
+       }
+
+       dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n",
+               __func__, curr_region, free_region, free_size);
+       return curr_region;
+}
+
+/*
+ *  ======== get_free_region ========
+ *  Purpose:
+ *  Returns the requested free region
+ */
+static struct map_page *get_free_region(u32 len)
+{
+       struct map_page *curr_region = NULL;
+       u32 i = 0;
+       u32 region_size = 0;
+       u32 next_i = 0;
+
+       if (virtual_mapping_table == NULL)
+               return curr_region;
+       if (len > free_size) {
+               /* Find the largest free region
+                * (coalesce during the traversal) */
+               while (i < table_size) {
+                       region_size = virtual_mapping_table[i].region_size;
+                       next_i = i + region_size;
+                       if (virtual_mapping_table[i].reserved == false) {
+                               /* Coalesce, if possible */
+                               if (next_i < table_size &&
+                                   virtual_mapping_table[next_i].reserved
+                                   == false) {
+                                       virtual_mapping_table[i].region_size +=
+                                           virtual_mapping_table
+                                           [next_i].region_size;
+                                       continue;
+                               }
+                               region_size *= PG_SIZE4K;
+                               if (region_size > free_size) {
+                                       free_region = i;
+                                       free_size = region_size;
+                               }
+                       }
+                       i = next_i;
+               }
+       }
+       if (len <= free_size) {
+               curr_region = virtual_mapping_table + free_region;
+               free_region += (len / PG_SIZE4K);
+               free_size -= len;
+       }
+       return curr_region;
+}
+
+/*
+ *  ======== get_mapped_region ========
+ *  Purpose:
+ *  Returns the requestedmapped region
+ */
+static struct map_page *get_mapped_region(u32 addrs)
+{
+       u32 i = 0;
+       struct map_page *curr_region = NULL;
+
+       if (virtual_mapping_table == NULL)
+               return curr_region;
+
+       i = DMM_ADDR_TO_INDEX(addrs);
+       if (i < table_size && (virtual_mapping_table[i].mapped ||
+                              virtual_mapping_table[i].reserved))
+               curr_region = virtual_mapping_table + i;
+       return curr_region;
+}
+
+#ifdef DSP_DMM_DEBUG
+u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr)
+{
+       struct map_page *curr_node = NULL;
+       u32 i;
+       u32 freemem = 0;
+       u32 bigsize = 0;
+
+       spin_lock(&dmm_mgr->dmm_lock);
+
+       if (virtual_mapping_table != NULL) {
+               for (i = 0; i < table_size; i +=
+                    virtual_mapping_table[i].region_size) {
+                       curr_node = virtual_mapping_table + i;
+                       if (curr_node->reserved) {
+                               /*printk("RESERVED size = 0x%x, "
+                                  "Map size = 0x%x\n",
+                                  (curr_node->region_size * PG_SIZE4K),
+                                  (curr_node->mapped == false) ? 0 :
+                                  (curr_node->mapped_size * PG_SIZE4K));
+                                */
+                       } else {
+/*                             printk("UNRESERVED size = 0x%x\n",
+                                       (curr_node->region_size * PG_SIZE4K));
+ */
+                               freemem += (curr_node->region_size * PG_SIZE4K);
+                               if (curr_node->region_size > bigsize)
+                                       bigsize = curr_node->region_size;
+                       }
+               }
+       }
+       spin_unlock(&dmm_mgr->dmm_lock);
+       printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n",
+              freemem / (1024 * 1024));
+       printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n",
+              (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024));
+       printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n",
+              (bigsize * PG_SIZE4K / (1024 * 1024)));
+
+       return 0;
+}
+#endif
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c
new file mode 100644 (file)
index 0000000..7b42f72
--- /dev/null
@@ -0,0 +1,1906 @@
+/*
+ * dspapi.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Common DSP API functions, also includes the wrapper
+ * functions called directly by the DeviceIOControl interface.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/ntfy.h>
+#include <dspbridge/services.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/chnl.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/drv.h>
+
+#include <dspbridge/proc.h>
+#include <dspbridge/strm.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/disp.h>
+#include <dspbridge/mgr.h>
+#include <dspbridge/node.h>
+#include <dspbridge/rmm.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/msg.h>
+#include <dspbridge/cmm.h>
+#include <dspbridge/io.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/dspapi.h>
+#include <dspbridge/dbdcd.h>
+
+#include <dspbridge/resourcecleanup.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define MAX_TRACEBUFLEN 255
+#define MAX_LOADARGS    16
+#define MAX_NODES       64
+#define MAX_STREAMS     16
+#define MAX_BUFS       64
+
+/* Used to get dspbridge ioctl table */
+#define DB_GET_IOC_TABLE(cmd)  (DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT)
+
+/* Device IOCtl function pointer */
+struct api_cmd {
+       u32(*fxn) (union trapped_args *args, void *pr_ctxt);
+       u32 dw_index;
+};
+
+/*  ----------------------------------- Globals */
+static u32 api_c_refs;
+
+/*
+ *  Function tables.
+ *  The order of these functions MUST be the same as the order of the command
+ *  numbers defined in dspapi-ioctl.h  This is how an IOCTL number in user mode
+ *  turns into a function call in kernel mode.
+ */
+
+/* MGR wrapper functions */
+static struct api_cmd mgr_cmd[] = {
+       {mgrwrap_enum_node_info},       /* MGR_ENUMNODE_INFO */
+       {mgrwrap_enum_proc_info},       /* MGR_ENUMPROC_INFO */
+       {mgrwrap_register_object},      /* MGR_REGISTEROBJECT */
+       {mgrwrap_unregister_object},    /* MGR_UNREGISTEROBJECT */
+       {mgrwrap_wait_for_bridge_events},       /* MGR_WAIT */
+       {mgrwrap_get_process_resources_info},   /* MGR_GET_PROC_RES */
+};
+
+/* PROC wrapper functions */
+static struct api_cmd proc_cmd[] = {
+       {procwrap_attach},      /* PROC_ATTACH */
+       {procwrap_ctrl},        /* PROC_CTRL */
+       {procwrap_detach},      /* PROC_DETACH */
+       {procwrap_enum_node_info},      /* PROC_ENUMNODE */
+       {procwrap_enum_resources},      /* PROC_ENUMRESOURCES */
+       {procwrap_get_state},   /* PROC_GET_STATE */
+       {procwrap_get_trace},   /* PROC_GET_TRACE */
+       {procwrap_load},        /* PROC_LOAD */
+       {procwrap_register_notify},     /* PROC_REGISTERNOTIFY */
+       {procwrap_start},       /* PROC_START */
+       {procwrap_reserve_memory},      /* PROC_RSVMEM */
+       {procwrap_un_reserve_memory},   /* PROC_UNRSVMEM */
+       {procwrap_map},         /* PROC_MAPMEM */
+       {procwrap_un_map},      /* PROC_UNMAPMEM */
+       {procwrap_flush_memory},        /* PROC_FLUSHMEMORY */
+       {procwrap_stop},        /* PROC_STOP */
+       {procwrap_invalidate_memory},   /* PROC_INVALIDATEMEMORY */
+       {procwrap_begin_dma},   /* PROC_BEGINDMA */
+       {procwrap_end_dma},     /* PROC_ENDDMA */
+};
+
+/* NODE wrapper functions */
+static struct api_cmd node_cmd[] = {
+       {nodewrap_allocate},    /* NODE_ALLOCATE */
+       {nodewrap_alloc_msg_buf},       /* NODE_ALLOCMSGBUF */
+       {nodewrap_change_priority},     /* NODE_CHANGEPRIORITY */
+       {nodewrap_connect},     /* NODE_CONNECT */
+       {nodewrap_create},      /* NODE_CREATE */
+       {nodewrap_delete},      /* NODE_DELETE */
+       {nodewrap_free_msg_buf},        /* NODE_FREEMSGBUF */
+       {nodewrap_get_attr},    /* NODE_GETATTR */
+       {nodewrap_get_message}, /* NODE_GETMESSAGE */
+       {nodewrap_pause},       /* NODE_PAUSE */
+       {nodewrap_put_message}, /* NODE_PUTMESSAGE */
+       {nodewrap_register_notify},     /* NODE_REGISTERNOTIFY */
+       {nodewrap_run},         /* NODE_RUN */
+       {nodewrap_terminate},   /* NODE_TERMINATE */
+       {nodewrap_get_uuid_props},      /* NODE_GETUUIDPROPS */
+};
+
+/* STRM wrapper functions */
+static struct api_cmd strm_cmd[] = {
+       {strmwrap_allocate_buffer},     /* STRM_ALLOCATEBUFFER */
+       {strmwrap_close},       /* STRM_CLOSE */
+       {strmwrap_free_buffer}, /* STRM_FREEBUFFER */
+       {strmwrap_get_event_handle},    /* STRM_GETEVENTHANDLE */
+       {strmwrap_get_info},    /* STRM_GETINFO */
+       {strmwrap_idle},        /* STRM_IDLE */
+       {strmwrap_issue},       /* STRM_ISSUE */
+       {strmwrap_open},        /* STRM_OPEN */
+       {strmwrap_reclaim},     /* STRM_RECLAIM */
+       {strmwrap_register_notify},     /* STRM_REGISTERNOTIFY */
+       {strmwrap_select},      /* STRM_SELECT */
+};
+
+/* CMM wrapper functions */
+static struct api_cmd cmm_cmd[] = {
+       {cmmwrap_calloc_buf},   /* CMM_ALLOCBUF */
+       {cmmwrap_free_buf},     /* CMM_FREEBUF */
+       {cmmwrap_get_handle},   /* CMM_GETHANDLE */
+       {cmmwrap_get_info},     /* CMM_GETINFO */
+};
+
+/* Array used to store ioctl table sizes. It can hold up to 8 entries */
+static u8 size_cmd[] = {
+       ARRAY_SIZE(mgr_cmd),
+       ARRAY_SIZE(proc_cmd),
+       ARRAY_SIZE(node_cmd),
+       ARRAY_SIZE(strm_cmd),
+       ARRAY_SIZE(cmm_cmd),
+};
+
+static inline void _cp_fm_usr(void *to, const void __user * from,
+                             int *err, unsigned long bytes)
+{
+       if (*err)
+               return;
+
+       if (unlikely(!from)) {
+               *err = -EFAULT;
+               return;
+       }
+
+       if (unlikely(copy_from_user(to, from, bytes)))
+               *err = -EFAULT;
+}
+
+#define CP_FM_USR(to, from, err, n)                            \
+       _cp_fm_usr(to, from, &(err), (n) * sizeof(*(to)))
+
+static inline void _cp_to_usr(void __user *to, const void *from,
+                             int *err, unsigned long bytes)
+{
+       if (*err)
+               return;
+
+       if (unlikely(!to)) {
+               *err = -EFAULT;
+               return;
+       }
+
+       if (unlikely(copy_to_user(to, from, bytes)))
+               *err = -EFAULT;
+}
+
+#define CP_TO_USR(to, from, err, n)                            \
+       _cp_to_usr(to, from, &(err), (n) * sizeof(*(from)))
+
+/*
+ *  ======== api_call_dev_ioctl ========
+ *  Purpose:
+ *      Call the (wrapper) function for the corresponding API IOCTL.
+ */
+inline int api_call_dev_ioctl(u32 cmd, union trapped_args *args,
+                                     u32 *result, void *pr_ctxt)
+{
+       u32(*ioctl_cmd) (union trapped_args *args, void *pr_ctxt) = NULL;
+       int i;
+
+       if (_IOC_TYPE(cmd) != DB) {
+               pr_err("%s: Incompatible dspbridge ioctl number\n", __func__);
+               goto err;
+       }
+
+       if (DB_GET_IOC_TABLE(cmd) > ARRAY_SIZE(size_cmd)) {
+               pr_err("%s: undefined ioctl module\n", __func__);
+               goto err;
+       }
+
+       /* Check the size of the required cmd table */
+       i = DB_GET_IOC(cmd);
+       if (i > size_cmd[DB_GET_IOC_TABLE(cmd)]) {
+               pr_err("%s: requested ioctl %d out of bounds for table %d\n",
+                      __func__, i, DB_GET_IOC_TABLE(cmd));
+               goto err;
+       }
+
+       switch (DB_GET_MODULE(cmd)) {
+       case DB_MGR:
+               ioctl_cmd = mgr_cmd[i].fxn;
+               break;
+       case DB_PROC:
+               ioctl_cmd = proc_cmd[i].fxn;
+               break;
+       case DB_NODE:
+               ioctl_cmd = node_cmd[i].fxn;
+               break;
+       case DB_STRM:
+               ioctl_cmd = strm_cmd[i].fxn;
+               break;
+       case DB_CMM:
+               ioctl_cmd = cmm_cmd[i].fxn;
+               break;
+       }
+
+       if (!ioctl_cmd) {
+               pr_err("%s: requested ioctl not defined\n", __func__);
+               goto err;
+       } else {
+               *result = (*ioctl_cmd) (args, pr_ctxt);
+       }
+
+       return 0;
+
+err:
+       return -EINVAL;
+}
+
+/*
+ *  ======== api_exit ========
+ */
+void api_exit(void)
+{
+       DBC_REQUIRE(api_c_refs > 0);
+       api_c_refs--;
+
+       if (api_c_refs == 0) {
+               /* Release all modules initialized in api_init(). */
+               cod_exit();
+               dev_exit();
+               chnl_exit();
+               msg_exit();
+               io_exit();
+               strm_exit();
+               disp_exit();
+               node_exit();
+               proc_exit();
+               mgr_exit();
+               rmm_exit();
+               drv_exit();
+       }
+       DBC_ENSURE(api_c_refs >= 0);
+}
+
+/*
+ *  ======== api_init ========
+ *  Purpose:
+ *      Module initialization used by Bridge API.
+ */
+bool api_init(void)
+{
+       bool ret = true;
+       bool fdrv, fdev, fcod, fchnl, fmsg, fio;
+       bool fmgr, fproc, fnode, fdisp, fstrm, frmm;
+
+       if (api_c_refs == 0) {
+               /* initialize driver and other modules */
+               fdrv = drv_init();
+               fmgr = mgr_init();
+               fproc = proc_init();
+               fnode = node_init();
+               fdisp = disp_init();
+               fstrm = strm_init();
+               frmm = rmm_init();
+               fchnl = chnl_init();
+               fmsg = msg_mod_init();
+               fio = io_init();
+               fdev = dev_init();
+               fcod = cod_init();
+               ret = fdrv && fdev && fchnl && fcod && fmsg && fio;
+               ret = ret && fmgr && fproc && frmm;
+               if (!ret) {
+                       if (fdrv)
+                               drv_exit();
+
+                       if (fmgr)
+                               mgr_exit();
+
+                       if (fstrm)
+                               strm_exit();
+
+                       if (fproc)
+                               proc_exit();
+
+                       if (fnode)
+                               node_exit();
+
+                       if (fdisp)
+                               disp_exit();
+
+                       if (fchnl)
+                               chnl_exit();
+
+                       if (fmsg)
+                               msg_exit();
+
+                       if (fio)
+                               io_exit();
+
+                       if (fdev)
+                               dev_exit();
+
+                       if (fcod)
+                               cod_exit();
+
+                       if (frmm)
+                               rmm_exit();
+
+               }
+       }
+       if (ret)
+               api_c_refs++;
+
+       return ret;
+}
+
+/*
+ *  ======== api_init_complete2 ========
+ *  Purpose:
+ *      Perform any required bridge initialization which cannot
+ *      be performed in api_init() or dev_start_device() due
+ *      to the fact that some services are not yet
+ *      completely initialized.
+ *  Parameters:
+ *  Returns:
+ *      0:     Allow this device to load
+ *      -EPERM:      Failure.
+ *  Requires:
+ *      Bridge API initialized.
+ *  Ensures:
+ */
+int api_init_complete2(void)
+{
+       int status = 0;
+       struct cfg_devnode *dev_node;
+       struct dev_object *hdev_obj;
+       u8 dev_type;
+       u32 tmp;
+
+       DBC_REQUIRE(api_c_refs > 0);
+
+       /*  Walk the list of DevObjects, get each devnode, and attempting to
+        *  autostart the board. Note that this requires COF loading, which
+        *  requires KFILE. */
+       for (hdev_obj = dev_get_first(); hdev_obj != NULL;
+            hdev_obj = dev_get_next(hdev_obj)) {
+               if (dev_get_dev_node(hdev_obj, &dev_node))
+                       continue;
+
+               if (dev_get_dev_type(hdev_obj, &dev_type))
+                       continue;
+
+               if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT))
+                       if (cfg_get_auto_start(dev_node, &tmp) == 0
+                                                                       && tmp)
+                               proc_auto_start(dev_node, hdev_obj);
+       }
+
+       return status;
+}
+
+/* TODO: Remove deprecated and not implemented ioctl wrappers */
+
+/*
+ * ======== mgrwrap_enum_node_info ========
+ */
+u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
+{
+       u8 *pndb_props;
+       u32 num_nodes;
+       int status = 0;
+       u32 size = args->args_mgr_enumnode_info.undb_props_size;
+
+       if (size < sizeof(struct dsp_ndbprops))
+               return -EINVAL;
+
+       pndb_props = kmalloc(size, GFP_KERNEL);
+       if (pndb_props == NULL)
+               status = -ENOMEM;
+
+       if (!status) {
+               status =
+                   mgr_enum_node_info(args->args_mgr_enumnode_info.node_id,
+                                      (struct dsp_ndbprops *)pndb_props, size,
+                                      &num_nodes);
+       }
+       CP_TO_USR(args->args_mgr_enumnode_info.pndb_props, pndb_props, status,
+                 size);
+       CP_TO_USR(args->args_mgr_enumnode_info.pu_num_nodes, &num_nodes, status,
+                 1);
+       kfree(pndb_props);
+
+       return status;
+}
+
+/*
+ * ======== mgrwrap_enum_proc_info ========
+ */
+u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt)
+{
+       u8 *processor_info;
+       u8 num_procs;
+       int status = 0;
+       u32 size = args->args_mgr_enumproc_info.processor_info_size;
+
+       if (size < sizeof(struct dsp_processorinfo))
+               return -EINVAL;
+
+       processor_info = kmalloc(size, GFP_KERNEL);
+       if (processor_info == NULL)
+               status = -ENOMEM;
+
+       if (!status) {
+               status =
+                   mgr_enum_processor_info(args->args_mgr_enumproc_info.
+                                           processor_id,
+                                           (struct dsp_processorinfo *)
+                                           processor_info, size, &num_procs);
+       }
+       CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info,
+                 status, size);
+       CP_TO_USR(args->args_mgr_enumproc_info.pu_num_procs, &num_procs,
+                 status, 1);
+       kfree(processor_info);
+
+       return status;
+}
+
+#define WRAP_MAP2CALLER(x) x
+/*
+ * ======== mgrwrap_register_object ========
+ */
+u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+       struct dsp_uuid uuid_obj;
+       u32 path_size = 0;
+       char *psz_path_name = NULL;
+       int status = 0;
+
+       CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
+       if (status)
+               goto func_end;
+       /* path_size is increased by 1 to accommodate NULL */
+       path_size = strlen_user((char *)
+                               args->args_mgr_registerobject.psz_path_name) +
+           1;
+       psz_path_name = kmalloc(path_size, GFP_KERNEL);
+       if (!psz_path_name)
+               goto func_end;
+       ret = strncpy_from_user(psz_path_name,
+                               (char *)args->args_mgr_registerobject.
+                               psz_path_name, path_size);
+       if (!ret) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE)
+               return -EINVAL;
+
+       status = dcd_register_object(&uuid_obj,
+                                    args->args_mgr_registerobject.obj_type,
+                                    (char *)psz_path_name);
+func_end:
+       kfree(psz_path_name);
+       return status;
+}
+
+/*
+ * ======== mgrwrap_unregister_object ========
+ */
+u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_uuid uuid_obj;
+
+       CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
+       if (status)
+               goto func_end;
+
+       status = dcd_unregister_object(&uuid_obj,
+                                      args->args_mgr_unregisterobject.
+                                      obj_type);
+func_end:
+       return status;
+
+}
+
+/*
+ * ======== mgrwrap_wait_for_bridge_events ========
+ */
+u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_notification *anotifications[MAX_EVENTS];
+       struct dsp_notification notifications[MAX_EVENTS];
+       u32 index, i;
+       u32 count = args->args_mgr_wait.count;
+
+       if (count > MAX_EVENTS)
+               status = -EINVAL;
+
+       /* get the array of pointers to user structures */
+       CP_FM_USR(anotifications, args->args_mgr_wait.anotifications,
+                 status, count);
+       /* get the events */
+       for (i = 0; i < count; i++) {
+               CP_FM_USR(&notifications[i], anotifications[i], status, 1);
+               if (status || !notifications[i].handle) {
+                       status = -EINVAL;
+                       break;
+               }
+               /* set the array of pointers to kernel structures */
+               anotifications[i] = &notifications[i];
+       }
+       if (!status) {
+               status = mgr_wait_for_bridge_events(anotifications, count,
+                                                        &index,
+                                                        args->args_mgr_wait.
+                                                        utimeout);
+       }
+       CP_TO_USR(args->args_mgr_wait.pu_index, &index, status, 1);
+       return status;
+}
+
+/*
+ * ======== MGRWRAP_GetProcessResourceInfo ========
+ */
+u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args * args,
+                                                   void *pr_ctxt)
+{
+       pr_err("%s: deprecated dspbridge ioctl\n", __func__);
+       return 0;
+}
+
+/*
+ * ======== procwrap_attach ========
+ */
+u32 procwrap_attach(union trapped_args *args, void *pr_ctxt)
+{
+       void *processor;
+       int status = 0;
+       struct dsp_processorattrin proc_attr_in, *attr_in = NULL;
+
+       /* Optional argument */
+       if (args->args_proc_attach.attr_in) {
+               CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status,
+                         1);
+               if (!status)
+                       attr_in = &proc_attr_in;
+               else
+                       goto func_end;
+
+       }
+       status = proc_attach(args->args_proc_attach.processor_id, attr_in,
+                            &processor, pr_ctxt);
+       CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1);
+func_end:
+       return status;
+}
+
+/*
+ * ======== procwrap_ctrl ========
+ */
+u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt)
+{
+       u32 cb_data_size, __user * psize = (u32 __user *)
+           args->args_proc_ctrl.pargs;
+       u8 *pargs = NULL;
+       int status = 0;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if (psize) {
+               if (get_user(cb_data_size, psize)) {
+                       status = -EPERM;
+                       goto func_end;
+               }
+               cb_data_size += sizeof(u32);
+               pargs = kmalloc(cb_data_size, GFP_KERNEL);
+               if (pargs == NULL) {
+                       status = -ENOMEM;
+                       goto func_end;
+               }
+
+               CP_FM_USR(pargs, args->args_proc_ctrl.pargs, status,
+                         cb_data_size);
+       }
+       if (!status) {
+               status = proc_ctrl(hprocessor,
+                                  args->args_proc_ctrl.dw_cmd,
+                                  (struct dsp_cbdata *)pargs);
+       }
+
+       /* CP_TO_USR(args->args_proc_ctrl.pargs, pargs, status, 1); */
+       kfree(pargs);
+func_end:
+       return status;
+}
+
+/*
+ * ======== procwrap_detach ========
+ */
+u32 __deprecated procwrap_detach(union trapped_args * args, void *pr_ctxt)
+{
+       /* proc_detach called at bridge_release only */
+       pr_err("%s: deprecated dspbridge ioctl\n", __func__);
+       return 0;
+}
+
+/*
+ * ======== procwrap_enum_node_info ========
+ */
+u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       void *node_tab[MAX_NODES];
+       u32 num_nodes;
+       u32 alloc_cnt;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if (!args->args_proc_enumnode_info.node_tab_size)
+               return -EINVAL;
+
+       status = proc_enum_nodes(hprocessor,
+                                node_tab,
+                                args->args_proc_enumnode_info.node_tab_size,
+                                &num_nodes, &alloc_cnt);
+       CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status,
+                 num_nodes);
+       CP_TO_USR(args->args_proc_enumnode_info.pu_num_nodes, &num_nodes,
+                 status, 1);
+       CP_TO_USR(args->args_proc_enumnode_info.pu_allocated, &alloc_cnt,
+                 status, 1);
+       return status;
+}
+
+u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+
+       if (args->args_proc_dma.dir >= DMA_NONE)
+               return -EINVAL;
+
+       status = proc_end_dma(pr_ctxt,
+                                  args->args_proc_dma.pmpu_addr,
+                                  args->args_proc_dma.ul_size,
+                                  args->args_proc_dma.dir);
+       return status;
+}
+
+u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+
+       if (args->args_proc_dma.dir >= DMA_NONE)
+               return -EINVAL;
+
+       status = proc_begin_dma(pr_ctxt,
+                                  args->args_proc_dma.pmpu_addr,
+                                  args->args_proc_dma.ul_size,
+                                  args->args_proc_dma.dir);
+       return status;
+}
+
+/*
+ * ======== procwrap_flush_memory ========
+ */
+u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+
+       if (args->args_proc_flushmemory.ul_flags >
+           PROC_WRITEBACK_INVALIDATE_MEM)
+               return -EINVAL;
+
+       status = proc_flush_memory(pr_ctxt,
+                                  args->args_proc_flushmemory.pmpu_addr,
+                                  args->args_proc_flushmemory.ul_size,
+                                  args->args_proc_flushmemory.ul_flags);
+       return status;
+}
+
+/*
+ * ======== procwrap_invalidate_memory ========
+ */
+u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+
+       status =
+           proc_invalidate_memory(pr_ctxt,
+                                  args->args_proc_invalidatememory.pmpu_addr,
+                                  args->args_proc_invalidatememory.ul_size);
+       return status;
+}
+
+/*
+ * ======== procwrap_enum_resources ========
+ */
+u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_resourceinfo resource_info;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if (args->args_proc_enumresources.resource_info_size <
+           sizeof(struct dsp_resourceinfo))
+               return -EINVAL;
+
+       status =
+           proc_get_resource_info(hprocessor,
+                                  args->args_proc_enumresources.resource_type,
+                                  &resource_info,
+                                  args->args_proc_enumresources.
+                                  resource_info_size);
+
+       CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info,
+                 status, 1);
+
+       return status;
+
+}
+
+/*
+ * ======== procwrap_get_state ========
+ */
+u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       struct dsp_processorstate proc_state;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if (args->args_proc_getstate.state_info_size <
+           sizeof(struct dsp_processorstate))
+               return -EINVAL;
+
+       status = proc_get_state(hprocessor, &proc_state,
+                          args->args_proc_getstate.state_info_size);
+       CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status,
+                 1);
+       return status;
+
+}
+
+/*
+ * ======== procwrap_get_trace ========
+ */
+u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       u8 *pbuf;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN)
+               return -EINVAL;
+
+       pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL);
+       if (pbuf != NULL) {
+               status = proc_get_trace(hprocessor, pbuf,
+                                       args->args_proc_gettrace.max_size);
+       } else {
+               status = -ENOMEM;
+       }
+       CP_TO_USR(args->args_proc_gettrace.pbuf, pbuf, status,
+                 args->args_proc_gettrace.max_size);
+       kfree(pbuf);
+
+       return status;
+}
+
+/*
+ * ======== procwrap_load ========
+ */
+u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
+{
+       s32 i, len;
+       int status = 0;
+       char *temp;
+       s32 count = args->args_proc_load.argc_index;
+       u8 **argv = NULL, **envp = NULL;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if (count <= 0 || count > MAX_LOADARGS) {
+               status = -EINVAL;
+               goto func_cont;
+       }
+
+       argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
+       if (!argv) {
+               status = -ENOMEM;
+               goto func_cont;
+       }
+
+       CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
+       if (status) {
+               kfree(argv);
+               argv = NULL;
+               goto func_cont;
+       }
+
+       for (i = 0; i < count; i++) {
+               if (argv[i]) {
+                       /* User space pointer to argument */
+                       temp = (char *)argv[i];
+                       /* len is increased by 1 to accommodate NULL */
+                       len = strlen_user((char *)temp) + 1;
+                       /* Kernel space pointer to argument */
+                       argv[i] = kmalloc(len, GFP_KERNEL);
+                       if (argv[i]) {
+                               CP_FM_USR(argv[i], temp, status, len);
+                               if (status) {
+                                       kfree(argv[i]);
+                                       argv[i] = NULL;
+                                       goto func_cont;
+                               }
+                       } else {
+                               status = -ENOMEM;
+                               goto func_cont;
+                       }
+               }
+       }
+       /* TODO: validate this */
+       if (args->args_proc_load.user_envp) {
+               /* number of elements in the envp array including NULL */
+               count = 0;
+               do {
+                       get_user(temp, args->args_proc_load.user_envp + count);
+                       count++;
+               } while (temp);
+               envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
+               if (!envp) {
+                       status = -ENOMEM;
+                       goto func_cont;
+               }
+
+               CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
+               if (status) {
+                       kfree(envp);
+                       envp = NULL;
+                       goto func_cont;
+               }
+               for (i = 0; envp[i]; i++) {
+                       /* User space pointer to argument */
+                       temp = (char *)envp[i];
+                       /* len is increased by 1 to accommodate NULL */
+                       len = strlen_user((char *)temp) + 1;
+                       /* Kernel space pointer to argument */
+                       envp[i] = kmalloc(len, GFP_KERNEL);
+                       if (envp[i]) {
+                               CP_FM_USR(envp[i], temp, status, len);
+                               if (status) {
+                                       kfree(envp[i]);
+                                       envp[i] = NULL;
+                                       goto func_cont;
+                               }
+                       } else {
+                               status = -ENOMEM;
+                               goto func_cont;
+                       }
+               }
+       }
+
+       if (!status) {
+               status = proc_load(hprocessor,
+                                  args->args_proc_load.argc_index,
+                                  (const char **)argv, (const char **)envp);
+       }
+func_cont:
+       if (envp) {
+               i = 0;
+               while (envp[i])
+                       kfree(envp[i++]);
+
+               kfree(envp);
+       }
+
+       if (argv) {
+               count = args->args_proc_load.argc_index;
+               for (i = 0; (i < count) && argv[i]; i++)
+                       kfree(argv[i]);
+
+               kfree(argv);
+       }
+
+       return status;
+}
+
+/*
+ * ======== procwrap_map ========
+ */
+u32 procwrap_map(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       void *map_addr;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if (!args->args_proc_mapmem.ul_size)
+               return -EINVAL;
+
+       status = proc_map(args->args_proc_mapmem.hprocessor,
+                         args->args_proc_mapmem.pmpu_addr,
+                         args->args_proc_mapmem.ul_size,
+                         args->args_proc_mapmem.req_addr, &map_addr,
+                         args->args_proc_mapmem.ul_map_attr, pr_ctxt);
+       if (!status) {
+               if (put_user(map_addr, args->args_proc_mapmem.pp_map_addr)) {
+                       status = -EINVAL;
+                       proc_un_map(hprocessor, map_addr, pr_ctxt);
+               }
+
+       }
+       return status;
+}
+
+/*
+ * ======== procwrap_register_notify ========
+ */
+u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       struct dsp_notification notification;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       /* Initialize the notification data structure */
+       notification.ps_name = NULL;
+       notification.handle = NULL;
+
+       status = proc_register_notify(hprocessor,
+                                args->args_proc_register_notify.event_mask,
+                                args->args_proc_register_notify.notify_type,
+                                &notification);
+       CP_TO_USR(args->args_proc_register_notify.hnotification, &notification,
+                 status, 1);
+       return status;
+}
+
+/*
+ * ======== procwrap_reserve_memory ========
+ */
+u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       void *prsv_addr;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if ((args->args_proc_rsvmem.ul_size <= 0) ||
+           (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0)
+               return -EINVAL;
+
+       status = proc_reserve_memory(hprocessor,
+                                    args->args_proc_rsvmem.ul_size, &prsv_addr,
+                                    pr_ctxt);
+       if (!status) {
+               if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) {
+                       status = -EINVAL;
+                       proc_un_reserve_memory(args->args_proc_rsvmem.
+                                              hprocessor, prsv_addr, pr_ctxt);
+               }
+       }
+       return status;
+}
+
+/*
+ * ======== procwrap_start ========
+ */
+u32 procwrap_start(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+
+       ret = proc_start(((struct process_context *)pr_ctxt)->hprocessor);
+       return ret;
+}
+
+/*
+ * ======== procwrap_un_map ========
+ */
+u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+
+       status = proc_un_map(((struct process_context *)pr_ctxt)->hprocessor,
+                            args->args_proc_unmapmem.map_addr, pr_ctxt);
+       return status;
+}
+
+/*
+ * ======== procwrap_un_reserve_memory ========
+ */
+u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       status = proc_un_reserve_memory(hprocessor,
+                                       args->args_proc_unrsvmem.prsv_addr,
+                                       pr_ctxt);
+       return status;
+}
+
+/*
+ * ======== procwrap_stop ========
+ */
+u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+
+       ret = proc_stop(((struct process_context *)pr_ctxt)->hprocessor);
+
+       return ret;
+}
+
+/*
+ * ======== find_handle =========
+ */
+inline void find_node_handle(struct node_res_object **noderes,
+                               void *pr_ctxt, void *hnode)
+{
+       rcu_read_lock();
+       *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
+                                                               (int)hnode - 1);
+       rcu_read_unlock();
+       return;
+}
+
+
+/*
+ * ======== nodewrap_allocate ========
+ */
+u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_uuid node_uuid;
+       u32 cb_data_size = 0;
+       u32 __user *psize = (u32 __user *) args->args_node_allocate.pargs;
+       u8 *pargs = NULL;
+       struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
+       struct node_res_object *node_res;
+       int nodeid;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       /* Optional argument */
+       if (psize) {
+               if (get_user(cb_data_size, psize))
+                       status = -EPERM;
+
+               cb_data_size += sizeof(u32);
+               if (!status) {
+                       pargs = kmalloc(cb_data_size, GFP_KERNEL);
+                       if (pargs == NULL)
+                               status = -ENOMEM;
+
+               }
+               CP_FM_USR(pargs, args->args_node_allocate.pargs, status,
+                         cb_data_size);
+       }
+       CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1);
+       if (status)
+               goto func_cont;
+       /* Optional argument */
+       if (args->args_node_allocate.attr_in) {
+               CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in,
+                         status, 1);
+               if (!status)
+                       attr_in = &proc_attr_in;
+               else
+                       status = -ENOMEM;
+
+       }
+       if (!status) {
+               status = node_allocate(hprocessor,
+                                      &node_uuid, (struct dsp_cbdata *)pargs,
+                                      attr_in, &node_res, pr_ctxt);
+       }
+       if (!status) {
+               nodeid = node_res->id + 1;
+               CP_TO_USR(args->args_node_allocate.ph_node, &nodeid,
+                       status, 1);
+               if (status) {
+                       status = -EFAULT;
+                       node_delete(node_res, pr_ctxt);
+               }
+       }
+func_cont:
+       kfree(pargs);
+
+       return status;
+}
+
+/*
+ *  ======== nodewrap_alloc_msg_buf ========
+ */
+u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_bufferattr *pattr = NULL;
+       struct dsp_bufferattr attr;
+       u8 *pbuffer = NULL;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res,  pr_ctxt,
+                               args->args_node_allocmsgbuf.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       if (!args->args_node_allocmsgbuf.usize)
+               return -EINVAL;
+
+       if (args->args_node_allocmsgbuf.pattr) {        /* Optional argument */
+               CP_FM_USR(&attr, args->args_node_allocmsgbuf.pattr, status, 1);
+               if (!status)
+                       pattr = &attr;
+
+       }
+       /* argument */
+       CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1);
+       if (!status) {
+               status = node_alloc_msg_buf(node_res->hnode,
+                                           args->args_node_allocmsgbuf.usize,
+                                           pattr, &pbuffer);
+       }
+       CP_TO_USR(args->args_node_allocmsgbuf.pbuffer, &pbuffer, status, 1);
+       return status;
+}
+
+/*
+ * ======== nodewrap_change_priority ========
+ */
+u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt,
+                               args->args_node_changepriority.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       ret = node_change_priority(node_res->hnode,
+                                  args->args_node_changepriority.prio);
+
+       return ret;
+}
+
+/*
+ * ======== nodewrap_connect ========
+ */
+u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_strmattr attrs;
+       struct dsp_strmattr *pattrs = NULL;
+       u32 cb_data_size;
+       u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
+       u8 *pargs = NULL;
+       struct node_res_object *node_res1, *node_res2;
+       struct node_object *node1 = NULL, *node2 = NULL;
+
+       if ((int)args->args_node_connect.hnode != DSP_HGPPNODE) {
+               find_node_handle(&node_res1, pr_ctxt,
+                               args->args_node_connect.hnode);
+               if (node_res1)
+                       node1 = node_res1->hnode;
+       } else {
+               node1 = args->args_node_connect.hnode;
+       }
+
+       if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
+               find_node_handle(&node_res2, pr_ctxt,
+                               args->args_node_connect.other_node);
+               if (node_res2)
+                       node2 = node_res2->hnode;
+       } else {
+               node2 = args->args_node_connect.other_node;
+       }
+
+       if (!node1 || !node2)
+               return -EFAULT;
+
+       /* Optional argument */
+       if (psize) {
+               if (get_user(cb_data_size, psize))
+                       status = -EPERM;
+
+               cb_data_size += sizeof(u32);
+               if (!status) {
+                       pargs = kmalloc(cb_data_size, GFP_KERNEL);
+                       if (pargs == NULL) {
+                               status = -ENOMEM;
+                               goto func_cont;
+                       }
+
+               }
+               CP_FM_USR(pargs, args->args_node_connect.conn_param, status,
+                         cb_data_size);
+               if (status)
+                       goto func_cont;
+       }
+       if (args->args_node_connect.pattrs) {   /* Optional argument */
+               CP_FM_USR(&attrs, args->args_node_connect.pattrs, status, 1);
+               if (!status)
+                       pattrs = &attrs;
+
+       }
+       if (!status) {
+               status = node_connect(node1,
+                                     args->args_node_connect.stream_id,
+                                     node2,
+                                     args->args_node_connect.other_stream,
+                                     pattrs, (struct dsp_cbdata *)pargs);
+       }
+func_cont:
+       kfree(pargs);
+
+       return status;
+}
+
+/*
+ * ======== nodewrap_create ========
+ */
+u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_create.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       ret = node_create(node_res->hnode);
+
+       return ret;
+}
+
+/*
+ * ======== nodewrap_delete ========
+ */
+u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_delete.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       ret = node_delete(node_res, pr_ctxt);
+
+       return ret;
+}
+
+/*
+ *  ======== nodewrap_free_msg_buf ========
+ */
+u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_bufferattr *pattr = NULL;
+       struct dsp_bufferattr attr;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       if (args->args_node_freemsgbuf.pattr) { /* Optional argument */
+               CP_FM_USR(&attr, args->args_node_freemsgbuf.pattr, status, 1);
+               if (!status)
+                       pattr = &attr;
+
+       }
+
+       if (!args->args_node_freemsgbuf.pbuffer)
+               return -EFAULT;
+
+       if (!status) {
+               status = node_free_msg_buf(node_res->hnode,
+                                          args->args_node_freemsgbuf.pbuffer,
+                                          pattr);
+       }
+
+       return status;
+}
+
+/*
+ * ======== nodewrap_get_attr ========
+ */
+u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_nodeattr attr;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       status = node_get_attr(node_res->hnode, &attr,
+                              args->args_node_getattr.attr_size);
+       CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1);
+
+       return status;
+}
+
+/*
+ * ======== nodewrap_get_message ========
+ */
+u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       struct dsp_msg msg;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       status = node_get_message(node_res->hnode, &msg,
+                                 args->args_node_getmessage.utimeout);
+
+       CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1);
+
+       return status;
+}
+
+/*
+ * ======== nodewrap_pause ========
+ */
+u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_pause.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       ret = node_pause(node_res->hnode);
+
+       return ret;
+}
+
+/*
+ * ======== nodewrap_put_message ========
+ */
+u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_msg msg;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);
+
+       if (!status) {
+               status =
+                   node_put_message(node_res->hnode, &msg,
+                                    args->args_node_putmessage.utimeout);
+       }
+
+       return status;
+}
+
+/*
+ * ======== nodewrap_register_notify ========
+ */
+u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_notification notification;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt,
+                       args->args_node_registernotify.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       /* Initialize the notification data structure */
+       notification.ps_name = NULL;
+       notification.handle = NULL;
+
+       if (!args->args_proc_register_notify.event_mask)
+               CP_FM_USR(&notification,
+                         args->args_proc_register_notify.hnotification,
+                         status, 1);
+
+       status = node_register_notify(node_res->hnode,
+                                     args->args_node_registernotify.event_mask,
+                                     args->args_node_registernotify.
+                                     notify_type, &notification);
+       CP_TO_USR(args->args_node_registernotify.hnotification, &notification,
+                 status, 1);
+       return status;
+}
+
+/*
+ * ======== nodewrap_run ========
+ */
+u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_run.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       ret = node_run(node_res->hnode);
+
+       return ret;
+}
+
+/*
+ * ======== nodewrap_terminate ========
+ */
+u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       int tempstatus;
+       struct node_res_object *node_res;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       status = node_terminate(node_res->hnode, &tempstatus);
+
+       CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1);
+
+       return status;
+}
+
+/*
+ * ======== nodewrap_get_uuid_props ========
+ */
+u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_uuid node_uuid;
+       struct dsp_ndbprops *pnode_props = NULL;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status,
+                 1);
+       if (status)
+               goto func_cont;
+       pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL);
+       if (pnode_props != NULL) {
+               status =
+                   node_get_uuid_props(hprocessor, &node_uuid, pnode_props);
+               CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props,
+                         status, 1);
+       } else
+               status = -ENOMEM;
+func_cont:
+       kfree(pnode_props);
+       return status;
+}
+
+/*
+ * ======== find_strm_handle =========
+ */
+inline void find_strm_handle(struct strm_res_object **strmres,
+                               void *pr_ctxt, void *hstream)
+{
+       rcu_read_lock();
+       *strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id,
+                                                       (int)hstream - 1);
+       rcu_read_unlock();
+       return;
+}
+
+/*
+ * ======== strmwrap_allocate_buffer ========
+ */
+u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt)
+{
+       int status;
+       u8 **ap_buffer = NULL;
+       u32 num_bufs = args->args_strm_allocatebuffer.num_bufs;
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt,
+               args->args_strm_allocatebuffer.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       if (num_bufs > MAX_BUFS)
+               return -EINVAL;
+
+       ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
+       if (ap_buffer == NULL)
+               return -ENOMEM;
+
+       status = strm_allocate_buffer(strm_res,
+                                     args->args_strm_allocatebuffer.usize,
+                                     ap_buffer, num_bufs, pr_ctxt);
+       if (!status) {
+               CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer,
+                         status, num_bufs);
+               if (status) {
+                       status = -EFAULT;
+                       strm_free_buffer(strm_res,
+                                        ap_buffer, num_bufs, pr_ctxt);
+               }
+       }
+       kfree(ap_buffer);
+
+       return status;
+}
+
+/*
+ * ======== strmwrap_close ========
+ */
+u32 strmwrap_close(union trapped_args *args, void *pr_ctxt)
+{
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       return strm_close(strm_res, pr_ctxt);
+}
+
+/*
+ * ======== strmwrap_free_buffer ========
+ */
+u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       u8 **ap_buffer = NULL;
+       u32 num_bufs = args->args_strm_freebuffer.num_bufs;
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt,
+                       args->args_strm_freebuffer.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       if (num_bufs > MAX_BUFS)
+               return -EINVAL;
+
+       ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
+       if (ap_buffer == NULL)
+               return -ENOMEM;
+
+       CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status,
+                 num_bufs);
+
+       if (!status)
+               status = strm_free_buffer(strm_res,
+                                         ap_buffer, num_bufs, pr_ctxt);
+
+       CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status,
+                 num_bufs);
+       kfree(ap_buffer);
+
+       return status;
+}
+
+/*
+ * ======== strmwrap_get_event_handle ========
+ */
+u32 __deprecated strmwrap_get_event_handle(union trapped_args * args,
+                                          void *pr_ctxt)
+{
+       pr_err("%s: deprecated dspbridge ioctl\n", __func__);
+       return -ENOSYS;
+}
+
+/*
+ * ======== strmwrap_get_info ========
+ */
+u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct stream_info strm_info;
+       struct dsp_streaminfo user;
+       struct dsp_streaminfo *temp;
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt,
+                       args->args_strm_getinfo.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1);
+       temp = strm_info.user_strm;
+
+       strm_info.user_strm = &user;
+
+       if (!status) {
+               status = strm_get_info(strm_res->hstream,
+                                      &strm_info,
+                                      args->args_strm_getinfo.
+                                      stream_info_size);
+       }
+       CP_TO_USR(temp, strm_info.user_strm, status, 1);
+       strm_info.user_strm = temp;
+       CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1);
+       return status;
+}
+
+/*
+ * ======== strmwrap_idle ========
+ */
+u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt)
+{
+       u32 ret;
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       ret = strm_idle(strm_res->hstream, args->args_strm_idle.flush_flag);
+
+       return ret;
+}
+
+/*
+ * ======== strmwrap_issue ========
+ */
+u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       if (!args->args_strm_issue.pbuffer)
+               return -EFAULT;
+
+       /* No need of doing CP_FM_USR for the user buffer (pbuffer)
+          as this is done in Bridge internal function bridge_chnl_add_io_req
+          in chnl_sm.c */
+       status = strm_issue(strm_res->hstream,
+                           args->args_strm_issue.pbuffer,
+                           args->args_strm_issue.dw_bytes,
+                           args->args_strm_issue.dw_buf_size,
+                           args->args_strm_issue.dw_arg);
+
+       return status;
+}
+
+/*
+ * ======== strmwrap_open ========
+ */
+u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct strm_attr attr;
+       struct strm_res_object *strm_res_obj;
+       struct dsp_streamattrin strm_attr_in;
+       struct node_res_object *node_res;
+       int strmid;
+
+       find_node_handle(&node_res, pr_ctxt, args->args_strm_open.hnode);
+
+       if (!node_res)
+               return -EFAULT;
+
+       CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);
+
+       if (attr.stream_attr_in != NULL) {      /* Optional argument */
+               CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1);
+               if (!status) {
+                       attr.stream_attr_in = &strm_attr_in;
+                       if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA)
+                               return -ENOSYS;
+               }
+
+       }
+       status = strm_open(node_res->hnode,
+                          args->args_strm_open.direction,
+                          args->args_strm_open.index, &attr, &strm_res_obj,
+                          pr_ctxt);
+       if (!status) {
+               strmid = strm_res_obj->id + 1;
+               CP_TO_USR(args->args_strm_open.ph_stream, &strmid, status, 1);
+       }
+       return status;
+}
+
+/*
+ * ======== strmwrap_reclaim ========
+ */
+u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       u8 *buf_ptr;
+       u32 ul_bytes;
+       u32 dw_arg;
+       u32 ul_buf_size;
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       status = strm_reclaim(strm_res->hstream, &buf_ptr,
+                             &ul_bytes, &ul_buf_size, &dw_arg);
+       CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1);
+       CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1);
+       CP_TO_USR(args->args_strm_reclaim.pdw_arg, &dw_arg, status, 1);
+
+       if (args->args_strm_reclaim.buf_size_ptr != NULL) {
+               CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size,
+                         status, 1);
+       }
+
+       return status;
+}
+
+/*
+ * ======== strmwrap_register_notify ========
+ */
+u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct dsp_notification notification;
+       struct strm_res_object *strm_res;
+
+       find_strm_handle(&strm_res, pr_ctxt,
+                       args->args_strm_registernotify.hstream);
+
+       if (!strm_res)
+               return -EFAULT;
+
+       /* Initialize the notification data structure */
+       notification.ps_name = NULL;
+       notification.handle = NULL;
+
+       status = strm_register_notify(strm_res->hstream,
+                                     args->args_strm_registernotify.event_mask,
+                                     args->args_strm_registernotify.
+                                     notify_type, &notification);
+       CP_TO_USR(args->args_strm_registernotify.hnotification, &notification,
+                 status, 1);
+
+       return status;
+}
+
+/*
+ * ======== strmwrap_select ========
+ */
+u32 strmwrap_select(union trapped_args *args, void *pr_ctxt)
+{
+       u32 mask;
+       struct strm_object *strm_tab[MAX_STREAMS];
+       int status = 0;
+       struct strm_res_object *strm_res;
+       int *ids[MAX_STREAMS];
+       int i;
+
+       if (args->args_strm_select.strm_num > MAX_STREAMS)
+               return -EINVAL;
+
+       CP_FM_USR(ids, args->args_strm_select.stream_tab, status,
+               args->args_strm_select.strm_num);
+
+       if (status)
+               return status;
+
+       for (i = 0; i < args->args_strm_select.strm_num; i++) {
+               find_strm_handle(&strm_res, pr_ctxt, ids[i]);
+
+               if (!strm_res)
+                       return -EFAULT;
+
+               strm_tab[i] = strm_res->hstream;
+       }
+
+       if (!status) {
+               status = strm_select(strm_tab, args->args_strm_select.strm_num,
+                                    &mask, args->args_strm_select.utimeout);
+       }
+       CP_TO_USR(args->args_strm_select.pmask, &mask, status, 1);
+       return status;
+}
+
+/* CMM */
+
+/*
+ * ======== cmmwrap_calloc_buf ========
+ */
+u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt)
+{
+       /* This operation is done in kernel */
+       pr_err("%s: deprecated dspbridge ioctl\n", __func__);
+       return -ENOSYS;
+}
+
+/*
+ * ======== cmmwrap_free_buf ========
+ */
+u32 __deprecated cmmwrap_free_buf(union trapped_args * args, void *pr_ctxt)
+{
+       /* This operation is done in kernel */
+       pr_err("%s: deprecated dspbridge ioctl\n", __func__);
+       return -ENOSYS;
+}
+
+/*
+ * ======== cmmwrap_get_handle ========
+ */
+u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct cmm_object *hcmm_mgr;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       status = cmm_get_handle(hprocessor, &hcmm_mgr);
+
+       CP_TO_USR(args->args_cmm_gethandle.ph_cmm_mgr, &hcmm_mgr, status, 1);
+
+       return status;
+}
+
+/*
+ * ======== cmmwrap_get_info ========
+ */
+u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt)
+{
+       int status = 0;
+       struct cmm_info cmm_info_obj;
+
+       status = cmm_get_info(args->args_cmm_getinfo.hcmm_mgr, &cmm_info_obj);
+
+       CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status,
+                 1);
+
+       return status;
+}
diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c
new file mode 100644 (file)
index 0000000..7970fe5
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * io.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * IO manager interface: Manages IO between CHNL and msg_ctrl.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- This */
+#include <ioobj.h>
+#include <dspbridge/iodefs.h>
+#include <dspbridge/io.h>
+
+/*  ----------------------------------- Globals */
+static u32 refs;
+
+/*
+ *  ======== io_create ========
+ *  Purpose:
+ *      Create an IO manager object, responsible for managing IO between
+ *      CHNL and msg_ctrl
+ */
+int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj,
+                    const struct io_attrs *mgr_attrts)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct io_mgr *hio_mgr = NULL;
+       struct io_mgr_ *pio_mgr = NULL;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(io_man != NULL);
+       DBC_REQUIRE(mgr_attrts != NULL);
+
+       *io_man = NULL;
+
+       /* A memory base of 0 implies no memory base: */
+       if ((mgr_attrts->shm_base != 0) && (mgr_attrts->usm_length == 0))
+               status = -EINVAL;
+
+       if (mgr_attrts->word_size == 0)
+               status = -EINVAL;
+
+       if (!status) {
+               dev_get_intf_fxns(hdev_obj, &intf_fxns);
+
+               /* Let Bridge channel module finish the create: */
+               status = (*intf_fxns->pfn_io_create) (&hio_mgr, hdev_obj,
+                                                     mgr_attrts);
+
+               if (!status) {
+                       pio_mgr = (struct io_mgr_ *)hio_mgr;
+                       pio_mgr->intf_fxns = intf_fxns;
+                       pio_mgr->hdev_obj = hdev_obj;
+
+                       /* Return the new channel manager handle: */
+                       *io_man = hio_mgr;
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== io_destroy ========
+ *  Purpose:
+ *      Delete IO manager.
+ */
+int io_destroy(struct io_mgr *hio_mgr)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct io_mgr_ *pio_mgr = (struct io_mgr_ *)hio_mgr;
+       int status;
+
+       DBC_REQUIRE(refs > 0);
+
+       intf_fxns = pio_mgr->intf_fxns;
+
+       /* Let Bridge channel module destroy the io_mgr: */
+       status = (*intf_fxns->pfn_io_destroy) (hio_mgr);
+
+       return status;
+}
+
+/*
+ *  ======== io_exit ========
+ *  Purpose:
+ *      Discontinue usage of the IO module.
+ */
+void io_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== io_init ========
+ *  Purpose:
+ *      Initialize the IO module's private state.
+ */
+bool io_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
diff --git a/drivers/staging/tidspbridge/pmgr/ioobj.h b/drivers/staging/tidspbridge/pmgr/ioobj.h
new file mode 100644 (file)
index 0000000..f46355f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * ioobj.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Structure subcomponents of channel class library IO objects which
+ * are exposed to DSP API from Bridge driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef IOOBJ_
+#define IOOBJ_
+
+#include <dspbridge/devdefs.h>
+#include <dspbridge/dspdefs.h>
+
+/*
+ *  This struct is the first field in a io_mgr struct. Other, implementation
+ *  specific fields follow this structure in memory.
+ */
+struct io_mgr_ {
+       /* These must be the first fields in a io_mgr struct: */
+       struct bridge_dev_context *hbridge_context;     /* Bridge context. */
+       /* Function interface to Bridge driver. */
+       struct bridge_drv_interface *intf_fxns;
+       struct dev_object *hdev_obj;    /* Device this board represents. */
+};
+
+#endif /* IOOBJ_ */
diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c
new file mode 100644 (file)
index 0000000..abd4365
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * msg.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge msg_ctrl Module.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- Bridge Driver */
+#include <dspbridge/dspdefs.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- This */
+#include <msgobj.h>
+#include <dspbridge/msg.h>
+
+/*  ----------------------------------- Globals */
+static u32 refs;               /* module reference count */
+
+/*
+ *  ======== msg_create ========
+ *  Purpose:
+ *      Create an object to manage message queues. Only one of these objects
+ *      can exist per device object.
+ */
+int msg_create(struct msg_mgr **msg_man,
+                     struct dev_object *hdev_obj, msg_onexit msg_callback)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct msg_mgr_ *msg_mgr_obj;
+       struct msg_mgr *hmsg_mgr;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(msg_man != NULL);
+       DBC_REQUIRE(msg_callback != NULL);
+       DBC_REQUIRE(hdev_obj != NULL);
+
+       *msg_man = NULL;
+
+       dev_get_intf_fxns(hdev_obj, &intf_fxns);
+
+       /* Let Bridge message module finish the create: */
+       status =
+           (*intf_fxns->pfn_msg_create) (&hmsg_mgr, hdev_obj, msg_callback);
+
+       if (!status) {
+               /* Fill in DSP API message module's fields of the msg_mgr
+                * structure */
+               msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr;
+               msg_mgr_obj->intf_fxns = intf_fxns;
+
+               /* Finally, return the new message manager handle: */
+               *msg_man = hmsg_mgr;
+       } else {
+               status = -EPERM;
+       }
+       return status;
+}
+
+/*
+ *  ======== msg_delete ========
+ *  Purpose:
+ *      Delete a msg_ctrl manager allocated in msg_create().
+ */
+void msg_delete(struct msg_mgr *hmsg_mgr)
+{
+       struct msg_mgr_ *msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr;
+       struct bridge_drv_interface *intf_fxns;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (msg_mgr_obj) {
+               intf_fxns = msg_mgr_obj->intf_fxns;
+
+               /* Let Bridge message module destroy the msg_mgr: */
+               (*intf_fxns->pfn_msg_delete) (hmsg_mgr);
+       } else {
+               dev_dbg(bridge, "%s: Error hmsg_mgr handle: %p\n",
+                       __func__, hmsg_mgr);
+       }
+}
+
+/*
+ *  ======== msg_exit ========
+ */
+void msg_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== msg_mod_init ========
+ */
+bool msg_mod_init(void)
+{
+       DBC_REQUIRE(refs >= 0);
+
+       refs++;
+
+       DBC_ENSURE(refs >= 0);
+
+       return true;
+}
diff --git a/drivers/staging/tidspbridge/pmgr/msgobj.h b/drivers/staging/tidspbridge/pmgr/msgobj.h
new file mode 100644 (file)
index 0000000..14ca633
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * msgobj.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Structure subcomponents of channel class library msg_ctrl objects which
+ * are exposed to DSP API from Bridge driver.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef MSGOBJ_
+#define MSGOBJ_
+
+#include <dspbridge/dspdefs.h>
+
+#include <dspbridge/msgdefs.h>
+
+/*
+ *  This struct is the first field in a msg_mgr struct. Other, implementation
+ *  specific fields follow this structure in memory.
+ */
+struct msg_mgr_ {
+       /* The first field must match that in _msg_sm.h */
+
+       /* Function interface to Bridge driver. */
+       struct bridge_drv_interface *intf_fxns;
+};
+
+#endif /* MSGOBJ_ */
diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c
new file mode 100644 (file)
index 0000000..f71e860
--- /dev/null
@@ -0,0 +1,1512 @@
+/*
+ * dbdcd.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * This file contains the implementation of the DSP/BIOS Bridge
+ * Configuration Database (DCD).
+ *
+ * Notes:
+ *   The fxn dcd_get_objects can apply a callback fxn to each DCD object
+ *   that is located in a specified COFF file.  At the moment,
+ *   dcd_auto_register, dcd_auto_unregister, and NLDR module all use
+ *   dcd_get_objects.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/cod.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/uuidutil.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/dbdcd.h>
+
+/*  ----------------------------------- Global defines. */
+#define MAX_INT2CHAR_LENGTH     16     /* Max int2char len of 32 bit int */
+
+/* Name of section containing dependent libraries */
+#define DEPLIBSECT             ".dspbridge_deplibs"
+
+/* DCD specific structures. */
+struct dcd_manager {
+       struct cod_manager *cod_mgr;    /* Handle to COD manager object. */
+};
+
+/*  Pointer to the registry support key */
+static struct list_head reg_key_list;
+static DEFINE_SPINLOCK(dbdcd_lock);
+
+/* Global reference variables. */
+static u32 refs;
+static u32 enum_refs;
+
+/* Helper function prototypes. */
+static s32 atoi(char *psz_buf);
+static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
+                                    enum dsp_dcdobjtype obj_type,
+                                    struct dcd_genericobj *gen_obj);
+static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size);
+static char dsp_char2_gpp_char(char *word, s32 dsp_char_size);
+static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
+                                  struct dsp_uuid *uuid_obj,
+                                  u16 *num_libs,
+                                  u16 *num_pers_libs,
+                                  struct dsp_uuid *dep_lib_uuids,
+                                  bool *prstnt_dep_libs,
+                                  enum nldr_phase phase);
+
+/*
+ *  ======== dcd_auto_register ========
+ *  Purpose:
+ *      Parses the supplied image and resigsters with DCD.
+ */
+int dcd_auto_register(struct dcd_manager *hdcd_mgr,
+                            char *sz_coff_path)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (hdcd_mgr)
+               status = dcd_get_objects(hdcd_mgr, sz_coff_path,
+                                        (dcd_registerfxn) dcd_register_object,
+                                        (void *)sz_coff_path);
+       else
+               status = -EFAULT;
+
+       return status;
+}
+
+/*
+ *  ======== dcd_auto_unregister ========
+ *  Purpose:
+ *      Parses the supplied DSP image and unresiters from DCD.
+ */
+int dcd_auto_unregister(struct dcd_manager *hdcd_mgr,
+                              char *sz_coff_path)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (hdcd_mgr)
+               status = dcd_get_objects(hdcd_mgr, sz_coff_path,
+                                        (dcd_registerfxn) dcd_register_object,
+                                        NULL);
+       else
+               status = -EFAULT;
+
+       return status;
+}
+
+/*
+ *  ======== dcd_create_manager ========
+ *  Purpose:
+ *      Creates DCD manager.
+ */
+int dcd_create_manager(char *sz_zl_dll_name,
+                             struct dcd_manager **dcd_mgr)
+{
+       struct cod_manager *cod_mgr;    /* COD manager handle */
+       struct dcd_manager *dcd_mgr_obj = NULL; /* DCD Manager pointer */
+       int status = 0;
+
+       DBC_REQUIRE(refs >= 0);
+       DBC_REQUIRE(dcd_mgr);
+
+       status = cod_create(&cod_mgr, sz_zl_dll_name, NULL);
+       if (status)
+               goto func_end;
+
+       /* Create a DCD object. */
+       dcd_mgr_obj = kzalloc(sizeof(struct dcd_manager), GFP_KERNEL);
+       if (dcd_mgr_obj != NULL) {
+               /* Fill out the object. */
+               dcd_mgr_obj->cod_mgr = cod_mgr;
+
+               /* Return handle to this DCD interface. */
+               *dcd_mgr = dcd_mgr_obj;
+       } else {
+               status = -ENOMEM;
+
+               /*
+                * If allocation of DcdManager object failed, delete the
+                * COD manager.
+                */
+               cod_delete(cod_mgr);
+       }
+
+       DBC_ENSURE((!status) ||
+                       ((dcd_mgr_obj == NULL) && (status == -ENOMEM)));
+
+func_end:
+       return status;
+}
+
+/*
+ *  ======== dcd_destroy_manager ========
+ *  Purpose:
+ *      Frees DCD Manager object.
+ */
+int dcd_destroy_manager(struct dcd_manager *hdcd_mgr)
+{
+       struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
+       int status = -EFAULT;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (hdcd_mgr) {
+               /* Delete the COD manager. */
+               cod_delete(dcd_mgr_obj->cod_mgr);
+
+               /* Deallocate a DCD manager object. */
+               kfree(dcd_mgr_obj);
+
+               status = 0;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dcd_enumerate_object ========
+ *  Purpose:
+ *      Enumerates objects in the DCD.
+ */
+int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
+                               struct dsp_uuid *uuid_obj)
+{
+       int status = 0;
+       char sz_reg_key[DCD_MAXPATHLENGTH];
+       char sz_value[DCD_MAXPATHLENGTH];
+       struct dsp_uuid dsp_uuid_obj;
+       char sz_obj_type[MAX_INT2CHAR_LENGTH];  /* str. rep. of obj_type. */
+       u32 dw_key_len = 0;
+       struct dcd_key_elem *dcd_key;
+       int len;
+
+       DBC_REQUIRE(refs >= 0);
+       DBC_REQUIRE(index >= 0);
+       DBC_REQUIRE(uuid_obj != NULL);
+
+       if ((index != 0) && (enum_refs == 0)) {
+               /*
+                * If an enumeration is being performed on an index greater
+                * than zero, then the current enum_refs must have been
+                * incremented to greater than zero.
+                */
+               status = -EIDRM;
+       } else {
+               /*
+                * Pre-determine final key length. It's length of DCD_REGKEY +
+                *  "_\0" + length of sz_obj_type string + terminating NULL.
+                */
+               dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
+               DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
+
+               /* Create proper REG key; concatenate DCD_REGKEY with
+                * obj_type. */
+               strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
+               if ((strlen(sz_reg_key) + strlen("_\0")) <
+                   DCD_MAXPATHLENGTH) {
+                       strncat(sz_reg_key, "_\0", 2);
+               } else {
+                       status = -EPERM;
+               }
+
+               /* This snprintf is guaranteed not to exceed max size of an
+                * integer. */
+               status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d",
+                                 obj_type);
+
+               if (status == -1) {
+                       status = -EPERM;
+               } else {
+                       status = 0;
+                       if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
+                           DCD_MAXPATHLENGTH) {
+                               strncat(sz_reg_key, sz_obj_type,
+                                       strlen(sz_obj_type) + 1);
+                       } else {
+                               status = -EPERM;
+                       }
+               }
+
+               if (!status) {
+                       len = strlen(sz_reg_key);
+                       spin_lock(&dbdcd_lock);
+                       list_for_each_entry(dcd_key, &reg_key_list, link) {
+                               if (!strncmp(dcd_key->name, sz_reg_key, len)
+                                               && !index--) {
+                                       strncpy(sz_value, &dcd_key->name[len],
+                                              strlen(&dcd_key->name[len]) + 1);
+                                               break;
+                               }
+                       }
+                       spin_unlock(&dbdcd_lock);
+
+                       if (&dcd_key->link == &reg_key_list)
+                               status = -ENODATA;
+               }
+
+               if (!status) {
+                       /* Create UUID value using string retrieved from
+                        * registry. */
+                       uuid_uuid_from_string(sz_value, &dsp_uuid_obj);
+
+                       *uuid_obj = dsp_uuid_obj;
+
+                       /* Increment enum_refs to update reference count. */
+                       enum_refs++;
+
+                       status = 0;
+               } else if (status == -ENODATA) {
+                       /* At the end of enumeration. Reset enum_refs. */
+                       enum_refs = 0;
+
+                       /*
+                        * TODO: Revisit, this is not an errror case but code
+                        * expects non-zero value.
+                        */
+                       status = ENODATA;
+               } else {
+                       status = -EPERM;
+               }
+       }
+
+       DBC_ENSURE(uuid_obj || (status == -EPERM));
+
+       return status;
+}
+
+/*
+ *  ======== dcd_exit ========
+ *  Purpose:
+ *      Discontinue usage of the DCD module.
+ */
+void dcd_exit(void)
+{
+       struct dcd_key_elem *rv, *rv_tmp;
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+       if (refs == 0) {
+               cod_exit();
+               list_for_each_entry_safe(rv, rv_tmp, &reg_key_list, link) {
+                       list_del(&rv->link);
+                       kfree(rv->path);
+                       kfree(rv);
+               }
+       }
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== dcd_get_dep_libs ========
+ */
+int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr,
+                           struct dsp_uuid *uuid_obj,
+                           u16 num_libs, struct dsp_uuid *dep_lib_uuids,
+                           bool *prstnt_dep_libs,
+                           enum nldr_phase phase)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hdcd_mgr);
+       DBC_REQUIRE(uuid_obj != NULL);
+       DBC_REQUIRE(dep_lib_uuids != NULL);
+       DBC_REQUIRE(prstnt_dep_libs != NULL);
+
+       status =
+           get_dep_lib_info(hdcd_mgr, uuid_obj, &num_libs, NULL, dep_lib_uuids,
+                            prstnt_dep_libs, phase);
+
+       return status;
+}
+
+/*
+ *  ======== dcd_get_num_dep_libs ========
+ */
+int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr,
+                               struct dsp_uuid *uuid_obj,
+                               u16 *num_libs, u16 *num_pers_libs,
+                               enum nldr_phase phase)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hdcd_mgr);
+       DBC_REQUIRE(num_libs != NULL);
+       DBC_REQUIRE(num_pers_libs != NULL);
+       DBC_REQUIRE(uuid_obj != NULL);
+
+       status = get_dep_lib_info(hdcd_mgr, uuid_obj, num_libs, num_pers_libs,
+                                 NULL, NULL, phase);
+
+       return status;
+}
+
+/*
+ *  ======== dcd_get_object_def ========
+ *  Purpose:
+ *      Retrieves the properties of a node or processor based on the UUID and
+ *      object type.
+ */
+int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
+                             struct dsp_uuid *obj_uuid,
+                             enum dsp_dcdobjtype obj_type,
+                             struct dcd_genericobj *obj_def)
+{
+       struct dcd_manager *dcd_mgr_obj = hdcd_mgr;     /* ptr to DCD mgr */
+       struct cod_libraryobj *lib = NULL;
+       int status = 0;
+       u32 ul_addr = 0;        /* Used by cod_get_section */
+       u32 ul_len = 0;         /* Used by cod_get_section */
+       u32 dw_buf_size;        /* Used by REG functions */
+       char sz_reg_key[DCD_MAXPATHLENGTH];
+       char *sz_uuid;          /*[MAXUUIDLEN]; */
+       struct dcd_key_elem *dcd_key = NULL;
+       char sz_sect_name[MAXUUIDLEN + 2];      /* ".[UUID]\0" */
+       char *psz_coff_buf;
+       u32 dw_key_len;         /* Len of REG key. */
+       char sz_obj_type[MAX_INT2CHAR_LENGTH];  /* str. rep. of obj_type. */
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(obj_def != NULL);
+       DBC_REQUIRE(obj_uuid != NULL);
+
+       sz_uuid = kzalloc(MAXUUIDLEN, GFP_KERNEL);
+       if (!sz_uuid) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+
+       if (!hdcd_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       /* Pre-determine final key length. It's length of DCD_REGKEY +
+        *  "_\0" + length of sz_obj_type string + terminating NULL */
+       dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
+       DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
+
+       /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
+       strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
+
+       if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
+               strncat(sz_reg_key, "_\0", 2);
+       else
+               status = -EPERM;
+
+       status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
+       if (status == -1) {
+               status = -EPERM;
+       } else {
+               status = 0;
+
+               if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
+                   DCD_MAXPATHLENGTH) {
+                       strncat(sz_reg_key, sz_obj_type,
+                               strlen(sz_obj_type) + 1);
+               } else {
+                       status = -EPERM;
+               }
+
+               /* Create UUID value to set in registry. */
+               uuid_uuid_to_string(obj_uuid, sz_uuid, MAXUUIDLEN);
+
+               if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
+                       strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
+               else
+                       status = -EPERM;
+
+               /* Retrieve paths from the registry based on struct dsp_uuid */
+               dw_buf_size = DCD_MAXPATHLENGTH;
+       }
+       if (!status) {
+               spin_lock(&dbdcd_lock);
+               list_for_each_entry(dcd_key, &reg_key_list, link) {
+                       if (!strncmp(dcd_key->name, sz_reg_key,
+                                               strlen(sz_reg_key) + 1))
+                               break;
+               }
+               spin_unlock(&dbdcd_lock);
+               if (&dcd_key->link == &reg_key_list) {
+                       status = -ENOKEY;
+                       goto func_end;
+               }
+       }
+
+
+       /* Open COFF file. */
+       status = cod_open(dcd_mgr_obj->cod_mgr, dcd_key->path,
+                                                       COD_NOLOAD, &lib);
+       if (status) {
+               status = -EACCES;
+               goto func_end;
+       }
+
+       /* Ensure sz_uuid + 1 is not greater than sizeof sz_sect_name. */
+       DBC_ASSERT((strlen(sz_uuid) + 1) < sizeof(sz_sect_name));
+
+       /* Create section name based on node UUID. A period is
+        * pre-pended to the UUID string to form the section name.
+        * I.e. ".24BC8D90_BB45_11d4_B756_006008BDB66F" */
+       strncpy(sz_sect_name, ".", 2);
+       strncat(sz_sect_name, sz_uuid, strlen(sz_uuid));
+
+       /* Get section information. */
+       status = cod_get_section(lib, sz_sect_name, &ul_addr, &ul_len);
+       if (status) {
+               status = -EACCES;
+               goto func_end;
+       }
+
+       /* Allocate zeroed buffer. */
+       psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
+#ifdef _DB_TIOMAP
+       if (strstr(dcd_key->path, "iva") == NULL) {
+               /* Locate section by objectID and read its content. */
+               status =
+                   cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
+       } else {
+               status =
+                   cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
+               dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
+       }
+#else
+       status = cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
+#endif
+       if (!status) {
+               /* Compres DSP buffer to conform to PC format. */
+               if (strstr(dcd_key->path, "iva") == NULL) {
+                       compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
+               } else {
+                       compress_buf(psz_coff_buf, ul_len, 1);
+                       dev_dbg(bridge, "%s: Compressing IVA COFF buffer by 1 "
+                               "for IVA!!\n", __func__);
+               }
+
+               /* Parse the content of the COFF buffer. */
+               status =
+                   get_attrs_from_buf(psz_coff_buf, ul_len, obj_type, obj_def);
+               if (status)
+                       status = -EACCES;
+       } else {
+               status = -EACCES;
+       }
+
+       /* Free the previously allocated dynamic buffer. */
+       kfree(psz_coff_buf);
+func_end:
+       if (lib)
+               cod_close(lib);
+
+       kfree(sz_uuid);
+
+       return status;
+}
+
+/*
+ *  ======== dcd_get_objects ========
+ */
+int dcd_get_objects(struct dcd_manager *hdcd_mgr,
+                          char *sz_coff_path, dcd_registerfxn register_fxn,
+                          void *handle)
+{
+       struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
+       int status = 0;
+       char *psz_coff_buf;
+       char *psz_cur;
+       struct cod_libraryobj *lib = NULL;
+       u32 ul_addr = 0;        /* Used by cod_get_section */
+       u32 ul_len = 0;         /* Used by cod_get_section */
+       char seps[] = ":, ";
+       char *token = NULL;
+       struct dsp_uuid dsp_uuid_obj;
+       s32 object_type;
+
+       DBC_REQUIRE(refs > 0);
+       if (!hdcd_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       /* Open DSP coff file, don't load symbols. */
+       status = cod_open(dcd_mgr_obj->cod_mgr, sz_coff_path, COD_NOLOAD, &lib);
+       if (status) {
+               status = -EACCES;
+               goto func_cont;
+       }
+
+       /* Get DCD_RESIGER_SECTION section information. */
+       status = cod_get_section(lib, DCD_REGISTER_SECTION, &ul_addr, &ul_len);
+       if (status || !(ul_len > 0)) {
+               status = -EACCES;
+               goto func_cont;
+       }
+
+       /* Allocate zeroed buffer. */
+       psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
+#ifdef _DB_TIOMAP
+       if (strstr(sz_coff_path, "iva") == NULL) {
+               /* Locate section by objectID and read its content. */
+               status = cod_read_section(lib, DCD_REGISTER_SECTION,
+                                         psz_coff_buf, ul_len);
+       } else {
+               dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
+               status = cod_read_section(lib, DCD_REGISTER_SECTION,
+                                         psz_coff_buf, ul_len);
+       }
+#else
+       status =
+           cod_read_section(lib, DCD_REGISTER_SECTION, psz_coff_buf, ul_len);
+#endif
+       if (!status) {
+               /* Compress DSP buffer to conform to PC format. */
+               if (strstr(sz_coff_path, "iva") == NULL) {
+                       compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
+               } else {
+                       compress_buf(psz_coff_buf, ul_len, 1);
+                       dev_dbg(bridge, "%s: Compress COFF buffer with 1 word "
+                               "for IVA!!\n", __func__);
+               }
+
+               /* Read from buffer and register object in buffer. */
+               psz_cur = psz_coff_buf;
+               while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
+                       /*  Retrieve UUID string. */
+                       uuid_uuid_from_string(token, &dsp_uuid_obj);
+
+                       /*  Retrieve object type */
+                       token = strsep(&psz_cur, seps);
+
+                       /*  Retrieve object type */
+                       object_type = atoi(token);
+
+                       /*
+                        *  Apply register_fxn to the found DCD object.
+                        *  Possible actions include:
+                        *
+                        *  1) Register found DCD object.
+                        *  2) Unregister found DCD object (when handle == NULL)
+                        *  3) Add overlay node.
+                        */
+                       status =
+                           register_fxn(&dsp_uuid_obj, object_type, handle);
+                       if (status) {
+                               /* if error occurs, break from while loop. */
+                               break;
+                       }
+               }
+       } else {
+               status = -EACCES;
+       }
+
+       /* Free the previously allocated dynamic buffer. */
+       kfree(psz_coff_buf);
+func_cont:
+       if (lib)
+               cod_close(lib);
+
+func_end:
+       return status;
+}
+
+/*
+ *  ======== dcd_get_library_name ========
+ *  Purpose:
+ *      Retrieves the library name for the given UUID.
+ *
+ */
+int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
+                               struct dsp_uuid *uuid_obj,
+                               char *str_lib_name,
+                               u32 *buff_size,
+                               enum nldr_phase phase, bool *phase_split)
+{
+       char sz_reg_key[DCD_MAXPATHLENGTH];
+       char sz_uuid[MAXUUIDLEN];
+       u32 dw_key_len;         /* Len of REG key. */
+       char sz_obj_type[MAX_INT2CHAR_LENGTH];  /* str. rep. of obj_type. */
+       int status = 0;
+       struct dcd_key_elem *dcd_key = NULL;
+
+       DBC_REQUIRE(uuid_obj != NULL);
+       DBC_REQUIRE(str_lib_name != NULL);
+       DBC_REQUIRE(buff_size != NULL);
+       DBC_REQUIRE(hdcd_mgr);
+
+       dev_dbg(bridge, "%s: hdcd_mgr %p, uuid_obj %p, str_lib_name %p,"
+               " buff_size %p\n", __func__, hdcd_mgr, uuid_obj, str_lib_name,
+               buff_size);
+
+       /*
+        *  Pre-determine final key length. It's length of DCD_REGKEY +
+        *  "_\0" + length of sz_obj_type string + terminating NULL.
+        */
+       dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
+       DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
+
+       /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
+       strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
+       if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
+               strncat(sz_reg_key, "_\0", 2);
+       else
+               status = -EPERM;
+
+       switch (phase) {
+       case NLDR_CREATE:
+               /* create phase type */
+               sprintf(sz_obj_type, "%d", DSP_DCDCREATELIBTYPE);
+               break;
+       case NLDR_EXECUTE:
+               /* execute phase type */
+               sprintf(sz_obj_type, "%d", DSP_DCDEXECUTELIBTYPE);
+               break;
+       case NLDR_DELETE:
+               /* delete phase type */
+               sprintf(sz_obj_type, "%d", DSP_DCDDELETELIBTYPE);
+               break;
+       case NLDR_NOPHASE:
+               /* known to be a dependent library */
+               sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
+               break;
+       default:
+               status = -EINVAL;
+               DBC_ASSERT(false);
+       }
+       if (!status) {
+               if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
+                   DCD_MAXPATHLENGTH) {
+                       strncat(sz_reg_key, sz_obj_type,
+                               strlen(sz_obj_type) + 1);
+               } else {
+                       status = -EPERM;
+               }
+               /* Create UUID value to find match in registry. */
+               uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN);
+               if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
+                       strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
+               else
+                       status = -EPERM;
+       }
+       if (!status) {
+               spin_lock(&dbdcd_lock);
+               list_for_each_entry(dcd_key, &reg_key_list, link) {
+                       /*  See if the name matches. */
+                       if (!strncmp(dcd_key->name, sz_reg_key,
+                                               strlen(sz_reg_key) + 1))
+                               break;
+               }
+               spin_unlock(&dbdcd_lock);
+       }
+
+       if (&dcd_key->link == &reg_key_list)
+               status = -ENOKEY;
+
+       /* If can't find, phases might be registered as generic LIBRARYTYPE */
+       if (status && phase != NLDR_NOPHASE) {
+               if (phase_split)
+                       *phase_split = false;
+
+               strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
+               if ((strlen(sz_reg_key) + strlen("_\0")) <
+                   DCD_MAXPATHLENGTH) {
+                       strncat(sz_reg_key, "_\0", 2);
+               } else {
+                       status = -EPERM;
+               }
+               sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
+               if ((strlen(sz_reg_key) + strlen(sz_obj_type))
+                   < DCD_MAXPATHLENGTH) {
+                       strncat(sz_reg_key, sz_obj_type,
+                               strlen(sz_obj_type) + 1);
+               } else {
+                       status = -EPERM;
+               }
+               uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN);
+               if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
+                       strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
+               else
+                       status = -EPERM;
+
+               spin_lock(&dbdcd_lock);
+               list_for_each_entry(dcd_key, &reg_key_list, link) {
+                       /*  See if the name matches. */
+                       if (!strncmp(dcd_key->name, sz_reg_key,
+                                               strlen(sz_reg_key) + 1))
+                               break;
+               }
+               spin_unlock(&dbdcd_lock);
+
+               status = (&dcd_key->link != &reg_key_list) ?
+                                               0 : -ENOKEY;
+       }
+
+       if (!status)
+               memcpy(str_lib_name, dcd_key->path, strlen(dcd_key->path) + 1);
+       return status;
+}
+
+/*
+ *  ======== dcd_init ========
+ *  Purpose:
+ *      Initialize the DCD module.
+ */
+bool dcd_init(void)
+{
+       bool init_cod;
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (refs == 0) {
+               /* Initialize required modules. */
+               init_cod = cod_init();
+
+               if (!init_cod) {
+                       ret = false;
+                       /* Exit initialized modules. */
+                       if (init_cod)
+                               cod_exit();
+               }
+
+               INIT_LIST_HEAD(&reg_key_list);
+       }
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs == 0)));
+
+       return ret;
+}
+
+/*
+ *  ======== dcd_register_object ========
+ *  Purpose:
+ *      Registers a node or a processor with the DCD.
+ *      If psz_path_name == NULL, unregister the specified DCD object.
+ */
+int dcd_register_object(struct dsp_uuid *uuid_obj,
+                              enum dsp_dcdobjtype obj_type,
+                              char *psz_path_name)
+{
+       int status = 0;
+       char sz_reg_key[DCD_MAXPATHLENGTH];
+       char sz_uuid[MAXUUIDLEN + 1];
+       u32 dw_path_size = 0;
+       u32 dw_key_len;         /* Len of REG key. */
+       char sz_obj_type[MAX_INT2CHAR_LENGTH];  /* str. rep. of obj_type. */
+       struct dcd_key_elem *dcd_key = NULL;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(uuid_obj != NULL);
+       DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) ||
+                   (obj_type == DSP_DCDPROCESSORTYPE) ||
+                   (obj_type == DSP_DCDLIBRARYTYPE) ||
+                   (obj_type == DSP_DCDCREATELIBTYPE) ||
+                   (obj_type == DSP_DCDEXECUTELIBTYPE) ||
+                   (obj_type == DSP_DCDDELETELIBTYPE));
+
+       dev_dbg(bridge, "%s: object UUID %p, obj_type %d, szPathName %s\n",
+               __func__, uuid_obj, obj_type, psz_path_name);
+
+       /*
+        * Pre-determine final key length. It's length of DCD_REGKEY +
+        *  "_\0" + length of sz_obj_type string + terminating NULL.
+        */
+       dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
+       DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
+
+       /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
+       strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
+       if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
+               strncat(sz_reg_key, "_\0", 2);
+       else {
+               status = -EPERM;
+               goto func_end;
+       }
+
+       status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
+       if (status == -1) {
+               status = -EPERM;
+       } else {
+               status = 0;
+               if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
+                   DCD_MAXPATHLENGTH) {
+                       strncat(sz_reg_key, sz_obj_type,
+                               strlen(sz_obj_type) + 1);
+               } else
+                       status = -EPERM;
+
+               /* Create UUID value to set in registry. */
+               uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN);
+               if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
+                       strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
+               else
+                       status = -EPERM;
+       }
+
+       if (status)
+               goto func_end;
+
+       /*
+        * If psz_path_name != NULL, perform registration, otherwise,
+        * perform unregistration.
+        */
+
+       if (psz_path_name) {
+               dw_path_size = strlen(psz_path_name) + 1;
+               spin_lock(&dbdcd_lock);
+               list_for_each_entry(dcd_key, &reg_key_list, link) {
+                       /*  See if the name matches. */
+                       if (!strncmp(dcd_key->name, sz_reg_key,
+                                               strlen(sz_reg_key) + 1))
+                               break;
+               }
+               spin_unlock(&dbdcd_lock);
+               if (&dcd_key->link == &reg_key_list) {
+                       /*
+                        * Add new reg value (UUID+obj_type)
+                        * with COFF path info
+                        */
+
+                       dcd_key = kmalloc(sizeof(struct dcd_key_elem),
+                                                               GFP_KERNEL);
+                       if (!dcd_key) {
+                               status = -ENOMEM;
+                               goto func_end;
+                       }
+
+                       dcd_key->path = kmalloc(strlen(sz_reg_key) + 1,
+                                                               GFP_KERNEL);
+
+                       if (!dcd_key->path) {
+                               kfree(dcd_key);
+                               status = -ENOMEM;
+                               goto func_end;
+                       }
+
+                       strncpy(dcd_key->name, sz_reg_key,
+                                               strlen(sz_reg_key) + 1);
+                       strncpy(dcd_key->path, psz_path_name ,
+                                               dw_path_size);
+                       spin_lock(&dbdcd_lock);
+                       list_add_tail(&dcd_key->link, &reg_key_list);
+                       spin_unlock(&dbdcd_lock);
+               } else {
+                       /*  Make sure the new data is the same. */
+                       if (strncmp(dcd_key->path, psz_path_name,
+                                                       dw_path_size)) {
+                               /*  The caller needs a different data size! */
+                               kfree(dcd_key->path);
+                               dcd_key->path = kmalloc(dw_path_size,
+                                                               GFP_KERNEL);
+                               if (dcd_key->path == NULL) {
+                                       status = -ENOMEM;
+                                       goto func_end;
+                               }
+                       }
+
+                       /*  We have a match!  Copy out the data. */
+                       memcpy(dcd_key->path, psz_path_name, dw_path_size);
+               }
+               dev_dbg(bridge, "%s: psz_path_name=%s, dw_path_size=%d\n",
+                       __func__, psz_path_name, dw_path_size);
+       } else {
+               /* Deregister an existing object */
+               spin_lock(&dbdcd_lock);
+               list_for_each_entry(dcd_key, &reg_key_list, link) {
+                       if (!strncmp(dcd_key->name, sz_reg_key,
+                                               strlen(sz_reg_key) + 1)) {
+                               list_del(&dcd_key->link);
+                               kfree(dcd_key->path);
+                               kfree(dcd_key);
+                               break;
+                       }
+               }
+               spin_unlock(&dbdcd_lock);
+               if (&dcd_key->link == &reg_key_list)
+                       status = -EPERM;
+       }
+
+       if (!status) {
+               /*
+                *  Because the node database has been updated through a
+                *  successful object registration/de-registration operation,
+                *  we need to reset the object enumeration counter to allow
+                *  current enumerations to reflect this update in the node
+                *  database.
+                */
+               enum_refs = 0;
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== dcd_unregister_object ========
+ *  Call DCD_Register object with psz_path_name set to NULL to
+ *  perform actual object de-registration.
+ */
+int dcd_unregister_object(struct dsp_uuid *uuid_obj,
+                                enum dsp_dcdobjtype obj_type)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(uuid_obj != NULL);
+       DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) ||
+                   (obj_type == DSP_DCDPROCESSORTYPE) ||
+                   (obj_type == DSP_DCDLIBRARYTYPE) ||
+                   (obj_type == DSP_DCDCREATELIBTYPE) ||
+                   (obj_type == DSP_DCDEXECUTELIBTYPE) ||
+                   (obj_type == DSP_DCDDELETELIBTYPE));
+
+       /*
+        *  When dcd_register_object is called with NULL as pathname,
+        *  it indicates an unregister object operation.
+        */
+       status = dcd_register_object(uuid_obj, obj_type, NULL);
+
+       return status;
+}
+
+/*
+ **********************************************************************
+ * DCD Helper Functions
+ **********************************************************************
+ */
+
+/*
+ *  ======== atoi ========
+ *  Purpose:
+ *      This function converts strings in decimal or hex format to integers.
+ */
+static s32 atoi(char *psz_buf)
+{
+       char *pch = psz_buf;
+       s32 base = 0;
+       unsigned long res;
+       int ret_val;
+
+       while (isspace(*pch))
+               pch++;
+
+       if (*pch == '-' || *pch == '+') {
+               base = 10;
+               pch++;
+       } else if (*pch && tolower(pch[strlen(pch) - 1]) == 'h') {
+               base = 16;
+       }
+
+       ret_val = strict_strtoul(pch, base, &res);
+
+       return ret_val ? : res;
+}
+
+/*
+ *  ======== get_attrs_from_buf ========
+ *  Purpose:
+ *      Parse the content of a buffer filled with DSP-side data and
+ *      retrieve an object's attributes from it. IMPORTANT: Assume the
+ *      buffer has been converted from DSP format to GPP format.
+ */
+static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
+                                    enum dsp_dcdobjtype obj_type,
+                                    struct dcd_genericobj *gen_obj)
+{
+       int status = 0;
+       char seps[] = ", ";
+       char *psz_cur;
+       char *token;
+       s32 token_len = 0;
+       u32 i = 0;
+#ifdef _DB_TIOMAP
+       s32 entry_id;
+#endif
+
+       DBC_REQUIRE(psz_buf != NULL);
+       DBC_REQUIRE(ul_buf_size != 0);
+       DBC_REQUIRE((obj_type == DSP_DCDNODETYPE)
+                   || (obj_type == DSP_DCDPROCESSORTYPE));
+       DBC_REQUIRE(gen_obj != NULL);
+
+       switch (obj_type) {
+       case DSP_DCDNODETYPE:
+               /*
+                * Parse COFF sect buffer to retrieve individual tokens used
+                * to fill in object attrs.
+                */
+               psz_cur = psz_buf;
+               token = strsep(&psz_cur, seps);
+
+               /* u32 cb_struct */
+               gen_obj->obj_data.node_obj.ndb_props.cb_struct =
+                   (u32) atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* dsp_uuid ui_node_id */
+               uuid_uuid_from_string(token,
+                                     &gen_obj->obj_data.node_obj.ndb_props.
+                                     ui_node_id);
+               token = strsep(&psz_cur, seps);
+
+               /* ac_name */
+               DBC_REQUIRE(token);
+               token_len = strlen(token);
+               if (token_len > DSP_MAXNAMELEN - 1)
+                       token_len = DSP_MAXNAMELEN - 1;
+
+               strncpy(gen_obj->obj_data.node_obj.ndb_props.ac_name,
+                       token, token_len);
+               gen_obj->obj_data.node_obj.ndb_props.ac_name[token_len] = '\0';
+               token = strsep(&psz_cur, seps);
+               /* u32 ntype */
+               gen_obj->obj_data.node_obj.ndb_props.ntype = atoi(token);
+               token = strsep(&psz_cur, seps);
+               /* u32 cache_on_gpp */
+               gen_obj->obj_data.node_obj.ndb_props.cache_on_gpp = atoi(token);
+               token = strsep(&psz_cur, seps);
+               /* dsp_resourcereqmts dsp_resource_reqmts */
+               gen_obj->obj_data.node_obj.ndb_props.dsp_resource_reqmts.
+                   cb_struct = (u32) atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.static_data_size = atoi(token);
+               token = strsep(&psz_cur, seps);
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.global_data_size = atoi(token);
+               token = strsep(&psz_cur, seps);
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.program_mem_size = atoi(token);
+               token = strsep(&psz_cur, seps);
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.uwc_execution_time = atoi(token);
+               token = strsep(&psz_cur, seps);
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.uwc_period = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.uwc_deadline = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.avg_exection_time = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.node_obj.ndb_props.
+                   dsp_resource_reqmts.minimum_period = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* s32 prio */
+               gen_obj->obj_data.node_obj.ndb_props.prio = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* u32 stack_size */
+               gen_obj->obj_data.node_obj.ndb_props.stack_size = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* u32 sys_stack_size */
+               gen_obj->obj_data.node_obj.ndb_props.sys_stack_size =
+                   atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* u32 stack_seg */
+               gen_obj->obj_data.node_obj.ndb_props.stack_seg = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* u32 message_depth */
+               gen_obj->obj_data.node_obj.ndb_props.message_depth =
+                   atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* u32 num_input_streams */
+               gen_obj->obj_data.node_obj.ndb_props.num_input_streams =
+                   atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* u32 num_output_streams */
+               gen_obj->obj_data.node_obj.ndb_props.num_output_streams =
+                   atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* u32 utimeout */
+               gen_obj->obj_data.node_obj.ndb_props.utimeout = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* char *pstr_create_phase_fxn */
+               DBC_REQUIRE(token);
+               token_len = strlen(token);
+               gen_obj->obj_data.node_obj.pstr_create_phase_fxn =
+                                       kzalloc(token_len + 1, GFP_KERNEL);
+               strncpy(gen_obj->obj_data.node_obj.pstr_create_phase_fxn,
+                       token, token_len);
+               gen_obj->obj_data.node_obj.pstr_create_phase_fxn[token_len] =
+                   '\0';
+               token = strsep(&psz_cur, seps);
+
+               /* char *pstr_execute_phase_fxn */
+               DBC_REQUIRE(token);
+               token_len = strlen(token);
+               gen_obj->obj_data.node_obj.pstr_execute_phase_fxn =
+                                       kzalloc(token_len + 1, GFP_KERNEL);
+               strncpy(gen_obj->obj_data.node_obj.pstr_execute_phase_fxn,
+                       token, token_len);
+               gen_obj->obj_data.node_obj.pstr_execute_phase_fxn[token_len] =
+                   '\0';
+               token = strsep(&psz_cur, seps);
+
+               /* char *pstr_delete_phase_fxn */
+               DBC_REQUIRE(token);
+               token_len = strlen(token);
+               gen_obj->obj_data.node_obj.pstr_delete_phase_fxn =
+                                       kzalloc(token_len + 1, GFP_KERNEL);
+               strncpy(gen_obj->obj_data.node_obj.pstr_delete_phase_fxn,
+                       token, token_len);
+               gen_obj->obj_data.node_obj.pstr_delete_phase_fxn[token_len] =
+                   '\0';
+               token = strsep(&psz_cur, seps);
+
+               /* Segment id for message buffers */
+               gen_obj->obj_data.node_obj.msg_segid = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* Message notification type */
+               gen_obj->obj_data.node_obj.msg_notify_type = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               /* char *pstr_i_alg_name */
+               if (token) {
+                       token_len = strlen(token);
+                       gen_obj->obj_data.node_obj.pstr_i_alg_name =
+                                       kzalloc(token_len + 1, GFP_KERNEL);
+                       strncpy(gen_obj->obj_data.node_obj.pstr_i_alg_name,
+                               token, token_len);
+                       gen_obj->obj_data.node_obj.pstr_i_alg_name[token_len] =
+                           '\0';
+                       token = strsep(&psz_cur, seps);
+               }
+
+               /* Load type (static, dynamic, or overlay) */
+               if (token) {
+                       gen_obj->obj_data.node_obj.us_load_type = atoi(token);
+                       token = strsep(&psz_cur, seps);
+               }
+
+               /* Dynamic load data requirements */
+               if (token) {
+                       gen_obj->obj_data.node_obj.ul_data_mem_seg_mask =
+                           atoi(token);
+                       token = strsep(&psz_cur, seps);
+               }
+
+               /* Dynamic load code requirements */
+               if (token) {
+                       gen_obj->obj_data.node_obj.ul_code_mem_seg_mask =
+                           atoi(token);
+                       token = strsep(&psz_cur, seps);
+               }
+
+               /* Extract node profiles into node properties */
+               if (token) {
+
+                       gen_obj->obj_data.node_obj.ndb_props.count_profiles =
+                           atoi(token);
+                       for (i = 0;
+                            i <
+                            gen_obj->obj_data.node_obj.
+                            ndb_props.count_profiles; i++) {
+                               token = strsep(&psz_cur, seps);
+                               if (token) {
+                                       /* Heap Size for the node */
+                                       gen_obj->obj_data.node_obj.
+                                           ndb_props.node_profiles[i].
+                                           ul_heap_size = atoi(token);
+                               }
+                       }
+               }
+               token = strsep(&psz_cur, seps);
+               if (token) {
+                       gen_obj->obj_data.node_obj.ndb_props.stack_seg_name =
+                           (u32) (token);
+               }
+
+               break;
+
+       case DSP_DCDPROCESSORTYPE:
+               /*
+                * Parse COFF sect buffer to retrieve individual tokens used
+                * to fill in object attrs.
+                */
+               psz_cur = psz_buf;
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.cb_struct = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.processor_family = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.processor_type = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.clock_rate = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.ul_internal_mem_size = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.ul_external_mem_size = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.processor_id = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.ty_running_rtos = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.node_min_priority = atoi(token);
+               token = strsep(&psz_cur, seps);
+
+               gen_obj->obj_data.proc_info.node_max_priority = atoi(token);
+
+#ifdef _DB_TIOMAP
+               /* Proc object may contain additional(extended) attributes. */
+               /* attr must match proc.hxx */
+               for (entry_id = 0; entry_id < 7; entry_id++) {
+                       token = strsep(&psz_cur, seps);
+                       gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
+                           ul_gpp_phys = atoi(token);
+
+                       token = strsep(&psz_cur, seps);
+                       gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
+                           ul_dsp_virt = atoi(token);
+               }
+#endif
+
+               break;
+
+       default:
+               status = -EPERM;
+               break;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== CompressBuffer ========
+ *  Purpose:
+ *      Compress the DSP buffer, if necessary, to conform to PC format.
+ */
+static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size)
+{
+       char *p;
+       char ch;
+       char *q;
+
+       p = psz_buf;
+       if (p == NULL)
+               return;
+
+       for (q = psz_buf; q < (psz_buf + ul_buf_size);) {
+               ch = dsp_char2_gpp_char(q, char_size);
+               if (ch == '\\') {
+                       q += char_size;
+                       ch = dsp_char2_gpp_char(q, char_size);
+                       switch (ch) {
+                       case 't':
+                               *p = '\t';
+                               break;
+
+                       case 'n':
+                               *p = '\n';
+                               break;
+
+                       case 'r':
+                               *p = '\r';
+                               break;
+
+                       case '0':
+                               *p = '\0';
+                               break;
+
+                       default:
+                               *p = ch;
+                               break;
+                       }
+               } else {
+                       *p = ch;
+               }
+               p++;
+               q += char_size;
+       }
+
+       /* NULL out remainder of buffer. */
+       while (p < q)
+               *p++ = '\0';
+}
+
+/*
+ *  ======== dsp_char2_gpp_char ========
+ *  Purpose:
+ *      Convert DSP char to host GPP char in a portable manner
+ */
+static char dsp_char2_gpp_char(char *word, s32 dsp_char_size)
+{
+       char ch = '\0';
+       char *ch_src;
+       s32 i;
+
+       for (ch_src = word, i = dsp_char_size; i > 0; i--)
+               ch |= *ch_src++;
+
+       return ch;
+}
+
+/*
+ *  ======== get_dep_lib_info ========
+ */
+static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
+                                  struct dsp_uuid *uuid_obj,
+                                  u16 *num_libs,
+                                  u16 *num_pers_libs,
+                                  struct dsp_uuid *dep_lib_uuids,
+                                  bool *prstnt_dep_libs,
+                                  enum nldr_phase phase)
+{
+       struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
+       char *psz_coff_buf = NULL;
+       char *psz_cur;
+       char *psz_file_name = NULL;
+       struct cod_libraryobj *lib = NULL;
+       u32 ul_addr = 0;        /* Used by cod_get_section */
+       u32 ul_len = 0;         /* Used by cod_get_section */
+       u32 dw_data_size = COD_MAXPATHLENGTH;
+       char seps[] = ", ";
+       char *token = NULL;
+       bool get_uuids = (dep_lib_uuids != NULL);
+       u16 dep_libs = 0;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+
+       DBC_REQUIRE(hdcd_mgr);
+       DBC_REQUIRE(num_libs != NULL);
+       DBC_REQUIRE(uuid_obj != NULL);
+
+       /*  Initialize to 0 dependent libraries, if only counting number of
+        *  dependent libraries */
+       if (!get_uuids) {
+               *num_libs = 0;
+               *num_pers_libs = 0;
+       }
+
+       /* Allocate a buffer for file name */
+       psz_file_name = kzalloc(dw_data_size, GFP_KERNEL);
+       if (psz_file_name == NULL) {
+               status = -ENOMEM;
+       } else {
+               /* Get the name of the library */
+               status = dcd_get_library_name(hdcd_mgr, uuid_obj, psz_file_name,
+                                             &dw_data_size, phase, NULL);
+       }
+
+       /* Open the library */
+       if (!status) {
+               status = cod_open(dcd_mgr_obj->cod_mgr, psz_file_name,
+                                 COD_NOLOAD, &lib);
+       }
+       if (!status) {
+               /* Get dependent library section information. */
+               status = cod_get_section(lib, DEPLIBSECT, &ul_addr, &ul_len);
+
+               if (status) {
+                       /* Ok, no dependent libraries */
+                       ul_len = 0;
+                       status = 0;
+               }
+       }
+
+       if (status || !(ul_len > 0))
+               goto func_cont;
+
+       /* Allocate zeroed buffer. */
+       psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
+       if (psz_coff_buf == NULL)
+               status = -ENOMEM;
+
+       /* Read section contents. */
+       status = cod_read_section(lib, DEPLIBSECT, psz_coff_buf, ul_len);
+       if (status)
+               goto func_cont;
+
+       /* Compress and format DSP buffer to conform to PC format. */
+       compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
+
+       /* Read from buffer */
+       psz_cur = psz_coff_buf;
+       while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
+               if (get_uuids) {
+                       if (dep_libs >= *num_libs) {
+                               /* Gone beyond the limit */
+                               break;
+                       } else {
+                               /* Retrieve UUID string. */
+                               uuid_uuid_from_string(token,
+                                                     &(dep_lib_uuids
+                                                       [dep_libs]));
+                               /* Is this library persistent? */
+                               token = strsep(&psz_cur, seps);
+                               prstnt_dep_libs[dep_libs] = atoi(token);
+                               dep_libs++;
+                       }
+               } else {
+                       /* Advanc to next token */
+                       token = strsep(&psz_cur, seps);
+                       if (atoi(token))
+                               (*num_pers_libs)++;
+
+                       /* Just counting number of dependent libraries */
+                       (*num_libs)++;
+               }
+       }
+func_cont:
+       if (lib)
+               cod_close(lib);
+
+       /* Free previously allocated dynamic buffers. */
+       kfree(psz_file_name);
+
+       kfree(psz_coff_buf);
+
+       return status;
+}
diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c
new file mode 100644 (file)
index 0000000..b7ce435
--- /dev/null
@@ -0,0 +1,752 @@
+/*
+ * disp.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Node Dispatcher interface. Communicates with Resource Manager Server
+ * (RMS) on DSP. Access to RMS is synchronized in NODE.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Link Driver */
+#include <dspbridge/dspdefs.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+#include <dspbridge/chnldefs.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/nodedefs.h>
+#include <dspbridge/nodepriv.h>
+#include <dspbridge/rms_sh.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/disp.h>
+
+/* Size of a reply from RMS */
+#define REPLYSIZE (3 * sizeof(rms_word))
+
+/* Reserved channel offsets for communication with RMS */
+#define CHNLTORMSOFFSET       0
+#define CHNLFROMRMSOFFSET     1
+
+#define CHNLIOREQS      1
+
+/*
+ *  ======== disp_object ========
+ */
+struct disp_object {
+       struct dev_object *hdev_obj;    /* Device for this processor */
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+       struct chnl_mgr *hchnl_mgr;     /* Channel manager */
+       struct chnl_object *chnl_to_dsp;        /* Chnl for commands to RMS */
+       struct chnl_object *chnl_from_dsp;      /* Chnl for replies from RMS */
+       u8 *pbuf;               /* Buffer for commands, replies */
+       u32 ul_bufsize;         /* pbuf size in bytes */
+       u32 ul_bufsize_rms;     /* pbuf size in RMS words */
+       u32 char_size;          /* Size of DSP character */
+       u32 word_size;          /* Size of DSP word */
+       u32 data_mau_size;      /* Size of DSP Data MAU */
+};
+
+static u32 refs;
+
+static void delete_disp(struct disp_object *disp_obj);
+static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
+                                 struct node_strmdef strm_def, u32 max,
+                                 u32 chars_in_rms_word);
+static int send_message(struct disp_object *disp_obj, u32 timeout,
+                              u32 ul_bytes, u32 *pdw_arg);
+
+/*
+ *  ======== disp_create ========
+ *  Create a NODE Dispatcher object.
+ */
+int disp_create(struct disp_object **dispatch_obj,
+                      struct dev_object *hdev_obj,
+                      const struct disp_attr *disp_attrs)
+{
+       struct disp_object *disp_obj;
+       struct bridge_drv_interface *intf_fxns;
+       u32 ul_chnl_id;
+       struct chnl_attr chnl_attr_obj;
+       int status = 0;
+       u8 dev_type;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dispatch_obj != NULL);
+       DBC_REQUIRE(disp_attrs != NULL);
+       DBC_REQUIRE(hdev_obj != NULL);
+
+       *dispatch_obj = NULL;
+
+       /* Allocate Node Dispatcher object */
+       disp_obj = kzalloc(sizeof(struct disp_object), GFP_KERNEL);
+       if (disp_obj == NULL)
+               status = -ENOMEM;
+       else
+               disp_obj->hdev_obj = hdev_obj;
+
+       /* Get Channel manager and Bridge function interface */
+       if (!status) {
+               status = dev_get_chnl_mgr(hdev_obj, &(disp_obj->hchnl_mgr));
+               if (!status) {
+                       (void)dev_get_intf_fxns(hdev_obj, &intf_fxns);
+                       disp_obj->intf_fxns = intf_fxns;
+               }
+       }
+
+       /* check device type and decide if streams or messag'ing is used for
+        * RMS/EDS */
+       if (status)
+               goto func_cont;
+
+       status = dev_get_dev_type(hdev_obj, &dev_type);
+
+       if (status)
+               goto func_cont;
+
+       if (dev_type != DSP_UNIT) {
+               status = -EPERM;
+               goto func_cont;
+       }
+
+       disp_obj->char_size = DSPWORDSIZE;
+       disp_obj->word_size = DSPWORDSIZE;
+       disp_obj->data_mau_size = DSPWORDSIZE;
+       /* Open channels for communicating with the RMS */
+       chnl_attr_obj.uio_reqs = CHNLIOREQS;
+       chnl_attr_obj.event_obj = NULL;
+       ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLTORMSOFFSET;
+       status = (*intf_fxns->pfn_chnl_open) (&(disp_obj->chnl_to_dsp),
+                                             disp_obj->hchnl_mgr,
+                                             CHNL_MODETODSP, ul_chnl_id,
+                                             &chnl_attr_obj);
+
+       if (!status) {
+               ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLFROMRMSOFFSET;
+               status =
+                   (*intf_fxns->pfn_chnl_open) (&(disp_obj->chnl_from_dsp),
+                                                disp_obj->hchnl_mgr,
+                                                CHNL_MODEFROMDSP, ul_chnl_id,
+                                                &chnl_attr_obj);
+       }
+       if (!status) {
+               /* Allocate buffer for commands, replies */
+               disp_obj->ul_bufsize = disp_attrs->ul_chnl_buf_size;
+               disp_obj->ul_bufsize_rms = RMS_COMMANDBUFSIZE;
+               disp_obj->pbuf = kzalloc(disp_obj->ul_bufsize, GFP_KERNEL);
+               if (disp_obj->pbuf == NULL)
+                       status = -ENOMEM;
+       }
+func_cont:
+       if (!status)
+               *dispatch_obj = disp_obj;
+       else
+               delete_disp(disp_obj);
+
+       DBC_ENSURE((status && *dispatch_obj == NULL) ||
+                               (!status && *dispatch_obj));
+       return status;
+}
+
+/*
+ *  ======== disp_delete ========
+ *  Delete the NODE Dispatcher.
+ */
+void disp_delete(struct disp_object *disp_obj)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(disp_obj);
+
+       delete_disp(disp_obj);
+}
+
+/*
+ *  ======== disp_exit ========
+ *  Discontinue usage of DISP module.
+ */
+void disp_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== disp_init ========
+ *  Initialize the DISP module.
+ */
+bool disp_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+       return ret;
+}
+
+/*
+ *  ======== disp_node_change_priority ========
+ *  Change the priority of a node currently running on the target.
+ */
+int disp_node_change_priority(struct disp_object *disp_obj,
+                                    struct node_object *hnode,
+                                    u32 rms_fxn, nodeenv node_env, s32 prio)
+{
+       u32 dw_arg;
+       struct rms_command *rms_cmd;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(disp_obj);
+       DBC_REQUIRE(hnode != NULL);
+
+       /* Send message to RMS to change priority */
+       rms_cmd = (struct rms_command *)(disp_obj->pbuf);
+       rms_cmd->fxn = (rms_word) (rms_fxn);
+       rms_cmd->arg1 = (rms_word) node_env;
+       rms_cmd->arg2 = prio;
+       status = send_message(disp_obj, node_get_timeout(hnode),
+                             sizeof(struct rms_command), &dw_arg);
+
+       return status;
+}
+
+/*
+ *  ======== disp_node_create ========
+ *  Create a node on the DSP by remotely calling the node's create function.
+ */
+int disp_node_create(struct disp_object *disp_obj,
+                           struct node_object *hnode, u32 rms_fxn,
+                           u32 ul_create_fxn,
+                           const struct node_createargs *pargs,
+                           nodeenv *node_env)
+{
+       struct node_msgargs node_msg_args;
+       struct node_taskargs task_arg_obj;
+       struct rms_command *rms_cmd;
+       struct rms_msg_args *pmsg_args;
+       struct rms_more_task_args *more_task_args;
+       enum node_type node_type;
+       u32 dw_length;
+       rms_word *pdw_buf = NULL;
+       u32 ul_bytes;
+       u32 i;
+       u32 total;
+       u32 chars_in_rms_word;
+       s32 task_args_offset;
+       s32 sio_in_def_offset;
+       s32 sio_out_def_offset;
+       s32 sio_defs_offset;
+       s32 args_offset = -1;
+       s32 offset;
+       struct node_strmdef strm_def;
+       u32 max;
+       int status = 0;
+       struct dsp_nodeinfo node_info;
+       u8 dev_type;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(disp_obj);
+       DBC_REQUIRE(hnode != NULL);
+       DBC_REQUIRE(node_get_type(hnode) != NODE_DEVICE);
+       DBC_REQUIRE(node_env != NULL);
+
+       status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type);
+
+       if (status)
+               goto func_end;
+
+       if (dev_type != DSP_UNIT) {
+               dev_dbg(bridge, "%s: unknown device type = 0x%x\n",
+                       __func__, dev_type);
+               goto func_end;
+       }
+       DBC_REQUIRE(pargs != NULL);
+       node_type = node_get_type(hnode);
+       node_msg_args = pargs->asa.node_msg_args;
+       max = disp_obj->ul_bufsize_rms; /*Max # of RMS words that can be sent */
+       DBC_ASSERT(max == RMS_COMMANDBUFSIZE);
+       chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size;
+       /* Number of RMS words needed to hold arg data */
+       dw_length =
+           (node_msg_args.arg_length + chars_in_rms_word -
+            1) / chars_in_rms_word;
+       /* Make sure msg args and command fit in buffer */
+       total = sizeof(struct rms_command) / sizeof(rms_word) +
+           sizeof(struct rms_msg_args)
+           / sizeof(rms_word) - 1 + dw_length;
+       if (total >= max) {
+               status = -EPERM;
+               dev_dbg(bridge, "%s: Message args too large for buffer! size "
+                       "= %d, max = %d\n", __func__, total, max);
+       }
+       /*
+        *  Fill in buffer to send to RMS.
+        *  The buffer will have the following  format:
+        *
+        *  RMS command:
+        *      Address of RMS_CreateNode()
+        *      Address of node's create function
+        *      dummy argument
+        *      node type
+        *
+        *  Message Args:
+        *      max number of messages
+        *      segid for message buffer allocation
+        *      notification type to use when message is received
+        *      length of message arg data
+        *      message args data
+        *
+        *  Task Args (if task or socket node):
+        *      priority
+        *      stack size
+        *      system stack size
+        *      stack segment
+        *      misc
+        *      number of input streams
+        *      pSTRMInDef[] - offsets of STRM definitions for input streams
+        *      number of output streams
+        *      pSTRMOutDef[] - offsets of STRM definitions for output
+        *      streams
+        *      STRMInDef[] - array of STRM definitions for input streams
+        *      STRMOutDef[] - array of STRM definitions for output streams
+        *
+        *  Socket Args (if DAIS socket node):
+        *
+        */
+       if (!status) {
+               total = 0;      /* Total number of words in buffer so far */
+               pdw_buf = (rms_word *) disp_obj->pbuf;
+               rms_cmd = (struct rms_command *)pdw_buf;
+               rms_cmd->fxn = (rms_word) (rms_fxn);
+               rms_cmd->arg1 = (rms_word) (ul_create_fxn);
+               if (node_get_load_type(hnode) == NLDR_DYNAMICLOAD) {
+                       /* Flush ICACHE on Load */
+                       rms_cmd->arg2 = 1;      /* dummy argument */
+               } else {
+                       /* Do not flush ICACHE */
+                       rms_cmd->arg2 = 0;      /* dummy argument */
+               }
+               rms_cmd->data = node_get_type(hnode);
+               /*
+                *  args_offset is the offset of the data field in struct
+                *  rms_command structure. We need this to calculate stream
+                *  definition offsets.
+                */
+               args_offset = 3;
+               total += sizeof(struct rms_command) / sizeof(rms_word);
+               /* Message args */
+               pmsg_args = (struct rms_msg_args *)(pdw_buf + total);
+               pmsg_args->max_msgs = node_msg_args.max_msgs;
+               pmsg_args->segid = node_msg_args.seg_id;
+               pmsg_args->notify_type = node_msg_args.notify_type;
+               pmsg_args->arg_length = node_msg_args.arg_length;
+               total += sizeof(struct rms_msg_args) / sizeof(rms_word) - 1;
+               memcpy(pdw_buf + total, node_msg_args.pdata,
+                      node_msg_args.arg_length);
+               total += dw_length;
+       }
+       if (status)
+               goto func_end;
+
+       /* If node is a task node, copy task create arguments into  buffer */
+       if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) {
+               task_arg_obj = pargs->asa.task_arg_obj;
+               task_args_offset = total;
+               total += sizeof(struct rms_more_task_args) / sizeof(rms_word) +
+                   1 + task_arg_obj.num_inputs + task_arg_obj.num_outputs;
+               /* Copy task arguments */
+               if (total < max) {
+                       total = task_args_offset;
+                       more_task_args = (struct rms_more_task_args *)(pdw_buf +
+                                                                      total);
+                       /*
+                        * Get some important info about the node. Note that we
+                        * don't just reach into the hnode struct because
+                        * that would break the node object's abstraction.
+                        */
+                       get_node_info(hnode, &node_info);
+                       more_task_args->priority = node_info.execution_priority;
+                       more_task_args->stack_size = task_arg_obj.stack_size;
+                       more_task_args->sysstack_size =
+                           task_arg_obj.sys_stack_size;
+                       more_task_args->stack_seg = task_arg_obj.stack_seg;
+                       more_task_args->heap_addr = task_arg_obj.udsp_heap_addr;
+                       more_task_args->heap_size = task_arg_obj.heap_size;
+                       more_task_args->misc = task_arg_obj.ul_dais_arg;
+                       more_task_args->num_input_streams =
+                           task_arg_obj.num_inputs;
+                       total +=
+                           sizeof(struct rms_more_task_args) /
+                           sizeof(rms_word);
+                       dev_dbg(bridge, "%s: udsp_heap_addr %x, heap_size %x\n",
+                               __func__, task_arg_obj.udsp_heap_addr,
+                               task_arg_obj.heap_size);
+                       /* Keep track of pSIOInDef[] and pSIOOutDef[]
+                        * positions in the buffer, since this needs to be
+                        * filled in later. */
+                       sio_in_def_offset = total;
+                       total += task_arg_obj.num_inputs;
+                       pdw_buf[total++] = task_arg_obj.num_outputs;
+                       sio_out_def_offset = total;
+                       total += task_arg_obj.num_outputs;
+                       sio_defs_offset = total;
+                       /* Fill SIO defs and offsets */
+                       offset = sio_defs_offset;
+                       for (i = 0; i < task_arg_obj.num_inputs; i++) {
+                               if (status)
+                                       break;
+
+                               pdw_buf[sio_in_def_offset + i] =
+                                   (offset - args_offset)
+                                   * (sizeof(rms_word) / DSPWORDSIZE);
+                               strm_def = task_arg_obj.strm_in_def[i];
+                               status =
+                                   fill_stream_def(pdw_buf, &total, offset,
+                                                   strm_def, max,
+                                                   chars_in_rms_word);
+                               offset = total;
+                       }
+                       for (i = 0; (i < task_arg_obj.num_outputs) &&
+                            (!status); i++) {
+                               pdw_buf[sio_out_def_offset + i] =
+                                   (offset - args_offset)
+                                   * (sizeof(rms_word) / DSPWORDSIZE);
+                               strm_def = task_arg_obj.strm_out_def[i];
+                               status =
+                                   fill_stream_def(pdw_buf, &total, offset,
+                                                   strm_def, max,
+                                                   chars_in_rms_word);
+                               offset = total;
+                       }
+               } else {
+                       /* Args won't fit */
+                       status = -EPERM;
+               }
+       }
+       if (!status) {
+               ul_bytes = total * sizeof(rms_word);
+               DBC_ASSERT(ul_bytes < (RMS_COMMANDBUFSIZE * sizeof(rms_word)));
+               status = send_message(disp_obj, node_get_timeout(hnode),
+                                     ul_bytes, node_env);
+               if (status >= 0) {
+                       /*
+                        * Message successfully received from RMS.
+                        * Return the status of the Node's create function
+                        * on the DSP-side
+                        */
+                       status = (((rms_word *) (disp_obj->pbuf))[0]);
+                       if (status < 0)
+                               dev_dbg(bridge, "%s: DSP-side failed: 0x%x\n",
+                                       __func__, status);
+               }
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== disp_node_delete ========
+ *  purpose:
+ *      Delete a node on the DSP by remotely calling the node's delete function.
+ *
+ */
+int disp_node_delete(struct disp_object *disp_obj,
+                           struct node_object *hnode, u32 rms_fxn,
+                           u32 ul_delete_fxn, nodeenv node_env)
+{
+       u32 dw_arg;
+       struct rms_command *rms_cmd;
+       int status = 0;
+       u8 dev_type;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(disp_obj);
+       DBC_REQUIRE(hnode != NULL);
+
+       status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type);
+
+       if (!status) {
+
+               if (dev_type == DSP_UNIT) {
+
+                       /*
+                        *  Fill in buffer to send to RMS
+                        */
+                       rms_cmd = (struct rms_command *)disp_obj->pbuf;
+                       rms_cmd->fxn = (rms_word) (rms_fxn);
+                       rms_cmd->arg1 = (rms_word) node_env;
+                       rms_cmd->arg2 = (rms_word) (ul_delete_fxn);
+                       rms_cmd->data = node_get_type(hnode);
+
+                       status = send_message(disp_obj, node_get_timeout(hnode),
+                                             sizeof(struct rms_command),
+                                             &dw_arg);
+                       if (status >= 0) {
+                               /*
+                                * Message successfully received from RMS.
+                                * Return the status of the Node's delete
+                                * function on the DSP-side
+                                */
+                               status = (((rms_word *) (disp_obj->pbuf))[0]);
+                               if (status < 0)
+                                       dev_dbg(bridge, "%s: DSP-side failed: "
+                                               "0x%x\n", __func__, status);
+                       }
+
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== disp_node_run ========
+ *  purpose:
+ *      Start execution of a node's execute phase, or resume execution of a node
+ *      that has been suspended (via DISP_NodePause()) on the DSP.
+ */
+int disp_node_run(struct disp_object *disp_obj,
+                        struct node_object *hnode, u32 rms_fxn,
+                        u32 ul_execute_fxn, nodeenv node_env)
+{
+       u32 dw_arg;
+       struct rms_command *rms_cmd;
+       int status = 0;
+       u8 dev_type;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(disp_obj);
+       DBC_REQUIRE(hnode != NULL);
+
+       status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type);
+
+       if (!status) {
+
+               if (dev_type == DSP_UNIT) {
+
+                       /*
+                        *  Fill in buffer to send to RMS.
+                        */
+                       rms_cmd = (struct rms_command *)disp_obj->pbuf;
+                       rms_cmd->fxn = (rms_word) (rms_fxn);
+                       rms_cmd->arg1 = (rms_word) node_env;
+                       rms_cmd->arg2 = (rms_word) (ul_execute_fxn);
+                       rms_cmd->data = node_get_type(hnode);
+
+                       status = send_message(disp_obj, node_get_timeout(hnode),
+                                             sizeof(struct rms_command),
+                                             &dw_arg);
+                       if (status >= 0) {
+                               /*
+                                * Message successfully received from RMS.
+                                * Return the status of the Node's execute
+                                * function on the DSP-side
+                                */
+                               status = (((rms_word *) (disp_obj->pbuf))[0]);
+                               if (status < 0)
+                                       dev_dbg(bridge, "%s: DSP-side failed: "
+                                               "0x%x\n", __func__, status);
+                       }
+
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== delete_disp ========
+ *  purpose:
+ *      Frees the resources allocated for the dispatcher.
+ */
+static void delete_disp(struct disp_object *disp_obj)
+{
+       int status = 0;
+       struct bridge_drv_interface *intf_fxns;
+
+       if (disp_obj) {
+               intf_fxns = disp_obj->intf_fxns;
+
+               /* Free Node Dispatcher resources */
+               if (disp_obj->chnl_from_dsp) {
+                       /* Channel close can fail only if the channel handle
+                        * is invalid. */
+                       status = (*intf_fxns->pfn_chnl_close)
+                           (disp_obj->chnl_from_dsp);
+                       if (status) {
+                               dev_dbg(bridge, "%s: Failed to close channel "
+                                       "from RMS: 0x%x\n", __func__, status);
+                       }
+               }
+               if (disp_obj->chnl_to_dsp) {
+                       status =
+                           (*intf_fxns->pfn_chnl_close) (disp_obj->
+                                                         chnl_to_dsp);
+                       if (status) {
+                               dev_dbg(bridge, "%s: Failed to close channel to"
+                                       " RMS: 0x%x\n", __func__, status);
+                       }
+               }
+               kfree(disp_obj->pbuf);
+
+               kfree(disp_obj);
+       }
+}
+
+/*
+ *  ======== fill_stream_def ========
+ *  purpose:
+ *      Fills stream definitions.
+ */
+static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
+                                 struct node_strmdef strm_def, u32 max,
+                                 u32 chars_in_rms_word)
+{
+       struct rms_strm_def *strm_def_obj;
+       u32 total = *ptotal;
+       u32 name_len;
+       u32 dw_length;
+       int status = 0;
+
+       if (total + sizeof(struct rms_strm_def) / sizeof(rms_word) >= max) {
+               status = -EPERM;
+       } else {
+               strm_def_obj = (struct rms_strm_def *)(pdw_buf + total);
+               strm_def_obj->bufsize = strm_def.buf_size;
+               strm_def_obj->nbufs = strm_def.num_bufs;
+               strm_def_obj->segid = strm_def.seg_id;
+               strm_def_obj->align = strm_def.buf_alignment;
+               strm_def_obj->timeout = strm_def.utimeout;
+       }
+
+       if (!status) {
+               /*
+                *  Since we haven't added the device name yet, subtract
+                *  1 from total.
+                */
+               total += sizeof(struct rms_strm_def) / sizeof(rms_word) - 1;
+               DBC_REQUIRE(strm_def.sz_device);
+               dw_length = strlen(strm_def.sz_device) + 1;
+
+               /* Number of RMS_WORDS needed to hold device name */
+               name_len =
+                   (dw_length + chars_in_rms_word - 1) / chars_in_rms_word;
+
+               if (total + name_len >= max) {
+                       status = -EPERM;
+               } else {
+                       /*
+                        *  Zero out last word, since the device name may not
+                        *  extend to completely fill this word.
+                        */
+                       pdw_buf[total + name_len - 1] = 0;
+                       /** TODO USE SERVICES * */
+                       memcpy(pdw_buf + total, strm_def.sz_device, dw_length);
+                       total += name_len;
+                       *ptotal = total;
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== send_message ======
+ *  Send command message to RMS, get reply from RMS.
+ */
+static int send_message(struct disp_object *disp_obj, u32 timeout,
+                              u32 ul_bytes, u32 *pdw_arg)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct chnl_object *chnl_obj;
+       u32 dw_arg = 0;
+       u8 *pbuf;
+       struct chnl_ioc chnl_ioc_obj;
+       int status = 0;
+
+       DBC_REQUIRE(pdw_arg != NULL);
+
+       *pdw_arg = (u32) NULL;
+       intf_fxns = disp_obj->intf_fxns;
+       chnl_obj = disp_obj->chnl_to_dsp;
+       pbuf = disp_obj->pbuf;
+
+       /* Send the command */
+       status = (*intf_fxns->pfn_chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0,
+                                                   0L, dw_arg);
+       if (status)
+               goto func_end;
+
+       status =
+           (*intf_fxns->pfn_chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
+       if (!status) {
+               if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
+                       if (CHNL_IS_TIMED_OUT(chnl_ioc_obj))
+                               status = -ETIME;
+                       else
+                               status = -EPERM;
+               }
+       }
+       /* Get the reply */
+       if (status)
+               goto func_end;
+
+       chnl_obj = disp_obj->chnl_from_dsp;
+       ul_bytes = REPLYSIZE;
+       status = (*intf_fxns->pfn_chnl_add_io_req) (chnl_obj, pbuf, ul_bytes,
+                                                   0, 0L, dw_arg);
+       if (status)
+               goto func_end;
+
+       status =
+           (*intf_fxns->pfn_chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
+       if (!status) {
+               if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
+                       status = -ETIME;
+               } else if (chnl_ioc_obj.byte_size < ul_bytes) {
+                       /* Did not get all of the reply from the RMS */
+                       status = -EPERM;
+               } else {
+                       if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
+                               DBC_ASSERT(chnl_ioc_obj.pbuf == pbuf);
+                               status = (*((rms_word *) chnl_ioc_obj.pbuf));
+                               *pdw_arg =
+                                   (((rms_word *) (chnl_ioc_obj.pbuf))[1]);
+                       } else {
+                               status = -EPERM;
+                       }
+               }
+       }
+func_end:
+       return status;
+}
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
new file mode 100644 (file)
index 0000000..8a8dea6
--- /dev/null
@@ -0,0 +1,929 @@
+/*
+ * drv.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge resource allocation module.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/list.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/drv.h>
+#include <dspbridge/dev.h>
+
+#include <dspbridge/node.h>
+#include <dspbridge/proc.h>
+#include <dspbridge/strm.h>
+#include <dspbridge/nodepriv.h>
+#include <dspbridge/dspchnl.h>
+#include <dspbridge/resourcecleanup.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+struct drv_object {
+       struct lst_list *dev_list;
+       struct lst_list *dev_node_string;
+};
+
+/*
+ *  This is the Device Extension. Named with the Prefix
+ *  DRV_ since it is living in this module
+ */
+struct drv_ext {
+       struct list_head link;
+       char sz_string[MAXREGPATHLENGTH];
+};
+
+/*  ----------------------------------- Globals */
+static s32 refs;
+static bool ext_phys_mem_pool_enabled;
+struct ext_phys_mem_pool {
+       u32 phys_mem_base;
+       u32 phys_mem_size;
+       u32 virt_mem_base;
+       u32 next_phys_alloc_ptr;
+};
+static struct ext_phys_mem_pool ext_mem_pool;
+
+/*  ----------------------------------- Function Prototypes */
+static int request_bridge_resources(struct cfg_hostres *res);
+
+
+/* GPP PROCESS CLEANUP CODE */
+
+static int drv_proc_free_node_res(int id, void *p, void *data);
+
+/* Allocate and add a node resource element
+* This function is called from .Node_Allocate. */
+int drv_insert_node_res_element(void *hnode, void *node_resource,
+                                      void *process_ctxt)
+{
+       struct node_res_object **node_res_obj =
+           (struct node_res_object **)node_resource;
+       struct process_context *ctxt = (struct process_context *)process_ctxt;
+       int status = 0;
+       int retval;
+
+       *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
+       if (!*node_res_obj) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+
+       (*node_res_obj)->hnode = hnode;
+       retval = idr_get_new(ctxt->node_id, *node_res_obj,
+                                               &(*node_res_obj)->id);
+       if (retval == -EAGAIN) {
+               if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) {
+                       pr_err("%s: OUT OF MEMORY\n", __func__);
+                       status = -ENOMEM;
+                       goto func_end;
+               }
+
+               retval = idr_get_new(ctxt->node_id, *node_res_obj,
+                                               &(*node_res_obj)->id);
+       }
+       if (retval) {
+               pr_err("%s: FAILED, IDR is FULL\n", __func__);
+               status = -EFAULT;
+       }
+func_end:
+       if (status)
+               kfree(*node_res_obj);
+
+       return status;
+}
+
+/* Release all Node resources and its context
+ * Actual Node De-Allocation */
+static int drv_proc_free_node_res(int id, void *p, void *data)
+{
+       struct process_context *ctxt = data;
+       int status;
+       struct node_res_object *node_res_obj = p;
+       u32 node_state;
+
+       if (node_res_obj->node_allocated) {
+               node_state = node_get_state(node_res_obj->hnode);
+               if (node_state <= NODE_DELETING) {
+                       if ((node_state == NODE_RUNNING) ||
+                           (node_state == NODE_PAUSED) ||
+                           (node_state == NODE_TERMINATING))
+                               node_terminate
+                                   (node_res_obj->hnode, &status);
+
+                       node_delete(node_res_obj, ctxt);
+               }
+       }
+
+       return 0;
+}
+
+/* Release all Mapped and Reserved DMM resources */
+int drv_remove_all_dmm_res_elements(void *process_ctxt)
+{
+       struct process_context *ctxt = (struct process_context *)process_ctxt;
+       int status = 0;
+       struct dmm_map_object *temp_map, *map_obj;
+       struct dmm_rsv_object *temp_rsv, *rsv_obj;
+
+       /* Free DMM mapped memory resources */
+       list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) {
+               status = proc_un_map(ctxt->hprocessor,
+                                    (void *)map_obj->dsp_addr, ctxt);
+               if (status)
+                       pr_err("%s: proc_un_map failed!"
+                              " status = 0x%xn", __func__, status);
+       }
+
+       /* Free DMM reserved memory resources */
+       list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) {
+               status = proc_un_reserve_memory(ctxt->hprocessor, (void *)
+                                               rsv_obj->dsp_reserved_addr,
+                                               ctxt);
+               if (status)
+                       pr_err("%s: proc_un_reserve_memory failed!"
+                              " status = 0x%xn", __func__, status);
+       }
+       return status;
+}
+
+/* Update Node allocation status */
+void drv_proc_node_update_status(void *node_resource, s32 status)
+{
+       struct node_res_object *node_res_obj =
+           (struct node_res_object *)node_resource;
+       DBC_ASSERT(node_resource != NULL);
+       node_res_obj->node_allocated = status;
+}
+
+/* Update Node Heap status */
+void drv_proc_node_update_heap_status(void *node_resource, s32 status)
+{
+       struct node_res_object *node_res_obj =
+           (struct node_res_object *)node_resource;
+       DBC_ASSERT(node_resource != NULL);
+       node_res_obj->heap_allocated = status;
+}
+
+/* Release all Node resources and its context
+* This is called from .bridge_release.
+ */
+int drv_remove_all_node_res_elements(void *process_ctxt)
+{
+       struct process_context *ctxt = process_ctxt;
+
+       idr_for_each(ctxt->node_id, drv_proc_free_node_res, ctxt);
+       idr_destroy(ctxt->node_id);
+
+       return 0;
+}
+
+/* Allocate the STRM resource element
+* This is called after the actual resource is allocated
+ */
+int drv_proc_insert_strm_res_element(void *stream_obj,
+                                           void *strm_res, void *process_ctxt)
+{
+       struct strm_res_object **pstrm_res =
+           (struct strm_res_object **)strm_res;
+       struct process_context *ctxt = (struct process_context *)process_ctxt;
+       int status = 0;
+       int retval;
+
+       *pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
+       if (*pstrm_res == NULL) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       (*pstrm_res)->hstream = stream_obj;
+       retval = idr_get_new(ctxt->stream_id, *pstrm_res,
+                                               &(*pstrm_res)->id);
+       if (retval == -EAGAIN) {
+               if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) {
+                       pr_err("%s: OUT OF MEMORY\n", __func__);
+                       status = -ENOMEM;
+                       goto func_end;
+               }
+
+               retval = idr_get_new(ctxt->stream_id, *pstrm_res,
+                                               &(*pstrm_res)->id);
+       }
+       if (retval) {
+               pr_err("%s: FAILED, IDR is FULL\n", __func__);
+               status = -EPERM;
+       }
+
+func_end:
+       return status;
+}
+
+static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
+{
+       struct process_context *ctxt = process_ctxt;
+       struct strm_res_object *strm_res = p;
+       struct stream_info strm_info;
+       struct dsp_streaminfo user;
+       u8 **ap_buffer = NULL;
+       u8 *buf_ptr;
+       u32 ul_bytes;
+       u32 dw_arg;
+       s32 ul_buf_size;
+
+       if (strm_res->num_bufs) {
+               ap_buffer = kmalloc((strm_res->num_bufs *
+                                      sizeof(u8 *)), GFP_KERNEL);
+               if (ap_buffer) {
+                       strm_free_buffer(strm_res,
+                                                 ap_buffer,
+                                                 strm_res->num_bufs,
+                                                 ctxt);
+                       kfree(ap_buffer);
+               }
+       }
+       strm_info.user_strm = &user;
+       user.number_bufs_in_stream = 0;
+       strm_get_info(strm_res->hstream, &strm_info, sizeof(strm_info));
+       while (user.number_bufs_in_stream--)
+               strm_reclaim(strm_res->hstream, &buf_ptr, &ul_bytes,
+                            (u32 *) &ul_buf_size, &dw_arg);
+       strm_close(strm_res, ctxt);
+       return 0;
+}
+
+/* Release all Stream resources and its context
+* This is called from .bridge_release.
+ */
+int drv_remove_all_strm_res_elements(void *process_ctxt)
+{
+       struct process_context *ctxt = process_ctxt;
+
+       idr_for_each(ctxt->stream_id, drv_proc_free_strm_res, ctxt);
+       idr_destroy(ctxt->stream_id);
+
+       return 0;
+}
+
+/* Updating the stream resource element */
+int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources)
+{
+       int status = 0;
+       struct strm_res_object **strm_res =
+           (struct strm_res_object **)strm_resources;
+
+       (*strm_res)->num_bufs = num_bufs;
+       return status;
+}
+
+/* GPP PROCESS CLEANUP CODE END */
+
+/*
+ *  ======== = drv_create ======== =
+ *  Purpose:
+ *      DRV Object gets created only once during Driver Loading.
+ */
+int drv_create(struct drv_object **drv_obj)
+{
+       int status = 0;
+       struct drv_object *pdrv_object = NULL;
+
+       DBC_REQUIRE(drv_obj != NULL);
+       DBC_REQUIRE(refs > 0);
+
+       pdrv_object = kzalloc(sizeof(struct drv_object), GFP_KERNEL);
+       if (pdrv_object) {
+               /* Create and Initialize List of device objects */
+               pdrv_object->dev_list = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               if (pdrv_object->dev_list) {
+                       /* Create and Initialize List of device Extension */
+                       pdrv_object->dev_node_string =
+                               kzalloc(sizeof(struct lst_list), GFP_KERNEL);
+                       if (!(pdrv_object->dev_node_string)) {
+                               status = -EPERM;
+                       } else {
+                               INIT_LIST_HEAD(&pdrv_object->
+                                              dev_node_string->head);
+                               INIT_LIST_HEAD(&pdrv_object->dev_list->head);
+                       }
+               } else {
+                       status = -ENOMEM;
+               }
+       } else {
+               status = -ENOMEM;
+       }
+       /* Store the DRV Object in the Registry */
+       if (!status)
+               status = cfg_set_object((u32) pdrv_object, REG_DRV_OBJECT);
+       if (!status) {
+               *drv_obj = pdrv_object;
+       } else {
+               kfree(pdrv_object->dev_list);
+               kfree(pdrv_object->dev_node_string);
+               /* Free the DRV Object */
+               kfree(pdrv_object);
+       }
+
+       DBC_ENSURE(status || pdrv_object);
+       return status;
+}
+
+/*
+ *  ======== drv_exit ========
+ *  Purpose:
+ *      Discontinue usage of the DRV module.
+ */
+void drv_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== = drv_destroy ======== =
+ *  purpose:
+ *      Invoked during bridge de-initialization
+ */
+int drv_destroy(struct drv_object *driver_obj)
+{
+       int status = 0;
+       struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pdrv_object);
+
+       /*
+        *  Delete the List if it exists.Should not come here
+        *  as the drv_remove_dev_object and the Last drv_request_resources
+        *  removes the list if the lists are empty.
+        */
+       kfree(pdrv_object->dev_list);
+       kfree(pdrv_object->dev_node_string);
+       kfree(pdrv_object);
+       /* Update the DRV Object in Registry to be 0 */
+       (void)cfg_set_object(0, REG_DRV_OBJECT);
+
+       return status;
+}
+
+/*
+ *  ======== drv_get_dev_object ========
+ *  Purpose:
+ *      Given a index, returns a handle to DevObject from the list.
+ */
+int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj,
+                             struct dev_object **device_obj)
+{
+       int status = 0;
+#ifdef CONFIG_TIDSPBRIDGE_DEBUG
+       /* used only for Assertions and debug messages */
+       struct drv_object *pdrv_obj = (struct drv_object *)hdrv_obj;
+#endif
+       struct dev_object *dev_obj;
+       u32 i;
+       DBC_REQUIRE(pdrv_obj);
+       DBC_REQUIRE(device_obj != NULL);
+       DBC_REQUIRE(index >= 0);
+       DBC_REQUIRE(refs > 0);
+       DBC_ASSERT(!(LST_IS_EMPTY(pdrv_obj->dev_list)));
+
+       dev_obj = (struct dev_object *)drv_get_first_dev_object();
+       for (i = 0; i < index; i++) {
+               dev_obj =
+                   (struct dev_object *)drv_get_next_dev_object((u32) dev_obj);
+       }
+       if (dev_obj) {
+               *device_obj = (struct dev_object *)dev_obj;
+       } else {
+               *device_obj = NULL;
+               status = -EPERM;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== drv_get_first_dev_object ========
+ *  Purpose:
+ *      Retrieve the first Device Object handle from an internal linked list of
+ *      of DEV_OBJECTs maintained by DRV.
+ */
+u32 drv_get_first_dev_object(void)
+{
+       u32 dw_dev_object = 0;
+       struct drv_object *pdrv_obj;
+
+       if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
+               if ((pdrv_obj->dev_list != NULL) &&
+                   !LST_IS_EMPTY(pdrv_obj->dev_list))
+                       dw_dev_object = (u32) lst_first(pdrv_obj->dev_list);
+       }
+
+       return dw_dev_object;
+}
+
+/*
+ *  ======== DRV_GetFirstDevNodeString ========
+ *  Purpose:
+ *      Retrieve the first Device Extension from an internal linked list of
+ *      of Pointer to dev_node Strings maintained by DRV.
+ */
+u32 drv_get_first_dev_extension(void)
+{
+       u32 dw_dev_extension = 0;
+       struct drv_object *pdrv_obj;
+
+       if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
+
+               if ((pdrv_obj->dev_node_string != NULL) &&
+                   !LST_IS_EMPTY(pdrv_obj->dev_node_string)) {
+                       dw_dev_extension =
+                           (u32) lst_first(pdrv_obj->dev_node_string);
+               }
+       }
+
+       return dw_dev_extension;
+}
+
+/*
+ *  ======== drv_get_next_dev_object ========
+ *  Purpose:
+ *      Retrieve the next Device Object handle from an internal linked list of
+ *      of DEV_OBJECTs maintained by DRV, after having previously called
+ *      drv_get_first_dev_object() and zero or more DRV_GetNext.
+ */
+u32 drv_get_next_dev_object(u32 hdev_obj)
+{
+       u32 dw_next_dev_object = 0;
+       struct drv_object *pdrv_obj;
+
+       DBC_REQUIRE(hdev_obj != 0);
+
+       if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
+
+               if ((pdrv_obj->dev_list != NULL) &&
+                   !LST_IS_EMPTY(pdrv_obj->dev_list)) {
+                       dw_next_dev_object = (u32) lst_next(pdrv_obj->dev_list,
+                                                           (struct list_head *)
+                                                           hdev_obj);
+               }
+       }
+       return dw_next_dev_object;
+}
+
+/*
+ *  ======== drv_get_next_dev_extension ========
+ *  Purpose:
+ *      Retrieve the next Device Extension from an internal linked list of
+ *      of pointer to DevNodeString maintained by DRV, after having previously
+ *      called drv_get_first_dev_extension() and zero or more
+ *      drv_get_next_dev_extension().
+ */
+u32 drv_get_next_dev_extension(u32 dev_extension)
+{
+       u32 dw_dev_extension = 0;
+       struct drv_object *pdrv_obj;
+
+       DBC_REQUIRE(dev_extension != 0);
+
+       if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
+               if ((pdrv_obj->dev_node_string != NULL) &&
+                   !LST_IS_EMPTY(pdrv_obj->dev_node_string)) {
+                       dw_dev_extension =
+                           (u32) lst_next(pdrv_obj->dev_node_string,
+                                          (struct list_head *)dev_extension);
+               }
+       }
+
+       return dw_dev_extension;
+}
+
+/*
+ *  ======== drv_init ========
+ *  Purpose:
+ *      Initialize DRV module private state.
+ */
+int drv_init(void)
+{
+       s32 ret = 1;            /* function return value */
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
+
+/*
+ *  ======== drv_insert_dev_object ========
+ *  Purpose:
+ *      Insert a DevObject into the list of Manager object.
+ */
+int drv_insert_dev_object(struct drv_object *driver_obj,
+                                struct dev_object *hdev_obj)
+{
+       struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hdev_obj != NULL);
+       DBC_REQUIRE(pdrv_object);
+       DBC_ASSERT(pdrv_object->dev_list);
+
+       lst_put_tail(pdrv_object->dev_list, (struct list_head *)hdev_obj);
+
+       DBC_ENSURE(!LST_IS_EMPTY(pdrv_object->dev_list));
+
+       return 0;
+}
+
+/*
+ *  ======== drv_remove_dev_object ========
+ *  Purpose:
+ *      Search for and remove a DeviceObject from the given list of DRV
+ *      objects.
+ */
+int drv_remove_dev_object(struct drv_object *driver_obj,
+                                struct dev_object *hdev_obj)
+{
+       int status = -EPERM;
+       struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
+       struct list_head *cur_elem;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pdrv_object);
+       DBC_REQUIRE(hdev_obj != NULL);
+
+       DBC_REQUIRE(pdrv_object->dev_list != NULL);
+       DBC_REQUIRE(!LST_IS_EMPTY(pdrv_object->dev_list));
+
+       /* Search list for p_proc_object: */
+       for (cur_elem = lst_first(pdrv_object->dev_list); cur_elem != NULL;
+            cur_elem = lst_next(pdrv_object->dev_list, cur_elem)) {
+               /* If found, remove it. */
+               if ((struct dev_object *)cur_elem == hdev_obj) {
+                       lst_remove_elem(pdrv_object->dev_list, cur_elem);
+                       status = 0;
+                       break;
+               }
+       }
+       /* Remove list if empty. */
+       if (LST_IS_EMPTY(pdrv_object->dev_list)) {
+               kfree(pdrv_object->dev_list);
+               pdrv_object->dev_list = NULL;
+       }
+       DBC_ENSURE((pdrv_object->dev_list == NULL) ||
+                  !LST_IS_EMPTY(pdrv_object->dev_list));
+
+       return status;
+}
+
+/*
+ *  ======== drv_request_resources ========
+ *  Purpose:
+ *      Requests  resources from the OS.
+ */
+int drv_request_resources(u32 dw_context, u32 *dev_node_strg)
+{
+       int status = 0;
+       struct drv_object *pdrv_object;
+       struct drv_ext *pszdev_node;
+
+       DBC_REQUIRE(dw_context != 0);
+       DBC_REQUIRE(dev_node_strg != NULL);
+
+       /*
+        *  Allocate memory to hold the string. This will live untill
+        *  it is freed in the Release resources. Update the driver object
+        *  list.
+        */
+
+       status = cfg_get_object((u32 *) &pdrv_object, REG_DRV_OBJECT);
+       if (!status) {
+               pszdev_node = kzalloc(sizeof(struct drv_ext), GFP_KERNEL);
+               if (pszdev_node) {
+                       lst_init_elem(&pszdev_node->link);
+                       strncpy(pszdev_node->sz_string,
+                               (char *)dw_context, MAXREGPATHLENGTH - 1);
+                       pszdev_node->sz_string[MAXREGPATHLENGTH - 1] = '\0';
+                       /* Update the Driver Object List */
+                       *dev_node_strg = (u32) pszdev_node->sz_string;
+                       lst_put_tail(pdrv_object->dev_node_string,
+                                    (struct list_head *)pszdev_node);
+               } else {
+                       status = -ENOMEM;
+                       *dev_node_strg = 0;
+               }
+       } else {
+               dev_dbg(bridge, "%s: Failed to get Driver Object from Registry",
+                       __func__);
+               *dev_node_strg = 0;
+       }
+
+       DBC_ENSURE((!status && dev_node_strg != NULL &&
+                   !LST_IS_EMPTY(pdrv_object->dev_node_string)) ||
+                  (status && *dev_node_strg == 0));
+
+       return status;
+}
+
+/*
+ *  ======== drv_release_resources ========
+ *  Purpose:
+ *      Releases  resources from the OS.
+ */
+int drv_release_resources(u32 dw_context, struct drv_object *hdrv_obj)
+{
+       int status = 0;
+       struct drv_object *pdrv_object = (struct drv_object *)hdrv_obj;
+       struct drv_ext *pszdev_node;
+
+       /*
+        *  Irrespective of the status go ahead and clean it
+        *  The following will over write the status.
+        */
+       for (pszdev_node = (struct drv_ext *)drv_get_first_dev_extension();
+            pszdev_node != NULL; pszdev_node = (struct drv_ext *)
+            drv_get_next_dev_extension((u32) pszdev_node)) {
+               if (!pdrv_object->dev_node_string) {
+                       /* When this could happen? */
+                       continue;
+               }
+               if ((u32) pszdev_node == dw_context) {
+                       /* Found it */
+                       /* Delete from the Driver object list */
+                       lst_remove_elem(pdrv_object->dev_node_string,
+                                       (struct list_head *)pszdev_node);
+                       kfree((void *)pszdev_node);
+                       break;
+               }
+               /* Delete the List if it is empty */
+               if (LST_IS_EMPTY(pdrv_object->dev_node_string)) {
+                       kfree(pdrv_object->dev_node_string);
+                       pdrv_object->dev_node_string = NULL;
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== request_bridge_resources ========
+ *  Purpose:
+ *      Reserves shared memory for bridge.
+ */
+static int request_bridge_resources(struct cfg_hostres *res)
+{
+       struct cfg_hostres *host_res = res;
+
+       /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
+       host_res->num_mem_windows = 2;
+
+       /* First window is for DSP internal memory */
+       host_res->dw_sys_ctrl_base = ioremap(OMAP_SYSC_BASE, OMAP_SYSC_SIZE);
+       dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]);
+       dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]);
+       dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base);
+
+       /* for 24xx base port is not mapping the mamory for DSP
+        * internal memory TODO Do a ioremap here */
+       /* Second window is for DSP external memory shared with MPU */
+
+       /* These are hard-coded values */
+       host_res->birq_registers = 0;
+       host_res->birq_attrib = 0;
+       host_res->dw_offset_for_monitor = 0;
+       host_res->dw_chnl_offset = 0;
+       /* CHNL_MAXCHANNELS */
+       host_res->dw_num_chnls = CHNL_MAXCHANNELS;
+       host_res->dw_chnl_buf_size = 0x400;
+
+       return 0;
+}
+
+/*
+ *  ======== drv_request_bridge_res_dsp ========
+ *  Purpose:
+ *      Reserves shared memory for bridge.
+ */
+int drv_request_bridge_res_dsp(void **phost_resources)
+{
+       int status = 0;
+       struct cfg_hostres *host_res;
+       u32 dw_buff_size;
+       u32 dma_addr;
+       u32 shm_size;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       dw_buff_size = sizeof(struct cfg_hostres);
+
+       host_res = kzalloc(dw_buff_size, GFP_KERNEL);
+
+       if (host_res != NULL) {
+               request_bridge_resources(host_res);
+               /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
+               host_res->num_mem_windows = 4;
+
+               host_res->dw_mem_base[0] = 0;
+               host_res->dw_mem_base[2] = (u32) ioremap(OMAP_DSP_MEM1_BASE,
+                                                        OMAP_DSP_MEM1_SIZE);
+               host_res->dw_mem_base[3] = (u32) ioremap(OMAP_DSP_MEM2_BASE,
+                                                        OMAP_DSP_MEM2_SIZE);
+               host_res->dw_mem_base[4] = (u32) ioremap(OMAP_DSP_MEM3_BASE,
+                                                        OMAP_DSP_MEM3_SIZE);
+               host_res->dw_per_base = ioremap(OMAP_PER_CM_BASE,
+                                               OMAP_PER_CM_SIZE);
+               host_res->dw_per_pm_base = (u32) ioremap(OMAP_PER_PRM_BASE,
+                                                        OMAP_PER_PRM_SIZE);
+               host_res->dw_core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE,
+                                                         OMAP_CORE_PRM_SIZE);
+               host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE,
+                                                OMAP_DMMU_SIZE);
+
+               dev_dbg(bridge, "dw_mem_base[0] 0x%x\n",
+                       host_res->dw_mem_base[0]);
+               dev_dbg(bridge, "dw_mem_base[1] 0x%x\n",
+                       host_res->dw_mem_base[1]);
+               dev_dbg(bridge, "dw_mem_base[2] 0x%x\n",
+                       host_res->dw_mem_base[2]);
+               dev_dbg(bridge, "dw_mem_base[3] 0x%x\n",
+                       host_res->dw_mem_base[3]);
+               dev_dbg(bridge, "dw_mem_base[4] 0x%x\n",
+                       host_res->dw_mem_base[4]);
+               dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base);
+
+               shm_size = drv_datap->shm_size;
+               if (shm_size >= 0x10000) {
+                       /* Allocate Physically contiguous,
+                        * non-cacheable  memory */
+                       host_res->dw_mem_base[1] =
+                           (u32) mem_alloc_phys_mem(shm_size, 0x100000,
+                                                    &dma_addr);
+                       if (host_res->dw_mem_base[1] == 0) {
+                               status = -ENOMEM;
+                               pr_err("shm reservation Failed\n");
+                       } else {
+                               host_res->dw_mem_length[1] = shm_size;
+                               host_res->dw_mem_phys[1] = dma_addr;
+
+                               dev_dbg(bridge, "%s: Bridge shm address 0x%x "
+                                       "dma_addr %x size %x\n", __func__,
+                                       host_res->dw_mem_base[1],
+                                       dma_addr, shm_size);
+                       }
+               }
+               if (!status) {
+                       /* These are hard-coded values */
+                       host_res->birq_registers = 0;
+                       host_res->birq_attrib = 0;
+                       host_res->dw_offset_for_monitor = 0;
+                       host_res->dw_chnl_offset = 0;
+                       /* CHNL_MAXCHANNELS */
+                       host_res->dw_num_chnls = CHNL_MAXCHANNELS;
+                       host_res->dw_chnl_buf_size = 0x400;
+                       dw_buff_size = sizeof(struct cfg_hostres);
+               }
+               *phost_resources = host_res;
+       }
+       /* End Mem alloc */
+       return status;
+}
+
+void mem_ext_phys_pool_init(u32 pool_phys_base, u32 pool_size)
+{
+       u32 pool_virt_base;
+
+       /* get the virtual address for the physical memory pool passed */
+       pool_virt_base = (u32) ioremap(pool_phys_base, pool_size);
+
+       if ((void **)pool_virt_base == NULL) {
+               pr_err("%s: external physical memory map failed\n", __func__);
+               ext_phys_mem_pool_enabled = false;
+       } else {
+               ext_mem_pool.phys_mem_base = pool_phys_base;
+               ext_mem_pool.phys_mem_size = pool_size;
+               ext_mem_pool.virt_mem_base = pool_virt_base;
+               ext_mem_pool.next_phys_alloc_ptr = pool_phys_base;
+               ext_phys_mem_pool_enabled = true;
+       }
+}
+
+void mem_ext_phys_pool_release(void)
+{
+       if (ext_phys_mem_pool_enabled) {
+               iounmap((void *)(ext_mem_pool.virt_mem_base));
+               ext_phys_mem_pool_enabled = false;
+       }
+}
+
+/*
+ *  ======== mem_ext_phys_mem_alloc ========
+ *  Purpose:
+ *     Allocate physically contiguous, uncached memory from external memory pool
+ */
+
+static void *mem_ext_phys_mem_alloc(u32 bytes, u32 align, u32 * phys_addr)
+{
+       u32 new_alloc_ptr;
+       u32 offset;
+       u32 virt_addr;
+
+       if (align == 0)
+               align = 1;
+
+       if (bytes > ((ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size)
+                    - ext_mem_pool.next_phys_alloc_ptr)) {
+               phys_addr = NULL;
+               return NULL;
+       } else {
+               offset = (ext_mem_pool.next_phys_alloc_ptr & (align - 1));
+               if (offset == 0)
+                       new_alloc_ptr = ext_mem_pool.next_phys_alloc_ptr;
+               else
+                       new_alloc_ptr = (ext_mem_pool.next_phys_alloc_ptr) +
+                           (align - offset);
+               if ((new_alloc_ptr + bytes) <=
+                   (ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size)) {
+                       /* we can allocate */
+                       *phys_addr = new_alloc_ptr;
+                       ext_mem_pool.next_phys_alloc_ptr =
+                           new_alloc_ptr + bytes;
+                       virt_addr =
+                           ext_mem_pool.virt_mem_base + (new_alloc_ptr -
+                                                         ext_mem_pool.
+                                                         phys_mem_base);
+                       return (void *)virt_addr;
+               } else {
+                       *phys_addr = 0;
+                       return NULL;
+               }
+       }
+}
+
+/*
+ *  ======== mem_alloc_phys_mem ========
+ *  Purpose:
+ *      Allocate physically contiguous, uncached memory
+ */
+void *mem_alloc_phys_mem(u32 byte_size, u32 align_mask,
+                               u32 *physical_address)
+{
+       void *va_mem = NULL;
+       dma_addr_t pa_mem;
+
+       if (byte_size > 0) {
+               if (ext_phys_mem_pool_enabled) {
+                       va_mem = mem_ext_phys_mem_alloc(byte_size, align_mask,
+                                                       (u32 *) &pa_mem);
+               } else
+                       va_mem = dma_alloc_coherent(NULL, byte_size, &pa_mem,
+                                                               GFP_KERNEL);
+               if (va_mem == NULL)
+                       *physical_address = 0;
+               else
+                       *physical_address = pa_mem;
+       }
+       return va_mem;
+}
+
+/*
+ *  ======== mem_free_phys_mem ========
+ *  Purpose:
+ *      Free the given block of physically contiguous memory.
+ */
+void mem_free_phys_mem(void *virtual_address, u32 physical_address,
+                      u32 byte_size)
+{
+       DBC_REQUIRE(virtual_address != NULL);
+
+       if (!ext_phys_mem_pool_enabled)
+               dma_free_coherent(NULL, byte_size, virtual_address,
+                                 physical_address);
+}
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
new file mode 100644 (file)
index 0000000..7ee8949
--- /dev/null
@@ -0,0 +1,656 @@
+/*
+ * drv_interface.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge driver interface.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- Host OS */
+
+#include <dspbridge/host_os.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/cdev.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/services.h>
+#include <dspbridge/clk.h>
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dspapi-ioctl.h>
+#include <dspbridge/dspapi.h>
+#include <dspbridge/dspdrv.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/pwr.h>
+
+/*  ----------------------------------- This */
+#include <drv_interface.h>
+
+#include <dspbridge/cfg.h>
+#include <dspbridge/resourcecleanup.h>
+#include <dspbridge/chnl.h>
+#include <dspbridge/proc.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/drvdefs.h>
+#include <dspbridge/drv.h>
+
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+#include <mach-omap2/omap3-opp.h>
+#endif
+
+#define BRIDGE_NAME "C6410"
+/*  ----------------------------------- Globals */
+#define DRIVER_NAME  "DspBridge"
+#define DSPBRIDGE_VERSION      "0.3"
+s32 dsp_debug;
+
+struct platform_device *omap_dspbridge_dev;
+struct device *bridge;
+
+/* This is a test variable used by Bridge to test different sleep states */
+s32 dsp_test_sleepstate;
+
+static struct cdev bridge_cdev;
+
+static struct class *bridge_class;
+
+static u32 driver_context;
+static s32 driver_major;
+static char *base_img;
+char *iva_img;
+static s32 shm_size = 0x500000;        /* 5 MB */
+static int tc_wordswapon;      /* Default value is always false */
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+#define REC_TIMEOUT 5000       /*recovery timeout in msecs */
+static atomic_t bridge_cref;   /* number of bridge open handles */
+static struct workqueue_struct *bridge_rec_queue;
+static struct work_struct bridge_recovery_work;
+static DECLARE_COMPLETION(bridge_comp);
+static DECLARE_COMPLETION(bridge_open_comp);
+static bool recover;
+#endif
+
+#ifdef CONFIG_PM
+struct omap34_xx_bridge_suspend_data {
+       int suspended;
+       wait_queue_head_t suspend_wq;
+};
+
+static struct omap34_xx_bridge_suspend_data bridge_suspend_data;
+
+static int omap34_xxbridge_suspend_lockout(struct omap34_xx_bridge_suspend_data
+                                          *s, struct file *f)
+{
+       if ((s)->suspended) {
+               if ((f)->f_flags & O_NONBLOCK)
+                       return -EPERM;
+               wait_event_interruptible((s)->suspend_wq, (s)->suspended == 0);
+       }
+       return 0;
+}
+#endif
+
+module_param(dsp_debug, int, 0);
+MODULE_PARM_DESC(dsp_debug, "Wait after loading DSP image. default = false");
+
+module_param(dsp_test_sleepstate, int, 0);
+MODULE_PARM_DESC(dsp_test_sleepstate, "DSP Sleep state = 0");
+
+module_param(base_img, charp, 0);
+MODULE_PARM_DESC(base_img, "DSP base image, default = NULL");
+
+module_param(shm_size, int, 0);
+MODULE_PARM_DESC(shm_size, "shm size, default = 4 MB, minimum = 64 KB");
+
+module_param(tc_wordswapon, int, 0);
+MODULE_PARM_DESC(tc_wordswapon, "TC Word Swap Option. default = 0");
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DSPBRIDGE_VERSION);
+
+static char *driver_name = DRIVER_NAME;
+
+static const struct file_operations bridge_fops = {
+       .open = bridge_open,
+       .release = bridge_release,
+       .unlocked_ioctl = bridge_ioctl,
+       .mmap = bridge_mmap,
+};
+
+#ifdef CONFIG_PM
+static u32 time_out = 1000;
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+s32 dsp_max_opps = VDD1_OPP5;
+#endif
+
+/* Maximum Opps that can be requested by IVA */
+/*vdd1 rate table */
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+const struct omap_opp vdd1_rate_table_bridge[] = {
+       {0, 0, 0},
+       /*OPP1 */
+       {S125M, VDD1_OPP1, 0},
+       /*OPP2 */
+       {S250M, VDD1_OPP2, 0},
+       /*OPP3 */
+       {S500M, VDD1_OPP3, 0},
+       /*OPP4 */
+       {S550M, VDD1_OPP4, 0},
+       /*OPP5 */
+       {S600M, VDD1_OPP5, 0},
+};
+#endif
+#endif
+
+struct dspbridge_platform_data *omap_dspbridge_pdata;
+
+u32 vdd1_dsp_freq[6][4] = {
+       {0, 0, 0, 0},
+       /*OPP1 */
+       {0, 90000, 0, 86000},
+       /*OPP2 */
+       {0, 180000, 80000, 170000},
+       /*OPP3 */
+       {0, 360000, 160000, 340000},
+       /*OPP4 */
+       {0, 396000, 325000, 376000},
+       /*OPP5 */
+       {0, 430000, 355000, 430000},
+};
+
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+static void bridge_recover(struct work_struct *work)
+{
+       struct dev_object *dev;
+       struct cfg_devnode *dev_node;
+       if (atomic_read(&bridge_cref)) {
+               INIT_COMPLETION(bridge_comp);
+               while (!wait_for_completion_timeout(&bridge_comp,
+                                               msecs_to_jiffies(REC_TIMEOUT)))
+                       pr_info("%s:%d handle(s) still opened\n",
+                                       __func__, atomic_read(&bridge_cref));
+       }
+       dev = dev_get_first();
+       dev_get_dev_node(dev, &dev_node);
+       if (!dev_node || proc_auto_start(dev_node, dev))
+               pr_err("DSP could not be restarted\n");
+       recover = false;
+       complete_all(&bridge_open_comp);
+}
+
+void bridge_recover_schedule(void)
+{
+       INIT_COMPLETION(bridge_open_comp);
+       recover = true;
+       queue_work(bridge_rec_queue, &bridge_recovery_work);
+}
+#endif
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+static int dspbridge_scale_notification(struct notifier_block *op,
+               unsigned long val, void *ptr)
+{
+       struct dspbridge_platform_data *pdata =
+                                       omap_dspbridge_dev->dev.platform_data;
+
+       if (CPUFREQ_POSTCHANGE == val && pdata->dsp_get_opp)
+               pwr_pm_post_scale(PRCM_VDD1, pdata->dsp_get_opp());
+
+       return 0;
+}
+
+static struct notifier_block iva_clk_notifier = {
+       .notifier_call = dspbridge_scale_notification,
+       NULL,
+};
+#endif
+
+/**
+ * omap3_bridge_startup() - perform low lever initializations
+ * @pdev:      pointer to platform device
+ *
+ * Initializes recovery, PM and DVFS required data, before calling
+ * clk and memory init routines.
+ */
+static int omap3_bridge_startup(struct platform_device *pdev)
+{
+       struct dspbridge_platform_data *pdata = pdev->dev.platform_data;
+       struct drv_data *drv_datap = NULL;
+       u32 phys_membase, phys_memsize;
+       int err;
+
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+       bridge_rec_queue = create_workqueue("bridge_rec_queue");
+       INIT_WORK(&bridge_recovery_work, bridge_recover);
+       INIT_COMPLETION(bridge_comp);
+#endif
+
+#ifdef CONFIG_PM
+       /* Initialize the wait queue */
+       bridge_suspend_data.suspended = 0;
+       init_waitqueue_head(&bridge_suspend_data.suspend_wq);
+
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       for (i = 0; i < 6; i++)
+               pdata->mpu_speed[i] = vdd1_rate_table_bridge[i].rate;
+
+       err = cpufreq_register_notifier(&iva_clk_notifier,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
+       if (err)
+               pr_err("%s: clk_notifier_register failed for iva2_ck\n",
+                                                               __func__);
+#endif
+#endif
+
+       dsp_clk_init();
+       services_init();
+
+       drv_datap = kzalloc(sizeof(struct drv_data), GFP_KERNEL);
+       if (!drv_datap) {
+               err = -ENOMEM;
+               goto err1;
+       }
+
+       drv_datap->shm_size = shm_size;
+       drv_datap->tc_wordswapon = tc_wordswapon;
+
+       if (base_img) {
+               drv_datap->base_img = kmalloc(strlen(base_img) + 1, GFP_KERNEL);
+               if (!drv_datap->base_img) {
+                       err = -ENOMEM;
+                       goto err2;
+               }
+               strncpy(drv_datap->base_img, base_img, strlen(base_img) + 1);
+       }
+
+       dev_set_drvdata(bridge, drv_datap);
+
+       if (shm_size < 0x10000) {       /* 64 KB */
+               err = -EINVAL;
+               pr_err("%s: shm size must be at least 64 KB\n", __func__);
+               goto err3;
+       }
+       dev_dbg(bridge, "%s: requested shm_size = 0x%x\n", __func__, shm_size);
+
+       phys_membase = pdata->phys_mempool_base;
+       phys_memsize = pdata->phys_mempool_size;
+       if (phys_membase > 0 && phys_memsize > 0)
+               mem_ext_phys_pool_init(phys_membase, phys_memsize);
+
+       if (tc_wordswapon)
+               dev_dbg(bridge, "%s: TC Word Swap is enabled\n", __func__);
+
+       driver_context = dsp_init(&err);
+       if (err) {
+               pr_err("DSP Bridge driver initialization failed\n");
+               goto err4;
+       }
+
+       return 0;
+
+err4:
+       mem_ext_phys_pool_release();
+err3:
+       kfree(drv_datap->base_img);
+err2:
+       kfree(drv_datap);
+err1:
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       cpufreq_unregister_notifier(&iva_clk_notifier,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+       dsp_clk_exit();
+       services_exit();
+
+       return err;
+}
+
+static int __devinit omap34_xx_bridge_probe(struct platform_device *pdev)
+{
+       int err;
+       dev_t dev = 0;
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       int i = 0;
+#endif
+
+       omap_dspbridge_dev = pdev;
+
+       /* Global bridge device */
+       bridge = &omap_dspbridge_dev->dev;
+
+       /* Bridge low level initializations */
+       err = omap3_bridge_startup(pdev);
+       if (err)
+               goto err1;
+
+       /* use 2.6 device model */
+       err = alloc_chrdev_region(&dev, 0, 1, driver_name);
+       if (err) {
+               pr_err("%s: Can't get major %d\n", __func__, driver_major);
+               goto err1;
+       }
+
+       cdev_init(&bridge_cdev, &bridge_fops);
+       bridge_cdev.owner = THIS_MODULE;
+
+       err = cdev_add(&bridge_cdev, dev, 1);
+       if (err) {
+               pr_err("%s: Failed to add bridge device\n", __func__);
+               goto err2;
+       }
+
+       /* udev support */
+       bridge_class = class_create(THIS_MODULE, "ti_bridge");
+       if (IS_ERR(bridge_class)) {
+               pr_err("%s: Error creating bridge class\n", __func__);
+               goto err3;
+       }
+
+       driver_major = MAJOR(dev);
+       device_create(bridge_class, NULL, MKDEV(driver_major, 0),
+                     NULL, "DspBridge");
+       pr_info("DSP Bridge driver loaded\n");
+
+       return 0;
+
+err3:
+       cdev_del(&bridge_cdev);
+err2:
+       unregister_chrdev_region(dev, 1);
+err1:
+       return err;
+}
+
+static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev)
+{
+       dev_t devno;
+       bool ret;
+       int status = 0;
+       void *hdrv_obj = NULL;
+
+       status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
+       if (status)
+               goto func_cont;
+
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
+       if (cpufreq_unregister_notifier(&iva_clk_notifier,
+                                               CPUFREQ_TRANSITION_NOTIFIER))
+               pr_err("%s: cpufreq_unregister_notifier failed for iva2_ck\n",
+                      __func__);
+#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
+
+       if (driver_context) {
+               /* Put the DSP in reset state */
+               ret = dsp_deinit(driver_context);
+               driver_context = 0;
+               DBC_ASSERT(ret == true);
+       }
+
+func_cont:
+       mem_ext_phys_pool_release();
+
+       dsp_clk_exit();
+       services_exit();
+
+       devno = MKDEV(driver_major, 0);
+       cdev_del(&bridge_cdev);
+       unregister_chrdev_region(devno, 1);
+       if (bridge_class) {
+               /* remove the device from sysfs */
+               device_destroy(bridge_class, MKDEV(driver_major, 0));
+               class_destroy(bridge_class);
+
+       }
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int BRIDGE_SUSPEND(struct platform_device *pdev, pm_message_t state)
+{
+       u32 status;
+       u32 command = PWR_EMERGENCYDEEPSLEEP;
+
+       status = pwr_sleep_dsp(command, time_out);
+       if (status)
+               return -1;
+
+       bridge_suspend_data.suspended = 1;
+       return 0;
+}
+
+static int BRIDGE_RESUME(struct platform_device *pdev)
+{
+       u32 status;
+
+       status = pwr_wake_dsp(time_out);
+       if (status)
+               return -1;
+
+       bridge_suspend_data.suspended = 0;
+       wake_up(&bridge_suspend_data.suspend_wq);
+       return 0;
+}
+#else
+#define BRIDGE_SUSPEND NULL
+#define BRIDGE_RESUME NULL
+#endif
+
+static struct platform_driver bridge_driver = {
+       .driver = {
+                  .name = BRIDGE_NAME,
+                  },
+       .probe = omap34_xx_bridge_probe,
+       .remove = __devexit_p(omap34_xx_bridge_remove),
+       .suspend = BRIDGE_SUSPEND,
+       .resume = BRIDGE_RESUME,
+};
+
+static int __init bridge_init(void)
+{
+       return platform_driver_register(&bridge_driver);
+}
+
+static void __exit bridge_exit(void)
+{
+       platform_driver_unregister(&bridge_driver);
+}
+
+/*
+ * This function is called when an application opens handle to the
+ * bridge driver.
+ */
+static int bridge_open(struct inode *ip, struct file *filp)
+{
+       int status = 0;
+       struct process_context *pr_ctxt = NULL;
+
+       /*
+        * Allocate a new process context and insert it into global
+        * process context list.
+        */
+
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+       if (recover) {
+               if (filp->f_flags & O_NONBLOCK ||
+                       wait_for_completion_interruptible(&bridge_open_comp))
+                       return -EBUSY;
+       }
+#endif
+       pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
+       if (pr_ctxt) {
+               pr_ctxt->res_state = PROC_RES_ALLOCATED;
+               spin_lock_init(&pr_ctxt->dmm_map_lock);
+               INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
+               spin_lock_init(&pr_ctxt->dmm_rsv_lock);
+               INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
+
+               pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+               if (pr_ctxt->node_id) {
+                       idr_init(pr_ctxt->node_id);
+               } else {
+                       status = -ENOMEM;
+                       goto err;
+               }
+
+               pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+               if (pr_ctxt->stream_id)
+                       idr_init(pr_ctxt->stream_id);
+               else
+                       status = -ENOMEM;
+       } else {
+               status = -ENOMEM;
+       }
+err:
+       filp->private_data = pr_ctxt;
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+       if (!status)
+               atomic_inc(&bridge_cref);
+#endif
+       return status;
+}
+
+/*
+ * This function is called when an application closes handle to the bridge
+ * driver.
+ */
+static int bridge_release(struct inode *ip, struct file *filp)
+{
+       int status = 0;
+       struct process_context *pr_ctxt;
+
+       if (!filp->private_data) {
+               status = -EIO;
+               goto err;
+       }
+
+       pr_ctxt = filp->private_data;
+       flush_signals(current);
+       drv_remove_all_resources(pr_ctxt);
+       proc_detach(pr_ctxt);
+       kfree(pr_ctxt);
+
+       filp->private_data = NULL;
+
+err:
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+       if (!atomic_dec_return(&bridge_cref))
+               complete(&bridge_comp);
+#endif
+       return status;
+}
+
+/* This function provides IO interface to the bridge driver. */
+static long bridge_ioctl(struct file *filp, unsigned int code,
+                        unsigned long args)
+{
+       int status;
+       u32 retval = 0;
+       union trapped_args buf_in;
+
+       DBC_REQUIRE(filp != NULL);
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+       if (recover) {
+               status = -EIO;
+               goto err;
+       }
+#endif
+#ifdef CONFIG_PM
+       status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp);
+       if (status != 0)
+               return status;
+#endif
+
+       if (!filp->private_data) {
+               status = -EIO;
+               goto err;
+       }
+
+       status = copy_from_user(&buf_in, (union trapped_args *)args,
+                               sizeof(union trapped_args));
+
+       if (!status) {
+               status = api_call_dev_ioctl(code, &buf_in, &retval,
+                                            filp->private_data);
+
+               if (!status) {
+                       status = retval;
+               } else {
+                       dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x "
+                               "status 0x%x\n", __func__, code, status);
+                       status = -1;
+               }
+
+       }
+
+err:
+       return status;
+}
+
+/* This function maps kernel space memory to user space memory. */
+static int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       u32 offset = vma->vm_pgoff << PAGE_SHIFT;
+       u32 status;
+
+       DBC_ASSERT(vma->vm_start < vma->vm_end);
+
+       vma->vm_flags |= VM_RESERVED | VM_IO;
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       dev_dbg(bridge, "%s: vm filp %p offset %x start %lx end %lx page_prot "
+               "%lx flags %lx\n", __func__, filp, offset,
+               vma->vm_start, vma->vm_end, vma->vm_page_prot, vma->vm_flags);
+
+       status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+                                vma->vm_end - vma->vm_start,
+                                vma->vm_page_prot);
+       if (status != 0)
+               status = -EAGAIN;
+
+       return status;
+}
+
+/* To remove all process resources before removing the process from the
+ * process context list */
+int drv_remove_all_resources(void *process_ctxt)
+{
+       int status = 0;
+       struct process_context *ctxt = (struct process_context *)process_ctxt;
+       drv_remove_all_strm_res_elements(ctxt);
+       drv_remove_all_node_res_elements(ctxt);
+       drv_remove_all_dmm_res_elements(ctxt);
+       ctxt->res_state = PROC_RES_FREED;
+       return status;
+}
+
+/* Bridge driver initialization and de-initialization functions */
+module_init(bridge_init);
+module_exit(bridge_exit);
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.h b/drivers/staging/tidspbridge/rmgr/drv_interface.h
new file mode 100644 (file)
index 0000000..ab07060
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * drv_interface.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef        _DRV_INTERFACE_H_
+#define _DRV_INTERFACE_H_
+
+/* Prototypes for all functions in this bridge */
+static int __init bridge_init(void);   /* Initialize bridge */
+static void __exit bridge_exit(void);  /* Opposite of initialize */
+static int bridge_open(struct inode *ip, struct file *filp);   /* Open */
+static int bridge_release(struct inode *ip, struct file *filp);        /* Release */
+static long bridge_ioctl(struct file *filp, unsigned int code,
+                               unsigned long args);
+static int bridge_mmap(struct file *filp, struct vm_area_struct *vma);
+#endif /* ifndef _DRV_INTERFACE_H_ */
diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c
new file mode 100644 (file)
index 0000000..714f348
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * dspdrv.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Interface to allocate and free bridge resources.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <linux/types.h>
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/drv.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/dspapi.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/mgr.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/dspdrv.h>
+
+/*
+ *  ======== dsp_init ========
+ *     Allocates bridge resources. Loads a base image onto DSP, if specified.
+ */
+u32 dsp_init(u32 *init_status)
+{
+       char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510";
+       int status = -EPERM;
+       struct drv_object *drv_obj = NULL;
+       u32 device_node;
+       u32 device_node_string;
+
+       if (!api_init())
+               goto func_cont;
+
+       status = drv_create(&drv_obj);
+       if (status) {
+               api_exit();
+               goto func_cont;
+       }
+
+       /* End drv_create */
+       /* Request Resources */
+       status = drv_request_resources((u32) &dev_node, &device_node_string);
+       if (!status) {
+               /* Attempt to Start the Device */
+               status = dev_start_device((struct cfg_devnode *)
+                                         device_node_string);
+               if (status)
+                       (void)drv_release_resources
+                           ((u32) device_node_string, drv_obj);
+       } else {
+               dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__);
+               status = -EPERM;
+       }
+
+       /* Unwind whatever was loaded */
+       if (status) {
+               /* irrespective of the status of dev_remove_device we conitinue
+                * unloading. Get the Driver Object iterate through and remove.
+                * Reset the status to E_FAIL to avoid going through
+                * api_init_complete2. */
+               for (device_node = drv_get_first_dev_extension();
+                    device_node != 0;
+                    device_node = drv_get_next_dev_extension(device_node)) {
+                       (void)dev_remove_device((struct cfg_devnode *)
+                                               device_node);
+                       (void)drv_release_resources((u32) device_node, drv_obj);
+               }
+               /* Remove the Driver Object */
+               (void)drv_destroy(drv_obj);
+               drv_obj = NULL;
+               api_exit();
+               dev_dbg(bridge, "%s: Logical device failed init\n", __func__);
+       }                       /* Unwinding the loaded drivers */
+func_cont:
+       /* Attempt to Start the Board */
+       if (!status) {
+               /* BRD_AutoStart could fail if the dsp execuetable is not the
+                * correct one. We should not propagate that error
+                * into the device loader. */
+               (void)api_init_complete2();
+       } else {
+               dev_dbg(bridge, "%s: Failed\n", __func__);
+       }                       /* End api_init_complete2 */
+       DBC_ENSURE((!status && drv_obj != NULL) ||
+                  (status && drv_obj == NULL));
+       *init_status = status;
+       /* Return the Driver Object */
+       return (u32) drv_obj;
+}
+
+/*
+ *  ======== dsp_deinit ========
+ *     Frees the resources allocated for bridge.
+ */
+bool dsp_deinit(u32 device_context)
+{
+       bool ret = true;
+       u32 device_node;
+       struct mgr_object *mgr_obj = NULL;
+
+       while ((device_node = drv_get_first_dev_extension()) != 0) {
+               (void)dev_remove_device((struct cfg_devnode *)device_node);
+
+               (void)drv_release_resources((u32) device_node,
+                                       (struct drv_object *)device_context);
+       }
+
+       (void)drv_destroy((struct drv_object *)device_context);
+
+       /* Get the Manager Object from Registry
+        * MGR Destroy will unload the DCD dll */
+       if (!cfg_get_object((u32 *) &mgr_obj, REG_MGR_OBJECT))
+               (void)mgr_destroy(mgr_obj);
+
+       api_exit();
+
+       return ret;
+}
diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c
new file mode 100644 (file)
index 0000000..57a39b9
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * mgr.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implementation of Manager interface to the device object at the
+ * driver level. This queries the NDB data base and retrieves the
+ * data about Node and Processor.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/dbdcd.h>
+#include <dspbridge/drv.h>
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/mgr.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define ZLDLLNAME               ""
+
+struct mgr_object {
+       struct dcd_manager *hdcd_mgr;   /* Proc/Node data manager */
+};
+
+/*  ----------------------------------- Globals */
+static u32 refs;
+
+/*
+ *  ========= mgr_create =========
+ *  Purpose:
+ *      MGR Object gets created only once during driver Loading.
+ */
+int mgr_create(struct mgr_object **mgr_obj,
+                     struct cfg_devnode *dev_node_obj)
+{
+       int status = 0;
+       struct mgr_object *pmgr_obj = NULL;
+
+       DBC_REQUIRE(mgr_obj != NULL);
+       DBC_REQUIRE(refs > 0);
+
+       pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL);
+       if (pmgr_obj) {
+               status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->hdcd_mgr);
+               if (!status) {
+                       /* If succeeded store the handle in the MGR Object */
+                       status = cfg_set_object((u32) pmgr_obj, REG_MGR_OBJECT);
+                       if (!status) {
+                               *mgr_obj = pmgr_obj;
+                       } else {
+                               dcd_destroy_manager(pmgr_obj->hdcd_mgr);
+                               kfree(pmgr_obj);
+                       }
+               } else {
+                       /* failed to Create DCD Manager */
+                       kfree(pmgr_obj);
+               }
+       } else {
+               status = -ENOMEM;
+       }
+
+       DBC_ENSURE(status || pmgr_obj);
+       return status;
+}
+
+/*
+ *  ========= mgr_destroy =========
+ *     This function is invoked during bridge driver unloading.Frees MGR object.
+ */
+int mgr_destroy(struct mgr_object *hmgr_obj)
+{
+       int status = 0;
+       struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hmgr_obj);
+
+       /* Free resources */
+       if (hmgr_obj->hdcd_mgr)
+               dcd_destroy_manager(hmgr_obj->hdcd_mgr);
+
+       kfree(pmgr_obj);
+       /* Update the Registry with NULL for MGR Object */
+       (void)cfg_set_object(0, REG_MGR_OBJECT);
+
+       return status;
+}
+
+/*
+ *  ======== mgr_enum_node_info ========
+ *      Enumerate and get configuration information about nodes configured
+ *      in the node database.
+ */
+int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
+                             u32 undb_props_size, u32 *pu_num_nodes)
+{
+       int status = 0;
+       struct dsp_uuid node_uuid, temp_uuid;
+       u32 temp_index = 0;
+       u32 node_index = 0;
+       struct dcd_genericobj gen_obj;
+       struct mgr_object *pmgr_obj = NULL;
+
+       DBC_REQUIRE(pndb_props != NULL);
+       DBC_REQUIRE(pu_num_nodes != NULL);
+       DBC_REQUIRE(undb_props_size >= sizeof(struct dsp_ndbprops));
+       DBC_REQUIRE(refs > 0);
+
+       *pu_num_nodes = 0;
+       /* Get The Manager Object from the Registry */
+       status = cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT);
+       if (status)
+               goto func_cont;
+
+       DBC_ASSERT(pmgr_obj);
+       /* Forever loop till we hit failed or no more items in the
+        * Enumeration. We will exit the loop other than 0; */
+       while (status == 0) {
+               status = dcd_enumerate_object(temp_index++, DSP_DCDNODETYPE,
+                                             &temp_uuid);
+               if (status == 0) {
+                       node_index++;
+                       if (node_id == (node_index - 1))
+                               node_uuid = temp_uuid;
+
+               }
+       }
+       if (!status) {
+               if (node_id > (node_index - 1)) {
+                       status = -EINVAL;
+               } else {
+                       status = dcd_get_object_def(pmgr_obj->hdcd_mgr,
+                                                   (struct dsp_uuid *)
+                                                   &node_uuid, DSP_DCDNODETYPE,
+                                                   &gen_obj);
+                       if (!status) {
+                               /* Get the Obj def */
+                               *pndb_props =
+                                   gen_obj.obj_data.node_obj.ndb_props;
+                               *pu_num_nodes = node_index;
+                       }
+               }
+       }
+
+func_cont:
+       DBC_ENSURE((!status && *pu_num_nodes > 0) ||
+                  (status && *pu_num_nodes == 0));
+
+       return status;
+}
+
+/*
+ *  ======== mgr_enum_processor_info ========
+ *      Enumerate and get configuration information about available
+ *      DSP processors.
+ */
+int mgr_enum_processor_info(u32 processor_id,
+                                  struct dsp_processorinfo *
+                                  processor_info, u32 processor_info_size,
+                                  u8 *pu_num_procs)
+{
+       int status = 0;
+       int status1 = 0;
+       int status2 = 0;
+       struct dsp_uuid temp_uuid;
+       u32 temp_index = 0;
+       u32 proc_index = 0;
+       struct dcd_genericobj gen_obj;
+       struct mgr_object *pmgr_obj = NULL;
+       struct mgr_processorextinfo *ext_info;
+       struct dev_object *hdev_obj;
+       struct drv_object *hdrv_obj;
+       u8 dev_type;
+       struct cfg_devnode *dev_node;
+       bool proc_detect = false;
+
+       DBC_REQUIRE(processor_info != NULL);
+       DBC_REQUIRE(pu_num_procs != NULL);
+       DBC_REQUIRE(processor_info_size >= sizeof(struct dsp_processorinfo));
+       DBC_REQUIRE(refs > 0);
+
+       *pu_num_procs = 0;
+       status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
+       if (!status) {
+               status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
+               if (!status) {
+                       status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
+                       status = dev_get_dev_node(hdev_obj, &dev_node);
+                       if (dev_type != DSP_UNIT)
+                               status = -EPERM;
+
+                       if (!status)
+                               processor_info->processor_type = DSPTYPE64;
+               }
+       }
+       if (status)
+               goto func_end;
+
+       /* Get The Manager Object from the Registry */
+       if (cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT)) {
+               dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
+               goto func_end;
+       }
+       DBC_ASSERT(pmgr_obj);
+       /* Forever loop till we hit no more items in the
+        * Enumeration. We will exit the loop other than 0; */
+       while (status1 == 0) {
+               status1 = dcd_enumerate_object(temp_index++,
+                                              DSP_DCDPROCESSORTYPE,
+                                              &temp_uuid);
+               if (status1 != 0)
+                       break;
+
+               proc_index++;
+               /* Get the Object properties to find the Device/Processor
+                * Type */
+               if (proc_detect != false)
+                       continue;
+
+               status2 = dcd_get_object_def(pmgr_obj->hdcd_mgr,
+                                            (struct dsp_uuid *)&temp_uuid,
+                                            DSP_DCDPROCESSORTYPE, &gen_obj);
+               if (!status2) {
+                       /* Get the Obj def */
+                       if (processor_info_size <
+                           sizeof(struct mgr_processorextinfo)) {
+                               *processor_info = gen_obj.obj_data.proc_info;
+                       } else {
+                               /* extended info */
+                               ext_info = (struct mgr_processorextinfo *)
+                                   processor_info;
+                               *ext_info = gen_obj.obj_data.ext_proc_obj;
+                       }
+                       dev_dbg(bridge, "%s: Got proctype  from DCD %x\n",
+                               __func__, processor_info->processor_type);
+                       /* See if we got the needed processor */
+                       if (dev_type == DSP_UNIT) {
+                               if (processor_info->processor_type ==
+                                   DSPPROCTYPE_C64)
+                                       proc_detect = true;
+                       } else if (dev_type == IVA_UNIT) {
+                               if (processor_info->processor_type ==
+                                   IVAPROCTYPE_ARM7)
+                                       proc_detect = true;
+                       }
+                       /* User applciatiuons aonly check for chip type, so
+                        * this clumsy overwrite */
+                       processor_info->processor_type = DSPTYPE64;
+               } else {
+                       dev_dbg(bridge, "%s: Failed to get DCD processor info "
+                               "%x\n", __func__, status2);
+                       status = -EPERM;
+               }
+       }
+       *pu_num_procs = proc_index;
+       if (proc_detect == false) {
+               dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use "
+                       "CFG registry\n", __func__);
+               processor_info->processor_type = DSPTYPE64;
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== mgr_exit ========
+ *      Decrement reference count, and free resources when reference count is
+ *      0.
+ */
+void mgr_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+       refs--;
+       if (refs == 0)
+               dcd_exit();
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== mgr_get_dcd_handle ========
+ *      Retrieves the MGR handle. Accessor Function.
+ */
+int mgr_get_dcd_handle(struct mgr_object *mgr_handle,
+                             u32 *dcd_handle)
+{
+       int status = -EPERM;
+       struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dcd_handle != NULL);
+
+       *dcd_handle = (u32) NULL;
+       if (pmgr_obj) {
+               *dcd_handle = (u32) pmgr_obj->hdcd_mgr;
+               status = 0;
+       }
+       DBC_ENSURE((!status && *dcd_handle != (u32) NULL) ||
+                  (status && *dcd_handle == (u32) NULL));
+
+       return status;
+}
+
+/*
+ *  ======== mgr_init ========
+ *      Initialize MGR's private state, keeping a reference count on each call.
+ */
+bool mgr_init(void)
+{
+       bool ret = true;
+       bool init_dcd = false;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (refs == 0) {
+               init_dcd = dcd_init();  /*  DCD Module */
+
+               if (!init_dcd)
+                       ret = false;
+       }
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
+
+/*
+ *  ======== mgr_wait_for_bridge_events ========
+ *      Block on any Bridge event(s)
+ */
+int mgr_wait_for_bridge_events(struct dsp_notification **anotifications,
+                                     u32 count, u32 *pu_index,
+                                     u32 utimeout)
+{
+       int status;
+       struct sync_object *sync_events[MAX_EVENTS];
+       u32 i;
+
+       DBC_REQUIRE(count < MAX_EVENTS);
+
+       for (i = 0; i < count; i++)
+               sync_events[i] = anotifications[i]->handle;
+
+       status = sync_wait_on_multiple_events(sync_events, count, utimeout,
+                                             pu_index);
+
+       return status;
+
+}
diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c
new file mode 100644 (file)
index 0000000..d8f4eeb
--- /dev/null
@@ -0,0 +1,1974 @@
+/*
+ * nldr.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge dynamic + overlay Node loader.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+#include <dspbridge/host_os.h>
+
+#include <dspbridge/dbdefs.h>
+
+#include <dspbridge/dbc.h>
+
+/* Platform manager */
+#include <dspbridge/cod.h>
+#include <dspbridge/dev.h>
+
+/* Resource manager */
+#include <dspbridge/dbll.h>
+#include <dspbridge/dbdcd.h>
+#include <dspbridge/rmm.h>
+#include <dspbridge/uuidutil.h>
+
+#include <dspbridge/nldr.h>
+#include <linux/gcd.h>
+
+/* Name of section containing dynamic load mem */
+#define DYNMEMSECT  ".dspbridge_mem"
+
+/* Name of section containing dependent library information */
+#define DEPLIBSECT  ".dspbridge_deplibs"
+
+/* Max depth of recursion for loading node's dependent libraries */
+#define MAXDEPTH           5
+
+/* Max number of persistent libraries kept by a node */
+#define MAXLIBS         5
+
+/*
+ *  Defines for extracting packed dynamic load memory requirements from two
+ *  masks.
+ *  These defines must match node.cdb and dynm.cdb
+ *  Format of data/code mask is:
+ *   uuuuuuuu|fueeeeee|fudddddd|fucccccc|
+ *  where
+ *      u = unused
+ *      cccccc = prefered/required dynamic mem segid for create phase data/code
+ *      dddddd = prefered/required dynamic mem segid for delete phase data/code
+ *      eeeeee = prefered/req. dynamic mem segid for execute phase data/code
+ *      f = flag indicating if memory is preferred or required:
+ *       f = 1 if required, f = 0 if preferred.
+ *
+ *  The 6 bits of the segid are interpreted as follows:
+ *
+ *  If the 6th bit (bit 5) is not set, then this specifies a memory segment
+ *  between 0 and 31 (a maximum of 32 dynamic loading memory segments).
+ *  If the 6th bit (bit 5) is set, segid has the following interpretation:
+ *      segid = 32 - Any internal memory segment can be used.
+ *      segid = 33 - Any external memory segment can be used.
+ *      segid = 63 - Any memory segment can be used (in this case the
+ *                required/preferred flag is irrelevant).
+ *
+ */
+/* Maximum allowed dynamic loading memory segments */
+#define MAXMEMSEGS      32
+
+#define MAXSEGID       3       /* Largest possible (real) segid */
+#define MEMINTERNALID   32     /* Segid meaning use internal mem */
+#define MEMEXTERNALID   33     /* Segid meaning use external mem */
+#define NULLID   63            /* Segid meaning no memory req/pref */
+#define FLAGBIT         7              /* 7th bit is pref./req. flag */
+#define SEGMASK         0x3f           /* Bits 0 - 5 */
+
+#define CREATEBIT      0       /* Create segid starts at bit 0 */
+#define DELETEBIT      8       /* Delete segid starts at bit 8 */
+#define EXECUTEBIT      16     /* Execute segid starts at bit 16 */
+
+/*
+ *  Masks that define memory type.  Must match defines in dynm.cdb.
+ */
+#define DYNM_CODE      0x2
+#define DYNM_DATA      0x4
+#define DYNM_CODEDATA   (DYNM_CODE | DYNM_DATA)
+#define DYNM_INTERNAL   0x8
+#define DYNM_EXTERNAL   0x10
+
+/*
+ *  Defines for packing memory requirement/preference flags for code and
+ *  data of each of the node's phases into one mask.
+ *  The bit is set if the segid is required for loading code/data of the
+ *  given phase. The bit is not set, if the segid is preferred only.
+ *
+ *  These defines are also used as indeces into a segid array for the node.
+ *  eg node's segid[CREATEDATAFLAGBIT] is the memory segment id that the
+ *  create phase data is required or preferred to be loaded into.
+ */
+#define CREATEDATAFLAGBIT   0
+#define CREATECODEFLAGBIT   1
+#define EXECUTEDATAFLAGBIT  2
+#define EXECUTECODEFLAGBIT  3
+#define DELETEDATAFLAGBIT   4
+#define DELETECODEFLAGBIT   5
+#define MAXFLAGS           6
+
+    /*
+     *  These names may be embedded in overlay sections to identify which
+     *  node phase the section should be overlayed.
+ */
+#define PCREATE         "create"
+#define PDELETE         "delete"
+#define PEXECUTE       "execute"
+
+static inline bool is_equal_uuid(struct dsp_uuid *uuid1,
+                                                       struct dsp_uuid *uuid2)
+{
+       return !memcmp(uuid1, uuid2, sizeof(struct dsp_uuid));
+}
+
+    /*
+     *  ======== mem_seg_info ========
+     *  Format of dynamic loading memory segment info in coff file.
+     *  Must match dynm.h55.
+ */
+struct mem_seg_info {
+       u32 segid;              /* Dynamic loading memory segment number */
+       u32 base;
+       u32 len;
+       u32 type;               /* Mask of DYNM_CODE, DYNM_INTERNAL, etc. */
+};
+
+/*
+ *  ======== lib_node ========
+ *  For maintaining a tree of library dependencies.
+ */
+struct lib_node {
+       struct dbll_library_obj *lib;   /* The library */
+       u16 dep_libs;           /* Number of dependent libraries */
+       struct lib_node *dep_libs_tree; /* Dependent libraries of lib */
+};
+
+/*
+ *  ======== ovly_sect ========
+ *  Information needed to overlay a section.
+ */
+struct ovly_sect {
+       struct ovly_sect *next_sect;
+       u32 sect_load_addr;     /* Load address of section */
+       u32 sect_run_addr;      /* Run address of section */
+       u32 size;               /* Size of section */
+       u16 page;               /* DBL_CODE, DBL_DATA */
+};
+
+/*
+ *  ======== ovly_node ========
+ *  For maintaining a list of overlay nodes, with sections that need to be
+ *  overlayed for each of the nodes phases.
+ */
+struct ovly_node {
+       struct dsp_uuid uuid;
+       char *node_name;
+       struct ovly_sect *create_sects_list;
+       struct ovly_sect *delete_sects_list;
+       struct ovly_sect *execute_sects_list;
+       struct ovly_sect *other_sects_list;
+       u16 create_sects;
+       u16 delete_sects;
+       u16 execute_sects;
+       u16 other_sects;
+       u16 create_ref;
+       u16 delete_ref;
+       u16 execute_ref;
+       u16 other_ref;
+};
+
+/*
+ *  ======== nldr_object ========
+ *  Overlay loader object.
+ */
+struct nldr_object {
+       struct dev_object *hdev_obj;    /* Device object */
+       struct dcd_manager *hdcd_mgr;   /* Proc/Node data manager */
+       struct dbll_tar_obj *dbll;      /* The DBL loader */
+       struct dbll_library_obj *base_lib;      /* Base image library */
+       struct rmm_target_obj *rmm;     /* Remote memory manager for DSP */
+       struct dbll_fxns ldr_fxns;      /* Loader function table */
+       struct dbll_attrs ldr_attrs;    /* attrs to pass to loader functions */
+       nldr_ovlyfxn ovly_fxn;  /* "write" for overlay nodes */
+       nldr_writefxn write_fxn;        /* "write" for dynamic nodes */
+       struct ovly_node *ovly_table;   /* Table of overlay nodes */
+       u16 ovly_nodes;         /* Number of overlay nodes in base */
+       u16 ovly_nid;           /* Index for tracking overlay nodes */
+       u16 dload_segs;         /* Number of dynamic load mem segs */
+       u32 *seg_table;         /* memtypes of dynamic memory segs
+                                * indexed by segid
+                                */
+       u16 us_dsp_mau_size;    /* Size of DSP MAU */
+       u16 us_dsp_word_size;   /* Size of DSP word */
+};
+
+/*
+ *  ======== nldr_nodeobject ========
+ *  Dynamic node object. This object is created when a node is allocated.
+ */
+struct nldr_nodeobject {
+       struct nldr_object *nldr_obj;   /* Dynamic loader handle */
+       void *priv_ref;         /* Handle to pass to dbl_write_fxn */
+       struct dsp_uuid uuid;   /* Node's UUID */
+       bool dynamic;           /* Dynamically loaded node? */
+       bool overlay;           /* Overlay node? */
+       bool *pf_phase_split;   /* Multiple phase libraries? */
+       struct lib_node root;   /* Library containing node phase */
+       struct lib_node create_lib;     /* Library with create phase lib */
+       struct lib_node execute_lib;    /* Library with execute phase lib */
+       struct lib_node delete_lib;     /* Library with delete phase lib */
+       /* libs remain loaded until Delete */
+       struct lib_node pers_lib_table[MAXLIBS];
+       s32 pers_libs;          /* Number of persistent libraries */
+       /* Path in lib dependency tree */
+       struct dbll_library_obj *lib_path[MAXDEPTH + 1];
+       enum nldr_phase phase;  /* Node phase currently being loaded */
+
+       /*
+        *  Dynamic loading memory segments for data and code of each phase.
+        */
+       u16 seg_id[MAXFLAGS];
+
+       /*
+        *  Mask indicating whether each mem segment specified in seg_id[]
+        *  is preferred or required.
+        *  For example
+        *      if (code_data_flag_mask & (1 << EXECUTEDATAFLAGBIT)) != 0,
+        *  then it is required to load execute phase data into the memory
+        *  specified by seg_id[EXECUTEDATAFLAGBIT].
+        */
+       u32 code_data_flag_mask;
+};
+
+/* Dynamic loader function table */
+static struct dbll_fxns ldr_fxns = {
+       (dbll_close_fxn) dbll_close,
+       (dbll_create_fxn) dbll_create,
+       (dbll_delete_fxn) dbll_delete,
+       (dbll_exit_fxn) dbll_exit,
+       (dbll_get_attrs_fxn) dbll_get_attrs,
+       (dbll_get_addr_fxn) dbll_get_addr,
+       (dbll_get_c_addr_fxn) dbll_get_c_addr,
+       (dbll_get_sect_fxn) dbll_get_sect,
+       (dbll_init_fxn) dbll_init,
+       (dbll_load_fxn) dbll_load,
+       (dbll_load_sect_fxn) dbll_load_sect,
+       (dbll_open_fxn) dbll_open,
+       (dbll_read_sect_fxn) dbll_read_sect,
+       (dbll_set_attrs_fxn) dbll_set_attrs,
+       (dbll_unload_fxn) dbll_unload,
+       (dbll_unload_sect_fxn) dbll_unload_sect,
+};
+
+static u32 refs;               /* module reference count */
+
+static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info,
+                               u32 addr, u32 bytes);
+static int add_ovly_node(struct dsp_uuid *uuid_obj,
+                               enum dsp_dcdobjtype obj_type, void *handle);
+static int add_ovly_sect(struct nldr_object *nldr_obj,
+                               struct ovly_sect **lst,
+                               struct dbll_sect_info *sect_inf,
+                               bool *exists, u32 addr, u32 bytes);
+static s32 fake_ovly_write(void *handle, u32 dsp_address, void *buf, u32 bytes,
+                          s32 mtype);
+static void free_sects(struct nldr_object *nldr_obj,
+                      struct ovly_sect *phase_sects, u16 alloc_num);
+static bool get_symbol_value(void *handle, void *parg, void *rmm_handle,
+                            char *sym_name, struct dbll_sym_val **sym);
+static int load_lib(struct nldr_nodeobject *nldr_node_obj,
+                          struct lib_node *root, struct dsp_uuid uuid,
+                          bool root_prstnt,
+                          struct dbll_library_obj **lib_path,
+                          enum nldr_phase phase, u16 depth);
+static int load_ovly(struct nldr_nodeobject *nldr_node_obj,
+                           enum nldr_phase phase);
+static int remote_alloc(void **ref, u16 mem_sect, u32 size,
+                              u32 align, u32 *dsp_address,
+                              s32 segmnt_id,
+                              s32 req, bool reserve);
+static int remote_free(void **ref, u16 space, u32 dsp_address, u32 size,
+                             bool reserve);
+
+static void unload_lib(struct nldr_nodeobject *nldr_node_obj,
+                      struct lib_node *root);
+static void unload_ovly(struct nldr_nodeobject *nldr_node_obj,
+                       enum nldr_phase phase);
+static bool find_in_persistent_lib_array(struct nldr_nodeobject *nldr_node_obj,
+                                        struct dbll_library_obj *lib);
+static u32 find_lcm(u32 a, u32 b);
+
+/*
+ *  ======== nldr_allocate ========
+ */
+int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref,
+                        const struct dcd_nodeprops *node_props,
+                        struct nldr_nodeobject **nldr_nodeobj,
+                        bool *pf_phase_split)
+{
+       struct nldr_nodeobject *nldr_node_obj = NULL;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(node_props != NULL);
+       DBC_REQUIRE(nldr_nodeobj != NULL);
+       DBC_REQUIRE(nldr_obj);
+
+       /* Initialize handle in case of failure */
+       *nldr_nodeobj = NULL;
+       /* Allocate node object */
+       nldr_node_obj = kzalloc(sizeof(struct nldr_nodeobject), GFP_KERNEL);
+
+       if (nldr_node_obj == NULL) {
+               status = -ENOMEM;
+       } else {
+               nldr_node_obj->pf_phase_split = pf_phase_split;
+               nldr_node_obj->pers_libs = 0;
+               nldr_node_obj->nldr_obj = nldr_obj;
+               nldr_node_obj->priv_ref = priv_ref;
+               /* Save node's UUID. */
+               nldr_node_obj->uuid = node_props->ndb_props.ui_node_id;
+               /*
+                *  Determine if node is a dynamically loaded node from
+                *  ndb_props.
+                */
+               if (node_props->us_load_type == NLDR_DYNAMICLOAD) {
+                       /* Dynamic node */
+                       nldr_node_obj->dynamic = true;
+                       /*
+                        *  Extract memory requirements from ndb_props masks
+                        */
+                       /* Create phase */
+                       nldr_node_obj->seg_id[CREATEDATAFLAGBIT] = (u16)
+                           (node_props->ul_data_mem_seg_mask >> CREATEBIT) &
+                           SEGMASK;
+                       nldr_node_obj->code_data_flag_mask |=
+                           ((node_props->ul_data_mem_seg_mask >>
+                             (CREATEBIT + FLAGBIT)) & 1) << CREATEDATAFLAGBIT;
+                       nldr_node_obj->seg_id[CREATECODEFLAGBIT] = (u16)
+                           (node_props->ul_code_mem_seg_mask >>
+                            CREATEBIT) & SEGMASK;
+                       nldr_node_obj->code_data_flag_mask |=
+                           ((node_props->ul_code_mem_seg_mask >>
+                             (CREATEBIT + FLAGBIT)) & 1) << CREATECODEFLAGBIT;
+                       /* Execute phase */
+                       nldr_node_obj->seg_id[EXECUTEDATAFLAGBIT] = (u16)
+                           (node_props->ul_data_mem_seg_mask >>
+                            EXECUTEBIT) & SEGMASK;
+                       nldr_node_obj->code_data_flag_mask |=
+                           ((node_props->ul_data_mem_seg_mask >>
+                             (EXECUTEBIT + FLAGBIT)) & 1) <<
+                           EXECUTEDATAFLAGBIT;
+                       nldr_node_obj->seg_id[EXECUTECODEFLAGBIT] = (u16)
+                           (node_props->ul_code_mem_seg_mask >>
+                            EXECUTEBIT) & SEGMASK;
+                       nldr_node_obj->code_data_flag_mask |=
+                           ((node_props->ul_code_mem_seg_mask >>
+                             (EXECUTEBIT + FLAGBIT)) & 1) <<
+                           EXECUTECODEFLAGBIT;
+                       /* Delete phase */
+                       nldr_node_obj->seg_id[DELETEDATAFLAGBIT] = (u16)
+                           (node_props->ul_data_mem_seg_mask >> DELETEBIT) &
+                           SEGMASK;
+                       nldr_node_obj->code_data_flag_mask |=
+                           ((node_props->ul_data_mem_seg_mask >>
+                             (DELETEBIT + FLAGBIT)) & 1) << DELETEDATAFLAGBIT;
+                       nldr_node_obj->seg_id[DELETECODEFLAGBIT] = (u16)
+                           (node_props->ul_code_mem_seg_mask >>
+                            DELETEBIT) & SEGMASK;
+                       nldr_node_obj->code_data_flag_mask |=
+                           ((node_props->ul_code_mem_seg_mask >>
+                             (DELETEBIT + FLAGBIT)) & 1) << DELETECODEFLAGBIT;
+               } else {
+                       /* Non-dynamically loaded nodes are part of the
+                        * base image */
+                       nldr_node_obj->root.lib = nldr_obj->base_lib;
+                       /* Check for overlay node */
+                       if (node_props->us_load_type == NLDR_OVLYLOAD)
+                               nldr_node_obj->overlay = true;
+
+               }
+               *nldr_nodeobj = (struct nldr_nodeobject *)nldr_node_obj;
+       }
+       /* Cleanup on failure */
+       if (status && nldr_node_obj)
+               kfree(nldr_node_obj);
+
+       DBC_ENSURE((!status && *nldr_nodeobj)
+                  || (status && *nldr_nodeobj == NULL));
+       return status;
+}
+
+/*
+ *  ======== nldr_create ========
+ */
+int nldr_create(struct nldr_object **nldr,
+                      struct dev_object *hdev_obj,
+                      const struct nldr_attrs *pattrs)
+{
+       struct cod_manager *cod_mgr;    /* COD manager */
+       char *psz_coff_buf = NULL;
+       char sz_zl_file[COD_MAXPATHLENGTH];
+       struct nldr_object *nldr_obj = NULL;
+       struct dbll_attrs save_attrs;
+       struct dbll_attrs new_attrs;
+       dbll_flags flags;
+       u32 ul_entry;
+       u16 dload_segs = 0;
+       struct mem_seg_info *mem_info_obj;
+       u32 ul_len = 0;
+       u32 ul_addr;
+       struct rmm_segment *rmm_segs = NULL;
+       u16 i;
+       int status = 0;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(nldr != NULL);
+       DBC_REQUIRE(hdev_obj != NULL);
+       DBC_REQUIRE(pattrs != NULL);
+       DBC_REQUIRE(pattrs->pfn_ovly != NULL);
+       DBC_REQUIRE(pattrs->pfn_write != NULL);
+
+       /* Allocate dynamic loader object */
+       nldr_obj = kzalloc(sizeof(struct nldr_object), GFP_KERNEL);
+       if (nldr_obj) {
+               nldr_obj->hdev_obj = hdev_obj;
+               /* warning, lazy status checking alert! */
+               dev_get_cod_mgr(hdev_obj, &cod_mgr);
+               if (cod_mgr) {
+                       status = cod_get_loader(cod_mgr, &nldr_obj->dbll);
+                       DBC_ASSERT(!status);
+                       status = cod_get_base_lib(cod_mgr, &nldr_obj->base_lib);
+                       DBC_ASSERT(!status);
+                       status =
+                           cod_get_base_name(cod_mgr, sz_zl_file,
+                                                       COD_MAXPATHLENGTH);
+                       DBC_ASSERT(!status);
+               }
+               status = 0;
+               /* end lazy status checking */
+               nldr_obj->us_dsp_mau_size = pattrs->us_dsp_mau_size;
+               nldr_obj->us_dsp_word_size = pattrs->us_dsp_word_size;
+               nldr_obj->ldr_fxns = ldr_fxns;
+               if (!(nldr_obj->ldr_fxns.init_fxn()))
+                       status = -ENOMEM;
+
+       } else {
+               status = -ENOMEM;
+       }
+       /* Create the DCD Manager */
+       if (!status)
+               status = dcd_create_manager(NULL, &nldr_obj->hdcd_mgr);
+
+       /* Get dynamic loading memory sections from base lib */
+       if (!status) {
+               status =
+                   nldr_obj->ldr_fxns.get_sect_fxn(nldr_obj->base_lib,
+                                                   DYNMEMSECT, &ul_addr,
+                                                   &ul_len);
+               if (!status) {
+                       psz_coff_buf =
+                               kzalloc(ul_len * nldr_obj->us_dsp_mau_size,
+                                                               GFP_KERNEL);
+                       if (!psz_coff_buf)
+                               status = -ENOMEM;
+               } else {
+                       /* Ok to not have dynamic loading memory */
+                       status = 0;
+                       ul_len = 0;
+                       dev_dbg(bridge, "%s: failed - no dynamic loading mem "
+                               "segments: 0x%x\n", __func__, status);
+               }
+       }
+       if (!status && ul_len > 0) {
+               /* Read section containing dynamic load mem segments */
+               status =
+                   nldr_obj->ldr_fxns.read_sect_fxn(nldr_obj->base_lib,
+                                                    DYNMEMSECT, psz_coff_buf,
+                                                    ul_len);
+       }
+       if (!status && ul_len > 0) {
+               /* Parse memory segment data */
+               dload_segs = (u16) (*((u32 *) psz_coff_buf));
+               if (dload_segs > MAXMEMSEGS)
+                       status = -EBADF;
+       }
+       /* Parse dynamic load memory segments */
+       if (!status && dload_segs > 0) {
+               rmm_segs = kzalloc(sizeof(struct rmm_segment) * dload_segs,
+                                                               GFP_KERNEL);
+               nldr_obj->seg_table =
+                               kzalloc(sizeof(u32) * dload_segs, GFP_KERNEL);
+               if (rmm_segs == NULL || nldr_obj->seg_table == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       nldr_obj->dload_segs = dload_segs;
+                       mem_info_obj = (struct mem_seg_info *)(psz_coff_buf +
+                                                              sizeof(u32));
+                       for (i = 0; i < dload_segs; i++) {
+                               rmm_segs[i].base = (mem_info_obj + i)->base;
+                               rmm_segs[i].length = (mem_info_obj + i)->len;
+                               rmm_segs[i].space = 0;
+                               nldr_obj->seg_table[i] =
+                                   (mem_info_obj + i)->type;
+                               dev_dbg(bridge,
+                                       "(proc) DLL MEMSEGMENT: %d, "
+                                       "Base: 0x%x, Length: 0x%x\n", i,
+                                       rmm_segs[i].base, rmm_segs[i].length);
+                       }
+               }
+       }
+       /* Create Remote memory manager */
+       if (!status)
+               status = rmm_create(&nldr_obj->rmm, rmm_segs, dload_segs);
+
+       if (!status) {
+               /* set the alloc, free, write functions for loader */
+               nldr_obj->ldr_fxns.get_attrs_fxn(nldr_obj->dbll, &save_attrs);
+               new_attrs = save_attrs;
+               new_attrs.alloc = (dbll_alloc_fxn) remote_alloc;
+               new_attrs.free = (dbll_free_fxn) remote_free;
+               new_attrs.sym_lookup = (dbll_sym_lookup) get_symbol_value;
+               new_attrs.sym_handle = nldr_obj;
+               new_attrs.write = (dbll_write_fxn) pattrs->pfn_write;
+               nldr_obj->ovly_fxn = pattrs->pfn_ovly;
+               nldr_obj->write_fxn = pattrs->pfn_write;
+               nldr_obj->ldr_attrs = new_attrs;
+       }
+       kfree(rmm_segs);
+
+       kfree(psz_coff_buf);
+
+       /* Get overlay nodes */
+       if (!status) {
+               status =
+                   cod_get_base_name(cod_mgr, sz_zl_file, COD_MAXPATHLENGTH);
+               /* lazy check */
+               DBC_ASSERT(!status);
+               /* First count number of overlay nodes */
+               status =
+                   dcd_get_objects(nldr_obj->hdcd_mgr, sz_zl_file,
+                                   add_ovly_node, (void *)nldr_obj);
+               /* Now build table of overlay nodes */
+               if (!status && nldr_obj->ovly_nodes > 0) {
+                       /* Allocate table for overlay nodes */
+                       nldr_obj->ovly_table =
+                                       kzalloc(sizeof(struct ovly_node) *
+                                       nldr_obj->ovly_nodes, GFP_KERNEL);
+                       /* Put overlay nodes in the table */
+                       nldr_obj->ovly_nid = 0;
+                       status = dcd_get_objects(nldr_obj->hdcd_mgr, sz_zl_file,
+                                                add_ovly_node,
+                                                (void *)nldr_obj);
+               }
+       }
+       /* Do a fake reload of the base image to get overlay section info */
+       if (!status && nldr_obj->ovly_nodes > 0) {
+               save_attrs.write = fake_ovly_write;
+               save_attrs.log_write = add_ovly_info;
+               save_attrs.log_write_handle = nldr_obj;
+               flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
+               status = nldr_obj->ldr_fxns.load_fxn(nldr_obj->base_lib, flags,
+                                                    &save_attrs, &ul_entry);
+       }
+       if (!status) {
+               *nldr = (struct nldr_object *)nldr_obj;
+       } else {
+               if (nldr_obj)
+                       nldr_delete((struct nldr_object *)nldr_obj);
+
+               *nldr = NULL;
+       }
+       /* FIXME:Temp. Fix. Must be removed */
+       DBC_ENSURE((!status && *nldr) || (status && *nldr == NULL));
+       return status;
+}
+
+/*
+ *  ======== nldr_delete ========
+ */
+void nldr_delete(struct nldr_object *nldr_obj)
+{
+       struct ovly_sect *ovly_section;
+       struct ovly_sect *next;
+       u16 i;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(nldr_obj);
+
+       nldr_obj->ldr_fxns.exit_fxn();
+       if (nldr_obj->rmm)
+               rmm_delete(nldr_obj->rmm);
+
+       kfree(nldr_obj->seg_table);
+
+       if (nldr_obj->hdcd_mgr)
+               dcd_destroy_manager(nldr_obj->hdcd_mgr);
+
+       /* Free overlay node information */
+       if (nldr_obj->ovly_table) {
+               for (i = 0; i < nldr_obj->ovly_nodes; i++) {
+                       ovly_section =
+                           nldr_obj->ovly_table[i].create_sects_list;
+                       while (ovly_section) {
+                               next = ovly_section->next_sect;
+                               kfree(ovly_section);
+                               ovly_section = next;
+                       }
+                       ovly_section =
+                           nldr_obj->ovly_table[i].delete_sects_list;
+                       while (ovly_section) {
+                               next = ovly_section->next_sect;
+                               kfree(ovly_section);
+                               ovly_section = next;
+                       }
+                       ovly_section =
+                           nldr_obj->ovly_table[i].execute_sects_list;
+                       while (ovly_section) {
+                               next = ovly_section->next_sect;
+                               kfree(ovly_section);
+                               ovly_section = next;
+                       }
+                       ovly_section = nldr_obj->ovly_table[i].other_sects_list;
+                       while (ovly_section) {
+                               next = ovly_section->next_sect;
+                               kfree(ovly_section);
+                               ovly_section = next;
+                       }
+               }
+               kfree(nldr_obj->ovly_table);
+       }
+       kfree(nldr_obj);
+}
+
+/*
+ *  ======== nldr_exit ========
+ *  Discontinue usage of NLDR module.
+ */
+void nldr_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       if (refs == 0)
+               rmm_exit();
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== nldr_get_fxn_addr ========
+ */
+int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj,
+                            char *str_fxn, u32 * addr)
+{
+       struct dbll_sym_val *dbll_sym;
+       struct nldr_object *nldr_obj;
+       int status = 0;
+       bool status1 = false;
+       s32 i = 0;
+       struct lib_node root = { NULL, 0, NULL };
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(nldr_node_obj);
+       DBC_REQUIRE(addr != NULL);
+       DBC_REQUIRE(str_fxn != NULL);
+
+       nldr_obj = nldr_node_obj->nldr_obj;
+       /* Called from node_create(), node_delete(), or node_run(). */
+       if (nldr_node_obj->dynamic && *nldr_node_obj->pf_phase_split) {
+               switch (nldr_node_obj->phase) {
+               case NLDR_CREATE:
+                       root = nldr_node_obj->create_lib;
+                       break;
+               case NLDR_EXECUTE:
+                       root = nldr_node_obj->execute_lib;
+                       break;
+               case NLDR_DELETE:
+                       root = nldr_node_obj->delete_lib;
+                       break;
+               default:
+                       DBC_ASSERT(false);
+                       break;
+               }
+       } else {
+               /* for Overlay nodes or non-split Dynamic nodes */
+               root = nldr_node_obj->root;
+       }
+       status1 =
+           nldr_obj->ldr_fxns.get_c_addr_fxn(root.lib, str_fxn, &dbll_sym);
+       if (!status1)
+               status1 =
+                   nldr_obj->ldr_fxns.get_addr_fxn(root.lib, str_fxn,
+                                                   &dbll_sym);
+
+       /* If symbol not found, check dependent libraries */
+       if (!status1) {
+               for (i = 0; i < root.dep_libs; i++) {
+                       status1 =
+                           nldr_obj->ldr_fxns.get_addr_fxn(root.dep_libs_tree
+                                                           [i].lib, str_fxn,
+                                                           &dbll_sym);
+                       if (!status1) {
+                               status1 =
+                                   nldr_obj->ldr_fxns.
+                                   get_c_addr_fxn(root.dep_libs_tree[i].lib,
+                                                  str_fxn, &dbll_sym);
+                       }
+                       if (status1) {
+                               /* Symbol found */
+                               break;
+                       }
+               }
+       }
+       /* Check persistent libraries */
+       if (!status1) {
+               for (i = 0; i < nldr_node_obj->pers_libs; i++) {
+                       status1 =
+                           nldr_obj->ldr_fxns.
+                           get_addr_fxn(nldr_node_obj->pers_lib_table[i].lib,
+                                        str_fxn, &dbll_sym);
+                       if (!status1) {
+                               status1 =
+                                   nldr_obj->ldr_fxns.
+                                   get_c_addr_fxn(nldr_node_obj->pers_lib_table
+                                                  [i].lib, str_fxn, &dbll_sym);
+                       }
+                       if (status1) {
+                               /* Symbol found */
+                               break;
+                       }
+               }
+       }
+
+       if (status1)
+               *addr = dbll_sym->value;
+       else
+               status = -ESPIPE;
+
+       return status;
+}
+
+/*
+ *  ======== nldr_get_rmm_manager ========
+ *  Given a NLDR object, retrieve RMM Manager Handle
+ */
+int nldr_get_rmm_manager(struct nldr_object *nldr,
+                               struct rmm_target_obj **rmm_mgr)
+{
+       int status = 0;
+       struct nldr_object *nldr_obj = nldr;
+       DBC_REQUIRE(rmm_mgr != NULL);
+
+       if (nldr) {
+               *rmm_mgr = nldr_obj->rmm;
+       } else {
+               *rmm_mgr = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (rmm_mgr != NULL && *rmm_mgr == NULL));
+
+       return status;
+}
+
+/*
+ *  ======== nldr_init ========
+ *  Initialize the NLDR module.
+ */
+bool nldr_init(void)
+{
+       DBC_REQUIRE(refs >= 0);
+
+       if (refs == 0)
+               rmm_init();
+
+       refs++;
+
+       DBC_ENSURE(refs > 0);
+       return true;
+}
+
+/*
+ *  ======== nldr_load ========
+ */
+int nldr_load(struct nldr_nodeobject *nldr_node_obj,
+                    enum nldr_phase phase)
+{
+       struct nldr_object *nldr_obj;
+       struct dsp_uuid lib_uuid;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(nldr_node_obj);
+
+       nldr_obj = nldr_node_obj->nldr_obj;
+
+       if (nldr_node_obj->dynamic) {
+               nldr_node_obj->phase = phase;
+
+               lib_uuid = nldr_node_obj->uuid;
+
+               /* At this point, we may not know if node is split into
+                * different libraries. So we'll go ahead and load the
+                * library, and then save the pointer to the appropriate
+                * location after we know. */
+
+               status =
+                   load_lib(nldr_node_obj, &nldr_node_obj->root, lib_uuid,
+                            false, nldr_node_obj->lib_path, phase, 0);
+
+               if (!status) {
+                       if (*nldr_node_obj->pf_phase_split) {
+                               switch (phase) {
+                               case NLDR_CREATE:
+                                       nldr_node_obj->create_lib =
+                                           nldr_node_obj->root;
+                                       break;
+
+                               case NLDR_EXECUTE:
+                                       nldr_node_obj->execute_lib =
+                                           nldr_node_obj->root;
+                                       break;
+
+                               case NLDR_DELETE:
+                                       nldr_node_obj->delete_lib =
+                                           nldr_node_obj->root;
+                                       break;
+
+                               default:
+                                       DBC_ASSERT(false);
+                                       break;
+                               }
+                       }
+               }
+       } else {
+               if (nldr_node_obj->overlay)
+                       status = load_ovly(nldr_node_obj, phase);
+
+       }
+
+       return status;
+}
+
+/*
+ *  ======== nldr_unload ========
+ */
+int nldr_unload(struct nldr_nodeobject *nldr_node_obj,
+                      enum nldr_phase phase)
+{
+       int status = 0;
+       struct lib_node *root_lib = NULL;
+       s32 i = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(nldr_node_obj);
+
+       if (nldr_node_obj != NULL) {
+               if (nldr_node_obj->dynamic) {
+                       if (*nldr_node_obj->pf_phase_split) {
+                               switch (phase) {
+                               case NLDR_CREATE:
+                                       root_lib = &nldr_node_obj->create_lib;
+                                       break;
+                               case NLDR_EXECUTE:
+                                       root_lib = &nldr_node_obj->execute_lib;
+                                       break;
+                               case NLDR_DELETE:
+                                       root_lib = &nldr_node_obj->delete_lib;
+                                       /* Unload persistent libraries */
+                                       for (i = 0;
+                                            i < nldr_node_obj->pers_libs;
+                                            i++) {
+                                               unload_lib(nldr_node_obj,
+                                                          &nldr_node_obj->
+                                                          pers_lib_table[i]);
+                                       }
+                                       nldr_node_obj->pers_libs = 0;
+                                       break;
+                               default:
+                                       DBC_ASSERT(false);
+                                       break;
+                               }
+                       } else {
+                               /* Unload main library */
+                               root_lib = &nldr_node_obj->root;
+                       }
+                       if (root_lib)
+                               unload_lib(nldr_node_obj, root_lib);
+               } else {
+                       if (nldr_node_obj->overlay)
+                               unload_ovly(nldr_node_obj, phase);
+
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== add_ovly_info ========
+ */
+static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info,
+                               u32 addr, u32 bytes)
+{
+       char *node_name;
+       char *sect_name = (char *)sect_info->name;
+       bool sect_exists = false;
+       char seps = ':';
+       char *pch;
+       u16 i;
+       struct nldr_object *nldr_obj = (struct nldr_object *)handle;
+       int status = 0;
+
+       /* Is this an overlay section (load address != run address)? */
+       if (sect_info->sect_load_addr == sect_info->sect_run_addr)
+               goto func_end;
+
+       /* Find the node it belongs to */
+       for (i = 0; i < nldr_obj->ovly_nodes; i++) {
+               node_name = nldr_obj->ovly_table[i].node_name;
+               DBC_REQUIRE(node_name);
+               if (strncmp(node_name, sect_name + 1, strlen(node_name)) == 0) {
+                       /* Found the node */
+                       break;
+               }
+       }
+       if (!(i < nldr_obj->ovly_nodes))
+               goto func_end;
+
+       /* Determine which phase this section belongs to */
+       for (pch = sect_name + 1; *pch && *pch != seps; pch++)
+               ;;
+
+       if (*pch) {
+               pch++;          /* Skip over the ':' */
+               if (strncmp(pch, PCREATE, strlen(PCREATE)) == 0) {
+                       status =
+                           add_ovly_sect(nldr_obj,
+                                         &nldr_obj->
+                                         ovly_table[i].create_sects_list,
+                                         sect_info, &sect_exists, addr, bytes);
+                       if (!status && !sect_exists)
+                               nldr_obj->ovly_table[i].create_sects++;
+
+               } else if (strncmp(pch, PDELETE, strlen(PDELETE)) == 0) {
+                       status =
+                           add_ovly_sect(nldr_obj,
+                                         &nldr_obj->
+                                         ovly_table[i].delete_sects_list,
+                                         sect_info, &sect_exists, addr, bytes);
+                       if (!status && !sect_exists)
+                               nldr_obj->ovly_table[i].delete_sects++;
+
+               } else if (strncmp(pch, PEXECUTE, strlen(PEXECUTE)) == 0) {
+                       status =
+                           add_ovly_sect(nldr_obj,
+                                         &nldr_obj->
+                                         ovly_table[i].execute_sects_list,
+                                         sect_info, &sect_exists, addr, bytes);
+                       if (!status && !sect_exists)
+                               nldr_obj->ovly_table[i].execute_sects++;
+
+               } else {
+                       /* Put in "other" sectins */
+                       status =
+                           add_ovly_sect(nldr_obj,
+                                         &nldr_obj->
+                                         ovly_table[i].other_sects_list,
+                                         sect_info, &sect_exists, addr, bytes);
+                       if (!status && !sect_exists)
+                               nldr_obj->ovly_table[i].other_sects++;
+
+               }
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== add_ovly_node =========
+ *  Callback function passed to dcd_get_objects.
+ */
+static int add_ovly_node(struct dsp_uuid *uuid_obj,
+                               enum dsp_dcdobjtype obj_type, void *handle)
+{
+       struct nldr_object *nldr_obj = (struct nldr_object *)handle;
+       char *node_name = NULL;
+       char *pbuf = NULL;
+       u32 len;
+       struct dcd_genericobj obj_def;
+       int status = 0;
+
+       if (obj_type != DSP_DCDNODETYPE)
+               goto func_end;
+
+       status =
+           dcd_get_object_def(nldr_obj->hdcd_mgr, uuid_obj, obj_type,
+                              &obj_def);
+       if (status)
+               goto func_end;
+
+       /* If overlay node, add to the list */
+       if (obj_def.obj_data.node_obj.us_load_type == NLDR_OVLYLOAD) {
+               if (nldr_obj->ovly_table == NULL) {
+                       nldr_obj->ovly_nodes++;
+               } else {
+                       /* Add node to table */
+                       nldr_obj->ovly_table[nldr_obj->ovly_nid].uuid =
+                           *uuid_obj;
+                       DBC_REQUIRE(obj_def.obj_data.node_obj.ndb_props.
+                                   ac_name);
+                       len =
+                           strlen(obj_def.obj_data.node_obj.ndb_props.ac_name);
+                       node_name = obj_def.obj_data.node_obj.ndb_props.ac_name;
+                       pbuf = kzalloc(len + 1, GFP_KERNEL);
+                       if (pbuf == NULL) {
+                               status = -ENOMEM;
+                       } else {
+                               strncpy(pbuf, node_name, len);
+                               nldr_obj->ovly_table[nldr_obj->ovly_nid].
+                                   node_name = pbuf;
+                               nldr_obj->ovly_nid++;
+                       }
+               }
+       }
+       /* These were allocated in dcd_get_object_def */
+       kfree(obj_def.obj_data.node_obj.pstr_create_phase_fxn);
+
+       kfree(obj_def.obj_data.node_obj.pstr_execute_phase_fxn);
+
+       kfree(obj_def.obj_data.node_obj.pstr_delete_phase_fxn);
+
+       kfree(obj_def.obj_data.node_obj.pstr_i_alg_name);
+
+func_end:
+       return status;
+}
+
+/*
+ *  ======== add_ovly_sect ========
+ */
+static int add_ovly_sect(struct nldr_object *nldr_obj,
+                               struct ovly_sect **lst,
+                               struct dbll_sect_info *sect_inf,
+                               bool *exists, u32 addr, u32 bytes)
+{
+       struct ovly_sect *new_sect = NULL;
+       struct ovly_sect *last_sect;
+       struct ovly_sect *ovly_section;
+       int status = 0;
+
+       ovly_section = last_sect = *lst;
+       *exists = false;
+       while (ovly_section) {
+               /*
+                *  Make sure section has not already been added. Multiple
+                *  'write' calls may be made to load the section.
+                */
+               if (ovly_section->sect_load_addr == addr) {
+                       /* Already added */
+                       *exists = true;
+                       break;
+               }
+               last_sect = ovly_section;
+               ovly_section = ovly_section->next_sect;
+       }
+
+       if (!ovly_section) {
+               /* New section */
+               new_sect = kzalloc(sizeof(struct ovly_sect), GFP_KERNEL);
+               if (new_sect == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       new_sect->sect_load_addr = addr;
+                       new_sect->sect_run_addr = sect_inf->sect_run_addr +
+                           (addr - sect_inf->sect_load_addr);
+                       new_sect->size = bytes;
+                       new_sect->page = sect_inf->type;
+               }
+
+               /* Add to the list */
+               if (!status) {
+                       if (*lst == NULL) {
+                               /* First in the list */
+                               *lst = new_sect;
+                       } else {
+                               last_sect->next_sect = new_sect;
+                       }
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== fake_ovly_write ========
+ */
+static s32 fake_ovly_write(void *handle, u32 dsp_address, void *buf, u32 bytes,
+                          s32 mtype)
+{
+       return (s32) bytes;
+}
+
+/*
+ *  ======== free_sects ========
+ */
+static void free_sects(struct nldr_object *nldr_obj,
+                      struct ovly_sect *phase_sects, u16 alloc_num)
+{
+       struct ovly_sect *ovly_section = phase_sects;
+       u16 i = 0;
+       bool ret;
+
+       while (ovly_section && i < alloc_num) {
+               /* 'Deallocate' */
+               /* segid - page not supported yet */
+               /* Reserved memory */
+               ret =
+                   rmm_free(nldr_obj->rmm, 0, ovly_section->sect_run_addr,
+                            ovly_section->size, true);
+               DBC_ASSERT(ret);
+               ovly_section = ovly_section->next_sect;
+               i++;
+       }
+}
+
+/*
+ *  ======== get_symbol_value ========
+ *  Find symbol in library's base image.  If not there, check dependent
+ *  libraries.
+ */
+static bool get_symbol_value(void *handle, void *parg, void *rmm_handle,
+                            char *sym_name, struct dbll_sym_val **sym)
+{
+       struct nldr_object *nldr_obj = (struct nldr_object *)handle;
+       struct nldr_nodeobject *nldr_node_obj =
+           (struct nldr_nodeobject *)rmm_handle;
+       struct lib_node *root = (struct lib_node *)parg;
+       u16 i;
+       bool status = false;
+
+       /* check the base image */
+       status = nldr_obj->ldr_fxns.get_addr_fxn(nldr_obj->base_lib,
+                                                sym_name, sym);
+       if (!status)
+               status =
+                   nldr_obj->ldr_fxns.get_c_addr_fxn(nldr_obj->base_lib,
+                                                       sym_name, sym);
+
+       /*
+        *  Check in root lib itself. If the library consists of
+        *  multiple object files linked together, some symbols in the
+        *  library may need to be resolved.
+        */
+       if (!status) {
+               status = nldr_obj->ldr_fxns.get_addr_fxn(root->lib, sym_name,
+                                                        sym);
+               if (!status) {
+                       status =
+                           nldr_obj->ldr_fxns.get_c_addr_fxn(root->lib,
+                                                             sym_name, sym);
+               }
+       }
+
+       /*
+        *  Check in root lib's dependent libraries, but not dependent
+        *  libraries' dependents.
+        */
+       if (!status) {
+               for (i = 0; i < root->dep_libs; i++) {
+                       status =
+                           nldr_obj->ldr_fxns.get_addr_fxn(root->
+                                                           dep_libs_tree
+                                                           [i].lib,
+                                                           sym_name, sym);
+                       if (!status) {
+                               status =
+                                   nldr_obj->ldr_fxns.
+                                   get_c_addr_fxn(root->dep_libs_tree[i].lib,
+                                                  sym_name, sym);
+                       }
+                       if (status) {
+                               /* Symbol found */
+                               break;
+                       }
+               }
+       }
+       /*
+        * Check in persistent libraries
+        */
+       if (!status) {
+               for (i = 0; i < nldr_node_obj->pers_libs; i++) {
+                       status =
+                           nldr_obj->ldr_fxns.
+                           get_addr_fxn(nldr_node_obj->pers_lib_table[i].lib,
+                                        sym_name, sym);
+                       if (!status) {
+                               status = nldr_obj->ldr_fxns.get_c_addr_fxn
+                                   (nldr_node_obj->pers_lib_table[i].lib,
+                                    sym_name, sym);
+                       }
+                       if (status) {
+                               /* Symbol found */
+                               break;
+                       }
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== load_lib ========
+ *  Recursively load library and all its dependent libraries. The library
+ *  we're loading is specified by a uuid.
+ */
+static int load_lib(struct nldr_nodeobject *nldr_node_obj,
+                          struct lib_node *root, struct dsp_uuid uuid,
+                          bool root_prstnt,
+                          struct dbll_library_obj **lib_path,
+                          enum nldr_phase phase, u16 depth)
+{
+       struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
+       u16 nd_libs = 0;        /* Number of dependent libraries */
+       u16 np_libs = 0;        /* Number of persistent libraries */
+       u16 nd_libs_loaded = 0; /* Number of dep. libraries loaded */
+       u16 i;
+       u32 entry;
+       u32 dw_buf_size = NLDR_MAXPATHLENGTH;
+       dbll_flags flags = DBLL_SYMB | DBLL_CODE | DBLL_DATA | DBLL_DYNAMIC;
+       struct dbll_attrs new_attrs;
+       char *psz_file_name = NULL;
+       struct dsp_uuid *dep_lib_uui_ds = NULL;
+       bool *persistent_dep_libs = NULL;
+       int status = 0;
+       bool lib_status = false;
+       struct lib_node *dep_lib;
+
+       if (depth > MAXDEPTH) {
+               /* Error */
+               DBC_ASSERT(false);
+       }
+       root->lib = NULL;
+       /* Allocate a buffer for library file name of size DBL_MAXPATHLENGTH */
+       psz_file_name = kzalloc(DBLL_MAXPATHLENGTH, GFP_KERNEL);
+       if (psz_file_name == NULL)
+               status = -ENOMEM;
+
+       if (!status) {
+               /* Get the name of the library */
+               if (depth == 0) {
+                       status =
+                           dcd_get_library_name(nldr_node_obj->nldr_obj->
+                                                hdcd_mgr, &uuid, psz_file_name,
+                                                &dw_buf_size, phase,
+                                                nldr_node_obj->pf_phase_split);
+               } else {
+                       /* Dependent libraries are registered with a phase */
+                       status =
+                           dcd_get_library_name(nldr_node_obj->nldr_obj->
+                                                hdcd_mgr, &uuid, psz_file_name,
+                                                &dw_buf_size, NLDR_NOPHASE,
+                                                NULL);
+               }
+       }
+       if (!status) {
+               /* Open the library, don't load symbols */
+               status =
+                   nldr_obj->ldr_fxns.open_fxn(nldr_obj->dbll, psz_file_name,
+                                               DBLL_NOLOAD, &root->lib);
+       }
+       /* Done with file name */
+       kfree(psz_file_name);
+
+       /* Check to see if library not already loaded */
+       if (!status && root_prstnt) {
+               lib_status =
+                   find_in_persistent_lib_array(nldr_node_obj, root->lib);
+               /* Close library */
+               if (lib_status) {
+                       nldr_obj->ldr_fxns.close_fxn(root->lib);
+                       return 0;
+               }
+       }
+       if (!status) {
+               /* Check for circular dependencies. */
+               for (i = 0; i < depth; i++) {
+                       if (root->lib == lib_path[i]) {
+                               /* This condition could be checked by a
+                                * tool at build time. */
+                               status = -EILSEQ;
+                       }
+               }
+       }
+       if (!status) {
+               /* Add library to current path in dependency tree */
+               lib_path[depth] = root->lib;
+               depth++;
+               /* Get number of dependent libraries */
+               status =
+                   dcd_get_num_dep_libs(nldr_node_obj->nldr_obj->hdcd_mgr,
+                                        &uuid, &nd_libs, &np_libs, phase);
+       }
+       DBC_ASSERT(nd_libs >= np_libs);
+       if (!status) {
+               if (!(*nldr_node_obj->pf_phase_split))
+                       np_libs = 0;
+
+               /* nd_libs = #of dependent libraries */
+               root->dep_libs = nd_libs - np_libs;
+               if (nd_libs > 0) {
+                       dep_lib_uui_ds = kzalloc(sizeof(struct dsp_uuid) *
+                                                       nd_libs, GFP_KERNEL);
+                       persistent_dep_libs =
+                               kzalloc(sizeof(bool) * nd_libs, GFP_KERNEL);
+                       if (!dep_lib_uui_ds || !persistent_dep_libs)
+                               status = -ENOMEM;
+
+                       if (root->dep_libs > 0) {
+                               /* Allocate arrays for dependent lib UUIDs,
+                                * lib nodes */
+                               root->dep_libs_tree = kzalloc
+                                               (sizeof(struct lib_node) *
+                                               (root->dep_libs), GFP_KERNEL);
+                               if (!(root->dep_libs_tree))
+                                       status = -ENOMEM;
+
+                       }
+
+                       if (!status) {
+                               /* Get the dependent library UUIDs */
+                               status =
+                                   dcd_get_dep_libs(nldr_node_obj->
+                                                    nldr_obj->hdcd_mgr, &uuid,
+                                                    nd_libs, dep_lib_uui_ds,
+                                                    persistent_dep_libs,
+                                                    phase);
+                       }
+               }
+       }
+
+       /*
+        *  Recursively load dependent libraries.
+        */
+       if (!status) {
+               for (i = 0; i < nd_libs; i++) {
+                       /* If root library is NOT persistent, and dep library
+                        * is, then record it.  If root library IS persistent,
+                        * the deplib is already included */
+                       if (!root_prstnt && persistent_dep_libs[i] &&
+                           *nldr_node_obj->pf_phase_split) {
+                               if ((nldr_node_obj->pers_libs) >= MAXLIBS) {
+                                       status = -EILSEQ;
+                                       break;
+                               }
+
+                               /* Allocate library outside of phase */
+                               dep_lib =
+                                   &nldr_node_obj->pers_lib_table
+                                   [nldr_node_obj->pers_libs];
+                       } else {
+                               if (root_prstnt)
+                                       persistent_dep_libs[i] = true;
+
+                               /* Allocate library within phase */
+                               dep_lib = &root->dep_libs_tree[nd_libs_loaded];
+                       }
+
+                       status = load_lib(nldr_node_obj, dep_lib,
+                                         dep_lib_uui_ds[i],
+                                         persistent_dep_libs[i], lib_path,
+                                         phase, depth);
+
+                       if (!status) {
+                               if ((status != 0) &&
+                                   !root_prstnt && persistent_dep_libs[i] &&
+                                   *nldr_node_obj->pf_phase_split) {
+                                       (nldr_node_obj->pers_libs)++;
+                               } else {
+                                       if (!persistent_dep_libs[i] ||
+                                           !(*nldr_node_obj->pf_phase_split)) {
+                                               nd_libs_loaded++;
+                                       }
+                               }
+                       } else {
+                               break;
+                       }
+               }
+       }
+
+       /* Now we can load the root library */
+       if (!status) {
+               new_attrs = nldr_obj->ldr_attrs;
+               new_attrs.sym_arg = root;
+               new_attrs.rmm_handle = nldr_node_obj;
+               new_attrs.input_params = nldr_node_obj->priv_ref;
+               new_attrs.base_image = false;
+
+               status =
+                   nldr_obj->ldr_fxns.load_fxn(root->lib, flags, &new_attrs,
+                                               &entry);
+       }
+
+       /*
+        *  In case of failure, unload any dependent libraries that
+        *  were loaded, and close the root library.
+        *  (Persistent libraries are unloaded from the very top)
+        */
+       if (status) {
+               if (phase != NLDR_EXECUTE) {
+                       for (i = 0; i < nldr_node_obj->pers_libs; i++)
+                               unload_lib(nldr_node_obj,
+                                          &nldr_node_obj->pers_lib_table[i]);
+
+                       nldr_node_obj->pers_libs = 0;
+               }
+               for (i = 0; i < nd_libs_loaded; i++)
+                       unload_lib(nldr_node_obj, &root->dep_libs_tree[i]);
+
+               if (root->lib)
+                       nldr_obj->ldr_fxns.close_fxn(root->lib);
+
+       }
+
+       /* Going up one node in the dependency tree */
+       depth--;
+
+       kfree(dep_lib_uui_ds);
+       dep_lib_uui_ds = NULL;
+
+       kfree(persistent_dep_libs);
+       persistent_dep_libs = NULL;
+
+       return status;
+}
+
+/*
+ *  ======== load_ovly ========
+ */
+static int load_ovly(struct nldr_nodeobject *nldr_node_obj,
+                           enum nldr_phase phase)
+{
+       struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
+       struct ovly_node *po_node = NULL;
+       struct ovly_sect *phase_sects = NULL;
+       struct ovly_sect *other_sects_list = NULL;
+       u16 i;
+       u16 alloc_num = 0;
+       u16 other_alloc = 0;
+       u16 *ref_count = NULL;
+       u16 *other_ref = NULL;
+       u32 bytes;
+       struct ovly_sect *ovly_section;
+       int status = 0;
+
+       /* Find the node in the table */
+       for (i = 0; i < nldr_obj->ovly_nodes; i++) {
+               if (is_equal_uuid
+                   (&nldr_node_obj->uuid, &nldr_obj->ovly_table[i].uuid)) {
+                       /* Found it */
+                       po_node = &(nldr_obj->ovly_table[i]);
+                       break;
+               }
+       }
+
+       DBC_ASSERT(i < nldr_obj->ovly_nodes);
+
+       if (!po_node) {
+               status = -ENOENT;
+               goto func_end;
+       }
+
+       switch (phase) {
+       case NLDR_CREATE:
+               ref_count = &(po_node->create_ref);
+               other_ref = &(po_node->other_ref);
+               phase_sects = po_node->create_sects_list;
+               other_sects_list = po_node->other_sects_list;
+               break;
+
+       case NLDR_EXECUTE:
+               ref_count = &(po_node->execute_ref);
+               phase_sects = po_node->execute_sects_list;
+               break;
+
+       case NLDR_DELETE:
+               ref_count = &(po_node->delete_ref);
+               phase_sects = po_node->delete_sects_list;
+               break;
+
+       default:
+               DBC_ASSERT(false);
+               break;
+       }
+
+       if (ref_count == NULL)
+               goto func_end;
+
+       if (*ref_count != 0)
+               goto func_end;
+
+       /* 'Allocate' memory for overlay sections of this phase */
+       ovly_section = phase_sects;
+       while (ovly_section) {
+               /* allocate *//* page not supported yet */
+               /* reserve *//* align */
+               status = rmm_alloc(nldr_obj->rmm, 0, ovly_section->size, 0,
+                                  &(ovly_section->sect_run_addr), true);
+               if (!status) {
+                       ovly_section = ovly_section->next_sect;
+                       alloc_num++;
+               } else {
+                       break;
+               }
+       }
+       if (other_ref && *other_ref == 0) {
+               /* 'Allocate' memory for other overlay sections
+                * (create phase) */
+               if (!status) {
+                       ovly_section = other_sects_list;
+                       while (ovly_section) {
+                               /* page not supported *//* align */
+                               /* reserve */
+                               status =
+                                   rmm_alloc(nldr_obj->rmm, 0,
+                                             ovly_section->size, 0,
+                                             &(ovly_section->sect_run_addr),
+                                             true);
+                               if (!status) {
+                                       ovly_section = ovly_section->next_sect;
+                                       other_alloc++;
+                               } else {
+                                       break;
+                               }
+                       }
+               }
+       }
+       if (*ref_count == 0) {
+               if (!status) {
+                       /* Load sections for this phase */
+                       ovly_section = phase_sects;
+                       while (ovly_section && !status) {
+                               bytes =
+                                   (*nldr_obj->ovly_fxn) (nldr_node_obj->
+                                                          priv_ref,
+                                                          ovly_section->
+                                                          sect_run_addr,
+                                                          ovly_section->
+                                                          sect_load_addr,
+                                                          ovly_section->size,
+                                                          ovly_section->page);
+                               if (bytes != ovly_section->size)
+                                       status = -EPERM;
+
+                               ovly_section = ovly_section->next_sect;
+                       }
+               }
+       }
+       if (other_ref && *other_ref == 0) {
+               if (!status) {
+                       /* Load other sections (create phase) */
+                       ovly_section = other_sects_list;
+                       while (ovly_section && !status) {
+                               bytes =
+                                   (*nldr_obj->ovly_fxn) (nldr_node_obj->
+                                                          priv_ref,
+                                                          ovly_section->
+                                                          sect_run_addr,
+                                                          ovly_section->
+                                                          sect_load_addr,
+                                                          ovly_section->size,
+                                                          ovly_section->page);
+                               if (bytes != ovly_section->size)
+                                       status = -EPERM;
+
+                               ovly_section = ovly_section->next_sect;
+                       }
+               }
+       }
+       if (status) {
+               /* 'Deallocate' memory */
+               free_sects(nldr_obj, phase_sects, alloc_num);
+               free_sects(nldr_obj, other_sects_list, other_alloc);
+       }
+func_end:
+       if (!status && (ref_count != NULL)) {
+               *ref_count += 1;
+               if (other_ref)
+                       *other_ref += 1;
+
+       }
+
+       return status;
+}
+
+/*
+ *  ======== remote_alloc ========
+ */
+static int remote_alloc(void **ref, u16 mem_sect, u32 size,
+                              u32 align, u32 *dsp_address,
+                              s32 segmnt_id, s32 req,
+                              bool reserve)
+{
+       struct nldr_nodeobject *hnode = (struct nldr_nodeobject *)ref;
+       struct nldr_object *nldr_obj;
+       struct rmm_target_obj *rmm;
+       u16 mem_phase_bit = MAXFLAGS;
+       u16 segid = 0;
+       u16 i;
+       u16 mem_sect_type;
+       u32 word_size;
+       struct rmm_addr *rmm_addr_obj = (struct rmm_addr *)dsp_address;
+       bool mem_load_req = false;
+       int status = -ENOMEM;   /* Set to fail */
+       DBC_REQUIRE(hnode);
+       DBC_REQUIRE(mem_sect == DBLL_CODE || mem_sect == DBLL_DATA ||
+                   mem_sect == DBLL_BSS);
+       nldr_obj = hnode->nldr_obj;
+       rmm = nldr_obj->rmm;
+       /* Convert size to DSP words */
+       word_size =
+           (size + nldr_obj->us_dsp_word_size -
+            1) / nldr_obj->us_dsp_word_size;
+       /* Modify memory 'align' to account for DSP cache line size */
+       align = find_lcm(GEM_CACHE_LINE_SIZE, align);
+       dev_dbg(bridge, "%s: memory align to 0x%x\n", __func__, align);
+       if (segmnt_id != -1) {
+               rmm_addr_obj->segid = segmnt_id;
+               segid = segmnt_id;
+               mem_load_req = req;
+       } else {
+               switch (hnode->phase) {
+               case NLDR_CREATE:
+                       mem_phase_bit = CREATEDATAFLAGBIT;
+                       break;
+               case NLDR_DELETE:
+                       mem_phase_bit = DELETEDATAFLAGBIT;
+                       break;
+               case NLDR_EXECUTE:
+                       mem_phase_bit = EXECUTEDATAFLAGBIT;
+                       break;
+               default:
+                       DBC_ASSERT(false);
+                       break;
+               }
+               if (mem_sect == DBLL_CODE)
+                       mem_phase_bit++;
+
+               if (mem_phase_bit < MAXFLAGS)
+                       segid = hnode->seg_id[mem_phase_bit];
+
+               /* Determine if there is a memory loading requirement */
+               if ((hnode->code_data_flag_mask >> mem_phase_bit) & 0x1)
+                       mem_load_req = true;
+
+       }
+       mem_sect_type = (mem_sect == DBLL_CODE) ? DYNM_CODE : DYNM_DATA;
+
+       /* Find an appropriate segment based on mem_sect */
+       if (segid == NULLID) {
+               /* No memory requirements of preferences */
+               DBC_ASSERT(!mem_load_req);
+               goto func_cont;
+       }
+       if (segid <= MAXSEGID) {
+               DBC_ASSERT(segid < nldr_obj->dload_segs);
+               /* Attempt to allocate from segid first. */
+               rmm_addr_obj->segid = segid;
+               status =
+                   rmm_alloc(rmm, segid, word_size, align, dsp_address, false);
+               if (status) {
+                       dev_dbg(bridge, "%s: Unable allocate from segment %d\n",
+                               __func__, segid);
+               }
+       } else {
+               /* segid > MAXSEGID ==> Internal or external memory */
+               DBC_ASSERT(segid == MEMINTERNALID || segid == MEMEXTERNALID);
+               /*  Check for any internal or external memory segment,
+                *  depending on segid. */
+               mem_sect_type |= segid == MEMINTERNALID ?
+                   DYNM_INTERNAL : DYNM_EXTERNAL;
+               for (i = 0; i < nldr_obj->dload_segs; i++) {
+                       if ((nldr_obj->seg_table[i] & mem_sect_type) !=
+                           mem_sect_type)
+                               continue;
+
+                       status = rmm_alloc(rmm, i, word_size, align,
+                                       dsp_address, false);
+                       if (!status) {
+                               /* Save segid for freeing later */
+                               rmm_addr_obj->segid = i;
+                               break;
+                       }
+               }
+       }
+func_cont:
+       /* Haven't found memory yet, attempt to find any segment that works */
+       if (status == -ENOMEM && !mem_load_req) {
+               dev_dbg(bridge, "%s: Preferred segment unavailable, trying "
+                       "another\n", __func__);
+               for (i = 0; i < nldr_obj->dload_segs; i++) {
+                       /* All bits of mem_sect_type must be set */
+                       if ((nldr_obj->seg_table[i] & mem_sect_type) !=
+                           mem_sect_type)
+                               continue;
+
+                       status = rmm_alloc(rmm, i, word_size, align,
+                                          dsp_address, false);
+                       if (!status) {
+                               /* Save segid */
+                               rmm_addr_obj->segid = i;
+                               break;
+                       }
+               }
+       }
+
+       return status;
+}
+
+static int remote_free(void **ref, u16 space, u32 dsp_address,
+                             u32 size, bool reserve)
+{
+       struct nldr_object *nldr_obj = (struct nldr_object *)ref;
+       struct rmm_target_obj *rmm;
+       u32 word_size;
+       int status = -ENOMEM;   /* Set to fail */
+
+       DBC_REQUIRE(nldr_obj);
+
+       rmm = nldr_obj->rmm;
+
+       /* Convert size to DSP words */
+       word_size =
+           (size + nldr_obj->us_dsp_word_size -
+            1) / nldr_obj->us_dsp_word_size;
+
+       if (rmm_free(rmm, space, dsp_address, word_size, reserve))
+               status = 0;
+
+       return status;
+}
+
+/*
+ *  ======== unload_lib ========
+ */
+static void unload_lib(struct nldr_nodeobject *nldr_node_obj,
+                      struct lib_node *root)
+{
+       struct dbll_attrs new_attrs;
+       struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
+       u16 i;
+
+       DBC_ASSERT(root != NULL);
+
+       /* Unload dependent libraries */
+       for (i = 0; i < root->dep_libs; i++)
+               unload_lib(nldr_node_obj, &root->dep_libs_tree[i]);
+
+       root->dep_libs = 0;
+
+       new_attrs = nldr_obj->ldr_attrs;
+       new_attrs.rmm_handle = nldr_obj->rmm;
+       new_attrs.input_params = nldr_node_obj->priv_ref;
+       new_attrs.base_image = false;
+       new_attrs.sym_arg = root;
+
+       if (root->lib) {
+               /* Unload the root library */
+               nldr_obj->ldr_fxns.unload_fxn(root->lib, &new_attrs);
+               nldr_obj->ldr_fxns.close_fxn(root->lib);
+       }
+
+       /* Free dependent library list */
+       kfree(root->dep_libs_tree);
+       root->dep_libs_tree = NULL;
+}
+
+/*
+ *  ======== unload_ovly ========
+ */
+static void unload_ovly(struct nldr_nodeobject *nldr_node_obj,
+                       enum nldr_phase phase)
+{
+       struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
+       struct ovly_node *po_node = NULL;
+       struct ovly_sect *phase_sects = NULL;
+       struct ovly_sect *other_sects_list = NULL;
+       u16 i;
+       u16 alloc_num = 0;
+       u16 other_alloc = 0;
+       u16 *ref_count = NULL;
+       u16 *other_ref = NULL;
+
+       /* Find the node in the table */
+       for (i = 0; i < nldr_obj->ovly_nodes; i++) {
+               if (is_equal_uuid
+                   (&nldr_node_obj->uuid, &nldr_obj->ovly_table[i].uuid)) {
+                       /* Found it */
+                       po_node = &(nldr_obj->ovly_table[i]);
+                       break;
+               }
+       }
+
+       DBC_ASSERT(i < nldr_obj->ovly_nodes);
+
+       if (!po_node)
+               /* TODO: Should we print warning here? */
+               return;
+
+       switch (phase) {
+       case NLDR_CREATE:
+               ref_count = &(po_node->create_ref);
+               phase_sects = po_node->create_sects_list;
+               alloc_num = po_node->create_sects;
+               break;
+       case NLDR_EXECUTE:
+               ref_count = &(po_node->execute_ref);
+               phase_sects = po_node->execute_sects_list;
+               alloc_num = po_node->execute_sects;
+               break;
+       case NLDR_DELETE:
+               ref_count = &(po_node->delete_ref);
+               other_ref = &(po_node->other_ref);
+               phase_sects = po_node->delete_sects_list;
+               /* 'Other' overlay sections are unloaded in the delete phase */
+               other_sects_list = po_node->other_sects_list;
+               alloc_num = po_node->delete_sects;
+               other_alloc = po_node->other_sects;
+               break;
+       default:
+               DBC_ASSERT(false);
+               break;
+       }
+       DBC_ASSERT(ref_count && (*ref_count > 0));
+       if (ref_count && (*ref_count > 0)) {
+               *ref_count -= 1;
+               if (other_ref) {
+                       DBC_ASSERT(*other_ref > 0);
+                       *other_ref -= 1;
+               }
+       }
+
+       if (ref_count && *ref_count == 0) {
+               /* 'Deallocate' memory */
+               free_sects(nldr_obj, phase_sects, alloc_num);
+       }
+       if (other_ref && *other_ref == 0)
+               free_sects(nldr_obj, other_sects_list, other_alloc);
+}
+
+/*
+ *  ======== find_in_persistent_lib_array ========
+ */
+static bool find_in_persistent_lib_array(struct nldr_nodeobject *nldr_node_obj,
+                                        struct dbll_library_obj *lib)
+{
+       s32 i = 0;
+
+       for (i = 0; i < nldr_node_obj->pers_libs; i++) {
+               if (lib == nldr_node_obj->pers_lib_table[i].lib)
+                       return true;
+
+       }
+
+       return false;
+}
+
+/*
+ * ================ Find LCM (Least Common Multiplier ===
+ */
+static u32 find_lcm(u32 a, u32 b)
+{
+       u32 ret;
+
+       ret = a * b / gcd(a, b);
+
+       return ret;
+}
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+/**
+ * nldr_find_addr() - Find the closest symbol to the given address based on
+ *             dynamic node object.
+ *
+ * @nldr_node:         Dynamic node object
+ * @sym_addr:          Given address to find the dsp symbol
+ * @offset_range:              offset range to look for dsp symbol
+ * @offset_output:             Symbol Output address
+ * @sym_name:          String with the dsp symbol
+ *
+ *     This function finds the node library for a given address and
+ *     retrieves the dsp symbol by calling dbll_find_dsp_symbol.
+ */
+int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr,
+                       u32 offset_range, void *offset_output, char *sym_name)
+{
+       int status = 0;
+       bool status1 = false;
+       s32 i = 0;
+       struct lib_node root = { NULL, 0, NULL };
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(offset_output != NULL);
+       DBC_REQUIRE(sym_name != NULL);
+       pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x,  %s)\n", __func__, (u32) nldr_node,
+                       sym_addr, offset_range, (u32) offset_output, sym_name);
+
+       if (nldr_node->dynamic && *nldr_node->pf_phase_split) {
+               switch (nldr_node->phase) {
+               case NLDR_CREATE:
+                       root = nldr_node->create_lib;
+                       break;
+               case NLDR_EXECUTE:
+                       root = nldr_node->execute_lib;
+                       break;
+               case NLDR_DELETE:
+                       root = nldr_node->delete_lib;
+                       break;
+               default:
+                       DBC_ASSERT(false);
+                       break;
+               }
+       } else {
+               /* for Overlay nodes or non-split Dynamic nodes */
+               root = nldr_node->root;
+       }
+
+       status1 = dbll_find_dsp_symbol(root.lib, sym_addr,
+                       offset_range, offset_output, sym_name);
+
+       /* If symbol not found, check dependent libraries */
+       if (!status1)
+               for (i = 0; i < root.dep_libs; i++) {
+                       status1 = dbll_find_dsp_symbol(
+                               root.dep_libs_tree[i].lib, sym_addr,
+                               offset_range, offset_output, sym_name);
+                       if (status1)
+                               /* Symbol found */
+                               break;
+               }
+       /* Check persistent libraries */
+       if (!status1)
+               for (i = 0; i < nldr_node->pers_libs; i++) {
+                       status1 = dbll_find_dsp_symbol(
+                               nldr_node->pers_lib_table[i].lib, sym_addr,
+                               offset_range, offset_output, sym_name);
+                       if (status1)
+                               /* Symbol found */
+                               break;
+               }
+
+       if (!status1) {
+               pr_debug("%s: Address 0x%x not found in range %d.\n",
+                                       __func__, sym_addr, offset_range);
+               status = -ESPIPE;
+       }
+
+       return status;
+}
+#endif
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
new file mode 100644 (file)
index 0000000..6e9441e
--- /dev/null
@@ -0,0 +1,3234 @@
+/*
+ * node.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge Node Manager.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/list.h>
+#include <dspbridge/memdefs.h>
+#include <dspbridge/proc.h>
+#include <dspbridge/strm.h>
+#include <dspbridge/sync.h>
+#include <dspbridge/ntfy.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/cmm.h>
+#include <dspbridge/cod.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/msg.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/dbdcd.h>
+#include <dspbridge/disp.h>
+#include <dspbridge/rms_sh.h>
+
+/*  ----------------------------------- Link Driver */
+#include <dspbridge/dspdefs.h>
+#include <dspbridge/dspioctl.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/gb.h>
+#include <dspbridge/uuidutil.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/nodepriv.h>
+#include <dspbridge/node.h>
+#include <dspbridge/dmm.h>
+
+/* Static/Dynamic Loader includes */
+#include <dspbridge/dbll.h>
+#include <dspbridge/nldr.h>
+
+#include <dspbridge/drv.h>
+#include <dspbridge/drvdefs.h>
+#include <dspbridge/resourcecleanup.h>
+#include <_tiomap.h>
+
+#include <dspbridge/dspdeh.h>
+
+#define HOSTPREFIX       "/host"
+#define PIPEPREFIX       "/dbpipe"
+
+#define MAX_INPUTS(h)  \
+               ((h)->dcd_props.obj_data.node_obj.ndb_props.num_input_streams)
+#define MAX_OUTPUTS(h) \
+               ((h)->dcd_props.obj_data.node_obj.ndb_props.num_output_streams)
+
+#define NODE_GET_PRIORITY(h) ((h)->prio)
+#define NODE_SET_PRIORITY(hnode, prio) ((hnode)->prio = prio)
+#define NODE_SET_STATE(hnode, state) ((hnode)->node_state = state)
+
+#define MAXPIPES       100     /* Max # of /pipe connections (CSL limit) */
+#define MAXDEVSUFFIXLEN 2      /* Max(Log base 10 of MAXPIPES, MAXSTREAMS) */
+
+#define PIPENAMELEN     (sizeof(PIPEPREFIX) + MAXDEVSUFFIXLEN)
+#define HOSTNAMELEN     (sizeof(HOSTPREFIX) + MAXDEVSUFFIXLEN)
+
+#define MAXDEVNAMELEN  32      /* dsp_ndbprops.ac_name size */
+#define CREATEPHASE    1
+#define EXECUTEPHASE   2
+#define DELETEPHASE    3
+
+/* Define default STRM parameters */
+/*
+ *  TBD: Put in header file, make global DSP_STRMATTRS with defaults,
+ *  or make defaults configurable.
+ */
+#define DEFAULTBUFSIZE         32
+#define DEFAULTNBUFS           2
+#define DEFAULTSEGID           0
+#define DEFAULTALIGNMENT       0
+#define DEFAULTTIMEOUT         10000
+
+#define RMSQUERYSERVER         0
+#define RMSCONFIGURESERVER     1
+#define RMSCREATENODE          2
+#define RMSEXECUTENODE         3
+#define RMSDELETENODE          4
+#define RMSCHANGENODEPRIORITY  5
+#define RMSREADMEMORY          6
+#define RMSWRITEMEMORY         7
+#define RMSCOPY                        8
+#define MAXTIMEOUT             2000
+
+#define NUMRMSFXNS             9
+
+#define PWR_TIMEOUT            500     /* default PWR timeout in msec */
+
+#define STACKSEGLABEL "L1DSRAM_HEAP"   /* Label for DSP Stack Segment Addr */
+
+/*
+ *  ======== node_mgr ========
+ */
+struct node_mgr {
+       struct dev_object *hdev_obj;    /* Device object */
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+       struct dcd_manager *hdcd_mgr;   /* Proc/Node data manager */
+       struct disp_object *disp_obj;   /* Node dispatcher */
+       struct lst_list *node_list;     /* List of all allocated nodes */
+       u32 num_nodes;          /* Number of nodes in node_list */
+       u32 num_created;        /* Number of nodes *created* on DSP */
+       struct gb_t_map *pipe_map;      /* Pipe connection bit map */
+       struct gb_t_map *pipe_done_map; /* Pipes that are half free */
+       struct gb_t_map *chnl_map;      /* Channel allocation bit map */
+       struct gb_t_map *dma_chnl_map;  /* DMA Channel allocation bit map */
+       struct gb_t_map *zc_chnl_map;   /* Zero-Copy Channel alloc bit map */
+       struct ntfy_object *ntfy_obj;   /* Manages registered notifications */
+       struct mutex node_mgr_lock;     /* For critical sections */
+       u32 ul_fxn_addrs[NUMRMSFXNS];   /* RMS function addresses */
+       struct msg_mgr *msg_mgr_obj;
+
+       /* Processor properties needed by Node Dispatcher */
+       u32 ul_num_chnls;       /* Total number of channels */
+       u32 ul_chnl_offset;     /* Offset of chnl ids rsvd for RMS */
+       u32 ul_chnl_buf_size;   /* Buffer size for data to RMS */
+       int proc_family;        /* eg, 5000 */
+       int proc_type;          /* eg, 5510 */
+       u32 udsp_word_size;     /* Size of DSP word on host bytes */
+       u32 udsp_data_mau_size; /* Size of DSP data MAU */
+       u32 udsp_mau_size;      /* Size of MAU */
+       s32 min_pri;            /* Minimum runtime priority for node */
+       s32 max_pri;            /* Maximum runtime priority for node */
+
+       struct strm_mgr *strm_mgr_obj;  /* STRM manager */
+
+       /* Loader properties */
+       struct nldr_object *nldr_obj;   /* Handle to loader */
+       struct node_ldr_fxns nldr_fxns; /* Handle to loader functions */
+       bool loader_init;       /* Loader Init function succeeded? */
+};
+
+/*
+ *  ======== connecttype ========
+ */
+enum connecttype {
+       NOTCONNECTED = 0,
+       NODECONNECT,
+       HOSTCONNECT,
+       DEVICECONNECT,
+};
+
+/*
+ *  ======== stream_chnl ========
+ */
+struct stream_chnl {
+       enum connecttype type;  /* Type of stream connection */
+       u32 dev_id;             /* pipe or channel id */
+};
+
+/*
+ *  ======== node_object ========
+ */
+struct node_object {
+       struct list_head list_elem;
+       struct node_mgr *hnode_mgr;     /* The manager of this node */
+       struct proc_object *hprocessor; /* Back pointer to processor */
+       struct dsp_uuid node_uuid;      /* Node's ID */
+       s32 prio;               /* Node's current priority */
+       u32 utimeout;           /* Timeout for blocking NODE calls */
+       u32 heap_size;          /* Heap Size */
+       u32 udsp_heap_virt_addr;        /* Heap Size */
+       u32 ugpp_heap_virt_addr;        /* Heap Size */
+       enum node_type ntype;   /* Type of node: message, task, etc */
+       enum node_state node_state;     /* NODE_ALLOCATED, NODE_CREATED, ... */
+       u32 num_inputs;         /* Current number of inputs */
+       u32 num_outputs;        /* Current number of outputs */
+       u32 max_input_index;    /* Current max input stream index */
+       u32 max_output_index;   /* Current max output stream index */
+       struct stream_chnl *inputs;     /* Node's input streams */
+       struct stream_chnl *outputs;    /* Node's output streams */
+       struct node_createargs create_args;     /* Args for node create func */
+       nodeenv node_env;       /* Environment returned by RMS */
+       struct dcd_genericobj dcd_props;        /* Node properties from DCD */
+       struct dsp_cbdata *pargs;       /* Optional args to pass to node */
+       struct ntfy_object *ntfy_obj;   /* Manages registered notifications */
+       char *pstr_dev_name;    /* device name, if device node */
+       struct sync_object *sync_done;  /* Synchronize node_terminate */
+       s32 exit_status;        /* execute function return status */
+
+       /* Information needed for node_get_attr() */
+       void *device_owner;     /* If dev node, task that owns it */
+       u32 num_gpp_inputs;     /* Current # of from GPP streams */
+       u32 num_gpp_outputs;    /* Current # of to GPP streams */
+       /* Current stream connections */
+       struct dsp_streamconnect *stream_connect;
+
+       /* Message queue */
+       struct msg_queue *msg_queue_obj;
+
+       /* These fields used for SM messaging */
+       struct cmm_xlatorobject *xlator;        /* Node's SM addr translator */
+
+       /* Handle to pass to dynamic loader */
+       struct nldr_nodeobject *nldr_node_obj;
+       bool loaded;            /* Code is (dynamically) loaded */
+       bool phase_split;       /* Phases split in many libs or ovly */
+
+};
+
+/* Default buffer attributes */
+static struct dsp_bufferattr node_dfltbufattrs = {
+       0,                      /* cb_struct */
+       1,                      /* segment_id */
+       0,                      /* buf_alignment */
+};
+
+static void delete_node(struct node_object *hnode,
+                       struct process_context *pr_ctxt);
+static void delete_node_mgr(struct node_mgr *hnode_mgr);
+static void fill_stream_connect(struct node_object *node1,
+                               struct node_object *node2, u32 stream1,
+                               u32 stream2);
+static void fill_stream_def(struct node_object *hnode,
+                           struct node_strmdef *pstrm_def,
+                           struct dsp_strmattr *pattrs);
+static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream);
+static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr,
+                                 u32 phase);
+static int get_node_props(struct dcd_manager *hdcd_mgr,
+                                struct node_object *hnode,
+                                const struct dsp_uuid *node_uuid,
+                                struct dcd_genericobj *dcd_prop);
+static int get_proc_props(struct node_mgr *hnode_mgr,
+                                struct dev_object *hdev_obj);
+static int get_rms_fxns(struct node_mgr *hnode_mgr);
+static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr,
+               u32 ul_num_bytes, u32 mem_space);
+static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf,
+                    u32 ul_num_bytes, u32 mem_space);
+
+static u32 refs;               /* module reference count */
+
+/* Dynamic loader functions. */
+static struct node_ldr_fxns nldr_fxns = {
+       nldr_allocate,
+       nldr_create,
+       nldr_delete,
+       nldr_exit,
+       nldr_get_fxn_addr,
+       nldr_init,
+       nldr_load,
+       nldr_unload,
+};
+
+enum node_state node_get_state(void *hnode)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       if (!pnode)
+               return -1;
+       else
+               return pnode->node_state;
+}
+
+/*
+ *  ======== node_allocate ========
+ *  Purpose:
+ *      Allocate GPP resources to manage a node on the DSP.
+ */
+int node_allocate(struct proc_object *hprocessor,
+                       const struct dsp_uuid *node_uuid,
+                       const struct dsp_cbdata *pargs,
+                       const struct dsp_nodeattrin *attr_in,
+                       struct node_res_object **noderes,
+                       struct process_context *pr_ctxt)
+{
+       struct node_mgr *hnode_mgr;
+       struct dev_object *hdev_obj;
+       struct node_object *pnode = NULL;
+       enum node_type node_type = NODE_TASK;
+       struct node_msgargs *pmsg_args;
+       struct node_taskargs *ptask_args;
+       u32 num_streams;
+       struct bridge_drv_interface *intf_fxns;
+       int status = 0;
+       struct cmm_object *hcmm_mgr = NULL;     /* Shared memory manager hndl */
+       u32 proc_id;
+       u32 pul_value;
+       u32 dynext_base;
+       u32 off_set = 0;
+       u32 ul_stack_seg_addr, ul_stack_seg_val;
+       u32 ul_gpp_mem_base;
+       struct cfg_hostres *host_res;
+       struct bridge_dev_context *pbridge_context;
+       u32 mapped_addr = 0;
+       u32 map_attrs = 0x0;
+       struct dsp_processorstate proc_state;
+#ifdef DSP_DMM_DEBUG
+       struct dmm_object *dmm_mgr;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+#endif
+
+       void *node_res;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hprocessor != NULL);
+       DBC_REQUIRE(noderes != NULL);
+       DBC_REQUIRE(node_uuid != NULL);
+
+       *noderes = NULL;
+
+       status = proc_get_processor_id(hprocessor, &proc_id);
+
+       if (proc_id != DSP_UNIT)
+               goto func_end;
+
+       status = proc_get_dev_object(hprocessor, &hdev_obj);
+       if (!status) {
+               status = dev_get_node_manager(hdev_obj, &hnode_mgr);
+               if (hnode_mgr == NULL)
+                       status = -EPERM;
+
+       }
+
+       if (status)
+               goto func_end;
+
+       status = dev_get_bridge_context(hdev_obj, &pbridge_context);
+       if (!pbridge_context) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = proc_get_state(hprocessor, &proc_state,
+                               sizeof(struct dsp_processorstate));
+       if (status)
+               goto func_end;
+       /* If processor is in error state then don't attempt
+          to send the message */
+       if (proc_state.proc_state == PROC_ERROR) {
+               status = -EPERM;
+               goto func_end;
+       }
+
+       /* Assuming that 0 is not a valid function address */
+       if (hnode_mgr->ul_fxn_addrs[0] == 0) {
+               /* No RMS on target - we currently can't handle this */
+               pr_err("%s: Failed, no RMS in base image\n", __func__);
+               status = -EPERM;
+       } else {
+               /* Validate attr_in fields, if non-NULL */
+               if (attr_in) {
+                       /* Check if attr_in->prio is within range */
+                       if (attr_in->prio < hnode_mgr->min_pri ||
+                           attr_in->prio > hnode_mgr->max_pri)
+                               status = -EDOM;
+               }
+       }
+       /* Allocate node object and fill in */
+       if (status)
+               goto func_end;
+
+       pnode = kzalloc(sizeof(struct node_object), GFP_KERNEL);
+       if (pnode == NULL) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       pnode->hnode_mgr = hnode_mgr;
+       /* This critical section protects get_node_props */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       /* Get dsp_ndbprops from node database */
+       status = get_node_props(hnode_mgr->hdcd_mgr, pnode, node_uuid,
+                               &(pnode->dcd_props));
+       if (status)
+               goto func_cont;
+
+       pnode->node_uuid = *node_uuid;
+       pnode->hprocessor = hprocessor;
+       pnode->ntype = pnode->dcd_props.obj_data.node_obj.ndb_props.ntype;
+       pnode->utimeout = pnode->dcd_props.obj_data.node_obj.ndb_props.utimeout;
+       pnode->prio = pnode->dcd_props.obj_data.node_obj.ndb_props.prio;
+
+       /* Currently only C64 DSP builds support Node Dynamic * heaps */
+       /* Allocate memory for node heap */
+       pnode->create_args.asa.task_arg_obj.heap_size = 0;
+       pnode->create_args.asa.task_arg_obj.udsp_heap_addr = 0;
+       pnode->create_args.asa.task_arg_obj.udsp_heap_res_addr = 0;
+       pnode->create_args.asa.task_arg_obj.ugpp_heap_addr = 0;
+       if (!attr_in)
+               goto func_cont;
+
+       /* Check if we have a user allocated node heap */
+       if (!(attr_in->pgpp_virt_addr))
+               goto func_cont;
+
+       /* check for page aligned Heap size */
+       if (((attr_in->heap_size) & (PG_SIZE4K - 1))) {
+               pr_err("%s: node heap size not aligned to 4K, size = 0x%x \n",
+                      __func__, attr_in->heap_size);
+               status = -EINVAL;
+       } else {
+               pnode->create_args.asa.task_arg_obj.heap_size =
+                   attr_in->heap_size;
+               pnode->create_args.asa.task_arg_obj.ugpp_heap_addr =
+                   (u32) attr_in->pgpp_virt_addr;
+       }
+       if (status)
+               goto func_cont;
+
+       status = proc_reserve_memory(hprocessor,
+                                    pnode->create_args.asa.task_arg_obj.
+                                    heap_size + PAGE_SIZE,
+                                    (void **)&(pnode->create_args.asa.
+                                       task_arg_obj.udsp_heap_res_addr),
+                                    pr_ctxt);
+       if (status) {
+               pr_err("%s: Failed to reserve memory for heap: 0x%x\n",
+                      __func__, status);
+               goto func_cont;
+       }
+#ifdef DSP_DMM_DEBUG
+       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = DSP_EHANDLE;
+               goto func_cont;
+       }
+
+       dmm_mem_map_dump(dmm_mgr);
+#endif
+
+       map_attrs |= DSP_MAPLITTLEENDIAN;
+       map_attrs |= DSP_MAPELEMSIZE32;
+       map_attrs |= DSP_MAPVIRTUALADDR;
+       status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr,
+                         pnode->create_args.asa.task_arg_obj.heap_size,
+                         (void *)pnode->create_args.asa.task_arg_obj.
+                         udsp_heap_res_addr, (void **)&mapped_addr, map_attrs,
+                         pr_ctxt);
+       if (status)
+               pr_err("%s: Failed to map memory for Heap: 0x%x\n",
+                      __func__, status);
+       else
+               pnode->create_args.asa.task_arg_obj.udsp_heap_addr =
+                   (u32) mapped_addr;
+
+func_cont:
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+       if (attr_in != NULL) {
+               /* Overrides of NBD properties */
+               pnode->utimeout = attr_in->utimeout;
+               pnode->prio = attr_in->prio;
+       }
+       /* Create object to manage notifications */
+       if (!status) {
+               pnode->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
+                                                       GFP_KERNEL);
+               if (pnode->ntfy_obj)
+                       ntfy_init(pnode->ntfy_obj);
+               else
+                       status = -ENOMEM;
+       }
+
+       if (!status) {
+               node_type = node_get_type(pnode);
+               /*  Allocate dsp_streamconnect array for device, task, and
+                *  dais socket nodes. */
+               if (node_type != NODE_MESSAGE) {
+                       num_streams = MAX_INPUTS(pnode) + MAX_OUTPUTS(pnode);
+                       pnode->stream_connect = kzalloc(num_streams *
+                                       sizeof(struct dsp_streamconnect),
+                                       GFP_KERNEL);
+                       if (num_streams > 0 && pnode->stream_connect == NULL)
+                               status = -ENOMEM;
+
+               }
+               if (!status && (node_type == NODE_TASK ||
+                                             node_type == NODE_DAISSOCKET)) {
+                       /* Allocate arrays for maintainig stream connections */
+                       pnode->inputs = kzalloc(MAX_INPUTS(pnode) *
+                                       sizeof(struct stream_chnl), GFP_KERNEL);
+                       pnode->outputs = kzalloc(MAX_OUTPUTS(pnode) *
+                                       sizeof(struct stream_chnl), GFP_KERNEL);
+                       ptask_args = &(pnode->create_args.asa.task_arg_obj);
+                       ptask_args->strm_in_def = kzalloc(MAX_INPUTS(pnode) *
+                                               sizeof(struct node_strmdef),
+                                               GFP_KERNEL);
+                       ptask_args->strm_out_def = kzalloc(MAX_OUTPUTS(pnode) *
+                                               sizeof(struct node_strmdef),
+                                               GFP_KERNEL);
+                       if ((MAX_INPUTS(pnode) > 0 && (pnode->inputs == NULL ||
+                                                      ptask_args->strm_in_def
+                                                      == NULL))
+                           || (MAX_OUTPUTS(pnode) > 0
+                               && (pnode->outputs == NULL
+                                   || ptask_args->strm_out_def == NULL)))
+                               status = -ENOMEM;
+               }
+       }
+       if (!status && (node_type != NODE_DEVICE)) {
+               /* Create an event that will be posted when RMS_EXIT is
+                * received. */
+               pnode->sync_done = kzalloc(sizeof(struct sync_object),
+                                                               GFP_KERNEL);
+               if (pnode->sync_done)
+                       sync_init_event(pnode->sync_done);
+               else
+                       status = -ENOMEM;
+
+               if (!status) {
+                       /*Get the shared mem mgr for this nodes dev object */
+                       status = cmm_get_handle(hprocessor, &hcmm_mgr);
+                       if (!status) {
+                               /* Allocate a SM addr translator for this node
+                                * w/ deflt attr */
+                               status = cmm_xlator_create(&pnode->xlator,
+                                                          hcmm_mgr, NULL);
+                       }
+               }
+               if (!status) {
+                       /* Fill in message args */
+                       if ((pargs != NULL) && (pargs->cb_data > 0)) {
+                               pmsg_args =
+                                   &(pnode->create_args.asa.node_msg_args);
+                               pmsg_args->pdata = kzalloc(pargs->cb_data,
+                                                               GFP_KERNEL);
+                               if (pmsg_args->pdata == NULL) {
+                                       status = -ENOMEM;
+                               } else {
+                                       pmsg_args->arg_length = pargs->cb_data;
+                                       memcpy(pmsg_args->pdata,
+                                              pargs->node_data,
+                                              pargs->cb_data);
+                               }
+                       }
+               }
+       }
+
+       if (!status && node_type != NODE_DEVICE) {
+               /* Create a message queue for this node */
+               intf_fxns = hnode_mgr->intf_fxns;
+               status =
+                   (*intf_fxns->pfn_msg_create_queue) (hnode_mgr->msg_mgr_obj,
+                                                       &pnode->msg_queue_obj,
+                                                       0,
+                                                       pnode->create_args.asa.
+                                                       node_msg_args.max_msgs,
+                                                       pnode);
+       }
+
+       if (!status) {
+               /* Create object for dynamic loading */
+
+               status = hnode_mgr->nldr_fxns.pfn_allocate(hnode_mgr->nldr_obj,
+                                                          (void *)pnode,
+                                                          &pnode->dcd_props.
+                                                          obj_data.node_obj,
+                                                          &pnode->
+                                                          nldr_node_obj,
+                                                          &pnode->phase_split);
+       }
+
+       /* Compare value read from Node Properties and check if it is same as
+        * STACKSEGLABEL, if yes read the Address of STACKSEGLABEL, calculate
+        * GPP Address, Read the value in that address and override the
+        * stack_seg value in task args */
+       if (!status &&
+           (char *)pnode->dcd_props.obj_data.node_obj.ndb_props.
+           stack_seg_name != NULL) {
+               if (strcmp((char *)
+                          pnode->dcd_props.obj_data.node_obj.ndb_props.
+                          stack_seg_name, STACKSEGLABEL) == 0) {
+                       status =
+                           hnode_mgr->nldr_fxns.
+                           pfn_get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG",
+                                            &dynext_base);
+                       if (status)
+                               pr_err("%s: Failed to get addr for DYNEXT_BEG"
+                                      " status = 0x%x\n", __func__, status);
+
+                       status =
+                           hnode_mgr->nldr_fxns.
+                           pfn_get_fxn_addr(pnode->nldr_node_obj,
+                                            "L1DSRAM_HEAP", &pul_value);
+
+                       if (status)
+                               pr_err("%s: Failed to get addr for L1DSRAM_HEAP"
+                                      " status = 0x%x\n", __func__, status);
+
+                       host_res = pbridge_context->resources;
+                       if (!host_res)
+                               status = -EPERM;
+
+                       if (status) {
+                               pr_err("%s: Failed to get host resource, status"
+                                      " = 0x%x\n", __func__, status);
+                               goto func_end;
+                       }
+
+                       ul_gpp_mem_base = (u32) host_res->dw_mem_base[1];
+                       off_set = pul_value - dynext_base;
+                       ul_stack_seg_addr = ul_gpp_mem_base + off_set;
+                       ul_stack_seg_val = readl(ul_stack_seg_addr);
+
+                       dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr ="
+                               " 0x%x\n", __func__, ul_stack_seg_val,
+                               ul_stack_seg_addr);
+
+                       pnode->create_args.asa.task_arg_obj.stack_seg =
+                           ul_stack_seg_val;
+
+               }
+       }
+
+       if (!status) {
+               /* Add the node to the node manager's list of allocated
+                * nodes. */
+               lst_init_elem((struct list_head *)pnode);
+               NODE_SET_STATE(pnode, NODE_ALLOCATED);
+
+               mutex_lock(&hnode_mgr->node_mgr_lock);
+
+               lst_put_tail(hnode_mgr->node_list, (struct list_head *) pnode);
+                       ++(hnode_mgr->num_nodes);
+
+               /* Exit critical section */
+               mutex_unlock(&hnode_mgr->node_mgr_lock);
+
+               /* Preset this to assume phases are split
+                * (for overlay and dll) */
+               pnode->phase_split = true;
+
+               /* Notify all clients registered for DSP_NODESTATECHANGE. */
+               proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE);
+       } else {
+               /* Cleanup */
+               if (pnode)
+                       delete_node(pnode, pr_ctxt);
+
+       }
+
+       if (!status) {
+               status = drv_insert_node_res_element(pnode, &node_res, pr_ctxt);
+               if (status) {
+                       delete_node(pnode, pr_ctxt);
+                       goto func_end;
+               }
+
+               *noderes = (struct node_res_object *)node_res;
+               drv_proc_node_update_heap_status(node_res, true);
+               drv_proc_node_update_status(node_res, true);
+       }
+       DBC_ENSURE((status && *noderes == NULL) || (!status && *noderes));
+func_end:
+       dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p "
+               "node_res: %p status: 0x%x\n", __func__, hprocessor,
+               node_uuid, pargs, attr_in, noderes, status);
+       return status;
+}
+
+/*
+ *  ======== node_alloc_msg_buf ========
+ *  Purpose:
+ *      Allocates buffer for zero copy messaging.
+ */
+DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize,
+                        struct dsp_bufferattr *pattr,
+                        u8 **pbuffer)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       int status = 0;
+       bool va_flag = false;
+       bool set_info;
+       u32 proc_id;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pbuffer != NULL);
+
+       DBC_REQUIRE(usize > 0);
+
+       if (!pnode)
+               status = -EFAULT;
+       else if (node_get_type(pnode) == NODE_DEVICE)
+               status = -EPERM;
+
+       if (status)
+               goto func_end;
+
+       if (pattr == NULL)
+               pattr = &node_dfltbufattrs;     /* set defaults */
+
+       status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+       if (proc_id != DSP_UNIT) {
+               DBC_ASSERT(NULL);
+               goto func_end;
+       }
+       /*  If segment ID includes MEM_SETVIRTUALSEGID then pbuffer is a
+        *  virt  address, so set this info in this node's translator
+        *  object for  future ref. If MEM_GETVIRTUALSEGID then retrieve
+        *  virtual address  from node's translator. */
+       if ((pattr->segment_id & MEM_SETVIRTUALSEGID) ||
+           (pattr->segment_id & MEM_GETVIRTUALSEGID)) {
+               va_flag = true;
+               set_info = (pattr->segment_id & MEM_SETVIRTUALSEGID) ?
+                   true : false;
+               /* Clear mask bits */
+               pattr->segment_id &= ~MEM_MASKVIRTUALSEGID;
+               /* Set/get this node's translators virtual address base/size */
+               status = cmm_xlator_info(pnode->xlator, pbuffer, usize,
+                                        pattr->segment_id, set_info);
+       }
+       if (!status && (!va_flag)) {
+               if (pattr->segment_id != 1) {
+                       /* Node supports single SM segment only. */
+                       status = -EBADR;
+               }
+               /*  Arbitrary SM buffer alignment not supported for host side
+                *  allocs, but guaranteed for the following alignment
+                *  values. */
+               switch (pattr->buf_alignment) {
+               case 0:
+               case 1:
+               case 2:
+               case 4:
+                       break;
+               default:
+                       /* alignment value not suportted */
+                       status = -EPERM;
+                       break;
+               }
+               if (!status) {
+                       /* allocate physical buffer from seg_id in node's
+                        * translator */
+                       (void)cmm_xlator_alloc_buf(pnode->xlator, pbuffer,
+                                                  usize);
+                       if (*pbuffer == NULL) {
+                               pr_err("%s: error - Out of shared memory\n",
+                                      __func__);
+                               status = -ENOMEM;
+                       }
+               }
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== node_change_priority ========
+ *  Purpose:
+ *      Change the priority of a node in the allocated state, or that is
+ *      currently running or paused on the target.
+ */
+int node_change_priority(struct node_object *hnode, s32 prio)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       struct node_mgr *hnode_mgr = NULL;
+       enum node_type node_type;
+       enum node_state state;
+       int status = 0;
+       u32 proc_id;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!hnode || !hnode->hnode_mgr) {
+               status = -EFAULT;
+       } else {
+               hnode_mgr = hnode->hnode_mgr;
+               node_type = node_get_type(hnode);
+               if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
+                       status = -EPERM;
+               else if (prio < hnode_mgr->min_pri || prio > hnode_mgr->max_pri)
+                       status = -EDOM;
+       }
+       if (status)
+               goto func_end;
+
+       /* Enter critical section */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       state = node_get_state(hnode);
+       if (state == NODE_ALLOCATED || state == NODE_PAUSED) {
+               NODE_SET_PRIORITY(hnode, prio);
+       } else {
+               if (state != NODE_RUNNING) {
+                       status = -EBADR;
+                       goto func_cont;
+               }
+               status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+               if (proc_id == DSP_UNIT) {
+                       status =
+                           disp_node_change_priority(hnode_mgr->disp_obj,
+                                                     hnode,
+                                                     hnode_mgr->ul_fxn_addrs
+                                                     [RMSCHANGENODEPRIORITY],
+                                                     hnode->node_env, prio);
+               }
+               if (status >= 0)
+                       NODE_SET_PRIORITY(hnode, prio);
+
+       }
+func_cont:
+       /* Leave critical section */
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+func_end:
+       return status;
+}
+
+/*
+ *  ======== node_connect ========
+ *  Purpose:
+ *      Connect two nodes on the DSP, or a node on the DSP to the GPP.
+ */
+int node_connect(struct node_object *node1, u32 stream1,
+                       struct node_object *node2,
+                       u32 stream2, struct dsp_strmattr *pattrs,
+                       struct dsp_cbdata *conn_param)
+{
+       struct node_mgr *hnode_mgr;
+       char *pstr_dev_name = NULL;
+       enum node_type node1_type = NODE_TASK;
+       enum node_type node2_type = NODE_TASK;
+       struct node_strmdef *pstrm_def;
+       struct node_strmdef *input = NULL;
+       struct node_strmdef *output = NULL;
+       struct node_object *dev_node_obj;
+       struct node_object *hnode;
+       struct stream_chnl *pstream;
+       u32 pipe_id = GB_NOBITS;
+       u32 chnl_id = GB_NOBITS;
+       s8 chnl_mode;
+       u32 dw_length;
+       int status = 0;
+       DBC_REQUIRE(refs > 0);
+
+       if ((node1 != (struct node_object *)DSP_HGPPNODE && !node1) ||
+           (node2 != (struct node_object *)DSP_HGPPNODE && !node2))
+               status = -EFAULT;
+
+       if (!status) {
+               /* The two nodes must be on the same processor */
+               if (node1 != (struct node_object *)DSP_HGPPNODE &&
+                   node2 != (struct node_object *)DSP_HGPPNODE &&
+                   node1->hnode_mgr != node2->hnode_mgr)
+                       status = -EPERM;
+               /* Cannot connect a node to itself */
+               if (node1 == node2)
+                       status = -EPERM;
+
+       }
+       if (!status) {
+               /* node_get_type() will return NODE_GPP if hnode =
+                * DSP_HGPPNODE. */
+               node1_type = node_get_type(node1);
+               node2_type = node_get_type(node2);
+               /* Check stream indices ranges */
+               if ((node1_type != NODE_GPP && node1_type != NODE_DEVICE &&
+                    stream1 >= MAX_OUTPUTS(node1)) || (node2_type != NODE_GPP
+                                                         && node2_type !=
+                                                         NODE_DEVICE
+                                                         && stream2 >=
+                                                         MAX_INPUTS(node2)))
+                       status = -EINVAL;
+       }
+       if (!status) {
+               /*
+                *  Only the following types of connections are allowed:
+                *      task/dais socket < == > task/dais socket
+                *      task/dais socket < == > device
+                *      task/dais socket < == > GPP
+                *
+                *  ie, no message nodes, and at least one task or dais
+                *  socket node.
+                */
+               if (node1_type == NODE_MESSAGE || node2_type == NODE_MESSAGE ||
+                   (node1_type != NODE_TASK && node1_type != NODE_DAISSOCKET &&
+                    node2_type != NODE_TASK && node2_type != NODE_DAISSOCKET))
+                       status = -EPERM;
+       }
+       /*
+        * Check stream mode. Default is STRMMODE_PROCCOPY.
+        */
+       if (!status && pattrs) {
+               if (pattrs->strm_mode != STRMMODE_PROCCOPY)
+                       status = -EPERM;        /* illegal stream mode */
+
+       }
+       if (status)
+               goto func_end;
+
+       if (node1_type != NODE_GPP) {
+               hnode_mgr = node1->hnode_mgr;
+       } else {
+               DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE);
+               hnode_mgr = node2->hnode_mgr;
+       }
+       /* Enter critical section */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       /* Nodes must be in the allocated state */
+       if (node1_type != NODE_GPP && node_get_state(node1) != NODE_ALLOCATED)
+               status = -EBADR;
+
+       if (node2_type != NODE_GPP && node_get_state(node2) != NODE_ALLOCATED)
+               status = -EBADR;
+
+       if (!status) {
+               /*  Check that stream indices for task and dais socket nodes
+                *  are not already be used. (Device nodes checked later) */
+               if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) {
+                       output =
+                           &(node1->create_args.asa.
+                             task_arg_obj.strm_out_def[stream1]);
+                       if (output->sz_device != NULL)
+                               status = -EISCONN;
+
+               }
+               if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) {
+                       input =
+                           &(node2->create_args.asa.
+                             task_arg_obj.strm_in_def[stream2]);
+                       if (input->sz_device != NULL)
+                               status = -EISCONN;
+
+               }
+       }
+       /* Connecting two task nodes? */
+       if (!status && ((node1_type == NODE_TASK ||
+                                      node1_type == NODE_DAISSOCKET)
+                                     && (node2_type == NODE_TASK
+                                         || node2_type == NODE_DAISSOCKET))) {
+               /* Find available pipe */
+               pipe_id = gb_findandset(hnode_mgr->pipe_map);
+               if (pipe_id == GB_NOBITS) {
+                       status = -ECONNREFUSED;
+               } else {
+                       node1->outputs[stream1].type = NODECONNECT;
+                       node2->inputs[stream2].type = NODECONNECT;
+                       node1->outputs[stream1].dev_id = pipe_id;
+                       node2->inputs[stream2].dev_id = pipe_id;
+                       output->sz_device = kzalloc(PIPENAMELEN + 1,
+                                                       GFP_KERNEL);
+                       input->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL);
+                       if (output->sz_device == NULL ||
+                           input->sz_device == NULL) {
+                               /* Undo the connection */
+                               kfree(output->sz_device);
+
+                               kfree(input->sz_device);
+
+                               output->sz_device = NULL;
+                               input->sz_device = NULL;
+                               gb_clear(hnode_mgr->pipe_map, pipe_id);
+                               status = -ENOMEM;
+                       } else {
+                               /* Copy "/dbpipe<pipId>" name to device names */
+                               sprintf(output->sz_device, "%s%d",
+                                       PIPEPREFIX, pipe_id);
+                               strcpy(input->sz_device, output->sz_device);
+                       }
+               }
+       }
+       /* Connecting task node to host? */
+       if (!status && (node1_type == NODE_GPP ||
+                                     node2_type == NODE_GPP)) {
+               if (node1_type == NODE_GPP) {
+                       chnl_mode = CHNL_MODETODSP;
+               } else {
+                       DBC_ASSERT(node2_type == NODE_GPP);
+                       chnl_mode = CHNL_MODEFROMDSP;
+               }
+               /*  Reserve a channel id. We need to put the name "/host<id>"
+                *  in the node's create_args, but the host
+                *  side channel will not be opened until DSPStream_Open is
+                *  called for this node. */
+               if (pattrs) {
+                       if (pattrs->strm_mode == STRMMODE_RDMA) {
+                               chnl_id =
+                                   gb_findandset(hnode_mgr->dma_chnl_map);
+                               /* dma chans are 2nd transport chnl set
+                                * ids(e.g. 16-31) */
+                               (chnl_id != GB_NOBITS) ?
+                                   (chnl_id =
+                                    chnl_id +
+                                    hnode_mgr->ul_num_chnls) : chnl_id;
+                       } else if (pattrs->strm_mode == STRMMODE_ZEROCOPY) {
+                               chnl_id = gb_findandset(hnode_mgr->zc_chnl_map);
+                               /* zero-copy chans are 3nd transport set
+                                * (e.g. 32-47) */
+                               (chnl_id != GB_NOBITS) ? (chnl_id = chnl_id +
+                                                         (2 *
+                                                          hnode_mgr->
+                                                          ul_num_chnls))
+                                   : chnl_id;
+                       } else {        /* must be PROCCOPY */
+                               DBC_ASSERT(pattrs->strm_mode ==
+                                          STRMMODE_PROCCOPY);
+                               chnl_id = gb_findandset(hnode_mgr->chnl_map);
+                               /* e.g. 0-15 */
+                       }
+               } else {
+                       /* default to PROCCOPY */
+                       chnl_id = gb_findandset(hnode_mgr->chnl_map);
+               }
+               if (chnl_id == GB_NOBITS) {
+                       status = -ECONNREFUSED;
+                       goto func_cont2;
+               }
+               pstr_dev_name = kzalloc(HOSTNAMELEN + 1, GFP_KERNEL);
+               if (pstr_dev_name != NULL)
+                       goto func_cont2;
+
+               if (pattrs) {
+                       if (pattrs->strm_mode == STRMMODE_RDMA) {
+                               gb_clear(hnode_mgr->dma_chnl_map, chnl_id -
+                                        hnode_mgr->ul_num_chnls);
+                       } else if (pattrs->strm_mode == STRMMODE_ZEROCOPY) {
+                               gb_clear(hnode_mgr->zc_chnl_map, chnl_id -
+                                        (2 * hnode_mgr->ul_num_chnls));
+                       } else {
+                               DBC_ASSERT(pattrs->strm_mode ==
+                                          STRMMODE_PROCCOPY);
+                               gb_clear(hnode_mgr->chnl_map, chnl_id);
+                       }
+               } else {
+                       gb_clear(hnode_mgr->chnl_map, chnl_id);
+               }
+               status = -ENOMEM;
+func_cont2:
+               if (!status) {
+                       if (node1 == (struct node_object *)DSP_HGPPNODE) {
+                               node2->inputs[stream2].type = HOSTCONNECT;
+                               node2->inputs[stream2].dev_id = chnl_id;
+                               input->sz_device = pstr_dev_name;
+                       } else {
+                               node1->outputs[stream1].type = HOSTCONNECT;
+                               node1->outputs[stream1].dev_id = chnl_id;
+                               output->sz_device = pstr_dev_name;
+                       }
+                       sprintf(pstr_dev_name, "%s%d", HOSTPREFIX, chnl_id);
+               }
+       }
+       /* Connecting task node to device node? */
+       if (!status && ((node1_type == NODE_DEVICE) ||
+                                     (node2_type == NODE_DEVICE))) {
+               if (node2_type == NODE_DEVICE) {
+                       /* node1 == > device */
+                       dev_node_obj = node2;
+                       hnode = node1;
+                       pstream = &(node1->outputs[stream1]);
+                       pstrm_def = output;
+               } else {
+                       /* device == > node2 */
+                       dev_node_obj = node1;
+                       hnode = node2;
+                       pstream = &(node2->inputs[stream2]);
+                       pstrm_def = input;
+               }
+               /* Set up create args */
+               pstream->type = DEVICECONNECT;
+               dw_length = strlen(dev_node_obj->pstr_dev_name);
+               if (conn_param != NULL) {
+                       pstrm_def->sz_device = kzalloc(dw_length + 1 +
+                                                       conn_param->cb_data,
+                                                       GFP_KERNEL);
+               } else {
+                       pstrm_def->sz_device = kzalloc(dw_length + 1,
+                                                       GFP_KERNEL);
+               }
+               if (pstrm_def->sz_device == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       /* Copy device name */
+                       strncpy(pstrm_def->sz_device,
+                               dev_node_obj->pstr_dev_name, dw_length);
+                       if (conn_param != NULL) {
+                               strncat(pstrm_def->sz_device,
+                                       (char *)conn_param->node_data,
+                                       (u32) conn_param->cb_data);
+                       }
+                       dev_node_obj->device_owner = hnode;
+               }
+       }
+       if (!status) {
+               /* Fill in create args */
+               if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) {
+                       node1->create_args.asa.task_arg_obj.num_outputs++;
+                       fill_stream_def(node1, output, pattrs);
+               }
+               if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) {
+                       node2->create_args.asa.task_arg_obj.num_inputs++;
+                       fill_stream_def(node2, input, pattrs);
+               }
+               /* Update node1 and node2 stream_connect */
+               if (node1_type != NODE_GPP && node1_type != NODE_DEVICE) {
+                       node1->num_outputs++;
+                       if (stream1 > node1->max_output_index)
+                               node1->max_output_index = stream1;
+
+               }
+               if (node2_type != NODE_GPP && node2_type != NODE_DEVICE) {
+                       node2->num_inputs++;
+                       if (stream2 > node2->max_input_index)
+                               node2->max_input_index = stream2;
+
+               }
+               fill_stream_connect(node1, node2, stream1, stream2);
+       }
+       /* end of sync_enter_cs */
+       /* Exit critical section */
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+func_end:
+       dev_dbg(bridge, "%s: node1: %p stream1: %d node2: %p stream2: %d"
+               "pattrs: %p status: 0x%x\n", __func__, node1,
+               stream1, node2, stream2, pattrs, status);
+       return status;
+}
+
+/*
+ *  ======== node_create ========
+ *  Purpose:
+ *      Create a node on the DSP by remotely calling the node's create function.
+ */
+int node_create(struct node_object *hnode)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       struct node_mgr *hnode_mgr;
+       struct bridge_drv_interface *intf_fxns;
+       u32 ul_create_fxn;
+       enum node_type node_type;
+       int status = 0;
+       int status1 = 0;
+       struct dsp_cbdata cb_data;
+       u32 proc_id = 255;
+       struct dsp_processorstate proc_state;
+       struct proc_object *hprocessor;
+#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
+       struct dspbridge_platform_data *pdata =
+           omap_dspbridge_dev->dev.platform_data;
+#endif
+
+       DBC_REQUIRE(refs > 0);
+       if (!pnode) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       hprocessor = hnode->hprocessor;
+       status = proc_get_state(hprocessor, &proc_state,
+                               sizeof(struct dsp_processorstate));
+       if (status)
+               goto func_end;
+       /* If processor is in error state then don't attempt to create
+          new node */
+       if (proc_state.proc_state == PROC_ERROR) {
+               status = -EPERM;
+               goto func_end;
+       }
+       /* create struct dsp_cbdata struct for PWR calls */
+       cb_data.cb_data = PWR_TIMEOUT;
+       node_type = node_get_type(hnode);
+       hnode_mgr = hnode->hnode_mgr;
+       intf_fxns = hnode_mgr->intf_fxns;
+       /* Get access to node dispatcher */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       /* Check node state */
+       if (node_get_state(hnode) != NODE_ALLOCATED)
+               status = -EBADR;
+
+       if (!status)
+               status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+
+       if (status)
+               goto func_cont2;
+
+       if (proc_id != DSP_UNIT)
+               goto func_cont2;
+
+       /* Make sure streams are properly connected */
+       if ((hnode->num_inputs && hnode->max_input_index >
+            hnode->num_inputs - 1) ||
+           (hnode->num_outputs && hnode->max_output_index >
+            hnode->num_outputs - 1))
+               status = -ENOTCONN;
+
+       if (!status) {
+               /* If node's create function is not loaded, load it */
+               /* Boost the OPP level to max level that DSP can be requested */
+#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
+               if (pdata->cpu_set_freq)
+                       (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP3]);
+#endif
+               status = hnode_mgr->nldr_fxns.pfn_load(hnode->nldr_node_obj,
+                                                      NLDR_CREATE);
+               /* Get address of node's create function */
+               if (!status) {
+                       hnode->loaded = true;
+                       if (node_type != NODE_DEVICE) {
+                               status = get_fxn_address(hnode, &ul_create_fxn,
+                                                        CREATEPHASE);
+                       }
+               } else {
+                       pr_err("%s: failed to load create code: 0x%x\n",
+                              __func__, status);
+               }
+               /* Request the lowest OPP level */
+#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
+               if (pdata->cpu_set_freq)
+                       (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
+#endif
+               /* Get address of iAlg functions, if socket node */
+               if (!status) {
+                       if (node_type == NODE_DAISSOCKET) {
+                               status = hnode_mgr->nldr_fxns.pfn_get_fxn_addr
+                                   (hnode->nldr_node_obj,
+                                    hnode->dcd_props.obj_data.node_obj.
+                                    pstr_i_alg_name,
+                                    &hnode->create_args.asa.
+                                    task_arg_obj.ul_dais_arg);
+                       }
+               }
+       }
+       if (!status) {
+               if (node_type != NODE_DEVICE) {
+                       status = disp_node_create(hnode_mgr->disp_obj, hnode,
+                                                 hnode_mgr->ul_fxn_addrs
+                                                 [RMSCREATENODE],
+                                                 ul_create_fxn,
+                                                 &(hnode->create_args),
+                                                 &(hnode->node_env));
+                       if (status >= 0) {
+                               /* Set the message queue id to the node env
+                                * pointer */
+                               intf_fxns = hnode_mgr->intf_fxns;
+                               (*intf_fxns->pfn_msg_set_queue_id) (hnode->
+                                                       msg_queue_obj,
+                                                       hnode->node_env);
+                       }
+               }
+       }
+       /*  Phase II/Overlays: Create, execute, delete phases  possibly in
+        *  different files/sections. */
+       if (hnode->loaded && hnode->phase_split) {
+               /* If create code was dynamically loaded, we can now unload
+                * it. */
+               status1 = hnode_mgr->nldr_fxns.pfn_unload(hnode->nldr_node_obj,
+                                                         NLDR_CREATE);
+               hnode->loaded = false;
+       }
+       if (status1)
+               pr_err("%s: Failed to unload create code: 0x%x\n",
+                      __func__, status1);
+func_cont2:
+       /* Update node state and node manager state */
+       if (status >= 0) {
+               NODE_SET_STATE(hnode, NODE_CREATED);
+               hnode_mgr->num_created++;
+               goto func_cont;
+       }
+       if (status != -EBADR) {
+               /* Put back in NODE_ALLOCATED state if error occurred */
+               NODE_SET_STATE(hnode, NODE_ALLOCATED);
+       }
+func_cont:
+       /* Free access to node dispatcher */
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+func_end:
+       if (status >= 0) {
+               proc_notify_clients(hnode->hprocessor, DSP_NODESTATECHANGE);
+               ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
+       }
+
+       dev_dbg(bridge, "%s: hnode: %p status: 0x%x\n", __func__,
+               hnode, status);
+       return status;
+}
+
+/*
+ *  ======== node_create_mgr ========
+ *  Purpose:
+ *      Create a NODE Manager object.
+ */
+int node_create_mgr(struct node_mgr **node_man,
+                          struct dev_object *hdev_obj)
+{
+       u32 i;
+       struct node_mgr *node_mgr_obj = NULL;
+       struct disp_attr disp_attr_obj;
+       char *sz_zl_file = "";
+       struct nldr_attrs nldr_attrs_obj;
+       int status = 0;
+       u8 dev_type;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(node_man != NULL);
+       DBC_REQUIRE(hdev_obj != NULL);
+
+       *node_man = NULL;
+       /* Allocate Node manager object */
+       node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL);
+       if (node_mgr_obj) {
+               node_mgr_obj->hdev_obj = hdev_obj;
+               node_mgr_obj->node_list = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               node_mgr_obj->pipe_map = gb_create(MAXPIPES);
+               node_mgr_obj->pipe_done_map = gb_create(MAXPIPES);
+               if (node_mgr_obj->node_list == NULL
+                   || node_mgr_obj->pipe_map == NULL
+                   || node_mgr_obj->pipe_done_map == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       INIT_LIST_HEAD(&node_mgr_obj->node_list->head);
+                       node_mgr_obj->ntfy_obj = kmalloc(
+                               sizeof(struct ntfy_object), GFP_KERNEL);
+                       if (node_mgr_obj->ntfy_obj)
+                               ntfy_init(node_mgr_obj->ntfy_obj);
+                       else
+                               status = -ENOMEM;
+               }
+               node_mgr_obj->num_created = 0;
+       } else {
+               status = -ENOMEM;
+       }
+       /* get devNodeType */
+       if (!status)
+               status = dev_get_dev_type(hdev_obj, &dev_type);
+
+       /* Create the DCD Manager */
+       if (!status) {
+               status =
+                   dcd_create_manager(sz_zl_file, &node_mgr_obj->hdcd_mgr);
+               if (!status)
+                       status = get_proc_props(node_mgr_obj, hdev_obj);
+
+       }
+       /* Create NODE Dispatcher */
+       if (!status) {
+               disp_attr_obj.ul_chnl_offset = node_mgr_obj->ul_chnl_offset;
+               disp_attr_obj.ul_chnl_buf_size = node_mgr_obj->ul_chnl_buf_size;
+               disp_attr_obj.proc_family = node_mgr_obj->proc_family;
+               disp_attr_obj.proc_type = node_mgr_obj->proc_type;
+               status =
+                   disp_create(&node_mgr_obj->disp_obj, hdev_obj,
+                               &disp_attr_obj);
+       }
+       /* Create a STRM Manager */
+       if (!status)
+               status = strm_create(&node_mgr_obj->strm_mgr_obj, hdev_obj);
+
+       if (!status) {
+               dev_get_intf_fxns(hdev_obj, &node_mgr_obj->intf_fxns);
+               /* Get msg_ctrl queue manager */
+               dev_get_msg_mgr(hdev_obj, &node_mgr_obj->msg_mgr_obj);
+               mutex_init(&node_mgr_obj->node_mgr_lock);
+               node_mgr_obj->chnl_map = gb_create(node_mgr_obj->ul_num_chnls);
+               /* dma chnl map. ul_num_chnls is # per transport */
+               node_mgr_obj->dma_chnl_map =
+                   gb_create(node_mgr_obj->ul_num_chnls);
+               node_mgr_obj->zc_chnl_map =
+                   gb_create(node_mgr_obj->ul_num_chnls);
+               if ((node_mgr_obj->chnl_map == NULL)
+                   || (node_mgr_obj->dma_chnl_map == NULL)
+                   || (node_mgr_obj->zc_chnl_map == NULL)) {
+                       status = -ENOMEM;
+               } else {
+                       /* Block out reserved channels */
+                       for (i = 0; i < node_mgr_obj->ul_chnl_offset; i++)
+                               gb_set(node_mgr_obj->chnl_map, i);
+
+                       /* Block out channels reserved for RMS */
+                       gb_set(node_mgr_obj->chnl_map,
+                              node_mgr_obj->ul_chnl_offset);
+                       gb_set(node_mgr_obj->chnl_map,
+                              node_mgr_obj->ul_chnl_offset + 1);
+               }
+       }
+       if (!status) {
+               /* NO RM Server on the IVA */
+               if (dev_type != IVA_UNIT) {
+                       /* Get addresses of any RMS functions loaded */
+                       status = get_rms_fxns(node_mgr_obj);
+               }
+       }
+
+       /* Get loader functions and create loader */
+       if (!status)
+               node_mgr_obj->nldr_fxns = nldr_fxns;    /* Dyn loader funcs */
+
+       if (!status) {
+               nldr_attrs_obj.pfn_ovly = ovly;
+               nldr_attrs_obj.pfn_write = mem_write;
+               nldr_attrs_obj.us_dsp_word_size = node_mgr_obj->udsp_word_size;
+               nldr_attrs_obj.us_dsp_mau_size = node_mgr_obj->udsp_mau_size;
+               node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.pfn_init();
+               status =
+                   node_mgr_obj->nldr_fxns.pfn_create(&node_mgr_obj->nldr_obj,
+                                                      hdev_obj,
+                                                      &nldr_attrs_obj);
+       }
+       if (!status)
+               *node_man = node_mgr_obj;
+       else
+               delete_node_mgr(node_mgr_obj);
+
+       DBC_ENSURE((status && *node_man == NULL) || (!status && *node_man));
+
+       return status;
+}
+
+/*
+ *  ======== node_delete ========
+ *  Purpose:
+ *      Delete a node on the DSP by remotely calling the node's delete function.
+ *      Loads the node's delete function if necessary. Free GPP side resources
+ *      after node's delete function returns.
+ */
+int node_delete(struct node_res_object *noderes,
+                      struct process_context *pr_ctxt)
+{
+       struct node_object *pnode = noderes->hnode;
+       struct node_mgr *hnode_mgr;
+       struct proc_object *hprocessor;
+       struct disp_object *disp_obj;
+       u32 ul_delete_fxn;
+       enum node_type node_type;
+       enum node_state state;
+       int status = 0;
+       int status1 = 0;
+       struct dsp_cbdata cb_data;
+       u32 proc_id;
+       struct bridge_drv_interface *intf_fxns;
+
+       void *node_res = noderes;
+
+       struct dsp_processorstate proc_state;
+       DBC_REQUIRE(refs > 0);
+
+       if (!pnode) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       /* create struct dsp_cbdata struct for PWR call */
+       cb_data.cb_data = PWR_TIMEOUT;
+       hnode_mgr = pnode->hnode_mgr;
+       hprocessor = pnode->hprocessor;
+       disp_obj = hnode_mgr->disp_obj;
+       node_type = node_get_type(pnode);
+       intf_fxns = hnode_mgr->intf_fxns;
+       /* Enter critical section */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       state = node_get_state(pnode);
+       /*  Execute delete phase code for non-device node in all cases
+        *  except when the node was only allocated. Delete phase must be
+        *  executed even if create phase was executed, but failed.
+        *  If the node environment pointer is non-NULL, the delete phase
+        *  code must be  executed. */
+       if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) &&
+           node_type != NODE_DEVICE) {
+               status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+               if (status)
+                       goto func_cont1;
+
+               if (proc_id == DSP_UNIT || proc_id == IVA_UNIT) {
+                       /*  If node has terminated, execute phase code will
+                        *  have already been unloaded in node_on_exit(). If the
+                        *  node is PAUSED, the execute phase is loaded, and it
+                        *  is now ok to unload it. If the node is running, we
+                        *  will unload the execute phase only after deleting
+                        *  the node. */
+                       if (state == NODE_PAUSED && pnode->loaded &&
+                           pnode->phase_split) {
+                               /* Ok to unload execute code as long as node
+                                * is not * running */
+                               status1 =
+                                   hnode_mgr->nldr_fxns.
+                                   pfn_unload(pnode->nldr_node_obj,
+                                              NLDR_EXECUTE);
+                               pnode->loaded = false;
+                               NODE_SET_STATE(pnode, NODE_DONE);
+                       }
+                       /* Load delete phase code if not loaded or if haven't
+                        * * unloaded EXECUTE phase */
+                       if ((!(pnode->loaded) || (state == NODE_RUNNING)) &&
+                           pnode->phase_split) {
+                               status =
+                                   hnode_mgr->nldr_fxns.
+                                   pfn_load(pnode->nldr_node_obj, NLDR_DELETE);
+                               if (!status)
+                                       pnode->loaded = true;
+                               else
+                                       pr_err("%s: fail - load delete code:"
+                                              " 0x%x\n", __func__, status);
+                       }
+               }
+func_cont1:
+               if (!status) {
+                       /* Unblock a thread trying to terminate the node */
+                       (void)sync_set_event(pnode->sync_done);
+                       if (proc_id == DSP_UNIT) {
+                               /* ul_delete_fxn = address of node's delete
+                                * function */
+                               status = get_fxn_address(pnode, &ul_delete_fxn,
+                                                        DELETEPHASE);
+                       } else if (proc_id == IVA_UNIT)
+                               ul_delete_fxn = (u32) pnode->node_env;
+                       if (!status) {
+                               status = proc_get_state(hprocessor,
+                                               &proc_state,
+                                               sizeof(struct
+                                                      dsp_processorstate));
+                               if (proc_state.proc_state != PROC_ERROR) {
+                                       status =
+                                           disp_node_delete(disp_obj, pnode,
+                                                            hnode_mgr->
+                                                            ul_fxn_addrs
+                                                            [RMSDELETENODE],
+                                                            ul_delete_fxn,
+                                                            pnode->node_env);
+                               } else
+                                       NODE_SET_STATE(pnode, NODE_DONE);
+
+                               /* Unload execute, if not unloaded, and delete
+                                * function */
+                               if (state == NODE_RUNNING &&
+                                   pnode->phase_split) {
+                                       status1 =
+                                           hnode_mgr->nldr_fxns.
+                                           pfn_unload(pnode->nldr_node_obj,
+                                                      NLDR_EXECUTE);
+                               }
+                               if (status1)
+                                       pr_err("%s: fail - unload execute code:"
+                                              " 0x%x\n", __func__, status1);
+
+                               status1 =
+                                   hnode_mgr->nldr_fxns.pfn_unload(pnode->
+                                                           nldr_node_obj,
+                                                           NLDR_DELETE);
+                               pnode->loaded = false;
+                               if (status1)
+                                       pr_err("%s: fail - unload delete code: "
+                                              "0x%x\n", __func__, status1);
+                       }
+               }
+       }
+       /* Free host side resources even if a failure occurred */
+       /* Remove node from hnode_mgr->node_list */
+       lst_remove_elem(hnode_mgr->node_list, (struct list_head *)pnode);
+       hnode_mgr->num_nodes--;
+       /* Decrement count of nodes created on DSP */
+       if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) &&
+                                         (pnode->node_env != (u32) NULL)))
+               hnode_mgr->num_created--;
+       /*  Free host-side resources allocated by node_create()
+        *  delete_node() fails if SM buffers not freed by client! */
+       drv_proc_node_update_status(node_res, false);
+       delete_node(pnode, pr_ctxt);
+
+       /*
+        * Release all Node resources and its context
+        */
+       idr_remove(pr_ctxt->node_id, ((struct node_res_object *)node_res)->id);
+       kfree(node_res);
+
+       /* Exit critical section */
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+       proc_notify_clients(hprocessor, DSP_NODESTATECHANGE);
+func_end:
+       dev_dbg(bridge, "%s: pnode: %p status 0x%x\n", __func__, pnode, status);
+       return status;
+}
+
+/*
+ *  ======== node_delete_mgr ========
+ *  Purpose:
+ *      Delete the NODE Manager.
+ */
+int node_delete_mgr(struct node_mgr *hnode_mgr)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (hnode_mgr)
+               delete_node_mgr(hnode_mgr);
+       else
+               status = -EFAULT;
+
+       return status;
+}
+
+/*
+ *  ======== node_enum_nodes ========
+ *  Purpose:
+ *      Enumerate currently allocated nodes.
+ */
+int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab,
+                          u32 node_tab_size, u32 *pu_num_nodes,
+                          u32 *pu_allocated)
+{
+       struct node_object *hnode;
+       u32 i;
+       int status = 0;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(node_tab != NULL || node_tab_size == 0);
+       DBC_REQUIRE(pu_num_nodes != NULL);
+       DBC_REQUIRE(pu_allocated != NULL);
+
+       if (!hnode_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       /* Enter critical section */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       if (hnode_mgr->num_nodes > node_tab_size) {
+               *pu_allocated = hnode_mgr->num_nodes;
+               *pu_num_nodes = 0;
+               status = -EINVAL;
+       } else {
+               hnode = (struct node_object *)lst_first(hnode_mgr->
+                       node_list);
+               for (i = 0; i < hnode_mgr->num_nodes; i++) {
+                       DBC_ASSERT(hnode);
+                       node_tab[i] = hnode;
+                       hnode = (struct node_object *)lst_next
+                               (hnode_mgr->node_list,
+                               (struct list_head *)hnode);
+               }
+               *pu_allocated = *pu_num_nodes = hnode_mgr->num_nodes;
+       }
+       /* end of sync_enter_cs */
+       /* Exit critical section */
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+func_end:
+       return status;
+}
+
+/*
+ *  ======== node_exit ========
+ *  Purpose:
+ *      Discontinue usage of NODE module.
+ */
+void node_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== node_free_msg_buf ========
+ *  Purpose:
+ *      Frees the message buffer.
+ */
+int node_free_msg_buf(struct node_object *hnode, u8 * pbuffer,
+                            struct dsp_bufferattr *pattr)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       int status = 0;
+       u32 proc_id;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pbuffer != NULL);
+       DBC_REQUIRE(pnode != NULL);
+       DBC_REQUIRE(pnode->xlator != NULL);
+
+       if (!hnode) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+       if (proc_id == DSP_UNIT) {
+               if (!status) {
+                       if (pattr == NULL) {
+                               /* set defaults */
+                               pattr = &node_dfltbufattrs;
+                       }
+                       /* Node supports single SM segment only */
+                       if (pattr->segment_id != 1)
+                               status = -EBADR;
+
+                       /* pbuffer is clients Va. */
+                       status = cmm_xlator_free_buf(pnode->xlator, pbuffer);
+               }
+       } else {
+               DBC_ASSERT(NULL);       /* BUG */
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== node_get_attr ========
+ *  Purpose:
+ *      Copy the current attributes of the specified node into a dsp_nodeattr
+ *      structure.
+ */
+int node_get_attr(struct node_object *hnode,
+                        struct dsp_nodeattr *pattr, u32 attr_size)
+{
+       struct node_mgr *hnode_mgr;
+       int status = 0;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pattr != NULL);
+       DBC_REQUIRE(attr_size >= sizeof(struct dsp_nodeattr));
+
+       if (!hnode) {
+               status = -EFAULT;
+       } else {
+               hnode_mgr = hnode->hnode_mgr;
+               /* Enter hnode_mgr critical section (since we're accessing
+                * data that could be changed by node_change_priority() and
+                * node_connect(). */
+               mutex_lock(&hnode_mgr->node_mgr_lock);
+               pattr->cb_struct = sizeof(struct dsp_nodeattr);
+               /* dsp_nodeattrin */
+               pattr->in_node_attr_in.cb_struct =
+                                sizeof(struct dsp_nodeattrin);
+               pattr->in_node_attr_in.prio = hnode->prio;
+               pattr->in_node_attr_in.utimeout = hnode->utimeout;
+               pattr->in_node_attr_in.heap_size =
+                       hnode->create_args.asa.task_arg_obj.heap_size;
+               pattr->in_node_attr_in.pgpp_virt_addr = (void *)
+                       hnode->create_args.asa.task_arg_obj.ugpp_heap_addr;
+               pattr->node_attr_inputs = hnode->num_gpp_inputs;
+               pattr->node_attr_outputs = hnode->num_gpp_outputs;
+               /* dsp_nodeinfo */
+               get_node_info(hnode, &(pattr->node_info));
+               /* end of sync_enter_cs */
+               /* Exit critical section */
+               mutex_unlock(&hnode_mgr->node_mgr_lock);
+       }
+       return status;
+}
+
+/*
+ *  ======== node_get_channel_id ========
+ *  Purpose:
+ *      Get the channel index reserved for a stream connection between the
+ *      host and a node.
+ */
+int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index,
+                              u32 *chan_id)
+{
+       enum node_type node_type;
+       int status = -EINVAL;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dir == DSP_TONODE || dir == DSP_FROMNODE);
+       DBC_REQUIRE(chan_id != NULL);
+
+       if (!hnode) {
+               status = -EFAULT;
+               return status;
+       }
+       node_type = node_get_type(hnode);
+       if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) {
+               status = -EPERM;
+               return status;
+       }
+       if (dir == DSP_TONODE) {
+               if (index < MAX_INPUTS(hnode)) {
+                       if (hnode->inputs[index].type == HOSTCONNECT) {
+                               *chan_id = hnode->inputs[index].dev_id;
+                               status = 0;
+                       }
+               }
+       } else {
+               DBC_ASSERT(dir == DSP_FROMNODE);
+               if (index < MAX_OUTPUTS(hnode)) {
+                       if (hnode->outputs[index].type == HOSTCONNECT) {
+                               *chan_id = hnode->outputs[index].dev_id;
+                               status = 0;
+                       }
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== node_get_message ========
+ *  Purpose:
+ *      Retrieve a message from a node on the DSP.
+ */
+int node_get_message(struct node_object *hnode,
+                           struct dsp_msg *message, u32 utimeout)
+{
+       struct node_mgr *hnode_mgr;
+       enum node_type node_type;
+       struct bridge_drv_interface *intf_fxns;
+       int status = 0;
+       void *tmp_buf;
+       struct dsp_processorstate proc_state;
+       struct proc_object *hprocessor;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(message != NULL);
+
+       if (!hnode) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       hprocessor = hnode->hprocessor;
+       status = proc_get_state(hprocessor, &proc_state,
+                               sizeof(struct dsp_processorstate));
+       if (status)
+               goto func_end;
+       /* If processor is in error state then don't attempt to get the
+          message */
+       if (proc_state.proc_state == PROC_ERROR) {
+               status = -EPERM;
+               goto func_end;
+       }
+       hnode_mgr = hnode->hnode_mgr;
+       node_type = node_get_type(hnode);
+       if (node_type != NODE_MESSAGE && node_type != NODE_TASK &&
+           node_type != NODE_DAISSOCKET) {
+               status = -EPERM;
+               goto func_end;
+       }
+       /*  This function will block unless a message is available. Since
+        *  DSPNode_RegisterNotify() allows notification when a message
+        *  is available, the system can be designed so that
+        *  DSPNode_GetMessage() is only called when a message is
+        *  available. */
+       intf_fxns = hnode_mgr->intf_fxns;
+       status =
+           (*intf_fxns->pfn_msg_get) (hnode->msg_queue_obj, message, utimeout);
+       /* Check if message contains SM descriptor */
+       if (status || !(message->dw_cmd & DSP_RMSBUFDESC))
+               goto func_end;
+
+       /* Translate DSP byte addr to GPP Va. */
+       tmp_buf = cmm_xlator_translate(hnode->xlator,
+                                      (void *)(message->dw_arg1 *
+                                               hnode->hnode_mgr->
+                                               udsp_word_size), CMM_DSPPA2PA);
+       if (tmp_buf != NULL) {
+               /* now convert this GPP Pa to Va */
+               tmp_buf = cmm_xlator_translate(hnode->xlator, tmp_buf,
+                                              CMM_PA2VA);
+               if (tmp_buf != NULL) {
+                       /* Adjust SM size in msg */
+                       message->dw_arg1 = (u32) tmp_buf;
+                       message->dw_arg2 *= hnode->hnode_mgr->udsp_word_size;
+               } else {
+                       status = -ESRCH;
+               }
+       } else {
+               status = -ESRCH;
+       }
+func_end:
+       dev_dbg(bridge, "%s: hnode: %p message: %p utimeout: 0x%x\n", __func__,
+               hnode, message, utimeout);
+       return status;
+}
+
+/*
+ *   ======== node_get_nldr_obj ========
+ */
+int node_get_nldr_obj(struct node_mgr *hnode_mgr,
+                            struct nldr_object **nldr_ovlyobj)
+{
+       int status = 0;
+       struct node_mgr *node_mgr_obj = hnode_mgr;
+       DBC_REQUIRE(nldr_ovlyobj != NULL);
+
+       if (!hnode_mgr)
+               status = -EFAULT;
+       else
+               *nldr_ovlyobj = node_mgr_obj->nldr_obj;
+
+       DBC_ENSURE(!status || (nldr_ovlyobj != NULL && *nldr_ovlyobj == NULL));
+       return status;
+}
+
+/*
+ *  ======== node_get_strm_mgr ========
+ *  Purpose:
+ *      Returns the Stream manager.
+ */
+int node_get_strm_mgr(struct node_object *hnode,
+                            struct strm_mgr **strm_man)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!hnode)
+               status = -EFAULT;
+       else
+               *strm_man = hnode->hnode_mgr->strm_mgr_obj;
+
+       return status;
+}
+
+/*
+ *  ======== node_get_load_type ========
+ */
+enum nldr_loadtype node_get_load_type(struct node_object *hnode)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hnode);
+       if (!hnode) {
+               dev_dbg(bridge, "%s: Failed. hnode: %p\n", __func__, hnode);
+               return -1;
+       } else {
+               return hnode->dcd_props.obj_data.node_obj.us_load_type;
+       }
+}
+
+/*
+ *  ======== node_get_timeout ========
+ *  Purpose:
+ *      Returns the timeout value for this node.
+ */
+u32 node_get_timeout(struct node_object *hnode)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hnode);
+       if (!hnode) {
+               dev_dbg(bridge, "%s: failed. hnode: %p\n", __func__, hnode);
+               return 0;
+       } else {
+               return hnode->utimeout;
+       }
+}
+
+/*
+ *  ======== node_get_type ========
+ *  Purpose:
+ *      Returns the node type.
+ */
+enum node_type node_get_type(struct node_object *hnode)
+{
+       enum node_type node_type;
+
+       if (hnode == (struct node_object *)DSP_HGPPNODE)
+               node_type = NODE_GPP;
+       else {
+               if (!hnode)
+                       node_type = -1;
+               else
+                       node_type = hnode->ntype;
+       }
+       return node_type;
+}
+
+/*
+ *  ======== node_init ========
+ *  Purpose:
+ *      Initialize the NODE module.
+ */
+bool node_init(void)
+{
+       DBC_REQUIRE(refs >= 0);
+
+       refs++;
+
+       return true;
+}
+
+/*
+ *  ======== node_on_exit ========
+ *  Purpose:
+ *      Gets called when RMS_EXIT is received for a node.
+ */
+void node_on_exit(struct node_object *hnode, s32 node_status)
+{
+       if (!hnode)
+               return;
+
+       /* Set node state to done */
+       NODE_SET_STATE(hnode, NODE_DONE);
+       hnode->exit_status = node_status;
+       if (hnode->loaded && hnode->phase_split) {
+               (void)hnode->hnode_mgr->nldr_fxns.pfn_unload(hnode->
+                                                            nldr_node_obj,
+                                                            NLDR_EXECUTE);
+               hnode->loaded = false;
+       }
+       /* Unblock call to node_terminate */
+       (void)sync_set_event(hnode->sync_done);
+       /* Notify clients */
+       proc_notify_clients(hnode->hprocessor, DSP_NODESTATECHANGE);
+       ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
+}
+
+/*
+ *  ======== node_pause ========
+ *  Purpose:
+ *      Suspend execution of a node currently running on the DSP.
+ */
+int node_pause(struct node_object *hnode)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       enum node_type node_type;
+       enum node_state state;
+       struct node_mgr *hnode_mgr;
+       int status = 0;
+       u32 proc_id;
+       struct dsp_processorstate proc_state;
+       struct proc_object *hprocessor;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!hnode) {
+               status = -EFAULT;
+       } else {
+               node_type = node_get_type(hnode);
+               if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
+                       status = -EPERM;
+       }
+       if (status)
+               goto func_end;
+
+       status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+
+       if (proc_id == IVA_UNIT)
+               status = -ENOSYS;
+
+       if (!status) {
+               hnode_mgr = hnode->hnode_mgr;
+
+               /* Enter critical section */
+               mutex_lock(&hnode_mgr->node_mgr_lock);
+               state = node_get_state(hnode);
+               /* Check node state */
+               if (state != NODE_RUNNING)
+                       status = -EBADR;
+
+               if (status)
+                       goto func_cont;
+               hprocessor = hnode->hprocessor;
+               status = proc_get_state(hprocessor, &proc_state,
+                               sizeof(struct dsp_processorstate));
+               if (status)
+                       goto func_cont;
+               /* If processor is in error state then don't attempt
+                  to send the message */
+               if (proc_state.proc_state == PROC_ERROR) {
+                       status = -EPERM;
+                       goto func_cont;
+               }
+
+               status = disp_node_change_priority(hnode_mgr->disp_obj, hnode,
+                       hnode_mgr->ul_fxn_addrs[RMSCHANGENODEPRIORITY],
+                       hnode->node_env, NODE_SUSPENDEDPRI);
+
+               /* Update state */
+               if (status >= 0)
+                       NODE_SET_STATE(hnode, NODE_PAUSED);
+
+func_cont:
+               /* End of sync_enter_cs */
+               /* Leave critical section */
+               mutex_unlock(&hnode_mgr->node_mgr_lock);
+               if (status >= 0) {
+                       proc_notify_clients(hnode->hprocessor,
+                                           DSP_NODESTATECHANGE);
+                       ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
+               }
+       }
+func_end:
+       dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status);
+       return status;
+}
+
+/*
+ *  ======== node_put_message ========
+ *  Purpose:
+ *      Send a message to a message node, task node, or XDAIS socket node. This
+ *      function will block until the message stream can accommodate the
+ *      message, or a timeout occurs.
+ */
+int node_put_message(struct node_object *hnode,
+                           const struct dsp_msg *pmsg, u32 utimeout)
+{
+       struct node_mgr *hnode_mgr = NULL;
+       enum node_type node_type;
+       struct bridge_drv_interface *intf_fxns;
+       enum node_state state;
+       int status = 0;
+       void *tmp_buf;
+       struct dsp_msg new_msg;
+       struct dsp_processorstate proc_state;
+       struct proc_object *hprocessor;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pmsg != NULL);
+
+       if (!hnode) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       hprocessor = hnode->hprocessor;
+       status = proc_get_state(hprocessor, &proc_state,
+                               sizeof(struct dsp_processorstate));
+       if (status)
+               goto func_end;
+       /* If processor is in bad state then don't attempt sending the
+          message */
+       if (proc_state.proc_state == PROC_ERROR) {
+               status = -EPERM;
+               goto func_end;
+       }
+       hnode_mgr = hnode->hnode_mgr;
+       node_type = node_get_type(hnode);
+       if (node_type != NODE_MESSAGE && node_type != NODE_TASK &&
+           node_type != NODE_DAISSOCKET)
+               status = -EPERM;
+
+       if (!status) {
+               /*  Check node state. Can't send messages to a node after
+                *  we've sent the RMS_EXIT command. There is still the
+                *  possibility that node_terminate can be called after we've
+                *  checked the state. Could add another SYNC object to
+                *  prevent this (can't use node_mgr_lock, since we don't
+                *  want to block other NODE functions). However, the node may
+                *  still exit on its own, before this message is sent. */
+               mutex_lock(&hnode_mgr->node_mgr_lock);
+               state = node_get_state(hnode);
+               if (state == NODE_TERMINATING || state == NODE_DONE)
+                       status = -EBADR;
+
+               /* end of sync_enter_cs */
+               mutex_unlock(&hnode_mgr->node_mgr_lock);
+       }
+       if (status)
+               goto func_end;
+
+       /* assign pmsg values to new msg */
+       new_msg = *pmsg;
+       /* Now, check if message contains a SM buffer descriptor */
+       if (pmsg->dw_cmd & DSP_RMSBUFDESC) {
+               /* Translate GPP Va to DSP physical buf Ptr. */
+               tmp_buf = cmm_xlator_translate(hnode->xlator,
+                                              (void *)new_msg.dw_arg1,
+                                              CMM_VA2DSPPA);
+               if (tmp_buf != NULL) {
+                       /* got translation, convert to MAUs in msg */
+                       if (hnode->hnode_mgr->udsp_word_size != 0) {
+                               new_msg.dw_arg1 =
+                                   (u32) tmp_buf /
+                                   hnode->hnode_mgr->udsp_word_size;
+                               /* MAUs */
+                               new_msg.dw_arg2 /= hnode->hnode_mgr->
+                                   udsp_word_size;
+                       } else {
+                               pr_err("%s: udsp_word_size is zero!\n",
+                                      __func__);
+                               status = -EPERM;        /* bad DSPWordSize */
+                       }
+               } else {        /* failed to translate buffer address */
+                       status = -ESRCH;
+               }
+       }
+       if (!status) {
+               intf_fxns = hnode_mgr->intf_fxns;
+               status = (*intf_fxns->pfn_msg_put) (hnode->msg_queue_obj,
+                                                   &new_msg, utimeout);
+       }
+func_end:
+       dev_dbg(bridge, "%s: hnode: %p pmsg: %p utimeout: 0x%x, "
+               "status 0x%x\n", __func__, hnode, pmsg, utimeout, status);
+       return status;
+}
+
+/*
+ *  ======== node_register_notify ========
+ *  Purpose:
+ *      Register to be notified on specific events for this node.
+ */
+int node_register_notify(struct node_object *hnode, u32 event_mask,
+                               u32 notify_type,
+                               struct dsp_notification *hnotification)
+{
+       struct bridge_drv_interface *intf_fxns;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hnotification != NULL);
+
+       if (!hnode) {
+               status = -EFAULT;
+       } else {
+               /* Check if event mask is a valid node related event */
+               if (event_mask & ~(DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY))
+                       status = -EINVAL;
+
+               /* Check if notify type is valid */
+               if (notify_type != DSP_SIGNALEVENT)
+                       status = -EINVAL;
+
+               /* Only one Notification can be registered at a
+                * time - Limitation */
+               if (event_mask == (DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY))
+                       status = -EINVAL;
+       }
+       if (!status) {
+               if (event_mask == DSP_NODESTATECHANGE) {
+                       status = ntfy_register(hnode->ntfy_obj, hnotification,
+                                              event_mask & DSP_NODESTATECHANGE,
+                                              notify_type);
+               } else {
+                       /* Send Message part of event mask to msg_ctrl */
+                       intf_fxns = hnode->hnode_mgr->intf_fxns;
+                       status = (*intf_fxns->pfn_msg_register_notify)
+                           (hnode->msg_queue_obj,
+                            event_mask & DSP_NODEMESSAGEREADY, notify_type,
+                            hnotification);
+               }
+
+       }
+       dev_dbg(bridge, "%s: hnode: %p event_mask: 0x%x notify_type: 0x%x "
+               "hnotification: %p status 0x%x\n", __func__, hnode,
+               event_mask, notify_type, hnotification, status);
+       return status;
+}
+
+/*
+ *  ======== node_run ========
+ *  Purpose:
+ *      Start execution of a node's execute phase, or resume execution of a node
+ *      that has been suspended (via NODE_NodePause()) on the DSP. Load the
+ *      node's execute function if necessary.
+ */
+int node_run(struct node_object *hnode)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       struct node_mgr *hnode_mgr;
+       enum node_type node_type;
+       enum node_state state;
+       u32 ul_execute_fxn;
+       u32 ul_fxn_addr;
+       int status = 0;
+       u32 proc_id;
+       struct bridge_drv_interface *intf_fxns;
+       struct dsp_processorstate proc_state;
+       struct proc_object *hprocessor;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!hnode) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       hprocessor = hnode->hprocessor;
+       status = proc_get_state(hprocessor, &proc_state,
+                               sizeof(struct dsp_processorstate));
+       if (status)
+               goto func_end;
+       /* If processor is in error state then don't attempt to run the node */
+       if (proc_state.proc_state == PROC_ERROR) {
+               status = -EPERM;
+               goto func_end;
+       }
+       node_type = node_get_type(hnode);
+       if (node_type == NODE_DEVICE)
+               status = -EPERM;
+       if (status)
+               goto func_end;
+
+       hnode_mgr = hnode->hnode_mgr;
+       if (!hnode_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       intf_fxns = hnode_mgr->intf_fxns;
+       /* Enter critical section */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       state = node_get_state(hnode);
+       if (state != NODE_CREATED && state != NODE_PAUSED)
+               status = -EBADR;
+
+       if (!status)
+               status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+
+       if (status)
+               goto func_cont1;
+
+       if ((proc_id != DSP_UNIT) && (proc_id != IVA_UNIT))
+               goto func_cont1;
+
+       if (state == NODE_CREATED) {
+               /* If node's execute function is not loaded, load it */
+               if (!(hnode->loaded) && hnode->phase_split) {
+                       status =
+                           hnode_mgr->nldr_fxns.pfn_load(hnode->nldr_node_obj,
+                                                         NLDR_EXECUTE);
+                       if (!status) {
+                               hnode->loaded = true;
+                       } else {
+                               pr_err("%s: fail - load execute code: 0x%x\n",
+                                      __func__, status);
+                       }
+               }
+               if (!status) {
+                       /* Get address of node's execute function */
+                       if (proc_id == IVA_UNIT)
+                               ul_execute_fxn = (u32) hnode->node_env;
+                       else {
+                               status = get_fxn_address(hnode, &ul_execute_fxn,
+                                                        EXECUTEPHASE);
+                       }
+               }
+               if (!status) {
+                       ul_fxn_addr = hnode_mgr->ul_fxn_addrs[RMSEXECUTENODE];
+                       status =
+                           disp_node_run(hnode_mgr->disp_obj, hnode,
+                                         ul_fxn_addr, ul_execute_fxn,
+                                         hnode->node_env);
+               }
+       } else if (state == NODE_PAUSED) {
+               ul_fxn_addr = hnode_mgr->ul_fxn_addrs[RMSCHANGENODEPRIORITY];
+               status = disp_node_change_priority(hnode_mgr->disp_obj, hnode,
+                                                  ul_fxn_addr, hnode->node_env,
+                                                  NODE_GET_PRIORITY(hnode));
+       } else {
+               /* We should never get here */
+               DBC_ASSERT(false);
+       }
+func_cont1:
+       /* Update node state. */
+       if (status >= 0)
+               NODE_SET_STATE(hnode, NODE_RUNNING);
+       else                    /* Set state back to previous value */
+               NODE_SET_STATE(hnode, state);
+       /*End of sync_enter_cs */
+       /* Exit critical section */
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+       if (status >= 0) {
+               proc_notify_clients(hnode->hprocessor, DSP_NODESTATECHANGE);
+               ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
+       }
+func_end:
+       dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status);
+       return status;
+}
+
+/*
+ *  ======== node_terminate ========
+ *  Purpose:
+ *      Signal a node running on the DSP that it should exit its execute phase
+ *      function.
+ */
+int node_terminate(struct node_object *hnode, int *pstatus)
+{
+       struct node_object *pnode = (struct node_object *)hnode;
+       struct node_mgr *hnode_mgr = NULL;
+       enum node_type node_type;
+       struct bridge_drv_interface *intf_fxns;
+       enum node_state state;
+       struct dsp_msg msg, killmsg;
+       int status = 0;
+       u32 proc_id, kill_time_out;
+       struct deh_mgr *hdeh_mgr;
+       struct dsp_processorstate proc_state;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pstatus != NULL);
+
+       if (!hnode || !hnode->hnode_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       if (pnode->hprocessor == NULL) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       status = proc_get_processor_id(pnode->hprocessor, &proc_id);
+
+       if (!status) {
+               hnode_mgr = hnode->hnode_mgr;
+               node_type = node_get_type(hnode);
+               if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
+                       status = -EPERM;
+       }
+       if (!status) {
+               /* Check node state */
+               mutex_lock(&hnode_mgr->node_mgr_lock);
+               state = node_get_state(hnode);
+               if (state != NODE_RUNNING) {
+                       status = -EBADR;
+                       /* Set the exit status if node terminated on
+                        * its own. */
+                       if (state == NODE_DONE)
+                               *pstatus = hnode->exit_status;
+
+               } else {
+                       NODE_SET_STATE(hnode, NODE_TERMINATING);
+               }
+               /* end of sync_enter_cs */
+               mutex_unlock(&hnode_mgr->node_mgr_lock);
+       }
+       if (!status) {
+               /*
+                *  Send exit message. Do not change state to NODE_DONE
+                *  here. That will be done in callback.
+                */
+               status = proc_get_state(pnode->hprocessor, &proc_state,
+                                       sizeof(struct dsp_processorstate));
+               if (status)
+                       goto func_cont;
+               /* If processor is in error state then don't attempt to send
+                * A kill task command */
+               if (proc_state.proc_state == PROC_ERROR) {
+                       status = -EPERM;
+                       goto func_cont;
+               }
+
+               msg.dw_cmd = RMS_EXIT;
+               msg.dw_arg1 = hnode->node_env;
+               killmsg.dw_cmd = RMS_KILLTASK;
+               killmsg.dw_arg1 = hnode->node_env;
+               intf_fxns = hnode_mgr->intf_fxns;
+
+               if (hnode->utimeout > MAXTIMEOUT)
+                       kill_time_out = MAXTIMEOUT;
+               else
+                       kill_time_out = (hnode->utimeout) * 2;
+
+               status = (*intf_fxns->pfn_msg_put) (hnode->msg_queue_obj, &msg,
+                                                   hnode->utimeout);
+               if (status)
+                       goto func_cont;
+
+               /*
+                * Wait on synchronization object that will be
+                * posted in the callback on receiving RMS_EXIT
+                * message, or by node_delete. Check for valid hnode,
+                * in case posted by node_delete().
+                */
+               status = sync_wait_on_event(hnode->sync_done,
+                                           kill_time_out / 2);
+               if (status != ETIME)
+                       goto func_cont;
+
+               status = (*intf_fxns->pfn_msg_put)(hnode->msg_queue_obj,
+                                               &killmsg, hnode->utimeout);
+               if (status)
+                       goto func_cont;
+               status = sync_wait_on_event(hnode->sync_done,
+                                            kill_time_out / 2);
+               if (status) {
+                       /*
+                        * Here it goes the part of the simulation of
+                        * the DSP exception.
+                        */
+                       dev_get_deh_mgr(hnode_mgr->hdev_obj, &hdeh_mgr);
+                       if (!hdeh_mgr)
+                               goto func_cont;
+
+                       bridge_deh_notify(hdeh_mgr, DSP_SYSERROR, DSP_EXCEPTIONABORT);
+               }
+       }
+func_cont:
+       if (!status) {
+               /* Enter CS before getting exit status, in case node was
+                * deleted. */
+               mutex_lock(&hnode_mgr->node_mgr_lock);
+               /* Make sure node wasn't deleted while we blocked */
+               if (!hnode) {
+                       status = -EPERM;
+               } else {
+                       *pstatus = hnode->exit_status;
+                       dev_dbg(bridge, "%s: hnode: %p env 0x%x status 0x%x\n",
+                               __func__, hnode, hnode->node_env, status);
+               }
+               mutex_unlock(&hnode_mgr->node_mgr_lock);
+       }                       /*End of sync_enter_cs */
+func_end:
+       return status;
+}
+
+/*
+ *  ======== delete_node ========
+ *  Purpose:
+ *      Free GPP resources allocated in node_allocate() or node_connect().
+ */
+static void delete_node(struct node_object *hnode,
+                       struct process_context *pr_ctxt)
+{
+       struct node_mgr *hnode_mgr;
+       struct cmm_xlatorobject *xlator;
+       struct bridge_drv_interface *intf_fxns;
+       u32 i;
+       enum node_type node_type;
+       struct stream_chnl stream;
+       struct node_msgargs node_msg_args;
+       struct node_taskargs task_arg_obj;
+#ifdef DSP_DMM_DEBUG
+       struct dmm_object *dmm_mgr;
+       struct proc_object *p_proc_object =
+           (struct proc_object *)hnode->hprocessor;
+#endif
+       int status;
+       if (!hnode)
+               goto func_end;
+       hnode_mgr = hnode->hnode_mgr;
+       if (!hnode_mgr)
+               goto func_end;
+       xlator = hnode->xlator;
+       node_type = node_get_type(hnode);
+       if (node_type != NODE_DEVICE) {
+               node_msg_args = hnode->create_args.asa.node_msg_args;
+               kfree(node_msg_args.pdata);
+
+               /* Free msg_ctrl queue */
+               if (hnode->msg_queue_obj) {
+                       intf_fxns = hnode_mgr->intf_fxns;
+                       (*intf_fxns->pfn_msg_delete_queue) (hnode->
+                                                           msg_queue_obj);
+                       hnode->msg_queue_obj = NULL;
+               }
+
+               kfree(hnode->sync_done);
+
+               /* Free all stream info */
+               if (hnode->inputs) {
+                       for (i = 0; i < MAX_INPUTS(hnode); i++) {
+                               stream = hnode->inputs[i];
+                               free_stream(hnode_mgr, stream);
+                       }
+                       kfree(hnode->inputs);
+                       hnode->inputs = NULL;
+               }
+               if (hnode->outputs) {
+                       for (i = 0; i < MAX_OUTPUTS(hnode); i++) {
+                               stream = hnode->outputs[i];
+                               free_stream(hnode_mgr, stream);
+                       }
+                       kfree(hnode->outputs);
+                       hnode->outputs = NULL;
+               }
+               task_arg_obj = hnode->create_args.asa.task_arg_obj;
+               if (task_arg_obj.strm_in_def) {
+                       for (i = 0; i < MAX_INPUTS(hnode); i++) {
+                               kfree(task_arg_obj.strm_in_def[i].sz_device);
+                               task_arg_obj.strm_in_def[i].sz_device = NULL;
+                       }
+                       kfree(task_arg_obj.strm_in_def);
+                       task_arg_obj.strm_in_def = NULL;
+               }
+               if (task_arg_obj.strm_out_def) {
+                       for (i = 0; i < MAX_OUTPUTS(hnode); i++) {
+                               kfree(task_arg_obj.strm_out_def[i].sz_device);
+                               task_arg_obj.strm_out_def[i].sz_device = NULL;
+                       }
+                       kfree(task_arg_obj.strm_out_def);
+                       task_arg_obj.strm_out_def = NULL;
+               }
+               if (task_arg_obj.udsp_heap_res_addr) {
+                       status = proc_un_map(hnode->hprocessor, (void *)
+                                            task_arg_obj.udsp_heap_addr,
+                                            pr_ctxt);
+
+                       status = proc_un_reserve_memory(hnode->hprocessor,
+                                                       (void *)
+                                                       task_arg_obj.
+                                                       udsp_heap_res_addr,
+                                                       pr_ctxt);
+#ifdef DSP_DMM_DEBUG
+                       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+                       if (dmm_mgr)
+                               dmm_mem_map_dump(dmm_mgr);
+                       else
+                               status = DSP_EHANDLE;
+#endif
+               }
+       }
+       if (node_type != NODE_MESSAGE) {
+               kfree(hnode->stream_connect);
+               hnode->stream_connect = NULL;
+       }
+       kfree(hnode->pstr_dev_name);
+       hnode->pstr_dev_name = NULL;
+
+       if (hnode->ntfy_obj) {
+               ntfy_delete(hnode->ntfy_obj);
+               kfree(hnode->ntfy_obj);
+               hnode->ntfy_obj = NULL;
+       }
+
+       /* These were allocated in dcd_get_object_def (via node_allocate) */
+       kfree(hnode->dcd_props.obj_data.node_obj.pstr_create_phase_fxn);
+       hnode->dcd_props.obj_data.node_obj.pstr_create_phase_fxn = NULL;
+
+       kfree(hnode->dcd_props.obj_data.node_obj.pstr_execute_phase_fxn);
+       hnode->dcd_props.obj_data.node_obj.pstr_execute_phase_fxn = NULL;
+
+       kfree(hnode->dcd_props.obj_data.node_obj.pstr_delete_phase_fxn);
+       hnode->dcd_props.obj_data.node_obj.pstr_delete_phase_fxn = NULL;
+
+       kfree(hnode->dcd_props.obj_data.node_obj.pstr_i_alg_name);
+       hnode->dcd_props.obj_data.node_obj.pstr_i_alg_name = NULL;
+
+       /* Free all SM address translator resources */
+       if (xlator) {
+               (void)cmm_xlator_delete(xlator, true);  /* force free */
+               xlator = NULL;
+       }
+
+       kfree(hnode->nldr_node_obj);
+       hnode->nldr_node_obj = NULL;
+       hnode->hnode_mgr = NULL;
+       kfree(hnode);
+       hnode = NULL;
+func_end:
+       return;
+}
+
+/*
+ *  ======== delete_node_mgr ========
+ *  Purpose:
+ *      Frees the node manager.
+ */
+static void delete_node_mgr(struct node_mgr *hnode_mgr)
+{
+       struct node_object *hnode;
+
+       if (hnode_mgr) {
+               /* Free resources */
+               if (hnode_mgr->hdcd_mgr)
+                       dcd_destroy_manager(hnode_mgr->hdcd_mgr);
+
+               /* Remove any elements remaining in lists */
+               if (hnode_mgr->node_list) {
+                       while ((hnode = (struct node_object *)
+                               lst_get_head(hnode_mgr->node_list)))
+                               delete_node(hnode, NULL);
+
+                       DBC_ASSERT(LST_IS_EMPTY(hnode_mgr->node_list));
+                       kfree(hnode_mgr->node_list);
+               }
+               mutex_destroy(&hnode_mgr->node_mgr_lock);
+               if (hnode_mgr->ntfy_obj) {
+                       ntfy_delete(hnode_mgr->ntfy_obj);
+                       kfree(hnode_mgr->ntfy_obj);
+               }
+
+               if (hnode_mgr->pipe_map)
+                       gb_delete(hnode_mgr->pipe_map);
+
+               if (hnode_mgr->pipe_done_map)
+                       gb_delete(hnode_mgr->pipe_done_map);
+
+               if (hnode_mgr->chnl_map)
+                       gb_delete(hnode_mgr->chnl_map);
+
+               if (hnode_mgr->dma_chnl_map)
+                       gb_delete(hnode_mgr->dma_chnl_map);
+
+               if (hnode_mgr->zc_chnl_map)
+                       gb_delete(hnode_mgr->zc_chnl_map);
+
+               if (hnode_mgr->disp_obj)
+                       disp_delete(hnode_mgr->disp_obj);
+
+               if (hnode_mgr->strm_mgr_obj)
+                       strm_delete(hnode_mgr->strm_mgr_obj);
+
+               /* Delete the loader */
+               if (hnode_mgr->nldr_obj)
+                       hnode_mgr->nldr_fxns.pfn_delete(hnode_mgr->nldr_obj);
+
+               if (hnode_mgr->loader_init)
+                       hnode_mgr->nldr_fxns.pfn_exit();
+
+               kfree(hnode_mgr);
+       }
+}
+
+/*
+ *  ======== fill_stream_connect ========
+ *  Purpose:
+ *      Fills stream information.
+ */
+static void fill_stream_connect(struct node_object *node1,
+                               struct node_object *node2,
+                               u32 stream1, u32 stream2)
+{
+       u32 strm_index;
+       struct dsp_streamconnect *strm1 = NULL;
+       struct dsp_streamconnect *strm2 = NULL;
+       enum node_type node1_type = NODE_TASK;
+       enum node_type node2_type = NODE_TASK;
+
+       node1_type = node_get_type(node1);
+       node2_type = node_get_type(node2);
+       if (node1 != (struct node_object *)DSP_HGPPNODE) {
+
+               if (node1_type != NODE_DEVICE) {
+                       strm_index = node1->num_inputs +
+                           node1->num_outputs - 1;
+                       strm1 = &(node1->stream_connect[strm_index]);
+                       strm1->cb_struct = sizeof(struct dsp_streamconnect);
+                       strm1->this_node_stream_index = stream1;
+               }
+
+               if (node2 != (struct node_object *)DSP_HGPPNODE) {
+                       /* NODE == > NODE */
+                       if (node1_type != NODE_DEVICE) {
+                               strm1->connected_node = node2;
+                               strm1->ui_connected_node_id = node2->node_uuid;
+                               strm1->connected_node_stream_index = stream2;
+                               strm1->connect_type = CONNECTTYPE_NODEOUTPUT;
+                       }
+                       if (node2_type != NODE_DEVICE) {
+                               strm_index = node2->num_inputs +
+                                   node2->num_outputs - 1;
+                               strm2 = &(node2->stream_connect[strm_index]);
+                               strm2->cb_struct =
+                                   sizeof(struct dsp_streamconnect);
+                               strm2->this_node_stream_index = stream2;
+                               strm2->connected_node = node1;
+                               strm2->ui_connected_node_id = node1->node_uuid;
+                               strm2->connected_node_stream_index = stream1;
+                               strm2->connect_type = CONNECTTYPE_NODEINPUT;
+                       }
+               } else if (node1_type != NODE_DEVICE)
+                       strm1->connect_type = CONNECTTYPE_GPPOUTPUT;
+       } else {
+               /* GPP == > NODE */
+               DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE);
+               strm_index = node2->num_inputs + node2->num_outputs - 1;
+               strm2 = &(node2->stream_connect[strm_index]);
+               strm2->cb_struct = sizeof(struct dsp_streamconnect);
+               strm2->this_node_stream_index = stream2;
+               strm2->connect_type = CONNECTTYPE_GPPINPUT;
+       }
+}
+
+/*
+ *  ======== fill_stream_def ========
+ *  Purpose:
+ *      Fills Stream attributes.
+ */
+static void fill_stream_def(struct node_object *hnode,
+                           struct node_strmdef *pstrm_def,
+                           struct dsp_strmattr *pattrs)
+{
+       struct node_mgr *hnode_mgr = hnode->hnode_mgr;
+
+       if (pattrs != NULL) {
+               pstrm_def->num_bufs = pattrs->num_bufs;
+               pstrm_def->buf_size =
+                   pattrs->buf_size / hnode_mgr->udsp_data_mau_size;
+               pstrm_def->seg_id = pattrs->seg_id;
+               pstrm_def->buf_alignment = pattrs->buf_alignment;
+               pstrm_def->utimeout = pattrs->utimeout;
+       } else {
+               pstrm_def->num_bufs = DEFAULTNBUFS;
+               pstrm_def->buf_size =
+                   DEFAULTBUFSIZE / hnode_mgr->udsp_data_mau_size;
+               pstrm_def->seg_id = DEFAULTSEGID;
+               pstrm_def->buf_alignment = DEFAULTALIGNMENT;
+               pstrm_def->utimeout = DEFAULTTIMEOUT;
+       }
+}
+
+/*
+ *  ======== free_stream ========
+ *  Purpose:
+ *      Updates the channel mask and frees the pipe id.
+ */
+static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream)
+{
+       /* Free up the pipe id unless other node has not yet been deleted. */
+       if (stream.type == NODECONNECT) {
+               if (gb_test(hnode_mgr->pipe_done_map, stream.dev_id)) {
+                       /* The other node has already been deleted */
+                       gb_clear(hnode_mgr->pipe_done_map, stream.dev_id);
+                       gb_clear(hnode_mgr->pipe_map, stream.dev_id);
+               } else {
+                       /* The other node has not been deleted yet */
+                       gb_set(hnode_mgr->pipe_done_map, stream.dev_id);
+               }
+       } else if (stream.type == HOSTCONNECT) {
+               if (stream.dev_id < hnode_mgr->ul_num_chnls) {
+                       gb_clear(hnode_mgr->chnl_map, stream.dev_id);
+               } else if (stream.dev_id < (2 * hnode_mgr->ul_num_chnls)) {
+                       /* dsp-dma */
+                       gb_clear(hnode_mgr->dma_chnl_map, stream.dev_id -
+                                (1 * hnode_mgr->ul_num_chnls));
+               } else if (stream.dev_id < (3 * hnode_mgr->ul_num_chnls)) {
+                       /* zero-copy */
+                       gb_clear(hnode_mgr->zc_chnl_map, stream.dev_id -
+                                (2 * hnode_mgr->ul_num_chnls));
+               }
+       }
+}
+
+/*
+ *  ======== get_fxn_address ========
+ *  Purpose:
+ *      Retrieves the address for create, execute or delete phase for a node.
+ */
+static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr,
+                                 u32 phase)
+{
+       char *pstr_fxn_name = NULL;
+       struct node_mgr *hnode_mgr = hnode->hnode_mgr;
+       int status = 0;
+       DBC_REQUIRE(node_get_type(hnode) == NODE_TASK ||
+                   node_get_type(hnode) == NODE_DAISSOCKET ||
+                   node_get_type(hnode) == NODE_MESSAGE);
+
+       switch (phase) {
+       case CREATEPHASE:
+               pstr_fxn_name =
+                   hnode->dcd_props.obj_data.node_obj.pstr_create_phase_fxn;
+               break;
+       case EXECUTEPHASE:
+               pstr_fxn_name =
+                   hnode->dcd_props.obj_data.node_obj.pstr_execute_phase_fxn;
+               break;
+       case DELETEPHASE:
+               pstr_fxn_name =
+                   hnode->dcd_props.obj_data.node_obj.pstr_delete_phase_fxn;
+               break;
+       default:
+               /* Should never get here */
+               DBC_ASSERT(false);
+               break;
+       }
+
+       status =
+           hnode_mgr->nldr_fxns.pfn_get_fxn_addr(hnode->nldr_node_obj,
+                                                 pstr_fxn_name, fxn_addr);
+
+       return status;
+}
+
+/*
+ *  ======== get_node_info ========
+ *  Purpose:
+ *      Retrieves the node information.
+ */
+void get_node_info(struct node_object *hnode, struct dsp_nodeinfo *node_info)
+{
+       u32 i;
+
+       DBC_REQUIRE(hnode);
+       DBC_REQUIRE(node_info != NULL);
+
+       node_info->cb_struct = sizeof(struct dsp_nodeinfo);
+       node_info->nb_node_database_props =
+           hnode->dcd_props.obj_data.node_obj.ndb_props;
+       node_info->execution_priority = hnode->prio;
+       node_info->device_owner = hnode->device_owner;
+       node_info->number_streams = hnode->num_inputs + hnode->num_outputs;
+       node_info->node_env = hnode->node_env;
+
+       node_info->ns_execution_state = node_get_state(hnode);
+
+       /* Copy stream connect data */
+       for (i = 0; i < hnode->num_inputs + hnode->num_outputs; i++)
+               node_info->sc_stream_connection[i] = hnode->stream_connect[i];
+
+}
+
+/*
+ *  ======== get_node_props ========
+ *  Purpose:
+ *      Retrieve node properties.
+ */
+static int get_node_props(struct dcd_manager *hdcd_mgr,
+                                struct node_object *hnode,
+                                const struct dsp_uuid *node_uuid,
+                                struct dcd_genericobj *dcd_prop)
+{
+       u32 len;
+       struct node_msgargs *pmsg_args;
+       struct node_taskargs *task_arg_obj;
+       enum node_type node_type = NODE_TASK;
+       struct dsp_ndbprops *pndb_props =
+           &(dcd_prop->obj_data.node_obj.ndb_props);
+       int status = 0;
+       char sz_uuid[MAXUUIDLEN];
+
+       status = dcd_get_object_def(hdcd_mgr, (struct dsp_uuid *)node_uuid,
+                                   DSP_DCDNODETYPE, dcd_prop);
+
+       if (!status) {
+               hnode->ntype = node_type = pndb_props->ntype;
+
+               /* Create UUID value to set in registry. */
+               uuid_uuid_to_string((struct dsp_uuid *)node_uuid, sz_uuid,
+                                   MAXUUIDLEN);
+               dev_dbg(bridge, "(node) UUID: %s\n", sz_uuid);
+
+               /* Fill in message args that come from NDB */
+               if (node_type != NODE_DEVICE) {
+                       pmsg_args = &(hnode->create_args.asa.node_msg_args);
+                       pmsg_args->seg_id =
+                           dcd_prop->obj_data.node_obj.msg_segid;
+                       pmsg_args->notify_type =
+                           dcd_prop->obj_data.node_obj.msg_notify_type;
+                       pmsg_args->max_msgs = pndb_props->message_depth;
+                       dev_dbg(bridge, "(node) Max Number of Messages: 0x%x\n",
+                               pmsg_args->max_msgs);
+               } else {
+                       /* Copy device name */
+                       DBC_REQUIRE(pndb_props->ac_name);
+                       len = strlen(pndb_props->ac_name);
+                       DBC_ASSERT(len < MAXDEVNAMELEN);
+                       hnode->pstr_dev_name = kzalloc(len + 1, GFP_KERNEL);
+                       if (hnode->pstr_dev_name == NULL) {
+                               status = -ENOMEM;
+                       } else {
+                               strncpy(hnode->pstr_dev_name,
+                                       pndb_props->ac_name, len);
+                       }
+               }
+       }
+       if (!status) {
+               /* Fill in create args that come from NDB */
+               if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) {
+                       task_arg_obj = &(hnode->create_args.asa.task_arg_obj);
+                       task_arg_obj->prio = pndb_props->prio;
+                       task_arg_obj->stack_size = pndb_props->stack_size;
+                       task_arg_obj->sys_stack_size =
+                           pndb_props->sys_stack_size;
+                       task_arg_obj->stack_seg = pndb_props->stack_seg;
+                       dev_dbg(bridge, "(node) Priority: 0x%x Stack Size: "
+                               "0x%x words System Stack Size: 0x%x words "
+                               "Stack Segment: 0x%x profile count : 0x%x\n",
+                               task_arg_obj->prio, task_arg_obj->stack_size,
+                               task_arg_obj->sys_stack_size,
+                               task_arg_obj->stack_seg,
+                               pndb_props->count_profiles);
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== get_proc_props ========
+ *  Purpose:
+ *      Retrieve the processor properties.
+ */
+static int get_proc_props(struct node_mgr *hnode_mgr,
+                                struct dev_object *hdev_obj)
+{
+       struct cfg_hostres *host_res;
+       struct bridge_dev_context *pbridge_context;
+       int status = 0;
+
+       status = dev_get_bridge_context(hdev_obj, &pbridge_context);
+       if (!pbridge_context)
+               status = -EFAULT;
+
+       if (!status) {
+               host_res = pbridge_context->resources;
+               if (!host_res)
+                       return -EPERM;
+               hnode_mgr->ul_chnl_offset = host_res->dw_chnl_offset;
+               hnode_mgr->ul_chnl_buf_size = host_res->dw_chnl_buf_size;
+               hnode_mgr->ul_num_chnls = host_res->dw_num_chnls;
+
+               /*
+                *  PROC will add an API to get dsp_processorinfo.
+                *  Fill in default values for now.
+                */
+               /* TODO -- Instead of hard coding, take from registry */
+               hnode_mgr->proc_family = 6000;
+               hnode_mgr->proc_type = 6410;
+               hnode_mgr->min_pri = DSP_NODE_MIN_PRIORITY;
+               hnode_mgr->max_pri = DSP_NODE_MAX_PRIORITY;
+               hnode_mgr->udsp_word_size = DSPWORDSIZE;
+               hnode_mgr->udsp_data_mau_size = DSPWORDSIZE;
+               hnode_mgr->udsp_mau_size = 1;
+
+       }
+       return status;
+}
+
+/*
+ *  ======== node_get_uuid_props ========
+ *  Purpose:
+ *      Fetch Node UUID properties from DCD/DOF file.
+ */
+int node_get_uuid_props(void *hprocessor,
+                              const struct dsp_uuid *node_uuid,
+                              struct dsp_ndbprops *node_props)
+{
+       struct node_mgr *hnode_mgr = NULL;
+       struct dev_object *hdev_obj;
+       int status = 0;
+       struct dcd_nodeprops dcd_node_props;
+       struct dsp_processorstate proc_state;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hprocessor != NULL);
+       DBC_REQUIRE(node_uuid != NULL);
+
+       if (hprocessor == NULL || node_uuid == NULL) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       status = proc_get_state(hprocessor, &proc_state,
+                               sizeof(struct dsp_processorstate));
+       if (status)
+               goto func_end;
+       /* If processor is in error state then don't attempt
+          to send the message */
+       if (proc_state.proc_state == PROC_ERROR) {
+               status = -EPERM;
+               goto func_end;
+       }
+
+       status = proc_get_dev_object(hprocessor, &hdev_obj);
+       if (hdev_obj) {
+               status = dev_get_node_manager(hdev_obj, &hnode_mgr);
+               if (hnode_mgr == NULL) {
+                       status = -EFAULT;
+                       goto func_end;
+               }
+       }
+
+       /*
+        * Enter the critical section. This is needed because
+        * dcd_get_object_def will ultimately end up calling dbll_open/close,
+        * which needs to be protected in order to not corrupt the zlib manager
+        * (COD).
+        */
+       mutex_lock(&hnode_mgr->node_mgr_lock);
+
+       dcd_node_props.pstr_create_phase_fxn = NULL;
+       dcd_node_props.pstr_execute_phase_fxn = NULL;
+       dcd_node_props.pstr_delete_phase_fxn = NULL;
+       dcd_node_props.pstr_i_alg_name = NULL;
+
+       status = dcd_get_object_def(hnode_mgr->hdcd_mgr,
+               (struct dsp_uuid *)node_uuid, DSP_DCDNODETYPE,
+               (struct dcd_genericobj *)&dcd_node_props);
+
+       if (!status) {
+               *node_props = dcd_node_props.ndb_props;
+               kfree(dcd_node_props.pstr_create_phase_fxn);
+
+               kfree(dcd_node_props.pstr_execute_phase_fxn);
+
+               kfree(dcd_node_props.pstr_delete_phase_fxn);
+
+               kfree(dcd_node_props.pstr_i_alg_name);
+       }
+       /*  Leave the critical section, we're done. */
+       mutex_unlock(&hnode_mgr->node_mgr_lock);
+func_end:
+       return status;
+}
+
+/*
+ *  ======== get_rms_fxns ========
+ *  Purpose:
+ *      Retrieve the RMS functions.
+ */
+static int get_rms_fxns(struct node_mgr *hnode_mgr)
+{
+       s32 i;
+       struct dev_object *dev_obj = hnode_mgr->hdev_obj;
+       int status = 0;
+
+       static char *psz_fxns[NUMRMSFXNS] = {
+               "RMS_queryServer",      /* RMSQUERYSERVER */
+               "RMS_configureServer",  /* RMSCONFIGURESERVER */
+               "RMS_createNode",       /* RMSCREATENODE */
+               "RMS_executeNode",      /* RMSEXECUTENODE */
+               "RMS_deleteNode",       /* RMSDELETENODE */
+               "RMS_changeNodePriority",       /* RMSCHANGENODEPRIORITY */
+               "RMS_readMemory",       /* RMSREADMEMORY */
+               "RMS_writeMemory",      /* RMSWRITEMEMORY */
+               "RMS_copy",     /* RMSCOPY */
+       };
+
+       for (i = 0; i < NUMRMSFXNS; i++) {
+               status = dev_get_symbol(dev_obj, psz_fxns[i],
+                                       &(hnode_mgr->ul_fxn_addrs[i]));
+               if (status) {
+                       if (status == -ESPIPE) {
+                               /*
+                                *  May be loaded dynamically (in the future),
+                                *  but return an error for now.
+                                */
+                               dev_dbg(bridge, "%s: RMS function: %s currently"
+                                       " not loaded\n", __func__, psz_fxns[i]);
+                       } else {
+                               dev_dbg(bridge, "%s: Symbol not found: %s "
+                                       "status = 0x%x\n", __func__,
+                                       psz_fxns[i], status);
+                               break;
+                       }
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== ovly ========
+ *  Purpose:
+ *      Called during overlay.Sends command to RMS to copy a block of data.
+ */
+static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr,
+               u32 ul_num_bytes, u32 mem_space)
+{
+       struct node_object *hnode = (struct node_object *)priv_ref;
+       struct node_mgr *hnode_mgr;
+       u32 ul_bytes = 0;
+       u32 ul_size;
+       u32 ul_timeout;
+       int status = 0;
+       struct bridge_dev_context *hbridge_context;
+       /* Function interface to Bridge driver*/
+       struct bridge_drv_interface *intf_fxns;
+
+       DBC_REQUIRE(hnode);
+
+       hnode_mgr = hnode->hnode_mgr;
+
+       ul_size = ul_num_bytes / hnode_mgr->udsp_word_size;
+       ul_timeout = hnode->utimeout;
+
+       /* Call new MemCopy function */
+       intf_fxns = hnode_mgr->intf_fxns;
+       status = dev_get_bridge_context(hnode_mgr->hdev_obj, &hbridge_context);
+       if (!status) {
+               status =
+                   (*intf_fxns->pfn_brd_mem_copy) (hbridge_context,
+                                               dsp_run_addr, dsp_load_addr,
+                                               ul_num_bytes, (u32) mem_space);
+               if (!status)
+                       ul_bytes = ul_num_bytes;
+               else
+                       pr_debug("%s: failed to copy brd memory, status 0x%x\n",
+                                __func__, status);
+       } else {
+               pr_debug("%s: failed to get Bridge context, status 0x%x\n",
+                        __func__, status);
+       }
+
+       return ul_bytes;
+}
+
+/*
+ *  ======== mem_write ========
+ */
+static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf,
+                    u32 ul_num_bytes, u32 mem_space)
+{
+       struct node_object *hnode = (struct node_object *)priv_ref;
+       struct node_mgr *hnode_mgr;
+       u16 mem_sect_type;
+       u32 ul_timeout;
+       int status = 0;
+       struct bridge_dev_context *hbridge_context;
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+
+       DBC_REQUIRE(hnode);
+       DBC_REQUIRE(mem_space & DBLL_CODE || mem_space & DBLL_DATA);
+
+       hnode_mgr = hnode->hnode_mgr;
+
+       ul_timeout = hnode->utimeout;
+       mem_sect_type = (mem_space & DBLL_CODE) ? RMS_CODE : RMS_DATA;
+
+       /* Call new MemWrite function */
+       intf_fxns = hnode_mgr->intf_fxns;
+       status = dev_get_bridge_context(hnode_mgr->hdev_obj, &hbridge_context);
+       status = (*intf_fxns->pfn_brd_mem_write) (hbridge_context, pbuf,
+                                       dsp_add, ul_num_bytes, mem_sect_type);
+
+       return ul_num_bytes;
+}
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+/*
+ *  ======== node_find_addr ========
+ */
+int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
+               u32 offset_range, void *sym_addr_output, char *sym_name)
+{
+       struct node_object *node_obj;
+       int status = -ENOENT;
+       u32 n;
+
+       pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x,  %s)\n", __func__,
+                       (unsigned int) node_mgr,
+                       sym_addr, offset_range,
+                       (unsigned int) sym_addr_output, sym_name);
+
+       node_obj = (struct node_object *)(node_mgr->node_list->head.next);
+
+       for (n = 0; n < node_mgr->num_nodes; n++) {
+               status = nldr_find_addr(node_obj->nldr_node_obj, sym_addr,
+                       offset_range, sym_addr_output, sym_name);
+
+               if (!status)
+                       break;
+
+               node_obj = (struct node_object *) (node_obj->list_elem.next);
+       }
+
+       return status;
+}
+#endif
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
new file mode 100644 (file)
index 0000000..44c26e1
--- /dev/null
@@ -0,0 +1,1936 @@
+/*
+ * proc.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Processor interface at the driver level.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+/* ------------------------------------ Host OS */
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/list.h>
+#include <dspbridge/ntfy.h>
+#include <dspbridge/sync.h>
+/*  ----------------------------------- Bridge Driver */
+#include <dspbridge/dspdefs.h>
+#include <dspbridge/dspdeh.h>
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/cod.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/procpriv.h>
+#include <dspbridge/dmm.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/mgr.h>
+#include <dspbridge/node.h>
+#include <dspbridge/nldr.h>
+#include <dspbridge/rmm.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/dbdcd.h>
+#include <dspbridge/msg.h>
+#include <dspbridge/dspioctl.h>
+#include <dspbridge/drv.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/proc.h>
+#include <dspbridge/pwr.h>
+
+#include <dspbridge/resourcecleanup.h>
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define MAXCMDLINELEN       255
+#define PROC_ENVPROCID      "PROC_ID=%d"
+#define MAXPROCIDLEN   (8 + 5)
+#define PROC_DFLT_TIMEOUT   10000      /* Time out in milliseconds */
+#define PWR_TIMEOUT     500    /* Sleep/wake timout in msec */
+#define EXTEND       "_EXT_END"        /* Extmem end addr in DSP binary */
+
+#define DSP_CACHE_LINE 128
+
+#define BUFMODE_MASK   (3 << 14)
+
+/* Buffer modes from DSP perspective */
+#define RBUF           0x4000          /* Input buffer */
+#define WBUF           0x8000          /* Output Buffer */
+
+extern struct device *bridge;
+
+/*  ----------------------------------- Globals */
+
+/* The proc_object structure. */
+struct proc_object {
+       struct list_head link;  /* Link to next proc_object */
+       struct dev_object *hdev_obj;    /* Device this PROC represents */
+       u32 process;            /* Process owning this Processor */
+       struct mgr_object *hmgr_obj;    /* Manager Object Handle */
+       u32 attach_count;       /* Processor attach count */
+       u32 processor_id;       /* Processor number */
+       u32 utimeout;           /* Time out count */
+       enum dsp_procstate proc_state;  /* Processor state */
+       u32 ul_unit;            /* DDSP unit number */
+       bool is_already_attached;       /*
+                                        * True if the Device below has
+                                        * GPP Client attached
+                                        */
+       struct ntfy_object *ntfy_obj;   /* Manages  notifications */
+       /* Bridge Context Handle */
+       struct bridge_dev_context *hbridge_context;
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+       char *psz_last_coff;
+       struct list_head proc_list;
+};
+
+static u32 refs;
+
+DEFINE_MUTEX(proc_lock);       /* For critical sections */
+
+/*  ----------------------------------- Function Prototypes */
+static int proc_monitor(struct proc_object *proc_obj);
+static s32 get_envp_count(char **envp);
+static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
+                          s32 cnew_envp, char *sz_var);
+
+/* remember mapping information */
+static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt,
+                               u32 mpu_addr, u32 dsp_addr, u32 size)
+{
+       struct dmm_map_object *map_obj;
+
+       u32 num_usr_pgs = size / PG_SIZE4K;
+
+       pr_debug("%s: adding map info: mpu_addr 0x%x virt 0x%x size 0x%x\n",
+                                               __func__, mpu_addr,
+                                               dsp_addr, size);
+
+       map_obj = kzalloc(sizeof(struct dmm_map_object), GFP_KERNEL);
+       if (!map_obj) {
+               pr_err("%s: kzalloc failed\n", __func__);
+               return NULL;
+       }
+       INIT_LIST_HEAD(&map_obj->link);
+
+       map_obj->pages = kcalloc(num_usr_pgs, sizeof(struct page *),
+                                                       GFP_KERNEL);
+       if (!map_obj->pages) {
+               pr_err("%s: kzalloc failed\n", __func__);
+               kfree(map_obj);
+               return NULL;
+       }
+
+       map_obj->mpu_addr = mpu_addr;
+       map_obj->dsp_addr = dsp_addr;
+       map_obj->size = size;
+       map_obj->num_usr_pgs = num_usr_pgs;
+
+       spin_lock(&pr_ctxt->dmm_map_lock);
+       list_add(&map_obj->link, &pr_ctxt->dmm_map_list);
+       spin_unlock(&pr_ctxt->dmm_map_lock);
+
+       return map_obj;
+}
+
+static int match_exact_map_obj(struct dmm_map_object *map_obj,
+                                       u32 dsp_addr, u32 size)
+{
+       if (map_obj->dsp_addr == dsp_addr && map_obj->size != size)
+               pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n",
+                               __func__, dsp_addr, map_obj->size, size);
+
+       return map_obj->dsp_addr == dsp_addr &&
+               map_obj->size == size;
+}
+
+static void remove_mapping_information(struct process_context *pr_ctxt,
+                                               u32 dsp_addr, u32 size)
+{
+       struct dmm_map_object *map_obj;
+
+       pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__,
+                                                       dsp_addr, size);
+
+       spin_lock(&pr_ctxt->dmm_map_lock);
+       list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
+               pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
+                                                       __func__,
+                                                       map_obj->mpu_addr,
+                                                       map_obj->dsp_addr,
+                                                       map_obj->size);
+
+               if (match_exact_map_obj(map_obj, dsp_addr, size)) {
+                       pr_debug("%s: match, deleting map info\n", __func__);
+                       list_del(&map_obj->link);
+                       kfree(map_obj->dma_info.sg);
+                       kfree(map_obj->pages);
+                       kfree(map_obj);
+                       goto out;
+               }
+               pr_debug("%s: candidate didn't match\n", __func__);
+       }
+
+       pr_err("%s: failed to find given map info\n", __func__);
+out:
+       spin_unlock(&pr_ctxt->dmm_map_lock);
+}
+
+static int match_containing_map_obj(struct dmm_map_object *map_obj,
+                                       u32 mpu_addr, u32 size)
+{
+       u32 map_obj_end = map_obj->mpu_addr + map_obj->size;
+
+       return mpu_addr >= map_obj->mpu_addr &&
+               mpu_addr + size <= map_obj_end;
+}
+
+static struct dmm_map_object *find_containing_mapping(
+                               struct process_context *pr_ctxt,
+                               u32 mpu_addr, u32 size)
+{
+       struct dmm_map_object *map_obj;
+       pr_debug("%s: looking for mpu_addr 0x%x size 0x%x\n", __func__,
+                                               mpu_addr, size);
+
+       spin_lock(&pr_ctxt->dmm_map_lock);
+       list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
+               pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
+                                               __func__,
+                                               map_obj->mpu_addr,
+                                               map_obj->dsp_addr,
+                                               map_obj->size);
+               if (match_containing_map_obj(map_obj, mpu_addr, size)) {
+                       pr_debug("%s: match!\n", __func__);
+                       goto out;
+               }
+
+               pr_debug("%s: no match!\n", __func__);
+       }
+
+       map_obj = NULL;
+out:
+       spin_unlock(&pr_ctxt->dmm_map_lock);
+       return map_obj;
+}
+
+static int find_first_page_in_cache(struct dmm_map_object *map_obj,
+                                       unsigned long mpu_addr)
+{
+       u32 mapped_base_page = map_obj->mpu_addr >> PAGE_SHIFT;
+       u32 requested_base_page = mpu_addr >> PAGE_SHIFT;
+       int pg_index = requested_base_page - mapped_base_page;
+
+       if (pg_index < 0 || pg_index >= map_obj->num_usr_pgs) {
+               pr_err("%s: failed (got %d)\n", __func__, pg_index);
+               return -1;
+       }
+
+       pr_debug("%s: first page is %d\n", __func__, pg_index);
+       return pg_index;
+}
+
+static inline struct page *get_mapping_page(struct dmm_map_object *map_obj,
+                                                               int pg_i)
+{
+       pr_debug("%s: looking for pg_i %d, num_usr_pgs: %d\n", __func__,
+                                       pg_i, map_obj->num_usr_pgs);
+
+       if (pg_i < 0 || pg_i >= map_obj->num_usr_pgs) {
+               pr_err("%s: requested pg_i %d is out of mapped range\n",
+                               __func__, pg_i);
+               return NULL;
+       }
+
+       return map_obj->pages[pg_i];
+}
+
+/*
+ *  ======== proc_attach ========
+ *  Purpose:
+ *      Prepare for communication with a particular DSP processor, and return
+ *      a handle to the processor object.
+ */
+int
+proc_attach(u32 processor_id,
+           const struct dsp_processorattrin *attr_in,
+           void **ph_processor, struct process_context *pr_ctxt)
+{
+       int status = 0;
+       struct dev_object *hdev_obj;
+       struct proc_object *p_proc_object = NULL;
+       struct mgr_object *hmgr_obj = NULL;
+       struct drv_object *hdrv_obj = NULL;
+       u8 dev_type;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(ph_processor != NULL);
+
+       if (pr_ctxt->hprocessor) {
+               *ph_processor = pr_ctxt->hprocessor;
+               return status;
+       }
+
+       /* Get the Driver and Manager Object Handles */
+       status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
+       if (!status)
+               status = cfg_get_object((u32 *) &hmgr_obj, REG_MGR_OBJECT);
+
+       if (!status) {
+               /* Get the Device Object */
+               status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
+       }
+       if (!status)
+               status = dev_get_dev_type(hdev_obj, &dev_type);
+
+       if (status)
+               goto func_end;
+
+       /* If we made it this far, create the Proceesor object: */
+       p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
+       /* Fill out the Processor Object: */
+       if (p_proc_object == NULL) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       p_proc_object->hdev_obj = hdev_obj;
+       p_proc_object->hmgr_obj = hmgr_obj;
+       p_proc_object->processor_id = dev_type;
+       /* Store TGID instead of process handle */
+       p_proc_object->process = current->tgid;
+
+       INIT_LIST_HEAD(&p_proc_object->proc_list);
+
+       if (attr_in)
+               p_proc_object->utimeout = attr_in->utimeout;
+       else
+               p_proc_object->utimeout = PROC_DFLT_TIMEOUT;
+
+       status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
+       if (!status) {
+               status = dev_get_bridge_context(hdev_obj,
+                                            &p_proc_object->hbridge_context);
+               if (status)
+                       kfree(p_proc_object);
+       } else
+               kfree(p_proc_object);
+
+       if (status)
+               goto func_end;
+
+       /* Create the Notification Object */
+       /* This is created with no event mask, no notify mask
+        * and no valid handle to the notification. They all get
+        * filled up when proc_register_notify is called */
+       p_proc_object->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
+                                                       GFP_KERNEL);
+       if (p_proc_object->ntfy_obj)
+               ntfy_init(p_proc_object->ntfy_obj);
+       else
+               status = -ENOMEM;
+
+       if (!status) {
+               /* Insert the Processor Object into the DEV List.
+                * Return handle to this Processor Object:
+                * Find out if the Device is already attached to a
+                * Processor. If so, return AlreadyAttached status */
+               lst_init_elem(&p_proc_object->link);
+               status = dev_insert_proc_object(p_proc_object->hdev_obj,
+                                               (u32) p_proc_object,
+                                               &p_proc_object->
+                                               is_already_attached);
+               if (!status) {
+                       if (p_proc_object->is_already_attached)
+                               status = 0;
+               } else {
+                       if (p_proc_object->ntfy_obj) {
+                               ntfy_delete(p_proc_object->ntfy_obj);
+                               kfree(p_proc_object->ntfy_obj);
+                       }
+
+                       kfree(p_proc_object);
+               }
+               if (!status) {
+                       *ph_processor = (void *)p_proc_object;
+                       pr_ctxt->hprocessor = *ph_processor;
+                       (void)proc_notify_clients(p_proc_object,
+                                                 DSP_PROCESSORATTACH);
+               }
+       } else {
+               /* Don't leak memory if status is failed */
+               kfree(p_proc_object);
+       }
+func_end:
+       DBC_ENSURE((status == -EPERM && *ph_processor == NULL) ||
+                  (!status && p_proc_object) ||
+                  (status == 0 && p_proc_object));
+
+       return status;
+}
+
+static int get_exec_file(struct cfg_devnode *dev_node_obj,
+                               struct dev_object *hdev_obj,
+                               u32 size, char *exec_file)
+{
+       u8 dev_type;
+       s32 len;
+
+       dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
+       if (dev_type == DSP_UNIT) {
+               return cfg_get_exec_file(dev_node_obj, size, exec_file);
+       } else if (dev_type == IVA_UNIT) {
+               if (iva_img) {
+                       len = strlen(iva_img);
+                       strncpy(exec_file, iva_img, len + 1);
+                       return 0;
+               }
+       }
+       return -ENOENT;
+}
+
+/*
+ *  ======== proc_auto_start ======== =
+ *  Purpose:
+ *      A Particular device gets loaded with the default image
+ *      if the AutoStart flag is set.
+ *  Parameters:
+ *      hdev_obj:     Handle to the Device
+ *  Returns:
+ *      0:   On Successful Loading
+ *      -EPERM  General Failure
+ *  Requires:
+ *      hdev_obj != NULL
+ *  Ensures:
+ */
+int proc_auto_start(struct cfg_devnode *dev_node_obj,
+                          struct dev_object *hdev_obj)
+{
+       int status = -EPERM;
+       struct proc_object *p_proc_object;
+       char sz_exec_file[MAXCMDLINELEN];
+       char *argv[2];
+       struct mgr_object *hmgr_obj = NULL;
+       u8 dev_type;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dev_node_obj != NULL);
+       DBC_REQUIRE(hdev_obj != NULL);
+
+       /* Create a Dummy PROC Object */
+       status = cfg_get_object((u32 *) &hmgr_obj, REG_MGR_OBJECT);
+       if (status)
+               goto func_end;
+
+       p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
+       if (p_proc_object == NULL) {
+               status = -ENOMEM;
+               goto func_end;
+       }
+       p_proc_object->hdev_obj = hdev_obj;
+       p_proc_object->hmgr_obj = hmgr_obj;
+       status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
+       if (!status)
+               status = dev_get_bridge_context(hdev_obj,
+                                            &p_proc_object->hbridge_context);
+       if (status)
+               goto func_cont;
+
+       /* Stop the Device, put it into standby mode */
+       status = proc_stop(p_proc_object);
+
+       if (status)
+               goto func_cont;
+
+       /* Get the default executable for this board... */
+       dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
+       p_proc_object->processor_id = dev_type;
+       status = get_exec_file(dev_node_obj, hdev_obj, sizeof(sz_exec_file),
+                              sz_exec_file);
+       if (!status) {
+               argv[0] = sz_exec_file;
+               argv[1] = NULL;
+               /* ...and try to load it: */
+               status = proc_load(p_proc_object, 1, (const char **)argv, NULL);
+               if (!status)
+                       status = proc_start(p_proc_object);
+       }
+       kfree(p_proc_object->psz_last_coff);
+       p_proc_object->psz_last_coff = NULL;
+func_cont:
+       kfree(p_proc_object);
+func_end:
+       return status;
+}
+
+/*
+ *  ======== proc_ctrl ========
+ *  Purpose:
+ *      Pass control information to the GPP device driver managing the
+ *      DSP processor.
+ *
+ *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
+ *      application developer's API.
+ *      Call the bridge_dev_ctrl fxn with the Argument. This is a Synchronous
+ *      Operation. arg can be null.
+ */
+int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = hprocessor;
+       u32 timeout = 0;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (p_proc_object) {
+               /* intercept PWR deep sleep command */
+               if (dw_cmd == BRDIOCTL_DEEPSLEEP) {
+                       timeout = arg->cb_data;
+                       status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
+               }
+               /* intercept PWR emergency sleep command */
+               else if (dw_cmd == BRDIOCTL_EMERGENCYSLEEP) {
+                       timeout = arg->cb_data;
+                       status = pwr_sleep_dsp(PWR_EMERGENCYDEEPSLEEP, timeout);
+               } else if (dw_cmd == PWR_DEEPSLEEP) {
+                       /* timeout = arg->cb_data; */
+                       status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
+               }
+               /* intercept PWR wake commands */
+               else if (dw_cmd == BRDIOCTL_WAKEUP) {
+                       timeout = arg->cb_data;
+                       status = pwr_wake_dsp(timeout);
+               } else if (dw_cmd == PWR_WAKEUP) {
+                       /* timeout = arg->cb_data; */
+                       status = pwr_wake_dsp(timeout);
+               } else
+                   if (!((*p_proc_object->intf_fxns->pfn_dev_cntrl)
+                                     (p_proc_object->hbridge_context, dw_cmd,
+                                      arg))) {
+                       status = 0;
+               } else {
+                       status = -EPERM;
+               }
+       } else {
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== proc_detach ========
+ *  Purpose:
+ *      Destroys the  Processor Object. Removes the notification from the Dev
+ *      List.
+ */
+int proc_detach(struct process_context *pr_ctxt)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = NULL;
+
+       DBC_REQUIRE(refs > 0);
+
+       p_proc_object = (struct proc_object *)pr_ctxt->hprocessor;
+
+       if (p_proc_object) {
+               /* Notify the Client */
+               ntfy_notify(p_proc_object->ntfy_obj, DSP_PROCESSORDETACH);
+               /* Remove the notification memory */
+               if (p_proc_object->ntfy_obj) {
+                       ntfy_delete(p_proc_object->ntfy_obj);
+                       kfree(p_proc_object->ntfy_obj);
+               }
+
+               kfree(p_proc_object->psz_last_coff);
+               p_proc_object->psz_last_coff = NULL;
+               /* Remove the Proc from the DEV List */
+               (void)dev_remove_proc_object(p_proc_object->hdev_obj,
+                                            (u32) p_proc_object);
+               /* Free the Processor Object */
+               kfree(p_proc_object);
+               pr_ctxt->hprocessor = NULL;
+       } else {
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== proc_enum_nodes ========
+ *  Purpose:
+ *      Enumerate and get configuration information about nodes allocated
+ *      on a DSP processor.
+ */
+int proc_enum_nodes(void *hprocessor, void **node_tab,
+                          u32 node_tab_size, u32 *pu_num_nodes,
+                          u32 *pu_allocated)
+{
+       int status = -EPERM;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct node_mgr *hnode_mgr = NULL;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(node_tab != NULL || node_tab_size == 0);
+       DBC_REQUIRE(pu_num_nodes != NULL);
+       DBC_REQUIRE(pu_allocated != NULL);
+
+       if (p_proc_object) {
+               if (!(dev_get_node_manager(p_proc_object->hdev_obj,
+                                                      &hnode_mgr))) {
+                       if (hnode_mgr) {
+                               status = node_enum_nodes(hnode_mgr, node_tab,
+                                                        node_tab_size,
+                                                        pu_num_nodes,
+                                                        pu_allocated);
+                       }
+               }
+       } else {
+               status = -EFAULT;
+       }
+
+       return status;
+}
+
+/* Cache operation against kernel address instead of users */
+static int build_dma_sg(struct dmm_map_object *map_obj, unsigned long start,
+                                               ssize_t len, int pg_i)
+{
+       struct page *page;
+       unsigned long offset;
+       ssize_t rest;
+       int ret = 0, i = 0;
+       struct scatterlist *sg = map_obj->dma_info.sg;
+
+       while (len) {
+               page = get_mapping_page(map_obj, pg_i);
+               if (!page) {
+                       pr_err("%s: no page for %08lx\n", __func__, start);
+                       ret = -EINVAL;
+                       goto out;
+               } else if (IS_ERR(page)) {
+                       pr_err("%s: err page for %08lx(%lu)\n", __func__, start,
+                              PTR_ERR(page));
+                       ret = PTR_ERR(page);
+                       goto out;
+               }
+
+               offset = start & ~PAGE_MASK;
+               rest = min_t(ssize_t, PAGE_SIZE - offset, len);
+
+               sg_set_page(&sg[i], page, rest, offset);
+
+               len -= rest;
+               start += rest;
+               pg_i++, i++;
+       }
+
+       if (i != map_obj->dma_info.num_pages) {
+               pr_err("%s: bad number of sg iterations\n", __func__);
+               ret = -EFAULT;
+               goto out;
+       }
+
+out:
+       return ret;
+}
+
+static int memory_regain_ownership(struct dmm_map_object *map_obj,
+               unsigned long start, ssize_t len, enum dma_data_direction dir)
+{
+       int ret = 0;
+       unsigned long first_data_page = start >> PAGE_SHIFT;
+       unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
+       /* calculating the number of pages this area spans */
+       unsigned long num_pages = last_data_page - first_data_page + 1;
+       struct bridge_dma_map_info *dma_info = &map_obj->dma_info;
+
+       if (!dma_info->sg)
+               goto out;
+
+       if (dma_info->dir != dir || dma_info->num_pages != num_pages) {
+               pr_err("%s: dma info doesn't match given params\n", __func__);
+               return -EINVAL;
+       }
+
+       dma_unmap_sg(bridge, dma_info->sg, num_pages, dma_info->dir);
+
+       pr_debug("%s: dma_map_sg unmapped\n", __func__);
+
+       kfree(dma_info->sg);
+
+       map_obj->dma_info.sg = NULL;
+
+out:
+       return ret;
+}
+
+/* Cache operation against kernel address instead of users */
+static int memory_give_ownership(struct dmm_map_object *map_obj,
+               unsigned long start, ssize_t len, enum dma_data_direction dir)
+{
+       int pg_i, ret, sg_num;
+       struct scatterlist *sg;
+       unsigned long first_data_page = start >> PAGE_SHIFT;
+       unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
+       /* calculating the number of pages this area spans */
+       unsigned long num_pages = last_data_page - first_data_page + 1;
+
+       pg_i = find_first_page_in_cache(map_obj, start);
+       if (pg_i < 0) {
+               pr_err("%s: failed to find first page in cache\n", __func__);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       sg = kcalloc(num_pages, sizeof(*sg), GFP_KERNEL);
+       if (!sg) {
+               pr_err("%s: kcalloc failed\n", __func__);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       sg_init_table(sg, num_pages);
+
+       /* cleanup a previous sg allocation */
+       /* this may happen if application doesn't signal for e/o DMA */
+       kfree(map_obj->dma_info.sg);
+
+       map_obj->dma_info.sg = sg;
+       map_obj->dma_info.dir = dir;
+       map_obj->dma_info.num_pages = num_pages;
+
+       ret = build_dma_sg(map_obj, start, len, pg_i);
+       if (ret)
+               goto kfree_sg;
+
+       sg_num = dma_map_sg(bridge, sg, num_pages, dir);
+       if (sg_num < 1) {
+               pr_err("%s: dma_map_sg failed: %d\n", __func__, sg_num);
+               ret = -EFAULT;
+               goto kfree_sg;
+       }
+
+       pr_debug("%s: dma_map_sg mapped %d elements\n", __func__, sg_num);
+       map_obj->dma_info.sg_num = sg_num;
+
+       return 0;
+
+kfree_sg:
+       kfree(sg);
+       map_obj->dma_info.sg = NULL;
+out:
+       return ret;
+}
+
+int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
+                               enum dma_data_direction dir)
+{
+       /* Keep STATUS here for future additions to this function */
+       int status = 0;
+       struct process_context *pr_ctxt = (struct process_context *) hprocessor;
+       struct dmm_map_object *map_obj;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!pr_ctxt) {
+               status = -EFAULT;
+               goto err_out;
+       }
+
+       pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
+                                                       (u32)pmpu_addr,
+                                                       ul_size, dir);
+
+       /* find requested memory are in cached mapping information */
+       map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
+       if (!map_obj) {
+               pr_err("%s: find_containing_mapping failed\n", __func__);
+               status = -EFAULT;
+               goto err_out;
+       }
+
+       if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
+               pr_err("%s: InValid address parameters %p %x\n",
+                              __func__, pmpu_addr, ul_size);
+               status = -EFAULT;
+       }
+
+err_out:
+
+       return status;
+}
+
+int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
+                       enum dma_data_direction dir)
+{
+       /* Keep STATUS here for future additions to this function */
+       int status = 0;
+       struct process_context *pr_ctxt = (struct process_context *) hprocessor;
+       struct dmm_map_object *map_obj;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!pr_ctxt) {
+               status = -EFAULT;
+               goto err_out;
+       }
+
+       pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
+                                                       (u32)pmpu_addr,
+                                                       ul_size, dir);
+
+       /* find requested memory are in cached mapping information */
+       map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
+       if (!map_obj) {
+               pr_err("%s: find_containing_mapping failed\n", __func__);
+               status = -EFAULT;
+               goto err_out;
+       }
+
+       if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
+               pr_err("%s: InValid address parameters %p %x\n",
+                      __func__, pmpu_addr, ul_size);
+               status = -EFAULT;
+               goto err_out;
+       }
+
+err_out:
+       return status;
+}
+
+/*
+ *  ======== proc_flush_memory ========
+ *  Purpose:
+ *     Flush cache
+ */
+int proc_flush_memory(void *hprocessor, void *pmpu_addr,
+                            u32 ul_size, u32 ul_flags)
+{
+       enum dma_data_direction dir = DMA_BIDIRECTIONAL;
+
+       return proc_begin_dma(hprocessor, pmpu_addr, ul_size, dir);
+}
+
+/*
+ *  ======== proc_invalidate_memory ========
+ *  Purpose:
+ *     Invalidates the memory specified
+ */
+int proc_invalidate_memory(void *hprocessor, void *pmpu_addr, u32 size)
+{
+       enum dma_data_direction dir = DMA_FROM_DEVICE;
+
+       return proc_begin_dma(hprocessor, pmpu_addr, size, dir);
+}
+
+/*
+ *  ======== proc_get_resource_info ========
+ *  Purpose:
+ *      Enumerate the resources currently available on a processor.
+ */
+int proc_get_resource_info(void *hprocessor, u32 resource_type,
+                                 struct dsp_resourceinfo *resource_info,
+                                 u32 resource_info_size)
+{
+       int status = -EPERM;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct node_mgr *hnode_mgr = NULL;
+       struct nldr_object *nldr_obj = NULL;
+       struct rmm_target_obj *rmm = NULL;
+       struct io_mgr *hio_mgr = NULL;  /* IO manager handle */
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(resource_info != NULL);
+       DBC_REQUIRE(resource_info_size >= sizeof(struct dsp_resourceinfo));
+
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       switch (resource_type) {
+       case DSP_RESOURCE_DYNDARAM:
+       case DSP_RESOURCE_DYNSARAM:
+       case DSP_RESOURCE_DYNEXTERNAL:
+       case DSP_RESOURCE_DYNSRAM:
+               status = dev_get_node_manager(p_proc_object->hdev_obj,
+                                             &hnode_mgr);
+               if (!hnode_mgr) {
+                       status = -EFAULT;
+                       goto func_end;
+               }
+
+               status = node_get_nldr_obj(hnode_mgr, &nldr_obj);
+               if (!status) {
+                       status = nldr_get_rmm_manager(nldr_obj, &rmm);
+                       if (rmm) {
+                               if (!rmm_stat(rmm,
+                                             (enum dsp_memtype)resource_type,
+                                             (struct dsp_memstat *)
+                                             &(resource_info->result.
+                                               mem_stat)))
+                                       status = -EINVAL;
+                       } else {
+                               status = -EFAULT;
+                       }
+               }
+               break;
+       case DSP_RESOURCE_PROCLOAD:
+               status = dev_get_io_mgr(p_proc_object->hdev_obj, &hio_mgr);
+               if (hio_mgr)
+                       status =
+                           p_proc_object->intf_fxns->
+                           pfn_io_get_proc_load(hio_mgr,
+                                                (struct dsp_procloadstat *)
+                                                &(resource_info->result.
+                                                  proc_load_stat));
+               else
+                       status = -EFAULT;
+               break;
+       default:
+               status = -EPERM;
+               break;
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== proc_exit ========
+ *  Purpose:
+ *      Decrement reference count, and free resources when reference count is
+ *      0.
+ */
+void proc_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== proc_get_dev_object ========
+ *  Purpose:
+ *      Return the Dev Object handle for a given Processor.
+ *
+ */
+int proc_get_dev_object(void *hprocessor,
+                              struct dev_object **device_obj)
+{
+       int status = -EPERM;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(device_obj != NULL);
+
+       if (p_proc_object) {
+               *device_obj = p_proc_object->hdev_obj;
+               status = 0;
+       } else {
+               *device_obj = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE((!status && *device_obj != NULL) ||
+                  (status && *device_obj == NULL));
+
+       return status;
+}
+
+/*
+ *  ======== proc_get_state ========
+ *  Purpose:
+ *      Report the state of the specified DSP processor.
+ */
+int proc_get_state(void *hprocessor,
+                         struct dsp_processorstate *proc_state_obj,
+                         u32 state_info_size)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       int brd_status;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(proc_state_obj != NULL);
+       DBC_REQUIRE(state_info_size >= sizeof(struct dsp_processorstate));
+
+       if (p_proc_object) {
+               /* First, retrieve BRD state information */
+               status = (*p_proc_object->intf_fxns->pfn_brd_status)
+                   (p_proc_object->hbridge_context, &brd_status);
+               if (!status) {
+                       switch (brd_status) {
+                       case BRD_STOPPED:
+                               proc_state_obj->proc_state = PROC_STOPPED;
+                               break;
+                       case BRD_SLEEP_TRANSITION:
+                       case BRD_DSP_HIBERNATION:
+                               /* Fall through */
+                       case BRD_RUNNING:
+                               proc_state_obj->proc_state = PROC_RUNNING;
+                               break;
+                       case BRD_LOADED:
+                               proc_state_obj->proc_state = PROC_LOADED;
+                               break;
+                       case BRD_ERROR:
+                               proc_state_obj->proc_state = PROC_ERROR;
+                               break;
+                       default:
+                               proc_state_obj->proc_state = 0xFF;
+                               status = -EPERM;
+                               break;
+                       }
+               }
+       } else {
+               status = -EFAULT;
+       }
+       dev_dbg(bridge, "%s, results: status: 0x%x proc_state_obj: 0x%x\n",
+               __func__, status, proc_state_obj->proc_state);
+       return status;
+}
+
+/*
+ *  ======== proc_get_trace ========
+ *  Purpose:
+ *      Retrieve the current contents of the trace buffer, located on the
+ *      Processor.  Predefined symbols for the trace buffer must have been
+ *      configured into the DSP executable.
+ *  Details:
+ *      We support using the symbols SYS_PUTCBEG and SYS_PUTCEND to define a
+ *      trace buffer, only.  Treat it as an undocumented feature.
+ *      This call is destructive, meaning the processor is placed in the monitor
+ *      state as a result of this function.
+ */
+int proc_get_trace(void *hprocessor, u8 * pbuf, u32 max_size)
+{
+       int status;
+       status = -ENOSYS;
+       return status;
+}
+
+/*
+ *  ======== proc_init ========
+ *  Purpose:
+ *      Initialize PROC's private state, keeping a reference count on each call
+ */
+bool proc_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
+
+/*
+ *  ======== proc_load ========
+ *  Purpose:
+ *      Reset a processor and load a new base program image.
+ *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
+ *      application developer's API.
+ */
+int proc_load(void *hprocessor, const s32 argc_index,
+                    const char **user_args, const char **user_envp)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct io_mgr *hio_mgr; /* IO manager handle */
+       struct msg_mgr *hmsg_mgr;
+       struct cod_manager *cod_mgr;    /* Code manager handle */
+       char *pargv0;           /* temp argv[0] ptr */
+       char **new_envp;        /* Updated envp[] array. */
+       char sz_proc_id[MAXPROCIDLEN];  /* Size of "PROC_ID=<n>" */
+       s32 envp_elems;         /* Num elements in envp[]. */
+       s32 cnew_envp;          /* "  " in new_envp[] */
+       s32 nproc_id = 0;       /* Anticipate MP version. */
+       struct dcd_manager *hdcd_handle;
+       struct dmm_object *dmm_mgr;
+       u32 dw_ext_end;
+       u32 proc_id;
+       int brd_state;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+#ifdef OPT_LOAD_TIME_INSTRUMENTATION
+       struct timeval tv1;
+       struct timeval tv2;
+#endif
+
+#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
+       struct dspbridge_platform_data *pdata =
+           omap_dspbridge_dev->dev.platform_data;
+#endif
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(argc_index > 0);
+       DBC_REQUIRE(user_args != NULL);
+
+#ifdef OPT_LOAD_TIME_INSTRUMENTATION
+       do_gettimeofday(&tv1);
+#endif
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       dev_get_cod_mgr(p_proc_object->hdev_obj, &cod_mgr);
+       if (!cod_mgr) {
+               status = -EPERM;
+               goto func_end;
+       }
+       status = proc_stop(hprocessor);
+       if (status)
+               goto func_end;
+
+       /* Place the board in the monitor state. */
+       status = proc_monitor(hprocessor);
+       if (status)
+               goto func_end;
+
+       /* Save ptr to  original argv[0]. */
+       pargv0 = (char *)user_args[0];
+       /*Prepend "PROC_ID=<nproc_id>"to envp array for target. */
+       envp_elems = get_envp_count((char **)user_envp);
+       cnew_envp = (envp_elems ? (envp_elems + 1) : (envp_elems + 2));
+       new_envp = kzalloc(cnew_envp * sizeof(char **), GFP_KERNEL);
+       if (new_envp) {
+               status = snprintf(sz_proc_id, MAXPROCIDLEN, PROC_ENVPROCID,
+                                 nproc_id);
+               if (status == -1) {
+                       dev_dbg(bridge, "%s: Proc ID string overflow\n",
+                               __func__);
+                       status = -EPERM;
+               } else {
+                       new_envp =
+                           prepend_envp(new_envp, (char **)user_envp,
+                                        envp_elems, cnew_envp, sz_proc_id);
+                       /* Get the DCD Handle */
+                       status = mgr_get_dcd_handle(p_proc_object->hmgr_obj,
+                                                   (u32 *) &hdcd_handle);
+                       if (!status) {
+                               /*  Before proceeding with new load,
+                                *  check if a previously registered COFF
+                                *  exists.
+                                *  If yes, unregister nodes in previously
+                                *  registered COFF.  If any error occurred,
+                                *  set previously registered COFF to NULL. */
+                               if (p_proc_object->psz_last_coff != NULL) {
+                                       status =
+                                           dcd_auto_unregister(hdcd_handle,
+                                                               p_proc_object->
+                                                               psz_last_coff);
+                                       /* Regardless of auto unregister status,
+                                        *  free previously allocated
+                                        *  memory. */
+                                       kfree(p_proc_object->psz_last_coff);
+                                       p_proc_object->psz_last_coff = NULL;
+                               }
+                       }
+                       /* On success, do cod_open_base() */
+                       status = cod_open_base(cod_mgr, (char *)user_args[0],
+                                              COD_SYMB);
+               }
+       } else {
+               status = -ENOMEM;
+       }
+       if (!status) {
+               /* Auto-register data base */
+               /* Get the DCD Handle */
+               status = mgr_get_dcd_handle(p_proc_object->hmgr_obj,
+                                           (u32 *) &hdcd_handle);
+               if (!status) {
+                       /*  Auto register nodes in specified COFF
+                        *  file.  If registration did not fail,
+                        *  (status = 0 or -EACCES)
+                        *  save the name of the COFF file for
+                        *  de-registration in the future. */
+                       status =
+                           dcd_auto_register(hdcd_handle,
+                                             (char *)user_args[0]);
+                       if (status == -EACCES)
+                               status = 0;
+
+                       if (status) {
+                               status = -EPERM;
+                       } else {
+                               DBC_ASSERT(p_proc_object->psz_last_coff ==
+                                          NULL);
+                               /* Allocate memory for pszLastCoff */
+                               p_proc_object->psz_last_coff =
+                                               kzalloc((strlen(user_args[0]) +
+                                               1), GFP_KERNEL);
+                               /* If memory allocated, save COFF file name */
+                               if (p_proc_object->psz_last_coff) {
+                                       strncpy(p_proc_object->psz_last_coff,
+                                               (char *)user_args[0],
+                                               (strlen((char *)user_args[0]) +
+                                                1));
+                               }
+                       }
+               }
+       }
+       /* Update shared memory address and size */
+       if (!status) {
+               /*  Create the message manager. This must be done
+                *  before calling the IOOnLoaded function. */
+               dev_get_msg_mgr(p_proc_object->hdev_obj, &hmsg_mgr);
+               if (!hmsg_mgr) {
+                       status = msg_create(&hmsg_mgr, p_proc_object->hdev_obj,
+                                           (msg_onexit) node_on_exit);
+                       DBC_ASSERT(!status);
+                       dev_set_msg_mgr(p_proc_object->hdev_obj, hmsg_mgr);
+               }
+       }
+       if (!status) {
+               /* Set the Device object's message manager */
+               status = dev_get_io_mgr(p_proc_object->hdev_obj, &hio_mgr);
+               if (hio_mgr)
+                       status = (*p_proc_object->intf_fxns->pfn_io_on_loaded)
+                                                               (hio_mgr);
+               else
+                       status = -EFAULT;
+       }
+       if (!status) {
+               /* Now, attempt to load an exec: */
+
+               /* Boost the OPP level to Maximum level supported by baseport */
+#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
+               if (pdata->cpu_set_freq)
+                       (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP5]);
+#endif
+               status = cod_load_base(cod_mgr, argc_index, (char **)user_args,
+                                      dev_brd_write_fxn,
+                                      p_proc_object->hdev_obj, NULL);
+               if (status) {
+                       if (status == -EBADF) {
+                               dev_dbg(bridge, "%s: Failure to Load the EXE\n",
+                                       __func__);
+                       }
+                       if (status == -ESPIPE) {
+                               pr_err("%s: Couldn't parse the file\n",
+                                      __func__);
+                       }
+               }
+               /* Requesting the lowest opp supported */
+#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
+               if (pdata->cpu_set_freq)
+                       (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
+#endif
+
+       }
+       if (!status) {
+               /* Update the Processor status to loaded */
+               status = (*p_proc_object->intf_fxns->pfn_brd_set_state)
+                   (p_proc_object->hbridge_context, BRD_LOADED);
+               if (!status) {
+                       p_proc_object->proc_state = PROC_LOADED;
+                       if (p_proc_object->ntfy_obj)
+                               proc_notify_clients(p_proc_object,
+                                                   DSP_PROCESSORSTATECHANGE);
+               }
+       }
+       if (!status) {
+               status = proc_get_processor_id(hprocessor, &proc_id);
+               if (proc_id == DSP_UNIT) {
+                       /* Use all available DSP address space after EXTMEM
+                        * for DMM */
+                       if (!status)
+                               status = cod_get_sym_value(cod_mgr, EXTEND,
+                                                          &dw_ext_end);
+
+                       /* Reset DMM structs and add an initial free chunk */
+                       if (!status) {
+                               status =
+                                   dev_get_dmm_mgr(p_proc_object->hdev_obj,
+                                                   &dmm_mgr);
+                               if (dmm_mgr) {
+                                       /* Set dw_ext_end to DMM START u8
+                                        * address */
+                                       dw_ext_end =
+                                           (dw_ext_end + 1) * DSPWORDSIZE;
+                                       /* DMM memory is from EXT_END */
+                                       status = dmm_create_tables(dmm_mgr,
+                                                                  dw_ext_end,
+                                                                  DMMPOOLSIZE);
+                               } else {
+                                       status = -EFAULT;
+                               }
+                       }
+               }
+       }
+       /* Restore the original argv[0] */
+       kfree(new_envp);
+       user_args[0] = pargv0;
+       if (!status) {
+               if (!((*p_proc_object->intf_fxns->pfn_brd_status)
+                               (p_proc_object->hbridge_context, &brd_state))) {
+                       pr_info("%s: Processor Loaded %s\n", __func__, pargv0);
+                       kfree(drv_datap->base_img);
+                       drv_datap->base_img = kmalloc(strlen(pargv0) + 1,
+                                                               GFP_KERNEL);
+                       if (drv_datap->base_img)
+                               strncpy(drv_datap->base_img, pargv0,
+                                                       strlen(pargv0) + 1);
+                       else
+                               status = -ENOMEM;
+                       DBC_ASSERT(brd_state == BRD_LOADED);
+               }
+       }
+
+func_end:
+       if (status) {
+               pr_err("%s: Processor failed to load\n", __func__);
+               proc_stop(p_proc_object);
+       }
+       DBC_ENSURE((!status
+                   && p_proc_object->proc_state == PROC_LOADED)
+                  || status);
+#ifdef OPT_LOAD_TIME_INSTRUMENTATION
+       do_gettimeofday(&tv2);
+       if (tv2.tv_usec < tv1.tv_usec) {
+               tv2.tv_usec += 1000000;
+               tv2.tv_sec--;
+       }
+       dev_dbg(bridge, "%s: time to load %d sec and %d usec\n", __func__,
+               tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec);
+#endif
+       return status;
+}
+
+/*
+ *  ======== proc_map ========
+ *  Purpose:
+ *      Maps a MPU buffer to DSP address space.
+ */
+int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
+                   void *req_addr, void **pp_map_addr, u32 ul_map_attr,
+                   struct process_context *pr_ctxt)
+{
+       u32 va_align;
+       u32 pa_align;
+       struct dmm_object *dmm_mgr;
+       u32 size_align;
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct dmm_map_object *map_obj;
+       u32 tmp_addr = 0;
+
+#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
+       if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
+               if (!IS_ALIGNED((u32)pmpu_addr, DSP_CACHE_LINE) ||
+                   !IS_ALIGNED(ul_size, DSP_CACHE_LINE)) {
+                       pr_err("%s: not aligned: 0x%x (%d)\n", __func__,
+                                               (u32)pmpu_addr, ul_size);
+                       return -EFAULT;
+               }
+       }
+#endif
+
+       /* Calculate the page-aligned PA, VA and size */
+       va_align = PG_ALIGN_LOW((u32) req_addr, PG_SIZE4K);
+       pa_align = PG_ALIGN_LOW((u32) pmpu_addr, PG_SIZE4K);
+       size_align = PG_ALIGN_HIGH(ul_size + (u32) pmpu_addr - pa_align,
+                                  PG_SIZE4K);
+
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       /* Critical section */
+       mutex_lock(&proc_lock);
+       dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (dmm_mgr)
+               status = dmm_map_memory(dmm_mgr, va_align, size_align);
+       else
+               status = -EFAULT;
+
+       /* Add mapping to the page tables. */
+       if (!status) {
+
+               /* Mapped address = MSB of VA | LSB of PA */
+               tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
+               /* mapped memory resource tracking */
+               map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
+                                               size_align);
+               if (!map_obj)
+                       status = -ENOMEM;
+               else
+                       status = (*p_proc_object->intf_fxns->pfn_brd_mem_map)
+                           (p_proc_object->hbridge_context, pa_align, va_align,
+                            size_align, ul_map_attr, map_obj->pages);
+       }
+       if (!status) {
+               /* Mapped address = MSB of VA | LSB of PA */
+               *pp_map_addr = (void *) tmp_addr;
+       } else {
+               remove_mapping_information(pr_ctxt, tmp_addr, size_align);
+               dmm_un_map_memory(dmm_mgr, va_align, &size_align);
+       }
+       mutex_unlock(&proc_lock);
+
+       if (status)
+               goto func_end;
+
+func_end:
+       dev_dbg(bridge, "%s: hprocessor %p, pmpu_addr %p, ul_size %x, "
+               "req_addr %p, ul_map_attr %x, pp_map_addr %p, va_align %x, "
+               "pa_align %x, size_align %x status 0x%x\n", __func__,
+               hprocessor, pmpu_addr, ul_size, req_addr, ul_map_attr,
+               pp_map_addr, va_align, pa_align, size_align, status);
+
+       return status;
+}
+
+/*
+ *  ======== proc_register_notify ========
+ *  Purpose:
+ *      Register to be notified of specific processor events.
+ */
+int proc_register_notify(void *hprocessor, u32 event_mask,
+                               u32 notify_type, struct dsp_notification
+                               * hnotification)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct deh_mgr *hdeh_mgr;
+
+       DBC_REQUIRE(hnotification != NULL);
+       DBC_REQUIRE(refs > 0);
+
+       /* Check processor handle */
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       /* Check if event mask is a valid processor related event */
+       if (event_mask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH |
+                       DSP_PROCESSORDETACH | DSP_PROCESSORRESTART |
+                       DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR |
+                       DSP_WDTOVERFLOW))
+               status = -EINVAL;
+
+       /* Check if notify type is valid */
+       if (notify_type != DSP_SIGNALEVENT)
+               status = -EINVAL;
+
+       if (!status) {
+               /* If event mask is not DSP_SYSERROR, DSP_MMUFAULT,
+                * or DSP_PWRERROR then register event immediately. */
+               if (event_mask &
+                   ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR |
+                               DSP_WDTOVERFLOW)) {
+                       status = ntfy_register(p_proc_object->ntfy_obj,
+                                              hnotification, event_mask,
+                                              notify_type);
+                       /* Special case alert, special case alert!
+                        * If we're trying to *deregister* (i.e. event_mask
+                        * is 0), a DSP_SYSERROR or DSP_MMUFAULT notification,
+                        * we have to deregister with the DEH manager.
+                        * There's no way to know, based on event_mask which
+                        * manager the notification event was registered with,
+                        * so if we're trying to deregister and ntfy_register
+                        * failed, we'll give the deh manager a shot.
+                        */
+                       if ((event_mask == 0) && status) {
+                               status =
+                                   dev_get_deh_mgr(p_proc_object->hdev_obj,
+                                                   &hdeh_mgr);
+                               status =
+                                       bridge_deh_register_notify(hdeh_mgr,
+                                                       event_mask,
+                                                       notify_type,
+                                                       hnotification);
+                       }
+               } else {
+                       status = dev_get_deh_mgr(p_proc_object->hdev_obj,
+                                                &hdeh_mgr);
+                       status =
+                           bridge_deh_register_notify(hdeh_mgr,
+                                           event_mask,
+                                           notify_type,
+                                           hnotification);
+
+               }
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== proc_reserve_memory ========
+ *  Purpose:
+ *      Reserve a virtually contiguous region of DSP address space.
+ */
+int proc_reserve_memory(void *hprocessor, u32 ul_size,
+                              void **pp_rsv_addr,
+                              struct process_context *pr_ctxt)
+{
+       struct dmm_object *dmm_mgr;
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct dmm_rsv_object *rsv_obj;
+
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr);
+       if (status != 0)
+               goto func_end;
+
+       /*
+        * A successful reserve should be followed by insertion of rsv_obj
+        * into dmm_rsv_list, so that reserved memory resource tracking
+        * remains uptodate
+        */
+       rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL);
+       if (rsv_obj) {
+               rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr;
+               spin_lock(&pr_ctxt->dmm_rsv_lock);
+               list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
+               spin_unlock(&pr_ctxt->dmm_rsv_lock);
+       }
+
+func_end:
+       dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
+               "status 0x%x\n", __func__, hprocessor,
+               ul_size, pp_rsv_addr, status);
+       return status;
+}
+
+/*
+ *  ======== proc_start ========
+ *  Purpose:
+ *      Start a processor running.
+ */
+int proc_start(void *hprocessor)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct cod_manager *cod_mgr;    /* Code manager handle */
+       u32 dw_dsp_addr;        /* Loaded code's entry point. */
+       int brd_state;
+
+       DBC_REQUIRE(refs > 0);
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       /* Call the bridge_brd_start */
+       if (p_proc_object->proc_state != PROC_LOADED) {
+               status = -EBADR;
+               goto func_end;
+       }
+       status = dev_get_cod_mgr(p_proc_object->hdev_obj, &cod_mgr);
+       if (!cod_mgr) {
+               status = -EFAULT;
+               goto func_cont;
+       }
+
+       status = cod_get_entry(cod_mgr, &dw_dsp_addr);
+       if (status)
+               goto func_cont;
+
+       status = (*p_proc_object->intf_fxns->pfn_brd_start)
+           (p_proc_object->hbridge_context, dw_dsp_addr);
+       if (status)
+               goto func_cont;
+
+       /* Call dev_create2 */
+       status = dev_create2(p_proc_object->hdev_obj);
+       if (!status) {
+               p_proc_object->proc_state = PROC_RUNNING;
+               /* Deep sleep switces off the peripheral clocks.
+                * we just put the DSP CPU in idle in the idle loop.
+                * so there is no need to send a command to DSP */
+
+               if (p_proc_object->ntfy_obj) {
+                       proc_notify_clients(p_proc_object,
+                                           DSP_PROCESSORSTATECHANGE);
+               }
+       } else {
+               /* Failed to Create Node Manager and DISP Object
+                * Stop the Processor from running. Put it in STOPPED State */
+               (void)(*p_proc_object->intf_fxns->
+                      pfn_brd_stop) (p_proc_object->hbridge_context);
+               p_proc_object->proc_state = PROC_STOPPED;
+       }
+func_cont:
+       if (!status) {
+               if (!((*p_proc_object->intf_fxns->pfn_brd_status)
+                               (p_proc_object->hbridge_context, &brd_state))) {
+                       pr_info("%s: dsp in running state\n", __func__);
+                       DBC_ASSERT(brd_state != BRD_HIBERNATION);
+               }
+       } else {
+               pr_err("%s: Failed to start the dsp\n", __func__);
+               proc_stop(p_proc_object);
+       }
+
+func_end:
+       DBC_ENSURE((!status && p_proc_object->proc_state ==
+                   PROC_RUNNING) || status);
+       return status;
+}
+
+/*
+ *  ======== proc_stop ========
+ *  Purpose:
+ *      Stop a processor running.
+ */
+int proc_stop(void *hprocessor)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct msg_mgr *hmsg_mgr;
+       struct node_mgr *hnode_mgr;
+       void *hnode;
+       u32 node_tab_size = 1;
+       u32 num_nodes = 0;
+       u32 nodes_allocated = 0;
+       int brd_state;
+
+       DBC_REQUIRE(refs > 0);
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       /* check if there are any running nodes */
+       status = dev_get_node_manager(p_proc_object->hdev_obj, &hnode_mgr);
+       if (!status && hnode_mgr) {
+               status = node_enum_nodes(hnode_mgr, &hnode, node_tab_size,
+                                        &num_nodes, &nodes_allocated);
+               if ((status == -EINVAL) || (nodes_allocated > 0)) {
+                       pr_err("%s: Can't stop device, active nodes = %d \n",
+                              __func__, nodes_allocated);
+                       return -EBADR;
+               }
+       }
+       /* Call the bridge_brd_stop */
+       /* It is OK to stop a device that does n't have nodes OR not started */
+       status =
+           (*p_proc_object->intf_fxns->
+            pfn_brd_stop) (p_proc_object->hbridge_context);
+       if (!status) {
+               dev_dbg(bridge, "%s: processor in standby mode\n", __func__);
+               p_proc_object->proc_state = PROC_STOPPED;
+               /* Destory the Node Manager, msg_ctrl Manager */
+               if (!(dev_destroy2(p_proc_object->hdev_obj))) {
+                       /* Destroy the msg_ctrl by calling msg_delete */
+                       dev_get_msg_mgr(p_proc_object->hdev_obj, &hmsg_mgr);
+                       if (hmsg_mgr) {
+                               msg_delete(hmsg_mgr);
+                               dev_set_msg_mgr(p_proc_object->hdev_obj, NULL);
+                       }
+                       if (!((*p_proc_object->
+                             intf_fxns->pfn_brd_status) (p_proc_object->
+                                                         hbridge_context,
+                                                         &brd_state)))
+                               DBC_ASSERT(brd_state == BRD_STOPPED);
+               }
+       } else {
+               pr_err("%s: Failed to stop the processor\n", __func__);
+       }
+func_end:
+
+       return status;
+}
+
+/*
+ *  ======== proc_un_map ========
+ *  Purpose:
+ *      Removes a MPU buffer mapping from the DSP address space.
+ */
+int proc_un_map(void *hprocessor, void *map_addr,
+                      struct process_context *pr_ctxt)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct dmm_object *dmm_mgr;
+       u32 va_align;
+       u32 size_align;
+
+       va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K);
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_get_handle(hprocessor, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       /* Critical section */
+       mutex_lock(&proc_lock);
+       /*
+        * Update DMM structures. Get the size to unmap.
+        * This function returns error if the VA is not mapped
+        */
+       status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
+       /* Remove mapping from the page tables. */
+       if (!status) {
+               status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map)
+                   (p_proc_object->hbridge_context, va_align, size_align);
+       }
+
+       mutex_unlock(&proc_lock);
+       if (status)
+               goto func_end;
+
+       /*
+        * A successful unmap should be followed by removal of map_obj
+        * from dmm_map_list, so that mapped memory resource tracking
+        * remains uptodate
+        */
+       remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);
+
+func_end:
+       dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n",
+               __func__, hprocessor, map_addr, status);
+       return status;
+}
+
+/*
+ *  ======== proc_un_reserve_memory ========
+ *  Purpose:
+ *      Frees a previously reserved region of DSP address space.
+ */
+int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
+                                 struct process_context *pr_ctxt)
+{
+       struct dmm_object *dmm_mgr;
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct dmm_rsv_object *rsv_obj;
+
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr);
+       if (status != 0)
+               goto func_end;
+
+       /*
+        * A successful unreserve should be followed by removal of rsv_obj
+        * from dmm_rsv_list, so that reserved memory resource tracking
+        * remains uptodate
+        */
+       spin_lock(&pr_ctxt->dmm_rsv_lock);
+       list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) {
+               if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) {
+                       list_del(&rsv_obj->link);
+                       kfree(rsv_obj);
+                       break;
+               }
+       }
+       spin_unlock(&pr_ctxt->dmm_rsv_lock);
+
+func_end:
+       dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
+               __func__, hprocessor, prsv_addr, status);
+       return status;
+}
+
+/*
+ *  ======== = proc_monitor ======== ==
+ *  Purpose:
+ *      Place the Processor in Monitor State. This is an internal
+ *      function and a requirement before Processor is loaded.
+ *      This does a bridge_brd_stop, dev_destroy2 and bridge_brd_monitor.
+ *      In dev_destroy2 we delete the node manager.
+ *  Parameters:
+ *      p_proc_object:    Pointer to Processor Object
+ *  Returns:
+ *      0:     Processor placed in monitor mode.
+ *      !0:       Failed to place processor in monitor mode.
+ *  Requires:
+ *      Valid Processor Handle
+ *  Ensures:
+ *      Success:       ProcObject state is PROC_IDLE
+ */
+static int proc_monitor(struct proc_object *proc_obj)
+{
+       int status = -EPERM;
+       struct msg_mgr *hmsg_mgr;
+       int brd_state;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(proc_obj);
+
+       /* This is needed only when Device is loaded when it is
+        * already 'ACTIVE' */
+       /* Destory the Node Manager, msg_ctrl Manager */
+       if (!dev_destroy2(proc_obj->hdev_obj)) {
+               /* Destroy the msg_ctrl by calling msg_delete */
+               dev_get_msg_mgr(proc_obj->hdev_obj, &hmsg_mgr);
+               if (hmsg_mgr) {
+                       msg_delete(hmsg_mgr);
+                       dev_set_msg_mgr(proc_obj->hdev_obj, NULL);
+               }
+       }
+       /* Place the Board in the Monitor State */
+       if (!((*proc_obj->intf_fxns->pfn_brd_monitor)
+                         (proc_obj->hbridge_context))) {
+               status = 0;
+               if (!((*proc_obj->intf_fxns->pfn_brd_status)
+                                 (proc_obj->hbridge_context, &brd_state)))
+                       DBC_ASSERT(brd_state == BRD_IDLE);
+       }
+
+       DBC_ENSURE((!status && brd_state == BRD_IDLE) ||
+                  status);
+       return status;
+}
+
+/*
+ *  ======== get_envp_count ========
+ *  Purpose:
+ *      Return the number of elements in the envp array, including the
+ *      terminating NULL element.
+ */
+static s32 get_envp_count(char **envp)
+{
+       s32 ret = 0;
+       if (envp) {
+               while (*envp++)
+                       ret++;
+
+               ret += 1;       /* Include the terminating NULL in the count. */
+       }
+
+       return ret;
+}
+
+/*
+ *  ======== prepend_envp ========
+ *  Purpose:
+ *      Prepend an environment variable=value pair to the new envp array, and
+ *      copy in the existing var=value pairs in the old envp array.
+ */
+static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
+                          s32 cnew_envp, char *sz_var)
+{
+       char **pp_envp = new_envp;
+
+       DBC_REQUIRE(new_envp);
+
+       /* Prepend new environ var=value string */
+       *new_envp++ = sz_var;
+
+       /* Copy user's environment into our own. */
+       while (envp_elems--)
+               *new_envp++ = *envp++;
+
+       /* Ensure NULL terminates the new environment strings array. */
+       if (envp_elems == 0)
+               *new_envp = NULL;
+
+       return pp_envp;
+}
+
+/*
+ *  ======== proc_notify_clients ========
+ *  Purpose:
+ *      Notify the processor the events.
+ */
+int proc_notify_clients(void *proc, u32 events)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)proc;
+
+       DBC_REQUIRE(p_proc_object);
+       DBC_REQUIRE(is_valid_proc_event(events));
+       DBC_REQUIRE(refs > 0);
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       ntfy_notify(p_proc_object->ntfy_obj, events);
+func_end:
+       return status;
+}
+
+/*
+ *  ======== proc_notify_all_clients ========
+ *  Purpose:
+ *      Notify the processor the events. This includes notifying all clients
+ *      attached to a particulat DSP.
+ */
+int proc_notify_all_clients(void *proc, u32 events)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)proc;
+
+       DBC_REQUIRE(is_valid_proc_event(events));
+       DBC_REQUIRE(refs > 0);
+
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       dev_notify_clients(p_proc_object->hdev_obj, events);
+
+func_end:
+       return status;
+}
+
+/*
+ *  ======== proc_get_processor_id ========
+ *  Purpose:
+ *      Retrieves the processor ID.
+ */
+int proc_get_processor_id(void *proc, u32 * proc_id)
+{
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)proc;
+
+       if (p_proc_object)
+               *proc_id = p_proc_object->processor_id;
+       else
+               status = -EFAULT;
+
+       return status;
+}
diff --git a/drivers/staging/tidspbridge/rmgr/pwr.c b/drivers/staging/tidspbridge/rmgr/pwr.c
new file mode 100644 (file)
index 0000000..85cb1a2
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * pwr.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * PWR API for controlling DSP power states.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/pwr.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/devdefs.h>
+#include <dspbridge/drv.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+
+/*  ----------------------------------- Link Driver */
+#include <dspbridge/dspioctl.h>
+
+/*
+ *  ======== pwr_sleep_dsp ========
+ *    Send command to DSP to enter sleep state.
+ */
+int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct bridge_dev_context *dw_context;
+       int status = -EPERM;
+       struct dev_object *hdev_obj = NULL;
+       u32 ioctlcode = 0;
+       u32 arg = timeout;
+
+       for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
+            hdev_obj != NULL;
+            hdev_obj =
+            (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) {
+               if (dev_get_bridge_context(hdev_obj,
+                                               (struct bridge_dev_context **)
+                                                  &dw_context)) {
+                       continue;
+               }
+               if (dev_get_intf_fxns(hdev_obj,
+                                               (struct bridge_drv_interface **)
+                                               &intf_fxns)) {
+                       continue;
+               }
+               if (sleep_code == PWR_DEEPSLEEP)
+                       ioctlcode = BRDIOCTL_DEEPSLEEP;
+               else if (sleep_code == PWR_EMERGENCYDEEPSLEEP)
+                       ioctlcode = BRDIOCTL_EMERGENCYSLEEP;
+               else
+                       status = -EINVAL;
+
+               if (status != -EINVAL) {
+                       status = (*intf_fxns->pfn_dev_cntrl) (dw_context,
+                                                             ioctlcode,
+                                                             (void *)&arg);
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== pwr_wake_dsp ========
+ *    Send command to DSP to wake it from sleep.
+ */
+int pwr_wake_dsp(const u32 timeout)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct bridge_dev_context *dw_context;
+       int status = -EPERM;
+       struct dev_object *hdev_obj = NULL;
+       u32 arg = timeout;
+
+       for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
+            hdev_obj != NULL;
+            hdev_obj = (struct dev_object *)drv_get_next_dev_object
+            ((u32) hdev_obj)) {
+               if (!(dev_get_bridge_context(hdev_obj,
+                                                     (struct bridge_dev_context
+                                                      **)&dw_context))) {
+                       if (!(dev_get_intf_fxns(hdev_obj,
+                             (struct bridge_drv_interface **)&intf_fxns))) {
+                               status =
+                                   (*intf_fxns->pfn_dev_cntrl) (dw_context,
+                                                       BRDIOCTL_WAKEUP,
+                                                       (void *)&arg);
+                       }
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== pwr_pm_pre_scale========
+ *    Sends pre-notification message to DSP.
+ */
+int pwr_pm_pre_scale(u16 voltage_domain, u32 level)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct bridge_dev_context *dw_context;
+       int status = -EPERM;
+       struct dev_object *hdev_obj = NULL;
+       u32 arg[2];
+
+       arg[0] = voltage_domain;
+       arg[1] = level;
+
+       for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
+            hdev_obj != NULL;
+            hdev_obj = (struct dev_object *)drv_get_next_dev_object
+            ((u32) hdev_obj)) {
+               if (!(dev_get_bridge_context(hdev_obj,
+                                                     (struct bridge_dev_context
+                                                      **)&dw_context))) {
+                       if (!(dev_get_intf_fxns(hdev_obj,
+                             (struct bridge_drv_interface **)&intf_fxns))) {
+                               status =
+                                   (*intf_fxns->pfn_dev_cntrl) (dw_context,
+                                               BRDIOCTL_PRESCALE_NOTIFY,
+                                               (void *)&arg);
+                       }
+               }
+       }
+       return status;
+}
+
+/*
+ *  ======== pwr_pm_post_scale========
+ *    Sends post-notification message to DSP.
+ */
+int pwr_pm_post_scale(u16 voltage_domain, u32 level)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct bridge_dev_context *dw_context;
+       int status = -EPERM;
+       struct dev_object *hdev_obj = NULL;
+       u32 arg[2];
+
+       arg[0] = voltage_domain;
+       arg[1] = level;
+
+       for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
+            hdev_obj != NULL;
+            hdev_obj = (struct dev_object *)drv_get_next_dev_object
+            ((u32) hdev_obj)) {
+               if (!(dev_get_bridge_context(hdev_obj,
+                                                     (struct bridge_dev_context
+                                                      **)&dw_context))) {
+                       if (!(dev_get_intf_fxns(hdev_obj,
+                             (struct bridge_drv_interface **)&intf_fxns))) {
+                               status =
+                                   (*intf_fxns->pfn_dev_cntrl) (dw_context,
+                                               BRDIOCTL_POSTSCALE_NOTIFY,
+                                               (void *)&arg);
+                       }
+               }
+       }
+       return status;
+
+}
diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c
new file mode 100644 (file)
index 0000000..761e8f4
--- /dev/null
@@ -0,0 +1,537 @@
+/*
+ * rmm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *  This memory manager provides general heap management and arbitrary
+ *  alignment for any number of memory segments.
+ *
+ *  Notes:
+ *
+ *  Memory blocks are allocated from the end of the first free memory
+ *  block large enough to satisfy the request.  Alignment requirements
+ *  are satisfied by "sliding" the block forward until its base satisfies
+ *  the alignment specification; if this is not possible then the next
+ *  free block large enough to hold the request is tried.
+ *
+ *  Since alignment can cause the creation of a new free block - the
+ *  unused memory formed between the start of the original free block
+ *  and the start of the allocated block - the memory manager must free
+ *  this memory to prevent a memory leak.
+ *
+ *  Overlay memory is managed by reserving through rmm_alloc, and freeing
+ *  it through rmm_free. The memory manager prevents DSP code/data that is
+ *  overlayed from being overwritten as long as the memory it runs at has
+ *  been allocated, and not yet freed.
+ */
+
+#include <linux/types.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/list.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/rmm.h>
+
+/*
+ *  ======== rmm_header ========
+ *  This header is used to maintain a list of free memory blocks.
+ */
+struct rmm_header {
+       struct rmm_header *next;        /* form a free memory link list */
+       u32 size;               /* size of the free memory */
+       u32 addr;               /* DSP address of memory block */
+};
+
+/*
+ *  ======== rmm_ovly_sect ========
+ *  Keeps track of memory occupied by overlay section.
+ */
+struct rmm_ovly_sect {
+       struct list_head list_elem;
+       u32 addr;               /* Start of memory section */
+       u32 size;               /* Length (target MAUs) of section */
+       s32 page;               /* Memory page */
+};
+
+/*
+ *  ======== rmm_target_obj ========
+ */
+struct rmm_target_obj {
+       struct rmm_segment *seg_tab;
+       struct rmm_header **free_list;
+       u32 num_segs;
+       struct lst_list *ovly_list;     /* List of overlay memory in use */
+};
+
+static u32 refs;               /* module reference count */
+
+static bool alloc_block(struct rmm_target_obj *target, u32 segid, u32 size,
+                       u32 align, u32 *dsp_address);
+static bool free_block(struct rmm_target_obj *target, u32 segid, u32 addr,
+                      u32 size);
+
+/*
+ *  ======== rmm_alloc ========
+ */
+int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size,
+                    u32 align, u32 *dsp_address, bool reserve)
+{
+       struct rmm_ovly_sect *sect;
+       struct rmm_ovly_sect *prev_sect = NULL;
+       struct rmm_ovly_sect *new_sect;
+       u32 addr;
+       int status = 0;
+
+       DBC_REQUIRE(target);
+       DBC_REQUIRE(dsp_address != NULL);
+       DBC_REQUIRE(size > 0);
+       DBC_REQUIRE(reserve || (target->num_segs > 0));
+       DBC_REQUIRE(refs > 0);
+
+       if (!reserve) {
+               if (!alloc_block(target, segid, size, align, dsp_address)) {
+                       status = -ENOMEM;
+               } else {
+                       /* Increment the number of allocated blocks in this
+                        * segment */
+                       target->seg_tab[segid].number++;
+               }
+               goto func_end;
+       }
+       /* An overlay section - See if block is already in use. If not,
+        * insert into the list in ascending address size. */
+       addr = *dsp_address;
+       sect = (struct rmm_ovly_sect *)lst_first(target->ovly_list);
+       /*  Find place to insert new list element. List is sorted from
+        *  smallest to largest address. */
+       while (sect != NULL) {
+               if (addr <= sect->addr) {
+                       /* Check for overlap with sect */
+                       if ((addr + size > sect->addr) || (prev_sect &&
+                                                          (prev_sect->addr +
+                                                           prev_sect->size >
+                                                           addr))) {
+                               status = -ENXIO;
+                       }
+                       break;
+               }
+               prev_sect = sect;
+               sect = (struct rmm_ovly_sect *)lst_next(target->ovly_list,
+                                                       (struct list_head *)
+                                                       sect);
+       }
+       if (!status) {
+               /* No overlap - allocate list element for new section. */
+               new_sect = kzalloc(sizeof(struct rmm_ovly_sect), GFP_KERNEL);
+               if (new_sect == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       lst_init_elem((struct list_head *)new_sect);
+                       new_sect->addr = addr;
+                       new_sect->size = size;
+                       new_sect->page = segid;
+                       if (sect == NULL) {
+                               /* Put new section at the end of the list */
+                               lst_put_tail(target->ovly_list,
+                                            (struct list_head *)new_sect);
+                       } else {
+                               /* Put new section just before sect */
+                               lst_insert_before(target->ovly_list,
+                                                 (struct list_head *)new_sect,
+                                                 (struct list_head *)sect);
+                       }
+               }
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== rmm_create ========
+ */
+int rmm_create(struct rmm_target_obj **target_obj,
+                     struct rmm_segment seg_tab[], u32 num_segs)
+{
+       struct rmm_header *hptr;
+       struct rmm_segment *sptr, *tmp;
+       struct rmm_target_obj *target;
+       s32 i;
+       int status = 0;
+
+       DBC_REQUIRE(target_obj != NULL);
+       DBC_REQUIRE(num_segs == 0 || seg_tab != NULL);
+
+       /* Allocate DBL target object */
+       target = kzalloc(sizeof(struct rmm_target_obj), GFP_KERNEL);
+
+       if (target == NULL)
+               status = -ENOMEM;
+
+       if (status)
+               goto func_cont;
+
+       target->num_segs = num_segs;
+       if (!(num_segs > 0))
+               goto func_cont;
+
+       /* Allocate the memory for freelist from host's memory */
+       target->free_list = kzalloc(num_segs * sizeof(struct rmm_header *),
+                                                       GFP_KERNEL);
+       if (target->free_list == NULL) {
+               status = -ENOMEM;
+       } else {
+               /* Allocate headers for each element on the free list */
+               for (i = 0; i < (s32) num_segs; i++) {
+                       target->free_list[i] =
+                               kzalloc(sizeof(struct rmm_header), GFP_KERNEL);
+                       if (target->free_list[i] == NULL) {
+                               status = -ENOMEM;
+                               break;
+                       }
+               }
+               /* Allocate memory for initial segment table */
+               target->seg_tab = kzalloc(num_segs * sizeof(struct rmm_segment),
+                                                               GFP_KERNEL);
+               if (target->seg_tab == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       /* Initialize segment table and free list */
+                       sptr = target->seg_tab;
+                       for (i = 0, tmp = seg_tab; num_segs > 0;
+                            num_segs--, i++) {
+                               *sptr = *tmp;
+                               hptr = target->free_list[i];
+                               hptr->addr = tmp->base;
+                               hptr->size = tmp->length;
+                               hptr->next = NULL;
+                               tmp++;
+                               sptr++;
+                       }
+               }
+       }
+func_cont:
+       /* Initialize overlay memory list */
+       if (!status) {
+               target->ovly_list = kzalloc(sizeof(struct lst_list),
+                                                       GFP_KERNEL);
+               if (target->ovly_list == NULL)
+                       status = -ENOMEM;
+               else
+                       INIT_LIST_HEAD(&target->ovly_list->head);
+       }
+
+       if (!status) {
+               *target_obj = target;
+       } else {
+               *target_obj = NULL;
+               if (target)
+                       rmm_delete(target);
+
+       }
+
+       DBC_ENSURE((!status && *target_obj)
+                  || (status && *target_obj == NULL));
+
+       return status;
+}
+
+/*
+ *  ======== rmm_delete ========
+ */
+void rmm_delete(struct rmm_target_obj *target)
+{
+       struct rmm_ovly_sect *ovly_section;
+       struct rmm_header *hptr;
+       struct rmm_header *next;
+       u32 i;
+
+       DBC_REQUIRE(target);
+
+       kfree(target->seg_tab);
+
+       if (target->ovly_list) {
+               while ((ovly_section = (struct rmm_ovly_sect *)lst_get_head
+                       (target->ovly_list))) {
+                       kfree(ovly_section);
+               }
+               DBC_ASSERT(LST_IS_EMPTY(target->ovly_list));
+               kfree(target->ovly_list);
+       }
+
+       if (target->free_list != NULL) {
+               /* Free elements on freelist */
+               for (i = 0; i < target->num_segs; i++) {
+                       hptr = next = target->free_list[i];
+                       while (next) {
+                               hptr = next;
+                               next = hptr->next;
+                               kfree(hptr);
+                       }
+               }
+               kfree(target->free_list);
+       }
+
+       kfree(target);
+}
+
+/*
+ *  ======== rmm_exit ========
+ */
+void rmm_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== rmm_free ========
+ */
+bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size,
+             bool reserved)
+{
+       struct rmm_ovly_sect *sect;
+       bool ret = true;
+
+       DBC_REQUIRE(target);
+
+       DBC_REQUIRE(reserved || segid < target->num_segs);
+       DBC_REQUIRE(reserved || (dsp_addr >= target->seg_tab[segid].base &&
+                                (dsp_addr + size) <= (target->seg_tab[segid].
+                                                  base +
+                                                  target->seg_tab[segid].
+                                                  length)));
+
+       /*
+        *  Free or unreserve memory.
+        */
+       if (!reserved) {
+               ret = free_block(target, segid, dsp_addr, size);
+               if (ret)
+                       target->seg_tab[segid].number--;
+
+       } else {
+               /* Unreserve memory */
+               sect = (struct rmm_ovly_sect *)lst_first(target->ovly_list);
+               while (sect != NULL) {
+                       if (dsp_addr == sect->addr) {
+                               DBC_ASSERT(size == sect->size);
+                               /* Remove from list */
+                               lst_remove_elem(target->ovly_list,
+                                               (struct list_head *)sect);
+                               kfree(sect);
+                               break;
+                       }
+                       sect =
+                           (struct rmm_ovly_sect *)lst_next(target->ovly_list,
+                                                            (struct list_head
+                                                             *)sect);
+               }
+               if (sect == NULL)
+                       ret = false;
+
+       }
+       return ret;
+}
+
+/*
+ *  ======== rmm_init ========
+ */
+bool rmm_init(void)
+{
+       DBC_REQUIRE(refs >= 0);
+
+       refs++;
+
+       return true;
+}
+
+/*
+ *  ======== rmm_stat ========
+ */
+bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid,
+             struct dsp_memstat *mem_stat_buf)
+{
+       struct rmm_header *head;
+       bool ret = false;
+       u32 max_free_size = 0;
+       u32 total_free_size = 0;
+       u32 free_blocks = 0;
+
+       DBC_REQUIRE(mem_stat_buf != NULL);
+       DBC_ASSERT(target != NULL);
+
+       if ((u32) segid < target->num_segs) {
+               head = target->free_list[segid];
+
+               /* Collect data from free_list */
+               while (head != NULL) {
+                       max_free_size = max(max_free_size, head->size);
+                       total_free_size += head->size;
+                       free_blocks++;
+                       head = head->next;
+               }
+
+               /* ul_size */
+               mem_stat_buf->ul_size = target->seg_tab[segid].length;
+
+               /* ul_num_free_blocks */
+               mem_stat_buf->ul_num_free_blocks = free_blocks;
+
+               /* ul_total_free_size */
+               mem_stat_buf->ul_total_free_size = total_free_size;
+
+               /* ul_len_max_free_block */
+               mem_stat_buf->ul_len_max_free_block = max_free_size;
+
+               /* ul_num_alloc_blocks */
+               mem_stat_buf->ul_num_alloc_blocks =
+                   target->seg_tab[segid].number;
+
+               ret = true;
+       }
+
+       return ret;
+}
+
+/*
+ *  ======== balloc ========
+ *  This allocation function allocates memory from the lowest addresses
+ *  first.
+ */
+static bool alloc_block(struct rmm_target_obj *target, u32 segid, u32 size,
+                       u32 align, u32 *dsp_address)
+{
+       struct rmm_header *head;
+       struct rmm_header *prevhead = NULL;
+       struct rmm_header *next;
+       u32 tmpalign;
+       u32 alignbytes;
+       u32 hsize;
+       u32 allocsize;
+       u32 addr;
+
+       alignbytes = (align == 0) ? 1 : align;
+       prevhead = NULL;
+       head = target->free_list[segid];
+
+       do {
+               hsize = head->size;
+               next = head->next;
+
+               addr = head->addr;      /* alloc from the bottom */
+
+               /* align allocation */
+               (tmpalign = (u32) addr % alignbytes);
+               if (tmpalign != 0)
+                       tmpalign = alignbytes - tmpalign;
+
+               allocsize = size + tmpalign;
+
+               if (hsize >= allocsize) {       /* big enough */
+                       if (hsize == allocsize && prevhead != NULL) {
+                               prevhead->next = next;
+                               kfree(head);
+                       } else {
+                               head->size = hsize - allocsize;
+                               head->addr += allocsize;
+                       }
+
+                       /* free up any hole created by alignment */
+                       if (tmpalign)
+                               free_block(target, segid, addr, tmpalign);
+
+                       *dsp_address = addr + tmpalign;
+                       return true;
+               }
+
+               prevhead = head;
+               head = next;
+
+       } while (head != NULL);
+
+       return false;
+}
+
+/*
+ *  ======== free_block ========
+ *  TO DO: free_block() allocates memory, which could result in failure.
+ *  Could allocate an rmm_header in rmm_alloc(), to be kept in a pool.
+ *  free_block() could use an rmm_header from the pool, freeing as blocks
+ *  are coalesced.
+ */
+static bool free_block(struct rmm_target_obj *target, u32 segid, u32 addr,
+                      u32 size)
+{
+       struct rmm_header *head;
+       struct rmm_header *thead;
+       struct rmm_header *rhead;
+       bool ret = true;
+
+       /* Create a memory header to hold the newly free'd block. */
+       rhead = kzalloc(sizeof(struct rmm_header), GFP_KERNEL);
+       if (rhead == NULL) {
+               ret = false;
+       } else {
+               /* search down the free list to find the right place for addr */
+               head = target->free_list[segid];
+
+               if (addr >= head->addr) {
+                       while (head->next != NULL && addr > head->next->addr)
+                               head = head->next;
+
+                       thead = head->next;
+
+                       head->next = rhead;
+                       rhead->next = thead;
+                       rhead->addr = addr;
+                       rhead->size = size;
+               } else {
+                       *rhead = *head;
+                       head->next = rhead;
+                       head->addr = addr;
+                       head->size = size;
+                       thead = rhead->next;
+               }
+
+               /* join with upper block, if possible */
+               if (thead != NULL && (rhead->addr + rhead->size) ==
+                   thead->addr) {
+                       head->next = rhead->next;
+                       thead->size = size + thead->size;
+                       thead->addr = addr;
+                       kfree(rhead);
+                       rhead = thead;
+               }
+
+               /* join with the lower block, if possible */
+               if ((head->addr + head->size) == rhead->addr) {
+                       head->next = rhead->next;
+                       head->size = head->size + rhead->size;
+                       kfree(rhead);
+               }
+       }
+
+       return ret;
+}
diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c
new file mode 100644 (file)
index 0000000..ef2ec94
--- /dev/null
@@ -0,0 +1,853 @@
+/*
+ * strm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * DSP/BIOS Bridge Stream Manager.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Bridge Driver */
+#include <dspbridge/dspdefs.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <dspbridge/nodepriv.h>
+
+/*  ----------------------------------- Others */
+#include <dspbridge/cmm.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/strm.h>
+
+#include <dspbridge/cfg.h>
+#include <dspbridge/resourcecleanup.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define DEFAULTTIMEOUT      10000
+#define DEFAULTNUMBUFS      2
+
+/*
+ *  ======== strm_mgr ========
+ *  The strm_mgr contains device information needed to open the underlying
+ *  channels of a stream.
+ */
+struct strm_mgr {
+       struct dev_object *dev_obj;     /* Device for this processor */
+       struct chnl_mgr *hchnl_mgr;     /* Channel manager */
+       /* Function interface to Bridge driver */
+       struct bridge_drv_interface *intf_fxns;
+};
+
+/*
+ *  ======== strm_object ========
+ *  This object is allocated in strm_open().
+ */
+struct strm_object {
+       struct strm_mgr *strm_mgr_obj;
+       struct chnl_object *chnl_obj;
+       u32 dir;                /* DSP_TONODE or DSP_FROMNODE */
+       u32 utimeout;
+       u32 num_bufs;           /* Max # of bufs allowed in stream */
+       u32 un_bufs_in_strm;    /* Current # of bufs in stream */
+       u32 ul_n_bytes;         /* bytes transferred since idled */
+       /* STREAM_IDLE, STREAM_READY, ... */
+       enum dsp_streamstate strm_state;
+       void *user_event;       /* Saved for strm_get_info() */
+       enum dsp_strmmode strm_mode;    /* STRMMODE_[PROCCOPY][ZEROCOPY]... */
+       u32 udma_chnl_id;       /* DMA chnl id */
+       u32 udma_priority;      /* DMA priority:DMAPRI_[LOW][HIGH] */
+       u32 segment_id;         /* >0 is SM segment.=0 is local heap */
+       u32 buf_alignment;      /* Alignment for stream bufs */
+       /* Stream's SM address translator */
+       struct cmm_xlatorobject *xlator;
+};
+
+/*  ----------------------------------- Globals */
+static u32 refs;               /* module reference count */
+
+/*  ----------------------------------- Function Prototypes */
+static int delete_strm(struct strm_object *stream_obj);
+
+/*
+ *  ======== strm_allocate_buffer ========
+ *  Purpose:
+ *      Allocates buffers for a stream.
+ */
+int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize,
+                               u8 **ap_buffer, u32 num_bufs,
+                               struct process_context *pr_ctxt)
+{
+       int status = 0;
+       u32 alloc_cnt = 0;
+       u32 i;
+       struct strm_object *stream_obj = strmres->hstream;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(ap_buffer != NULL);
+
+       if (stream_obj) {
+               /*
+                * Allocate from segment specified at time of stream open.
+                */
+               if (usize == 0)
+                       status = -EINVAL;
+
+       } else {
+               status = -EFAULT;
+       }
+
+       if (status)
+               goto func_end;
+
+       for (i = 0; i < num_bufs; i++) {
+               DBC_ASSERT(stream_obj->xlator != NULL);
+               (void)cmm_xlator_alloc_buf(stream_obj->xlator, &ap_buffer[i],
+                                          usize);
+               if (ap_buffer[i] == NULL) {
+                       status = -ENOMEM;
+                       alloc_cnt = i;
+                       break;
+               }
+       }
+       if (status)
+               strm_free_buffer(strmres, ap_buffer, alloc_cnt, pr_ctxt);
+
+       if (status)
+               goto func_end;
+
+       drv_proc_update_strm_res(num_bufs, strmres);
+
+func_end:
+       return status;
+}
+
+/*
+ *  ======== strm_close ========
+ *  Purpose:
+ *      Close a stream opened with strm_open().
+ */
+int strm_close(struct strm_res_object *strmres,
+                     struct process_context *pr_ctxt)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct chnl_info chnl_info_obj;
+       int status = 0;
+       struct strm_object *stream_obj = strmres->hstream;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!stream_obj) {
+               status = -EFAULT;
+       } else {
+               /* Have all buffers been reclaimed? If not, return
+                * -EPIPE */
+               intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
+               status =
+                   (*intf_fxns->pfn_chnl_get_info) (stream_obj->chnl_obj,
+                                                    &chnl_info_obj);
+               DBC_ASSERT(!status);
+
+               if (chnl_info_obj.cio_cs > 0 || chnl_info_obj.cio_reqs > 0)
+                       status = -EPIPE;
+               else
+                       status = delete_strm(stream_obj);
+       }
+
+       if (status)
+               goto func_end;
+
+       idr_remove(pr_ctxt->stream_id, strmres->id);
+func_end:
+       DBC_ENSURE(status == 0 || status == -EFAULT ||
+                  status == -EPIPE || status == -EPERM);
+
+       dev_dbg(bridge, "%s: stream_obj: %p, status 0x%x\n", __func__,
+               stream_obj, status);
+       return status;
+}
+
+/*
+ *  ======== strm_create ========
+ *  Purpose:
+ *      Create a STRM manager object.
+ */
+int strm_create(struct strm_mgr **strm_man,
+                      struct dev_object *dev_obj)
+{
+       struct strm_mgr *strm_mgr_obj;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(strm_man != NULL);
+       DBC_REQUIRE(dev_obj != NULL);
+
+       *strm_man = NULL;
+       /* Allocate STRM manager object */
+       strm_mgr_obj = kzalloc(sizeof(struct strm_mgr), GFP_KERNEL);
+       if (strm_mgr_obj == NULL)
+               status = -ENOMEM;
+       else
+               strm_mgr_obj->dev_obj = dev_obj;
+
+       /* Get Channel manager and Bridge function interface */
+       if (!status) {
+               status = dev_get_chnl_mgr(dev_obj, &(strm_mgr_obj->hchnl_mgr));
+               if (!status) {
+                       (void)dev_get_intf_fxns(dev_obj,
+                                               &(strm_mgr_obj->intf_fxns));
+                       DBC_ASSERT(strm_mgr_obj->intf_fxns != NULL);
+               }
+       }
+
+       if (!status)
+               *strm_man = strm_mgr_obj;
+       else
+               kfree(strm_mgr_obj);
+
+       DBC_ENSURE((!status && *strm_man) || (status && *strm_man == NULL));
+
+       return status;
+}
+
+/*
+ *  ======== strm_delete ========
+ *  Purpose:
+ *      Delete the STRM Manager Object.
+ */
+void strm_delete(struct strm_mgr *strm_mgr_obj)
+{
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(strm_mgr_obj);
+
+       kfree(strm_mgr_obj);
+}
+
+/*
+ *  ======== strm_exit ========
+ *  Purpose:
+ *      Discontinue usage of STRM module.
+ */
+void strm_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+
+       DBC_ENSURE(refs >= 0);
+}
+
+/*
+ *  ======== strm_free_buffer ========
+ *  Purpose:
+ *      Frees the buffers allocated for a stream.
+ */
+int strm_free_buffer(struct strm_res_object *strmres, u8 ** ap_buffer,
+                           u32 num_bufs, struct process_context *pr_ctxt)
+{
+       int status = 0;
+       u32 i = 0;
+       struct strm_object *stream_obj = strmres->hstream;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(ap_buffer != NULL);
+
+       if (!stream_obj)
+               status = -EFAULT;
+
+       if (!status) {
+               for (i = 0; i < num_bufs; i++) {
+                       DBC_ASSERT(stream_obj->xlator != NULL);
+                       status =
+                           cmm_xlator_free_buf(stream_obj->xlator,
+                                               ap_buffer[i]);
+                       if (status)
+                               break;
+                       ap_buffer[i] = NULL;
+               }
+       }
+       drv_proc_update_strm_res(num_bufs - i, strmres);
+
+       return status;
+}
+
+/*
+ *  ======== strm_get_info ========
+ *  Purpose:
+ *      Retrieves information about a stream.
+ */
+int strm_get_info(struct strm_object *stream_obj,
+                        struct stream_info *stream_info,
+                        u32 stream_info_size)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct chnl_info chnl_info_obj;
+       int status = 0;
+       void *virt_base = NULL; /* NULL if no SM used */
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(stream_info != NULL);
+       DBC_REQUIRE(stream_info_size >= sizeof(struct stream_info));
+
+       if (!stream_obj) {
+               status = -EFAULT;
+       } else {
+               if (stream_info_size < sizeof(struct stream_info)) {
+                       /* size of users info */
+                       status = -EINVAL;
+               }
+       }
+       if (status)
+               goto func_end;
+
+       intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
+       status =
+           (*intf_fxns->pfn_chnl_get_info) (stream_obj->chnl_obj,
+                                                 &chnl_info_obj);
+       if (status)
+               goto func_end;
+
+       if (stream_obj->xlator) {
+               /* We have a translator */
+               DBC_ASSERT(stream_obj->segment_id > 0);
+               cmm_xlator_info(stream_obj->xlator, (u8 **) &virt_base, 0,
+                               stream_obj->segment_id, false);
+       }
+       stream_info->segment_id = stream_obj->segment_id;
+       stream_info->strm_mode = stream_obj->strm_mode;
+       stream_info->virt_base = virt_base;
+       stream_info->user_strm->number_bufs_allowed = stream_obj->num_bufs;
+       stream_info->user_strm->number_bufs_in_stream = chnl_info_obj.cio_cs +
+           chnl_info_obj.cio_reqs;
+       /* # of bytes transferred since last call to DSPStream_Idle() */
+       stream_info->user_strm->ul_number_bytes = chnl_info_obj.bytes_tx;
+       stream_info->user_strm->sync_object_handle = chnl_info_obj.event_obj;
+       /* Determine stream state based on channel state and info */
+       if (chnl_info_obj.dw_state & CHNL_STATEEOS) {
+               stream_info->user_strm->ss_stream_state = STREAM_DONE;
+       } else {
+               if (chnl_info_obj.cio_cs > 0)
+                       stream_info->user_strm->ss_stream_state = STREAM_READY;
+               else if (chnl_info_obj.cio_reqs > 0)
+                       stream_info->user_strm->ss_stream_state =
+                           STREAM_PENDING;
+               else
+                       stream_info->user_strm->ss_stream_state = STREAM_IDLE;
+
+       }
+func_end:
+       return status;
+}
+
+/*
+ *  ======== strm_idle ========
+ *  Purpose:
+ *      Idles a particular stream.
+ */
+int strm_idle(struct strm_object *stream_obj, bool flush_data)
+{
+       struct bridge_drv_interface *intf_fxns;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+
+       if (!stream_obj) {
+               status = -EFAULT;
+       } else {
+               intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
+
+               status = (*intf_fxns->pfn_chnl_idle) (stream_obj->chnl_obj,
+                                                     stream_obj->utimeout,
+                                                     flush_data);
+       }
+
+       dev_dbg(bridge, "%s: stream_obj: %p flush_data: 0x%x status: 0x%x\n",
+               __func__, stream_obj, flush_data, status);
+       return status;
+}
+
+/*
+ *  ======== strm_init ========
+ *  Purpose:
+ *      Initialize the STRM module.
+ */
+bool strm_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       return ret;
+}
+
+/*
+ *  ======== strm_issue ========
+ *  Purpose:
+ *      Issues a buffer on a stream
+ */
+int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes,
+                     u32 ul_buf_size, u32 dw_arg)
+{
+       struct bridge_drv_interface *intf_fxns;
+       int status = 0;
+       void *tmp_buf = NULL;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(pbuf != NULL);
+
+       if (!stream_obj) {
+               status = -EFAULT;
+       } else {
+               intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
+
+               if (stream_obj->segment_id != 0) {
+                       tmp_buf = cmm_xlator_translate(stream_obj->xlator,
+                                                      (void *)pbuf,
+                                                      CMM_VA2DSPPA);
+                       if (tmp_buf == NULL)
+                               status = -ESRCH;
+
+               }
+               if (!status) {
+                       status = (*intf_fxns->pfn_chnl_add_io_req)
+                           (stream_obj->chnl_obj, pbuf, ul_bytes, ul_buf_size,
+                            (u32) tmp_buf, dw_arg);
+               }
+               if (status == -EIO)
+                       status = -ENOSR;
+       }
+
+       dev_dbg(bridge, "%s: stream_obj: %p pbuf: %p ul_bytes: 0x%x dw_arg:"
+               " 0x%x status: 0x%x\n", __func__, stream_obj, pbuf,
+               ul_bytes, dw_arg, status);
+       return status;
+}
+
+/*
+ *  ======== strm_open ========
+ *  Purpose:
+ *      Open a stream for sending/receiving data buffers to/from a task or
+ *      XDAIS socket node on the DSP.
+ */
+int strm_open(struct node_object *hnode, u32 dir, u32 index,
+                    struct strm_attr *pattr,
+                    struct strm_res_object **strmres,
+                    struct process_context *pr_ctxt)
+{
+       struct strm_mgr *strm_mgr_obj;
+       struct bridge_drv_interface *intf_fxns;
+       u32 ul_chnl_id;
+       struct strm_object *strm_obj = NULL;
+       s8 chnl_mode;
+       struct chnl_attr chnl_attr_obj;
+       int status = 0;
+       struct cmm_object *hcmm_mgr = NULL;     /* Shared memory manager hndl */
+
+       void *stream_res;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(strmres != NULL);
+       DBC_REQUIRE(pattr != NULL);
+       *strmres = NULL;
+       if (dir != DSP_TONODE && dir != DSP_FROMNODE) {
+               status = -EPERM;
+       } else {
+               /* Get the channel id from the node (set in node_connect()) */
+               status = node_get_channel_id(hnode, dir, index, &ul_chnl_id);
+       }
+       if (!status)
+               status = node_get_strm_mgr(hnode, &strm_mgr_obj);
+
+       if (!status) {
+               strm_obj = kzalloc(sizeof(struct strm_object), GFP_KERNEL);
+               if (strm_obj == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       strm_obj->strm_mgr_obj = strm_mgr_obj;
+                       strm_obj->dir = dir;
+                       strm_obj->strm_state = STREAM_IDLE;
+                       strm_obj->user_event = pattr->user_event;
+                       if (pattr->stream_attr_in != NULL) {
+                               strm_obj->utimeout =
+                                   pattr->stream_attr_in->utimeout;
+                               strm_obj->num_bufs =
+                                   pattr->stream_attr_in->num_bufs;
+                               strm_obj->strm_mode =
+                                   pattr->stream_attr_in->strm_mode;
+                               strm_obj->segment_id =
+                                   pattr->stream_attr_in->segment_id;
+                               strm_obj->buf_alignment =
+                                   pattr->stream_attr_in->buf_alignment;
+                               strm_obj->udma_chnl_id =
+                                   pattr->stream_attr_in->udma_chnl_id;
+                               strm_obj->udma_priority =
+                                   pattr->stream_attr_in->udma_priority;
+                               chnl_attr_obj.uio_reqs =
+                                   pattr->stream_attr_in->num_bufs;
+                       } else {
+                               strm_obj->utimeout = DEFAULTTIMEOUT;
+                               strm_obj->num_bufs = DEFAULTNUMBUFS;
+                               strm_obj->strm_mode = STRMMODE_PROCCOPY;
+                               strm_obj->segment_id = 0;       /* local mem */
+                               strm_obj->buf_alignment = 0;
+                               strm_obj->udma_chnl_id = 0;
+                               strm_obj->udma_priority = 0;
+                               chnl_attr_obj.uio_reqs = DEFAULTNUMBUFS;
+                       }
+                       chnl_attr_obj.reserved1 = NULL;
+                       /* DMA chnl flush timeout */
+                       chnl_attr_obj.reserved2 = strm_obj->utimeout;
+                       chnl_attr_obj.event_obj = NULL;
+                       if (pattr->user_event != NULL)
+                               chnl_attr_obj.event_obj = pattr->user_event;
+
+               }
+       }
+       if (status)
+               goto func_cont;
+
+       if ((pattr->virt_base == NULL) || !(pattr->ul_virt_size > 0))
+               goto func_cont;
+
+       /* No System DMA */
+       DBC_ASSERT(strm_obj->strm_mode != STRMMODE_LDMA);
+       /* Get the shared mem mgr for this streams dev object */
+       status = dev_get_cmm_mgr(strm_mgr_obj->dev_obj, &hcmm_mgr);
+       if (!status) {
+               /*Allocate a SM addr translator for this strm. */
+               status = cmm_xlator_create(&strm_obj->xlator, hcmm_mgr, NULL);
+               if (!status) {
+                       DBC_ASSERT(strm_obj->segment_id > 0);
+                       /*  Set translators Virt Addr attributes */
+                       status = cmm_xlator_info(strm_obj->xlator,
+                                                (u8 **) &pattr->virt_base,
+                                                pattr->ul_virt_size,
+                                                strm_obj->segment_id, true);
+               }
+       }
+func_cont:
+       if (!status) {
+               /* Open channel */
+               chnl_mode = (dir == DSP_TONODE) ?
+                   CHNL_MODETODSP : CHNL_MODEFROMDSP;
+               intf_fxns = strm_mgr_obj->intf_fxns;
+               status = (*intf_fxns->pfn_chnl_open) (&(strm_obj->chnl_obj),
+                                                     strm_mgr_obj->hchnl_mgr,
+                                                     chnl_mode, ul_chnl_id,
+                                                     &chnl_attr_obj);
+               if (status) {
+                       /*
+                        * over-ride non-returnable status codes so we return
+                        * something documented
+                        */
+                       if (status != -ENOMEM && status !=
+                           -EINVAL && status != -EPERM) {
+                               /*
+                                * We got a status that's not return-able.
+                                * Assert that we got something we were
+                                * expecting (-EFAULT isn't acceptable,
+                                * strm_mgr_obj->hchnl_mgr better be valid or we
+                                * assert here), and then return -EPERM.
+                                */
+                               DBC_ASSERT(status == -ENOSR ||
+                                          status == -ECHRNG ||
+                                          status == -EALREADY ||
+                                          status == -EIO);
+                               status = -EPERM;
+                       }
+               }
+       }
+       if (!status) {
+               status = drv_proc_insert_strm_res_element(strm_obj,
+                                                       &stream_res, pr_ctxt);
+               if (status)
+                       delete_strm(strm_obj);
+               else
+                       *strmres = (struct strm_res_object *)stream_res;
+       } else {
+               (void)delete_strm(strm_obj);
+       }
+
+       /* ensure we return a documented error code */
+       DBC_ENSURE((!status && strm_obj) ||
+                  (*strmres == NULL && (status == -EFAULT ||
+                                       status == -EPERM
+                                       || status == -EINVAL)));
+
+       dev_dbg(bridge, "%s: hnode: %p dir: 0x%x index: 0x%x pattr: %p "
+               "strmres: %p status: 0x%x\n", __func__,
+               hnode, dir, index, pattr, strmres, status);
+       return status;
+}
+
+/*
+ *  ======== strm_reclaim ========
+ *  Purpose:
+ *      Relcaims a buffer from a stream.
+ */
+int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr,
+                       u32 *nbytes, u32 *buff_size, u32 *pdw_arg)
+{
+       struct bridge_drv_interface *intf_fxns;
+       struct chnl_ioc chnl_ioc_obj;
+       int status = 0;
+       void *tmp_buf = NULL;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(buf_ptr != NULL);
+       DBC_REQUIRE(nbytes != NULL);
+       DBC_REQUIRE(pdw_arg != NULL);
+
+       if (!stream_obj) {
+               status = -EFAULT;
+               goto func_end;
+       }
+       intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
+
+       status =
+           (*intf_fxns->pfn_chnl_get_ioc) (stream_obj->chnl_obj,
+                                           stream_obj->utimeout,
+                                           &chnl_ioc_obj);
+       if (!status) {
+               *nbytes = chnl_ioc_obj.byte_size;
+               if (buff_size)
+                       *buff_size = chnl_ioc_obj.buf_size;
+
+               *pdw_arg = chnl_ioc_obj.dw_arg;
+               if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
+                       if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
+                               status = -ETIME;
+                       } else {
+                               /* Allow reclaims after idle to succeed */
+                               if (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
+                                       status = -EPERM;
+
+                       }
+               }
+               /* Translate zerocopy buffer if channel not canceled. */
+               if (!status
+                   && (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
+                   && (stream_obj->strm_mode == STRMMODE_ZEROCOPY)) {
+                       /*
+                        *  This is a zero-copy channel so chnl_ioc_obj.pbuf
+                        *  contains the DSP address of SM. We need to
+                        *  translate it to a virtual address for the user
+                        *  thread to access.
+                        *  Note: Could add CMM_DSPPA2VA to CMM in the future.
+                        */
+                       tmp_buf = cmm_xlator_translate(stream_obj->xlator,
+                                                      chnl_ioc_obj.pbuf,
+                                                      CMM_DSPPA2PA);
+                       if (tmp_buf != NULL) {
+                               /* now convert this GPP Pa to Va */
+                               tmp_buf = cmm_xlator_translate(stream_obj->
+                                                              xlator,
+                                                              tmp_buf,
+                                                              CMM_PA2VA);
+                       }
+                       if (tmp_buf == NULL)
+                               status = -ESRCH;
+
+                       chnl_ioc_obj.pbuf = tmp_buf;
+               }
+               *buf_ptr = chnl_ioc_obj.pbuf;
+       }
+func_end:
+       /* ensure we return a documented return code */
+       DBC_ENSURE(!status || status == -EFAULT ||
+                  status == -ETIME || status == -ESRCH ||
+                  status == -EPERM);
+
+       dev_dbg(bridge, "%s: stream_obj: %p buf_ptr: %p nbytes: %p "
+               "pdw_arg: %p status 0x%x\n", __func__, stream_obj,
+               buf_ptr, nbytes, pdw_arg, status);
+       return status;
+}
+
+/*
+ *  ======== strm_register_notify ========
+ *  Purpose:
+ *      Register to be notified on specific events for this stream.
+ */
+int strm_register_notify(struct strm_object *stream_obj, u32 event_mask,
+                               u32 notify_type, struct dsp_notification
+                               * hnotification)
+{
+       struct bridge_drv_interface *intf_fxns;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(hnotification != NULL);
+
+       if (!stream_obj) {
+               status = -EFAULT;
+       } else if ((event_mask & ~((DSP_STREAMIOCOMPLETION) |
+                                  DSP_STREAMDONE)) != 0) {
+               status = -EINVAL;
+       } else {
+               if (notify_type != DSP_SIGNALEVENT)
+                       status = -ENOSYS;
+
+       }
+       if (!status) {
+               intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
+
+               status =
+                   (*intf_fxns->pfn_chnl_register_notify) (stream_obj->
+                                                           chnl_obj,
+                                                           event_mask,
+                                                           notify_type,
+                                                           hnotification);
+       }
+       /* ensure we return a documented return code */
+       DBC_ENSURE(!status || status == -EFAULT ||
+                  status == -ETIME || status == -ESRCH ||
+                  status == -ENOSYS || status == -EPERM);
+       return status;
+}
+
+/*
+ *  ======== strm_select ========
+ *  Purpose:
+ *      Selects a ready stream.
+ */
+int strm_select(struct strm_object **strm_tab, u32 strms,
+                      u32 *pmask, u32 utimeout)
+{
+       u32 index;
+       struct chnl_info chnl_info_obj;
+       struct bridge_drv_interface *intf_fxns;
+       struct sync_object **sync_events = NULL;
+       u32 i;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(strm_tab != NULL);
+       DBC_REQUIRE(pmask != NULL);
+       DBC_REQUIRE(strms > 0);
+
+       *pmask = 0;
+       for (i = 0; i < strms; i++) {
+               if (!strm_tab[i]) {
+                       status = -EFAULT;
+                       break;
+               }
+       }
+       if (status)
+               goto func_end;
+
+       /* Determine which channels have IO ready */
+       for (i = 0; i < strms; i++) {
+               intf_fxns = strm_tab[i]->strm_mgr_obj->intf_fxns;
+               status = (*intf_fxns->pfn_chnl_get_info) (strm_tab[i]->chnl_obj,
+                                                         &chnl_info_obj);
+               if (status) {
+                       break;
+               } else {
+                       if (chnl_info_obj.cio_cs > 0)
+                               *pmask |= (1 << i);
+
+               }
+       }
+       if (!status && utimeout > 0 && *pmask == 0) {
+               /* Non-zero timeout */
+               sync_events = kmalloc(strms * sizeof(struct sync_object *),
+                                                               GFP_KERNEL);
+
+               if (sync_events == NULL) {
+                       status = -ENOMEM;
+               } else {
+                       for (i = 0; i < strms; i++) {
+                               intf_fxns =
+                                   strm_tab[i]->strm_mgr_obj->intf_fxns;
+                               status = (*intf_fxns->pfn_chnl_get_info)
+                                   (strm_tab[i]->chnl_obj, &chnl_info_obj);
+                               if (status)
+                                       break;
+                               else
+                                       sync_events[i] =
+                                           chnl_info_obj.sync_event;
+
+                       }
+               }
+               if (!status) {
+                       status =
+                           sync_wait_on_multiple_events(sync_events, strms,
+                                                        utimeout, &index);
+                       if (!status) {
+                               /* Since we waited on the event, we have to
+                                * reset it */
+                               sync_set_event(sync_events[index]);
+                               *pmask = 1 << index;
+                       }
+               }
+       }
+func_end:
+       kfree(sync_events);
+
+       DBC_ENSURE((!status && (*pmask != 0 || utimeout == 0)) ||
+                  (status && *pmask == 0));
+
+       return status;
+}
+
+/*
+ *  ======== delete_strm ========
+ *  Purpose:
+ *      Frees the resources allocated for a stream.
+ */
+static int delete_strm(struct strm_object *stream_obj)
+{
+       struct bridge_drv_interface *intf_fxns;
+       int status = 0;
+
+       if (stream_obj) {
+               if (stream_obj->chnl_obj) {
+                       intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
+                       /* Channel close can fail only if the channel handle
+                        * is invalid. */
+                       status = (*intf_fxns->pfn_chnl_close)
+                                       (stream_obj->chnl_obj);
+                       /* Free all SM address translator resources */
+                       if (!status) {
+                               if (stream_obj->xlator) {
+                                       /* force free */
+                                       (void)cmm_xlator_delete(stream_obj->
+                                                               xlator,
+                                                               true);
+                               }
+                       }
+               }
+               kfree(stream_obj);
+       } else {
+               status = -EFAULT;
+       }
+       return status;
+}
diff --git a/drivers/staging/tidspbridge/services/cfg.c b/drivers/staging/tidspbridge/services/cfg.c
new file mode 100644 (file)
index 0000000..a7af74f
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * cfg.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Implementation of platform specific config services.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+
+/*  ----------------------------------- This */
+#include <dspbridge/cfg.h>
+#include <dspbridge/drv.h>
+
+struct drv_ext {
+       struct list_head link;
+       char sz_string[MAXREGPATHLENGTH];
+};
+
+/*
+ *  ======== cfg_exit ========
+ *  Purpose:
+ *      Discontinue usage of the CFG module.
+ */
+void cfg_exit(void)
+{
+       /* Do nothing */
+}
+
+/*
+ *  ======== cfg_get_auto_start ========
+ *  Purpose:
+ *      Retreive the autostart mask, if any, for this board.
+ */
+int cfg_get_auto_start(struct cfg_devnode *dev_node_obj,
+                             u32 *auto_start)
+{
+       int status = 0;
+       u32 dw_buf_size;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       dw_buf_size = sizeof(*auto_start);
+       if (!dev_node_obj)
+               status = -EFAULT;
+       if (!auto_start || !drv_datap)
+               status = -EFAULT;
+       if (!status)
+               *auto_start = (drv_datap->base_img) ? 1 : 0;
+
+       DBC_ENSURE((status == 0 &&
+                   (*auto_start == 0 || *auto_start == 1))
+                  || status != 0);
+       return status;
+}
+
+/*
+ *  ======== cfg_get_dev_object ========
+ *  Purpose:
+ *      Retrieve the Device Object handle for a given devnode.
+ */
+int cfg_get_dev_object(struct cfg_devnode *dev_node_obj,
+                             u32 *value)
+{
+       int status = 0;
+       u32 dw_buf_size;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       if (!drv_datap)
+               status = -EPERM;
+
+       if (!dev_node_obj)
+               status = -EFAULT;
+
+       if (!value)
+               status = -EFAULT;
+
+       dw_buf_size = sizeof(value);
+       if (!status) {
+
+               /* check the device string and then store dev object */
+               if (!
+                   (strcmp
+                    ((char *)((struct drv_ext *)dev_node_obj)->sz_string,
+                     "TIOMAP1510")))
+                       *value = (u32)drv_datap->dev_object;
+       }
+       if (status)
+               pr_err("%s: Failed, status 0x%x\n", __func__, status);
+       return status;
+}
+
+/*
+ *  ======== cfg_get_exec_file ========
+ *  Purpose:
+ *      Retreive the default executable, if any, for this board.
+ */
+int cfg_get_exec_file(struct cfg_devnode *dev_node_obj, u32 buf_size,
+                            char *str_exec_file)
+{
+       int status = 0;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       if (!dev_node_obj)
+               status = -EFAULT;
+
+       else if (!str_exec_file || !drv_datap)
+               status = -EFAULT;
+
+       if (strlen(drv_datap->base_img) > buf_size)
+               status = -EINVAL;
+
+       if (!status && drv_datap->base_img)
+               strcpy(str_exec_file, drv_datap->base_img);
+
+       if (status)
+               pr_err("%s: Failed, status 0x%x\n", __func__, status);
+       DBC_ENSURE(((status == 0) &&
+                   (strlen(str_exec_file) <= buf_size))
+                  || (status != 0));
+       return status;
+}
+
+/*
+ *  ======== cfg_get_object ========
+ *  Purpose:
+ *      Retrieve the Object handle from the Registry
+ */
+int cfg_get_object(u32 *value, u8 dw_type)
+{
+       int status = -EINVAL;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       DBC_REQUIRE(value != NULL);
+
+       if (!drv_datap)
+               return -EPERM;
+
+       switch (dw_type) {
+       case (REG_DRV_OBJECT):
+               if (drv_datap->drv_object) {
+                       *value = (u32)drv_datap->drv_object;
+                       status = 0;
+               } else {
+                       status = -ENODATA;
+               }
+               break;
+       case (REG_MGR_OBJECT):
+               if (drv_datap->mgr_object) {
+                       *value = (u32)drv_datap->mgr_object;
+                       status = 0;
+               } else {
+                       status = -ENODATA;
+               }
+               break;
+
+       default:
+               break;
+       }
+       if (status) {
+               *value = 0;
+               pr_err("%s: Failed, status 0x%x\n", __func__, status);
+       }
+       DBC_ENSURE((!status && *value != 0) || (status && *value == 0));
+       return status;
+}
+
+/*
+ *  ======== cfg_init ========
+ *  Purpose:
+ *      Initialize the CFG module's private state.
+ */
+bool cfg_init(void)
+{
+       return true;
+}
+
+/*
+ *  ======== cfg_set_dev_object ========
+ *  Purpose:
+ *      Store the Device Object handle and dev_node pointer for a given devnode.
+ */
+int cfg_set_dev_object(struct cfg_devnode *dev_node_obj, u32 value)
+{
+       int status = 0;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       if (!drv_datap) {
+               pr_err("%s: Failed, status 0x%x\n", __func__, status);
+               return -EPERM;
+       }
+
+       if (!dev_node_obj)
+               status = -EFAULT;
+
+       if (!status) {
+               /* Store the Bridge device object in the Registry */
+
+               if (!(strcmp((char *)dev_node_obj, "TIOMAP1510")))
+                       drv_datap->dev_object = (void *) value;
+       }
+       if (status)
+               pr_err("%s: Failed, status 0x%x\n", __func__, status);
+
+       return status;
+}
+
+/*
+ *  ======== cfg_set_object ========
+ *  Purpose:
+ *      Store the Driver Object handle
+ */
+int cfg_set_object(u32 value, u8 dw_type)
+{
+       int status = -EINVAL;
+       struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+       if (!drv_datap)
+               return -EPERM;
+
+       switch (dw_type) {
+       case (REG_DRV_OBJECT):
+               drv_datap->drv_object = (void *)value;
+               status = 0;
+               break;
+       case (REG_MGR_OBJECT):
+               drv_datap->mgr_object = (void *)value;
+               status = 0;
+               break;
+       default:
+               break;
+       }
+       if (status)
+               pr_err("%s: Failed, status 0x%x\n", __func__, status);
+       return status;
+}
diff --git a/drivers/staging/tidspbridge/services/ntfy.c b/drivers/staging/tidspbridge/services/ntfy.c
new file mode 100644 (file)
index 0000000..a2ea698
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * ntfy.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Manage lists of notification events.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- This */
+#include <dspbridge/ntfy.h>
+
+int dsp_notifier_event(struct notifier_block *this, unsigned long event,
+                          void *data)
+{
+       struct  ntfy_event *ne = container_of(this, struct ntfy_event,
+                                                       noti_block);
+       if (ne->event & event)
+               sync_set_event(&ne->sync_obj);
+       return NOTIFY_OK;
+}
+
diff --git a/drivers/staging/tidspbridge/services/services.c b/drivers/staging/tidspbridge/services/services.c
new file mode 100644 (file)
index 0000000..6a7dd6f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * services.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Provide SERVICES loading.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/cfg.h>
+#include <dspbridge/ntfy.h>
+#include <dspbridge/sync.h>
+#include <dspbridge/clk.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/services.h>
+
+/*
+ *  ======== services_exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ */
+void services_exit(void)
+{
+       cfg_exit();
+}
+
+/*
+ *  ======== services_init ========
+ *  Purpose:
+ *      Initializes SERVICES modules.
+ */
+bool services_init(void)
+{
+       bool ret = true;
+       bool fcfg;
+
+       /* Perform required initialization of SERVICES modules. */
+       fcfg = cfg_init();
+
+       ret = fcfg;
+
+       if (!ret) {
+               if (fcfg)
+                       cfg_exit();
+       }
+
+       return ret;
+}
diff --git a/drivers/staging/tidspbridge/services/sync.c b/drivers/staging/tidspbridge/services/sync.c
new file mode 100644 (file)
index 0000000..9010b37
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * sync.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Synchronization services.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/sync.h>
+
+DEFINE_SPINLOCK(sync_lock);
+
+/**
+ * sync_set_event() - set or signal and specified event
+ * @event:     Event to be set..
+ *
+ * set the @event, if there is an thread waiting for the event
+ * it will be waken up, this function only wakes one thread.
+ */
+
+void sync_set_event(struct sync_object *event)
+{
+       spin_lock_bh(&sync_lock);
+       complete(&event->comp);
+       if (event->multi_comp)
+               complete(event->multi_comp);
+       spin_unlock_bh(&sync_lock);
+}
+
+/**
+ * sync_wait_on_multiple_events() - waits for multiple events to be set.
+ * @events:    Array of events to wait for them.
+ * @count:     number of elements of the array.
+ * @timeout    timeout on waiting for the evetns.
+ * @pu_index   index of the event set.
+ *
+ * This functios will wait until any of the array element is set or until
+ * timeout. In case of success the function will return 0 and
+ * @pu_index will store the index of the array element set or in case
+ * of timeout the function will return -ETIME or in case of
+ * interrupting by a signal it will return -EPERM.
+ */
+
+int sync_wait_on_multiple_events(struct sync_object **events,
+                                    unsigned count, unsigned timeout,
+                                    unsigned *index)
+{
+       unsigned i;
+       int status = -EPERM;
+       struct completion m_comp;
+
+       init_completion(&m_comp);
+
+       if (SYNC_INFINITE == timeout)
+               timeout = MAX_SCHEDULE_TIMEOUT;
+
+       spin_lock_bh(&sync_lock);
+       for (i = 0; i < count; i++) {
+               if (completion_done(&events[i]->comp)) {
+                       INIT_COMPLETION(events[i]->comp);
+                       *index = i;
+                       spin_unlock_bh(&sync_lock);
+                       status = 0;
+                       goto func_end;
+               }
+       }
+
+       for (i = 0; i < count; i++)
+               events[i]->multi_comp = &m_comp;
+
+       spin_unlock_bh(&sync_lock);
+
+       if (!wait_for_completion_interruptible_timeout(&m_comp,
+                                       msecs_to_jiffies(timeout)))
+               status = -ETIME;
+
+       spin_lock_bh(&sync_lock);
+       for (i = 0; i < count; i++) {
+               if (completion_done(&events[i]->comp)) {
+                       INIT_COMPLETION(events[i]->comp);
+                       *index = i;
+                       status = 0;
+               }
+               events[i]->multi_comp = NULL;
+       }
+       spin_unlock_bh(&sync_lock);
+func_end:
+       return status;
+}
+
index 022d0649ac5ee219b67d5b50ad7f95f58432b5d3..30dbfb6d16f20febb872a60ab882490d9c87abfb 100644 (file)
 #include <linux/module.h>
 #include <linux/net.h>
 
+#define STUB_BUSID_OTHER 0
+#define STUB_BUSID_REMOV 1
+#define STUB_BUSID_ADDED 2
+#define STUB_BUSID_ALLOC 3
+
 struct stub_device {
        struct usb_interface *interface;
        struct list_head list;
@@ -72,6 +77,14 @@ struct stub_unlink {
        __u32 status;
 };
 
+#define BUSID_SIZE 20
+struct bus_id_priv {
+       char name[BUSID_SIZE];
+       char status;
+       int interf_count;
+       struct stub_device *sdev;
+       char shutdown_busid;
+};
 
 extern struct kmem_cache *stub_priv_cache;
 
@@ -91,5 +104,7 @@ void stub_rx_loop(struct usbip_task *);
 void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
 
 /* stub_main.c */
-int match_busid(const char *busid);
+struct bus_id_priv *get_busid_priv(const char *busid);
+int del_match_busid(char *busid);
+
 void stub_device_cleanup_urbs(struct stub_device *sdev);
index 3f95605427a7447c92ebd2e2b95d7600adafa20e..b6b753a493469c4c2a7067eb8a3a0542bf9f39c1 100644 (file)
@@ -393,11 +393,14 @@ static int stub_probe(struct usb_interface *interface,
        struct stub_device *sdev = NULL;
        const char *udev_busid = dev_name(interface->dev.parent);
        int err = 0;
+       struct bus_id_priv *busid_priv;
 
        dev_dbg(&interface->dev, "Enter\n");
 
        /* check we should claim or not by busid_table */
-       if (match_busid(udev_busid)) {
+       busid_priv = get_busid_priv(udev_busid);
+       if (!busid_priv  || (busid_priv->status == STUB_BUSID_REMOV) ||
+                            (busid_priv->status == STUB_BUSID_OTHER)) {
                dev_info(&interface->dev,
                         "this device %s is not in match_busid table. skip!\n",
                         udev_busid);
@@ -422,28 +425,80 @@ static int stub_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
+
+       if (busid_priv->status == STUB_BUSID_ALLOC) {
+               busid_priv->interf_count++;
+               sdev = busid_priv->sdev;
+               if (!sdev)
+                       return -ENODEV;
+
+               dev_info(&interface->dev,
+                "USB/IP Stub: register a new interface "
+                "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
+                interface->cur_altsetting->desc.bInterfaceNumber);
+
+               /* set private data to usb_interface */
+               usb_set_intfdata(interface, sdev);
+
+               err = stub_add_files(&interface->dev);
+               if (err) {
+                       dev_err(&interface->dev, "create sysfs files for %s\n",
+                               udev_busid);
+                       usb_set_intfdata(interface, NULL);
+                       busid_priv->interf_count--;
+
+                       return err;
+               }
+
+               return 0;
+       }
+
        /* ok. this is my device. */
        sdev = stub_device_alloc(interface);
        if (!sdev)
                return -ENOMEM;
 
-       dev_info(&interface->dev, "USB/IP Stub: register a new interface "
+       dev_info(&interface->dev, "USB/IP Stub: register a new device "
                 "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
                 interface->cur_altsetting->desc.bInterfaceNumber);
 
+       busid_priv->interf_count = 0;
+       busid_priv->shutdown_busid = 0;
+
        /* set private data to usb_interface */
        usb_set_intfdata(interface, sdev);
+       busid_priv->interf_count++;
+
+       busid_priv->sdev = sdev;
 
        err = stub_add_files(&interface->dev);
        if (err) {
                dev_err(&interface->dev, "create sysfs files for %s\n",
                        udev_busid);
+               usb_set_intfdata(interface, NULL);
+               busid_priv->interf_count = 0;
+
+               busid_priv->sdev = NULL;
+               stub_device_free(sdev);
                return err;
        }
+       busid_priv->status = STUB_BUSID_ALLOC;
 
        return 0;
 }
 
+static void shutdown_busid(struct bus_id_priv *busid_priv)
+{
+       if (busid_priv->sdev && !busid_priv->shutdown_busid) {
+               busid_priv->shutdown_busid = 1;
+               usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
+
+               /* 2. wait for the stop of the event handler */
+               usbip_stop_eh(&busid_priv->sdev->ud);
+       }
+
+}
+
 
 /*
  * called in usb_disconnect() or usb_deregister()
@@ -451,10 +506,21 @@ static int stub_probe(struct usb_interface *interface,
  */
 static void stub_disconnect(struct usb_interface *interface)
 {
-       struct stub_device *sdev = usb_get_intfdata(interface);
+       struct stub_device *sdev;
+       const char *udev_busid = dev_name(interface->dev.parent);
+       struct bus_id_priv *busid_priv;
+
+       busid_priv = get_busid_priv(udev_busid);
 
        usbip_udbg("Enter\n");
 
+       if (!busid_priv) {
+               BUG();
+               return;
+       }
+
+       sdev = usb_get_intfdata(interface);
+
        /* get stub_device */
        if (!sdev) {
                err(" could not get device from inteface data");
@@ -464,22 +530,39 @@ static void stub_disconnect(struct usb_interface *interface)
 
        usb_set_intfdata(interface, NULL);
 
-
        /*
         * NOTE:
         * rx/tx threads are invoked for each usb_device.
         */
        stub_remove_files(&interface->dev);
 
-       /* 1. shutdown the current connection */
-       usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED);
+       /*If usb reset called from event handler*/
+       if (busid_priv->sdev->ud.eh.thread == current) {
+               busid_priv->interf_count--;
+               return;
+       }
+
+       if (busid_priv->interf_count > 1) {
+               busid_priv->interf_count--;
+               shutdown_busid(busid_priv);
+               return;
+       }
+
+       busid_priv->interf_count = 0;
 
-       /* 2. wait for the stop of the event handler */
-       usbip_stop_eh(&sdev->ud);
+
+       /* 1. shutdown the current connection */
+       shutdown_busid(busid_priv);
 
        /* 3. free sdev */
+       busid_priv->sdev = NULL;
        stub_device_free(sdev);
 
-
+       if (busid_priv->status == STUB_BUSID_ALLOC) {
+               busid_priv->status = STUB_BUSID_ADDED;
+       } else {
+               busid_priv->status = STUB_BUSID_OTHER;
+               del_match_busid((char *)udev_busid);
+       }
        usbip_udbg("bye\n");
 }
index 6665cefe573b539a2c4046bc2280594500f8d2a6..f3a40968aae2f60614e45af70b4eee660b4f5d58 100644 (file)
@@ -41,8 +41,7 @@ struct kmem_cache *stub_priv_cache;
  * remote host.
  */
 #define MAX_BUSID 16
-#define BUSID_SIZE 20
-static char busid_table[MAX_BUSID][BUSID_SIZE];
+static struct bus_id_priv busid_table[MAX_BUSID];
 static spinlock_t busid_table_lock;
 
 
@@ -53,8 +52,8 @@ int match_busid(const char *busid)
        spin_lock(&busid_table_lock);
 
        for (i = 0; i < MAX_BUSID; i++)
-               if (busid_table[i][0])
-                       if (!strncmp(busid_table[i], busid, BUSID_SIZE)) {
+               if (busid_table[i].name[0])
+                       if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
                                /* already registerd */
                                spin_unlock(&busid_table_lock);
                                return 0;
@@ -65,6 +64,25 @@ int match_busid(const char *busid)
        return 1;
 }
 
+struct bus_id_priv *get_busid_priv(const char *busid)
+{
+       int i;
+
+       spin_lock(&busid_table_lock);
+
+       for (i = 0; i < MAX_BUSID; i++)
+               if (busid_table[i].name[0])
+                       if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
+                               /* already registerd */
+                               spin_unlock(&busid_table_lock);
+                               return &(busid_table[i]);
+                       }
+
+       spin_unlock(&busid_table_lock);
+
+       return NULL;
+}
+
 static ssize_t show_match_busid(struct device_driver *drv, char *buf)
 {
        int i;
@@ -73,8 +91,8 @@ static ssize_t show_match_busid(struct device_driver *drv, char *buf)
        spin_lock(&busid_table_lock);
 
        for (i = 0; i < MAX_BUSID; i++)
-               if (busid_table[i][0])
-                       out += sprintf(out, "%s ", busid_table[i]);
+               if (busid_table[i].name[0])
+                       out += sprintf(out, "%s ", busid_table[i].name);
 
        spin_unlock(&busid_table_lock);
 
@@ -93,8 +111,11 @@ static int add_match_busid(char *busid)
        spin_lock(&busid_table_lock);
 
        for (i = 0; i < MAX_BUSID; i++)
-               if (!busid_table[i][0]) {
-                       strncpy(busid_table[i], busid, BUSID_SIZE);
+               if (!busid_table[i].name[0]) {
+                       strncpy(busid_table[i].name, busid, BUSID_SIZE);
+                       if ((busid_table[i].status != STUB_BUSID_ALLOC) &&
+                           (busid_table[i].status != STUB_BUSID_REMOV))
+                               busid_table[i].status = STUB_BUSID_ADDED;
                        spin_unlock(&busid_table_lock);
                        return 0;
                }
@@ -104,16 +125,21 @@ static int add_match_busid(char *busid)
        return -1;
 }
 
-static int del_match_busid(char *busid)
+int del_match_busid(char *busid)
 {
        int i;
 
        spin_lock(&busid_table_lock);
 
        for (i = 0; i < MAX_BUSID; i++)
-               if (!strncmp(busid_table[i], busid, BUSID_SIZE)) {
+               if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
                        /* found */
-                       memset(busid_table[i], 0, BUSID_SIZE);
+                       if (busid_table[i].status == STUB_BUSID_OTHER)
+                               memset(busid_table[i].name, 0, BUSID_SIZE);
+                       if ((busid_table[i].status != STUB_BUSID_OTHER) &&
+                           (busid_table[i].status != STUB_BUSID_ADDED)) {
+                               busid_table[i].status = STUB_BUSID_REMOV;
+                       }
                        spin_unlock(&busid_table_lock);
                        return 0;
                }
@@ -122,6 +148,20 @@ static int del_match_busid(char *busid)
 
        return -1;
 }
+static void init_busid_table(void)
+{
+       int i;
+
+
+       for (i = 0; i < MAX_BUSID; i++) {
+               memset(busid_table[i].name, 0, BUSID_SIZE);
+               busid_table[i].status = STUB_BUSID_OTHER;
+               busid_table[i].interf_count = 0;
+               busid_table[i].sdev = NULL;
+               busid_table[i].shutdown_busid = 0;
+       }
+       spin_lock_init(&busid_table_lock);
+}
 
 static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
                size_t count)
@@ -261,8 +301,7 @@ static int __init usb_stub_init(void)
        printk(KERN_INFO KBUILD_MODNAME ":"
               DRIVER_DESC ":" DRIVER_VERSION "\n");
 
-       memset(busid_table, 0, sizeof(busid_table));
-       spin_lock_init(&busid_table_lock);
+       init_busid_table();
 
        ret = driver_create_file(&stub_driver.drvwrap.driver,
                                 &driver_attr_match_busid);
index 5972ae70e3813d2ae72f2da2f9dae8b67e406fce..3de6fd2539dcb65efa74d25040f25cf9c22beb6e 100644 (file)
@@ -362,54 +362,16 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
        return priv;
 }
 
-
-static struct usb_host_endpoint *get_ep_from_epnum(struct usb_device *udev,
-               int epnum0)
-{
-       struct usb_host_config *config;
-       int i = 0, j = 0;
-       struct usb_host_endpoint *ep = NULL;
-       int epnum;
-       int found = 0;
-
-       if (epnum0 == 0)
-               return &udev->ep0;
-
-       config = udev->actconfig;
-       if (!config)
-               return NULL;
-
-       for (i = 0; i < config->desc.bNumInterfaces; i++) {
-               struct usb_host_interface *setting;
-
-               setting = config->interface[i]->cur_altsetting;
-
-               for (j = 0; j < setting->desc.bNumEndpoints; j++) {
-                       ep = &setting->endpoint[j];
-                       epnum = (ep->desc.bEndpointAddress & 0x7f);
-
-                       if (epnum == epnum0) {
-                               /* usbip_uinfo("found epnum %d\n", epnum0);*/
-                               found = 1;
-                               break;
-                       }
-               }
-       }
-
-       if (found)
-               return ep;
-       else
-               return NULL;
-}
-
-
 static int get_pipe(struct stub_device *sdev, int epnum, int dir)
 {
        struct usb_device *udev = interface_to_usbdev(sdev->interface);
        struct usb_host_endpoint *ep;
        struct usb_endpoint_descriptor *epd = NULL;
 
-       ep = get_ep_from_epnum(udev, epnum);
+       if (dir == USBIP_DIR_IN)
+               ep = udev->ep_in[epnum & 0x7f];
+       else
+               ep = udev->ep_out[epnum & 0x7f];
        if (!ep) {
                dev_err(&sdev->interface->dev, "no such endpoint?, %d\n",
                        epnum);
@@ -462,6 +424,60 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir)
        return 0;
 }
 
+static void masking_bogus_flags(struct urb *urb)
+{
+       int                             xfertype;
+       struct usb_device               *dev;
+       struct usb_host_endpoint        *ep;
+       int                             is_out;
+       unsigned int    allowed;
+
+       if (!urb || urb->hcpriv || !urb->complete)
+               return;
+       dev = urb->dev;
+       if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
+               return;
+
+       ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out)
+                       [usb_pipeendpoint(urb->pipe)];
+       if (!ep)
+               return;
+
+       xfertype = usb_endpoint_type(&ep->desc);
+       if (xfertype == USB_ENDPOINT_XFER_CONTROL) {
+               struct usb_ctrlrequest *setup =
+                               (struct usb_ctrlrequest *) urb->setup_packet;
+
+               if (!setup)
+                       return;
+               is_out = !(setup->bRequestType & USB_DIR_IN) ||
+                               !setup->wLength;
+       } else {
+               is_out = usb_endpoint_dir_out(&ep->desc);
+       }
+
+       /* enforce simple/standard policy */
+       allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT |
+                  URB_DIR_MASK | URB_FREE_BUFFER);
+       switch (xfertype) {
+       case USB_ENDPOINT_XFER_BULK:
+               if (is_out)
+                       allowed |= URB_ZERO_PACKET;
+               /* FALLTHROUGH */
+       case USB_ENDPOINT_XFER_CONTROL:
+               allowed |= URB_NO_FSBR; /* only affects UHCI */
+               /* FALLTHROUGH */
+       default:                        /* all non-iso endpoints */
+               if (!is_out)
+                       allowed |= URB_SHORT_NOT_OK;
+               break;
+       case USB_ENDPOINT_XFER_ISOC:
+               allowed |= URB_ISO_ASAP;
+               break;
+       }
+       urb->transfer_flags &= allowed;
+}
+
 static void stub_recv_cmd_submit(struct stub_device *sdev,
                                 struct usbip_header *pdu)
 {
@@ -528,6 +544,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
        /* no need to submit an intercepted request, but harmless? */
        tweak_special_requests(priv->urb);
 
+       masking_bogus_flags(priv->urb);
        /* urb is now ready to submit */
        ret = usb_submit_urb(priv->urb, GFP_KERNEL);
 
index e1bbd1287e282e7c0946e8fbcacb05ddb0ddf95b..d280e234e0670bca4220095c295c999e03213ade 100644 (file)
@@ -172,7 +172,7 @@ struct usbip_header_basic {
 #define USBIP_RET_UNLINK       0x0004
        __u32 command;
 
-        /* sequencial number which identifies requests.
+        /* sequential number which identifies requests.
          * incremented per connections */
        __u32 seqnum;
 
index 0f9ea58ff71705bb10823b83158ad99ae996c1d9..06bd793c52b5e82d100e0e855c89e2821d6db29f 100644 (file)
@@ -900,7 +900,8 @@ unsigned int ca91cx42_master_rmw(struct vme_master_resource *image,
        /* Address must be 4-byte aligned */
        if (pci_addr & 0x3) {
                dev_err(dev, "RMW Address not 4-byte aligned\n");
-               return -EINVAL;
+               result = -EINVAL;
+               goto out;
        }
 
        /* Ensure RMW Disabled whilst configuring */
@@ -921,6 +922,7 @@ unsigned int ca91cx42_master_rmw(struct vme_master_resource *image,
        /* Disable RMW */
        iowrite32(0, bridge->base + SCYC_CTL);
 
+out:
        spin_unlock(&(image->lock));
 
        mutex_unlock(&(bridge->vme_rmw));
@@ -961,11 +963,11 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
 
        if (dest->type == VME_DMA_VME) {
                entry->descriptor.dctl |= CA91CX42_DCTL_L2V;
-               vme_attr = (struct vme_dma_vme *)dest->private;
-               pci_attr = (struct vme_dma_pci *)src->private;
+               vme_attr = dest->private;
+               pci_attr = src->private;
        } else {
-               vme_attr = (struct vme_dma_vme *)src->private;
-               pci_attr = (struct vme_dma_pci *)dest->private;
+               vme_attr = src->private;
+               pci_attr = dest->private;
        }
 
        /* Check we can do fullfill required attributes */
index f09cac163139680a20eee6b9905c42ebce2b05f5..492ddb2d51080b3fab00137a1e8ca72e1104d587 100644 (file)
@@ -1649,7 +1649,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
        /* Fill out source part */
        switch (src->type) {
        case VME_DMA_PATTERN:
-               pattern_attr = (struct vme_dma_pattern *)src->private;
+               pattern_attr = src->private;
 
                entry->descriptor.dsal = pattern_attr->pattern;
                entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PAT;
@@ -1663,7 +1663,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
 
                break;
        case VME_DMA_PCI:
-               pci_attr = (struct vme_dma_pci *)src->private;
+               pci_attr = src->private;
 
                reg_split((unsigned long long)pci_attr->address, &address_high,
                        &address_low);
@@ -1672,7 +1672,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
                entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PCI;
                break;
        case VME_DMA_VME:
-               vme_attr = (struct vme_dma_vme *)src->private;
+               vme_attr = src->private;
 
                reg_split((unsigned long long)vme_attr->address, &address_high,
                        &address_low);
@@ -1701,7 +1701,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
        /* Fill out destination part */
        switch (dest->type) {
        case VME_DMA_PCI:
-               pci_attr = (struct vme_dma_pci *)dest->private;
+               pci_attr = dest->private;
 
                reg_split((unsigned long long)pci_attr->address, &address_high,
                        &address_low);
@@ -1710,7 +1710,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
                entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_PCI;
                break;
        case VME_DMA_VME:
-               vme_attr = (struct vme_dma_vme *)dest->private;
+               vme_attr = dest->private;
 
                reg_split((unsigned long long)vme_attr->address, &address_high,
                        &address_low);
index bc16fc070fd3841304bda64f1c4675c5d6a3a6ca..8f77bd24630c40a298dfc68b860ed97c544295d5 100644 (file)
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
 #include <linux/types.h>
 
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 
 #include "../vme.h"
 #include "vme_user.h"
 
+static DEFINE_MUTEX(vme_user_mutex);
 static char driver_name[] = "vme_user";
 
 static int bus[USER_BUS_MAX];
@@ -48,19 +49,19 @@ static int bus_num;
 /* Currently Documentation/devices.txt defines the following for VME:
  *
  * 221 char    VME bus
- *               0 = /dev/bus/vme/m0           First master image
- *               1 = /dev/bus/vme/m1           Second master image
- *               2 = /dev/bus/vme/m2           Third master image
- *               3 = /dev/bus/vme/m3           Fourth master image
- *               4 = /dev/bus/vme/s0           First slave image
- *               5 = /dev/bus/vme/s1           Second slave image
- *               6 = /dev/bus/vme/s2           Third slave image
- *               7 = /dev/bus/vme/s3           Fourth slave image
- *               8 = /dev/bus/vme/ctl          Control
+ *               0 = /dev/bus/vme/m0           First master image
+ *               1 = /dev/bus/vme/m1           Second master image
+ *               2 = /dev/bus/vme/m2           Third master image
+ *               3 = /dev/bus/vme/m3           Fourth master image
+ *               4 = /dev/bus/vme/s0           First slave image
+ *               5 = /dev/bus/vme/s1           Second slave image
+ *               6 = /dev/bus/vme/s2           Third slave image
+ *               7 = /dev/bus/vme/s3           Fourth slave image
+ *               8 = /dev/bus/vme/ctl          Control
  *
- *             It is expected that all VME bus drivers will use the
- *             same interface.  For interface documentation see
- *             http://www.vmelinux.org/.
+ *             It is expected that all VME bus drivers will use the
+ *             same interface.  For interface documentation see
+ *             http://www.vmelinux.org/.
  *
  * However the VME driver at http://www.vmelinux.org/ is rather old and doesn't
  * even support the tsi148 chipset (which has 8 master and 8 slave windows).
@@ -137,12 +138,12 @@ static int __init vme_user_probe(struct device *, int, int);
 static int __exit vme_user_remove(struct device *, int, int);
 
 static struct file_operations vme_user_fops = {
-        .open = vme_user_open,
-        .release = vme_user_release,
-        .read = vme_user_read,
-        .write = vme_user_write,
-        .llseek = vme_user_llseek,
-        .unlocked_ioctl = vme_user_unlocked_ioctl,
+       .open = vme_user_open,
+       .release = vme_user_release,
+       .read = vme_user_read,
+       .write = vme_user_write,
+       .llseek = vme_user_llseek,
+       .unlocked_ioctl = vme_user_unlocked_ioctl,
 };
 
 
@@ -151,13 +152,13 @@ static struct file_operations vme_user_fops = {
  */
 static void reset_counters(void)
 {
-        statistics.reads = 0;
-        statistics.writes = 0;
-        statistics.ioctls = 0;
-        statistics.irqs = 0;
-        statistics.berrs = 0;
-        statistics.dmaErrors = 0;
-        statistics.timeouts = 0;
+       statistics.reads = 0;
+       statistics.writes = 0;
+       statistics.ioctls = 0;
+       statistics.irqs = 0;
+       statistics.berrs = 0;
+       statistics.dmaErrors = 0;
+       statistics.timeouts = 0;
 }
 
 static int vme_user_open(struct inode *inode, struct file *file)
@@ -216,21 +217,20 @@ static ssize_t resource_to_user(int minor, char __user *buf, size_t count,
                /* We copy to kernel buffer */
                copied = vme_master_read(image[minor].resource,
                        image[minor].kern_buf, count, *ppos);
-               if (copied < 0) {
+               if (copied < 0)
                        return (int)copied;
-               }
 
                retval = __copy_to_user(buf, image[minor].kern_buf,
                        (unsigned long)copied);
                if (retval != 0) {
                        copied = (copied - retval);
-                       printk("User copy failed\n");
+                       printk(KERN_INFO "User copy failed\n");
                        return -EINVAL;
                }
 
        } else {
                /* XXX Need to write this */
-               printk("Currently don't support large transfers\n");
+               printk(KERN_INFO "Currently don't support large transfers\n");
                /* Map in pages from userspace */
 
                /* Call vme_master_read to do the transfer */
@@ -264,7 +264,7 @@ static ssize_t resource_from_user(unsigned int minor, const char *buf,
                        image[minor].kern_buf, copied, *ppos);
        } else {
                /* XXX Need to write this */
-               printk("Currently don't support large transfers\n");
+               printk(KERN_INFO "Currently don't support large transfers\n");
                /* Map in pages from userspace */
 
                /* Call vme_master_write to do the transfer */
@@ -313,7 +313,7 @@ static ssize_t buffer_from_user(unsigned int minor, const char *buf,
 }
 
 static ssize_t vme_user_read(struct file *file, char *buf, size_t count,
-                       loff_t * ppos)
+                       loff_t *ppos)
 {
        unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
        ssize_t retval;
@@ -337,7 +337,7 @@ static ssize_t vme_user_read(struct file *file, char *buf, size_t count,
        else
                okcount = count;
 
-       switch (type[minor]){
+       switch (type[minor]) {
        case MASTER_MINOR:
                retval = resource_to_user(minor, buf, okcount, ppos);
                break;
@@ -380,7 +380,7 @@ static ssize_t vme_user_write(struct file *file, const char *buf, size_t count,
        else
                okcount = count;
 
-       switch (type[minor]){
+       switch (type[minor]) {
        case MASTER_MINOR:
                retval = resource_from_user(minor, buf, okcount, ppos);
                break;
@@ -560,9 +560,9 @@ vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        int ret;
 
-       lock_kernel();
+       mutex_lock(&vme_user_mutex);
        ret = vme_user_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
-       unlock_kernel();
+       mutex_unlock(&vme_user_mutex);
 
        return ret;
 }
@@ -571,7 +571,7 @@ vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 /*
  * Unallocate a previously allocated buffer
  */
-static void buf_unalloc (int num)
+static void buf_unalloc(int num)
 {
        if (image[num].kern_buf) {
 #ifdef VME_DEBUG
@@ -594,8 +594,8 @@ static void buf_unalloc (int num)
 }
 
 static struct vme_driver vme_user_driver = {
-        .name = driver_name,
-        .probe = vme_user_probe,
+       .name = driver_name,
+       .probe = vme_user_probe,
        .remove = vme_user_remove,
 };
 
@@ -770,16 +770,16 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
        }
 
        /* Add sysfs Entries */
-       for (i=0; i<VME_DEVS; i++) {
+       for (i = 0; i < VME_DEVS; i++) {
                switch (type[i]) {
                case MASTER_MINOR:
-                       sprintf(name,"bus/vme/m%%d");
+                       sprintf(name, "bus/vme/m%%d");
                        break;
                case CONTROL_MINOR:
-                       sprintf(name,"bus/vme/ctl");
+                       sprintf(name, "bus/vme/ctl");
                        break;
                case SLAVE_MINOR:
-                       sprintf(name,"bus/vme/s%%d");
+                       sprintf(name, "bus/vme/s%%d");
                        break;
                default:
                        err = -EINVAL;
@@ -790,9 +790,9 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
                image[i].device =
                        device_create(vme_user_sysfs_class, NULL,
                                MKDEV(VME_MAJOR, i), NULL, name,
-                               (type[i] == SLAVE_MINOR)? i - (MASTER_MAX + 1) : i);
+                               (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i);
                if (IS_ERR(image[i].device)) {
-                       printk("%s: Error creating sysfs device\n",
+                       printk(KERN_INFO "%s: Error creating sysfs device\n",
                                driver_name);
                        err = PTR_ERR(image[i].device);
                        goto err_sysfs;
@@ -804,7 +804,7 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
        /* Ensure counter set correcty to destroy all sysfs devices */
        i = VME_DEVS;
 err_sysfs:
-       while (i > 0){
+       while (i > 0) {
                i--;
                device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i));
        }
@@ -845,9 +845,8 @@ static int __exit vme_user_remove(struct device *dev, int cur_bus, int cur_slot)
        int i;
 
        /* Remove sysfs Entries */
-       for(i=0; i<VME_DEVS; i++) {
+       for (i = 0; i < VME_DEVS; i++)
                device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i));
-       }
        class_destroy(vme_user_sysfs_class);
 
        for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
index b7b170e19aa294a3ca4eff306e807aeddce44d51..f55283b86410519606a82a0996e50b8cb51989b8 100644 (file)
 #ifdef __BIG_ENDIAN
 
 /* GET & SET Frame Control bit */
-#define WLAN_GET_FC_PRVER(n)    ((((WORD)(n) >> 8) & (BIT0 | BIT1))
-#define WLAN_GET_FC_FTYPE(n)    ((((WORD)(n) >> 8) & (BIT2 | BIT3)) >> 2)
-#define WLAN_GET_FC_FSTYPE(n)   ((((WORD)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
-#define WLAN_GET_FC_TODS(n)     ((((WORD)(n) << 8) & (BIT8)) >> 8)
-#define WLAN_GET_FC_FROMDS(n)   ((((WORD)(n) << 8) & (BIT9)) >> 9)
-#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n) << 8) & (BIT10)) >> 10)
-#define WLAN_GET_FC_RETRY(n)    ((((WORD)(n) << 8) & (BIT11)) >> 11)
-#define WLAN_GET_FC_PWRMGT(n)   ((((WORD)(n) << 8) & (BIT12)) >> 12)
-#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n) << 8) & (BIT13)) >> 13)
-#define WLAN_GET_FC_ISWEP(n)    ((((WORD)(n) << 8) & (BIT14)) >> 14)
-#define WLAN_GET_FC_ORDER(n)    ((((WORD)(n) << 8) & (BIT15)) >> 15)
+#define WLAN_GET_FC_PRVER(n)    ((((unsigned short)(n) >> 8) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n)    ((((unsigned short)(n) >> 8) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)   ((((unsigned short)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n)     ((((unsigned short)(n) << 8) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n)   ((((unsigned short)(n) << 8) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((unsigned short)(n) << 8) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n)    ((((unsigned short)(n) << 8) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n)   ((((unsigned short)(n) << 8) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((unsigned short)(n) << 8) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n)    ((((unsigned short)(n) << 8) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n)    ((((unsigned short)(n) << 8) & (BIT15)) >> 15)
 
 /* Sequence Field bit */
-#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3))
-#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+#define WLAN_GET_SEQ_FRGNUM(n) (((unsigned short)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((unsigned short)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
 
 
 /* Capability Field bit */
 #else
 
 /* GET & SET Frame Control bit */
-#define WLAN_GET_FC_PRVER(n)    (((WORD)(n)) & (BIT0 | BIT1))
-#define WLAN_GET_FC_FTYPE(n)    ((((WORD)(n)) & (BIT2 | BIT3)) >> 2)
-#define WLAN_GET_FC_FSTYPE(n)   ((((WORD)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
-#define WLAN_GET_FC_TODS(n)     ((((WORD)(n)) & (BIT8)) >> 8)
-#define WLAN_GET_FC_FROMDS(n)   ((((WORD)(n)) & (BIT9)) >> 9)
-#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n)) & (BIT10)) >> 10)
-#define WLAN_GET_FC_RETRY(n)    ((((WORD)(n)) & (BIT11)) >> 11)
-#define WLAN_GET_FC_PWRMGT(n)   ((((WORD)(n)) & (BIT12)) >> 12)
-#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n)) & (BIT13)) >> 13)
-#define WLAN_GET_FC_ISWEP(n)    ((((WORD)(n)) & (BIT14)) >> 14)
-#define WLAN_GET_FC_ORDER(n)    ((((WORD)(n)) & (BIT15)) >> 15)
+#define WLAN_GET_FC_PRVER(n)    (((unsigned short)(n)) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n)    ((((unsigned short)(n)) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)   ((((unsigned short)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n)     ((((unsigned short)(n)) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n)   ((((unsigned short)(n)) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((unsigned short)(n)) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n)    ((((unsigned short)(n)) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n)   ((((unsigned short)(n)) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((unsigned short)(n)) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n)    ((((unsigned short)(n)) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n)    ((((unsigned short)(n)) & (BIT15)) >> 15)
 
 
 /* Sequence Field bit */
-#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n)) & (BIT0|BIT1|BIT2|BIT3))
-#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+#define WLAN_GET_SEQ_FRGNUM(n) (((unsigned short)(n)) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((unsigned short)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
 
 
 /* Capability Field bit */
 #define WLAN_SET_CAP_INFO_GRPACK(n)        ((n) << 14)
 
 
-#define WLAN_SET_FC_PRVER(n)    ((WORD)(n))
-#define WLAN_SET_FC_FTYPE(n)    (((WORD)(n)) << 2)
-#define WLAN_SET_FC_FSTYPE(n)   (((WORD)(n)) << 4)
-#define WLAN_SET_FC_TODS(n)     (((WORD)(n)) << 8)
-#define WLAN_SET_FC_FROMDS(n)   (((WORD)(n)) << 9)
-#define WLAN_SET_FC_MOREFRAG(n) (((WORD)(n)) << 10)
-#define WLAN_SET_FC_RETRY(n)    (((WORD)(n)) << 11)
-#define WLAN_SET_FC_PWRMGT(n)   (((WORD)(n)) << 12)
-#define WLAN_SET_FC_MOREDATA(n) (((WORD)(n)) << 13)
-#define WLAN_SET_FC_ISWEP(n)    (((WORD)(n)) << 14)
-#define WLAN_SET_FC_ORDER(n)    (((WORD)(n)) << 15)
+#define WLAN_SET_FC_PRVER(n)    ((unsigned short)(n))
+#define WLAN_SET_FC_FTYPE(n)    (((unsigned short)(n)) << 2)
+#define WLAN_SET_FC_FSTYPE(n)   (((unsigned short)(n)) << 4)
+#define WLAN_SET_FC_TODS(n)     (((unsigned short)(n)) << 8)
+#define WLAN_SET_FC_FROMDS(n)   (((unsigned short)(n)) << 9)
+#define WLAN_SET_FC_MOREFRAG(n) (((unsigned short)(n)) << 10)
+#define WLAN_SET_FC_RETRY(n)    (((unsigned short)(n)) << 11)
+#define WLAN_SET_FC_PWRMGT(n)   (((unsigned short)(n)) << 12)
+#define WLAN_SET_FC_MOREDATA(n) (((unsigned short)(n)) << 13)
+#define WLAN_SET_FC_ISWEP(n)    (((unsigned short)(n)) << 14)
+#define WLAN_SET_FC_ORDER(n)    (((unsigned short)(n)) << 15)
 
-#define WLAN_SET_SEQ_FRGNUM(n) ((WORD)(n))
-#define WLAN_SET_SEQ_SEQNUM(n) (((WORD)(n)) << 4)
+#define WLAN_SET_SEQ_FRGNUM(n) ((unsigned short)(n))
+#define WLAN_SET_SEQ_SEQNUM(n) (((unsigned short)(n)) << 4)
 
 /* ERP Field bit */
 
 #define WLAN_MGMT_GET_TIM_OFFSET(b)     (((b) & ~BIT0) >> 1)
 
 /* 3-Addr & 4-Addr */
-#define WLAN_HDR_A3_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR3_LEN)
-#define WLAN_HDR_A4_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR4_LEN)
+#define WLAN_HDR_A3_DATA_PTR(p) (((unsigned char *)(p)) + WLAN_HDR_ADDR3_LEN)
+#define WLAN_HDR_A4_DATA_PTR(p) (((unsigned char *)(p)) + WLAN_HDR_ADDR4_LEN)
 
 /* IEEE ADDR */
 #define IEEE_ADDR_UNIVERSAL         0x02
 #define IEEE_ADDR_GROUP             0x01
 
 typedef struct {
-    BYTE            abyAddr[6];
+    unsigned char abyAddr[6];
 } IEEE_ADDR, *PIEEE_ADDR;
 
 /* 802.11 Header Format */
 
 typedef struct tagWLAN_80211HDR_A2 {
 
-    WORD    wFrameCtl;
-    WORD    wDurationID;
-    BYTE    abyAddr1[WLAN_ADDR_LEN];
-    BYTE    abyAddr2[WLAN_ADDR_LEN];
+    unsigned short wFrameCtl;
+    unsigned short wDurationID;
+    unsigned char abyAddr1[WLAN_ADDR_LEN];
+    unsigned char abyAddr2[WLAN_ADDR_LEN];
 
 } __attribute__ ((__packed__))
 WLAN_80211HDR_A2, *PWLAN_80211HDR_A2;
 
 typedef struct tagWLAN_80211HDR_A3 {
 
-    WORD    wFrameCtl;
-    WORD    wDurationID;
-    BYTE    abyAddr1[WLAN_ADDR_LEN];
-    BYTE    abyAddr2[WLAN_ADDR_LEN];
-    BYTE    abyAddr3[WLAN_ADDR_LEN];
-    WORD    wSeqCtl;
+    unsigned short wFrameCtl;
+    unsigned short wDurationID;
+    unsigned char abyAddr1[WLAN_ADDR_LEN];
+    unsigned char abyAddr2[WLAN_ADDR_LEN];
+    unsigned char abyAddr3[WLAN_ADDR_LEN];
+    unsigned short wSeqCtl;
 
 }__attribute__ ((__packed__))
 WLAN_80211HDR_A3, *PWLAN_80211HDR_A3;
 
 typedef struct tagWLAN_80211HDR_A4 {
 
-    WORD    wFrameCtl;
-    WORD    wDurationID;
-    BYTE    abyAddr1[WLAN_ADDR_LEN];
-    BYTE    abyAddr2[WLAN_ADDR_LEN];
-    BYTE    abyAddr3[WLAN_ADDR_LEN];
-    WORD    wSeqCtl;
-    BYTE    abyAddr4[WLAN_ADDR_LEN];
+    unsigned short wFrameCtl;
+    unsigned short wDurationID;
+    unsigned char abyAddr1[WLAN_ADDR_LEN];
+    unsigned char abyAddr2[WLAN_ADDR_LEN];
+    unsigned char abyAddr3[WLAN_ADDR_LEN];
+    unsigned short wSeqCtl;
+    unsigned char abyAddr4[WLAN_ADDR_LEN];
 
 } __attribute__ ((__packed__))
 WLAN_80211HDR_A4, *PWLAN_80211HDR_A4;
index 38697c862489bec73d82b775c43521313bd6e194..1ed0f260b1620f657f6c881d8a66ee651b678d22 100644 (file)
@@ -99,9 +99,9 @@ vMgrEncodeBeacon(
     // Fixed Fields
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_BEACON_OFF_TS);
-    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_BEACON_OFF_BCN_INT);
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_BEACON_OFF_CAPINFO);
 
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID;
@@ -133,15 +133,15 @@ vMgrDecodeBeacon(
     // Fixed Fields
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_BEACON_OFF_TS);
-    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_BEACON_OFF_BCN_INT);
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_BEACON_OFF_CAPINFO);
 
     // Information elements
-    pItem = (PWLAN_IE)((PBYTE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)))
+    pItem = (PWLAN_IE)((unsigned char *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)))
                        + WLAN_BEACON_OFF_SSID);
-    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ){
+    while( ((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) ){
 
         switch (pItem->byElementID) {
             case WLAN_EID_SSID:
@@ -179,7 +179,7 @@ vMgrDecodeBeacon(
                 break;
             case WLAN_EID_RSN_WPA:
                 if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
                         pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
                 }
                 break;
@@ -223,7 +223,7 @@ vMgrDecodeBeacon(
                 break;
 
         }
-        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+        pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
     }
 
     return;
@@ -296,7 +296,7 @@ vMgrEncodeDisassociation(
 
 
     // Fixed Fields
-    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DISASSOC_OFF_REASON);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason));
 
@@ -323,7 +323,7 @@ vMgrDecodeDisassociation(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DISASSOC_OFF_REASON);
 
     return;
@@ -348,9 +348,9 @@ vMgrEncodeAssocRequest(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCREQ_OFF_CAP_INFO);
-    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_ASSOCREQ_OFF_LISTEN_INT);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval));
     return;
@@ -377,16 +377,16 @@ vMgrDecodeAssocRequest(
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCREQ_OFF_CAP_INFO);
-    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCREQ_OFF_LISTEN_INT);
 
     // Information elements
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_ASSOCREQ_OFF_SSID);
 
-    while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
+    while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) {
         switch (pItem->byElementID){
             case WLAN_EID_SSID:
                 if (pFrame->pSSID == NULL)
@@ -404,7 +404,7 @@ vMgrDecodeAssocRequest(
                 break;
             case WLAN_EID_RSN_WPA:
                 if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
                         pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
                 }
                 break;
@@ -418,7 +418,7 @@ vMgrDecodeAssocRequest(
                         pItem->byElementID);
                 break;
         }
-        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+        pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
     }
     return;
 }
@@ -442,11 +442,11 @@ vMgrEncodeAssocResponse(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCRESP_OFF_CAP_INFO);
-    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_ASSOCRESP_OFF_STATUS);
-    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_ASSOCRESP_OFF_AID);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID
                   + sizeof(*(pFrame->pwAid));
@@ -476,11 +476,11 @@ vMgrDecodeAssocResponse(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCRESP_OFF_CAP_INFO);
-    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_ASSOCRESP_OFF_STATUS);
-    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_ASSOCRESP_OFF_AID);
 
     // Information elements
@@ -488,9 +488,10 @@ vMgrDecodeAssocResponse(
                            + WLAN_ASSOCRESP_OFF_SUPP_RATES);
 
     pItem = (PWLAN_IE)(pFrame->pSuppRates);
-    pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
 
-    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+    if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) &&
+                   (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
         pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
     }
@@ -520,9 +521,9 @@ vMgrEncodeReassocRequest(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCREQ_OFF_CAP_INFO);
-    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                       + WLAN_REASSOCREQ_OFF_LISTEN_INT);
     pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_REASSOCREQ_OFF_CURR_AP);
@@ -553,9 +554,9 @@ vMgrDecodeReassocRequest(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCREQ_OFF_CAP_INFO);
-    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                       + WLAN_REASSOCREQ_OFF_LISTEN_INT);
     pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_REASSOCREQ_OFF_CURR_AP);
@@ -564,7 +565,7 @@ vMgrDecodeReassocRequest(
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                        + WLAN_REASSOCREQ_OFF_SSID);
 
-    while(((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
+    while(((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) {
 
         switch (pItem->byElementID){
             case WLAN_EID_SSID:
@@ -583,7 +584,7 @@ vMgrDecodeReassocRequest(
                 break;
             case WLAN_EID_RSN_WPA:
                 if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
                         pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
                 }
                 break;
@@ -597,7 +598,7 @@ vMgrDecodeReassocRequest(
                             pItem->byElementID);
                 break;
         }
-        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+        pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
     }
     return;
 }
@@ -649,7 +650,7 @@ vMgrDecodeProbeRequest(
     // Information elements
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)));
 
-    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+    while( ((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) ) {
 
         switch (pItem->byElementID) {
             case WLAN_EID_SSID:
@@ -672,7 +673,7 @@ vMgrDecodeProbeRequest(
                 break;
         }
 
-        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
+        pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 +  pItem->len);
     }
     return;
 }
@@ -700,9 +701,9 @@ vMgrEncodeProbeResponse(
     // Fixed Fields
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_PROBERESP_OFF_TS);
-    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_PROBERESP_OFF_BCN_INT);
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_PROBERESP_OFF_CAP_INFO);
 
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO +
@@ -737,16 +738,16 @@ vMgrDecodeProbeResponse(
     // Fixed Fields
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_PROBERESP_OFF_TS);
-    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_PROBERESP_OFF_BCN_INT);
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_PROBERESP_OFF_CAP_INFO);
 
     // Information elements
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                        + WLAN_PROBERESP_OFF_SSID);
 
-    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+    while( ((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) ) {
         switch (pItem->byElementID) {
             case WLAN_EID_SSID:
                 if (pFrame->pSSID == NULL)
@@ -778,7 +779,7 @@ vMgrDecodeProbeResponse(
                 break;
             case WLAN_EID_RSN_WPA:
                 if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
                         pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
                 }
                 break;
@@ -821,7 +822,7 @@ vMgrDecodeProbeResponse(
                 break;
         }
 
-        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
+        pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 +  pItem->len);
     }
     return;
 }
@@ -846,11 +847,11 @@ vMgrEncodeAuthen(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAuthAlgorithm = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                       + WLAN_AUTHEN_OFF_AUTH_ALG);
-    pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAuthSequence = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                      + WLAN_AUTHEN_OFF_AUTH_SEQ);
-    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_AUTHEN_OFF_STATUS);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus));
 
@@ -879,18 +880,18 @@ vMgrDecodeAuthen(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAuthAlgorithm = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                       + WLAN_AUTHEN_OFF_AUTH_ALG);
-    pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAuthSequence = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                      + WLAN_AUTHEN_OFF_AUTH_SEQ);
-    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_AUTHEN_OFF_STATUS);
 
     // Information elements
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                        + WLAN_AUTHEN_OFF_CHALLENGE);
 
-    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) {
+    if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) {
         pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
     }
 
@@ -917,7 +918,7 @@ vMgrEncodeDeauthen(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DEAUTHEN_OFF_REASON);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason));
 
@@ -944,7 +945,7 @@ vMgrDecodeDeauthen(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DEAUTHEN_OFF_REASON);
 
     return;
@@ -970,11 +971,11 @@ vMgrEncodeReassocResponse(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCRESP_OFF_CAP_INFO);
-    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_REASSOCRESP_OFF_STATUS);
-    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_REASSOCRESP_OFF_AID);
 
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid));
@@ -1005,11 +1006,11 @@ vMgrDecodeReassocResponse(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
     // Fixed Fields
-    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCRESP_OFF_CAP_INFO);
-    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_REASSOCRESP_OFF_STATUS);
-    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+    pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_REASSOCRESP_OFF_AID);
 
     //Information elements
@@ -1017,9 +1018,10 @@ vMgrDecodeReassocResponse(
                                                + WLAN_REASSOCRESP_OFF_SUPP_RATES);
 
     pItem = (PWLAN_IE)(pFrame->pSuppRates);
-    pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
 
-    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+    if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) &&
+                   (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
         pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
     }
     return;
index 658fe144f8987b013784c40ce5a0bd30755a8166..3bdab3f56f1c92a1cbed0e2343dffc300ab1d55c 100644 (file)
@@ -19,7 +19,7 @@
  *
  * File: 80211mgr.h
  *
- * Purpose: 802.11 managment frames pre-defines.
+ * Purpose: 802.11 management frames pre-defines.
  *
  *
  * Author: Lyndon Chen
 
 #pragma pack(1)
 typedef struct tagWLAN_IE {
-    BYTE   byElementID;
-    BYTE   len;
+    unsigned char byElementID;
+    unsigned char len;
 }__attribute__ ((__packed__))
 WLAN_IE, *PWLAN_IE;
 
@@ -239,9 +239,9 @@ WLAN_IE, *PWLAN_IE;
 // Service Set Identity (SSID)
 #pragma pack(1)
 typedef struct tagWLAN_IE_SSID {
-    BYTE   byElementID;
-    BYTE   len;
-    BYTE   abySSID[1];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char abySSID[1];
 }__attribute__ ((__packed__))
 WLAN_IE_SSID, *PWLAN_IE_SSID;
 
@@ -249,9 +249,9 @@ WLAN_IE_SSID, *PWLAN_IE_SSID;
 // Supported Rates
 #pragma pack(1)
 typedef struct tagWLAN_IE_SUPP_RATES {
-    BYTE   byElementID;
-    BYTE   len;
-    BYTE   abyRates[1];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char abyRates[1];
 }__attribute__ ((__packed__))
 WLAN_IE_SUPP_RATES,  *PWLAN_IE_SUPP_RATES;
 
@@ -260,20 +260,20 @@ WLAN_IE_SUPP_RATES,  *PWLAN_IE_SUPP_RATES;
 // FH Parameter Set
 #pragma pack(1)
 typedef struct _WLAN_IE_FH_PARMS {
-    BYTE    byElementID;
-    BYTE    len;
-    WORD    wDwellTime;
-    BYTE    byHopSet;
-    BYTE    byHopPattern;
-    BYTE    byHopIndex;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned short wDwellTime;
+    unsigned char byHopSet;
+    unsigned char byHopPattern;
+    unsigned char byHopIndex;
 } WLAN_IE_FH_PARMS,  *PWLAN_IE_FH_PARMS;
 
 // DS Parameter Set
 #pragma pack(1)
 typedef struct tagWLAN_IE_DS_PARMS {
-    BYTE   byElementID;
-    BYTE   len;
-    BYTE   byCurrChannel;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byCurrChannel;
 }__attribute__ ((__packed__))
 WLAN_IE_DS_PARMS,  *PWLAN_IE_DS_PARMS;
 
@@ -281,12 +281,12 @@ WLAN_IE_DS_PARMS,  *PWLAN_IE_DS_PARMS;
 // CF Parameter Set
 #pragma pack(1)
 typedef struct tagWLAN_IE_CF_PARMS {
-    BYTE   byElementID;
-    BYTE   len;
-    BYTE   byCFPCount;
-    BYTE   byCFPPeriod;
-    WORD   wCFPMaxDuration;
-    WORD   wCFPDurRemaining;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byCFPCount;
+    unsigned char byCFPPeriod;
+    unsigned short wCFPMaxDuration;
+    unsigned short wCFPDurRemaining;
 }__attribute__ ((__packed__))
 WLAN_IE_CF_PARMS,  *PWLAN_IE_CF_PARMS;
 
@@ -294,12 +294,12 @@ WLAN_IE_CF_PARMS,  *PWLAN_IE_CF_PARMS;
 // TIM
 #pragma pack(1)
 typedef struct tagWLAN_IE_TIM {
-    BYTE   byElementID;
-    BYTE   len;
-    BYTE   byDTIMCount;
-    BYTE   byDTIMPeriod;
-    BYTE   byBitMapCtl;
-    BYTE   byVirtBitMap[1];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byDTIMCount;
+    unsigned char byDTIMPeriod;
+    unsigned char byBitMapCtl;
+    unsigned char byVirtBitMap[1];
 }__attribute__ ((__packed__))
 WLAN_IE_TIM,  *PWLAN_IE_TIM;
 
@@ -307,9 +307,9 @@ WLAN_IE_TIM,  *PWLAN_IE_TIM;
 // IBSS Parameter Set
 #pragma pack(1)
 typedef struct tagWLAN_IE_IBSS_PARMS {
-    BYTE   byElementID;
-    BYTE   len;
-    WORD   wATIMWindow;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned short wATIMWindow;
 }__attribute__ ((__packed__))
 WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS;
 
@@ -317,84 +317,84 @@ WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS;
 // Challenge Text
 #pragma pack(1)
 typedef struct tagWLAN_IE_CHALLENGE {
-    BYTE   byElementID;
-    BYTE   len;
-    BYTE   abyChallenge[1];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char abyChallenge[1];
 }__attribute__ ((__packed__))
 WLAN_IE_CHALLENGE,  *PWLAN_IE_CHALLENGE;
 
 
 #pragma pack(1)
 typedef struct tagWLAN_IE_RSN_EXT {
-    BYTE byElementID;
-    BYTE len;
-    BYTE abyOUI[4];
-    WORD wVersion;
-    BYTE abyMulticast[4];
-    WORD wPKCount;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char abyOUI[4];
+    unsigned short wVersion;
+    unsigned char abyMulticast[4];
+    unsigned short wPKCount;
     struct {
-        BYTE abyOUI[4];
+        unsigned char abyOUI[4];
     } PKSList[1]; // the rest is variable so need to
     // overlay ieauth structure
 } WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT;
 
 #pragma pack(1)
 typedef struct tagWLAN_IE_RSN_AUTH {
-    WORD wAuthCount;
+    unsigned short wAuthCount;
     struct {
-        BYTE abyOUI[4];
+        unsigned char abyOUI[4];
     } AuthKSList[1];
 } WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH;
 
 // RSN Identity
 #pragma pack(1)
 typedef struct tagWLAN_IE_RSN {
-    BYTE   byElementID;
-    BYTE   len;
-    WORD   wVersion;
-    BYTE   abyRSN[WLAN_MIN_ARRAY];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned short wVersion;
+    unsigned char abyRSN[WLAN_MIN_ARRAY];
 } WLAN_IE_RSN, *PWLAN_IE_RSN;
 
 
 // ERP
 #pragma pack(1)
 typedef struct tagWLAN_IE_ERP {
-    BYTE   byElementID;
-    BYTE   len;
-    BYTE   byContext;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byContext;
 }__attribute__ ((__packed__))
 WLAN_IE_ERP,  *PWLAN_IE_ERP;
 
 
 #pragma pack(1)
 typedef struct _MEASEURE_REQ {
-    BYTE                byChannel;
-    BYTE                abyStartTime[8];
-    BYTE                abyDuration[2];
+    unsigned char byChannel;
+    unsigned char abyStartTime[8];
+    unsigned char abyDuration[2];
 } MEASEURE_REQ, *PMEASEURE_REQ,
   MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC,
   MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA,
   MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI;
 
 typedef struct _MEASEURE_REP_BASIC {
-    BYTE                byChannel;
-    BYTE                abyStartTime[8];
-    BYTE                abyDuration[2];
-    BYTE                byMap;
+    unsigned char byChannel;
+    unsigned char abyStartTime[8];
+    unsigned char abyDuration[2];
+    unsigned char byMap;
 } MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC;
 
 typedef struct _MEASEURE_REP_CCA {
-    BYTE                byChannel;
-    BYTE                abyStartTime[8];
-    BYTE                abyDuration[2];
-    BYTE                byCCABusyFraction;
+    unsigned char byChannel;
+    unsigned char abyStartTime[8];
+    unsigned char abyDuration[2];
+    unsigned char byCCABusyFraction;
 } MEASEURE_REP_CCA, *PMEASEURE_REP_CCA;
 
 typedef struct _MEASEURE_REP_RPI {
-    BYTE                byChannel;
-    BYTE                abyStartTime[8];
-    BYTE                abyDuration[2];
-    BYTE                abyRPIdensity[8];
+    unsigned char byChannel;
+    unsigned char abyStartTime[8];
+    unsigned char abyDuration[2];
+    unsigned char abyRPIdensity[8];
 } MEASEURE_REP_RPI, *PMEASEURE_REP_RPI;
 
 typedef union _MEASEURE_REP {
@@ -406,85 +406,85 @@ typedef union _MEASEURE_REP {
 } MEASEURE_REP, *PMEASEURE_REP;
 
 typedef struct _WLAN_IE_MEASURE_REQ {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                byToken;
-    BYTE                byMode;
-    BYTE                byType;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byToken;
+    unsigned char byMode;
+    unsigned char byType;
     MEASEURE_REQ        sReq;
 } WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ;
 
 typedef struct _WLAN_IE_MEASURE_REP {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                byToken;
-    BYTE                byMode;
-    BYTE                byType;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byToken;
+    unsigned char byMode;
+    unsigned char byType;
     MEASEURE_REP        sRep;
 } WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP;
 
 typedef struct _WLAN_IE_CH_SW {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                byMode;
-    BYTE                byChannel;
-    BYTE                byCount;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byMode;
+    unsigned char byChannel;
+    unsigned char byCount;
 } WLAN_IE_CH_SW, *PWLAN_IE_CH_SW;
 
 typedef struct _WLAN_IE_QUIET {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                byQuietCount;
-    BYTE                byQuietPeriod;
-    BYTE                abyQuietDuration[2];
-    BYTE                abyQuietOffset[2];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byQuietCount;
+    unsigned char byQuietPeriod;
+    unsigned char abyQuietDuration[2];
+    unsigned char abyQuietOffset[2];
 } WLAN_IE_QUIET, *PWLAN_IE_QUIET;
 
 typedef struct _WLAN_IE_COUNTRY {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                abyCountryString[3];
-    BYTE                abyCountryInfo[3];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char abyCountryString[3];
+    unsigned char abyCountryInfo[3];
 } WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY;
 
 typedef struct _WLAN_IE_PW_CONST {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                byPower;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byPower;
 } WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST;
 
 typedef struct _WLAN_IE_PW_CAP {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                byMinPower;
-    BYTE                byMaxPower;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byMinPower;
+    unsigned char byMaxPower;
 } WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP;
 
 typedef struct _WLAN_IE_SUPP_CH {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                abyChannelTuple[2];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char abyChannelTuple[2];
 } WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH;
 
 typedef struct _WLAN_IE_TPC_REQ {
-    BYTE                byElementID;
-    BYTE                len;
+    unsigned char byElementID;
+    unsigned char len;
 } WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ;
 
 typedef struct _WLAN_IE_TPC_REP {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                byTxPower;
-    BYTE                byLinkMargin;
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char byTxPower;
+    unsigned char byLinkMargin;
 } WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP;
 
 
 typedef struct _WLAN_IE_IBSS_DFS {
-    BYTE                byElementID;
-    BYTE                len;
-    BYTE                abyDFSOwner[6];
-    BYTE                byDFSRecovery;
-    BYTE                abyChannelMap[2];
+    unsigned char byElementID;
+    unsigned char len;
+    unsigned char abyDFSOwner[6];
+    unsigned char byDFSRecovery;
+    unsigned char abyChannelMap[2];
 } WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS;
 
 #pragma pack()
@@ -495,9 +495,9 @@ typedef struct _WLAN_IE_IBSS_DFS {
 // prototype structure, all mgmt frame types will start with these members
 typedef struct tagWLAN_FR_MGMT {
 
-    UINT                  uType;
-    UINT                  len;
-    PBYTE                 pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR       pHdr;
 
 } WLAN_FR_MGMT,  *PWLAN_FR_MGMT;
@@ -505,14 +505,14 @@ typedef struct tagWLAN_FR_MGMT {
 // Beacon frame
 typedef struct tagWLAN_FR_BEACON {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     // fixed fields
     PQWORD                  pqwTimestamp;
-    PWORD                   pwBeaconInterval;
-    PWORD                   pwCapInfo;
+    unsigned short *pwBeaconInterval;
+    unsigned short *pwCapInfo;
     /*-- info elements ----------*/
     PWLAN_IE_SSID           pSSID;
     PWLAN_IE_SUPP_RATES     pSuppRates;
@@ -537,9 +537,9 @@ typedef struct tagWLAN_FR_BEACON {
 // IBSS ATIM frame
 typedef struct tagWLAN_FR_IBSSATIM {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
 
     // fixed fields
@@ -551,12 +551,12 @@ typedef struct tagWLAN_FR_IBSSATIM {
 // Disassociation
 typedef struct tagWLAN_FR_DISASSOC {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
-    PWORD                   pwReason;
+    unsigned short *pwReason;
     /*-- info elements ----------*/
 
 } WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC;
@@ -564,13 +564,13 @@ typedef struct tagWLAN_FR_DISASSOC {
 // Association Request
 typedef struct tagWLAN_FR_ASSOCREQ {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
-    PWORD                   pwCapInfo;
-    PWORD                   pwListenInterval;
+    unsigned short *pwCapInfo;
+    unsigned short *pwListenInterval;
     /*-- info elements ----------*/
     PWLAN_IE_SSID           pSSID;
     PWLAN_IE_SUPP_RATES     pSuppRates;
@@ -585,14 +585,14 @@ typedef struct tagWLAN_FR_ASSOCREQ {
 // Association Response
 typedef struct tagWLAN_FR_ASSOCRESP {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
-    PWORD                   pwCapInfo;
-    PWORD                   pwStatus;
-    PWORD                   pwAid;
+    unsigned short *pwCapInfo;
+    unsigned short *pwStatus;
+    unsigned short *pwAid;
     /*-- info elements ----------*/
     PWLAN_IE_SUPP_RATES     pSuppRates;
     PWLAN_IE_SUPP_RATES     pExtSuppRates;
@@ -602,14 +602,14 @@ typedef struct tagWLAN_FR_ASSOCRESP {
 // Reassociation Request
 typedef struct tagWLAN_FR_REASSOCREQ {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
 
     /*-- fixed fields -----------*/
-    PWORD                   pwCapInfo;
-    PWORD                   pwListenInterval;
+    unsigned short *pwCapInfo;
+    unsigned short *pwListenInterval;
     PIEEE_ADDR              pAddrCurrAP;
 
     /*-- info elements ----------*/
@@ -624,14 +624,14 @@ typedef struct tagWLAN_FR_REASSOCREQ {
 // Reassociation Response
 typedef struct tagWLAN_FR_REASSOCRESP {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
-    PWORD                   pwCapInfo;
-    PWORD                   pwStatus;
-    PWORD                   pwAid;
+    unsigned short *pwCapInfo;
+    unsigned short *pwStatus;
+    unsigned short *pwAid;
     /*-- info elements ----------*/
     PWLAN_IE_SUPP_RATES     pSuppRates;
     PWLAN_IE_SUPP_RATES     pExtSuppRates;
@@ -641,9 +641,9 @@ typedef struct tagWLAN_FR_REASSOCRESP {
 // Probe Request
 typedef struct tagWLAN_FR_PROBEREQ {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
     /*-- info elements ----------*/
@@ -656,14 +656,14 @@ typedef struct tagWLAN_FR_PROBEREQ {
 // Probe Response
 typedef struct tagWLAN_FR_PROBERESP {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
     PQWORD                  pqwTimestamp;
-    PWORD                   pwBeaconInterval;
-    PWORD                   pwCapInfo;
+    unsigned short *pwBeaconInterval;
+    unsigned short *pwCapInfo;
     /*-- info elements ----------*/
     PWLAN_IE_SSID           pSSID;
     PWLAN_IE_SUPP_RATES     pSuppRates;
@@ -685,14 +685,14 @@ typedef struct tagWLAN_FR_PROBERESP {
 // Authentication
 typedef struct tagWLAN_FR_AUTHEN {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
-    PWORD                   pwAuthAlgorithm;
-    PWORD                   pwAuthSequence;
-    PWORD                   pwStatus;
+    unsigned short *pwAuthAlgorithm;
+    unsigned short *pwAuthSequence;
+    unsigned short *pwStatus;
     /*-- info elements ----------*/
     PWLAN_IE_CHALLENGE      pChallenge;
 
@@ -701,12 +701,12 @@ typedef struct tagWLAN_FR_AUTHEN {
 // Deauthenication
 typedef struct tagWLAN_FR_DEAUTHEN {
 
-    UINT                    uType;
-    UINT                    len;
-    PBYTE                   pBuf;
+    unsigned int       uType;
+    unsigned int       len;
+    unsigned char *pBuf;
     PUWLAN_80211HDR         pHdr;
     /*-- fixed fields -----------*/
-    PWORD                   pwReason;
+    unsigned short *pwReason;
 
     /*-- info elements ----------*/
 
index 22f12f5ef90cec123143c92333bf84e5c5b96515..e07ebd578d449e17ed5b79e6f9c7722239e4ea6b 100644 (file)
@@ -38,6 +38,7 @@
 #include "device.h"
 #include "wmgr.h"
 #include "rxtx.h"
+#include "channel.h"
 
 /*---------------------  Static Definitions -------------------------*/
 static int          msglevel                =MSG_LEVEL_INFO;
@@ -46,40 +47,40 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 typedef struct _WLAN_FRAME_ACTION {
     WLAN_80211HDR_A3    Header;
-    BYTE                byCategory;
-    BYTE                byAction;
-    BYTE                abyVars[1];
+    unsigned char byCategory;
+    unsigned char byAction;
+    unsigned char abyVars[1];
 } WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION;
 
 typedef struct _WLAN_FRAME_MSRREQ {
     WLAN_80211HDR_A3    Header;
-    BYTE                byCategory;
-    BYTE                byAction;
-    BYTE                byDialogToken;
+    unsigned char byCategory;
+    unsigned char byAction;
+    unsigned char byDialogToken;
     WLAN_IE_MEASURE_REQ sMSRReqEIDs[1];
 } WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ;
 
 typedef struct _WLAN_FRAME_MSRREP {
     WLAN_80211HDR_A3    Header;
-    BYTE                byCategory;
-    BYTE                byAction;
-    BYTE                byDialogToken;
+    unsigned char byCategory;
+    unsigned char byAction;
+    unsigned char byDialogToken;
     WLAN_IE_MEASURE_REP sMSRRepEIDs[1];
 } WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP;
 
 typedef struct _WLAN_FRAME_TPCREQ {
     WLAN_80211HDR_A3    Header;
-    BYTE                byCategory;
-    BYTE                byAction;
-    BYTE                byDialogToken;
+    unsigned char byCategory;
+    unsigned char byAction;
+    unsigned char byDialogToken;
     WLAN_IE_TPC_REQ     sTPCReqEIDs;
 } WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ;
 
 typedef struct _WLAN_FRAME_TPCREP {
     WLAN_80211HDR_A3    Header;
-    BYTE                byCategory;
-    BYTE                byAction;
-    BYTE                byDialogToken;
+    unsigned char byCategory;
+    unsigned char byAction;
+    unsigned char byDialogToken;
     WLAN_IE_TPC_REP     sTPCRepEIDs;
 } WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP;
 
@@ -97,10 +98,11 @@ typedef struct _WLAN_FRAME_TPCREP {
 /*---------------------  Static Variables  --------------------------*/
 
 /*---------------------  Static Functions  --------------------------*/
-static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength)
+static bool s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq,
+               unsigned int uLength)
 {
     size_t    uNumOfEIDs = 0;
-    BOOL    bResult = TRUE;
+    bool bResult = true;
 
     if (uLength <= WLAN_A3FR_MAXLEN) {
         memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
@@ -116,7 +118,7 @@ static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLe
 }
 
 
-static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byRate, BYTE byRSSI)
+static bool s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, unsigned char byRate, unsigned char byRSSI)
 {
     PWLAN_FRAME_TPCREP  pFrame;
     PSTxMgmtPacket      pTxPacket = NULL;
@@ -124,9 +126,9 @@ static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byR
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
 
-    pFrame = (PWLAN_FRAME_TPCREP)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
 
     pFrame->Header.wFrameCtl = (   WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
                                     WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
@@ -174,8 +176,8 @@ static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byR
     pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
     pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN;
     if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
-        return (FALSE);
-    return (TRUE);
+        return (false);
+    return (true);
 //    return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP)));
 
 }
@@ -201,7 +203,7 @@ static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byR
  * Return Value: None.
  *
 -*/
-BOOL
+bool
 IEEE11hbMgrRxAction (
     void *pMgmtHandle,
     void *pRxPacket
@@ -209,14 +211,14 @@ IEEE11hbMgrRxAction (
 {
     PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
     PWLAN_FRAME_ACTION      pAction = NULL;
-    UINT                    uLength = 0;
+    unsigned int uLength = 0;
     PWLAN_IE_CH_SW          pChannelSwitch = NULL;
 
 
     // decode the frame
     uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
     if (uLength > WLAN_A3FR_MAXLEN) {
-        return (FALSE);
+        return (false);
     }
 
 
@@ -233,7 +235,7 @@ IEEE11hbMgrRxAction (
                 return (s_bRxTPCReq(pMgmt,
                                     (PWLAN_FRAME_TPCREQ) pAction,
                                     ((PSRxMgmtPacket)pRxPacket)->byRxRate,
-                                    (BYTE) ((PSRxMgmtPacket)pRxPacket)->uRSSI));
+                                    (unsigned char) ((PSRxMgmtPacket)pRxPacket)->uRSSI));
                 break;
             case ACTION_TPCREP:
                 break;
@@ -244,7 +246,7 @@ IEEE11hbMgrRxAction (
                     // valid element id
                     CARDbChannelSwitch( pMgmt->pAdapter,
                                         pChannelSwitch->byMode,
-                                        CARDbyGetChannelMapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode),
+                                        get_channel_mapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode),
                                         pChannelSwitch->byCount
                                         );
                 }
@@ -258,13 +260,13 @@ IEEE11hbMgrRxAction (
         pAction->byCategory |= 0x80;
 
        //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength));
-        return (TRUE);
+        return (true);
     }
-    return (TRUE);
+    return (true);
 }
 
 
-BOOL IEEE11hbMSRRepTx (
+bool IEEE11hbMSRRepTx (
     void *pMgmtHandle
     )
 {
@@ -275,7 +277,7 @@ BOOL IEEE11hbMSRRepTx (
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
 
 
     pMSRRep->Header.wFrameCtl = (   WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
@@ -295,8 +297,8 @@ BOOL IEEE11hbMSRRepTx (
     pTxPacket->cbMPDULen = uLength;
     pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
     if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
-        return (FALSE);
-    return (TRUE);
+        return (false);
+    return (true);
 //    return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength));
 
 }
index ae32498a511de892165ad8b5dcffa4be5aeca1b8..542340b96e3868b25d42c30f473a7850eb904dee 100644 (file)
@@ -45,7 +45,7 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL IEEE11hbMSRRepTx (
+bool IEEE11hbMSRRepTx (
     void *pMgmtHandle
     );
 
index 931deb109ee87082dc9c0bdc7c020035d24c5f99..824c97187872e9cab4c2804306f7480a444c0635 100644 (file)
@@ -4,6 +4,7 @@ EXTRA_CFLAGS += -DHOSTAP
 
 vt6655_stage-y +=      device_main.o \
        card.o \
+       channel.o \
        mac.o \
        baseband.o \
        wctl.o \
index cb04aaafc46f1810e111a356c11823bb53ffcd8e..63607ef9c97e55418a4d65b6dc66fe6e50e43f9a 100644 (file)
@@ -3,7 +3,6 @@ TODO:
 - prepare for merge with vt6656 driver:
   - rename DEVICE_PRT() to DBG_PRT() -- done
   - share 80211*.h includes
-  - move code for channel mapping from card.c to channel.c
   - split rf.c
   - remove dead code
   - abstract VT3253 chipset specific code
@@ -11,6 +10,8 @@ TODO:
 - kill ttype.h
 - switch to use LIB80211
 - switch to use MAC80211
+- verify unsigned long usage for x86-64 arch
+- reduce .data footprint
 - use kernel coding style
 - checkpatch.pl fixes
 - sparse fixes
index fef1b91c2925bf632b2403cccc543c387926f613..e30168f2da2f58a02f72dd46343fb54b86f1f285 100644 (file)
@@ -46,7 +46,7 @@
  * SBOX Table
  */
 
-BYTE sbox_table[256] =
+unsigned char sbox_table[256] =
 {
 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
@@ -66,7 +66,7 @@ BYTE sbox_table[256] =
 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
 };
 
-BYTE dot2_table[256] = {
+unsigned char dot2_table[256] = {
 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
@@ -85,7 +85,7 @@ BYTE dot2_table[256] = {
 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
 };
 
-BYTE dot3_table[256] = {
+unsigned char dot3_table[256] = {
 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
@@ -110,11 +110,11 @@ BYTE dot3_table[256] = {
 
 /*---------------------  Export Functions  --------------------------*/
 
-void xor_128(BYTE *a, BYTE *b, BYTE *out)
+void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
 {
-PDWORD dwPtrA = (PDWORD) a;
-PDWORD dwPtrB = (PDWORD) b;
-PDWORD dwPtrOut =(PDWORD) out;
+unsigned long *dwPtrA = (unsigned long *) a;
+unsigned long *dwPtrB = (unsigned long *) b;
+unsigned long *dwPtrOut =(unsigned long *) out;
 
     (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
     (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
@@ -123,19 +123,19 @@ PDWORD dwPtrOut =(PDWORD) out;
 }
 
 
-void xor_32(BYTE *a, BYTE *b, BYTE *out)
+void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
 {
-PDWORD dwPtrA = (PDWORD) a;
-PDWORD dwPtrB = (PDWORD) b;
-PDWORD dwPtrOut =(PDWORD) out;
+unsigned long *dwPtrA = (unsigned long *) a;
+unsigned long *dwPtrB = (unsigned long *) b;
+unsigned long *dwPtrOut =(unsigned long *) out;
 
     (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
 }
 
-void AddRoundKey(BYTE *key, int round)
+void AddRoundKey(unsigned char *key, int round)
 {
-BYTE sbox_key[4];
-BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
+unsigned char sbox_key[4];
+unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
 
     sbox_key[0] = sbox_table[key[13]];
     sbox_key[1] = sbox_table[key[14]];
@@ -150,7 +150,7 @@ BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x
     xor_32(&key[12], &key[8], &key[12]);
 }
 
-void SubBytes(BYTE *in, BYTE *out)
+void SubBytes(unsigned char *in, unsigned char *out)
 {
 int i;
 
@@ -160,7 +160,7 @@ int i;
     }
 }
 
-void ShiftRows(BYTE *in, BYTE *out)
+void ShiftRows(unsigned char *in, unsigned char *out)
 {
     out[0]  = in[0];
     out[1]  = in[5];
@@ -180,7 +180,7 @@ void ShiftRows(BYTE *in, BYTE *out)
     out[15] = in[11];
 }
 
-void MixColumns(BYTE *in, BYTE *out)
+void MixColumns(unsigned char *in, unsigned char *out)
 {
 
     out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
@@ -190,13 +190,13 @@ void MixColumns(BYTE *in, BYTE *out)
 }
 
 
-void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext)
+void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
 {
 int  i;
 int  round;
-BYTE TmpdataA[16];
-BYTE TmpdataB[16];
-BYTE abyRoundKey[16];
+unsigned char TmpdataA[16];
+unsigned char TmpdataB[16];
+unsigned char abyRoundKey[16];
 
     for(i=0; i<16; i++)
         abyRoundKey[i] = key[i];
@@ -243,33 +243,33 @@ BYTE abyRoundKey[16];
  * Return Value: MIC compare result
  *
  */
-BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize)
+bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize)
 {
-BYTE            abyNonce[13];
-BYTE            MIC_IV[16];
-BYTE            MIC_HDR1[16];
-BYTE            MIC_HDR2[16];
-BYTE            abyMIC[16];
-BYTE            abyCTRPLD[16];
-BYTE            abyTmp[16];
-BYTE            abyPlainText[16];
-BYTE            abyLastCipher[16];
+unsigned char abyNonce[13];
+unsigned char MIC_IV[16];
+unsigned char MIC_HDR1[16];
+unsigned char MIC_HDR2[16];
+unsigned char abyMIC[16];
+unsigned char abyCTRPLD[16];
+unsigned char abyTmp[16];
+unsigned char abyPlainText[16];
+unsigned char abyLastCipher[16];
 
 PS802_11Header  pMACHeader = (PS802_11Header) pbyFrame;
-PBYTE           pbyIV;
-PBYTE           pbyPayload;
-WORD            wHLen = 22;
-WORD            wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC
-BOOL            bA4 = FALSE;
-BYTE            byTmp;
-WORD            wCnt;
+unsigned char *pbyIV;
+unsigned char *pbyPayload;
+unsigned short wHLen = 22;
+unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC
+bool bA4 = false;
+unsigned char byTmp;
+unsigned short wCnt;
 int             ii,jj,kk;
 
 
     pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
-    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
-         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
-         bA4 = TRUE;
+    if ( WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame) ) {
+         bA4 = true;
          pbyIV += 6;             // 6 is 802.11 address4
          wHLen += 6;
          wPayloadSize -= 6;
@@ -288,15 +288,15 @@ int             ii,jj,kk;
     //MIC_IV
     MIC_IV[0] = 0x59;
     memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
-    MIC_IV[14] = (BYTE)(wPayloadSize >> 8);
-    MIC_IV[15] = (BYTE)(wPayloadSize & 0xff);
+    MIC_IV[14] = (unsigned char)(wPayloadSize >> 8);
+    MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff);
 
     //MIC_HDR1
-    MIC_HDR1[0] = (BYTE)(wHLen >> 8);
-    MIC_HDR1[1] = (BYTE)(wHLen & 0xff);
-    byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff);
+    MIC_HDR1[0] = (unsigned char)(wHLen >> 8);
+    MIC_HDR1[1] = (unsigned char)(wHLen & 0xff);
+    byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff);
     MIC_HDR1[2] = byTmp & 0x8f;
-    byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8);
+    byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8);
     byTmp &= 0x87;
     MIC_HDR1[3] = byTmp | 0x40;
     memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN);
@@ -304,7 +304,7 @@ int             ii,jj,kk;
 
     //MIC_HDR2
     memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN);
-    byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff);
+    byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff);
     MIC_HDR2[6] = byTmp & 0x0f;
     MIC_HDR2[7] = 0;
     if ( bA4 ) {
@@ -337,8 +337,8 @@ int             ii,jj,kk;
 
     for(jj=wPayloadSize; jj>16; jj=jj-16) {
 
-        abyCTRPLD[14] = (BYTE) (wCnt >> 8);
-        abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+        abyCTRPLD[14] = (unsigned char) (wCnt >> 8);
+        abyCTRPLD[15] = (unsigned char) (wCnt & 0xff);
 
         AESv128(pbyRxKey,abyCTRPLD,abyTmp);
 
@@ -361,8 +361,8 @@ int             ii,jj,kk;
         abyLastCipher[ii] = 0x00;
     }
 
-    abyCTRPLD[14] = (BYTE) (wCnt >> 8);
-    abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+    abyCTRPLD[14] = (unsigned char) (wCnt >> 8);
+    abyCTRPLD[15] = (unsigned char) (wCnt & 0xff);
 
     AESv128(pbyRxKey,abyCTRPLD,abyTmp);
     for ( kk=0; kk<16; kk++ ) {
@@ -384,8 +384,8 @@ int             ii,jj,kk;
     //--------------------------------------------
 
     wCnt = 0;
-    abyCTRPLD[14] = (BYTE) (wCnt >> 8);
-    abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+    abyCTRPLD[14] = (unsigned char) (wCnt >> 8);
+    abyCTRPLD[15] = (unsigned char) (wCnt & 0xff);
     AESv128(pbyRxKey,abyCTRPLD,abyTmp);
     for ( kk=0; kk<8; kk++ ) {
         abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
@@ -394,9 +394,9 @@ int             ii,jj,kk;
     //--------------------------------------------
 
     if ( !memcmp(abyMIC,abyTmp,8) ) {
-        return TRUE;
+        return true;
     } else {
-        return FALSE;
+        return false;
     }
 
 }
index f2ba1d5aa1e56e2bf4d74e492547c6b580a88f31..c8b28b0e9bdcc3740f2ce241eb97bee21876d8f3 100644 (file)
@@ -41,6 +41,6 @@
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize);
+bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize);
 
 #endif //__AES_H__
index 5414c6c6c0509e194e50a784a5f91641ac1a182c..1e1c6e34f786bd72c63759c1b9304905deb71849 100644 (file)
@@ -79,7 +79,7 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 
 #define CB_VT3253_INIT_FOR_RFMD 446
-BYTE byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = {
+unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = {
     {0x00, 0x30},
     {0x01, 0x00},
     {0x02, 0x00},
@@ -529,7 +529,7 @@ BYTE byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = {
 };
 
 #define CB_VT3253B0_INIT_FOR_RFMD 256
-BYTE byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = {
+unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = {
     {0x00, 0x31},
     {0x01, 0x00},
     {0x02, 0x00},
@@ -790,7 +790,7 @@ BYTE byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = {
 
 #define CB_VT3253B0_AGC_FOR_RFMD2959 195
 // For RFMD2959
-BYTE byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
+unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
     {0xF0, 0x00},
     {0xF1, 0x3E},
     {0xF0, 0x80},
@@ -990,7 +990,7 @@ BYTE byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
 
 #define CB_VT3253B0_INIT_FOR_AIROHA2230 256
 // For AIROHA
-BYTE byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
+unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
     {0x00, 0x31},
     {0x01, 0x00},
     {0x02, 0x00},
@@ -1254,7 +1254,7 @@ BYTE byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
 
 #define CB_VT3253B0_INIT_FOR_UW2451 256
 //For UW2451
-BYTE byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
+unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
     {0x00, 0x31},
     {0x01, 0x00},
     {0x02, 0x00},
@@ -1516,7 +1516,7 @@ BYTE byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
 
 #define CB_VT3253B0_AGC 193
 // For AIROHA
-BYTE byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
+unsigned char byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
     {0xF0, 0x00},
     {0xF1, 0x00},
     {0xF0, 0x80},
@@ -1712,14 +1712,14 @@ BYTE byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
     {0xF0, 0x00},
 };
 
-const WORD awcFrameTime[MAX_RATE] =
+const unsigned short awcFrameTime[MAX_RATE] =
 {10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
 
 
 /*---------------------  Static Functions  --------------------------*/
 
 static
-ULONG
+unsigned long
 s_ulGetRatio(PSDevice pDevice);
 
 static
@@ -1740,13 +1740,13 @@ s_vChangeAntenna (
 #endif
     if ( pDevice->dwRxAntennaSel == 0) {
         pDevice->dwRxAntennaSel=1;
-        if (pDevice->bTxRxAntInv == TRUE)
+        if (pDevice->bTxRxAntInv == true)
             BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A);
         else
             BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B);
     } else {
         pDevice->dwRxAntennaSel=0;
-        if (pDevice->bTxRxAntInv == TRUE)
+        if (pDevice->bTxRxAntInv == true)
             BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B);
         else
             BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A);
@@ -1776,19 +1776,19 @@ s_vChangeAntenna (
  * Return Value: FrameTime
  *
  */
-UINT
+unsigned int
 BBuGetFrameTime (
-    BYTE byPreambleType,
-    BYTE byPktType,
-    UINT cbFrameLength,
-    WORD wRate
+    unsigned char byPreambleType,
+    unsigned char byPktType,
+    unsigned int cbFrameLength,
+    unsigned short wRate
     )
 {
-    UINT uFrameTime;
-    UINT uPreamble;
-    UINT uTmp;
-    UINT uRateIdx = (UINT)wRate;
-    UINT uRate = 0;
+    unsigned int uFrameTime;
+    unsigned int uPreamble;
+    unsigned int uTmp;
+    unsigned int uRateIdx = (unsigned int) wRate;
+    unsigned int uRate = 0;
 
 
     if (uRateIdx > RATE_54M) {
@@ -1796,7 +1796,7 @@ BBuGetFrameTime (
         return 0;
     }
 
-    uRate = (UINT)awcFrameTime[uRateIdx];
+    uRate = (unsigned int) awcFrameTime[uRateIdx];
 
     if (uRateIdx <= 3) {          //CCK mode
 
@@ -1846,23 +1846,23 @@ BBuGetFrameTime (
 void
 BBvCaculateParameter (
     PSDevice pDevice,
-    UINT cbFrameLength,
-    WORD wRate,
-    BYTE byPacketType,
-    PWORD pwPhyLen,
-    PBYTE pbyPhySrv,
-    PBYTE pbyPhySgn
+    unsigned int cbFrameLength,
+    unsigned short wRate,
+    unsigned char byPacketType,
+    unsigned short *pwPhyLen,
+    unsigned char *pbyPhySrv,
+    unsigned char *pbyPhySgn
     )
 {
-    UINT cbBitCount;
-    UINT cbUsCount = 0;
-    UINT cbTmp;
-    BOOL bExtBit;
-    BYTE byPreambleType = pDevice->byPreambleType;
-    BOOL bCCK = pDevice->bCCK;
+    unsigned int cbBitCount;
+    unsigned int cbUsCount = 0;
+    unsigned int cbTmp;
+    bool bExtBit;
+    unsigned char byPreambleType = pDevice->byPreambleType;
+    bool bCCK = pDevice->bCCK;
 
     cbBitCount = cbFrameLength * 8;
-    bExtBit = FALSE;
+    bExtBit = false;
 
     switch (wRate) {
     case RATE_1M :
@@ -1879,7 +1879,7 @@ BBvCaculateParameter (
         break;
 
     case RATE_5M :
-        if (bCCK == FALSE)
+        if (bCCK == false)
             cbBitCount ++;
         cbUsCount = (cbBitCount * 10) / 55;
         cbTmp = (cbUsCount * 55) / 10;
@@ -1893,14 +1893,14 @@ BBvCaculateParameter (
 
     case RATE_11M :
 
-        if (bCCK == FALSE)
+        if (bCCK == false)
             cbBitCount ++;
         cbUsCount = cbBitCount / 11;
         cbTmp = cbUsCount * 11;
         if (cbTmp != cbBitCount) {
             cbUsCount ++;
             if ((cbBitCount - cbTmp) <= 3)
-                bExtBit = TRUE;
+                bExtBit = true;
         }
         if (byPreambleType == 1)
             *pbyPhySgn = 0x0b;
@@ -1994,11 +1994,11 @@ BBvCaculateParameter (
         *pbyPhySrv = 0x00;
         if (bExtBit)
             *pbyPhySrv = *pbyPhySrv | 0x80;
-        *pwPhyLen = (WORD)cbUsCount;
+        *pwPhyLen = (unsigned short)cbUsCount;
     }
     else {
         *pbyPhySrv = 0x00;
-        *pwPhyLen = (WORD)cbFrameLength;
+        *pwPhyLen = (unsigned short)cbFrameLength;
     }
 }
 
@@ -2012,13 +2012,13 @@ BBvCaculateParameter (
  *  Out:
  *      pbyData     - data read
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL BBbReadEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData)
+bool BBbReadEmbeded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData)
 {
-    WORD    ww;
-    BYTE    byValue;
+    unsigned short ww;
+    unsigned char byValue;
 
     // BB reg offset
     VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr);
@@ -2038,9 +2038,9 @@ BOOL BBbReadEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x30);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x30)\n");
-        return FALSE;
+        return false;
     }
-    return TRUE;
+    return true;
 }
 
 
@@ -2055,13 +2055,13 @@ BOOL BBbReadEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL BBbWriteEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData)
+bool BBbWriteEmbeded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData)
 {
-    WORD    ww;
-    BYTE    byValue;
+    unsigned short ww;
+    unsigned char byValue;
 
     // BB reg offset
     VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr);
@@ -2080,9 +2080,9 @@ BOOL BBbWriteEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x31);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x31)\n");
-        return FALSE;
+        return false;
     }
-    return TRUE;
+    return true;
 }
 
 
@@ -2097,12 +2097,12 @@ BOOL BBbWriteEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all TestBits are set; FALSE otherwise.
+ * Return Value: true if all TestBits are set; false otherwise.
  *
  */
-BOOL BBbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
+bool BBbIsRegBitsOn (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits)
 {
-    BYTE byOrgData;
+    unsigned char byOrgData;
 
     BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData);
     return (byOrgData & byTestBits) == byTestBits;
@@ -2120,12 +2120,12 @@ BOOL BBbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all TestBits are clear; FALSE otherwise.
+ * Return Value: true if all TestBits are clear; false otherwise.
  *
  */
-BOOL BBbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
+bool BBbIsRegBitsOff (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits)
 {
-    BYTE byOrgData;
+    unsigned char byOrgData;
 
     BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData);
     return (byOrgData & byTestBits) == 0;
@@ -2142,17 +2142,17 @@ BOOL BBbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
-BOOL BBbVT3253Init (PSDevice pDevice)
+bool BBbVT3253Init (PSDevice pDevice)
 {
-    BOOL       bResult = TRUE;
+    bool bResult = true;
     int        ii;
-    DWORD_PTR  dwIoBase = pDevice->PortOffset;
-    BYTE       byRFType = pDevice->byRFType;
-    BYTE       byLocalID = pDevice->byLocalID;
+    unsigned long dwIoBase = pDevice->PortOffset;
+    unsigned char byRFType = pDevice->byRFType;
+    unsigned char byLocalID = pDevice->byLocalID;
 
     if (byRFType == RF_RFMD2959) {
         if (byLocalID <= REV_ID_VT3253_A1) {
@@ -2294,7 +2294,7 @@ BOOL BBbVT3253Init (PSDevice pDevice)
     //}} RobertYu
     } else {
        // No VGA Table now
-       pDevice->bUpdateBBVGA = FALSE;
+       pDevice->bUpdateBBVGA = false;
         pDevice->abyBBVGA[0] = 0x1C;
     }
 
@@ -2321,12 +2321,12 @@ BOOL BBbVT3253Init (PSDevice pDevice)
  * Return Value: none
  *
  */
-void BBvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyBBRegs)
+void BBvReadAllRegs (unsigned long dwIoBase, unsigned char *pbyBBRegs)
 {
     int  ii;
-    BYTE byBase = 1;
+    unsigned char byBase = 1;
     for (ii = 0; ii < BB_MAX_CONTEXT_SIZE; ii++) {
-        BBbReadEmbeded(dwIoBase, (BYTE)(ii*byBase), pbyBBRegs);
+        BBbReadEmbeded(dwIoBase, (unsigned char)(ii*byBase), pbyBBRegs);
         pbyBBRegs += byBase;
     }
 }
@@ -2348,8 +2348,8 @@ void BBvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyBBRegs)
 
 void BBvLoopbackOn (PSDevice pDevice)
 {
-    BYTE      byData;
-    DWORD_PTR dwIoBase = pDevice->PortOffset;
+    unsigned char byData;
+    unsigned long dwIoBase = pDevice->PortOffset;
 
     //CR C9 = 0x00
     BBbReadEmbeded(dwIoBase, 0xC9, &pDevice->byBBCRc9);//CR201
@@ -2363,7 +2363,7 @@ void BBvLoopbackOn (PSDevice pDevice)
     if (pDevice->uConnectionRate <= RATE_11M) { //CCK
         // Enable internal digital loopback: CR33 |= 0000 0001
         BBbReadEmbeded(dwIoBase, 0x21, &byData);//CR33
-        BBbWriteEmbeded(dwIoBase, 0x21, (BYTE)(byData | 0x01));//CR33
+        BBbWriteEmbeded(dwIoBase, 0x21, (unsigned char)(byData | 0x01));//CR33
         // CR154 = 0x00
         BBbWriteEmbeded(dwIoBase, 0x9A, 0);   //CR154
 
@@ -2372,7 +2372,7 @@ void BBvLoopbackOn (PSDevice pDevice)
     else { //OFDM
         // Enable internal digital loopback:CR154 |= 0000 0001
         BBbReadEmbeded(dwIoBase, 0x9A, &byData);//CR154
-        BBbWriteEmbeded(dwIoBase, 0x9A, (BYTE)(byData | 0x01));//CR154
+        BBbWriteEmbeded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01));//CR154
         // CR33 = 0x00
         BBbWriteEmbeded(dwIoBase, 0x21, 0);   //CR33
 
@@ -2384,7 +2384,7 @@ void BBvLoopbackOn (PSDevice pDevice)
 
     // Disable TX_IQUN
     BBbReadEmbeded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09);
-    BBbWriteEmbeded(pDevice->PortOffset, 0x09, (BYTE)(pDevice->byBBCR09 & 0xDE));
+    BBbWriteEmbeded(pDevice->PortOffset, 0x09, (unsigned char)(pDevice->byBBCR09 & 0xDE));
 }
 
 /*
@@ -2402,8 +2402,8 @@ void BBvLoopbackOn (PSDevice pDevice)
  */
 void BBvLoopbackOff (PSDevice pDevice)
 {
-    BYTE      byData;
-    DWORD_PTR dwIoBase = pDevice->PortOffset;
+    unsigned char byData;
+    unsigned long dwIoBase = pDevice->PortOffset;
 
     BBbWriteEmbeded(dwIoBase, 0xC9, pDevice->byBBCRc9);//CR201
     BBbWriteEmbeded(dwIoBase, 0x88, pDevice->byBBCR88);//CR136
@@ -2413,14 +2413,14 @@ void BBvLoopbackOff (PSDevice pDevice)
     if (pDevice->uConnectionRate <= RATE_11M) { // CCK
         // Set the CR33 Bit2 to disable internal Loopback.
         BBbReadEmbeded(dwIoBase, 0x21, &byData);//CR33
-        BBbWriteEmbeded(dwIoBase, 0x21, (BYTE)(byData & 0xFE));//CR33
+        BBbWriteEmbeded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE));//CR33
     }
     else { // OFDM
         BBbReadEmbeded(dwIoBase, 0x9A, &byData);//CR154
-        BBbWriteEmbeded(dwIoBase, 0x9A, (BYTE)(byData & 0xFE));//CR154
+        BBbWriteEmbeded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE));//CR154
     }
     BBbReadEmbeded(dwIoBase, 0x0E, &byData);//CR14
-    BBbWriteEmbeded(dwIoBase, 0x0E, (BYTE)(byData | 0x80));//CR14
+    BBbWriteEmbeded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80));//CR14
 
 }
 
@@ -2441,8 +2441,8 @@ void BBvLoopbackOff (PSDevice pDevice)
 void
 BBvSetShortSlotTime (PSDevice pDevice)
 {
-    BYTE byBBRxConf=0;
-    BYTE byBBVGA=0;
+    unsigned char byBBRxConf=0;
+    unsigned char byBBVGA=0;
 
     BBbReadEmbeded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10
 
@@ -2462,9 +2462,9 @@ BBvSetShortSlotTime (PSDevice pDevice)
 
 }
 
-void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData)
+void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData)
 {
-    BYTE byBBRxConf=0;
+    unsigned char byBBRxConf=0;
 
     BBbWriteEmbeded(pDevice->PortOffset, 0xE7, byData);
 
@@ -2495,7 +2495,7 @@ void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData)
  *
  */
 void
-BBvSoftwareReset (DWORD_PTR dwIoBase)
+BBvSoftwareReset (unsigned long dwIoBase)
 {
     BBbWriteEmbeded(dwIoBase, 0x50, 0x40);
     BBbWriteEmbeded(dwIoBase, 0x50, 0);
@@ -2516,9 +2516,9 @@ BBvSoftwareReset (DWORD_PTR dwIoBase)
  *
  */
 void
-BBvPowerSaveModeON (DWORD_PTR dwIoBase)
+BBvPowerSaveModeON (unsigned long dwIoBase)
 {
-    BYTE byOrgData;
+    unsigned char byOrgData;
 
     BBbReadEmbeded(dwIoBase, 0x0D, &byOrgData);
     byOrgData |= BIT0;
@@ -2538,9 +2538,9 @@ BBvPowerSaveModeON (DWORD_PTR dwIoBase)
  *
  */
 void
-BBvPowerSaveModeOFF (DWORD_PTR dwIoBase)
+BBvPowerSaveModeOFF (unsigned long dwIoBase)
 {
-    BYTE byOrgData;
+    unsigned char byOrgData;
 
     BBbReadEmbeded(dwIoBase, 0x0D, &byOrgData);
     byOrgData &= ~(BIT0);
@@ -2562,9 +2562,9 @@ BBvPowerSaveModeOFF (DWORD_PTR dwIoBase)
  */
 
 void
-BBvSetTxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode)
+BBvSetTxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode)
 {
-    BYTE byBBTxConf;
+    unsigned char byBBTxConf;
 
 #ifdef PLICE_DEBUG
        //printk("Enter BBvSetTxAntennaMode\n");
@@ -2604,9 +2604,9 @@ BBvSetTxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode)
  */
 
 void
-BBvSetRxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode)
+BBvSetRxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode)
 {
-    BYTE byBBRxConf;
+    unsigned char byBBRxConf;
 
     BBbReadEmbeded(dwIoBase, 0x0A, &byBBRxConf);//CR10
     if (byAntennaMode == ANT_DIVERSITY) {
@@ -2635,14 +2635,14 @@ BBvSetRxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode)
  *
  */
 void
-BBvSetDeepSleep (DWORD_PTR dwIoBase, BYTE byLocalID)
+BBvSetDeepSleep (unsigned long dwIoBase, unsigned char byLocalID)
 {
     BBbWriteEmbeded(dwIoBase, 0x0C, 0x17);//CR12
     BBbWriteEmbeded(dwIoBase, 0x0D, 0xB9);//CR13
 }
 
 void
-BBvExitDeepSleep (DWORD_PTR dwIoBase, BYTE byLocalID)
+BBvExitDeepSleep (unsigned long dwIoBase, unsigned char byLocalID)
 {
     BBbWriteEmbeded(dwIoBase, 0x0C, 0x00);//CR12
     BBbWriteEmbeded(dwIoBase, 0x0D, 0x01);//CR13
@@ -2651,12 +2651,12 @@ BBvExitDeepSleep (DWORD_PTR dwIoBase, BYTE byLocalID)
 
 
 static
-ULONG
+unsigned long
 s_ulGetRatio (PSDevice pDevice)
 {
-ULONG   ulRatio = 0;
-ULONG   ulMaxPacket;
-ULONG   ulPacketNum;
+unsigned long ulRatio = 0;
+unsigned long ulMaxPacket;
+unsigned long ulPacketNum;
 
     //This is a thousand-ratio
     ulMaxPacket = pDevice->uNumSQ3[RATE_54M];
@@ -2762,7 +2762,7 @@ ULONG   ulPacketNum;
 void
 BBvClearAntDivSQ3Value (PSDevice pDevice)
 {
-    UINT    ii;
+    unsigned int ii;
 
     pDevice->uDiversityCnt = 0;
     for (ii = 0; ii < MAX_RATE; ii++) {
@@ -2787,7 +2787,7 @@ BBvClearAntDivSQ3Value (PSDevice pDevice)
  */
 
 void
-BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3)
+BBvAntennaDiversity (PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ3)
 {
 
     if ((byRxRate >= MAX_RATE) || (pDevice->wAntDiversityMaxRate >= MAX_RATE)) {
index b236ff4139a05fba5c25c03d95243f32c2142b37..8294bdbb7b51c7b4ed518e288b299a6dd201f66f 100644 (file)
 
 /*---------------------  Export Functions  --------------------------*/
 
-UINT
+unsigned int
 BBuGetFrameTime(
-    BYTE byPreambleType,
-    BYTE byPktType,
-    UINT cbFrameLength,
-    WORD wRate
+    unsigned char byPreambleType,
+    unsigned char byPktType,
+    unsigned int cbFrameLength,
+    unsigned short wRate
     );
 
 void
 BBvCaculateParameter (
     PSDevice pDevice,
-    UINT cbFrameLength,
-    WORD wRate,
-    BYTE byPacketType,
-    PWORD pwPhyLen,
-    PBYTE pbyPhySrv,
-    PBYTE pbyPhySgn
+    unsigned int cbFrameLength,
+    unsigned short wRate,
+    unsigned char byPacketType,
+    unsigned short *pwPhyLen,
+    unsigned char *pbyPhySrv,
+    unsigned char *pbyPhySgn
     );
 
-BOOL BBbReadEmbeded(DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData);
-BOOL BBbWriteEmbeded(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData);
+bool BBbReadEmbeded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData);
+bool BBbWriteEmbeded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData);
 
-void BBvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyBBRegs);
+void BBvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyBBRegs);
 void BBvLoopbackOn(PSDevice pDevice);
 void BBvLoopbackOff(PSDevice pDevice);
 void BBvSetShortSlotTime(PSDevice pDevice);
-BOOL BBbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits);
-BOOL BBbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits);
-void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData);
+bool BBbIsRegBitsOn(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits);
+bool BBbIsRegBitsOff(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits);
+void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData);
 
 // VT3253 Baseband
-BOOL BBbVT3253Init(PSDevice pDevice);
-void BBvSoftwareReset(DWORD_PTR dwIoBase);
-void BBvPowerSaveModeON(DWORD_PTR dwIoBase);
-void BBvPowerSaveModeOFF(DWORD_PTR dwIoBase);
-void BBvSetTxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode);
-void BBvSetRxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode);
-void BBvSetDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID);
-void BBvExitDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID);
+bool BBbVT3253Init(PSDevice pDevice);
+void BBvSoftwareReset(unsigned long dwIoBase);
+void BBvPowerSaveModeON(unsigned long dwIoBase);
+void BBvPowerSaveModeOFF(unsigned long dwIoBase);
+void BBvSetTxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode);
+void BBvSetRxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode);
+void BBvSetDeepSleep(unsigned long dwIoBase, unsigned char byLocalID);
+void BBvExitDeepSleep(unsigned long dwIoBase, unsigned char byLocalID);
 
 // timer for antenna diversity
 
@@ -170,7 +170,7 @@ TimerState1CallBack(
     void *hDeviceContext
     );
 
-void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3);
+void BBvAntennaDiversity(PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ3);
 void
 BBvClearAntDivSQ3Value (PSDevice pDevice);
 
index 6312a55dab1a96d8ecebe9c82f25cf5761f9ad01..57c1cc90afcc1f809c63c62fb932a008016d4f97 100644 (file)
@@ -53,6 +53,7 @@
 #include "baseband.h"
 #include "rf.h"
 #include "card.h"
+#include "channel.h"
 #include "mac.h"
 #include "wpa2.h"
 #include "iowpa.h"
@@ -71,14 +72,14 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 
 
-const WORD             awHWRetry0[5][5] = {
+const unsigned short awHWRetry0[5][5] = {
                                             {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
                                             {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
                                             {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
                                             {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
                                             {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
                                            };
-const WORD             awHWRetry1[5][5] = {
+const unsigned short awHWRetry1[5][5] = {
                                             {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
                                             {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
                                             {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
@@ -126,25 +127,25 @@ void s_vCheckPreEDThreshold(
 PKnownBSS
 BSSpSearchBSSList(
     void *hDeviceContext,
-    PBYTE pbyDesireBSSID,
-    PBYTE pbyDesireSSID,
+    unsigned char *pbyDesireBSSID,
+    unsigned char *pbyDesireSSID,
     CARD_PHY_TYPE  ePhyType
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    PBYTE           pbyBSSID = NULL;
+    unsigned char *pbyBSSID = NULL;
     PWLAN_IE_SSID   pSSID = NULL;
     PKnownBSS       pCurrBSS = NULL;
     PKnownBSS       pSelect = NULL;
-BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
-    UINT            ii = 0;
-//    UINT            jj = 0;   //DavidWang
+    unsigned char ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
+    unsigned int ii = 0;
+
     if (pbyDesireBSSID != NULL) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n",
                             *pbyDesireBSSID,*(pbyDesireBSSID+1),*(pbyDesireBSSID+2),
                             *(pbyDesireBSSID+3),*(pbyDesireBSSID+4),*(pbyDesireBSSID+5));
-        if ((!IS_BROADCAST_ADDRESS(pbyDesireBSSID)) &&
+        if ((!is_broadcast_ether_addr(pbyDesireBSSID)) &&
             (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){
             pbyBSSID = pbyDesireBSSID;
         }
@@ -159,10 +160,10 @@ BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
         // match BSSID first
         for (ii = 0; ii <MAX_BSS_NUM; ii++) {
             pCurrBSS = &(pMgmt->sBSSList[ii]);
-if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
+if(pDevice->bLinkPass==false) pCurrBSS->bSelected = false;
             if ((pCurrBSS->bActive) &&
-                (pCurrBSS->bSelected == FALSE)) {
-                if (IS_ETH_ADDRESS_EQUAL(pCurrBSS->abyBSSID, pbyBSSID)) {
+                (pCurrBSS->bSelected == false)) {
+                if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
                     if (pSSID != NULL) {
                         // compare ssid
                         if ( !memcmp(pSSID->abySSID,
@@ -172,7 +173,7 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
                                 ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
                                 ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
                                 ) {
-                                pCurrBSS->bSelected = TRUE;
+                                pCurrBSS->bSelected = true;
                                 return(pCurrBSS);
                             }
                         }
@@ -181,7 +182,7 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
                             ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
                             ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
                             ) {
-                            pCurrBSS->bSelected = TRUE;
+                            pCurrBSS->bSelected = true;
                             return(pCurrBSS);
                         }
                     }
@@ -193,7 +194,7 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
         for (ii = 0; ii <MAX_BSS_NUM; ii++) {
             pCurrBSS = &(pMgmt->sBSSList[ii]);
        //2007-0721-01<Add>by MikeLiu
-         pCurrBSS->bSelected = FALSE;
+         pCurrBSS->bSelected = false;
           if (pCurrBSS->bActive) {
 
                 if (pSSID != NULL) {
@@ -224,19 +225,19 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
                 }
 /*
                 if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) {
-                    if (pCurrBSS->bWPAValid == TRUE) {
+                    if (pCurrBSS->bWPAValid == true) {
                         // WPA AP will reject connection of station without WPA enable.
                         continue;
                     }
                 } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
                            (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
-                    if (pCurrBSS->bWPAValid == FALSE) {
+                    if (pCurrBSS->bWPAValid == false) {
                         // station with WPA enable can't join NonWPA AP.
                         continue;
                     }
                 } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
                            (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
-                    if (pCurrBSS->bWPA2Valid == FALSE) {
+                    if (pCurrBSS->bWPA2Valid == false) {
                         // station with WPA2 enable can't join NonWPA2 AP.
                         continue;
                     }
@@ -253,9 +254,9 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
             }
         }
         if (pSelect != NULL) {
-            pSelect->bSelected = TRUE;
+            pSelect->bSelected = true;
 /*
-                        if (pDevice->bRoaming == FALSE)  {
+                        if (pDevice->bRoaming == false)  {
        //       Einsn Add @20070907
                        memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
                        memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ;
@@ -283,18 +284,18 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
 void
 BSSvClearBSSList(
     void *hDeviceContext,
-    BOOL bKeepCurrBSSID
+    bool bKeepCurrBSSID
     )
 {
     PSDevice     pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            ii;
+    unsigned int ii;
 
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         if (bKeepCurrBSSID) {
             if (pMgmt->sBSSList[ii].bActive &&
-                IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
-               // bKeepCurrBSSID = FALSE;
+                !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
+               // bKeepCurrBSSID = false;
                 continue;
             }
         }
@@ -304,7 +305,7 @@ BSSvClearBSSList(
              continue;
         }
 
-        pMgmt->sBSSList[ii].bActive = FALSE;
+        pMgmt->sBSSList[ii].bActive = false;
         memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
     }
     BSSvClearAnyBSSJoinRecord(pDevice);
@@ -320,25 +321,25 @@ BSSvClearBSSList(
  *    search BSS list by BSSID & SSID if matched
  *
  * Return Value:
- *    TRUE if found.
+ *    true if found.
  *
 -*/
 PKnownBSS
 BSSpAddrIsInBSSList(
     void *hDeviceContext,
-    PBYTE abyBSSID,
+    unsigned char *abyBSSID,
     PWLAN_IE_SSID pSSID
     )
 {
     PSDevice     pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PKnownBSS       pBSSList = NULL;
-    UINT            ii;
+    unsigned int ii;
 
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         pBSSList = &(pMgmt->sBSSList[ii]);
         if (pBSSList->bActive) {
-            if (IS_ETH_ADDRESS_EQUAL(pBSSList->abyBSSID, abyBSSID)) {
+            if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
 //                if (pSSID == NULL)
 //                    return pBSSList;
                 if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
@@ -362,18 +363,18 @@ BSSpAddrIsInBSSList(
  *    Insert a BSS set into known BSS list
  *
  * Return Value:
- *    TRUE if success.
+ *    true if success.
  *
 -*/
 
-BOOL
+bool
 BSSbInsertToBSSList (
     void *hDeviceContext,
-    PBYTE abyBSSIDAddr,
+    unsigned char *abyBSSIDAddr,
     QWORD qwTimestamp,
-    WORD wBeaconInterval,
-    WORD wCapInfo,
-    BYTE byCurrChannel,
+    unsigned short wBeaconInterval,
+    unsigned short wCapInfo,
+    unsigned char byCurrChannel,
     PWLAN_IE_SSID pSSID,
     PWLAN_IE_SUPP_RATES pSuppRates,
     PWLAN_IE_SUPP_RATES pExtSuppRates,
@@ -382,8 +383,8 @@ BSSbInsertToBSSList (
     PWLAN_IE_RSN_EXT pRSNWPA,
     PWLAN_IE_COUNTRY pIE_Country,
     PWLAN_IE_QUIET pIE_Quiet,
-    UINT uIELength,
-    PBYTE pbyIEs,
+    unsigned int uIELength,
+    unsigned char *pbyIEs,
     void *pRxPacketContext
     )
 {
@@ -392,8 +393,8 @@ BSSbInsertToBSSList (
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
     PKnownBSS       pBSSList = NULL;
-    UINT            ii;
-    BOOL            bParsingQuiet = FALSE;
+    unsigned int ii;
+    bool bParsingQuiet = false;
     PWLAN_IE_QUIET  pQuiet = NULL;
 
 
@@ -408,10 +409,10 @@ BSSbInsertToBSSList (
 
     if (ii == MAX_BSS_NUM){
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
-        return FALSE;
+        return false;
     }
     // save the BSS info
-    pBSSList->bActive = TRUE;
+    pBSSList->bActive = true;
     memcpy( pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
     HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
     LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
@@ -445,7 +446,7 @@ BSSbInsertToBSSList (
     if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
         pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
     } else {
-        if (pBSSList->sERP.bERPExist == TRUE) {
+        if (pBSSList->sERP.bERPExist == true) {
             pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
         } else {
             pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
@@ -461,16 +462,16 @@ BSSbInsertToBSSList (
         (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
         // assoc with BSS
         if (pBSSList == pMgmt->pCurrBSS) {
-            bParsingQuiet = TRUE;
+            bParsingQuiet = true;
         }
     }
 
     WPA_ClearRSN(pBSSList);
 
     if (pRSNWPA != NULL) {
-        UINT uLen = pRSNWPA->len + 2;
+        unsigned int uLen = pRSNWPA->len + 2;
 
-        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) {
+        if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) {
             pBSSList->wWPALen = uLen;
             memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
             WPA_ParseRSN(pBSSList, pRSNWPA);
@@ -480,33 +481,33 @@ BSSbInsertToBSSList (
     WPA2_ClearRSN(pBSSList);
 
     if (pRSN != NULL) {
-        UINT uLen = pRSN->len + 2;
-        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) {
+        unsigned int uLen = pRSN->len + 2;
+        if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
             pBSSList->wRSNLen = uLen;
             memcpy(pBSSList->byRSNIE, pRSN, uLen);
             WPA2vParseRSN(pBSSList, pRSN);
         }
     }
 
-    if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == TRUE)) {
+    if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == true)) {
 
         PSKeyItem  pTransmitKey = NULL;
-        BOOL       bIs802_1x = FALSE;
+        bool bIs802_1x = false;
 
         for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii ++) {
             if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) {
-                bIs802_1x = TRUE;
+                bIs802_1x = true;
                 break;
             }
         }
-        if ((bIs802_1x == TRUE) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
+        if ((bIs802_1x == true) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
             ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
 
             bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj);
 
-            if ((pDevice->bLinkPass == TRUE) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
-                if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE) ||
-                    (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == TRUE)) {
+            if ((pDevice->bLinkPass == true) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) ||
+                    (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == true)) {
                     pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList;
                     pDevice->gsPMKIDCandidate.Version = 1;
 
@@ -519,46 +520,45 @@ BSSbInsertToBSSList (
     if (pDevice->bUpdateBBVGA) {
         // Moniter if RSSI is too strong.
         pBSSList->byRSSIStatCnt = 0;
-        RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
+        RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
         pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
         for (ii = 1; ii < RSSI_STAT_COUNT; ii++)
             pBSSList->ldBmAverage[ii] = 0;
     }
 
     if ((pIE_Country != NULL) &&
-        (pMgmt->b11hEnable == TRUE)) {
-        CARDvSetCountryInfo(pMgmt->pAdapter,
-                            pBSSList->eNetworkTypeInUse,
+        (pMgmt->b11hEnable == true)) {
+        set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
                             pIE_Country);
     }
 
-    if ((bParsingQuiet == TRUE) && (pIE_Quiet != NULL)) {
+    if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
         if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
             (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
             // valid EID
             if (pQuiet == NULL) {
                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
                 CARDbSetQuiet(  pMgmt->pAdapter,
-                                TRUE,
+                                true,
                                 pQuiet->byQuietCount,
                                 pQuiet->byQuietPeriod,
-                                *((PWORD)pQuiet->abyQuietDuration),
-                                *((PWORD)pQuiet->abyQuietOffset)
+                                *((unsigned short *)pQuiet->abyQuietDuration),
+                                *((unsigned short *)pQuiet->abyQuietOffset)
                                 );
             } else {
                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
                 CARDbSetQuiet(  pMgmt->pAdapter,
-                                FALSE,
+                                false,
                                 pQuiet->byQuietCount,
                                 pQuiet->byQuietPeriod,
-                                *((PWORD)pQuiet->abyQuietDuration),
-                                *((PWORD)pQuiet->abyQuietOffset)
+                                *((unsigned short *)pQuiet->abyQuietDuration),
+                                *((unsigned short *)pQuiet->abyQuietOffset)
                                 );
             }
         }
     }
 
-    if ((bParsingQuiet == TRUE) &&
+    if ((bParsingQuiet == true) &&
         (pQuiet != NULL)) {
         CARDbStartQuiet(pMgmt->pAdapter);
     }
@@ -568,7 +568,7 @@ BSSbInsertToBSSList (
         pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
     memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
 
-    return TRUE;
+    return true;
 }
 
 
@@ -578,19 +578,19 @@ BSSbInsertToBSSList (
  *    Update BSS set in known BSS list
  *
  * Return Value:
- *    TRUE if success.
+ *    true if success.
  *
 -*/
 // TODO: input structure modify
 
-BOOL
+bool
 BSSbUpdateToBSSList (
     void *hDeviceContext,
     QWORD qwTimestamp,
-    WORD wBeaconInterval,
-    WORD wCapInfo,
-    BYTE byCurrChannel,
-    BOOL bChannelHit,
+    unsigned short wBeaconInterval,
+    unsigned short wCapInfo,
+    unsigned char byCurrChannel,
+    bool bChannelHit,
     PWLAN_IE_SSID pSSID,
     PWLAN_IE_SUPP_RATES pSuppRates,
     PWLAN_IE_SUPP_RATES pExtSuppRates,
@@ -600,8 +600,8 @@ BSSbUpdateToBSSList (
     PWLAN_IE_COUNTRY pIE_Country,
     PWLAN_IE_QUIET pIE_Quiet,
     PKnownBSS pBSSList,
-    UINT uIELength,
-    PBYTE pbyIEs,
+    unsigned int uIELength,
+    unsigned char *pbyIEs,
     void *pRxPacketContext
     )
 {
@@ -609,14 +609,14 @@ BSSbUpdateToBSSList (
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
-    LONG            ldBm;
-    BOOL            bParsingQuiet = FALSE;
+    long            ldBm;
+    bool bParsingQuiet = false;
     PWLAN_IE_QUIET  pQuiet = NULL;
 
 
 
     if (pBSSList == NULL)
-        return FALSE;
+        return false;
 
 
     HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
@@ -646,7 +646,7 @@ BSSbUpdateToBSSList (
     if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
         pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
     } else {
-        if (pBSSList->sERP.bERPExist == TRUE) {
+        if (pBSSList->sERP.bERPExist == true) {
             pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
         } else {
             pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
@@ -663,15 +663,15 @@ BSSbUpdateToBSSList (
         (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
         // assoc with BSS
         if (pBSSList == pMgmt->pCurrBSS) {
-            bParsingQuiet = TRUE;
+            bParsingQuiet = true;
         }
     }
 
    WPA_ClearRSN(pBSSList);         //mike update
 
     if (pRSNWPA != NULL) {
-        UINT uLen = pRSNWPA->len + 2;
-        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) {
+        unsigned int uLen = pRSNWPA->len + 2;
+        if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) {
             pBSSList->wWPALen = uLen;
             memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
             WPA_ParseRSN(pBSSList, pRSNWPA);
@@ -681,8 +681,8 @@ BSSbUpdateToBSSList (
    WPA2_ClearRSN(pBSSList);  //mike update
 
     if (pRSN != NULL) {
-        UINT uLen = pRSN->len + 2;
-        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) {
+        unsigned int uLen = pRSN->len + 2;
+        if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
             pBSSList->wRSNLen = uLen;
             memcpy(pBSSList->byRSNIE, pRSN, uLen);
             WPA2vParseRSN(pBSSList, pRSN);
@@ -690,7 +690,7 @@ BSSbUpdateToBSSList (
     }
 
     if (pRxPacket->uRSSI != 0) {
-        RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &ldBm);
+        RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm);
         // Moniter if RSSI is too strong.
         pBSSList->byRSSIStatCnt++;
         pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
@@ -703,39 +703,38 @@ BSSbUpdateToBSSList (
     }
 
     if ((pIE_Country != NULL) &&
-        (pMgmt->b11hEnable == TRUE)) {
-        CARDvSetCountryInfo(pMgmt->pAdapter,
-                            pBSSList->eNetworkTypeInUse,
+        (pMgmt->b11hEnable == true)) {
+        set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
                             pIE_Country);
     }
 
-    if ((bParsingQuiet == TRUE) && (pIE_Quiet != NULL)) {
+    if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
         if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
             (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
             // valid EID
             if (pQuiet == NULL) {
                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
                 CARDbSetQuiet(  pMgmt->pAdapter,
-                                TRUE,
+                                true,
                                 pQuiet->byQuietCount,
                                 pQuiet->byQuietPeriod,
-                                *((PWORD)pQuiet->abyQuietDuration),
-                                *((PWORD)pQuiet->abyQuietOffset)
+                                *((unsigned short *)pQuiet->abyQuietDuration),
+                                *((unsigned short *)pQuiet->abyQuietOffset)
                                 );
             } else {
                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
                 CARDbSetQuiet(  pMgmt->pAdapter,
-                                FALSE,
+                                false,
                                 pQuiet->byQuietCount,
                                 pQuiet->byQuietPeriod,
-                                *((PWORD)pQuiet->abyQuietDuration),
-                                *((PWORD)pQuiet->abyQuietOffset)
+                                *((unsigned short *)pQuiet->abyQuietDuration),
+                                *((unsigned short *)pQuiet->abyQuietOffset)
                                 );
             }
         }
     }
 
-    if ((bParsingQuiet == TRUE) &&
+    if ((bParsingQuiet == true) &&
         (pQuiet != NULL)) {
         CARDbStartQuiet(pMgmt->pAdapter);
     }
@@ -745,7 +744,7 @@ BSSbUpdateToBSSList (
         pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
     memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
 
-    return TRUE;
+    return true;
 }
 
 
@@ -762,27 +761,24 @@ BSSbUpdateToBSSList (
  *
 -*/
 
-BOOL
-BSSDBbIsSTAInNodeDB(
-    void *pMgmtObject,
-    PBYTE abyDstAddr,
-    PUINT puNodeIndex
-    )
+bool
+BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr,
+               unsigned int *puNodeIndex)
 {
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
-    UINT            ii;
+    unsigned int ii;
 
     // Index = 0 reserved for AP Node
     for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
         if (pMgmt->sNodeDBTable[ii].bActive) {
-            if (IS_ETH_ADDRESS_EQUAL(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+            if (!compare_ether_addr(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
                 *puNodeIndex = ii;
-                return TRUE;
+                return true;
             }
         }
     }
 
-   return FALSE;
+   return false;
 };
 
 
@@ -798,17 +794,14 @@ BSSDBbIsSTAInNodeDB(
  *
 -*/
 void
-BSSvCreateOneNode(
-    void *hDeviceContext,
-    PUINT puNodeIndex
-    )
+BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex)
 {
 
     PSDevice     pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            ii;
-    UINT            BigestCount = 0;
-    UINT            SelectIndex;
+    unsigned int ii;
+    unsigned int BigestCount = 0;
+    unsigned int SelectIndex;
     struct sk_buff  *skb;
     // Index = 0 reserved for AP Node (In STA mode)
     // Index = 0 reserved for Broadcast/MultiCast (In AP mode)
@@ -840,7 +833,7 @@ BSSvCreateOneNode(
     }
 
     memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
-    pMgmt->sNodeDBTable[*puNodeIndex].bActive = TRUE;
+    pMgmt->sNodeDBTable[*puNodeIndex].bActive = true;
     pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
     // for AP mode PS queue
     skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
@@ -865,13 +858,13 @@ BSSvCreateOneNode(
 void
 BSSvRemoveOneNode(
     void *hDeviceContext,
-    UINT uNodeIndex
+    unsigned int uNodeIndex
     )
 {
 
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
     struct sk_buff  *skb;
 
 
@@ -898,18 +891,18 @@ BSSvRemoveOneNode(
 void
 BSSvUpdateAPNode(
     void *hDeviceContext,
-    PWORD pwCapInfo,
+    unsigned short *pwCapInfo,
     PWLAN_IE_SUPP_RATES pSuppRates,
     PWLAN_IE_SUPP_RATES pExtSuppRates
     )
 {
     PSDevice     pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            uRateLen = WLAN_RATES_MAXLEN;
+    unsigned int uRateLen = WLAN_RATES_MAXLEN;
 
     memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
 
-    pMgmt->sNodeDBTable[0].bActive = TRUE;
+    pMgmt->sNodeDBTable[0].bActive = true;
     if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
         uRateLen = WLAN_RATES_MAXLEN_11B;
     }
@@ -922,7 +915,7 @@ BSSvUpdateAPNode(
     RATEvParseMaxRate((void *)pDevice,
                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
-                       TRUE,
+                       true,
                        &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
                        &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
                        &(pMgmt->sNodeDBTable[0].wSuppRate),
@@ -969,13 +962,13 @@ BSSvAddMulticastNode(
     if (!pDevice->bEnableHostWEP)
         memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
     memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN);
-    pMgmt->sNodeDBTable[0].bActive = TRUE;
-    pMgmt->sNodeDBTable[0].bPSEnable = FALSE;
+    pMgmt->sNodeDBTable[0].bActive = true;
+    pMgmt->sNodeDBTable[0].bPSEnable = false;
     skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue);
     RATEvParseMaxRate((void *)pDevice,
                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
-                      TRUE,
+                      true,
                       &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
                       &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
                        &(pMgmt->sNodeDBTable[0].wSuppRate),
@@ -1008,8 +1001,8 @@ BSSvAddMulticastNode(
 -*/
  //2008-4-14 <add> by chester for led issue
  #ifdef FOR_LED_ON_NOTEBOOK
-BOOL cc=FALSE;
-UINT status;
+bool cc=false;
+unsigned int status;
 #endif
 void
 BSSvSecondCallBack(
@@ -1018,11 +1011,11 @@ BSSvSecondCallBack(
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            ii;
+    unsigned int ii;
     PWLAN_IE_SSID   pItemSSID, pCurrSSID;
-    UINT            uSleepySTACnt = 0;
-    UINT            uNonShortSlotSTACnt = 0;
-    UINT            uLongPreambleSTACnt = 0;
+    unsigned int uSleepySTACnt = 0;
+    unsigned int uNonShortSlotSTACnt = 0;
+    unsigned int uLongPreambleSTACnt = 0;
     viawget_wpa_header* wpahdr;  //DavidWang
 
     spin_lock_irq(&pDevice->lock);
@@ -1034,22 +1027,22 @@ BSSvSecondCallBack(
  //2008-4-14 <add> by chester for led issue
 #ifdef FOR_LED_ON_NOTEBOOK
 MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
-if ((( !(pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == FALSE))||((pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == TRUE)))&&(cc==FALSE)){
-cc=TRUE;
+if ((( !(pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == false))||((pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == true)))&&(cc==false)){
+cc=true;
 }
-else if(cc==TRUE){
+else if(cc==true){
 
-if(pDevice->bHWRadioOff == TRUE){
+if(pDevice->bHWRadioOff == true){
             if ( !(pDevice->byGPIO & GPIO0_DATA))
 //||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
 {if(status==1) goto start;
 status=1;
 CARDbRadioPowerOff(pDevice);
-                pMgmt->sNodeDBTable[0].bActive = FALSE;
+                pMgmt->sNodeDBTable[0].bActive = false;
                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
                 //netif_stop_queue(pDevice->dev);
-                pDevice->bLinkPass = FALSE;
+                pDevice->bLinkPass = false;
 
 }
   if (pDevice->byGPIO &GPIO0_DATA)
@@ -1064,11 +1057,11 @@ else{
 {if(status==3) goto start;
 status=3;
 CARDbRadioPowerOff(pDevice);
-                pMgmt->sNodeDBTable[0].bActive = FALSE;
+                pMgmt->sNodeDBTable[0].bActive = false;
                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
                 //netif_stop_queue(pDevice->dev);
-                pDevice->bLinkPass = FALSE;
+                pDevice->bLinkPass = false;
 
 }
   if ( !(pDevice->byGPIO & GPIO0_DATA))
@@ -1092,11 +1085,11 @@ start:
 
 {
        pDevice->byReAssocCount++;
-   if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != TRUE)) {  //10 sec timeout
+   if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) {  //10 sec timeout
                      printk("Re-association timeout!!!\n");
                   pDevice->byReAssocCount = 0;
                      #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                    // if(pDevice->bWPASuppWextEnabled == true)
                         {
                        union iwreq_data  wrqu;
                        memset(&wrqu, 0, sizeof (wrqu));
@@ -1106,7 +1099,7 @@ start:
                        }
                     #endif
      }
-   else if(pDevice->bLinkPass == TRUE)
+   else if(pDevice->bLinkPass == true)
        pDevice->byReAssocCount = 0;
 }
 
@@ -1200,27 +1193,27 @@ start:
         if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
             if (!pDevice->bProtectMode) {
                 MACvEnableProtectMD(pDevice->PortOffset);
-                pDevice->bProtectMode = TRUE;
+                pDevice->bProtectMode = true;
             }
         }
         else {
             if (pDevice->bProtectMode) {
                 MACvDisableProtectMD(pDevice->PortOffset);
-                pDevice->bProtectMode = FALSE;
+                pDevice->bProtectMode = false;
             }
         }
         // on/off short slot time
 
         if (uNonShortSlotSTACnt > 0) {
             if (pDevice->bShortSlotTime) {
-                pDevice->bShortSlotTime = FALSE;
+                pDevice->bShortSlotTime = false;
                 BBvSetShortSlotTime(pDevice);
                 vUpdateIFS((void *)pDevice);
             }
         }
         else {
             if (!pDevice->bShortSlotTime) {
-                pDevice->bShortSlotTime = TRUE;
+                pDevice->bShortSlotTime = true;
                 BBvSetShortSlotTime(pDevice);
                 vUpdateIFS((void *)pDevice);
             }
@@ -1231,13 +1224,13 @@ start:
         if (uLongPreambleSTACnt > 0) {
             if (!pDevice->bBarkerPreambleMd) {
                 MACvEnableBarkerPreambleMd(pDevice->PortOffset);
-                pDevice->bBarkerPreambleMd = TRUE;
+                pDevice->bBarkerPreambleMd = true;
             }
         }
         else {
             if (pDevice->bBarkerPreambleMd) {
                 MACvDisableBarkerPreambleMd(pDevice->PortOffset);
-                pDevice->bBarkerPreambleMd = FALSE;
+                pDevice->bBarkerPreambleMd = false;
             }
         }
 
@@ -1247,9 +1240,9 @@ start:
     // Check if any STA in PS mode, enable DTIM multicast deliver
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
         if (uSleepySTACnt > 0)
-            pMgmt->sNodeDBTable[0].bPSEnable = TRUE;
+            pMgmt->sNodeDBTable[0].bPSEnable = true;
         else
-            pMgmt->sNodeDBTable[0].bPSEnable = FALSE;
+            pMgmt->sNodeDBTable[0].bPSEnable = false;
     }
 
     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
@@ -1276,12 +1269,12 @@ start:
            }
 
                if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) {
-                pMgmt->sNodeDBTable[0].bActive = FALSE;
+                pMgmt->sNodeDBTable[0].bActive = false;
                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
                 netif_stop_queue(pDevice->dev);
-                pDevice->bLinkPass = FALSE;
-                pDevice->bRoaming = TRUE;
+                pDevice->bLinkPass = false;
+                pDevice->bRoaming = true;
                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
         if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
              wpahdr = (viawget_wpa_header *)pDevice->skb->data;
@@ -1298,7 +1291,7 @@ start:
              pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
          };
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-  // if(pDevice->bWPASuppWextEnabled == TRUE)
+  // if(pDevice->bWPASuppWextEnabled == true)
       {
        union iwreq_data  wrqu;
        memset(&wrqu, 0, sizeof (wrqu));
@@ -1314,7 +1307,7 @@ start:
                 pDevice->uAutoReConnectTime++;
               #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
                 //network manager support need not do Roaming scan???
-                if(pDevice->bWPASuppWextEnabled ==TRUE)
+                if(pDevice->bWPASuppWextEnabled ==true)
                 pDevice->uAutoReConnectTime = 0;
             #endif
             }
@@ -1358,7 +1351,7 @@ start:
                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
                 pMgmt->eCurrState = WMAC_STATE_STARTED;
                 netif_stop_queue(pDevice->dev);
-                pDevice->bLinkPass = FALSE;
+                pDevice->bLinkPass = false;
             }
         }
     }
@@ -1391,23 +1384,23 @@ start:
 void
 BSSvUpdateNodeTxCounter(
     void *hDeviceContext,
-    BYTE        byTsr0,
-    BYTE        byTsr1,
-    PBYTE       pbyBuffer,
-    UINT        uFIFOHeaderSize
+    unsigned char byTsr0,
+    unsigned char byTsr1,
+    unsigned char *pbyBuffer,
+    unsigned int uFIFOHeaderSize
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            uNodeIndex = 0;
-    BYTE            byTxRetry = (byTsr0 & TSR0_NCR);
+    unsigned int uNodeIndex = 0;
+    unsigned char byTxRetry = (byTsr0 & TSR0_NCR);
     PSTxBufHead     pTxBufHead;
     PS802_11Header  pMACHeader;
-    WORD            wRate;
-    WORD            wFallBackRate = RATE_1M;
-    BYTE            byFallBack;
-    UINT            ii;
-//     UINT            txRetryTemp;
+    unsigned short wRate;
+    unsigned short wFallBackRate = RATE_1M;
+    unsigned char byFallBack;
+    unsigned int ii;
+//     unsigned int txRetryTemp;
 //PLICE_DEBUG->
        //txRetryTemp = byTxRetry;
        //if (txRetryTemp== 8)
@@ -1584,14 +1577,14 @@ BSSvUpdateNodeTxCounter(
 void
 BSSvClearNodeDBTable(
     void *hDeviceContext,
-    UINT uStartIndex
+    unsigned int uStartIndex
     )
 
 {
     PSDevice     pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     struct sk_buff  *skb;
-    UINT            ii;
+    unsigned int ii;
 
     for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
         if (pMgmt->sNodeDBTable[ii].bActive) {
@@ -1629,8 +1622,8 @@ void s_vCheckSensitivity(
         pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
         if (pBSSList != NULL) {
             // Updata BB Reg if RSSI is too strong.
-            LONG    LocalldBmAverage = 0;
-            LONG    uNumofdBm = 0;
+            long    LocalldBmAverage = 0;
+            long    uNumofdBm = 0;
             for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
                 if (pBSSList->ldBmAverage[ii] != 0) {
                     uNumofdBm ++;
@@ -1666,10 +1659,10 @@ BSSvClearAnyBSSJoinRecord (
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            ii;
+    unsigned int ii;
 
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
-        pMgmt->sBSSList[ii].bSelected = FALSE;
+        pMgmt->sBSSList[ii].bSelected = false;
     }
     return;
 }
@@ -1680,9 +1673,9 @@ void s_uCalculateLinkQual(
     )
 {
    PSDevice        pDevice = (PSDevice)hDeviceContext;
-   ULONG TxOkRatio, TxCnt;
-   ULONG RxOkRatio,RxCnt;
-   ULONG RssiRatio;
+   unsigned long TxOkRatio, TxCnt;
+   unsigned long RxOkRatio,RxCnt;
+   unsigned long RssiRatio;
    long ldBm;
 
 TxCnt = pDevice->scStatistic.TxNoRetryOkCount +
@@ -1693,7 +1686,7 @@ RxCnt = pDevice->scStatistic.RxFcsErrCnt +
 TxOkRatio = (TxCnt < 6) ? 4000:((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt);
 RxOkRatio = (RxCnt < 6) ? 2000:((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt);
 //decide link quality
-if(pDevice->bLinkPass !=TRUE)
+if(pDevice->bLinkPass !=true)
 {
  //  printk("s_uCalculateLinkQual-->Link disconnect and Poor quality**\n");
    pDevice->scStatistic.LinkQuality = 0;
@@ -1701,7 +1694,7 @@ if(pDevice->bLinkPass !=TRUE)
 }
 else
 {
-   RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+   RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm);
    if(-ldBm < 50)  {
        RssiRatio = 4000;
      }
@@ -1735,8 +1728,8 @@ void s_vCheckPreEDThreshold(
         ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
         pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
         if (pBSSList != NULL) {
-            pDevice->byBBPreEDRSSI = (BYTE) (~(pBSSList->ldBmAverRange) + 1);
-            //BBvUpdatePreEDThreshold(pDevice, FALSE);
+            pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1);
+            //BBvUpdatePreEDThreshold(pDevice, false);
         }
     }
     return;
index e09ef8762979a536bb0344fc210c61a6642bdd00..0af42118612218aabe7c7c1794da88e97a3bd32c 100644 (file)
@@ -90,69 +90,69 @@ typedef enum _NDIS_802_11_NETWORK_TYPE
 
 
 typedef struct tagSERPObject {
-    BOOL    bERPExist;
-    BYTE    byERP;
+    bool bERPExist;
+    unsigned char byERP;
 }ERPObject, *PERPObject;
 
 
 typedef struct tagSRSNCapObject {
-    BOOL    bRSNCapExist;
-    WORD    wRSNCap;
+    bool bRSNCapExist;
+    unsigned short wRSNCap;
 }SRSNCapObject, *PSRSNCapObject;
 
 // BSS info(AP)
 #pragma pack(1)
 typedef struct tagKnownBSS {
     // BSS info
-    BOOL            bActive;
-    BYTE            abyBSSID[WLAN_BSSID_LEN];
-    UINT            uChannel;
-    BYTE            abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-    BYTE            abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-    UINT            uRSSI;
-    BYTE            bySQ;
-    WORD            wBeaconInterval;
-    WORD            wCapInfo;
-    BYTE            abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-    BYTE            byRxRate;
-
-//    WORD            wATIMWindow;
-    BYTE            byRSSIStatCnt;
-    LONG            ldBmMAX;
-    LONG            ldBmAverage[RSSI_STAT_COUNT];
-    LONG            ldBmAverRange;
+    bool bActive;
+    unsigned char abyBSSID[WLAN_BSSID_LEN];
+    unsigned int       uChannel;
+    unsigned char abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned char abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned int       uRSSI;
+    unsigned char bySQ;
+    unsigned short wBeaconInterval;
+    unsigned short wCapInfo;
+    unsigned char abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    unsigned char byRxRate;
+
+//    unsigned short wATIMWindow;
+    unsigned char byRSSIStatCnt;
+    long            ldBmMAX;
+    long            ldBmAverage[RSSI_STAT_COUNT];
+    long            ldBmAverRange;
     //For any BSSID selection improvment
-    BOOL            bSelected;
+    bool bSelected;
 
     //++ WPA informations
-    BOOL            bWPAValid;
-    BYTE            byGKType;
-    BYTE            abyPKType[4];
-    WORD            wPKCount;
-    BYTE            abyAuthType[4];
-    WORD            wAuthCount;
-    BYTE            byDefaultK_as_PK;
-    BYTE            byReplayIdx;
+    bool bWPAValid;
+    unsigned char byGKType;
+    unsigned char abyPKType[4];
+    unsigned short wPKCount;
+    unsigned char abyAuthType[4];
+    unsigned short wAuthCount;
+    unsigned char byDefaultK_as_PK;
+    unsigned char byReplayIdx;
     //--
 
     //++ WPA2 informations
-    BOOL            bWPA2Valid;
-    BYTE            byCSSGK;
-    WORD            wCSSPKCount;
-    BYTE            abyCSSPK[4];
-    WORD            wAKMSSAuthCount;
-    BYTE            abyAKMSSAuthType[4];
+    bool bWPA2Valid;
+    unsigned char byCSSGK;
+    unsigned short wCSSPKCount;
+    unsigned char abyCSSPK[4];
+    unsigned short wAKMSSAuthCount;
+    unsigned char abyAKMSSAuthType[4];
 
     //++  wpactl
-    BYTE            byWPAIE[MAX_WPA_IE_LEN];
-    BYTE            byRSNIE[MAX_WPA_IE_LEN];
-    WORD            wWPALen;
-    WORD            wRSNLen;
+    unsigned char byWPAIE[MAX_WPA_IE_LEN];
+    unsigned char byRSNIE[MAX_WPA_IE_LEN];
+    unsigned short wWPALen;
+    unsigned short wRSNLen;
 
     // Clear count
-    UINT            uClearCount;
-//    BYTE            abyIEs[WLAN_BEACON_FR_MAXLEN];
-    UINT            uIELength;
+    unsigned int       uClearCount;
+//    unsigned char abyIEs[WLAN_BEACON_FR_MAXLEN];
+    unsigned int       uIELength;
     QWORD           qwBSSTimestamp;
     QWORD           qwLocalTSF;     // local TSF timer
 
@@ -161,7 +161,7 @@ typedef struct tagKnownBSS {
 
     ERPObject       sERP;
     SRSNCapObject   sRSNCapObj;
-    BYTE            abyIEs[1024];   // don't move this field !!
+    unsigned char abyIEs[1024];   // don't move this field !!
 
 }__attribute__ ((__packed__))
 KnownBSS , *PKnownBSS;
@@ -181,59 +181,59 @@ typedef enum tagNODE_STATE {
 // STA node info
 typedef struct tagKnownNodeDB {
     // STA info
-    BOOL            bActive;
-    BYTE            abyMACAddr[WLAN_ADDR_LEN];
-    BYTE            abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
-    BYTE            abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
-    WORD            wTxDataRate;
-    BOOL            bShortPreamble;
-    BOOL            bERPExist;
-    BOOL            bShortSlotTime;
-    UINT            uInActiveCount;
-    WORD            wMaxBasicRate;     //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp.
-    WORD            wMaxSuppRate;      //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon.
-    WORD            wSuppRate;
-    BYTE            byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode
-    BYTE            byTopCCKBasicRate; //Records the highest basic rate in CCK mode
+    bool bActive;
+    unsigned char abyMACAddr[WLAN_ADDR_LEN];
+    unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+    unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+    unsigned short wTxDataRate;
+    bool bShortPreamble;
+    bool bERPExist;
+    bool bShortSlotTime;
+    unsigned int       uInActiveCount;
+    unsigned short wMaxBasicRate;     //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp.
+    unsigned short wMaxSuppRate;      //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon.
+    unsigned short wSuppRate;
+    unsigned char byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode
+    unsigned char byTopCCKBasicRate; //Records the highest basic rate in CCK mode
 
     // For AP mode
     struct sk_buff_head sTxPSQueue;
-    WORD            wCapInfo;
-    WORD            wListenInterval;
-    WORD            wAID;
+    unsigned short wCapInfo;
+    unsigned short wListenInterval;
+    unsigned short wAID;
     NODE_STATE      eNodeState;
-    BOOL            bPSEnable;
-    BOOL            bRxPSPoll;
-    BYTE            byAuthSequence;
-    ULONG           ulLastRxJiffer;
-    BYTE            bySuppRate;
-    DWORD           dwFlags;
-    WORD            wEnQueueCnt;
-
-    BOOL            bOnFly;
-    ULONGLONG       KeyRSC;
-    BYTE            byKeyIndex;
-    DWORD           dwKeyIndex;
-    BYTE            byCipherSuite;
-    DWORD           dwTSC47_16;
-    WORD            wTSC15_0;
-    UINT            uWepKeyLength;
-    BYTE            abyWepKey[WLAN_WEPMAX_KEYLEN];
+    bool bPSEnable;
+    bool bRxPSPoll;
+    unsigned char byAuthSequence;
+    unsigned long ulLastRxJiffer;
+    unsigned char bySuppRate;
+    unsigned long dwFlags;
+    unsigned short wEnQueueCnt;
+
+    bool bOnFly;
+    unsigned long long       KeyRSC;
+    unsigned char byKeyIndex;
+    unsigned long dwKeyIndex;
+    unsigned char byCipherSuite;
+    unsigned long dwTSC47_16;
+    unsigned short wTSC15_0;
+    unsigned int       uWepKeyLength;
+    unsigned char abyWepKey[WLAN_WEPMAX_KEYLEN];
     //
     // Auto rate fallback vars
-    BOOL            bIsInFallback;
-    UINT            uAverageRSSI;
-    UINT            uRateRecoveryTimeout;
-    UINT            uRatePollTimeout;
-    UINT            uTxFailures;
-    UINT            uTxAttempts;
-
-    UINT            uTxRetry;
-    UINT            uFailureRatio;
-    UINT            uRetryRatio;
-    UINT            uTxOk[MAX_RATE+1];
-    UINT            uTxFail[MAX_RATE+1];
-    UINT            uTimeCount;
+    bool bIsInFallback;
+    unsigned int       uAverageRSSI;
+    unsigned int       uRateRecoveryTimeout;
+    unsigned int       uRatePollTimeout;
+    unsigned int       uTxFailures;
+    unsigned int       uTxAttempts;
+
+    unsigned int       uTxRetry;
+    unsigned int       uFailureRatio;
+    unsigned int       uRetryRatio;
+    unsigned int       uTxOk[MAX_RATE+1];
+    unsigned int       uTxFail[MAX_RATE+1];
+    unsigned int       uTimeCount;
 
 } KnownNodeDB, *PKnownNodeDB;
 
@@ -245,32 +245,32 @@ typedef struct tagKnownNodeDB {
 PKnownBSS
 BSSpSearchBSSList(
     void *hDeviceContext,
-    PBYTE pbyDesireBSSID,
-    PBYTE pbyDesireSSID,
+    unsigned char *pbyDesireBSSID,
+    unsigned char *pbyDesireSSID,
     CARD_PHY_TYPE ePhyType
     );
 
 PKnownBSS
 BSSpAddrIsInBSSList(
     void *hDeviceContext,
-    PBYTE abyBSSID,
+    unsigned char *abyBSSID,
     PWLAN_IE_SSID pSSID
     );
 
 void
 BSSvClearBSSList(
     void *hDeviceContext,
-    BOOL bKeepCurrBSSID
+    bool bKeepCurrBSSID
     );
 
-BOOL
+bool
 BSSbInsertToBSSList(
     void *hDeviceContext,
-    PBYTE abyBSSIDAddr,
+    unsigned char *abyBSSIDAddr,
     QWORD qwTimestamp,
-    WORD wBeaconInterval,
-    WORD wCapInfo,
-    BYTE byCurrChannel,
+    unsigned short wBeaconInterval,
+    unsigned short wCapInfo,
+    unsigned char byCurrChannel,
     PWLAN_IE_SSID pSSID,
     PWLAN_IE_SUPP_RATES pSuppRates,
     PWLAN_IE_SUPP_RATES pExtSuppRates,
@@ -279,20 +279,20 @@ BSSbInsertToBSSList(
     PWLAN_IE_RSN_EXT pRSNWPA,
     PWLAN_IE_COUNTRY pIE_Country,
     PWLAN_IE_QUIET pIE_Quiet,
-    UINT uIELength,
-    PBYTE pbyIEs,
+    unsigned int uIELength,
+    unsigned char *pbyIEs,
     void *pRxPacketContext
     );
 
 
-BOOL
+bool
 BSSbUpdateToBSSList(
     void *hDeviceContext,
     QWORD qwTimestamp,
-    WORD wBeaconInterval,
-    WORD wCapInfo,
-    BYTE byCurrChannel,
-    BOOL bChannelHit,
+    unsigned short wBeaconInterval,
+    unsigned short wCapInfo,
+    unsigned char byCurrChannel,
+    bool bChannelHit,
     PWLAN_IE_SSID pSSID,
     PWLAN_IE_SUPP_RATES pSuppRates,
     PWLAN_IE_SUPP_RATES pExtSuppRates,
@@ -302,29 +302,23 @@ BSSbUpdateToBSSList(
     PWLAN_IE_COUNTRY pIE_Country,
     PWLAN_IE_QUIET pIE_Quiet,
     PKnownBSS pBSSList,
-    UINT uIELength,
-    PBYTE pbyIEs,
+    unsigned int uIELength,
+    unsigned char *pbyIEs,
     void *pRxPacketContext
     );
 
 
-BOOL
-BSSDBbIsSTAInNodeDB(
-    void *hDeviceContext,
-    PBYTE abyDstAddr,
-    PUINT puNodeIndex
-    );
+bool
+BSSDBbIsSTAInNodeDB(void *hDeviceContext, unsigned char *abyDstAddr,
+               unsigned int *puNodeIndex);
 
 void
-BSSvCreateOneNode(
-    void *hDeviceContext,
-    PUINT puNodeIndex
-    );
+BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex);
 
 void
 BSSvUpdateAPNode(
     void *hDeviceContext,
-    PWORD pwCapInfo,
+    unsigned short *pwCapInfo,
     PWLAN_IE_SUPP_RATES pItemRates,
     PWLAN_IE_SUPP_RATES pExtSuppRates
     );
@@ -339,16 +333,16 @@ BSSvSecondCallBack(
 void
 BSSvUpdateNodeTxCounter(
     void *hDeviceContext,
-    BYTE        byTsr0,
-    BYTE        byTsr1,
-    PBYTE       pbyBuffer,
-    UINT        uFIFOHeaderSize
+    unsigned char byTsr0,
+    unsigned char byTsr1,
+    unsigned char *pbyBuffer,
+    unsigned int uFIFOHeaderSize
     );
 
 void
 BSSvRemoveOneNode(
     void *hDeviceContext,
-    UINT uNodeIndex
+    unsigned int uNodeIndex
     );
 
 void
@@ -360,7 +354,7 @@ BSSvAddMulticastNode(
 void
 BSSvClearNodeDBTable(
     void *hDeviceContext,
-    UINT uStartIndex
+    unsigned int uStartIndex
     );
 
 void
index 7bc2d7654b070971e50a5fadfd0243ecd02241d2..32d095c4d51cecd2680f4d672fc323f22c17c0eb 100644 (file)
@@ -56,6 +56,7 @@
 #include "key.h"
 #include "rc4.h"
 #include "country.h"
+#include "channel.h"
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -76,411 +77,39 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 #define C_CWMAX         1023    // slot time
 
-#define CARD_MAX_CHANNEL_TBL    56
-
 #define WAIT_BEACON_TX_DOWN_TMO         3    // Times
 
-typedef struct tagSChannelTblElement {
-    BYTE    byChannelNumber;
-    UINT    uFrequency;
-    BOOL    bValid;
-    BYTE    byMAP;
-}SChannelTblElement, *PSChannelTblElement;
-
                                                               //1M,   2M,   5M,  11M,  18M,  24M,  36M,  54M
-static BYTE abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+static unsigned char abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
                                                                     //6M,   9M,  12M,  48M
-static BYTE abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+static unsigned char abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
                                                               //6M,   9M,  12M,  18M,  24M,  36M,  48M,  54M
-static BYTE abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+static unsigned char abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
                                                               //1M,   2M,   5M,  11M,
-static BYTE abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
-
-
+static unsigned char abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
 
-/*---------------------  Static Classes  ----------------------------*/
 
 /*---------------------  Static Variables  --------------------------*/
 
 
-const WORD cwRXBCNTSFOff[MAX_RATE] =
+const unsigned short cwRXBCNTSFOff[MAX_RATE] =
 {17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
 
-static SChannelTblElement sChannelTbl[CARD_MAX_CHANNEL_TBL+1] =
-{
-  {0,   0,    FALSE,    0},
-  {1,   2412, TRUE,     0},
-  {2,   2417, TRUE,     0},
-  {3,   2422, TRUE,     0},
-  {4,   2427, TRUE,     0},
-  {5,   2432, TRUE,     0},
-  {6,   2437, TRUE,     0},
-  {7,   2442, TRUE,     0},
-  {8,   2447, TRUE,     0},
-  {9,   2452, TRUE,     0},
-  {10,  2457, TRUE,     0},
-  {11,  2462, TRUE,     0},
-  {12,  2467, TRUE,     0},
-  {13,  2472, TRUE,     0},
-  {14,  2484, TRUE,     0},
-  {183, 4915, TRUE,     0},
-  {184, 4920, TRUE,     0},
-  {185, 4925, TRUE,     0},
-  {187, 4935, TRUE,     0},
-  {188, 4940, TRUE,     0},
-  {189, 4945, TRUE,     0},
-  {192, 4960, TRUE,     0},
-  {196, 4980, TRUE,     0},
-  {7,   5035, TRUE,     0},
-  {8,   5040, TRUE,     0},
-  {9,   5045, TRUE,     0},
-  {11,  5055, TRUE,     0},
-  {12,  5060, TRUE,     0},
-  {16,  5080, TRUE,     0},
-  {34,  5170, TRUE,     0},
-  {36,  5180, TRUE,     0},
-  {38,  5190, TRUE,     0},
-  {40,  5200, TRUE,     0},
-  {42,  5210, TRUE,     0},
-  {44,  5220, TRUE,     0},
-  {46,  5230, TRUE,     0},
-  {48,  5240, TRUE,     0},
-  {52,  5260, TRUE,     0},
-  {56,  5280, TRUE,     0},
-  {60,  5300, TRUE,     0},
-  {64,  5320, TRUE,     0},
-  {100, 5500, TRUE,     0},
-  {104, 5520, TRUE,     0},
-  {108, 5540, TRUE,     0},
-  {112, 5560, TRUE,     0},
-  {116, 5580, TRUE,     0},
-  {120, 5600, TRUE,     0},
-  {124, 5620, TRUE,     0},
-  {128, 5640, TRUE,     0},
-  {132, 5660, TRUE,     0},
-  {136, 5680, TRUE,     0},
-  {140, 5700, TRUE,     0},
-  {149, 5745, TRUE,     0},
-  {153, 5765, TRUE,     0},
-  {157, 5785, TRUE,     0},
-  {161, 5805, TRUE,     0},
-  {165, 5825, TRUE,     0}
-};
-
-
-/************************************************************************
- * The Radar regulation rules for each country
- ************************************************************************/
-SCountryTable ChannelRuleTab[CCODE_MAX+1] =
-{
-/************************************************************************
- * This table is based on Athero driver rules
- ************************************************************************/
-/* Country          Available channels, ended with 0                    */
-/*                                              1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  */
-{CCODE_FCC,                     {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_TELEC,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  0,  0,  1,  0,  1,  1,  0,  1,  0,  0,  1,  1,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0, 23,  0,  0, 23,  0, 23, 23,  0, 23,  0,  0, 23, 23, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ETSI,                    {'E','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_RESV3,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESV4,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESV5,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESV6,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESV7,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESV8,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESV9,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESVa,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESVb,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESVc,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESVd,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RESVe,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ALLBAND,                 {' ',' '},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ALBANIA,                 {'A','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ALGERIA,                 {'D','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ARGENTINA,               {'A','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
-{CCODE_ARMENIA,                 {'A','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_AUSTRALIA,               {'A','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_AUSTRIA,                 {'A','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15,  0, 15,  0, 15,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_AZERBAIJAN,              {'A','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_BAHRAIN,                 {'B','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_BELARUS,                 {'B','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_BELGIUM,                 {'B','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_BELIZE,                  {'B','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_BOLIVIA,                 {'B','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_BRAZIL,                  {'B','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_BRUNEI_DARUSSALAM,       {'B','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_BULGARIA,                {'B','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23,  0,  0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0}  },
-{CCODE_CANADA,                  {'C','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_CHILE,                   {'C','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17, 17}  },
-{CCODE_CHINA,                   {'C','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_COLOMBIA,                {'C','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_COSTA_RICA,              {'C','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_CROATIA,                 {'H','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_CYPRUS,                  {'C','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_CZECH,                   {'C','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_DENMARK,                 {'D','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_DOMINICAN_REPUBLIC,      {'D','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_ECUADOR,                 {'E','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_EGYPT,                   {'E','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_EL_SALVADOR,             {'S','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ESTONIA,                 {'E','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_FINLAND,                 {'F','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_FRANCE,                  {'F','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_GERMANY,                 {'D','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_GREECE,                  {'G','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_GEORGIA,                 {'G','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_GUATEMALA,               {'G','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_HONDURAS,                {'H','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_HONG_KONG,               {'H','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_HUNGARY,                 {'H','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ICELAND,                 {'I','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_INDIA,                   {'I','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_INDONESIA,               {'I','D'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_IRAN,                    {'I','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_IRELAND,                 {'I','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_ITALY,                   {'I','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_ISRAEL,                  {'I','L'},  {   0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_JAPAN,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_JORDAN,                  {'J','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_KAZAKHSTAN,              {'K','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_KUWAIT,                  {'K','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_LATVIA,                  {'L','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_LEBANON,                 {'L','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_LEICHTENSTEIN,           {'L','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_LITHUANIA,               {'L','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_LUXEMBURG,               {'L','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_MACAU,                   {'M','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_MACEDONIA,               {'M','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_MALTA,                   {'M','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
-{CCODE_MALAYSIA,                {'M','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_MEXICO,                  {'M','X'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_MONACO,                  {'M','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_MOROCCO,                 {'M','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_NETHERLANDS,             {'N','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_NEW_ZEALAND,             {'N','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_NORTH_KOREA,             {'K','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
-{CCODE_NORWAY,                  {'N','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_OMAN,                    {'O','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_PAKISTAN,                {'P','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_PANAMA,                  {'P','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_PERU,                    {'P','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_PHILIPPINES,             {'P','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_POLAND,                  {'P','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_PORTUGAL,                {'P','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_PUERTO_RICO,             {'P','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_QATAR,                   {'Q','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ROMANIA,                 {'R','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_RUSSIA,                  {'R','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_SAUDI_ARABIA,            {'S','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_SINGAPORE,               {'S','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 20, 20, 20, 20}  },
-{CCODE_SLOVAKIA,                {'S','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
-{CCODE_SLOVENIA,                {'S','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_SOUTH_AFRICA,            {'Z','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_SOUTH_KOREA,             {'K','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
-{CCODE_SPAIN,                   {'E','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
-{CCODE_SWEDEN,                  {'S','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_SWITZERLAND,             {'C','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_SYRIA,                   {'S','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_TAIWAN,                  {'T','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
-{CCODE_THAILAND,                {'T','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
-{CCODE_TRINIDAD_TOBAGO,         {'T','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_TUNISIA,                 {'T','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_TURKEY,                  {'T','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_UK,                      {'G','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
-{CCODE_UKRAINE,                 {'U','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_UNITED_ARAB_EMIRATES,    {'A','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_UNITED_STATES,           {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
-                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
-{CCODE_URUGUAY,                 {'U','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
-{CCODE_UZBEKISTAN,              {'U','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_VENEZUELA,               {'V','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
-                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
-{CCODE_VIETNAM,                 {'V','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_YEMEN,                   {'Y','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_ZIMBABWE,                {'Z','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_JAPAN_W52_W53,           {'J','J'},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
-{CCODE_MAX,                     {'U','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
-                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  }
-/*                                              1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  */
-};
-
 
 /*---------------------  Static Functions  --------------------------*/
 
 static
 void
 s_vCaculateOFDMRParameter(
-    BYTE byRate,
+    unsigned char byRate,
     CARD_PHY_TYPE ePHYType,
-    PBYTE pbyTxRate,
-    PBYTE pbyRsvTime
+    unsigned char *pbyTxRate,
+    unsigned char *pbyRsvTime
     );
 
 
-/*---------------------  Export Variables  --------------------------*/
-
 /*---------------------  Export Functions  --------------------------*/
 
-
-/*---------------------  Export function  -------------------------*/
-/************************************************************************
- * Country Channel Valid
- *  Input:  CountryCode, ChannelNum
- *          ChanneIndex is defined as VT3253 MAC channel:
- *              1   = 2.4G channel 1
- *              2   = 2.4G channel 2
- *              ...
- *              14  = 2.4G channel 14
- *              15  = 4.9G channel 183
- *              16  = 4.9G channel 184
- *              .....
- *  Output: TRUE if the specified 5GHz band is allowed to be used.
-            False otherwise.
-// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
-
-// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
-// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
- ************************************************************************/
-//2008-8-4 <add> by chester
-BOOL
-ChannelValid(UINT CountryCode, UINT ChannelIndex)
-{
-    BOOL    bValid;
-
-    bValid = FALSE;
-    /*
-     * If Channel Index is invalid, return invalid
-     */
-    if ((ChannelIndex > CB_MAX_CHANNEL) ||
-        (ChannelIndex == 0))
-    {
-        bValid = FALSE;
-        goto exit;
-    }
-
-    bValid = sChannelTbl[ChannelIndex].bValid;
-
-exit:
-    return (bValid);
-
-} /* end ChannelValid */
-
-
 /*
  * Description: Caculate TxRate and RsvTime fields for RSPINF in OFDM mode.
  *
@@ -498,10 +127,10 @@ exit:
 static
 void
 s_vCaculateOFDMRParameter (
-    BYTE byRate,
+    unsigned char byRate,
     CARD_PHY_TYPE ePHYType,
-    PBYTE pbyTxRate,
-    PBYTE pbyRsvTime
+    unsigned char *pbyTxRate,
+    unsigned char *pbyRsvTime
     )
 {
     switch (byRate) {
@@ -614,9 +243,9 @@ static
 void
 s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, void *pvExtSupportRateIEs)
 {
-    BYTE  byServ = 0, bySignal = 0; // For CCK
-    WORD  wLen = 0;
-    BYTE  byTxRate = 0, byRsvTime = 0;    // For OFDM
+    unsigned char byServ = 0, bySignal = 0; // For CCK
+    unsigned short wLen = 0;
+    unsigned char byTxRate = 0, byRsvTime = 0;    // For OFDM
 
     //Set to Page1
     MACvSelectPage1(pDevice->PortOffset);
@@ -722,120 +351,7 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs,
     MACvSelectPage0(pDevice->PortOffset);
 }
 
-
-
-
-/*---------------------  Export Variables  --------------------------*/
-
 /*---------------------  Export Functions  --------------------------*/
-BYTE CARDbyGetChannelMapping (void *pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType)
-{
-    UINT        ii;
-
-    if ((ePhyType == PHY_TYPE_11B) || (ePhyType == PHY_TYPE_11G)) {
-        return (byChannelNumber);
-    }
-
-    for(ii = (CB_MAX_CHANNEL_24G + 1); ii <= CB_MAX_CHANNEL; ) {
-        if (sChannelTbl[ii].byChannelNumber == byChannelNumber) {
-            return ((BYTE) ii);
-        }
-        ii++;
-    }
-    return (0);
-}
-
-
-BYTE CARDbyGetChannelNumber (void *pDeviceHandler, BYTE byChannelIndex)
-{
-//    PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    return(sChannelTbl[byChannelIndex].byChannelNumber);
-}
-
-/*
- * Description: Set NIC media channel
- *
- * Parameters:
- *  In:
- *      pDeviceHandler      - The adapter to be set
- *      uConnectionChannel  - Channel to be set
- *  Out:
- *      none
- *
- * Return Value: TRUE if succeeded; FALSE if failed.
- *
- */
-BOOL CARDbSetChannel (void *pDeviceHandler, UINT uConnectionChannel)
-{
-    PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    BOOL        bResult = TRUE;
-
-
-    if (pDevice->byCurrentCh == uConnectionChannel) {
-        return bResult;
-    }
-
-    if (sChannelTbl[uConnectionChannel].bValid == FALSE) {
-        return (FALSE);
-    }
-
-    if ((uConnectionChannel > CB_MAX_CHANNEL_24G) &&
-        (pDevice->eCurrentPHYType != PHY_TYPE_11A)) {
-        CARDbSetPhyParameter(pDevice, PHY_TYPE_11A, 0, 0, NULL, NULL);
-    } else if ((uConnectionChannel <= CB_MAX_CHANNEL_24G) &&
-        (pDevice->eCurrentPHYType == PHY_TYPE_11A)) {
-        CARDbSetPhyParameter(pDevice, PHY_TYPE_11G, 0, 0, NULL, NULL);
-    }
-    // clear NAV
-    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV);
-
-    //{{ RobertYu: 20041202
-    //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
-
-    if ( pDevice->byRFType == RF_AIROHA7230 )
-    {
-        RFbAL7230SelectChannelPostProcess(pDevice->PortOffset, pDevice->byCurrentCh, (BYTE)uConnectionChannel);
-    }
-    //}} RobertYu
-
-
-    pDevice->byCurrentCh = (BYTE)uConnectionChannel;
-    bResult &= RFbSelectChannel(pDevice->PortOffset, pDevice->byRFType, (BYTE)uConnectionChannel);
-
-    // Init Synthesizer Table
-    if (pDevice->bEnablePSMode == TRUE)
-        RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel);
-
-
-    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDbSetMediaChannel: %d\n", (BYTE)uConnectionChannel);
-    BBvSoftwareReset(pDevice->PortOffset);
-
-    if (pDevice->byLocalID > REV_ID_VT3253_B1) {
-        // set HW default power register
-        MACvSelectPage1(pDevice->PortOffset);
-        RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
-        VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWRCCK, pDevice->byCurPwr);
-        RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
-        VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr);
-        MACvSelectPage0(pDevice->PortOffset);
-    }
-
-    if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
-#ifdef PLICE_DEBUG
-       //printk("Func:CARDbSetChannel:call RFbSetPower:11B\n");
-#endif
-        RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
-    } else {
-#ifdef PLICE_DEBUG
-       //printk("Func:CARDbSetChannel:call RFbSetPower\n");
-#endif
-               RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
-    }
-
-    return(bResult);
-}
-
-
 
 /*
  * Description: Card Send packet function
@@ -849,11 +365,11 @@ BOOL CARDbSetChannel (void *pDeviceHandler, UINT uConnectionChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 /*
-BOOL CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, UINT uLength)
+bool CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, unsigned int uLength)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
     if (ePktType == PKT_TYPE_802_11_MNG) {
@@ -864,7 +380,7 @@ BOOL CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktTyp
         return TXbTD1Send(pDevice, pPacket, uLength);
     }
 
-    return (TRUE);
+    return (true);
 }
 */
 
@@ -878,16 +394,16 @@ BOOL CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktTyp
  *  Out:
  *      none
  *
- * Return Value: TRUE if short preamble; otherwise FALSE
+ * Return Value: true if short preamble; otherwise false
  *
  */
-BOOL CARDbIsShortPreamble (void *pDeviceHandler)
+bool CARDbIsShortPreamble (void *pDeviceHandler)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
     if (pDevice->byPreambleType == 0) {
-        return(FALSE);
+        return(false);
     }
-    return(TRUE);
+    return(true);
 }
 
 /*
@@ -899,10 +415,10 @@ BOOL CARDbIsShortPreamble (void *pDeviceHandler)
  *  Out:
  *      none
  *
- * Return Value: TRUE if short slot time; otherwise FALSE
+ * Return Value: true if short slot time; otherwise false
  *
  */
-BOOL CARDbIsShorSlotTime (void *pDeviceHandler)
+bool CARDbIsShorSlotTime (void *pDeviceHandler)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
     return(pDevice->bShortSlotTime);
@@ -921,14 +437,14 @@ BOOL CARDbIsShorSlotTime (void *pDeviceHandler)
  * Return Value: None.
  *
  */
-BOOL CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs)
+bool CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    BYTE        byCWMaxMin = 0;
-    BYTE        bySlot = 0;
-    BYTE        bySIFS = 0;
-    BYTE        byDIFS = 0;
-    BYTE        byData;
+    unsigned char byCWMaxMin = 0;
+    unsigned char bySlot = 0;
+    unsigned char bySIFS = 0;
+    unsigned char byDIFS = 0;
+    unsigned char byData;
 //    PWLAN_IE_SUPP_RATES pRates = NULL;
     PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs;
     PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs;
@@ -1071,9 +587,9 @@ BOOL CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wC
         pDevice->bySlot = bySlot;
         VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, pDevice->bySlot);
         if (pDevice->bySlot == C_SLOT_SHORT) {
-            pDevice->bShortSlotTime = TRUE;
+            pDevice->bShortSlotTime = true;
         } else {
-            pDevice->bShortSlotTime = FALSE;
+            pDevice->bShortSlotTime = false;
         }
         BBvSetShortSlotTime(pDevice);
     }
@@ -1089,7 +605,7 @@ BOOL CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wC
     s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates);
     pDevice->eCurrentPHYType = ePHYType;
     // set for NDIS OID_802_11SUPPORTED_RATES
-    return (TRUE);
+    return (true);
 }
 
 /*
@@ -1108,7 +624,7 @@ BOOL CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wC
  * Return Value: none
  *
  */
-BOOL CARDbUpdateTSF (void *pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF)
+bool CARDbUpdateTSF (void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
     QWORD       qwTSFOffset;
@@ -1125,7 +641,7 @@ BOOL CARDbUpdateTSF (void *pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp,
         VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, HIDWORD(qwTSFOffset));
         MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
     }
-    return(TRUE);
+    return(true);
 }
 
 
@@ -1140,16 +656,16 @@ BOOL CARDbUpdateTSF (void *pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp,
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeed; otherwise FALSE
+ * Return Value: true if succeed; otherwise false
  *
  */
-BOOL CARDbSetBeaconPeriod (void *pDeviceHandler, WORD wBeaconInterval)
+bool CARDbSetBeaconPeriod (void *pDeviceHandler, unsigned short wBeaconInterval)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    UINT        uBeaconInterval = 0;
-    UINT        uLowNextTBTT = 0;
-    UINT        uHighRemain = 0;
-    UINT        uLowRemain = 0;
+    unsigned int uBeaconInterval = 0;
+    unsigned int uLowNextTBTT = 0;
+    unsigned int uHighRemain = 0;
+    unsigned int uLowRemain = 0;
     QWORD       qwNextTBTT;
 
     HIDWORD(qwNextTBTT) = 0;
@@ -1179,7 +695,7 @@ BOOL CARDbSetBeaconPeriod (void *pDeviceHandler, WORD wBeaconInterval)
     VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT));
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
 
-    return(TRUE);
+    return(true);
 }
 
 
@@ -1194,51 +710,51 @@ BOOL CARDbSetBeaconPeriod (void *pDeviceHandler, WORD wBeaconInterval)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all data packet complete; otherwise FALSE.
+ * Return Value: true if all data packet complete; otherwise false.
  *
  */
-BOOL CARDbStopTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType)
+bool CARDbStopTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
 
 
     if (ePktType == PKT_TYPE_802_11_ALL) {
-        pDevice->bStopBeacon = TRUE;
-        pDevice->bStopTx0Pkt = TRUE;
-        pDevice->bStopDataPkt = TRUE;
+        pDevice->bStopBeacon = true;
+        pDevice->bStopTx0Pkt = true;
+        pDevice->bStopDataPkt = true;
     } else if (ePktType == PKT_TYPE_802_11_BCN) {
-        pDevice->bStopBeacon = TRUE;
+        pDevice->bStopBeacon = true;
     } else if (ePktType == PKT_TYPE_802_11_MNG) {
-        pDevice->bStopTx0Pkt = TRUE;
+        pDevice->bStopTx0Pkt = true;
     } else if (ePktType == PKT_TYPE_802_11_DATA) {
-        pDevice->bStopDataPkt = TRUE;
+        pDevice->bStopDataPkt = true;
     }
 
-    if (pDevice->bStopBeacon == TRUE) {
-        if (pDevice->bIsBeaconBufReadySet == TRUE) {
+    if (pDevice->bStopBeacon == true) {
+        if (pDevice->bIsBeaconBufReadySet == true) {
             if (pDevice->cbBeaconBufReadySetCnt < WAIT_BEACON_TX_DOWN_TMO) {
                 pDevice->cbBeaconBufReadySetCnt ++;
-                return(FALSE);
+                return(false);
             }
         }
-        pDevice->bIsBeaconBufReadySet = FALSE;
+        pDevice->bIsBeaconBufReadySet = false;
         pDevice->cbBeaconBufReadySetCnt = 0;
         MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
     }
     // wait all TD0 complete
-    if (pDevice->bStopTx0Pkt == TRUE) {
+    if (pDevice->bStopTx0Pkt == true) {
          if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){
-            return(FALSE);
+            return(false);
         }
     }
     // wait all Data TD complete
-    if (pDevice->bStopDataPkt == TRUE) {
+    if (pDevice->bStopDataPkt == true) {
         if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){
-            return(FALSE);
+            return(false);
         }
     }
 
-    return(TRUE);
+    return(true);
 }
 
 
@@ -1252,33 +768,33 @@ BOOL CARDbStopTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; FALSE if failed.
+ * Return Value: true if success; false if failed.
  *
  */
-BOOL CARDbStartTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType)
+bool CARDbStartTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
 
 
     if (ePktType == PKT_TYPE_802_11_ALL) {
-        pDevice->bStopBeacon = FALSE;
-        pDevice->bStopTx0Pkt = FALSE;
-        pDevice->bStopDataPkt = FALSE;
+        pDevice->bStopBeacon = false;
+        pDevice->bStopTx0Pkt = false;
+        pDevice->bStopDataPkt = false;
     } else if (ePktType == PKT_TYPE_802_11_BCN) {
-        pDevice->bStopBeacon = FALSE;
+        pDevice->bStopBeacon = false;
     } else if (ePktType == PKT_TYPE_802_11_MNG) {
-        pDevice->bStopTx0Pkt = FALSE;
+        pDevice->bStopTx0Pkt = false;
     } else if (ePktType == PKT_TYPE_802_11_DATA) {
-        pDevice->bStopDataPkt = FALSE;
+        pDevice->bStopDataPkt = false;
     }
 
-    if ((pDevice->bStopBeacon == FALSE) &&
-        (pDevice->bBeaconBufReady == TRUE) &&
+    if ((pDevice->bStopBeacon == false) &&
+        (pDevice->bBeaconBufReady == true) &&
         (pDevice->eOPMode == OP_MODE_ADHOC)) {
         MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
     }
 
-    return(TRUE);
+    return(true);
 }
 
 
@@ -1294,10 +810,10 @@ BOOL CARDbStartTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; FALSE if failed.
+ * Return Value: true if success; false if failed.
  *
  */
-BOOL CARDbSetBSSID(void *pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode)
+bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE eOPMode)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
 
@@ -1315,20 +831,20 @@ BOOL CARDbSetBSSID(void *pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode)
     }
     if (eOPMode == OP_MODE_UNKNOWN) {
         MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
-        pDevice->bBSSIDFilter = FALSE;
+        pDevice->bBSSIDFilter = false;
         pDevice->byRxMode &= ~RCR_BSSID;
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
     } else {
-        if (IS_NULL_ADDRESS(pDevice->abyBSSID) == FALSE) {
+        if (is_zero_ether_addr(pDevice->abyBSSID) == false) {
             MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
-            pDevice->bBSSIDFilter = TRUE;
+            pDevice->bBSSIDFilter = true;
             pDevice->byRxMode |= RCR_BSSID;
            }
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode );
     }
     // Adopt BSS state in Adapter Device Object
     pDevice->eOPMode = eOPMode;
-    return(TRUE);
+    return(true);
 }
 
 
@@ -1342,7 +858,7 @@ BOOL CARDbSetBSSID(void *pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; FALSE if failed.
+ * Return Value: true if success; false if failed.
  *
  */
 
@@ -1363,18 +879,18 @@ BOOL CARDbSetBSSID(void *pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeed; otherwise FALSE
+ * Return Value: true if succeed; otherwise false
  *
  */
-BOOL CARDbSetTxDataRate(
+bool CARDbSetTxDataRate(
     void *pDeviceHandler,
-    WORD    wDataRate
+    unsigned short wDataRate
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
 
     pDevice->wCurrentRate = wDataRate;
-    return(TRUE);
+    return(true);
 }
 
 /*+
@@ -1388,20 +904,20 @@ BOOL CARDbSetTxDataRate(
  *  Out:
  *      none
  *
- * Return Value: TRUE if power down success; otherwise FALSE
+ * Return Value: true if power down success; otherwise false
  *
 -*/
-BOOL
+bool
 CARDbPowerDown(
     void *pDeviceHandler
     )
 {
     PSDevice        pDevice = (PSDevice)pDeviceHandler;
-    UINT            uIdx;
+    unsigned int uIdx;
 
     // check if already in Doze mode
     if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS))
-        return TRUE;
+        return true;
 
     // Froce PSEN on
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
@@ -1410,12 +926,12 @@ CARDbPowerDown(
 
     for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) {
         if (pDevice->iTDUsed[uIdx] != 0)
-            return FALSE;
+            return false;
     }
 
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Go to Doze ZZZZZZZZZZZZZZZ\n");
-    return TRUE;
+    return true;
 }
 
 /*
@@ -1427,16 +943,16 @@ CARDbPowerDown(
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL CARDbRadioPowerOff (void *pDeviceHandler)
+bool CARDbRadioPowerOff (void *pDeviceHandler)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    BOOL        bResult = TRUE;
+    bool bResult = true;
 
-    if (pDevice->bRadioOff == TRUE)
-        return TRUE;
+    if (pDevice->bRadioOff == true)
+        return true;
 
 
     switch (pDevice->byRFType) {
@@ -1459,7 +975,7 @@ BOOL CARDbRadioPowerOff (void *pDeviceHandler)
 
     BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID);
 
-    pDevice->bRadioOff = TRUE;
+    pDevice->bRadioOff = true;
      //2007-0409-03,<Add> by chester
 printk("chester power off\n");
 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET);  //LED issue
@@ -1476,23 +992,23 @@ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET);  //LED issue
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL CARDbRadioPowerOn (void *pDeviceHandler)
+bool CARDbRadioPowerOn (void *pDeviceHandler)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    BOOL        bResult = TRUE;
+    bool bResult = true;
 printk("chester power on\n");
-    if (pDevice->bRadioControlOff == TRUE){
-if (pDevice->bHWRadioOff == TRUE) printk("chester bHWRadioOff\n");
-if (pDevice->bRadioControlOff == TRUE) printk("chester bRadioControlOff\n");
-        return FALSE;}
+    if (pDevice->bRadioControlOff == true){
+if (pDevice->bHWRadioOff == true) printk("chester bHWRadioOff\n");
+if (pDevice->bRadioControlOff == true) printk("chester bRadioControlOff\n");
+        return false;}
 
-    if (pDevice->bRadioOff == FALSE)
+    if (pDevice->bRadioOff == false)
        {
 printk("chester pbRadioOff\n");
-return TRUE;}
+return true;}
 
     BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID);
 
@@ -1514,7 +1030,7 @@ return TRUE;}
 
     }
 
-    pDevice->bRadioOff = FALSE;
+    pDevice->bRadioOff = false;
 //  2007-0409-03,<Add> by chester
 printk("chester power on\n");
 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue
@@ -1523,12 +1039,12 @@ MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue
 
 
 
-BOOL CARDbRemoveKey (void *pDeviceHandler, PBYTE pbyBSSID)
+bool CARDbRemoveKey (void *pDeviceHandler, unsigned char *pbyBSSID)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
 
     KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset);
-    return (TRUE);
+    return (true);
 }
 
 
@@ -1548,17 +1064,17 @@ BOOL CARDbRemoveKey (void *pDeviceHandler, PBYTE pbyBSSID)
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 CARDbAdd_PMKID_Candidate (
     void *pDeviceHandler,
-    PBYTE            pbyBSSID,
-    BOOL             bRSNCapExist,
-    WORD             wRSNCap
+    unsigned char *pbyBSSID,
+    bool bRSNCapExist,
+    unsigned short wRSNCap
     )
 {
     PSDevice            pDevice = (PSDevice) pDeviceHandler;
     PPMKID_CANDIDATE    pCandidateList;
-    UINT                ii = 0;
+    unsigned int ii = 0;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
 
@@ -1577,18 +1093,18 @@ CARDbAdd_PMKID_Candidate (
     for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
         pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
         if ( !memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
-            if ((bRSNCapExist == TRUE) && (wRSNCap & BIT0)) {
+            if ((bRSNCapExist == true) && (wRSNCap & BIT0)) {
                 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
             } else {
                 pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
             }
-            return TRUE;
+            return true;
         }
     }
 
     // New Candidate
     pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
-    if ((bRSNCapExist == TRUE) && (wRSNCap & BIT0)) {
+    if ((bRSNCapExist == true) && (wRSNCap & BIT0)) {
         pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
     } else {
         pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
@@ -1596,7 +1112,7 @@ CARDbAdd_PMKID_Candidate (
     memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
     pDevice->gsPMKIDCandidate.NumCandidates++;
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
-    return TRUE;
+    return true;
 }
 
 void *
@@ -1609,89 +1125,6 @@ CARDpGetCurrentAddress (
     return (pDevice->abyCurrentNetAddr);
 }
 
-
-
-void CARDvInitChannelTable (void *pDeviceHandler)
-{
-    PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    BOOL        bMultiBand = FALSE;
-    UINT        ii;
-
-    for(ii=1;ii<=CARD_MAX_CHANNEL_TBL;ii++) {
-        sChannelTbl[ii].bValid = FALSE;
-    }
-
-    switch (pDevice->byRFType) {
-        case RF_RFMD2959 :
-        case RF_AIROHA :
-        case RF_AL2230S:
-        case RF_UW2451 :
-        case RF_VT3226 :
-       //              printk("chester-false\n");
-            bMultiBand = FALSE;
-            break;
-        case RF_AIROHA7230 :
-        case RF_UW2452 :
-        case RF_NOTHING :
-        default :
-            bMultiBand = TRUE;
-            break;
-    }
-
-    if ((pDevice->dwDiagRefCount != 0) ||
-        (pDevice->b11hEnable == TRUE)) {
-        if (bMultiBand == TRUE) {
-            for(ii=0;ii<CARD_MAX_CHANNEL_TBL;ii++) {
-                sChannelTbl[ii+1].bValid = TRUE;
-                pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
-                pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
-            }
-            for(ii=0;ii<CHANNEL_MAX_24G;ii++) {
-                pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
-                pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
-            }
-        } else {
-            for(ii=0;ii<CHANNEL_MAX_24G;ii++) {
-//2008-8-4 <add> by chester
- if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
-                sChannelTbl[ii+1].bValid = TRUE;
-                pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
-                pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
-       }
-            }
-        }
-    } else if (pDevice->byZoneType <= CCODE_MAX) {
-        if (bMultiBand == TRUE) {
-            for(ii=0;ii<CARD_MAX_CHANNEL_TBL;ii++) {
-                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
-                    sChannelTbl[ii+1].bValid = TRUE;
-                    pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
-                    pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
-                }
-            }
-        } else {
-            for(ii=0;ii<CHANNEL_MAX_24G;ii++) {
-                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
-                    sChannelTbl[ii+1].bValid = TRUE;
-                    pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
-                    pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
-                }
-            }
-        }
-    }
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
-    for(ii=0;ii<CARD_MAX_CHANNEL_TBL;ii++) {
-        if (pDevice->abyRegPwr[ii+1] == 0) {
-            pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
-        }
-        if (pDevice->abyLocalPwr[ii+1] == 0) {
-            pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
-        }
-    }
-}
-
-
-
 /*
  *
  * Description:
@@ -1706,27 +1139,27 @@ void CARDvInitChannelTable (void *pDeviceHandler)
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 CARDbStartMeasure (
     void *pDeviceHandler,
     void *pvMeasureEIDs,
-    UINT             uNumOfMeasureEIDs
+    unsigned int uNumOfMeasureEIDs
     )
 {
     PSDevice                pDevice = (PSDevice) pDeviceHandler;
     PWLAN_IE_MEASURE_REQ    pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs;
     QWORD                   qwCurrTSF;
     QWORD                   qwStartTSF;
-    BOOL                    bExpired = TRUE;
-    WORD                    wDuration = 0;
+    bool bExpired = true;
+    unsigned short wDuration = 0;
 
     if ((pEID == NULL) ||
         (uNumOfMeasureEIDs == 0)) {
-        return (TRUE);
+        return (true);
     }
     CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
-    if (pDevice->bMeasureInProgress == TRUE) {
-        pDevice->bMeasureInProgress = FALSE;
+    if (pDevice->bMeasureInProgress == true) {
+        pDevice->bMeasureInProgress = false;
         VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
         MACvSelectPage1(pDevice->PortOffset);
         VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
@@ -1734,7 +1167,7 @@ CARDbStartMeasure (
         // clear measure control
         MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
         MACvSelectPage0(pDevice->PortOffset);
-        CARDbSetChannel(pDevice, pDevice->byOrgChannel);
+        set_channel(pDevice, pDevice->byOrgChannel);
         MACvSelectPage1(pDevice->PortOffset);
         MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
         MACvSelectPage0(pDevice->PortOffset);
@@ -1749,7 +1182,7 @@ CARDbStartMeasure (
         if (pDevice->byLocalID > REV_ID_VT3253_B1) {
             HIDWORD(qwStartTSF) = HIDWORD(*((PQWORD) (pDevice->pCurrMeasureEID->sReq.abyStartTime)));
             LODWORD(qwStartTSF) = LODWORD(*((PQWORD) (pDevice->pCurrMeasureEID->sReq.abyStartTime)));
-            wDuration = *((PWORD) (pDevice->pCurrMeasureEID->sReq.abyDuration));
+            wDuration = *((unsigned short *) (pDevice->pCurrMeasureEID->sReq.abyDuration));
             wDuration += 1; // 1 TU for channel switching
 
             if ((LODWORD(qwStartTSF) == 0) && (HIDWORD(qwStartTSF) == 0)) {
@@ -1759,7 +1192,7 @@ CARDbStartMeasure (
                 if (LODWORD(qwCurrTSF) > LODWORD(qwStartTSF)) {
                     HIDWORD(qwStartTSF)++;
                 }
-                bExpired = FALSE;
+                bExpired = false;
                 break;
             } else {
                 // start at setting start TSF - 1TU(for channel switching)
@@ -1773,11 +1206,11 @@ CARDbStartMeasure (
                 ((HIDWORD(qwCurrTSF) == HIDWORD(qwStartTSF)) &&
                 (LODWORD(qwCurrTSF) < LODWORD(qwStartTSF)))
                 ) {
-                bExpired = FALSE;
+                bExpired = false;
                 break;
             }
             VNTWIFIbMeasureReport(  pDevice->pMgmt,
-                                    FALSE,
+                                    false,
                                     pDevice->pCurrMeasureEID,
                                     MEASURE_MODE_LATE,
                                     pDevice->byBasicMap,
@@ -1787,7 +1220,7 @@ CARDbStartMeasure (
         } else {
             // hardware do not support measure
             VNTWIFIbMeasureReport(  pDevice->pMgmt,
-                                    FALSE,
+                                    false,
                                     pDevice->pCurrMeasureEID,
                                     MEASURE_MODE_INCAPABLE,
                                     pDevice->byBasicMap,
@@ -1797,7 +1230,7 @@ CARDbStartMeasure (
         }
     } while (pDevice->uNumOfMeasureEIDs != 0);
 
-    if (bExpired == FALSE) {
+    if (bExpired == false) {
         MACvSelectPage1(pDevice->PortOffset);
         VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF));
         VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF));
@@ -1807,7 +1240,7 @@ CARDbStartMeasure (
     } else {
         // all measure start time expired we should complete action
         VNTWIFIbMeasureReport(  pDevice->pMgmt,
-                                TRUE,
+                                true,
                                 NULL,
                                 0,
                                 pDevice->byBasicMap,
@@ -1815,7 +1248,7 @@ CARDbStartMeasure (
                                 pDevice->abyRPIs
                                 );
     }
-    return (TRUE);
+    return (true);
 }
 
 
@@ -1833,19 +1266,19 @@ CARDbStartMeasure (
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 CARDbChannelSwitch (
     void *pDeviceHandler,
-    BYTE             byMode,
-    BYTE             byNewChannel,
-    BYTE             byCount
+    unsigned char byMode,
+    unsigned char byNewChannel,
+    unsigned char byCount
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    BOOL        bResult = TRUE;
+    bool bResult = true;
 
     if (byCount == 0) {
-        bResult = CARDbSetChannel(pDevice, byNewChannel);
+        bResult = set_channel(pDevice, byNewChannel);
         VNTWIFIbChannelSwitch(pDevice->pMgmt, byNewChannel);
         MACvSelectPage1(pDevice->PortOffset);
         MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
@@ -1854,7 +1287,7 @@ CARDbChannelSwitch (
     }
     pDevice->byChannelSwitchCount = byCount;
     pDevice->byNewChannel = byNewChannel;
-    pDevice->bChannelSwitch = TRUE;
+    pDevice->bChannelSwitch = true;
     if (byMode == 1) {
         bResult=CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL);
     }
@@ -1876,34 +1309,34 @@ CARDbChannelSwitch (
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 CARDbSetQuiet (
     void *pDeviceHandler,
-    BOOL             bResetQuiet,
-    BYTE             byQuietCount,
-    BYTE             byQuietPeriod,
-    WORD             wQuietDuration,
-    WORD             wQuietOffset
+    bool bResetQuiet,
+    unsigned char byQuietCount,
+    unsigned char byQuietPeriod,
+    unsigned short wQuietDuration,
+    unsigned short wQuietOffset
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    UINT        ii = 0;
+    unsigned int ii = 0;
 
-    if (bResetQuiet == TRUE) {
+    if (bResetQuiet == true) {
         MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
         for(ii=0;ii<MAX_QUIET_COUNT;ii++) {
-            pDevice->sQuiet[ii].bEnable = FALSE;
+            pDevice->sQuiet[ii].bEnable = false;
         }
         pDevice->uQuietEnqueue = 0;
-        pDevice->bEnableFirstQuiet = FALSE;
-        pDevice->bQuietEnable = FALSE;
+        pDevice->bEnableFirstQuiet = false;
+        pDevice->bQuietEnable = false;
         pDevice->byQuietStartCount = byQuietCount;
     }
-    if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == FALSE) {
-        pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = TRUE;
+    if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == false) {
+        pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = true;
         pDevice->sQuiet[pDevice->uQuietEnqueue].byPeriod = byQuietPeriod;
         pDevice->sQuiet[pDevice->uQuietEnqueue].wDuration = wQuietDuration;
-        pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (DWORD) byQuietCount;
+        pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (unsigned long) byQuietCount;
         pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime *= pDevice->wBeaconInterval;
         pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime += wQuietOffset;
         pDevice->uQuietEnqueue++;
@@ -1914,7 +1347,7 @@ CARDbSetQuiet (
     } else {
         // we can not handle Quiet EID more
     }
-    return (TRUE);
+    return (true);
 }
 
 
@@ -1932,21 +1365,21 @@ CARDbSetQuiet (
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 CARDbStartQuiet (
     void *pDeviceHandler
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    UINT        ii = 0;
-    DWORD       dwStartTime = 0xFFFFFFFF;
-    UINT        uCurrentQuietIndex = 0;
-    DWORD       dwNextTime = 0;
-    DWORD       dwGap = 0;
-    DWORD       dwDuration = 0;
+    unsigned int ii = 0;
+    unsigned long dwStartTime = 0xFFFFFFFF;
+    unsigned int uCurrentQuietIndex = 0;
+    unsigned long dwNextTime = 0;
+    unsigned long dwGap = 0;
+    unsigned long dwDuration = 0;
 
     for(ii=0;ii<MAX_QUIET_COUNT;ii++) {
-        if ((pDevice->sQuiet[ii].bEnable == TRUE) &&
+        if ((pDevice->sQuiet[ii].bEnable == true) &&
             (dwStartTime > pDevice->sQuiet[ii].dwStartTime)) {
             dwStartTime = pDevice->sQuiet[ii].dwStartTime;
             uCurrentQuietIndex = ii;
@@ -1954,22 +1387,22 @@ CARDbStartQuiet (
     }
     if (dwStartTime == 0xFFFFFFFF) {
         // no more quiet
-        pDevice->bQuietEnable = FALSE;
+        pDevice->bQuietEnable = false;
         MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
     } else {
-        if (pDevice->bQuietEnable == FALSE) {
+        if (pDevice->bQuietEnable == false) {
             // first quiet
             pDevice->byQuietStartCount--;
             dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
             dwNextTime %= pDevice->wBeaconInterval;
             MACvSelectPage1(pDevice->PortOffset);
-            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (WORD) dwNextTime);
-            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (WORD) pDevice->sQuiet[uCurrentQuietIndex].wDuration);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (unsigned short) dwNextTime);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) pDevice->sQuiet[uCurrentQuietIndex].wDuration);
             if (pDevice->byQuietStartCount == 0) {
-                pDevice->bEnableFirstQuiet = FALSE;
+                pDevice->bEnableFirstQuiet = false;
                 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
             } else {
-                pDevice->bEnableFirstQuiet = TRUE;
+                pDevice->bEnableFirstQuiet = true;
             }
             MACvSelectPage0(pDevice->PortOffset);
         } else {
@@ -1977,8 +1410,8 @@ CARDbStartQuiet (
                 // overlap with previous Quiet
                 dwGap =  pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
                 if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) {
-                    // return FALSE to indicate next quiet expired, should call this function again
-                    return (FALSE);
+                    // return false to indicate next quiet expired, should call this function again
+                    return (false);
                 }
                 dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap;
                 dwGap = 0;
@@ -1988,94 +1421,34 @@ CARDbStartQuiet (
             }
             // set GAP and Next duration
             MACvSelectPage1(pDevice->PortOffset);
-            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (WORD) dwGap);
-            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (WORD) dwDuration);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (unsigned short) dwGap);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) dwDuration);
             MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_QUIETRPT);
             MACvSelectPage0(pDevice->PortOffset);
         }
-        pDevice->bQuietEnable = TRUE;
+        pDevice->bQuietEnable = true;
         pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
         pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration;
         if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) {
             // not period disable current quiet element
-            pDevice->sQuiet[uCurrentQuietIndex].bEnable = FALSE;
+            pDevice->sQuiet[uCurrentQuietIndex].bEnable = false;
         } else {
             // set next period start time
-            dwNextTime = (DWORD) pDevice->sQuiet[uCurrentQuietIndex].byPeriod;
+            dwNextTime = (unsigned long) pDevice->sQuiet[uCurrentQuietIndex].byPeriod;
             dwNextTime *= pDevice->wBeaconInterval;
             pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime;
         }
         if (pDevice->dwCurrentQuietEndTime > 0x80010000) {
             // decreament all time to avoid wrap around
             for(ii=0;ii<MAX_QUIET_COUNT;ii++) {
-                if (pDevice->sQuiet[ii].bEnable == TRUE) {
+                if (pDevice->sQuiet[ii].bEnable == true) {
                     pDevice->sQuiet[ii].dwStartTime -= 0x80000000;
                 }
             }
             pDevice->dwCurrentQuietEndTime -= 0x80000000;
         }
     }
-    return (TRUE);
-}
-
-
-/*
- *
- * Description:
- *    Set Channel Info of Country
- *
- * Parameters:
- *  In:
- *      hDeviceContext - device structure point
- *  Out:
- *      none
- *
- * Return Value: none.
- *
--*/
-void
-CARDvSetCountryInfo (
-    void *pDeviceHandler,
-    CARD_PHY_TYPE    ePHYType,
-    void *pIE
-    )
-{
-    PSDevice            pDevice = (PSDevice) pDeviceHandler;
-    UINT                ii = 0;
-    UINT                uu = 0;
-    UINT                step = 0;
-    UINT                uNumOfCountryInfo = 0;
-    BYTE                byCh = 0;
-    PWLAN_IE_COUNTRY    pIE_Country = (PWLAN_IE_COUNTRY) pIE;
-
-
-    uNumOfCountryInfo = (pIE_Country->len - 3);
-    uNumOfCountryInfo /= 3;
-
-    if (ePHYType == PHY_TYPE_11A) {
-        pDevice->bCountryInfo5G = TRUE;
-        for(ii=CB_MAX_CHANNEL_24G+1;ii<=CARD_MAX_CHANNEL_TBL;ii++) {
-            sChannelTbl[ii].bValid = FALSE;
-        }
-        step = 4;
-    } else {
-        pDevice->bCountryInfo24G = TRUE;
-        for(ii=1;ii<=CB_MAX_CHANNEL_24G;ii++) {
-            sChannelTbl[ii].bValid = FALSE;
-        }
-        step = 1;
-    }
-    pDevice->abyCountryCode[0] = pIE_Country->abyCountryString[0];
-    pDevice->abyCountryCode[1] = pIE_Country->abyCountryString[1];
-    pDevice->abyCountryCode[2] = pIE_Country->abyCountryString[2];
-
-    for(ii=0;ii<uNumOfCountryInfo;ii++) {
-        for(uu=0;uu<pIE_Country->abyCountryInfo[ii*3+1];uu++) {
-            byCh = CARDbyGetChannelMapping(pDevice, (BYTE)(pIE_Country->abyCountryInfo[ii*3]+step*uu), ePHYType);
-            sChannelTbl[byCh].bValid = TRUE;
-            pDevice->abyRegPwr[byCh] = pIE_Country->abyCountryInfo[ii*3+2];
-        }
-    }
+    return (true);
 }
 
 /*
@@ -2095,18 +1468,18 @@ CARDvSetCountryInfo (
 void
 CARDvSetPowerConstraint (
     void *pDeviceHandler,
-    BYTE             byChannel,
-    I8               byPower
+    unsigned char byChannel,
+    char byPower
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
 
     if (byChannel > CB_MAX_CHANNEL_24G) {
-        if (pDevice->bCountryInfo5G == TRUE) {
+        if (pDevice->bCountryInfo5G == true) {
             pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower;
         }
     } else {
-        if (pDevice->bCountryInfo24G == TRUE) {
+        if (pDevice->bCountryInfo24G == true) {
             pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower;
         }
     }
@@ -2130,12 +1503,12 @@ CARDvSetPowerConstraint (
 void
 CARDvGetPowerCapability (
     void *pDeviceHandler,
-    PBYTE           pbyMinPower,
-    PBYTE           pbyMaxPower
+    unsigned char *pbyMinPower,
+    unsigned char *pbyMaxPower
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    BYTE        byDec = 0;
+    unsigned char byDec = 0;
 
     *pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh];
     byDec = pDevice->abyOFDMPwrTbl[pDevice->byCurrentCh];
@@ -2148,98 +1521,6 @@ CARDvGetPowerCapability (
     *pbyMinPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh] - byDec;
 }
 
-
-/*
- *
- * Description:
- *    Set Support Channels IE defined in 802.11h
- *
- * Parameters:
- *  In:
- *      hDeviceContext - device structure point
- *  Out:
- *      none
- *
- * Return Value: none.
- *
--*/
-BYTE
-CARDbySetSupportChannels (
-    void *pDeviceHandler,
-    PBYTE        pbyIEs
-    )
-{
-    PSDevice            pDevice = (PSDevice) pDeviceHandler;
-    UINT                ii;
-    BYTE                byCount;
-    PWLAN_IE_SUPP_CH    pIE = (PWLAN_IE_SUPP_CH) pbyIEs;
-    PBYTE               pbyChTupple;
-    BYTE                byLen = 0;
-
-
-    pIE->byElementID = WLAN_EID_SUPP_CH;
-    pIE->len = 0;
-    pbyChTupple = pIE->abyChannelTuple;
-    byLen = 2;
-    // lower band
-    byCount = 0;
-    if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[28] == TRUE) {
-        for (ii=28;ii<36;ii+=2) {
-            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
-                byCount++;
-            }
-        }
-        *pbyChTupple++ = 34;
-        *pbyChTupple++ = byCount;
-        byLen += 2;
-    } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[29] == TRUE) {
-        for (ii=29;ii<36;ii+=2) {
-            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
-                byCount++;
-            }
-        }
-        *pbyChTupple++ = 36;
-        *pbyChTupple++ = byCount;
-        byLen += 2;
-    }
-    // middle band
-    byCount = 0;
-    if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[36] == TRUE) {
-        for (ii=36;ii<40;ii++) {
-            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
-                byCount++;
-            }
-        }
-        *pbyChTupple++ = 52;
-        *pbyChTupple++ = byCount;
-        byLen += 2;
-    }
-    // higher band
-    byCount = 0;
-    if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[40] == TRUE) {
-        for (ii=40;ii<51;ii++) {
-            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
-                byCount++;
-            }
-        }
-        *pbyChTupple++ = 100;
-        *pbyChTupple++ = byCount;
-        byLen += 2;
-    } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[51] == TRUE) {
-        for (ii=51;ii<56;ii++) {
-            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
-                byCount++;
-            }
-        }
-        *pbyChTupple++ = 149;
-        *pbyChTupple++ = byCount;
-        byLen += 2;
-    }
-    pIE->len += (byLen - 2);
-    return (byLen);
-}
-
-
 /*
  *
  * Description:
@@ -2253,8 +1534,8 @@ CARDbySetSupportChannels (
  *
  * Return Value: none.
  *
--*/
-I8
+ */
+char
 CARDbyGetTransmitPower (
     void *pDeviceHandler
     )
@@ -2264,161 +1545,6 @@ CARDbyGetTransmitPower (
     return (pDevice->byCurPwrdBm);
 }
 
-
-BOOL
-CARDbChannelGetList (
-     UINT       uCountryCodeIdx,
-    PBYTE      pbyChannelTable
-    )
-{
-    if (uCountryCodeIdx >= CCODE_MAX) {
-        return (FALSE);
-    }
-    memcpy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL);
-    return (TRUE);
-}
-
-
-void
-CARDvSetCountryIE(
-    void *pDeviceHandler,
-    void *pIE
-    )
-{
-    PSDevice            pDevice = (PSDevice) pDeviceHandler;
-    UINT                ii;
-    PWLAN_IE_COUNTRY    pIECountry = (PWLAN_IE_COUNTRY) pIE;
-
-    pIECountry->byElementID = WLAN_EID_COUNTRY;
-    pIECountry->len = 0;
-    pIECountry->abyCountryString[0] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[0];
-    pIECountry->abyCountryString[1] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[1];
-    pIECountry->abyCountryString[2] = ' ';
-    for (ii = CB_MAX_CHANNEL_24G; ii < CB_MAX_CHANNEL; ii++ ) {
-        if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
-            pIECountry->abyCountryInfo[pIECountry->len++] = sChannelTbl[ii+1].byChannelNumber;
-            pIECountry->abyCountryInfo[pIECountry->len++] = 1;
-            pIECountry->abyCountryInfo[pIECountry->len++] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
-        }
-    }
-    pIECountry->len += 3;
-}
-
-
-BOOL
-CARDbGetChannelMapInfo(
-    void *pDeviceHandler,
-    UINT         uChannelIndex,
-    PBYTE       pbyChannelNumber,
-    PBYTE       pbyMap
-    )
-{
-//    PSDevice            pDevice = (PSDevice) pDeviceHandler;
-
-    if (uChannelIndex > CB_MAX_CHANNEL) {
-        return FALSE;
-    }
-    *pbyChannelNumber = sChannelTbl[uChannelIndex].byChannelNumber;
-    *pbyMap = sChannelTbl[uChannelIndex].byMAP;
-    return sChannelTbl[uChannelIndex].bValid;
-}
-
-
-void
-CARDvSetChannelMapInfo(
-    void *pDeviceHandler,
-    UINT         uChannelIndex,
-    BYTE         byMap
-    )
-{
-//    PSDevice            pDevice = (PSDevice) pDeviceHandler;
-
-    if (uChannelIndex > CB_MAX_CHANNEL) {
-        return;
-    }
-    sChannelTbl[uChannelIndex].byMAP |= byMap;
-}
-
-
-void
-CARDvClearChannelMapInfo(
-    void *pDeviceHandler
-    )
-{
-//    PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    UINT        ii = 0;
-
-    for (ii = 1; ii <=  CB_MAX_CHANNEL; ii++) {
-        sChannelTbl[ii].byMAP = 0;
-    }
-}
-
-
-BYTE
-CARDbyAutoChannelSelect(
-    void *pDeviceHandler,
-    CARD_PHY_TYPE   ePHYType
-    )
-{
-//    PSDevice        pDevice = (PSDevice) pDeviceHandler;
-    UINT            ii = 0;
-    BYTE            byOptionChannel = 0;
-    INT             aiWeight[CB_MAX_CHANNEL_24G+1] = {-1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-    if (ePHYType == PHY_TYPE_11A) {
-        for(ii=CB_MAX_CHANNEL_24G+1;ii<=CB_MAX_CHANNEL;ii++) {
-            if (sChannelTbl[ii].bValid == TRUE) {
-                if (byOptionChannel == 0) {
-                    byOptionChannel = (BYTE) ii;
-                }
-                if (sChannelTbl[ii].byMAP == 0) {
-                    return ((BYTE) ii);
-                } else if ( !(sChannelTbl[ii].byMAP & 0x08)) {
-                    byOptionChannel = (BYTE) ii;
-                }
-            }
-        }
-    } else {
-        byOptionChannel = 0;
-        for(ii=1;ii<=CB_MAX_CHANNEL_24G;ii++) {
-            if (sChannelTbl[ii].bValid == TRUE) {
-                if (sChannelTbl[ii].byMAP == 0) {
-                    aiWeight[ii] += 100;
-                } else if (sChannelTbl[ii].byMAP & 0x01) {
-                    if (ii > 3) {
-                        aiWeight[ii-3] -= 10;
-                    }
-                    if (ii > 2) {
-                        aiWeight[ii-2] -= 20;
-                    }
-                    if (ii > 1) {
-                        aiWeight[ii-1] -= 40;
-                    }
-                    aiWeight[ii] -= 80;
-                    if (ii < CB_MAX_CHANNEL_24G) {
-                        aiWeight[ii+1] -= 40;
-                    }
-                    if (ii < (CB_MAX_CHANNEL_24G - 1)) {
-                        aiWeight[ii+2] -= 20;
-                    }
-                    if (ii < (CB_MAX_CHANNEL_24G - 2)) {
-                        aiWeight[ii+3] -= 10;
-                    }
-                }
-            }
-        }
-        for(ii=1;ii<=CB_MAX_CHANNEL_24G;ii++) {
-            if ((sChannelTbl[ii].bValid == TRUE) &&
-                (aiWeight[ii] > aiWeight[byOptionChannel])) {
-                byOptionChannel = (BYTE) ii;
-            }
-        }
-    }
-    return (byOptionChannel);
-}
-
-
-
 //xxx
 void
 CARDvSafeResetTx (
@@ -2426,7 +1552,7 @@ CARDvSafeResetTx (
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    UINT        uu;
+    unsigned int uu;
     PSTxDesc    pCurrTD;
 
     // initialize TD index
@@ -2482,7 +1608,7 @@ CARDvSafeResetRx (
     )
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    UINT        uu;
+    unsigned int uu;
     PSRxDesc    pDesc;
 
 
@@ -2494,17 +1620,17 @@ CARDvSafeResetRx (
     // init state, all RD is chip's
     for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) {
         pDesc =&(pDevice->aRD0Ring[uu]);
-        pDesc->m_rd0RD0.wResCount = (WORD)(pDevice->rx_buf_sz);
+        pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz);
         pDesc->m_rd0RD0.f1Owner=OWNED_BY_NIC;
-        pDesc->m_rd1RD1.wReqCount = (WORD)(pDevice->rx_buf_sz);
+        pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz);
     }
 
     // init state, all RD is chip's
     for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) {
         pDesc =&(pDevice->aRD1Ring[uu]);
-        pDesc->m_rd0RD0.wResCount = (WORD)(pDevice->rx_buf_sz);
+        pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz);
         pDesc->m_rd0RD0.f1Owner=OWNED_BY_NIC;
-        pDesc->m_rd1RD1.wReqCount = (WORD)(pDevice->rx_buf_sz);
+        pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz);
     }
 
     pDevice->cbDFCB = CB_MAX_RX_FRAG;
@@ -2537,18 +1663,18 @@ CARDvSafeResetRx (
  * Return Value: response Control frame rate
  *
  */
-WORD CARDwGetCCKControlRate(void *pDeviceHandler, WORD wRateIdx)
+unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRateIdx)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
-    UINT ui = (UINT)wRateIdx;
+    unsigned int ui = (unsigned int) wRateIdx;
 
     while (ui > RATE_1M) {
-        if (pDevice->wBasicRate & ((WORD)1 << ui)) {
-            return (WORD)ui;
+        if (pDevice->wBasicRate & ((unsigned short)1 << ui)) {
+            return (unsigned short)ui;
         }
         ui --;
     }
-    return (WORD)RATE_1M;
+    return (unsigned short)RATE_1M;
 }
 
 /*
@@ -2564,10 +1690,10 @@ WORD CARDwGetCCKControlRate(void *pDeviceHandler, WORD wRateIdx)
  * Return Value: response Control frame rate
  *
  */
-WORD CARDwGetOFDMControlRate (void *pDeviceHandler, WORD wRateIdx)
+unsigned short CARDwGetOFDMControlRate (void *pDeviceHandler, unsigned short wRateIdx)
 {
     PSDevice pDevice = (PSDevice) pDeviceHandler;
-    UINT ui = (UINT)wRateIdx;
+    unsigned int ui = (unsigned int) wRateIdx;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate);
 
@@ -2578,14 +1704,14 @@ WORD CARDwGetOFDMControlRate (void *pDeviceHandler, WORD wRateIdx)
         return wRateIdx;
     }
     while (ui > RATE_11M) {
-        if (pDevice->wBasicRate & ((WORD)1 << ui)) {
+        if (pDevice->wBasicRate & ((unsigned short)1 << ui)) {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate : %d\n", ui);
-            return (WORD)ui;
+            return (unsigned short)ui;
         }
         ui --;
     }
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate: 6M\n");
-    return (WORD)RATE_24M;
+    return (unsigned short)RATE_24M;
 }
 
 
@@ -2604,9 +1730,9 @@ WORD CARDwGetOFDMControlRate (void *pDeviceHandler, WORD wRateIdx)
 void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType)
 {
     PSDevice pDevice = (PSDevice) pDeviceHandler;
-    BYTE  byServ = 0x00, bySignal = 0x00; //For CCK
-    WORD  wLen = 0x0000;
-    BYTE  byTxRate, byRsvTime;             //For OFDM
+    unsigned char byServ = 0x00, bySignal = 0x00; //For CCK
+    unsigned short wLen = 0x0000;
+    unsigned char byTxRate, byRsvTime;             //For OFDM
 
     //Set to Page1
     MACvSelectPage1(pDevice->PortOffset);
@@ -2731,7 +1857,7 @@ void vUpdateIFS (void *pDeviceHandler)
     //Set SIFS, DIFS, EIFS, SlotTime, CwMin
     PSDevice pDevice = (PSDevice) pDeviceHandler;
 
-    BYTE byMaxMin = 0;
+    unsigned char byMaxMin = 0;
     if (pDevice->byPacketType==PK_TYPE_11A) {//0000 0000 0000 0000,11a
         pDevice->uSlot = C_SLOT_SHORT;
         pDevice->uSIFS = C_SIFS_A;
@@ -2768,27 +1894,27 @@ void vUpdateIFS (void *pDeviceHandler)
     pDevice->uEIFS = C_EIFS;
     if (pDevice->byRFType == RF_RFMD2959) {
         // bcs TX_PE will reserve 3 us
-        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (BYTE)(pDevice->uSIFS - 3));
-        VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (BYTE)(pDevice->uDIFS - 3));
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)(pDevice->uSIFS - 3));
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)(pDevice->uDIFS - 3));
     } else {
-        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (BYTE)pDevice->uSIFS);
-        VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (BYTE)pDevice->uDIFS);
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)pDevice->uSIFS);
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)pDevice->uDIFS);
     }
-    VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (BYTE)pDevice->uEIFS);
-    VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (BYTE)pDevice->uSlot);
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (unsigned char)pDevice->uEIFS);
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (unsigned char)pDevice->uSlot);
     byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023
-    VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (BYTE)byMaxMin);
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (unsigned char)byMaxMin);
 }
 
 void CARDvUpdateBasicTopRate (void *pDeviceHandler)
 {
     PSDevice pDevice = (PSDevice) pDeviceHandler;
-    BYTE byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
-    BYTE ii;
+    unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
+    unsigned char ii;
 
      //Determines the highest basic rate.
      for (ii = RATE_54M; ii >= RATE_6M; ii --) {
-         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
+         if ( (pDevice->wBasicRate) & ((unsigned short)(1<<ii)) ) {
              byTopOFDM = ii;
              break;
          }
@@ -2796,7 +1922,7 @@ void CARDvUpdateBasicTopRate (void *pDeviceHandler)
      pDevice->byTopOFDMBasicRate = byTopOFDM;
 
      for (ii = RATE_11M;; ii --) {
-         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
+         if ( (pDevice->wBasicRate) & ((unsigned short)(1<<ii)) ) {
              byTopCCK = ii;
              break;
          }
@@ -2817,40 +1943,40 @@ void CARDvUpdateBasicTopRate (void *pDeviceHandler)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL CARDbAddBasicRate (void *pDeviceHandler, WORD wRateIdx)
+bool CARDbAddBasicRate (void *pDeviceHandler, unsigned short wRateIdx)
 {
     PSDevice pDevice = (PSDevice) pDeviceHandler;
-    WORD wRate = (WORD)(1<<wRateIdx);
+    unsigned short wRate = (unsigned short)(1<<wRateIdx);
 
     pDevice->wBasicRate |= wRate;
 
     //Determines the highest basic rate.
     CARDvUpdateBasicTopRate((void *)pDevice);
 
-    return(TRUE);
+    return(true);
 }
 
-BOOL CARDbIsOFDMinBasicRate (void *pDeviceHandler)
+bool CARDbIsOFDMinBasicRate (void *pDeviceHandler)
 {
     PSDevice pDevice = (PSDevice) pDeviceHandler;
     int ii;
 
     for (ii = RATE_54M; ii >= RATE_6M; ii --) {
-        if ((pDevice->wBasicRate) & ((WORD)(1<<ii)))
-            return TRUE;
+        if ((pDevice->wBasicRate) & ((unsigned short)(1<<ii)))
+            return true;
     }
-    return FALSE;
+    return false;
 }
 
-BYTE CARDbyGetPktType (void *pDeviceHandler)
+unsigned char CARDbyGetPktType (void *pDeviceHandler)
 {
     PSDevice pDevice = (PSDevice) pDeviceHandler;
 
     if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
-        return (BYTE)pDevice->byBBType;
+        return (unsigned char)pDevice->byBBType;
     }
     else if (CARDbIsOFDMinBasicRate((void *)pDevice)) {
         return PK_TYPE_11GA;
@@ -2873,7 +1999,7 @@ BYTE CARDbyGetPktType (void *pDeviceHandler)
  * Return Value: none
  *
  */
-void CARDvSetLoopbackMode (DWORD_PTR dwIoBase, WORD wLoopbackMode)
+void CARDvSetLoopbackMode (unsigned long dwIoBase, unsigned short wLoopbackMode)
 {
     switch(wLoopbackMode) {
     case CARD_LB_NONE:
@@ -2881,7 +2007,7 @@ void CARDvSetLoopbackMode (DWORD_PTR dwIoBase, WORD wLoopbackMode)
     case CARD_LB_PHY:
         break;
     default:
-        ASSERT(FALSE);
+        ASSERT(false);
         break;
     }
     // set MAC loopback
@@ -2902,15 +2028,15 @@ void CARDvSetLoopbackMode (DWORD_PTR dwIoBase, WORD wLoopbackMode)
  * Return Value: none
  *
  */
-BOOL CARDbSoftwareReset (void *pDeviceHandler)
+bool CARDbSoftwareReset (void *pDeviceHandler)
 {
     PSDevice pDevice = (PSDevice) pDeviceHandler;
 
     // reset MAC
     if (!MACbSafeSoftwareReset(pDevice->PortOffset))
-        return FALSE;
+        return false;
 
-    return TRUE;
+    return true;
 }
 
 
@@ -2929,16 +2055,16 @@ BOOL CARDbSoftwareReset (void *pDeviceHandler)
  * Return Value: TSF Offset value
  *
  */
-QWORD CARDqGetTSFOffset (BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2)
+QWORD CARDqGetTSFOffset (unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2)
 {
     QWORD   qwTSFOffset;
-    WORD    wRxBcnTSFOffst= 0;;
+    unsigned short wRxBcnTSFOffst= 0;;
 
     HIDWORD(qwTSFOffset) = 0;
     LODWORD(qwTSFOffset) = 0;
     wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE];
-    (qwTSF2).u.dwLowDword += (DWORD)(wRxBcnTSFOffst);
-    if ((qwTSF2).u.dwLowDword < (DWORD)(wRxBcnTSFOffst)) {
+    (qwTSF2).u.dwLowDword += (unsigned long)(wRxBcnTSFOffst);
+    if ((qwTSF2).u.dwLowDword < (unsigned long)(wRxBcnTSFOffst)) {
         (qwTSF2).u.dwHighDword++;
     }
     LODWORD(qwTSFOffset) = LODWORD(qwTSF1) - LODWORD(qwTSF2);
@@ -2963,13 +2089,13 @@ QWORD CARDqGetTSFOffset (BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2)
  *  Out:
  *      qwCurrTSF       - Current TSF counter
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL CARDbGetCurrentTSF (DWORD_PTR dwIoBase, PQWORD pqwCurrTSF)
+bool CARDbGetCurrentTSF (unsigned long dwIoBase, PQWORD pqwCurrTSF)
 {
-    WORD    ww;
-    BYTE    byData;
+    unsigned short ww;
+    unsigned char byData;
 
     MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
@@ -2978,11 +2104,11 @@ BOOL CARDbGetCurrentTSF (DWORD_PTR dwIoBase, PQWORD pqwCurrTSF)
             break;
     }
     if (ww == W_MAX_TIMEOUT)
-        return(FALSE);
+        return(false);
     VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, &LODWORD(*pqwCurrTSF));
     VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, &HIDWORD(*pqwCurrTSF));
 
-    return(TRUE);
+    return(true);
 }
 
 
@@ -3000,12 +2126,12 @@ BOOL CARDbGetCurrentTSF (DWORD_PTR dwIoBase, PQWORD pqwCurrTSF)
  * Return Value: TSF value of next Beacon
  *
  */
-QWORD CARDqGetNextTBTT (QWORD qwTSF, WORD wBeaconInterval)
+QWORD CARDqGetNextTBTT (QWORD qwTSF, unsigned short wBeaconInterval)
 {
 
-    UINT    uLowNextTBTT;
-    UINT    uHighRemain, uLowRemain;
-    UINT    uBeaconInterval;
+    unsigned int uLowNextTBTT;
+    unsigned int uHighRemain, uLowRemain;
+    unsigned int uBeaconInterval;
 
     uBeaconInterval = wBeaconInterval * 1024;
     // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
@@ -3044,7 +2170,7 @@ QWORD CARDqGetNextTBTT (QWORD qwTSF, WORD wBeaconInterval)
  * Return Value: none
  *
  */
-void CARDvSetFirstNextTBTT (DWORD_PTR dwIoBase, WORD wBeaconInterval)
+void CARDvSetFirstNextTBTT (unsigned long dwIoBase, unsigned short wBeaconInterval)
 {
 
     QWORD   qwNextTBTT;
@@ -3077,7 +2203,7 @@ void CARDvSetFirstNextTBTT (DWORD_PTR dwIoBase, WORD wBeaconInterval)
  * Return Value: none
  *
  */
-void CARDvUpdateNextTBTT (DWORD_PTR dwIoBase, QWORD qwTSF, WORD wBeaconInterval)
+void CARDvUpdateNextTBTT (unsigned long dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval)
 {
 
     qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
@@ -3085,7 +2211,8 @@ void CARDvUpdateNextTBTT (DWORD_PTR dwIoBase, QWORD qwTSF, WORD wBeaconInterval)
     VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF));
     VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF));
     MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n",(UINT)HIDWORD(qwTSF), (UINT)LODWORD(qwTSF));
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n",
+                   (unsigned int) HIDWORD(qwTSF), (unsigned int) LODWORD(qwTSF));
 
     return;
 }
index 76313462cf761e3c39f175b1b21ad8c25954188d..e0836e1d5116aec0e60c3449145a5eb56cc5b775 100644 (file)
@@ -30,6 +30,7 @@
 #define __CARD_H__
 
 #include "ttype.h"
+#include <linux/types.h>
 
 /*---------------------  Export Definitions -------------------------*/
 //
@@ -86,57 +87,55 @@ typedef enum _CARD_OP_MODE {
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL ChannelValid(UINT CountryCode, UINT ChannelIndex);
 void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType);
 void vUpdateIFS(void *pDeviceHandler);
 void CARDvUpdateBasicTopRate(void *pDeviceHandler);
-BOOL CARDbAddBasicRate(void *pDeviceHandler, WORD wRateIdx);
-BOOL CARDbIsOFDMinBasicRate(void *pDeviceHandler);
-void CARDvSetLoopbackMode(DWORD_PTR dwIoBase, WORD wLoopbackMode);
-BOOL CARDbSoftwareReset(void *pDeviceHandler);
-void CARDvSetFirstNextTBTT(DWORD_PTR dwIoBase, WORD wBeaconInterval);
-void CARDvUpdateNextTBTT(DWORD_PTR dwIoBase, QWORD qwTSF, WORD wBeaconInterval);
-BOOL CARDbGetCurrentTSF(DWORD_PTR dwIoBase, PQWORD pqwCurrTSF);
-QWORD CARDqGetNextTBTT(QWORD qwTSF, WORD wBeaconInterval);
-QWORD CARDqGetTSFOffset(BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2);
-BOOL CARDbSetTxPower(void *pDeviceHandler, ULONG ulTxPower);
-BYTE CARDbyGetPktType(void *pDeviceHandler);
+bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx);
+bool CARDbIsOFDMinBasicRate(void *pDeviceHandler);
+void CARDvSetLoopbackMode(unsigned long dwIoBase, unsigned short wLoopbackMode);
+bool CARDbSoftwareReset(void *pDeviceHandler);
+void CARDvSetFirstNextTBTT(unsigned long dwIoBase, unsigned short wBeaconInterval);
+void CARDvUpdateNextTBTT(unsigned long dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval);
+bool CARDbGetCurrentTSF(unsigned long dwIoBase, PQWORD pqwCurrTSF);
+QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval);
+QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2);
+bool CARDbSetTxPower(void *pDeviceHandler, unsigned long ulTxPower);
+unsigned char CARDbyGetPktType(void *pDeviceHandler);
 void CARDvSafeResetTx(void *pDeviceHandler);
 void CARDvSafeResetRx(void *pDeviceHandler);
 
 //xxx
-BOOL CARDbRadioPowerOff(void *pDeviceHandler);
-BOOL CARDbRadioPowerOn(void *pDeviceHandler);
-BOOL CARDbSetChannel(void *pDeviceHandler, UINT uConnectionChannel);
-//BOOL CARDbSendPacket(void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, UINT uLength);
-BOOL CARDbIsShortPreamble(void *pDeviceHandler);
-BOOL CARDbIsShorSlotTime(void *pDeviceHandler);
-BOOL CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs);
-BOOL CARDbUpdateTSF(void *pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF);
-BOOL CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType);
-BOOL CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType);
-BOOL CARDbSetBeaconPeriod(void *pDeviceHandler, WORD wBeaconInterval);
-BOOL CARDbSetBSSID(void *pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode);
-
-BOOL
+bool CARDbRadioPowerOff(void *pDeviceHandler);
+bool CARDbRadioPowerOn(void *pDeviceHandler);
+//bool CARDbSendPacket(void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, unsigned int uLength);
+bool CARDbIsShortPreamble(void *pDeviceHandler);
+bool CARDbIsShorSlotTime(void *pDeviceHandler);
+bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs);
+bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF);
+bool CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType);
+bool CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType);
+bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval);
+bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE eOPMode);
+
+bool
 CARDbPowerDown(
     void *pDeviceHandler
     );
 
-BOOL CARDbSetTxDataRate(
+bool CARDbSetTxDataRate(
     void *pDeviceHandler,
-    WORD    wDataRate
+    unsigned short wDataRate
     );
 
 
-BOOL CARDbRemoveKey (void *pDeviceHandler, PBYTE pbyBSSID);
+bool CARDbRemoveKey (void *pDeviceHandler, unsigned char *pbyBSSID);
 
-BOOL
+bool
 CARDbAdd_PMKID_Candidate (
     void *pDeviceHandler,
-    PBYTE            pbyBSSID,
-    BOOL             bRSNCapExist,
-    WORD             wRSNCap
+    unsigned char *pbyBSSID,
+    bool bRSNCapExist,
+    unsigned short wRSNCap
     );
 
 void *
@@ -144,112 +143,55 @@ CARDpGetCurrentAddress (
     void *pDeviceHandler
     );
 
-
-void CARDvInitChannelTable(void *pDeviceHandler);
-BYTE CARDbyGetChannelMapping(void *pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType);
-
-BOOL
+bool
 CARDbStartMeasure (
     void *pDeviceHandler,
     void *pvMeasureEIDs,
-    UINT             uNumOfMeasureEIDs
+    unsigned int uNumOfMeasureEIDs
     );
 
-BOOL
+bool
 CARDbChannelSwitch (
     void *pDeviceHandler,
-    BYTE             byMode,
-    BYTE             byNewChannel,
-    BYTE             byCount
+    unsigned char byMode,
+    unsigned char byNewChannel,
+    unsigned char byCount
     );
 
-BOOL
+bool
 CARDbSetQuiet (
     void *pDeviceHandler,
-    BOOL             bResetQuiet,
-    BYTE             byQuietCount,
-    BYTE             byQuietPeriod,
-    WORD             wQuietDuration,
-    WORD             wQuietOffset
+    bool bResetQuiet,
+    unsigned char byQuietCount,
+    unsigned char byQuietPeriod,
+    unsigned short wQuietDuration,
+    unsigned short wQuietOffset
     );
 
-BOOL
+bool
 CARDbStartQuiet (
     void *pDeviceHandler
     );
 
-void
-CARDvSetCountryInfo (
-    void *pDeviceHandler,
-    CARD_PHY_TYPE    ePHYType,
-    void *pIE
-    );
-
 void
 CARDvSetPowerConstraint (
     void *pDeviceHandler,
-    BYTE             byChannel,
-    I8               byPower
+    unsigned char byChannel,
+    char byPower
     );
 
 void
 CARDvGetPowerCapability (
     void *pDeviceHandler,
-    PBYTE           pbyMinPower,
-    PBYTE           pbyMaxPower
+    unsigned char *pbyMinPower,
+    unsigned char *pbyMaxPower
     );
 
-BYTE
-CARDbySetSupportChannels (
-    void *pDeviceHandler,
-    PBYTE        pbyIEs
-    );
-
-I8
+char
 CARDbyGetTransmitPower (
     void *pDeviceHandler
     );
 
-BOOL
-CARDbChannelGetList (
-     UINT       uCountryCodeIdx,
-    PBYTE      pbyChannelTable
-    );
-
-void
-CARDvSetCountryIE(
-    void *pDeviceHandler,
-    void *pIE
-    );
-
-BOOL
-CARDbGetChannelMapInfo(
-    void *pDeviceHandler,
-    UINT         uChannelIndex,
-    PBYTE       pbyChannelNumber,
-    PBYTE       pbyMap
-    );
-
-void
-CARDvSetChannelMapInfo(
-    void *pDeviceHandler,
-    UINT         uChannelIndex,
-    BYTE         byMap
-    );
-
-void
-CARDvClearChannelMapInfo(
-    void *pDeviceHandler
-    );
-
-BYTE
-CARDbyAutoChannelSelect(
-    void *pDeviceHandler,
-    CARD_PHY_TYPE   ePHYType
-    );
-
-BYTE CARDbyGetChannelNumber(void *pDeviceHandler, BYTE byChannelIndex);
-
 #endif // __CARD_H__
 
 
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c
new file mode 100644 (file)
index 0000000..47c156b
--- /dev/null
@@ -0,0 +1,835 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: channel.c
+ *
+ */
+
+#include "baseband.h"
+#include "country.h"
+#include "channel.h"
+#include "device.h"
+#include "rf.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+#define CARD_MAX_CHANNEL_TBL    56
+
+//static int msglevel = MSG_LEVEL_DEBUG;
+static int msglevel = MSG_LEVEL_INFO;
+
+/*---------------------  Static Variables  --------------------------*/
+
+static SChannelTblElement sChannelTbl[CARD_MAX_CHANNEL_TBL + 1] =
+{
+  {0,   0,    false,    0},
+  {1,   2412, true,     0},
+  {2,   2417, true,     0},
+  {3,   2422, true,     0},
+  {4,   2427, true,     0},
+  {5,   2432, true,     0},
+  {6,   2437, true,     0},
+  {7,   2442, true,     0},
+  {8,   2447, true,     0},
+  {9,   2452, true,     0},
+  {10,  2457, true,     0},
+  {11,  2462, true,     0},
+  {12,  2467, true,     0},
+  {13,  2472, true,     0},
+  {14,  2484, true,     0},
+  {183, 4915, true,     0},
+  {184, 4920, true,     0},
+  {185, 4925, true,     0},
+  {187, 4935, true,     0},
+  {188, 4940, true,     0},
+  {189, 4945, true,     0},
+  {192, 4960, true,     0},
+  {196, 4980, true,     0},
+  {7,   5035, true,     0},
+  {8,   5040, true,     0},
+  {9,   5045, true,     0},
+  {11,  5055, true,     0},
+  {12,  5060, true,     0},
+  {16,  5080, true,     0},
+  {34,  5170, true,     0},
+  {36,  5180, true,     0},
+  {38,  5190, true,     0},
+  {40,  5200, true,     0},
+  {42,  5210, true,     0},
+  {44,  5220, true,     0},
+  {46,  5230, true,     0},
+  {48,  5240, true,     0},
+  {52,  5260, true,     0},
+  {56,  5280, true,     0},
+  {60,  5300, true,     0},
+  {64,  5320, true,     0},
+  {100, 5500, true,     0},
+  {104, 5520, true,     0},
+  {108, 5540, true,     0},
+  {112, 5560, true,     0},
+  {116, 5580, true,     0},
+  {120, 5600, true,     0},
+  {124, 5620, true,     0},
+  {128, 5640, true,     0},
+  {132, 5660, true,     0},
+  {136, 5680, true,     0},
+  {140, 5700, true,     0},
+  {149, 5745, true,     0},
+  {153, 5765, true,     0},
+  {157, 5785, true,     0},
+  {161, 5805, true,     0},
+  {165, 5825, true,     0}
+};
+
+/************************************************************************
+ * The Radar regulation rules for each country
+ ************************************************************************/
+static struct
+{
+       unsigned char byChannelCountryCode;             /* The country code         */
+       char chCountryCode[2];
+       unsigned char bChannelIdxList[CB_MAX_CHANNEL];  /* Available channels Index */
+       unsigned char byPower[CB_MAX_CHANNEL];
+} ChannelRuleTab[] =
+{
+/************************************************************************
+ * This table is based on Athero driver rules
+ ************************************************************************/
+/* Country          Available channels, ended with 0                    */
+/*                                              1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  */
+{CCODE_FCC,                     {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_TELEC,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  0,  0,  1,  0,  1,  1,  0,  1,  0,  0,  1,  1,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0, 23,  0,  0, 23,  0, 23, 23,  0, 23,  0,  0, 23, 23, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ETSI,                    {'E','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_RESV3,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV4,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV5,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV6,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV7,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV8,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV9,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVa,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVb,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVc,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVd,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVe,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALLBAND,                 {' ',' '},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALBANIA,                 {'A','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALGERIA,                 {'D','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ARGENTINA,               {'A','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
+{CCODE_ARMENIA,                 {'A','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_AUSTRALIA,               {'A','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_AUSTRIA,                 {'A','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15,  0, 15,  0, 15,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_AZERBAIJAN,              {'A','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BAHRAIN,                 {'B','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELARUS,                 {'B','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELGIUM,                 {'B','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELIZE,                  {'B','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BOLIVIA,                 {'B','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BRAZIL,                  {'B','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BRUNEI_DARUSSALAM,       {'B','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BULGARIA,                {'B','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23,  0,  0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0}  },
+{CCODE_CANADA,                  {'C','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_CHILE,                   {'C','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17, 17}  },
+{CCODE_CHINA,                   {'C','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_COLOMBIA,                {'C','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_COSTA_RICA,              {'C','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_CROATIA,                 {'H','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_CYPRUS,                  {'C','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_CZECH,                   {'C','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_DENMARK,                 {'D','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_DOMINICAN_REPUBLIC,      {'D','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_ECUADOR,                 {'E','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_EGYPT,                   {'E','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_EL_SALVADOR,             {'S','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ESTONIA,                 {'E','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_FINLAND,                 {'F','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_FRANCE,                  {'F','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GERMANY,                 {'D','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_GREECE,                  {'G','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GEORGIA,                 {'G','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GUATEMALA,               {'G','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_HONDURAS,                {'H','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_HONG_KONG,               {'H','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_HUNGARY,                 {'H','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ICELAND,                 {'I','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_INDIA,                   {'I','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_INDONESIA,               {'I','D'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_IRAN,                    {'I','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_IRELAND,                 {'I','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_ITALY,                   {'I','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_ISRAEL,                  {'I','L'},  {   0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JAPAN,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JORDAN,                  {'J','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_KAZAKHSTAN,              {'K','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_KUWAIT,                  {'K','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LATVIA,                  {'L','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LEBANON,                 {'L','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LEICHTENSTEIN,           {'L','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LITHUANIA,               {'L','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_LUXEMBURG,               {'L','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_MACAU,                   {'M','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_MACEDONIA,               {'M','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MALTA,                   {'M','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_MALAYSIA,                {'M','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MEXICO,                  {'M','X'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_MONACO,                  {'M','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MOROCCO,                 {'M','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_NETHERLANDS,             {'N','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_NEW_ZEALAND,             {'N','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_NORTH_KOREA,             {'K','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_NORWAY,                  {'N','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_OMAN,                    {'O','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PAKISTAN,                {'P','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PANAMA,                  {'P','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_PERU,                    {'P','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PHILIPPINES,             {'P','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_POLAND,                  {'P','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_PORTUGAL,                {'P','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_PUERTO_RICO,             {'P','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_QATAR,                   {'Q','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ROMANIA,                 {'R','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RUSSIA,                  {'R','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SAUDI_ARABIA,            {'S','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SINGAPORE,               {'S','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 20, 20, 20, 20}  },
+{CCODE_SLOVAKIA,                {'S','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_SLOVENIA,                {'S','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SOUTH_AFRICA,            {'Z','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SOUTH_KOREA,             {'K','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_SPAIN,                   {'E','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_SWEDEN,                  {'S','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SWITZERLAND,             {'C','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SYRIA,                   {'S','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TAIWAN,                  {'T','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
+{CCODE_THAILAND,                {'T','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_TRINIDAD_TOBAGO,         {'T','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TUNISIA,                 {'T','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TURKEY,                  {'T','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UK,                      {'G','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_UKRAINE,                 {'U','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UNITED_ARAB_EMIRATES,    {'A','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UNITED_STATES,           {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                         ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_URUGUAY,                 {'U','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_UZBEKISTAN,              {'U','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_VENEZUELA,               {'V','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                         ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_VIETNAM,                 {'V','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_YEMEN,                   {'Y','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ZIMBABWE,                {'Z','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JAPAN_W52_W53,           {'J','J'},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MAX,                     {'U','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
+                                         ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  }
+/*                                              1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  */
+};
+
+/*---------------------  Export Functions  --------------------------*/
+
+/**
+ * is_channel_valid() - Is Country Channel Valid
+ *  @ChanneIndex: defined as VT3253 MAC channel:
+ *              1   = 2.4G channel 1
+ *              2   = 2.4G channel 2
+ *              ...
+ *              14  = 2.4G channel 14
+ *              15  = 4.9G channel 183
+ *              16  = 4.9G channel 184
+ *              .....
+ *  Output: true if the specified 5GHz band is allowed to be used,
+ *          false otherwise.
+ * 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+ *
+ * 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+ * 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ */
+
+bool is_channel_valid(unsigned int ChannelIndex)
+{
+       bool bValid;
+
+       bValid = false;
+       /*
+        * If Channel Index is invalid, return invalid
+        */
+       if ((ChannelIndex > CB_MAX_CHANNEL) ||
+               (ChannelIndex == 0))
+       {
+               bValid = false;
+               goto exit;
+       }
+
+       bValid = sChannelTbl[ChannelIndex].bValid;
+
+exit:
+       return (bValid);
+
+}
+
+/**
+ * channel_get_list() - Get Available Channel List for a given country
+ * @CountryCode: The country code defined in country.h
+ *
+ * Output:
+ *      pbyChannelTable:   (QWORD *) correspondent bit mask
+ *                          of available channels
+ *                          0x0000000000000001 means channel 1 is supported
+ *                          0x0000000000000003 means channel 1,2 are supported
+ *                          0x000000000000000F means channel 1,2,..15 are supported
+ */
+
+bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable)
+{
+       if (uCountryCodeIdx >= CCODE_MAX)
+               return (false);
+
+       memcpy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL);
+
+       return (true);
+}
+
+void init_channel_table(void *pDeviceHandler)
+{
+       PSDevice    pDevice = (PSDevice) pDeviceHandler;
+       bool bMultiBand = false;
+       unsigned int ii;
+
+       for(ii = 1 ; ii<=CARD_MAX_CHANNEL_TBL ; ii++) {
+               sChannelTbl[ii].bValid = false;
+       }
+
+       switch (pDevice->byRFType) {
+               case RF_RFMD2959 :
+               case RF_AIROHA :
+               case RF_AL2230S:
+               case RF_UW2451 :
+               case RF_VT3226 :
+                       //printk("chester-false\n");
+                       bMultiBand = false;
+                       break;
+               case RF_AIROHA7230 :
+               case RF_UW2452 :
+               case RF_NOTHING :
+               default :
+                       bMultiBand = true;
+                       break;
+       }
+
+       if ((pDevice->dwDiagRefCount != 0) || (pDevice->b11hEnable == true)) {
+               if (bMultiBand == true) {
+                       for(ii = 0 ; ii<CARD_MAX_CHANNEL_TBL ; ii++) {
+                               sChannelTbl[ii+1].bValid = true;
+                               pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+                               pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+                       }
+                       for(ii = 0 ; ii<CHANNEL_MAX_24G ; ii++) {
+                               pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                               pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                       }
+               } else {
+                       for(ii = 0 ; ii<CHANNEL_MAX_24G ; ii++) {
+                               //2008-8-4 <add> by chester
+                               if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                                       sChannelTbl[ii+1].bValid = true;
+                                       pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                                       pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                               }
+                       }
+               }
+       } else if (pDevice->byZoneType <= CCODE_MAX) {
+               if (bMultiBand == true) {
+                       for(ii = 0 ; ii<CARD_MAX_CHANNEL_TBL ; ii++) {
+                               if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                                       sChannelTbl[ii+1].bValid = true;
+                                       pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                                       pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                               }
+                       }
+               } else {
+                       for(ii = 0 ; ii<CHANNEL_MAX_24G ; ii++) {
+                               if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                                       sChannelTbl[ii+1].bValid = true;
+                                       pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                                       pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                               }
+                       }
+               }
+       }
+
+       DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
+
+       for(ii = 0 ; ii<CARD_MAX_CHANNEL_TBL ; ii++) {
+               if (pDevice->abyRegPwr[ii+1] == 0)
+                       pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+               if (pDevice->abyLocalPwr[ii+1] == 0)
+                       pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+       }
+}
+
+unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType)
+{
+       unsigned int ii;
+
+       if ((ePhyType == PHY_TYPE_11B) || (ePhyType == PHY_TYPE_11G))
+               return (byChannelNumber);
+
+       for(ii = (CB_MAX_CHANNEL_24G + 1); ii <= CB_MAX_CHANNEL; ) {
+               if (sChannelTbl[ii].byChannelNumber == byChannelNumber)
+                       return ((unsigned char) ii);
+               ii++;
+       }
+       return 0;
+}
+
+unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex)
+{
+       //PSDevice    pDevice = (PSDevice) pDeviceHandler;
+       return(sChannelTbl[byChannelIndex].byChannelNumber);
+}
+
+/**
+ * set_channel() - Set NIC media channel
+ *
+ * @pDeviceHandler: The adapter to be set
+ * @uConnectionChannel: Channel to be set
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool set_channel (void *pDeviceHandler, unsigned int uConnectionChannel)
+{
+       PSDevice pDevice = (PSDevice) pDeviceHandler;
+       bool bResult = true;
+
+
+       if (pDevice->byCurrentCh == uConnectionChannel) {
+               return bResult;
+       }
+
+       if (sChannelTbl[uConnectionChannel].bValid == false) {
+               return (false);
+       }
+
+       if ((uConnectionChannel > CB_MAX_CHANNEL_24G) &&
+                       (pDevice->eCurrentPHYType != PHY_TYPE_11A)) {
+               CARDbSetPhyParameter(pDevice, PHY_TYPE_11A, 0, 0, NULL, NULL);
+       } else if ((uConnectionChannel <= CB_MAX_CHANNEL_24G) &&
+                       (pDevice->eCurrentPHYType == PHY_TYPE_11A)) {
+               CARDbSetPhyParameter(pDevice, PHY_TYPE_11G, 0, 0, NULL, NULL);
+       }
+       // clear NAV
+       MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV);
+
+       //{{ RobertYu: 20041202
+       //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
+
+       if ( pDevice->byRFType == RF_AIROHA7230 )
+       {
+               RFbAL7230SelectChannelPostProcess(pDevice->PortOffset, pDevice->byCurrentCh, (unsigned char)uConnectionChannel);
+       }
+       //}} RobertYu
+
+
+       pDevice->byCurrentCh = (unsigned char)uConnectionChannel;
+       bResult &= RFbSelectChannel(pDevice->PortOffset, pDevice->byRFType, (unsigned char)uConnectionChannel);
+
+       // Init Synthesizer Table
+       if (pDevice->bEnablePSMode == true)
+               RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel);
+
+
+       //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDbSetMediaChannel: %d\n", (unsigned char)uConnectionChannel);
+       BBvSoftwareReset(pDevice->PortOffset);
+
+       if (pDevice->byLocalID > REV_ID_VT3253_B1) {
+               // set HW default power register
+               MACvSelectPage1(pDevice->PortOffset);
+               RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
+               VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWRCCK, pDevice->byCurPwr);
+               RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
+               VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr);
+               MACvSelectPage0(pDevice->PortOffset);
+       }
+
+       if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+#ifdef PLICE_DEBUG
+               //printk("Func:ChbSetChannel:call RFbSetPower:11B\n");
+#endif
+               RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
+       } else {
+#ifdef PLICE_DEBUG
+               //printk("Func:ChbSetChannel:call RFbSetPower\n");
+#endif
+               RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
+       }
+
+       return(bResult);
+}
+
+/**
+ * set_country_info() - Set Channel Info of Country
+ *
+ * Return Value: none.
+ *
+ */
+
+void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE)
+{
+       PSDevice pDevice = (PSDevice) pDeviceHandler;
+       unsigned int ii = 0;
+       unsigned int uu = 0;
+       unsigned int step = 0;
+       unsigned int uNumOfCountryInfo = 0;
+       unsigned char byCh = 0;
+       PWLAN_IE_COUNTRY pIE_Country = (PWLAN_IE_COUNTRY) pIE;
+
+
+       uNumOfCountryInfo = (pIE_Country->len - 3);
+       uNumOfCountryInfo /= 3;
+
+       if (ePHYType == PHY_TYPE_11A) {
+               pDevice->bCountryInfo5G = true;
+               for(ii = CB_MAX_CHANNEL_24G + 1 ; ii <= CARD_MAX_CHANNEL_TBL ; ii++) {
+                       sChannelTbl[ii].bValid = false;
+               }
+               step = 4;
+       } else {
+               pDevice->bCountryInfo24G = true;
+               for(ii = 1 ; ii <= CB_MAX_CHANNEL_24G ; ii++) {
+                       sChannelTbl[ii].bValid = false;
+               }
+               step = 1;
+       }
+       pDevice->abyCountryCode[0] = pIE_Country->abyCountryString[0];
+       pDevice->abyCountryCode[1] = pIE_Country->abyCountryString[1];
+       pDevice->abyCountryCode[2] = pIE_Country->abyCountryString[2];
+
+       for(ii = 0 ; ii < uNumOfCountryInfo ; ii++) {
+               for(uu = 0 ; uu < pIE_Country->abyCountryInfo[ii*3+1] ; uu++) {
+                       byCh = get_channel_mapping(pDevice, (unsigned char)(pIE_Country->abyCountryInfo[ii*3]+step*uu), ePHYType);
+                       sChannelTbl[byCh].bValid = true;
+                       pDevice->abyRegPwr[byCh] = pIE_Country->abyCountryInfo[ii*3+2];
+               }
+       }
+}
+
+/**
+ *
+ * set_support_channels() - Set Support Channels IE defined in 802.11h
+ *
+ * @hDeviceContext: device structure point
+ *
+ * Return Value: none.
+ *
+ */
+
+unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs)
+{
+       PSDevice pDevice = (PSDevice) pDeviceHandler;
+       unsigned int ii;
+       unsigned char byCount;
+       PWLAN_IE_SUPP_CH pIE = (PWLAN_IE_SUPP_CH) pbyIEs;
+       unsigned char *pbyChTupple;
+       unsigned char byLen = 0;
+
+
+       pIE->byElementID = WLAN_EID_SUPP_CH;
+       pIE->len = 0;
+       pbyChTupple = pIE->abyChannelTuple;
+       byLen = 2;
+       // lower band
+       byCount = 0;
+       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[28] == true) {
+               for (ii = 28 ; ii < 36 ; ii+= 2) {
+                       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) {
+                               byCount++;
+                       }
+               }
+               *pbyChTupple++ = 34;
+               *pbyChTupple++ = byCount;
+               byLen += 2;
+       } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[29] == true) {
+               for (ii = 29 ; ii < 36 ; ii+= 2) {
+                       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) {
+                               byCount++;
+                       }
+               }
+               *pbyChTupple++ = 36;
+               *pbyChTupple++ = byCount;
+               byLen += 2;
+       }
+       // middle band
+       byCount = 0;
+       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[36] == true) {
+               for (ii = 36 ; ii < 40 ; ii++) {
+                       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) {
+                               byCount++;
+                       }
+               }
+               *pbyChTupple++ = 52;
+               *pbyChTupple++ = byCount;
+               byLen += 2;
+       }
+       // higher band
+       byCount = 0;
+       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[40] == true) {
+               for (ii = 40 ; ii < 51 ; ii++) {
+                       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) {
+                               byCount++;
+                       }
+               }
+               *pbyChTupple++ = 100;
+               *pbyChTupple++ = byCount;
+               byLen += 2;
+       } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[51] == true) {
+               for (ii = 51 ; ii < 56 ; ii++) {
+                       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) {
+                               byCount++;
+                       }
+               }
+               *pbyChTupple++ = 149;
+               *pbyChTupple++ = byCount;
+               byLen += 2;
+       }
+       pIE->len += (byLen - 2);
+       return (byLen);
+}
+
+void set_country_IE(void *pDeviceHandler, void *pIE)
+{
+       PSDevice pDevice = (PSDevice) pDeviceHandler;
+       unsigned int ii;
+       PWLAN_IE_COUNTRY pIECountry = (PWLAN_IE_COUNTRY) pIE;
+
+       pIECountry->byElementID = WLAN_EID_COUNTRY;
+       pIECountry->len = 0;
+       pIECountry->abyCountryString[0] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[0];
+       pIECountry->abyCountryString[1] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[1];
+       pIECountry->abyCountryString[2] = ' ';
+       for (ii = CB_MAX_CHANNEL_24G; ii < CB_MAX_CHANNEL; ii++ ) {
+               if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                       pIECountry->abyCountryInfo[pIECountry->len++] = sChannelTbl[ii+1].byChannelNumber;
+                       pIECountry->abyCountryInfo[pIECountry->len++] = 1;
+                       pIECountry->abyCountryInfo[pIECountry->len++] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+               }
+       }
+       pIECountry->len += 3;
+}
+
+bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex,
+               unsigned char *pbyChannelNumber, unsigned char *pbyMap)
+{
+
+       if (uChannelIndex > CB_MAX_CHANNEL) {
+               return false;
+       }
+       *pbyChannelNumber = sChannelTbl[uChannelIndex].byChannelNumber;
+       *pbyMap = sChannelTbl[uChannelIndex].byMAP;
+       return sChannelTbl[uChannelIndex].bValid;
+}
+
+void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex,
+               unsigned char byMap)
+{
+
+       if (uChannelIndex > CB_MAX_CHANNEL) {
+               return;
+       }
+       sChannelTbl[uChannelIndex].byMAP |= byMap;
+}
+
+void clear_channel_map_info(void *pDeviceHandler)
+{
+       unsigned int ii = 0;
+
+       for (ii = 1; ii <=  CB_MAX_CHANNEL; ii++) {
+               sChannelTbl[ii].byMAP = 0;
+       }
+}
+
+unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType)
+{
+       unsigned int ii = 0;
+       unsigned char byOptionChannel = 0;
+       int aiWeight[CB_MAX_CHANNEL_24G+1] = {-1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+       if (ePHYType == PHY_TYPE_11A) {
+               for(ii = CB_MAX_CHANNEL_24G + 1 ; ii <= CB_MAX_CHANNEL ; ii++) {
+                       if (sChannelTbl[ii].bValid == true) {
+                               if (byOptionChannel == 0) {
+                                       byOptionChannel = (unsigned char) ii;
+                               }
+                               if (sChannelTbl[ii].byMAP == 0) {
+                                       return ((unsigned char) ii);
+                               } else if ( !(sChannelTbl[ii].byMAP & 0x08)) {
+                                       byOptionChannel = (unsigned char) ii;
+                               }
+                       }
+               }
+       } else {
+               byOptionChannel = 0;
+               for(ii = 1 ; ii <= CB_MAX_CHANNEL_24G ; ii++) {
+                       if (sChannelTbl[ii].bValid == true) {
+                               if (sChannelTbl[ii].byMAP == 0) {
+                                       aiWeight[ii] += 100;
+                               } else if (sChannelTbl[ii].byMAP & 0x01) {
+                                       if (ii > 3) {
+                                               aiWeight[ii-3] -= 10;
+                                       }
+                                       if (ii > 2) {
+                                               aiWeight[ii-2] -= 20;
+                                       }
+                                       if (ii > 1) {
+                                               aiWeight[ii-1] -= 40;
+                                       }
+                                       aiWeight[ii] -= 80;
+                                       if (ii < CB_MAX_CHANNEL_24G) {
+                                               aiWeight[ii+1] -= 40;
+                                       }
+                                       if (ii < (CB_MAX_CHANNEL_24G - 1)) {
+                                               aiWeight[ii+2] -= 20;
+                                       }
+                                       if (ii < (CB_MAX_CHANNEL_24G - 2)) {
+                                               aiWeight[ii+3] -= 10;
+                                       }
+                               }
+                       }
+               }
+               for(ii = 1 ; ii <= CB_MAX_CHANNEL_24G ; ii++) {
+                       if ((sChannelTbl[ii].bValid == true) &&
+                                       (aiWeight[ii] > aiWeight[byOptionChannel])) {
+                               byOptionChannel = (unsigned char) ii;
+                       }
+               }
+       }
+       return (byOptionChannel);
+}
diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h
new file mode 100644 (file)
index 0000000..7038f0d
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: channel.h
+ *
+ */
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#include "ttype.h"
+#include "card.h"
+
+/*---------------------  Export Classes  ----------------------------*/
+
+typedef struct tagSChannelTblElement {
+    unsigned char byChannelNumber;
+    unsigned int uFrequency;
+    bool bValid;
+    unsigned char byMAP;
+}SChannelTblElement, *PSChannelTblElement;
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+bool is_channel_valid(unsigned int CountryCode);
+void init_channel_table(void *pDeviceHandler);
+unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType);
+bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable);
+unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex);
+bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel);
+void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE);
+unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs);
+void set_country_IE(void *pDeviceHandler, void *pIE);
+bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex,
+               unsigned char *pbyChannelNumber, unsigned char *pbyMap);
+void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex,
+               unsigned char byMap);
+void clear_channel_map_info(void *pDeviceHandler);
+unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType);
+
+
+#endif /* _CHANNEL_H_ */
index 2005d27686803348f56203cc8dad29442cdec849..05fda4104200b3b43cc63da351d77308e28538b8 100644 (file)
@@ -159,19 +159,4 @@ typedef enum _COUNTRY_CODE {
     CCODE_MAX
 } COUNTRY_CODE;
 
-typedef struct tagSCountryTable
-{
-    BYTE    byChannelCountryCode;             /* The country code         */
-    CHAR    chCountryCode[2];
-    BYTE    bChannelIdxList[CB_MAX_CHANNEL];  /* Available channels Index */
-    BYTE    byPower[CB_MAX_CHANNEL];
-}   SCountryTable, *PSCountryTable;
-
-/*---------------------  Export Classes  ----------------------------*/
-
-/*---------------------  Export Variables  --------------------------*/
-extern SCountryTable ChannelRuleTab[CCODE_MAX+1];
-
-/*---------------------  Export Functions  --------------------------*/
-
 #endif  /* __COUNTRY_H__ */
index 38b09a7fb53bc657515720ff91b7cbd2543e0ca9..efbb8f45f728dc6035d59e0f1a4fd61f0344baef 100644 (file)
 /*---------------------  Static Classes  ----------------------------*/
 
 
- extern WORD TxRate_iwconfig; //2008-5-8 <add> by chester
+ extern unsigned short TxRate_iwconfig; //2008-5-8 <add> by chester
 /*---------------------  Static Variables  --------------------------*/
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 static int          msglevel                =MSG_LEVEL_INFO;
-const BYTE acbyIERate[MAX_RATE] =
+const unsigned char acbyIERate[MAX_RATE] =
 {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
 
 #define AUTORATE_TXOK_CNT       0x0400
@@ -75,7 +75,7 @@ s_vResetCounter (
     PKnownNodeDB psNodeDBTable
     )
 {
-    BYTE            ii;
+    unsigned char ii;
 
     // clear statistic counter for auto_rate
     for(ii=0;ii<=MAX_RATE;ii++) {
@@ -97,19 +97,19 @@ s_vResetCounter (
  *
  * Parameters:
  *  In:
- *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
+ *      unsigned char - Rate value in SuppRates IE or ExtSuppRates IE
  *  Out:
  *      none
  *
  * Return Value: RateIdx
  *
 -*/
-BYTE
+unsigned char
 DATARATEbyGetRateIdx (
-    BYTE byRate
+    unsigned char byRate
     )
 {
-    BYTE    ii;
+    unsigned char ii;
 
     //Erase basicRate flag.
     byRate = byRate & 0x7F;//0111 1111
@@ -151,19 +151,19 @@ DATARATEbyGetRateIdx (
  *
  * Parameters:
  *  In:
- *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
+ *      unsigned char - Rate value in SuppRates IE or ExtSuppRates IE
  *  Out:
  *      none
  *
  * Return Value: RateIdx
  *
 -*/
-WORD
+unsigned short
 wGetRateIdx(
-    BYTE byRate
+    unsigned char byRate
     )
 {
-    WORD    ii;
+    unsigned short ii;
 
     //Erase basicRate flag.
     byRate = byRate & 0x7F;//0111 1111
@@ -199,20 +199,20 @@ RATEvParseMaxRate (
     void *pDeviceHandler,
     PWLAN_IE_SUPP_RATES pItemRates,
     PWLAN_IE_SUPP_RATES pItemExtRates,
-    BOOL bUpdateBasicRate,
-    PWORD pwMaxBasicRate,
-    PWORD pwMaxSuppRate,
-    PWORD pwSuppRate,
-    PBYTE pbyTopCCKRate,
-    PBYTE pbyTopOFDMRate
+    bool bUpdateBasicRate,
+    unsigned short *pwMaxBasicRate,
+    unsigned short *pwMaxSuppRate,
+    unsigned short *pwSuppRate,
+    unsigned char *pbyTopCCKRate,
+    unsigned char *pbyTopOFDMRate
     )
 {
 PSDevice  pDevice = (PSDevice) pDeviceHandler;
-UINT  ii;
-BYTE  byHighSuppRate = 0;
-BYTE  byRate = 0;
-WORD  wOldBasicRate = pDevice->wBasicRate;
-UINT  uRateLen;
+unsigned int ii;
+unsigned char byHighSuppRate = 0;
+unsigned char byRate = 0;
+unsigned short wOldBasicRate = pDevice->wBasicRate;
+unsigned int uRateLen;
 
 
     if (pItemRates == NULL)
@@ -231,14 +231,14 @@ UINT  uRateLen;
     }
 
     for (ii = 0; ii < uRateLen; ii++) {
-       byRate = (BYTE)(pItemRates->abyRates[ii]);
+       byRate = (unsigned char)(pItemRates->abyRates[ii]);
         if (WLAN_MGMT_IS_BASICRATE(byRate) &&
-            (bUpdateBasicRate == TRUE))  {
+            (bUpdateBasicRate == true))  {
             // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
             CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate));
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
         }
-        byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+        byRate = (unsigned char)(pItemRates->abyRates[ii]&0x7F);
         if (byHighSuppRate == 0)
             byHighSuppRate = byRate;
         if (byRate > byHighSuppRate)
@@ -248,20 +248,20 @@ UINT  uRateLen;
     if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
         (pDevice->eCurrentPHYType != PHY_TYPE_11B)) {
 
-        UINT  uExtRateLen = pItemExtRates->len;
+        unsigned int uExtRateLen = pItemExtRates->len;
 
         if (uExtRateLen > WLAN_RATES_MAXLEN)
             uExtRateLen = WLAN_RATES_MAXLEN;
 
         for (ii = 0; ii < uExtRateLen ; ii++) {
-            byRate = (BYTE)(pItemExtRates->abyRates[ii]);
+            byRate = (unsigned char)(pItemExtRates->abyRates[ii]);
             // select highest basic rate
             if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
                // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
                 CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate));
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
             }
-            byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F);
+            byRate = (unsigned char)(pItemExtRates->abyRates[ii]&0x7F);
             if (byHighSuppRate == 0)
                 byHighSuppRate = byRate;
             if (byRate > byHighSuppRate)
@@ -314,14 +314,14 @@ RATEvTxRateFallBack (
     )
 {
 PSDevice        pDevice = (PSDevice) pDeviceHandler;
-WORD            wIdxDownRate = 0;
-UINT            ii;
-//DWORD           dwRateTable[MAX_RATE]  = {1,   2,   5,   11,  6,    9,    12,   18,  24,  36,  48,  54};
-BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
-DWORD           dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
-DWORD           dwThroughput = 0;
-WORD            wIdxUpRate = 0;
-DWORD           dwTxDiff = 0;
+unsigned short wIdxDownRate = 0;
+unsigned int ii;
+//unsigned long dwRateTable[MAX_RATE]  = {1,   2,   5,   11,  6,    9,    12,   18,  24,  36,  48,  54};
+bool bAutoRate[MAX_RATE]    = {true,true,true,true,false,false,true,true,true,true,true,true};
+       unsigned long dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
+       unsigned long dwThroughput = 0;
+       unsigned short wIdxUpRate = 0;
+       unsigned long dwTxDiff = 0;
 
     if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) {
         // Don't do Fallback when scanning Channel
@@ -346,11 +346,11 @@ DWORD           dwTxDiff = 0;
 
     for(ii=0;ii<MAX_RATE;ii++) {
         if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
-            if (bAutoRate[ii] == TRUE) {
-                wIdxUpRate = (WORD) ii;
+            if (bAutoRate[ii] == true) {
+                wIdxUpRate = (unsigned short) ii;
             }
         } else {
-            bAutoRate[ii] = FALSE;
+            bAutoRate[ii] = false;
         }
     }
 
@@ -372,9 +372,9 @@ DWORD           dwTxDiff = 0;
     for(ii = psNodeDBTable->wTxDataRate; ii > 0;) {
         ii--;
         if ( (dwThroughputTbl[ii] > dwThroughput) &&
-             (bAutoRate[ii]==TRUE) ) {
+             (bAutoRate[ii]==true) ) {
             dwThroughput = dwThroughputTbl[ii];
-            wIdxDownRate = (WORD) ii;
+            wIdxDownRate = (unsigned short) ii;
         }
     }
     psNodeDBTable->wTxDataRate = wIdxDownRate;
@@ -409,14 +409,14 @@ TxRate_iwconfig=psNodeDBTable->wTxDataRate;
  * Return Value: None
  *
 -*/
-BYTE
+unsigned char
 RATEuSetIE (
     PWLAN_IE_SUPP_RATES pSrcRates,
     PWLAN_IE_SUPP_RATES pDstRates,
-    UINT                uRateLen
+    unsigned int uRateLen
     )
 {
-    UINT ii, uu, uRateCnt = 0;
+    unsigned int ii, uu, uRateCnt = 0;
 
     if ((pSrcRates == NULL) || (pDstRates == NULL))
         return 0;
@@ -432,6 +432,6 @@ RATEuSetIE (
             }
         }
     }
-    return (BYTE)uRateCnt;
+    return (unsigned char)uRateCnt;
 }
 
index b8ca792e9c6e93b884dfa3e07dd79728151b9d13..4f8ea0b0532d751f7b5866e46ba916da7da3502d 100644 (file)
@@ -59,12 +59,12 @@ RATEvParseMaxRate(
     void *pDeviceHandler,
     PWLAN_IE_SUPP_RATES pItemRates,
     PWLAN_IE_SUPP_RATES pItemExtRates,
-    BOOL bUpdateBasicRate,
-    PWORD pwMaxBasicRate,
-    PWORD pwMaxSuppRate,
-    PWORD pwSuppRate,
-    PBYTE pbyTopCCKRate,
-    PBYTE pbyTopOFDMRate
+    bool bUpdateBasicRate,
+    unsigned short *pwMaxBasicRate,
+    unsigned short *pwMaxSuppRate,
+    unsigned short *pwSuppRate,
+    unsigned char *pbyTopCCKRate,
+    unsigned char *pbyTopOFDMRate
     );
 
 void
@@ -73,22 +73,22 @@ RATEvTxRateFallBack(
     PKnownNodeDB psNodeDBTable
     );
 
-BYTE
+unsigned char
 RATEuSetIE(
     PWLAN_IE_SUPP_RATES pSrcRates,
     PWLAN_IE_SUPP_RATES pDstRates,
-    UINT                uRateLen
+    unsigned int uRateLen
     );
 
-WORD
+unsigned short
 wGetRateIdx(
-    BYTE byRate
+    unsigned char byRate
     );
 
 
-BYTE
+unsigned char
 DATARATEbyGetRateIdx(
-    BYTE byRate
+    unsigned char byRate
     );
 
 
index cedb1e7df4fa4f33c0dbe2204bc5b88c19c34dfb..138897a79325106fbe6867a7706d3dd857c01380 100644 (file)
@@ -244,10 +244,10 @@ static inline PDEVICE_RD_INFO alloc_rd_info(void) {
 
 /*
 typedef struct tagRDES0 {
-    WORD    wResCount;
-    WORD    wf1Owner ;
-//    WORD    f15Reserved : 15;
-//    WORD    f1Owner : 1;
+    unsigned short wResCount;
+    unsigned short wf1Owner ;
+//    unsigned short f15Reserved : 15;
+//    unsigned short f1Owner : 1;
 } __attribute__ ((__packed__))
 SRDES0;
 */
@@ -255,13 +255,13 @@ SRDES0;
 #ifdef __BIG_ENDIAN
 
 typedef struct tagRDES0 {
-   volatile WORD    wResCount;
+   volatile unsigned short wResCount;
        union {
-               volatile U16    f15Reserved;
+               volatile u16    f15Reserved;
                struct {
-            volatile U8 f8Reserved1;
-                       volatile U8 f1Owner:1;
-                       volatile U8 f7Reserved:7;
+            volatile u8 f8Reserved1;
+                       volatile u8 f1Owner:1;
+                       volatile u8 f7Reserved:7;
                } __attribute__ ((__packed__));
        } __attribute__ ((__packed__));
 } __attribute__ ((__packed__))
@@ -270,9 +270,9 @@ SRDES0, *PSRDES0;
 #else
 
 typedef struct tagRDES0 {
-    WORD    wResCount;
-    WORD    f15Reserved : 15;
-    WORD    f1Owner : 1;
+    unsigned short wResCount;
+    unsigned short f15Reserved : 15;
+    unsigned short f1Owner : 1;
 } __attribute__ ((__packed__))
 SRDES0;
 
@@ -280,8 +280,8 @@ SRDES0;
 #endif
 
 typedef struct tagRDES1 {
-    WORD   wReqCount;
-    WORD   wReserved;
+    unsigned short wReqCount;
+    unsigned short wReserved;
 } __attribute__ ((__packed__))
 SRDES1;
 
@@ -291,11 +291,11 @@ SRDES1;
 typedef struct tagSRxDesc {
     volatile SRDES0 m_rd0RD0;
     volatile SRDES1 m_rd1RD1;
-    volatile U32    buff_addr;
-    volatile U32    next_desc;
+    volatile u32    buff_addr;
+    volatile u32    next_desc;
     struct tagSRxDesc   *next;//4 bytes
     volatile PDEVICE_RD_INFO    pRDInfo;//4 bytes
-    volatile U32    Reserved[2];//8 bytes
+    volatile u32    Reserved[2];//8 bytes
 } __attribute__ ((__packed__))
 SRxDesc, *PSRxDesc;
 typedef const SRxDesc *PCSRxDesc;
@@ -304,24 +304,24 @@ typedef const SRxDesc *PCSRxDesc;
 
 /*
 typedef struct tagTDES0 {
-    volatile    BYTE    byTSR0;
-    volatile    BYTE    byTSR1;
-    volatile    WORD    wOwner_Txtime;
-//    volatile    WORD    f15Txtime : 15;
-//    volatile    WORD    f1Owner:1;
+    volatile    unsigned char byTSR0;
+    volatile    unsigned char byTSR1;
+    volatile    unsigned short wOwner_Txtime;
+//    volatile    unsigned short f15Txtime : 15;
+//    volatile    unsigned short f1Owner:1;
 } __attribute__ ((__packed__))
 STDES0;
 */
 
 typedef struct tagTDES0 {
-    volatile    BYTE    byTSR0;
-    volatile    BYTE    byTSR1;
+    volatile    unsigned char byTSR0;
+    volatile    unsigned char byTSR1;
        union {
-               volatile U16    f15Txtime;
+               volatile u16    f15Txtime;
                struct {
-            volatile U8 f8Reserved1;
-                       volatile U8 f1Owner:1;
-                       volatile U8 f7Reserved:7;
+            volatile u8 f8Reserved1;
+                       volatile u8 f1Owner:1;
+                       volatile u8 f7Reserved:7;
                } __attribute__ ((__packed__));
        } __attribute__ ((__packed__));
 } __attribute__ ((__packed__))
@@ -330,10 +330,10 @@ STDES0, PSTDES0;
 #else
 
 typedef struct tagTDES0 {
-    volatile    BYTE    byTSR0;
-    volatile    BYTE    byTSR1;
-    volatile    WORD    f15Txtime : 15;
-    volatile    WORD    f1Owner:1;
+    volatile    unsigned char byTSR0;
+    volatile    unsigned char byTSR1;
+    volatile    unsigned short f15Txtime : 15;
+    volatile    unsigned short f1Owner:1;
 } __attribute__ ((__packed__))
 STDES0;
 
@@ -341,22 +341,22 @@ STDES0;
 
 
 typedef struct tagTDES1 {
-    volatile    WORD    wReqCount;
-    volatile    BYTE    byTCR;
-    volatile    BYTE    byReserved;
+    volatile    unsigned short wReqCount;
+    volatile    unsigned char byTCR;
+    volatile    unsigned char byReserved;
 } __attribute__ ((__packed__))
 STDES1;
 
 
 typedef struct tagDEVICE_TD_INFO{
     struct sk_buff*     skb;
-    PBYTE               buf;
+    unsigned char *buf;
     dma_addr_t          skb_dma;
     dma_addr_t          buf_dma;
     dma_addr_t          curr_desc;
-    DWORD               dwReqCount;
-    DWORD               dwHeaderLength;
-    BYTE                byFlags;
+    unsigned long dwReqCount;
+    unsigned long dwHeaderLength;
+    unsigned char byFlags;
 } DEVICE_TD_INFO,    *PDEVICE_TD_INFO;
 
 /*
@@ -378,11 +378,11 @@ static inline PDEVICE_TD_INFO alloc_td_info(void) {
 typedef struct tagSTxDesc {
     volatile    STDES0  m_td0TD0;
     volatile    STDES1  m_td1TD1;
-    volatile    U32    buff_addr;
-    volatile    U32    next_desc;
+    volatile    u32    buff_addr;
+    volatile    u32    next_desc;
     struct tagSTxDesc*  next; //4 bytes
     volatile    PDEVICE_TD_INFO pTDInfo;//4 bytes
-    volatile    U32    Reserved[2];//8 bytes
+    volatile    u32    Reserved[2];//8 bytes
 } __attribute__ ((__packed__))
 STxDesc, *PSTxDesc;
 typedef const STxDesc *PCSTxDesc;
@@ -391,13 +391,13 @@ typedef const STxDesc *PCSTxDesc;
 typedef struct tagSTxSyncDesc {
     volatile    STDES0  m_td0TD0;
     volatile    STDES1  m_td1TD1;
-    volatile    DWORD   buff_addr; // pointer to logical buffer
-    volatile    DWORD   next_desc; // pointer to next logical descriptor
-    volatile    WORD    m_wFIFOCtl;
-    volatile    WORD    m_wTimeStamp;
+    volatile    u32 buff_addr; // pointer to logical buffer
+    volatile    u32 next_desc; // pointer to next logical descriptor
+    volatile    unsigned short m_wFIFOCtl;
+    volatile    unsigned short m_wTimeStamp;
     struct tagSTxSyncDesc*  next; //4 bytes
     volatile    PDEVICE_TD_INFO pTDInfo;//4 bytes
-    volatile    DWORD   m_dwReserved2;
+    volatile    u32 m_dwReserved2;
 } __attribute__ ((__packed__))
 STxSyncDesc, *PSTxSyncDesc;
 typedef const STxSyncDesc *PCSTxSyncDesc;
@@ -407,35 +407,35 @@ typedef const STxSyncDesc *PCSTxSyncDesc;
 // RsvTime buffer header
 //
 typedef struct tagSRrvTime_gRTS {
-    WORD        wRTSTxRrvTime_ba;
-    WORD        wRTSTxRrvTime_aa;
-    WORD        wRTSTxRrvTime_bb;
-    WORD        wReserved;
-    WORD        wTxRrvTime_b;
-    WORD        wTxRrvTime_a;
+    unsigned short wRTSTxRrvTime_ba;
+    unsigned short wRTSTxRrvTime_aa;
+    unsigned short wRTSTxRrvTime_bb;
+    unsigned short wReserved;
+    unsigned short wTxRrvTime_b;
+    unsigned short wTxRrvTime_a;
 }__attribute__ ((__packed__))
 SRrvTime_gRTS, *PSRrvTime_gRTS;
 typedef const SRrvTime_gRTS *PCSRrvTime_gRTS;
 
 typedef struct tagSRrvTime_gCTS {
-    WORD        wCTSTxRrvTime_ba;
-    WORD        wReserved;
-    WORD        wTxRrvTime_b;
-    WORD        wTxRrvTime_a;
+    unsigned short wCTSTxRrvTime_ba;
+    unsigned short wReserved;
+    unsigned short wTxRrvTime_b;
+    unsigned short wTxRrvTime_a;
 }__attribute__ ((__packed__))
 SRrvTime_gCTS, *PSRrvTime_gCTS;
 typedef const SRrvTime_gCTS *PCSRrvTime_gCTS;
 
 typedef struct tagSRrvTime_ab {
-    WORD        wRTSTxRrvTime;
-    WORD        wTxRrvTime;
+    unsigned short wRTSTxRrvTime;
+    unsigned short wTxRrvTime;
 }__attribute__ ((__packed__))
 SRrvTime_ab, *PSRrvTime_ab;
 typedef const SRrvTime_ab *PCSRrvTime_ab;
 
 typedef struct tagSRrvTime_atim {
-    WORD        wCTSTxRrvTime_ba;
-    WORD        wTxRrvTime_a;
+    unsigned short wCTSTxRrvTime_ba;
+    unsigned short wTxRrvTime_a;
 }__attribute__ ((__packed__))
 SRrvTime_atim, *PSRrvTime_atim;
 typedef const SRrvTime_atim *PCSRrvTime_atim;
@@ -444,25 +444,25 @@ typedef const SRrvTime_atim *PCSRrvTime_atim;
 // RTS buffer header
 //
 typedef struct tagSRTSData {
-    WORD    wFrameControl;
-    WORD    wDurationID;
-    BYTE    abyRA[ETH_ALEN];
-    BYTE    abyTA[ETH_ALEN];
+    unsigned short wFrameControl;
+    unsigned short wDurationID;
+    unsigned char abyRA[ETH_ALEN];
+    unsigned char abyTA[ETH_ALEN];
 }__attribute__ ((__packed__))
 SRTSData, *PSRTSData;
 typedef const SRTSData *PCSRTSData;
 
 typedef struct tagSRTS_g {
-    BYTE        bySignalField_b;
-    BYTE        byServiceField_b;
-    WORD        wTransmitLength_b;
-    BYTE        bySignalField_a;
-    BYTE        byServiceField_a;
-    WORD        wTransmitLength_a;
-    WORD        wDuration_ba;
-    WORD        wDuration_aa;
-    WORD        wDuration_bb;
-    WORD        wReserved;
+    unsigned char bySignalField_b;
+    unsigned char byServiceField_b;
+    unsigned short wTransmitLength_b;
+    unsigned char bySignalField_a;
+    unsigned char byServiceField_a;
+    unsigned short wTransmitLength_a;
+    unsigned short wDuration_ba;
+    unsigned short wDuration_aa;
+    unsigned short wDuration_bb;
+    unsigned short wReserved;
     SRTSData    Data;
 }__attribute__ ((__packed__))
 SRTS_g, *PSRTS_g;
@@ -470,20 +470,20 @@ typedef const SRTS_g *PCSRTS_g;
 
 
 typedef struct tagSRTS_g_FB {
-    BYTE        bySignalField_b;
-    BYTE        byServiceField_b;
-    WORD        wTransmitLength_b;
-    BYTE        bySignalField_a;
-    BYTE        byServiceField_a;
-    WORD        wTransmitLength_a;
-    WORD        wDuration_ba;
-    WORD        wDuration_aa;
-    WORD        wDuration_bb;
-    WORD        wReserved;
-    WORD        wRTSDuration_ba_f0;
-    WORD        wRTSDuration_aa_f0;
-    WORD        wRTSDuration_ba_f1;
-    WORD        wRTSDuration_aa_f1;
+    unsigned char bySignalField_b;
+    unsigned char byServiceField_b;
+    unsigned short wTransmitLength_b;
+    unsigned char bySignalField_a;
+    unsigned char byServiceField_a;
+    unsigned short wTransmitLength_a;
+    unsigned short wDuration_ba;
+    unsigned short wDuration_aa;
+    unsigned short wDuration_bb;
+    unsigned short wReserved;
+    unsigned short wRTSDuration_ba_f0;
+    unsigned short wRTSDuration_aa_f0;
+    unsigned short wRTSDuration_ba_f1;
+    unsigned short wRTSDuration_aa_f1;
     SRTSData    Data;
 }__attribute__ ((__packed__))
 SRTS_g_FB, *PSRTS_g_FB;
@@ -491,11 +491,11 @@ typedef const SRTS_g_FB *PCSRTS_g_FB;
 
 
 typedef struct tagSRTS_ab {
-    BYTE        bySignalField;
-    BYTE        byServiceField;
-    WORD        wTransmitLength;
-    WORD        wDuration;
-    WORD        wReserved;
+    unsigned char bySignalField;
+    unsigned char byServiceField;
+    unsigned short wTransmitLength;
+    unsigned short wDuration;
+    unsigned short wReserved;
     SRTSData    Data;
 }__attribute__ ((__packed__))
 SRTS_ab, *PSRTS_ab;
@@ -503,13 +503,13 @@ typedef const SRTS_ab *PCSRTS_ab;
 
 
 typedef struct tagSRTS_a_FB {
-    BYTE        bySignalField;
-    BYTE        byServiceField;
-    WORD        wTransmitLength;
-    WORD        wDuration;
-    WORD        wReserved;
-    WORD        wRTSDuration_f0;
-    WORD        wRTSDuration_f1;
+    unsigned char bySignalField;
+    unsigned char byServiceField;
+    unsigned short wTransmitLength;
+    unsigned short wDuration;
+    unsigned short wReserved;
+    unsigned short wRTSDuration_f0;
+    unsigned short wRTSDuration_f1;
     SRTSData    Data;
 }__attribute__ ((__packed__))
 SRTS_a_FB, *PSRTS_a_FB;
@@ -520,32 +520,32 @@ typedef const SRTS_a_FB *PCSRTS_a_FB;
 // CTS buffer header
 //
 typedef struct tagSCTSData {
-    WORD    wFrameControl;
-    WORD    wDurationID;
-    BYTE    abyRA[ETH_ALEN];
-    WORD    wReserved;
+    unsigned short wFrameControl;
+    unsigned short wDurationID;
+    unsigned char abyRA[ETH_ALEN];
+    unsigned short wReserved;
 }__attribute__ ((__packed__))
 SCTSData, *PSCTSData;
 
 typedef struct tagSCTS {
-    BYTE        bySignalField_b;
-    BYTE        byServiceField_b;
-    WORD        wTransmitLength_b;
-    WORD        wDuration_ba;
-    WORD        wReserved;
+    unsigned char bySignalField_b;
+    unsigned char byServiceField_b;
+    unsigned short wTransmitLength_b;
+    unsigned short wDuration_ba;
+    unsigned short wReserved;
     SCTSData    Data;
 }__attribute__ ((__packed__))
 SCTS, *PSCTS;
 typedef const SCTS *PCSCTS;
 
 typedef struct tagSCTS_FB {
-    BYTE        bySignalField_b;
-    BYTE        byServiceField_b;
-    WORD        wTransmitLength_b;
-    WORD        wDuration_ba;
-    WORD        wReserved;
-    WORD        wCTSDuration_ba_f0;
-    WORD        wCTSDuration_ba_f1;
+    unsigned char bySignalField_b;
+    unsigned char byServiceField_b;
+    unsigned short wTransmitLength_b;
+    unsigned short wDuration_ba;
+    unsigned short wReserved;
+    unsigned short wCTSDuration_ba_f0;
+    unsigned short wCTSDuration_ba_f1;
     SCTSData    Data;
 }__attribute__ ((__packed__))
 SCTS_FB, *PSCTS_FB;
@@ -556,19 +556,19 @@ typedef const SCTS_FB *PCSCTS_FB;
 // Tx FIFO header
 //
 typedef struct tagSTxBufHead {
-    DWORD   adwTxKey[4];
-    WORD    wFIFOCtl;
-    WORD    wTimeStamp;
-    WORD    wFragCtl;
-    BYTE    byTxPower;
-    BYTE    wReserved;
+    u32 adwTxKey[4];
+    unsigned short wFIFOCtl;
+    unsigned short wTimeStamp;
+    unsigned short wFragCtl;
+    unsigned char byTxPower;
+    unsigned char wReserved;
 }__attribute__ ((__packed__))
 STxBufHead, *PSTxBufHead;
 typedef const STxBufHead *PCSTxBufHead;
 
 typedef struct tagSTxShortBufHead {
-    WORD    wFIFOCtl;
-    WORD    wTimeStamp;
+    unsigned short wFIFOCtl;
+    unsigned short wTimeStamp;
 }__attribute__ ((__packed__))
 STxShortBufHead, *PSTxShortBufHead;
 typedef const STxShortBufHead *PCSTxShortBufHead;
@@ -577,57 +577,57 @@ typedef const STxShortBufHead *PCSTxShortBufHead;
 // Tx data header
 //
 typedef struct tagSTxDataHead_g {
-    BYTE    bySignalField_b;
-    BYTE    byServiceField_b;
-    WORD    wTransmitLength_b;
-    BYTE    bySignalField_a;
-    BYTE    byServiceField_a;
-    WORD    wTransmitLength_a;
-    WORD    wDuration_b;
-    WORD    wDuration_a;
-    WORD    wTimeStampOff_b;
-    WORD    wTimeStampOff_a;
+    unsigned char bySignalField_b;
+    unsigned char byServiceField_b;
+    unsigned short wTransmitLength_b;
+    unsigned char bySignalField_a;
+    unsigned char byServiceField_a;
+    unsigned short wTransmitLength_a;
+    unsigned short wDuration_b;
+    unsigned short wDuration_a;
+    unsigned short wTimeStampOff_b;
+    unsigned short wTimeStampOff_a;
 }__attribute__ ((__packed__))
 STxDataHead_g, *PSTxDataHead_g;
 typedef const STxDataHead_g *PCSTxDataHead_g;
 
 typedef struct tagSTxDataHead_g_FB {
-    BYTE    bySignalField_b;
-    BYTE    byServiceField_b;
-    WORD    wTransmitLength_b;
-    BYTE    bySignalField_a;
-    BYTE    byServiceField_a;
-    WORD    wTransmitLength_a;
-    WORD    wDuration_b;
-    WORD    wDuration_a;
-    WORD    wDuration_a_f0;
-    WORD    wDuration_a_f1;
-    WORD    wTimeStampOff_b;
-    WORD    wTimeStampOff_a;
+    unsigned char bySignalField_b;
+    unsigned char byServiceField_b;
+    unsigned short wTransmitLength_b;
+    unsigned char bySignalField_a;
+    unsigned char byServiceField_a;
+    unsigned short wTransmitLength_a;
+    unsigned short wDuration_b;
+    unsigned short wDuration_a;
+    unsigned short wDuration_a_f0;
+    unsigned short wDuration_a_f1;
+    unsigned short wTimeStampOff_b;
+    unsigned short wTimeStampOff_a;
 }__attribute__ ((__packed__))
 STxDataHead_g_FB, *PSTxDataHead_g_FB;
 typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB;
 
 
 typedef struct tagSTxDataHead_ab {
-    BYTE    bySignalField;
-    BYTE    byServiceField;
-    WORD    wTransmitLength;
-    WORD    wDuration;
-    WORD    wTimeStampOff;
+    unsigned char bySignalField;
+    unsigned char byServiceField;
+    unsigned short wTransmitLength;
+    unsigned short wDuration;
+    unsigned short wTimeStampOff;
 }__attribute__ ((__packed__))
 STxDataHead_ab, *PSTxDataHead_ab;
 typedef const STxDataHead_ab *PCSTxDataHead_ab;
 
 
 typedef struct tagSTxDataHead_a_FB {
-    BYTE    bySignalField;
-    BYTE    byServiceField;
-    WORD    wTransmitLength;
-    WORD    wDuration;
-    WORD    wTimeStampOff;
-    WORD    wDuration_f0;
-    WORD    wDuration_f1;
+    unsigned char bySignalField;
+    unsigned char byServiceField;
+    unsigned short wTransmitLength;
+    unsigned short wDuration;
+    unsigned short wTimeStampOff;
+    unsigned short wDuration_f0;
+    unsigned short wDuration_f1;
 }__attribute__ ((__packed__))
 STxDataHead_a_FB, *PSTxDataHead_a_FB;
 typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
@@ -636,37 +636,37 @@ typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
 // MICHDR data header
 //
 typedef struct tagSMICHDRHead {
-    DWORD   adwHDR0[4];
-    DWORD   adwHDR1[4];
-    DWORD   adwHDR2[4];
+    u32 adwHDR0[4];
+    u32 adwHDR1[4];
+    u32 adwHDR2[4];
 }__attribute__ ((__packed__))
 SMICHDRHead, *PSMICHDRHead;
 typedef const SMICHDRHead *PCSMICHDRHead;
 
 typedef struct tagSBEACONCtl {
-    DWORD   BufReady : 1;
-    DWORD   TSF      : 15;
-    DWORD   BufLen   : 11;
-    DWORD   Reserved : 5;
+    u32 BufReady : 1;
+    u32 TSF      : 15;
+    u32 BufLen   : 11;
+    u32 Reserved : 5;
 }__attribute__ ((__packed__))
 SBEACONCtl;
 
 
 typedef struct tagSSecretKey {
-    DWORD   dwLowDword;
-    BYTE    byHighByte;
+    u32 dwLowDword;
+    unsigned char byHighByte;
 }__attribute__ ((__packed__))
 SSecretKey;
 
 typedef struct tagSKeyEntry {
-    BYTE  abyAddrHi[2];
-    WORD  wKCTL;
-    BYTE  abyAddrLo[4];
-    DWORD dwKey0[4];
-    DWORD dwKey1[4];
-    DWORD dwKey2[4];
-    DWORD dwKey3[4];
-    DWORD dwKey4[4];
+    unsigned char abyAddrHi[2];
+    unsigned short wKCTL;
+    unsigned char abyAddrLo[4];
+    u32 dwKey0[4];
+    u32 dwKey1[4];
+    u32 dwKey2[4];
+    u32 dwKey3[4];
+    u32 dwKey4[4];
 }__attribute__ ((__packed__))
 SKeyEntry;
 /*---------------------  Export Macros ------------------------------*/
index 40ee4e14237e7a912eea443a4efb09de63b3a542..2e7c2fd7b7e6b306edc20297cc32c2717077705d 100644 (file)
 #include <linux/wait.h>
 #include <linux/if_arp.h>
 #include <linux/sched.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/if.h>
 //#include <linux/config.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/proc_fs.h>
 #include <linux/inetdevice.h>
 #include <linux/reboot.h>
@@ -218,7 +218,7 @@ typedef enum __device_init_type {
 #define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED    0x01
 
 // PMKID Structures
-typedef UCHAR   NDIS_802_11_PMKID_VALUE[16];
+typedef unsigned char NDIS_802_11_PMKID_VALUE[16];
 
 
 typedef enum _NDIS_802_11_WEP_STATUS
@@ -250,7 +250,7 @@ typedef enum _NDIS_802_11_STATUS_TYPE
 //Added new types for PMKID Candidate lists.
 typedef struct _PMKID_CANDIDATE {
     NDIS_802_11_MAC_ADDRESS BSSID;
-    ULONG Flags;
+    unsigned long Flags;
 } PMKID_CANDIDATE, *PPMKID_CANDIDATE;
 
 
@@ -261,15 +261,15 @@ typedef struct _BSSID_INFO
 } BSSID_INFO, *PBSSID_INFO;
 
 typedef struct tagSPMKID {
-    ULONG Length;
-    ULONG BSSIDInfoCount;
+    unsigned long Length;
+    unsigned long BSSIDInfoCount;
     BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID];
 } SPMKID, *PSPMKID;
 
 typedef struct tagSPMKIDCandidateEvent {
     NDIS_802_11_STATUS_TYPE     StatusType;
-    ULONG Version;       // Version of the structure
-    ULONG NumCandidates; // No. of pmkid candidates
+    unsigned long Version;       // Version of the structure
+    unsigned long NumCandidates; // No. of pmkid candidates
     PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST];
 } SPMKIDCandidateEvent, *PSPMKIDCandidateEvent;
 
@@ -279,10 +279,10 @@ typedef struct tagSPMKIDCandidateEvent {
 #define MAX_QUIET_COUNT     8
 
 typedef struct tagSQuietControl {
-    BOOL        bEnable;
-    DWORD       dwStartTime;
-    BYTE        byPeriod;
-    WORD        wDuration;
+    bool bEnable;
+    unsigned long dwStartTime;
+    unsigned char byPeriod;
+    unsigned short wDuration;
 } SQuietControl, *PSQuietControl;
 
 //--
@@ -291,7 +291,7 @@ typedef struct __chip_info_tbl{
     char*       name;
     int         io_size;
     int         nTxQueue;
-    U32         flags;
+    u32         flags;
 } CHIP_INFO, *PCHIP_INFO;
 
 
@@ -303,15 +303,15 @@ typedef enum {
 
 // The receive duplicate detection cache entry
 typedef struct tagSCacheEntry{
-    WORD        wFmSequence;
-    BYTE        abyAddr2[ETH_ALEN];
+    unsigned short wFmSequence;
+    unsigned char abyAddr2[ETH_ALEN];
 } SCacheEntry, *PSCacheEntry;
 
 typedef struct tagSCache{
 /* The receive cache is updated circularly.  The next entry to be written is
  * indexed by the "InPtr".
 */
-    UINT            uInPtr;         // Place to use next
+    unsigned int uInPtr;         // Place to use next
     SCacheEntry     asCacheEntry[DUPLICATE_RX_CACHE_LENGTH];
 } SCache, *PSCache;
 
@@ -319,14 +319,14 @@ typedef struct tagSCache{
 // DeFragment Control Block, used for collecting fragments prior to reassembly
 typedef struct tagSDeFragControlBlock
 {
-    WORD            wSequence;
-    WORD            wFragNum;
-    BYTE            abyAddr2[ETH_ALEN];
-       UINT            uLifetime;
+    unsigned short wSequence;
+    unsigned short wFragNum;
+    unsigned char abyAddr2[ETH_ALEN];
+    unsigned int uLifetime;
     struct sk_buff* skb;
-    PBYTE           pbyRxBuffer;
-    UINT            cbFrameLength;
-    BOOL            bInUse;
+    unsigned char *pbyRxBuffer;
+    unsigned int cbFrameLength;
+    bool bInUse;
 } SDeFragControlBlock, *PSDeFragControlBlock;
 
 
@@ -386,7 +386,7 @@ typedef struct __device_opt {
     int         short_retry;
     int         long_retry;
     int         bbp_type;
-    U32         flags;
+    u32         flags;
 } OPTIONS, *POPTIONS;
 
 
@@ -417,21 +417,21 @@ typedef struct __device_info {
     dma_addr_t                  tx_bufs_dma1;
     dma_addr_t                  tx_beacon_dma;
 
-    PBYTE                       tx0_bufs;
-    PBYTE                       tx1_bufs;
-    PBYTE                       tx_beacon_bufs;
+    unsigned char *tx0_bufs;
+    unsigned char *tx1_bufs;
+    unsigned char *tx_beacon_bufs;
 
     CHIP_TYPE                   chip_id;
 
-    U32                         PortOffset;
-    DWORD                       dwIsr;
-    U32                         memaddr;
-    U32                         ioaddr;
-    U32                         io_size;
+    unsigned long               PortOffset;
+    unsigned long dwIsr;
+    u32                         memaddr;
+    u32                         ioaddr;
+    u32                         io_size;
 
-    BYTE                        byRevId;
-    WORD                        SubSystemID;
-    WORD                        SubVendorID;
+    unsigned char byRevId;
+    unsigned short SubSystemID;
+    unsigned short SubVendorID;
 
     int                         nTxQueues;
     volatile int                iTDUsed[TYPE_MAXTD];
@@ -448,17 +448,17 @@ typedef struct __device_info {
     SCache                      sDupRxCache;
 
     SDeFragControlBlock         sRxDFCB[CB_MAX_RX_FRAG];
-    UINT                        cbDFCB;
-    UINT                        cbFreeDFCB;
-    UINT                        uCurrentDFCBIdx;
+    unsigned int       cbDFCB;
+    unsigned int       cbFreeDFCB;
+    unsigned int       uCurrentDFCBIdx;
 
     OPTIONS                     sOpts;
 
-    U32                         flags;
+    u32                         flags;
 
-    U32                         rx_buf_sz;
+    u32                         rx_buf_sz;
     int                         multicast_limit;
-    BYTE                        byRxMode;
+    unsigned char byRxMode;
 
     spinlock_t                  lock;
 //PLICE_DEBUG->
@@ -472,19 +472,19 @@ typedef struct __device_info {
 //PLICE_DEBUG <-
 
 
-    U32                         rx_bytes;
+    u32                         rx_bytes;
 
     // Version control
-    BYTE                        byLocalID;
-    BYTE                        byRFType;
+    unsigned char byLocalID;
+    unsigned char byRFType;
 
-    BYTE                        byMaxPwrLevel;
-    BYTE                        byZoneType;
-    BOOL                        bZoneRegExist;
-   BYTE                        byOriginalZonetype;
-    BYTE                        abyMacContext[MAC_MAX_CONTEXT_REG];
-    BOOL                        bLinkPass;          // link status: OK or fail
-    BYTE                        abyCurrentNetAddr[ETH_ALEN];
+    unsigned char byMaxPwrLevel;
+    unsigned char byZoneType;
+    bool bZoneRegExist;
+   unsigned char byOriginalZonetype;
+    unsigned char abyMacContext[MAC_MAX_CONTEXT_REG];
+    bool bLinkPass;          // link status: OK or fail
+    unsigned char abyCurrentNetAddr[ETH_ALEN];
 
     // Adapter statistics
     SStatCounter                scStatistic;
@@ -497,249 +497,249 @@ typedef struct __device_info {
     SMgmtObject                 sMgmtObj;
 
     // 802.11 MAC specific
-    UINT                        uCurrRSSI;
-    BYTE                        byCurrSQ;
-
-    DWORD                       dwTxAntennaSel;
-    DWORD                       dwRxAntennaSel;
-    BYTE                        byAntennaCount;
-    BYTE                        byRxAntennaMode;
-    BYTE                        byTxAntennaMode;
-    BOOL                        bTxRxAntInv;
-
-    PBYTE                       pbyTmpBuff;
-    UINT                        uSIFS;    //Current SIFS
-    UINT                        uDIFS;    //Current DIFS
-    UINT                        uEIFS;    //Current EIFS
-    UINT                        uSlot;    //Current SlotTime
-    UINT                        uCwMin;   //Current CwMin
-    UINT                        uCwMax;   //CwMax is fixed on 1023.
+    unsigned int       uCurrRSSI;
+    unsigned char byCurrSQ;
+
+    unsigned long dwTxAntennaSel;
+    unsigned long dwRxAntennaSel;
+    unsigned char byAntennaCount;
+    unsigned char byRxAntennaMode;
+    unsigned char byTxAntennaMode;
+    bool bTxRxAntInv;
+
+    unsigned char *pbyTmpBuff;
+    unsigned int       uSIFS;    //Current SIFS
+    unsigned int       uDIFS;    //Current DIFS
+    unsigned int       uEIFS;    //Current EIFS
+    unsigned int       uSlot;    //Current SlotTime
+    unsigned int       uCwMin;   //Current CwMin
+    unsigned int       uCwMax;   //CwMax is fixed on 1023.
     // PHY parameter
-    BYTE                        bySIFS;
-    BYTE                        byDIFS;
-    BYTE                        byEIFS;
-    BYTE                        bySlot;
-    BYTE                        byCWMaxMin;
+    unsigned char bySIFS;
+    unsigned char byDIFS;
+    unsigned char byEIFS;
+    unsigned char bySlot;
+    unsigned char byCWMaxMin;
     CARD_PHY_TYPE               eCurrentPHYType;
 
 
     VIA_BB_TYPE                 byBBType; //0: 11A, 1:11B, 2:11G
     VIA_PKT_TYPE                byPacketType; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
-    WORD                        wBasicRate;
-    BYTE                        byACKRate;
-    BYTE                        byTopOFDMBasicRate;
-    BYTE                        byTopCCKBasicRate;
-
-    BYTE                        byMinChannel;
-    BYTE                        byMaxChannel;
-    UINT                        uConnectionRate;
-
-    BYTE                        byPreambleType;
-    BYTE                        byShortPreamble;
-
-    WORD                        wCurrentRate;
-    WORD                        wRTSThreshold;
-    WORD                        wFragmentationThreshold;
-    BYTE                        byShortRetryLimit;
-    BYTE                        byLongRetryLimit;
+    unsigned short wBasicRate;
+    unsigned char byACKRate;
+    unsigned char byTopOFDMBasicRate;
+    unsigned char byTopCCKBasicRate;
+
+    unsigned char byMinChannel;
+    unsigned char byMaxChannel;
+    unsigned int       uConnectionRate;
+
+    unsigned char byPreambleType;
+    unsigned char byShortPreamble;
+
+    unsigned short wCurrentRate;
+    unsigned short wRTSThreshold;
+    unsigned short wFragmentationThreshold;
+    unsigned char byShortRetryLimit;
+    unsigned char byLongRetryLimit;
     CARD_OP_MODE                eOPMode;
-    BYTE                        byOpMode;
-    BOOL                        bBSSIDFilter;
-    WORD                        wMaxTransmitMSDULifetime;
-    BYTE                        abyBSSID[ETH_ALEN];
-    BYTE                        abyDesireBSSID[ETH_ALEN];
-    WORD                        wCTSDuration;       // update while speed change
-    WORD                        wACKDuration;       // update while speed change
-    WORD                        wRTSTransmitLen;    // update while speed change
-    BYTE                        byRTSServiceField;  // update while speed change
-    BYTE                        byRTSSignalField;   // update while speed change
-
-    DWORD                       dwMaxReceiveLifetime;       // dot11MaxReceiveLifetime
-
-    BOOL                        bCCK;
-    BOOL                        bEncryptionEnable;
-    BOOL                        bLongHeader;
-    BOOL                        bShortSlotTime;
-    BOOL                        bProtectMode;
-    BOOL                        bNonERPPresent;
-    BOOL                        bBarkerPreambleMd;
-
-    BYTE                        byERPFlag;
-    WORD                        wUseProtectCntDown;
-
-    BOOL                        bRadioControlOff;
-    BOOL                        bRadioOff;
-    BOOL                    bEnablePSMode;
-    WORD                    wListenInterval;
-    BOOL                    bPWBitOn;
+    unsigned char byOpMode;
+    bool bBSSIDFilter;
+    unsigned short wMaxTransmitMSDULifetime;
+    unsigned char abyBSSID[ETH_ALEN];
+    unsigned char abyDesireBSSID[ETH_ALEN];
+    unsigned short wCTSDuration;       // update while speed change
+    unsigned short wACKDuration;       // update while speed change
+    unsigned short wRTSTransmitLen;    // update while speed change
+    unsigned char byRTSServiceField;  // update while speed change
+    unsigned char byRTSSignalField;   // update while speed change
+
+    unsigned long dwMaxReceiveLifetime;       // dot11MaxReceiveLifetime
+
+    bool bCCK;
+    bool bEncryptionEnable;
+    bool bLongHeader;
+    bool bShortSlotTime;
+    bool bProtectMode;
+    bool bNonERPPresent;
+    bool bBarkerPreambleMd;
+
+    unsigned char byERPFlag;
+    unsigned short wUseProtectCntDown;
+
+    bool bRadioControlOff;
+    bool bRadioOff;
+    bool bEnablePSMode;
+    unsigned short wListenInterval;
+    bool bPWBitOn;
     WMAC_POWER_MODE         ePSMode;
 
 
     // GPIO Radio Control
-    BYTE                    byRadioCtl;
-    BYTE                    byGPIO;
-    BOOL                    bHWRadioOff;
-    BOOL                    bPrvActive4RadioOFF;
-    BOOL                    bGPIOBlockRead;
+    unsigned char byRadioCtl;
+    unsigned char byGPIO;
+    bool bHWRadioOff;
+    bool bPrvActive4RadioOFF;
+    bool bGPIOBlockRead;
 
     // Beacon releated
-    WORD                    wSeqCounter;
-    WORD                    wBCNBufLen;
-    BOOL                    bBeaconBufReady;
-    BOOL                    bBeaconSent;
-    BOOL                    bIsBeaconBufReadySet;
-    UINT                    cbBeaconBufReadySetCnt;
-    BOOL                    bFixRate;
-    BYTE                    byCurrentCh;
-    UINT                    uScanTime;
+    unsigned short wSeqCounter;
+    unsigned short wBCNBufLen;
+    bool bBeaconBufReady;
+    bool bBeaconSent;
+    bool bIsBeaconBufReadySet;
+    unsigned int       cbBeaconBufReadySetCnt;
+    bool bFixRate;
+    unsigned char byCurrentCh;
+    unsigned int       uScanTime;
 
     CMD_STATE               eCommandState;
 
     CMD_CODE                eCommand;
-    BOOL                    bBeaconTx;
+    bool bBeaconTx;
 
-    BOOL                    bStopBeacon;
-    BOOL                    bStopDataPkt;
-    BOOL                    bStopTx0Pkt;
-    UINT                    uAutoReConnectTime;
+    bool bStopBeacon;
+    bool bStopDataPkt;
+    bool bStopTx0Pkt;
+    unsigned int       uAutoReConnectTime;
 
     // 802.11 counter
 
     CMD_ITEM                eCmdQueue[CMD_Q_SIZE];
-    UINT                    uCmdDequeueIdx;
-    UINT                    uCmdEnqueueIdx;
-    UINT                    cbFreeCmdQueue;
-    BOOL                    bCmdRunning;
-    BOOL                    bCmdClear;
+    unsigned int       uCmdDequeueIdx;
+    unsigned int       uCmdEnqueueIdx;
+    unsigned int       cbFreeCmdQueue;
+    bool bCmdRunning;
+    bool bCmdClear;
 
 
 
-    BOOL                    bRoaming;
+    bool bRoaming;
     //WOW
-    BYTE                    abyIPAddr[4];
+    unsigned char abyIPAddr[4];
 
-    ULONG                   ulTxPower;
+    unsigned long ulTxPower;
     NDIS_802_11_WEP_STATUS  eEncryptionStatus;
-    BOOL                    bTransmitKey;
+    bool bTransmitKey;
 //2007-0925-01<Add>by MikeLiu
 //mike add :save old Encryption
     NDIS_802_11_WEP_STATUS  eOldEncryptionStatus;
 
     SKeyManagement          sKey;
-    DWORD                   dwIVCounter;
+    unsigned long dwIVCounter;
 
     QWORD                   qwPacketNumber; //For CCMP and TKIP as TSC(6 bytes)
-    UINT                    uCurrentWEPMode;
+    unsigned int       uCurrentWEPMode;
 
     RC4Ext                  SBox;
-    BYTE                    abyPRNG[WLAN_WEPMAX_KEYLEN+3];
-    BYTE                    byKeyIndex;
-    UINT                    uKeyLength;
-    BYTE                    abyKey[WLAN_WEP232_KEYLEN];
+    unsigned char abyPRNG[WLAN_WEPMAX_KEYLEN+3];
+    unsigned char byKeyIndex;
+    unsigned int       uKeyLength;
+    unsigned char abyKey[WLAN_WEP232_KEYLEN];
 
-    BOOL                    bAES;
-    BYTE                    byCntMeasure;
+    bool bAES;
+    unsigned char byCntMeasure;
 
     // for AP mode
-    UINT                    uAssocCount;
-    BOOL                    bMoreData;
+    unsigned int       uAssocCount;
+    bool bMoreData;
 
     // QoS
-    BOOL                    bGrpAckPolicy;
+    bool bGrpAckPolicy;
 
     // for OID_802_11_ASSOCIATION_INFORMATION
-    BOOL                    bAssocInfoSet;
+    bool bAssocInfoSet;
 
 
-    BYTE                    byAutoFBCtrl;
+    unsigned char byAutoFBCtrl;
 
-    BOOL                    bTxMICFail;
-    BOOL                    bRxMICFail;
+    bool bTxMICFail;
+    bool bRxMICFail;
 
 
-    UINT                    uRATEIdx;
+    unsigned int       uRATEIdx;
 
 
     // For Update BaseBand VGA Gain Offset
-    BOOL                    bUpdateBBVGA;
-    UINT                    uBBVGADiffCount;
-    BYTE                    byBBVGANew;
-    BYTE                    byBBVGACurrent;
-    BYTE                    abyBBVGA[BB_VGA_LEVEL];
-    LONG                    ldBmThreshold[BB_VGA_LEVEL];
+    bool bUpdateBBVGA;
+    unsigned int       uBBVGADiffCount;
+    unsigned char byBBVGANew;
+    unsigned char byBBVGACurrent;
+    unsigned char abyBBVGA[BB_VGA_LEVEL];
+    long                    ldBmThreshold[BB_VGA_LEVEL];
 
-    BYTE                    byBBPreEDRSSI;
-    BYTE                    byBBPreEDIndex;
+    unsigned char byBBPreEDRSSI;
+    unsigned char byBBPreEDIndex;
 
 
-    BOOL                    bRadioCmd;
-    DWORD                   dwDiagRefCount;
+    bool bRadioCmd;
+    unsigned long dwDiagRefCount;
 
     // For FOE Tuning
-    BYTE                    byFOETuning;
+    unsigned char byFOETuning;
 
     // For Auto Power Tunning
 
-    BYTE                    byAutoPwrTunning;
-    SHORT                   sPSetPointCCK;
-    SHORT                   sPSetPointOFDMG;
-    SHORT                   sPSetPointOFDMA;
-    LONG                    lPFormulaOffset;
-    SHORT                   sPThreshold;
-    CHAR                    cAdjustStep;
-    CHAR                    cMinTxAGC;
+    unsigned char byAutoPwrTunning;
+    short                   sPSetPointCCK;
+    short                   sPSetPointOFDMG;
+    short                   sPSetPointOFDMA;
+    long                    lPFormulaOffset;
+    short                   sPThreshold;
+    char                    cAdjustStep;
+    char                    cMinTxAGC;
 
     // For RF Power table
-    BYTE                    byCCKPwr;
-    BYTE                    byOFDMPwrG;
-    BYTE                    byCurPwr;
-    I8                      byCurPwrdBm;
-    BYTE                    abyCCKPwrTbl[CB_MAX_CHANNEL_24G+1];
-    BYTE                    abyOFDMPwrTbl[CB_MAX_CHANNEL+1];
-    I8                      abyCCKDefaultPwr[CB_MAX_CHANNEL_24G+1];
-    I8                      abyOFDMDefaultPwr[CB_MAX_CHANNEL+1];
-    I8                      abyRegPwr[CB_MAX_CHANNEL+1];
-    I8                      abyLocalPwr[CB_MAX_CHANNEL+1];
+    unsigned char byCCKPwr;
+    unsigned char byOFDMPwrG;
+    unsigned char byCurPwr;
+    char        byCurPwrdBm;
+    unsigned char abyCCKPwrTbl[CB_MAX_CHANNEL_24G+1];
+    unsigned char abyOFDMPwrTbl[CB_MAX_CHANNEL+1];
+    char       abyCCKDefaultPwr[CB_MAX_CHANNEL_24G+1];
+    char       abyOFDMDefaultPwr[CB_MAX_CHANNEL+1];
+    char       abyRegPwr[CB_MAX_CHANNEL+1];
+    char       abyLocalPwr[CB_MAX_CHANNEL+1];
 
 
     // BaseBand Loopback Use
-    BYTE                    byBBCR4d;
-    BYTE                    byBBCRc9;
-    BYTE                    byBBCR88;
-    BYTE                    byBBCR09;
+    unsigned char byBBCR4d;
+    unsigned char byBBCRc9;
+    unsigned char byBBCR88;
+    unsigned char byBBCR09;
 
     // command timer
     struct timer_list       sTimerCommand;
 #ifdef TxInSleep
      struct timer_list       sTimerTxData;
-     ULONG                       nTxDataTimeCout;
-     BOOL  fTxDataInSleep;
-     BOOL  IsTxDataTrigger;
+     unsigned long nTxDataTimeCout;
+     bool fTxDataInSleep;
+     bool IsTxDataTrigger;
 #endif
 
 #ifdef WPA_SM_Transtatus
-    BOOL  fWPA_Authened;           //is WPA/WPA-PSK or WPA2/WPA2-PSK authen??
+    bool fWPA_Authened;           //is WPA/WPA-PSK or WPA2/WPA2-PSK authen??
 #endif
-    BYTE            byReAssocCount;   //mike add:re-association retry times!
-    BYTE            byLinkWaitCount;
+    unsigned char byReAssocCount;   //mike add:re-association retry times!
+    unsigned char byLinkWaitCount;
 
 
-    BYTE                    abyNodeName[17];
+    unsigned char abyNodeName[17];
 
-    BOOL                    bDiversityRegCtlON;
-    BOOL                    bDiversityEnable;
-    ULONG                   ulDiversityNValue;
-    ULONG                   ulDiversityMValue;
-    BYTE                    byTMax;
-    BYTE                    byTMax2;
-    BYTE                    byTMax3;
-    ULONG                   ulSQ3TH;
+    bool bDiversityRegCtlON;
+    bool bDiversityEnable;
+    unsigned long ulDiversityNValue;
+    unsigned long ulDiversityMValue;
+    unsigned char byTMax;
+    unsigned char byTMax2;
+    unsigned char byTMax3;
+    unsigned long ulSQ3TH;
 
 // ANT diversity
-    ULONG                   uDiversityCnt;
-    BYTE                    byAntennaState;
-    ULONG                   ulRatio_State0;
-    ULONG                   ulRatio_State1;
+    unsigned long uDiversityCnt;
+    unsigned char byAntennaState;
+    unsigned long ulRatio_State0;
+    unsigned long ulRatio_State1;
 
     //SQ3 functions for antenna diversity
     struct timer_list           TimerSQ3Tmax1;
@@ -747,80 +747,80 @@ typedef struct __device_info {
     struct timer_list           TimerSQ3Tmax3;
 
 
-    ULONG                   uNumSQ3[MAX_RATE];
-    WORD                    wAntDiversityMaxRate;
+    unsigned long uNumSQ3[MAX_RATE];
+    unsigned short wAntDiversityMaxRate;
 
 
     SEthernetHeader         sTxEthHeader;
     SEthernetHeader         sRxEthHeader;
-    BYTE                    abyBroadcastAddr[ETH_ALEN];
-    BYTE                    abySNAP_RFC1042[ETH_ALEN];
-    BYTE                    abySNAP_Bridgetunnel[ETH_ALEN];
-     BYTE                        abyEEPROM[EEP_MAX_CONTEXT_SIZE];  //DWORD alignment
+    unsigned char abyBroadcastAddr[ETH_ALEN];
+    unsigned char abySNAP_RFC1042[ETH_ALEN];
+    unsigned char abySNAP_Bridgetunnel[ETH_ALEN];
+     unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE];  //unsigned long alignment
     // Pre-Authentication & PMK cache
     SPMKID                  gsPMKID;
     SPMKIDCandidateEvent    gsPMKIDCandidate;
 
 
     // for 802.11h
-    BOOL                    b11hEnable;
-    BYTE                    abyCountryCode[3];
+    bool b11hEnable;
+    unsigned char abyCountryCode[3];
     // for 802.11h DFS
-    UINT                    uNumOfMeasureEIDs;
+    unsigned int       uNumOfMeasureEIDs;
     PWLAN_IE_MEASURE_REQ    pCurrMeasureEID;
-    BOOL                    bMeasureInProgress;
-    BYTE                    byOrgChannel;
-    BYTE                    byOrgRCR;
-    DWORD                   dwOrgMAR0;
-    DWORD                   dwOrgMAR4;
-    BYTE                    byBasicMap;
-    BYTE                    byCCAFraction;
-    BYTE                    abyRPIs[8];
-    DWORD                   dwRPIs[8];
-    BOOL                    bChannelSwitch;
-    BYTE                    byNewChannel;
-    BYTE                    byChannelSwitchCount;
-    BOOL                    bQuietEnable;
-    BOOL                    bEnableFirstQuiet;
-    BYTE                    byQuietStartCount;
-    UINT                    uQuietEnqueue;
-    DWORD                   dwCurrentQuietEndTime;
+    bool bMeasureInProgress;
+    unsigned char byOrgChannel;
+    unsigned char byOrgRCR;
+    unsigned long dwOrgMAR0;
+    unsigned long dwOrgMAR4;
+    unsigned char byBasicMap;
+    unsigned char byCCAFraction;
+    unsigned char abyRPIs[8];
+    unsigned long dwRPIs[8];
+    bool bChannelSwitch;
+    unsigned char byNewChannel;
+    unsigned char byChannelSwitchCount;
+    bool bQuietEnable;
+    bool bEnableFirstQuiet;
+    unsigned char byQuietStartCount;
+    unsigned int       uQuietEnqueue;
+    unsigned long dwCurrentQuietEndTime;
     SQuietControl           sQuiet[MAX_QUIET_COUNT];
     // for 802.11h TPC
-    BOOL                    bCountryInfo5G;
-    BOOL                    bCountryInfo24G;
+    bool bCountryInfo5G;
+    bool bCountryInfo24G;
 
-    WORD                    wBeaconInterval;
+    unsigned short wBeaconInterval;
 
     //WPA supplicant deamon
        struct net_device       *wpadev;
-       BOOL                    bWPADEVUp;
+       bool bWPADEVUp;
     struct sk_buff          *skb;
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 /*
-        BOOL                 bwextstep0;
-        BOOL                 bwextstep1;
-        BOOL                 bwextstep2;
-        BOOL                 bwextstep3;
+        bool bwextstep0;
+        bool bwextstep1;
+        bool bwextstep2;
+        bool bwextstep3;
         */
-        UINT                   bwextcount;
-        BOOL                 bWPASuppWextEnabled;
+        unsigned int   bwextcount;
+        bool bWPASuppWextEnabled;
 #endif
 
     //--
 #ifdef HOSTAP
     // user space daemon: hostapd, is used for HOSTAP
-       BOOL                    bEnableHostapd;
-       BOOL                    bEnable8021x;
-       BOOL                    bEnableHostWEP;
+       bool bEnableHostapd;
+       bool bEnable8021x;
+       bool bEnableHostWEP;
        struct net_device       *apdev;
        int (*tx_80211)(struct sk_buff *skb, struct net_device *dev);
 #endif
-    UINT                    uChannel;
-    BOOL                    bMACSuspend;
+    unsigned int       uChannel;
+    bool bMACSuspend;
 
        struct iw_statistics    wstats;         // wireless stats
-    BOOL                    bCommit;
+    bool bCommit;
 
 } DEVICE_INFO, *PSDevice;
 
@@ -880,7 +880,7 @@ void        InitRxManagementQueue(PSDevice   pDevice);
 
 
 
-inline static BOOL device_get_ip(PSDevice pInfo) {
+inline static bool device_get_ip(PSDevice pInfo) {
     struct in_device* in_dev=(struct in_device*) pInfo->dev->ip_ptr;
     struct in_ifaddr* ifa;
 
@@ -888,10 +888,10 @@ inline static BOOL device_get_ip(PSDevice pInfo) {
         ifa=(struct in_ifaddr*) in_dev->ifa_list;
         if (ifa!=NULL) {
             memcpy(pInfo->abyIPAddr,&ifa->ifa_address,4);
-            return TRUE;
+            return true;
         }
     }
-    return FALSE;
+    return false;
 }
 
 
@@ -920,9 +920,9 @@ static inline PDEVICE_TD_INFO alloc_td_info(void) {
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex);
-BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF);
-int Config_FileOperation(PSDevice pDevice,BOOL fwrite,unsigned char *Parameter);
+bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex);
+bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF);
+int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter);
 #endif
 
 
index d1e9c1930bdba530696a66b24ae8776ff0a35c3f..408edc27075fdf674643fb32cbf1276711553c37 100644 (file)
@@ -39,14 +39,6 @@ struct _version {
     unsigned char   build;
 } version_t, *pversion_t;
 
-#ifndef FALSE
-#define FALSE   (0)
-#endif
-
-#ifndef TRUE
-#define TRUE    (!(FALSE))
-#endif
-
 #define VID_TABLE_SIZE      64
 #define MCAST_TABLE_SIZE    64
 #define MCAM_SIZE           32
index e49bb258b5c3e26a1053627eecf41974894d0142..4d6b66a4fd9dd26f1887948bad00711efb2c975e 100644 (file)
@@ -26,9 +26,9 @@
  *
  * Functions:
  *
- *   device_found1 - module initial (insmod) driver entry
- *   device_remove1 - module remove entry
- *   device_init_info - device structure resource allocation function
+ *   vt6655_probe - module initial (insmod) driver entry
+ *   vt6655_remove - module remove entry
+ *   vt6655_init_info - device structure resource allocation function
  *   device_free_info - device structure resource free function
  *   device_get_pci_info - get allocated pci io/mem resource
  *   device_print_info - print out resource
@@ -62,6 +62,7 @@
 
 #include "device.h"
 #include "card.h"
+#include "channel.h"
 #include "baseband.h"
 #include "mac.h"
 #include "tether.h"
@@ -133,10 +134,10 @@ DEVICE_PARAM(TxDescriptors1,"Number of transmit descriptors1");
 
 
 #define IP_ALIG_DEF     0
-/* IP_byte_align[] is used for IP header DWORD byte aligned
-   0: indicate the IP header won't be DWORD byte aligned.(Default) .
-   1: indicate the IP header will be DWORD byte aligned.
-      In some enviroment, the IP header should be DWORD byte aligned,
+/* IP_byte_align[] is used for IP header unsigned long byte aligned
+   0: indicate the IP header won't be unsigned long byte aligned.(Default) .
+   1: indicate the IP header will be unsigned long byte aligned.
+      In some enviroment, the IP header should be unsigned long byte aligned,
       or the packet will be droped when we receive it. (eg: IPVS)
 */
 DEVICE_PARAM(IP_byte_align,"Enable IP header dword aligned");
@@ -284,7 +285,7 @@ static CHIP_INFO chip_info_table[]= {
     {0,NULL}
 };
 
-DEFINE_PCI_DEVICE_TABLE(device_id_table) = {
+DEFINE_PCI_DEVICE_TABLE(vt6655_pci_id_table) = {
        { PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table},
        { 0, }
 };
@@ -292,10 +293,10 @@ DEFINE_PCI_DEVICE_TABLE(device_id_table) = {
 /*---------------------  Static Functions  --------------------------*/
 
 
-static int  device_found1(struct pci_dev *pcid, const struct pci_device_id *ent);
-static BOOL device_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO);
+static int  vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent);
+static bool vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO);
 static void device_free_info(PSDevice pDevice);
-static BOOL device_get_pci_info(PSDevice, struct pci_dev* pcid);
+static bool device_get_pci_info(PSDevice, struct pci_dev* pcid);
 static void device_print_info(PSDevice pDevice);
 static struct net_device_stats *device_get_stats(struct net_device *dev);
 static void device_init_diversity_timer(PSDevice pDevice);
@@ -326,12 +327,12 @@ static void device_init_td1_ring(PSDevice pDevice);
 
 static int  device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
 //2008-0714<Add>by Mike Liu
-static BOOL device_release_WPADEV(PSDevice pDevice);
+static bool device_release_WPADEV(PSDevice pDevice);
 
 static int  ethtool_ioctl(struct net_device *dev, void *useraddr);
-static int  device_rx_srv(PSDevice pDevice, UINT uIdx);
-static int  device_tx_srv(PSDevice pDevice, UINT uIdx);
-static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc);
+static int  device_rx_srv(PSDevice pDevice, unsigned int uIdx);
+static int  device_tx_srv(PSDevice pDevice, unsigned int uIdx);
+static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc);
 static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
 static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc);
 static void device_free_td0_ring(PSDevice pDevice);
@@ -340,7 +341,8 @@ static void device_free_rd0_ring(PSDevice pDevice);
 static void device_free_rd1_ring(PSDevice pDevice);
 static void device_free_rings(PSDevice pDevice);
 static void device_free_frag_buf(PSDevice pDevice);
-static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source);
+static int Config_FileGetParameter(unsigned char *string,
+               unsigned char *dest, unsigned char *source);
 
 
 /*---------------------  Export Variables  --------------------------*/
@@ -357,7 +359,7 @@ static char* get_chip_name(int chip_id) {
     return chip_info_table[i].name;
 }
 
-static void device_remove1(struct pci_dev *pcid)
+static void __devexit vt6655_remove(struct pci_dev *pcid)
 {
     PSDevice pDevice=pci_get_drvdata(pcid);
 
@@ -384,7 +386,7 @@ device_set_int_opt(int *opt, int val, int min, int max, int def,char* name,char*
 }
 
 static void
-device_set_bool_opt(unsigned int *opt, int val,BOOL def,U32 flag, char* name,char* devname) {
+device_set_bool_opt(unsigned int *opt, int val,bool def,u32 flag, char* name,char* devname) {
     (*opt)&=(~flag);
     if (val==-1)
         *opt|=(def ? flag : 0);
@@ -394,7 +396,7 @@ device_set_bool_opt(unsigned int *opt, int val,BOOL def,U32 flag, char* name,cha
         *opt|=(def ? flag : 0);
     } else {
         DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: set parameter %s to %s\n",
-            devname,name , val ? "TRUE" : "FALSE");
+            devname,name , val ? "true" : "false");
         *opt|=(val ? flag : 0);
     }
 }
@@ -429,9 +431,9 @@ pOpts->flags|=DEVICE_FLAGS_DiversityANT;
 static void
 device_set_options(PSDevice pDevice) {
 
-    BYTE    abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-    BYTE    abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
-    BYTE    abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+    unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+    unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
 
 
     memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
@@ -450,7 +452,7 @@ device_set_options(PSDevice pDevice) {
     pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0;
     pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
     pDevice->uConnectionRate = pDevice->sOpts.data_rate;
-    if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = TRUE;
+    if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = true;
     pDevice->byBBType = pDevice->sOpts.bbp_type;
     pDevice->byPacketType = pDevice->byBBType;
 
@@ -458,45 +460,45 @@ device_set_options(PSDevice pDevice) {
        pDevice->byAutoFBCtrl = AUTO_FB_0;
        //pDevice->byAutoFBCtrl = AUTO_FB_1;
 //PLICE_DEBUG<-
-pDevice->bUpdateBBVGA = TRUE;
+pDevice->bUpdateBBVGA = true;
     pDevice->byFOETuning = 0;
     pDevice->wCTSDuration = 0;
     pDevice->byPreambleType = 0;
 
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uChannel= %d\n",(INT)pDevice->uChannel);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byOpMode= %d\n",(INT)pDevice->byOpMode);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ePSMode= %d\n",(INT)pDevice->ePSMode);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" wRTSThreshold= %d\n",(INT)pDevice->wRTSThreshold);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortRetryLimit= %d\n",(INT)pDevice->byShortRetryLimit);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byLongRetryLimit= %d\n",(INT)pDevice->byLongRetryLimit);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byPreambleType= %d\n",(INT)pDevice->byPreambleType);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortPreamble= %d\n",(INT)pDevice->byShortPreamble);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uConnectionRate= %d\n",(INT)pDevice->uConnectionRate);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byBBType= %d\n",(INT)pDevice->byBBType);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->b11hEnable= %d\n",(INT)pDevice->b11hEnable);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(INT)pDevice->bDiversityRegCtlON);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uChannel= %d\n",(int)pDevice->uChannel);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byOpMode= %d\n",(int)pDevice->byOpMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ePSMode= %d\n",(int)pDevice->ePSMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" wRTSThreshold= %d\n",(int)pDevice->wRTSThreshold);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortRetryLimit= %d\n",(int)pDevice->byShortRetryLimit);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byLongRetryLimit= %d\n",(int)pDevice->byLongRetryLimit);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byPreambleType= %d\n",(int)pDevice->byPreambleType);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortPreamble= %d\n",(int)pDevice->byShortPreamble);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uConnectionRate= %d\n",(int)pDevice->uConnectionRate);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byBBType= %d\n",(int)pDevice->byBBType);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->b11hEnable= %d\n",(int)pDevice->b11hEnable);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(int)pDevice->bDiversityRegCtlON);
 }
 
-static void s_vCompleteCurrentMeasure (PSDevice pDevice, BYTE byResult)
+static void s_vCompleteCurrentMeasure (PSDevice pDevice, unsigned char byResult)
 {
-    UINT    ii;
-    DWORD   dwDuration = 0;
-    BYTE    byRPI0 = 0;
+    unsigned int ii;
+    unsigned long dwDuration = 0;
+    unsigned char byRPI0 = 0;
 
     for(ii=1;ii<8;ii++) {
         pDevice->dwRPIs[ii] *= 255;
-        dwDuration |= *((PWORD) (pDevice->pCurrMeasureEID->sReq.abyDuration));
+        dwDuration |= *((unsigned short *) (pDevice->pCurrMeasureEID->sReq.abyDuration));
         dwDuration <<= 10;
         pDevice->dwRPIs[ii] /= dwDuration;
-        pDevice->abyRPIs[ii] = (BYTE) pDevice->dwRPIs[ii];
+        pDevice->abyRPIs[ii] = (unsigned char) pDevice->dwRPIs[ii];
         byRPI0 += pDevice->abyRPIs[ii];
     }
     pDevice->abyRPIs[0] = (0xFF - byRPI0);
 
      if (pDevice->uNumOfMeasureEIDs == 0) {
         VNTWIFIbMeasureReport(  pDevice->pMgmt,
-                                TRUE,
+                                true,
                                 pDevice->pCurrMeasureEID,
                                 byResult,
                                 pDevice->byBasicMap,
@@ -505,7 +507,7 @@ static void s_vCompleteCurrentMeasure (PSDevice pDevice, BYTE byResult)
                                 );
     } else {
         VNTWIFIbMeasureReport(  pDevice->pMgmt,
-                                FALSE,
+                                false,
                                 pDevice->pCurrMeasureEID,
                                 byResult,
                                 pDevice->byBasicMap,
@@ -525,12 +527,12 @@ static void s_vCompleteCurrentMeasure (PSDevice pDevice, BYTE byResult)
 
 static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
 {
-    UINT    ii;
-    BYTE    byValue;
-       BYTE    byValue1;
-    BYTE    byCCKPwrdBm = 0;
-    BYTE    byOFDMPwrdBm = 0;
-    INT zonetype=0;
+    unsigned int ii;
+    unsigned char byValue;
+    unsigned char byValue1;
+    unsigned char byCCKPwrdBm = 0;
+    unsigned char byOFDMPwrdBm = 0;
+    int zonetype=0;
      PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
     MACbShutdown(pDevice->PortOffset);
     BBvSoftwareReset(pDevice->PortOffset);
@@ -540,11 +542,11 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
         // Do MACbSoftwareReset in MACvInitialize
         MACbSoftwareReset(pDevice->PortOffset);
         // force CCK
-        pDevice->bCCK = TRUE;
-        pDevice->bAES = FALSE;
-        pDevice->bProtectMode = FALSE;      //Only used in 11g type, sync with ERP IE
-        pDevice->bNonERPPresent = FALSE;
-        pDevice->bBarkerPreambleMd = FALSE;
+        pDevice->bCCK = true;
+        pDevice->bAES = false;
+        pDevice->bProtectMode = false;      //Only used in 11g type, sync with ERP IE
+        pDevice->bNonERPPresent = false;
+        pDevice->bBarkerPreambleMd = false;
         pDevice->wCurrentRate = RATE_1M;
         pDevice->byTopOFDMBasicRate = RATE_24M;
         pDevice->byTopCCKBasicRate = RATE_1M;
@@ -570,9 +572,9 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
         // Get Antena
         byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
         if (byValue & EEP_ANTINV)
-            pDevice->bTxRxAntInv = TRUE;
+            pDevice->bTxRxAntInv = true;
         else
-            pDevice->bTxRxAntInv = FALSE;
+            pDevice->bTxRxAntInv = false;
 #ifdef PLICE_DEBUG
        //printk("init_register:TxRxAntInv is %d,byValue is %d\n",pDevice->bTxRxAntInv,byValue);
 #endif
@@ -587,7 +589,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
         pDevice->ulDiversityMValue = 100*16;//SROMbyReadEmbedded(pDevice->PortOffset, 0x52);
         pDevice->byTMax = 1;//SROMbyReadEmbedded(pDevice->PortOffset, 0x53);
         pDevice->byTMax2 = 4;//SROMbyReadEmbedded(pDevice->PortOffset, 0x54);
-        pDevice->ulSQ3TH = 0;//(ULONG) SROMbyReadEmbedded(pDevice->PortOffset, 0x55);
+        pDevice->ulSQ3TH = 0;//(unsigned long) SROMbyReadEmbedded(pDevice->PortOffset, 0x55);
         pDevice->byTMax3 = 64;//SROMbyReadEmbedded(pDevice->PortOffset, 0x56);
 
         if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
@@ -595,7 +597,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
             pDevice->byTxAntennaMode = ANT_B;
             pDevice->dwTxAntennaSel = 1;
             pDevice->dwRxAntennaSel = 1;
-            if (pDevice->bTxRxAntInv == TRUE)
+            if (pDevice->bTxRxAntInv == true)
                 pDevice->byRxAntennaMode = ANT_A;
             else
                 pDevice->byRxAntennaMode = ANT_B;
@@ -603,26 +605,26 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
 byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
           //  if (pDevice->bDiversityRegCtlON)
           if((byValue1&0x08)==0)
-                pDevice->bDiversityEnable = FALSE;//SROMbyReadEmbedded(pDevice->PortOffset, 0x50);
+                pDevice->bDiversityEnable = false;//SROMbyReadEmbedded(pDevice->PortOffset, 0x50);
             else
-                pDevice->bDiversityEnable = TRUE;
+                pDevice->bDiversityEnable = true;
 #ifdef PLICE_DEBUG
                //printk("aux |main antenna: RxAntennaMode is %d\n",pDevice->byRxAntennaMode);
 #endif
        } else  {
-            pDevice->bDiversityEnable = FALSE;
+            pDevice->bDiversityEnable = false;
             pDevice->byAntennaCount = 1;
             pDevice->dwTxAntennaSel = 0;
             pDevice->dwRxAntennaSel = 0;
             if (byValue & EEP_ANTENNA_AUX) {
                 pDevice->byTxAntennaMode = ANT_A;
-                if (pDevice->bTxRxAntInv == TRUE)
+                if (pDevice->bTxRxAntInv == true)
                     pDevice->byRxAntennaMode = ANT_B;
                 else
                     pDevice->byRxAntennaMode = ANT_A;
             } else {
                 pDevice->byTxAntennaMode = ANT_B;
-                if (pDevice->bTxRxAntInv == TRUE)
+                if (pDevice->bTxRxAntInv == true)
                     pDevice->byRxAntennaMode = ANT_A;
                 else
                     pDevice->byRxAntennaMode = ANT_B;
@@ -638,7 +640,7 @@ byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
 //2008-8-4 <add> by chester
 //zonetype initial
  pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
- zonetype = Config_FileOperation(pDevice,FALSE,NULL);
+ zonetype = Config_FileOperation(pDevice,false,NULL);
  if (zonetype >= 0) {         //read zonetype file ok!
   if ((zonetype == 0)&&
         (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){          //for USA
@@ -680,7 +682,7 @@ else
         pDevice->byRFType &= RF_MASK;
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
 
-        if (pDevice->bZoneRegExist == FALSE) {
+        if (pDevice->bZoneRegExist == false) {
             pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
         }
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
@@ -700,11 +702,11 @@ else
 
 
         for (ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
-            pDevice->abyCCKPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_CCK_PWR_TBL));
+            pDevice->abyCCKPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
             if (pDevice->abyCCKPwrTbl[ii+1] == 0) {
                 pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
             }
-            pDevice->abyOFDMPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDM_PWR_TBL));
+            pDevice->abyOFDMPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
             if (pDevice->abyOFDMPwrTbl[ii+1] == 0) {
                 pDevice->abyOFDMPwrTbl[ii+1] = pDevice->byOFDMPwrG;
             }
@@ -726,10 +728,10 @@ else
 
         // Load OFDM A Power Table
         for (ii=0;ii<CB_MAX_CHANNEL_5G;ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
-            pDevice->abyOFDMPwrTbl[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDMA_PWR_TBL));
-            pDevice->abyOFDMDefaultPwr[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDMA_PWR_dBm));
+            pDevice->abyOFDMPwrTbl[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
+            pDevice->abyOFDMDefaultPwr[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
         }
-        CARDvInitChannelTable((void *)pDevice);
+        init_channel_table((void *)pDevice);
 
 
         if (pDevice->byLocalID > REV_ID_VT3253_B1) {
@@ -773,38 +775,38 @@ else
         if (pDevice->uConnectionRate == RATE_AUTO) {
             pDevice->wCurrentRate = RATE_54M;
         } else {
-            pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
         }
 
         // default G Mode
         VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
         VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
 
-        pDevice->bRadioOff = FALSE;
+        pDevice->bRadioOff = false;
 
         pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL);
-        pDevice->bHWRadioOff = FALSE;
+        pDevice->bHWRadioOff = false;
 
         if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
             // Get GPIO
             MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
 //2008-4-14 <add> by chester for led issue
  #ifdef FOR_LED_ON_NOTEBOOK
-if (pDevice->byGPIO & GPIO0_DATA){pDevice->bHWRadioOff = TRUE;}
-if ( !(pDevice->byGPIO & GPIO0_DATA)){pDevice->bHWRadioOff = FALSE;}
+if (pDevice->byGPIO & GPIO0_DATA){pDevice->bHWRadioOff = true;}
+if ( !(pDevice->byGPIO & GPIO0_DATA)){pDevice->bHWRadioOff = false;}
 
             }
-        if ( (pDevice->bRadioControlOff == TRUE)) {
+        if ( (pDevice->bRadioControlOff == true)) {
             CARDbRadioPowerOff(pDevice);
         }
 else  CARDbRadioPowerOn(pDevice);
 #else
             if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
                 ( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) {
-                pDevice->bHWRadioOff = TRUE;
+                pDevice->bHWRadioOff = true;
             }
         }
-        if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
+        if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
             CARDbRadioPowerOff(pDevice);
         }
 
@@ -850,17 +852,17 @@ else  CARDbRadioPowerOn(pDevice);
 static void device_init_diversity_timer(PSDevice pDevice) {
 
     init_timer(&pDevice->TimerSQ3Tmax1);
-    pDevice->TimerSQ3Tmax1.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
     pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
     pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
 
     init_timer(&pDevice->TimerSQ3Tmax2);
-    pDevice->TimerSQ3Tmax2.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice;
     pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
     pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
 
     init_timer(&pDevice->TimerSQ3Tmax3);
-    pDevice->TimerSQ3Tmax3.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
     pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack;
     pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
 
@@ -868,13 +870,13 @@ static void device_init_diversity_timer(PSDevice pDevice) {
 }
 
 
-static BOOL device_release_WPADEV(PSDevice pDevice)
+static bool device_release_WPADEV(PSDevice pDevice)
 {
   viawget_wpa_header *wpahdr;
   int ii=0;
  // wait_queue_head_t  Set_wait;
   //send device close to wpa_supplicnat layer
-    if (pDevice->bWPADEVUp==TRUE) {
+    if (pDevice->bWPADEVUp==true) {
                  wpahdr = (viawget_wpa_header *)pDevice->skb->data;
                  wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
                  wpahdr->resp_ie_len = 0;
@@ -891,7 +893,7 @@ static BOOL device_release_WPADEV(PSDevice pDevice)
  //wait release WPADEV
               //    init_waitqueue_head(&Set_wait);
               //    wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ);    //1s wait
-              while((pDevice->bWPADEVUp==TRUE)) {
+              while((pDevice->bWPADEVUp==true)) {
                set_current_state(TASK_UNINTERRUPTIBLE);
                  schedule_timeout (HZ/20);          //wait 50ms
                  ii++;
@@ -899,7 +901,7 @@ static BOOL device_release_WPADEV(PSDevice pDevice)
                  break;
               }
            };
-    return TRUE;
+    return true;
 }
 
 
@@ -914,10 +916,10 @@ static const struct net_device_ops device_netdev_ops = {
 
 
 
-static int
-device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
+static int __devinit
+vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
 {
-    static BOOL bFirst = TRUE;
+    static bool bFirst = true;
     struct net_device*  dev = NULL;
     PCHIP_INFO  pChip_info = (PCHIP_INFO)ent->driver_data;
     PSDevice    pDevice;
@@ -944,10 +946,10 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
     if (bFirst) {
         printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
         printk(KERN_NOTICE "Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
-        bFirst=FALSE;
+        bFirst=false;
     }
 
-    if (!device_init_info(pcid, &pDevice, pChip_info)) {
+    if (!vt6655_init_info(pcid, &pDevice, pChip_info)) {
         return -ENOMEM;
     }
     pDevice->dev = dev;
@@ -962,7 +964,7 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
 #ifdef DEBUG
        printk("Before get pci_info memaddr is %x\n",pDevice->memaddr);
 #endif
-    if (device_get_pci_info(pDevice,pcid) == FALSE) {
+    if (device_get_pci_info(pDevice,pcid) == false) {
         printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n");
         device_free_info(pDevice);
         return -ENODEV;
@@ -976,7 +978,7 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
        printk("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n",pDevice->memaddr,pDevice->ioaddr,pDevice->io_size);
        {
                int i;
-               U32                     bar,len;
+               u32                     bar,len;
                u32 address[] = {
                PCI_BASE_ADDRESS_0,
                PCI_BASE_ADDRESS_1,
@@ -1020,8 +1022,8 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
 #ifdef DEBUG
        //return  0  ;
 #endif
-    pDevice->PortOffset = (DWORD)ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
-       //pDevice->PortOffset = (DWORD)ioremap(pDevice->ioaddr & PCI_BASE_ADDRESS_IO_MASK, pDevice->io_size);
+    pDevice->PortOffset = (unsigned long)ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
+       //pDevice->PortOffset = (unsigned long)ioremap(pDevice->ioaddr & PCI_BASE_ADDRESS_IO_MASK, pDevice->io_size);
 
        if(pDevice->PortOffset == 0) {
        printk(KERN_ERR DEVICE_NAME ": Failed to IO remapping ..\n");
@@ -1041,7 +1043,7 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
 
     dev->base_addr = pDevice->ioaddr;
 #ifdef PLICE_DEBUG
-       BYTE    value;
+       unsigned char   value;
 
        VNSvInPortB(pDevice->PortOffset+0x4F, &value);
        printk("Before write: value is %x\n",value);
@@ -1111,16 +1113,17 @@ static void device_print_info(PSDevice pDevice)
     DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id));
     DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
 #ifdef IO_MAP
-    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx  ",(ULONG) pDevice->ioaddr);
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx  ",(unsigned long) pDevice->ioaddr);
     DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
 #else
-    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx Mem=0x%lx ",(ULONG) pDevice->ioaddr,(ULONG) pDevice->PortOffset);
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx Mem=0x%lx ",
+                   (unsigned long) pDevice->ioaddr,(unsigned long) pDevice->PortOffset);
     DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
 #endif
 
 }
 
-static BOOL device_init_info(struct pci_dev* pcid, PSDevice* ppDevice,
+static bool __devinit vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice,
     PCHIP_INFO pChip_info) {
 
     PSDevice p;
@@ -1145,19 +1148,19 @@ static BOOL device_init_info(struct pci_dev* pcid, PSDevice* ppDevice,
 
     spin_lock_init(&((*ppDevice)->lock));
 
-    return TRUE;
+    return true;
 }
 
-static BOOL device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) {
+static bool device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) {
 
-    U16 pci_cmd;
-    U8  b;
-    UINT cis_addr;
+    u16 pci_cmd;
+    u8  b;
+    unsigned int cis_addr;
 #ifdef PLICE_DEBUG
-       BYTE       pci_config[256];
-       BYTE    value =0x00;
+       unsigned char pci_config[256];
+       unsigned char   value =0x00;
        int             ii,j;
-       U16     max_lat=0x0000;
+       u16     max_lat=0x0000;
        memset(pci_config,0x00,256);
 #endif
 
@@ -1211,7 +1214,7 @@ static BOOL device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) {
                }
        }
 #endif
-    return TRUE;
+    return true;
 }
 
 static void device_free_info(PSDevice pDevice) {
@@ -1263,7 +1266,7 @@ device_release_WPADEV(pDevice);
     }
 }
 
-static BOOL device_init_rings(PSDevice pDevice) {
+static bool device_init_rings(PSDevice pDevice) {
     void*   vir_pool;
 
 
@@ -1277,7 +1280,7 @@ static BOOL device_init_rings(PSDevice pDevice) {
 
     if (vir_pool == NULL) {
         DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name);
-        return FALSE;
+        return false;
     }
 
     memset(vir_pool, 0,
@@ -1312,7 +1315,7 @@ static BOOL device_init_rings(PSDevice pDevice) {
             pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
             vir_pool, pDevice->pool_dma
             );
-        return FALSE;
+        return false;
     }
 
     memset(pDevice->tx0_bufs, 0,
@@ -1358,7 +1361,7 @@ static BOOL device_init_rings(PSDevice pDevice) {
             pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
 
 
-    return TRUE;
+    return true;
 }
 
 static void device_free_rings(PSDevice pDevice) {
@@ -1593,7 +1596,7 @@ static void device_free_td1_ring(PSDevice pDevice) {
 
 /*-----------------------------------------------------------------*/
 
-static int device_rx_srv(PSDevice pDevice, UINT uIdx) {
+static int device_rx_srv(PSDevice pDevice, unsigned int uIdx) {
     PSRxDesc    pRD;
     int works = 0;
 
@@ -1621,7 +1624,7 @@ static int device_rx_srv(PSDevice pDevice, UINT uIdx) {
 }
 
 
-static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
+static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
 
     PDEVICE_RD_INFO pRDInfo=pRD->pRDInfo;
 
@@ -1631,7 +1634,7 @@ static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
        //printk("device_alloc_rx_buf:skb is %x\n",pRDInfo->skb);
 #endif
     if (pRDInfo->skb==NULL)
-        return FALSE;
+        return false;
     ASSERT(pRDInfo->skb);
     pRDInfo->skb->dev = pDevice->dev;
     pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb),
@@ -1643,35 +1646,35 @@ static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
     pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
     pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma);
 
-    return TRUE;
+    return true;
 }
 
 
 
-BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
+bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
 
     pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
     if (pDeF->skb == NULL)
-        return FALSE;
+        return false;
     ASSERT(pDeF->skb);
     pDeF->skb->dev = pDevice->dev;
 
-    return TRUE;
+    return true;
 }
 
 
 
-static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
+static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) {
     PSTxDesc                 pTD;
-    BOOL                     bFull=FALSE;
+    bool bFull=false;
     int                      works = 0;
-    BYTE                     byTsr0;
-    BYTE                     byTsr1;
-    UINT                     uFrameSize, uFIFOHeaderSize;
+    unsigned char byTsr0;
+    unsigned char byTsr1;
+    unsigned int       uFrameSize, uFIFOHeaderSize;
     PSTxBufHead              pTxBufHead;
     struct net_device_stats* pStats = &pDevice->stats;
     struct sk_buff*          skb;
-    UINT                     uNodeIndex;
+    unsigned int       uNodeIndex;
     PSMgmtObject             pMgmt = pDevice->pMgmt;
 
 
@@ -1697,20 +1700,20 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
 
                 STAvUpdateTDStatCounter(&pDevice->scStatistic,
                         byTsr0, byTsr1,
-                        (PBYTE)(pTD->pTDInfo->buf + uFIFOHeaderSize),
+                        (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize),
                         uFrameSize, uIdx);
 
 
                 BSSvUpdateNodeTxCounter(pDevice,
                          byTsr0, byTsr1,
-                         (PBYTE)(pTD->pTDInfo->buf),
+                         (unsigned char *)(pTD->pTDInfo->buf),
                          uFIFOHeaderSize
                          );
 
                 if ( !(byTsr1 & TSR1_TERR)) {
                     if (byTsr0 != 0) {
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n",
-                           (INT)uIdx, byTsr1, byTsr0);
+                           (int)uIdx, byTsr1, byTsr0);
                     }
                     if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) {
                         pDevice->s802_11Counter.TransmittedFragmentCount ++;
@@ -1720,7 +1723,7 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
                 }
                 else {
                      DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n",
-                           (INT)uIdx, byTsr1, byTsr0);
+                           (int)uIdx, byTsr1, byTsr0);
                     pStats->tx_errors++;
                     pStats->tx_dropped++;
                 }
@@ -1742,19 +1745,19 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
             if (byTsr1 & TSR1_TERR) {
             if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
-                          (INT)uIdx, byTsr1, byTsr0);
+                          (int)uIdx, byTsr1, byTsr0);
             }
 
 //                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
-//                          (INT)uIdx, byTsr1, byTsr0);
+//                          (int)uIdx, byTsr1, byTsr0);
 
                 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
                     (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) {
-                    WORD    wAID;
-                    BYTE    byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+                    unsigned short wAID;
+                    unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
 
                     skb = pTD->pTDInfo->skb;
-                    if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(skb->data), &uNodeIndex)) {
+                    if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
                         if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
                             skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
                             pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
@@ -1763,7 +1766,7 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
                             pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
                             pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB);
                             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n"
-                                    ,(INT)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
+                                    ,(int)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
                             pStats->tx_errors--;
                             pStats->tx_dropped--;
                         }
@@ -1780,10 +1783,10 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
         // RESERV_AC0DMA reserved for relay
 
         if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) {
-            bFull = TRUE;
+            bFull = true;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
         }
-        if (netif_queue_stopped(pDevice->dev) && (bFull==FALSE)){
+        if (netif_queue_stopped(pDevice->dev) && (bFull==false)){
             netif_wake_queue(pDevice->dev);
         }
     }
@@ -1795,7 +1798,7 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
 }
 
 
-static void device_error(PSDevice pDevice, WORD status) {
+static void device_error(PSDevice pDevice, unsigned short status) {
 
     if (status & ISR_FETALERR) {
         DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
@@ -1804,7 +1807,7 @@ static void device_error(PSDevice pDevice, WORD status) {
         netif_stop_queue(pDevice->dev);
         del_timer(&pDevice->sTimerCommand);
         del_timer(&(pDevice->pMgmt->sTimerSecondCallback));
-        pDevice->bCmdRunning = FALSE;
+        pDevice->bCmdRunning = false;
         MACbShutdown(pDevice->PortOffset);
         return;
     }
@@ -1844,7 +1847,7 @@ void      InitRxManagementQueue(PSDevice  pDevice)
 
 
 //PLICE_DEBUG ->
-INT MlmeThread(
+int MlmeThread(
      void * Context)
 {
        PSDevice        pDevice =  (PSDevice) Context;
@@ -1914,8 +1917,8 @@ static int  device_open(struct net_device *dev) {
      wpa_Result.proto = 0;
      wpa_Result.key_mgmt = 0;
      wpa_Result.eap_type = 0;
-     wpa_Result.authenticated = FALSE;
-     pDevice->fWPA_Authened = FALSE;
+     wpa_Result.authenticated = false;
+     pDevice->fWPA_Authened = false;
 #endif
 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n");
 device_init_rd0_ring(pDevice);
@@ -1980,20 +1983,20 @@ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
 
        #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
        /*
-     pDevice->bwextstep0 = FALSE;
-     pDevice->bwextstep1 = FALSE;
-     pDevice->bwextstep2 = FALSE;
-     pDevice->bwextstep3 = FALSE;
+     pDevice->bwextstep0 = false;
+     pDevice->bwextstep1 = false;
+     pDevice->bwextstep2 = false;
+     pDevice->bwextstep3 = false;
      */
        pDevice->bwextcount=0;
-     pDevice->bWPASuppWextEnabled = FALSE;
+     pDevice->bWPASuppWextEnabled = false;
 #endif
     pDevice->byReAssocCount = 0;
-   pDevice->bWPADEVUp = FALSE;
+   pDevice->bWPADEVUp = false;
     // Patch: if WEP key already set by iwconfig but device not yet open
-    if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
+    if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) {
         KeybSetDefaultKey(&(pDevice->sKey),
-                            (DWORD)(pDevice->byKeyIndex | (1 << 31)),
+                            (unsigned long)(pDevice->byKeyIndex | (1 << 31)),
                             pDevice->uKeyLength,
                             NULL,
                             pDevice->abyKey,
@@ -2052,12 +2055,12 @@ static int  device_close(struct net_device *dev) {
        tasklet_kill(&pDevice->RxMngWorkItem);
 #endif
      netif_stop_queue(dev);
-    pDevice->bCmdRunning = FALSE;
+    pDevice->bCmdRunning = false;
     MACbShutdown(pDevice->PortOffset);
     MACbSoftwareReset(pDevice->PortOffset);
     CARDbRadioPowerOff(pDevice);
 
-    pDevice->bLinkPass = FALSE;
+    pDevice->bLinkPass = false;
     memset(pMgmt->abyCurrBSSID, 0, 6);
     pMgmt->eCurrState = WMAC_STATE_IDLE;
     device_free_td0_ring(pDevice);
@@ -2082,8 +2085,8 @@ device_release_WPADEV(pDevice);
 
 static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
     PSDevice        pDevice=netdev_priv(dev);
-    PBYTE           pbMPDU;
-    UINT            cbMPDULen = 0;
+    unsigned char *pbMPDU;
+    unsigned int cbMPDULen = 0;
 
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
@@ -2096,7 +2099,7 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
         return 0;
     }
 
-    if (pDevice->bStopTx0Pkt == TRUE) {
+    if (pDevice->bStopTx0Pkt == true) {
         dev_kfree_skb_irq(skb);
         spin_unlock_irq(&pDevice->lock);
         return 0;
@@ -2115,36 +2118,36 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
 
 
 
-BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
+bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex) {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSTxDesc        pHeadTD, pLastTD;
-    UINT            cbFrameBodySize;
-    UINT            uMACfragNum;
-    BYTE            byPktType;
-    BOOL            bNeedEncryption = FALSE;
+    unsigned int cbFrameBodySize;
+    unsigned int uMACfragNum;
+    unsigned char byPktType;
+    bool bNeedEncryption = false;
     PSKeyItem       pTransmitKey = NULL;
-    UINT            cbHeaderSize;
-    UINT            ii;
+    unsigned int cbHeaderSize;
+    unsigned int ii;
     SKeyItem        STempKey;
-//    BYTE            byKeyIndex = 0;
+//    unsigned char byKeyIndex = 0;
 
 
-    if (pDevice->bStopTx0Pkt == TRUE) {
+    if (pDevice->bStopTx0Pkt == true) {
         dev_kfree_skb_irq(skb);
-        return FALSE;
+        return false;
     };
 
     if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
         dev_kfree_skb_irq(skb);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n");
-        return FALSE;
+        return false;
     }
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
         if (pDevice->uAssocCount == 0) {
             dev_kfree_skb_irq(skb);
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n");
-            return FALSE;
+            return false;
         }
     }
 
@@ -2152,7 +2155,7 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
 
     pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
 
-    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN);
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
     cbFrameBodySize = skb->len - ETH_HLEN;
 
     // 802.1H
@@ -2163,9 +2166,9 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
 
     if ( uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) {
         dev_kfree_skb_irq(skb);
-        return FALSE;
+        return false;
     }
-    byPktType = (BYTE)pDevice->byPacketType;
+    byPktType = (unsigned char)pDevice->byPacketType;
 
 
     if (pDevice->bFixRate) {
@@ -2173,13 +2176,13 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
             if (pDevice->uConnectionRate >= RATE_11M) {
                 pDevice->wCurrentRate = RATE_11M;
             } else {
-                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+                pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
             }
         } else {
             if (pDevice->uConnectionRate >= RATE_54M)
                 pDevice->wCurrentRate = RATE_54M;
             else
-                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+                pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
         }
     }
     else {
@@ -2202,15 +2205,15 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
     } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
         byPktType = PK_TYPE_11A;
     } else {
-        if (pDevice->bProtectMode == TRUE) {
+        if (pDevice->bProtectMode == true) {
             byPktType = PK_TYPE_11GB;
         } else {
             byPktType = PK_TYPE_11GA;
         }
     }
 
-    if (pDevice->bEncryptionEnable == TRUE)
-        bNeedEncryption = TRUE;
+    if (pDevice->bEncryptionEnable == true)
+        bNeedEncryption = true;
 
     if (pDevice->bEnableHostWEP) {
         pTransmitKey = &STempKey;
@@ -2226,7 +2229,7 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
     }
     vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
                         cbFrameBodySize, TYPE_TXDMA0, pHeadTD,
-                        &pDevice->sTxEthHeader, (PBYTE)skb->data, pTransmitKey, uNodeIndex,
+                        &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
                         &uMACfragNum,
                         &cbHeaderSize
                         );
@@ -2236,7 +2239,7 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
         MACbPSWakeup(pDevice->PortOffset);
     }
 
-    pDevice->bPWBitOn = FALSE;
+    pDevice->bPWBitOn = false;
 
     pLastTD = pHeadTD;
     for (ii = 0; ii < uMACfragNum; ii++) {
@@ -2260,7 +2263,7 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
     MACvTransmit0(pDevice->PortOffset);
 
 
-    return TRUE;
+    return true;
 }
 
 //TYPE_AC0DMA data tx
@@ -2269,26 +2272,26 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
 
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSTxDesc        pHeadTD, pLastTD;
-    UINT            uNodeIndex = 0;
-    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
-    WORD            wAID;
-    UINT            uMACfragNum = 1;
-    UINT            cbFrameBodySize;
-    BYTE            byPktType;
-    UINT            cbHeaderSize;
-    BOOL            bNeedEncryption = FALSE;
+    unsigned int uNodeIndex = 0;
+    unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    unsigned short wAID;
+    unsigned int uMACfragNum = 1;
+    unsigned int cbFrameBodySize;
+    unsigned char byPktType;
+    unsigned int cbHeaderSize;
+    bool bNeedEncryption = false;
     PSKeyItem       pTransmitKey = NULL;
     SKeyItem        STempKey;
-    UINT            ii;
-    BOOL            bTKIP_UseGTK = FALSE;
-    BOOL            bNeedDeAuth = FALSE;
-    PBYTE           pbyBSSID;
-    BOOL            bNodeExist = FALSE;
+    unsigned int ii;
+    bool bTKIP_UseGTK = false;
+    bool bNeedDeAuth = false;
+    unsigned char *pbyBSSID;
+    bool bNodeExist = false;
 
 
 
     spin_lock_irq(&pDevice->lock);
-    if (pDevice->bLinkPass == FALSE) {
+    if (pDevice->bLinkPass == false) {
         dev_kfree_skb_irq(skb);
         spin_unlock_irq(&pDevice->lock);
         return 0;
@@ -2307,9 +2310,9 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
             spin_unlock_irq(&pDevice->lock);
             return 0;
         }
-        if (IS_MULTICAST_ADDRESS((PBYTE)(skb->data))) {
+        if (is_multicast_ether_addr((unsigned char *)(skb->data))) {
             uNodeIndex = 0;
-            bNodeExist = TRUE;
+            bNodeExist = true;
             if (pMgmt->sNodeDBTable[0].bPSEnable) {
                 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
                 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
@@ -2319,7 +2322,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                 return 0;
             }
 }else {
-            if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(skb->data), &uNodeIndex)) {
+            if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
                 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
                     skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
                     pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
@@ -2338,12 +2341,12 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                 }else {
                     pDevice->byPreambleType = PREAMBLE_LONG;
                 }
-                bNodeExist = TRUE;
+                bNodeExist = true;
 
             }
         }
 
-        if (bNodeExist == FALSE) {
+        if (bNodeExist == false) {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
             dev_kfree_skb_irq(skb);
             spin_unlock_irq(&pDevice->lock);
@@ -2356,7 +2359,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
     pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
 
 
-    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN);
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
     cbFrameBodySize = skb->len - ETH_HLEN;
     // 802.1H
     if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) {
@@ -2364,18 +2367,18 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
     }
 
 
-    if (pDevice->bEncryptionEnable == TRUE) {
-        bNeedEncryption = TRUE;
+    if (pDevice->bEncryptionEnable == true) {
+        bNeedEncryption = true;
         // get Transmit key
         do {
             if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
                 (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
                 pbyBSSID = pDevice->abyBSSID;
                 // get pairwise key
-                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
+                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
                     // get group key
-                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
-                        bTKIP_UseGTK = TRUE;
+                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
+                        bTKIP_UseGTK = true;
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
                         break;
                     }
@@ -2392,12 +2395,12 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
 
                 // get pairwise key
-                if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE)
+                if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
                     break;
             }
             // get group key
             pbyBSSID = pDevice->abyBroadcastAddr;
-            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
                 pTransmitKey = NULL;
                 if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
@@ -2405,15 +2408,15 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                 else
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
             } else {
-                bTKIP_UseGTK = TRUE;
+                bTKIP_UseGTK = true;
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
             }
-        } while(FALSE);
+        } while(false);
     }
 
     if (pDevice->bEnableHostWEP) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
-        if (pDevice->bEncryptionEnable == TRUE) {
+        if (pDevice->bEncryptionEnable == true) {
             pTransmitKey = &STempKey;
             pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
             pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
@@ -2443,7 +2446,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
         }
     }
 
-    byPktType = (BYTE)pDevice->byPacketType;
+    byPktType = (unsigned char)pDevice->byPacketType;
 
     if (pDevice->bFixRate) {
 #ifdef PLICE_DEBUG
@@ -2454,7 +2457,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
             if (pDevice->uConnectionRate >= RATE_11M) {
                 pDevice->wCurrentRate = RATE_11M;
             } else {
-                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+                pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
             }
         } else {
             if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
@@ -2464,11 +2467,11 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                 if (pDevice->uConnectionRate >= RATE_54M)
                     pDevice->wCurrentRate = RATE_54M;
                 else
-                    pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+                    pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
 
             }
         }
-        pDevice->byACKRate = (BYTE) pDevice->wCurrentRate;
+        pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate;
         pDevice->byTopCCKBasicRate = RATE_1M;
         pDevice->byTopOFDMBasicRate = RATE_6M;
     }
@@ -2521,7 +2524,7 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
     } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
         byPktType = PK_TYPE_11A;
     } else {
-        if (pDevice->bProtectMode == TRUE) {
+        if (pDevice->bProtectMode == true) {
             byPktType = PK_TYPE_11GB;
         } else {
             byPktType = PK_TYPE_11GA;
@@ -2532,28 +2535,28 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
 //     printk("FIX RATE:CurrentRate is %d");
 //#endif
 
-    if (bNeedEncryption == TRUE) {
+    if (bNeedEncryption == true) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
         if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
-            bNeedEncryption = FALSE;
+            bNeedEncryption = false;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
             if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
                 if (pTransmitKey == NULL) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
                 }
                 else {
-                    if (bTKIP_UseGTK == TRUE) {
+                    if (bTKIP_UseGTK == true) {
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
                     }
                     else {
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
-                        bNeedEncryption = TRUE;
+                        bNeedEncryption = true;
                     }
                 }
             }
 
             if (pDevice->byCntMeasure == 2) {
-                bNeedDeAuth = TRUE;
+                bNeedDeAuth = true;
                 pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
             }
 
@@ -2561,7 +2564,7 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
                 if ((uNodeIndex != 0) &&
                     (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
-                    bNeedEncryption = TRUE;
+                    bNeedEncryption = true;
                  }
              }
         }
@@ -2584,7 +2587,7 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
 #endif
     vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
                         cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
-                        &pDevice->sTxEthHeader, (PBYTE)skb->data, pTransmitKey, uNodeIndex,
+                        &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
                         &uMACfragNum,
                         &cbHeaderSize
                         );
@@ -2593,7 +2596,7 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
         // Disable PS
         MACbPSWakeup(pDevice->PortOffset);
     }
-    pDevice->bPWBitOn = FALSE;
+    pDevice->bPWBitOn = false;
 
     pLastTD = pHeadTD;
     for (ii = 0; ii < uMACfragNum; ii++) {
@@ -2631,11 +2634,11 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
 //#endif
 
 {
-    BYTE  Protocol_Version;    //802.1x Authentication
-    BYTE  Packet_Type;           //802.1x Authentication
-    BYTE  Descriptor_type;
-    WORD Key_info;
-BOOL            bTxeapol_key = FALSE;
+    unsigned char Protocol_Version;    //802.1x Authentication
+    unsigned char Packet_Type;           //802.1x Authentication
+    unsigned char Descriptor_type;
+    unsigned short Key_info;
+bool bTxeapol_key = false;
     Protocol_Version = skb->data[ETH_HLEN];
     Packet_Type = skb->data[ETH_HLEN+1];
     Descriptor_type = skb->data[ETH_HLEN+1+1+2];
@@ -2643,11 +2646,11 @@ BOOL            bTxeapol_key = FALSE;
    if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
            if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
                (Packet_Type==3)) {  //802.1x OR eapol-key challenge frame transfer
-                        bTxeapol_key = TRUE;
+                        bTxeapol_key = true;
                if((Descriptor_type==254)||(Descriptor_type==2)) {       //WPA or RSN
                        if(!(Key_info & BIT3) &&   //group-key challenge
                           (Key_info & BIT8) && (Key_info & BIT9)) {    //send 2/2 key
-                         pDevice->fWPA_Authened = TRUE;
+                         pDevice->fWPA_Authened = true;
                          if(Descriptor_type==254)
                              printk("WPA ");
                          else
@@ -2674,13 +2677,13 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
     PSDevice     pDevice=(PSDevice) netdev_priv(dev);
 
     int             max_count=0;
-    DWORD           dwMIBCounter=0;
+    unsigned long dwMIBCounter=0;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    BYTE            byOrgPageSel=0;
+    unsigned char byOrgPageSel=0;
     int             handled = 0;
-    BYTE            byData = 0;
+    unsigned char byData = 0;
     int             ii= 0;
-//    BYTE            byRSSI;
+//    unsigned char byRSSI;
 
 
     MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
@@ -2697,7 +2700,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
 
        if ((pDevice->dwIsr & ISR_RXDMA0) &&
         (pDevice->byLocalID != REV_ID_VT3253_B0) &&
-        (pDevice->bBSSIDFilter == TRUE)) {
+        (pDevice->bBSSIDFilter == true)) {
         // update RSSI
         //BBbReadEmbeded(pDevice->PortOffset, 0x3E, &byRSSI);
         //pDevice->uCurrRSSI = byRSSI;
@@ -2746,9 +2749,9 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                 VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4));
                 MACvSelectPage0(pDevice->PortOffset);
                //xxxx
-               // WCMDbFlushCommandQueue(pDevice->pMgmt, TRUE);
-                if (CARDbSetChannel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == TRUE) {
-                    pDevice->bMeasureInProgress = TRUE;
+               // WCMDbFlushCommandQueue(pDevice->pMgmt, true);
+                if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == true) {
+                    pDevice->bMeasureInProgress = true;
                     MACvSelectPage1(pDevice->PortOffset);
                     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY);
                     MACvSelectPage0(pDevice->PortOffset);
@@ -2770,7 +2773,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
             }
             if (pDevice->dwIsr & ISR_MEASUREEND) {
                 // 802.11h measure end
-                pDevice->bMeasureInProgress = FALSE;
+                pDevice->bMeasureInProgress = false;
                 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
                 MACvSelectPage1(pDevice->PortOffset);
                 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
@@ -2782,7 +2785,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                 // clear measure control
                 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
                 MACvSelectPage0(pDevice->PortOffset);
-                CARDbSetChannel(pDevice, pDevice->byOrgChannel);
+                set_channel(pDevice, pDevice->byOrgChannel);
                 // WCMDbResetCommandQueue(pDevice->pMgmt);
                 MACvSelectPage1(pDevice->PortOffset);
                 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
@@ -2798,26 +2801,26 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
             if (pDevice->dwIsr & ISR_QUIETSTART) {
                 do {
                     ;
-                } while (CARDbStartQuiet(pDevice) == FALSE);
+                } while (CARDbStartQuiet(pDevice) == false);
             }
         }
 
         if (pDevice->dwIsr & ISR_TBTT) {
-            if (pDevice->bEnableFirstQuiet == TRUE) {
+            if (pDevice->bEnableFirstQuiet == true) {
                 pDevice->byQuietStartCount--;
                 if (pDevice->byQuietStartCount == 0) {
-                    pDevice->bEnableFirstQuiet = FALSE;
+                    pDevice->bEnableFirstQuiet = false;
                     MACvSelectPage1(pDevice->PortOffset);
                     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
                     MACvSelectPage0(pDevice->PortOffset);
                 }
             }
-            if ((pDevice->bChannelSwitch == TRUE) &&
+            if ((pDevice->bChannelSwitch == true) &&
                 (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) {
                 pDevice->byChannelSwitchCount--;
                 if (pDevice->byChannelSwitchCount == 0) {
-                    pDevice->bChannelSwitch = FALSE;
-                    CARDbSetChannel(pDevice, pDevice->byNewChannel);
+                    pDevice->bChannelSwitch = false;
+                    set_channel(pDevice, pDevice->byNewChannel);
                     VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
                     MACvSelectPage1(pDevice->PortOffset);
                     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
@@ -2827,12 +2830,12 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                 }
             }
             if (pDevice->eOPMode == OP_MODE_ADHOC) {
-                //pDevice->bBeaconSent = FALSE;
+                //pDevice->bBeaconSent = false;
             } else {
-                if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == TRUE) && (pDevice->uCurrRSSI != 0)) {
-                    LONG            ldBm;
+                if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == true) && (pDevice->uCurrRSSI != 0)) {
+                    long            ldBm;
 
-                    RFvRSSITodBm(pDevice, (BYTE) pDevice->uCurrRSSI, &ldBm);
+                    RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
                     for (ii=0;ii<BB_VGA_LEVEL;ii++) {
                         if (ldBm < pDevice->ldBmThreshold[ii]) {
                             pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
@@ -2858,7 +2861,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                 }
             }
 
-            pDevice->bBeaconSent = FALSE;
+            pDevice->bBeaconSent = false;
             if (pDevice->bEnablePSMode) {
                 PSbIsNextTBTTWakeUp((void *)pDevice);
             };
@@ -2879,31 +2882,31 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
         if (pDevice->dwIsr & ISR_BNTX) {
 
             if (pDevice->eOPMode == OP_MODE_ADHOC) {
-                pDevice->bIsBeaconBufReadySet = FALSE;
+                pDevice->bIsBeaconBufReadySet = false;
                 pDevice->cbBeaconBufReadySetCnt = 0;
             };
 
             if (pDevice->eOPMode == OP_MODE_AP) {
                 if(pMgmt->byDTIMCount > 0) {
                    pMgmt->byDTIMCount --;
-                   pMgmt->sNodeDBTable[0].bRxPSPoll = FALSE;
+                   pMgmt->sNodeDBTable[0].bRxPSPoll = false;
                 }
                 else {
                     if(pMgmt->byDTIMCount == 0) {
                         // check if mutltcast tx bufferring
                         pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
-                        pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
+                        pMgmt->sNodeDBTable[0].bRxPSPoll = true;
                         bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
                     }
                 }
             }
-            pDevice->bBeaconSent = TRUE;
+            pDevice->bBeaconSent = true;
 
-            if (pDevice->bChannelSwitch == TRUE) {
+            if (pDevice->bChannelSwitch == true) {
                 pDevice->byChannelSwitchCount--;
                 if (pDevice->byChannelSwitchCount == 0) {
-                    pDevice->bChannelSwitch = FALSE;
-                    CARDbSetChannel(pDevice, pDevice->byNewChannel);
+                    pDevice->bChannelSwitch = false;
+                    set_channel(pDevice, pDevice->byNewChannel);
                     VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
                     MACvSelectPage1(pDevice->PortOffset);
                     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
@@ -2978,9 +2981,10 @@ static inline u32 ether_crc(int length, unsigned char *data)
 }
 
 //2008-8-4 <add> by chester
-static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source)
+static int Config_FileGetParameter(unsigned char *string,
+               unsigned char *dest, unsigned char *source)
 {
-  UCHAR buf1[100];
+  unsigned char buf1[100];
   int source_len = strlen(source);
 
     memset(buf1,0,100);
@@ -2989,13 +2993,13 @@ static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source)
     source+=strlen(buf1);
 
    memcpy(dest,source,source_len-strlen(buf1));
- return TRUE;
+ return true;
 }
 
-int Config_FileOperation(PSDevice pDevice,BOOL fwrite,unsigned char *Parameter) {
-    UCHAR    *config_path=CONFIG_PATH;
-    UCHAR    *buffer=NULL;
-    UCHAR      tmpbuffer[20];
+int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter) {
+    unsigned char *config_path = CONFIG_PATH;
+    unsigned char *buffer = NULL;
+    unsigned char tmpbuffer[20];
     struct file   *filp=NULL;
     mm_segment_t old_fs = get_fs();
     //int oldfsuid=0,oldfsgid=0;
@@ -3038,7 +3042,7 @@ if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
  goto error1;
 }
 
-if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=TRUE) {
+if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) {
   printk("get parameter error?\n");
   result = -1;
   goto error1;
@@ -3555,19 +3559,19 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
        else {
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
            spin_lock_irq(&pDevice->lock);
-           pDevice->bLinkPass = FALSE;
+           pDevice->bLinkPass = false;
            memset(pMgmt->abyCurrBSSID, 0, 6);
            pMgmt->eCurrState = WMAC_STATE_IDLE;
            netif_stop_queue(pDevice->dev);
        #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
              pMgmt->eScanType = WMAC_SCAN_ACTIVE;
-        if(pDevice->bWPASuppWextEnabled !=TRUE)
+        if(pDevice->bWPASuppWextEnabled !=true)
         #endif
            bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
            bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL);
            spin_unlock_irq(&pDevice->lock);
       }
-      pDevice->bCommit = FALSE;
+      pDevice->bCommit = false;
     }
 
     return rc;
@@ -3598,20 +3602,20 @@ static int ethtool_ioctl(struct net_device *dev, void *useraddr)
 
 /*------------------------------------------------------------------*/
 
-MODULE_DEVICE_TABLE(pci, device_id_table);
+MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table);
 
 static struct pci_driver device_driver = {
         name:       DEVICE_NAME,
-        id_table:   device_id_table,
-        probe:      device_found1,
-        remove:     device_remove1,
+        id_table:   vt6655_pci_id_table,
+        probe:      vt6655_probe,
+        remove:     vt6655_remove,
 #ifdef CONFIG_PM
         suspend:    viawget_suspend,
         resume:     viawget_resume,
 #endif
 };
 
-static int __init device_init_module(void)
+static int __init vt6655_init_module(void)
 {
     int ret;
 
@@ -3627,7 +3631,7 @@ static int __init device_init_module(void)
     return ret;
 }
 
-static void __exit device_cleanup_module(void)
+static void __exit vt6655_cleanup_module(void)
 {
 
 
@@ -3638,8 +3642,8 @@ static void __exit device_cleanup_module(void)
 
 }
 
-module_init(device_init_module);
-module_exit(device_cleanup_module);
+module_init(vt6655_init_module);
+module_exit(vt6655_cleanup_module);
 
 
 #ifdef CONFIG_PM
@@ -3651,7 +3655,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
     case SYS_DOWN:
     case SYS_HALT:
     case SYS_POWER_OFF:
-        while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+       for_each_pci_dev(pdev) {
             if(pci_dev_driver(pdev) == &device_driver) {
                 if (pci_get_drvdata(pdev))
                     viawget_suspend(pdev, PMSG_HIBERNATE);
@@ -3677,10 +3681,10 @@ viawget_suspend(struct pci_dev *pcid, pm_message_t state)
     pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
     pDevice->uCmdDequeueIdx = 0;
     pDevice->uCmdEnqueueIdx = 0;
-    pDevice->bCmdRunning = FALSE;
+    pDevice->bCmdRunning = false;
     MACbShutdown(pDevice->PortOffset);
     MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext);
-    pDevice->bLinkPass = FALSE;
+    pDevice->bLinkPass = false;
     memset(pMgmt->abyCurrBSSID, 0, 6);
     pMgmt->eCurrState = WMAC_STATE_IDLE;
     pci_disable_device(pcid);
@@ -3704,9 +3708,9 @@ viawget_resume(struct pci_dev *pcid)
         spin_lock_irq(&pDevice->lock);
         MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
         device_init_registers(pDevice, DEVICE_INIT_DXPL);
-        if (pMgmt->sNodeDBTable[0].bActive == TRUE) { // Assoc with BSS
-            pMgmt->sNodeDBTable[0].bActive = FALSE;
-            pDevice->bLinkPass = FALSE;
+        if (pMgmt->sNodeDBTable[0].bActive == true) { // Assoc with BSS
+            pMgmt->sNodeDBTable[0].bActive = false;
+            pDevice->bLinkPass = false;
             if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
                 // In Adhoc, BSS state set back to started.
                 pMgmt->eCurrState = WMAC_STATE_STARTED;
index 6b758a8c1af364f2556b848454109713bbeed578..15130733693ed8bbc9262ab335c93394f02d5370 100644 (file)
@@ -66,7 +66,7 @@
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 static int          msglevel                =MSG_LEVEL_INFO;
 
-const BYTE acbyRxRate[MAX_RATE] =
+const unsigned char acbyRxRate[MAX_RATE] =
 {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
 
 
@@ -76,70 +76,60 @@ const BYTE acbyRxRate[MAX_RATE] =
 
 /*---------------------  Static Functions  --------------------------*/
 
-static BYTE s_byGetRateIdx(BYTE byRate);
+static unsigned char s_byGetRateIdx(unsigned char byRate);
 
 
-static
-void
-s_vGetDASA(
-    PBYTE pbyRxBufferAddr,
-    PUINT pcbHeaderSize,
-    PSEthernetHeader psEthHeader
-    );
+static void
+s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
+               PSEthernetHeader psEthHeader);
 
-static
-void
-s_vProcessRxMACHeader (
-    PSDevice pDevice,
-    PBYTE pbyRxBufferAddr,
-    UINT cbPacketSize,
-    BOOL bIsWEP,
-    BOOL bExtIV,
-    PUINT pcbHeadSize
-    );
+static void
+s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr,
+               unsigned int cbPacketSize, bool bIsWEP, bool bExtIV,
+               unsigned int *pcbHeadSize);
 
-static BOOL s_bAPModeRxCtl(
+static bool s_bAPModeRxCtl(
     PSDevice pDevice,
-    PBYTE    pbyFrame,
-    INT      iSANodeIndex
+    unsigned char *pbyFrame,
+    int      iSANodeIndex
     );
 
 
 
-static BOOL s_bAPModeRxData (
+static bool s_bAPModeRxData (
     PSDevice pDevice,
     struct sk_buff* skb,
-    UINT     FrameSize,
-    UINT     cbHeaderOffset,
-    INT      iSANodeIndex,
-    INT      iDANodeIndex
+    unsigned int FrameSize,
+    unsigned int cbHeaderOffset,
+    int      iSANodeIndex,
+    int      iDANodeIndex
     );
 
 
-static BOOL s_bHandleRxEncryption(
+static bool s_bHandleRxEncryption(
     PSDevice     pDevice,
-    PBYTE        pbyFrame,
-    UINT         FrameSize,
-    PBYTE        pbyRsr,
-    PBYTE       pbyNewRsr,
+    unsigned char *pbyFrame,
+    unsigned int FrameSize,
+    unsigned char *pbyRsr,
+    unsigned char *pbyNewRsr,
     PSKeyItem   *pKeyOut,
-    int *       pbExtIV,
-    PWORD       pwRxTSC15_0,
-    PDWORD      pdwRxTSC47_16
+    bool *pbExtIV,
+    unsigned short *pwRxTSC15_0,
+    unsigned long *pdwRxTSC47_16
     );
 
-static BOOL s_bHostWepRxEncryption(
+static bool s_bHostWepRxEncryption(
 
     PSDevice     pDevice,
-    PBYTE        pbyFrame,
-    UINT         FrameSize,
-    PBYTE        pbyRsr,
-    BOOL         bOnFly,
+    unsigned char *pbyFrame,
+    unsigned int FrameSize,
+    unsigned char *pbyRsr,
+    bool bOnFly,
     PSKeyItem    pKey,
-    PBYTE       pbyNewRsr,
-    int *       pbExtIV,
-    PWORD       pwRxTSC15_0,
-    PDWORD      pdwRxTSC47_16
+    unsigned char *pbyNewRsr,
+    bool *pbExtIV,
+    unsigned short *pwRxTSC15_0,
+    unsigned long *pdwRxTSC47_16
 
     );
 
@@ -162,27 +152,21 @@ static BOOL s_bHostWepRxEncryption(
  * Return Value: None
  *
 -*/
-static
-void
-s_vProcessRxMACHeader (
-    PSDevice pDevice,
-    PBYTE pbyRxBufferAddr,
-    UINT cbPacketSize,
-    BOOL bIsWEP,
-    BOOL bExtIV,
-    PUINT pcbHeadSize
-    )
+static void
+s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr,
+               unsigned int cbPacketSize, bool bIsWEP, bool bExtIV,
+               unsigned int *pcbHeadSize)
 {
-    PBYTE           pbyRxBuffer;
-    UINT            cbHeaderSize = 0;
-    PWORD           pwType;
+    unsigned char *pbyRxBuffer;
+    unsigned int cbHeaderSize = 0;
+    unsigned short *pwType;
     PS802_11Header  pMACHeader;
     int             ii;
 
 
     pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
 
-    s_vGetDASA((PBYTE)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
+    s_vGetDASA((unsigned char *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
 
     if (bIsWEP) {
         if (bExtIV) {
@@ -197,18 +181,18 @@ s_vProcessRxMACHeader (
         cbHeaderSize += WLAN_HDR_ADDR3_LEN;
     };
 
-    pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize);
-    if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+    pbyRxBuffer = (unsigned char *) (pbyRxBufferAddr + cbHeaderSize);
+    if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
         cbHeaderSize += 6;
     }
-    else if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+    else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
         cbHeaderSize += 6;
-        pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+        pwType = (unsigned short *) (pbyRxBufferAddr + cbHeaderSize);
         if ((*pwType!= TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
         }
         else {
             cbHeaderSize -= 8;
-            pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+            pwType = (unsigned short *) (pbyRxBufferAddr + cbHeaderSize);
             if (bIsWEP) {
                 if (bExtIV) {
                     *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
@@ -223,7 +207,7 @@ s_vProcessRxMACHeader (
     }
     else {
         cbHeaderSize -= 2;
-        pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+        pwType = (unsigned short *) (pbyRxBufferAddr + cbHeaderSize);
         if (bIsWEP) {
             if (bExtIV) {
                 *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
@@ -237,7 +221,7 @@ s_vProcessRxMACHeader (
     }
 
     cbHeaderSize -= (ETH_ALEN * 2);
-    pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize);
+    pbyRxBuffer = (unsigned char *) (pbyRxBufferAddr + cbHeaderSize);
     for(ii=0;ii<ETH_ALEN;ii++)
         *pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii];
     for(ii=0;ii<ETH_ALEN;ii++)
@@ -249,9 +233,9 @@ s_vProcessRxMACHeader (
 
 
 
-static BYTE s_byGetRateIdx (BYTE byRate)
+static unsigned char s_byGetRateIdx (unsigned char byRate)
 {
-    BYTE    byRateIdx;
+    unsigned char byRateIdx;
 
     for (byRateIdx = 0; byRateIdx <MAX_RATE ; byRateIdx++) {
         if (acbyRxRate[byRateIdx%MAX_RATE] == byRate)
@@ -261,15 +245,11 @@ static BYTE s_byGetRateIdx (BYTE byRate)
 }
 
 
-static
-void
-s_vGetDASA (
-    PBYTE pbyRxBufferAddr,
-    PUINT pcbHeaderSize,
-    PSEthernetHeader psEthHeader
-    )
+static void
+s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
+       PSEthernetHeader psEthHeader)
 {
-    UINT            cbHeaderSize = 0;
+    unsigned int cbHeaderSize = 0;
     PS802_11Header  pMACHeader;
     int             ii;
 
@@ -333,7 +313,7 @@ void        MngWorkItem(void *Context)
 
 
 
-BOOL
+bool
 device_receive_frame (
     PSDevice pDevice,
     PSRxDesc pCurrRD
@@ -349,36 +329,36 @@ device_receive_frame (
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSRxMgmtPacket  pRxPacket = &(pDevice->pMgmt->sRxPacket);
     PS802_11Header  p802_11Header;
-    PBYTE           pbyRsr;
-    PBYTE           pbyNewRsr;
-    PBYTE           pbyRSSI;
+    unsigned char *pbyRsr;
+    unsigned char *pbyNewRsr;
+    unsigned char *pbyRSSI;
     PQWORD          pqwTSFTime;
-    PWORD           pwFrameSize;
-    PBYTE           pbyFrame;
-    BOOL            bDeFragRx = FALSE;
-    BOOL            bIsWEP = FALSE;
-    UINT            cbHeaderOffset;
-    UINT            FrameSize;
-    WORD            wEtherType = 0;
-    INT             iSANodeIndex = -1;
-    INT             iDANodeIndex = -1;
-    UINT            ii;
-    UINT            cbIVOffset;
-    BOOL            bExtIV = FALSE;
-    PBYTE           pbyRxSts;
-    PBYTE           pbyRxRate;
-    PBYTE           pbySQ;
-    UINT            cbHeaderSize;
+    unsigned short *pwFrameSize;
+    unsigned char *pbyFrame;
+    bool bDeFragRx = false;
+    bool bIsWEP = false;
+    unsigned int cbHeaderOffset;
+    unsigned int FrameSize;
+    unsigned short wEtherType = 0;
+    int             iSANodeIndex = -1;
+    int             iDANodeIndex = -1;
+    unsigned int ii;
+    unsigned int cbIVOffset;
+    bool bExtIV = false;
+    unsigned char *pbyRxSts;
+    unsigned char *pbyRxRate;
+    unsigned char *pbySQ;
+    unsigned int cbHeaderSize;
     PSKeyItem       pKey = NULL;
-    WORD            wRxTSC15_0 = 0;
-    DWORD           dwRxTSC47_16 = 0;
+    unsigned short wRxTSC15_0 = 0;
+    unsigned long dwRxTSC47_16 = 0;
     SKeyItem        STempKey;
     // 802.11h RPI
-    DWORD           dwDuration = 0;
-    LONG            ldBm = 0;
-    LONG            ldBmThreshold = 0;
+    unsigned long dwDuration = 0;
+    long            ldBm = 0;
+    long            ldBmThreshold = 0;
     PS802_11Header pMACHeader;
BOOL            bRxeapol_key = FALSE;
bool bRxeapol_key = false;
 
 //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- device_receive_frame---\n");
 
@@ -391,7 +371,7 @@ device_receive_frame (
                      pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
 #endif
 //PLICE_DEBUG<-
-    pwFrameSize = (PWORD)(skb->data + 2);
+    pwFrameSize = (unsigned short *)(skb->data + 2);
     FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount);
 
     // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
@@ -399,17 +379,17 @@ device_receive_frame (
     if ((FrameSize > 2364)||(FrameSize <= 32)) {
         // Frame Size error drop this packet.
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
-        return FALSE;
+        return false;
     }
 
-    pbyRxSts = (PBYTE) (skb->data);
-    pbyRxRate = (PBYTE) (skb->data + 1);
-    pbyRsr = (PBYTE) (skb->data + FrameSize - 1);
-    pbyRSSI = (PBYTE) (skb->data + FrameSize - 2);
-    pbyNewRsr = (PBYTE) (skb->data + FrameSize - 3);
-    pbySQ = (PBYTE) (skb->data + FrameSize - 4);
+    pbyRxSts = (unsigned char *) (skb->data);
+    pbyRxRate = (unsigned char *) (skb->data + 1);
+    pbyRsr = (unsigned char *) (skb->data + FrameSize - 1);
+    pbyRSSI = (unsigned char *) (skb->data + FrameSize - 2);
+    pbyNewRsr = (unsigned char *) (skb->data + FrameSize - 3);
+    pbySQ = (unsigned char *) (skb->data + FrameSize - 4);
     pqwTSFTime = (PQWORD) (skb->data + FrameSize - 12);
-    pbyFrame = (PBYTE)(skb->data + 4);
+    pbyFrame = (unsigned char *)(skb->data + 4);
 
     // get packet size
     FrameSize = cpu_to_le16(*pwFrameSize);
@@ -417,7 +397,7 @@ device_receive_frame (
     if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC
                                                // Min: 14 bytes ACK
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
-        return FALSE;
+        return false;
     }
 //PLICE_DEBUG->
 #if 1
@@ -431,9 +411,9 @@ device_receive_frame (
 
 #endif
 
-  pMACHeader=(PS802_11Header)((PBYTE) (skb->data)+8);
+  pMACHeader=(PS802_11Header)((unsigned char *) (skb->data)+8);
 //PLICE_DEBUG<-
-       if (pDevice->bMeasureInProgress == TRUE) {
+       if (pDevice->bMeasureInProgress == true) {
         if ((*pbyRsr & RSR_CRCOK) != 0) {
             pDevice->byBasicMap |= 0x01;
         }
@@ -460,13 +440,13 @@ device_receive_frame (
             ii--;
         }
         pDevice->dwRPIs[ii] += dwDuration;
-        return FALSE;
+        return false;
     }
 
-    if (!IS_MULTICAST_ADDRESS(pbyFrame) && !IS_BROADCAST_ADDRESS(pbyFrame)) {
+    if (!is_multicast_ether_addr(pbyFrame)) {
         if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) (skb->data + 4))) {
             pDevice->s802_11Counter.FrameDuplicateCount++;
-            return FALSE;
+            return false;
         }
     }
 
@@ -475,14 +455,14 @@ device_receive_frame (
     s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader);
 
     // filter packet send from myself
-    if (IS_ETH_ADDRESS_EQUAL((PBYTE)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
-        return FALSE;
+    if (!compare_ether_addr((unsigned char *)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
+        return false;
 
     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
         if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
             p802_11Header = (PS802_11Header) (pbyFrame);
             // get SA NodeIndex
-            if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) {
+            if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) {
                 pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
                 pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
             }
@@ -490,17 +470,17 @@ device_receive_frame (
     }
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
-        if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == TRUE) {
-            return FALSE;
+        if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) {
+            return false;
         }
     }
 
 
     if (IS_FC_WEP(pbyFrame)) {
-        BOOL     bRxDecryOK = FALSE;
+        bool bRxDecryOK = false;
 
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
-        bIsWEP = TRUE;
+        bIsWEP = true;
         if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) {
             pKey = &STempKey;
             pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite;
@@ -552,11 +532,11 @@ device_receive_frame (
 //                      pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++;
                     }
                 }
-                return FALSE;
+                return false;
             }
         } else {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
-            return FALSE;
+            return false;
         }
         if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
             FrameSize -= 8;         // Message Integrity Code
@@ -584,18 +564,18 @@ device_receive_frame (
 
         }
         else {
-            return FALSE;
+            return false;
         }
     }
 
 
 // Management & Control frame Handle
-    if ((IS_TYPE_DATA((skb->data+4))) == FALSE) {
+    if ((IS_TYPE_DATA((skb->data+4))) == false) {
         // Handle Control & Manage Frame
 
         if (IS_TYPE_MGMT((skb->data+4))) {
-            PBYTE pbyData1;
-            PBYTE pbyData2;
+            unsigned char *pbyData1;
+            unsigned char *pbyData2;
 
             pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4);
             pRxPacket->cbMPDULen = FrameSize;
@@ -649,13 +629,13 @@ device_receive_frame (
                skb->protocol = htons(ETH_P_802_2);
                    memset(skb->cb, 0, sizeof(skb->cb));
                    netif_rx(skb);
-                return TRUE;
+                return true;
                }
         }
         else {
             // Control Frame
         };
-        return FALSE;
+        return false;
     }
     else {
         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
@@ -667,12 +647,12 @@ device_receive_frame (
                         pDevice->dev->name);
                     }
                 }
-                return FALSE;
+                return false;
             }
         }
         else {
             // discard DATA packet while not associate || BSSID error
-            if ((pDevice->bLinkPass == FALSE) ||
+            if ((pDevice->bLinkPass == false) ||
                 !(*pbyRsr & RSR_BSSIDOK)) {
                 if (bDeFragRx) {
                     if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
@@ -680,12 +660,12 @@ device_receive_frame (
                         pDevice->dev->name);
                     }
                 }
-                return FALSE;
+                return false;
             }
    //mike add:station mode check eapol-key challenge--->
          {
-           BYTE  Protocol_Version;    //802.1x Authentication
-           BYTE  Packet_Type;           //802.1x Authentication
+           unsigned char Protocol_Version;    //802.1x Authentication
+           unsigned char Packet_Type;           //802.1x Authentication
               if (bIsWEP)
                   cbIVOffset = 8;
               else
@@ -697,7 +677,7 @@ device_receive_frame (
             if (wEtherType == ETH_P_PAE) {         //Protocol Type in LLC-Header
                   if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
                     (Packet_Type==3)) {  //802.1x OR eapol-key challenge frame receive
-                        bRxeapol_key = TRUE;
+                        bRxeapol_key = true;
                   }
              }
          }
@@ -716,8 +696,8 @@ device_receive_frame (
             }
         }
         else {
-            if (pDevice->pMgmt->bInTIMWake == TRUE) {
-                pDevice->pMgmt->bInTIMWake = FALSE;
+            if (pDevice->pMgmt->bInTIMWake == true) {
+                pDevice->pMgmt->bInTIMWake = false;
             }
         }
     };
@@ -725,7 +705,7 @@ device_receive_frame (
     // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
     if (pDevice->bDiversityEnable && (FrameSize>50) &&
         (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
-        (pDevice->bLinkPass == TRUE)) {
+        (pDevice->bLinkPass == true)) {
        //printk("device_receive_frame: RxRate is %d\n",*pbyRxRate);
                BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
     }
@@ -752,8 +732,8 @@ device_receive_frame (
 
     // -----------------------------------------------
 
-    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == TRUE)){
-        BYTE    abyMacHdr[24];
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)){
+        unsigned char abyMacHdr[24];
 
         // Only 802.1x packet incoming allowed
         if (bIsWEP)
@@ -767,7 +747,7 @@ device_receive_frame (
         if (wEtherType == ETH_P_PAE) {
             skb->dev = pDevice->apdev;
 
-            if (bIsWEP == TRUE) {
+            if (bIsWEP == true) {
                 // strip IV header(8)
                 memcpy(&abyMacHdr[0], (skb->data + 4), 24);
                 memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24);
@@ -781,12 +761,12 @@ device_receive_frame (
             skb->protocol = htons(ETH_P_802_2);
             memset(skb->cb, 0, sizeof(skb->cb));
             netif_rx(skb);
-            return TRUE;
+            return true;
 
 }
         // check if 802.1x authorized
         if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED))
-            return FALSE;
+            return false;
     }
 
 
@@ -800,53 +780,53 @@ device_receive_frame (
     // Soft MIC
     if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
         if (bIsWEP) {
-            PDWORD          pdwMIC_L;
-            PDWORD          pdwMIC_R;
-            DWORD           dwMIC_Priority;
-            DWORD           dwMICKey0 = 0, dwMICKey1 = 0;
-            DWORD           dwLocalMIC_L = 0;
-            DWORD           dwLocalMIC_R = 0;
+            unsigned long *pdwMIC_L;
+            unsigned long *pdwMIC_R;
+            unsigned long dwMIC_Priority;
+            unsigned long dwMICKey0 = 0, dwMICKey1 = 0;
+            unsigned long dwLocalMIC_L = 0;
+            unsigned long dwLocalMIC_R = 0;
             viawget_wpa_header *wpahdr;
 
 
             if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
-                dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24]));
-                dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28]));
+                dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24]));
+                dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28]));
             }
             else {
                 if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
-                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16]));
-                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20]));
+                    dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16]));
+                    dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20]));
                 } else if ((pKey->dwKeyIndex & BIT28) == 0) {
-                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16]));
-                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20]));
+                    dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16]));
+                    dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20]));
                 } else {
-                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24]));
-                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28]));
+                    dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24]));
+                    dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28]));
                 }
             }
 
             MIC_vInit(dwMICKey0, dwMICKey1);
-            MIC_vAppend((PBYTE)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12);
+            MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12);
             dwMIC_Priority = 0;
-            MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+            MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
             // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
-            MIC_vAppend((PBYTE)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8),
+            MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8),
                         FrameSize - WLAN_HDR_ADDR3_LEN - 8);
             MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
             MIC_vUnInit();
 
-            pdwMIC_L = (PDWORD)(skb->data + 4 + FrameSize);
-            pdwMIC_R = (PDWORD)(skb->data + 4 + FrameSize + 4);
+            pdwMIC_L = (unsigned long *)(skb->data + 4 + FrameSize);
+            pdwMIC_R = (unsigned long *)(skb->data + 4 + FrameSize + 4);
             //DBG_PRN_GRP12(("RxL: %lx, RxR: %lx\n", *pdwMIC_L, *pdwMIC_R));
             //DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R));
             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1);
 
 
             if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
-                (pDevice->bRxMICFail == TRUE)) {
+                (pDevice->bRxMICFail == true)) {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
-                pDevice->bRxMICFail = FALSE;
+                pDevice->bRxMICFail = false;
                 //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++;
                 pDevice->s802_11Counter.TKIPLocalMICFailures++;
                 if (bDeFragRx) {
@@ -858,7 +838,7 @@ device_receive_frame (
                //2008-0409-07, <Add> by Einsn Liu
        #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
                                //send event to wpa_supplicant
-                               //if(pDevice->bWPADevEnable == TRUE)
+                               //if(pDevice->bWPADevEnable == true)
                                {
                                        union iwreq_data wrqu;
                                        struct iw_michaelmicfailure ev;
@@ -906,7 +886,7 @@ device_receive_frame (
                      pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
                  };
 
-                return FALSE;
+                return false;
 
             }
         }
@@ -917,13 +897,13 @@ device_receive_frame (
     if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
                            (pKey->byCipherSuite == KEY_CTL_CCMP))) {
         if (bIsWEP) {
-            WORD        wLocalTSC15_0 = 0;
-            DWORD       dwLocalTSC47_16 = 0;
-            ULONGLONG       RSC = 0;
+            unsigned short wLocalTSC15_0 = 0;
+            unsigned long dwLocalTSC47_16 = 0;
+            unsigned long long       RSC = 0;
             // endian issues
-            RSC = *((ULONGLONG *) &(pKey->KeyRSC));
-            wLocalTSC15_0 = (WORD) RSC;
-            dwLocalTSC47_16 = (DWORD) (RSC>>16);
+            RSC = *((unsigned long long *) &(pKey->KeyRSC));
+            wLocalTSC15_0 = (unsigned short) RSC;
+            dwLocalTSC47_16 = (unsigned long) (RSC>>16);
 
             RSC = dwRxTSC47_16;
             RSC <<= 16;
@@ -950,7 +930,7 @@ device_receive_frame (
                                 pDevice->dev->name);
                         }
                     }
-                    return FALSE;
+                    return false;
                 }
             }
         }
@@ -963,13 +943,13 @@ device_receive_frame (
     }
 
 
-    s_vProcessRxMACHeader(pDevice, (PBYTE)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
+    s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
     FrameSize -= cbHeaderOffset;
     cbHeaderOffset += 4;        // 4 is Rcv buffer header
 
     // Null data, framesize = 14
     if (FrameSize < 15)
-        return FALSE;
+        return false;
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
         if (s_bAPModeRxData(pDevice,
@@ -978,7 +958,7 @@ device_receive_frame (
                             cbHeaderOffset,
                             iSANodeIndex,
                             iDANodeIndex
-                            ) == FALSE) {
+                            ) == false) {
 
             if (bDeFragRx) {
                 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
@@ -986,10 +966,10 @@ device_receive_frame (
                     pDevice->dev->name);
                 }
             }
-            return FALSE;
+            return false;
         }
 
-//        if(pDevice->bRxMICFail == FALSE) {
+//        if(pDevice->bRxMICFail == false) {
 //           for (ii =0; ii < 100; ii++)
 //                printk(" %02x", *(skb->data + ii));
 //           printk("\n");
@@ -1016,7 +996,7 @@ device_receive_frame (
                     pDevice->dev->name);
                 }
             }
-                       return FALSE;
+                       return false;
                }
        }
 */
@@ -1031,17 +1011,17 @@ device_receive_frame (
             DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                 pDevice->dev->name);
         }
-        return FALSE;
+        return false;
     }
 
-    return TRUE;
+    return true;
 }
 
 
-static BOOL s_bAPModeRxCtl (
+static bool s_bAPModeRxCtl (
     PSDevice pDevice,
-    PBYTE    pbyFrame,
-    INT      iSANodeIndex
+    unsigned char *pbyFrame,
+    int      iSANodeIndex
     )
 {
     PS802_11Header      p802_11Header;
@@ -1063,30 +1043,30 @@ static BOOL s_bAPModeRxCtl (
                     // reason = (6) class 2 received from nonauth sta
                     vMgrDeAuthenBeginSta(pDevice,
                                          pMgmt,
-                                         (PBYTE)(p802_11Header->abyAddr2),
+                                         (unsigned char *)(p802_11Header->abyAddr2),
                                          (WLAN_MGMT_REASON_CLASS2_NONAUTH),
                                          &Status
                                          );
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
-                    return TRUE;
+                    return true;
                 };
                 if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
                     // send deassoc notification
                     // reason = (7) class 3 received from nonassoc sta
                     vMgrDisassocBeginSta(pDevice,
                                          pMgmt,
-                                         (PBYTE)(p802_11Header->abyAddr2),
+                                         (unsigned char *)(p802_11Header->abyAddr2),
                                          (WLAN_MGMT_REASON_CLASS3_NONASSOC),
                                          &Status
                                          );
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
-                    return TRUE;
+                    return true;
                 };
 
                 if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
                     // delcare received ps-poll event
                     if (IS_CTL_PSPOLL(pbyFrame)) {
-                        pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                        pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
                         bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n");
                     }
@@ -1094,8 +1074,8 @@ static BOOL s_bAPModeRxCtl (
                         // check Data PS state
                         // if PW bit off, send out all PS bufferring packets.
                         if (!IS_FC_POWERMGT(pbyFrame)) {
-                            pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
-                            pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                            pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
+                            pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
                             bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
                             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n");
                         }
@@ -1103,15 +1083,15 @@ static BOOL s_bAPModeRxCtl (
                 }
                 else {
                    if (IS_FC_POWERMGT(pbyFrame)) {
-                       pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = TRUE;
+                       pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true;
                        // Once if STA in PS state, enable multicast bufferring
-                       pMgmt->sNodeDBTable[0].bPSEnable = TRUE;
+                       pMgmt->sNodeDBTable[0].bPSEnable = true;
                    }
                    else {
                       // clear all pending PS frame.
                       if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) {
-                          pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
-                          pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                          pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
+                          pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
                           bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
                          DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n");
 
@@ -1122,7 +1102,7 @@ static BOOL s_bAPModeRxCtl (
             else {
                   vMgrDeAuthenBeginSta(pDevice,
                                        pMgmt,
-                                       (PBYTE)(p802_11Header->abyAddr2),
+                                       (unsigned char *)(p802_11Header->abyAddr2),
                                        (WLAN_MGMT_REASON_CLASS2_NONAUTH),
                                        &Status
                                        );
@@ -1154,31 +1134,31 @@ static BOOL s_bAPModeRxCtl (
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl );
                     VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode );
-                    return TRUE;
+                    return true;
             }
         }
     }
-    return FALSE;
+    return false;
 
 }
 
-static BOOL s_bHandleRxEncryption (
+static bool s_bHandleRxEncryption (
     PSDevice     pDevice,
-    PBYTE        pbyFrame,
-    UINT         FrameSize,
-    PBYTE        pbyRsr,
-    PBYTE       pbyNewRsr,
+    unsigned char *pbyFrame,
+    unsigned int FrameSize,
+    unsigned char *pbyRsr,
+    unsigned char *pbyNewRsr,
     PSKeyItem   *pKeyOut,
-    int *       pbExtIV,
-    PWORD       pwRxTSC15_0,
-    PDWORD      pdwRxTSC47_16
+    bool *pbExtIV,
+    unsigned short *pwRxTSC15_0,
+    unsigned long *pdwRxTSC47_16
     )
 {
-    UINT            PayloadLen = FrameSize;
-    PBYTE           pbyIV;
-    BYTE            byKeyIdx;
+    unsigned int PayloadLen = FrameSize;
+    unsigned char *pbyIV;
+    unsigned char byKeyIdx;
     PSKeyItem       pKey = NULL;
-    BYTE            byDecMode = KEY_CTL_WEP;
+    unsigned char byDecMode = KEY_CTL_WEP;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
 
 
@@ -1186,8 +1166,8 @@ static BOOL s_bHandleRxEncryption (
     *pdwRxTSC47_16 = 0;
 
     pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
-    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
-         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+    if ( WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame) ) {
          pbyIV += 6;             // 6 is 802.11 address4
          PayloadLen -= 6;
     }
@@ -1204,7 +1184,7 @@ static BOOL s_bHandleRxEncryption (
             (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) {
             // unicast pkt use pairwise key
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
-            if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == TRUE) {
+            if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) {
                 if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP)
                     byDecMode = KEY_CTL_TKIP;
                 else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP)
@@ -1238,24 +1218,24 @@ static BOOL s_bHandleRxEncryption (
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
         if (byDecMode == KEY_CTL_WEP) {
 //            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
-        } else if (pDevice->bLinkPass == TRUE) {
+        } else if (pDevice->bLinkPass == true) {
 //            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
         }
-        return FALSE;
+        return false;
     }
     if (byDecMode != pKey->byCipherSuite) {
         if (byDecMode == KEY_CTL_WEP) {
 //            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
-        } else if (pDevice->bLinkPass == TRUE) {
+        } else if (pDevice->bLinkPass == true) {
 //            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
         }
         *pKeyOut = NULL;
-        return FALSE;
+        return false;
     }
     if (byDecMode == KEY_CTL_WEP) {
         // handle WEP
         if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
-            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE)) {
+            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) {
             // Software WEP
             // 1. 3253A
             // 2. WEP 256
@@ -1275,12 +1255,12 @@ static BOOL s_bHandleRxEncryption (
         // TKIP/AES
 
         PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
-        *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+        *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4));
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
         if (byDecMode == KEY_CTL_TKIP) {
             *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
         } else {
-            *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
+            *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV);
         }
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
 
@@ -1303,28 +1283,28 @@ static BOOL s_bHandleRxEncryption (
     }// end of TKIP/AES
 
     if ((*(pbyIV+3) & 0x20) != 0)
-        *pbExtIV = TRUE;
-    return TRUE;
+        *pbExtIV = true;
+    return true;
 }
 
 
-static BOOL s_bHostWepRxEncryption (
+static bool s_bHostWepRxEncryption (
     PSDevice     pDevice,
-    PBYTE        pbyFrame,
-    UINT         FrameSize,
-    PBYTE        pbyRsr,
-    BOOL         bOnFly,
+    unsigned char *pbyFrame,
+    unsigned int FrameSize,
+    unsigned char *pbyRsr,
+    bool bOnFly,
     PSKeyItem    pKey,
-    PBYTE       pbyNewRsr,
-    int *       pbExtIV,
-    PWORD       pwRxTSC15_0,
-    PDWORD      pdwRxTSC47_16
+    unsigned char *pbyNewRsr,
+    bool *pbExtIV,
+    unsigned short *pwRxTSC15_0,
+    unsigned long *pdwRxTSC47_16
     )
 {
-    UINT            PayloadLen = FrameSize;
-    PBYTE           pbyIV;
-    BYTE            byKeyIdx;
-    BYTE            byDecMode = KEY_CTL_WEP;
+    unsigned int PayloadLen = FrameSize;
+    unsigned char *pbyIV;
+    unsigned char byKeyIdx;
+    unsigned char byDecMode = KEY_CTL_WEP;
     PS802_11Header  pMACHeader;
 
 
@@ -1333,8 +1313,8 @@ static BOOL s_bHostWepRxEncryption (
     *pdwRxTSC47_16 = 0;
 
     pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
-    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
-         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+    if ( WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame) ) {
          pbyIV += 6;             // 6 is 802.11 address4
          PayloadLen -= 6;
     }
@@ -1353,18 +1333,18 @@ static BOOL s_bHostWepRxEncryption (
     if (byDecMode != pKey->byCipherSuite) {
         if (byDecMode == KEY_CTL_WEP) {
 //            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
-        } else if (pDevice->bLinkPass == TRUE) {
+        } else if (pDevice->bLinkPass == true) {
 //            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
         }
-        return FALSE;
+        return false;
     }
 
     if (byDecMode == KEY_CTL_WEP) {
         // handle WEP
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n");
         if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
-            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE) ||
-            (bOnFly == FALSE)) {
+            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) ||
+            (bOnFly == false)) {
             // Software WEP
             // 1. 3253A
             // 2. WEP 256
@@ -1385,19 +1365,19 @@ static BOOL s_bHostWepRxEncryption (
         // TKIP/AES
 
         PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
-        *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+        *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4));
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
 
         if (byDecMode == KEY_CTL_TKIP) {
             *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
         } else {
-            *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
+            *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV);
         }
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
 
         if (byDecMode == KEY_CTL_TKIP) {
 
-            if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == FALSE)) {
+            if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) {
                 // Software TKIP
                 // 1. 3253 A
                 // 2. NotOnFly
@@ -1417,7 +1397,7 @@ static BOOL s_bHostWepRxEncryption (
         }
 
         if (byDecMode == KEY_CTL_CCMP) {
-            if (bOnFly == FALSE) {
+            if (bOnFly == false) {
                 // Software CCMP
                 // NotOnFly
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n");
@@ -1433,34 +1413,34 @@ static BOOL s_bHostWepRxEncryption (
     }// end of TKIP/AES
 
     if ((*(pbyIV+3) & 0x20) != 0)
-        *pbExtIV = TRUE;
-    return TRUE;
+        *pbExtIV = true;
+    return true;
 }
 
 
 
-static BOOL s_bAPModeRxData (
+static bool s_bAPModeRxData (
     PSDevice pDevice,
     struct sk_buff* skb,
-    UINT     FrameSize,
-    UINT     cbHeaderOffset,
-    INT      iSANodeIndex,
-    INT      iDANodeIndex
+    unsigned int FrameSize,
+    unsigned int cbHeaderOffset,
+    int      iSANodeIndex,
+    int      iDANodeIndex
     )
 {
     PSMgmtObject        pMgmt = pDevice->pMgmt;
-    BOOL                bRelayAndForward = FALSE;
-    BOOL                bRelayOnly = FALSE;
-    BYTE                byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
-    WORD                wAID;
+    bool bRelayAndForward = false;
+    bool bRelayOnly = false;
+    unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    unsigned short wAID;
 
 
     struct sk_buff* skbcpy = NULL;
 
     if (FrameSize > CB_MAX_BUF_SIZE)
-        return FALSE;
+        return false;
     // check DA
-    if(IS_MULTICAST_ADDRESS((PBYTE)(skb->data+cbHeaderOffset))) {
+    if(is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) {
        if (pMgmt->sNodeDBTable[0].bPSEnable) {
 
            skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
@@ -1481,12 +1461,12 @@ static BOOL s_bAPModeRxData (
            }
        }
        else {
-           bRelayAndForward = TRUE;
+           bRelayAndForward = true;
        }
     }
     else {
         // check if relay
-        if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(skb->data+cbHeaderOffset), &iDANodeIndex)) {
+        if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) {
             if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) {
                 if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) {
                     // queue this skb until next PS tx, and then release.
@@ -1500,10 +1480,10 @@ static BOOL s_bAPModeRxData (
                     pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
                                iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
-                    return TRUE;
+                    return true;
                 }
                 else {
-                    bRelayOnly = TRUE;
+                    bRelayOnly = true;
                 }
             }
         };
@@ -1515,16 +1495,16 @@ static BOOL s_bAPModeRxData (
             iDANodeIndex = 0;
 
         if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) {
-            ROUTEbRelay(pDevice, (PBYTE)(skb->data + cbHeaderOffset), FrameSize, (UINT)iDANodeIndex);
+            ROUTEbRelay(pDevice, (unsigned char *)(skb->data + cbHeaderOffset), FrameSize, (unsigned int)iDANodeIndex);
         }
 
         if (bRelayOnly)
-            return FALSE;
+            return false;
     }
     // none associate, don't forward
     if (pDevice->uAssocCount == 0)
-        return FALSE;
+        return false;
 
-    return TRUE;
+    return true;
 }
 
index e574963fee0c96eb7bdc8277261eb86ba0aa8c17..c1b6e76a421f16b8fe7050fb7e5f70f1ca05900c 100644 (file)
@@ -41,7 +41,7 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL
+bool
 device_receive_frame (
     PSDevice pDevice,
     PSRxDesc pCurrRD
index 195cc36654aeea7a9628812807544d88f3dea5d6..5b83f942cdab3b1f2ec1e3245ef247261e10e215 100644 (file)
@@ -154,9 +154,9 @@ static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked)
        }
        kfree(pDevice->apdev);
        pDevice->apdev = NULL;
-    pDevice->bEnable8021x = FALSE;
-    pDevice->bEnableHostWEP = FALSE;
-    pDevice->bEncryptionEnable = FALSE;
+    pDevice->bEnable8021x = false;
+    pDevice->bEnableHostWEP = false;
+    pDevice->bEncryptionEnable = false;
 
 //4.2007-0118-03,<Add> by EinsnLiu
 //execute some clear work
@@ -215,7 +215,7 @@ int vt6655_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked)
 static int hostap_remove_sta(PSDevice pDevice,
                                     struct viawget_hostapd_param *param)
 {
-       UINT uNodeIndex;
+       unsigned int uNodeIndex;
 
 
     if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, param->sta_addr, &uNodeIndex)) {
@@ -244,7 +244,7 @@ static int hostap_add_sta(PSDevice pDevice,
                                  struct viawget_hostapd_param *param)
 {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-       UINT uNodeIndex;
+       unsigned int uNodeIndex;
 
 
     if (!BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
@@ -255,7 +255,7 @@ static int hostap_add_sta(PSDevice pDevice,
     pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability;
 // TODO listenInterval
 //    pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1;
-    pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = FALSE;
+    pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = false;
     pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates;
 
     // set max tx rate
@@ -267,7 +267,7 @@ static int hostap_add_sta(PSDevice pDevice,
     pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
             WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo);
 
-    pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid;
+    pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)param->u.add_sta.aid;
 
     pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
 
@@ -304,7 +304,7 @@ static int hostap_get_info_sta(PSDevice pDevice,
                                       struct viawget_hostapd_param *param)
 {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-       UINT uNodeIndex;
+       unsigned int uNodeIndex;
 
     if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
            param->u.get_info_sta.inactive_sec =
@@ -328,7 +328,7 @@ static int hostap_get_info_sta(PSDevice pDevice,
  *      pDevice   -
  *      param     -
  *  Out:
- *      TURE, FALSE
+ *      true, false
  *
  * Return Value:
  *
@@ -338,7 +338,7 @@ static int hostap_reset_txexc_sta(PSDevice pDevice,
                                          struct viawget_hostapd_param *param)
 {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-       UINT uNodeIndex;
+       unsigned int uNodeIndex;
 
     if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
         pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0;
@@ -368,13 +368,13 @@ static int hostap_set_flags_sta(PSDevice pDevice,
                                        struct viawget_hostapd_param *param)
 {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-       UINT uNodeIndex;
+       unsigned int uNodeIndex;
 
     if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
                pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
                pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n",
-                           (UINT)pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
+                           (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
        }
        else {
            return -ENOENT;
@@ -471,16 +471,16 @@ static int hostap_set_encryption(PSDevice pDevice,
                                       int param_len)
 {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    DWORD   dwKeyIndex = 0;
-    BYTE    abyKey[MAX_KEY_LEN];
-    BYTE    abySeq[MAX_KEY_LEN];
+    unsigned long dwKeyIndex = 0;
+    unsigned char abyKey[MAX_KEY_LEN];
+    unsigned char abySeq[MAX_KEY_LEN];
     NDIS_802_11_KEY_RSC   KeyRSC;
-    BYTE    byKeyDecMode = KEY_CTL_WEP;
+    unsigned char byKeyDecMode = KEY_CTL_WEP;
        int     ret = 0;
        int     iNodeIndex = -1;
        int     ii;
-       BOOL    bKeyTableFull = FALSE;
-       WORD    wKeyCtl = 0;
+       bool bKeyTableFull = false;
+       unsigned short wKeyCtl = 0;
 
 
        param->u.crypt.err = 0;
@@ -509,7 +509,7 @@ static int hostap_set_encryption(PSDevice pDevice,
         iNodeIndex = 0;
 
        } else {
-           if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == FALSE) {
+           if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) {
                param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
                return -EINVAL;
@@ -520,14 +520,14 @@ static int hostap_set_encryption(PSDevice pDevice,
 
        if (param->u.crypt.alg == WPA_ALG_NONE) {
 
-        if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == TRUE) {
+        if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) {
             if (KeybRemoveKey(&(pDevice->sKey),
                                 param->sta_addr,
                                 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex,
-                                pDevice->PortOffset) == FALSE) {
+                                pDevice->PortOffset) == false) {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
             }
-            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
         }
         pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0;
         pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0;
@@ -553,16 +553,16 @@ static int hostap_set_encryption(PSDevice pDevice,
             param->u.crypt.key_len
            );
 
-    dwKeyIndex = (DWORD)(param->u.crypt.idx);
+    dwKeyIndex = (unsigned long)(param->u.crypt.idx);
     if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
-        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
-        pDevice->bTransmitKey = TRUE;
+        pDevice->byKeyIndex = (unsigned char)dwKeyIndex;
+        pDevice->bTransmitKey = true;
         dwKeyIndex |= (1 << 31);
     }
 
        if (param->u.crypt.alg == WPA_ALG_WEP) {
 
-        if ((pDevice->bEnable8021x == FALSE) || (iNodeIndex == 0)) {
+        if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) {
             KeybSetDefaultKey(&(pDevice->sKey),
                                 dwKeyIndex & ~(BIT30 | USE_KEYRSC),
                                 param->u.crypt.key_len,
@@ -580,21 +580,21 @@ static int hostap_set_encryption(PSDevice pDevice,
                            dwKeyIndex & ~(USE_KEYRSC),
                            param->u.crypt.key_len,
                            (PQWORD) &(KeyRSC),
-                           (PBYTE)abyKey,
+                           (unsigned char *)abyKey,
                             KEY_CTL_WEP,
                             pDevice->PortOffset,
-                            pDevice->byLocalID) == TRUE) {
+                            pDevice->byLocalID) == true) {
 
-                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
 
             } else {
                 // Key Table Full
-                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
-                bKeyTableFull = TRUE;
+                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
+                bKeyTableFull = true;
             }
         }
         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
-        pDevice->bEncryptionEnable = TRUE;
+        pDevice->bEncryptionEnable = true;
         pMgmt->byCSSPK = KEY_CTL_WEP;
         pMgmt->byCSSGK = KEY_CTL_WEP;
         pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP;
@@ -640,7 +640,7 @@ static int hostap_set_encryption(PSDevice pDevice,
                            byKeyDecMode,
                            pDevice->PortOffset,
                            pDevice->byLocalID);
-       pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+       pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
 
     } else {
         dwKeyIndex |= (1 << 30); // set pairwise key
@@ -649,23 +649,23 @@ static int hostap_set_encryption(PSDevice pDevice,
                        dwKeyIndex,
                        param->u.crypt.key_len,
                        (PQWORD) &(KeyRSC),
-                       (PBYTE)abyKey,
+                       (unsigned char *)abyKey,
                         byKeyDecMode,
                         pDevice->PortOffset,
-                        pDevice->byLocalID) == TRUE) {
+                        pDevice->byLocalID) == true) {
 
-            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
 
         } else {
             // Key Table Full
-            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
-            bKeyTableFull = TRUE;
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
+            bKeyTableFull = true;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
         }
 
     }
 
-    if (bKeyTableFull == TRUE) {
+    if (bKeyTableFull == true) {
         wKeyCtl &= 0x7F00;              // clear all key control filed
         wKeyCtl |= (byKeyDecMode << 4);
         wKeyCtl |= (byKeyDecMode);
@@ -686,7 +686,7 @@ static int hostap_set_encryption(PSDevice pDevice,
               );
 
        // set wep key
-    pDevice->bEncryptionEnable = TRUE;
+    pDevice->bEncryptionEnable = true;
     pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode;
     pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
     pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
@@ -727,7 +727,7 @@ static int hostap_get_encryption(PSDevice pDevice,
            param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
         iNodeIndex = 0;
        } else {
-           if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == FALSE) {
+           if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) {
                param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
                return -EINVAL;
@@ -736,7 +736,7 @@ static int hostap_get_encryption(PSDevice pDevice,
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
     memset(param->u.crypt.seq, 0, 8);
     for (ii = 0 ; ii < 8 ; ii++) {
-        param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
+        param->u.crypt.seq[ii] = (unsigned char)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
     }
 
        return ret;
index 60c0a362361364158b411c063e57e7aa3c036aec..53c50c0fc813782558a20ede4542256c5c6a03af 100644 (file)
@@ -37,7 +37,6 @@
 #define DEF
 #endif
 
-//typedef int BOOL;
 //typedef uint32_t u32;
 //typedef uint16_t u16;
 //typedef uint8_t u8;
@@ -109,10 +108,10 @@ typedef enum tagWZONETYPE {
 //
 #pragma pack(1)
 typedef struct tagSCmdRequest {
-       U8          name[16];
+       u8          name[16];
        void    *data;
-       U16         wResult;
-       U16     wCmdCode;
+       u16         wResult;
+       u16     wCmdCode;
 } SCmdRequest, *PSCmdRequest;
 
 //
@@ -121,7 +120,7 @@ typedef struct tagSCmdRequest {
 
 typedef struct tagSCmdScan {
 
-    U8     ssid[SSID_MAXLEN + 2];
+       u8 ssid[SSID_MAXLEN + 2];
 
 } SCmdScan, *PSCmdScan;
 
@@ -132,12 +131,12 @@ typedef struct tagSCmdScan {
 
 typedef struct tagSCmdBSSJoin {
 
-    U16            wBSSType;
-    U16     wBBPType;
-    U8     ssid[SSID_MAXLEN + 2];
-    U32            uChannel;
-    BOOL    bPSEnable;
-    BOOL    bShareKeyAuth;
+    u16            wBSSType;
+    u16     wBBPType;
+    u8     ssid[SSID_MAXLEN + 2];
+    u32            uChannel;
+    bool bPSEnable;
+    bool bShareKeyAuth;
 
 } SCmdBSSJoin, *PSCmdBSSJoin;
 
@@ -147,7 +146,7 @@ typedef struct tagSCmdBSSJoin {
 
 typedef struct tagSCmdZoneTypeSet {
 
BOOL       bWrite;
bool bWrite;
  WZONETYPE  ZoneType;
 
 } SCmdZoneTypeSet, *PSCmdZoneTypeSet;
@@ -155,33 +154,33 @@ typedef struct tagSCmdZoneTypeSet {
 #ifdef WPA_SM_Transtatus
 typedef struct tagSWPAResult {
          char  ifname[100];
-         U8            proto;
-         U8   key_mgmt;
-         U8   eap_type;
-         BOOL authenticated;
+         u8 proto;
+         u8 key_mgmt;
+         u8 eap_type;
+         bool authenticated;
 } SWPAResult, *PSWPAResult;
 #endif
 
 typedef struct tagSCmdStartAP {
 
-    U16            wBSSType;
-    U16     wBBPType;
-    U8     ssid[SSID_MAXLEN + 2];
-    U32        uChannel;
-    U32     uBeaconInt;
-    BOOL    bShareKeyAuth;
-    U8      byBasicRate;
+    u16            wBSSType;
+    u16     wBBPType;
+    u8     ssid[SSID_MAXLEN + 2];
+    u32            uChannel;
+    u32     uBeaconInt;
+    bool bShareKeyAuth;
+    u8      byBasicRate;
 
 } SCmdStartAP, *PSCmdStartAP;
 
 
 typedef struct tagSCmdSetWEP {
 
-    BOOL    bEnableWep;
-    U8      byKeyIndex;
-    U8      abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN];
-    BOOL    bWepKeyAvailable[WEP_NKEYS];
-    U32     auWepKeyLength[WEP_NKEYS];
+    bool bEnableWep;
+    u8      byKeyIndex;
+    u8      abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN];
+    bool bWepKeyAvailable[WEP_NKEYS];
+    u32     auWepKeyLength[WEP_NKEYS];
 
 } SCmdSetWEP, *PSCmdSetWEP;
 
@@ -189,39 +188,39 @@ typedef struct tagSCmdSetWEP {
 
 typedef struct tagSBSSIDItem {
 
-       U32         uChannel;
-    U8      abyBSSID[BSSID_LEN];
-    U8      abySSID[SSID_MAXLEN + 1];
+       u32         uChannel;
+    u8      abyBSSID[BSSID_LEN];
+    u8      abySSID[SSID_MAXLEN + 1];
     //2006-1116-01,<Modify> by NomadZhao
-    //U16          wBeaconInterval;
-    //U16          wCapInfo;
-    //U8      byNetType;
-    U8      byNetType;
-    U16            wBeaconInterval;
-    U16            wCapInfo;        // for address of byNetType at align 4
+    //u16          wBeaconInterval;
+    //u16          wCapInfo;
+    //u8      byNetType;
+    u8      byNetType;
+    u16            wBeaconInterval;
+    u16            wCapInfo;        // for address of byNetType at align 4
 
-    BOOL    bWEPOn;
-    U32     uRSSI;
+    bool bWEPOn;
+    u32     uRSSI;
 
 } SBSSIDItem;
 
 
 typedef struct tagSBSSIDList {
 
-       U32                 uItem;
+       u32                 uItem;
        SBSSIDItem      sBSSIDList[0];
 } SBSSIDList, *PSBSSIDList;
 
 
 typedef struct tagSCmdLinkStatus {
 
-    BOOL    bLink;
-       U16         wBSSType;
-       U8      byState;
-    U8      abyBSSID[BSSID_LEN];
-    U8      abySSID[SSID_MAXLEN + 2];
-    U32     uChannel;
-    U32     uLinkRate;
+    bool bLink;
+       u16   wBSSType;
+       u8      byState;
+    u8      abyBSSID[BSSID_LEN];
+    u8      abySSID[SSID_MAXLEN + 2];
+    u32     uChannel;
+    u32     uLinkRate;
 
 } SCmdLinkStatus, *PSCmdLinkStatus;
 
@@ -229,18 +228,18 @@ typedef struct tagSCmdLinkStatus {
 // 802.11 counter
 //
 typedef struct tagSDot11MIBCount {
-    U32 TransmittedFragmentCount;
-    U32 MulticastTransmittedFrameCount;
-    U32 FailedCount;
-    U32 RetryCount;
-    U32 MultipleRetryCount;
-    U32 RTSSuccessCount;
-    U32 RTSFailureCount;
-    U32 ACKFailureCount;
-    U32 FrameDuplicateCount;
-    U32 ReceivedFragmentCount;
-    U32 MulticastReceivedFrameCount;
-    U32 FCSErrorCount;
+       u32 TransmittedFragmentCount;
+       u32 MulticastTransmittedFrameCount;
+       u32 FailedCount;
+       u32 RetryCount;
+       u32 MultipleRetryCount;
+       u32 RTSSuccessCount;
+       u32 RTSFailureCount;
+       u32 ACKFailureCount;
+       u32 FrameDuplicateCount;
+       u32 ReceivedFragmentCount;
+       u32 MulticastReceivedFrameCount;
+       u32 FCSErrorCount;
 } SDot11MIBCount, *PSDot11MIBCount;
 
 
@@ -252,129 +251,129 @@ typedef struct tagSStatMIBCount {
     //
     // ISR status count
     //
-    U32   dwIsrTx0OK;
-    U32   dwIsrTx1OK;
-    U32   dwIsrBeaconTxOK;
-    U32   dwIsrRxOK;
-    U32   dwIsrTBTTInt;
-    U32   dwIsrSTIMERInt;
-    U32   dwIsrUnrecoverableError;
-    U32   dwIsrSoftInterrupt;
-    U32   dwIsrRxNoBuf;
+       u32   dwIsrTx0OK;
+       u32   dwIsrTx1OK;
+       u32   dwIsrBeaconTxOK;
+       u32   dwIsrRxOK;
+       u32   dwIsrTBTTInt;
+       u32   dwIsrSTIMERInt;
+       u32   dwIsrUnrecoverableError;
+       u32   dwIsrSoftInterrupt;
+       u32   dwIsrRxNoBuf;
     /////////////////////////////////////
 
-    U32   dwIsrUnknown;               // unknown interrupt count
+       u32   dwIsrUnknown;               // unknown interrupt count
 
     // RSR status count
     //
-    U32   dwRsrFrmAlgnErr;
-    U32   dwRsrErr;
-    U32   dwRsrCRCErr;
-    U32   dwRsrCRCOk;
-    U32   dwRsrBSSIDOk;
-    U32   dwRsrADDROk;
-    U32   dwRsrICVOk;
-    U32   dwNewRsrShortPreamble;
-    U32   dwRsrLong;
-    U32   dwRsrRunt;
-
-    U32   dwRsrRxControl;
-    U32   dwRsrRxData;
-    U32   dwRsrRxManage;
-
-    U32   dwRsrRxPacket;
-    U32   dwRsrRxOctet;
-    U32   dwRsrBroadcast;
-    U32   dwRsrMulticast;
-    U32   dwRsrDirected;
+       u32   dwRsrFrmAlgnErr;
+       u32   dwRsrErr;
+       u32   dwRsrCRCErr;
+       u32   dwRsrCRCOk;
+       u32   dwRsrBSSIDOk;
+       u32   dwRsrADDROk;
+       u32   dwRsrICVOk;
+       u32   dwNewRsrShortPreamble;
+       u32   dwRsrLong;
+       u32   dwRsrRunt;
+
+       u32   dwRsrRxControl;
+       u32   dwRsrRxData;
+       u32   dwRsrRxManage;
+
+       u32   dwRsrRxPacket;
+       u32   dwRsrRxOctet;
+       u32   dwRsrBroadcast;
+       u32   dwRsrMulticast;
+       u32   dwRsrDirected;
     // 64-bit OID
-    U32   ullRsrOK;
+       u32   ullRsrOK;
 
     // for some optional OIDs (64 bits) and DMI support
-    U32   ullRxBroadcastBytes;
-    U32   ullRxMulticastBytes;
-    U32   ullRxDirectedBytes;
-    U32   ullRxBroadcastFrames;
-    U32   ullRxMulticastFrames;
-    U32   ullRxDirectedFrames;
-
-    U32   dwRsrRxFragment;
-    U32   dwRsrRxFrmLen64;
-    U32   dwRsrRxFrmLen65_127;
-    U32   dwRsrRxFrmLen128_255;
-    U32   dwRsrRxFrmLen256_511;
-    U32   dwRsrRxFrmLen512_1023;
-    U32   dwRsrRxFrmLen1024_1518;
+       u32   ullRxBroadcastBytes;
+       u32   ullRxMulticastBytes;
+       u32   ullRxDirectedBytes;
+       u32   ullRxBroadcastFrames;
+       u32   ullRxMulticastFrames;
+       u32   ullRxDirectedFrames;
+
+       u32   dwRsrRxFragment;
+       u32   dwRsrRxFrmLen64;
+       u32   dwRsrRxFrmLen65_127;
+       u32   dwRsrRxFrmLen128_255;
+       u32   dwRsrRxFrmLen256_511;
+       u32   dwRsrRxFrmLen512_1023;
+       u32   dwRsrRxFrmLen1024_1518;
 
     // TSR0,1 status count
     //
-    U32   dwTsrTotalRetry[2];        // total collision retry count
-    U32   dwTsrOnceRetry[2];         // this packet only occur one collision
-    U32   dwTsrMoreThanOnceRetry[2]; // this packet occur more than one collision
-    U32   dwTsrRetry[2];             // this packet has ever occur collision,
+       u32   dwTsrTotalRetry[2];        // total collision retry count
+       u32   dwTsrOnceRetry[2];         // this packet only occur one collision
+       u32   dwTsrMoreThanOnceRetry[2]; // this packet occur more than one collision
+       u32   dwTsrRetry[2];             // this packet has ever occur collision,
                                        // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0)
-    U32   dwTsrACKData[2];
-    U32   dwTsrErr[2];
-    U32   dwAllTsrOK[2];
-    U32   dwTsrRetryTimeout[2];
-    U32   dwTsrTransmitTimeout[2];
-
-    U32   dwTsrTxPacket[2];
-    U32   dwTsrTxOctet[2];
-    U32   dwTsrBroadcast[2];
-    U32   dwTsrMulticast[2];
-    U32   dwTsrDirected[2];
+       u32   dwTsrACKData[2];
+       u32   dwTsrErr[2];
+       u32   dwAllTsrOK[2];
+       u32   dwTsrRetryTimeout[2];
+       u32   dwTsrTransmitTimeout[2];
+
+       u32   dwTsrTxPacket[2];
+       u32   dwTsrTxOctet[2];
+       u32   dwTsrBroadcast[2];
+       u32   dwTsrMulticast[2];
+       u32   dwTsrDirected[2];
 
     // RD/TD count
-    U32   dwCntRxFrmLength;
-    U32   dwCntTxBufLength;
+       u32   dwCntRxFrmLength;
+       u32   dwCntTxBufLength;
 
-    U8    abyCntRxPattern[16];
-    U8    abyCntTxPattern[16];
+       u8    abyCntRxPattern[16];
+       u8    abyCntTxPattern[16];
 
     // Software check....
-    U32   dwCntRxDataErr;             // rx buffer data software compare CRC err count
-    U32   dwCntDecryptErr;            // rx buffer data software compare CRC err count
-    U32   dwCntRxICVErr;              // rx buffer data software compare CRC err count
-    U32    idxRxErrorDesc;             // index for rx data error RD
+       u32   dwCntRxDataErr;             // rx buffer data software compare CRC err count
+       u32   dwCntDecryptErr;            // rx buffer data software compare CRC err count
+       u32   dwCntRxICVErr;              // rx buffer data software compare CRC err count
+       u32    idxRxErrorDesc;             // index for rx data error RD
 
     // 64-bit OID
-    U32   ullTsrOK[2];
+       u32   ullTsrOK[2];
 
     // for some optional OIDs (64 bits) and DMI support
-    U32   ullTxBroadcastFrames[2];
-    U32   ullTxMulticastFrames[2];
-    U32   ullTxDirectedFrames[2];
-    U32   ullTxBroadcastBytes[2];
-    U32   ullTxMulticastBytes[2];
-    U32   ullTxDirectedBytes[2];
+       u32   ullTxBroadcastFrames[2];
+       u32   ullTxMulticastFrames[2];
+       u32   ullTxDirectedFrames[2];
+       u32   ullTxBroadcastBytes[2];
+       u32   ullTxMulticastBytes[2];
+       u32   ullTxDirectedBytes[2];
 } SStatMIBCount, *PSStatMIBCount;
 
 
 typedef struct tagSNodeItem {
     // STA info
-    U16            wAID;
-    U8             abyMACAddr[6];
-    U16            wTxDataRate;
-    U16            wInActiveCount;
-    U16            wEnQueueCnt;
-    U16            wFlags;
-    BOOL           bPWBitOn;
-    U8             byKeyIndex;
-    U16            wWepKeyLength;
-    U8            abyWepKey[WEP_KEYMAXLEN];
+    u16            wAID;
+    u8             abyMACAddr[6];
+    u16            wTxDataRate;
+    u16            wInActiveCount;
+    u16            wEnQueueCnt;
+    u16            wFlags;
+    bool bPWBitOn;
+    u8             byKeyIndex;
+    u16            wWepKeyLength;
+    u8            abyWepKey[WEP_KEYMAXLEN];
     // Auto rate fallback vars
-    BOOL           bIsInFallback;
-    U32            uTxFailures;
-    U32            uTxAttempts;
-    U16            wFailureRatio;
+    bool bIsInFallback;
+    u32            uTxFailures;
+    u32            uTxAttempts;
+    u16            wFailureRatio;
 
 } SNodeItem;
 
 
 typedef struct tagSNodeList {
 
-       U32                 uItem;
+       u32                 uItem;
        SNodeItem       sNodeList[0];
 
 } SNodeList, *PSNodeList;
@@ -383,7 +382,7 @@ typedef struct tagSNodeList {
 
 typedef struct tagSCmdValue {
 
-    U32     dwValue;
+       u32 dwValue;
 
 } SCmdValue,  *PSCmdValue;
 
@@ -418,46 +417,46 @@ enum {
 
 
 struct viawget_hostapd_param {
-       U32 cmd;
-       U8 sta_addr[6];
+       u32 cmd;
+       u8 sta_addr[6];
        union {
                struct {
-                       U16 aid;
-                       U16 capability;
-                       U8 tx_supp_rates;
+                       u16 aid;
+                       u16 capability;
+                       u8 tx_supp_rates;
                } add_sta;
                struct {
-                       U32 inactive_sec;
+                       u32 inactive_sec;
                } get_info_sta;
                struct {
-                       U8 alg;
-                       U32 flags;
-                       U32 err;
-                       U8 idx;
-                       U8 seq[8];
-                       U16 key_len;
-                       U8 key[0];
+                       u8 alg;
+                       u32 flags;
+                       u32 err;
+                       u8 idx;
+                       u8 seq[8];
+                       u16 key_len;
+                       u8 key[0];
                } crypt;
                struct {
-                       U32 flags_and;
-                       U32 flags_or;
+                       u32 flags_and;
+                       u32 flags_or;
                } set_flags_sta;
                struct {
-                       U16 rid;
-                       U16 len;
-                       U8 data[0];
+                       u16 rid;
+                       u16 len;
+                       u8 data[0];
                } rid;
                struct {
-                       U8 len;
-                       U8 data[0];
+                       u8 len;
+                       u8 data[0];
                } generic_elem;
                struct {
-                       U16 cmd;
-                       U16 reason_code;
+                       u16 cmd;
+                       u16 reason_code;
                } mlme;
                struct {
-                       U8 ssid_len;
-                       U8 ssid[32];
+                       u8 ssid_len;
+                       u8 ssid[32];
                } scan_req;
        } u;
 };
index 404287c6025281a019d573e6ceddc3f04da10f71..5624a41e3d5ea19f3813cd111c85592ec42cbf17 100644 (file)
@@ -70,16 +70,16 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
     SNodeList           sNodeList;
     PSBSSIDList         pList;
     PSNodeList          pNodeList;
-    UINT                cbListCount;
+    unsigned int cbListCount;
     PKnownBSS           pBSS;
     PKnownNodeDB        pNode;
-    UINT                ii, jj;
+    unsigned int ii, jj;
     SCmdLinkStatus      sLinkStatus;
-    BYTE                abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
-    BYTE                abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-    DWORD               dwKeyIndex= 0;
-    BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-    LONG                ldBm;
+    unsigned char abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+    unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    unsigned long dwKeyIndex= 0;
+    unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    long                ldBm;
 
     pReq->wResult = 0;
 
@@ -99,17 +99,17 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
             memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
         }
 
-        if (pDevice->bMACSuspend == TRUE) {
-            if (pDevice->bRadioOff == TRUE)
+        if (pDevice->bMACSuspend == true) {
+            if (pDevice->bRadioOff == true)
                 CARDbRadioPowerOn(pDevice);
             vMgrTimerInit(pDevice);
             MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
             add_timer(&pMgmt->sTimerSecondCallback);
-            pDevice->bMACSuspend = FALSE;
+            pDevice->bMACSuspend = false;
         }
         spin_lock_irq(&pDevice->lock);
         if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0)
-            BSSvClearBSSList((void *)pDevice, FALSE);
+            BSSvClearBSSList((void *)pDevice, false);
         else
             BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
 
@@ -130,7 +130,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                        break;
                };
 
-          if(sZoneTypeCmd.bWrite==TRUE) {
+          if(sZoneTypeCmd.bWrite==true) {
          //////write zonetype
                 if(sZoneTypeCmd.ZoneType == ZoneType_USA) {
                   //set to USA
@@ -147,7 +147,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
             }
        else {
           ///////read zonetype
-         BYTE                       zonetype=0;
+         unsigned char zonetype=0;
 
 
            if(zonetype == 0x00)  { //USA
@@ -174,13 +174,13 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
     case WLAN_CMD_BSS_JOIN:
 
-        if (pDevice->bMACSuspend == TRUE) {
-            if (pDevice->bRadioOff == TRUE)
+        if (pDevice->bMACSuspend == true) {
+            if (pDevice->bRadioOff == true)
                 CARDbRadioPowerOn(pDevice);
             vMgrTimerInit(pDevice);
             MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
             add_timer(&pMgmt->sTimerSecondCallback);
-            pDevice->bMACSuspend = FALSE;
+            pDevice->bMACSuspend = false;
         }
 
         if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) {
@@ -199,7 +199,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n");
            }
-           if (sJoinCmd.bPSEnable == TRUE) {
+           if (sJoinCmd.bPSEnable == true) {
             pDevice->ePSMode = WMAC_POWER_FAST;
 //            pDevice->ePSMode = WMAC_POWER_MAX;
             pMgmt->wListenInterval = 2;
@@ -211,12 +211,12 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off \n");
         }
 
-        if (sJoinCmd.bShareKeyAuth == TRUE){
-            pMgmt->bShareKeyAlgorithm = TRUE;
+        if (sJoinCmd.bShareKeyAuth == true){
+            pMgmt->bShareKeyAlgorithm = true;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
         }
         else {
-            pMgmt->bShareKeyAlgorithm = FALSE;
+            pMgmt->bShareKeyAlgorithm = false;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
         }
            pDevice->uChannel = sJoinCmd.uChannel;
@@ -235,8 +235,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                        result = -EFAULT;
                        break;
                };
-           if (sWEPCmd.bEnableWep != TRUE) {
-            pDevice->bEncryptionEnable = FALSE;
+           if (sWEPCmd.bEnableWep != true) {
+            pDevice->bEncryptionEnable = false;
             pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
             MACvDisableDefaultKey(pDevice->PortOffset);
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable. \n");
@@ -257,15 +257,15 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                                     dwKeyIndex,
                                     sWEPCmd.auWepKeyLength[ii],
                                     NULL,
-                                    (PBYTE)&sWEPCmd.abyWepKey[ii][0],
+                                    (unsigned char *)&sWEPCmd.abyWepKey[ii][0],
                                     KEY_CTL_WEP,
                                     pDevice->PortOffset,
                                     pDevice->byLocalID);
             }
         }
         pDevice->byKeyIndex = sWEPCmd.byKeyIndex;
-        pDevice->bTransmitKey = TRUE;
-        pDevice->bEncryptionEnable = TRUE;
+        pDevice->bTransmitKey = true;
+        pDevice->bEncryptionEnable = true;
         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
 
         break;
@@ -286,8 +286,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
             sLinkStatus.byState = ADHOC_STARTED;
 
         sLinkStatus.uChannel = pMgmt->uCurrChannel;
-        if (pDevice->bLinkPass == TRUE) {
-            sLinkStatus.bLink = TRUE;
+        if (pDevice->bLinkPass == true) {
+            sLinkStatus.bLink = true;
                    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
                    memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len);
                    memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
@@ -295,7 +295,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Link Success ! \n");
         }
         else {
-            sLinkStatus.bLink = FALSE;
+            sLinkStatus.bLink = false;
         }
         if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) {
                        result = -EFAULT;
@@ -340,8 +340,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                    pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval;
                    pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo;
 //                 pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI;
-                   RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
-                   pList->sBSSIDList[ii].uRSSI = (UINT)ldBm;
+                   RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm);
+                   pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm;
                    memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN);
                    pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
                    memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1);
@@ -353,10 +353,10 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                        pList->sBSSIDList[ii].byNetType = ADHOC;
                    }
                    if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
-                       pList->sBSSIDList[ii].bWEPOn = TRUE;
+                       pList->sBSSIDList[ii].bWEPOn = true;
                 }
                 else {
-                       pList->sBSSIDList[ii].bWEPOn = FALSE;
+                       pList->sBSSIDList[ii].bWEPOn = false;
                    }
                    ii ++;
                    if (ii >= pList->uItem)
@@ -391,16 +391,16 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         netif_stop_queue(pDevice->dev);
 
         spin_lock_irq(&pDevice->lock);
-        if (pDevice->bRadioOff == FALSE) {
+        if (pDevice->bRadioOff == false) {
             CARDbRadioPowerOff(pDevice);
         }
-        pDevice->bLinkPass = FALSE;
+        pDevice->bLinkPass = false;
         memset(pMgmt->abyCurrBSSID, 0, 6);
         pMgmt->eCurrState = WMAC_STATE_IDLE;
         del_timer(&pDevice->sTimerCommand);
         del_timer(&pMgmt->sTimerSecondCallback);
-        pDevice->bCmdRunning = FALSE;
-        pDevice->bMACSuspend = TRUE;
+        pDevice->bCmdRunning = false;
+        pDevice->bMACSuspend = true;
         MACvIntDisable(pDevice->PortOffset);
         spin_unlock_irq(&pDevice->lock);
 
@@ -410,13 +410,13 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
 
-        if (pDevice->bMACSuspend == TRUE) {
-            if (pDevice->bRadioOff == TRUE)
+        if (pDevice->bMACSuspend == true) {
+            if (pDevice->bRadioOff == true)
                 CARDbRadioPowerOn(pDevice);
             vMgrTimerInit(pDevice);
             MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
             add_timer(&pMgmt->sTimerSecondCallback);
-            pDevice->bMACSuspend = FALSE;
+            pDevice->bMACSuspend = false;
         }
         break;
 
@@ -458,11 +458,11 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                };
 
                if (sValue.dwValue == 1) {
-            pDevice->bEnable8021x = TRUE;
+            pDevice->bEnable8021x = true;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
         }
         else {
-            pDevice->bEnable8021x = FALSE;
+            pDevice->bEnable8021x = false;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
         }
 
@@ -478,11 +478,11 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                };
 
                if (sValue.dwValue == 1) {
-            pDevice->bEnableHostWEP = TRUE;
+            pDevice->bEnableHostWEP = true;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
         }
         else {
-            pDevice->bEnableHostWEP = FALSE;
+            pDevice->bEnableHostWEP = false;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
         }
 
@@ -498,11 +498,11 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                if (sValue.dwValue == 1) {
                      DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
                   memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, ETH_ALEN);
-                  pDevice->bWPADEVUp = TRUE;
+                  pDevice->bWPADEVUp = true;
         }
         else {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
-          pDevice->bWPADEVUp = FALSE;
+          pDevice->bWPADEVUp = false;
         }
 
         break;
@@ -510,7 +510,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
     case WLAN_CMD_AP_START:
 
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
-        if (pDevice->bRadioOff == TRUE) {
+        if (pDevice->bRadioOff == true) {
             CARDbRadioPowerOn(pDevice);
             vMgrTimerInit(pDevice);
             MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
@@ -554,12 +554,12 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         else
             pMgmt->wIBSSBeaconPeriod = 100;
 
-        if (sStartAPCmd.bShareKeyAuth == TRUE){
-            pMgmt->bShareKeyAlgorithm = TRUE;
+        if (sStartAPCmd.bShareKeyAuth == true){
+            pMgmt->bShareKeyAlgorithm = true;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
         }
         else {
-            pMgmt->bShareKeyAlgorithm = FALSE;
+            pMgmt->bShareKeyAlgorithm = false;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
         }
         memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6);
@@ -635,9 +635,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                    pNodeList->sNodeList[jj].wAID = pNode->wAID;
                    memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN);
                    pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate;
-                   pNodeList->sNodeList[jj].wInActiveCount = (WORD)pNode->uInActiveCount;
-                   pNodeList->sNodeList[jj].wEnQueueCnt = (WORD)pNode->wEnQueueCnt;
-                   pNodeList->sNodeList[jj].wFlags = (WORD)pNode->dwFlags;
+                   pNodeList->sNodeList[jj].wInActiveCount = (unsigned short)pNode->uInActiveCount;
+                   pNodeList->sNodeList[jj].wEnQueueCnt = (unsigned short)pNode->wEnQueueCnt;
+                   pNodeList->sNodeList[jj].wFlags = (unsigned short)pNode->dwFlags;
                    pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable;
                    pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex;
                    pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength;
@@ -652,7 +652,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
                    pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback;
                    pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures;
                    pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts;
-                   pNodeList->sNodeList[jj].wFailureRatio = (WORD)pNode->uFailureRatio;
+                   pNodeList->sNodeList[jj].wFailureRatio = (unsigned short)pNode->uFailureRatio;
                    jj ++;
                    if (jj >= pNodeList->uItem)
                        break;
@@ -672,14 +672,14 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
            wpa_Result.proto = 0;
            wpa_Result.key_mgmt = 0;
            wpa_Result.eap_type = 0;
-           wpa_Result.authenticated = FALSE;
-             pDevice->fWPA_Authened = FALSE;
+           wpa_Result.authenticated = false;
+             pDevice->fWPA_Authened = false;
         if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) {
             result = -EFAULT;
                        break;
                }
 
-if(wpa_Result.authenticated==TRUE) {
+if(wpa_Result.authenticated==true) {
    #ifdef SndEvt_ToAPI
    {
      union iwreq_data      wrqu;
@@ -692,7 +692,7 @@ if(wpa_Result.authenticated==TRUE) {
      wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
    }
    #endif
-         pDevice->fWPA_Authened = TRUE;           //is successful peer to wpa_Result.authenticated?
+         pDevice->fWPA_Authened = true;           //is successful peer to wpa_Result.authenticated?
 }
 
         //printk("get private wpa_supplicant announce WPA SM\n");
@@ -700,7 +700,7 @@ if(wpa_Result.authenticated==TRUE) {
        //printk("wpa-->proto=%d\n",wpa_Result.proto);
        //printk("wpa-->key-mgmt=%d\n",wpa_Result.key_mgmt);
        //printk("wpa-->eap_type=%d\n",wpa_Result.eap_type);
-       //printk("wpa-->authenticated is %s\n",(wpa_Result.authenticated==TRUE)?"TRUE":"FALSE");
+       //printk("wpa-->authenticated is %s\n",(wpa_Result.authenticated==true)?"true":"false");
 
        pReq->wResult = 0;
         break;
@@ -717,9 +717,9 @@ if(wpa_Result.authenticated==TRUE) {
 void
 vConfigWEPKey (
     PSDevice pDevice,
-    DWORD    dwKeyIndex,
-    PBYTE    pbyKey,
-    ULONG    uKeyLength
+    unsigned long dwKeyIndex,
+    unsigned char *pbyKey,
+    unsigned long uKeyLength
     )
 {
     int ii;
@@ -728,15 +728,15 @@ vConfigWEPKey (
     memset(&pDevice->abyWepKey[dwKeyIndex][0], 0, WLAN_WEPMAX_KEYLEN);
     memcpy(&pDevice->abyWepKey[dwKeyIndex][0], pbyKey, uKeyLength);
 
-    pDevice->bWepKeyAvailable[dwKeyIndex] = TRUE;
+    pDevice->bWepKeyAvailable[dwKeyIndex] = true;
     pDevice->auWepKeyLength[dwKeyIndex] = uKeyLength;
 
     MACvSetDefaultKeyEntry(pDevice->PortOffset, uKeyLength, dwKeyIndex,
-                           (PDWORD) &(pDevice->abyWepKey[dwKeyIndex][0]), pDevice->byLocalID);
+                           (unsigned long *) &(pDevice->abyWepKey[dwKeyIndex][0]), pDevice->byLocalID);
 
     if (pDevice->eEncryptionStatus < Ndis802_11EncryptionNotSupported) {
         for(ii=0; ii<MAX_GROUP_KEY; ii++) {
-            if ((pDevice->bWepKeyAvailable[ii] == TRUE) &&
+            if ((pDevice->bWepKeyAvailable[ii] == true) &&
                 (pDevice->auWepKeyLength[ii] == WLAN_WEP232_KEYLEN)) {
                 pDevice->uCurrentWEPMode = TX_WEP_SW232;
                 MACvDisableDefaultKey(pDevice->PortOffset);
index 0d10c2a923c60114efd636cce3d49b5d2bb87c3f..ba85015c11b639abe5fb99e9bb6608d2b946fa45 100644 (file)
@@ -45,9 +45,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq);
 /*
 void vConfigWEPKey (
     PSDevice pDevice,
-    DWORD    dwKeyIndex,
-    PBYTE    pbyKey,
-    ULONG    uKeyLength
+    unsigned long dwKeyIndex,
+    unsigned char *pbyKey,
+    unsigned long uKeyLength
     );
 */
 
index cf69034fc0f0078fc764ff73aa754ced740909a6..43227617aabe676886d1e74d80da6a41757f2e56 100644 (file)
@@ -45,7 +45,7 @@
 #endif
 
 #include <net/iw_handler.h>
-extern WORD TxRate_iwconfig;//2008-5-8 <add> by chester
+extern unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -99,16 +99,16 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
               else
                   pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
           }
-          if(pDevice->bLinkPass !=TRUE)
+          if(pDevice->bLinkPass !=true)
               pDevice->scStatistic.LinkQuality = 0;
          #endif
           if(pDevice->scStatistic.LinkQuality > 100)
               pDevice->scStatistic.LinkQuality = 100;
-               pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
+               pDevice->wstats.qual.qual =(unsigned char) pDevice->scStatistic.LinkQuality;
        #else
        pDevice->wstats.qual.qual = pDevice->byCurrSQ;
        #endif
-       RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+       RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm);
        pDevice->wstats.qual.level = ldBm;
        //pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
        pDevice->wstats.qual.noise = 0;
@@ -116,7 +116,7 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
        pDevice->wstats.discard.nwid = 0;
        pDevice->wstats.discard.code = 0;
        pDevice->wstats.discard.fragment = 0;
-       pDevice->wstats.discard.retries = (U32)pDevice->scStatistic.dwTsrErr;
+       pDevice->wstats.discard.retries = (unsigned long)pDevice->scStatistic.dwTsrErr;
        pDevice->wstats.discard.misc = 0;
        pDevice->wstats.miss.beacon = 0;
 
@@ -175,7 +175,7 @@ int iwctl_siwscan(struct net_device *dev,
        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
         PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
        struct iw_scan_req  *req = (struct iw_scan_req *)extra;
-       BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+       unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
        PWLAN_IE_SSID       pItemSSID=NULL;
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n");
 
@@ -309,7 +309,7 @@ int iwctl_giwscan(struct net_device *dev,
                        //ADD quality
             memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVQUAL;
-               RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+               RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm);
                    iwe.u.qual.level = ldBm;
                iwe.u.qual.noise = 0;
 //2008-0409-01, <Add> by Einsn Liu
@@ -426,7 +426,7 @@ int iwctl_siwfreq(struct net_device *dev,
                          pDevice->uChannel = channel;
                         //2007-0207-04,<Add> by EinsnLiu
                         //Make change effect at once
-                         pDevice->bCommit = TRUE;
+                         pDevice->bCommit = true;
                }
        }
 
@@ -489,7 +489,7 @@ int iwctl_siwmode(struct net_device *dev,
            if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
             pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
             if (pDevice->flags & DEVICE_FLAGS_OPENED) {
-                       pDevice->bCommit = TRUE;
+                       pDevice->bCommit = true;
                    }
                }
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
@@ -499,7 +499,7 @@ int iwctl_siwmode(struct net_device *dev,
            if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
             pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
             if (pDevice->flags & DEVICE_FLAGS_OPENED) {
-                       pDevice->bCommit = TRUE;
+                       pDevice->bCommit = true;
                    }
                }
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
@@ -513,7 +513,7 @@ int iwctl_siwmode(struct net_device *dev,
            if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
             pMgmt->eConfigMode = WMAC_CONFIG_AP;
             if (pDevice->flags & DEVICE_FLAGS_OPENED) {
-                       pDevice->bCommit = TRUE;
+                       pDevice->bCommit = true;
                    }
                }
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
@@ -577,7 +577,7 @@ int iwctl_giwrange(struct net_device *dev,
 {
        struct iw_range *range = (struct iw_range *) extra;
        int             i,k;
-    BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+    unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
 
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
@@ -688,7 +688,7 @@ int iwctl_siwap(struct net_device *dev,
        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
     int rc = 0;
-    BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
+    unsigned char ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n");
 if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
@@ -701,12 +701,12 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
        else {
                memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
                                //2008-0409-05, <Add> by Einsn Liu
-               if((pDevice->bLinkPass == TRUE) &&
+               if((pDevice->bLinkPass == true) &&
                      (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6)== 0)){
                        return rc;
                        }
        //mike :add
-        if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
+        if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
             (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
              PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
                return rc;
@@ -714,10 +714,10 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
        //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
        //                  then ignore,because you don't known which one to be connect with??
                {
-           UINT            ii , uSameBssidNum=0;
+           unsigned int ii , uSameBssidNum=0;
                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                      if (pMgmt->sBSSList[ii].bActive &&
-                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID,pMgmt->abyDesireBSSID)) {
+                        !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyDesireBSSID)) {
                         uSameBssidNum++;
                      }
                   }
@@ -728,7 +728,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
                }
 
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
-                   pDevice->bCommit = TRUE;
+                   pDevice->bCommit = true;
                }
        }
        return rc;
@@ -751,7 +751,7 @@ int iwctl_giwap(struct net_device *dev,
 
     memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
    //2008-0410,<Modify> by Einsn Liu
-    if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
+    if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
         memset(wrq->sa_data, 0, 6);
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
@@ -830,11 +830,11 @@ int iwctl_siwessid(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
     PWLAN_IE_SSID       pItemSSID;
   //2008-0409-05, <Add> by Einsn Liu
-    BYTE  len;
+    unsigned char len;
 
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n");
- pDevice->fWPA_Authened = FALSE;
+ pDevice->fWPA_Authened = false;
 if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
         // In scanning..
      printk("SIOCSIWESSID(??)-->In scanning...\n");
@@ -848,7 +848,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
            PRINT_K("set essid to 'any' \n");
            #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
              //Unknown desired AP,so here need not associate??
-            //if(pDevice->bWPASuppWextEnabled == TRUE)  {
+            //if(pDevice->bWPASuppWextEnabled == true)  {
                   return 0;
             // }
             #endif
@@ -868,7 +868,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
        printk("set essid to %s \n",pItemSSID->abySSID);
                //2008-0409-05, <Add> by Einsn Liu
        len=(pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)?pItemSSID->len:((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len;
-   if((pDevice->bLinkPass == TRUE) &&
+   if((pDevice->bLinkPass == true) &&
        (memcmp(pItemSSID->abySSID,((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,len)==0))
          return 0;
 
@@ -881,12 +881,12 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  //Wext wil order another command of siwap to link with desired AP,
  //so here need not associate??
-  if(pDevice->bWPASuppWextEnabled == TRUE)  {
+  if(pDevice->bWPASuppWextEnabled == true)  {
         /*******search if  in hidden ssid mode ****/
         {
            PKnownBSS       pCurr = NULL;
-           BYTE                   abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-         UINT            ii , uSameBssidNum=0;
+           unsigned char abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+         unsigned int ii , uSameBssidNum=0;
 
          memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
             pCurr = BSSpSearchBSSList(pDevice,
@@ -906,7 +906,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
                      //         by means of judging if there are two same BSSID exist in list ?
                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                      if (pMgmt->sBSSList[ii].bActive &&
-                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+                        !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
                         uSameBssidNum++;
                      }
                   }
@@ -927,7 +927,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
        }
 
     if (pDevice->flags & DEVICE_FLAGS_OPENED) {
-           pDevice->bCommit = TRUE;
+           pDevice->bCommit = true;
        }
 
 
@@ -981,7 +981,7 @@ int iwctl_siwrate(struct net_device *dev,
     int rc = 0;
        u8      brate = 0;
        int     i;
-       BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+       unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
 
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
@@ -1033,7 +1033,7 @@ int iwctl_siwrate(struct net_device *dev,
                // Fixed mode
                // One rate, fixed
        printk("Rate Fix\n");
-               pDevice->bFixRate = TRUE;
+               pDevice->bFixRate = true;
         if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
            pDevice->uConnectionRate = 3;
         }
@@ -1044,7 +1044,7 @@ int iwctl_siwrate(struct net_device *dev,
 
        }
        else {
-        pDevice->bFixRate = FALSE;
+        pDevice->bFixRate = false;
         pDevice->uConnectionRate = 13;
        printk("auto rate:connection_rate is 13\n");
      }
@@ -1068,11 +1068,11 @@ int iwctl_giwrate(struct net_device *dev,
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
     {
-        BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+        unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
            int brate = 0;
 //2008-5-8 <modify> by chester
 if(pDevice->bLinkPass){
-if(pDevice->bFixRate == TRUE){
+if(pDevice->bFixRate == true){
                if (pDevice->uConnectionRate < 13) {
                brate = abySupportedRates[pDevice->uConnectionRate];
            }else {
@@ -1108,8 +1108,8 @@ else brate =0;
 //                brate = abySupportedRates[pDevice->wCurrentRate];
            wrq->value = brate * 500000;
            // If more than one rate, set auto
-           if (pDevice->bFixRate == TRUE)
-               wrq->fixed = TRUE;
+           if (pDevice->bFixRate == true)
+               wrq->fixed = true;
     }
 
 
@@ -1294,7 +1294,7 @@ int iwctl_siwencode(struct net_device *dev,
 {
     PSDevice           pDevice = (PSDevice)netdev_priv(dev);
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
-       DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
+       unsigned long dwKeyIndex = (unsigned long)(wrq->flags & IW_ENCODE_INDEX);
        int ii,uu, rc = 0;
        int index = (wrq->flags & IW_ENCODE_INDEX);
 
@@ -1358,7 +1358,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
             spin_lock_irq(&pDevice->lock);
             KeybSetDefaultKey(&(pDevice->sKey),
-                            (DWORD)(dwKeyIndex | (1 << 31)),
+                            (unsigned long)(dwKeyIndex | (1 << 31)),
                                wrq->length,
                             NULL,
                             pDevice->abyKey,
@@ -1368,38 +1368,38 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
                           );
             spin_unlock_irq(&pDevice->lock);
         }
-        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+        pDevice->byKeyIndex = (unsigned char)dwKeyIndex;
         pDevice->uKeyLength = wrq->length;
-        pDevice->bTransmitKey = TRUE;
-        pDevice->bEncryptionEnable = TRUE;
+        pDevice->bTransmitKey = true;
+        pDevice->bEncryptionEnable = true;
         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
 
                }else if(index>0){
        //when the length is 0 the request only changes the default transmit key index
        //check the new key has a non zero lenget
-       if(pDevice->bEncryptionEnable==FALSE)
+       if(pDevice->bEncryptionEnable==false)
        {
                rc = -EINVAL;
                return rc;
        }
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n");
        pkeytab=&(pDevice->sKey.KeyTable[MAX_KEY_TABLE-1]);
-       if(pkeytab->GroupKey[(BYTE)dwKeyIndex].uKeyLength==0){
+       if(pkeytab->GroupKey[(unsigned char)dwKeyIndex].uKeyLength==0){
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n");
                rc = -EINVAL;
                return rc;
                }
-        pDevice->byKeyIndex =(BYTE)dwKeyIndex;
+        pDevice->byKeyIndex =(unsigned char)dwKeyIndex;
         pkeytab->dwGTKeyIndex =dwKeyIndex | (1 << 31);
-        pkeytab->GroupKey[(BYTE)dwKeyIndex].dwKeyIndex=dwKeyIndex | (1 << 31);
+        pkeytab->GroupKey[(unsigned char)dwKeyIndex].dwKeyIndex=dwKeyIndex | (1 << 31);
        }
 
 }else {//disable the key
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
-       if(pDevice->bEncryptionEnable==FALSE)
+       if(pDevice->bEncryptionEnable==false)
                return 0;
-       pMgmt->bShareKeyAlgorithm = FALSE;
-        pDevice->bEncryptionEnable = FALSE;
+       pMgmt->bShareKeyAlgorithm = false;
+        pDevice->bEncryptionEnable = false;
         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
             spin_lock_irq(&pDevice->lock);
@@ -1450,7 +1450,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
             spin_lock_irq(&pDevice->lock);
             KeybSetDefaultKey(&(pDevice->sKey),
-                            (DWORD)(pDevice->byKeyIndex | (1 << 31)),
+                            (unsigned long)(pDevice->byKeyIndex | (1 << 31)),
                             pDevice->uKeyLength,
                             NULL,
                             pDevice->abyKey,
@@ -1460,10 +1460,10 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
                           );
             spin_unlock_irq(&pDevice->lock);
         }
-        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+        pDevice->byKeyIndex = (unsigned char)dwKeyIndex;
         pDevice->uKeyLength = wrq->length;
-        pDevice->bTransmitKey = TRUE;
-        pDevice->bEncryptionEnable = TRUE;
+        pDevice->bTransmitKey = true;
+        pDevice->bEncryptionEnable = true;
         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
 
                // Do we want to just set the transmit key index ?
@@ -1479,8 +1479,8 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
        if(wrq->flags & IW_ENCODE_DISABLED){
 
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
-               pMgmt->bShareKeyAlgorithm = FALSE;
-        pDevice->bEncryptionEnable = FALSE;
+               pMgmt->bShareKeyAlgorithm = false;
+        pDevice->bEncryptionEnable = false;
         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
             spin_lock_irq(&pDevice->lock);
@@ -1493,11 +1493,11 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 
        if(wrq->flags & IW_ENCODE_RESTRICTED) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
-               pMgmt->bShareKeyAlgorithm = TRUE;
+               pMgmt->bShareKeyAlgorithm = true;
        }
        if(wrq->flags & IW_ENCODE_OPEN) {
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
-               pMgmt->bShareKeyAlgorithm = FALSE;
+               pMgmt->bShareKeyAlgorithm = false;
        }
        return rc;
 }
@@ -1515,7 +1515,7 @@ int iwctl_giwencode(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
     int rc = 0;
     char abyKey[WLAN_WEP232_KEYLEN];
-       UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
+       unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
        PSKeyItem   pKey = NULL;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
@@ -1549,7 +1549,7 @@ int iwctl_giwencode(struct net_device *dev,
        else
                wrq->flags |=  IW_ENCODE_OPEN;
 
-       if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
+       if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)){
         wrq->length = pKey->uKeyLength;
         memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
 //2007-0207-06,<Modify> by EinsnLiu
@@ -1584,7 +1584,7 @@ int iwctl_giwencode(struct net_device *dev,
        PSMgmtObject            pMgmt = &(pDevice->sMgmtObj);
        char abyKey[WLAN_WEP232_KEYLEN];
 
-       UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
+       unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
        PSKeyItem       pKey = NULL;
 
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
@@ -1622,7 +1622,7 @@ int iwctl_giwencode(struct net_device *dev,
                                  memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
                                  memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
                           }
-       }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
+       }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)){
                        wrq->length = pKey->uKeyLength;
                        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
                memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
@@ -1729,8 +1729,8 @@ int iwctl_giwsens(struct net_device *dev,
     long ldBm;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
-    if (pDevice->bLinkPass == TRUE) {
-        RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+    if (pDevice->bLinkPass == true) {
+        RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm);
            wrq->value = ldBm;
        }
        else {
@@ -1763,7 +1763,7 @@ int iwctl_siwauth(struct net_device *dev,
                wpa_version = wrq->value;
                if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
                       PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
-                       //pDevice->bWPADevEnable = FALSE;
+                       //pDevice->bWPADevEnable = false;
                }
                else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
                           PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
@@ -1771,7 +1771,7 @@ int iwctl_siwauth(struct net_device *dev,
                else {
                           PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
                }
-               //pDevice->bWPASuppWextEnabled =TRUE;
+               //pDevice->bWPASuppWextEnabled =true;
                break;
        case IW_AUTH_CIPHER_PAIRWISE:
                pairwise = wrq->value;
@@ -1818,9 +1818,9 @@ int iwctl_siwauth(struct net_device *dev,
                break;
        case IW_AUTH_80211_AUTH_ALG:
                if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
-                       pMgmt->bShareKeyAlgorithm=FALSE;
+                       pMgmt->bShareKeyAlgorithm=false;
                }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
-                       pMgmt->bShareKeyAlgorithm=TRUE;
+                       pMgmt->bShareKeyAlgorithm=true;
                }
                break;
        case IW_AUTH_WPA_ENABLED:
@@ -1833,13 +1833,13 @@ int iwctl_siwauth(struct net_device *dev,
                break;
        case IW_AUTH_PRIVACY_INVOKED:
                pDevice->bEncryptionEnable = !!wrq->value;
-               if(pDevice->bEncryptionEnable == FALSE){
+               if(pDevice->bEncryptionEnable == false){
                        wpa_version = 0;
                        pairwise = 0;
                        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-                       pMgmt->bShareKeyAlgorithm = FALSE;
-                       pMgmt->eAuthenMode = FALSE;
-                       //pDevice->bWPADevEnable = FALSE;
+                       pMgmt->bShareKeyAlgorithm = false;
+                       pMgmt->eAuthenMode = false;
+                       //pDevice->bWPADevEnable = false;
                }
 
                break;
@@ -1852,9 +1852,9 @@ int iwctl_siwauth(struct net_device *dev,
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
-       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
-       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
-       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"TRUE":"FALSE");
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"true":"false");
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"true":"false");
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"true":"false");
 */
    return ret;
 }
@@ -2055,12 +2055,12 @@ if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
 if( pDevice->bwextcount == 4) {
     printk("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
  pDevice->bwextcount=0;
-   pDevice->bWPASuppWextEnabled = TRUE;
+   pDevice->bWPASuppWextEnabled = true;
                 }
 //******
 
                spin_lock_irq(&pDevice->lock);
- ret = wpa_set_keys(pDevice, param, TRUE);
+ ret = wpa_set_keys(pDevice, param, true);
                spin_unlock_irq(&pDevice->lock);
 
 error:
@@ -2096,10 +2096,10 @@ int iwctl_siwmlme(struct net_device *dev,
        switch(mlme->cmd){
        case IW_MLME_DEAUTH:
                //this command seems to be not complete,please test it --einsnliu
-               //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason);
+               //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason);
                break;
        case IW_MLME_DISASSOC:
-               if(pDevice->bLinkPass == TRUE){
+               if(pDevice->bLinkPass == true){
                                          printk("iwctl_siwmlme--->send DISASSOCIATE\n");
                  //clear related flags
                   memset(pMgmt->abyDesireBSSID, 0xFF,6);
index bfc5c509d902360f58f12f0c24d74b01ce43dac5..0ff8d7bbf2a7879af4536dfe37d2708c6890f525 100644 (file)
@@ -59,22 +59,22 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 /*---------------------  Static Functions  --------------------------*/
 static void
-s_vCheckKeyTableValid (PSKeyManagement pTable, DWORD_PTR dwIoBase)
+s_vCheckKeyTableValid (PSKeyManagement pTable, unsigned long dwIoBase)
 {
     int i;
 
     for (i=0;i<MAX_KEY_TABLE;i++) {
-        if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            (pTable->KeyTable[i].PairwiseKey.bKeyValid == FALSE) &&
-            (pTable->KeyTable[i].GroupKey[0].bKeyValid == FALSE) &&
-            (pTable->KeyTable[i].GroupKey[1].bKeyValid == FALSE) &&
-            (pTable->KeyTable[i].GroupKey[2].bKeyValid == FALSE) &&
-            (pTable->KeyTable[i].GroupKey[3].bKeyValid == FALSE)
+        if ((pTable->KeyTable[i].bInUse == true) &&
+            (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) &&
+            (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) &&
+            (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) &&
+            (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) &&
+            (pTable->KeyTable[i].GroupKey[3].bKeyValid == false)
             ) {
 
-            pTable->KeyTable[i].bInUse = FALSE;
+            pTable->KeyTable[i].bInUse = false;
             pTable->KeyTable[i].wKeyCtl = 0;
-            pTable->KeyTable[i].bSoftWEP = FALSE;
+            pTable->KeyTable[i].bSoftWEP = false;
             MACvDisableKeyEntry(dwIoBase, i);
         }
     }
@@ -96,22 +96,22 @@ s_vCheckKeyTableValid (PSKeyManagement pTable, DWORD_PTR dwIoBase)
  * Return Value: none
  *
  */
-void KeyvInitTable (PSKeyManagement pTable, DWORD_PTR dwIoBase)
+void KeyvInitTable (PSKeyManagement pTable, unsigned long dwIoBase)
 {
     int i;
     int jj;
 
     for (i=0;i<MAX_KEY_TABLE;i++) {
-        pTable->KeyTable[i].bInUse = FALSE;
-        pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+        pTable->KeyTable[i].bInUse = false;
+        pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
         pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i];
         for (jj=0; jj < MAX_GROUP_KEY; jj++) {
-            pTable->KeyTable[i].GroupKey[jj].bKeyValid = FALSE;
+            pTable->KeyTable[i].GroupKey[jj].bKeyValid = false;
             pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i];
         }
         pTable->KeyTable[i].wKeyCtl = 0;
         pTable->KeyTable[i].dwGTKeyIndex = 0;
-        pTable->KeyTable[i].bSoftWEP = FALSE;
+        pTable->KeyTable[i].bSoftWEP = false;
         MACvDisableKeyEntry(dwIoBase, i);
     }
 }
@@ -128,13 +128,13 @@ void KeyvInitTable (PSKeyManagement pTable, DWORD_PTR dwIoBase)
  *  Out:
  *      pKey            - Key return
  *
- * Return Value: TRUE if found otherwise FALSE
+ * Return Value: true if found otherwise false
  *
  */
-BOOL KeybGetKey (
+bool KeybGetKey (
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyIndex,
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyIndex,
     PSKeyItem       *pKey
     )
 {
@@ -144,31 +144,31 @@ BOOL KeybGetKey (
 
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
-        if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+        if ((pTable->KeyTable[i].bInUse == true) &&
+            !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             if (dwKeyIndex == 0xFFFFFFFF) {
-                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
+                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
-                    return (TRUE);
+                    return (true);
                 }
                 else {
-                    return (FALSE);
+                    return (false);
                 }
             } else if (dwKeyIndex < MAX_GROUP_KEY) {
-                if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == TRUE) {
+                if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) {
                     *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
-                    return (TRUE);
+                    return (true);
                 }
                 else {
-                    return (FALSE);
+                    return (false);
                 }
             }
             else {
-                return (FALSE);
+                return (false);
             }
         }
     }
-    return (FALSE);
+    return (false);
 }
 
 
@@ -186,37 +186,37 @@ BOOL KeybGetKey (
  *  Out:
  *      none
  *
- * Return Value: TRUE if success otherwise FALSE
+ * Return Value: true if success otherwise false
  *
  */
-BOOL KeybSetKey (
+bool KeybSetKey (
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyIndex,
-    ULONG           uKeyLength,
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyIndex,
+    unsigned long uKeyLength,
     PQWORD          pKeyRSC,
-    PBYTE           pbyKey,
-    BYTE            byKeyDecMode,
-    DWORD_PTR       dwIoBase,
-    BYTE            byLocalID
+    unsigned char *pbyKey,
+    unsigned char byKeyDecMode,
+    unsigned long dwIoBase,
+    unsigned char byLocalID
     )
 {
     int         i,j;
-    UINT        ii;
+    unsigned int ii;
     PSKeyItem   pKey;
-    UINT        uKeyIdx;
+    unsigned int uKeyIdx;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
 
     j = (MAX_KEY_TABLE-1);
     for (i=0;i<(MAX_KEY_TABLE-1);i++) {
-        if ((pTable->KeyTable[i].bInUse == FALSE) &&
+        if ((pTable->KeyTable[i].bInUse == false) &&
             (j == (MAX_KEY_TABLE-1))) {
             // found empty table
             j = i;
         }
-        if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+        if ((pTable->KeyTable[i].bInUse == true) &&
+            !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             // found table already exist
             if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                 // Pairwise key
@@ -227,7 +227,7 @@ BOOL KeybSetKey (
             } else {
                 // Group key
                 if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
-                    return (FALSE);
+                    return (false);
                 pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
                 if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
                     // Group transmit key
@@ -241,7 +241,7 @@ BOOL KeybSetKey (
             }
             pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
 
-            pKey->bKeyValid = TRUE;
+            pKey->bKeyValid = true;
             pKey->uKeyLength = uKeyLength;
             pKey->dwKeyIndex = dwKeyIndex;
             pKey->byCipherSuite = byKeyDecMode;
@@ -252,7 +252,7 @@ BOOL KeybSetKey (
                 if (uKeyLength == WLAN_WEP104_KEYLEN)
                     pKey->abyKey[15] |= 0x80;
             }
-            MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+            MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
 
             if ((dwKeyIndex & USE_KEYRSC) == 0) {
                 // RSC set by NIC
@@ -277,12 +277,12 @@ BOOL KeybSetKey (
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
 
-            return (TRUE);
+            return (true);
         }
     }
     if (j < (MAX_KEY_TABLE-1)) {
         memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,ETH_ALEN);
-        pTable->KeyTable[j].bInUse = TRUE;
+        pTable->KeyTable[j].bInUse = true;
         if ((dwKeyIndex & PAIRWISE_KEY) != 0)  {
             // Pairwise key
             pKey = &(pTable->KeyTable[j].PairwiseKey);
@@ -292,7 +292,7 @@ BOOL KeybSetKey (
         } else {
             // Group key
             if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
-                return (FALSE);
+                return (false);
             pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
             if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
                 // Group transmit key
@@ -306,7 +306,7 @@ BOOL KeybSetKey (
         }
         pTable->KeyTable[j].wKeyCtl |= 0x8000;              // enable on-fly
 
-        pKey->bKeyValid = TRUE;
+        pKey->bKeyValid = true;
         pKey->uKeyLength = uKeyLength;
         pKey->dwKeyIndex = dwKeyIndex;
         pKey->byCipherSuite = byKeyDecMode;
@@ -317,7 +317,7 @@ BOOL KeybSetKey (
             if (uKeyLength == WLAN_WEP104_KEYLEN)
                 pKey->abyKey[15] |= 0x80;
         }
-        MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+        MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
 
         if ((dwKeyIndex & USE_KEYRSC) == 0) {
             // RSC set by NIC
@@ -342,9 +342,9 @@ BOOL KeybSetKey (
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
 
-        return (TRUE);
+        return (true);
     }
-    return (FALSE);
+    return (false);
 }
 
 
@@ -359,66 +359,66 @@ BOOL KeybSetKey (
  *  Out:
  *      none
  *
- * Return Value: TRUE if success otherwise FALSE
+ * Return Value: true if success otherwise false
  *
  */
-BOOL KeybRemoveKey (
+bool KeybRemoveKey (
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyIndex,
-    DWORD_PTR       dwIoBase
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyIndex,
+    unsigned long dwIoBase
     )
 {
     int  i;
 
-    if (IS_BROADCAST_ADDRESS(pbyBSSID)) {
+    if (is_broadcast_ether_addr(pbyBSSID)) {
         // dealte all key
         if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
             for (i=0;i<MAX_KEY_TABLE;i++) {
-                pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+                pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
             }
             s_vCheckKeyTableValid(pTable, dwIoBase);
-            return TRUE;
+            return true;
         }
         else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
             for (i=0;i<MAX_KEY_TABLE;i++) {
-                pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
                 if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
                     // remove Group transmit key
                     pTable->KeyTable[i].dwGTKeyIndex = 0;
                 }
             }
             s_vCheckKeyTableValid(pTable, dwIoBase);
-            return TRUE;
+            return true;
         }
         else {
-            return FALSE;
+            return false;
         }
     }
 
     for (i=0;i<MAX_KEY_TABLE;i++) {
-        if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+        if ((pTable->KeyTable[i].bInUse == true) &&
+            !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
-                pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+                pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
                 s_vCheckKeyTableValid(pTable, dwIoBase);
-                return (TRUE);
+                return (true);
             }
             else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
-                pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
                 if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
                     // remove Group transmit key
                     pTable->KeyTable[i].dwGTKeyIndex = 0;
                 }
                 s_vCheckKeyTableValid(pTable, dwIoBase);
-                return (TRUE);
+                return (true);
             }
             else {
-                return (FALSE);
+                return (false);
             }
         }
     }
-    return (FALSE);
+    return (false);
 }
 
 
@@ -432,30 +432,30 @@ BOOL KeybRemoveKey (
  *  Out:
  *      none
  *
- * Return Value: TRUE if success otherwise FALSE
+ * Return Value: true if success otherwise false
  *
  */
-BOOL KeybRemoveAllKey (
+bool KeybRemoveAllKey (
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD_PTR       dwIoBase
+    unsigned char *pbyBSSID,
+    unsigned long dwIoBase
     )
 {
     int  i,u;
 
     for (i=0;i<MAX_KEY_TABLE;i++) {
-        if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
-            pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+        if ((pTable->KeyTable[i].bInUse == true) &&
+            !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+            pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
             for(u=0;u<MAX_GROUP_KEY;u++) {
-                pTable->KeyTable[i].GroupKey[u].bKeyValid = FALSE;
+                pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
             }
             pTable->KeyTable[i].dwGTKeyIndex = 0;
             s_vCheckKeyTableValid(pTable, dwIoBase);
-            return (TRUE);
+            return (true);
         }
     }
-    return (FALSE);
+    return (false);
 }
 
 /*
@@ -467,20 +467,20 @@ BOOL KeybRemoveAllKey (
  *  Out:
  *      none
  *
- * Return Value: TRUE if success otherwise FALSE
+ * Return Value: true if success otherwise false
  *
  */
 void KeyvRemoveWEPKey (
     PSKeyManagement pTable,
-    DWORD           dwKeyIndex,
-    DWORD_PTR       dwIoBase
+    unsigned long dwKeyIndex,
+    unsigned long dwIoBase
     )
 {
 
    if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
-        if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == TRUE) {
+        if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == true) {
             if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) {
-                pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
                 if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) {
                     // remove Group transmit key
                     pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0;
@@ -494,7 +494,7 @@ void KeyvRemoveWEPKey (
 
 void KeyvRemoveAllWEPKey (
     PSKeyManagement pTable,
-    DWORD_PTR       dwIoBase
+    unsigned long dwIoBase
     )
 {
     int i;
@@ -514,13 +514,13 @@ void KeyvRemoveAllWEPKey (
  *  Out:
  *      pKey            - Key return
  *
- * Return Value: TRUE if found otherwise FALSE
+ * Return Value: true if found otherwise false
  *
  */
-BOOL KeybGetTransmitKey (
+bool KeybGetTransmitKey (
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyType,
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyType,
     PSKeyItem       *pKey
     )
 {
@@ -528,12 +528,12 @@ BOOL KeybGetTransmitKey (
 
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
-        if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+        if ((pTable->KeyTable[i].bInUse == true) &&
+            !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
 
             if (dwKeyType == PAIRWISE_KEY) {
 
-                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
+                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
 
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
@@ -544,19 +544,19 @@ BOOL KeybGetTransmitKey (
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 
 
-                    return (TRUE);
+                    return (true);
                 }
                 else {
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == FALSE\n");
-                    return (FALSE);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == false\n");
+                    return (false);
                 }
             } // End of Type == PAIRWISE
             else {
                 if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
-                    return FALSE;
+                    return false;
                 }
-                if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == TRUE) {
+                if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) {
                     *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
 
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
@@ -567,11 +567,11 @@ BOOL KeybGetTransmitKey (
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
 
-                    return (TRUE);
+                    return (true);
                 }
                 else {
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == FALSE\n");
-                    return (FALSE);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == false\n");
+                    return (false);
                 }
             } // End of Type = GROUP
         } // BSSID match
@@ -581,7 +581,7 @@ BOOL KeybGetTransmitKey (
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
     }
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
-    return (FALSE);
+    return (false);
 }
 
 
@@ -594,10 +594,10 @@ BOOL KeybGetTransmitKey (
  *  Out:
  *      none
  *
- * Return Value: TRUE if found otherwise FALSE
+ * Return Value: true if found otherwise false
  *
  */
-BOOL KeybCheckPairewiseKey (
+bool KeybCheckPairewiseKey (
     PSKeyManagement pTable,
     PSKeyItem       *pKey
     )
@@ -606,13 +606,13 @@ BOOL KeybCheckPairewiseKey (
 
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
-        if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE)) {
+        if ((pTable->KeyTable[i].bInUse == true) &&
+            (pTable->KeyTable[i].PairwiseKey.bKeyValid == true)) {
             *pKey = &(pTable->KeyTable[i].PairwiseKey);
-            return (TRUE);
+            return (true);
         }
     }
-    return (FALSE);
+    return (false);
 }
 
 /*
@@ -628,34 +628,34 @@ BOOL KeybCheckPairewiseKey (
  *  Out:
  *      none
  *
- * Return Value: TRUE if success otherwise FALSE
+ * Return Value: true if success otherwise false
  *
  */
-BOOL KeybSetDefaultKey (
+bool KeybSetDefaultKey (
     PSKeyManagement pTable,
-    DWORD           dwKeyIndex,
-    ULONG           uKeyLength,
+    unsigned long dwKeyIndex,
+    unsigned long uKeyLength,
     PQWORD          pKeyRSC,
-    PBYTE           pbyKey,
-    BYTE            byKeyDecMode,
-    DWORD_PTR       dwIoBase,
-    BYTE            byLocalID
+    unsigned char *pbyKey,
+    unsigned char byKeyDecMode,
+    unsigned long dwIoBase,
+    unsigned char byLocalID
     )
 {
-    UINT        ii;
+    unsigned int ii;
     PSKeyItem   pKey;
-    UINT        uKeyIdx;
+    unsigned int uKeyIdx;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
 
 
     if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
-        return (FALSE);
+        return (false);
     } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
-        return (FALSE);
+        return (false);
     }
 
-    pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE;
+    pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true;
     for(ii=0;ii<ETH_ALEN;ii++)
         pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
 
@@ -676,13 +676,13 @@ BOOL KeybSetDefaultKey (
     if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
         (byKeyDecMode == KEY_CTL_WEP)) {
         pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000;              // disable on-fly disable address match
-        pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = TRUE;
+        pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true;
     } else {
-        if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == FALSE)
+        if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false)
             pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000;          // enable on-fly disable address match
     }
 
-    pKey->bKeyValid = TRUE;
+    pKey->bKeyValid = true;
     pKey->uKeyLength = uKeyLength;
     pKey->dwKeyIndex = dwKeyIndex;
     pKey->byCipherSuite = byKeyDecMode;
@@ -693,7 +693,7 @@ BOOL KeybSetDefaultKey (
         if (uKeyLength == WLAN_WEP104_KEYLEN)
             pKey->abyKey[15] |= 0x80;
     }
-    MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+    MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
 
     if ((dwKeyIndex & USE_KEYRSC) == 0) {
         // RSC set by NIC
@@ -718,7 +718,7 @@ BOOL KeybSetDefaultKey (
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
 
-    return (TRUE);
+    return (true);
 }
 
 
@@ -735,36 +735,36 @@ BOOL KeybSetDefaultKey (
  *  Out:
  *      none
  *
- * Return Value: TRUE if success otherwise FALSE
+ * Return Value: true if success otherwise false
  *
  */
-BOOL KeybSetAllGroupKey (
+bool KeybSetAllGroupKey (
     PSKeyManagement pTable,
-    DWORD           dwKeyIndex,
-    ULONG           uKeyLength,
+    unsigned long dwKeyIndex,
+    unsigned long uKeyLength,
     PQWORD          pKeyRSC,
-    PBYTE           pbyKey,
-    BYTE            byKeyDecMode,
-    DWORD_PTR       dwIoBase,
-    BYTE            byLocalID
+    unsigned char *pbyKey,
+    unsigned char byKeyDecMode,
+    unsigned long dwIoBase,
+    unsigned char byLocalID
     )
 {
     int         i;
-    UINT        ii;
+    unsigned int ii;
     PSKeyItem   pKey;
-    UINT        uKeyIdx;
+    unsigned int uKeyIdx;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
 
 
     if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
-        return (FALSE);
+        return (false);
     } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
-        return (FALSE);
+        return (false);
     }
 
     for (i=0; i < MAX_KEY_TABLE-1; i++) {
-        if (pTable->KeyTable[i].bInUse == TRUE) {
+        if (pTable->KeyTable[i].bInUse == true) {
             // found table already exist
             // Group key
             pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
@@ -781,7 +781,7 @@ BOOL KeybSetAllGroupKey (
 
             pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
 
-            pKey->bKeyValid = TRUE;
+            pKey->bKeyValid = true;
             pKey->uKeyLength = uKeyLength;
             pKey->dwKeyIndex = dwKeyIndex;
             pKey->byCipherSuite = byKeyDecMode;
@@ -792,7 +792,7 @@ BOOL KeybSetAllGroupKey (
                 if (uKeyLength == WLAN_WEP104_KEYLEN)
                     pKey->abyKey[15] |= 0x80;
             }
-            MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+            MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
 
             if ((dwKeyIndex & USE_KEYRSC) == 0) {
                 // RSC set by NIC
@@ -817,7 +817,7 @@ BOOL KeybSetAllGroupKey (
             //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
             //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
 
-        } // (pTable->KeyTable[i].bInUse == TRUE)
+        } // (pTable->KeyTable[i].bInUse == true)
     }
-    return (TRUE);
+    return (true);
 }
index 39403d93aeb1604e7127ef3fc090fd988259e6be..6b2dad331a5bc7a3f1e5ad7f0371c383a8e23a3a 100644 (file)
 
 typedef struct tagSKeyItem
 {
-    BOOL        bKeyValid;
-    ULONG       uKeyLength;
-    BYTE        abyKey[MAX_KEY_LEN];
+    bool bKeyValid;
+    unsigned long uKeyLength;
+    unsigned char abyKey[MAX_KEY_LEN];
     QWORD       KeyRSC;
-    DWORD       dwTSC47_16;
-    WORD        wTSC15_0;
-    BYTE        byCipherSuite;
-    BYTE        byReserved0;
-    DWORD       dwKeyIndex;
+    unsigned long dwTSC47_16;
+    unsigned short wTSC15_0;
+    unsigned char byCipherSuite;
+    unsigned char byReserved0;
+    unsigned long dwKeyIndex;
     void *pvKeyTable;
 } SKeyItem, *PSKeyItem; //64
 
 typedef struct tagSKeyTable
 {
-    BYTE        abyBSSID[ETH_ALEN];  //6
-    BYTE        byReserved0[2];              //8
+    unsigned char abyBSSID[ETH_ALEN];  //6
+    unsigned char byReserved0[2];              //8
     SKeyItem    PairwiseKey;
     SKeyItem    GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328
-    DWORD       dwGTKeyIndex;            // GroupTransmitKey Index
-    BOOL        bInUse;
+    unsigned long dwGTKeyIndex;            // GroupTransmitKey Index
+    bool bInUse;
     //2006-1116-01,<Modify> by NomadZhao
-    //WORD      wKeyCtl;
-    //BOOL      bSoftWEP;
-    BOOL        bSoftWEP;
-    WORD        wKeyCtl;      // for address of wKeyCtl at align 4
+    //unsigned short wKeyCtl;
+    //bool bSoftWEP;
+    bool bSoftWEP;
+    unsigned short wKeyCtl;      // for address of wKeyCtl at align 4
 
-    BYTE        byReserved1[6];
+    unsigned char byReserved1[6];
 } SKeyTable, *PSKeyTable; //348
 
 typedef struct tagSKeyManagement
@@ -101,83 +101,83 @@ typedef struct tagSKeyManagement
 
 /*---------------------  Export Functions  --------------------------*/
 
-void KeyvInitTable(PSKeyManagement pTable, DWORD_PTR dwIoBase);
+void KeyvInitTable(PSKeyManagement pTable, unsigned long dwIoBase);
 
-BOOL KeybGetKey(
+bool KeybGetKey(
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyIndex,
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyIndex,
     PSKeyItem       *pKey
     );
 
-BOOL KeybSetKey(
+bool KeybSetKey(
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyIndex,
-    ULONG           uKeyLength,
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyIndex,
+    unsigned long uKeyLength,
     PQWORD          pKeyRSC,
-    PBYTE           pbyKey,
-    BYTE            byKeyDecMode,
-    DWORD_PTR       dwIoBase,
-    BYTE            byLocalID
+    unsigned char *pbyKey,
+    unsigned char byKeyDecMode,
+    unsigned long dwIoBase,
+    unsigned char byLocalID
     );
 
-BOOL KeybSetDefaultKey(
+bool KeybSetDefaultKey(
     PSKeyManagement pTable,
-    DWORD           dwKeyIndex,
-    ULONG           uKeyLength,
+    unsigned long dwKeyIndex,
+    unsigned long uKeyLength,
     PQWORD          pKeyRSC,
-    PBYTE           pbyKey,
-    BYTE            byKeyDecMode,
-    DWORD_PTR       dwIoBase,
-    BYTE            byLocalID
+    unsigned char *pbyKey,
+    unsigned char byKeyDecMode,
+    unsigned long dwIoBase,
+    unsigned char byLocalID
     );
 
-BOOL KeybRemoveKey(
+bool KeybRemoveKey(
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyIndex,
-    DWORD_PTR       dwIoBase
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyIndex,
+    unsigned long dwIoBase
     );
 
-BOOL KeybGetTransmitKey(
+bool KeybGetTransmitKey(
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD           dwKeyType,
+    unsigned char *pbyBSSID,
+    unsigned long dwKeyType,
     PSKeyItem       *pKey
     );
 
-BOOL KeybCheckPairewiseKey(
+bool KeybCheckPairewiseKey(
     PSKeyManagement pTable,
     PSKeyItem       *pKey
     );
 
-BOOL KeybRemoveAllKey(
+bool KeybRemoveAllKey(
     PSKeyManagement pTable,
-    PBYTE           pbyBSSID,
-    DWORD_PTR       dwIoBase
+    unsigned char *pbyBSSID,
+    unsigned long dwIoBase
     );
 
 void KeyvRemoveWEPKey(
     PSKeyManagement pTable,
-    DWORD           dwKeyIndex,
-    DWORD_PTR       dwIoBase
+    unsigned long dwKeyIndex,
+    unsigned long dwIoBase
     );
 
 void KeyvRemoveAllWEPKey(
     PSKeyManagement pTable,
-    DWORD_PTR       dwIoBase
+    unsigned long dwIoBase
     );
 
-BOOL KeybSetAllGroupKey (
+bool KeybSetAllGroupKey (
     PSKeyManagement pTable,
-    DWORD           dwKeyIndex,
-    ULONG           uKeyLength,
+    unsigned long dwKeyIndex,
+    unsigned long uKeyLength,
     PQWORD          pKeyRSC,
-    PBYTE           pbyKey,
-    BYTE            byKeyDecMode,
-    DWORD_PTR       dwIoBase,
-    BYTE            byLocalID
+    unsigned char *pbyKey,
+    unsigned char byKeyDecMode,
+    unsigned long dwIoBase,
+    unsigned char byLocalID
     );
 
 #endif // __KEY_H__
index f1ef7da75c2bdb011806a239bf7f9bccfdf5bcc2..f8d1651341f853c5fe53a10112f7a2d08cf47b25 100644 (file)
@@ -72,7 +72,7 @@
 #include "tether.h"
 #include "mac.h"
 
-WORD TxRate_iwconfig;//2008-5-8 <add> by chester
+unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester
 /*---------------------  Static Definitions -------------------------*/
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 static int          msglevel                =MSG_LEVEL_INFO;
@@ -103,7 +103,7 @@ static int          msglevel                =MSG_LEVEL_INFO;
  * Return Value: none
  *
  */
-void MACvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyMacRegs)
+void MACvReadAllRegs (unsigned long dwIoBase, unsigned char *pbyMacRegs)
 {
     int ii;
 
@@ -137,12 +137,12 @@ void MACvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyMacRegs)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all test bits On; otherwise FALSE
+ * Return Value: true if all test bits On; otherwise false
  *
  */
-BOOL MACbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
+bool MACbIsRegBitsOn (unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
 {
-    BYTE byData;
+    unsigned char byData;
 
     VNSvInPortB(dwIoBase + byRegOfs, &byData);
     return (byData & byTestBits) == byTestBits;
@@ -160,12 +160,12 @@ BOOL MACbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all test bits Off; otherwise FALSE
+ * Return Value: true if all test bits Off; otherwise false
  *
  */
-BOOL MACbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
+bool MACbIsRegBitsOff (unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
 {
-    BYTE byData;
+    unsigned char byData;
 
     VNSvInPortB(dwIoBase + byRegOfs, &byData);
     return !(byData & byTestBits);
@@ -181,18 +181,18 @@ BOOL MACbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
  *  Out:
  *      none
  *
- * Return Value: TRUE if interrupt is disable; otherwise FALSE
+ * Return Value: true if interrupt is disable; otherwise false
  *
  */
-BOOL MACbIsIntDisable (DWORD_PTR dwIoBase)
+bool MACbIsIntDisable (unsigned long dwIoBase)
 {
-    DWORD dwData;
+    unsigned long dwData;
 
     VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData);
     if (dwData != 0)
-        return FALSE;
+        return false;
 
-    return TRUE;
+    return true;
 }
 
 /*
@@ -209,9 +209,9 @@ BOOL MACbIsIntDisable (DWORD_PTR dwIoBase)
  * Return Value: Mask Value read
  *
  */
-BYTE MACbyReadMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx)
+unsigned char MACbyReadMultiAddr (unsigned long dwIoBase, unsigned int uByteIdx)
 {
-    BYTE byData;
+    unsigned char byData;
 
     MACvSelectPage1(dwIoBase);
     VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData);
@@ -234,7 +234,7 @@ BYTE MACbyReadMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx)
  * Return Value: none
  *
  */
-void MACvWriteMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData)
+void MACvWriteMultiAddr (unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData)
 {
     MACvSelectPage1(dwIoBase);
     VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData);
@@ -255,11 +255,11 @@ void MACvWriteMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData)
  * Return Value: none
  *
  */
-void MACvSetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
+void MACvSetMultiAddrByHash (unsigned long dwIoBase, unsigned char byHashIdx)
 {
-    UINT uByteIdx;
-    BYTE byBitMask;
-    BYTE byOrgValue;
+    unsigned int uByteIdx;
+    unsigned char byBitMask;
+    unsigned char byOrgValue;
 
     // calculate byte position
     uByteIdx = byHashIdx / 8;
@@ -269,7 +269,7 @@ void MACvSetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
     byBitMask <<= (byHashIdx % 8);
     // turn on the bit
     byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
-    MACvWriteMultiAddr(dwIoBase, uByteIdx, (BYTE)(byOrgValue | byBitMask));
+    MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue | byBitMask));
 }
 
 /*
@@ -286,11 +286,11 @@ void MACvSetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
  * Return Value: none
  *
  */
-void MACvResetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
+void MACvResetMultiAddrByHash (unsigned long dwIoBase, unsigned char byHashIdx)
 {
-    UINT uByteIdx;
-    BYTE byBitMask;
-    BYTE byOrgValue;
+    unsigned int uByteIdx;
+    unsigned char byBitMask;
+    unsigned char byOrgValue;
 
     // calculate byte position
     uByteIdx = byHashIdx / 8;
@@ -300,7 +300,7 @@ void MACvResetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
     byBitMask <<= (byHashIdx % 8);
     // turn off the bit
     byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
-    MACvWriteMultiAddr(dwIoBase, uByteIdx, (BYTE)(byOrgValue & (~byBitMask)));
+    MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue & (~byBitMask)));
 }
 
 /*
@@ -317,9 +317,9 @@ void MACvResetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
  * Return Value: none
  *
  */
-void MACvSetRxThreshold (DWORD_PTR dwIoBase, BYTE byThreshold)
+void MACvSetRxThreshold (unsigned long dwIoBase, unsigned char byThreshold)
 {
-    BYTE byOrgValue;
+    unsigned char byOrgValue;
 
     ASSERT(byThreshold < 4);
 
@@ -342,7 +342,7 @@ void MACvSetRxThreshold (DWORD_PTR dwIoBase, BYTE byThreshold)
  * Return Value: none
  *
  */
-void MACvGetRxThreshold (DWORD_PTR dwIoBase, PBYTE pbyThreshold)
+void MACvGetRxThreshold (unsigned long dwIoBase, unsigned char *pbyThreshold)
 {
     // get FCR0
     VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
@@ -363,9 +363,9 @@ void MACvGetRxThreshold (DWORD_PTR dwIoBase, PBYTE pbyThreshold)
  * Return Value: none
  *
  */
-void MACvSetTxThreshold (DWORD_PTR dwIoBase, BYTE byThreshold)
+void MACvSetTxThreshold (unsigned long dwIoBase, unsigned char byThreshold)
 {
-    BYTE byOrgValue;
+    unsigned char byOrgValue;
 
     ASSERT(byThreshold < 4);
 
@@ -388,7 +388,7 @@ void MACvSetTxThreshold (DWORD_PTR dwIoBase, BYTE byThreshold)
  * Return Value: none
  *
  */
-void MACvGetTxThreshold (DWORD_PTR dwIoBase, PBYTE pbyThreshold)
+void MACvGetTxThreshold (unsigned long dwIoBase, unsigned char *pbyThreshold)
 {
     // get FCR0
     VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
@@ -409,9 +409,9 @@ void MACvGetTxThreshold (DWORD_PTR dwIoBase, PBYTE pbyThreshold)
  * Return Value: none
  *
  */
-void MACvSetDmaLength (DWORD_PTR dwIoBase, BYTE byDmaLength)
+void MACvSetDmaLength (unsigned long dwIoBase, unsigned char byDmaLength)
 {
-    BYTE byOrgValue;
+    unsigned char byOrgValue;
 
     ASSERT(byDmaLength < 4);
 
@@ -434,7 +434,7 @@ void MACvSetDmaLength (DWORD_PTR dwIoBase, BYTE byDmaLength)
  * Return Value: none
  *
  */
-void MACvGetDmaLength (DWORD_PTR dwIoBase, PBYTE pbyDmaLength)
+void MACvGetDmaLength (unsigned long dwIoBase, unsigned char *pbyDmaLength)
 {
     // get FCR0
     VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength);
@@ -455,7 +455,7 @@ void MACvGetDmaLength (DWORD_PTR dwIoBase, PBYTE pbyDmaLength)
  * Return Value: none
  *
  */
-void MACvSetShortRetryLimit (DWORD_PTR dwIoBase, BYTE byRetryLimit)
+void MACvSetShortRetryLimit (unsigned long dwIoBase, unsigned char byRetryLimit)
 {
     // set SRT
     VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
@@ -474,7 +474,7 @@ void MACvSetShortRetryLimit (DWORD_PTR dwIoBase, BYTE byRetryLimit)
  * Return Value: none
  *
  */
-void MACvGetShortRetryLimit (DWORD_PTR dwIoBase, PBYTE pbyRetryLimit)
+void MACvGetShortRetryLimit (unsigned long dwIoBase, unsigned char *pbyRetryLimit)
 {
     // get SRT
     VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit);
@@ -494,7 +494,7 @@ void MACvGetShortRetryLimit (DWORD_PTR dwIoBase, PBYTE pbyRetryLimit)
  * Return Value: none
  *
  */
-void MACvSetLongRetryLimit (DWORD_PTR dwIoBase, BYTE byRetryLimit)
+void MACvSetLongRetryLimit (unsigned long dwIoBase, unsigned char byRetryLimit)
 {
     // set LRT
     VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit);
@@ -513,7 +513,7 @@ void MACvSetLongRetryLimit (DWORD_PTR dwIoBase, BYTE byRetryLimit)
  * Return Value: none
  *
  */
-void MACvGetLongRetryLimit (DWORD_PTR dwIoBase, PBYTE pbyRetryLimit)
+void MACvGetLongRetryLimit (unsigned long dwIoBase, unsigned char *pbyRetryLimit)
 {
     // get LRT
     VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit);
@@ -533,9 +533,9 @@ void MACvGetLongRetryLimit (DWORD_PTR dwIoBase, PBYTE pbyRetryLimit)
  * Return Value: none
  *
  */
-void MACvSetLoopbackMode (DWORD_PTR dwIoBase, BYTE byLoopbackMode)
+void MACvSetLoopbackMode (unsigned long dwIoBase, unsigned char byLoopbackMode)
 {
-    BYTE byOrgValue;
+    unsigned char byOrgValue;
 
     ASSERT(byLoopbackMode < 3);
     byLoopbackMode <<= 6;
@@ -556,17 +556,17 @@ void MACvSetLoopbackMode (DWORD_PTR dwIoBase, BYTE byLoopbackMode)
  *  Out:
  *      none
  *
- * Return Value: TRUE if in Loopback mode; otherwise FALSE
+ * Return Value: true if in Loopback mode; otherwise false
  *
  */
-BOOL MACbIsInLoopbackMode (DWORD_PTR dwIoBase)
+bool MACbIsInLoopbackMode (unsigned long dwIoBase)
 {
-    BYTE byOrgValue;
+    unsigned char byOrgValue;
 
     VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
     if (byOrgValue & (TEST_LBINT | TEST_LBEXT))
-        return TRUE;
-    return FALSE;
+        return true;
+    return false;
 }
 
 /*
@@ -583,10 +583,10 @@ BOOL MACbIsInLoopbackMode (DWORD_PTR dwIoBase)
  * Return Value: none
  *
  */
-void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
+void MACvSetPacketFilter (unsigned long dwIoBase, unsigned short wFilterType)
 {
-    BYTE    byOldRCR;
-    BYTE    byNewRCR = 0;
+    unsigned char byOldRCR;
+    unsigned char byNewRCR = 0;
 
     // if only in DIRECTED mode, multicast-address will set to zero,
     // but if other mode exist (e.g. PROMISCUOUS), multicast-address
@@ -595,7 +595,7 @@ void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
         // set multicast address to accept none
         MACvSelectPage1(dwIoBase);
         VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L);
-        VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(DWORD), 0L);
+        VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0L);
         MACvSelectPage0(dwIoBase);
     }
 
@@ -603,7 +603,7 @@ void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
         // set multicast address to accept all
         MACvSelectPage1(dwIoBase);
         VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL);
-        VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(DWORD), 0xFFFFFFFFL);
+        VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0xFFFFFFFFL);
         MACvSelectPage0(dwIoBase);
     }
 
@@ -643,7 +643,7 @@ void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
  * Return Value: none
  *
  */
-void MACvSaveContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
+void MACvSaveContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf)
 {
     int         ii;
 
@@ -676,7 +676,7 @@ void MACvSaveContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
  * Return Value: none
  *
  */
-void MACvRestoreContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
+void MACvRestoreContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf)
 {
     int         ii;
 
@@ -703,14 +703,14 @@ void MACvRestoreContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
     }
 
     // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
-    VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(PDWORD)(pbyCxtBuf + MAC_REG_TXDMAPTR0));
-    VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(PDWORD)(pbyCxtBuf + MAC_REG_AC0DMAPTR));
-    VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(PDWORD)(pbyCxtBuf + MAC_REG_BCNDMAPTR));
+    VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0));
+    VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR));
+    VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR));
 
 
-    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR0));
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0));
 
-    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR1));
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1));
 
 }
 
@@ -725,39 +725,39 @@ void MACvRestoreContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all values are the same; otherwise FALSE
+ * Return Value: true if all values are the same; otherwise false
  *
  */
-BOOL MACbCompareContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
+bool MACbCompareContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf)
 {
-    DWORD       dwData;
+    unsigned long dwData;
 
     // compare MAC context to determine if this is a power lost init,
-    // return TRUE for power remaining init, return FALSE for power lost init
+    // return true for power remaining init, return false for power lost init
 
     // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
     VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData);
-    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) {
-        return FALSE;
+    if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) {
+        return false;
     }
 
     VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData);
-    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) {
-        return FALSE;
+    if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) {
+        return false;
     }
 
     VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData);
-    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) {
-        return FALSE;
+    if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) {
+        return false;
     }
 
     VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData);
-    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) {
-        return FALSE;
+    if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) {
+        return false;
     }
 
 
-    return TRUE;
+    return true;
 }
 
 /*
@@ -770,13 +770,13 @@ BOOL MACbCompareContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
  *  Out:
  *      none
  *
- * Return Value: TRUE if Reset Success; otherwise FALSE
+ * Return Value: true if Reset Success; otherwise false
  *
  */
-BOOL MACbSoftwareReset (DWORD_PTR dwIoBase)
+bool MACbSoftwareReset (unsigned long dwIoBase)
 {
-    BYTE    byData;
-    WORD    ww;
+    unsigned char byData;
+    unsigned short ww;
 
     // turn on HOSTCR_SOFTRST, just write 0x01 to reset
     //MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_SOFTRST);
@@ -788,8 +788,8 @@ BOOL MACbSoftwareReset (DWORD_PTR dwIoBase)
             break;
     }
     if (ww == W_MAX_TIMEOUT)
-        return FALSE;
-    return TRUE;
+        return false;
+    return true;
 
 }
 
@@ -803,13 +803,13 @@ BOOL MACbSoftwareReset (DWORD_PTR dwIoBase)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL MACbSafeSoftwareReset (DWORD_PTR dwIoBase)
+bool MACbSafeSoftwareReset (unsigned long dwIoBase)
 {
-    BYTE    abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
-    BOOL    bRetVal;
+    unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
+    bool bRetVal;
 
     // PATCH....
     // save some important register's value, then do
@@ -836,14 +836,14 @@ BOOL MACbSafeSoftwareReset (DWORD_PTR dwIoBase)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
+bool MACbSafeRxOff (unsigned long dwIoBase)
 {
-    WORD    ww;
-    DWORD   dwData;
-    BYTE    byData;
+    unsigned short ww;
+    unsigned long dwData;
+    unsigned char byData;
 
     // turn off wow temp for turn off Rx safely
 
@@ -858,7 +858,7 @@ BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x10);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x10)\n");
-        return(FALSE);
+        return(false);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);
@@ -868,7 +868,7 @@ BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x11);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x11)\n");
-        return(FALSE);
+        return(false);
     }
 
     // try to safe shutdown RX
@@ -882,9 +882,9 @@ BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x12);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x12)\n");
-        return(FALSE);
+        return(false);
     }
-    return TRUE;
+    return true;
 }
 
 /*
@@ -897,14 +897,14 @@ BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
+bool MACbSafeTxOff (unsigned long dwIoBase)
 {
-    WORD    ww;
-    DWORD   dwData;
-    BYTE    byData;
+    unsigned short ww;
+    unsigned long dwData;
+    unsigned char byData;
 
     // Clear TX DMA
     //Tx0
@@ -921,7 +921,7 @@ BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x20);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x20)\n");
-        return(FALSE);
+        return(false);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);
@@ -931,7 +931,7 @@ BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x21);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x21)\n");
-        return(FALSE);
+        return(false);
     }
 
     // try to safe shutdown TX
@@ -946,9 +946,9 @@ BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x24);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x24)\n");
-        return(FALSE);
+        return(false);
     }
-    return TRUE;
+    return true;
 }
 
 /*
@@ -961,29 +961,29 @@ BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL MACbSafeStop (DWORD_PTR dwIoBase)
+bool MACbSafeStop (unsigned long dwIoBase)
 {
     MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
 
-    if (MACbSafeRxOff(dwIoBase) == FALSE) {
+    if (MACbSafeRxOff(dwIoBase) == false) {
         DBG_PORT80(0xA1);
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeRxOff == FALSE)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeRxOff == false)\n");
         MACbSafeSoftwareReset(dwIoBase);
-        return FALSE;
+        return false;
     }
-    if (MACbSafeTxOff(dwIoBase) == FALSE) {
+    if (MACbSafeTxOff(dwIoBase) == false) {
         DBG_PORT80(0xA2);
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeTxOff == FALSE)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeTxOff == false)\n");
         MACbSafeSoftwareReset(dwIoBase);
-        return FALSE;
+        return false;
     }
 
     MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN);
 
-    return TRUE;
+    return true;
 }
 
 /*
@@ -996,10 +996,10 @@ BOOL MACbSafeStop (DWORD_PTR dwIoBase)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL MACbShutdown (DWORD_PTR dwIoBase)
+bool MACbShutdown (unsigned long dwIoBase)
 {
     // disable MAC IMR
     MACvIntDisable(dwIoBase);
@@ -1007,10 +1007,10 @@ BOOL MACbShutdown (DWORD_PTR dwIoBase)
     // stop the adapter
     if (!MACbSafeStop(dwIoBase)) {
         MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
-        return FALSE;
+        return false;
     }
     MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
-    return TRUE;
+    return true;
 }
 
 /*
@@ -1026,7 +1026,7 @@ BOOL MACbShutdown (DWORD_PTR dwIoBase)
  * Return Value: none
  *
  */
-void MACvInitialize (DWORD_PTR dwIoBase)
+void MACvInitialize (unsigned long dwIoBase)
 {
     // clear sticky bits
     MACvClearStckDS(dwIoBase);
@@ -1045,8 +1045,8 @@ void MACvInitialize (DWORD_PTR dwIoBase)
     // issue AUTOLD in EECSR to reload eeprom
     //MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD);
     // wait until EEPROM loading complete
-    //while (TRUE) {
-    //    U8 u8Data;
+    //while (true) {
+    //    u8 u8Data;
     //    VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &u8Data);
     //    if ( !(u8Data & I2MCSR_AUTOLD))
     //        break;
@@ -1079,11 +1079,11 @@ void MACvInitialize (DWORD_PTR dwIoBase)
  * Return Value: none
  *
  */
-void MACvSetCurrRx0DescAddr (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+void MACvSetCurrRx0DescAddr (unsigned long dwIoBase, unsigned long dwCurrDescAddr)
 {
-WORD    ww;
-BYTE    byData;
-BYTE    byOrgDMACtl;
+unsigned short ww;
+unsigned char byData;
+unsigned char byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl);
     if (byOrgDMACtl & DMACTL_RUN) {
@@ -1117,11 +1117,11 @@ BYTE    byOrgDMACtl;
  * Return Value: none
  *
  */
-void MACvSetCurrRx1DescAddr (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+void MACvSetCurrRx1DescAddr (unsigned long dwIoBase, unsigned long dwCurrDescAddr)
 {
-WORD    ww;
-BYTE    byData;
-BYTE    byOrgDMACtl;
+unsigned short ww;
+unsigned char byData;
+unsigned char byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl);
     if (byOrgDMACtl & DMACTL_RUN) {
@@ -1155,11 +1155,11 @@ BYTE    byOrgDMACtl;
  * Return Value: none
  *
  */
-void MACvSetCurrTx0DescAddrEx (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+void MACvSetCurrTx0DescAddrEx (unsigned long dwIoBase, unsigned long dwCurrDescAddr)
 {
-WORD    ww;
-BYTE    byData;
-BYTE    byOrgDMACtl;
+unsigned short ww;
+unsigned char byData;
+unsigned char byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl);
     if (byOrgDMACtl & DMACTL_RUN) {
@@ -1194,11 +1194,11 @@ BYTE    byOrgDMACtl;
  *
  */
  //TxDMA1 = AC0DMA
-void MACvSetCurrAC0DescAddrEx (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+void MACvSetCurrAC0DescAddrEx (unsigned long dwIoBase, unsigned long dwCurrDescAddr)
 {
-WORD    ww;
-BYTE    byData;
-BYTE    byOrgDMACtl;
+unsigned short ww;
+unsigned char byData;
+unsigned char byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl);
     if (byOrgDMACtl & DMACTL_RUN) {
@@ -1221,7 +1221,7 @@ BYTE    byOrgDMACtl;
 
 
 
-void MACvSetCurrTXDescAddr (int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+void MACvSetCurrTXDescAddr (int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr)
 {
     if(iTxType == TYPE_AC0DMA){
         MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr);
@@ -1244,10 +1244,10 @@ void MACvSetCurrTXDescAddr (int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAdd
  * Return Value: none
  *
  */
-void MACvTimer0MicroSDelay (DWORD_PTR dwIoBase, UINT uDelay)
+void MACvTimer0MicroSDelay (unsigned long dwIoBase, unsigned int uDelay)
 {
-BYTE byValue;
-UINT uu,ii;
+unsigned char byValue;
+unsigned int uu,ii;
 
     VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
     VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay);
@@ -1280,7 +1280,7 @@ UINT uu,ii;
  * Return Value: none
  *
  */
-void MACvOneShotTimer0MicroSec (DWORD_PTR dwIoBase, UINT uDelayTime)
+void MACvOneShotTimer0MicroSec (unsigned long dwIoBase, unsigned int uDelayTime)
 {
     VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
     VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime);
@@ -1301,7 +1301,7 @@ void MACvOneShotTimer0MicroSec (DWORD_PTR dwIoBase, UINT uDelayTime)
  * Return Value: none
  *
  */
-void MACvOneShotTimer1MicroSec (DWORD_PTR dwIoBase, UINT uDelayTime)
+void MACvOneShotTimer1MicroSec (unsigned long dwIoBase, unsigned int uDelayTime)
 {
     VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0);
     VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime);
@@ -1309,7 +1309,7 @@ void MACvOneShotTimer1MicroSec (DWORD_PTR dwIoBase, UINT uDelayTime)
 }
 
 
-void MACvSetMISCFifo (DWORD_PTR dwIoBase, WORD wOffset, DWORD dwData)
+void MACvSetMISCFifo (unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData)
 {
     if (wOffset > 273)
         return;
@@ -1319,10 +1319,10 @@ void MACvSetMISCFifo (DWORD_PTR dwIoBase, WORD wOffset, DWORD dwData)
 }
 
 
-BOOL MACbTxDMAOff (DWORD_PTR dwIoBase, UINT idx)
+bool MACbTxDMAOff (unsigned long dwIoBase, unsigned int idx)
 {
-BYTE byData;
-UINT ww = 0;
+unsigned char byData;
+unsigned int ww = 0;
 
     if (idx == TYPE_TXDMA0) {
         VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
@@ -1342,15 +1342,15 @@ UINT ww = 0;
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x29);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x29)\n");
-        return FALSE;
+        return false;
     }
-    return TRUE;
+    return true;
 }
 
-void MACvClearBusSusInd (DWORD_PTR dwIoBase)
+void MACvClearBusSusInd (unsigned long dwIoBase)
 {
-    DWORD dwOrgValue;
-    UINT ww;
+    unsigned long dwOrgValue;
+    unsigned int ww;
     // check if BcnSusInd enabled
     VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
     if( !(dwOrgValue & EnCFG_BcnSusInd))
@@ -1369,11 +1369,11 @@ void MACvClearBusSusInd (DWORD_PTR dwIoBase)
     }
 }
 
-void MACvEnableBusSusEn (DWORD_PTR dwIoBase)
+void MACvEnableBusSusEn (unsigned long dwIoBase)
 {
-    BYTE  byOrgValue;
-    DWORD dwOrgValue;
-    UINT ww;
+    unsigned char byOrgValue;
+    unsigned long dwOrgValue;
+    unsigned int ww;
     // check if BcnSusInd enabled
     VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue);
 
@@ -1391,10 +1391,10 @@ void MACvEnableBusSusEn (DWORD_PTR dwIoBase)
     }
 }
 
-BOOL MACbFlushSYNCFifo (DWORD_PTR dwIoBase)
+bool MACbFlushSYNCFifo (unsigned long dwIoBase)
 {
-    BYTE  byOrgValue;
-    UINT ww;
+    unsigned char byOrgValue;
+    unsigned int ww;
     // Read MACCR
     VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
 
@@ -1412,16 +1412,16 @@ BOOL MACbFlushSYNCFifo (DWORD_PTR dwIoBase)
         DBG_PORT80(0x35);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
     }
-    return TRUE;
+    return true;
 }
 
-BOOL MACbPSWakeup (DWORD_PTR dwIoBase)
+bool MACbPSWakeup (unsigned long dwIoBase)
 {
-    BYTE  byOrgValue;
-    UINT ww;
+    unsigned char byOrgValue;
+    unsigned int ww;
     // Read PSCTL
     if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) {
-        return TRUE;
+        return true;
     }
     // Disable PS
     MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN);
@@ -1435,9 +1435,9 @@ BOOL MACbPSWakeup (DWORD_PTR dwIoBase)
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x36);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
-        return FALSE;
+        return false;
     }
-    return TRUE;
+    return true;
 }
 
 /*
@@ -1455,10 +1455,11 @@ BOOL MACbPSWakeup (DWORD_PTR dwIoBase)
  *
  */
 
-void MACvSetKeyEntry (DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey, BYTE byLocalID)
+void MACvSetKeyEntry (unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
+               unsigned int uKeyIdx, unsigned char *pbyAddr, unsigned long *pdwKey, unsigned char byLocalID)
 {
-WORD    wOffset;
-DWORD   dwData;
+unsigned short wOffset;
+unsigned long dwData;
 int     ii;
 
     if (byLocalID <= 1)
@@ -1521,9 +1522,9 @@ int     ii;
  * Return Value: none
  *
  */
-void MACvDisableKeyEntry (DWORD_PTR dwIoBase, UINT uEntryIdx)
+void MACvDisableKeyEntry (unsigned long dwIoBase, unsigned int uEntryIdx)
 {
-WORD    wOffset;
+unsigned short wOffset;
 
     wOffset = MISCFIFO_KEYETRY0;
     wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
@@ -1549,10 +1550,11 @@ WORD    wOffset;
  *
  */
 
-void MACvSetDefaultKeyEntry (DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID)
+void MACvSetDefaultKeyEntry (unsigned long dwIoBase, unsigned int uKeyLen,
+               unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
 {
-WORD    wOffset;
-DWORD   dwData;
+unsigned short wOffset;
+unsigned long dwData;
 int     ii;
 
     if (byLocalID <= 1)
@@ -1599,10 +1601,10 @@ int     ii;
  *
  */
 /*
-void MACvEnableDefaultKey (DWORD_PTR dwIoBase, BYTE byLocalID)
+void MACvEnableDefaultKey (unsigned long dwIoBase, unsigned char byLocalID)
 {
-WORD    wOffset;
-DWORD   dwData;
+unsigned short wOffset;
+unsigned long dwData;
 
 
     if (byLocalID <= 1)
@@ -1634,10 +1636,10 @@ DWORD   dwData;
  * Return Value: none
  *
  */
-void MACvDisableDefaultKey (DWORD_PTR dwIoBase)
+void MACvDisableDefaultKey (unsigned long dwIoBase)
 {
-WORD    wOffset;
-DWORD   dwData;
+unsigned short wOffset;
+unsigned long dwData;
 
 
     wOffset = MISCFIFO_KEYETRY0;
@@ -1664,10 +1666,11 @@ DWORD   dwData;
  * Return Value: none
  *
  */
-void MACvSetDefaultTKIPKeyEntry (DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID)
+void MACvSetDefaultTKIPKeyEntry (unsigned long dwIoBase, unsigned int uKeyLen,
+               unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
 {
-WORD    wOffset;
-DWORD   dwData;
+unsigned short wOffset;
+unsigned long dwData;
 int     ii;
 
     if (byLocalID <= 1)
@@ -1720,10 +1723,10 @@ int     ii;
  *
  */
 
-void MACvSetDefaultKeyCtl (DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, BYTE byLocalID)
+void MACvSetDefaultKeyCtl (unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID)
 {
-WORD    wOffset;
-DWORD   dwData;
+unsigned short wOffset;
+unsigned long dwData;
 
     if (byLocalID <= 1)
         return;
index 5eb7f57f7182108c9974eeda57170c35947e65fa..b96d27ee2540f2648c6d7881fccfe741e831e445 100644 (file)
 
 #define MACvRegBitsOn(dwIoBase, byRegOfs, byBits)           \
 {                                                           \
-    BYTE byData;                                            \
+    unsigned char byData;                                   \
     VNSvInPortB(dwIoBase + byRegOfs, &byData);              \
     VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits));   \
 }
 
 #define MACvWordRegBitsOn(dwIoBase, byRegOfs, wBits)        \
 {                                                           \
-    WORD wData;                                             \
+    unsigned short wData;                                   \
     VNSvInPortW(dwIoBase + byRegOfs, &wData);               \
     VNSvOutPortW(dwIoBase + byRegOfs, wData | (wBits));     \
 }
 
 #define MACvDWordRegBitsOn(dwIoBase, byRegOfs, dwBits)      \
 {                                                           \
-    DWORD dwData;                                           \
+    unsigned long dwData;                                   \
     VNSvInPortD(dwIoBase + byRegOfs, &dwData);              \
     VNSvOutPortD(dwIoBase + byRegOfs, dwData | (dwBits));   \
 }
 
 #define MACvRegBitsOnEx(dwIoBase, byRegOfs, byMask, byBits) \
 {                                                           \
-    BYTE byData;                                            \
+    unsigned char byData;                                   \
     VNSvInPortB(dwIoBase + byRegOfs, &byData);              \
     byData &= byMask;                                       \
     VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits));   \
 
 #define MACvRegBitsOff(dwIoBase, byRegOfs, byBits)          \
 {                                                           \
-    BYTE byData;                                            \
+    unsigned char byData;                                   \
     VNSvInPortB(dwIoBase + byRegOfs, &byData);              \
     VNSvOutPortB(dwIoBase + byRegOfs, byData & ~(byBits));  \
 }
 
 #define MACvWordRegBitsOff(dwIoBase, byRegOfs, wBits)       \
 {                                                           \
-    WORD wData;                                             \
+    unsigned short wData;                                   \
     VNSvInPortW(dwIoBase + byRegOfs, &wData);               \
     VNSvOutPortW(dwIoBase + byRegOfs, wData & ~(wBits));    \
 }
 
 #define MACvDWordRegBitsOff(dwIoBase, byRegOfs, dwBits)     \
 {                                                           \
-    DWORD dwData;                                           \
+    unsigned long dwData;                                   \
     VNSvInPortD(dwIoBase + byRegOfs, &dwData);              \
     VNSvOutPortD(dwIoBase + byRegOfs, dwData & ~(dwBits));  \
 }
 #define MACvGetCurrRx0DescAddr(dwIoBase, pdwCurrDescAddr)    \
 {                                                           \
     VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0,               \
-                (PDWORD)pdwCurrDescAddr);                   \
+                (unsigned long *)pdwCurrDescAddr);          \
 }
 
 #define MACvGetCurrRx1DescAddr(dwIoBase, pdwCurrDescAddr)   \
 {                                                           \
     VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1,               \
-                (PDWORD)pdwCurrDescAddr);                   \
+                (unsigned long *)pdwCurrDescAddr);          \
 }
 
 #define MACvGetCurrTx0DescAddr(dwIoBase, pdwCurrDescAddr)   \
 {                                                           \
     VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0,               \
-                (PDWORD)pdwCurrDescAddr);                   \
+                (unsigned long *)pdwCurrDescAddr);          \
 }
 
 #define MACvGetCurrAC0DescAddr(dwIoBase, pdwCurrDescAddr)   \
 {                                                           \
     VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR,               \
-                (PDWORD)pdwCurrDescAddr);                   \
+                (unsigned long *)pdwCurrDescAddr);          \
 }
 
 #define MACvGetCurrSyncDescAddr(dwIoBase, pdwCurrDescAddr)  \
 {                                                           \
     VNSvInPortD(dwIoBase + MAC_REG_SYNCDMAPTR,              \
-                (PDWORD)pdwCurrDescAddr);                   \
+                (unsigned long *)pdwCurrDescAddr);          \
 }
 
 #define MACvGetCurrATIMDescAddr(dwIoBase, pdwCurrDescAddr)  \
 {                                                           \
     VNSvInPortD(dwIoBase + MAC_REG_ATIMDMAPTR,              \
-                (PDWORD)pdwCurrDescAddr);                   \
+                (unsigned long *)pdwCurrDescAddr);          \
 }                                                           \
 
 // set the chip with current BCN tx descriptor address
 {                                                           \
     VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);           \
     VNSvInPortB(dwIoBase + MAC_REG_BSSID0,                  \
-                (PBYTE)pbyEtherAddr);                       \
+                (unsigned char *)pbyEtherAddr);             \
     VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 1,              \
                 pbyEtherAddr + 1);                          \
     VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 2,              \
 {                                                           \
     VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);           \
     VNSvInPortB(dwIoBase + MAC_REG_PAR0,                    \
-                (PBYTE)pbyEtherAddr);                       \
+                (unsigned char *)pbyEtherAddr);             \
     VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 1,                \
                 pbyEtherAddr + 1);                          \
     VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 2,                \
 
 #define MACvReceive0(dwIoBase)                                  \
 {                                                               \
-    DWORD dwData;                                               \
+    unsigned long dwData;                                       \
     VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);         \
     if (dwData & DMACTL_RUN) {                                  \
         VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_WAKE);\
 
 #define MACvReceive1(dwIoBase)                                  \
 {                                                               \
-    DWORD dwData;                                                \
+    unsigned long dwData;                                       \
     VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);         \
     if (dwData & DMACTL_RUN) {                                  \
         VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_WAKE);\
 
 #define MACvTransmit0(dwIoBase)                                 \
 {                                                               \
-    DWORD dwData;                                                \
+    unsigned long dwData;                                       \
     VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);         \
     if (dwData & DMACTL_RUN) {                                  \
         VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_WAKE);\
 
 #define MACvTransmitAC0(dwIoBase)                               \
 {                                                               \
-    DWORD dwData;                                                \
+    unsigned long dwData;                                       \
     VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);         \
     if (dwData & DMACTL_RUN) {                                  \
         VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_WAKE);\
 
 #define MACvTransmitSYNC(dwIoBase)                               \
 {                                                                \
-    DWORD dwData;                                                 \
+    unsigned long dwData;                                        \
     VNSvInPortD(dwIoBase + MAC_REG_SYNCDMACTL, &dwData);         \
     if (dwData & DMACTL_RUN) {                                   \
         VNSvOutPortD(dwIoBase + MAC_REG_SYNCDMACTL, DMACTL_WAKE);\
 
 #define MACvTransmitATIM(dwIoBase)                               \
 {                                                                \
-    DWORD dwData;                                                 \
+    unsigned long dwData;                                        \
     VNSvInPortD(dwIoBase + MAC_REG_ATIMDMACTL, &dwData);         \
     if (dwData & DMACTL_RUN) {                                   \
         VNSvOutPortD(dwIoBase + MAC_REG_ATIMDMACTL, DMACTL_WAKE);\
 
 #define MACvClearStckDS(dwIoBase)                           \
 {                                                           \
-    BYTE byOrgValue;                                        \
+    unsigned char byOrgValue;                               \
     VNSvInPortB(dwIoBase + MAC_REG_STICKHW, &byOrgValue);   \
     byOrgValue = byOrgValue & 0xFC;                         \
     VNSvOutPortB(dwIoBase + MAC_REG_STICKHW, byOrgValue);   \
 
 #define MACvEnableProtectMD(dwIoBase)                    \
 {                                                        \
-    DWORD dwOrgValue;                                    \
+    unsigned long dwOrgValue;                            \
     VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
     dwOrgValue = dwOrgValue | EnCFG_ProtectMd;           \
     VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
 
 #define MACvDisableProtectMD(dwIoBase)                   \
 {                                                        \
-    DWORD dwOrgValue;                                     \
+    unsigned long dwOrgValue;                            \
     VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
     dwOrgValue = dwOrgValue & ~EnCFG_ProtectMd;          \
     VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
 
 #define MACvEnableBarkerPreambleMd(dwIoBase)             \
 {                                                        \
-    DWORD dwOrgValue;                                    \
+    unsigned long dwOrgValue;                            \
     VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
     dwOrgValue = dwOrgValue | EnCFG_BarkerPream;         \
     VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
 
 #define MACvDisableBarkerPreambleMd(dwIoBase)            \
 {                                                        \
-    DWORD dwOrgValue;                                    \
+    unsigned long dwOrgValue;                            \
     VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
     dwOrgValue = dwOrgValue & ~EnCFG_BarkerPream;        \
     VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
 
 #define MACvSetBBType(dwIoBase, byTyp)                   \
 {                                                        \
-    DWORD dwOrgValue;                                    \
+    unsigned long dwOrgValue;                            \
     VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
     dwOrgValue = dwOrgValue & ~EnCFG_BBType_MASK;        \
-    dwOrgValue = dwOrgValue | (DWORD) byTyp;             \
+    dwOrgValue = dwOrgValue | (unsigned long) byTyp;     \
     VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
 }
 
 
 /*---------------------  Export Functions  --------------------------*/
 
-extern WORD TxRate_iwconfig;//2008-5-8 <add> by chester
-void MACvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyMacRegs);
-
-BOOL MACbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits);
-BOOL MACbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits);
-
-BOOL MACbIsIntDisable(DWORD_PTR dwIoBase);
-
-BYTE MACbyReadMultiAddr(DWORD_PTR dwIoBase, UINT uByteIdx);
-void MACvWriteMultiAddr(DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData);
-void MACvSetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx);
-void MACvResetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx);
-
-void MACvSetRxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold);
-void MACvGetRxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold);
-
-void MACvSetTxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold);
-void MACvGetTxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold);
-
-void MACvSetDmaLength(DWORD_PTR dwIoBase, BYTE byDmaLength);
-void MACvGetDmaLength(DWORD_PTR dwIoBase, PBYTE pbyDmaLength);
-
-void MACvSetShortRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit);
-void MACvGetShortRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit);
-
-void MACvSetLongRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit);
-void MACvGetLongRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit);
-
-void MACvSetLoopbackMode(DWORD_PTR dwIoBase, BYTE byLoopbackMode);
-BOOL MACbIsInLoopbackMode(DWORD_PTR dwIoBase);
-
-void MACvSetPacketFilter(DWORD_PTR dwIoBase, WORD wFilterType);
-
-void MACvSaveContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf);
-void MACvRestoreContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf);
-BOOL MACbCompareContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf);
-
-BOOL MACbSoftwareReset(DWORD_PTR dwIoBase);
-BOOL MACbSafeSoftwareReset(DWORD_PTR dwIoBase);
-BOOL MACbSafeRxOff(DWORD_PTR dwIoBase);
-BOOL MACbSafeTxOff(DWORD_PTR dwIoBase);
-BOOL MACbSafeStop(DWORD_PTR dwIoBase);
-BOOL MACbShutdown(DWORD_PTR dwIoBase);
-void MACvInitialize(DWORD_PTR dwIoBase);
-void MACvSetCurrRx0DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
-void MACvSetCurrRx1DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
-void MACvSetCurrTXDescAddr(int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
-void MACvSetCurrTx0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
-void MACvSetCurrAC0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
-void MACvSetCurrSyncDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
-void MACvSetCurrATIMDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
-void MACvTimer0MicroSDelay(DWORD_PTR dwIoBase, UINT uDelay);
-void MACvOneShotTimer0MicroSec(DWORD_PTR dwIoBase, UINT uDelayTime);
-void MACvOneShotTimer1MicroSec(DWORD_PTR dwIoBase, UINT uDelayTime);
-
-void MACvSetMISCFifo(DWORD_PTR dwIoBase, WORD wOffset, DWORD dwData);
-
-BOOL MACbTxDMAOff (DWORD_PTR dwIoBase, UINT idx);
-
-void MACvClearBusSusInd(DWORD_PTR dwIoBase);
-void MACvEnableBusSusEn(DWORD_PTR dwIoBase);
-
-BOOL MACbFlushSYNCFifo(DWORD_PTR dwIoBase);
-BOOL MACbPSWakeup(DWORD_PTR dwIoBase);
-
-void MACvSetKeyEntry(DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey, BYTE byLocalID);
-void MACvDisableKeyEntry(DWORD_PTR dwIoBase, UINT uEntryIdx);
-void MACvSetDefaultKeyEntry(DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID);
-//void MACvEnableDefaultKey(DWORD_PTR dwIoBase, BYTE byLocalID);
-void MACvDisableDefaultKey(DWORD_PTR dwIoBase);
-void MACvSetDefaultTKIPKeyEntry(DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID);
-void MACvSetDefaultKeyCtl(DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, BYTE byLocalID);
+extern unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester
+void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs);
+
+bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
+bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
+
+bool MACbIsIntDisable(unsigned long dwIoBase);
+
+unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx);
+void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData);
+void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx);
+void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx);
+
+void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold);
+void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold);
+
+void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold);
+void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold);
+
+void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength);
+void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength);
+
+void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit);
+void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit);
+
+void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit);
+void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit);
+
+void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode);
+bool MACbIsInLoopbackMode(unsigned long dwIoBase);
+
+void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType);
+
+void MACvSaveContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf);
+void MACvRestoreContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf);
+bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf);
+
+bool MACbSoftwareReset(unsigned long dwIoBase);
+bool MACbSafeSoftwareReset(unsigned long dwIoBase);
+bool MACbSafeRxOff(unsigned long dwIoBase);
+bool MACbSafeTxOff(unsigned long dwIoBase);
+bool MACbSafeStop(unsigned long dwIoBase);
+bool MACbShutdown(unsigned long dwIoBase);
+void MACvInitialize(unsigned long dwIoBase);
+void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrSyncDescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrATIMDescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
+void MACvTimer0MicroSDelay(unsigned long dwIoBase, unsigned int uDelay);
+void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime);
+void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime);
+
+void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData);
+
+bool MACbTxDMAOff (unsigned long dwIoBase, unsigned int idx);
+
+void MACvClearBusSusInd(unsigned long dwIoBase);
+void MACvEnableBusSusEn(unsigned long dwIoBase);
+
+bool MACbFlushSYNCFifo(unsigned long dwIoBase);
+bool MACbPSWakeup(unsigned long dwIoBase);
+
+void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
+               unsigned int uKeyIdx, unsigned char *pbyAddr, unsigned long *pdwKey, unsigned char byLocalID);
+void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx);
+void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
+               unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID);
+//void MACvEnableDefaultKey(unsigned long dwIoBase, unsigned char byLocalID);
+void MACvDisableDefaultKey(unsigned long dwIoBase);
+void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
+               unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID);
+void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID);
 
 #endif // __MAC_H__
 
index 4ca7877075b2dd0d7d32fbf8ad52dc7c8ff6a5e0..1b91a8370954570b930ab2ea11172239f692809b 100644 (file)
@@ -90,7 +90,7 @@ void STAvClearAllCounter (PSStatCounter pStatistic)
  * Return Value: none
  *
  */
-void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, DWORD dwIsr)
+void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, unsigned long dwIsr)
 {
     /**********************/
     /* ABNORMAL interrupt */
@@ -177,8 +177,8 @@ void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, DWORD dwIsr)
  *
  */
 void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
-                              BYTE byRSR, BYTE byNewRSR, BYTE byRxRate,
-                              PBYTE pbyBuffer, UINT cbFrameLength)
+                              unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate,
+                              unsigned char *pbyBuffer, unsigned int cbFrameLength)
 {
     //need change
     PS802_11Header pHeader = (PS802_11Header)pbyBuffer;
@@ -194,15 +194,15 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
             // update counters in case that successful transmit
             if (byRSR & RSR_ADDRBROAD) {
                 pStatistic->ullRxBroadcastFrames++;
-                pStatistic->ullRxBroadcastBytes += (ULONGLONG)cbFrameLength;
+                pStatistic->ullRxBroadcastBytes += (unsigned long long) cbFrameLength;
             }
             else if (byRSR & RSR_ADDRMULTI) {
                 pStatistic->ullRxMulticastFrames++;
-                pStatistic->ullRxMulticastBytes += (ULONGLONG)cbFrameLength;
+                pStatistic->ullRxMulticastBytes += (unsigned long long) cbFrameLength;
             }
             else {
                 pStatistic->ullRxDirectedFrames++;
-                pStatistic->ullRxDirectedBytes += (ULONGLONG)cbFrameLength;
+                pStatistic->ullRxDirectedBytes += (unsigned long long) cbFrameLength;
             }
         }
     }
@@ -212,87 +212,87 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr11MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr11M, (INT)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr11M, (int)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR);
     }
     else if(byRxRate==11) {
         pStatistic->CustomStat.ullRsr5M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr5MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr5M, (INT)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr5M, (int)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR);
     }
     else if(byRxRate==4) {
         pStatistic->CustomStat.ullRsr2M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr2MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr2M, (INT)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr2M, (int)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR);
     }
     else if(byRxRate==2){
         pStatistic->CustomStat.ullRsr1M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr1MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr1M, (INT)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr1M, (int)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR);
     }
     else if(byRxRate==12){
         pStatistic->CustomStat.ullRsr6M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr6MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr6M, (INT)pStatistic->CustomStat.ullRsr6MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr6M, (int)pStatistic->CustomStat.ullRsr6MCRCOk);
     }
     else if(byRxRate==18){
         pStatistic->CustomStat.ullRsr9M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr9MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr9M, (INT)pStatistic->CustomStat.ullRsr9MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr9M, (int)pStatistic->CustomStat.ullRsr9MCRCOk);
     }
     else if(byRxRate==24){
         pStatistic->CustomStat.ullRsr12M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr12MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr12M, (INT)pStatistic->CustomStat.ullRsr12MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr12M, (int)pStatistic->CustomStat.ullRsr12MCRCOk);
     }
     else if(byRxRate==36){
         pStatistic->CustomStat.ullRsr18M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr18MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr18M, (INT)pStatistic->CustomStat.ullRsr18MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr18M, (int)pStatistic->CustomStat.ullRsr18MCRCOk);
     }
     else if(byRxRate==48){
         pStatistic->CustomStat.ullRsr24M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr24MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr24M, (INT)pStatistic->CustomStat.ullRsr24MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr24M, (int)pStatistic->CustomStat.ullRsr24MCRCOk);
     }
     else if(byRxRate==72){
         pStatistic->CustomStat.ullRsr36M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr36MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr36M, (INT)pStatistic->CustomStat.ullRsr36MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr36M, (int)pStatistic->CustomStat.ullRsr36MCRCOk);
     }
     else if(byRxRate==96){
         pStatistic->CustomStat.ullRsr48M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr48MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr48M, (INT)pStatistic->CustomStat.ullRsr48MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr48M, (int)pStatistic->CustomStat.ullRsr48MCRCOk);
     }
     else if(byRxRate==108){
         pStatistic->CustomStat.ullRsr54M++;
         if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr54MCRCOk++;
         }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr54M, (INT)pStatistic->CustomStat.ullRsr54MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr54M, (int)pStatistic->CustomStat.ullRsr54MCRCOk);
     }
     else {
-       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (INT)pStatistic->dwRsrRxPacket+1, (INT)pStatistic->dwRsrCRCOk);
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (int)pStatistic->dwRsrRxPacket+1, (int)pStatistic->dwRsrCRCOk);
     }
 
     if (byRSR & RSR_BSSIDOK)
@@ -341,10 +341,10 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
     if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl))
         pStatistic->dwRsrRxFragment++;
 
-    if (cbFrameLength < MIN_PACKET_LEN + 4) {
+    if (cbFrameLength < ETH_ZLEN + 4) {
         pStatistic->dwRsrRunt++;
     }
-    else if (cbFrameLength == MIN_PACKET_LEN + 4) {
+    else if (cbFrameLength == ETH_ZLEN + 4) {
         pStatistic->dwRsrRxFrmLen64++;
     }
     else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) {
@@ -389,11 +389,11 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
 void
 STAvUpdateRDStatCounterEx (
     PSStatCounter   pStatistic,
-    BYTE            byRSR,
-    BYTE            byNewRSR,
-    BYTE            byRxRate,
-    PBYTE           pbyBuffer,
-    UINT            cbFrameLength
+    unsigned char byRSR,
+    unsigned char byNewRSR,
+    unsigned char byRxRate,
+    unsigned char *pbyBuffer,
+    unsigned int cbFrameLength
     )
 {
     STAvUpdateRDStatCounter(
@@ -408,7 +408,7 @@ STAvUpdateRDStatCounterEx (
     // rx length
     pStatistic->dwCntRxFrmLength = cbFrameLength;
     // rx pattern, we just see 10 bytes for sample
-    memcpy(pStatistic->abyCntRxPattern, (PBYTE)pbyBuffer, 10);
+    memcpy(pStatistic->abyCntRxPattern, (unsigned char *)pbyBuffer, 10);
 }
 
 
@@ -432,16 +432,16 @@ STAvUpdateRDStatCounterEx (
 void
 STAvUpdateTDStatCounter (
     PSStatCounter   pStatistic,
-    BYTE            byTSR0,
-    BYTE            byTSR1,
-    PBYTE           pbyBuffer,
-    UINT            cbFrameLength,
-    UINT            uIdx
+    unsigned char byTSR0,
+    unsigned char byTSR1,
+    unsigned char *pbyBuffer,
+    unsigned int cbFrameLength,
+    unsigned int uIdx
     )
 {
     PWLAN_80211HDR_A4   pHeader;
-    PBYTE               pbyDestAddr;
-    BYTE                byTSR0_NCR = byTSR0 & TSR0_NCR;
+    unsigned char *pbyDestAddr;
+    unsigned char byTSR0_NCR = byTSR0 & TSR0_NCR;
 
 
 
@@ -471,17 +471,17 @@ STAvUpdateTDStatCounter (
         pStatistic->CustomStat.ullTsrAllOK =
             (pStatistic->ullTsrOK[TYPE_AC0DMA] + pStatistic->ullTsrOK[TYPE_TXDMA0]);
         // update counters in case that successful transmit
-        if (IS_BROADCAST_ADDRESS(pbyDestAddr)) {
+        if (is_broadcast_ether_addr(pbyDestAddr)) {
             pStatistic->ullTxBroadcastFrames[uIdx]++;
-            pStatistic->ullTxBroadcastBytes[uIdx] += (ULONGLONG)cbFrameLength;
+            pStatistic->ullTxBroadcastBytes[uIdx] += (unsigned long long) cbFrameLength;
         }
-        else if (IS_MULTICAST_ADDRESS(pbyDestAddr)) {
+        else if (is_multicast_ether_addr(pbyDestAddr)) {
             pStatistic->ullTxMulticastFrames[uIdx]++;
-            pStatistic->ullTxMulticastBytes[uIdx] += (ULONGLONG)cbFrameLength;
+            pStatistic->ullTxMulticastBytes[uIdx] += (unsigned long long) cbFrameLength;
         }
         else {
             pStatistic->ullTxDirectedFrames[uIdx]++;
-            pStatistic->ullTxDirectedBytes[uIdx] += (ULONGLONG)cbFrameLength;
+            pStatistic->ullTxDirectedBytes[uIdx] += (unsigned long long) cbFrameLength;
         }
     }
     else {
@@ -495,9 +495,9 @@ STAvUpdateTDStatCounter (
             pStatistic->dwTsrACKData[uIdx]++;
     }
 
-    if (IS_BROADCAST_ADDRESS(pbyDestAddr))
+    if (is_broadcast_ether_addr(pbyDestAddr))
         pStatistic->dwTsrBroadcast[uIdx]++;
-    else if (IS_MULTICAST_ADDRESS(pbyDestAddr))
+    else if (is_multicast_ether_addr(pbyDestAddr))
         pStatistic->dwTsrMulticast[uIdx]++;
     else
         pStatistic->dwTsrDirected[uIdx]++;
@@ -522,13 +522,13 @@ STAvUpdateTDStatCounter (
 void
 STAvUpdateTDStatCounterEx (
     PSStatCounter   pStatistic,
-    PBYTE           pbyBuffer,
-    DWORD           cbFrameLength
+    unsigned char *pbyBuffer,
+    unsigned long cbFrameLength
     )
 {
-    UINT    uPktLength;
+    unsigned int uPktLength;
 
-    uPktLength = (UINT)cbFrameLength;
+    uPktLength = (unsigned int)cbFrameLength;
 
     // tx length
     pStatistic->dwCntTxBufLength = uPktLength;
@@ -555,25 +555,25 @@ void
 STAvUpdate802_11Counter(
     PSDot11Counters         p802_11Counter,
     PSStatCounter           pStatistic,
-    DWORD                   dwCounter
+    unsigned long dwCounter
     )
 {
     //p802_11Counter->TransmittedFragmentCount
-    p802_11Counter->MulticastTransmittedFrameCount = (ULONGLONG) (pStatistic->dwTsrBroadcast[TYPE_AC0DMA] +
+    p802_11Counter->MulticastTransmittedFrameCount = (unsigned long long) (pStatistic->dwTsrBroadcast[TYPE_AC0DMA] +
                                                                   pStatistic->dwTsrBroadcast[TYPE_TXDMA0] +
                                                                   pStatistic->dwTsrMulticast[TYPE_AC0DMA] +
                                                                   pStatistic->dwTsrMulticast[TYPE_TXDMA0]);
-    p802_11Counter->FailedCount = (ULONGLONG) (pStatistic->dwTsrErr[TYPE_AC0DMA] + pStatistic->dwTsrErr[TYPE_TXDMA0]);
-    p802_11Counter->RetryCount = (ULONGLONG) (pStatistic->dwTsrRetry[TYPE_AC0DMA] + pStatistic->dwTsrRetry[TYPE_TXDMA0]);
-    p802_11Counter->MultipleRetryCount = (ULONGLONG) (pStatistic->dwTsrMoreThanOnceRetry[TYPE_AC0DMA] +
+    p802_11Counter->FailedCount = (unsigned long long) (pStatistic->dwTsrErr[TYPE_AC0DMA] + pStatistic->dwTsrErr[TYPE_TXDMA0]);
+    p802_11Counter->RetryCount = (unsigned long long) (pStatistic->dwTsrRetry[TYPE_AC0DMA] + pStatistic->dwTsrRetry[TYPE_TXDMA0]);
+    p802_11Counter->MultipleRetryCount = (unsigned long long) (pStatistic->dwTsrMoreThanOnceRetry[TYPE_AC0DMA] +
                                                           pStatistic->dwTsrMoreThanOnceRetry[TYPE_TXDMA0]);
     //p802_11Counter->FrameDuplicateCount
-    p802_11Counter->RTSSuccessCount += (ULONGLONG)  (dwCounter & 0x000000ff);
-    p802_11Counter->RTSFailureCount += (ULONGLONG) ((dwCounter & 0x0000ff00) >> 8);
-    p802_11Counter->ACKFailureCount += (ULONGLONG) ((dwCounter & 0x00ff0000) >> 16);
-    p802_11Counter->FCSErrorCount +=   (ULONGLONG) ((dwCounter & 0xff000000) >> 24);
+    p802_11Counter->RTSSuccessCount += (unsigned long long)  (dwCounter & 0x000000ff);
+    p802_11Counter->RTSFailureCount += (unsigned long long) ((dwCounter & 0x0000ff00) >> 8);
+    p802_11Counter->ACKFailureCount += (unsigned long long) ((dwCounter & 0x00ff0000) >> 16);
+    p802_11Counter->FCSErrorCount +=   (unsigned long long) ((dwCounter & 0xff000000) >> 24);
     //p802_11Counter->ReceivedFragmentCount
-    p802_11Counter->MulticastReceivedFrameCount = (ULONGLONG) (pStatistic->dwRsrBroadcast +
+    p802_11Counter->MulticastReceivedFrameCount = (unsigned long long) (pStatistic->dwRsrBroadcast +
                                                                pStatistic->dwRsrMulticast);
 }
 
index 2308319a4051e5925863dbec1797b84fe8870321..009f3a4d29f600fc5819747dde4724933cff4c77 100644 (file)
 //
 
 typedef struct tagSDot11Counters {
-    ULONG       Length;             // Length of structure
-    ULONGLONG   TransmittedFragmentCount;
-    ULONGLONG   MulticastTransmittedFrameCount;
-    ULONGLONG   FailedCount;
-    ULONGLONG   RetryCount;
-    ULONGLONG   MultipleRetryCount;
-    ULONGLONG   RTSSuccessCount;
-    ULONGLONG   RTSFailureCount;
-    ULONGLONG   ACKFailureCount;
-    ULONGLONG   FrameDuplicateCount;
-    ULONGLONG   ReceivedFragmentCount;
-    ULONGLONG   MulticastReceivedFrameCount;
-    ULONGLONG   FCSErrorCount;
-    ULONGLONG   TKIPLocalMICFailures;
-    ULONGLONG   TKIPRemoteMICFailures;
-    ULONGLONG   TKIPICVErrors;
-    ULONGLONG   TKIPCounterMeasuresInvoked;
-    ULONGLONG   TKIPReplays;
-    ULONGLONG   CCMPFormatErrors;
-    ULONGLONG   CCMPReplays;
-    ULONGLONG   CCMPDecryptErrors;
-    ULONGLONG   FourWayHandshakeFailures;
-//    ULONGLONG   WEPUndecryptableCount;
-//    ULONGLONG   WEPICVErrorCount;
-//    ULONGLONG   DecryptSuccessCount;
-//    ULONGLONG   DecryptFailureCount;
+    unsigned long Length;             // Length of structure
+    unsigned long long   TransmittedFragmentCount;
+    unsigned long long   MulticastTransmittedFrameCount;
+    unsigned long long   FailedCount;
+    unsigned long long   RetryCount;
+    unsigned long long   MultipleRetryCount;
+    unsigned long long   RTSSuccessCount;
+    unsigned long long   RTSFailureCount;
+    unsigned long long   ACKFailureCount;
+    unsigned long long   FrameDuplicateCount;
+    unsigned long long   ReceivedFragmentCount;
+    unsigned long long   MulticastReceivedFrameCount;
+    unsigned long long   FCSErrorCount;
+    unsigned long long   TKIPLocalMICFailures;
+    unsigned long long   TKIPRemoteMICFailures;
+    unsigned long long   TKIPICVErrors;
+    unsigned long long   TKIPCounterMeasuresInvoked;
+    unsigned long long   TKIPReplays;
+    unsigned long long   CCMPFormatErrors;
+    unsigned long long   CCMPReplays;
+    unsigned long long   CCMPDecryptErrors;
+    unsigned long long   FourWayHandshakeFailures;
+//    unsigned long long   WEPUndecryptableCount;
+//    unsigned long long   WEPICVErrorCount;
+//    unsigned long long   DecryptSuccessCount;
+//    unsigned long long   DecryptFailureCount;
 } SDot11Counters, *PSDot11Counters;
 
 
@@ -72,29 +72,29 @@ typedef struct tagSDot11Counters {
 // MIB2 counter
 //
 typedef struct tagSMib2Counter {
-    LONG    ifIndex;
+    long    ifIndex;
     char    ifDescr[256];               // max size 255 plus zero ending
                                         // e.g. "interface 1"
-    LONG    ifType;
-    LONG    ifMtu;
-    DWORD   ifSpeed;
-    BYTE    ifPhysAddress[ETH_ALEN];
-    LONG    ifAdminStatus;
-    LONG    ifOperStatus;
-    DWORD   ifLastChange;
-    DWORD   ifInOctets;
-    DWORD   ifInUcastPkts;
-    DWORD   ifInNUcastPkts;
-    DWORD   ifInDiscards;
-    DWORD   ifInErrors;
-    DWORD   ifInUnknownProtos;
-    DWORD   ifOutOctets;
-    DWORD   ifOutUcastPkts;
-    DWORD   ifOutNUcastPkts;
-    DWORD   ifOutDiscards;
-    DWORD   ifOutErrors;
-    DWORD   ifOutQLen;
-    DWORD   ifSpecific;
+    long    ifType;
+    long    ifMtu;
+    unsigned long ifSpeed;
+    unsigned char ifPhysAddress[ETH_ALEN];
+    long    ifAdminStatus;
+    long    ifOperStatus;
+    unsigned long ifLastChange;
+    unsigned long ifInOctets;
+    unsigned long ifInUcastPkts;
+    unsigned long ifInNUcastPkts;
+    unsigned long ifInDiscards;
+    unsigned long ifInErrors;
+    unsigned long ifInUnknownProtos;
+    unsigned long ifOutOctets;
+    unsigned long ifOutUcastPkts;
+    unsigned long ifOutNUcastPkts;
+    unsigned long ifOutDiscards;
+    unsigned long ifOutErrors;
+    unsigned long ifOutQLen;
+    unsigned long ifSpecific;
 } SMib2Counter, *PSMib2Counter;
 
 // Value in the ifType entry
@@ -111,64 +111,64 @@ typedef struct tagSMib2Counter {
 // RMON counter
 //
 typedef struct tagSRmonCounter {
-    LONG    etherStatsIndex;
-    DWORD   etherStatsDataSource;
-    DWORD   etherStatsDropEvents;
-    DWORD   etherStatsOctets;
-    DWORD   etherStatsPkts;
-    DWORD   etherStatsBroadcastPkts;
-    DWORD   etherStatsMulticastPkts;
-    DWORD   etherStatsCRCAlignErrors;
-    DWORD   etherStatsUndersizePkts;
-    DWORD   etherStatsOversizePkts;
-    DWORD   etherStatsFragments;
-    DWORD   etherStatsJabbers;
-    DWORD   etherStatsCollisions;
-    DWORD   etherStatsPkt64Octets;
-    DWORD   etherStatsPkt65to127Octets;
-    DWORD   etherStatsPkt128to255Octets;
-    DWORD   etherStatsPkt256to511Octets;
-    DWORD   etherStatsPkt512to1023Octets;
-    DWORD   etherStatsPkt1024to1518Octets;
-    DWORD   etherStatsOwners;
-    DWORD   etherStatsStatus;
+    long    etherStatsIndex;
+    unsigned long etherStatsDataSource;
+    unsigned long etherStatsDropEvents;
+    unsigned long etherStatsOctets;
+    unsigned long etherStatsPkts;
+    unsigned long etherStatsBroadcastPkts;
+    unsigned long etherStatsMulticastPkts;
+    unsigned long etherStatsCRCAlignErrors;
+    unsigned long etherStatsUndersizePkts;
+    unsigned long etherStatsOversizePkts;
+    unsigned long etherStatsFragments;
+    unsigned long etherStatsJabbers;
+    unsigned long etherStatsCollisions;
+    unsigned long etherStatsPkt64Octets;
+    unsigned long etherStatsPkt65to127Octets;
+    unsigned long etherStatsPkt128to255Octets;
+    unsigned long etherStatsPkt256to511Octets;
+    unsigned long etherStatsPkt512to1023Octets;
+    unsigned long etherStatsPkt1024to1518Octets;
+    unsigned long etherStatsOwners;
+    unsigned long etherStatsStatus;
 } SRmonCounter, *PSRmonCounter;
 
 //
 // Custom counter
 //
 typedef struct tagSCustomCounters {
-    ULONG       Length;
-
-    ULONGLONG   ullTsrAllOK;
-
-    ULONGLONG   ullRsr11M;
-    ULONGLONG   ullRsr5M;
-    ULONGLONG   ullRsr2M;
-    ULONGLONG   ullRsr1M;
-
-    ULONGLONG   ullRsr11MCRCOk;
-    ULONGLONG   ullRsr5MCRCOk;
-    ULONGLONG   ullRsr2MCRCOk;
-    ULONGLONG   ullRsr1MCRCOk;
-
-    ULONGLONG   ullRsr54M;
-    ULONGLONG   ullRsr48M;
-    ULONGLONG   ullRsr36M;
-    ULONGLONG   ullRsr24M;
-    ULONGLONG   ullRsr18M;
-    ULONGLONG   ullRsr12M;
-    ULONGLONG   ullRsr9M;
-    ULONGLONG   ullRsr6M;
-
-    ULONGLONG   ullRsr54MCRCOk;
-    ULONGLONG   ullRsr48MCRCOk;
-    ULONGLONG   ullRsr36MCRCOk;
-    ULONGLONG   ullRsr24MCRCOk;
-    ULONGLONG   ullRsr18MCRCOk;
-    ULONGLONG   ullRsr12MCRCOk;
-    ULONGLONG   ullRsr9MCRCOk;
-    ULONGLONG   ullRsr6MCRCOk;
+    unsigned long Length;
+
+    unsigned long long   ullTsrAllOK;
+
+    unsigned long long   ullRsr11M;
+    unsigned long long   ullRsr5M;
+    unsigned long long   ullRsr2M;
+    unsigned long long   ullRsr1M;
+
+    unsigned long long   ullRsr11MCRCOk;
+    unsigned long long   ullRsr5MCRCOk;
+    unsigned long long   ullRsr2MCRCOk;
+    unsigned long long   ullRsr1MCRCOk;
+
+    unsigned long long   ullRsr54M;
+    unsigned long long   ullRsr48M;
+    unsigned long long   ullRsr36M;
+    unsigned long long   ullRsr24M;
+    unsigned long long   ullRsr18M;
+    unsigned long long   ullRsr12M;
+    unsigned long long   ullRsr9M;
+    unsigned long long   ullRsr6M;
+
+    unsigned long long   ullRsr54MCRCOk;
+    unsigned long long   ullRsr48MCRCOk;
+    unsigned long long   ullRsr36MCRCOk;
+    unsigned long long   ullRsr24MCRCOk;
+    unsigned long long   ullRsr18MCRCOk;
+    unsigned long long   ullRsr12MCRCOk;
+    unsigned long long   ullRsr9MCRCOk;
+    unsigned long long   ullRsr6MCRCOk;
 
 } SCustomCounters, *PSCustomCounters;
 
@@ -177,29 +177,29 @@ typedef struct tagSCustomCounters {
 // Custom counter
 //
 typedef struct tagSISRCounters {
-    ULONG   Length;
-
-    DWORD   dwIsrTx0OK;
-    DWORD   dwIsrAC0TxOK;
-    DWORD   dwIsrBeaconTxOK;
-    DWORD   dwIsrRx0OK;
-    DWORD   dwIsrTBTTInt;
-    DWORD   dwIsrSTIMERInt;
-    DWORD   dwIsrWatchDog;
-    DWORD   dwIsrUnrecoverableError;
-    DWORD   dwIsrSoftInterrupt;
-    DWORD   dwIsrMIBNearfull;
-    DWORD   dwIsrRxNoBuf;
-
-    DWORD   dwIsrUnknown;               // unknown interrupt count
-
-    DWORD   dwIsrRx1OK;
-    DWORD   dwIsrATIMTxOK;
-    DWORD   dwIsrSYNCTxOK;
-    DWORD   dwIsrCFPEnd;
-    DWORD   dwIsrATIMEnd;
-    DWORD   dwIsrSYNCFlushOK;
-    DWORD   dwIsrSTIMER1Int;
+    unsigned long Length;
+
+    unsigned long dwIsrTx0OK;
+    unsigned long dwIsrAC0TxOK;
+    unsigned long dwIsrBeaconTxOK;
+    unsigned long dwIsrRx0OK;
+    unsigned long dwIsrTBTTInt;
+    unsigned long dwIsrSTIMERInt;
+    unsigned long dwIsrWatchDog;
+    unsigned long dwIsrUnrecoverableError;
+    unsigned long dwIsrSoftInterrupt;
+    unsigned long dwIsrMIBNearfull;
+    unsigned long dwIsrRxNoBuf;
+
+    unsigned long dwIsrUnknown;               // unknown interrupt count
+
+    unsigned long dwIsrRx1OK;
+    unsigned long dwIsrATIMTxOK;
+    unsigned long dwIsrSYNCTxOK;
+    unsigned long dwIsrCFPEnd;
+    unsigned long dwIsrATIMEnd;
+    unsigned long dwIsrSYNCFlushOK;
+    unsigned long dwIsrSTIMER1Int;
     /////////////////////////////////////
 } SISRCounters, *PSISRCounters;
 
@@ -222,99 +222,99 @@ typedef struct tagSStatCounter {
 
     // RSR status count
     //
-    DWORD   dwRsrFrmAlgnErr;
-    DWORD   dwRsrErr;
-    DWORD   dwRsrCRCErr;
-    DWORD   dwRsrCRCOk;
-    DWORD   dwRsrBSSIDOk;
-    DWORD   dwRsrADDROk;
-    DWORD   dwRsrBCNSSIDOk;
-    DWORD   dwRsrLENErr;
-    DWORD   dwRsrTYPErr;
-
-    DWORD   dwNewRsrDECRYPTOK;
-    DWORD   dwNewRsrCFP;
-    DWORD   dwNewRsrUTSF;
-    DWORD   dwNewRsrHITAID;
-    DWORD   dwNewRsrHITAID0;
-
-    DWORD   dwRsrLong;
-    DWORD   dwRsrRunt;
-
-    DWORD   dwRsrRxControl;
-    DWORD   dwRsrRxData;
-    DWORD   dwRsrRxManage;
-
-    DWORD   dwRsrRxPacket;
-    DWORD   dwRsrRxOctet;
-    DWORD   dwRsrBroadcast;
-    DWORD   dwRsrMulticast;
-    DWORD   dwRsrDirected;
+    unsigned long dwRsrFrmAlgnErr;
+    unsigned long dwRsrErr;
+    unsigned long dwRsrCRCErr;
+    unsigned long dwRsrCRCOk;
+    unsigned long dwRsrBSSIDOk;
+    unsigned long dwRsrADDROk;
+    unsigned long dwRsrBCNSSIDOk;
+    unsigned long dwRsrLENErr;
+    unsigned long dwRsrTYPErr;
+
+    unsigned long dwNewRsrDECRYPTOK;
+    unsigned long dwNewRsrCFP;
+    unsigned long dwNewRsrUTSF;
+    unsigned long dwNewRsrHITAID;
+    unsigned long dwNewRsrHITAID0;
+
+    unsigned long dwRsrLong;
+    unsigned long dwRsrRunt;
+
+    unsigned long dwRsrRxControl;
+    unsigned long dwRsrRxData;
+    unsigned long dwRsrRxManage;
+
+    unsigned long dwRsrRxPacket;
+    unsigned long dwRsrRxOctet;
+    unsigned long dwRsrBroadcast;
+    unsigned long dwRsrMulticast;
+    unsigned long dwRsrDirected;
     // 64-bit OID
-    ULONGLONG   ullRsrOK;
+    unsigned long long   ullRsrOK;
 
     // for some optional OIDs (64 bits) and DMI support
-    ULONGLONG   ullRxBroadcastBytes;
-    ULONGLONG   ullRxMulticastBytes;
-    ULONGLONG   ullRxDirectedBytes;
-    ULONGLONG   ullRxBroadcastFrames;
-    ULONGLONG   ullRxMulticastFrames;
-    ULONGLONG   ullRxDirectedFrames;
-
-    DWORD   dwRsrRxFragment;
-    DWORD   dwRsrRxFrmLen64;
-    DWORD   dwRsrRxFrmLen65_127;
-    DWORD   dwRsrRxFrmLen128_255;
-    DWORD   dwRsrRxFrmLen256_511;
-    DWORD   dwRsrRxFrmLen512_1023;
-    DWORD   dwRsrRxFrmLen1024_1518;
+    unsigned long long   ullRxBroadcastBytes;
+    unsigned long long   ullRxMulticastBytes;
+    unsigned long long   ullRxDirectedBytes;
+    unsigned long long   ullRxBroadcastFrames;
+    unsigned long long   ullRxMulticastFrames;
+    unsigned long long   ullRxDirectedFrames;
+
+    unsigned long dwRsrRxFragment;
+    unsigned long dwRsrRxFrmLen64;
+    unsigned long dwRsrRxFrmLen65_127;
+    unsigned long dwRsrRxFrmLen128_255;
+    unsigned long dwRsrRxFrmLen256_511;
+    unsigned long dwRsrRxFrmLen512_1023;
+    unsigned long dwRsrRxFrmLen1024_1518;
 
     // TSR status count
     //
-    DWORD   dwTsrTotalRetry[TYPE_MAXTD];        // total collision retry count
-    DWORD   dwTsrOnceRetry[TYPE_MAXTD];         // this packet only occur one collision
-    DWORD   dwTsrMoreThanOnceRetry[TYPE_MAXTD]; // this packet occur more than one collision
-    DWORD   dwTsrRetry[TYPE_MAXTD];             // this packet has ever occur collision,
+    unsigned long dwTsrTotalRetry[TYPE_MAXTD];        // total collision retry count
+    unsigned long dwTsrOnceRetry[TYPE_MAXTD];         // this packet only occur one collision
+    unsigned long dwTsrMoreThanOnceRetry[TYPE_MAXTD]; // this packet occur more than one collision
+    unsigned long dwTsrRetry[TYPE_MAXTD];             // this packet has ever occur collision,
                                          // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0)
-    DWORD   dwTsrACKData[TYPE_MAXTD];
-    DWORD   dwTsrErr[TYPE_MAXTD];
-    DWORD   dwAllTsrOK[TYPE_MAXTD];
-    DWORD   dwTsrRetryTimeout[TYPE_MAXTD];
-    DWORD   dwTsrTransmitTimeout[TYPE_MAXTD];
-
-    DWORD   dwTsrTxPacket[TYPE_MAXTD];
-    DWORD   dwTsrTxOctet[TYPE_MAXTD];
-    DWORD   dwTsrBroadcast[TYPE_MAXTD];
-    DWORD   dwTsrMulticast[TYPE_MAXTD];
-    DWORD   dwTsrDirected[TYPE_MAXTD];
+    unsigned long dwTsrACKData[TYPE_MAXTD];
+    unsigned long dwTsrErr[TYPE_MAXTD];
+    unsigned long dwAllTsrOK[TYPE_MAXTD];
+    unsigned long dwTsrRetryTimeout[TYPE_MAXTD];
+    unsigned long dwTsrTransmitTimeout[TYPE_MAXTD];
+
+    unsigned long dwTsrTxPacket[TYPE_MAXTD];
+    unsigned long dwTsrTxOctet[TYPE_MAXTD];
+    unsigned long dwTsrBroadcast[TYPE_MAXTD];
+    unsigned long dwTsrMulticast[TYPE_MAXTD];
+    unsigned long dwTsrDirected[TYPE_MAXTD];
 
     // RD/TD count
-    DWORD   dwCntRxFrmLength;
-    DWORD   dwCntTxBufLength;
+    unsigned long dwCntRxFrmLength;
+    unsigned long dwCntTxBufLength;
 
-    BYTE    abyCntRxPattern[16];
-    BYTE    abyCntTxPattern[16];
+    unsigned char abyCntRxPattern[16];
+    unsigned char abyCntTxPattern[16];
 
 
 
     // Software check....
-    DWORD   dwCntRxDataErr;             // rx buffer data software compare CRC err count
-    DWORD   dwCntDecryptErr;            // rx buffer data software compare CRC err count
-    DWORD   dwCntRxICVErr;              // rx buffer data software compare CRC err count
-    UINT    idxRxErrorDesc[TYPE_MAXRD]; // index for rx data error RD
+    unsigned long dwCntRxDataErr;             // rx buffer data software compare CRC err count
+    unsigned long dwCntDecryptErr;            // rx buffer data software compare CRC err count
+    unsigned long dwCntRxICVErr;              // rx buffer data software compare CRC err count
+    unsigned int idxRxErrorDesc[TYPE_MAXRD]; // index for rx data error RD
 
     // 64-bit OID
-    ULONGLONG   ullTsrOK[TYPE_MAXTD];
+    unsigned long long   ullTsrOK[TYPE_MAXTD];
 
     // for some optional OIDs (64 bits) and DMI support
-    ULONGLONG   ullTxBroadcastFrames[TYPE_MAXTD];
-    ULONGLONG   ullTxMulticastFrames[TYPE_MAXTD];
-    ULONGLONG   ullTxDirectedFrames[TYPE_MAXTD];
-    ULONGLONG   ullTxBroadcastBytes[TYPE_MAXTD];
-    ULONGLONG   ullTxMulticastBytes[TYPE_MAXTD];
-    ULONGLONG   ullTxDirectedBytes[TYPE_MAXTD];
-
-//    DWORD   dwTxRetryCount[8];
+    unsigned long long   ullTxBroadcastFrames[TYPE_MAXTD];
+    unsigned long long   ullTxMulticastFrames[TYPE_MAXTD];
+    unsigned long long   ullTxDirectedFrames[TYPE_MAXTD];
+    unsigned long long   ullTxBroadcastBytes[TYPE_MAXTD];
+    unsigned long long   ullTxMulticastBytes[TYPE_MAXTD];
+    unsigned long long   ullTxDirectedBytes[TYPE_MAXTD];
+
+//    unsigned long dwTxRetryCount[8];
     //
     // ISR status count
     //
@@ -324,15 +324,15 @@ typedef struct tagSStatCounter {
 
    #ifdef Calcu_LinkQual
        //Tx count:
-    ULONG TxNoRetryOkCount;         //success tx no retry !
-    ULONG TxRetryOkCount;              //success tx but retry !
-    ULONG TxFailCount;                      //fail tx ?
+    unsigned long TxNoRetryOkCount;         //success tx no retry !
+    unsigned long TxRetryOkCount;              //success tx but retry !
+    unsigned long TxFailCount;                      //fail tx ?
       //Rx count:
-    ULONG RxOkCnt;                          //success rx !
-    ULONG RxFcsErrCnt;                    //fail rx ?
+    unsigned long RxOkCnt;                          //success rx !
+    unsigned long RxFcsErrCnt;                    //fail rx ?
       //statistic
-    ULONG SignalStren;
-    ULONG LinkQuality;
+    unsigned long SignalStren;
+    unsigned long LinkQuality;
    #endif
 } SStatCounter, *PSStatCounter;
 
@@ -344,30 +344,29 @@ typedef struct tagSStatCounter {
 
 void STAvClearAllCounter(PSStatCounter pStatistic);
 
-void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, DWORD dwIsr);
+void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr);
 
 void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
-                              BYTE byRSR, BYTE byNewRSR, BYTE byRxRate,
-                              PBYTE pbyBuffer, UINT cbFrameLength);
+                              unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate,
+                              unsigned char *pbyBuffer, unsigned int cbFrameLength);
 
 void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic,
-                              BYTE byRSR, BYTE byNewRsr, BYTE byRxRate,
-                              PBYTE pbyBuffer, UINT cbFrameLength);
+                              unsigned char byRSR, unsigned char byNewRsr, unsigned char byRxRate,
+                              unsigned char *pbyBuffer, unsigned int cbFrameLength);
 
-void STAvUpdateTDStatCounter(PSStatCounter pStatistic,
-                             BYTE byTSR0, BYTE byTSR1,
-                             PBYTE pbyBuffer, UINT cbFrameLength, UINT uIdx );
+void STAvUpdateTDStatCounter(PSStatCounter pStatistic, unsigned char byTSR0, unsigned char byTSR1,
+               unsigned char *pbyBuffer, unsigned int cbFrameLength, unsigned int uIdx);
 
 void STAvUpdateTDStatCounterEx(
     PSStatCounter   pStatistic,
-    PBYTE           pbyBuffer,
-    DWORD           cbFrameLength
+    unsigned char *pbyBuffer,
+    unsigned long cbFrameLength
     );
 
 void STAvUpdate802_11Counter(
     PSDot11Counters p802_11Counter,
     PSStatCounter   pStatistic,
-    DWORD           dwCounter
+    unsigned long dwCounter
     );
 
 void STAvClear802_11Counter(PSDot11Counters p802_11Counter);
index 0bf57efdede071df4d1032a772c907a105513705..67618f069d0d96425c65faa835e7d20a8d88f010 100644 (file)
@@ -26,8 +26,8 @@
  * Date: Sep 4, 2002
  *
  * Functions:
- *      s_dwGetUINT32 - Convert from BYTE[] to DWORD in a portable way
- *      s_vPutUINT32 - Convert from DWORD to BYTE[] in a portable way
+ *      s_dwGetUINT32 - Convert from unsigned char [] to unsigned long in a portable way
+ *      s_vPutUINT32 - Convert from unsigned long to unsigned char [] in a portable way
  *      s_vClear - Reset the state to the empty message.
  *      s_vSetKey - Set the key.
  *      MIC_vInit - Set the key.
 
 /*---------------------  Static Functions  --------------------------*/
 /*
-static DWORD s_dwGetUINT32(BYTE * p);         // Get DWORD from 4 bytes LSByte first
-static void s_vPutUINT32(BYTE* p, DWORD val); // Put DWORD into 4 bytes LSByte first
+static unsigned long s_dwGetUINT32(unsigned char *p);         // Get unsigned long from 4 bytes LSByte first
+static void s_vPutUINT32(unsigned char *p, unsigned long val); // Put unsigned long into 4 bytes LSByte first
 */
 static void s_vClear(void);                       // Clear the internal message,
                                               // resets the object to the state just after construction.
-static void s_vSetKey(DWORD dwK0, DWORD dwK1);
-static void s_vAppendByte(BYTE b);            // Add a single byte to the internal message
+static void s_vSetKey(unsigned long dwK0, unsigned long dwK1);
+static void s_vAppendByte(unsigned char b);            // Add a single byte to the internal message
 
 /*---------------------  Export Variables  --------------------------*/
-static DWORD  L, R;           // Current state
+static unsigned long L, R;           // Current state
 
-static DWORD  K0, K1;         // Key
-static DWORD  M;              // Message accumulator (single word)
-static UINT   nBytesInM;      // # bytes in M
+static unsigned long K0, K1;         // Key
+static unsigned long M;              // Message accumulator (single word)
+static unsigned int nBytesInM;      // # bytes in M
 
 /*---------------------  Export Functions  --------------------------*/
 
 /*
-static DWORD s_dwGetUINT32 (BYTE * p)
-// Convert from BYTE[] to DWORD in a portable way
+static unsigned long s_dwGetUINT32 (unsigned char *p)
+// Convert from unsigned char [] to unsigned long in a portable way
 {
-    DWORD res = 0;
-    UINT i;
+    unsigned long res = 0;
+    unsigned int i;
     for(i=0; i<4; i++ )
     {
         res |= (*p++) << (8*i);
@@ -78,13 +78,13 @@ static DWORD s_dwGetUINT32 (BYTE * p)
     return res;
 }
 
-static void s_vPutUINT32 (BYTE* p, DWORD val)
-// Convert from DWORD to BYTE[] in a portable way
+static void s_vPutUINT32 (unsigned char *p, unsigned long val)
+// Convert from unsigned long to unsigned char [] in a portable way
 {
-    UINT i;
+    unsigned int i;
     for(i=0; i<4; i++ )
     {
-        *p++ = (BYTE) (val & 0xff);
+        *p++ = (unsigned char) (val & 0xff);
         val >>= 8;
     }
 }
@@ -99,7 +99,7 @@ static void s_vClear (void)
     M = 0;
 }
 
-static void s_vSetKey (DWORD dwK0, DWORD dwK1)
+static void s_vSetKey (unsigned long dwK0, unsigned long dwK1)
 {
     // Set the key
     K0 = dwK0;
@@ -108,7 +108,7 @@ static void s_vSetKey (DWORD dwK0, DWORD dwK1)
     s_vClear();
 }
 
-static void s_vAppendByte (BYTE b)
+static void s_vAppendByte (unsigned char b)
 {
     // Append the byte to our word-sized buffer
     M |= b << (8*nBytesInM);
@@ -131,7 +131,7 @@ static void s_vAppendByte (BYTE b)
     }
 }
 
-void MIC_vInit (DWORD dwK0, DWORD dwK1)
+void MIC_vInit (unsigned long dwK0, unsigned long dwK1)
 {
     // Set the key
     s_vSetKey(dwK0, dwK1);
@@ -149,7 +149,7 @@ void MIC_vUnInit (void)
     s_vClear();
 }
 
-void MIC_vAppend (PBYTE src, UINT nBytes)
+void MIC_vAppend (unsigned char *src, unsigned int nBytes)
 {
     // This is simple
     while (nBytes > 0)
@@ -159,7 +159,7 @@ void MIC_vAppend (PBYTE src, UINT nBytes)
     }
 }
 
-void MIC_vGetMIC (PDWORD pdwL, PDWORD pdwR)
+void MIC_vGetMIC (unsigned long *pdwL, unsigned long *pdwR)
 {
     // Append the minimum padding
     s_vAppendByte(0x5a);
index 97de77b4da2c1935f509011c554a283a25230f48..3131b161d6a9a235e7f507067637ee7dbb2f05bf 100644 (file)
 
 /*---------------------  Export Types  ------------------------------*/
 
-void MIC_vInit(DWORD dwK0, DWORD dwK1);
+void MIC_vInit(unsigned long dwK0, unsigned long dwK1);
 
 void MIC_vUnInit(void);
 
 // Append bytes to the message to be MICed
-void MIC_vAppend(PBYTE src, UINT nBytes);
+void MIC_vAppend(unsigned char *src, unsigned int nBytes);
 
 // Get the MIC result. Destination should accept 8 bytes of result.
 // This also resets the message to empty.
-void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR);
+void MIC_vGetMIC(unsigned long *pdwL, unsigned long *pdwR);
 
 /*---------------------  Export Macros ------------------------------*/
 
index 64c22c3e4bb39162e1197142b3529f60dbfa8a9b..7207aca1301252999d7f920d66df0e8dae328c9d 100644 (file)
@@ -77,12 +77,12 @@ static int          msglevel                =MSG_LEVEL_INFO;
 void
 PSvEnablePowerSaving(
     void *hDeviceContext,
-    WORD wListenInterval
+    unsigned short wListenInterval
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    WORD            wAID = pMgmt->wCurrAID | BIT14 | BIT15;
+    unsigned short wAID = pMgmt->wCurrAID | BIT14 | BIT15;
 
     // set period of power up before TBTT
     VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT);
@@ -115,7 +115,7 @@ PSvEnablePowerSaving(
 
     // enable power saving hw function
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
-    pDevice->bEnablePSMode = TRUE;
+    pDevice->bEnablePSMode = true;
 
     if (pDevice->eOPMode == OP_MODE_ADHOC) {
 //        bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
@@ -124,7 +124,7 @@ PSvEnablePowerSaving(
     else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
         PSbSendNullPacket(pDevice);
     }
-    pDevice->bPWBitOn = TRUE;
+    pDevice->bPWBitOn = true;
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n");
     return;
 }
@@ -161,12 +161,12 @@ PSvDisablePowerSaving(
     // set always listen beacon
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
 
-    pDevice->bEnablePSMode = FALSE;
+    pDevice->bEnablePSMode = false;
 
     if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
         PSbSendNullPacket(pDevice);
     }
-    pDevice->bPWBitOn = FALSE;
+    pDevice->bPWBitOn = false;
     return;
 }
 
@@ -177,35 +177,35 @@ PSvDisablePowerSaving(
  * Consider to power down when no more packets to tx or rx.
  *
  * Return Value:
- *    TRUE, if power down success
- *    FALSE, if fail
+ *    true, if power down success
+ *    false, if fail
 -*/
 
 
-BOOL
+bool
 PSbConsiderPowerDown(
     void *hDeviceContext,
-    BOOL bCheckRxDMA,
-    BOOL bCheckCountToWakeUp
+    bool bCheckRxDMA,
+    bool bCheckCountToWakeUp
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            uIdx;
+    unsigned int uIdx;
 
     // check if already in Doze mode
     if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS))
-        return TRUE;
+        return true;
 
     if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
         // check if in TIM wake period
         if (pMgmt->bInTIMWake)
-            return FALSE;
+            return false;
     }
 
     // check scan state
     if (pDevice->bCmdRunning)
-        return FALSE;
+        return false;
 
     // Froce PSEN on
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
@@ -213,27 +213,27 @@ PSbConsiderPowerDown(
     // check if all TD are empty,
     for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) {
         if (pDevice->iTDUsed[uIdx] != 0)
-            return FALSE;
+            return false;
     }
 
     // check if rx isr is clear
     if (bCheckRxDMA &&
         ((pDevice->dwIsr& ISR_RXDMA0) != 0) &&
         ((pDevice->dwIsr & ISR_RXDMA1) != 0)){
-        return FALSE;
+        return false;
     };
 
     if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
         if (bCheckCountToWakeUp &&
            (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) {
-             return FALSE;
+             return false;
         }
     }
 
     // no Tx, no Rx isr, now go to Doze
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
-    return TRUE;
+    return true;
 }
 
 
@@ -262,7 +262,7 @@ PSvSendPSPOLL(
 
     memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN);
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
     pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16(
          (
          WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) |
@@ -296,7 +296,7 @@ PSvSendPSPOLL(
  *    None.
  *
 -*/
-BOOL
+bool
 PSbSendNullPacket(
     void *hDeviceContext
     )
@@ -304,32 +304,32 @@ PSbSendNullPacket(
     PSDevice            pDevice = (PSDevice)hDeviceContext;
     PSTxMgmtPacket      pTxPacket = NULL;
     PSMgmtObject        pMgmt = pDevice->pMgmt;
-    UINT                uIdx;
+    unsigned int uIdx;
 
 
-    if (pDevice->bLinkPass == FALSE) {
-        return FALSE;
+    if (pDevice->bLinkPass == false) {
+        return false;
     }
     #ifdef TxInSleep
-     if ((pDevice->bEnablePSMode == FALSE) &&
-         (pDevice->fTxDataInSleep == FALSE)){
-        return FALSE;
+     if ((pDevice->bEnablePSMode == false) &&
+         (pDevice->fTxDataInSleep == false)){
+        return false;
     }
 #else
-    if (pDevice->bEnablePSMode == FALSE) {
-        return FALSE;
+    if (pDevice->bEnablePSMode == false) {
+        return false;
     }
 #endif
     if (pDevice->bEnablePSMode) {
         for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) {
             if (pDevice->iTDUsed[uIdx] != 0)
-                return FALSE;
+                return false;
         }
     }
 
     memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN);
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
 
     if (pDevice->bEnablePSMode) {
 
@@ -350,7 +350,7 @@ PSbSendNullPacket(
     }
 
     if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
-        pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1));
+        pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_TODS(1));
     }
 
     memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
@@ -361,7 +361,7 @@ PSbSendNullPacket(
     // send the frame
     if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
-        return FALSE;
+        return false;
     }
     else {
 
@@ -369,7 +369,7 @@ PSbSendNullPacket(
     }
 
 
-    return TRUE ;
+    return true ;
 }
 
 /*+
@@ -382,7 +382,7 @@ PSbSendNullPacket(
  *
 -*/
 
-BOOL
+bool
 PSbIsNextTBTTWakeUp(
     void *hDeviceContext
     )
@@ -390,7 +390,7 @@ PSbIsNextTBTTWakeUp(
 
     PSDevice         pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject        pMgmt = pDevice->pMgmt;
-    BOOL                bWakeUp = FALSE;
+    bool bWakeUp = false;
 
     if (pMgmt->wListenInterval >= 2) {
         if (pMgmt->wCountToWakeUp == 0) {
@@ -402,7 +402,7 @@ PSbIsNextTBTTWakeUp(
         if (pMgmt->wCountToWakeUp == 1) {
             // Turn on wake up to listen next beacon
             MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
-            bWakeUp = TRUE;
+            bWakeUp = true;
         }
 
     }
index c0dbe216e97765c3d6ecfb92f2f458464842cc86..01013b592285e53ca65ae33edf36c23f64f2eba4 100644 (file)
 // PSDevice pDevice
 // PSDevice hDeviceContext
 
-BOOL
+bool
 PSbConsiderPowerDown(
     void *hDeviceContext,
-    BOOL bCheckRxDMA,
-    BOOL bCheckCountToWakeUp
+    bool bCheckRxDMA,
+    bool bCheckCountToWakeUp
     );
 
 void
@@ -63,7 +63,7 @@ PSvDisablePowerSaving(
 void
 PSvEnablePowerSaving(
     void *hDeviceContext,
-    WORD wListenInterval
+    unsigned short wListenInterval
     );
 
 void
@@ -71,12 +71,12 @@ PSvSendPSPOLL(
     void *hDeviceContext
     );
 
-BOOL
+bool
 PSbSendNullPacket(
     void *hDeviceContext
     );
 
-BOOL
+bool
 PSbIsNextTBTTWakeUp(
     void *hDeviceContext
     );
index 4a53f159cb3072acc353b864d2a1f3a082954791..9856c08b3d77e4a1317b32bbcd18deb0e8687052 100644 (file)
 
 #include "rc4.h"
 
-void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len)
+void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len)
 {
-    UINT  ust1, ust2;
-    UINT  keyindex;
-    UINT  stateindex;
-    PBYTE pbyst;
-    UINT  idx;
+    unsigned int ust1, ust2;
+    unsigned int keyindex;
+    unsigned int stateindex;
+    unsigned char *pbyst;
+    unsigned int idx;
 
     pbyst = pRC4->abystate;
     pRC4->ux = 0;
     pRC4->uy = 0;
     for (idx = 0; idx < 256; idx++)
-        pbyst[idx] = (BYTE)idx;
+        pbyst[idx] = (unsigned char)idx;
     keyindex = 0;
     stateindex = 0;
     for (idx = 0; idx < 256; idx++) {
         ust1 = pbyst[idx];
         stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff;
         ust2 = pbyst[stateindex];
-        pbyst[stateindex] = (BYTE)ust1;
-        pbyst[idx] = (BYTE)ust2;
+        pbyst[stateindex] = (unsigned char)ust1;
+        pbyst[idx] = (unsigned char)ust2;
         if (++keyindex >= cbKey_len)
             keyindex = 0;
     }
 }
 
-UINT rc4_byte(PRC4Ext pRC4)
+unsigned int rc4_byte(PRC4Ext pRC4)
 {
-    UINT ux;
-    UINT uy;
-    UINT ustx, usty;
-    PBYTE pbyst;
+    unsigned int ux;
+    unsigned int uy;
+    unsigned int ustx, usty;
+    unsigned char *pbyst;
 
     pbyst = pRC4->abystate;
     ux = (pRC4->ux + 1) & 0xff;
@@ -72,16 +72,16 @@ UINT rc4_byte(PRC4Ext pRC4)
     usty = pbyst[uy];
     pRC4->ux = ux;
     pRC4->uy = uy;
-    pbyst[uy] = (BYTE)ustx;
-    pbyst[ux] = (BYTE)usty;
+    pbyst[uy] = (unsigned char)ustx;
+    pbyst[ux] = (unsigned char)usty;
 
     return pbyst[(ustx + usty) & 0xff];
 }
 
-void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest,
-                     PBYTE pbySrc, UINT cbData_len)
+void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest,
+                     unsigned char *pbySrc, unsigned int cbData_len)
 {
-    UINT ii;
+    unsigned int ii;
     for (ii = 0; ii < cbData_len; ii++)
-        pbyDest[ii] = (BYTE)(pbySrc[ii] ^ rc4_byte(pRC4));
+        pbyDest[ii] = (unsigned char)(pbySrc[ii] ^ rc4_byte(pRC4));
 }
index e65cae69efafb0e30b2aefddc53b5fae0d862c35..ad04e351365ef332e34e900fc5f3ca7002ce9b16 100644 (file)
 /*---------------------  Export Definitions -------------------------*/
 /*---------------------  Export Types  ------------------------------*/
 typedef struct {
-    UINT ux;
-    UINT uy;
-    BYTE abystate[256];
+    unsigned int ux;
+    unsigned int uy;
+    unsigned char abystate[256];
 } RC4Ext, *PRC4Ext;
 
-void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len);
-UINT rc4_byte(PRC4Ext pRC4);
-void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len);
+void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len);
+unsigned int rc4_byte(PRC4Ext pRC4);
+void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest, unsigned char *pbySrc, unsigned int cbData_len);
 
 #endif //__RC4_H__
index 7cb86fe2eeb95d418f8740b9e50a794417791c5e..b8ec783e55e0eb1c29a8c38f107129d0c717ce29 100644 (file)
@@ -94,7 +94,7 @@
 
 
 
-const DWORD dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
+const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
     0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
     0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
     0x01A00200+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
@@ -112,7 +112,7 @@ const DWORD dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
     0x00580F00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW
     };
 
-const DWORD dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
+const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
     0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
     0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
     0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
@@ -129,7 +129,7 @@ const DWORD dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
     0x03E7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
     };
 
-const DWORD dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
+const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
     0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
     0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
     0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
@@ -146,7 +146,7 @@ const DWORD dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
     0x06666100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
     };
 
-DWORD dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
+unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
     0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
     0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
     0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
@@ -216,7 +216,7 @@ DWORD dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
 //{{ RobertYu:20050104
 // 40MHz reference frequency
 // Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
-const DWORD dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
+const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
     0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
     0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
     0x841FF200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 451FE2
@@ -239,7 +239,7 @@ const DWORD dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
     0x1ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // Need modify for 11a: 12BACF
     };
 
-const DWORD dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
+const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
     0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
     0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
     0x451FE200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
@@ -259,7 +259,7 @@ const DWORD dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
     };
 
 
-const DWORD dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
+const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
     0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
     0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
     0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -325,7 +325,7 @@ const DWORD dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
     0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
     };
 
-const DWORD dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
+const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
     0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
     0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
     0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -389,7 +389,7 @@ const DWORD dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
     0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
     };
 
-const DWORD dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
+const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
     0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
     0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
     0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -471,15 +471,15 @@ const DWORD dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL s_bAL7230Init (DWORD_PTR dwIoBase)
+bool s_bAL7230Init (unsigned long dwIoBase)
 {
     int     ii;
-    BOOL    bResult;
+    bool bResult;
 
-    bResult = TRUE;
+    bResult = true;
 
     //3-wire control for normal mode
     VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0);
@@ -517,11 +517,11 @@ BOOL s_bAL7230Init (DWORD_PTR dwIoBase)
 }
 
 // Need to Pull PLLON low when writing channel registers through 3-wire interface
-BOOL s_bAL7230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
+bool s_bAL7230SelectChannel (unsigned long dwIoBase, unsigned char byChannel)
 {
-    BOOL    bResult;
+    bool bResult;
 
-    bResult = TRUE;
+    bResult = true;
 
     // PLLON Off
     MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
@@ -552,7 +552,7 @@ BOOL s_bAL7230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -567,7 +567,7 @@ BOOL s_bAL7230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -585,7 +585,7 @@ BOOL s_bAL7230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -599,7 +599,7 @@ BOOL s_bAL7230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -619,13 +619,13 @@ BOOL s_bAL7230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL IFRFbWriteEmbeded (DWORD_PTR dwIoBase, DWORD dwData)
+bool IFRFbWriteEmbeded (unsigned long dwIoBase, unsigned long dwData)
 {
-    WORD    ww;
-    DWORD   dwValue;
+    unsigned short ww;
+    unsigned long dwValue;
 
     VNSvOutPortD(dwIoBase + MAC_REG_IFREGCTL, dwData);
 
@@ -638,9 +638,9 @@ BOOL IFRFbWriteEmbeded (DWORD_PTR dwIoBase, DWORD dwData)
 
     if (ww == W_MAX_TIMEOUT) {
 //        DBG_PORT80_ALWAYS(0x32);
-        return FALSE;
+        return false;
     }
-    return TRUE;
+    return true;
 }
 
 
@@ -654,7 +654,7 @@ BOOL IFRFbWriteEmbeded (DWORD_PTR dwIoBase, DWORD dwData)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -668,7 +668,7 @@ BOOL IFRFbWriteEmbeded (DWORD_PTR dwIoBase, DWORD dwData)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -681,15 +681,15 @@ BOOL IFRFbWriteEmbeded (DWORD_PTR dwIoBase, DWORD dwData)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL RFbAL2230Init (DWORD_PTR dwIoBase)
+bool RFbAL2230Init (unsigned long dwIoBase)
 {
     int     ii;
-    BOOL    bResult;
+    bool bResult;
 
-    bResult = TRUE;
+    bResult = true;
 
     //3-wire control for normal mode
     VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0);
@@ -734,11 +734,11 @@ MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us
     return bResult;
 }
 
-BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
+bool RFbAL2230SelectChannel (unsigned long dwIoBase, unsigned char byChannel)
 {
-    BOOL    bResult;
+    bool bResult;
 
-    bResult = TRUE;
+    bResult = true;
 
     bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable0[byChannel-1]);
     bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable1[byChannel-1]);
@@ -761,7 +761,7 @@ BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -776,7 +776,7 @@ BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -790,7 +790,7 @@ BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
@@ -804,14 +804,14 @@ BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL RFbInit (
+bool RFbInit (
     PSDevice  pDevice
     )
 {
-BOOL    bResult = TRUE;
+bool bResult = true;
     switch (pDevice->byRFType) {
         case RF_AIROHA :
         case RF_AL2230S:
@@ -823,10 +823,10 @@ BOOL    bResult = TRUE;
             bResult = s_bAL7230Init(pDevice->PortOffset);
             break;
         case RF_NOTHING :
-            bResult = TRUE;
+            bResult = true;
             break;
         default :
-            bResult = FALSE;
+            bResult = false;
             break;
     }
     return bResult;
@@ -842,21 +842,21 @@ BOOL    bResult = TRUE;
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL RFbShutDown (
+bool RFbShutDown (
     PSDevice  pDevice
     )
 {
-BOOL    bResult = TRUE;
+bool bResult = true;
 
     switch (pDevice->byRFType) {
         case RF_AIROHA7230 :
             bResult = IFRFbWriteEmbeded (pDevice->PortOffset, 0x1ABAEF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
             break;
         default :
-            bResult = TRUE;
+            bResult = true;
             break;
     }
     return bResult;
@@ -872,12 +872,12 @@ BOOL    bResult = TRUE;
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL RFbSelectChannel (DWORD_PTR dwIoBase, BYTE byRFType, BYTE byChannel)
+bool RFbSelectChannel (unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel)
 {
-BOOL    bResult = TRUE;
+bool bResult = true;
     switch (byRFType) {
 
         case RF_AIROHA :
@@ -890,10 +890,10 @@ BOOL    bResult = TRUE;
             break;
         //}} RobertYu
         case RF_NOTHING :
-            bResult = TRUE;
+            bResult = true;
             break;
         default:
-            bResult = FALSE;
+            bResult = false;
             break;
     }
     return bResult;
@@ -911,11 +911,11 @@ BOOL    bResult = TRUE;
  * Return Value: None.
  *
  */
-BOOL RFvWriteWakeProgSyn (DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel)
+bool RFvWriteWakeProgSyn (unsigned long dwIoBase, unsigned char byRFType, unsigned int uChannel)
 {
     int   ii;
-    BYTE  byInitCount = 0;
-    BYTE  bySleepCount = 0;
+    unsigned char byInitCount = 0;
+    unsigned char bySleepCount = 0;
 
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, 0);
     switch (byRFType) {
@@ -923,20 +923,20 @@ BOOL RFvWriteWakeProgSyn (DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel)
         case RF_AL2230S:
 
             if (uChannel > CB_MAX_CHANNEL_24G)
-                return FALSE;
+                return false;
 
             byInitCount = CB_AL2230_INIT_SEQ + 2; // Init Reg + Channel Reg (2)
             bySleepCount = 0;
             if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) {
-                return FALSE;
+                return false;
             }
 
             for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++ ) {
-                MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230InitTable[ii]);
+                MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230InitTable[ii]);
             }
-            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable0[uChannel-1]);
+            MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable0[uChannel-1]);
             ii ++;
-            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable1[uChannel-1]);
+            MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable1[uChannel-1]);
             break;
 
         //{{ RobertYu: 20050104
@@ -945,42 +945,42 @@ BOOL RFvWriteWakeProgSyn (DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel)
             byInitCount = CB_AL7230_INIT_SEQ + 3; // Init Reg + Channel Reg (3)
             bySleepCount = 0;
             if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) {
-                return FALSE;
+                return false;
             }
 
             if (uChannel <= CB_MAX_CHANNEL_24G)
             {
                 for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++ ) {
-                    MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTable[ii]);
+                    MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTable[ii]);
                 }
             }
             else
             {
                 for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++ ) {
-                    MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTableAMode[ii]);
+                    MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTableAMode[ii]);
                 }
             }
 
-            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable0[uChannel-1]);
+            MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable0[uChannel-1]);
             ii ++;
-            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable1[uChannel-1]);
+            MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable1[uChannel-1]);
             ii ++;
-            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable2[uChannel-1]);
+            MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable2[uChannel-1]);
             break;
         //}} RobertYu
 
         case RF_NOTHING :
-            return TRUE;
+            return true;
             break;
 
         default:
-            return FALSE;
+            return false;
             break;
     }
 
-    MACvSetMISCFifo(dwIoBase, MISCFIFO_SYNINFO_IDX, (DWORD)MAKEWORD(bySleepCount, byInitCount));
+    MACvSetMISCFifo(dwIoBase, MISCFIFO_SYNINFO_IDX, (unsigned long )MAKEWORD(bySleepCount, byInitCount));
 
-    return TRUE;
+    return true;
 }
 
 /*
@@ -993,25 +993,25 @@ BOOL RFvWriteWakeProgSyn (DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL RFbSetPower (
+bool RFbSetPower (
     PSDevice  pDevice,
-    UINT      uRATE,
-    UINT      uCH
+    unsigned int uRATE,
+    unsigned int uCH
     )
 {
-BOOL    bResult = TRUE;
-BYTE    byPwr = 0;
-BYTE    byDec = 0;
-BYTE    byPwrdBm = 0;
+bool bResult = true;
+unsigned char byPwr = 0;
+unsigned char byDec = 0;
+unsigned char byPwrdBm = 0;
 
     if (pDevice->dwDiagRefCount != 0) {
-        return TRUE;
+        return true;
     }
     if ((uCH < 1) || (uCH > CB_MAX_CHANNEL)) {
-        return FALSE;
+        return false;
     }
 
     switch (uRATE) {
@@ -1070,7 +1070,7 @@ BYTE    byPwrdBm = 0;
 #if 0
 
     // 802.11h TPC
-    if (pDevice->bLinkPass == TRUE) {
+    if (pDevice->bLinkPass == true) {
         // do not over local constraint
         if (byPwrdBm > pDevice->abyLocalPwr[uCH]) {
             pDevice->byCurPwrdBm = pDevice->abyLocalPwr[uCH];
@@ -1111,11 +1111,11 @@ BYTE    byPwrdBm = 0;
 
 //    if (pDevice->byLocalID <= REV_ID_VT3253_B1) {
     if (pDevice->byCurPwr == byPwr) {
-        return TRUE;
+        return true;
     }
     bResult = RFbRawSetPower(pDevice, byPwr, uRATE);
 //    }
-    if (bResult == TRUE) {
+    if (bResult == true) {
        pDevice->byCurPwr = byPwr;
     }
     return bResult;
@@ -1131,21 +1131,21 @@ BYTE    byPwrdBm = 0;
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
 
-BOOL RFbRawSetPower (
+bool RFbRawSetPower (
     PSDevice  pDevice,
-    BYTE      byPwr,
-    UINT      uRATE
+    unsigned char byPwr,
+    unsigned int uRATE
     )
 {
-BOOL    bResult = TRUE;
-DWORD   dwMax7230Pwr = 0;
+bool bResult = true;
+unsigned long dwMax7230Pwr = 0;
 
     if (byPwr >=  pDevice->byMaxPwrLevel) {
-        return (FALSE);
+        return (false);
     }
     switch (pDevice->byRFType) {
 
@@ -1204,14 +1204,14 @@ DWORD   dwMax7230Pwr = 0;
 void
 RFvRSSITodBm (
     PSDevice pDevice,
-    BYTE     byCurrRSSI,
+    unsigned char byCurrRSSI,
     long *    pldBm
     )
 {
-    BYTE byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
-    LONG b = (byCurrRSSI & 0x3F);
-    LONG a = 0;
-    BYTE abyAIROHARF[4] = {0, 18, 0, 40};
+    unsigned char byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
+    long b = (byCurrRSSI & 0x3F);
+    long a = 0;
+    unsigned char abyAIROHARF[4] = {0, 18, 0, 40};
 
     switch (pDevice->byRFType) {
         case RF_AIROHA:
@@ -1232,11 +1232,11 @@ RFvRSSITodBm (
 
 // Post processing for the 11b/g and 11a.
 // for save time on changing Reg2,3,5,7,10,12,15
-BOOL RFbAL7230SelectChannelPostProcess (DWORD_PTR dwIoBase, BYTE byOldChannel, BYTE byNewChannel)
+bool RFbAL7230SelectChannelPostProcess (unsigned long dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel)
 {
-    BOOL    bResult;
+    bool bResult;
 
-    bResult = TRUE;
+    bResult = true;
 
     // if change between 11 b/g and 11a need to update the following register
     // Channel Index 1~14
index 25dfc7942f6760b29b34dd584f268fc760a4a2f4..1f8d82e130419cb04448ae3030c6cb3719714a3a 100644 (file)
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL IFRFbWriteEmbeded(DWORD_PTR dwIoBase, DWORD dwData);
-BOOL RFbSelectChannel(DWORD_PTR dwIoBase, BYTE byRFType, BYTE byChannel);
-BOOL RFbInit (
+bool IFRFbWriteEmbeded(unsigned long dwIoBase, unsigned long dwData);
+bool RFbSelectChannel(unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel);
+bool RFbInit (
     PSDevice  pDevice
     );
-BOOL RFvWriteWakeProgSyn(DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel);
-BOOL RFbSetPower(PSDevice pDevice, UINT uRATE, UINT uCH);
-BOOL RFbRawSetPower(
+bool RFvWriteWakeProgSyn(unsigned long dwIoBase, unsigned char byRFType, unsigned int uChannel);
+bool RFbSetPower(PSDevice pDevice, unsigned int uRATE, unsigned int uCH);
+bool RFbRawSetPower(
     PSDevice  pDevice,
-    BYTE      byPwr,
-    UINT      uRATE
+    unsigned char byPwr,
+    unsigned int uRATE
     );
 
 void
 RFvRSSITodBm(
     PSDevice pDevice,
-    BYTE     byCurrRSSI,
+    unsigned char byCurrRSSI,
     long    *pldBm
     );
 
 //{{ RobertYu: 20050104
-BOOL RFbAL7230SelectChannelPostProcess(DWORD_PTR dwIoBase, BYTE byOldChannel, BYTE byNewChannel);
+bool RFbAL7230SelectChannelPostProcess(unsigned long dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel);
 //}} RobertYu
 
 #endif // __RF_H__
index a0445c3427ea266335c410400dc3ef6be875552f..c920cf694054ec8983256b841079ad96cf9ba8e6 100644 (file)
@@ -80,16 +80,16 @@ static int          msglevel                =MSG_LEVEL_INFO;
 #define CRITICAL_PACKET_LEN      256    // if packet size < 256 -> in-direct send
                                         //    packet size >= 256 -> direct send
 
-const WORD wTimeStampOff[2][MAX_RATE] = {
+const unsigned short wTimeStampOff[2][MAX_RATE] = {
         {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
         {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
     };
 
-const WORD wFB_Opt0[2][5] = {
+const unsigned short wFB_Opt0[2][5] = {
         {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
         {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
     };
-const WORD wFB_Opt1[2][5] = {
+const unsigned short wFB_Opt1[2][5] = {
         {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
         {RATE_6M , RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
     };
@@ -118,12 +118,12 @@ static
 void
 s_vFillTxKey(
     PSDevice   pDevice,
-    PBYTE      pbyBuf,
-    PBYTE      pbyIVHead,
+    unsigned char *pbyBuf,
+    unsigned char *pbyIVHead,
     PSKeyItem  pTransmitKey,
-    PBYTE      pbyHdrBuf,
-    WORD       wPayloadLen,
-    PBYTE      pMICHDR
+    unsigned char *pbyHdrBuf,
+    unsigned short wPayloadLen,
+    unsigned char *pMICHDR
     );
 
 
@@ -132,76 +132,65 @@ static
 void
 s_vFillRTSHead(
     PSDevice         pDevice,
-    BYTE             byPktType,
+    unsigned char byPktType,
     void *           pvRTS,
-    UINT             cbFrameLength,
-    BOOL             bNeedAck,
-    BOOL             bDisCRC,
+    unsigned int       cbFrameLength,
+    bool bNeedAck,
+    bool bDisCRC,
     PSEthernetHeader psEthHeader,
-    WORD             wCurrentRate,
-    BYTE             byFBOption
+    unsigned short wCurrentRate,
+    unsigned char byFBOption
     );
 
 static
 void
 s_vGenerateTxParameter(
     PSDevice         pDevice,
-    BYTE            byPktType,
+    unsigned char byPktType,
     void *           pTxBufHead,
     void *           pvRrvTime,
     void *           pvRTS,
     void *           pvCTS,
-    UINT             cbFrameSize,
-    BOOL             bNeedACK,
-    UINT             uDMAIdx,
+    unsigned int       cbFrameSize,
+    bool bNeedACK,
+    unsigned int       uDMAIdx,
     PSEthernetHeader psEthHeader,
-    WORD             wCurrentRate
+    unsigned short wCurrentRate
     );
 
 
 
 static void s_vFillFragParameter(
     PSDevice pDevice,
-    PBYTE    pbyBuffer,
-    UINT     uTxType,
+    unsigned char *pbyBuffer,
+    unsigned int       uTxType,
     void *   pvtdCurr,
-    WORD     wFragType,
-    UINT     cbReqCount
+    unsigned short wFragType,
+    unsigned int       cbReqCount
     );
 
 
-static
-UINT
-s_cbFillTxBufHead (
-    PSDevice         pDevice,
-    BYTE             byPktType,
-    PBYTE            pbyTxBufferAddr,
-    UINT             cbFrameBodySize,
-    UINT             uDMAIdx,
-    PSTxDesc         pHeadTD,
-    PSEthernetHeader psEthHeader,
-    PBYTE            pPacket,
-    BOOL             bNeedEncrypt,
-    PSKeyItem        pTransmitKey,
-    UINT             uNodeIndex,
-    PUINT            puMACfragNum
-    );
+static unsigned int
+s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr,
+       unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD,
+       PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt,
+       PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum);
 
 
 static
-UINT
+unsigned int
 s_uFillDataHead (
     PSDevice pDevice,
-    BYTE     byPktType,
+    unsigned char byPktType,
     void *   pTxDataHead,
-    UINT     cbFrameLength,
-    UINT     uDMAIdx,
-    BOOL     bNeedAck,
-    UINT     uFragIdx,
-    UINT     cbLastFragmentSize,
-    UINT     uMACfragNum,
-    BYTE     byFBOption,
-    WORD     wCurrentRate
+    unsigned int cbFrameLength,
+    unsigned int uDMAIdx,
+    bool bNeedAck,
+    unsigned int uFragIdx,
+    unsigned int cbLastFragmentSize,
+    unsigned int uMACfragNum,
+    unsigned char byFBOption,
+    unsigned short wCurrentRate
     );
 
 
@@ -213,20 +202,20 @@ static
 void
 s_vFillTxKey (
     PSDevice   pDevice,
-    PBYTE      pbyBuf,
-    PBYTE      pbyIVHead,
+    unsigned char *pbyBuf,
+    unsigned char *pbyIVHead,
     PSKeyItem  pTransmitKey,
-    PBYTE      pbyHdrBuf,
-    WORD       wPayloadLen,
-    PBYTE      pMICHDR
+    unsigned char *pbyHdrBuf,
+    unsigned short wPayloadLen,
+    unsigned char *pMICHDR
     )
 {
-    PDWORD          pdwIV = (PDWORD) pbyIVHead;
-    PDWORD          pdwExtIV = (PDWORD) ((PBYTE)pbyIVHead+4);
-    WORD            wValue;
+    unsigned long *pdwIV = (unsigned long *) pbyIVHead;
+    unsigned long *pdwExtIV = (unsigned long *) ((unsigned char *)pbyIVHead+4);
+    unsigned short wValue;
     PS802_11Header  pMACHeader = (PS802_11Header)pbyHdrBuf;
-    DWORD           dwRevIVCounter;
-    BYTE            byKeyIndex = 0;
+    unsigned long dwRevIVCounter;
+    unsigned char byKeyIndex = 0;
 
 
 
@@ -240,13 +229,13 @@ s_vFillTxKey (
 
     if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
         if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
-            memcpy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3);
+            memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3);
             memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
         } else {
-            memcpy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3);
+            memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3);
             memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
             if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
-                memcpy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3);
+                memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3);
                 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
             }
             memcpy(pDevice->abyPRNG, pbyBuf, 16);
@@ -270,7 +259,7 @@ s_vFillTxKey (
         // Make IV
         memcpy(pdwIV, pDevice->abyPRNG, 3);
 
-        *(pbyIVHead+3) = (BYTE)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+        *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
         // Append IV&ExtIV after Mac Header
         *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
@@ -284,33 +273,33 @@ s_vFillTxKey (
 
         // Make IV
         *pdwIV = 0;
-        *(pbyIVHead+3) = (BYTE)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
-        *pdwIV |= cpu_to_le16((WORD)(pTransmitKey->wTSC15_0));
+        *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+        *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0));
         //Append IV&ExtIV after Mac Header
         *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
 
         //Fill MICHDR0
         *pMICHDR = 0x59;
-        *((PBYTE)(pMICHDR+1)) = 0; // TxPriority
+        *((unsigned char *)(pMICHDR+1)) = 0; // TxPriority
         memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6);
-        *((PBYTE)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
-        *((PBYTE)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
-        *((PBYTE)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
-        *((PBYTE)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
-        *((PBYTE)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
-        *((PBYTE)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
-        *((PBYTE)(pMICHDR+14)) = HIBYTE(wPayloadLen);
-        *((PBYTE)(pMICHDR+15)) = LOBYTE(wPayloadLen);
+        *((unsigned char *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+        *((unsigned char *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+        *((unsigned char *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+        *((unsigned char *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+        *((unsigned char *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
+        *((unsigned char *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
+        *((unsigned char *)(pMICHDR+14)) = HIBYTE(wPayloadLen);
+        *((unsigned char *)(pMICHDR+15)) = LOBYTE(wPayloadLen);
 
         //Fill MICHDR1
-        *((PBYTE)(pMICHDR+16)) = 0; // HLEN[15:8]
+        *((unsigned char *)(pMICHDR+16)) = 0; // HLEN[15:8]
         if (pDevice->bLongHeader) {
-            *((PBYTE)(pMICHDR+17)) = 28; // HLEN[7:0]
+            *((unsigned char *)(pMICHDR+17)) = 28; // HLEN[7:0]
         } else {
-            *((PBYTE)(pMICHDR+17)) = 22; // HLEN[7:0]
+            *((unsigned char *)(pMICHDR+17)) = 22; // HLEN[7:0]
         }
         wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F);
-        memcpy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL
+        memcpy(pMICHDR+18, (unsigned char *)&wValue, 2); // MSKFRACTL
         memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6);
         memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6);
 
@@ -319,7 +308,7 @@ s_vFillTxKey (
         wValue = pMACHeader->wSeqCtl;
         wValue &= 0x000F;
         wValue = cpu_to_le16(wValue);
-        memcpy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL
+        memcpy(pMICHDR+38, (unsigned char *)&wValue, 2); // MSKSEQCTL
         if (pDevice->bLongHeader) {
             memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6);
         }
@@ -332,13 +321,13 @@ void
 s_vSWencryption (
     PSDevice            pDevice,
     PSKeyItem           pTransmitKey,
-    PBYTE               pbyPayloadHead,
-    WORD                wPayloadSize
+    unsigned char *pbyPayloadHead,
+    unsigned short wPayloadSize
     )
 {
-    UINT   cbICVlen = 4;
-    DWORD  dwICV = 0xFFFFFFFFL;
-    PDWORD pdwICV;
+    unsigned int cbICVlen = 4;
+    unsigned long dwICV = 0xFFFFFFFFL;
+    unsigned long *pdwICV;
 
     if (pTransmitKey == NULL)
         return;
@@ -347,7 +336,7 @@ s_vSWencryption (
         //=======================================================================
         // Append ICV after payload
         dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
-        pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
+        pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
         // finally, we must invert dwCRC to get the correct answer
         *pdwICV = cpu_to_le32(~dwICV);
         // RC4 encryption
@@ -358,7 +347,7 @@ s_vSWencryption (
         //=======================================================================
         //Append ICV after payload
         dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
-        pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
+        pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
         // finally, we must invert dwCRC to get the correct answer
         *pdwICV = cpu_to_le32(~dwICV);
         // RC4 encryption
@@ -377,25 +366,25 @@ s_vSWencryption (
              PK_TYPE_11GA    3
 */
 static
-UINT
+unsigned int
 s_uGetTxRsvTime (
     PSDevice pDevice,
-    BYTE     byPktType,
-    UINT     cbFrameLength,
-    WORD     wRate,
-    BOOL     bNeedAck
+    unsigned char byPktType,
+    unsigned int cbFrameLength,
+    unsigned short wRate,
+    bool bNeedAck
     )
 {
-    UINT uDataTime, uAckTime;
+    unsigned int uDataTime, uAckTime;
 
     uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
 #ifdef PLICE_DEBUG
        //printk("s_uGetTxRsvTime is %d\n",uDataTime);
 #endif
     if (byPktType == PK_TYPE_11B) {//llb,CCK mode
-        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
     } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
-        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopOFDMBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
     }
 
     if (bNeedAck) {
@@ -408,16 +397,16 @@ s_uGetTxRsvTime (
 
 //byFreqType: 0=>5GHZ 1=>2.4GHZ
 static
-UINT
+unsigned int
 s_uGetRTSCTSRsvTime (
     PSDevice pDevice,
-    BYTE byRTSRsvType,
-    BYTE byPktType,
-    UINT cbFrameLength,
-    WORD wCurrentRate
+    unsigned char byRTSRsvType,
+    unsigned char byPktType,
+    unsigned int cbFrameLength,
+    unsigned short wCurrentRate
     )
 {
-    UINT uRrvTime  , uRTSTime, uCTSTime, uAckTime, uDataTime;
+    unsigned int uRrvTime  , uRTSTime, uCTSTime, uAckTime, uDataTime;
 
     uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
 
@@ -450,22 +439,22 @@ s_uGetRTSCTSRsvTime (
 
 //byFreqType 0: 5GHz, 1:2.4Ghz
 static
-UINT
+unsigned int
 s_uGetDataDuration (
     PSDevice pDevice,
-    BYTE     byDurType,
-    UINT     cbFrameLength,
-    BYTE     byPktType,
-    WORD     wRate,
-    BOOL     bNeedAck,
-    UINT     uFragIdx,
-    UINT     cbLastFragmentSize,
-    UINT     uMACfragNum,
-    BYTE     byFBOption
+    unsigned char byDurType,
+    unsigned int cbFrameLength,
+    unsigned char byPktType,
+    unsigned short wRate,
+    bool bNeedAck,
+    unsigned int uFragIdx,
+    unsigned int cbLastFragmentSize,
+    unsigned int uMACfragNum,
+    unsigned char byFBOption
     )
 {
-    BOOL bLastFrag = 0;
-    UINT uAckTime =0, uNextPktTime = 0;
+    bool bLastFrag = 0;
+    unsigned int uAckTime =0, uNextPktTime = 0;
 
 
 
@@ -614,25 +603,25 @@ s_uGetDataDuration (
         break;
     }
 
-       ASSERT(FALSE);
+       ASSERT(false);
        return 0;
 }
 
 
 //byFreqType: 0=>5GHZ 1=>2.4GHZ
 static
-UINT
+unsigned int
 s_uGetRTSCTSDuration (
     PSDevice pDevice,
-    BYTE byDurType,
-    UINT cbFrameLength,
-    BYTE byPktType,
-    WORD wRate,
-    BOOL bNeedAck,
-    BYTE byFBOption
+    unsigned char byDurType,
+    unsigned int cbFrameLength,
+    unsigned char byPktType,
+    unsigned short wRate,
+    bool bNeedAck,
+    unsigned char byFBOption
     )
 {
-    UINT uCTSTime = 0, uDurTime = 0;
+    unsigned int uCTSTime = 0, uDurTime = 0;
 
 
     switch (byDurType) {
@@ -719,22 +708,22 @@ s_uGetRTSCTSDuration (
 
 
 static
-UINT
+unsigned int
 s_uFillDataHead (
     PSDevice pDevice,
-    BYTE     byPktType,
+    unsigned char byPktType,
     void *   pTxDataHead,
-    UINT     cbFrameLength,
-    UINT     uDMAIdx,
-    BOOL     bNeedAck,
-    UINT     uFragIdx,
-    UINT     cbLastFragmentSize,
-    UINT     uMACfragNum,
-    BYTE     byFBOption,
-    WORD     wCurrentRate
+    unsigned int cbFrameLength,
+    unsigned int uDMAIdx,
+    bool bNeedAck,
+    unsigned int uFragIdx,
+    unsigned int cbLastFragmentSize,
+    unsigned int uMACfragNum,
+    unsigned char byFBOption,
+    unsigned short wCurrentRate
     )
 {
-    WORD  wLen = 0x0000;
+    unsigned short wLen = 0x0000;
 
     if (pTxDataHead == NULL) {
         return 0;
@@ -745,19 +734,19 @@ s_uFillDataHead (
             PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
             BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             //Get Duration and TimeStamp
-            pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
+            pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
                                                          byPktType, wCurrentRate, bNeedAck, uFragIdx,
                                                          cbLastFragmentSize, uMACfragNum,
                                                          byFBOption)); //1: 2.4GHz
-            pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
+            pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
                                                          PK_TYPE_11B, pDevice->byTopCCKBasicRate,
                                                          bNeedAck, uFragIdx, cbLastFragmentSize,
                                                          uMACfragNum, byFBOption)); //1: 2.4
@@ -771,21 +760,21 @@ s_uFillDataHead (
             PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
             BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             //Get Duration and TimeStamp
-            pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+            pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
                                          wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
-            pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
+            pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
                                          pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
-            pBuf->wDuration_a_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+            pBuf->wDuration_a_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
                                          wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
-            pBuf->wDuration_a_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+            pBuf->wDuration_a_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
                                          wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
 
             pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
@@ -800,16 +789,16 @@ s_uFillDataHead (
             PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration and TimeStampOff
 
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+            pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
-            pBuf->wDuration_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+            pBuf->wDuration_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
-            pBuf->wDuration_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+            pBuf->wDuration_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
             pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
             return (pBuf->wDuration);
@@ -817,12 +806,12 @@ s_uFillDataHead (
             PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration and TimeStampOff
 
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+            pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
                                                        wCurrentRate, bNeedAck, uFragIdx,
                                                        cbLastFragmentSize, uMACfragNum,
                                                        byFBOption));
@@ -835,11 +824,11 @@ s_uFillDataHead (
             PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration and TimeStampOff
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
+            pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
                                                        wCurrentRate, bNeedAck, uFragIdx,
                                                        cbLastFragmentSize, uMACfragNum,
                                                        byFBOption));
@@ -854,18 +843,18 @@ static
 void
 s_vFillRTSHead (
     PSDevice         pDevice,
-    BYTE             byPktType,
+    unsigned char byPktType,
     void *           pvRTS,
-    UINT             cbFrameLength,
-    BOOL             bNeedAck,
-    BOOL             bDisCRC,
+    unsigned int cbFrameLength,
+    bool bNeedAck,
+    bool bDisCRC,
     PSEthernetHeader psEthHeader,
-    WORD             wCurrentRate,
-    BYTE             byFBOption
+    unsigned short wCurrentRate,
+    unsigned char byFBOption
     )
 {
-    UINT uRTSFrameLen = 20;
-    WORD  wLen = 0x0000;
+    unsigned int uRTSFrameLen = 20;
+    unsigned short wLen = 0x0000;
 
     if (pvRTS == NULL)
        return;
@@ -883,17 +872,17 @@ s_vFillRTSHead (
             PSRTS_g pBuf = (PSRTS_g)pvRTS;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
             //Get Duration
-            pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
-            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
-            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+            pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
 
             pBuf->Data.wDurationID = pBuf->wDuration_aa;
             //Get RTS Frame body
@@ -916,22 +905,22 @@ s_vFillRTSHead (
            PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
 
             //Get Duration
-            pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
-            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
-            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
-            pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
-            pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
-            pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
-            pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
+            pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+            pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wRTSDuration_ba_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_ba_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
             pBuf->Data.wDurationID = pBuf->wDuration_aa;
             //Get RTS Frame body
             pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
@@ -958,11 +947,11 @@ s_vFillRTSHead (
             PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+            pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
            pBuf->Data.wDurationID = pBuf->wDuration;
             //Get RTS Frame body
             pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
@@ -987,13 +976,13 @@ s_vFillRTSHead (
             PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
-           pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
-           pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
+            pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+           pBuf->wRTSDuration_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
+           pBuf->wRTSDuration_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
            pBuf->Data.wDurationID = pBuf->wDuration;
            //Get RTS Frame body
             pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
@@ -1017,11 +1006,11 @@ s_vFillRTSHead (
         PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
         //Get SignalField,ServiceField,Length
         BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
-            (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
         );
         pBuf->wTransmitLength = cpu_to_le16(wLen);
         //Get Duration
-        pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+        pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
         pBuf->Data.wDurationID = pBuf->wDuration;
         //Get RTS Frame body
         pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
@@ -1048,18 +1037,18 @@ static
 void
 s_vFillCTSHead (
     PSDevice pDevice,
-    UINT     uDMAIdx,
-    BYTE     byPktType,
+    unsigned int uDMAIdx,
+    unsigned char byPktType,
     void *   pvCTS,
-    UINT     cbFrameLength,
-    BOOL     bNeedAck,
-    BOOL     bDisCRC,
-    WORD     wCurrentRate,
-    BYTE     byFBOption
+    unsigned int cbFrameLength,
+    bool bNeedAck,
+    bool bDisCRC,
+    unsigned short wCurrentRate,
+    unsigned char byFBOption
     )
 {
-    UINT uCTSFrameLen = 14;
-    WORD  wLen = 0x0000;
+    unsigned int uCTSFrameLen = 14;
+    unsigned short wLen = 0x0000;
 
     if (pvCTS == NULL) {
         return;
@@ -1077,21 +1066,21 @@ s_vFillCTSHead (
             PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
             );
 
 
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
 
-            pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wDuration_ba += pDevice->wCTSDuration;
             pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
             //Get CTSDuration_ba_f0
-            pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f0 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration;
             pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
             //Get CTSDuration_ba_f1
-            pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f1 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration;
             pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
             //Get CTS Frame body
@@ -1104,11 +1093,11 @@ s_vFillCTSHead (
             PSCTS pBuf = (PSCTS)pvCTS;
             //Get SignalField,ServiceField,Length
             BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
-                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             //Get CTSDuration_ba
-            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wDuration_ba += pDevice->wCTSDuration;
             pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
 
@@ -1148,28 +1137,28 @@ s_vFillCTSHead (
  * Return Value: none
  *
 -*/
-// UINT            cbFrameSize,//Hdr+Payload+FCS
+// unsigned int cbFrameSize,//Hdr+Payload+FCS
 static
 void
 s_vGenerateTxParameter (
     PSDevice         pDevice,
-    BYTE             byPktType,
+    unsigned char byPktType,
     void *           pTxBufHead,
     void *           pvRrvTime,
     void *           pvRTS,
     void *           pvCTS,
-    UINT             cbFrameSize,
-    BOOL             bNeedACK,
-    UINT             uDMAIdx,
+    unsigned int cbFrameSize,
+    bool bNeedACK,
+    unsigned int uDMAIdx,
     PSEthernetHeader psEthHeader,
-    WORD             wCurrentRate
+    unsigned short wCurrentRate
     )
 {
-    UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24
-    WORD wFifoCtl;
-    BOOL bDisCRC = FALSE;
-    BYTE byFBOption = AUTO_FB_NONE;
-//    WORD wCurrentRate = pDevice->wCurrentRate;
+    unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24
+    unsigned short wFifoCtl;
+    bool bDisCRC = false;
+    unsigned char byFBOption = AUTO_FB_NONE;
+//    unsigned short wCurrentRate = pDevice->wCurrentRate;
 
     //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
     PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
@@ -1177,7 +1166,7 @@ s_vGenerateTxParameter (
     wFifoCtl = pFifoHead->wFIFOCtl;
 
     if (wFifoCtl & FIFOCTL_CRCDIS) {
-        bDisCRC = TRUE;
+        bDisCRC = true;
     }
 
     if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
@@ -1196,11 +1185,11 @@ s_vGenerateTxParameter (
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
-                pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
-                pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
-                pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
-                pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
-                pBuf->wTxRrvTime_b = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+                pBuf->wRTSTxRrvTime_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
             }
             //Fill RTS
             s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
@@ -1210,9 +1199,9 @@ s_vGenerateTxParameter (
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
-                pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
-                pBuf->wTxRrvTime_b = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
-                pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
+                pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+                pBuf->wCTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
             }
 
 
@@ -1226,8 +1215,8 @@ s_vGenerateTxParameter (
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
-                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
-                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
+                pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
+                pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
             }
             //Fill RTS
             s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
@@ -1236,7 +1225,7 @@ s_vGenerateTxParameter (
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
-                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
+                pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
             }
         }
     }
@@ -1246,8 +1235,8 @@ s_vGenerateTxParameter (
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
-                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
-                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
+                pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
             }
             //Fill RTS
             s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
@@ -1256,26 +1245,26 @@ s_vGenerateTxParameter (
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
-                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
+                pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
             }
         }
     }
     //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
 }
 /*
-    PBYTE pbyBuffer,//point to pTxBufHead
-    WORD  wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
-    UINT  cbFragmentSize,//Hdr+payoad+FCS
+    unsigned char *pbyBuffer,//point to pTxBufHead
+    unsigned short wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
+    unsigned int cbFragmentSize,//Hdr+payoad+FCS
 */
 static
 void
 s_vFillFragParameter(
     PSDevice pDevice,
-    PBYTE    pbyBuffer,
-    UINT     uTxType,
+    unsigned char *pbyBuffer,
+    unsigned int uTxType,
     void *   pvtdCurr,
-    WORD     wFragType,
-    UINT     cbReqCount
+    unsigned short wFragType,
+    unsigned int cbReqCount
     )
 {
     PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer;
@@ -1289,7 +1278,7 @@ s_vFillFragParameter(
         ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl;
         ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp;
         //Set TSR1 & ReqCount in TxDescHead
-        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
         if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation
             ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
         }
@@ -1301,7 +1290,7 @@ s_vFillFragParameter(
         //PSTxDesc ptdCurr = (PSTxDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx);
         PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr;
         //Set TSR1 & ReqCount in TxDescHead
-        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
         if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation
             ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
         }
@@ -1310,81 +1299,70 @@ s_vFillFragParameter(
         }
     }
 
-    pTxBufHead->wFragCtl |= (WORD)wFragType;//0x0001; //0000 0000 0000 0001
+    pTxBufHead->wFragCtl |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001
 
     //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter END\n");
 }
 
-static
-UINT
-s_cbFillTxBufHead (
-    PSDevice         pDevice,
-    BYTE             byPktType,
-    PBYTE            pbyTxBufferAddr,
-    UINT             cbFrameBodySize,
-    UINT             uDMAIdx,
-    PSTxDesc         pHeadTD,
-    PSEthernetHeader psEthHeader,
-    PBYTE            pPacket,
-    BOOL             bNeedEncrypt,
-    PSKeyItem        pTransmitKey,
-    UINT             uNodeIndex,
-    PUINT            puMACfragNum
-    )
+static unsigned int
+s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr,
+       unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD,
+       PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt,
+       PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum)
 {
-    UINT           cbMACHdLen;
-    UINT           cbFrameSize;
-    UINT           cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
-    UINT           cbFragPayloadSize;
-    UINT           cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
-    UINT           cbLastFragPayloadSize;
-    UINT           uFragIdx;
-    PBYTE          pbyPayloadHead;
-    PBYTE          pbyIVHead;
-    PBYTE          pbyMacHdr;
-    WORD           wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last
-    UINT           uDuration;
-    PBYTE          pbyBuffer;
-//    UINT           uKeyEntryIdx = NUM_KEY_ENTRY+1;
-//    BYTE           byKeySel = 0xFF;
-    UINT           cbIVlen = 0;
-    UINT           cbICVlen = 0;
-    UINT           cbMIClen = 0;
-    UINT           cbFCSlen = 4;
-    UINT           cb802_1_H_len = 0;
-    UINT           uLength = 0;
-    UINT           uTmpLen = 0;
-//    BYTE           abyTmp[8];
-//    DWORD          dwCRC;
-    UINT           cbMICHDR = 0;
-    DWORD          dwMICKey0, dwMICKey1;
-    DWORD          dwMIC_Priority;
-    PDWORD         pdwMIC_L;
-    PDWORD         pdwMIC_R;
-    DWORD          dwSafeMIC_L, dwSafeMIC_R; //Fix "Last Frag Size" < "MIC length".
-    BOOL           bMIC2Frag = FALSE;
-    UINT           uMICFragLen = 0;
-    UINT           uMACfragNum = 1;
-    UINT           uPadding = 0;
-    UINT           cbReqCount = 0;
-
-    BOOL           bNeedACK;
-    BOOL           bRTS;
-    BOOL           bIsAdhoc;
-    PBYTE          pbyType;
+    unsigned int cbMACHdLen;
+    unsigned int cbFrameSize;
+    unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
+    unsigned int cbFragPayloadSize;
+    unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
+    unsigned int cbLastFragPayloadSize;
+    unsigned int uFragIdx;
+    unsigned char *pbyPayloadHead;
+    unsigned char *pbyIVHead;
+    unsigned char *pbyMacHdr;
+    unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last
+    unsigned int uDuration;
+    unsigned char *pbyBuffer;
+//    unsigned int uKeyEntryIdx = NUM_KEY_ENTRY+1;
+//    unsigned char byKeySel = 0xFF;
+    unsigned int cbIVlen = 0;
+    unsigned int cbICVlen = 0;
+    unsigned int cbMIClen = 0;
+    unsigned int cbFCSlen = 4;
+    unsigned int cb802_1_H_len = 0;
+    unsigned int uLength = 0;
+    unsigned int uTmpLen = 0;
+//    unsigned char abyTmp[8];
+//    unsigned long dwCRC;
+    unsigned int cbMICHDR = 0;
+    unsigned long dwMICKey0, dwMICKey1;
+    unsigned long dwMIC_Priority;
+    unsigned long *pdwMIC_L;
+    unsigned long *pdwMIC_R;
+    unsigned long dwSafeMIC_L, dwSafeMIC_R; //Fix "Last Frag Size" < "MIC length".
+    bool bMIC2Frag = false;
+    unsigned int uMICFragLen = 0;
+    unsigned int uMACfragNum = 1;
+    unsigned int uPadding = 0;
+    unsigned int cbReqCount = 0;
+
+    bool bNeedACK;
+    bool bRTS;
+    bool bIsAdhoc;
+    unsigned char *pbyType;
     PSTxDesc       ptdCurr;
     PSTxBufHead    psTxBufHd = (PSTxBufHead) pbyTxBufferAddr;
-//    UINT           tmpDescIdx;
-    UINT           cbHeaderLength = 0;
+//    unsigned int tmpDescIdx;
+    unsigned int cbHeaderLength = 0;
     void *         pvRrvTime;
     PSMICHDRHead   pMICHDR;
     void *         pvRTS;
     void *         pvCTS;
     void *         pvTxDataHd;
-    WORD           wTxBufSize;   // FFinfo size
-    UINT           uTotalCopyLength = 0;
-    BYTE           byFBOption = AUTO_FB_NONE;
-    BOOL           bIsWEP256 = FALSE;
+    unsigned short wTxBufSize;   // FFinfo size
+    unsigned int uTotalCopyLength = 0;
+    unsigned char byFBOption = AUTO_FB_NONE;
+    bool bIsWEP256 = false;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
 
 
@@ -1394,19 +1372,16 @@ s_cbFillTxBufHead (
     if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
         (pDevice->eOPMode == OP_MODE_AP)) {
 
-        if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
-            IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
-            bNeedACK = FALSE;
-        }
-        else {
-            bNeedACK = TRUE;
-        }
-        bIsAdhoc = TRUE;
+       if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0])))
+               bNeedACK = false;
+        else
+            bNeedACK = true;
+        bIsAdhoc = true;
     }
     else {
         // MSDUs in Infra mode always need ACK
-        bNeedACK = TRUE;
-        bIsAdhoc = FALSE;
+        bNeedACK = true;
+        bIsAdhoc = false;
     }
 
     if (pDevice->bLongHeader)
@@ -1415,12 +1390,12 @@ s_cbFillTxBufHead (
         cbMACHdLen = WLAN_HDR_ADDR3_LEN;
 
 
-    if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL)) {
+    if ((bNeedEncrypt == true) && (pTransmitKey != NULL)) {
         if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
             cbIVlen = 4;
             cbICVlen = 4;
             if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
-                bIsWEP256 = TRUE;
+                bIsWEP256 = true;
             }
         }
         if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
@@ -1443,14 +1418,14 @@ s_cbFillTxBufHead (
 
     cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
 
-    if ((bNeedACK == FALSE) ||
+    if ((bNeedACK == false) ||
         (cbFrameSize < pDevice->wRTSThreshold) ||
         ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold))
         ) {
-        bRTS = FALSE;
+        bRTS = false;
     }
     else {
-        bRTS = TRUE;
+        bRTS = true;
         psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
     }
     //
@@ -1469,7 +1444,7 @@ s_cbFillTxBufHead (
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
 
         if (byFBOption == AUTO_FB_NONE) {
-            if (bRTS == TRUE) {//RTS_need
+            if (bRTS == true) {//RTS_need
                 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
                 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
                 pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
@@ -1487,7 +1462,7 @@ s_cbFillTxBufHead (
             }
         } else {
             // Auto Fall Back
-            if (bRTS == TRUE) {//RTS_need
+            if (bRTS == true) {//RTS_need
                 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
                 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
                 pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
@@ -1508,7 +1483,7 @@ s_cbFillTxBufHead (
     else {//802.11a/b packet
 
         if (byFBOption == AUTO_FB_NONE) {
-            if (bRTS == TRUE) {
+            if (bRTS == true) {
                 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
                 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
                 pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
@@ -1526,7 +1501,7 @@ s_cbFillTxBufHead (
             }
         } else {
             // Auto Fall Back
-            if (bRTS == TRUE) {//RTS_need
+            if (bRTS == true) {//RTS_need
                 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
                 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
                 pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
@@ -1547,40 +1522,40 @@ s_cbFillTxBufHead (
     memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
 
 //////////////////////////////////////////////////////////////////
-    if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+    if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
         if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
-            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
-            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+            dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]);
         }
         else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
-            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
-            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+            dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]);
         }
         else {
-            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[24]);
-            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[28]);
+            dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[24]);
+            dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[28]);
         }
         // DO Software Michael
         MIC_vInit(dwMICKey0, dwMICKey1);
-        MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12);
+        MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12);
         dwMIC_Priority = 0;
-        MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+        MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
     }
 
 ///////////////////////////////////////////////////////////////////
 
-    pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderLength);
-    pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
-    pbyIVHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding);
+    pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength);
+    pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
+    pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding);
 
-    if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == TRUE) && (bIsWEP256 == FALSE)) {
+    if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true) && (bIsWEP256 == false)) {
         // Fragmentation
         // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS)
         cbFragmentSize = pDevice->wFragmentationThreshold;
         cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
         //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS)))
-        uMACfragNum = (WORD) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
+        uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
         cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
         if (cbLastFragPayloadSize == 0) {
             cbLastFragPayloadSize = cbFragPayloadSize;
@@ -1606,13 +1581,13 @@ s_cbFillTxBufHead (
                 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
                                             uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
                 // Generate TX MAC Header
-                vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+                vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
                                    wFragType, uDMAIdx, uFragIdx);
 
-                if (bNeedEncrypt == TRUE) {
+                if (bNeedEncrypt == true) {
                     //Fill TXKEY
-                    s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
-                                 pbyMacHdr, (WORD)cbFragPayloadSize, (PBYTE)pMICHDR);
+                    s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                                 pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR);
                     //Fill IV(ExtIV,RSNHDR)
                     if (pDevice->bEnableHostWEP) {
                         pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
@@ -1625,13 +1600,13 @@ s_cbFillTxBufHead (
                 if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
                     if ((psEthHeader->wType == TYPE_PKT_IPX) ||
                         (psEthHeader->wType == cpu_to_le16(0xF380))) {
-                        memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
+                        memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
                     }
                     else {
-                        memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
+                        memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
                     }
-                    pbyType = (PBYTE) (pbyPayloadHead + 6);
-                    memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD));
+                    pbyType = (unsigned char *) (pbyPayloadHead + 6);
+                    memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short));
                     cb802_1_H_len = 8;
                 }
 
@@ -1641,15 +1616,15 @@ s_cbFillTxBufHead (
                 //---------------------------
                 //Fill MICHDR
                 //if (pDevice->bAES) {
-                //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize);
+                //    s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFragPayloadSize);
                 //}
                 //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel,
-                //                                pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx);
+                //                                pbyPayloadHead, (unsigned short)cbFragPayloadSize, uDMAIdx);
 
 
 
-                //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr;
-                pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
+                //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr;
+                pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
 
                 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
                 //copy TxBufferHeader + MacHeader to desc
@@ -1661,7 +1636,7 @@ s_cbFillTxBufHead (
 
                 uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len;
 
-                if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+                if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start MIC: %d\n", cbFragPayloadSize);
                     MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize);
 
@@ -1672,7 +1647,7 @@ s_cbFillTxBufHead (
                 //---------------------------
                 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
                     if (bNeedEncrypt) {
-                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (WORD)cbFragPayloadSize);
+                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (unsigned short)cbFragPayloadSize);
                         cbReqCount += cbICVlen;
                     }
                 }
@@ -1711,13 +1686,13 @@ s_cbFillTxBufHead (
                                             uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
 
                 // Generate TX MAC Header
-                vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+                vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
                                    wFragType, uDMAIdx, uFragIdx);
 
-                if (bNeedEncrypt == TRUE) {
+                if (bNeedEncrypt == true) {
                     //Fill TXKEY
-                    s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
-                                 pbyMacHdr, (WORD)cbLastFragPayloadSize, (PBYTE)pMICHDR);
+                    s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                                 pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)pMICHDR);
 
                     if (pDevice->bEnableHostWEP) {
                         pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
@@ -1734,8 +1709,8 @@ s_cbFillTxBufHead (
 
 
 
-                pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
-                //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr;
+                pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
+                //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr;
 
                 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
 
@@ -1743,7 +1718,7 @@ s_cbFillTxBufHead (
                 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
 
                 // Copy the Packet into a tx Buffer
-                if (bMIC2Frag == FALSE) {
+                if (bMIC2Frag == false) {
 
                     memcpy((pbyBuffer + uLength),
                              (pPacket + 14 + uTotalCopyLength),
@@ -1753,36 +1728,36 @@ s_cbFillTxBufHead (
                     uTmpLen = cbLastFragPayloadSize - cbMIClen;
 
                 }
-                if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+                if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n",
                                    uMICFragLen, cbLastFragPayloadSize, uTmpLen);
 
-                    if (bMIC2Frag == FALSE) {
+                    if (bMIC2Frag == false) {
                         if (uTmpLen != 0)
                             MIC_vAppend((pbyBuffer + uLength), uTmpLen);
-                        pdwMIC_L = (PDWORD)(pbyBuffer + uLength + uTmpLen);
-                        pdwMIC_R = (PDWORD)(pbyBuffer + uLength + uTmpLen + 4);
+                        pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen);
+                        pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4);
                         MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
                     } else {
                         if (uMICFragLen >= 4) {
-                            memcpy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)),
+                            memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)),
                                      (cbMIClen - uMICFragLen));
                             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen >= 4: %X, %d\n",
-                                           *(PBYTE)((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)),
+                                           *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)),
                                            (cbMIClen - uMICFragLen));
 
                         } else {
-                            memcpy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_L + uMICFragLen),
+                            memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen),
                                      (4 - uMICFragLen));
                             memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4);
                             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen < 4: %X, %d\n",
-                                           *(PBYTE)((PBYTE)&dwSafeMIC_R + uMICFragLen - 4),
+                                           *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4),
                                            (cbMIClen - uMICFragLen));
                         }
                         /*
                         for (ii = 0; ii < cbLastFragPayloadSize + 8 + 24; ii++) {
-                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii - 8 - 24)));
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii - 8 - 24)));
                         }
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
                         */
@@ -1798,7 +1773,7 @@ s_cbFillTxBufHead (
                 //---------------------------
                 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
                     if (bNeedEncrypt) {
-                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (WORD)cbLastFragPayloadSize);
+                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbLastFragPayloadSize);
                         cbReqCount += cbICVlen;
                     }
                 }
@@ -1841,14 +1816,14 @@ s_cbFillTxBufHead (
                                             uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
 
                 // Generate TX MAC Header
-                vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+                vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
                                    wFragType, uDMAIdx, uFragIdx);
 
 
-                if (bNeedEncrypt == TRUE) {
+                if (bNeedEncrypt == true) {
                     //Fill TXKEY
-                    s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
-                                 pbyMacHdr, (WORD)cbFragPayloadSize, (PBYTE)pMICHDR);
+                    s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                                 pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR);
 
                     if (pDevice->bEnableHostWEP) {
                         pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
@@ -1862,14 +1837,14 @@ s_cbFillTxBufHead (
                 //---------------------------
                 //Fill MICHDR
                 //if (pDevice->bAES) {
-                //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize);
+                //    s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFragPayloadSize);
                 //}
                 //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel,
-                //                              pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx);
+                //                              pbyPayloadHead, (unsigned short)cbFragPayloadSize, uDMAIdx);
 
 
-                pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
-                //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr;
+                pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
+                //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr;
 
 
                 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
@@ -1886,17 +1861,17 @@ s_cbFillTxBufHead (
 
                 uTotalCopyLength += uTmpLen;
 
-                if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+                if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
 
                     MIC_vAppend((pbyBuffer + uLength), uTmpLen);
 
                     if (uTmpLen < cbFragPayloadSize) {
-                        bMIC2Frag = TRUE;
+                        bMIC2Frag = true;
                         uMICFragLen = cbFragPayloadSize - uTmpLen;
                         ASSERT(uMICFragLen < cbMIClen);
 
-                        pdwMIC_L = (PDWORD)(pbyBuffer + uLength + uTmpLen);
-                        pdwMIC_R = (PDWORD)(pbyBuffer + uLength + uTmpLen + 4);
+                        pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen);
+                        pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4);
                         MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
                         dwSafeMIC_L = *pdwMIC_L;
                         dwSafeMIC_R = *pdwMIC_R;
@@ -1906,7 +1881,7 @@ s_cbFillTxBufHead (
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MIC in Middle frag [%d]\n", uMICFragLen);
                         /*
                         for (ii = 0; ii < uMICFragLen; ii++) {
-                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength + uTmpLen) + ii)));
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength + uTmpLen) + ii)));
                         }
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
                         */
@@ -1915,7 +1890,7 @@ s_cbFillTxBufHead (
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle frag len: %d\n", uTmpLen);
                     /*
                     for (ii = 0; ii < uTmpLen; ii++) {
-                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii)));
                     }
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
                     */
@@ -1926,7 +1901,7 @@ s_cbFillTxBufHead (
 
                 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
                     if (bNeedEncrypt) {
-                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (WORD)cbFragPayloadSize);
+                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbFragPayloadSize);
                         cbReqCount += cbICVlen;
                     }
                 }
@@ -1961,7 +1936,7 @@ s_cbFillTxBufHead (
         wFragType = FRAGCTL_NONFRAG;
 
         //Set FragCtl in TxBufferHead
-        psTxBufHd->wFragCtl |= (WORD)wFragType;
+        psTxBufHd->wFragCtl |= (unsigned short)wFragType;
 
         //Fill FIFO,RrvTime,RTS,and CTS
         s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
@@ -1971,13 +1946,13 @@ s_cbFillTxBufHead (
                                     0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate);
 
         // Generate TX MAC Header
-        vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+        vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
                            wFragType, uDMAIdx, 0);
 
-        if (bNeedEncrypt == TRUE) {
+        if (bNeedEncrypt == true) {
             //Fill TXKEY
-            s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
-                         pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
+            s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                         pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR);
 
             if (pDevice->bEnableHostWEP) {
                 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
@@ -1989,13 +1964,13 @@ s_cbFillTxBufHead (
         if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
             if ((psEthHeader->wType == TYPE_PKT_IPX) ||
                 (psEthHeader->wType == cpu_to_le16(0xF380))) {
-                memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
+                memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
             }
             else {
-                memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
+                memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
             }
-            pbyType = (PBYTE) (pbyPayloadHead + 6);
-            memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD));
+            pbyType = (unsigned char *) (pbyPayloadHead + 6);
+            memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short));
             cb802_1_H_len = 8;
         }
 
@@ -2006,11 +1981,11 @@ s_cbFillTxBufHead (
         //Fill MICHDR
         //if (pDevice->bAES) {
         //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MICHDR...\n");
-        //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFrameBodySize);
+        //    s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFrameBodySize);
         //}
 
-        pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
-        //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr;
+        pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
+        //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr;
 
         uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
 
@@ -2023,29 +1998,29 @@ s_cbFillTxBufHead (
                  cbFrameBodySize - cb802_1_H_len
                  );
 
-        if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)){
+        if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)){
 
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength);
             /*
             for (ii = 0; ii < (cbFrameBodySize - cb802_1_H_len); ii++) {
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii)));
             }
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
             */
 
             MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize);
 
-            pdwMIC_L = (PDWORD)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize);
-            pdwMIC_R = (PDWORD)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4);
+            pdwMIC_L = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize);
+            pdwMIC_R = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4);
 
             MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
             MIC_vUnInit();
 
 
-            if (pDevice->bTxMICFail == TRUE) {
+            if (pDevice->bTxMICFail == true) {
                 *pdwMIC_L = 0;
                 *pdwMIC_R = 0;
-                pDevice->bTxMICFail = FALSE;
+                pDevice->bTxMICFail = false;
             }
 
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
@@ -2053,7 +2028,7 @@ s_cbFillTxBufHead (
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
 /*
             for (ii = 0; ii < 8; ii++) {
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(((PBYTE)(pdwMIC_L) + ii)));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(((unsigned char *)(pdwMIC_L) + ii)));
             }
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 */
@@ -2064,7 +2039,7 @@ s_cbFillTxBufHead (
         if ((pDevice->byLocalID <= REV_ID_VT3253_A1)){
             if (bNeedEncrypt) {
                 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len),
-                                (WORD)(cbFrameBodySize + cbMIClen));
+                                (unsigned short)(cbFrameBodySize + cbMIClen));
                 cbReqCount += cbICVlen;
             }
         }
@@ -2078,7 +2053,7 @@ s_cbFillTxBufHead (
         ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
            //Set TSR1 & ReqCount in TxDescHead
         ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
-        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
 
         pDevice->iTDUsed[uDMAIdx]++;
 
@@ -2094,26 +2069,16 @@ s_cbFillTxBufHead (
 
 
 void
-vGenerateFIFOHeader (
-    PSDevice         pDevice,
-    BYTE             byPktType,
-    PBYTE            pbyTxBufferAddr,
-    BOOL             bNeedEncrypt,
-    UINT             cbPayloadSize,
-    UINT             uDMAIdx,
-    PSTxDesc         pHeadTD,
-    PSEthernetHeader psEthHeader,
-    PBYTE            pPacket,
-    PSKeyItem        pTransmitKey,
-    UINT             uNodeIndex,
-    PUINT            puMACfragNum,
-    PUINT            pcbHeaderSize
-    )
+vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr,
+       bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx,
+       PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket,
+       PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum,
+       unsigned int *pcbHeaderSize)
 {
-    UINT            wTxBufSize;       // FFinfo size
-    BOOL            bNeedACK;
-    BOOL            bIsAdhoc;
-    WORD            cbMacHdLen;
+    unsigned int wTxBufSize;       // FFinfo size
+    bool bNeedACK;
+    bool bIsAdhoc;
+    unsigned short cbMacHdLen;
     PSTxBufHead     pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
 
     wTxBufSize = sizeof(STxBufHead);
@@ -2123,22 +2088,21 @@ vGenerateFIFOHeader (
 
     if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
         (pDevice->eOPMode == OP_MODE_AP)) {
-        if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
-            IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
-            bNeedACK = FALSE;
+        if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) {
+            bNeedACK = false;
             pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
         }
         else {
-            bNeedACK = TRUE;
+            bNeedACK = true;
             pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
         }
-        bIsAdhoc = TRUE;
+        bIsAdhoc = true;
     }
     else {
         // MSDUs in Infra mode always need ACK
-        bNeedACK = TRUE;
+        bNeedACK = true;
         pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
-        bIsAdhoc = FALSE;
+        bIsAdhoc = false;
     }
 
 
@@ -2165,7 +2129,7 @@ vGenerateFIFOHeader (
     } else {
         cbMacHdLen = WLAN_HDR_ADDR3_LEN;
     }
-    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10));
+    pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
 
     //Set packet type
     if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
@@ -2181,7 +2145,7 @@ vGenerateFIFOHeader (
         pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
     }
     //Set FIFOCTL_GrpAckPolicy
-    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+    if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
         pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
     }
 
@@ -2195,7 +2159,7 @@ vGenerateFIFOHeader (
     }
 
     //Set FRAGCTL_WEPTYP
-    pDevice->bAES = FALSE;
+    pDevice->bAES = false;
 
     //Set FRAGCTL_WEPTYP
     if (pDevice->byLocalID > REV_ID_VT3253_A1) {
@@ -2267,13 +2231,13 @@ vGenerateFIFOHeader (
 void
 vGenerateMACHeader (
     PSDevice         pDevice,
-    PBYTE            pbyBufferAddr,
-    WORD             wDuration,
+    unsigned char *pbyBufferAddr,
+    unsigned short wDuration,
     PSEthernetHeader psEthHeader,
-    BOOL             bNeedEncrypt,
-    WORD             wFragType,
-    UINT             uDMAIdx,
-    UINT             uFragIdx
+    bool bNeedEncrypt,
+    unsigned short wFragType,
+    unsigned int uDMAIdx,
+    unsigned int uFragIdx
     )
 {
     PS802_11Header  pMACHeader = (PS802_11Header)pbyBufferAddr;
@@ -2307,7 +2271,7 @@ vGenerateMACHeader (
     }
 
     if (bNeedEncrypt)
-        pMACHeader->wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_ISWEP(1));
+        pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1));
 
     pMACHeader->wDurationID = cpu_to_le16(wDuration);
 
@@ -2319,7 +2283,7 @@ vGenerateMACHeader (
     pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
 
     //Set FragNumber in Sequence Control
-    pMACHeader->wSeqCtl |= cpu_to_le16((WORD)uFragIdx);
+    pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx);
 
     if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
         pDevice->wSeqCounter++;
@@ -2340,32 +2304,32 @@ vGenerateMACHeader (
 CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
     PSTxDesc        pFrstTD;
-    BYTE            byPktType;
-    PBYTE           pbyTxBufferAddr;
+    unsigned char byPktType;
+    unsigned char *pbyTxBufferAddr;
     void *          pvRTS;
     PSCTS           pCTS;
     void *          pvTxDataHd;
-    UINT            uDuration;
-    UINT            cbReqCount;
+    unsigned int uDuration;
+    unsigned int cbReqCount;
     PS802_11Header  pMACHeader;
-    UINT            cbHeaderSize;
-    UINT            cbFrameBodySize;
-    BOOL            bNeedACK;
-    BOOL            bIsPSPOLL = FALSE;
+    unsigned int cbHeaderSize;
+    unsigned int cbFrameBodySize;
+    bool bNeedACK;
+    bool bIsPSPOLL = false;
     PSTxBufHead     pTxBufHead;
-    UINT            cbFrameSize;
-    UINT            cbIVlen = 0;
-    UINT            cbICVlen = 0;
-    UINT            cbMIClen = 0;
-    UINT            cbFCSlen = 4;
-    UINT            uPadding = 0;
-    WORD            wTxBufSize;
-    UINT            cbMacHdLen;
+    unsigned int cbFrameSize;
+    unsigned int cbIVlen = 0;
+    unsigned int cbICVlen = 0;
+    unsigned int cbMIClen = 0;
+    unsigned int cbFCSlen = 4;
+    unsigned int uPadding = 0;
+    unsigned short wTxBufSize;
+    unsigned int cbMacHdLen;
     SEthernetHeader sEthHeader;
     void *          pvRrvTime;
     void *          pMICHDR;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    WORD            wCurrentRate = RATE_1M;
+    unsigned short wCurrentRate = RATE_1M;
 
 
     if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
@@ -2373,7 +2337,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     }
 
     pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
-    pbyTxBufferAddr = (PBYTE)pFrstTD->pTDInfo->buf;
+    pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
     cbFrameBodySize = pPacket->cbPayloadLen;
     pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
     wTxBufSize = sizeof(STxBufHead);
@@ -2424,12 +2388,10 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
 
 
-    if (IS_MULTICAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0])) ||
-        IS_BROADCAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0]))) {
-        bNeedACK = FALSE;
-    }
+    if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0])))
+        bNeedACK = false;
     else {
-        bNeedACK = TRUE;
+        bNeedACK = true;
         pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
     };
 
@@ -2441,7 +2403,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
         //pDevice->byPreambleType = PREAMBLE_LONG;
         // probe-response don't retry
         //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
-        //     bNeedACK = FALSE;
+        //     bNeedACK = false;
         //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK);
         //}
     }
@@ -2449,19 +2411,19 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
 
     if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
-        bIsPSPOLL = TRUE;
+        bIsPSPOLL = true;
         cbMacHdLen = WLAN_HDR_ADDR2_LEN;
     } else {
         cbMacHdLen = WLAN_HDR_ADDR3_LEN;
     }
 
     //Set FRAGCTL_MACHDCNT
-    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10));
+    pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
 
     // Notes:
     // Although spec says MMPDU can be fragmented; In most case,
     // no one will send a MMPDU under fragmentation. With RTS may occur.
-    pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP
+    pDevice->bAES = false;  //Set FRAGCTL_WEPTYP
 
     if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
         if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
@@ -2482,7 +2444,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
             cbIVlen = 8;//RSN Header
             cbICVlen = 8;//MIC
             pTxBufHead->wFragCtl |= FRAGCTL_AES;
-            pDevice->bAES = TRUE;
+            pDevice->bAES = true;
         }
         //MAC Header should be padding 0 to DW alignment.
         uPadding = 4 - (cbMacHdLen%4);
@@ -2492,7 +2454,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
 
     //Set FIFOCTL_GrpAckPolicy
-    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+    if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
         pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
     }
     //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
@@ -2523,7 +2485,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     //=========================
     //    No Fragmentation
     //=========================
-    pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
+    pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
 
 
     //Fill FIFO,RrvTime,RTS,and CTS
@@ -2539,17 +2501,17 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
 
     if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
-        PBYTE           pbyIVHead;
-        PBYTE           pbyPayloadHead;
-        PBYTE           pbyBSSID;
+        unsigned char *pbyIVHead;
+        unsigned char *pbyPayloadHead;
+        unsigned char *pbyBSSID;
         PSKeyItem       pTransmitKey = NULL;
 
-        pbyIVHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
-        pbyPayloadHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
+        pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
+        pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
 
         //Fill TXKEY
         //Kyle: Need fix: TKIP and AES did't encryt Mnt Packet.
-        //s_vFillTxKey(pDevice, (PBYTE)pTxBufHead->adwTxKey, NULL);
+        //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL);
 
         //Fill IV(ExtIV,RSNHDR)
         //s_vFillPrePayload(pDevice, pbyIVHead, NULL);
@@ -2558,16 +2520,16 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
         //---------------------------
         //Fill MICHDR
         //if (pDevice->bAES) {
-        //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, (PBYTE)pMACHeader, (WORD)cbFrameBodySize);
+        //    s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize);
         //}
         do {
             if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
-                (pDevice->bLinkPass == TRUE)) {
+                (pDevice->bLinkPass == true)) {
                 pbyBSSID = pDevice->abyBSSID;
                 // get pairwise key
-                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
+                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
                     // get group key
-                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
+                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
                         break;
                     }
@@ -2578,19 +2540,19 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
             }
             // get group key
             pbyBSSID = pDevice->abyBroadcastAddr;
-            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
                 pTransmitKey = NULL;
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
             } else {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
             }
-        } while(FALSE);
+        } while(false);
         //Fill TXKEY
-        s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
-                     (PBYTE)pMACHeader, (WORD)cbFrameBodySize, NULL);
+        s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+                     (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL);
 
         memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
-        memcpy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen),
+        memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen),
                  cbFrameBodySize);
     }
     else {
@@ -2622,7 +2584,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     //Set TSR1 & ReqCount in TxDescHead
     pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
     pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
-    pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+    pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
     pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
     pFrstTD->pTDInfo->byFlags = 0;
 
@@ -2630,7 +2592,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
         // Disable PS
         MACbPSWakeup(pDevice->PortOffset);
     }
-    pDevice->bPWBitOn = FALSE;
+    pDevice->bPWBitOn = false;
 
     wmb();
     pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
@@ -2661,16 +2623,16 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
 CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
-    BYTE             byPktType;
-    PBYTE            pbyBuffer = (PBYTE)pDevice->tx_beacon_bufs;
-    UINT             cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
-    UINT             cbHeaderSize = 0;
-    WORD             wTxBufSize = sizeof(STxShortBufHead);
+    unsigned char byPktType;
+    unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs;
+    unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
+    unsigned int cbHeaderSize = 0;
+    unsigned short wTxBufSize = sizeof(STxShortBufHead);
     PSTxShortBufHead pTxBufHead = (PSTxShortBufHead) pbyBuffer;
     PSTxDataHead_ab  pTxDataHead = (PSTxDataHead_ab) (pbyBuffer + wTxBufSize);
     PS802_11Header   pMACHeader;
-    WORD             wCurrentRate;
-    WORD             wLen = 0x0000;
+    unsigned short wCurrentRate;
+    unsigned short wLen = 0x0000;
 
 
     memset(pTxBufHead, 0, wTxBufSize);
@@ -2693,17 +2655,17 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
     //Set packet type & Get Duration
     if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
-        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktType,
-                                                          wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
+        pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktType,
+                                                          wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
     }
     else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
-        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktType,
-                                                          wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
+        pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktType,
+                                                          wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
     }
 
     BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType,
-        (PWORD)&(wLen), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField)
+        (unsigned short *)&(wLen), (unsigned char *)&(pTxDataHead->byServiceField), (unsigned char *)&(pTxDataHead->bySignalField)
     );
     pTxDataHead->wTransmitLength = cpu_to_le16(wLen);
     //Get TimeStampOff
@@ -2736,41 +2698,38 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
 
 
-UINT
+unsigned int
 cbGetFragCount (
     PSDevice         pDevice,
     PSKeyItem        pTransmitKey,
-    UINT             cbFrameBodySize,
+    unsigned int cbFrameBodySize,
     PSEthernetHeader psEthHeader
     )
 {
-    UINT           cbMACHdLen;
-    UINT           cbFrameSize;
-    UINT           cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
-    UINT           cbFragPayloadSize;
-    UINT           cbLastFragPayloadSize;
-    UINT           cbIVlen = 0;
-    UINT           cbICVlen = 0;
-    UINT           cbMIClen = 0;
-    UINT           cbFCSlen = 4;
-    UINT           uMACfragNum = 1;
-    BOOL           bNeedACK;
+    unsigned int cbMACHdLen;
+    unsigned int cbFrameSize;
+    unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
+    unsigned int cbFragPayloadSize;
+    unsigned int cbLastFragPayloadSize;
+    unsigned int cbIVlen = 0;
+    unsigned int cbICVlen = 0;
+    unsigned int cbMIClen = 0;
+    unsigned int cbFCSlen = 4;
+    unsigned int uMACfragNum = 1;
+    bool bNeedACK;
 
 
 
     if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
         (pDevice->eOPMode == OP_MODE_AP)) {
-        if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
-            IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
-            bNeedACK = FALSE;
-        }
-        else {
-            bNeedACK = TRUE;
-        }
+        if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0])))
+            bNeedACK = false;
+        else
+            bNeedACK = true;
     }
     else {
         // MSDUs in Infra mode always need ACK
-        bNeedACK = TRUE;
+        bNeedACK = true;
     }
 
     if (pDevice->bLongHeader)
@@ -2779,7 +2738,7 @@ cbGetFragCount (
         cbMACHdLen = WLAN_HDR_ADDR3_LEN;
 
 
-    if (pDevice->bEncryptionEnable == TRUE) {
+    if (pDevice->bEncryptionEnable == true) {
 
         if (pTransmitKey == NULL) {
             if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) ||
@@ -2809,11 +2768,11 @@ cbGetFragCount (
 
     cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
 
-    if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == TRUE)) {
+    if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) {
         // Fragmentation
         cbFragmentSize = pDevice->wFragmentationThreshold;
         cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
-        uMACfragNum = (WORD) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
+        uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
         cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
         if (cbLastFragPayloadSize == 0) {
             cbLastFragPayloadSize = cbFragPayloadSize;
@@ -2826,51 +2785,51 @@ cbGetFragCount (
 
 
 void
-vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen) {
+vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, unsigned char *pbMPDU, unsigned int cbMPDULen) {
 
     PSTxDesc        pFrstTD;
-    BYTE            byPktType;
-    PBYTE           pbyTxBufferAddr;
+    unsigned char byPktType;
+    unsigned char *pbyTxBufferAddr;
     void *          pvRTS;
     void *          pvCTS;
     void *          pvTxDataHd;
-    UINT            uDuration;
-    UINT            cbReqCount;
+    unsigned int uDuration;
+    unsigned int cbReqCount;
     PS802_11Header  pMACHeader;
-    UINT            cbHeaderSize;
-    UINT            cbFrameBodySize;
-    BOOL            bNeedACK;
-    BOOL            bIsPSPOLL = FALSE;
+    unsigned int cbHeaderSize;
+    unsigned int cbFrameBodySize;
+    bool bNeedACK;
+    bool bIsPSPOLL = false;
     PSTxBufHead     pTxBufHead;
-    UINT            cbFrameSize;
-    UINT            cbIVlen = 0;
-    UINT            cbICVlen = 0;
-    UINT            cbMIClen = 0;
-    UINT            cbFCSlen = 4;
-    UINT            uPadding = 0;
-    UINT            cbMICHDR = 0;
-    UINT            uLength = 0;
-    DWORD           dwMICKey0, dwMICKey1;
-    DWORD           dwMIC_Priority;
-    PDWORD          pdwMIC_L;
-    PDWORD          pdwMIC_R;
-    WORD            wTxBufSize;
-    UINT            cbMacHdLen;
+    unsigned int cbFrameSize;
+    unsigned int cbIVlen = 0;
+    unsigned int cbICVlen = 0;
+    unsigned int cbMIClen = 0;
+    unsigned int cbFCSlen = 4;
+    unsigned int uPadding = 0;
+    unsigned int cbMICHDR = 0;
+    unsigned int uLength = 0;
+    unsigned long dwMICKey0, dwMICKey1;
+    unsigned long dwMIC_Priority;
+    unsigned long *pdwMIC_L;
+    unsigned long *pdwMIC_R;
+    unsigned short wTxBufSize;
+    unsigned int cbMacHdLen;
     SEthernetHeader sEthHeader;
     void *          pvRrvTime;
     void *          pMICHDR;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    WORD            wCurrentRate = RATE_1M;
+    unsigned short wCurrentRate = RATE_1M;
     PUWLAN_80211HDR  p80211Header;
-    UINT             uNodeIndex = 0;
-    BOOL            bNodeExist = FALSE;
+    unsigned int uNodeIndex = 0;
+    bool bNodeExist = false;
     SKeyItem        STempKey;
     PSKeyItem       pTransmitKey = NULL;
-    PBYTE           pbyIVHead;
-    PBYTE           pbyPayloadHead;
-    PBYTE           pbyMacHdr;
+    unsigned char *pbyIVHead;
+    unsigned char *pbyPayloadHead;
+    unsigned char *pbyMacHdr;
 
-    UINT            cbExtSuppRate = 0;
+    unsigned int cbExtSuppRate = 0;
 //    PWLAN_IE        pItem;
 
 
@@ -2886,7 +2845,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
 
     pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
-    pbyTxBufferAddr = (PBYTE)pFrstTD->pTDInfo->buf;
+    pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
     pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
     wTxBufSize = sizeof(STxBufHead);
     memset(pTxBufHead, 0, wTxBufSize);
@@ -2938,20 +2897,19 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
     pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
 
 
-    if (IS_MULTICAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0])) ||
-        IS_BROADCAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0]))) {
-        bNeedACK = FALSE;
+    if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) {
+        bNeedACK = false;
         if (pDevice->bEnableHostWEP) {
             uNodeIndex = 0;
-            bNodeExist = TRUE;
+            bNodeExist = true;
         };
     }
     else {
         if (pDevice->bEnableHostWEP) {
-            if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (PBYTE)(p80211Header->sA3.abyAddr1), &uNodeIndex))
-                bNodeExist = TRUE;
+            if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
+                bNodeExist = true;
         };
-        bNeedACK = TRUE;
+        bNeedACK = true;
         pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
     };
 
@@ -2964,7 +2922,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
         // probe-response don't retry
         //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
-        //     bNeedACK = FALSE;
+        //     bNeedACK = false;
         //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK);
         //}
     }
@@ -2972,7 +2930,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
     pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
 
     if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
-        bIsPSPOLL = TRUE;
+        bIsPSPOLL = true;
         cbMacHdLen = WLAN_HDR_ADDR2_LEN;
     } else {
         cbMacHdLen = WLAN_HDR_ADDR3_LEN;
@@ -2996,12 +2954,12 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
 
     //Set FRAGCTL_MACHDCNT
-    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)cbMacHdLen << 10);
+    pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10);
 
     // Notes:
     // Although spec says MMPDU can be fragmented; In most case,
     // no one will send a MMPDU under fragmentation. With RTS may occur.
-    pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP
+    pDevice->bAES = false;  //Set FRAGCTL_WEPTYP
 
 
     if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
@@ -3024,7 +2982,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
             cbICVlen = 8;//MIC
             cbMICHDR = sizeof(SMICHDRHead);
             pTxBufHead->wFragCtl |= FRAGCTL_AES;
-            pDevice->bAES = TRUE;
+            pDevice->bAES = true;
         }
         //MAC Header should be padding 0 to DW alignment.
         uPadding = 4 - (cbMacHdLen%4);
@@ -3034,7 +2992,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
     cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
 
     //Set FIFOCTL_GrpAckPolicy
-    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+    if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
         pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
     }
     //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
@@ -3067,7 +3025,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
     //=========================
     //    No Fragmentation
     //=========================
-    pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
+    pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
 
 
     //Fill FIFO,RrvTime,RTS,and CTS
@@ -3082,9 +3040,9 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
 
-    pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderSize);
-    pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
-    pbyIVHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding);
+    pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize);
+    pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
+    pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding);
 
     // Copy the Packet into a tx Buffer
     memcpy(pbyMacHdr, pbMPDU, cbMacHdLen);
@@ -3127,30 +3085,30 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
         if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
 
-            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
-            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+            dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]);
 
             // DO Software Michael
             MIC_vInit(dwMICKey0, dwMICKey1);
-            MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12);
+            MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12);
             dwMIC_Priority = 0;
-            MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+            MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
 
             uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
 
             MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
 
-            pdwMIC_L = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize);
-            pdwMIC_R = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
+            pdwMIC_L = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
+            pdwMIC_R = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
 
             MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
             MIC_vUnInit();
 
-            if (pDevice->bTxMICFail == TRUE) {
+            if (pDevice->bTxMICFail == true) {
                 *pdwMIC_L = 0;
                 *pdwMIC_R = 0;
-                pDevice->bTxMICFail = FALSE;
+                pDevice->bTxMICFail = false;
             }
 
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
@@ -3160,8 +3118,8 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
         }
 
 
-        s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
-                     pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
+        s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+                     pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR);
 
         if (pDevice->bEnableHostWEP) {
             pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
@@ -3169,7 +3127,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
         }
 
         if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
-            s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (WORD)(cbFrameBodySize + cbMIClen));
+            s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen));
         }
     }
 
@@ -3208,7 +3166,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
         // Disable PS
         MACbPSWakeup(pDevice->PortOffset);
     }
-    pDevice->bPWBitOn = FALSE;
+    pDevice->bPWBitOn = false;
 
     wmb();
     pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
index b008fc23adb90ec41a903fc206168bbf11aa7fc8..fa827b828a300d9d8c19a9d9aab74b4c55d1f3a2 100644 (file)
 /*---------------------  Export Functions  --------------------------*/
 
 /*
-void vGenerateMACHeader(
-    PSDevice pDevice,
-    DWORD dwTxBufferAddr,
-    PBYTE pbySkbData,
-    UINT cbPacketSize,
-    BOOL bDMA0Used,
-    PUINT pcbHeadSize,
-    PUINT pcbAppendPayload
-     );
-
-void vProcessRxMACHeader (
-    PSDevice pDevice,
-    DWORD dwRxBufferAddr,
-    UINT cbPacketSize,
-    BOOL bIsWEP,
-    PUINT pcbHeadSize
-    );
+void
+vGenerateMACHeader(PSDevice pDevice, unsigned long dwTxBufferAddr, unsigned char *pbySkbData,
+       unsigned int cbPacketSize, bool bDMA0Used, unsigned int *pcbHeadSize,
+       unsigned int *pcbAppendPayload);
+
+void
+vProcessRxMACHeader(PSDevice pDevice, unsigned long dwRxBufferAddr, unsigned int cbPacketSize,
+       bool bIsWEP, unsigned int *pcbHeadSize);
 */
 
 
 void
 vGenerateMACHeader (
     PSDevice         pDevice,
-    PBYTE            pbyBufferAddr,
-    WORD             wDuration,
+    unsigned char *pbyBufferAddr,
+    unsigned short wDuration,
     PSEthernetHeader psEthHeader,
-    BOOL             bNeedEncrypt,
-    WORD             wFragType,
-    UINT             uDMAIdx,
-    UINT             uFragIdx
+    bool bNeedEncrypt,
+    unsigned short wFragType,
+    unsigned int uDMAIdx,
+    unsigned int uFragIdx
     );
 
 
-UINT
+unsigned int
 cbGetFragCount(
     PSDevice         pDevice,
     PSKeyItem        pTransmitKey,
-    UINT             cbFrameBodySize,
+    unsigned int       cbFrameBodySize,
     PSEthernetHeader psEthHeader
     );
 
 
 void
-vGenerateFIFOHeader (
-    PSDevice         pDevice,
-    BYTE             byPktTyp,
-    PBYTE            pbyTxBufferAddr,
-    BOOL             bNeedEncrypt,
-    UINT             cbPayloadSize,
-    UINT             uDMAIdx,
-    PSTxDesc         pHeadTD,
-    PSEthernetHeader psEthHeader,
-    PBYTE            pPacket,
-    PSKeyItem        pTransmitKey,
-    UINT             uNodeIndex,
-    PUINT            puMACfragNum,
-    PUINT            pcbHeaderSize
-    );
+vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktTyp, unsigned char *pbyTxBufferAddr,
+       bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx, PSTxDesc pHeadTD,
+       PSEthernetHeader psEthHeader, unsigned char *pPacket, PSKeyItem pTransmitKey,
+       unsigned int uNodeIndex, unsigned int *puMACfragNum, unsigned int *pcbHeaderSize);
 
 
-void vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen);
+void vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, unsigned char *pbMPDU, unsigned int cbMPDULen);
 CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
 CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
 
index 418575fdc2c069cbd66cf3133d8830c67d8a96fa..6a0a232d1a0c80b14d53f9312f0fb870a31a3b7e 100644 (file)
  * Return Value: data read
  *
  */
-BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset)
+unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntOffset)
 {
-    WORD    wDelay, wNoACK;
-    BYTE    byWait;
-    BYTE    byData;
-    BYTE    byOrg;
+    unsigned short wDelay, wNoACK;
+    unsigned char byWait;
+    unsigned char byData;
+    unsigned char byOrg;
 
     byData = 0xFF;
     VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
@@ -122,15 +122,15 @@ BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset)
  *  Out:
  *      none
  *
- * Return Value: TRUE if succeeded; FALSE if failed.
+ * Return Value: true if succeeded; false if failed.
  *
  */
-BOOL SROMbWriteEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData)
+bool SROMbWriteEmbedded(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byData)
 {
-    WORD    wDelay, wNoACK;
-    BYTE    byWait;
+    unsigned short wDelay, wNoACK;
+    unsigned char byWait;
 
-    BYTE    byOrg;
+    unsigned char byOrg;
 
     VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
     /* turn off hardware retry for getting NACK */
@@ -157,10 +157,10 @@ BOOL SROMbWriteEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData)
     }
     if (wNoACK == W_MAX_I2CRETRY) {
         VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
-        return FALSE;
+        return false;
     }
     VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
-    return TRUE;
+    return true;
 }
 
 
@@ -178,12 +178,12 @@ BOOL SROMbWriteEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData)
  * Return Value: none
  *
  */
-void SROMvRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits)
+void SROMvRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits)
 {
-    BYTE    byOrgData;
+    unsigned char byOrgData;
 
     byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
-    SROMbWriteEmbedded(dwIoBase, byContntOffset,(BYTE)(byOrgData | byBits));
+    SROMbWriteEmbedded(dwIoBase, byContntOffset,(unsigned char)(byOrgData | byBits));
 }
 
 
@@ -199,12 +199,12 @@ void SROMvRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits)
  *      none
  *
  */
-void SROMvRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits)
+void SROMvRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits)
 {
-    BYTE    byOrgData;
+    unsigned char byOrgData;
 
     byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
-    SROMbWriteEmbedded(dwIoBase, byContntOffset,(BYTE)(byOrgData & (~byBits)));
+    SROMbWriteEmbedded(dwIoBase, byContntOffset,(unsigned char)(byOrgData & (~byBits)));
 }
 
 
@@ -219,12 +219,12 @@ void SROMvRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all test bits on; otherwise FALSE
+ * Return Value: true if all test bits on; otherwise false
  *
  */
-BOOL SROMbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits)
+bool SROMbIsRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
 {
-    BYTE    byOrgData;
+    unsigned char byOrgData;
 
     byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
     return (byOrgData & byTestBits) == byTestBits;
@@ -242,12 +242,12 @@ BOOL SROMbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits)
  *  Out:
  *      none
  *
- * Return Value: TRUE if all test bits off; otherwise FALSE
+ * Return Value: true if all test bits off; otherwise false
  *
  */
-BOOL SROMbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits)
+bool SROMbIsRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
 {
-    BYTE    byOrgData;
+    unsigned char byOrgData;
 
     byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
     return !(byOrgData & byTestBits);
@@ -266,13 +266,13 @@ BOOL SROMbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits)
  * Return Value: none
  *
  */
-void SROMvReadAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs)
+void SROMvReadAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs)
 {
     int     ii;
 
     /* ii = Rom Address */
     for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
-        *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase,(BYTE) ii);
+        *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase,(unsigned char) ii);
         pbyEepromRegs++;
     }
 }
@@ -291,13 +291,13 @@ void SROMvReadAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs)
  * Return Value: none
  *
  */
-void SROMvWriteAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs)
+void SROMvWriteAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs)
 {
     int     ii;
 
     /* ii = Rom Address */
     for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
-        SROMbWriteEmbedded(dwIoBase,(BYTE) ii, *pbyEepromRegs);
+        SROMbWriteEmbedded(dwIoBase,(unsigned char) ii, *pbyEepromRegs);
         pbyEepromRegs++;
     }
 }
@@ -315,9 +315,9 @@ void SROMvWriteAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs)
  * Return Value: none
  *
  */
-void SROMvReadEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress)
+void SROMvReadEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress)
 {
-    BYTE     ii;
+    unsigned char ii;
 
     /* ii = Rom Address */
     for (ii = 0; ii < ETH_ALEN; ii++) {
@@ -340,9 +340,9 @@ void SROMvReadEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress)
  * Return Value: none
  *
  */
-void SROMvWriteEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress)
+void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress)
 {
-    BYTE     ii;
+    unsigned char ii;
 
     /* ii = Rom Address */
     for (ii = 0; ii < ETH_ALEN; ii++) {
@@ -364,11 +364,11 @@ void SROMvWriteEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress)
  * Return Value: none
  *
  */
-void SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId)
+void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId)
 {
-    PBYTE   pbyData;
+    unsigned char *pbyData;
 
-    pbyData = (PBYTE)pdwSubSysVenId;
+    pbyData = (unsigned char *)pdwSubSysVenId;
     /* sub vendor */
     *pbyData = SROMbyReadEmbedded(dwIoBase, 6);
     *(pbyData+1) = SROMbyReadEmbedded(dwIoBase, 7);
@@ -386,15 +386,15 @@ void SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId)
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL SROMbAutoLoad(DWORD_PTR dwIoBase)
+bool SROMbAutoLoad(unsigned long dwIoBase)
 {
-    BYTE    byWait;
+    unsigned char byWait;
     int     ii;
 
-    BYTE    byOrg;
+    unsigned char byOrg;
 
     VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
     /* turn on hardware retry */
@@ -413,8 +413,8 @@ BOOL SROMbAutoLoad(DWORD_PTR dwIoBase)
     VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
 
     if (ii == EEP_MAX_CONTEXT_SIZE)
-        return FALSE;
-    return TRUE;
+        return false;
+    return true;
 }
 
 
index dbb3f5efe9798fadacef1cd74e1fa6863eb49b56..4c261dac01b5b1bcec5e9a39cc8fd438e21c990e 100644 (file)
 //      2048 bits = 256 bytes = 128 words
 //
 typedef struct tagSSromReg {
-    BYTE    abyPAR[6];                  // 0x00 (WORD)
-
-    WORD    wSUB_VID;                   // 0x03 (WORD)
-    WORD    wSUB_SID;
-
-    BYTE    byBCFG0;                    // 0x05 (WORD)
-    BYTE    byBCFG1;
-
-    BYTE    byFCR0;                     // 0x06 (WORD)
-    BYTE    byFCR1;
-    BYTE    byPMC0;                     // 0x07 (WORD)
-    BYTE    byPMC1;
-    BYTE    byMAXLAT;                   // 0x08 (WORD)
-    BYTE    byMINGNT;
-    BYTE    byCFG0;                     // 0x09 (WORD)
-    BYTE    byCFG1;
-    WORD    wCISPTR;                    // 0x0A (WORD)
-    WORD    wRsv0;                      // 0x0B (WORD)
-    WORD    wRsv1;                      // 0x0C (WORD)
-    BYTE    byBBPAIR;                   // 0x0D (WORD)
-    BYTE    byRFTYPE;
-    BYTE    byMinChannel;               // 0x0E (WORD)
-    BYTE    byMaxChannel;
-    BYTE    bySignature;                // 0x0F (WORD)
-    BYTE    byCheckSum;
-
-    BYTE    abyReserved0[96];           // 0x10 (WORD)
-    BYTE    abyCIS[128];                // 0x80 (WORD)
+    unsigned char abyPAR[6];                  // 0x00 (unsigned short)
+
+    unsigned short wSUB_VID;                   // 0x03 (unsigned short)
+    unsigned short wSUB_SID;
+
+    unsigned char byBCFG0;                    // 0x05 (unsigned short)
+    unsigned char byBCFG1;
+
+    unsigned char byFCR0;                     // 0x06 (unsigned short)
+    unsigned char byFCR1;
+    unsigned char byPMC0;                     // 0x07 (unsigned short)
+    unsigned char byPMC1;
+    unsigned char byMAXLAT;                   // 0x08 (unsigned short)
+    unsigned char byMINGNT;
+    unsigned char byCFG0;                     // 0x09 (unsigned short)
+    unsigned char byCFG1;
+    unsigned short wCISPTR;                    // 0x0A (unsigned short)
+    unsigned short wRsv0;                      // 0x0B (unsigned short)
+    unsigned short wRsv1;                      // 0x0C (unsigned short)
+    unsigned char byBBPAIR;                   // 0x0D (unsigned short)
+    unsigned char byRFTYPE;
+    unsigned char byMinChannel;               // 0x0E (unsigned short)
+    unsigned char byMaxChannel;
+    unsigned char bySignature;                // 0x0F (unsigned short)
+    unsigned char byCheckSum;
+
+    unsigned char abyReserved0[96];           // 0x10 (unsigned short)
+    unsigned char abyCIS[128];                // 0x80 (unsigned short)
 } SSromReg, *PSSromReg;
 
 /*---------------------  Export Macros ------------------------------*/
@@ -135,23 +135,23 @@ typedef struct tagSSromReg {
 
 /*---------------------  Export Functions  --------------------------*/
 
-BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset);
-BOOL SROMbWriteEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData);
+unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntOffset);
+bool SROMbWriteEmbedded(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byData);
 
-void SROMvRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits);
-void SROMvRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits);
+void SROMvRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits);
+void SROMvRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits);
 
-BOOL SROMbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits);
-BOOL SROMbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits);
+bool SROMbIsRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits);
+bool SROMbIsRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits);
 
-void SROMvReadAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs);
-void SROMvWriteAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs);
+void SROMvReadAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs);
+void SROMvWriteAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs);
 
-void SROMvReadEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress);
-void SROMvWriteEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress);
+void SROMvReadEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress);
+void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress);
 
-void SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId);
+void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId);
 
-BOOL SROMbAutoLoad (DWORD_PTR dwIoBase);
+bool SROMbAutoLoad (unsigned long dwIoBase);
 
 #endif // __EEPROM_H__
index 5f0c74763f8706ae6fb3ab23d3fe760746f34451..f9c28bf8a6afc5b446e7f8b94c4a86c0262ae9f7 100644 (file)
@@ -42,7 +42,7 @@
 /*---------------------  Static Variables  --------------------------*/
 
 // 32-bit CRC table
-static const DWORD s_adwCrc32Table[256] = {
+static const unsigned long s_adwCrc32Table[256] = {
     0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
     0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
     0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
@@ -132,13 +132,13 @@ static const DWORD s_adwCrc32Table[256] = {
  * Return Value: CRC-32
  *
 -*/
-DWORD CRCdwCrc32 (PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed)
+unsigned long CRCdwCrc32 (unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed)
 {
-    DWORD dwCrc;
+    unsigned long dwCrc;
 
     dwCrc = dwCrcSeed;
     while (cbByte--) {
-        dwCrc = s_adwCrc32Table[(BYTE)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8);
+        dwCrc = s_adwCrc32Table[(unsigned char)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8);
         pbyData++;
     }
 
@@ -164,7 +164,7 @@ DWORD CRCdwCrc32 (PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed)
  * Return Value: CRC-32
  *
 -*/
-DWORD CRCdwGetCrc32 (PBYTE pbyData, UINT cbByte)
+unsigned long CRCdwGetCrc32 (unsigned char *pbyData, unsigned int cbByte)
 {
     return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL);
 }
@@ -190,7 +190,7 @@ DWORD CRCdwGetCrc32 (PBYTE pbyData, UINT cbByte)
  * Return Value: CRC-32
  *
 -*/
-DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC)
+unsigned long CRCdwGetCrc32Ex(unsigned char *pbyData, unsigned int cbByte, unsigned long dwPreCRC)
 {
     return CRCdwCrc32(pbyData, cbByte, dwPreCRC);
 }
index 5faa48b0a74827c80467babbb31f0ac6d347abaf..d0449855beb16fc107c3d7b386b751a5be119c5b 100644 (file)
@@ -43,9 +43,9 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed);
-DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte);
-DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC);
+unsigned long CRCdwCrc32(unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed);
+unsigned long CRCdwGetCrc32(unsigned char *pbyData, unsigned int cbByte);
+unsigned long CRCdwGetCrc32Ex(unsigned char *pbyData, unsigned int cbByte, unsigned long dwPreCRC);
 
 #endif // __TCRC_H__
 
index d8ba67395cb183ba85c8f06fcb032ca7d80c5df4..1cf8508e407d0b15c169f8680cbabd6d0830be81 100644 (file)
  * Return Value: Hash value
  *
  */
-BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr)
+unsigned char ETHbyGetHashIndexByCrc32 (unsigned char *pbyMultiAddr)
 {
     int     ii;
-    BYTE    byTmpHash;
-    BYTE    byHash = 0;
+    unsigned char byTmpHash;
+    unsigned char byHash = 0;
 
     // get the least 6-bits from CRC generator
-    byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN,
+    byTmpHash = (unsigned char)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN,
             0xFFFFFFFFL) & 0x3F);
     // reverse most bit to least bit
     for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) {
@@ -93,17 +93,17 @@ BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr)
  *  Out:
  *      none
  *
- * Return Value: TRUE if ok; FALSE if error.
+ * Return Value: true if ok; false if error.
  *
  */
-BOOL ETHbIsBufferCrc32Ok (PBYTE pbyBuffer, UINT cbFrameLength)
+bool ETHbIsBufferCrc32Ok (unsigned char *pbyBuffer, unsigned int cbFrameLength)
 {
-    DWORD dwCRC;
+    unsigned long dwCRC;
 
     dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4);
-    if (cpu_to_le32(*((PDWORD)(pbyBuffer + cbFrameLength - 4))) != dwCRC) {
-        return FALSE;
+    if (cpu_to_le32(*((unsigned long *)(pbyBuffer + cbFrameLength - 4))) != dwCRC) {
+        return false;
     }
-    return TRUE;
+    return true;
 }
 
index 3c9acd7903a89178cd09d4a6071521a510e001b0..787d885deee978696f57a61d16a80d159d72dbe0 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef __TETHER_H__
 #define __TETHER_H__
 
-#include <linux/if_ether.h>
+#include <linux/etherdevice.h>
 #include "ttype.h"
 
 /*---------------------  Export Definitions -------------------------*/
 #define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1)
                                         // Ethernet address string length
 
-#define MIN_DATA_LEN        46          // min data length
-
-#define MIN_PACKET_LEN      (MIN_DATA_LEN + ETH_HLEN)
-                                        // 60
-                                        // min total packet length (tx)
-
 #define MAX_LOOKAHEAD_SIZE  ETH_FRAME_LEN
 
 #define U_MULTI_ADDR_LEN    8           // multicast address length
 // Ethernet packet
 //
 typedef struct tagSEthernetHeader {
-    BYTE    abyDstAddr[ETH_ALEN];
-    BYTE    abySrcAddr[ETH_ALEN];
-    WORD    wType;
+    unsigned char abyDstAddr[ETH_ALEN];
+    unsigned char abySrcAddr[ETH_ALEN];
+    unsigned short wType;
 }__attribute__ ((__packed__))
 SEthernetHeader, *PSEthernetHeader;
 
@@ -171,9 +165,9 @@ SEthernetHeader, *PSEthernetHeader;
 // 802_3 packet
 //
 typedef struct tagS802_3Header {
-    BYTE    abyDstAddr[ETH_ALEN];
-    BYTE    abySrcAddr[ETH_ALEN];
-    WORD    wLen;
+    unsigned char abyDstAddr[ETH_ALEN];
+    unsigned char abySrcAddr[ETH_ALEN];
+    unsigned short wLen;
 }__attribute__ ((__packed__))
 S802_3Header, *PS802_3Header;
 
@@ -181,37 +175,17 @@ S802_3Header, *PS802_3Header;
 // 802_11 packet
 //
 typedef struct tagS802_11Header {
-    WORD    wFrameCtl;
-    WORD    wDurationID;
-    BYTE    abyAddr1[ETH_ALEN];
-    BYTE    abyAddr2[ETH_ALEN];
-    BYTE    abyAddr3[ETH_ALEN];
-    WORD    wSeqCtl;
-    BYTE    abyAddr4[ETH_ALEN];
+    unsigned short wFrameCtl;
+    unsigned short wDurationID;
+    unsigned char abyAddr1[ETH_ALEN];
+    unsigned char abyAddr2[ETH_ALEN];
+    unsigned char abyAddr3[ETH_ALEN];
+    unsigned short wSeqCtl;
+    unsigned char abyAddr4[ETH_ALEN];
 }__attribute__ ((__packed__))
 S802_11Header, *PS802_11Header;
 
 /*---------------------  Export Macros ------------------------------*/
-// Frame type macro
-
-#define IS_MULTICAST_ADDRESS(pbyEtherAddr)          \
-    ((*(PBYTE)(pbyEtherAddr) & 0x01) == 1)
-
-#define IS_BROADCAST_ADDRESS(pbyEtherAddr) (        \
-    (*(PDWORD)(pbyEtherAddr) == 0xFFFFFFFFL) &&     \
-    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0xFFFF) \
-)
-
-#define IS_NULL_ADDRESS(pbyEtherAddr) (             \
-    (*(PDWORD)(pbyEtherAddr) == 0L) &&              \
-    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0)      \
-)
-
-#define IS_ETH_ADDRESS_EQUAL(pbyAddr1, pbyAddr2) (  \
-    (*(PDWORD)(pbyAddr1) == *(PDWORD)(pbyAddr2)) && \
-    (*(PWORD)((PBYTE)(pbyAddr1) + 4) ==             \
-    *(PWORD)((PBYTE)(pbyAddr2) + 4))                \
-)
 
 /*---------------------  Export Classes  ----------------------------*/
 
@@ -219,9 +193,9 @@ S802_11Header, *PS802_11Header;
 
 /*---------------------  Export Functions  --------------------------*/
 
-BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr);
-//BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr);
-BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength);
+unsigned char ETHbyGetHashIndexByCrc32(unsigned char *pbyMultiAddr);
+//unsigned char ETHbyGetHashIndexByCrc(unsigned char *pbyMultiAddr);
+bool ETHbIsBufferCrc32Ok(unsigned char *pbyBuffer, unsigned int cbFrameLength);
 
 #endif // __TETHER_H__
 
index f83af5913aa6268eefd271616c1957aac91cdd03..ed3eac17ae8d9ac1c761e52a5a63cc72937f4f0d 100644 (file)
@@ -55,7 +55,7 @@
 /* The 2nd table is the same as the 1st but with the upper and lower   */
 /* bytes swapped. To allow an endian tolerant implementation, the byte */
 /* halves have been expressed independently here.                      */
-const BYTE TKIP_Sbox_Lower[256] = {
+const unsigned char TKIP_Sbox_Lower[256] = {
     0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
     0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
     0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
@@ -90,7 +90,7 @@ const BYTE TKIP_Sbox_Lower[256] = {
     0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
 };
 
-const BYTE TKIP_Sbox_Upper[256] = {
+const unsigned char TKIP_Sbox_Upper[256] = {
     0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
     0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
     0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
@@ -184,11 +184,11 @@ unsigned int rotr1(unsigned int a)
  *
  */
 void TKIPvMixKey(
-    PBYTE   pbyTKey,
-    PBYTE   pbyTA,
-    WORD    wTSC15_0,
-    DWORD   dwTSC47_16,
-    PBYTE   pbyRC4Key
+    unsigned char *pbyTKey,
+    unsigned char *pbyTA,
+    unsigned short wTSC15_0,
+    unsigned long dwTSC47_16,
+    unsigned char *pbyRC4Key
     )
 {
     unsigned int p1k[5];
index 3dfa7f5ee7ec74f82d4c5d77fcf99a93a6c7ac35..eb5951d726e0f36763e4357fa9458b8e8732d92b 100644 (file)
 /*---------------------  Export Functions  --------------------------*/
 
 void TKIPvMixKey(
-    PBYTE   pbyTKey,
-    PBYTE   pbyTA,
-    WORD    wTSC15_0,
-    DWORD   dwTSC47_16,
-    PBYTE   pbyRC4Key
+    unsigned char *pbyTKey,
+    unsigned char *pbyTA,
+    unsigned short wTSC15_0,
+    unsigned long dwTSC47_16,
+    unsigned char *pbyRC4Key
     );
 
 #endif // __TKIP_H__
index e96c140de0528cdeb86f1d960b5d6845961dd93d..e8b177d4128b5f45c9ef9b81d1da12d5a5742b33 100644 (file)
 /****** Common helper macros ***********************************************/
 
 #if !defined(LOBYTE)
-#define LOBYTE(w)           ((BYTE)(w))
+#define LOBYTE(w)           ((unsigned char)(w))
 #endif
 #if !defined(HIBYTE)
-#define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF))
+#define HIBYTE(w)           ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF))
 #endif
 
 #if !defined(LOWORD)
-#define LOWORD(d)           ((WORD)(d))
+#define LOWORD(d)           ((unsigned short)(d))
 #endif
 #if !defined(HIWORD)
-#define HIWORD(d)           ((WORD)((((DWORD)(d)) >> 16) & 0xFFFF))
+#define HIWORD(d)           ((unsigned short)((((unsigned long)(d)) >> 16) & 0xFFFF))
 #endif
 
 #define LODWORD(q)          ((q).u.dwLowDword)
 #define HIDWORD(q)          ((q).u.dwHighDword)
 
 #if !defined(MAKEWORD)
-#define MAKEWORD(lb, hb)    ((WORD)(((BYTE)(lb)) | (((WORD)((BYTE)(hb))) << 8)))
+#define MAKEWORD(lb, hb)    ((unsigned short)(((unsigned char)(lb)) | (((unsigned short)((unsigned char)(hb))) << 8)))
 #endif
 #if !defined(MAKEDWORD)
-#define MAKEDWORD(lw, hw)   ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16)))
+#define MAKEDWORD(lw, hw)   ((unsigned long)(((unsigned short)(lw)) | (((unsigned long)((unsigned short)(hw))) << 16)))
 #endif
 
 #endif // __TMACRO_H__
index 2921083a9f22e9342cf27b5e40e58ee9a42a6574..37c8fba1fd1d3613d343f0b95e2f22f0d36c5ec9 100644 (file)
 
 /******* Common definitions and typedefs ***********************************/
 
-#ifndef OUT
-#define OUT
-#endif
-
 #ifndef TxInSleep
 #define TxInSleep
 #endif
 
-typedef int             BOOL;
-
-#if !defined(TRUE)
-#define TRUE            1
-#endif
-#if !defined(FALSE)
-#define FALSE           0
-#endif
-
 //2007-0809-01<Add>by MikeLiu
 #ifndef  update_BssList
 #define update_BssList
@@ -65,10 +52,6 @@ typedef int             BOOL;
 #define Calcu_LinkQual
 #endif
 
-#ifndef Calcu_LinkQual
-#define Calcu_LinkQual
-#endif
-
 /****** Simple typedefs  ***************************************************/
 
 /* These lines assume that your compiler's longs are 32 bits and
@@ -76,37 +59,13 @@ typedef int             BOOL;
  * but it doesn't matter if they're signed or unsigned.
  */
 
-typedef signed char             I8;     /* 8-bit signed integer */
-
-typedef unsigned char           U8;     /* 8-bit unsigned integer */
-typedef unsigned short          U16;    /* 16-bit unsigned integer */
-typedef unsigned long           U32;    /* 32-bit unsigned integer */
-
-
-typedef char            CHAR;
-typedef signed short    SHORT;
-typedef signed int      INT;
-typedef signed long     LONG;
-
-typedef unsigned char   UCHAR;
-typedef unsigned short  USHORT;
-typedef unsigned int    UINT;
-typedef unsigned long   ULONG;
-typedef unsigned long long     ULONGLONG; //64 bit
-
-
-
-typedef unsigned char   BYTE;           //  8-bit
-typedef unsigned short  WORD;           // 16-bit
-typedef unsigned long   DWORD;          // 32-bit
-
 // QWORD is for those situation that we want
 // an 8-byte-aligned 8 byte long structure
 // which is NOT really a floating point number.
 typedef union tagUQuadWord {
     struct {
-        DWORD   dwLowDword;
-        DWORD   dwHighDword;
+        unsigned int dwLowDword;
+        unsigned int dwHighDword;
     } u;
     double      DoNotUseThisField;
 } UQuadWord;
@@ -114,18 +73,6 @@ typedef UQuadWord       QWORD;          // 64-bit
 
 /****** Common pointer types ***********************************************/
 
-typedef unsigned long   ULONG_PTR;      // 32-bit
-typedef unsigned long   DWORD_PTR;      // 32-bit
-
-// boolean pointer
-typedef unsigned int *   PUINT;
-
-typedef BYTE *           PBYTE;
-
-typedef WORD *           PWORD;
-
-typedef DWORD *          PDWORD;
-
 typedef QWORD *          PQWORD;
 
 #endif // __TTYPE_H__
index acd1b661490db496cfa8e016a4116bbc17a00bec..9596fdef0e3cc01c5a7336c808c78090f8fdab0c 100644 (file)
 
 
 #define VNSvInPortB(dwIOAddress, pbyData) {                     \
-       volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress));            \
+       volatile unsigned char * pbyAddr = ((unsigned char *)(dwIOAddress));            \
        *(pbyData) = readb(pbyAddr);                           \
 }
 
 
 #define VNSvInPortW(dwIOAddress, pwData) {                      \
-       volatile WORD* pwAddr = ((PWORD)(dwIOAddress));             \
+       volatile unsigned short *pwAddr = ((unsigned short *)(dwIOAddress));             \
        *(pwData) = readw(pwAddr);                             \
 }
 
 #define VNSvInPortD(dwIOAddress, pdwData) {                     \
-       volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress));          \
+       volatile unsigned long *pdwAddr = ((unsigned long *)(dwIOAddress));          \
        *(pdwData) = readl(pdwAddr);                           \
 }
 
 
 #define VNSvOutPortB(dwIOAddress, byData) {                     \
-    volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress));            \
-    writeb((BYTE)byData, pbyAddr);                                                     \
+    volatile unsigned char * pbyAddr = ((unsigned char *)(dwIOAddress));            \
+    writeb((unsigned char)byData, pbyAddr);                                                    \
 }
 
 
 #define VNSvOutPortW(dwIOAddress, wData) {                      \
-    volatile WORD* pwAddr = ((PWORD)(dwIOAddress));             \
-    writew((WORD)wData, pwAddr);                                                       \
+    volatile unsigned short *pwAddr = ((unsigned short *)(dwIOAddress));             \
+    writew((unsigned short)wData, pwAddr);                                                     \
 }
 
 #define VNSvOutPortD(dwIOAddress, dwData) {                     \
-    volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress));          \
-    writel((DWORD)dwData, pdwAddr);                                        \
+    volatile unsigned long *pdwAddr = ((unsigned long *)(dwIOAddress));          \
+    writel((unsigned long)dwData, pdwAddr);                                        \
 }
 
 #endif
 
 
 #define PCAvDelayByIO(uDelayUnit) {             \
-    BYTE    byData;                             \
-    ULONG   ii;                                 \
+    unsigned char byData;                       \
+    unsigned long ii;                           \
                                                 \
     if (uDelayUnit <= 50) {                     \
         udelay(uDelayUnit);                     \
index b527a019188bac0c0a9ef3c2e9f6714aec26e6fc..fcf26ab920d0a5b7155130be5875c0c3cada54e4 100644 (file)
@@ -101,9 +101,9 @@ VNTWIFIvSetOPMode (
 void
 VNTWIFIvSetIBSSParameter (
     void *pMgmtHandle,
-    WORD  wBeaconPeriod,
-    WORD  wATIMWindow,
-    UINT  uChannel
+    unsigned short wBeaconPeriod,
+    unsigned short wATIMWindow,
+    unsigned int uChannel
     )
 {
     PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
@@ -150,7 +150,7 @@ VNTWIFIpGetCurrentSSID (
  * Return Value: current Channel.
  *
 -*/
-UINT
+unsigned int
 VNTWIFIpGetCurrentChannel (
     void *pMgmtHandle
     )
@@ -176,7 +176,7 @@ VNTWIFIpGetCurrentChannel (
  * Return Value: current Assoc ID
  *
 -*/
-WORD
+unsigned short
 VNTWIFIwGetAssocID (
     void *pMgmtHandle
     )
@@ -202,15 +202,15 @@ VNTWIFIwGetAssocID (
  * Return Value: max support rate
  *
 -*/
-BYTE
+unsigned char
 VNTWIFIbyGetMaxSupportRate (
     PWLAN_IE_SUPP_RATES pSupportRateIEs,
     PWLAN_IE_SUPP_RATES pExtSupportRateIEs
     )
 {
-    BYTE    byMaxSupportRate = RATE_1M;
-    BYTE    bySupportRate = RATE_1M;
-    UINT    ii = 0;
+    unsigned char byMaxSupportRate = RATE_1M;
+    unsigned char bySupportRate = RATE_1M;
+    unsigned int ii = 0;
 
     if (pSupportRateIEs) {
         for (ii = 0; ii < pSupportRateIEs->len; ii++) {
@@ -248,16 +248,16 @@ VNTWIFIbyGetMaxSupportRate (
  * Return Value: max support rate
  *
 -*/
-BYTE
+unsigned char
 VNTWIFIbyGetACKTxRate (
-    BYTE byRxDataRate,
+    unsigned char byRxDataRate,
     PWLAN_IE_SUPP_RATES pSupportRateIEs,
     PWLAN_IE_SUPP_RATES pExtSupportRateIEs
     )
 {
-    BYTE    byMaxAckRate;
-    BYTE    byBasicRate;
-    UINT    ii;
+    unsigned char byMaxAckRate;
+    unsigned char byBasicRate;
+    unsigned int ii;
 
     if (byRxDataRate <= RATE_11M) {
         byMaxAckRate = RATE_1M;
@@ -317,9 +317,9 @@ VNTWIFIvSetAuthenticationMode (
     pMgmt->eAuthenMode = eAuthMode;
     if ((eAuthMode == WMAC_AUTH_SHAREKEY) ||
         (eAuthMode == WMAC_AUTH_AUTO)) {
-        pMgmt->bShareKeyAlgorithm = TRUE;
+        pMgmt->bShareKeyAlgorithm = true;
     } else {
-        pMgmt->bShareKeyAlgorithm = FALSE;
+        pMgmt->bShareKeyAlgorithm = false;
     }
 }
 
@@ -350,15 +350,15 @@ VNTWIFIvSetEncryptionMode (
     if ((eEncryptionMode == WMAC_ENCRYPTION_WEPEnabled) ||
         (eEncryptionMode == WMAC_ENCRYPTION_TKIPEnabled) ||
         (eEncryptionMode == WMAC_ENCRYPTION_AESEnabled) ) {
-        pMgmt->bPrivacyInvoked = TRUE;
+        pMgmt->bPrivacyInvoked = true;
     } else {
-        pMgmt->bPrivacyInvoked = FALSE;
+        pMgmt->bPrivacyInvoked = false;
     }
 }
 
 
 
-BOOL
+bool
 VNTWIFIbConfigPhyMode (
     void *pMgmtHandle,
     CARD_PHY_TYPE ePhyType
@@ -368,14 +368,14 @@ VNTWIFIbConfigPhyMode (
 
     if ((ePhyType != PHY_TYPE_AUTO) &&
         (ePhyType != pMgmt->eCurrentPHYMode)) {
-        if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL)==TRUE) {
+        if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL)==true) {
             pMgmt->eCurrentPHYMode = ePhyType;
         } else {
-            return(FALSE);
+            return(false);
         }
     }
     pMgmt->eConfigPHYMode = ePhyType;
-    return(TRUE);
+    return(true);
 }
 
 
@@ -425,16 +425,12 @@ VNTWIFIbGetConfigPhyMode (
 -*/
 
 void
-VNTWIFIvQueryBSSList (
-    void *pMgmtHandle,
-    PUINT   puBSSCount,
-    void **pvFirstBSS
-    )
+VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, void **pvFirstBSS)
 {
-    UINT            ii = 0;
+    unsigned int ii = 0;
     PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
     PKnownBSS       pBSS = NULL;
-    UINT            uCount = 0;
+    unsigned int uCount = 0;
 
     *pvFirstBSS = NULL;
 
@@ -471,7 +467,7 @@ VNTWIFIvGetNextBSS (
         if (pBSS > &(pMgmt->sBSSList[MAX_BSS_NUM])) {
             return;
         }
-        if (pBSS->bActive == TRUE) {
+        if (pBSS->bActive == true) {
             *pvNextBSS = pBSS;
             return;
         }
@@ -497,24 +493,24 @@ VNTWIFIvGetNextBSS (
 void
 VNTWIFIvUpdateNodeTxCounter(
     void *pMgmtHandle,
-    PBYTE    pbyDestAddress,
-    BOOL     bTxOk,
-    WORD     wRate,
-    PBYTE    pbyTxFailCount
+    unsigned char *pbyDestAddress,
+    bool bTxOk,
+    unsigned short wRate,
+    unsigned char *pbyTxFailCount
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
-    UINT            uNodeIndex = 0;
-    UINT            ii;
+    unsigned int uNodeIndex = 0;
+    unsigned int ii;
 
     if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
         (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
-        if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == FALSE) {
+        if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == false) {
             return;
         }
     }
     pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++;
-    if (bTxOk == TRUE) {
+    if (bTxOk == true) {
         // transmit success, TxAttempts at least plus one
         pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
         pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++;
@@ -532,19 +528,19 @@ VNTWIFIvUpdateNodeTxCounter(
 void
 VNTWIFIvGetTxRate(
     void *pMgmtHandle,
-    PBYTE    pbyDestAddress,
-    PWORD   pwTxDataRate,
-    PBYTE   pbyACKRate,
-    PBYTE   pbyCCKBasicRate,
-    PBYTE   pbyOFDMBasicRate
+    unsigned char *pbyDestAddress,
+    unsigned short *pwTxDataRate,
+    unsigned char *pbyACKRate,
+    unsigned char *pbyCCKBasicRate,
+    unsigned char *pbyOFDMBasicRate
     )
 {
     PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
-    UINT                uNodeIndex = 0;
-    WORD                wTxDataRate = RATE_1M;
-    BYTE                byACKRate = RATE_1M;
-    BYTE                byCCKBasicRate = RATE_1M;
-    BYTE                byOFDMBasicRate = RATE_24M;
+    unsigned int uNodeIndex = 0;
+    unsigned short wTxDataRate = RATE_1M;
+    unsigned char byACKRate = RATE_1M;
+    unsigned char byCCKBasicRate = RATE_1M;
+    unsigned char byOFDMBasicRate = RATE_24M;
     PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL;
     PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL;
 
@@ -579,12 +575,12 @@ VNTWIFIvGetTxRate(
         pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates;
         pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates;
     }
-    byACKRate = VNTWIFIbyGetACKTxRate(  (BYTE) wTxDataRate,
+    byACKRate = VNTWIFIbyGetACKTxRate(  (unsigned char) wTxDataRate,
                                         pSupportRateIEs,
                                         pExtSupportRateIEs
                                         );
-    if (byACKRate > (BYTE) wTxDataRate) {
-        byACKRate = (BYTE) wTxDataRate;
+    if (byACKRate > (unsigned char) wTxDataRate) {
+        byACKRate = (unsigned char) wTxDataRate;
     }
     byCCKBasicRate = VNTWIFIbyGetACKTxRate( RATE_11M,
                                             pSupportRateIEs,
@@ -601,15 +597,15 @@ VNTWIFIvGetTxRate(
     return;
 }
 
-BYTE
+unsigned char
 VNTWIFIbyGetKeyCypher(
     void *pMgmtHandle,
-    BOOL     bGroupKey
+    bool bGroupKey
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
 
-    if (bGroupKey == TRUE) {
+    if (bGroupKey == true) {
         return (pMgmt->byCSSGK);
     } else {
         return (pMgmt->byCSSPK);
@@ -618,7 +614,7 @@ VNTWIFIbyGetKeyCypher(
 
 
 /*
-BOOL
+bool
 VNTWIFIbInit(
     void *pAdapterHandler,
     void **pMgmtHandler
@@ -626,13 +622,13 @@ VNTWIFIbInit(
 {
 
     PSMgmtObject        pMgmt = NULL;
-    UINT                ii;
+    unsigned int ii;
 
 
     pMgmt = (PSMgmtObject)kmalloc(sizeof(SMgmtObject), (int)GFP_ATOMIC);
     if (pMgmt == NULL) {
         *pMgmtHandler = NULL;
-        return FALSE;
+        return false;
     }
 
     memset(pMgmt, 0, sizeof(SMgmtObject));
@@ -652,41 +648,41 @@ VNTWIFIbInit(
     pMgmt->uCmdDequeueIdx = 0;
     pMgmt->uCmdEnqueueIdx = 0;
     pMgmt->eCommandState = WLAN_CMD_STATE_IDLE;
-    pMgmt->bCmdStop = FALSE;
-    pMgmt->bCmdRunning = FALSE;
+    pMgmt->bCmdStop = false;
+    pMgmt->bCmdRunning = false;
 
     *pMgmtHandler = pMgmt;
-    return TRUE;
+    return true;
 }
 */
 
 
 
-BOOL
+bool
 VNTWIFIbSetPMKIDCache (
     void *pMgmtObject,
-    ULONG ulCount,
+    unsigned long ulCount,
     void *pPMKIDInfo
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
 
     if (ulCount > MAX_PMKID_CACHE) {
-        return (FALSE);
+        return (false);
     }
     pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount;
     memcpy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo)));
-    return (TRUE);
+    return (true);
 }
 
 
 
-WORD
+unsigned short
 VNTWIFIwGetMaxSupportRate(
     void *pMgmtObject
     )
 {
-    WORD wRate = RATE_54M;
+    unsigned short wRate = RATE_54M;
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
 
     for(wRate = RATE_54M; wRate > RATE_1M; wRate--) {
@@ -705,7 +701,7 @@ VNTWIFIwGetMaxSupportRate(
 void
 VNTWIFIvSet11h (
     void *pMgmtObject,
-    BOOL  b11hEnable
+    bool b11hEnable
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
@@ -713,19 +709,19 @@ VNTWIFIvSet11h (
     pMgmt->b11hEnable = b11hEnable;
 }
 
-BOOL
+bool
 VNTWIFIbMeasureReport(
     void *pMgmtObject,
-    BOOL  bEndOfReport,
+    bool bEndOfReport,
     void *pvMeasureEID,
-    BYTE  byReportMode,
-    BYTE  byBasicMap,
-    BYTE  byCCAFraction,
-    PBYTE pbyRPIs
+    unsigned char byReportMode,
+    unsigned char byBasicMap,
+    unsigned char byCCAFraction,
+    unsigned char *pbyRPIs
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
-    PBYTE           pbyCurrentEID = (PBYTE) (pMgmt->pCurrMeasureEIDRep);
+    unsigned char *pbyCurrentEID = (unsigned char *) (pMgmt->pCurrMeasureEIDRep);
 
     //spin_lock_irq(&pDevice->lock);
     if ((pvMeasureEID != NULL) &&
@@ -765,49 +761,49 @@ VNTWIFIbMeasureReport(
         pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len);
         pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID;
     }
-    if (bEndOfReport == TRUE) {
+    if (bEndOfReport == true) {
         IEEE11hbMSRRepTx(pMgmt);
     }
     //spin_unlock_irq(&pDevice->lock);
-    return (TRUE);
+    return (true);
 }
 
 
-BOOL
+bool
 VNTWIFIbChannelSwitch(
     void *pMgmtObject,
-    BYTE  byNewChannel
+    unsigned char byNewChannel
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
 
     //spin_lock_irq(&pDevice->lock);
     pMgmt->uCurrChannel = byNewChannel;
-    pMgmt->bSwitchChannel = FALSE;
+    pMgmt->bSwitchChannel = false;
     //spin_unlock_irq(&pDevice->lock);
-    return TRUE;
+    return true;
 }
 
 /*
-BOOL
+bool
 VNTWIFIbRadarPresent(
     void *pMgmtObject,
-    BYTE  byChannel
+    unsigned char byChannel
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
     if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
-        (byChannel == (BYTE) pMgmt->uCurrChannel) &&
-        (pMgmt->bSwitchChannel != TRUE) &&
-        (pMgmt->b11hEnable == TRUE)) {
-        if (IS_ETH_ADDRESS_EQUAL(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) {
-            pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(BYTE) pMgmt->uCurrChannel);
-            pMgmt->bSwitchChannel = TRUE;
+        (byChannel == (unsigned char) pMgmt->uCurrChannel) &&
+        (pMgmt->bSwitchChannel != true) &&
+        (pMgmt->b11hEnable == true)) {
+        if (!compare_ether_addr(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) {
+            pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(unsigned char) pMgmt->uCurrChannel);
+            pMgmt->bSwitchChannel = true;
         }
         BEACONbSendBeacon(pMgmt);
         CARDbChannelSwitch(pMgmt->pAdapter, 0, pMgmt->byNewChannel, 10);
     }
-    return TRUE;
+    return true;
 }
 */
 
index c91dfd79adca625d2d04d9a4f8eb842cf01e2156..f4327abaa773f400e1a5a7131c8f20e3f9ace4dc 100644 (file)
@@ -143,9 +143,9 @@ typedef enum tagWMAC_POWER_MODE {
 void
 VNTWIFIvSetIBSSParameter (
     void *pMgmtHandle,
-    WORD  wBeaconPeriod,
-    WORD  wATIMWindow,
-    UINT  uChannel
+    unsigned short wBeaconPeriod,
+    unsigned short wATIMWindow,
+    unsigned int uChannel
     );
 
 void
@@ -159,25 +159,25 @@ VNTWIFIpGetCurrentSSID(
     void *pMgmtHandle
     );
 
-UINT
+unsigned int
 VNTWIFIpGetCurrentChannel(
     void *pMgmtHandle
     );
 
-WORD
+unsigned short
 VNTWIFIwGetAssocID (
     void *pMgmtHandle
     );
 
-BYTE
+unsigned char
 VNTWIFIbyGetMaxSupportRate (
     PWLAN_IE_SUPP_RATES pSupportRateIEs,
     PWLAN_IE_SUPP_RATES pExtSupportRateIEs
     );
 
-BYTE
+unsigned char
 VNTWIFIbyGetACKTxRate (
-    BYTE byRxDataRate,
+    unsigned char byRxDataRate,
     PWLAN_IE_SUPP_RATES pSupportRateIEs,
     PWLAN_IE_SUPP_RATES pExtSupportRateIEs
     );
@@ -195,7 +195,7 @@ VNTWIFIvSetEncryptionMode (
     );
 
 
-BOOL
+bool
 VNTWIFIbConfigPhyMode(
     void *pMgmtHandle,
     CARD_PHY_TYPE ePhyType
@@ -208,14 +208,8 @@ VNTWIFIbGetConfigPhyMode(
     );
 
 void
-VNTWIFIvQueryBSSList(
-    void *pMgmtHandle,
-    PUINT   puBSSCount,
-    void **pvFirstBSS
-    );
-
-
-
+VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount,
+               void **pvFirstBSS);
 
 void
 VNTWIFIvGetNextBSS (
@@ -229,52 +223,52 @@ VNTWIFIvGetNextBSS (
 void
 VNTWIFIvUpdateNodeTxCounter(
     void *pMgmtHandle,
-    PBYTE    pbyDestAddress,
-    BOOL     bTxOk,
-    WORD     wRate,
-    PBYTE    pbyTxFailCount
+    unsigned char *pbyDestAddress,
+    bool bTxOk,
+    unsigned short wRate,
+    unsigned char *pbyTxFailCount
     );
 
 
 void
 VNTWIFIvGetTxRate(
     void *pMgmtHandle,
-    PBYTE    pbyDestAddress,
-    PWORD   pwTxDataRate,
-    PBYTE   pbyACKRate,
-    PBYTE   pbyCCKBasicRate,
-    PBYTE   pbyOFDMBasicRate
+    unsigned char *pbyDestAddress,
+    unsigned short *pwTxDataRate,
+    unsigned char *pbyACKRate,
+    unsigned char *pbyCCKBasicRate,
+    unsigned char *pbyOFDMBasicRate
     );
 /*
-BOOL
+bool
 VNTWIFIbInit(
     void *pAdapterHandler,
     void **pMgmtHandler
     );
 */
 
-BYTE
+unsigned char
 VNTWIFIbyGetKeyCypher(
     void *pMgmtHandle,
-    BOOL     bGroupKey
+    bool bGroupKey
     );
 
 
 
 
-BOOL
+bool
 VNTWIFIbSetPMKIDCache (
     void *pMgmtObject,
-    ULONG ulCount,
+    unsigned long ulCount,
     void *pPMKIDInfo
     );
 
-BOOL
+bool
 VNTWIFIbCommandRunning (
     void *pMgmtObject
     );
 
-WORD
+unsigned short
 VNTWIFIwGetMaxSupportRate(
     void *pMgmtObject
     );
@@ -283,30 +277,30 @@ VNTWIFIwGetMaxSupportRate(
 void
 VNTWIFIvSet11h (
     void *pMgmtObject,
-    BOOL  b11hEnable
+    bool b11hEnable
     );
 
-BOOL
+bool
 VNTWIFIbMeasureReport(
     void *pMgmtObject,
-    BOOL  bEndOfReport,
+    bool bEndOfReport,
     void *pvMeasureEID,
-    BYTE  byReportMode,
-    BYTE  byBasicMap,
-    BYTE  byCCAFraction,
-    PBYTE pbyRPIs
+    unsigned char byReportMode,
+    unsigned char byBasicMap,
+    unsigned char byCCAFraction,
+    unsigned char *pbyRPIs
     );
 
-BOOL
+bool
 VNTWIFIbChannelSwitch(
     void *pMgmtObject,
-    BYTE  byNewChannel
+    unsigned char byNewChannel
     );
 /*
-BOOL
+bool
 VNTWIFIbRadarPresent(
     void *pMgmtObject,
-    BYTE  byChannel
+    unsigned char byChannel
     );
 */
 
index 28665d870f597e1491e7b0b3e8532f4e5ac990ce..abd6745bc3fe08226a48ce6d0dd245b40176d268 100644 (file)
@@ -52,6 +52,7 @@
 #include "rxtx.h"
 #include "rf.h"
 #include "iowpa.h"
+#include "channel.h"
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -77,7 +78,7 @@ PSTxMgmtPacket
 s_MgrMakeProbeRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    PBYTE pScanBSSID,
+    unsigned char *pScanBSSID,
     PWLAN_IE_SSID pSSID,
     PWLAN_IE_SUPP_RATES pCurrRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
@@ -85,7 +86,7 @@ s_MgrMakeProbeRequest(
 
 
 static
-BOOL
+bool
 s_bCommandComplete (
     PSDevice pDevice
     );
@@ -116,7 +117,7 @@ vAdHocBeaconStop(PSDevice  pDevice)
 {
 
     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
-    BOOL            bStop;
+    bool bStop;
 
     /*
      * temporarily stop Beacon packet for AdHoc Server
@@ -129,18 +130,18 @@ vAdHocBeaconStop(PSDevice  pDevice)
      *      or
      *      (3.2) AdHoc channel is in A mode
      */
-    bStop = FALSE;
+    bStop = false;
     if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
     (pMgmt->eCurrState >= WMAC_STATE_STARTED))
     {
         if ((pMgmt->uIBSSChannel <=  CB_MAX_CHANNEL_24G) &&
              (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G))
         {
-            bStop = TRUE;
+            bStop = true;
         }
         if (pMgmt->uIBSSChannel >  CB_MAX_CHANNEL_24G)
         {
-            bStop = TRUE;
+            bStop = true;
         }
     }
 
@@ -208,15 +209,15 @@ s_vProbeChannel(
     )
 {
                                                      //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
-    BYTE abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
-    BYTE abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+    unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+    unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
                                                            //6M,   9M,   12M,  48M
-    BYTE abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
-    BYTE abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
-    PBYTE           pbyRate;
+    unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+    unsigned char *pbyRate;
     PSTxMgmtPacket  pTxPacket;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
-    UINT            ii;
+    unsigned int ii;
 
 
     if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
@@ -269,7 +270,7 @@ PSTxMgmtPacket
 s_MgrMakeProbeRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    PBYTE pScanBSSID,
+    unsigned char *pScanBSSID,
     PWLAN_IE_SSID pSSID,
     PWLAN_IE_SUPP_RATES pCurrRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
@@ -282,8 +283,8 @@ s_MgrMakeProbeRequest(
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
     vMgrEncodeProbeRequest(&sFrame);
     sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
@@ -320,16 +321,16 @@ s_MgrMakeProbeRequest(
 void
 vCommandTimerWait(
     void *hDeviceContext,
-    UINT MSecond
+    unsigned int MSecond
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
 
     init_timer(&pDevice->sTimerCommand);
-    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.data = (unsigned long) pDevice;
     pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
     // RUN_AT :1 msec ~= (HZ/1024)
-    pDevice->sTimerCommand.expires = (UINT)RUN_AT((MSecond * HZ) >> 10);
+    pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10);
     add_timer(&pDevice->sTimerCommand);
     return;
 }
@@ -347,14 +348,14 @@ vCommandTimer (
     PWLAN_IE_SSID   pItemSSID;
     PWLAN_IE_SSID   pItemSSIDCurr;
     CMD_STATUS      Status;
-    UINT            ii;
-    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    unsigned int ii;
+    unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
     struct sk_buff  *skb;
 
 
     if (pDevice->dwDiagRefCount != 0)
         return;
-    if (pDevice->bCmdRunning != TRUE)
+    if (pDevice->bCmdRunning != true)
         return;
 
     spin_lock_irq(&pDevice->lock);
@@ -364,7 +365,7 @@ vCommandTimer (
         case WLAN_CMD_SCAN_START:
 
        pDevice->byReAssocCount = 0;
-            if (pDevice->bRadioOff == TRUE) {
+            if (pDevice->bRadioOff == true) {
                 s_bCommandComplete(pDevice);
                 spin_unlock_irq(&pDevice->lock);
                 return;
@@ -396,7 +397,7 @@ vCommandTimer (
 
                 // Set Baseband's sensitivity back.
                 // Set channel back
-                CARDbSetChannel(pMgmt->pAdapter, pMgmt->uCurrChannel);
+                set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel);
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
                 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
                     CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
@@ -408,7 +409,7 @@ vCommandTimer (
 
             } else {
 //2008-8-4 <add> by chester
-                 if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
+               if (!is_channel_valid(pMgmt->uScanChannel)) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
                     s_bCommandComplete(pDevice);
                     return;
@@ -431,7 +432,7 @@ vCommandTimer (
 
                 vAdHocBeaconStop(pDevice);
 
-                if (CARDbSetChannel(pMgmt->pAdapter, pMgmt->uScanChannel) == TRUE) {
+                if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel) == true) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SCAN Channel: %d\n", pMgmt->uScanChannel);
                 } else {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel);
@@ -441,7 +442,7 @@ vCommandTimer (
       //          printk("chester-ch=%d\n",pMgmt->uScanChannel);
        pMgmt->uScanChannel++;
 //2008-8-4 <modify> by chester
-        if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) &&
+               if (!is_channel_valid(pMgmt->uScanChannel) &&
                         pMgmt->uScanChannel <= pDevice->byMaxChannel ){
                     pMgmt->uScanChannel=pDevice->byMaxChannel+1;
                 pMgmt->eCommandState = WLAN_CMD_SCAN_END;
@@ -449,7 +450,7 @@ vCommandTimer (
                 }
 
 
-                if ((pMgmt->b11hEnable == FALSE) ||
+                if ((pMgmt->b11hEnable == false) ||
                     (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
                     s_vProbeChannel(pDevice);
                     spin_unlock_irq(&pDevice->lock);
@@ -469,7 +470,7 @@ vCommandTimer (
 
             // Set Baseband's sensitivity back.
             // Set channel back
-            CARDbSetChannel(pMgmt->pAdapter, pMgmt->uCurrChannel);
+            set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel);
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
             if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
                 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
@@ -502,14 +503,14 @@ vCommandTimer (
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
                 // reason = 8 : disassoc because sta has left
                 vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status);
-                pDevice->bLinkPass = FALSE;
+                pDevice->bLinkPass = false;
                 // unlock command busy
                 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
                 pItemSSID->len = 0;
                 memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
-                pMgmt->sNodeDBTable[0].bActive = FALSE;
-//                pDevice->bBeaconBufReady = FALSE;
+                pMgmt->sNodeDBTable[0].bActive = false;
+//                pDevice->bBeaconBufReady = false;
             }
             netif_stop_queue(pDevice->dev);
             pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT;
@@ -539,7 +540,7 @@ vCommandTimer (
 
         case WLAN_CMD_SSID_START:
                pDevice->byReAssocCount = 0;
-            if (pDevice->bRadioOff == TRUE) {
+            if (pDevice->bRadioOff == true) {
                 s_bCommandComplete(pDevice);
                 spin_unlock_irq(&pDevice->lock);
                 return;
@@ -573,7 +574,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                 }
 
                 netif_stop_queue(pDevice->dev);
-                pDevice->bLinkPass = FALSE;
+                pDevice->bLinkPass = false;
             }
             // set initial state
             pMgmt->eCurrState = WMAC_STATE_IDLE;
@@ -607,9 +608,9 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                     if (netif_queue_stopped(pDevice->dev)){
                         netif_wake_queue(pDevice->dev);
                     }
-                    pDevice->bLinkPass = TRUE;
+                    pDevice->bLinkPass = true;
 
-                    pMgmt->sNodeDBTable[0].bActive = TRUE;
+                    pMgmt->sNodeDBTable[0].bActive = true;
                     pMgmt->sNodeDBTable[0].uInActiveCount = 0;
                     bClearBSSID_SCAN(pDevice);
                 }
@@ -635,12 +636,12 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                     if (netif_queue_stopped(pDevice->dev)){
                         netif_wake_queue(pDevice->dev);
                     }
-                    pDevice->bLinkPass = TRUE;
+                    pDevice->bLinkPass = true;
                 }
                 else {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
                  #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                    // if(pDevice->bWPASuppWextEnabled == true)
                         {
                        union iwreq_data  wrqu;
                        memset(&wrqu, 0, sizeof (wrqu));
@@ -685,7 +686,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                  pDevice->byLinkWaitCount = 0;
                 #if 0
                      #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                    // if(pDevice->bWPASuppWextEnabled == true)
                         {
                        union iwreq_data  wrqu;
                        memset(&wrqu, 0, sizeof (wrqu));
@@ -707,7 +708,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                 if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
                     KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset);
                 }
-                pDevice->bLinkPass = TRUE;
+                pDevice->bLinkPass = true;
                 pDevice->byLinkWaitCount = 0;
                 pDevice->byReAssocCount = 0;
                 bClearBSSID_SCAN(pDevice);
@@ -719,20 +720,20 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                     netif_wake_queue(pDevice->dev);
                 }
             #ifdef TxInSleep
-                if(pDevice->IsTxDataTrigger != FALSE)   {    //TxDataTimer is not triggered at the first time
+                if(pDevice->IsTxDataTrigger != false)   {    //TxDataTimer is not triggered at the first time
                      // printk("Re-initial TxDataTimer****\n");
                    del_timer(&pDevice->sTimerTxData);
                       init_timer(&pDevice->sTimerTxData);
-                      pDevice->sTimerTxData.data = (ULONG)pDevice;
+                      pDevice->sTimerTxData.data = (unsigned long) pDevice;
                       pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
                       pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
-                      pDevice->fTxDataInSleep = FALSE;
+                      pDevice->fTxDataInSleep = false;
                       pDevice->nTxDataTimeCout = 0;
                 }
                 else {
                   // printk("mike:-->First time triger TimerTxData InSleep\n");
                 }
-               pDevice->IsTxDataTrigger = TRUE;
+               pDevice->IsTxDataTrigger = true;
                 add_timer(&pDevice->sTimerTxData);
              #endif
             }
@@ -749,7 +750,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                  pDevice->byLinkWaitCount = 0;
                #if 0
                      #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                    // if(pDevice->bWPASuppWextEnabled == true)
                         {
                        union iwreq_data  wrqu;
                        memset(&wrqu, 0, sizeof (wrqu));
@@ -770,14 +771,14 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                 del_timer(&pMgmt->sTimerSecondCallback);
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
-                pDevice->bLinkPass = FALSE;
-                if (pDevice->bEnableHostWEP == TRUE)
+                pDevice->bLinkPass = false;
+                if (pDevice->bEnableHostWEP == true)
                     BSSvClearNodeDBTable(pDevice, 1);
                 else
                     BSSvClearNodeDBTable(pDevice, 0);
                 pDevice->uAssocCount = 0;
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
-                pDevice->bFixRate = FALSE;
+                pDevice->bFixRate = false;
 
                 vMgrCreateOwnIBSS((void *)pDevice, &Status);
                 if (Status != CMD_STATUS_SUCCESS){
@@ -791,7 +792,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                 if (netif_queue_stopped(pDevice->dev)){
                     netif_wake_queue(pDevice->dev);
                 }
-                pDevice->bLinkPass = TRUE;
+                pDevice->bLinkPass = true;
                 add_timer(&pMgmt->sTimerSecondCallback);
             }
             s_bCommandComplete(pDevice);
@@ -803,10 +804,10 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                 while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
                     if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
                         pMgmt->abyPSTxMap[0] &= ~byMask[0];
-                        pDevice->bMoreData = FALSE;
+                        pDevice->bMoreData = false;
                     }
                     else {
-                        pDevice->bMoreData = TRUE;
+                        pDevice->bMoreData = true;
                     }
                     if (!device_dma0_xmit(pDevice, skb, 0)) {
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
@@ -826,10 +827,10 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                             // clear tx map
                             pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
                                     ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
-                            pDevice->bMoreData = FALSE;
+                            pDevice->bMoreData = false;
                         }
                         else {
-                            pDevice->bMoreData = TRUE;
+                            pDevice->bMoreData = true;
                         }
                         if (!device_dma0_xmit(pDevice, skb, ii)) {
                             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
@@ -846,7 +847,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                                     ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
                     }
-                    pMgmt->sNodeDBTable[ii].bRxPSPoll = FALSE;
+                    pMgmt->sNodeDBTable[ii].bRxPSPoll = false;
                 }
             }
 
@@ -856,7 +857,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
 
         case WLAN_CMD_RADIO_START :
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
-            if (pDevice->bRadioCmd == TRUE)
+            if (pDevice->bRadioCmd == true)
                 CARDbRadioPowerOn(pDevice);
             else
                 CARDbRadioPowerOff(pDevice);
@@ -896,23 +897,23 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
 
 
 static
-BOOL
+bool
 s_bCommandComplete (
     PSDevice pDevice
     )
 {
     PWLAN_IE_SSID pSSID;
-    BOOL          bRadioCmd = FALSE;
-    //WORD          wDeAuthenReason = 0;
-    BOOL          bForceSCAN = TRUE;
+    bool bRadioCmd = false;
+    //unsigned short wDeAuthenReason = 0;
+    bool bForceSCAN = true;
     PSMgmtObject  pMgmt = pDevice->pMgmt;
 
 
     pDevice->eCommandState = WLAN_CMD_IDLE;
     if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
         //Command Queue Empty
-        pDevice->bCmdRunning = FALSE;
-        return TRUE;
+        pDevice->bCmdRunning = false;
+        return true;
     }
     else {
         pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
@@ -921,7 +922,7 @@ s_bCommandComplete (
         bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
         ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
         pDevice->cbFreeCmdQueue++;
-        pDevice->bCmdRunning = TRUE;
+        pDevice->bCmdRunning = true;
         switch ( pDevice->eCommand ) {
             case WLAN_CMD_BSSID_SCAN:
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
@@ -933,7 +934,7 @@ s_bCommandComplete (
                     memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
                 }
 /*
-                if ((bForceSCAN == FALSE) && (pDevice->bLinkPass == TRUE)) {
+                if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) {
                     if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
                         ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
                         pDevice->eCommandState = WLAN_CMD_IDLE;
@@ -974,25 +975,25 @@ s_bCommandComplete (
         vCommandTimerWait((void *)pDevice, 0);
     }
 
-    return TRUE;
+    return true;
 }
 
 
 
-BOOL bScheduleCommand (
+bool bScheduleCommand (
     void *hDeviceContext,
     CMD_CODE    eCommand,
-    PBYTE       pbyItem0
+    unsigned char *pbyItem0
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
 
 
     if (pDevice->cbFreeCmdQueue == 0) {
-        return (FALSE);
+        return (false);
     }
     pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
-    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = TRUE;
+    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true;
     memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
 
     if (pbyItem0 != NULL) {
@@ -1001,7 +1002,7 @@ BOOL bScheduleCommand (
             case WLAN_CMD_BSSID_SCAN:
                 memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
                          pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = FALSE;
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false;
                 break;
 
             case WLAN_CMD_SSID:
@@ -1014,7 +1015,7 @@ BOOL bScheduleCommand (
                 break;
 /*
             case WLAN_CMD_DEAUTH:
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((PWORD)pbyItem0);
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((unsigned short *)pbyItem0);
                 break;
 */
 
@@ -1037,12 +1038,12 @@ BOOL bScheduleCommand (
     ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
     pDevice->cbFreeCmdQueue--;
 
-    if (pDevice->bCmdRunning == FALSE) {
+    if (pDevice->bCmdRunning == false) {
         s_bCommandComplete(pDevice);
     }
     else {
     }
-    return (TRUE);
+    return (true);
 
 }
 
@@ -1057,16 +1058,16 @@ BOOL bScheduleCommand (
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
+ * Return Value: true if success; otherwise false
  *
  */
-BOOL bClearBSSID_SCAN (
+bool bClearBSSID_SCAN (
     void *hDeviceContext
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
-    UINT            uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
-    UINT            ii;
+    unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
+    unsigned int ii;
 
     if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
         for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii ++) {
@@ -1077,7 +1078,7 @@ BOOL bClearBSSID_SCAN (
                 break;
         }
     }
-    return TRUE;
+    return true;
 }
 
 //mike add:reset command timer
@@ -1092,15 +1093,15 @@ vResetCommandTimer(
       del_timer(&pDevice->sTimerCommand);
   //init timer
       init_timer(&pDevice->sTimerCommand);
-    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.data = (unsigned long) pDevice;
     pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
     pDevice->sTimerCommand.expires = RUN_AT(HZ);
     pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
     pDevice->uCmdDequeueIdx = 0;
     pDevice->uCmdEnqueueIdx = 0;
     pDevice->eCommandState = WLAN_CMD_IDLE;
-    pDevice->bCmdRunning = FALSE;
-    pDevice->bCmdClear = FALSE;
+    pDevice->bCmdRunning = false;
+    pDevice->bCmdClear = false;
 }
 
 
@@ -1125,16 +1126,16 @@ BSSvSecondTxData(
 
   spin_lock_irq(&pDevice->lock);
   #if 1
-  if(((pDevice->bLinkPass ==TRUE)&&(pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
-      (pDevice->fWPA_Authened == TRUE)) {   //wpa linking
+  if(((pDevice->bLinkPass ==true)&&(pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
+      (pDevice->fWPA_Authened == true)) {   //wpa linking
  #else
-  if(pDevice->bLinkPass ==TRUE) {
+  if(pDevice->bLinkPass ==true) {
  #endif
 
         //   printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__);
-         pDevice->fTxDataInSleep = TRUE;
+         pDevice->fTxDataInSleep = true;
          PSbSendNullPacket(pDevice);      //send null packet
-         pDevice->fTxDataInSleep = FALSE;
+         pDevice->fTxDataInSleep = false;
        }
   spin_unlock_irq(&pDevice->lock);
 
index c3c418089513c001a6507877b17eee3e07b65a5e..69d4fc55b843e14b8774d7ee0789e7f0ee206c7a 100644 (file)
@@ -75,11 +75,11 @@ typedef enum tagCMD_STATUS {
 
 typedef struct tagCMD_ITEM {
     CMD_CODE eCmd;
-    BYTE     abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-    BOOL     bNeedRadioOFF;
-    WORD     wDeAuthenReason;
-    BOOL     bRadioCmd;
-    BOOL     bForceSCAN;
+    unsigned char abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    bool bNeedRadioOFF;
+    unsigned short wDeAuthenReason;
+    bool bRadioCmd;
+    bool bForceSCAN;
 } CMD_ITEM, *PCMD_ITEM;
 
 // Command state
@@ -119,21 +119,21 @@ vCommandTimer (
     void *hDeviceContext
     );
 
-BOOL bClearBSSID_SCAN(
+bool bClearBSSID_SCAN(
     void *hDeviceContext
     );
 
-BOOL
+bool
 bScheduleCommand(
     void *hDeviceContext,
     CMD_CODE    eCommand,
-    PBYTE       pbyItem0
+    unsigned char *pbyItem0
     );
 
 void
 vCommandTimerWait(
     void *hDeviceContext,
-    UINT MSecond
+    unsigned int MSecond
     );
 #ifdef TxInSleep
 void
index 64a66b2f1fc5ae323d008c8fe0c2c1f0ac87ef04..c096583a7726110043f76a7288752d6f68a4a722 100644 (file)
@@ -52,8 +52,8 @@
 
 /*
  * Description:
- *      Scan Rx cache.  Return TRUE if packet is duplicate, else
- *      inserts in receive cache and returns FALSE.
+ *      Scan Rx cache.  Return true if packet is duplicate, else
+ *      inserts in receive cache and returns false.
  *
  * Parameters:
  *  In:
  *  Out:
  *      none
  *
- * Return Value: TRUE if packet duplicate; otherwise FALSE
+ * Return Value: true if packet duplicate; otherwise false
  *
  */
 
-BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
+bool WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
 {
-    UINT            uIndex;
-    UINT            ii;
+    unsigned int uIndex;
+    unsigned int ii;
     PSCacheEntry    pCacheEntry;
 
     if (IS_FC_RETRY(pMACHeader)) {
@@ -78,10 +78,10 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
         for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
             pCacheEntry = &(pCache->asCacheEntry[uIndex]);
             if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) &&
-                (IS_ETH_ADDRESS_EQUAL (&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
+                (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
                 ) {
                 /* Duplicate match */
-                return TRUE;
+                return true;
             }
             ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH);
         }
@@ -91,7 +91,7 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
     pCacheEntry->wFmSequence = pMACHeader->wSeqCtl;
     memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN);
     ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH);
-    return FALSE;
+    return false;
 }
 
 /*
@@ -108,13 +108,13 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
  * Return Value: index number in Defragment Database
  *
  */
-UINT WCTLuSearchDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
+unsigned int WCTLuSearchDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
 {
-UINT ii;
+unsigned int ii;
 
     for(ii=0;ii<pDevice->cbDFCB;ii++) {
-        if ((pDevice->sRxDFCB[ii].bInUse == TRUE) &&
-            (IS_ETH_ADDRESS_EQUAL (&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
+        if ((pDevice->sRxDFCB[ii].bInUse == true) &&
+            (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
             ) {
             //
             return(ii);
@@ -138,17 +138,17 @@ UINT ii;
  * Return Value: index number in Defragment Database
  *
  */
-UINT WCTLuInsertDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
+unsigned int WCTLuInsertDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
 {
-UINT ii;
+unsigned int ii;
 
     if (pDevice->cbFreeDFCB == 0)
         return(pDevice->cbDFCB);
     for(ii=0;ii<pDevice->cbDFCB;ii++) {
-        if (pDevice->sRxDFCB[ii].bInUse == FALSE) {
+        if (pDevice->sRxDFCB[ii].bInUse == false) {
             pDevice->cbFreeDFCB--;
             pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime;
-            pDevice->sRxDFCB[ii].bInUse = TRUE;
+            pDevice->sRxDFCB[ii].bInUse = true;
             pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4);
             pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F);
             memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN);
@@ -172,15 +172,15 @@ UINT ii;
  *  Out:
  *      none
  *
- * Return Value: TRUE if it is valid fragment packet and we have resource to defragment; otherwise FALSE
+ * Return Value: true if it is valid fragment packet and we have resource to defragment; otherwise false
  *
  */
-BOOL WCTLbHandleFragment (PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV)
+bool WCTLbHandleFragment (PSDevice pDevice, PS802_11Header pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV)
 {
-UINT            uHeaderSize;
+unsigned int uHeaderSize;
 
 
-    if (bWEP == TRUE) {
+    if (bWEP == true) {
         uHeaderSize = 28;
         if (bExtIV)
         // ExtIV
@@ -201,17 +201,17 @@ UINT            uHeaderSize;
         else {
             pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader);
             if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) {
-                return(FALSE);
+                return(false);
             }
         }
         // reserve 4 byte to match MAC RX Buffer
-        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4);
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (unsigned char *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4);
         memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength);
         pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength;
         pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength;
         pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
         //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
-        return(FALSE);
+        return(false);
     }
     else {
         pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader);
@@ -220,7 +220,7 @@ UINT            uHeaderSize;
                 (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) &&
                 ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) {
 
-                memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((PBYTE) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize));
+                memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((unsigned char *) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize));
                 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize);
                 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize);
                 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
@@ -229,21 +229,21 @@ UINT            uHeaderSize;
             else {
                 // seq error or frag # error flush DFCB
                 pDevice->cbFreeDFCB++;
-                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = FALSE;
-                return(FALSE);
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false;
+                return(false);
             }
         }
         else {
-            return(FALSE);
+            return(false);
         }
         if (IS_LAST_FRAGMENT_PKT(pMACHeader)) {
             //enq defragcontrolblock
             pDevice->cbFreeDFCB++;
-            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = FALSE;
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false;
             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
-            return(TRUE);
+            return(true);
         }
-        return(FALSE);
+        return(false);
     }
 }
 
index a1ac4791bfd3015abd5f1262633522b65f8d494a..a92bb6d2b3f0e9868fdc1ab2624366609922844e 100644 (file)
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader);
-BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV);
-UINT WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
-UINT WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
+bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader);
+bool WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader,
+               unsigned int cbFrameLength, bool bWEP, bool bExtIV);
+unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
+unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
 
 #endif // __WCTL_H__
 
index 8af356fd139e213c7a79d715d23c6e0985b91240..e540110a430e75fc77ccc6edf325c1a70b4edc8b 100644 (file)
@@ -65,6 +65,7 @@
 #include "desc.h"
 #include "device.h"
 #include "card.h"
+#include "channel.h"
 #include "80211hdr.h"
 #include "80211mgr.h"
 #include "wmgr.h"
@@ -93,9 +94,9 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 /*---------------------  Static Functions  --------------------------*/
 //2008-8-4 <add> by chester
-static BOOL ChannelExceedZoneType(
+static bool ChannelExceedZoneType(
     PSDevice pDevice,
-    BYTE byCurrChannel
+    unsigned char byCurrChannel
     );
 
 // Association/diassociation functions
@@ -104,9 +105,9 @@ PSTxMgmtPacket
 s_MgrMakeAssocRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    PBYTE pDAddr,
-    WORD wCurrCapInfo,
-    WORD wListenInterval,
+    unsigned char *pDAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wListenInterval,
     PWLAN_IE_SSID pCurrSSID,
     PWLAN_IE_SUPP_RATES pCurrRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
@@ -118,7 +119,7 @@ s_vMgrRxAssocRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
     PSRxMgmtPacket pRxPacket,
-    UINT  uNodeIndex
+    unsigned int uNodeIndex
     );
 
 static
@@ -126,9 +127,9 @@ PSTxMgmtPacket
 s_MgrMakeReAssocRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    PBYTE pDAddr,
-    WORD wCurrCapInfo,
-    WORD wListenInterval,
+    unsigned char *pDAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wListenInterval,
     PWLAN_IE_SSID pCurrSSID,
     PWLAN_IE_SUPP_RATES pCurrRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
@@ -140,7 +141,7 @@ s_vMgrRxAssocResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
     PSRxMgmtPacket pRxPacket,
-    BOOL bReAssocType
+    bool bReAssocType
     );
 
 static
@@ -225,7 +226,7 @@ s_vMgrRxBeacon(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
     PSRxMgmtPacket pRxPacket,
-    BOOL bInScan
+    bool bInScan
     );
 
 static
@@ -240,12 +241,12 @@ PSTxMgmtPacket
 s_MgrMakeBeacon(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wCurrBeaconPeriod,
-    UINT uCurrChannel,
-    WORD wCurrATIMWinodw,
+    unsigned short wCurrCapInfo,
+    unsigned short wCurrBeaconPeriod,
+    unsigned int uCurrChannel,
+    unsigned short wCurrATIMWinodw,
     PWLAN_IE_SSID pCurrSSID,
-    PBYTE pCurrBSSID,
+    unsigned char *pCurrBSSID,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
     );
@@ -257,10 +258,10 @@ PSTxMgmtPacket
 s_MgrMakeAssocResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wAssocStatus,
-    WORD wAssocAID,
-    PBYTE pDstAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wAssocStatus,
+    unsigned short wAssocAID,
+    unsigned char *pDstAddr,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
     );
@@ -271,10 +272,10 @@ PSTxMgmtPacket
 s_MgrMakeReAssocResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wAssocStatus,
-    WORD wAssocAID,
-    PBYTE pDstAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wAssocStatus,
+    unsigned short wAssocAID,
+    unsigned char *pDstAddr,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
     );
@@ -285,16 +286,16 @@ PSTxMgmtPacket
 s_MgrMakeProbeResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wCurrBeaconPeriod,
-    UINT uCurrChannel,
-    WORD wCurrATIMWinodw,
-    PBYTE pDstAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wCurrBeaconPeriod,
+    unsigned int uCurrChannel,
+    unsigned short wCurrATIMWinodw,
+    unsigned char *pDstAddr,
     PWLAN_IE_SSID pCurrSSID,
-    PBYTE pCurrBSSID,
+    unsigned char *pCurrBSSID,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
-    BYTE byPHYType
+    unsigned char byPHYType
     );
 
 // received status
@@ -302,7 +303,7 @@ static
 void
 s_vMgrLogStatus(
     PSMgmtObject pMgmt,
-    WORD wStatus
+    unsigned short wStatus
     );
 
 
@@ -310,18 +311,18 @@ static
 void
 s_vMgrSynchBSS (
     PSDevice      pDevice,
-    UINT          uBSSMode,
+    unsigned int uBSSMode,
     PKnownBSS     pCurr,
     PCMD_STATUS  pStatus
     );
 
 
-static BOOL
+static bool
 s_bCipherMatch (
     PKnownBSS                        pBSSNode,
     NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
-    PBYTE                           pbyCCSPK,
-    PBYTE                           pbyCCSGK
+    unsigned char *pbyCCSPK,
+    unsigned char *pbyCCSGK
     );
 
  static void  Encyption_Rebuild(
@@ -368,7 +369,7 @@ vMgrObjectInit(
     pMgmt->byCSSPK = KEY_CTL_NONE;
     pMgmt->byCSSGK = KEY_CTL_NONE;
     pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
-    BSSvClearBSSList((void *)pDevice, FALSE);
+    BSSvClearBSSList((void *)pDevice, false);
 
     return;
 }
@@ -393,22 +394,22 @@ vMgrTimerInit(
 
 
     init_timer(&pMgmt->sTimerSecondCallback);
-    pMgmt->sTimerSecondCallback.data = (ULONG)pDevice;
+    pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice;
     pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
     pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
 
     init_timer(&pDevice->sTimerCommand);
-    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.data = (unsigned long) pDevice;
     pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
     pDevice->sTimerCommand.expires = RUN_AT(HZ);
 
    #ifdef TxInSleep
     init_timer(&pDevice->sTimerTxData);
-    pDevice->sTimerTxData.data = (ULONG)pDevice;
+    pDevice->sTimerTxData.data = (unsigned long) pDevice;
     pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
     pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
-    pDevice->fTxDataInSleep = FALSE;
-    pDevice->IsTxDataTrigger = FALSE;
+    pDevice->fTxDataInSleep = false;
+    pDevice->IsTxDataTrigger = false;
     pDevice->nTxDataTimeCout = 0;
    #endif
 
@@ -441,7 +442,7 @@ vMgrObjectReset(
 
     pMgmt->eCurrMode = WMAC_MODE_STANDBY;
     pMgmt->eCurrState = WMAC_STATE_IDLE;
-    pDevice->bEnablePSMode = FALSE;
+    pDevice->bEnablePSMode = false;
     // TODO: timer
 
     return;
@@ -487,15 +488,15 @@ vMgrAssocBeginSta(
     // ERP Phy (802.11g) should support short preamble.
     if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
-        if (CARDbIsShorSlotTime(pMgmt->pAdapter) == TRUE) {
+        if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) {
             pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
         }
     } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
-        if (CARDbIsShortPreamble(pMgmt->pAdapter) == TRUE) {
+        if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) {
             pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
         }
     }
-    if (pMgmt->b11hEnable == TRUE)
+    if (pMgmt->b11hEnable == true)
         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
 
     /* build an assocreq frame and send it */
@@ -566,15 +567,15 @@ vMgrReAssocBeginSta(
     // ERP Phy (802.11g) should support short preamble.
     if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
-        if (CARDbIsShorSlotTime(pMgmt->pAdapter) == TRUE) {
+        if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) {
             pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
         }
     } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
-        if (CARDbIsShortPreamble(pMgmt->pAdapter) == TRUE) {
+        if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) {
             pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
         }
     }
-    if (pMgmt->b11hEnable == TRUE)
+    if (pMgmt->b11hEnable == true)
         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
 
 
@@ -619,8 +620,8 @@ void
 vMgrDisassocBeginSta(
     void *hDeviceContext,
     PSMgmtObject pMgmt,
-    PBYTE  abyDestAddress,
-    WORD    wReason,
+    unsigned char *abyDestAddress,
+    unsigned short wReason,
     PCMD_STATUS pStatus
     )
 {
@@ -630,10 +631,10 @@ vMgrDisassocBeginSta(
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
 
     // Setup the sFrame structure
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
 
     // format fixed field frame structure
@@ -683,17 +684,17 @@ s_vMgrRxAssocRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
     PSRxMgmtPacket pRxPacket,
-    UINT uNodeIndex
+    unsigned int uNodeIndex
     )
 {
     WLAN_FR_ASSOCREQ    sFrame;
     CMD_STATUS          Status;
     PSTxMgmtPacket      pTxPacket;
-    WORD                wAssocStatus = 0;
-    WORD                wAssocAID = 0;
-    UINT                uRateLen = WLAN_RATES_MAXLEN;
-    BYTE                abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-    BYTE                abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned short wAssocStatus = 0;
+    unsigned short wAssocAID = 0;
+    unsigned int uRateLen = WLAN_RATES_MAXLEN;
+    unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
 
 
     if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
@@ -708,7 +709,7 @@ s_vMgrRxAssocRequest(
     memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
     memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
     sFrame.len = pRxPacket->cbMPDULen;
-    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
 
     vMgrDecodeAssocRequest(&sFrame);
 
@@ -717,7 +718,7 @@ s_vMgrRxAssocRequest(
         pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
         pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
         pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
-                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? TRUE : FALSE;
+                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
         // Todo: check sta basic rate, if ap can't support, set status code
         if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
             uRateLen = WLAN_RATES_MAXLEN_11B;
@@ -739,7 +740,7 @@ s_vMgrRxAssocRequest(
         RATEvParseMaxRate((void *)pDevice,
                            (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
                            (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
-                           FALSE, // do not change our basic rate
+                           false, // do not change our basic rate
                            &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
                            &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
                            &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
@@ -758,20 +759,20 @@ s_vMgrRxAssocRequest(
                 WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
         pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
                 WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
-        pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex;
+        pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
         wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
-        wAssocAID = (WORD)uNodeIndex;
+        wAssocAID = (unsigned short)uNodeIndex;
         // check if ERP support
         if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
-           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
 
         if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
             // B only STA join
-            pDevice->bProtectMode = TRUE;
-            pDevice->bNonERPPresent = TRUE;
+            pDevice->bProtectMode = true;
+            pDevice->bNonERPPresent = true;
         }
-        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == FALSE) {
-            pDevice->bBarkerPreambleMd = TRUE;
+        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
+            pDevice->bBarkerPreambleMd = true;
         }
 
         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
@@ -845,17 +846,17 @@ s_vMgrRxReAssocRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
     PSRxMgmtPacket pRxPacket,
-    UINT uNodeIndex
+    unsigned int uNodeIndex
     )
 {
     WLAN_FR_REASSOCREQ    sFrame;
     CMD_STATUS          Status;
     PSTxMgmtPacket      pTxPacket;
-    WORD                wAssocStatus = 0;
-    WORD                wAssocAID = 0;
-    UINT                uRateLen = WLAN_RATES_MAXLEN;
-    BYTE                abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-    BYTE                abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned short wAssocStatus = 0;
+    unsigned short wAssocAID = 0;
+    unsigned int       uRateLen = WLAN_RATES_MAXLEN;
+    unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
 
     if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
         return;
@@ -866,7 +867,7 @@ s_vMgrRxReAssocRequest(
     //decode the frame
     memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ));
     sFrame.len = pRxPacket->cbMPDULen;
-    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
     vMgrDecodeReassocRequest(&sFrame);
 
     if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
@@ -874,7 +875,7 @@ s_vMgrRxReAssocRequest(
         pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
         pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
         pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
-                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? TRUE : FALSE;
+                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
         // Todo: check sta basic rate, if ap can't support, set status code
 
         if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
@@ -898,7 +899,7 @@ s_vMgrRxReAssocRequest(
         RATEvParseMaxRate((void *)pDevice,
                           (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
                           (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
-                           FALSE, // do not change our basic rate
+                           false, // do not change our basic rate
                            &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
                            &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
                            &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
@@ -917,21 +918,21 @@ s_vMgrRxReAssocRequest(
                 WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
         pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
                 WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
-        pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex;
+        pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
         wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
-        wAssocAID = (WORD)uNodeIndex;
+        wAssocAID = (unsigned short)uNodeIndex;
 
         // if suppurt ERP
         if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
-           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
 
         if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
             // B only STA join
-            pDevice->bProtectMode = TRUE;
-            pDevice->bNonERPPresent = TRUE;
+            pDevice->bProtectMode = true;
+            pDevice->bNonERPPresent = true;
         }
-        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == FALSE) {
-            pDevice->bBarkerPreambleMd = TRUE;
+        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
+            pDevice->bBarkerPreambleMd = true;
         }
 
         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
@@ -995,12 +996,12 @@ s_vMgrRxAssocResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
     PSRxMgmtPacket pRxPacket,
-    BOOL bReAssocType
+    bool bReAssocType
     )
 {
     WLAN_FR_ASSOCRESP   sFrame;
     PWLAN_IE_SSID   pItemSSID;
-    PBYTE   pbyIEs;
+    unsigned char *pbyIEs;
     viawget_wpa_header *wpahdr;
 
 
@@ -1009,7 +1010,7 @@ s_vMgrRxAssocResponse(
          pMgmt->eCurrState == WMAC_STATE_ASSOC) {
 
         sFrame.len = pRxPacket->cbMPDULen;
-        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
         // decode the frame
         vMgrDecodeAssocResponse(&sFrame);
         if ((sFrame.pwCapInfo == 0) ||
@@ -1044,7 +1045,7 @@ s_vMgrRxAssocResponse(
             BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
             pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
             DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
-            pDevice->bLinkPass = TRUE;
+            pDevice->bLinkPass = true;
             pDevice->uBBVGADiffCount = 0;
             if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
          if(skb_tailroom(pDevice->skb) <(sizeof(viawget_wpa_header)+pMgmt->sAssocInfo.AssocInfo.ResponseIELength+
@@ -1073,9 +1074,9 @@ s_vMgrRxAssocResponse(
 
 //2008-0409-07, <Add> by Einsn Liu
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-       //if(pDevice->bWPADevEnable == TRUE)
+       //if(pDevice->bWPADevEnable == true)
                {
-               BYTE buf[512];
+               unsigned char buf[512];
                size_t len;
                union iwreq_data  wrqu;
                int we_event;
@@ -1128,7 +1129,7 @@ s_vMgrRxAssocResponse(
 //need clear flags related to Networkmanager
 
               pDevice->bwextcount = 0;
-              pDevice->bWPASuppWextEnabled = FALSE;
+              pDevice->bWPASuppWextEnabled = false;
 #endif
 
 
@@ -1163,8 +1164,8 @@ vMgrAuthenBeginSta(
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
     vMgrEncodeAuthen(&sFrame);
     /* insert values */
@@ -1212,8 +1213,8 @@ void
 vMgrDeAuthenBeginSta(
     void *hDeviceContext,
     PSMgmtObject  pMgmt,
-    PBYTE  abyDestAddress,
-    WORD    wReason,
+    unsigned char *abyDestAddress,
+    unsigned short wReason,
     PCMD_STATUS pStatus
     )
 {
@@ -1224,8 +1225,8 @@ vMgrDeAuthenBeginSta(
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN;
     vMgrEncodeDeauthen(&sFrame);
     /* insert values */
@@ -1282,7 +1283,7 @@ s_vMgrRxAuthentication(
 
     // decode the frame
     sFrame.len = pRxPacket->cbMPDULen;
-    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
     vMgrDecodeAuthen(&sFrame);
     switch (cpu_to_le16((*(sFrame.pwAuthSequence )))){
         case 1:
@@ -1331,7 +1332,7 @@ s_vMgrRxAuthenSequence_1(
      )
 {
     PSTxMgmtPacket      pTxPacket = NULL;
-    UINT                uNodeIndex;
+    unsigned int       uNodeIndex;
     WLAN_FR_AUTHEN      sFrame;
     PSKeyItem           pTransmitKey;
 
@@ -1353,8 +1354,8 @@ s_vMgrRxAuthenSequence_1(
     // send auth reply
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
     // format buffer structure
     vMgrEncodeAuthen(&sFrame);
@@ -1393,7 +1394,7 @@ s_vMgrRxAuthenSequence_1(
         sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
         memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN);
         // get group key
-        if(KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == TRUE) {
+        if(KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) {
             rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3);
             rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN);
         }
@@ -1466,8 +1467,8 @@ s_vMgrRxAuthenSequence_2(
             if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
                 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
                 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
-                pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
-                sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+                pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
+                sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
                 sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
                 // format buffer structure
                 vMgrEncodeAuthen(&sFrame);
@@ -1539,8 +1540,8 @@ s_vMgrRxAuthenSequence_3(
     )
 {
     PSTxMgmtPacket      pTxPacket = NULL;
-    UINT                uStatusCode = 0 ;
-    UINT                uNodeIndex = 0;
+    unsigned int uStatusCode = 0 ;
+    unsigned int uNodeIndex = 0;
     WLAN_FR_AUTHEN      sFrame;
 
     if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
@@ -1573,8 +1574,8 @@ reply:
     // send auth reply
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
     // format buffer structure
     vMgrEncodeAuthen(&sFrame);
@@ -1666,7 +1667,7 @@ s_vMgrRxDisassociation(
     )
 {
     WLAN_FR_DISASSOC    sFrame;
-    UINT        uNodeIndex = 0;
+    unsigned int uNodeIndex = 0;
 //    CMD_STATUS          CmdStatus;
     viawget_wpa_header *wpahdr;
 
@@ -1674,7 +1675,7 @@ s_vMgrRxDisassociation(
         // if is acting an AP..
         // a STA is leaving this BSS..
         sFrame.len = pRxPacket->cbMPDULen;
-        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
         if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
             BSSvRemoveOneNode(pDevice, uNodeIndex);
         }
@@ -1684,7 +1685,7 @@ s_vMgrRxDisassociation(
     }
     else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ){
         sFrame.len = pRxPacket->cbMPDULen;
-        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
         vMgrDecodeDisassociation(&sFrame);
         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
         //TODO: do something let upper layer know or
@@ -1709,7 +1710,7 @@ s_vMgrRxDisassociation(
          };
 
  #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-  // if(pDevice->bWPASuppWextEnabled == TRUE)
+  // if(pDevice->bWPASuppWextEnabled == true)
       {
        union iwreq_data  wrqu;
        memset(&wrqu, 0, sizeof (wrqu));
@@ -1745,7 +1746,7 @@ s_vMgrRxDeauthentication(
     )
 {
     WLAN_FR_DEAUTHEN    sFrame;
-    UINT        uNodeIndex = 0;
+    unsigned int uNodeIndex = 0;
     viawget_wpa_header *wpahdr;
 
 
@@ -1754,7 +1755,7 @@ s_vMgrRxDeauthentication(
         // if is acting an AP..
         // a STA is leaving this BSS..
         sFrame.len = pRxPacket->cbMPDULen;
-        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
         if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
             BSSvRemoveOneNode(pDevice, uNodeIndex);
         }
@@ -1765,17 +1766,17 @@ s_vMgrRxDeauthentication(
     else {
         if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ) {
             sFrame.len = pRxPacket->cbMPDULen;
-            sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+            sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
             vMgrDecodeDeauthen(&sFrame);
             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
             // TODO: update BSS list for specific BSSID if pre-authentication case
-            if (IS_ETH_ADDRESS_EQUAL(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
+            if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
                 if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
-                    pMgmt->sNodeDBTable[0].bActive = FALSE;
+                    pMgmt->sNodeDBTable[0].bActive = false;
                     pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                     pMgmt->eCurrState = WMAC_STATE_IDLE;
                     netif_stop_queue(pDevice->dev);
-                    pDevice->bLinkPass = FALSE;
+                    pDevice->bLinkPass = false;
                 }
             };
 
@@ -1795,7 +1796,7 @@ s_vMgrRxDeauthentication(
            };
 
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-  // if(pDevice->bWPASuppWextEnabled == TRUE)
+  // if(pDevice->bWPASuppWextEnabled == true)
       {
        union iwreq_data  wrqu;
        memset(&wrqu, 0, sizeof (wrqu));
@@ -1825,23 +1826,23 @@ s_vMgrRxDeauthentication(
  *               True:exceed;
  *                False:normal case
 -*/
-static BOOL
+static bool
 ChannelExceedZoneType(
     PSDevice pDevice,
-    BYTE byCurrChannel
+    unsigned char byCurrChannel
     )
 {
-  BOOL exceed=FALSE;
+  bool exceed=false;
 
   switch(pDevice->byZoneType) {
        case 0x00:                  //USA:1~11
                      if((byCurrChannel<1) ||(byCurrChannel>11))
-                       exceed = TRUE;
+                       exceed = true;
                 break;
        case 0x01:                  //Japan:1~13
        case 0x02:                  //Europe:1~13
                      if((byCurrChannel<1) ||(byCurrChannel>13))
-                       exceed = TRUE;
+                       exceed = true;
                 break;
        default:                    //reserve for other zonetype
                break;
@@ -1868,39 +1869,39 @@ s_vMgrRxBeacon(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
     PSRxMgmtPacket pRxPacket,
-    BOOL bInScan
+    bool bInScan
     )
 {
 
     PKnownBSS           pBSSList;
     WLAN_FR_BEACON      sFrame;
     QWORD               qwTSFOffset;
-    BOOL                bIsBSSIDEqual = FALSE;
-    BOOL                bIsSSIDEqual = FALSE;
-    BOOL                bTSFLargeDiff = FALSE;
-    BOOL                bTSFOffsetPostive = FALSE;
-    BOOL                bUpdateTSF = FALSE;
-    BOOL                bIsAPBeacon = FALSE;
-    BOOL                bIsChannelEqual = FALSE;
-    UINT                uLocateByteIndex;
-    BYTE                byTIMBitOn = 0;
-    WORD                wAIDNumber = 0;
-    UINT                uNodeIndex;
+    bool bIsBSSIDEqual = false;
+    bool bIsSSIDEqual = false;
+    bool bTSFLargeDiff = false;
+    bool bTSFOffsetPostive = false;
+    bool bUpdateTSF = false;
+    bool bIsAPBeacon = false;
+    bool bIsChannelEqual = false;
+    unsigned int uLocateByteIndex;
+    unsigned char byTIMBitOn = 0;
+    unsigned short wAIDNumber = 0;
+    unsigned int uNodeIndex;
     QWORD               qwTimestamp, qwLocalTSF;
     QWORD               qwCurrTSF;
-    WORD                wStartIndex = 0;
-    WORD                wAIDIndex = 0;
-    BYTE                byCurrChannel = pRxPacket->byRxChannel;
+    unsigned short wStartIndex = 0;
+    unsigned short wAIDIndex = 0;
+    unsigned char byCurrChannel = pRxPacket->byRxChannel;
     ERPObject           sERP;
-    UINT                uRateLen = WLAN_RATES_MAXLEN;
-    BOOL                bChannelHit = FALSE;
-    BOOL                bUpdatePhyParameter = FALSE;
-    BYTE                byIEChannel = 0;
+    unsigned int uRateLen = WLAN_RATES_MAXLEN;
+    bool bChannelHit = false;
+    bool bUpdatePhyParameter = false;
+    unsigned char byIEChannel = 0;
 
 
     memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
     sFrame.len = pRxPacket->cbMPDULen;
-    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
 
     // decode the beacon frame
     vMgrDecodeBeacon(&sFrame);
@@ -1917,29 +1918,29 @@ s_vMgrRxBeacon(
     if (sFrame.pDSParms != NULL) {
         if (byCurrChannel > CB_MAX_CHANNEL_24G) {
             // channel remapping to
-            byIEChannel = CARDbyGetChannelMapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
+            byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
         } else {
             byIEChannel = sFrame.pDSParms->byCurrChannel;
         }
         if (byCurrChannel != byIEChannel) {
             // adjust channel info. bcs we rcv adjcent channel pakckets
-            bChannelHit = FALSE;
+            bChannelHit = false;
             byCurrChannel = byIEChannel;
         }
     } else {
         // no DS channel info
-        bChannelHit = TRUE;
+        bChannelHit = true;
     }
 //2008-0730-01<Add>by MikeLiu
-if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
+if(ChannelExceedZoneType(pDevice,byCurrChannel)==true)
       return;
 
     if (sFrame.pERP != NULL) {
         sERP.byERP = sFrame.pERP->byContext;
-        sERP.bERPExist = TRUE;
+        sERP.bERPExist = true;
 
     } else {
-        sERP.bERPExist = FALSE;
+        sERP.bERPExist = false;
         sERP.byERP = 0;
     }
 
@@ -1993,8 +1994,8 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
         return;
     }
 
-    if(byCurrChannel == (BYTE)pMgmt->uCurrChannel)
-       bIsChannelEqual = TRUE;
+    if(byCurrChannel == (unsigned char)pMgmt->uCurrChannel)
+       bIsChannelEqual = true;
 
     if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
 
@@ -2021,7 +2022,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
         if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)){
             if (!pDevice->bProtectMode) {
                  MACvEnableProtectMD(pDevice->PortOffset);
-                 pDevice->bProtectMode = TRUE;
+                 pDevice->bProtectMode = true;
             }
         }
     }
@@ -2035,7 +2036,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                pMgmt->abyCurrBSSID,
                WLAN_BSSID_LEN) == 0) {
 
-        bIsBSSIDEqual = TRUE;
+        bIsBSSIDEqual = true;
 
 // 2008-05-21 <add> by Richardtai
         pDevice->uCurrRSSI = pRxPacket->uRSSI;
@@ -2052,30 +2053,30 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                    ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
                    sFrame.pSSID->len
                    ) == 0) {
-            bIsSSIDEqual = TRUE;
+            bIsSSIDEqual = true;
         };
     }
 
-    if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== TRUE) &&
-        (bIsBSSIDEqual == TRUE) &&
-        (bIsSSIDEqual == TRUE) &&
+    if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== true) &&
+        (bIsBSSIDEqual == true) &&
+        (bIsSSIDEqual == true) &&
         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
         (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
         // add state check to prevent reconnect fail since we'll receive Beacon
 
-        bIsAPBeacon = TRUE;
+        bIsAPBeacon = true;
 
         if (pBSSList != NULL) {
 
             // Compare PHY paramater setting
             if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) {
-                bUpdatePhyParameter = TRUE;
+                bUpdatePhyParameter = true;
                 pMgmt->wCurrCapInfo = pBSSList->wCapInfo;
             }
             if (sFrame.pERP != NULL) {
                 if ((sFrame.pERP->byElementID == WLAN_EID_ERP) &&
                     (pMgmt->byERPContext != sFrame.pERP->byContext)) {
-                    bUpdatePhyParameter = TRUE;
+                    bUpdatePhyParameter = true;
                     pMgmt->byERPContext = sFrame.pERP->byContext;
                 }
             }
@@ -2094,7 +2095,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
             RATEvParseMaxRate( (void *)pDevice,
                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
-                               TRUE,
+                               true,
                                &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
                                &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
                                &(pMgmt->sNodeDBTable[0].wSuppRate),
@@ -2104,7 +2105,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
 #ifdef PLICE_DEBUG
                //printk("RxBeacon:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate);
 #endif
-                       if (bUpdatePhyParameter == TRUE) {
+                       if (bUpdatePhyParameter == true) {
                 CARDbSetPhyParameter( pMgmt->pAdapter,
                                       pMgmt->eCurrentPHYMode,
                                       pMgmt->wCurrCapInfo,
@@ -2115,19 +2116,19 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
             }
             if (sFrame.pIE_PowerConstraint != NULL) {
                 CARDvSetPowerConstraint(pMgmt->pAdapter,
-                                        (BYTE) pBSSList->uChannel,
+                                        (unsigned char) pBSSList->uChannel,
                                         sFrame.pIE_PowerConstraint->byPower
                                         );
             }
             if (sFrame.pIE_CHSW != NULL) {
                 CARDbChannelSwitch( pMgmt->pAdapter,
                                     sFrame.pIE_CHSW->byMode,
-                                    CARDbyGetChannelMapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode),
+                                    get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode),
                                     sFrame.pIE_CHSW->byCount
                                     );
 
-            } else if (bIsChannelEqual == FALSE) {
-                CARDbSetChannel(pMgmt->pAdapter, pBSSList->uChannel);
+            } else if (bIsChannelEqual == false) {
+                set_channel(pMgmt->pAdapter, pBSSList->uChannel);
             }
         }
     }
@@ -2148,17 +2149,17 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
     // check if beacon TSF larger or small than our local TSF
     if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) {
         if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) {
-            bTSFOffsetPostive = TRUE;
+            bTSFOffsetPostive = true;
         }
         else {
-            bTSFOffsetPostive = FALSE;
+            bTSFOffsetPostive = false;
         }
     }
     else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) {
-        bTSFOffsetPostive = TRUE;
+        bTSFOffsetPostive = true;
     }
     else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
-        bTSFOffsetPostive = FALSE;
+        bTSFOffsetPostive = false;
     };
 
     if (bTSFOffsetPostive) {
@@ -2170,21 +2171,21 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
 
     if (HIDWORD(qwTSFOffset) != 0 ||
         (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE )) {
-         bTSFLargeDiff = TRUE;
+         bTSFLargeDiff = true;
     }
 
 
     // if infra mode
-    if (bIsAPBeacon == TRUE) {
+    if (bIsAPBeacon == true) {
 
         // Infra mode: Local TSF always follow AP's TSF if Difference huge.
         if (bTSFLargeDiff)
-            bUpdateTSF = TRUE;
+            bUpdateTSF = true;
 
-        if ((pDevice->bEnablePSMode == TRUE) &&(sFrame.pTIM != 0)) {
+        if ((pDevice->bEnablePSMode == true) &&(sFrame.pTIM != 0)) {
 
             // deal with DTIM, analysis TIM
-            pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? TRUE : FALSE ;
+            pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false ;
             pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
             pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
             wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
@@ -2199,19 +2200,19 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                 // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
                 if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
                     byTIMBitOn  = (0x01) << ((wAIDNumber) % 8);
-                    pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? TRUE : FALSE;
+                    pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false;
                 }
                 else {
-                    pMgmt->bInTIM = FALSE;
+                    pMgmt->bInTIM = false;
                 };
             }
             else {
-                pMgmt->bInTIM = FALSE;
+                pMgmt->bInTIM = false;
             };
 
             if (pMgmt->bInTIM ||
                 (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
-                pMgmt->bInTIMWake = TRUE;
+                pMgmt->bInTIMWake = true;
                 // send out ps-poll packet
 //                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
                 if (pMgmt->bInTIM) {
@@ -2221,14 +2222,14 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
 
             }
             else {
-                pMgmt->bInTIMWake = FALSE;
+                pMgmt->bInTIMWake = false;
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
-                if (pDevice->bPWBitOn == FALSE) {
+                if (pDevice->bPWBitOn == false) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
                     if (PSbSendNullPacket(pDevice))
-                        pDevice->bPWBitOn = TRUE;
+                        pDevice->bPWBitOn = true;
                 }
-                if(PSbConsiderPowerDown(pDevice, FALSE, FALSE)) {
+                if(PSbConsiderPowerDown(pDevice, false, false)) {
                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
                 };
             }
@@ -2246,7 +2247,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
             // adhoc mode:TSF updated only when beacon larger then local TSF
             if (bTSFLargeDiff && bTSFOffsetPostive &&
                 (pMgmt->eCurrState == WMAC_STATE_JOINTED))
-                bUpdateTSF = TRUE;
+                bUpdateTSF = true;
 
             // During dpc, already in spinlocked.
             if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
@@ -2259,7 +2260,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                 RATEvParseMaxRate( (void *)pDevice,
                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                                    NULL,
-                                   TRUE,
+                                   true,
                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
                                    &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
@@ -2280,7 +2281,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                 RATEvParseMaxRate( (void *)pDevice,
                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                                    NULL,
-                                   TRUE,
+                                   true,
                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
                                    &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
@@ -2300,7 +2301,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
 /*
                 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
                 if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
-                       pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+                       pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
 */
             }
 
@@ -2308,11 +2309,11 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
             if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
                 pMgmt->eCurrState = WMAC_STATE_JOINTED;
-                pDevice->bLinkPass = TRUE;
+                pDevice->bLinkPass = true;
                 if (netif_queue_stopped(pDevice->dev)){
                     netif_wake_queue(pDevice->dev);
                 }
-                pMgmt->sNodeDBTable[0].bActive = TRUE;
+                pMgmt->sNodeDBTable[0].bActive = true;
                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
 
             };
@@ -2392,16 +2393,16 @@ vMgrCreateOwnIBSS(
 {
     PSDevice            pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject        pMgmt = pDevice->pMgmt;
-    WORD                wMaxBasicRate;
-    WORD                wMaxSuppRate;
-    BYTE                byTopCCKBasicRate;
-    BYTE                byTopOFDMBasicRate;
+    unsigned short wMaxBasicRate;
+    unsigned short wMaxSuppRate;
+    unsigned char byTopCCKBasicRate;
+    unsigned char byTopOFDMBasicRate;
     QWORD               qwCurrTSF;
-    UINT                ii;
-    BYTE    abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
-    BYTE    abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
-    BYTE    abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
-    WORD                wSuppRate;
+    unsigned int ii;
+    unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
+    unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
+    unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    unsigned short wSuppRate;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
 
@@ -2486,7 +2487,7 @@ vMgrCreateOwnIBSS(
     // set basic rate
 
     RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
-                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true,
                       &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
                       &byTopCCKBasicRate, &byTopOFDMBasicRate);
 
@@ -2533,12 +2534,12 @@ vMgrCreateOwnIBSS(
     if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
 
         // BSSID selected must be randomized as spec 11.1.3
-        pMgmt->abyCurrBSSID[5] = (BYTE) (LODWORD(qwCurrTSF)& 0x000000ff);
-        pMgmt->abyCurrBSSID[4] = (BYTE)((LODWORD(qwCurrTSF)& 0x0000ff00) >> 8);
-        pMgmt->abyCurrBSSID[3] = (BYTE)((LODWORD(qwCurrTSF)& 0x00ff0000) >> 16);
-        pMgmt->abyCurrBSSID[2] = (BYTE)((LODWORD(qwCurrTSF)& 0x00000ff0) >> 4);
-        pMgmt->abyCurrBSSID[1] = (BYTE)((LODWORD(qwCurrTSF)& 0x000ff000) >> 12);
-        pMgmt->abyCurrBSSID[0] = (BYTE)((LODWORD(qwCurrTSF)& 0x0ff00000) >> 20);
+        pMgmt->abyCurrBSSID[5] = (unsigned char) (LODWORD(qwCurrTSF)& 0x000000ff);
+        pMgmt->abyCurrBSSID[4] = (unsigned char)((LODWORD(qwCurrTSF)& 0x0000ff00) >> 8);
+        pMgmt->abyCurrBSSID[3] = (unsigned char)((LODWORD(qwCurrTSF)& 0x00ff0000) >> 16);
+        pMgmt->abyCurrBSSID[2] = (unsigned char)((LODWORD(qwCurrTSF)& 0x00000ff0) >> 4);
+        pMgmt->abyCurrBSSID[1] = (unsigned char)((LODWORD(qwCurrTSF)& 0x000ff000) >> 12);
+        pMgmt->abyCurrBSSID[0] = (unsigned char)((LODWORD(qwCurrTSF)& 0x0ff00000) >> 20);
         pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
         pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
         pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
@@ -2611,7 +2612,7 @@ vMgrCreateOwnIBSS(
 
     CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod);
     // set channel and clear NAV
-    CARDbSetChannel(pMgmt->pAdapter, pMgmt->uIBSSChannel);
+    set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel);
     pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
 
     if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
@@ -2620,7 +2621,7 @@ vMgrCreateOwnIBSS(
         pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
     }
 
-    if ((pMgmt->b11hEnable == TRUE) &&
+    if ((pMgmt->b11hEnable == true) &&
         (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
     } else {
@@ -2661,20 +2662,20 @@ vMgrJoinBSSBegin(
     PSDevice     pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PKnownBSS       pCurr = NULL;
-    UINT            ii, uu;
+    unsigned int ii, uu;
     PWLAN_IE_SUPP_RATES pItemRates = NULL;
     PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
     PWLAN_IE_SSID   pItemSSID;
-    UINT            uRateLen = WLAN_RATES_MAXLEN;
-    WORD            wMaxBasicRate = RATE_1M;
-    WORD            wMaxSuppRate = RATE_1M;
-    WORD            wSuppRate;
-    BYTE            byTopCCKBasicRate = RATE_1M;
-    BYTE            byTopOFDMBasicRate = RATE_1M;
+    unsigned int uRateLen = WLAN_RATES_MAXLEN;
+    unsigned short wMaxBasicRate = RATE_1M;
+    unsigned short wMaxSuppRate = RATE_1M;
+    unsigned short wSuppRate;
+    unsigned char byTopCCKBasicRate = RATE_1M;
+    unsigned char byTopOFDMBasicRate = RATE_1M;
 
 
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
-        if (pMgmt->sBSSList[ii].bActive == TRUE)
+        if (pMgmt->sBSSList[ii].bActive == true)
             break;
     }
 
@@ -2708,14 +2709,14 @@ vMgrJoinBSSBegin(
     // patch for CISCO migration mode
 /*
             if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
-                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
+                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
                     // encryption mode error
                     pMgmt->eCurrState = WMAC_STATE_IDLE;
                     return;
                 }
             } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
-                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
+                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
                     // encryption mode error
                     pMgmt->eCurrState = WMAC_STATE_IDLE;
@@ -2726,7 +2727,7 @@ vMgrJoinBSSBegin(
         }
 
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-       //if(pDevice->bWPASuppWextEnabled == TRUE)
+       //if(pDevice->bWPASuppWextEnabled == true)
             Encyption_Rebuild(pDevice, pCurr);
 #endif
         // Infrastructure BSS
@@ -2764,15 +2765,15 @@ vMgrJoinBSSBegin(
                                             uRateLen);
             // Stuffing Rate IE
             if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
-                for (ii = 0; ii < (UINT)(8 - pItemRates->len); ) {
+                for (ii = 0; ii < (unsigned int)(8 - pItemRates->len); ) {
                     pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii];
                     ii ++;
                     if (pItemExtRates->len <= ii)
                         break;
                 }
-                pItemRates->len += (BYTE)ii;
+                pItemRates->len += (unsigned char)ii;
                 if (pItemExtRates->len - ii > 0) {
-                    pItemExtRates->len -= (BYTE)ii;
+                    pItemExtRates->len -= (unsigned char)ii;
                     for (uu = 0; uu < pItemExtRates->len; uu ++) {
                         pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
                     }
@@ -2781,7 +2782,7 @@ vMgrJoinBSSBegin(
                 }
             }
 
-            RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, TRUE,
+            RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true,
                               &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
                               &byTopCCKBasicRate, &byTopOFDMBasicRate);
 
@@ -2802,9 +2803,9 @@ vMgrJoinBSSBegin(
             // Add current BSS to Candidate list
             // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
             if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
-                BOOL bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
+                bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
-                if (bResult == FALSE) {
+                if (bResult == false) {
                     vFlush_PMKID_Candidate((void *)pDevice);
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n");
                     bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
@@ -2831,13 +2832,13 @@ vMgrJoinBSSBegin(
         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
 
             if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
-                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
+                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
                     // encryption mode error
                     pMgmt->eCurrState = WMAC_STATE_IDLE;
                     return;
                 }
             } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
-                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
+                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
                     // encryption mode error
                     pMgmt->eCurrState = WMAC_STATE_IDLE;
                     return;
@@ -2868,7 +2869,7 @@ vMgrJoinBSSBegin(
                                                     WLAN_RATES_MAXLEN_11B);
             // set basic rate
             RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
-                              NULL, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+                              NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
                               &byTopCCKBasicRate, &byTopOFDMBasicRate);
 
             pMgmt->wCurrCapInfo = pCurr->wCapInfo;
@@ -2883,7 +2884,7 @@ vMgrJoinBSSBegin(
             pMgmt->eCurrState = WMAC_STATE_STARTED;
             // Adopt BSS state in Adapter Device Object
             //pDevice->byOpMode = OP_MODE_ADHOC;
-//            pDevice->bLinkPass = TRUE;
+//            pDevice->bLinkPass = true;
 //            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
 
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n",
@@ -2923,7 +2924,7 @@ static
 void
 s_vMgrSynchBSS (
     PSDevice      pDevice,
-    UINT          uBSSMode,
+    unsigned int uBSSMode,
     PKnownBSS     pCurr,
     PCMD_STATUS  pStatus
     )
@@ -2932,11 +2933,11 @@ s_vMgrSynchBSS (
     PSMgmtObject  pMgmt = pDevice->pMgmt;
 //    int     ii;
                                                      //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
-    BYTE abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
-    BYTE abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+    unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+    unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
                                                            //6M,   9M,   12M,  48M
-    BYTE abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
-    BYTE abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+    unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
 
 
     *pStatus = CMD_STATUS_FAILURE;
@@ -2944,7 +2945,7 @@ s_vMgrSynchBSS (
     if (s_bCipherMatch(pCurr,
                        pDevice->eEncryptionStatus,
                        &(pMgmt->byCSSPK),
-                       &(pMgmt->byCSSGK)) == FALSE) {
+                       &(pMgmt->byCSSGK)) == false) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
         return;
     }
@@ -2958,12 +2959,12 @@ s_vMgrSynchBSS (
     }
 
     // Init the BSS informations
-    pDevice->bCCK = TRUE;
-    pDevice->bProtectMode = FALSE;
+    pDevice->bCCK = true;
+    pDevice->bProtectMode = false;
     MACvDisableProtectMD(pDevice->PortOffset);
-    pDevice->bBarkerPreambleMd = FALSE;
+    pDevice->bBarkerPreambleMd = false;
     MACvDisableBarkerPreambleMd(pDevice->PortOffset);
-    pDevice->bNonERPPresent = FALSE;
+    pDevice->bNonERPPresent = false;
     pDevice->byPreambleType = 0;
     pDevice->wBasicRate = 0;
     // Set Basic Rate
@@ -3046,12 +3047,12 @@ s_vMgrSynchBSS (
                                 pCurr->sERP.byERP,
                                 pMgmt->abyCurrSuppRates,
                                 pMgmt->abyCurrExtSuppRates
-                            ) != TRUE) {
+                            ) != true) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
         return;
     }
     // set channel and clear NAV
-    if (CARDbSetChannel(pMgmt->pAdapter, pCurr->uChannel) == FALSE) {
+    if (set_channel(pMgmt->pAdapter, pCurr->uChannel) == false) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
         return;
     }
@@ -3077,7 +3078,7 @@ s_vMgrSynchBSS (
     pMgmt->uCurrChannel = pCurr->uChannel;
     pMgmt->eCurrentPHYMode = ePhyType;
     pMgmt->byERPContext = pCurr->sERP.byERP;
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (INT)pCurr->uChannel);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (int)pCurr->uChannel);
 
 
     *pStatus = CMD_STATUS_SUCCESS;
@@ -3094,18 +3095,18 @@ s_vMgrSynchBSS (
  )
  {
   PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
- // UINT            ii , uSameBssidNum=0;
+ // unsigned int ii , uSameBssidNum=0;
 
         //  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
           //   if (pMgmt->sBSSList[ii].bActive &&
-            //      IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+            //      !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
              //       uSameBssidNum++;
                //   }
            // }
   //   if( uSameBssidNum>=2) {  //we only check AP in hidden sssid  mode
         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selsection,
              (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-selsect it according to real pairwise-key info.
-               if(pCurr->bWPAValid == TRUE)  {   //WPA-PSK
+               if(pCurr->bWPAValid == true)  {   //WPA-PSK
                           pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
                    if(pCurr->abyPKType[0] == WPA_TKIP) {
                        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
@@ -3116,7 +3117,7 @@ s_vMgrSynchBSS (
                           PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
                     }
                        }
-               else if(pCurr->bWPA2Valid == TRUE) {  //WPA2-PSK
+               else if(pCurr->bWPA2Valid == true) {  //WPA2-PSK
                          pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
                       if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
                           pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
@@ -3151,13 +3152,13 @@ s_vMgrFormatTIM(
     PWLAN_IE_TIM pTIM
     )
 {
-    BYTE        byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
-    BYTE        byMap;
-    UINT        ii, jj;
-    BOOL        bStartFound = FALSE;
-    BOOL        bMulticast = FALSE;
-    WORD        wStartIndex = 0;
-    WORD        wEndIndex = 0;
+    unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    unsigned char byMap;
+    unsigned int ii, jj;
+    bool bStartFound = false;
+    bool bMulticast = false;
+    unsigned short wStartIndex = 0;
+    unsigned short wEndIndex = 0;
 
 
     // Find size of partial virtual bitmap
@@ -3167,13 +3168,13 @@ s_vMgrFormatTIM(
             // Mask out the broadcast bit which is indicated separately.
             bMulticast = (byMap & byMask[0]) != 0;
             if(bMulticast) {
-               pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
+               pMgmt->sNodeDBTable[0].bRxPSPoll = true;
             }
             byMap = 0;
         }
         if (byMap) {
             if (!bStartFound) {
-                bStartFound = TRUE;
+                bStartFound = true;
                 wStartIndex = ii;
             }
             wEndIndex = ii;
@@ -3224,30 +3225,30 @@ PSTxMgmtPacket
 s_MgrMakeBeacon(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wCurrBeaconPeriod,
-    UINT uCurrChannel,
-    WORD wCurrATIMWinodw,
+    unsigned short wCurrCapInfo,
+    unsigned short wCurrBeaconPeriod,
+    unsigned int uCurrChannel,
+    unsigned short wCurrATIMWinodw,
     PWLAN_IE_SSID pCurrSSID,
-    PBYTE pCurrBSSID,
+    unsigned char *pCurrBSSID,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
     )
 {
     PSTxMgmtPacket      pTxPacket = NULL;
     WLAN_FR_BEACON      sFrame;
-    BYTE                abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-    PBYTE               pbyBuffer;
-    UINT                uLength = 0;
+    unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    unsigned char *pbyBuffer;
+    unsigned int uLength = 0;
     PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
-    UINT                ii;
+    unsigned int ii;
 
     // prepare beacon frame
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
     // Setup the sFrame structure.
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_BEACON_FR_MAXLEN;
     vMgrEncodeBeacon(&sFrame);
     // Setup the header
@@ -3258,7 +3259,7 @@ s_MgrMakeBeacon(
         ));
 
     if (pDevice->bEnablePSMode) {
-        sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_PWRMGT(1));
+        sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1));
     }
 
     memcpy( sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
@@ -3286,7 +3287,7 @@ s_MgrMakeBeacon(
         sFrame.len += (1) + WLAN_IEHDR_LEN;
         sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
         sFrame.pDSParms->len = 1;
-        sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
+        sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
     }
     // TIM field
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
@@ -3329,22 +3330,22 @@ s_MgrMakeBeacon(
             // Pairwise Key Cipher Suite
             sFrame.pRSNWPA->wPKCount = 0;
             // Auth Key Management Suite
-            *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+            *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
             sFrame.pRSNWPA->len +=2;
 
             // RSN Capabilites
-            *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+            *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
             sFrame.pRSNWPA->len +=2;
             sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
         }
     }
 
-    if ((pMgmt->b11hEnable == TRUE) &&
+    if ((pMgmt->b11hEnable == true) &&
         (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
         // Country IE
-        pbyBuffer = (PBYTE)(sFrame.pBuf + sFrame.len);
-        CARDvSetCountryIE(pMgmt->pAdapter, pbyBuffer);
-        CARDvSetCountryInfo(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
+        pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
+        set_country_IE(pMgmt->pAdapter, pbyBuffer);
+        set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
         uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
         pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
         // Power Constrain IE
@@ -3353,12 +3354,12 @@ s_MgrMakeBeacon(
         ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
         pbyBuffer += (1) + WLAN_IEHDR_LEN;
         uLength += (1) + WLAN_IEHDR_LEN;
-        if (pMgmt->bSwitchChannel == TRUE) {
+        if (pMgmt->bSwitchChannel == true) {
             // Channel Switch IE
             ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
             ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
             ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
-            ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = CARDbyGetChannelNumber(pMgmt->pAdapter, pMgmt->byNewChannel);
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
             ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
             pbyBuffer += (3) + WLAN_IEHDR_LEN;
             uLength += (3) + WLAN_IEHDR_LEN;
@@ -3382,7 +3383,7 @@ s_MgrMakeBeacon(
             pbyBuffer += (7) + WLAN_IEHDR_LEN;
             uLength += (7) + WLAN_IEHDR_LEN;
             for(ii=CB_MAX_CHANNEL_24G+1; ii<=CB_MAX_CHANNEL; ii++ ) {
-                if (CARDbGetChannelMapInfo(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == TRUE) {
+                if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) {
                     pbyBuffer += 2;
                     uLength += 2;
                     pIBSSDFS->len += 2;
@@ -3398,11 +3399,11 @@ s_MgrMakeBeacon(
         sFrame.pERP->byElementID = WLAN_EID_ERP;
         sFrame.pERP->len = 1;
         sFrame.pERP->byContext = 0;
-        if (pDevice->bProtectMode == TRUE)
+        if (pDevice->bProtectMode == true)
             sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
-        if (pDevice->bNonERPPresent == TRUE)
+        if (pDevice->bNonERPPresent == true)
             sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
-        if (pDevice->bBarkerPreambleMd == TRUE)
+        if (pDevice->bBarkerPreambleMd == true)
             sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
     }
     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
@@ -3414,7 +3415,7 @@ s_MgrMakeBeacon(
              );
     }
     // hostapd wpa/wpa2 IE
-    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) {
          if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
              if (pMgmt->wWPAIELen != 0) {
                  sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
@@ -3453,31 +3454,31 @@ PSTxMgmtPacket
 s_MgrMakeProbeResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wCurrBeaconPeriod,
-    UINT uCurrChannel,
-    WORD wCurrATIMWinodw,
-    PBYTE pDstAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wCurrBeaconPeriod,
+    unsigned int uCurrChannel,
+    unsigned short wCurrATIMWinodw,
+    unsigned char *pDstAddr,
     PWLAN_IE_SSID pCurrSSID,
-    PBYTE pCurrBSSID,
+    unsigned char *pCurrBSSID,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
-    BYTE byPHYType
+    unsigned char byPHYType
     )
 {
     PSTxMgmtPacket      pTxPacket = NULL;
     WLAN_FR_PROBERESP   sFrame;
-    PBYTE               pbyBuffer;
-    UINT                uLength = 0;
+    unsigned char *pbyBuffer;
+    unsigned int uLength = 0;
     PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
-    UINT                ii;
+    unsigned int ii;
 
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
     // Setup the sFrame structure.
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
     vMgrEncodeProbeResponse(&sFrame);
     // Setup the header
@@ -3493,7 +3494,7 @@ s_MgrMakeProbeResponse(
     *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
 
     if (byPHYType == BB_TYPE_11B) {
-        *sFrame.pwCapInfo &= cpu_to_le16((WORD)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
+        *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
     }
 
     // Copy SSID
@@ -3518,7 +3519,7 @@ s_MgrMakeProbeResponse(
         sFrame.len += (1) + WLAN_IEHDR_LEN;
         sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
         sFrame.pDSParms->len = 1;
-        sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
+        sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
     }
 
     if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
@@ -3535,20 +3536,20 @@ s_MgrMakeProbeResponse(
         sFrame.pERP->byElementID = WLAN_EID_ERP;
         sFrame.pERP->len = 1;
         sFrame.pERP->byContext = 0;
-        if (pDevice->bProtectMode == TRUE)
+        if (pDevice->bProtectMode == true)
             sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
-        if (pDevice->bNonERPPresent == TRUE)
+        if (pDevice->bNonERPPresent == true)
             sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
-        if (pDevice->bBarkerPreambleMd == TRUE)
+        if (pDevice->bBarkerPreambleMd == true)
             sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
     }
 
-    if ((pMgmt->b11hEnable == TRUE) &&
+    if ((pMgmt->b11hEnable == true) &&
         (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
         // Country IE
-        pbyBuffer = (PBYTE)(sFrame.pBuf + sFrame.len);
-        CARDvSetCountryIE(pMgmt->pAdapter, pbyBuffer);
-        CARDvSetCountryInfo(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
+        pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
+        set_country_IE(pMgmt->pAdapter, pbyBuffer);
+        set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
         uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
         pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
         // Power Constrain IE
@@ -3557,12 +3558,12 @@ s_MgrMakeProbeResponse(
         ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
         pbyBuffer += (1) + WLAN_IEHDR_LEN;
         uLength += (1) + WLAN_IEHDR_LEN;
-        if (pMgmt->bSwitchChannel == TRUE) {
+        if (pMgmt->bSwitchChannel == true) {
             // Channel Switch IE
             ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
             ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
             ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
-            ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = CARDbyGetChannelNumber(pMgmt->pAdapter, pMgmt->byNewChannel);
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
             ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
             pbyBuffer += (3) + WLAN_IEHDR_LEN;
             uLength += (3) + WLAN_IEHDR_LEN;
@@ -3586,7 +3587,7 @@ s_MgrMakeProbeResponse(
             pbyBuffer += (7) + WLAN_IEHDR_LEN;
             uLength += (7) + WLAN_IEHDR_LEN;
             for(ii=CB_MAX_CHANNEL_24G+1; ii<=CB_MAX_CHANNEL; ii++ ) {
-                if (CARDbGetChannelMapInfo(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == TRUE) {
+                if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) {
                     pbyBuffer += 2;
                     uLength += 2;
                     pIBSSDFS->len += 2;
@@ -3607,7 +3608,7 @@ s_MgrMakeProbeResponse(
     }
 
     // hostapd wpa/wpa2 IE
-    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) {
          if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
              if (pMgmt->wWPAIELen != 0) {
                  sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
@@ -3642,9 +3643,9 @@ PSTxMgmtPacket
 s_MgrMakeAssocRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    PBYTE pDAddr,
-    WORD wCurrCapInfo,
-    WORD wListenInterval,
+    unsigned char *pDAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wListenInterval,
     PWLAN_IE_SSID pCurrSSID,
     PWLAN_IE_SUPP_RATES pCurrRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
@@ -3652,15 +3653,15 @@ s_MgrMakeAssocRequest(
 {
     PSTxMgmtPacket      pTxPacket = NULL;
     WLAN_FR_ASSOCREQ    sFrame;
-    PBYTE               pbyIEs;
-    PBYTE               pbyRSN;
+    unsigned char *pbyIEs;
+    unsigned char *pbyRSN;
 
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
     // Setup the sFrame structure.
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
     // format fixed field frame structure
     vMgrEncodeAssocRequest(&sFrame);
@@ -3709,7 +3710,7 @@ s_MgrMakeAssocRequest(
     pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
 
     // for 802.11h
-    if (pMgmt->b11hEnable == TRUE) {
+    if (pMgmt->b11hEnable == true) {
         if (sFrame.pCurrPowerCap == NULL) {
             sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len);
             sFrame.len += (2 + WLAN_IEHDR_LEN);
@@ -3722,7 +3723,7 @@ s_MgrMakeAssocRequest(
         }
         if (sFrame.pCurrSuppCh == NULL) {
             sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len);
-            sFrame.len += CARDbySetSupportChannels(pMgmt->pAdapter,(PBYTE)sFrame.pCurrSuppCh);
+            sFrame.len += set_support_channels(pMgmt->pAdapter,(unsigned char *)sFrame.pCurrSuppCh);
         }
     }
 
@@ -3765,7 +3766,7 @@ s_MgrMakeAssocRequest(
             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
         }
         // Auth Key Management Suite
-        pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
+        pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
         *pbyRSN++=0x01;
         *pbyRSN++=0x00;
         *pbyRSN++=0x00;
@@ -3799,8 +3800,8 @@ s_MgrMakeAssocRequest(
     } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
                 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
                (pMgmt->pCurrBSS != NULL)) {
-        UINT                ii;
-        PWORD               pwPMKID;
+        unsigned int ii;
+        unsigned short *pwPMKID;
 
         // WPA IE
         sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
@@ -3854,7 +3855,7 @@ s_MgrMakeAssocRequest(
         sFrame.pRSN->len +=6;
 
         // RSN Capabilites
-        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
             memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
         } else {
             sFrame.pRSN->abyRSN[16] = 0;
@@ -3862,10 +3863,10 @@ s_MgrMakeAssocRequest(
         }
         sFrame.pRSN->len +=2;
 
-        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
             // RSN PMKID
             pbyRSN = &sFrame.pRSN->abyRSN[18];
-            pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
+            pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
             *pwPMKID = 0;            // Initialize PMKID count
             pbyRSN += 2;             // Point to PMKID list
             for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
@@ -3917,9 +3918,9 @@ PSTxMgmtPacket
 s_MgrMakeReAssocRequest(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    PBYTE pDAddr,
-    WORD wCurrCapInfo,
-    WORD wListenInterval,
+    unsigned char *pDAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wListenInterval,
     PWLAN_IE_SSID pCurrSSID,
     PWLAN_IE_SUPP_RATES pCurrRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
@@ -3927,15 +3928,15 @@ s_MgrMakeReAssocRequest(
 {
     PSTxMgmtPacket      pTxPacket = NULL;
     WLAN_FR_REASSOCREQ  sFrame;
-    PBYTE               pbyIEs;
-    PBYTE               pbyRSN;
+    unsigned char *pbyIEs;
+    unsigned char *pbyRSN;
 
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset( pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
     /* Setup the sFrame structure. */
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
 
     // format fixed field frame structure
@@ -4024,7 +4025,7 @@ s_MgrMakeReAssocRequest(
             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
         }
         // Auth Key Management Suite
-        pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
+        pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
         *pbyRSN++=0x01;
         *pbyRSN++=0x00;
         *pbyRSN++=0x00;
@@ -4055,8 +4056,8 @@ s_MgrMakeReAssocRequest(
     } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
                 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
                (pMgmt->pCurrBSS != NULL)) {
-        UINT                ii;
-        PWORD               pwPMKID;
+        unsigned int ii;
+        unsigned short *pwPMKID;
 
         /* WPA IE */
         sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
@@ -4110,7 +4111,7 @@ s_MgrMakeReAssocRequest(
         sFrame.pRSN->len +=6;
 
         // RSN Capabilites
-        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
             memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
         } else {
             sFrame.pRSN->abyRSN[16] = 0;
@@ -4118,10 +4119,10 @@ s_MgrMakeReAssocRequest(
         }
         sFrame.pRSN->len +=2;
 
-        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
             // RSN PMKID
             pbyRSN = &sFrame.pRSN->abyRSN[18];
-            pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
+            pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
             *pwPMKID = 0;            // Initialize PMKID count
             pbyRSN += 2;             // Point to PMKID list
             for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
@@ -4169,10 +4170,10 @@ PSTxMgmtPacket
 s_MgrMakeAssocResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wAssocStatus,
-    WORD wAssocAID,
-    PBYTE pDstAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wAssocStatus,
+    unsigned short wAssocAID,
+    unsigned char *pDstAddr,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
     )
@@ -4183,9 +4184,9 @@ s_MgrMakeAssocResponse(
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
     // Setup the sFrame structure
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
     vMgrEncodeAssocResponse(&sFrame);
     // Setup the header
@@ -4200,7 +4201,7 @@ s_MgrMakeAssocResponse(
 
     *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
     *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
-    *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
+    *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
 
     // Copy the rate set
     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
@@ -4243,10 +4244,10 @@ PSTxMgmtPacket
 s_MgrMakeReAssocResponse(
     PSDevice pDevice,
     PSMgmtObject pMgmt,
-    WORD wCurrCapInfo,
-    WORD wAssocStatus,
-    WORD wAssocAID,
-    PBYTE pDstAddr,
+    unsigned short wCurrCapInfo,
+    unsigned short wAssocStatus,
+    unsigned short wAssocAID,
+    unsigned char *pDstAddr,
     PWLAN_IE_SUPP_RATES pCurrSuppRates,
     PWLAN_IE_SUPP_RATES pCurrExtSuppRates
     )
@@ -4257,9 +4258,9 @@ s_MgrMakeReAssocResponse(
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
-    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
     // Setup the sFrame structure
-    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
     sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
     vMgrEncodeReassocResponse(&sFrame);
     // Setup the header
@@ -4274,7 +4275,7 @@ s_MgrMakeReAssocResponse(
 
     *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
     *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
-    *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
+    *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
 
     // Copy the rate set
     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
@@ -4322,16 +4323,16 @@ s_vMgrRxProbeResponse(
 {
     PKnownBSS           pBSSList = NULL;
     WLAN_FR_PROBERESP   sFrame;
-    BYTE                byCurrChannel = pRxPacket->byRxChannel;
+    unsigned char byCurrChannel = pRxPacket->byRxChannel;
     ERPObject           sERP;
-    BYTE                byIEChannel = 0;
-    BOOL                bChannelHit = TRUE;
+    unsigned char byIEChannel = 0;
+    bool bChannelHit = true;
 
 
     memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
     // decode the frame
     sFrame.len = pRxPacket->cbMPDULen;
-    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
     vMgrDecodeProbeResponse(&sFrame);
 
     if ((sFrame.pqwTimestamp == 0) ||
@@ -4350,29 +4351,29 @@ s_vMgrRxProbeResponse(
     if (sFrame.pDSParms != 0) {
         if (byCurrChannel > CB_MAX_CHANNEL_24G) {
             // channel remapping to
-            byIEChannel = CARDbyGetChannelMapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
+            byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
         } else {
             byIEChannel = sFrame.pDSParms->byCurrChannel;
         }
         if (byCurrChannel != byIEChannel) {
             // adjust channel info. bcs we rcv adjcent channel pakckets
-            bChannelHit = FALSE;
+            bChannelHit = false;
             byCurrChannel = byIEChannel;
         }
     } else {
         // no DS channel info
-        bChannelHit = TRUE;
+        bChannelHit = true;
     }
 
 //2008-0730-01<Add>by MikeLiu
-if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
+if(ChannelExceedZoneType(pDevice,byCurrChannel)==true)
       return;
 
     if (sFrame.pERP != NULL) {
         sERP.byERP = sFrame.pERP->byContext;
-        sERP.bERPExist = TRUE;
+        sERP.bERPExist = true;
     } else {
-        sERP.bERPExist = FALSE;
+        sERP.bERPExist = false;
         sERP.byERP = 0;
     }
 
@@ -4448,7 +4449,7 @@ s_vMgrRxProbeRequest(
     WLAN_FR_PROBEREQ    sFrame;
     CMD_STATUS          Status;
     PSTxMgmtPacket      pTxPacket;
-    BYTE                byPHYType = BB_TYPE_11B;
+    unsigned char byPHYType = BB_TYPE_11B;
 
     // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
     // STA have to response this request.
@@ -4458,7 +4459,7 @@ s_vMgrRxProbeRequest(
         memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
         // decode the frame
         sFrame.len = pRxPacket->cbMPDULen;
-        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
         vMgrDecodeProbeRequest(&sFrame);
 /*
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n",
@@ -4495,7 +4496,7 @@ s_vMgrRxProbeRequest(
                       0,
                       sFrame.pHdr->sA3.abyAddr2,
                       (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
-                      (PBYTE)pMgmt->abyCurrBSSID,
+                      (unsigned char *)pMgmt->abyCurrBSSID,
                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
                        byPHYType
@@ -4542,8 +4543,8 @@ vMgrRxManagePacket(
      )
 {
     PSDevice    pDevice = (PSDevice)hDeviceContext;
-    BOOL        bInScan = FALSE;
-    UINT        uNodeIndex = 0;
+    bool bInScan = false;
+    unsigned int uNodeIndex = 0;
     NODE_STATE  eNodeState = 0;
     CMD_STATUS  Status;
 
@@ -4577,7 +4578,7 @@ vMgrRxManagePacket(
         case WLAN_FSTYPE_ASSOCRESP:
             // Frame Clase = 2
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
-            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, FALSE);
+            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false);
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
             break;
 
@@ -4603,7 +4604,7 @@ vMgrRxManagePacket(
         case WLAN_FSTYPE_REASSOCRESP:
             // Frame Clase = 2
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
-            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, TRUE);
+            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true);
             break;
 
         case WLAN_FSTYPE_PROBEREQ:
@@ -4623,7 +4624,7 @@ vMgrRxManagePacket(
             // Frame Clase = 0
             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
             if (pMgmt->eScanState != WMAC_NO_SCANNING) {
-                bInScan = TRUE;
+                bInScan = true;
             };
             s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
             break;
@@ -4680,10 +4681,10 @@ vMgrRxManagePacket(
  *  Prepare beacon to send
  *
  * Return Value:
- *    TRUE if success; FALSE if failed.
+ *    true if success; false if failed.
  *
 -*/
-BOOL
+bool
 bMgrPrepareBeaconToSend(
     void *hDeviceContext,
     PSMgmtObject pMgmt
@@ -4692,7 +4693,7 @@ bMgrPrepareBeaconToSend(
     PSDevice            pDevice = (PSDevice)hDeviceContext;
     PSTxMgmtPacket      pTxPacket;
 
-//    pDevice->bBeaconBufReady = FALSE;
+//    pDevice->bBeaconBufReady = false;
     if (pDevice->bEncryptionEnable || pDevice->bEnable8021x){
         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
     }
@@ -4708,18 +4709,18 @@ bMgrPrepareBeaconToSend(
                   pMgmt->uCurrChannel,
                   pMgmt->wCurrATIMWindow, //0,
                   (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
-                  (PBYTE)pMgmt->abyCurrBSSID,
+                  (unsigned char *)pMgmt->abyCurrBSSID,
                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
                 );
 
     if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
         (pMgmt->abyCurrBSSID[0] == 0))
-        return FALSE;
+        return false;
 
     csBeacon_xmit(pDevice, pTxPacket);
 
-    return TRUE;
+    return true;
 }
 
 
@@ -4741,7 +4742,7 @@ static
 void
 s_vMgrLogStatus(
     PSMgmtObject pMgmt,
-    WORD  wStatus
+    unsigned short wStatus
     )
 {
     switch( wStatus ){
@@ -4807,24 +4808,24 @@ s_vMgrLogStatus(
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 bAdd_PMKID_Candidate (
     void *hDeviceContext,
-    PBYTE          pbyBSSID,
+    unsigned char *pbyBSSID,
     PSRSNCapObject psRSNCapObj
     )
 {
     PSDevice         pDevice = (PSDevice)hDeviceContext;
     PPMKID_CANDIDATE pCandidateList;
-    UINT             ii = 0;
+    unsigned int ii = 0;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
 
     if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
-        return FALSE;
+        return false;
 
     if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
-        return FALSE;
+        return false;
 
 
 
@@ -4832,18 +4833,18 @@ bAdd_PMKID_Candidate (
     for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
         pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
         if ( !memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
-            if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
+            if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) {
                 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
             } else {
                 pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
             }
-            return TRUE;
+            return true;
         }
     }
 
     // New Candidate
     pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
-    if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
+    if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) {
         pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
     } else {
         pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
@@ -4851,7 +4852,7 @@ bAdd_PMKID_Candidate (
     memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
     pDevice->gsPMKIDCandidate.NumCandidates++;
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
-    return TRUE;
+    return true;
 }
 
 /*
@@ -4881,20 +4882,20 @@ vFlush_PMKID_Candidate (
     memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
 }
 
-static BOOL
+static bool
 s_bCipherMatch (
     PKnownBSS                        pBSSNode,
     NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
-    PBYTE                           pbyCCSPK,
-    PBYTE                           pbyCCSGK
+    unsigned char *pbyCCSPK,
+    unsigned char *pbyCCSGK
     )
 {
-    BYTE byMulticastCipher = KEY_CTL_INVALID;
-    BYTE byCipherMask = 0x00;
+    unsigned char byMulticastCipher = KEY_CTL_INVALID;
+    unsigned char byCipherMask = 0x00;
     int i;
 
     if (pBSSNode == NULL)
-        return FALSE;
+        return false;
 
     // check cap. of BSS
     if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
@@ -4904,7 +4905,7 @@ s_bCipherMatch (
     }
 
     if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
-        (pBSSNode->bWPA2Valid == TRUE) &&
+        (pBSSNode->bWPA2Valid == true) &&
           //20080123-01,<Add> by Einsn Liu
         ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) {
         //WPA2
@@ -4938,7 +4939,7 @@ s_bCipherMatch (
         }
 
     } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
-                (pBSSNode->bWPAValid == TRUE) &&
+                (pBSSNode->bWPAValid == true) &&
                 ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
         //WPA
         // check Group Key Cipher
@@ -4978,9 +4979,9 @@ s_bCipherMatch (
             (byCipherMask == 0)) {
             *pbyCCSGK = KEY_CTL_WEP;
             *pbyCCSPK = KEY_CTL_NONE;
-            return TRUE;
+            return true;
         } else {
-            return FALSE;
+            return false;
         }
 
     } else if (EncStatus == Ndis802_11Encryption2Enabled) {
@@ -4988,45 +4989,45 @@ s_bCipherMatch (
             (byCipherMask == 0)) {
             *pbyCCSGK = KEY_CTL_TKIP;
             *pbyCCSPK = KEY_CTL_NONE;
-            return TRUE;
+            return true;
         } else if ((byMulticastCipher == KEY_CTL_WEP) &&
                    ((byCipherMask & 0x02) != 0)) {
             *pbyCCSGK = KEY_CTL_WEP;
             *pbyCCSPK = KEY_CTL_TKIP;
-            return TRUE;
+            return true;
         } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
                    ((byCipherMask & 0x02) != 0)) {
             *pbyCCSGK = KEY_CTL_TKIP;
             *pbyCCSPK = KEY_CTL_TKIP;
-            return TRUE;
+            return true;
         } else {
-            return FALSE;
+            return false;
         }
     } else if (EncStatus == Ndis802_11Encryption3Enabled) {
         if ((byMulticastCipher == KEY_CTL_CCMP) &&
             (byCipherMask == 0)) {
             // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
-            return FALSE;
+            return false;
         } else if ((byMulticastCipher == KEY_CTL_WEP) &&
                    ((byCipherMask & 0x04) != 0)) {
             *pbyCCSGK = KEY_CTL_WEP;
             *pbyCCSPK = KEY_CTL_CCMP;
-            return TRUE;
+            return true;
         } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
                    ((byCipherMask & 0x04) != 0)) {
             *pbyCCSGK = KEY_CTL_TKIP;
             *pbyCCSPK = KEY_CTL_CCMP;
-            return TRUE;
+            return true;
         } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
                    ((byCipherMask & 0x04) != 0)) {
             *pbyCCSGK = KEY_CTL_CCMP;
             *pbyCCSPK = KEY_CTL_CCMP;
-            return TRUE;
+            return true;
         } else {
-            return FALSE;
+            return false;
         }
     }
-    return TRUE;
+    return true;
 }
 
 
index 9ae7e0d55bc492c91a6df40dc0228c277491346e..141e80b843afa7d11abb03789bfc30837a793e8b 100644 (file)
 
 /*---------------------  Export Types  ------------------------------*/
 #define timer_expire(timer,next_tick)   mod_timer(&timer, RUN_AT(next_tick))
-typedef void (*TimerFunction)(ULONG);
+typedef void (*TimerFunction)(unsigned long);
 
 
 //+++ NDIS related
 
-typedef UCHAR   NDIS_802_11_MAC_ADDRESS[6];
+typedef unsigned char NDIS_802_11_MAC_ADDRESS[6];
 typedef struct _NDIS_802_11_AI_REQFI
 {
-    USHORT Capabilities;
-    USHORT ListenInterval;
+    unsigned short Capabilities;
+    unsigned short ListenInterval;
     NDIS_802_11_MAC_ADDRESS  CurrentAPAddress;
 } NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
 
 typedef struct _NDIS_802_11_AI_RESFI
 {
-    USHORT Capabilities;
-    USHORT StatusCode;
-    USHORT AssociationId;
+    unsigned short Capabilities;
+    unsigned short StatusCode;
+    unsigned short AssociationId;
 } NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
 
 typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
 {
-    ULONG                   Length;
-    USHORT                  AvailableRequestFixedIEs;
+    unsigned long Length;
+    unsigned short          AvailableRequestFixedIEs;
     NDIS_802_11_AI_REQFI    RequestFixedIEs;
-    ULONG                   RequestIELength;
-    ULONG                   OffsetRequestIEs;
-    USHORT                  AvailableResponseFixedIEs;
+    unsigned long RequestIELength;
+    unsigned long OffsetRequestIEs;
+    unsigned short          AvailableResponseFixedIEs;
     NDIS_802_11_AI_RESFI    ResponseFixedIEs;
-    ULONG                   ResponseIELength;
-    ULONG                   OffsetResponseIEs;
+    unsigned long ResponseIELength;
+    unsigned long OffsetResponseIEs;
 } NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
 
 
 
 typedef struct tagSAssocInfo {
     NDIS_802_11_ASSOCIATION_INFORMATION     AssocInfo;
-    BYTE                                    abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
+    unsigned char abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
     // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION
-    ULONG                                   RequestIELength;
-    BYTE                                    abyReqIEs[WLAN_BEACON_FR_MAXLEN];
+    unsigned long RequestIELength;
+    unsigned char abyReqIEs[WLAN_BEACON_FR_MAXLEN];
 } SAssocInfo, *PSAssocInfo;
 //---
 
@@ -224,8 +224,8 @@ typedef enum tagWMAC_POWER_MODE {
 typedef struct tagSTxMgmtPacket {
 
     PUWLAN_80211HDR     p80211Header;
-    UINT                cbMPDULen;
-    UINT                cbPayloadLen;
+    unsigned int cbMPDULen;
+    unsigned int cbPayloadLen;
 
 } STxMgmtPacket, *PSTxMgmtPacket;
 
@@ -235,12 +235,12 @@ typedef struct tagSRxMgmtPacket {
 
     PUWLAN_80211HDR     p80211Header;
     QWORD               qwLocalTSF;
-    UINT                cbMPDULen;
-    UINT                cbPayloadLen;
-    UINT                uRSSI;
-    BYTE                bySQ;
-    BYTE                byRxRate;
-    BYTE                byRxChannel;
+    unsigned int cbMPDULen;
+    unsigned int cbPayloadLen;
+    unsigned int uRSSI;
+    unsigned char bySQ;
+    unsigned char byRxRate;
+    unsigned char byRxChannel;
 
 } SRxMgmtPacket, *PSRxMgmtPacket;
 
@@ -251,7 +251,7 @@ typedef struct tagSMgmtObject
 
     void *                   pAdapter;
     // MAC address
-    BYTE                    abyMACAddr[WLAN_ADDR_LEN];
+    unsigned char abyMACAddr[WLAN_ADDR_LEN];
 
     // Configuration Mode
     WMAC_CONFIG_MODE        eConfigMode; // MAC pre-configed mode
@@ -264,86 +264,86 @@ typedef struct tagSMgmtObject
     WMAC_BSS_STATE          eCurrState;  // MAC current BSS state
 
     PKnownBSS               pCurrBSS;
-    BYTE                    byCSSGK;
-    BYTE                    byCSSPK;
+    unsigned char byCSSGK;
+    unsigned char byCSSPK;
 
-//    BYTE                    abyNewSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
-//    BYTE                    abyNewExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+//    unsigned char abyNewSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+//    unsigned char abyNewExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
 
     // Current state vars
-    UINT                    uCurrChannel;
-    BYTE                    abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-    BYTE                    abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-    BYTE                    abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-    BYTE                    abyCurrBSSID[WLAN_BSSID_LEN];
-    WORD                    wCurrCapInfo;
-    WORD                    wCurrAID;
-    WORD                    wCurrATIMWindow;
-    WORD                    wCurrBeaconPeriod;
-    BOOL                    bIsDS;
-    BYTE                    byERPContext;
+    unsigned int       uCurrChannel;
+    unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned char abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    unsigned char abyCurrBSSID[WLAN_BSSID_LEN];
+    unsigned short wCurrCapInfo;
+    unsigned short wCurrAID;
+    unsigned short wCurrATIMWindow;
+    unsigned short wCurrBeaconPeriod;
+    bool bIsDS;
+    unsigned char byERPContext;
 
     CMD_STATE               eCommandState;
-    UINT                    uScanChannel;
+    unsigned int       uScanChannel;
 
     // Desire joinning BSS vars
-    BYTE                    abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-    BYTE                    abyDesireBSSID[WLAN_BSSID_LEN];
+    unsigned char abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    unsigned char abyDesireBSSID[WLAN_BSSID_LEN];
 
     // Adhoc or AP configuration vars
-  //BYTE                    abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-    WORD                    wIBSSBeaconPeriod;
-    WORD                    wIBSSATIMWindow;
-    UINT                    uIBSSChannel;
-    BYTE                    abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-    BYTE                    byAPBBType;
-    BYTE                    abyWPAIE[MAX_WPA_IE_LEN];
-    WORD                    wWPAIELen;
-
-    UINT                    uAssocCount;
-    BOOL                    bMoreData;
+  //unsigned char abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    unsigned short wIBSSBeaconPeriod;
+    unsigned short wIBSSATIMWindow;
+    unsigned int       uIBSSChannel;
+    unsigned char abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    unsigned char byAPBBType;
+    unsigned char abyWPAIE[MAX_WPA_IE_LEN];
+    unsigned short wWPAIELen;
+
+    unsigned int       uAssocCount;
+    bool bMoreData;
 
     // Scan state vars
     WMAC_SCAN_STATE         eScanState;
     WMAC_SCAN_TYPE          eScanType;
-    UINT                    uScanStartCh;
-    UINT                    uScanEndCh;
-    WORD                    wScanSteps;
-    UINT                    uScanBSSType;
+    unsigned int       uScanStartCh;
+    unsigned int       uScanEndCh;
+    unsigned short wScanSteps;
+    unsigned int       uScanBSSType;
     // Desire scannig vars
-    BYTE                    abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-    BYTE                    abyScanBSSID[WLAN_BSSID_LEN];
+    unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    unsigned char abyScanBSSID[WLAN_BSSID_LEN];
 
     // Privacy
     WMAC_AUTHENTICATION_MODE eAuthenMode;
     WMAC_ENCRYPTION_MODE    eEncryptionMode;
-    BOOL                    bShareKeyAlgorithm;
-    BYTE                    abyChallenge[WLAN_CHALLENGE_LEN];
-    BOOL                    bPrivacyInvoked;
+    bool bShareKeyAlgorithm;
+    unsigned char abyChallenge[WLAN_CHALLENGE_LEN];
+    bool bPrivacyInvoked;
 
     // Received beacon state vars
-    BOOL                    bInTIM;
-    BOOL                    bMulticastTIM;
-    BYTE                    byDTIMCount;
-    BYTE                    byDTIMPeriod;
+    bool bInTIM;
+    bool bMulticastTIM;
+    unsigned char byDTIMCount;
+    unsigned char byDTIMPeriod;
 
     // Power saving state vars
     WMAC_POWER_MODE         ePSMode;
-    WORD                    wListenInterval;
-    WORD                    wCountToWakeUp;
-    BOOL                    bInTIMWake;
-    PBYTE                   pbyPSPacketPool;
-    BYTE                    byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN];
-    BOOL                    bRxBeaconInTBTTWake;
-    BYTE                    abyPSTxMap[MAX_NODE_NUM + 1];
+    unsigned short wListenInterval;
+    unsigned short wCountToWakeUp;
+    bool bInTIMWake;
+    unsigned char *pbyPSPacketPool;
+    unsigned char byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN];
+    bool bRxBeaconInTBTTWake;
+    unsigned char abyPSTxMap[MAX_NODE_NUM + 1];
 
     // management command related
-    UINT                    uCmdBusy;
-    UINT                    uCmdHostAPBusy;
+    unsigned int       uCmdBusy;
+    unsigned int       uCmdHostAPBusy;
 
     // management packet pool
-    PBYTE                   pbyMgmtPacketPool;
-    BYTE                    byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+    unsigned char *pbyMgmtPacketPool;
+    unsigned char byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
 
 
     // One second callback timer
@@ -366,7 +366,7 @@ typedef struct tagSMgmtObject
 
     // WPA2 PMKID Cache
     SPMKIDCache             gsPMKIDCache;
-    BOOL                    bRoaming;
+    bool bRoaming;
 
     // rate fall back vars
 
@@ -377,16 +377,16 @@ typedef struct tagSMgmtObject
 
 
     // for 802.11h
-    BOOL                    b11hEnable;
-    BOOL                    bSwitchChannel;
-    BYTE                    byNewChannel;
+    bool b11hEnable;
+    bool bSwitchChannel;
+    unsigned char byNewChannel;
     PWLAN_IE_MEASURE_REP    pCurrMeasureEIDRep;
-    UINT                    uLengthOfRepEIDs;
-    BYTE                    abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
-    BYTE                    abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
-    BYTE                    abyIECountry[WLAN_A3FR_MAXLEN];
-    BYTE                    abyIBSSDFSOwner[6];
-    BYTE                    byIBSSDFSRecovery;
+    unsigned int       uLengthOfRepEIDs;
+    unsigned char abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+    unsigned char abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+    unsigned char abyIECountry[WLAN_A3FR_MAXLEN];
+    unsigned char abyIBSSDFSOwner[6];
+    unsigned char byIBSSDFSRecovery;
 
     struct sk_buff  skb;
 
@@ -432,8 +432,8 @@ void
 vMgrDisassocBeginSta(
     void *hDeviceContext,
     PSMgmtObject pMgmt,
-    PBYTE  abyDestAddress,
-    WORD    wReason,
+    unsigned char *abyDestAddress,
+    unsigned short wReason,
     PCMD_STATUS pStatus
     );
 
@@ -475,22 +475,22 @@ void
 vMgrDeAuthenBeginSta(
     void *hDeviceContext,
     PSMgmtObject  pMgmt,
-    PBYTE   abyDestAddress,
-    WORD    wReason,
+    unsigned char *abyDestAddress,
+    unsigned short wReason,
     PCMD_STATUS pStatus
     );
 
-BOOL
+bool
 bMgrPrepareBeaconToSend(
     void *hDeviceContext,
     PSMgmtObject pMgmt
     );
 
 
-BOOL
+bool
 bAdd_PMKID_Candidate (
     void *hDeviceContext,
-    PBYTE          pbyBSSID,
+    unsigned char *pbyBSSID,
     PSRSNCapObject psRSNCapObj
     );
 
index da5c814e200eba598b2dd008c25ef776e9127079..61ac46fa505e9f1bbe6105a4b5c93bf9a4c38884 100644 (file)
 /*---------------------  Static Variables  --------------------------*/
 static int          msglevel                =MSG_LEVEL_INFO;
 
-const BYTE abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
-const BYTE abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
-const BYTE abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
-const BYTE abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
-const BYTE abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
-const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
+const unsigned char abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
+const unsigned char abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
+const unsigned char abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
+const unsigned char abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
+const unsigned char abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
+const unsigned char abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
 
 
 /*+
@@ -83,9 +83,9 @@ WPA_ClearRSN (
     pBSSList->wAuthCount = 0;
     pBSSList->byDefaultK_as_PK = 0;
     pBSSList->byReplayIdx = 0;
-    pBSSList->sRSNCapObj.bRSNCapExist = FALSE;
+    pBSSList->sRSNCapObj.bRSNCapExist = false;
     pBSSList->sRSNCapObj.wRSNCap = 0;
-    pBSSList->bWPAValid = FALSE;
+    pBSSList->bWPAValid = false;
 }
 
 
@@ -112,7 +112,7 @@ WPA_ParseRSN (
 {
     PWLAN_IE_RSN_AUTH  pIE_RSN_Auth = NULL;
     int                i, j, m, n = 0;
-    PBYTE              pbyCaps;
+    unsigned char *pbyCaps;
 
     WPA_ClearRSN(pBSSList);
 
@@ -148,7 +148,7 @@ WPA_ParseRSN (
         {
             j = 0;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
-            for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
+            for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(unsigned char)); i++) {
                 if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
                     if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
                         pBSSList->abyPKType[j++] = WPA_NONE;
@@ -166,7 +166,7 @@ WPA_ParseRSN (
                     break;
                 //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1]));
             } //for
-            pBSSList->wPKCount = (WORD)j;
+            pBSSList->wPKCount = (unsigned short)j;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount);
         }
 
@@ -180,7 +180,7 @@ WPA_ParseRSN (
             j = 0;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n",
                           pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
-            for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
+            for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(unsigned char)); i++) {
                 if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
                     if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
                         pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X;
@@ -195,7 +195,7 @@ WPA_ParseRSN (
                 //DBG_PRN_GRP14(("abyAuthType[%d]: %X\n", j-1, pBSSList->abyAuthType[j-1]));
             }
             if(j > 0)
-                pBSSList->wAuthCount = (WORD)j;
+                pBSSList->wAuthCount = (unsigned short)j;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount);
         }
 
@@ -207,17 +207,17 @@ WPA_ParseRSN (
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4);
 
             if(pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2)
-                pbyCaps = (PBYTE)pIE_RSN_Auth->AuthKSList[n].abyOUI;
+                pbyCaps = (unsigned char *)pIE_RSN_Auth->AuthKSList[n].abyOUI;
                 pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG;
                 pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS);
-                pBSSList->sRSNCapObj.bRSNCapExist = TRUE;
-                pBSSList->sRSNCapObj.wRSNCap = *(PWORD)pbyCaps;
+                pBSSList->sRSNCapObj.bRSNCapExist = true;
+                pBSSList->sRSNCapObj.wRSNCap = *(unsigned short *)pbyCaps;
                 //DBG_PRN_GRP14(("pbyCaps: %X\n", *pbyCaps));
                 //DBG_PRN_GRP14(("byDefaultK_as_PK: %X\n", pBSSList->byDefaultK_as_PK));
                 //DBG_PRN_GRP14(("byReplayIdx: %X\n", pBSSList->byReplayIdx));
             }
         }
-        pBSSList->bWPAValid = TRUE;
+        pBSSList->bWPAValid = true;
     }
 }
 
@@ -237,24 +237,24 @@ WPA_ParseRSN (
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 WPA_SearchRSN (
-    BYTE                byCmd,
-    BYTE                byEncrypt,
+    unsigned char byCmd,
+    unsigned char byEncrypt,
     PKnownBSS        pBSSList
     )
 {
     int ii;
-    BYTE byPKType = WPA_NONE;
+    unsigned char byPKType = WPA_NONE;
 
-    if (pBSSList->bWPAValid == FALSE)
-        return FALSE;
+    if (pBSSList->bWPAValid == false)
+        return false;
 
     switch(byCmd) {
     case 0:
 
         if (byEncrypt != pBSSList->byGKType)
-            return FALSE;
+            return false;
 
         if (pBSSList->wPKCount > 0) {
             for (ii = 0; ii < pBSSList->wPKCount; ii ++) {
@@ -268,9 +268,9 @@ WPA_SearchRSN (
                      byPKType = WPA_WEP104;
             }
             if (byEncrypt != byPKType)
-                return FALSE;
+                return false;
         }
-        return TRUE;
+        return true;
 //        if (pBSSList->wAuthCount > 0)
 //            for (ii=0; ii < pBSSList->wAuthCount; ii ++)
 //                if (byAuth == pBSSList->abyAuthType[ii])
@@ -280,7 +280,7 @@ WPA_SearchRSN (
     default:
         break;
     }
-    return FALSE;
+    return false;
 }
 
 /*+
@@ -297,20 +297,20 @@ WPA_SearchRSN (
  * Return Value: none.
  *
 -*/
-BOOL
+bool
 WPAb_Is_RSN (
     PWLAN_IE_RSN_EXT pRSN
     )
 {
     if (pRSN == NULL)
-        return FALSE;
+        return false;
 
     if ((pRSN->len >= 6) && // oui1(4)+ver(2)
         (pRSN->byElementID == WLAN_EID_RSN_WPA) &&  !memcmp(pRSN->abyOUI, abyOUI01, 4) &&
         (pRSN->wVersion == 1)) {
-        return TRUE;
+        return true;
     }
     else
-        return FALSE;
+        return false;
 }
 
index 80d990b09d25edf95bc3b58f5586cc8ea66229a0..921fd7ae9d3870285d1f4aeed015f75dfa86e87d 100644 (file)
@@ -69,14 +69,14 @@ WPA_ParseRSN(
     PWLAN_IE_RSN_EXT pRSN
     );
 
-BOOL
+bool
 WPA_SearchRSN(
-    BYTE                byCmd,
-    BYTE                byEncrypt,
+    unsigned char byCmd,
+    unsigned char byEncrypt,
     PKnownBSS        pBSSList
     );
 
-BOOL
+bool
 WPAb_Is_RSN(
     PWLAN_IE_RSN_EXT pRSN
     );
index 7a42a0aad7d24c47e39cb8b7e6a57dee6f97c73e..805164bed7e4bf1a27f30be1ec3a1d4cc8ff6dbe 100644 (file)
@@ -42,14 +42,14 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 /*---------------------  Static Variables  --------------------------*/
 
-const BYTE abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
-const BYTE abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
-const BYTE abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
-const BYTE abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
-const BYTE abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
+const unsigned char abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
+const unsigned char abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+const unsigned char abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
+const unsigned char abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
+const unsigned char abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
 
-const BYTE abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
-const BYTE abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
+const unsigned char abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+const unsigned char abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
 
 
 /*---------------------  Static Functions  --------------------------*/
@@ -79,7 +79,7 @@ WPA2_ClearRSN (
 {
     int ii;
 
-    pBSSNode->bWPA2Valid = FALSE;
+    pBSSNode->bWPA2Valid = false;
 
     pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
     for (ii=0; ii < 4; ii ++)
@@ -88,7 +88,7 @@ WPA2_ClearRSN (
     for (ii=0; ii < 4; ii ++)
         pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X;
     pBSSNode->wAKMSSAuthCount = 1;
-    pBSSNode->sRSNCapObj.bRSNCapExist = FALSE;
+    pBSSNode->sRSNCapObj.bRSNCapExist = false;
     pBSSNode->sRSNCapObj.wRSNCap = 0;
 }
 
@@ -114,9 +114,9 @@ WPA2vParseRSN (
     )
 {
     int                 i, j;
-    WORD                m = 0, n = 0;
-    PBYTE               pbyOUI;
-    BOOL                bUseGK = FALSE;
+    unsigned short m = 0, n = 0;
+    unsigned char *pbyOUI;
+    bool bUseGK = false;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len);
 
@@ -124,7 +124,7 @@ WPA2vParseRSN (
 
     if (pRSN->len == 2) { // ver(2)
         if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) {
-            pBSSNode->bWPA2Valid = TRUE;
+            pBSSNode->bWPA2Valid = true;
         }
         return;
     }
@@ -159,21 +159,21 @@ WPA2vParseRSN (
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"802.11i CSS: %X\n", pBSSNode->byCSSGK);
 
         if (pRSN->len == 6) {
-            pBSSNode->bWPA2Valid = TRUE;
+            pBSSNode->bWPA2Valid = true;
             return;
         }
 
         if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2)
-            pBSSNode->wCSSPKCount = *((PWORD) &(pRSN->abyRSN[4]));
+            pBSSNode->wCSSPKCount = *((unsigned short *) &(pRSN->abyRSN[4]));
             j = 0;
             pbyOUI = &(pRSN->abyRSN[6]);
 
-            for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(BYTE)); i++) {
+            for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(unsigned char)); i++) {
 
                 if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i)
                     if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
                         pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP;
-                        bUseGK = TRUE;
+                        bUseGK = true;
                     } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) {
                         // Invialid CSS, continue to parsing
                     } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) {
@@ -195,7 +195,7 @@ WPA2vParseRSN (
                     break;
             } //for
 
-            if (bUseGK == TRUE) {
+            if (bUseGK == true) {
                 if (j != 1) {
                     // invalid CSS, This should be only PK CSS.
                     return;
@@ -209,17 +209,17 @@ WPA2vParseRSN (
                 // invalid CSS, No valid PK.
                 return;
             }
-            pBSSNode->wCSSPKCount = (WORD)j;
+            pBSSNode->wCSSPKCount = (unsigned short)j;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount);
         }
 
-        m = *((PWORD) &(pRSN->abyRSN[4]));
+        m = *((unsigned short *) &(pRSN->abyRSN[4]));
 
         if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2)
-            pBSSNode->wAKMSSAuthCount = *((PWORD) &(pRSN->abyRSN[6+4*m]));;
+            pBSSNode->wAKMSSAuthCount = *((unsigned short *) &(pRSN->abyRSN[6+4*m]));;
             j = 0;
             pbyOUI = &(pRSN->abyRSN[8+4*m]);
-            for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(BYTE)); i++) {
+            for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(unsigned char)); i++) {
                 if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i)
                     if ( !memcmp(pbyOUI, abyOUI8021X, 4))
                         pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X;
@@ -232,17 +232,17 @@ WPA2vParseRSN (
                 } else
                     break;
             }
-            pBSSNode->wAKMSSAuthCount = (WORD)j;
+            pBSSNode->wAKMSSAuthCount = (unsigned short)j;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount);
 
-            n = *((PWORD) &(pRSN->abyRSN[6+4*m]));;
+            n = *((unsigned short *) &(pRSN->abyRSN[6+4*m]));;
             if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2)
-                pBSSNode->sRSNCapObj.bRSNCapExist = TRUE;
-                pBSSNode->sRSNCapObj.wRSNCap = *((PWORD) &(pRSN->abyRSN[8+4*m+4*n]));
+                pBSSNode->sRSNCapObj.bRSNCapExist = true;
+                pBSSNode->sRSNCapObj.wRSNCap = *((unsigned short *) &(pRSN->abyRSN[8+4*m+4*n]));
             }
         }
         //ignore PMKID lists bcs only (Re)Assocrequest has this field
-        pBSSNode->bWPA2Valid = TRUE;
+        pBSSNode->bWPA2Valid = true;
     }
 }
 
@@ -261,16 +261,16 @@ WPA2vParseRSN (
  * Return Value: length of IEs.
  *
 -*/
-UINT
+unsigned int
 WPA2uSetIEs(
     void *pMgmtHandle,
     PWLAN_IE_RSN pRSNIEs
     )
 {
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtHandle;
-    PBYTE           pbyBuffer = NULL;
-    UINT            ii = 0;
-    PWORD           pwPMKID = NULL;
+    unsigned char *pbyBuffer = NULL;
+    unsigned int ii = 0;
+    unsigned short *pwPMKID = NULL;
 
     if (pRSNIEs == NULL) {
         return(0);
@@ -279,7 +279,7 @@ WPA2uSetIEs(
          (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
         (pMgmt->pCurrBSS != NULL)) {
         /* WPA2 IE */
-        pbyBuffer = (PBYTE) pRSNIEs;
+        pbyBuffer = (unsigned char *) pRSNIEs;
         pRSNIEs->byElementID = WLAN_EID_RSN;
         pRSNIEs->len = 6; //Version(2)+GK(4)
         pRSNIEs->wVersion = 1;
@@ -330,7 +330,7 @@ WPA2uSetIEs(
         pRSNIEs->len +=6;
 
         // RSN Capabilites
-        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
             memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
         } else {
             pRSNIEs->abyRSN[16] = 0;
@@ -339,10 +339,10 @@ WPA2uSetIEs(
         pRSNIEs->len +=2;
 
         if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) &&
-            (pMgmt->bRoaming == TRUE) &&
+            (pMgmt->bRoaming == true) &&
             (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
             // RSN PMKID
-            pwPMKID = (PWORD)(&pRSNIEs->abyRSN[18]);  // Point to PMKID count
+            pwPMKID = (unsigned short *)(&pRSNIEs->abyRSN[18]);  // Point to PMKID count
             *pwPMKID = 0;                               // Initialize PMKID count
             pbyBuffer = &pRSNIEs->abyRSN[20];           // Point to PMKID list
             for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) {
index 7200db37f43056202444f43b4c12407114e2395b..718208beb72fa87e0ff3d62de446b25295b2b376 100644 (file)
 #define MAX_PMKID_CACHE         16
 
 typedef struct tagsPMKIDInfo {
-    BYTE    abyBSSID[6];
-    BYTE    abyPMKID[16];
+    unsigned char abyBSSID[6];
+    unsigned char abyPMKID[16];
 } PMKIDInfo, *PPMKIDInfo;
 
 typedef struct tagSPMKIDCache {
-    ULONG       BSSIDInfoCount;
+    unsigned long BSSIDInfoCount;
     PMKIDInfo   BSSIDInfo[MAX_PMKID_CACHE];
 } SPMKIDCache, *PSPMKIDCache;
 
@@ -69,7 +69,7 @@ WPA2vParseRSN (
     PWLAN_IE_RSN     pRSN
     );
 
-UINT
+unsigned int
 WPA2uSetIEs(
     void *pMgmtHandle,
     PWLAN_IE_RSN pRSNIEs
index 22c2fab3f328499c2a3c0dea44ad9b9f8caff2fe..0142338bcafe7fc0440edbf3c65a12d7f9b0df85 100644 (file)
@@ -199,16 +199,16 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
  *
  */
 
- int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
+ int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
 {
     struct viawget_wpa_param *param=ctx;
     PSMgmtObject pMgmt = pDevice->pMgmt;
-    DWORD   dwKeyIndex = 0;
-    BYTE    abyKey[MAX_KEY_LEN];
-    BYTE    abySeq[MAX_KEY_LEN];
+    unsigned long dwKeyIndex = 0;
+    unsigned char abyKey[MAX_KEY_LEN];
+    unsigned char abySeq[MAX_KEY_LEN];
     QWORD   KeyRSC;
 //    NDIS_802_11_KEY_RSC KeyRSC;
-    BYTE    byKeyDecMode = KEY_CTL_WEP;
+    unsigned char byKeyDecMode = KEY_CTL_WEP;
        int ret = 0;
        int uu, ii;
 
@@ -219,9 +219,9 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
        if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-        pDevice->bEncryptionEnable = FALSE;
+        pDevice->bEncryptionEnable = false;
         pDevice->byKeyIndex = 0;
-        pDevice->bTransmitKey = FALSE;
+        pDevice->bTransmitKey = false;
         KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset);
         for (uu=0; uu<MAX_KEY_TABLE; uu++) {
             MACvDisableKeyEntry(pDevice->PortOffset, uu);
@@ -243,7 +243,7 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
 spin_lock_irq(&pDevice->lock);
        }
 
-    dwKeyIndex = (DWORD)(param->u.wpa_key.key_index);
+    dwKeyIndex = (unsigned long)(param->u.wpa_key.key_index);
 
        if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
         if (dwKeyIndex > 3) {
@@ -251,8 +251,8 @@ spin_lock_irq(&pDevice->lock);
         }
         else {
             if (param->u.wpa_key.set_tx) {
-                pDevice->byKeyIndex = (BYTE)dwKeyIndex;
-                pDevice->bTransmitKey = TRUE;
+                pDevice->byKeyIndex = (unsigned char)dwKeyIndex;
+                pDevice->bTransmitKey = true;
                        dwKeyIndex |= (1 << 31);
             }
             KeybSetDefaultKey(&(pDevice->sKey),
@@ -266,7 +266,7 @@ spin_lock_irq(&pDevice->lock);
 
         }
         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
-        pDevice->bEncryptionEnable = TRUE;
+        pDevice->bEncryptionEnable = true;
         return ret;
        }
 
@@ -351,26 +351,26 @@ spin_lock_irq(&pDevice->lock);
     }
 
    // spin_lock_irq(&pDevice->lock);
-    if (IS_BROADCAST_ADDRESS(&param->addr[0]) || (param->addr == NULL)) {
-        // If IS_BROADCAST_ADDRESS, set the key as every key entry's group key.
+    if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
+        // If is_broadcast_ether_addr, set the key as every key entry's group key.
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
 
         if ((KeybSetAllGroupKey(&(pDevice->sKey),
                             dwKeyIndex,
                             param->u.wpa_key.key_len,
                             (PQWORD) &(KeyRSC),
-                            (PBYTE)abyKey,
+                            (unsigned char *)abyKey,
                             byKeyDecMode,
                             pDevice->PortOffset,
-                            pDevice->byLocalID) == TRUE) &&
+                            pDevice->byLocalID) == true) &&
             (KeybSetDefaultKey(&(pDevice->sKey),
                             dwKeyIndex,
                             param->u.wpa_key.key_len,
                             (PQWORD) &(KeyRSC),
-                            (PBYTE)abyKey,
+                            (unsigned char *)abyKey,
                             byKeyDecMode,
                             pDevice->PortOffset,
-                            pDevice->byLocalID) == TRUE) ) {
+                            pDevice->byLocalID) == true) ) {
              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
 
         } else {
@@ -400,15 +400,15 @@ spin_lock_irq(&pDevice->lock);
                        dwKeyIndex,
                        param->u.wpa_key.key_len,
                        (PQWORD) &(KeyRSC),
-                       (PBYTE)abyKey,
+                       (unsigned char *)abyKey,
                         byKeyDecMode,
                         pDevice->PortOffset,
-                        pDevice->byLocalID) == TRUE) {
+                        pDevice->byLocalID) == true) {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
 
         } else {
             // Key Table Full
-            if (IS_ETH_ADDRESS_EQUAL(&param->addr[0], pDevice->abyBSSID)) {
+            if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
                 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
                 //spin_unlock_irq(&pDevice->lock);
                 return -EINVAL;
@@ -422,10 +422,10 @@ spin_lock_irq(&pDevice->lock);
         }
     } // BSSID not 0xffffffffffff
     if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
-        pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index;
-        pDevice->bTransmitKey = TRUE;
+        pDevice->byKeyIndex = (unsigned char)param->u.wpa_key.key_index;
+        pDevice->bTransmitKey = true;
     }
-    pDevice->bEncryptionEnable = TRUE;
+    pDevice->bEncryptionEnable = true;
     //spin_unlock_irq(&pDevice->lock);
 
 /*
@@ -465,7 +465,7 @@ static int wpa_set_wpa(PSDevice pDevice,
        int ret = 0;
 
     pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
-    pMgmt->bShareKeyAlgorithm = FALSE;
+    pMgmt->bShareKeyAlgorithm = false;
 
     return ret;
 }
@@ -613,13 +613,13 @@ static int wpa_get_scan(PSDevice pDevice,
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PWLAN_IE_SSID   pItemSSID;
     PKnownBSS pBSS;
-       PBYTE  pBuf;
+       unsigned char *pBuf;
        int ret = 0;
        u16 count = 0;
        u16 ii, jj;
 #if 1
 
-    PBYTE ptempBSS;
+    unsigned char *ptempBSS;
 
 
 
@@ -639,9 +639,9 @@ static int wpa_get_scan(PSDevice pDevice,
 
          for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {
 
-           if((pMgmt->sBSSList[jj].bActive!=TRUE) ||
+           if((pMgmt->sBSSList[jj].bActive!=true) ||
 
-                ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) {
+                ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=false))) {
 
                  memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));
 
@@ -713,7 +713,7 @@ static int wpa_get_scan(PSDevice pDevice,
                 scan_buf->rsn_ie_len = pBSS->wRSNLen;
                 memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
             }
-            scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result));
+            scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result));
             jj ++;
         }
     }
@@ -752,10 +752,10 @@ static int wpa_set_associate(PSDevice pDevice,
 {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PWLAN_IE_SSID   pItemSSID;
-    BYTE    abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-    BYTE    abyWPAIE[64];
+    unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    unsigned char abyWPAIE[64];
     int ret = 0;
-    BOOL bWepEnabled=FALSE;
+    bool bWepEnabled=false;
 
        // set key type & algorithm
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
@@ -817,7 +817,7 @@ else
        case CIPHER_WEP40:
        case CIPHER_WEP104:
                pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
-               bWepEnabled=TRUE;
+               bWepEnabled=true;
                break;
        case CIPHER_NONE:
                if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
@@ -834,26 +834,26 @@ else
       if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) {
             pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
             //pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
-            pMgmt->bShareKeyAlgorithm = TRUE;
+            pMgmt->bShareKeyAlgorithm = true;
              }
      else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
           if(!bWepEnabled)  pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
        else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
             //pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
-            //pMgmt->bShareKeyAlgorithm = FALSE; //20080717-06,<Modify> by chester//Fix Open mode, WEP encrytion
+            //pMgmt->bShareKeyAlgorithm = false; //20080717-06,<Modify> by chester//Fix Open mode, WEP encrytion
            }
 //mike save old encryption status
        pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;
 
     if (pDevice->eEncryptionStatus !=  Ndis802_11EncryptionDisabled)
-        pDevice->bEncryptionEnable = TRUE;
+        pDevice->bEncryptionEnable = true;
     else
-        pDevice->bEncryptionEnable = FALSE;
+        pDevice->bEncryptionEnable = false;
 if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
-      ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled==TRUE))) )  //DavidWang  //20080717-06,<Modify> by chester//Not to initial WEP
+      ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled==true))) )  //DavidWang  //20080717-06,<Modify> by chester//Not to initial WEP
     KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
     spin_lock_irq(&pDevice->lock);
-    pDevice->bLinkPass = FALSE;
+    pDevice->bLinkPass = false;
     memset(pMgmt->abyCurrBSSID, 0, 6);
     pMgmt->eCurrState = WMAC_STATE_IDLE;
     netif_stop_queue(pDevice->dev);
@@ -922,7 +922,7 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
        case VIAWGET_SET_KEY:
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
            spin_lock_irq(&pDevice->lock);
-        ret = wpa_set_keys(pDevice, param, FALSE);
+        ret = wpa_set_keys(pDevice, param, false);
         spin_unlock_irq(&pDevice->lock);
                break;
 
index b0d92d51a2a671383041c1c9739c8a7e1c11a2c5..dbe8e861d991e226648fbd53b15d4fc1164e14b5 100644 (file)
@@ -54,7 +54,7 @@ typedef enum { KEY_MGMT_802_1X, KEY_MGMT_CCKM,KEY_MGMT_PSK, KEY_MGMT_NONE,
 
 
 
-typedef ULONGLONG   NDIS_802_11_KEY_RSC;
+typedef unsigned long long   NDIS_802_11_KEY_RSC;
 
 /*---------------------  Export Classes  ----------------------------*/
 
@@ -64,7 +64,7 @@ typedef ULONGLONG   NDIS_802_11_KEY_RSC;
 
 int wpa_set_wpadev(PSDevice pDevice, int val);
 int wpa_ioctl(PSDevice pDevice, struct iw_point *p);
-int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel);
+int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel);
 
 #endif // __WPACL_H__
 
index bf92fb9908fe50a66ce9f9f08dc6e0db37a1cb08..66e2eeae628bcc5d47f7b40a5b52b579db1a71c8 100644 (file)
@@ -53,45 +53,45 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 /*
  * Description:
- *      Relay packet.  Return TRUE if packet is copy to DMA1
+ *      Relay packet.  Return true if packet is copy to DMA1
  *
  * Parameters:
  *  In:
  *      pDevice             -
  *      pbySkbData          - rx packet skb data
  *  Out:
- *      TURE, FALSE
+ *      true, false
  *
- * Return Value: TRUE if packet duplicate; otherwise FALSE
+ * Return Value: true if packet duplicate; otherwise false
  *
  */
-BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex)
+bool ROUTEbRelay (PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex)
 {
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSTxDesc        pHeadTD, pLastTD;
-    UINT            cbFrameBodySize;
-    UINT            uMACfragNum;
-    BYTE            byPktType;
-    BOOL            bNeedEncryption = FALSE;
+    unsigned int cbFrameBodySize;
+    unsigned int uMACfragNum;
+    unsigned char byPktType;
+    bool bNeedEncryption = false;
     SKeyItem        STempKey;
     PSKeyItem       pTransmitKey = NULL;
-    UINT            cbHeaderSize;
-    UINT            ii;
-    PBYTE           pbyBSSID;
+    unsigned int cbHeaderSize;
+    unsigned int ii;
+    unsigned char *pbyBSSID;
 
 
 
 
     if (AVAIL_TD(pDevice, TYPE_AC0DMA)<=0) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n");
-        return FALSE;
+        return false;
     }
 
     pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
 
     pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
 
-    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, ETH_HLEN);
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)pbySkbData, ETH_HLEN);
 
     cbFrameBodySize = uDataLen - ETH_HLEN;
 
@@ -99,12 +99,12 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
         cbFrameBodySize += 8;
     }
 
-    if (pDevice->bEncryptionEnable == TRUE) {
-        bNeedEncryption = TRUE;
+    if (pDevice->bEncryptionEnable == true) {
+        bNeedEncryption = true;
 
         // get group key
         pbyBSSID = pDevice->abyBroadcastAddr;
-        if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+        if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
             pTransmitKey = NULL;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
         } else {
@@ -130,16 +130,16 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
     uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
 
     if (uMACfragNum > AVAIL_TD(pDevice,TYPE_AC0DMA)) {
-        return FALSE;
+        return false;
     }
-    byPktType = (BYTE)pDevice->byPacketType;
+    byPktType = (unsigned char)pDevice->byPacketType;
 
     if (pDevice->bFixRate) {
         if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
             if (pDevice->uConnectionRate >= RATE_11M) {
                 pDevice->wCurrentRate = RATE_11M;
             } else {
-                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+                pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
             }
         } else {
             if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
@@ -149,7 +149,7 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
                 if (pDevice->uConnectionRate >= RATE_54M)
                     pDevice->wCurrentRate = RATE_54M;
                 else
-                    pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+                    pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
             }
         }
     }
@@ -172,7 +172,7 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
         MACbPSWakeup(pDevice->PortOffset);
     }
 
-    pDevice->bPWBitOn = FALSE;
+    pDevice->bPWBitOn = false;
 
     pLastTD = pHeadTD;
     for (ii = 0; ii < uMACfragNum; ii++) {
@@ -192,7 +192,7 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
 
     MACvTransmitAC0(pDevice->PortOffset);
 
-    return TRUE;
+    return true;
 }
 
 
index 295cdc5b8e9d4471cfa5a872fd3ba2383bf2be2e..34f9e43a6cc478ccae3df77dc38ee26a27790aba 100644 (file)
@@ -39,7 +39,7 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex);
+bool ROUTEbRelay (PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex);
 
 #endif // __WROUTE_H__
 
index f24dc55e68f1e291905ab6a7ca1b62b2923a6368..fceec4999c361b6e3aa897bfa8e8bee72885a100 100644 (file)
@@ -18,7 +18,7 @@
  *
  * File: 80211mgr.c
  *
- * Purpose: Handles the 802.11 managment support functions
+ * Purpose: Handles the 802.11 management support functions
  *
  * Author: Lyndon Chen
  *
@@ -67,8 +67,8 @@
 
 /*---------------------  Static Variables  --------------------------*/
 
-static int          msglevel                =MSG_LEVEL_INFO;
-//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                = MSG_LEVEL_INFO;
+/*static int          msglevel                =MSG_LEVEL_DEBUG;*/
 /*---------------------  Static Functions  --------------------------*/
 
 
@@ -96,7 +96,7 @@ vMgrEncodeBeacon(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_BEACON_OFF_TS);
     pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -130,7 +130,7 @@ vMgrDecodeBeacon(
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_BEACON_OFF_TS);
     pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -138,88 +138,87 @@ vMgrDecodeBeacon(
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_BEACON_OFF_CAPINFO);
 
-    // Information elements
+    /* Information elements */
     pItem = (PWLAN_IE)((PBYTE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)))
                        + WLAN_BEACON_OFF_SSID);
-    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ){
+    while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
 
         switch (pItem->byElementID) {
-            case WLAN_EID_SSID:
-                if (pFrame->pSSID == NULL)
-                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
-                break;
-            case WLAN_EID_SUPP_RATES:
-                if (pFrame->pSuppRates == NULL)
-                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-            case WLAN_EID_FH_PARMS:
-                //pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem;
-                break;
-            case WLAN_EID_DS_PARMS:
-                if (pFrame->pDSParms == NULL)
-                    pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
-                break;
-            case WLAN_EID_CF_PARMS:
-                if (pFrame->pCFParms == NULL)
-                    pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
-                break;
-            case WLAN_EID_IBSS_PARMS:
-                if (pFrame->pIBSSParms == NULL)
-                    pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
-                break;
-            case WLAN_EID_TIM:
-                if (pFrame->pTIM == NULL)
-                    pFrame->pTIM = (PWLAN_IE_TIM)pItem;
-                break;
-
-            case WLAN_EID_RSN:
-                if (pFrame->pRSN == NULL) {
-                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                }
-                break;
-            case WLAN_EID_RSN_WPA:
-                if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
-                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
-                }
-                break;
-
-            case WLAN_EID_ERP:
-                if (pFrame->pERP == NULL)
-                    pFrame->pERP = (PWLAN_IE_ERP)pItem;
-                break;
-            case WLAN_EID_EXTSUPP_RATES:
-                if (pFrame->pExtSuppRates == NULL)
-                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-
-            case WLAN_EID_COUNTRY:      //7
-                if (pFrame->pIE_Country == NULL)
-                    pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
-                break;
-
-            case WLAN_EID_PWR_CONSTRAINT:   //32
-                if (pFrame->pIE_PowerConstraint == NULL)
-                    pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
-                break;
-
-            case WLAN_EID_CH_SWITCH:    //37
-                if (pFrame->pIE_CHSW == NULL)
-                    pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
-                break;
-
-            case WLAN_EID_QUIET:        //40
-                if (pFrame->pIE_Quiet == NULL)
-                    pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
-                break;
-
-            case WLAN_EID_IBSS_DFS:
-                if (pFrame->pIE_IBSSDFS == NULL)
-                    pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
-                break;
-
-            default:
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
+        case WLAN_EID_SSID:
+            if (pFrame->pSSID == NULL)
+                pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+            break;
+        case WLAN_EID_SUPP_RATES:
+            if (pFrame->pSuppRates == NULL)
+                pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
+        case WLAN_EID_FH_PARMS:
+            /* pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem; */
+            break;
+        case WLAN_EID_DS_PARMS:
+            if (pFrame->pDSParms == NULL)
+                pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+            break;
+        case WLAN_EID_CF_PARMS:
+            if (pFrame->pCFParms == NULL)
+                pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+            break;
+        case WLAN_EID_IBSS_PARMS:
+            if (pFrame->pIBSSParms == NULL)
+                pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+            break;
+        case WLAN_EID_TIM:
+            if (pFrame->pTIM == NULL)
+                pFrame->pTIM = (PWLAN_IE_TIM)pItem;
+            break;
+
+        case WLAN_EID_RSN:
+            if (pFrame->pRSN == NULL) 
+                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+            break;
+        case WLAN_EID_RSN_WPA:
+            if (pFrame->pRSNWPA == NULL) {
+                if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+            }
+            break;
+
+        case WLAN_EID_ERP:
+            if (pFrame->pERP == NULL)
+                pFrame->pERP = (PWLAN_IE_ERP)pItem;
+            break;
+        case WLAN_EID_EXTSUPP_RATES:
+            if (pFrame->pExtSuppRates == NULL)
+                pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
+
+        case WLAN_EID_COUNTRY:      /* 7 */
+            if (pFrame->pIE_Country == NULL)
+                pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+            break;
+
+        case WLAN_EID_PWR_CONSTRAINT:   /* 32 */
+            if (pFrame->pIE_PowerConstraint == NULL)
+                pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+            break;
+
+        case WLAN_EID_CH_SWITCH:    /* 37 */
+            if (pFrame->pIE_CHSW == NULL)
+                pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+            break;
+
+        case WLAN_EID_QUIET:        /* 40 */
+            if (pFrame->pIE_Quiet == NULL)
+                pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+            break;
+
+        case WLAN_EID_IBSS_DFS:
+            if (pFrame->pIE_IBSSDFS == NULL)
+                pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+            break;
+
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
                 break;
 
         }
@@ -295,7 +294,7 @@ vMgrEncodeDisassociation(
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DISASSOC_OFF_REASON);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason));
@@ -322,7 +321,7 @@ vMgrDecodeDisassociation(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DISASSOC_OFF_REASON);
 
@@ -347,7 +346,7 @@ vMgrEncodeAssocRequest(
     )
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCREQ_OFF_CAP_INFO);
     pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -376,47 +375,46 @@ vMgrDecodeAssocRequest(
     PWLAN_IE   pItem;
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCREQ_OFF_CAP_INFO);
     pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCREQ_OFF_LISTEN_INT);
 
-    // Information elements
+    /* Information elements */
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_ASSOCREQ_OFF_SSID);
 
     while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
-        switch (pItem->byElementID){
-            case WLAN_EID_SSID:
-                if (pFrame->pSSID == NULL)
-                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
-                break;
-            case WLAN_EID_SUPP_RATES:
-                if (pFrame->pSuppRates == NULL)
-                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-
-            case WLAN_EID_RSN:
-                if (pFrame->pRSN == NULL) {
-                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                }
-                break;
-            case WLAN_EID_RSN_WPA:
-                if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
-                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
-                }
-                break;
-            case WLAN_EID_EXTSUPP_RATES:
-                if (pFrame->pExtSuppRates == NULL)
-                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-
-            default:
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
-                        pItem->byElementID);
-                break;
+        switch (pItem->byElementID) {
+        case WLAN_EID_SSID:
+            if (pFrame->pSSID == NULL)
+                pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+            break;
+        case WLAN_EID_SUPP_RATES:
+            if (pFrame->pSuppRates == NULL)
+                pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
+
+        case WLAN_EID_RSN:
+            if (pFrame->pRSN == NULL)
+                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+            break;
+        case WLAN_EID_RSN_WPA:
+            if (pFrame->pRSNWPA == NULL) {
+                if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+            }
+            break;
+        case WLAN_EID_EXTSUPP_RATES:
+            if (pFrame->pExtSuppRates == NULL)
+                pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
+
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
+                    pItem->byElementID);
+            break;
         }
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
     }
@@ -441,7 +439,7 @@ vMgrEncodeAssocResponse(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCRESP_OFF_CAP_INFO);
     pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -475,7 +473,7 @@ vMgrDecodeAssocResponse(
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_ASSOCRESP_OFF_CAP_INFO);
     pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -483,7 +481,7 @@ vMgrDecodeAssocResponse(
     pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_ASSOCRESP_OFF_AID);
 
-    // Information elements
+    /* Information elements */
     pFrame->pSuppRates  = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                            + WLAN_ASSOCRESP_OFF_SUPP_RATES);
 
@@ -493,8 +491,7 @@ vMgrDecodeAssocResponse(
     if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
         pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
-    }
-    else {
+    } else {
         pFrame->pExtSuppRates = NULL;
     }
     return;
@@ -519,7 +516,7 @@ vMgrEncodeReassocRequest(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCREQ_OFF_CAP_INFO);
     pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -552,7 +549,7 @@ vMgrDecodeReassocRequest(
     PWLAN_IE   pItem;
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCREQ_OFF_CAP_INFO);
     pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -560,42 +557,41 @@ vMgrDecodeReassocRequest(
     pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_REASSOCREQ_OFF_CURR_AP);
 
-    // Information elements
+    /* Information elements */
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                        + WLAN_REASSOCREQ_OFF_SSID);
 
-    while(((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
-
-        switch (pItem->byElementID){
-            case WLAN_EID_SSID:
-                if (pFrame->pSSID == NULL)
-                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
-                break;
-            case WLAN_EID_SUPP_RATES:
-                if (pFrame->pSuppRates == NULL)
-                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-
-            case WLAN_EID_RSN:
-                if (pFrame->pRSN == NULL) {
-                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                }
-                break;
-            case WLAN_EID_RSN_WPA:
-                if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
-                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
-                }
-                break;
+    while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
 
-            case WLAN_EID_EXTSUPP_RATES:
-                if (pFrame->pExtSuppRates == NULL)
-                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-            default:
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
-                            pItem->byElementID);
-                break;
+        switch (pItem->byElementID) {
+        case WLAN_EID_SSID:
+            if (pFrame->pSSID == NULL)
+                pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+            break;
+        case WLAN_EID_SUPP_RATES:
+            if (pFrame->pSuppRates == NULL)
+                pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
+
+        case WLAN_EID_RSN:
+            if (pFrame->pRSN == NULL)
+                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+            break;
+        case WLAN_EID_RSN_WPA:
+            if (pFrame->pRSNWPA == NULL) {
+                if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+            }
+            break;
+
+        case WLAN_EID_EXTSUPP_RATES:
+            if (pFrame->pExtSuppRates == NULL)
+                pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
+                        pItem->byElementID);
+            break;
         }
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
     }
@@ -646,30 +642,30 @@ vMgrDecodeProbeRequest(
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Information elements
+    /* Information elements */
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)));
 
-    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+    while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
 
         switch (pItem->byElementID) {
-            case WLAN_EID_SSID:
-                if (pFrame->pSSID == NULL)
-                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
-                break;
+        case WLAN_EID_SSID:
+            if (pFrame->pSSID == NULL)
+                pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+            break;
 
-            case WLAN_EID_SUPP_RATES:
-                if (pFrame->pSuppRates == NULL)
-                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
+        case WLAN_EID_SUPP_RATES:
+            if (pFrame->pSuppRates == NULL)
+                pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
 
-            case WLAN_EID_EXTSUPP_RATES:
-                if (pFrame->pExtSuppRates == NULL)
-                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
+        case WLAN_EID_EXTSUPP_RATES:
+            if (pFrame->pExtSuppRates == NULL)
+                pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
 
-            default:
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
-                break;
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
+            break;
         }
 
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
@@ -697,7 +693,7 @@ vMgrEncodeProbeResponse(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_PROBERESP_OFF_TS);
     pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -734,7 +730,7 @@ vMgrDecodeProbeResponse(
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                     + WLAN_PROBERESP_OFF_TS);
     pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -742,83 +738,82 @@ vMgrDecodeProbeResponse(
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_PROBERESP_OFF_CAP_INFO);
 
-    // Information elements
+    /* Information elements */
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                        + WLAN_PROBERESP_OFF_SSID);
 
-    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+    while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
         switch (pItem->byElementID) {
-            case WLAN_EID_SSID:
-                if (pFrame->pSSID == NULL)
+        case WLAN_EID_SSID:
+            if (pFrame->pSSID == NULL)
                 pFrame->pSSID = (PWLAN_IE_SSID)pItem;
-                break;
-            case WLAN_EID_SUPP_RATES:
-                if (pFrame->pSuppRates == NULL)
+            break;
+        case WLAN_EID_SUPP_RATES:
+            if (pFrame->pSuppRates == NULL)
                 pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-            case WLAN_EID_FH_PARMS:
-                break;
-            case WLAN_EID_DS_PARMS:
-                if (pFrame->pDSParms == NULL)
-                    pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
-                break;
-            case WLAN_EID_CF_PARMS:
-                if (pFrame->pCFParms == NULL)
-                    pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
-                break;
-            case WLAN_EID_IBSS_PARMS:
-                if (pFrame->pIBSSParms == NULL)
-                    pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
-                break;
-
-            case WLAN_EID_RSN:
-                if (pFrame->pRSN == NULL) {
-                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                }
-                break;
-            case WLAN_EID_RSN_WPA:
-                if (pFrame->pRSNWPA == NULL) {
-                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
-                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
-                }
-                break;
-            case WLAN_EID_ERP:
-                if (pFrame->pERP == NULL)
-                    pFrame->pERP = (PWLAN_IE_ERP)pItem;
-                break;
-            case WLAN_EID_EXTSUPP_RATES:
-                if (pFrame->pExtSuppRates == NULL)
-                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-                break;
-
-            case WLAN_EID_COUNTRY:      //7
-                if (pFrame->pIE_Country == NULL)
-                    pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
-                break;
-
-            case WLAN_EID_PWR_CONSTRAINT:   //32
-                if (pFrame->pIE_PowerConstraint == NULL)
-                    pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
-                break;
-
-            case WLAN_EID_CH_SWITCH:    //37
-                if (pFrame->pIE_CHSW == NULL)
-                    pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
-                break;
-
-            case WLAN_EID_QUIET:        //40
-                if (pFrame->pIE_Quiet == NULL)
-                    pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
-                break;
-
-            case WLAN_EID_IBSS_DFS:
-                if (pFrame->pIE_IBSSDFS == NULL)
-                    pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
-                break;
-
-            default:
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
-                break;
+            break;
+        case WLAN_EID_FH_PARMS:
+            break;
+        case WLAN_EID_DS_PARMS:
+            if (pFrame->pDSParms == NULL)
+                pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+            break;
+        case WLAN_EID_CF_PARMS:
+            if (pFrame->pCFParms == NULL)
+                pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+            break;
+        case WLAN_EID_IBSS_PARMS:
+            if (pFrame->pIBSSParms == NULL)
+                pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+            break;
+
+        case WLAN_EID_RSN:
+            if (pFrame->pRSN == NULL)
+                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+            break;
+        case WLAN_EID_RSN_WPA:
+            if (pFrame->pRSNWPA == NULL) {
+                if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                    pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+            }
+            break;
+        case WLAN_EID_ERP:
+            if (pFrame->pERP == NULL)
+                pFrame->pERP = (PWLAN_IE_ERP)pItem;
+            break;
+        case WLAN_EID_EXTSUPP_RATES:
+            if (pFrame->pExtSuppRates == NULL)
+                pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+            break;
+
+        case WLAN_EID_COUNTRY:      /* 7 */
+            if (pFrame->pIE_Country == NULL)
+                pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+            break;
+
+        case WLAN_EID_PWR_CONSTRAINT:   /* 32 */
+            if (pFrame->pIE_PowerConstraint == NULL)
+                pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+            break;
+
+        case WLAN_EID_CH_SWITCH:    /* 37 */
+            if (pFrame->pIE_CHSW == NULL)
+                pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+            break;
+
+        case WLAN_EID_QUIET:        /* 40 */
+            if (pFrame->pIE_Quiet == NULL)
+                pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+            break;
+
+        case WLAN_EID_IBSS_DFS:
+            if (pFrame->pIE_IBSSDFS == NULL)
+                pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+            break;
+
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
+            break;
         }
 
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
@@ -845,7 +840,7 @@ vMgrEncodeAuthen(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                       + WLAN_AUTHEN_OFF_AUTH_ALG);
     pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -853,7 +848,6 @@ vMgrEncodeAuthen(
     pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_AUTHEN_OFF_STATUS);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus));
-
     return;
 }
 
@@ -878,7 +872,7 @@ vMgrDecodeAuthen(
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                       + WLAN_AUTHEN_OFF_AUTH_ALG);
     pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -886,14 +880,12 @@ vMgrDecodeAuthen(
     pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_AUTHEN_OFF_STATUS);
 
-    // Information elements
+    /* Information elements */
     pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                        + WLAN_AUTHEN_OFF_CHALLENGE);
 
-    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) {
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE))
         pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
-    }
-
     return;
 }
 
@@ -916,11 +908,10 @@ vMgrEncodeDeauthen(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DEAUTHEN_OFF_REASON);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason));
-
     return;
 }
 
@@ -943,10 +934,9 @@ vMgrDecodeDeauthen(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DEAUTHEN_OFF_REASON);
-
     return;
 }
 
@@ -969,7 +959,7 @@ vMgrEncodeReassocResponse(
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCRESP_OFF_CAP_INFO);
     pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -978,7 +968,6 @@ vMgrEncodeReassocResponse(
                             + WLAN_REASSOCRESP_OFF_AID);
 
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid));
-
     return;
 }
 
@@ -1004,7 +993,7 @@ vMgrDecodeReassocResponse(
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
 
-    // Fixed Fields
+    /* Fixed Fields */
     pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                 + WLAN_REASSOCRESP_OFF_CAP_INFO);
     pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
@@ -1012,15 +1001,14 @@ vMgrDecodeReassocResponse(
     pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                             + WLAN_REASSOCRESP_OFF_AID);
 
-    //Information elements
+    /* Information elements */
     pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                                + WLAN_REASSOCRESP_OFF_SUPP_RATES);
 
     pItem = (PWLAN_IE)(pFrame->pSuppRates);
     pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
 
-    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES))
         pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-    }
     return;
 }
index c140a957d9df60a58d2cb124ad7262c94b471e8a..3d57f793986d0186ca78d1d53aa1553d837b8700 100644 (file)
@@ -19,7 +19,7 @@
  *
  * File: 80211mgr.h
  *
- * Purpose: 802.11 managment frames pre-defines.
+ * Purpose: 802.11 management frames pre-defines.
  *
  *
  * Author: Lyndon Chen
 #define MEASURE_MODE_INCAPABLE  0x02
 #define MEASURE_MODE_REFUSED    0x04
 
-
-
 /*---------------------  Export Classes  ----------------------------*/
 
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Types  ------------------------------*/
 
-
 // Information Element Types
 
 #pragma pack(1)
 typedef struct tagWLAN_IE {
     BYTE   byElementID;
     BYTE   len;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE, *PWLAN_IE;
 
-
 // Service Set Identity (SSID)
 #pragma pack(1)
 typedef struct tagWLAN_IE_SSID {
     BYTE   byElementID;
     BYTE   len;
     BYTE   abySSID[1];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_SSID, *PWLAN_IE_SSID;
 
-
 // Supported Rates
 #pragma pack(1)
 typedef struct tagWLAN_IE_SUPP_RATES {
     BYTE   byElementID;
     BYTE   len;
     BYTE   abyRates[1];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_SUPP_RATES,  *PWLAN_IE_SUPP_RATES;
 
-
-
 // FH Parameter Set
 #pragma pack(1)
 typedef struct _WLAN_IE_FH_PARMS {
@@ -279,10 +272,9 @@ typedef struct tagWLAN_IE_DS_PARMS {
     BYTE   byElementID;
     BYTE   len;
     BYTE   byCurrChannel;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_DS_PARMS,  *PWLAN_IE_DS_PARMS;
 
-
 // CF Parameter Set
 #pragma pack(1)
 typedef struct tagWLAN_IE_CF_PARMS {
@@ -292,10 +284,9 @@ typedef struct tagWLAN_IE_CF_PARMS {
     BYTE   byCFPPeriod;
     WORD   wCFPMaxDuration;
     WORD   wCFPDurRemaining;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_CF_PARMS,  *PWLAN_IE_CF_PARMS;
 
-
 // TIM
 #pragma pack(1)
 typedef struct tagWLAN_IE_TIM {
@@ -305,30 +296,27 @@ typedef struct tagWLAN_IE_TIM {
     BYTE   byDTIMPeriod;
     BYTE   byBitMapCtl;
     BYTE   byVirtBitMap[1];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_TIM,  *PWLAN_IE_TIM;
 
-
 // IBSS Parameter Set
 #pragma pack(1)
 typedef struct tagWLAN_IE_IBSS_PARMS {
     BYTE   byElementID;
     BYTE   len;
     WORD   wATIMWindow;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS;
 
-
 // Challenge Text
 #pragma pack(1)
 typedef struct tagWLAN_IE_CHALLENGE {
     BYTE   byElementID;
     BYTE   len;
     BYTE   abyChallenge[1];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_CHALLENGE,  *PWLAN_IE_CHALLENGE;
 
-
 #pragma pack(1)
 typedef struct tagWLAN_IE_RSN_EXT {
     BYTE byElementID;
@@ -391,10 +379,9 @@ typedef struct tagWLAN_IE_ERP {
     BYTE   byElementID;
     BYTE   len;
     BYTE   byContext;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 WLAN_IE_ERP,  *PWLAN_IE_ERP;
 
-
 #pragma pack(1)
 typedef struct _MEASEURE_REQ {
     BYTE                byChannel;
index b3d367b9bdc6548325497301f581c6e67fc43ad0..f7a3b8f8da708e55aeb290670bba8f49144e6794 100644 (file)
@@ -106,7 +106,7 @@ BYTE dot3_table[256] = {
 
 /*---------------------  Export Functions  --------------------------*/
 
-void xor_128(BYTE *a, BYTE *b, BYTE *out)
+static void xor_128(BYTE *a, BYTE *b, BYTE *out)
 {
        PDWORD dwPtrA = (PDWORD) a;
        PDWORD dwPtrB = (PDWORD) b;
@@ -119,7 +119,7 @@ void xor_128(BYTE *a, BYTE *b, BYTE *out)
 }
 
 
-void xor_32(BYTE *a, BYTE *b, BYTE *out)
+static void xor_32(BYTE *a, BYTE *b, BYTE *out)
 {
        PDWORD dwPtrA = (PDWORD) a;
        PDWORD dwPtrB = (PDWORD) b;
index d3de94f36c6e5889f166c4881ae4193764bcc200..29902492975ca1a081288e7e6694765acc7c3472 100644 (file)
@@ -989,10 +989,10 @@ BBvSetAntennaMode (PSDevice pDevice, BYTE byAntennaMode)
  * Return Value: none
  *
  */
-BOOL
-BBbVT3184Init (PSDevice pDevice)
+
+BOOL BBbVT3184Init(PSDevice pDevice)
 {
-    NTSTATUS                ntStatus;
+       int ntStatus;
     WORD                    wLength;
     PBYTE                   pbyAddr;
     PBYTE                   pbyAgc;
index bc4633d5feadf06eddc4550ddde1561e3b669df7..8db8cd07d5f5c7683aebf6596ea369627e602660 100644 (file)
@@ -104,16 +104,13 @@ BBuGetFrameTime(
      WORD wRate
     );
 
-void
-BBvCaculateParameter (
-      PSDevice pDevice,
-      unsigned int cbFrameLength,
-      WORD wRate,
-      BYTE byPacketType,
-     PWORD pwPhyLen,
-     PBYTE pbyPhySrv,
-     PBYTE pbyPhySgn
-    );
+void BBvCaculateParameter(PSDevice pDevice,
+                         unsigned int cbFrameLength,
+                         WORD wRate,
+                         BYTE byPacketType,
+                         PWORD pwPhyLen,
+                         PBYTE pbyPhySrv,
+                         PBYTE pbyPhySgn);
 
 // timer for antenna diversity
 
@@ -128,7 +125,7 @@ void BBvSoftwareReset(PSDevice pDevice);
 void BBvSetShortSlotTime(PSDevice pDevice);
 void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData);
 void BBvSetAntennaMode(PSDevice pDevice, BYTE byAntennaMode);
-BOOL BBbVT3184Init (PSDevice pDevice);
+BOOL BBbVT3184Init(PSDevice pDevice);
 void BBvSetDeepSleep(PSDevice pDevice);
 void BBvExitDeepSleep(PSDevice pDevice);
 void BBvUpdatePreEDThreshold(
index 36ed61b595ca3287b8a28db2e1a15fb459877d1a..a9f68bd5afa615c41721aec07c85079a72c89d13 100644 (file)
@@ -93,10 +93,7 @@ const WORD             awHWRetry1[5][5] = {
 
 void s_vCheckSensitivity(void *hDeviceContext);
 void s_vCheckPreEDThreshold(void *hDeviceContext);
-
-#ifdef Calcu_LinkQual
 void s_uCalculateLinkQual(void *hDeviceContext);
-#endif
 
 /*---------------------  Export Variables  --------------------------*/
 
@@ -135,7 +132,7 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext,
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n",
                             *pbyDesireBSSID,*(pbyDesireBSSID+1),*(pbyDesireBSSID+2),
                             *(pbyDesireBSSID+3),*(pbyDesireBSSID+4),*(pbyDesireBSSID+5));
-        if ((!IS_BROADCAST_ADDRESS(pbyDesireBSSID)) &&
+       if ((!is_broadcast_ether_addr(pbyDesireBSSID)) &&
             (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){
             pbyBSSID = pbyDesireBSSID;
         }
@@ -156,7 +153,7 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext,
 
             if ((pCurrBSS->bActive) &&
                 (pCurrBSS->bSelected == FALSE)) {
-                if (IS_ETH_ADDRESS_EQUAL(pCurrBSS->abyBSSID, pbyBSSID)) {
+                   if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
                     if (pSSID != NULL) {
                         // compare ssid
                         if ( !memcmp(pSSID->abySSID,
@@ -296,7 +293,8 @@ void BSSvClearBSSList(void *hDeviceContext, BOOL bKeepCurrBSSID)
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         if (bKeepCurrBSSID) {
             if (pMgmt->sBSSList[ii].bActive &&
-                IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
+               !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
+                                   pMgmt->abyCurrBSSID)) {
  //mike mark: there are two same BSSID in list if that AP is in hidden ssid mode,one 's SSID is null,
  //                 but other's is obvious, so if it acssociate with your STA  exactly,you must keep two
  //                 of them!!!!!!!!!
@@ -341,7 +339,7 @@ PKnownBSS BSSpAddrIsInBSSList(void *hDeviceContext,
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         pBSSList = &(pMgmt->sBSSList[ii]);
         if (pBSSList->bActive) {
-            if (IS_ETH_ADDRESS_EQUAL(pBSSList->abyBSSID, abyBSSID)) {
+               if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
                 if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
                     if (memcmp(pSSID->abySSID,
                             ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
@@ -699,12 +697,14 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext,
         pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
         pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
         ldBmSum = 0;
-        for(ii=0, jj=0;ii<RSSI_STAT_COUNT;ii++) {
-            if (pBSSList->ldBmAverage[ii] != 0) {
-                pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm);
-                ldBmSum += pBSSList->ldBmAverage[ii];
-                jj++;
-            }
+       for (ii = 0, jj = 0; ii < RSSI_STAT_COUNT; ii++) {
+               if (pBSSList->ldBmAverage[ii] != 0) {
+                       pBSSList->ldBmMAX =
+                               max(pBSSList->ldBmAverage[ii], ldBm);
+                       ldBmSum +=
+                               pBSSList->ldBmAverage[ii];
+                       jj++;
+               }
         }
         pBSSList->ldBmAverRange = ldBmSum /jj;
     }
@@ -714,28 +714,6 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext,
         pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
     memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
 
-//mike add: if  the AP in this pBSSList is hidden ssid and we can find two of them,
-//                  you need upgrade the other related pBSSList of which ssid is obvious,
-//                  for these two AP is the same one!!!!
-/********judge by:BSSID is the same,but ssid is different!*****************/
-#if 0
-   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
-      if (IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pBSSList->abyBSSID)) {   //BSSID is the same!
-         if (memcmp(((PWLAN_IE_SSID)pMgmt->sBSSList[ii].abySSID)->abySSID,                  //ssid is different??
-                             ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
-                             ((PWLAN_IE_SSID)pBSSList->abySSID)->len) != 0) {
-                  //reserve temp
-               memset(abyTmpSSID,0,sizeof(abyTmpSSID));
-             memcpy(abyTmpSSID,pMgmt->sBSSList[ii].abySSID,sizeof(abyTmpSSID));
-                 //upgrade the other one pBSSList
-             memcpy(&(pMgmt->sBSSList[ii]),pBSSList,sizeof(KnownBSS));
-                 //recover ssid info
-             memcpy(pMgmt->sBSSList[ii].abySSID,abyTmpSSID,sizeof(abyTmpSSID));
-           }
-       }
-    }
-#endif
-
     return TRUE;
 }
 
@@ -755,7 +733,7 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext,
 
 BOOL BSSbIsSTAInNodeDB(void *hDeviceContext,
                       PBYTE abyDstAddr,
-                      PUINT puNodeIndex)
+                      unsigned int *puNodeIndex)
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
@@ -764,7 +742,8 @@ BOOL BSSbIsSTAInNodeDB(void *hDeviceContext,
     // Index = 0 reserved for AP Node
     for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
         if (pMgmt->sNodeDBTable[ii].bActive) {
-            if (IS_ETH_ADDRESS_EQUAL(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+               if (!compare_ether_addr(abyDstAddr,
+                                       pMgmt->sNodeDBTable[ii].abyMACAddr)) {
                 *puNodeIndex = ii;
                 return TRUE;
             }
@@ -786,7 +765,7 @@ BOOL BSSbIsSTAInNodeDB(void *hDeviceContext,
  *    None
  *
 -*/
-void BSSvCreateOneNode(void *hDeviceContext, PUINT puNodeIndex)
+void BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex)
 {
 
     PSDevice     pDevice = (PSDevice)hDeviceContext;
@@ -1023,7 +1002,6 @@ if(pDevice->byReAssocCount > 0) {
        pDevice->byReAssocCount = 0;
 }
 
-#ifdef SndEvt_ToAPI
 if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
      (pMgmt->eLastState==WMAC_STATE_ASSOC))
 {
@@ -1033,11 +1011,8 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
   wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
 }
  pMgmt->eLastState = pMgmt->eCurrState ;
-#endif
 
-#ifdef Calcu_LinkQual
    s_uCalculateLinkQual((void *)pDevice);
-#endif
 
     for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
 
@@ -1422,21 +1397,25 @@ void BSSvUpdateNodeTxCounter(void *hDeviceContext,
                      (wRate < RATE_18M) ) {
                     pMgmt->sNodeDBTable[0].uTxFail[wRate]+=byTxRetry;
                 } else if (byFallBack == AUTO_FB_0) {
-                    for(ii=0;ii<byTxRetry;ii++) {
-                        if (ii < 5)
-                            wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
-                        else
-                            wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
-                        pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
-                    }
+                       for (ii = 0; ii < byTxRetry; ii++) {
+                               if (ii < 5)
+                                       wFallBackRate =
+                                               awHWRetry0[wRate-RATE_18M][ii];
+                               else
+                                       wFallBackRate =
+                                               awHWRetry0[wRate-RATE_18M][4];
+                               pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+                       }
                 } else if (byFallBack == AUTO_FB_1) {
-                    for(ii=0;ii<byTxRetry;ii++) {
-                        if (ii < 5)
-                            wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
-                        else
-                            wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
-                        pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
-                    }
+                       for (ii = 0; ii < byTxRetry; ii++) {
+                               if (ii < 5)
+                                       wFallBackRate =
+                                               awHWRetry1[wRate-RATE_18M][ii];
+                               else
+                                       wFallBackRate =
+                                               awHWRetry1[wRate-RATE_18M][4];
+                               pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+                       }
                 }
             }
         };
@@ -1476,21 +1455,23 @@ void BSSvUpdateNodeTxCounter(void *hDeviceContext,
                          (wRate < RATE_18M) ) {
                         pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate]+=byTxRetry;
                     } else if (byFallBack == AUTO_FB_0) {
-                        for(ii=0;ii<byTxRetry;ii++) {
-                            if (ii < 5)
-                                wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
-                            else
-                                wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
-                            pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+                       for (ii = 0; ii < byTxRetry; ii++) {
+                               if (ii < 5)
+                                       wFallBackRate =
+                                               awHWRetry0[wRate-RATE_18M][ii];
+                               else
+                                       wFallBackRate =
+                                               awHWRetry0[wRate-RATE_18M][4];
+                               pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
                         }
                     } else if (byFallBack == AUTO_FB_1) {
-                        for(ii=0;ii<byTxRetry;ii++) {
-                            if (ii < 5)
+                     for (ii = 0; ii < byTxRetry; ii++) {
+                       if (ii < 5)
                                 wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
-                            else
+                       else
                                 wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
-                            pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
-                        }
+                       pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+                     }
                     }
                 }
             };
@@ -1587,7 +1568,6 @@ void s_vCheckSensitivity(void *hDeviceContext)
     }
 }
 
-#ifdef Calcu_LinkQual
 void s_uCalculateLinkQual(void *hDeviceContext)
 {
    PSDevice        pDevice = (PSDevice)hDeviceContext;
@@ -1632,7 +1612,6 @@ else
    pDevice->scStatistic.TxRetryOkCount = 0;
    return;
 }
-#endif
 
 void BSSvClearAnyBSSJoinRecord(void *hDeviceContext)
 {
index 9686d8600d635b5ed16c9be2d51dd5923ec04248..a8f97ebb659b54c87682e753f1e1fa504c311a74 100644 (file)
@@ -40,7 +40,7 @@
 
 #define MAX_NODE_NUM             64
 #define MAX_BSS_NUM              42
-#define LOST_BEACON_COUNT               10   // 10 sec, XP defined
+#define LOST_BEACON_COUNT        10   /* 10 sec, XP defined */
 #define MAX_PS_TX_BUF            32   // sta max power saving tx buf
 #define ADHOC_LOST_BEACON_COUNT  30   // 30 sec, beacon lost for adhoc only
 #define MAX_INACTIVE_COUNT       300  // 300 sec, inactive STA node refresh
 typedef struct tagSERPObject {
     BOOL    bERPExist;
     BYTE    byERP;
-}ERPObject, *PERPObject;
+} ERPObject, *PERPObject;
 
 
 typedef struct tagSRSNCapObject {
     BOOL    bRSNCapExist;
     WORD    wRSNCap;
-}SRSNCapObject, *PSRSNCapObject;
+} SRSNCapObject, *PSRSNCapObject;
 
 // BSS info(AP)
 #pragma pack(1)
@@ -153,7 +153,7 @@ typedef struct tagKnownBSS {
     SRSNCapObject   sRSNCapObj;
     BYTE            abyIEs[1024];   // don't move this field !!
 
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 KnownBSS , *PKnownBSS;
 
 
@@ -278,9 +278,9 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext,
 
 BOOL BSSbIsSTAInNodeDB(void *hDeviceContext,
                       PBYTE abyDstAddr,
-                      PUINT puNodeIndex);
+                      unsigned int *puNodeIndex);
 
-void BSSvCreateOneNode(void *hDeviceContext, PUINT puNodeIndex);
+void BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex);
 
 void BSSvUpdateAPNode(void *hDeviceContext,
                      PWORD pwCapInfo,
index fe4ec913ffea9e97dedc2c9960cc5e77a754f265..35bf4fda330d086370e389ea6b920390be96386b 100644 (file)
@@ -457,12 +457,11 @@ void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType)
     abyData[14] = abySignal[3];
     abyData[15] = abyServ[3];
 
-    for(i=0;i<9;i++) {
-        abyData[16+i*2] = abyTxRate[i];
-        abyData[16+i*2+1] = abyRsvTime[i];
+    for (i = 0; i < 9; i++) {
+       abyData[16+i*2] = abyTxRate[i];
+       abyData[16+i*2+1] = abyRsvTime[i];
     }
 
-
     CONTROLnsRequestOut(pDevice,
                         MESSAGE_TYPE_WRITE,
                         MAC_REG_RSPINF_B_1,
index f49b6e1333945ff3bd89151faebe0fee47ba0b70..6ad03e492edb6ed62300c958f249f1887ebee4a3 100644 (file)
@@ -441,11 +441,10 @@ void CHvInitChannelTable(void *pDeviceHandler)
 {
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
     BOOL        bMultiBand = FALSE;
-    unsigned int        ii;
+    unsigned int ii;
 
-    for(ii=1;ii<=CB_MAX_CHANNEL;ii++) {
-        sChannelTbl[ii].bValid = FALSE;
-    }
+    for (ii = 1; ii <= CB_MAX_CHANNEL; ii++)
+       sChannelTbl[ii].bValid = FALSE;
 
     switch (pDevice->byRFType) {
         case RF_AL2230:
@@ -464,43 +463,43 @@ void CHvInitChannelTable(void *pDeviceHandler)
     if ((pDevice->dwDiagRefCount != 0) ||
         (pDevice->b11hEable == TRUE)) {
         if (bMultiBand == TRUE) {
-            for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
-                sChannelTbl[ii+1].bValid = TRUE;
+               for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
+                       sChannelTbl[ii+1].bValid = TRUE;
                 //pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
                 //pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
-            }
-            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+               }
+               for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
                 //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
                 //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
-            }
+               }
         } else {
-            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
-                sChannelTbl[ii+1].bValid = TRUE;
+               for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
+                       sChannelTbl[ii+1].bValid = TRUE;
                 //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
                 //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
-            }
+               }
         }
     } else if (pDevice->byZoneType <= CCODE_MAX) {
         if (bMultiBand == TRUE) {
-            for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
-                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
-                    sChannelTbl[ii+1].bValid = TRUE;
+               for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
+                       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                               sChannelTbl[ii+1].bValid = TRUE;
                     //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
                     //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
-                }
-            }
+                       }
+               }
         } else {
-            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
-                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
-                    sChannelTbl[ii+1].bValid = TRUE;
+               for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
+                       if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                               sChannelTbl[ii+1].bValid = TRUE;
                     //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
                     //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
-                }
-            }
+                       }
+               }
         }
     }
     DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
-    for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
+    for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Channel[%d] is [%d]\n",sChannelTbl[ii].byChannelNumber,sChannelTbl[ii+1].bValid);
         /*if (pDevice->abyRegPwr[ii+1] == 0) {
             pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
index 91c2ffc6f1f05c5ba241ee6258e92af8880d7ea5..e7b3c1231825bec340d44b4d4e529700ff72a055 100644 (file)
 /*---------------------  Export Definitions -------------------------*/
 
 /*---------------------  Export Classes  ----------------------------*/
+
 typedef struct tagSChannelTblElement {
     BYTE    byChannelNumber;
     unsigned int    uFrequency;
     BOOL    bValid;
-}SChannelTblElement, *PSChannelTblElement;
+} SChannelTblElement, *PSChannelTblElement;
 
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
+
 BOOL    ChannelValid(unsigned int CountryCode, unsigned int ChannelNum);
 void    CHvInitChannelTable(void *pDeviceHandler);
 BYTE    CHbyGetChannelMapping(BYTE byChannelNumber);
 
-BOOL
-CHvChannelGetList (
-      unsigned int       uCountryCodeIdx,
-     PBYTE      pbyChannelTable
-    );
+BOOL CHvChannelGetList(unsigned int uCountryCodeIdx, PBYTE pbyChannelTable);
 
-#endif  /* _REGULATE_H_ */
+#endif  /* _CHANNEL_H_ */
index 8aab6718ff47377af7cef801ba3cc581587a8d19..5d8c5719419b09390530537daca8530eb06a56bf 100644 (file)
@@ -72,7 +72,7 @@ void ControlvWriteByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs,
 void ControlvReadByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs,
                        PBYTE pbyData)
 {
-       NTSTATUS        ntStatus;
+       int ntStatus;
        BYTE    byData1;
        ntStatus = CONTROLnsRequestIn(pDevice,
                                        MESSAGE_TYPE_READ,
index 146b450e13d09e21848d9e1797736c617acb849e..bbe610fd8b5a06608341424896a19ab05f9e6651 100644 (file)
 
 /*---------------------  Export Definitions -------------------------*/
 
+#define CONTROLnsRequestOut(Device, Request, Value, Index, Length, Buffer) \
+       PIPEnsControlOut(Device, Request, Value, Index, Length, Buffer)
 
-#define CONTROLnsRequestOut( Device,Request,Value,Index,Length,Buffer) \
-        PIPEnsControlOut( Device,Request,Value,Index,Length,Buffer)
-
-#define CONTROLnsRequestOutAsyn( Device,Request,Value,Index,Length,Buffer) \
-        PIPEnsControlOutAsyn( Device,Request,Value,Index,Length,Buffer)
-
-#define CONTROLnsRequestIn( Device,Request,Value,Index,Length,Buffer) \
-        PIPEnsControlIn( Device,Request,Value,Index,Length,Buffer)
+#define CONTROLnsRequestOutAsyn(Device, Request, Value, Index, Length, Buffer) \
+       PIPEnsControlOutAsyn(Device, Request, Value, Index, Length, Buffer)
 
+#define CONTROLnsRequestIn(Device, Request, Value, Index, Length, Buffer) \
+       PIPEnsControlIn(Device, Request, Value, Index, Length, Buffer)
 
 /*---------------------  Export Classes  ----------------------------*/
 
index 2e183ddbfd0e92123884676389a49eb29d6a2966..5c2719fa72f7a38796a54768e6ac6d1e330525f4 100644 (file)
@@ -72,7 +72,7 @@ void s_vResetCounter(PKnownNodeDB psNodeDBTable)
     BYTE            ii;
 
     // clear statistic counter for auto_rate
-    for(ii=0;ii<=MAX_RATE;ii++) {
+    for (ii = 0; ii <= MAX_RATE; ii++) {
         psNodeDBTable->uTxOk[ii] = 0;
         psNodeDBTable->uTxFail[ii] = 0;
     }
@@ -309,7 +309,6 @@ RATEvTxRateFallBack(
 {
 PSDevice        pDevice = (PSDevice) pDeviceHandler;
 PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
-#if 1  //mike fixed old: use packet lose ratio algorithm to control rate
 WORD            wIdxDownRate = 0;
 unsigned int            ii;
 BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
@@ -337,7 +336,7 @@ DWORD           dwTxDiff = 0;
         psNodeDBTable->uTimeCount = 0;
     }
 
-    for(ii=0;ii<MAX_RATE;ii++) {
+    for (ii = 0; ii < MAX_RATE; ii++) {
         if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
             if (bAutoRate[ii] == TRUE) {
                 wIdxUpRate = (WORD) ii;
@@ -347,7 +346,7 @@ DWORD           dwTxDiff = 0;
         }
     }
 
-    for(ii=0;ii<=psNodeDBTable->wTxDataRate;ii++) {
+    for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) {
         if ( (psNodeDBTable->uTxOk[ii] != 0) ||
              (psNodeDBTable->uTxFail[ii] != 0) ) {
             dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
@@ -362,7 +361,7 @@ DWORD           dwTxDiff = 0;
     dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
 
     wIdxDownRate = psNodeDBTable->wTxDataRate;
-    for(ii = psNodeDBTable->wTxDataRate; ii > 0;) {
+    for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
         ii--;
         if ( (dwThroughputTbl[ii] > dwThroughput) &&
              (bAutoRate[ii]==TRUE) ) {
@@ -389,66 +388,6 @@ DWORD           dwTxDiff = 0;
     s_vResetCounter(psNodeDBTable);
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
     return;
-#else  //mike fixed new: use differ-signal strength to control rate
-WORD            wIdxUpRate = 0;
-BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
-unsigned int            ii;
-long  ldBm;
-
-    if (pMgmt->eScanState != WMAC_NO_SCANNING) {
-        // Don't do Fallback when scanning Channel
-        return;
-    }
-
-    for(ii=0;ii<MAX_RATE;ii++) {
-        if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
-            if (bAutoRate[ii] == TRUE) {
-                wIdxUpRate = (WORD) ii;
-            }
-        } else {
-            bAutoRate[ii] = FALSE;
-        }
-    }
-
-         RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
-
-       if (ldBm > -55) {
-               if ( psNodeDBTable->wSuppRate & (0x0001<<RATE_54M) )  //11a/g
-               {
-                       psNodeDBTable->wTxDataRate = RATE_54M;
-               }
-               else{ //11b
-                       psNodeDBTable->wTxDataRate = RATE_11M;
-               }
-       }
-
-if (wIdxUpRate == RATE_54M ) {     //11a/g
-               if (ldBm > -56 )
-                       psNodeDBTable->wTxDataRate = RATE_54M;
-               else if (ldBm > -61 )
-                       psNodeDBTable->wTxDataRate = RATE_48M;
-               else if (ldBm > -66 )
-                       psNodeDBTable->wTxDataRate = RATE_36M;
-               else if (ldBm > -72 )
-                       psNodeDBTable->wTxDataRate = RATE_24M;
-               else if (ldBm > -80 )
-                       psNodeDBTable->wTxDataRate = RATE_5M;
-               else {
-                       psNodeDBTable->wTxDataRate = RATE_1M;
-                       //increasingVGA = TRUE;
-               }
-       }
-       else {  //11b
-               if (ldBm > -65 )
-                       psNodeDBTable->wTxDataRate = RATE_11M;
-               else if (ldBm > -75 )
-                       psNodeDBTable->wTxDataRate = RATE_5M;
-               else
-                       psNodeDBTable->wTxDataRate = RATE_1M;
-       }
-
-   return;
-#endif
 }
 
 /*+
index 07f794ec6db24dd5a07eaa76c0db57fc15b57ecb..767112b3c4a9569ac7b5239e3577486848e12c7e 100644 (file)
@@ -51,7 +51,6 @@
 
 #define MAX_INTERRUPT_SIZE              32
 
-
 #define RX_BLOCKS           64          // form 0x60 to 0xA0
 #define TX_BLOCKS           32          // from 0xA0 to 0xC0
 
@@ -63,8 +62,6 @@
 #define CB_RD_NUM           64          // default # of RD
 #define CB_TD_NUM           64          // default # of TD
 
-
-
 //
 // Bits in the RSR register
 //
@@ -87,7 +84,6 @@
 #define NEWRSR_BCNHITAID    0x02        // 0000 0010
 #define NEWRSR_BCNHITAID0   0x01        // 0000 0001
 
-
 //
 // Bits in the TSR register
 //
 #define TSR_ACKDATA         0x02        // 0000 0010
 #define TSR_VALID           0x01        // 0000 0001
 
-
 #define CB_PROTOCOL_RESERVED_SECTION    16
 
-
-
 // if retrys excess 15 times , tx will abort, and
 // if tx fifo underflow, tx will fail
 // we should try to resend it
 #define CB_MAX_TX_ABORT_RETRY   3
 
-
 #define FIFOCTL_AUTO_FB_1   0x1000 // 0001 0000 0000 0000
 #define FIFOCTL_AUTO_FB_0   0x0800 // 0000 1000 0000 0000
 #define FIFOCTL_GRPACK      0x0400 // 0000 0100 0000 0000
 #define FRAGCTL_STAFRAG     0x0001 // 0000 0000 0000 0001
 #define FRAGCTL_NONFRAG     0x0000 // 0000 0000 0000 0000
 
-
 //#define TYPE_AC0DMA     0
 //#define TYPE_TXDMA0     1
 #define TYPE_TXDMA0     0
 #define TYPE_RXDMA1     1
 #define TYPE_MAXRD      2
 
-
-
 // TD_INFO flags control bit
 #define TD_FLAGS_NETIF_SKB               0x01       // check if need release skb
 #define TD_FLAGS_PRIV_SKB                0x02       // check if called from private skb(hostap)
 
 /*---------------------  Export Types  ------------------------------*/
 
-
 //
 // RsvTime buffer header
 //
@@ -173,8 +161,9 @@ typedef struct tagSRrvTime_gRTS {
     WORD        wReserved;
     WORD        wTxRrvTime_b;
     WORD        wTxRrvTime_a;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRrvTime_gRTS, *PSRrvTime_gRTS;
+
 typedef const SRrvTime_gRTS *PCSRrvTime_gRTS;
 
 typedef struct tagSRrvTime_gCTS {
@@ -182,22 +171,25 @@ typedef struct tagSRrvTime_gCTS {
     WORD        wReserved;
     WORD        wTxRrvTime_b;
     WORD        wTxRrvTime_a;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRrvTime_gCTS, *PSRrvTime_gCTS;
+
 typedef const SRrvTime_gCTS *PCSRrvTime_gCTS;
 
 typedef struct tagSRrvTime_ab {
     WORD        wRTSTxRrvTime;
     WORD        wTxRrvTime;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRrvTime_ab, *PSRrvTime_ab;
+
 typedef const SRrvTime_ab *PCSRrvTime_ab;
 
 typedef struct tagSRrvTime_atim {
     WORD        wCTSTxRrvTime_ba;
     WORD        wTxRrvTime_a;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRrvTime_atim, *PSRrvTime_atim;
+
 typedef const SRrvTime_atim *PCSRrvTime_atim;
 
 //
@@ -208,8 +200,9 @@ typedef struct tagSRTSData {
     WORD    wDurationID;
     BYTE    abyRA[ETH_ALEN];
     BYTE    abyTA[ETH_ALEN];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRTSData, *PSRTSData;
+
 typedef const SRTSData *PCSRTSData;
 
 typedef struct tagSRTS_g {
@@ -224,11 +217,10 @@ typedef struct tagSRTS_g {
     WORD        wDuration_bb;
     WORD        wReserved;
     SRTSData    Data;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRTS_g, *PSRTS_g;
 typedef const SRTS_g *PCSRTS_g;
 
-
 typedef struct tagSRTS_g_FB {
     BYTE        bySignalField_b;
     BYTE        byServiceField_b;
@@ -245,10 +237,10 @@ typedef struct tagSRTS_g_FB {
     WORD        wRTSDuration_ba_f1;
     WORD        wRTSDuration_aa_f1;
     SRTSData    Data;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRTS_g_FB, *PSRTS_g_FB;
-typedef const SRTS_g_FB *PCSRTS_g_FB;
 
+typedef const SRTS_g_FB *PCSRTS_g_FB;
 
 typedef struct tagSRTS_ab {
     BYTE        bySignalField;
@@ -257,10 +249,10 @@ typedef struct tagSRTS_ab {
     WORD        wDuration;
     WORD        wReserved;
     SRTSData    Data;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRTS_ab, *PSRTS_ab;
-typedef const SRTS_ab *PCSRTS_ab;
 
+typedef const SRTS_ab *PCSRTS_ab;
 
 typedef struct tagSRTS_a_FB {
     BYTE        bySignalField;
@@ -271,8 +263,9 @@ typedef struct tagSRTS_a_FB {
     WORD        wRTSDuration_f0;
     WORD        wRTSDuration_f1;
     SRTSData    Data;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SRTS_a_FB, *PSRTS_a_FB;
+
 typedef const SRTS_a_FB *PCSRTS_a_FB;
 
 
@@ -284,7 +277,7 @@ typedef struct tagSCTSData {
     WORD    wDurationID;
     BYTE    abyRA[ETH_ALEN];
     WORD    wReserved;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SCTSData, *PSCTSData;
 
 typedef struct tagSCTS {
@@ -294,8 +287,9 @@ typedef struct tagSCTS {
     WORD        wDuration_ba;
     WORD        wReserved;
     SCTSData    Data;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SCTS, *PSCTS;
+
 typedef const SCTS *PCSCTS;
 
 typedef struct tagSCTS_FB {
@@ -307,10 +301,10 @@ typedef struct tagSCTS_FB {
     WORD        wCTSDuration_ba_f0;
     WORD        wCTSDuration_ba_f1;
     SCTSData    Data;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SCTS_FB, *PSCTS_FB;
-typedef const SCTS_FB *PCSCTS_FB;
 
+typedef const SCTS_FB *PCSCTS_FB;
 
 //
 // Tx FIFO header
@@ -321,14 +315,14 @@ typedef struct tagSTxBufHead {
     WORD    wTimeStamp;
     WORD    wFragCtl;
     WORD    wReserved;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 STxBufHead, *PSTxBufHead;
 typedef const STxBufHead *PCSTxBufHead;
 
 typedef struct tagSTxShortBufHead {
     WORD    wFIFOCtl;
     WORD    wTimeStamp;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 STxShortBufHead, *PSTxShortBufHead;
 typedef const STxShortBufHead *PCSTxShortBufHead;
 
@@ -346,8 +340,9 @@ typedef struct tagSTxDataHead_g {
     WORD    wDuration_a;
     WORD    wTimeStampOff_b;
     WORD    wTimeStampOff_a;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 STxDataHead_g, *PSTxDataHead_g;
+
 typedef const STxDataHead_g *PCSTxDataHead_g;
 
 typedef struct tagSTxDataHead_g_FB {
@@ -363,22 +358,20 @@ typedef struct tagSTxDataHead_g_FB {
     WORD    wDuration_a_f1;
     WORD    wTimeStampOff_b;
     WORD    wTimeStampOff_a;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 STxDataHead_g_FB, *PSTxDataHead_g_FB;
 typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB;
 
-
 typedef struct tagSTxDataHead_ab {
     BYTE    bySignalField;
     BYTE    byServiceField;
     WORD    wTransmitLength;
     WORD    wDuration;
     WORD    wTimeStampOff;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 STxDataHead_ab, *PSTxDataHead_ab;
 typedef const STxDataHead_ab *PCSTxDataHead_ab;
 
-
 typedef struct tagSTxDataHead_a_FB {
     BYTE    bySignalField;
     BYTE    byServiceField;
@@ -387,7 +380,7 @@ typedef struct tagSTxDataHead_a_FB {
     WORD    wTimeStampOff;
     WORD    wDuration_f0;
     WORD    wDuration_f1;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 STxDataHead_a_FB, *PSTxDataHead_a_FB;
 typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
 
@@ -398,23 +391,23 @@ typedef struct tagSMICHDRHead {
     DWORD   adwHDR0[4];
     DWORD   adwHDR1[4];
     DWORD   adwHDR2[4];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SMICHDRHead, *PSMICHDRHead;
+
 typedef const SMICHDRHead *PCSMICHDRHead;
 
 typedef struct tagSBEACONCtl {
     DWORD   BufReady : 1;
-    DWORD   TSF      : 15;
-    DWORD   BufLen   : 11;
+    DWORD   TSF : 15;
+    DWORD   BufLen : 11;
     DWORD   Reserved : 5;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SBEACONCtl;
 
-
 typedef struct tagSSecretKey {
     DWORD   dwLowDword;
     BYTE    byHighByte;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SSecretKey;
 
 typedef struct tagSKeyEntry {
@@ -426,7 +419,7 @@ typedef struct tagSKeyEntry {
     DWORD dwKey2[4];
     DWORD dwKey3[4];
     DWORD dwKey4[4];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SKeyEntry;
 /*---------------------  Export Macros ------------------------------*/
 
index ef9fd97d3ca79b504eaa2d5af245d6f1d89a31f4..b9852aa22c06b3faadaae68398386b060fff90c7 100644 (file)
@@ -71,9 +71,6 @@
 #define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 #endif
 
-//2007-0920-01<Add>by MikeLiu
-#ifndef SndEvt_ToAPI
-#define SndEvt_ToAPI
 //please copy below macro to driver_event.c for API
 #define RT_INSMOD_EVENT_FLAG                             0x0101
 #define RT_UPDEV_EVENT_FLAG                               0x0102
@@ -81,7 +78,6 @@
 #define RT_WPACONNECTED_EVENT_FLAG             0x0104
 #define RT_DOWNDEV_EVENT_FLAG                        0x0105
 #define RT_RMMOD_EVENT_FLAG                              0x0106
-#endif
 
 //
 // device specific
 #define MAX_MULTICAST_ADDRESS_NUM       32
 #define MULTICAST_ADDRESS_LIST_SIZE     (MAX_MULTICAST_ADDRESS_NUM * ETH_ALEN)
 
-
 //#define OP_MODE_INFRASTRUCTURE  0
 //#define OP_MODE_ADHOC           1
 //#define OP_MODE_AP              2
 #define KEYSEL_TKIP                     2
 #define KEYSEL_CCMP                     3
 
-
-
 #define AUTO_FB_NONE            0
 #define AUTO_FB_0               1
 #define AUTO_FB_1               2
 #define BB_VGA_LEVEL            4
 #define BB_VGA_CHANGE_THRESHOLD 3
 
-
-
 #ifndef RUN_AT
 #define RUN_AT(x)                       (jiffies+(x))
 #endif
 
 /*---------------------  Export Types  ------------------------------*/
 
-#define DBG_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
-#define PRINT_K(p, args...) {if (PRIVATE_Message) printk( p ,##args);}
+#define DBG_PRT(l, p, args...) { if (l <= msglevel) printk(p, ##args); }
+#define PRINT_K(p, args...) { if (PRIVATE_Message) printk(p, ##args); }
 
 typedef enum __device_msg_level {
-    MSG_LEVEL_ERR=0,            //Errors that will cause abnormal operation.
-    MSG_LEVEL_NOTICE=1,         //Some errors need users to be notified.
-    MSG_LEVEL_INFO=2,           //Normal message.
-    MSG_LEVEL_VERBOSE=3,        //Will report all trival errors.
-    MSG_LEVEL_DEBUG=4           //Only for debug purpose.
+       MSG_LEVEL_ERR = 0,            /* Errors causing abnormal operation */
+       MSG_LEVEL_NOTICE = 1,         /* Errors needing user notification */
+       MSG_LEVEL_INFO = 2,           /* Normal message. */
+       MSG_LEVEL_VERBOSE = 3,        /* Will report all trival errors. */
+       MSG_LEVEL_DEBUG = 4           /* Only for debug purpose. */
 } DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL;
 
 typedef enum __device_init_type {
-    DEVICE_INIT_COLD=0,         // cold init
-    DEVICE_INIT_RESET,          // reset init or Dx to D0 power remain init
-    DEVICE_INIT_DXPL            // Dx to D0 power lost init
+       DEVICE_INIT_COLD = 0,       /* cold init */
+       DEVICE_INIT_RESET,          /* reset init or Dx to D0 power remain */
+       DEVICE_INIT_DXPL            /* Dx to D0 power lost init */
 } DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE;
 
-
 //USB
 
 //
@@ -203,9 +193,6 @@ typedef enum _CONTEXT_TYPE {
     CONTEXT_MGMT_PACKET
 } CONTEXT_TYPE;
 
-
-
-
 // RCB (Receive Control Block)
 typedef struct _RCB
 {
@@ -219,7 +206,6 @@ typedef struct _RCB
 
 } RCB, *PRCB;
 
-
 // used to track bulk out irps
 typedef struct _USB_SEND_CONTEXT {
     void *pDevice;
@@ -233,7 +219,6 @@ typedef struct _USB_SEND_CONTEXT {
     unsigned char           Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS];
 } USB_SEND_CONTEXT, *PUSB_SEND_CONTEXT;
 
-
 /* structure got from configuration file as user-desired default settings */
 typedef struct _DEFAULT_CONFIG {
        signed int    ZoneType;
@@ -254,12 +239,10 @@ typedef struct {
     BOOL            bInUse;
 } INT_BUFFER, *PINT_BUFFER;
 
-
-
 //0:11A 1:11B 2:11G
 typedef enum _VIA_BB_TYPE
 {
-    BB_TYPE_11A=0,
+    BB_TYPE_11A = 0,
     BB_TYPE_11B,
     BB_TYPE_11G
 } VIA_BB_TYPE, *PVIA_BB_TYPE;
@@ -267,22 +250,18 @@ typedef enum _VIA_BB_TYPE
 //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
 typedef enum _VIA_PKT_TYPE
 {
-    PK_TYPE_11A=0,
+    PK_TYPE_11A = 0,
     PK_TYPE_11B,
     PK_TYPE_11GB,
     PK_TYPE_11GA
 } VIA_PKT_TYPE, *PVIA_PKT_TYPE;
 
-
-
-
 //++ NDIS related
 
 #define NDIS_STATUS     int
-#define NTSTATUS        int
 
 typedef enum __DEVICE_NDIS_STATUS {
-    STATUS_SUCCESS=0,
+    STATUS_SUCCESS = 0,
     STATUS_FAILURE,
     STATUS_RESOURCES,
     STATUS_PENDING,
@@ -810,17 +789,12 @@ typedef struct __device_info {
     // command timer
     struct timer_list       sTimerCommand;
 
-//2007-0115-01<Add>by MikeLiu
-#ifdef TxInSleep
      struct timer_list       sTimerTxData;
      unsigned long                       nTxDataTimeCout;
      BOOL  fTxDataInSleep;
      BOOL  IsTxDataTrigger;
-#endif
 
-#ifdef WPA_SM_Transtatus
     BOOL  fWPA_Authened;           //is WPA/WPA-PSK or WPA2/WPA2-PSK authen??
-#endif
     BYTE            byReAssocCount;   //mike add:re-association retry times!
     BYTE            byLinkWaitCount;
 
index c816901882ad1057f49f12e2c6df3cc341b42395..a0b82169dad3c5fdaf45a5caea96e2104abbdfb8 100644 (file)
@@ -77,25 +77,20 @@ struct _version {
 //Max: 2378=2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
 #define PKT_BUF_SZ          2390
 
-
 #define MAX_UINTS           8
 #define OPTION_DEFAULT      { [0 ... MAX_UINTS-1] = -1}
 
-
-
-typedef enum  _chip_type{
-    VT3184=1
+typedef enum  _chip_type {
+    VT3184 = 1
 } CHIP_TYPE, *PCHIP_TYPE;
 
-
-
 #ifdef VIAWET_DEBUG
 #define ASSERT(x) { \
     if (!(x)) { \
-        printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\
+       printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x, \
         __FUNCTION__, __LINE__);\
-        *(int*) 0=0;\
-    }\
+       *(int *) 0 = 0;         \
+    } \
 }
 #define DBG_PORT80(value)                   outb(value, 0x80)
 #else
@@ -103,5 +98,4 @@ typedef enum  _chip_type{
 #define DBG_PORT80(value)
 #endif
 
-
 #endif
index 9afe76cacef58d0f93e6a8047e48d04ecf7281b9..5e88349d3b95b064f602cb9b7fc2ad5dc3012586 100644 (file)
@@ -80,7 +80,7 @@ static
 void
 s_vGetDASA(
       PBYTE pbyRxBufferAddr,
-     PUINT pcbHeaderSize,
+     unsigned int *pcbHeaderSize,
      PSEthernetHeader psEthHeader
     );
 
@@ -92,7 +92,7 @@ s_vProcessRxMACHeader (
       unsigned int cbPacketSize,
       BOOL bIsWEP,
       BOOL bExtIV,
-     PUINT pcbHeadSize
+     unsigned int *pcbHeadSize
     );
 
 static BOOL s_bAPModeRxCtl(
@@ -167,7 +167,7 @@ s_vProcessRxMACHeader (
       unsigned int cbPacketSize,
       BOOL bIsWEP,
       BOOL bExtIV,
-     PUINT pcbHeadSize
+     unsigned int *pcbHeadSize
     )
 {
     PBYTE           pbyRxBuffer;
@@ -195,10 +195,9 @@ s_vProcessRxMACHeader (
     };
 
     pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize);
-    if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+    if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
         cbHeaderSize += 6;
-    }
-    else if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+    } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
         cbHeaderSize += 6;
         pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
         if ((*pwType!= TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
@@ -262,7 +261,7 @@ static
 void
 s_vGetDASA (
       PBYTE pbyRxBufferAddr,
-     PUINT pcbHeaderSize,
+     unsigned int *pcbHeaderSize,
      PSEthernetHeader psEthHeader
     )
 {
@@ -343,9 +342,7 @@ RXbBulkInProcessData (
     PBYTE           pbyRxSts;
     PBYTE           pbyRxRate;
     PBYTE           pbySQ;
-#ifdef Calcu_LinkQual
     PBYTE           pby3SQ;
-#endif
     unsigned int            cbHeaderSize;
     PSKeyItem       pKey = NULL;
     WORD            wRxTSC15_0 = 0;
@@ -416,7 +413,6 @@ RXbBulkInProcessData (
     wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4;
 
     pqwTSFTime = (PQWORD) (pbyDAddress + 8 + wPLCPwithPadding);
-#ifdef Calcu_LinkQual
   if(pDevice->byBBType == BB_TYPE_11G)  {
       pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12;
       pbySQ = pby3SQ;
@@ -425,9 +421,6 @@ RXbBulkInProcessData (
    pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
    pby3SQ = pbySQ;
   }
-#else
-    pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
-#endif
     pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9;
     pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10;
     pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11;
@@ -453,21 +446,22 @@ RXbBulkInProcessData (
     if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
        if (pMgmt->sNodeDBTable[0].bActive) {
-         if(IS_ETH_ADDRESS_EQUAL (pMgmt->abyCurrBSSID, pMACHeader->abyAddr2) ) {
+        if (!compare_ether_addr(pMgmt->abyCurrBSSID, pMACHeader->abyAddr2)) {
            if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
                   pMgmt->sNodeDBTable[0].uInActiveCount = 0;
            }
        }
     }
 
-    if (!IS_MULTICAST_ADDRESS(pMACHeader->abyAddr1) && !IS_BROADCAST_ADDRESS(pMACHeader->abyAddr1)) {
+    if (!is_multicast_ether_addr(pMACHeader->abyAddr1) && !is_broadcast_ether_addr(pMACHeader->abyAddr1)) {
         if ( WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) pbyFrame) ) {
             pDevice->s802_11Counter.FrameDuplicateCount++;
             return FALSE;
         }
 
-        if ( !IS_ETH_ADDRESS_EQUAL (pDevice->abyCurrentNetAddr, pMACHeader->abyAddr1) ) {
-            return FALSE;
+       if (compare_ether_addr(pDevice->abyCurrentNetAddr,
+                              pMACHeader->abyAddr1)) {
+               return FALSE;
         }
     }
 
@@ -475,7 +469,8 @@ RXbBulkInProcessData (
     // Use for TKIP MIC
     s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
 
-    if (IS_ETH_ADDRESS_EQUAL((PBYTE)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
+    if (!compare_ether_addr((PBYTE)&(pDevice->sRxEthHeader.abySrcAddr[0]),
+                           pDevice->abyCurrentNetAddr))
         return FALSE;
 
     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
@@ -568,8 +563,8 @@ RXbBulkInProcessData (
     //
     // RX OK
     //
-    //remove the CRC length
-    FrameSize -= U_CRC_LEN;
+    /* remove the FCS/CRC length */
+    FrameSize -= ETH_FCS_LEN;
 
     if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address
         (IS_FRAGMENT_PKT((pbyFrame)))
@@ -758,10 +753,11 @@ RXbBulkInProcessData (
         pMgmt->pCurrBSS->byRSSIStatCnt++;
         pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT;
         pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm;
-        for(ii=0;ii<RSSI_STAT_COUNT;ii++) {
-            if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) {
-            pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
-            }
+       for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
+               if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) {
+                       pMgmt->pCurrBSS->ldBmMAX =
+                               max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
+               }
         }
     }
 */
@@ -1448,7 +1444,7 @@ static BOOL s_bAPModeRxData (
     if (FrameSize > CB_MAX_BUF_SIZE)
         return FALSE;
     // check DA
-    if(IS_MULTICAST_ADDRESS((PBYTE)(skb->data+cbHeaderOffset))) {
+    if (is_multicast_ether_addr((PBYTE)(skb->data+cbHeaderOffset))) {
        if (pMgmt->sNodeDBTable[0].bPSEnable) {
 
            skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
@@ -1523,7 +1519,7 @@ static BOOL s_bAPModeRxData (
 void RXvWorkItem(void *Context)
 {
     PSDevice pDevice = (PSDevice) Context;
-    NTSTATUS        ntStatus;
+    int ntStatus;
     PRCB            pRCB=NULL;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
index e1f96d7086f7eb7466a523c83f534a2075abd3e5..ebb9c99df70c91503db373de904b8f95fcb805ab 100644 (file)
@@ -848,7 +848,7 @@ FIRMWAREbCheckVersion(
      PSDevice pDevice
     )
 {
-    NTSTATUS                ntStatus;
+       int ntStatus;
 
     ntStatus = CONTROLnsRequestIn(pDevice,
                                     MESSAGE_TYPE_READ,
index 89f5b18bdf1f6bc5ac93f305ff82cc4275298641..c95833ac58e024f06b8683a8920689099a34bb79 100644 (file)
@@ -82,7 +82,7 @@ static int msglevel = MSG_LEVEL_INFO;
 void INTvWorkItem(void *Context)
 {
        PSDevice pDevice = (PSDevice) Context;
-       NTSTATUS ntStatus;
+       int ntStatus;
 
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n");
 
@@ -92,10 +92,9 @@ void INTvWorkItem(void *Context)
        spin_unlock_irq(&pDevice->lock);
 }
 
-NTSTATUS
-INTnsProcessData(PSDevice pDevice)
+int INTnsProcessData(PSDevice pDevice)
 {
-       NTSTATUS        status = STATUS_SUCCESS;
+       int status = STATUS_SUCCESS;
        PSINTData       pINTData;
        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
        struct net_device_stats *pStats = &pDevice->stats;
index cdf355130de718898a7fd4fdc29e2827b84b4791..3176c8d08d6ded41790077c13b4f8d7022a9a0b7 100644 (file)
@@ -57,7 +57,7 @@ typedef struct tagSINTData {
     BYTE    byACKFail;
     BYTE    byFCSErr;
     BYTE    abySW[2];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SINTData, *PSINTData;
 
 
@@ -68,10 +68,6 @@ SINTData, *PSINTData;
 /*---------------------  Export Functions  --------------------------*/
 
 void INTvWorkItem(void *Context);
-
-NTSTATUS
-INTnsProcessData(
-      PSDevice pDevice
-    );
+int INTnsProcessData(PSDevice pDevice);
 
 #endif /* __INT_H__ */
index fbba1d53e49daa4eb30f7771126136de215cb804..1ce39a4ba2f4861ea36c9e38b2d67fdbed13771b 100644 (file)
@@ -70,10 +70,10 @@ typedef enum tagWMAC_CMD {
 } WMAC_CMD, *PWMAC_CMD;
 
 typedef enum tagWZONETYPE {
-  ZoneType_USA=0,
-  ZoneType_Japan=1,
-  ZoneType_Europe=2
-}WZONETYPE;
+  ZoneType_USA = 0,
+  ZoneType_Japan = 1,
+  ZoneType_Europe = 2
+} WZONETYPE;
 
 #define ADHOC  0
 #define INFRA  1
@@ -83,9 +83,9 @@ typedef enum tagWZONETYPE {
 #define ADHOC_STARTED     1
 #define ADHOC_JOINTED     2
 
-#define PHY80211a          0
-#define PHY80211b       1
-#define PHY80211g       2
+#define PHY80211a 0
+#define PHY80211b 1
+#define PHY80211g 2
 
 #define SSID_ID                0
 #define SSID_MAXLEN            32
@@ -143,7 +143,6 @@ typedef struct tagSCmdZoneTypeSet {
 
 } SCmdZoneTypeSet, *PSCmdZoneTypeSet;
 
-#ifdef WPA_SM_Transtatus
 typedef struct tagSWPAResult {
          char  ifname[100];
        u8 proto;
@@ -151,7 +150,6 @@ typedef struct tagSWPAResult {
        u8 eap_type;
          BOOL authenticated;
 } SWPAResult, *PSWPAResult;
-#endif
 
 typedef struct tagSCmdStartAP {
 
index 19a84b66b0975d5631ef108139efdae343267b2d..d532618639bc5f3c32965f89d9737957ab4c186d 100644 (file)
@@ -48,9 +48,7 @@
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 static int          msglevel                =MSG_LEVEL_INFO;
 
-#ifdef WPA_SM_Transtatus
     SWPAResult wpa_Result;
-#endif
 
 /*---------------------  Static Functions  --------------------------*/
 
@@ -232,10 +230,10 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
             pDevice->bEncryptionEnable = FALSE;
             pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
             spin_lock_irq(&pDevice->lock);
-            for(uu=0;uu<MAX_KEY_TABLE;uu++)
-                MACvDisableKeyEntry(pDevice,uu);
+           for (uu = 0; uu < MAX_KEY_TABLE; uu++)
+               MACvDisableKeyEntry(pDevice, uu);
             spin_unlock_irq(&pDevice->lock);
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable. \n");
+           DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable.\n");
             break;
         }
 
@@ -656,7 +654,6 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         pReq->wResult = 0;
         break;
 
-#ifdef WPA_SM_Transtatus
     case 0xFF:
         memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
            wpa_Result.proto = 0;
@@ -676,7 +673,6 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 //DavidWang
 
 if(wpa_Result.authenticated==TRUE) {
-   #ifdef SndEvt_ToAPI
    {
      union iwreq_data      wrqu;
 
@@ -687,7 +683,6 @@ if(wpa_Result.authenticated==TRUE) {
      wrqu.data.length =pItemSSID->len;
      wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
    }
-   #endif
          pDevice->fWPA_Authened = TRUE;           //is successful peer to wpa_Result.authenticated?
 }
 
@@ -700,7 +695,6 @@ if(wpa_Result.authenticated==TRUE) {
 
        pReq->wResult = 0;
         break;
-#endif
 
     default:
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n");
index da03edcbacb0c79407638552ba5bee5a557ae328..959c8868f6e2add1f86531ae68e96e5b58eb83fa 100644 (file)
 
 /*---------------------  Export Definitions -------------------------*/
 
-
 #define WPA_IE_LEN 64
 
-
 //WPA related
 /*
 typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
@@ -54,7 +52,7 @@ enum {
        VIAWGET_SET_DROP_UNENCRYPT = 7,
        VIAWGET_SET_DEAUTHENTICATE = 8,
        VIAWGET_SET_ASSOCIATE = 9,
-       VIAWGET_SET_DISASSOCIATE= 10
+       VIAWGET_SET_DISASSOCIATE = 10
 };
 
 
@@ -76,8 +74,6 @@ typedef struct viawget_wpa_header {
        u16 resp_ie_len;
 } viawget_wpa_header;
 
-
-
 struct viawget_wpa_param {
        u32 cmd;
        u8 addr[6];
@@ -86,43 +82,37 @@ struct viawget_wpa_param {
                        u8 len;
                        u8 data[0];
                } generic_elem;
-
                struct {
-               u8 bssid[6];
+                       u8 bssid[6];
                        u8 ssid[32];
                        u8 ssid_len;
-               u8 *wpa_ie;
-               u16 wpa_ie_len;
-               int pairwise_suite;
-               int group_suite;
-               int key_mgmt_suite;
-               int auth_alg;
-               int mode;
-                u8 roam_dbm;  //DavidWang
+                       u8 *wpa_ie;
+                       u16 wpa_ie_len;
+                       int pairwise_suite;
+                       int group_suite;
+                       int key_mgmt_suite;
+                       int auth_alg;
+                       int mode;
+                       u8 roam_dbm;
                } wpa_associate;
-
                struct {
-               int alg_name;
-               u16 key_index;
-               u16 set_tx;
-               u8 *seq;
-               u16 seq_len;
-               u8 *key;
-               u16 key_len;
+                       int alg_name;
+                       u16 key_index;
+                       u16 set_tx;
+                       u8 *seq;
+                       u16 seq_len;
+                       u8 *key;
+                       u16 key_len;
                } wpa_key;
-
                struct {
                        u8 ssid_len;
                        u8 ssid[32];
                } scan_req;
-
                struct {
                        u16 scan_count;
                        u8 *buf;
                } scan_results;
-
        } u;
-
 };
 
 #pragma pack(1)
@@ -142,15 +132,12 @@ struct viawget_scan_result {
        int maxrate;
 };
 
-
 /*---------------------  Export Classes  ----------------------------*/
 
 /*---------------------  Export Variables  --------------------------*/
 
-
 /*---------------------  Export Types  ------------------------------*/
 
-
 /*---------------------  Export Functions  --------------------------*/
 
 #endif /* __IOWPA_H__ */
index fa40522d4a9aaa14207aff1983f9bf2107c939bc..016b8e7766f39820ac7883b950f4cf4d7631acc5 100644 (file)
@@ -83,31 +83,9 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
        long ldBm;
 
        pDevice->wstats.status = pDevice->eOPMode;
-       #ifdef Calcu_LinkQual
-        #if 0
-         if(pDevice->byBBType == BB_TYPE_11B) {
-            if(pDevice->byCurrSQ > 120)
-                  pDevice->scStatistic.LinkQuality = 100;
-            else
-                pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
-           }
-         else if(pDevice->byBBType == BB_TYPE_11G) {
-                if(pDevice->byCurrSQ < 20)
-                  pDevice->scStatistic.LinkQuality = 100;
-              else if(pDevice->byCurrSQ >96)
-                  pDevice->scStatistic.LinkQuality  = 0;
-              else
-                  pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
-          }
-          if(pDevice->bLinkPass !=TRUE)
-              pDevice->scStatistic.LinkQuality = 0;
-         #endif
           if(pDevice->scStatistic.LinkQuality > 100)
               pDevice->scStatistic.LinkQuality = 100;
                pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
-       #else
-       pDevice->wstats.qual.qual = pDevice->byCurrSQ;
-       #endif
        RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
        pDevice->wstats.qual.level = ldBm;
        //pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
@@ -133,18 +111,9 @@ static int iwctl_commit(struct net_device *dev,
                              void *wrq,
                              char *extra)
 {
-//2008-0409-02, <Mark> by Einsn Liu
-/*
-#ifdef Safe_Close
-  PSDevice             pDevice = (PSDevice)netdev_priv(dev);
-  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
-        return -EINVAL;
-#endif
-*/
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT\n");
 
        return 0;
-
 }
 
 /*
@@ -209,9 +178,7 @@ if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
 
        spin_lock_irq(&pDevice->lock);
 
-#ifdef update_BssList
        BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
-#endif
 
 //mike add: active scan OR passive scan OR desire_ssid scan
  if(wrq->length == sizeof(struct iw_scan_req)) {
@@ -273,14 +240,7 @@ int iwctl_giwscan(struct net_device *dev,
        long ldBm;
        char buf[MAX_WPA_IE_LEN * 2 + 30];
 
-//2008-0409-02, <Mark> by Einsn Liu
-/*
-#ifdef Safe_Close
-  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
-        return -EINVAL;
-#endif
-*/
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
 
     if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
         // In scanning..
@@ -349,39 +309,6 @@ int iwctl_giwscan(struct net_device *dev,
                        }
                        iwe.u.qual.updated=7;
 
-//2008-0409-01, <Mark> by Einsn Liu
-/*
-//2008-0220-03, <Modify>  by Einsn Liu
-       if(pDevice->bLinkPass== TRUE && IS_ETH_ADDRESS_EQUAL(pBSS->abyBSSID, pMgmt->abyCurrBSSID)){
-       #ifdef Calcu_LinkQual
-        #if 0
-         if(pDevice->byBBType == BB_TYPE_11B) {
-            if(pDevice->byCurrSQ > 120)
-                  pDevice->scStatistic.LinkQuality = 100;
-            else
-                pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
-           }
-         else if(pDevice->byBBType == BB_TYPE_11G) {
-                if(pDevice->byCurrSQ < 20)
-                  pDevice->scStatistic.LinkQuality = 100;
-              else if(pDevice->byCurrSQ >96)
-                  pDevice->scStatistic.LinkQuality  = 0;
-              else
-                  pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
-          }
-          if(pDevice->bLinkPass !=TRUE)
-              pDevice->scStatistic.LinkQuality = 0;
-         #endif
-          if(pDevice->scStatistic.LinkQuality > 100)
-              pDevice->scStatistic.LinkQuality = 100;
-              iwe.u.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
-       #else
-       iwe.u.qual.qual = pDevice->byCurrSQ;
-       #endif
-               }else {
-               iwe.u.qual.qual = 0;
-               }
-*/
                  current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
                //ADD encryption
             memset(&iwe, 0, sizeof(iwe));
@@ -634,16 +561,8 @@ int iwctl_giwrange(struct net_device *dev,
        struct iw_range *range = (struct iw_range *) extra;
        int             i,k;
     BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
-//2008-0409-02, <Mark> by Einsn Liu
-/*
- #ifdef Safe_Close
-  PSDevice             pDevice = (PSDevice)netdev_priv(dev);
-  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
-        return -EINVAL;
-#endif
- */
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
        if (wrq->pointer) {
                wrq->length = sizeof(struct iw_range);
                memset(range, 0, sizeof(struct iw_range));
@@ -653,23 +572,19 @@ int iwctl_giwrange(struct net_device *dev,
                // Should be based on cap_rid.country to give only
                //  what the current card support
                k = 0;
-               for(i = 0; i < 14; i++) {
+               for (i = 0; i < 14; i++) {
                        range->freq[k].i = i + 1; // List index
                        range->freq[k].m = frequency_list[i] * 100000;
                        range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
                }
                range->num_frequency = k;
                // Hum... Should put the right values there
-            #ifdef Calcu_LinkQual
                  range->max_qual.qual = 100;
-            #else
-               range->max_qual.qual = 255;
-            #endif
                range->max_qual.level = 0;
                range->max_qual.noise = 0;
                range->sensitivity = 255;
 
-               for(i = 0 ; i < 13 ; i++) {
+               for (i = 0 ; i < 13 ; i++) {
                        range->bitrate[i] = abySupportedRates[i] * 500000;
                        if(range->bitrate[i] == 0)
                                break;
@@ -761,7 +676,7 @@ int iwctl_siwap(struct net_device *dev,
                memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
 
        //mike :add
-        if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
+        if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
             (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
              PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
                return rc;
@@ -772,7 +687,8 @@ int iwctl_siwap(struct net_device *dev,
                unsigned int ii, uSameBssidNum = 0;
                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                      if (pMgmt->sBSSList[ii].bActive &&
-                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID,pMgmt->abyDesireBSSID)) {
+                        !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
+                                            pMgmt->abyDesireBSSID)) {
                         uSameBssidNum++;
                      }
                   }
@@ -957,7 +873,8 @@ int iwctl_siwessid(struct net_device *dev,
                      //         by means of judging if there are two same BSSID exist in list ?
                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                      if (pMgmt->sBSSList[ii].bActive &&
-                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+                        !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
+                                            pCurr->abyBSSID)) {
                         uSameBssidNum++;
                      }
                   }
@@ -1057,7 +974,7 @@ int iwctl_siwrate(struct net_device *dev,
                u8      normvalue = (u8) (wrq->value/500000);
 
                // Check if rate is valid
-               for(i = 0 ; i < 13 ; i++) {
+               for (i = 0 ; i < 13 ; i++) {
                        if(normvalue == abySupportedRates[i]) {
                                brate = i;
                                break;
@@ -1067,7 +984,7 @@ int iwctl_siwrate(struct net_device *dev,
        // -1 designed the max rate (mostly auto mode)
        if(wrq->value == -1) {
                // Get the highest available rate
-               for(i = 0 ; i < 13 ; i++) {
+               for (i = 0 ; i < 13 ; i++) {
                        if(abySupportedRates[i] == 0)
                                break;
                }
@@ -1405,8 +1322,8 @@ int iwctl_siwencode(struct net_device *dev,
         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
             spin_lock_irq(&pDevice->lock);
-            for(uu=0;uu<MAX_KEY_TABLE;uu++)
-                MACvDisableKeyEntry(pDevice,uu);
+           for (uu = 0; uu < MAX_KEY_TABLE; uu++)
+               MACvDisableKeyEntry(pDevice, uu);
             spin_unlock_irq(&pDevice->lock);
         }
        }
@@ -1926,26 +1843,6 @@ param->u.wpa_key.key = (u8 *)key_array;
 param->u.wpa_key.seq = (u8 *)seq;
 param->u.wpa_key.seq_len = seq_len;
 
-#if 0
-printk("param->u.wpa_key.alg_name =%d\n",param->u.wpa_key.alg_name);
-printk("param->addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
-             param->addr[0],param->addr[1],param->addr[2],
-             param->addr[3],param->addr[4],param->addr[5]);
-printk("param->u.wpa_key.set_tx =%d\n",param->u.wpa_key.set_tx);
-printk("param->u.wpa_key.key_index =%d\n",param->u.wpa_key.key_index);
-printk("param->u.wpa_key.key_len =%d\n",param->u.wpa_key.key_len);
-printk("param->u.wpa_key.key =");
-for(ii=0;ii<param->u.wpa_key.key_len;ii++)
-       printk("%02x:",param->u.wpa_key.key[ii]);
-         printk("\n");
-printk("param->u.wpa_key.seq_len =%d\n",param->u.wpa_key.seq_len);
-printk("param->u.wpa_key.seq =");
-for(ii=0;ii<param->u.wpa_key.seq_len;ii++)
-       printk("%02x:",param->u.wpa_key.seq[ii]);
-         printk("\n");
-
-printk("...........\n");
-#endif
 //****set if current action is Network Manager count??
 //****this method is so foolish,but there is no other way???
 if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
index df9a4cf3baac605d54c3d0d3c0567513fb69930b..d601e9220219c35fa177f2a864f40076d7eef973 100644 (file)
 
 /*---------------------  Export Definitions -------------------------*/
 
-
 /*---------------------  Export Classes  ----------------------------*/
 
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
 
-struct iw_statistics *iwctl_get_wireless_stats (struct net_device *dev);
-
+struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev);
 
 int iwctl_siwap(struct net_device *dev,
              struct iw_request_info *info,
index b0890c181e7dcb9d235f8e94ba48a55f680bb852..d181a2f66266bd6b3d62d17e4d14a065e807341f 100644 (file)
@@ -174,7 +174,7 @@ BOOL KeybGetKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex,
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
         if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             if (dwKeyIndex == 0xFFFFFFFF) {
                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
@@ -245,7 +245,7 @@ BOOL KeybSetKey(
             j = i;
         }
         if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             // found table already exist
             if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                 // Pairwise key
@@ -402,7 +402,7 @@ BOOL KeybRemoveKey(
     int     i;
     BOOL    bReturnValue = FALSE;
 
-    if (IS_BROADCAST_ADDRESS(pbyBSSID)) {
+    if (is_broadcast_ether_addr(pbyBSSID)) {
         // dealte all key
         if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
             for (i=0;i<MAX_KEY_TABLE;i++) {
@@ -427,7 +427,7 @@ BOOL KeybRemoveKey(
     } else {
         for (i=0;i<MAX_KEY_TABLE;i++) {
             if ( (pTable->KeyTable[i].bInUse == TRUE) &&
-                 IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+                !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
 
                 if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                     pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
@@ -483,11 +483,11 @@ BOOL KeybRemoveAllKey(
 
     for (i=0;i<MAX_KEY_TABLE;i++) {
         if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
-            for(u=0;u<MAX_GROUP_KEY;u++) {
-                pTable->KeyTable[i].GroupKey[u].bKeyValid = FALSE;
-            }
+           for (u = 0; u < MAX_GROUP_KEY; u++)
+               pTable->KeyTable[i].GroupKey[u].bKeyValid = FALSE;
+
             pTable->KeyTable[i].dwGTKeyIndex = 0;
             s_vCheckKeyTableValid(pDevice, pTable);
             return (TRUE);
@@ -531,19 +531,13 @@ void KeyvRemoveWEPKey(
     return;
 }
 
-void KeyvRemoveAllWEPKey(
-    void *pDeviceHandler,
-    PSKeyManagement pTable
-    )
+void KeyvRemoveAllWEPKey(void *pDeviceHandler, PSKeyManagement pTable)
 {
-    PSDevice    pDevice = (PSDevice) pDeviceHandler;
-
-    int i;
-
-    for(i=0;i<MAX_GROUP_KEY;i++) {
-        KeyvRemoveWEPKey(pDevice,pTable, i);
-    }
+       PSDevice pDevice = (PSDevice) pDeviceHandler;
+       int i;
 
+       for (i = 0; i < MAX_GROUP_KEY; i++)
+               KeyvRemoveWEPKey(pDevice, pTable, i);
 }
 
 /*
@@ -567,7 +561,7 @@ BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType,
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
         if ((pTable->KeyTable[i].bInUse == TRUE) &&
-            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
 
             if (dwKeyType == PAIRWISE_KEY) {
 
index 0ab3db025f33322edd3204ace770609d4879635c..33698edde4fb443562fe3bb887580a8b5735c01c 100644 (file)
@@ -306,8 +306,8 @@ BYTE            pbyData[24];
     pbyData[5] = (BYTE)(dwData2>>8);
     pbyData[6] = (BYTE)(dwData2>>16);
     pbyData[7] = (BYTE)(dwData2>>24);
-    for(ii=8;ii<24;ii++)
-        pbyData[ii] = *pbyKey++;
+    for (ii = 8; ii < 24; ii++)
+       pbyData[ii] = *pbyKey++;
 
     CONTROLnsRequestOut(pDevice,
                         MESSAGE_TYPE_SETKEY,
index 775c70928ec7a7dc7f8df485f75c35273c8701a0..491ff5ecd04b3be8a2b91f04b947f5d2befaf013 100644 (file)
 
 /*---------------------  Export Functions  --------------------------*/
 
-void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx);
+void MACvSetMultiAddrByHash(PSDevice pDevice, BYTE byHashIdx);
 void MACvWriteMultiAddr(PSDevice pDevice, unsigned int uByteIdx, BYTE byData);
-BOOL MACbShutdown(PSDevice pDevice);;
-void MACvSetBBType(PSDevice pDevice,BYTE byType);
-void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData);
+BOOL MACbShutdown(PSDevice pDevice);
+void MACvSetBBType(PSDevice pDevice, BYTE byType);
+void MACvSetMISCFifo(PSDevice pDevice, WORD wOffset, DWORD dwData);
 void MACvDisableKeyEntry(PSDevice pDevice, unsigned int uEntryIdx);
 void MACvSetKeyEntry(PSDevice pDevice, WORD wKeyCtl, unsigned int uEntryIdx,
                     unsigned int uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey);
index 098b0455e3255c6029d1092c0a77172902210b46..c528ef0f8ed4c81872728f8c659f021ecc26c1b2 100644 (file)
@@ -366,7 +366,7 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
     BYTE            byAntenna;
     unsigned int            ii;
     CMD_CARD_INIT   sInitCmd;
-    NTSTATUS        ntStatus = STATUS_SUCCESS;
+    int ntStatus = STATUS_SUCCESS;
     RSP_CARD_INIT   sInitRsp;
     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
     BYTE            byTmp;
@@ -407,8 +407,8 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
 
     sInitCmd.byInitClass = (BYTE)InitType;
     sInitCmd.bExistSWNetAddr = (BYTE) pDevice->bExistSWNetAddr;
-    for(ii=0;ii<6;ii++)
-        sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
+    for (ii = 0; ii < 6; ii++)
+       sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
     sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit;
     sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit;
 
@@ -487,10 +487,10 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
           if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
                (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&&
             (pDevice->byOriginalZonetype == ZoneType_USA)) {
-           for(ii=11;ii<14;ii++) {
-                pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
-              pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
-           }
+               for (ii = 11; ii < 14; ii++) {
+                       pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
+                       pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
+               }
          }
 
         //{{ RobertYu: 20041124
@@ -718,33 +718,32 @@ static BOOL device_release_WPADEV(PSDevice pDevice)
 
 static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
 {
- PSDevice  pDevice = usb_get_intfdata(intf);
- struct net_device *dev = pDevice->dev;
+       PSDevice device = usb_get_intfdata(intf);
 
- printk("VNTWUSB Suspend Start======>\n");
-if(dev != NULL) {
-  if(pDevice->flags & DEVICE_FLAGS_OPENED)
-     device_close(dev);
-}
+       if (!device || !device->dev)
+               return -ENODEV;
 
- usb_put_dev(interface_to_usbdev(intf));
- return 0;
+       if (device->flags & DEVICE_FLAGS_OPENED)
+               device_close(device->dev);
+
+       usb_put_dev(interface_to_usbdev(intf));
+
+       return 0;
 }
 
 static int vt6656_resume(struct usb_interface *intf)
 {
- PSDevice  pDevice = usb_get_intfdata(intf);
- struct net_device *dev = pDevice->dev;
-
- printk("VNTWUSB Resume Start======>\n");
- if(dev != NULL) {
-  usb_get_dev(interface_to_usbdev(intf));
-  if(!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
-    if(device_open(dev)!=0)
-        printk("VNTWUSB Resume Start======>open fail\n");
-   }
- }
- return 0;
+       PSDevice device = usb_get_intfdata(intf);
+
+       if (!device || !device->dev)
+               return -ENODEV;
+
+       usb_get_dev(interface_to_usbdev(intf));
+
+       if (!(device->flags & DEVICE_FLAGS_OPENED))
+               device_open(device->dev);
+
+       return 0;
 }
 
 #endif /* CONFIG_PM */
@@ -758,93 +757,75 @@ static const struct net_device_ops device_netdev_ops = {
     .ndo_set_multicast_list = device_set_multi,
 };
 
-
 static int __devinit
 vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
        struct usb_device *udev = interface_to_usbdev(intf);
-    int         rc = 0;
-    struct net_device *netdev = NULL;
-    PSDevice    pDevice = NULL;
-
+       int rc = 0;
+       struct net_device *netdev = NULL;
+       PSDevice pDevice = NULL;
 
-    printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
-    printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
+       printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+       printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
 
-  udev = usb_get_dev(udev);
-
-    netdev = alloc_etherdev(sizeof(DEVICE_INFO));
-
-    if (netdev == NULL) {
-        printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
-        kfree(pDevice);
-           goto err_nomem;
-    }
+       udev = usb_get_dev(udev);
+       netdev = alloc_etherdev(sizeof(DEVICE_INFO));
 
-    pDevice = netdev_priv(netdev);
-    memset(pDevice, 0, sizeof(DEVICE_INFO));
+       if (!netdev) {
+               printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
+               kfree(pDevice);
+               goto err_nomem;
+       }
 
-    pDevice->dev = netdev;
-    pDevice->usb = udev;
+       pDevice = netdev_priv(netdev);
+       memset(pDevice, 0, sizeof(DEVICE_INFO));
 
-    // Set initial settings
-    device_set_options(pDevice);
-    spin_lock_init(&pDevice->lock);
+       pDevice->dev = netdev;
+       pDevice->usb = udev;
 
-    pDevice->tx_80211 = device_dma0_tx_80211;
-    pDevice->sMgmtObj.pAdapter = (void *)pDevice;
+       device_set_options(pDevice);
+       spin_lock_init(&pDevice->lock);
 
-    netdev->netdev_ops         = &device_netdev_ops;
+       pDevice->tx_80211 = device_dma0_tx_80211;
+       pDevice->sMgmtObj.pAdapter = (void *) pDevice;
 
-       netdev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
+       netdev->netdev_ops = &device_netdev_ops;
+       netdev->wireless_handlers =
+               (struct iw_handler_def *) &iwctl_handler_def;
 
-   //2008-0623-01<Remark>by MikeLiu
-  //2007-0821-01<Add>by MikeLiu
-         usb_set_intfdata(intf, pDevice);
+       usb_set_intfdata(intf, pDevice);
        SET_NETDEV_DEV(netdev, &intf->dev);
-    memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
-    rc = register_netdev(netdev);
-    if (rc != 0) {
-        printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
+       memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
+       rc = register_netdev(netdev);
+       if (rc) {
+               printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
                free_netdev(netdev);
-        kfree(pDevice);
-        return -ENODEV;
-    }
-
-//2008-07-21-01<Add>by MikeLiu
-//register wpadev
-#if 0
-   if(wpa_set_wpadev(pDevice, 1)!=0) {
-     printk("Fail to Register WPADEV?\n");
-        unregister_netdev(pDevice->dev);
-        free_netdev(netdev);
-        kfree(pDevice);
-   }
-#endif
-         usb_device_reset(pDevice);
+               kfree(pDevice);
+               return -ENODEV;
+       }
 
-#ifdef SndEvt_ToAPI
-{
-  union iwreq_data      wrqu;
-  memset(&wrqu, 0, sizeof(wrqu));
-  wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
-  wrqu.data.length =IFNAMSIZ;
-  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pDevice->dev->name);
-}
-#endif
+       usb_device_reset(pDevice);
+
+       {
+               union iwreq_data wrqu;
+               memset(&wrqu, 0, sizeof(wrqu));
+               wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
+               wrqu.data.length = IFNAMSIZ;
+               wireless_send_event(pDevice->dev,
+                                   IWEVCUSTOM,
+                                   &wrqu,
+                                   pDevice->dev->name);
+       }
 
        return 0;
 
-
 err_nomem:
- //2008-0922-01<Add>by MikeLiu, decrease usb counter.
-    usb_put_dev(udev);
+       usb_put_dev(udev);
 
-    return -ENOMEM;
+       return -ENOMEM;
 }
 
-
 static void device_free_tx_bufs(PSDevice pDevice)
 {
     PUSB_SEND_CONTEXT pTxContext;
@@ -1065,7 +1046,6 @@ BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
 static int  device_open(struct net_device *dev) {
     PSDevice    pDevice=(PSDevice) netdev_priv(dev);
 
-#ifdef WPA_SM_Transtatus
      extern SWPAResult wpa_Result;
      memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
      wpa_Result.proto = 0;
@@ -1073,7 +1053,6 @@ static int  device_open(struct net_device *dev) {
      wpa_Result.eap_type = 0;
      wpa_Result.authenticated = FALSE;
      pDevice->fWPA_Authened = FALSE;
-#endif
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
 
@@ -1172,14 +1151,12 @@ static int  device_open(struct net_device *dev) {
     netif_stop_queue(pDevice->dev);
     pDevice->flags |= DEVICE_FLAGS_OPENED;
 
-#ifdef SndEvt_ToAPI
 {
   union iwreq_data      wrqu;
   memset(&wrqu, 0, sizeof(wrqu));
   wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
   wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
 }
-#endif
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
     return 0;
@@ -1211,14 +1188,12 @@ static int  device_close(struct net_device *dev) {
     if (pDevice == NULL)
         return -ENODEV;
 
-#ifdef SndEvt_ToAPI
 {
   union iwreq_data      wrqu;
   memset(&wrqu, 0, sizeof(wrqu));
   wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
   wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
 }
-#endif
 
 //2007-1121-02<Add>by EinsnLiu
     if (pDevice->bLinkPass) {
@@ -1234,10 +1209,10 @@ device_release_WPADEV(pDevice);
         pMgmt->bShareKeyAlgorithm = FALSE;
         pDevice->bEncryptionEnable = FALSE;
         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-            spin_lock_irq(&pDevice->lock);
-            for(uu=0;uu<MAX_KEY_TABLE;uu++)
+       spin_lock_irq(&pDevice->lock);
+       for (uu = 0; uu < MAX_KEY_TABLE; uu++)
                 MACvDisableKeyEntry(pDevice,uu);
-            spin_unlock_irq(&pDevice->lock);
+       spin_unlock_irq(&pDevice->lock);
 
     if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
         MACbShutdown(pDevice);
@@ -1250,10 +1225,7 @@ device_release_WPADEV(pDevice);
     del_timer(&pDevice->sTimerCommand);
     del_timer(&pMgmt->sTimerSecondCallback);
 
-//2007-0115-02<Add>by MikeLiu
-#ifdef TxInSleep
     del_timer(&pDevice->sTimerTxData);
-#endif
 
     if (pDevice->bDiversityRegCtlON) {
         del_timer(&pDevice->TimerSQ3Tmax1);
@@ -1290,112 +1262,81 @@ device_release_WPADEV(pDevice);
     return 0;
 }
 
-
 static void __devexit vt6656_disconnect(struct usb_interface *intf)
 {
+       PSDevice device = usb_get_intfdata(intf);
 
-       PSDevice  pDevice = usb_get_intfdata(intf);
+       if (!device)
+               return;
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect1.. \n");
-    if (pDevice == NULL)
-        return;
-
-#ifdef SndEvt_ToAPI
-{
-  union iwreq_data      wrqu;
-  memset(&wrqu, 0, sizeof(wrqu));
-  wrqu.data.flags = RT_RMMOD_EVENT_FLAG;
-  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
-}
-#endif
+       {
+               union iwreq_data req;
+               memset(&req, 0, sizeof(req));
+               req.data.flags = RT_RMMOD_EVENT_FLAG;
+               wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
+       }
 
-//2008-0714-01<Add>by MikeLiu
-device_release_WPADEV(pDevice);
+       device_release_WPADEV(device);
 
        usb_set_intfdata(intf, NULL);
-//2008-0922-01<Add>by MikeLiu, decrease usb counter.
-     usb_put_dev(interface_to_usbdev(intf));
+       usb_put_dev(interface_to_usbdev(intf));
 
-    pDevice->flags |= DEVICE_FLAGS_UNPLUG;
-    if (pDevice->dev != NULL) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unregister_netdev..\n");
-        unregister_netdev(pDevice->dev);
+       device->flags |= DEVICE_FLAGS_UNPLUG;
 
-//2008-07-21-01<Add>by MikeLiu
-//unregister wpadev
-   if(wpa_set_wpadev(pDevice, 0)!=0)
-     printk("unregister wpadev fail?\n");
-
-        free_netdev(pDevice->dev);
-    }
-
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect3.. \n");
+       if (device->dev) {
+               unregister_netdev(device->dev);
+               wpa_set_wpadev(device, 0);
+               free_netdev(device->dev);
+       }
 }
 
+static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
+{
+       PSDevice pDevice = netdev_priv(dev);
 
+       spin_lock_irq(&pDevice->lock);
 
+       if (unlikely(pDevice->bStopTx0Pkt))
+               dev_kfree_skb_irq(skb);
+       else
+               vDMA0_tx_80211(pDevice, skb);
 
-static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
-    PSDevice        pDevice=netdev_priv(dev);
-    PBYTE           pbMPDU;
-    unsigned int            cbMPDULen = 0;
-
-
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
-    spin_lock_irq(&pDevice->lock);
-
-    if (pDevice->bStopTx0Pkt == TRUE) {
-        dev_kfree_skb_irq(skb);
-        spin_unlock_irq(&pDevice->lock);
-        return 0;
-    };
-
-
-    cbMPDULen = skb->len;
-    pbMPDU = skb->data;
-
-    vDMA0_tx_80211(pDevice, skb);
-
-    spin_unlock_irq(&pDevice->lock);
-
-    return 0;
+       spin_unlock_irq(&pDevice->lock);
 
+       return NETDEV_TX_OK;
 }
 
+static int device_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       PSDevice pDevice = netdev_priv(dev);
+       struct net_device_stats *stats = &pDevice->stats;
 
-static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
-    PSDevice    pDevice=netdev_priv(dev);
-    struct net_device_stats* pStats = &pDevice->stats;
-
+       spin_lock_irq(&pDevice->lock);
 
-    spin_lock_irq(&pDevice->lock);
+       netif_stop_queue(dev);
 
-    netif_stop_queue(pDevice->dev);
+       if (!pDevice->bLinkPass) {
+               dev_kfree_skb_irq(skb);
+               goto out;
+       }
 
-    if (pDevice->bLinkPass == FALSE) {
-        dev_kfree_skb_irq(skb);
-        spin_unlock_irq(&pDevice->lock);
-        return 0;
-    }
-    if (pDevice->bStopDataPkt == TRUE) {
-        dev_kfree_skb_irq(skb);
-        pStats->tx_dropped++;
-        spin_unlock_irq(&pDevice->lock);
-        return 0;
-    }
+       if (pDevice->bStopDataPkt) {
+               dev_kfree_skb_irq(skb);
+               stats->tx_dropped++;
+               goto out;
+       }
 
-    if(nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) !=0) {  //mike add:xmit fail!
-         if (netif_queue_stopped(pDevice->dev))
-              netif_wake_queue(pDevice->dev);
-    }
+       if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb)) {
+               if (netif_queue_stopped(dev))
+                       netif_wake_queue(dev);
+       }
 
-    spin_unlock_irq(&pDevice->lock);
+out:
+       spin_unlock_irq(&pDevice->lock);
 
-    return 0;
+       return NETDEV_TX_OK;
 }
 
-
-
 static unsigned const ethernet_polynomial = 0x04c11db7U;
 static inline u32 ether_crc(int length, unsigned char *data)
 {
@@ -1447,12 +1388,12 @@ static int Config_FileGetParameter(unsigned char *string,
        return FALSE;
 
 //check if current config line is marked by "#" ??
-for(ii=1;;ii++) {
-  if(memcmp(start_p-ii,"\n",1)==0)
-      break;
-  if(memcmp(start_p-ii,"#",1)==0)
-      return FALSE;
-}
+    for (ii = 1; ; ii++) {
+       if (memcmp(start_p - ii, "\n", 1) == 0)
+               break;
+       if (memcmp(start_p - ii, "#", 1) == 0)
+               return FALSE;
+    }
 
 //find target string end point
      end_p = kstrstr(start_p,"\n");
@@ -1585,7 +1526,6 @@ static int Read_config_file(PSDevice pDevice) {
  }
 }
 
-#if 1
 //get other parameter
   {
        memset(tmpbuffer,0,sizeof(tmpbuffer));
@@ -1598,7 +1538,6 @@ static int Read_config_file(PSDevice pDevice) {
         pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
        }
   }
-#endif
 
   kfree(buffer);
   return result;
index b694fc86d74001b55d424c9214994a0c0ddfec29..8a6ee72f4409e6a8f1d499650f1b91fbf8428a18 100644 (file)
@@ -347,10 +347,9 @@ void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
     if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl))
         pStatistic->dwRsrRxFragment++;
 
-    if (cbFrameLength < MIN_PACKET_LEN + 4) {
+    if (cbFrameLength < ETH_ZLEN + 4) {
         pStatistic->dwRsrRunt++;
-    }
-    else if (cbFrameLength == MIN_PACKET_LEN + 4) {
+    } else if (cbFrameLength == ETH_ZLEN + 4) {
         pStatistic->dwRsrRxFrmLen64++;
     }
     else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) {
@@ -364,17 +363,14 @@ void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
     }
     else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) {
         pStatistic->dwRsrRxFrmLen512_1023++;
-    }
-    else if ((1024 <= cbFrameLength) && (cbFrameLength <= MAX_PACKET_LEN + 4)) {
+    } else if ((1024 <= cbFrameLength) &&
+              (cbFrameLength <= ETH_FRAME_LEN + 4)) {
         pStatistic->dwRsrRxFrmLen1024_1518++;
-    } else if (cbFrameLength > MAX_PACKET_LEN + 4) {
+    } else if (cbFrameLength > ETH_FRAME_LEN + 4) {
         pStatistic->dwRsrLong++;
     }
-
 }
 
-
-
 /*
  * Description: Update Rx Statistic Counter and copy Rx buffer
  *
@@ -467,12 +463,10 @@ STAvUpdateTDStatCounter (
     }
     if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
 
-#ifdef Calcu_LinkQual
    if (byRetyCnt < 2)
         pStatistic->TxNoRetryOkCount ++;
    else
         pStatistic->TxRetryOkCount ++;
-#endif
 
         pStatistic->ullTsrOK++;
         pStatistic->CustomStat.ullTsrAllOK++;
@@ -493,9 +487,7 @@ STAvUpdateTDStatCounter (
     }
     else {
 
-#ifdef Calcu_LinkQual
         pStatistic->TxFailCount ++;
-#endif
 
         pStatistic->dwTsrErr++;
         if (byTSR & TSR_RETRYTMO)
@@ -591,10 +583,7 @@ STAvClear802_11Counter(PSDot11Counters p802_11Counter)
  *
  */
 
-void
-STAvUpdateUSBCounter(PSUSBCounter pUsbCounter,
-                     NTSTATUS ntStatus
-                     )
+void STAvUpdateUSBCounter(PSUSBCounter pUsbCounter, int ntStatus)
 {
 
 //    if ( ntStatus == USBD_STATUS_CRC ) {
@@ -602,5 +591,3 @@ STAvUpdateUSBCounter(PSUSBCounter pUsbCounter,
 //    }
 
 }
-
-
index 0455ec9d327d28bdbbce116999d92ffe02a78ffd..a89cca0c5ecf2d16d2a4d95b7f6de240bf09fe07 100644 (file)
@@ -356,7 +356,6 @@ typedef struct tagSStatCounter {
 
     SCustomCounters CustomStat;
 
-   #ifdef Calcu_LinkQual
        //Tx count:
   unsigned long TxNoRetryOkCount;         /* success tx no retry ! */
   unsigned long TxRetryOkCount;           /* success tx but retry ! */
@@ -367,12 +366,9 @@ typedef struct tagSStatCounter {
       //statistic
     unsigned long SignalStren;
     unsigned long LinkQuality;
-   #endif
 
 } SStatCounter, *PSStatCounter;
 
-#define NTSTATUS        int
-
 /*---------------------  Export Classes  ----------------------------*/
 
 /*---------------------  Export Variables  --------------------------*/
@@ -381,7 +377,9 @@ typedef struct tagSStatCounter {
 
 void STAvClearAllCounter(PSStatCounter pStatistic);
 
-void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr1);
+void STAvUpdateIsrStatCounter(PSStatCounter pStatistic,
+                             BYTE byIsr0,
+                             BYTE byIsr1);
 
 void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
                             BYTE byRSR, BYTE byNewRSR, BYTE byRxSts,
@@ -393,14 +391,8 @@ void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic,
                               BYTE byRxRate, PBYTE pbyBuffer,
                               unsigned int cbFrameLength);
 
-void
-STAvUpdateTDStatCounter (
-    PSStatCounter   pStatistic,
-    BYTE            byPktNum,
-    BYTE            byRate,
-    BYTE            byTSR
-    );
-
+void STAvUpdateTDStatCounter(PSStatCounter pStatistic, BYTE byPktNum,
+                            BYTE byRate, BYTE byTSR);
 
 void
 STAvUpdate802_11Counter(
@@ -413,11 +405,6 @@ STAvUpdate802_11Counter(
     );
 
 void STAvClear802_11Counter(PSDot11Counters p802_11Counter);
-
-void
-STAvUpdateUSBCounter(
-    PSUSBCounter    pUsbCounter,
-    NTSTATUS        ntStatus
-    );
+void STAvUpdateUSBCounter(PSUSBCounter pUsbCounter, int ntStatus);
 
 #endif /* __MIB_H__ */
index 671a8cf33e23e38df2f3575c1a1efec112810520..4d419814f27f63c60cf386b442ad988b14de0ff1 100644 (file)
@@ -74,7 +74,7 @@ static DWORD s_dwGetUINT32 (BYTE * p)
 {
        DWORD res = 0;
        unsigned int i;
-       for(i=0; i<4; i++ )
+       for (i = 0; i < 4; i++)
                res |= (*p++) << (8*i);
        return res;
 }
@@ -83,7 +83,7 @@ static void s_vPutUINT32(BYTE *p, DWORD val)
 // Convert from DWORD to BYTE[] in a portable way
 {
        unsigned int i;
-       for(i=0; i<4; i++ ) {
+       for (i = 0; i < 4; i++) {
                *p++ = (BYTE) (val & 0xff);
                val >>= 8;
        }
index 3ab60928ef352e490012318eaaeeed465b30f062..81351f506232339188d54468792329756de93932 100644 (file)
@@ -49,8 +49,8 @@ void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR);
 /*---------------------  Export Macros ------------------------------*/
 
 // Rotation functions on 32 bit values
-#define ROL32( A, n ) \
- ( ((A) << (n)) | ( ((A)>>(32-(n)))  & ( (1UL << (n)) - 1 ) ) )
-#define ROR32( A, n ) ROL32( (A), 32-(n) )
+#define ROL32(A, n) \
+ (((A) << (n)) | (((A)>>(32-(n)))  & ((1UL << (n)) - 1)))
+#define ROR32(A, n) ROL32((A), 32-(n))
 
 #endif /* __MICHAEL_H__ */
index 766c5be6fd22e51d82324d0ccf93bc3c5d1d8011..4d7d4e014d008e9fd46ed7230fd69ef325e98877 100644 (file)
@@ -19,7 +19,7 @@
  *
  * File: power.c
  *
- * Purpose: Handles 802.11 power managment  functions
+ * Purpose: Handles 802.11 power management  functions
  *
  * Author: Lyndon Chen
  *
@@ -290,17 +290,11 @@ BOOL PSbSendNullPacket(void *hDeviceContext)
         return FALSE;
     }
 
-//2007-0115-03<Add>by MikeLiu
-#ifdef TxInSleep
      if ((pDevice->bEnablePSMode == FALSE) &&
          (pDevice->fTxDataInSleep == FALSE)){
         return FALSE;
     }
-#else
-    if (pDevice->bEnablePSMode == FALSE) {
-        return FALSE;
-    }
-#endif
+
     memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN);
     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
     pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
index 50792bb8c978c4c71d8c876068bad73b3b3f4a38..41bffe528b44c363512854306c1e79710f131ccb 100644 (file)
@@ -18,7 +18,7 @@
  *
  * File: power.h
  *
- * Purpose: Handles 802.11 power managment  functions
+ * Purpose: Handles 802.11 power management  functions
  *
  * Author: Lyndon Chen
  *
index d4f8b94132b9f5575a534723877747704ba0a5e2..f5ba8fd7f816a1e77c510b942132437d8150c539 100644 (file)
@@ -64,11 +64,7 @@ extern const BYTE RFaby11aChannelIndex[200];
 /*---------------------  Export Functions  --------------------------*/
 
 BOOL IFRFbWriteEmbeded(PSDevice pDevice, DWORD dwData);
-BOOL RFbSetPower (
-      PSDevice  pDevice,
-      unsigned int      uRATE,
-      unsigned int      uCH
-    );
+BOOL RFbSetPower(PSDevice pDevice, unsigned int uRATE, unsigned int uCH);
 
 BOOL RFbRawSetPower(
       PSDevice  pDevice,
@@ -76,17 +72,8 @@ BOOL RFbRawSetPower(
       unsigned int      uRATE
     );
 
-void
-RFvRSSITodBm (
-      PSDevice pDevice,
-      BYTE     byCurrRSSI,
-    long *    pldBm
-    );
-
-void
-RFbRFTableDownload (
-      PSDevice pDevice
-    );
+void RFvRSSITodBm(PSDevice pDevice, BYTE byCurrRSSI, long *pldBm);
+void RFbRFTableDownload(PSDevice pDevice);
 
 BOOL s_bVT3226D0_11bLoCurrentAdjust(
       PSDevice    pDevice,
index ac842dd13a6804a2e19ed0b69939834d4951c689..fccf7e98eb68d17e6b7c586b12bb92443f4e0d2f 100644 (file)
@@ -152,7 +152,7 @@ typedef struct _CMD_CHANGE_BBTYPE
 
 /*---------------------  Export Macros -------------------------*/
 
-#define EXCH_WORD(w)        ( (WORD)((WORD)(w)<<8) | (WORD)((WORD)(w)>>8) )
+#define EXCH_WORD(w) ((WORD)((WORD)(w)<<8) | (WORD)((WORD)(w)>>8))
 
 /*---------------------  Export Variables  --------------------------*/
 
index 3e7e56649a5fc7e67216f4495ad60e1844e882d3..deca2137d921e2b4185a92fdc1f5d2cf44b1a0b9 100644 (file)
 #include "rf.h"
 #include "datarate.h"
 #include "usbpipe.h"
-
-#ifdef WPA_SM_Transtatus
 #include "iocmd.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -304,10 +301,9 @@ s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLe
 {
     PSStatCounter           pStatistic=&(pDevice->scStatistic);
 
-
-    if (IS_BROADCAST_ADDRESS(pbyDestAddr))
+    if (is_broadcast_ether_addr(pbyDestAddr))
         pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
-    else if (IS_MULTICAST_ADDRESS(pbyDestAddr))
+    else if (is_multicast_ether_addr(pbyDestAddr))
         pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
     else
         pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
@@ -319,9 +315,6 @@ s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLe
           ETH_ALEN);
 }
 
-
-
-
 static
 void
 s_vFillTxKey (
@@ -1473,7 +1466,7 @@ s_bPacketToWirelessUsb(
     memset(pTxBufHead, 0, sizeof(TX_BUFFER));
 
     // Get pkt type
-    if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
+    if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
         if (pDevice->dwDiagRefCount == 0) {
             cb802_1_H_len = 8;
         } else {
@@ -1492,17 +1485,16 @@ s_bPacketToWirelessUsb(
         bNeedACK = FALSE;
         pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
     } else { //if (pDevice->dwDiagRefCount != 0) {
-        if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
-            (pDevice->eOPMode == OP_MODE_AP)) {
-            if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
-                IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
-                bNeedACK = FALSE;
-                pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
-            }
-            else {
-                bNeedACK = TRUE;
-                pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
-            }
+       if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+           (pDevice->eOPMode == OP_MODE_AP)) {
+               if (is_multicast_ether_addr(psEthHeader->abyDstAddr)) {
+                       bNeedACK = FALSE;
+                       pTxBufHead->wFIFOCtl =
+                               pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
+               } else {
+                       bNeedACK = TRUE;
+                       pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+               }
         }
         else {
             // MSDUs in Infra mode always need ACK
@@ -1708,7 +1700,7 @@ s_bPacketToWirelessUsb(
     }
 
     // 802.1H
-    if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
+    if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
         if (pDevice->dwDiagRefCount == 0) {
             if ( (psEthHeader->wType == TYPE_PKT_IPX) ||
                  (psEthHeader->wType == cpu_to_le16(0xF380))) {
@@ -2037,9 +2029,7 @@ CMD_STATUS csMgmt_xmit(
     pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
     pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
 
-
-    if (IS_MULTICAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0])) ||
-        IS_BROADCAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0]))) {
+    if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
         bNeedACK = FALSE;
     }
     else {
@@ -2446,9 +2436,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb) {
     pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
     pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
 
-
-    if (IS_MULTICAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0])) ||
-        IS_BROADCAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0]))) {
+    if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
         bNeedACK = FALSE;
         if (pDevice->bEnableHostWEP) {
             uNodeIndex = 0;
@@ -2741,14 +2729,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb) {
  * Return Value: NULL
  */
 
-
-
-NTSTATUS
-nsDMA_tx_packet(
-      PSDevice pDevice,
-      unsigned int    uDMAIdx,
-      struct sk_buff *skb
-    )
+int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)
 {
     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
     unsigned int BytesToWrite = 0, uHeaderLen = 0;
@@ -2770,9 +2751,6 @@ nsDMA_tx_packet(
     unsigned int            status;
     WORD            wKeepRate = pDevice->wCurrentRate;
     struct net_device_stats* pStats = &pDevice->stats;
-//#ifdef WPA_SM_Transtatus
-  //  extern SWPAResult wpa_Result;
-//#endif
      BOOL            bTxeapol_key = FALSE;
 
 
@@ -2783,7 +2761,7 @@ nsDMA_tx_packet(
             return 0;
         }
 
-        if (IS_MULTICAST_ADDRESS((PBYTE)(skb->data))) {
+       if (is_multicast_ether_addr((PBYTE)(skb->data))) {
             uNodeIndex = 0;
             bNodeExist = TRUE;
             if (pMgmt->sNodeDBTable[0].bPSEnable) {
@@ -2975,7 +2953,7 @@ nsDMA_tx_packet(
     else {
         if (pDevice->eOPMode == OP_MODE_ADHOC) {
             // Adhoc Tx rate decided from node DB
-            if (IS_MULTICAST_ADDRESS(&(pDevice->sTxEthHeader.abyDstAddr[0]))) {
+           if (is_multicast_ether_addr(pDevice->sTxEthHeader.abyDstAddr)) {
                 // Multicast use highest data rate
                 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
                 // preamble type
@@ -3071,28 +3049,12 @@ nsDMA_tx_packet(
         }
         else {
 
-#if 0
-            if((pDevice->fWPA_Authened == FALSE) &&
-               ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)||(pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK))){
-                  dev_kfree_skb_irq(skb);
-                  pStats->tx_dropped++;
-                  return STATUS_FAILURE;
-            }
-               else if (pTransmitKey == NULL) {
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
-                dev_kfree_skb_irq(skb);
-                pStats->tx_dropped++;
-                return STATUS_FAILURE;
-            }
-#else
             if (pTransmitKey == NULL) {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
                 dev_kfree_skb_irq(skb);
                 pStats->tx_dropped++;
                 return STATUS_FAILURE;
             }
-#endif
-
         }
     }
 
@@ -3261,7 +3223,8 @@ bRelayPacketSend (
     if (pDevice->wCurrentRate <= RATE_11M)
         byPktType = PK_TYPE_11B;
 
-    BytesToWrite = uDataLen + U_CRC_LEN;
+    BytesToWrite = uDataLen + ETH_FCS_LEN;
+
     // Convert the packet to an usb frame and copy into our buffer
     // and send the irp.
 
index f90de42d7abef545837ac90e0ca44998ee9bde1e..f99acf1d8eb9cf10f53d9754d38b66590ace87aa 100644 (file)
@@ -683,9 +683,9 @@ bPacketToWirelessUsb(
     );
 
 void vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb);
-NTSTATUS nsDMA_tx_packet(PSDevice  pDevice,
-                        unsigned int uDMAIdx,
-                        struct sk_buff *skb);
+int nsDMA_tx_packet(PSDevice pDevice,
+                   unsigned int uDMAIdx,
+                   struct sk_buff *skb);
 CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
 CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
 BOOL bRelayPacketSend(PSDevice pDevice, PBYTE pbySkbData,
index d63586d5cdb2a2ba14bd30097bb25fa3cd61ddd2..be87020d53237fa8071c5d76b172062a24424bb4 100644 (file)
 //
 // constants
 //
-#define U_CRC_LEN           4           //
 #define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1)
                                         // Ethernet address string length
-
-#define MIN_DATA_LEN        46          // min data length
-#define MAX_DATA_LEN        1500        // max data length
-
-#define MIN_PACKET_LEN      (MIN_DATA_LEN + ETH_HLEN)
-                                        // 60
-                                        // min total packet length (tx)
-#define MAX_PACKET_LEN      (MAX_DATA_LEN + ETH_HLEN)
-                                        // 1514
-                                        // max total packet length (tx)
-
-#define MAX_LOOKAHEAD_SIZE  MAX_PACKET_LEN
-
 #define U_MULTI_ADDR_LEN    8           // multicast address length
 
-
 #ifdef __BIG_ENDIAN
 
 #define TYPE_PKT_IP         0x0800      //
@@ -168,7 +153,7 @@ typedef struct tagSEthernetHeader {
     BYTE    abyDstAddr[ETH_ALEN];
     BYTE    abySrcAddr[ETH_ALEN];
     WORD    wType;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 SEthernetHeader, *PSEthernetHeader;
 
 
@@ -179,7 +164,7 @@ typedef struct tagS802_3Header {
     BYTE    abyDstAddr[ETH_ALEN];
     BYTE    abySrcAddr[ETH_ALEN];
     WORD    wLen;
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 S802_3Header, *PS802_3Header;
 
 //
@@ -193,30 +178,10 @@ typedef struct tagS802_11Header {
     BYTE    abyAddr3[ETH_ALEN];
     WORD    wSeqCtl;
     BYTE    abyAddr4[ETH_ALEN];
-}__attribute__ ((__packed__))
+} __attribute__ ((__packed__))
 S802_11Header, *PS802_11Header;
 
 /*---------------------  Export Macros ------------------------------*/
-// Frame type macro
-
-#define IS_MULTICAST_ADDRESS(pbyEtherAddr)          \
-    ((*(PBYTE)(pbyEtherAddr) & 0x01) == 1)
-
-#define IS_BROADCAST_ADDRESS(pbyEtherAddr) (        \
-    (*(PDWORD)(pbyEtherAddr) == 0xFFFFFFFFL) &&     \
-    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0xFFFF) \
-)
-
-#define IS_NULL_ADDRESS(pbyEtherAddr) (             \
-    (*(PDWORD)(pbyEtherAddr) == 0L) &&              \
-    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0)      \
-)
-
-#define IS_ETH_ADDRESS_EQUAL(pbyAddr1, pbyAddr2) (  \
-    (*(PDWORD)(pbyAddr1) == *(PDWORD)(pbyAddr2)) && \
-    (*(PWORD)((PBYTE)(pbyAddr1) + 4) ==             \
-    *(PWORD)((PBYTE)(pbyAddr2) + 4))                \
-)
 
 /*---------------------  Export Classes  ----------------------------*/
 
index f83af5913aa6268eefd271616c1957aac91cdd03..a6bd533f9577dc405a680535194ead57d617dd02 100644 (file)
@@ -129,8 +129,6 @@ const BYTE TKIP_Sbox_Upper[256] = {
 //STKIPKeyManagement  sTKIPKeyTable[MAX_TKIP_KEY];
 
 /*---------------------  Static Functions  --------------------------*/
-unsigned int tkip_sbox(unsigned int index);
-unsigned int rotr1(unsigned int a);
 
 /*---------------------  Export Variables  --------------------------*/
 
@@ -139,7 +137,7 @@ unsigned int rotr1(unsigned int a);
 /* Returns a 16 bit value from a 64K entry table. The Table */
 /* is synthesized from two 256 entry byte wide tables.      */
 /************************************************************/
-unsigned int tkip_sbox(unsigned int index)
+static unsigned int tkip_sbox(unsigned int index)
 {
     unsigned int index_low;
     unsigned int index_high;
@@ -155,7 +153,7 @@ unsigned int tkip_sbox(unsigned int index)
 };
 
 
-unsigned int rotr1(unsigned int a)
+static unsigned int rotr1(unsigned int a)
 {
     unsigned int b;
 
index c27f9858e2e9720b851f0d394e837dbd56201e35..8e9450ef39971187cda8d9fdaede1f5ff679201b 100644 (file)
 
 /******* Common definitions and typedefs ***********************************/
 
-//2007-0115-05<Add>by MikeLiu
-#ifndef TxInSleep
-#define TxInSleep
-#endif
-
-//DavidWang
-
-//2007-0814-01<Add>by MikeLiu
-#ifndef Safe_Close
-#define Safe_Close
-#endif
-
-//2008-0131-02<Add>by MikeLiu
-#ifndef Adhoc_STA
-#define Adhoc_STA
-#endif
-
 typedef int             BOOL;
 
 #if !defined(TRUE)
@@ -57,19 +40,6 @@ typedef int             BOOL;
 #define FALSE           0
 #endif
 
-//2007-0809-01<Add>by MikeLiu
-#ifndef  update_BssList
-#define update_BssList
-#endif
-
-#ifndef WPA_SM_Transtatus
-#define WPA_SM_Transtatus
-#endif
-
-#ifndef Calcu_LinkQual
-#define Calcu_LinkQual
-#endif
-
 /****** Simple typedefs  ***************************************************/
 
 typedef unsigned char   BYTE;           //  8-bit
@@ -94,7 +64,6 @@ typedef unsigned long   ULONG_PTR;      // 32-bit
 typedef unsigned long   DWORD_PTR;      // 32-bit
 
 // boolean pointer
-typedef unsigned int *   PUINT;
 
 typedef BYTE *           PBYTE;
 
index fd2355e34fb015cdc252a69f3aa9ec76c0e85b72..a32785cb9d18af8acc6433b3f50d2b3b41ef6756 100644 (file)
@@ -107,10 +107,7 @@ s_nsControlInUsbIoCompleteWrite(
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-
-NTSTATUS
-PIPEnsControlOutAsyn(
+int PIPEnsControlOutAsyn(
      PSDevice     pDevice,
      BYTE         byRequest,
      WORD         wValue,
@@ -119,8 +116,7 @@ PIPEnsControlOutAsyn(
      PBYTE        pbyBuffer
     )
 {
-    NTSTATUS                ntStatus;
-
+       int ntStatus;
 
     if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
         return STATUS_FAILURE;
@@ -156,12 +152,7 @@ PIPEnsControlOutAsyn(
     return ntStatus;
 }
 
-
-
-
-
-NTSTATUS
-PIPEnsControlOut(
+int PIPEnsControlOut(
      PSDevice     pDevice,
      BYTE         byRequest,
      WORD         wValue,
@@ -170,10 +161,9 @@ PIPEnsControlOut(
      PBYTE        pbyBuffer
     )
 {
-    NTSTATUS            ntStatus = 0;
+       int ntStatus = 0;
     int ii;
 
-
     if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
         return STATUS_FAILURE;
 
@@ -219,11 +209,7 @@ PIPEnsControlOut(
     return STATUS_SUCCESS;
 }
 
-
-
-
-NTSTATUS
-PIPEnsControlIn(
+int PIPEnsControlIn(
      PSDevice     pDevice,
      BYTE         byRequest,
      WORD         wValue,
@@ -232,7 +218,7 @@ PIPEnsControlIn(
        PBYTE   pbyBuffer
     )
 {
-    NTSTATUS            ntStatus = 0;
+       int ntStatus = 0;
     int ii;
 
     if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
@@ -360,13 +346,9 @@ s_nsControlInUsbIoCompleteRead(
  * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  *
  */
-NTSTATUS
-PIPEnsInterruptRead(
-     PSDevice pDevice
-    )
+int PIPEnsInterruptRead(PSDevice pDevice)
 {
-    NTSTATUS            ntStatus = STATUS_FAILURE;
-
+    int ntStatus = STATUS_FAILURE;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n");
 
@@ -381,29 +363,6 @@ PIPEnsInterruptRead(
     // Now that we have created the urb, we will send a
     // request to the USB device object.
     //
-#if 0            //reserve int URB submit
-       usb_fill_int_urb(pDevice->pInterruptURB,
-                        pDevice->usb,
-                        usb_rcvintpipe(pDevice->usb, 1),
-                        (void *) pDevice->intBuf.pDataBuf,
-                        MAX_INTERRUPT_SIZE,
-                        s_nsInterruptUsbIoCompleteRead,
-                        pDevice,
-                        pDevice->int_interval
-                        );
-#else            //replace int URB submit by bulk transfer
-#ifndef Safe_Close
-       usb_fill_int_urb(pDevice->pInterruptURB,
-                        pDevice->usb,
-                        usb_rcvintpipe(pDevice->usb, 1),
-                        (void *) pDevice->intBuf.pDataBuf,
-                        MAX_INTERRUPT_SIZE,
-                        s_nsInterruptUsbIoCompleteRead,
-                        pDevice,
-                        pDevice->int_interval
-                        );
-#else
-
     pDevice->pInterruptURB->interval = pDevice->int_interval;
 
 usb_fill_bulk_urb(pDevice->pInterruptURB,
@@ -413,8 +372,6 @@ usb_fill_bulk_urb(pDevice->pInterruptURB,
                MAX_INTERRUPT_SIZE,
                s_nsInterruptUsbIoCompleteRead,
                pDevice);
-#endif
-#endif
 
        ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC);
        if (ntStatus != 0) {
@@ -448,8 +405,7 @@ s_nsInterruptUsbIoCompleteRead(
 
 {
     PSDevice        pDevice;
-    NTSTATUS        ntStatus;
-
+    int ntStatus;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n");
     //
@@ -495,13 +451,6 @@ s_nsInterruptUsbIoCompleteRead(
 
 
     if (pDevice->fKillEventPollingThread != TRUE) {
-   #if 0               //reserve int URB submit
-       ntStatus = usb_submit_urb(urb, GFP_ATOMIC);
-       if (ntStatus != 0) {
-           DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus);
-    }
-   #else                                                                                     //replace int URB submit by bulk transfer
-    #ifdef Safe_Close
        usb_fill_bulk_urb(pDevice->pInterruptURB,
                      pDevice->usb,
                      usb_rcvbulkpipe(pDevice->usb, 1),
@@ -514,11 +463,6 @@ s_nsInterruptUsbIoCompleteRead(
        if (ntStatus != 0) {
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
            }
-
-    #else
-        tasklet_schedule(&pDevice->EventWorkItem);
-    #endif
-#endif
     }
     //
     // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
@@ -540,13 +484,9 @@ s_nsInterruptUsbIoCompleteRead(
  * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  *
  */
-NTSTATUS
-PIPEnsBulkInUsbRead(
-     PSDevice pDevice,
-     PRCB     pRCB
-    )
+int PIPEnsBulkInUsbRead(PSDevice pDevice, PRCB pRCB)
 {
-    NTSTATUS            ntStatus= 0;
+       int ntStatus = 0;
     struct urb          *pUrb;
 
 
@@ -616,9 +556,7 @@ s_nsBulkInUsbIoCompleteRead(
     unsigned long   bytesRead;
     BOOL    bIndicateReceive = FALSE;
     BOOL    bReAllocSkb = FALSE;
-    NTSTATUS    status;
-
-
+    int status;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n");
     status = urb->status;
@@ -628,9 +566,7 @@ s_nsBulkInUsbIoCompleteRead(
         pDevice->ulBulkInError++;
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK In failed %d\n", status);
 
-       #ifdef Calcu_LinkQual
            pDevice->scStatistic.RxFcsErrCnt ++;
-       #endif
 //todo...xxxxxx
 //        if (status == USBD_STATUS_CRC) {
 //            pDevice->ulBulkInContCRCError++;
@@ -644,9 +580,7 @@ s_nsBulkInUsbIoCompleteRead(
         pDevice->ulBulkInContCRCError = 0;
         pDevice->ulBulkInBytesRead += bytesRead;
 
-       #ifdef Calcu_LinkQual
            pDevice->scStatistic.RxOkCnt ++;
-       #endif
     }
 
 
@@ -690,7 +624,7 @@ PIPEnsSendBulkOut(
       PUSB_SEND_CONTEXT pContext
     )
 {
-    NTSTATUS            status;
+    int status;
     struct urb          *pUrb;
 
 
@@ -771,7 +705,7 @@ s_nsBulkOutIoCompleteWrite(
     )
 {
     PSDevice            pDevice;
-    NTSTATUS            status;
+    int status;
     CONTEXT_TYPE        ContextType;
     unsigned long               ulBufLen;
     PUSB_SEND_CONTEXT   pContext;
@@ -803,10 +737,7 @@ s_nsBulkOutIoCompleteWrite(
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
         pDevice->ulBulkOutBytesWrite += ulBufLen;
         pDevice->ulBulkOutContCRCError = 0;
-       //2007-0115-06<Add>by MikeLiu
-           #ifdef TxInSleep
-             pDevice->nTxDataTimeCout = 0;
-           #endif
+       pDevice->nTxDataTimeCout = 0;
 
     } else {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
index f852b39027a51e4cac3012769d2e6351a756bca2..b3673474a9e12783d036d3c1e9b744473b33c317 100644 (file)
@@ -41,8 +41,7 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-NTSTATUS
-PIPEnsControlOut(
+int PIPEnsControlOut(
      PSDevice     pDevice,
      BYTE         byRequest,
      WORD         wValue,
@@ -51,10 +50,7 @@ PIPEnsControlOut(
      PBYTE        pbyBuffer
     );
 
-
-
-NTSTATUS
-PIPEnsControlOutAsyn(
+int PIPEnsControlOutAsyn(
      PSDevice     pDevice,
      BYTE         byRequest,
      WORD         wValue,
@@ -63,8 +59,7 @@ PIPEnsControlOutAsyn(
      PBYTE        pbyBuffer
     );
 
-NTSTATUS
-PIPEnsControlIn(
+int PIPEnsControlIn(
      PSDevice     pDevice,
      BYTE         byRequest,
      WORD         wValue,
@@ -73,24 +68,8 @@ PIPEnsControlIn(
        PBYTE   pbyBuffer
     );
 
-
-
-
-NTSTATUS
-PIPEnsInterruptRead(
-     PSDevice pDevice
-    );
-
-NTSTATUS
-PIPEnsBulkInUsbRead(
-     PSDevice pDevice,
-     PRCB     pRCB
-    );
-
-NTSTATUS
-PIPEnsSendBulkOut(
-      PSDevice pDevice,
-      PUSB_SEND_CONTEXT pContext
-    );
+int PIPEnsInterruptRead(PSDevice pDevice);
+int PIPEnsBulkInUsbRead(PSDevice pDevice, PRCB pRCB);
+int PIPEnsSendBulkOut(PSDevice pDevice, PUSB_SEND_CONTEXT pContext);
 
 #endif /* __USBPIPE_H__ */
index 72e21b6f0e88cbdfe7d638bf078538539b49ab01..686747a09294a5ae8272859297d60c2903e037d1 100644 (file)
@@ -565,11 +565,9 @@ void vRunCommand(void *hDeviceContext)
                 return;
             }
 
-//20080131-03,<Add> by Mike Liu
-       #ifdef Adhoc_STA
             memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID,
                               ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
-       #endif
+
             pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
             pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
@@ -716,18 +714,6 @@ void vRunCommand(void *hDeviceContext)
               return;
           }
                  pDevice->byLinkWaitCount = 0;
-                #if 0
-                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-                    // if(pDevice->bWPASuppWextEnabled == TRUE)
-                        {
-                       union iwreq_data  wrqu;
-                       memset(&wrqu, 0, sizeof (wrqu));
-                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-                       printk("wireless_send_event--->SIOCGIWAP(disassociated:AUTHENTICATE_WAIT_timeout)\n");
-                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
-                       }
-                    #endif
-                #endif
 
             s_bCommandComplete(pDevice);
             break;
@@ -754,8 +740,6 @@ void vRunCommand(void *hDeviceContext)
                     netif_wake_queue(pDevice->dev);
                 }
 
-       //2007-0115-07<Add>by MikeLiu
-            #ifdef TxInSleep
                 if(pDevice->IsTxDataTrigger != FALSE)   {    //TxDataTimer is not triggered at the first time
                      // printk("Re-initial TxDataTimer****\n");
                    del_timer(&pDevice->sTimerTxData);
@@ -771,7 +755,6 @@ void vRunCommand(void *hDeviceContext)
                 }
                pDevice->IsTxDataTrigger = TRUE;
                 add_timer(&pDevice->sTimerTxData);
-             #endif
 
             }
           else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
@@ -785,18 +768,6 @@ void vRunCommand(void *hDeviceContext)
               return;
           }
                  pDevice->byLinkWaitCount = 0;
-               #if 0
-                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-                    // if(pDevice->bWPASuppWextEnabled == TRUE)
-                        {
-                       union iwreq_data  wrqu;
-                       memset(&wrqu, 0, sizeof (wrqu));
-                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-                       printk("wireless_send_event--->SIOCGIWAP(disassociated:ASSOCIATE_WAIT_timeout)\n");
-                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
-                       }
-                    #endif
-               #endif
 
             s_bCommandComplete(pDevice);
             break;
@@ -907,7 +878,7 @@ void vRunCommand(void *hDeviceContext)
        //         CARDbRadioPowerOff(pDevice);
        //2008-09-09<Add> BY Mike:Hot Key for Radio On/Off
        {
-        NTSTATUS        ntStatus = STATUS_SUCCESS;
+              int ntStatus = STATUS_SUCCESS;
         BYTE            byTmp;
 
         ntStatus = CONTROLnsRequestIn(pDevice,
@@ -1300,8 +1271,6 @@ void vResetCommandTimer(void *hDeviceContext)
     pDevice->bCmdClear = FALSE;
 }
 
-//2007-0115-08<Add>by MikeLiu
-#ifdef TxInSleep
 void BSSvSecondTxData(void *hDeviceContext)
 {
   PSDevice        pDevice = (PSDevice)hDeviceContext;
@@ -1320,12 +1289,8 @@ void BSSvSecondTxData(void *hDeviceContext)
 
   spin_lock_irq(&pDevice->lock);
   //is wap_supplicant running successful OR only open && sharekey mode!
-  #if 1
   if(((pDevice->bLinkPass ==TRUE)&&(pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
       (pDevice->fWPA_Authened == TRUE)) {   //wpa linking
- #else
-  if(pDevice->bLinkPass ==TRUE) {
- #endif
         //   printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__);
          pDevice->fTxDataInSleep = TRUE;
          PSbSendNullPacket(pDevice);      //send null packet
@@ -1337,5 +1302,3 @@ void BSSvSecondTxData(void *hDeviceContext)
   add_timer(&pDevice->sTimerTxData);
   return;
 }
-#endif
-
index 09c4411c689115c73ab8789c15c8d1af6563f144..d24a79dce61ad1dcf5a47c80f84d7aa3f3637d31 100644 (file)
@@ -128,9 +128,6 @@ WCMDvCommandThread(
     );
 */
 
-//2007-0115-09<Add>by MikeLiu
-#ifdef TxInSleep
 void BSSvSecondTxData(void *hDeviceContext);
-#endif
 
 #endif /* __WCMD_H__ */
index 857ce0bc00a486ef4db46e22ee318e1932e17215..c231ae7176f5ab0f2e54808727d244fe0e659ba0 100644 (file)
@@ -79,7 +79,8 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
         for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
             pCacheEntry = &(pCache->asCacheEntry[uIndex]);
             if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) &&
-                (IS_ETH_ADDRESS_EQUAL (&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]))) &&
+               (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]),
+                                    &(pMACHeader->abyAddr2[0]))) &&
                 (LOBYTE(pCacheEntry->wFrameCtl) == LOBYTE(pMACHeader->wFrameCtl))
                 ) {
                 /* Duplicate match */
@@ -111,22 +112,21 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
  * Return Value: index number in Defragment Database
  *
  */
+
 unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader)
 {
        unsigned int ii;
 
-    for(ii=0;ii<pDevice->cbDFCB;ii++) {
-        if ((pDevice->sRxDFCB[ii].bInUse == TRUE) &&
-            (IS_ETH_ADDRESS_EQUAL (&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
-            ) {
-            //
-            return(ii);
-        }
-    }
-    return(pDevice->cbDFCB);
+       for (ii = 0; ii < pDevice->cbDFCB; ii++) {
+               if ((pDevice->sRxDFCB[ii].bInUse == TRUE) &&
+                   (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]),
+                                         &(pMACHeader->abyAddr2[0])))) {
+                       return ii;
+               }
+       }
+       return pDevice->cbDFCB;
 }
 
-
 /*
  * Description:
  *      Insert received fragment packet in Defragment Database
@@ -147,7 +147,7 @@ unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader)
 
     if (pDevice->cbFreeDFCB == 0)
         return(pDevice->cbDFCB);
-    for(ii=0;ii<pDevice->cbDFCB;ii++) {
+    for (ii = 0; ii < pDevice->cbDFCB; ii++) {
         if (pDevice->sRxDFCB[ii].bInUse == FALSE) {
             pDevice->cbFreeDFCB--;
             pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime;
index 93c15f0580fe449933ea47322ab3103be0e0fafa..e4eca9b060b1fb37a5d16fa624589a0cdadecba5 100644 (file)
@@ -353,9 +353,9 @@ void vMgrObjectInit(void *hDeviceContext)
     pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
     pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
     pMgmt->uCurrChannel = pDevice->uChannel;
-    for(ii=0;ii<WLAN_BSSID_LEN;ii++) {
-        pMgmt->abyDesireBSSID[ii] = 0xFF;
-    }
+    for (ii = 0; ii < WLAN_BSSID_LEN; ii++)
+       pMgmt->abyDesireBSSID[ii] = 0xFF;
+
     pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
     //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1);
     pMgmt->byCSSPK = KEY_CTL_NONE;
@@ -373,8 +373,6 @@ void vMgrObjectInit(void *hDeviceContext)
     pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
     pDevice->sTimerCommand.expires = RUN_AT(HZ);
 
-//2007-0115-10<Add>by MikeLiu
-   #ifdef TxInSleep
     init_timer(&pDevice->sTimerTxData);
     pDevice->sTimerTxData.data = (unsigned long)pDevice;
     pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
@@ -382,7 +380,6 @@ void vMgrObjectInit(void *hDeviceContext)
     pDevice->fTxDataInSleep = FALSE;
     pDevice->IsTxDataTrigger = FALSE;
     pDevice->nTxDataTimeCout = 0;
-   #endif
 
     pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
     pDevice->uCmdDequeueIdx = 0;
@@ -1056,7 +1053,6 @@ s_vMgrRxAssocResponse(
 
     }
 
-#if 1
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 //need clear flags related to Networkmanager
               pDevice->bwextstep0 = FALSE;
@@ -1065,7 +1061,6 @@ s_vMgrRxAssocResponse(
               pDevice->bwextstep3 = FALSE;
               pDevice->bWPASuppWextEnabled = FALSE;
 #endif
-#endif
 
 if(pMgmt->eCurrState == WMAC_STATE_ASSOC)
       timer_expire(pDevice->sTimerCommand, 0);
@@ -1705,7 +1700,8 @@ s_vMgrRxDeauthentication(
           pDevice->fWPA_Authened = FALSE;
             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
             // TODO: update BSS list for specific BSSID if pre-authentication case
-            if (IS_ETH_ADDRESS_EQUAL(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
+           if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3,
+                                   pMgmt->abyCurrBSSID)) {
                 if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
                     pMgmt->sNodeDBTable[0].bActive = FALSE;
                     pMgmt->eCurrMode = WMAC_MODE_STANDBY;
@@ -2471,11 +2467,8 @@ void vMgrCreateOwnIBSS(void *hDeviceContext,
     pDevice->uCurrRSSI = 0;
     pDevice->byCurrSQ = 0;
 
-//20080131-04,<Add> by Mike Liu
-#ifdef Adhoc_STA
     memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID,
                       ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN);
-#endif
 
     memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
     memcpy(pMgmt->abyCurrSSID,
@@ -3099,12 +3092,6 @@ s_vMgrSynchBSS (
   PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
   /* unsigned int ii, uSameBssidNum=0; */
 
-        //  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
-          //   if (pMgmt->sBSSList[ii].bActive &&
-            //      IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
-             //       uSameBssidNum++;
-               //   }
-           // }
   //   if( uSameBssidNum>=2) {  //we only check AP in hidden sssid  mode
         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selsection,
              (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-selsect it according to real pairwise-key info.
@@ -4795,21 +4782,21 @@ s_bCipherMatch (
             byMulticastCipher = KEY_CTL_INVALID;
         }
 
-        // check Pairwise Key Cipher
-        for(i=0;i<pBSSNode->wCSSPKCount;i++) {
-            if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
-                (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
-                // this should not happen as defined 802.11i
-                byCipherMask |= 0x01;
-            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
-                byCipherMask |= 0x02;
-            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
-                byCipherMask |= 0x04;
-            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
-                // use group key only ignore all others
-                byCipherMask = 0;
-                i = pBSSNode->wCSSPKCount;
-            }
+       /* check Pairwise Key Cipher */
+       for (i = 0; i < pBSSNode->wCSSPKCount; i++) {
+               if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
+                   (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
+                       /* this should not happen as defined 802.11i */
+                       byCipherMask |= 0x01;
+               } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
+                       byCipherMask |= 0x02;
+               } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
+                       byCipherMask |= 0x04;
+               } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
+                       /* use group key only ignore all others */
+                       byCipherMask = 0;
+                       i = pBSSNode->wCSSPKCount;
+               }
         }
 
     } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
@@ -4828,17 +4815,17 @@ s_bCipherMatch (
             byMulticastCipher = KEY_CTL_INVALID;
         }
 
-        // check Pairwise Key Cipher
-        for(i=0;i<pBSSNode->wPKCount;i++) {
-            if (pBSSNode->abyPKType[i] == WPA_TKIP) {
-                byCipherMask |= 0x02;
-            } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
-                byCipherMask |= 0x04;
-            } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
-                // use group key only ignore all others
-                byCipherMask = 0;
-                i = pBSSNode->wPKCount;
-            }
+       /* check Pairwise Key Cipher */
+       for (i = 0; i < pBSSNode->wPKCount; i++) {
+               if (pBSSNode->abyPKType[i] == WPA_TKIP) {
+                       byCipherMask |= 0x02;
+               } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
+                       byCipherMask |= 0x04;
+               } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
+                       /* use group key only ignore all others */
+                       byCipherMask = 0;
+                       i = pBSSNode->wPKCount;
+               }
         }
     }
 
index 1e5b916aea1d17a6aa5862dfc2500dc238b7c15d..683840c0ac45f4639890d412c06f467eaa5588a3 100644 (file)
@@ -82,7 +82,7 @@
 
 /*---------------------  Export Types  ------------------------------*/
 //mike define: make timer  to expire after desired times
-#define timer_expire(timer,next_tick)   mod_timer(&timer, RUN_AT(next_tick))
+#define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick))
 
 typedef void (*TimerFunction)(unsigned long);
 
@@ -259,9 +259,7 @@ typedef struct tagSMgmtObject
     // Operation state variables
     WMAC_CURRENT_MODE       eCurrMode;   // MAC current connection mode
     WMAC_BSS_STATE          eCurrState;  // MAC current BSS state
-    #ifdef SndEvt_ToAPI
     WMAC_BSS_STATE          eLastState;  // MAC last BSS state
-    #endif
 
     PKnownBSS               pCurrBSS;
     BYTE                    byCSSGK;
@@ -293,10 +291,7 @@ typedef struct tagSMgmtObject
     BYTE                    abyDesireBSSID[WLAN_BSSID_LEN];
 
 //restore BSS info for Ad-Hoc mode
-//20080131-05,<Add> by Mike Liu
-#ifdef Adhoc_STA
      BYTE                    abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-#endif
 
     // Adhoc or AP configuration vars
     WORD                    wIBSSBeaconPeriod;
@@ -343,11 +338,11 @@ typedef struct tagSMgmtObject
     BOOL                    bRxBeaconInTBTTWake;
     BYTE                    abyPSTxMap[MAX_NODE_NUM + 1];
 
-    // managment command related
+    // management command related
     unsigned int                    uCmdBusy;
     unsigned int                    uCmdHostAPBusy;
 
-    // managment packet pool
+    // management packet pool
     PBYTE                   pbyMgmtPacketPool;
     BYTE                    byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
 
index 1fa6c9b88ed320fd0166b4144c08772df0f9c067..f492778ee8b6e91694646bc8c0744ff0b1543532 100644 (file)
@@ -148,7 +148,8 @@ WPA_ParseRSN (
         {
             j = 0;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
-            for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
+           for (i = 0; (i < pRSN->wPKCount) &&
+                  (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
                     if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
                         pBSSList->abyPKType[j++] = WPA_NONE;
@@ -180,7 +181,8 @@ WPA_ParseRSN (
             j = 0;
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n",
                           pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
-            for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
+           for (i = 0; (i < pIE_RSN_Auth->wAuthCount) &&
+                  (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
                     if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
                         pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X;
index 429a910a5c50f9b0c50071684d8ecc1e870aa313..46c295905b48adbc0e5f7da80e81ada654831444 100644 (file)
@@ -58,21 +58,9 @@ typedef struct tagSPMKIDCache {
 
 /*---------------------  Export Functions  --------------------------*/
 
-void
-WPA2_ClearRSN (
-     PKnownBSS        pBSSNode
-    );
+void WPA2_ClearRSN(PKnownBSS pBSSNode);
+void WPA2vParseRSN(PKnownBSS pBSSNode, PWLAN_IE_RSN pRSN);
 
-void
-WPA2vParseRSN (
-     PKnownBSS        pBSSNode,
-     PWLAN_IE_RSN     pRSN
-    );
-
-unsigned int
-WPA2uSetIEs(
-       void *pMgmtHandle,
-     PWLAN_IE_RSN pRSNIEs
-    );
+unsigned int WPA2uSetIEs(void *pMgmtHandle, PWLAN_IE_RSN pRSNIEs);
 
 #endif /* __WPA2_H__ */
index 961f583368a1825ee19f84f18996aa338b74ec72..b407ae536bf5a3d38cb97801e2fcbc6f4e20e635 100644 (file)
@@ -186,7 +186,6 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
                return wpa_release_wpadev(pDevice);
 }
 
-
 /*
  * Description:
  *      Set WPA algorithm & keys
@@ -349,9 +348,8 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
         return -EINVAL;
     }
 
-
-    if (IS_BROADCAST_ADDRESS(&param->addr[0]) || (param->addr == NULL)) {
-        // If IS_BROADCAST_ADDRESS, set the key as every key entry's group key.
+    if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
+       /* if broadcast, set the key as every key entry's group key */
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
 
         if ((KeybSetAllGroupKey(pDevice,
@@ -404,7 +402,7 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
 
         } else {
             // Key Table Full
-            if (IS_ETH_ADDRESS_EQUAL(&param->addr[0], pDevice->abyBSSID)) {
+           if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
                 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
                 return -EINVAL;
 
@@ -647,9 +645,9 @@ static int wpa_get_scan(PSDevice pDevice,
 
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
 
-         for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {
+       for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) {
 
-           if((pMgmt->sBSSList[jj].bActive!=TRUE) ||
+               if ((pMgmt->sBSSList[jj].bActive != TRUE) ||
 
                 ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) {
 
index 7441015cb187a4497d1d8aa9e93bf3391f02baf2..415256f69c322a10fbdaade59ca4e0df65907b94 100644 (file)
 #define DOT_11_MAC_HEADER_SIZE         24
 #define DOT_11_SNAP_SIZE                       6
 #define DOT_11_DURATION_OFFSET         2
-#define DOT_11_SEQUENCE_OFFSET         22 /* Sequence control offset */
-#define DOT_11_TYPE_OFFSET                     30 /* The start offset of 802.11 Frame// */
+/* Sequence control offset */
+#define DOT_11_SEQUENCE_OFFSET         22
+/* The start offset of 802.11 Frame// */
+#define DOT_11_TYPE_OFFSET                     30
 #define DOT_11_DATA_OFFSET          24
 #define DOT_11_DA_OFFSET                       4
 #define DOT_3_TYPE_ARP                         0x80F3
 #define ELEMENT_ID_CF_PARAMETER_SET         4
 #define ELEMENT_ID_TIM                      5
 #define ELEMENT_ID_IBSS_PARAMETER_SET       6
-// 7~15 reserverd
+/* 7~15 reserverd */
 #define ELEMENT_ID_CHALLENGE_TEXT           16
-// 17~31 reserved for challenge text extension
-// 32~255 reserved
-//--  11G  --
+/* 17~31 reserved for challenge text extension */
+/* 32~255 reserved */
+/*--  11G  -- */
 #define ELEMENT_ID_ERP_INFORMATION                     42
 #define ELEMENT_ID_EXTENDED_SUPPORTED_RATES 50
 
-//--  WPA  --
+/* --  WPA  -- */
 
 #define ELEMENT_ID_RSN_WPA                                     221
 #ifdef _WPA2_
 #define ELEMENT_ID_RSN_WPA2                                48
-#endif //endif WPA2
+#endif /* endif WPA2 */
 
 #define WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT    ((u16) 6)
 #define WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT  ((u16) 2)
 
-//===================================================================
-//  Reason Code (Table 18): indicate the reason of DisAssoc, DeAuthen
-//  length of ReasonCode is 2 Octs.
-//===================================================================
+/===================================================================
+*  Reason Code (Table 18): indicate the reason of DisAssoc, DeAuthen
+*  length of ReasonCode is 2 Octs.
+* =================================================================== */
 #define REASON_REASERED             0
 #define REASON_UNSPECIDIED          1
 #define REASON_PREAUTH_INVALID      2
@@ -385,9 +387,11 @@ struct Extended_Supported_Rates_Element {
 #ifdef _WPA2_
 #define VERSION_WPA2            1
 #endif /* end def  _WPA2_ */
-#define OUI_WPA                                        0x00F25000      /* WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type */
+/* WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type */
+#define OUI_WPA                                        0x00F25000
 #ifdef _WPA2_
-#define OUI_WPA2                               0x00AC0F00      /* for wpa2 change to 0x00ACOF04 by Ws 26/04/04 */
+/* for wpa2 change to 0x00ACOF04 by Ws 26/04/04 */
+#define OUI_WPA2                               0x00AC0F00
 #endif /* end def _WPA2_ */
 
 #define OUI_WPA_ADDITIONAL             0x01
@@ -400,8 +404,8 @@ struct Extended_Supported_Rates_Element {
 
 #define WPA_OUI_BIG    ((u32) 0x01F25000)/* added by ws 09/23/04 */
 #define WPA_OUI_LITTLE  ((u32) 0x01F25001)/* added by ws 09/23/04 */
-
-#define WPA_WPS_OUI                            cpu_to_le32(0x04F25000) /* 20061108 For WPS. It's little endian. Big endian is 0x0050F204 */
+/* 20061108 For WPS. It's little endian. Big endian is 0x0050F204 */
+#define WPA_WPS_OUI                            cpu_to_le32(0x04F25000)
 
 /* -----WPA2----- */
 #ifdef _WPA2_
@@ -420,75 +424,65 @@ struct Extended_Supported_Rates_Element {
 #define OUI_CIPHER_CCMP                                0x04
 #define OUI_CIPHER_WEP_104                     0x05
 
-struct suite_selector
-{
-       union
-       {
+struct suite_selector{
+       union{
                u8      Value[4];
-               struct _SUIT_
-               {
+               struct _SUIT_ {
                        u8      OUI[3];
                        u8      Type;
-               }SuitSelector;
+               } SuitSelector;
        };
 };
 
-//--  WPA  --
-struct RSN_Information_Element
-{
+/* --  WPA  -- */
+struct RSN_Information_Element{
        u8                                      Element_ID;
        u8                                      Length;
-       struct suite_selector   OuiWPAAdditional; /* WPA version 2.0 additional field, and should be 00:50:F2:01 */
+ /* WPA version 2.0 additional field, and should be 00:50:F2:01 */
+       struct suite_selector   OuiWPAAdditional;
        u16                                     Version;
        struct suite_selector           GroupKeySuite;
        u16                                     PairwiseKeySuiteCount;
        struct suite_selector           PairwiseKeySuite[1];
-}__attribute__ ((packed));
-struct RSN_Auth_Sub_Information_Element
-{
+} __attribute__ ((packed));
+struct RSN_Auth_Sub_Information_Element {
        u16                             AuthKeyMngtSuiteCount;
        struct suite_selector   AuthKeyMngtSuite[1];
-}__attribute__ ((packed));
+} __attribute__ ((packed));
 
 /* --  WPA2  -- */
-struct RSN_Capability_Element
-{
-  union
-  {
+struct RSN_Capability_Element {
+  union {
        u16     __attribute__ ((packed))        wValue;
     #ifdef _BIG_ENDIAN_         /* 20060927 add by anson's endian */
-    struct _RSN_Capability
-    {
-       u16   __attribute__ ((packed))  Reserved2 : 8; /* 20051201 */
-       u16   __attribute__ ((packed))  Reserved1 : 2;
-       u16   __attribute__ ((packed))  GTK_Replay_Counter : 2;
-       u16   __attribute__ ((packed))  PTK_Replay_Counter : 2;
-       u16   __attribute__ ((packed))  No_Pairwise : 1;
-        u16   __attribute__ ((packed))  Pre_Auth : 1;
-    }__attribute__ ((packed))  RSN_Capability;
+    struct _RSN_Capability {
+       u16   __attribute__ ((packed))  Reserved2:8; /* 20051201 */
+       u16   __attribute__ ((packed))  Reserved1:2;
+       u16   __attribute__ ((packed))  GTK_Replay_Counter:2;
+       u16   __attribute__ ((packed))  PTK_Replay_Counter:2;
+       u16   __attribute__ ((packed))  No_Pairwise:1;
+       u16   __attribute__ ((packed))  Pre_Auth:1;
+    } __attribute__ ((packed))  RSN_Capability;
     #else
-    struct _RSN_Capability
-    {
-        u16   __attribute__ ((packed))  Pre_Auth : 1;
-        u16   __attribute__ ((packed))  No_Pairwise : 1;
-        u16   __attribute__ ((packed))  PTK_Replay_Counter : 2;
-           u16   __attribute__ ((packed))  GTK_Replay_Counter : 2;
-           u16   __attribute__ ((packed))  Reserved1 : 2;
-           u16   __attribute__ ((packed))  Reserved2 : 8; /* 20051201 */
-    }__attribute__ ((packed))  RSN_Capability;
+    struct _RSN_Capability {
+       u16   __attribute__ ((packed))  Pre_Auth:1;
+       u16   __attribute__ ((packed))  No_Pairwise:1;
+       u16   __attribute__ ((packed))  PTK_Replay_Counter:2;
+       u16   __attribute__ ((packed))  GTK_Replay_Counter:2;
+       u16   __attribute__ ((packed))  Reserved1:2;
+       u16   __attribute__ ((packed))  Reserved2:8; /* 20051201 */
+    } __attribute__ ((packed))  RSN_Capability;
     #endif
 
-  }__attribute__ ((packed)) ;
-}__attribute__ ((packed)) ;
+  } __attribute__ ((packed)) ;
+} __attribute__ ((packed)) ;
 
 #ifdef _WPA2_
-struct pmkid
-{
+struct pmkid {
   u8 pValue[16];
 };
 
-struct WPA2_RSN_Information_Element
-{
+struct WPA2_RSN_Information_Element {
        u8                                      Element_ID;
        u8                                      Length;
        u16                                     Version;
@@ -496,29 +490,28 @@ struct    WPA2_RSN_Information_Element
        u16                                     PairwiseKeySuiteCount;
        struct suite_selector           PairwiseKeySuite[1];
 
-}__attribute__ ((packed));
+} __attribute__ ((packed));
 
-struct WPA2_RSN_Auth_Sub_Information_Element
-{
+struct WPA2_RSN_Auth_Sub_Information_Element {
        u16                             AuthKeyMngtSuiteCount;
        struct suite_selector   AuthKeyMngtSuite[1];
-}__attribute__ ((packed));
+} __attribute__ ((packed));
 
 
-struct PMKID_Information_Element
-{
+struct PMKID_Information_Element {
        u16                             PMKID_Count;
        struct pmkid pmkid[16];
-}__attribute__ ((packed));
+} __attribute__ ((packed));
 
 #endif /* enddef _WPA2_ */
 /*============================================================
 // MAC Frame structure (different type) and subfield structure
 //============================================================*/
-struct MAC_frame_control
-{
-    u8    mac_frame_info; /* a combination of the [Protocol Version, Control Type, Control Subtype]*/
-    #ifdef _BIG_ENDIAN_ /* 20060927 add by anson's endian */
+struct MAC_frame_control {
+/* a combination of the [Protocol Version, Control Type, Control Subtype]*/
+    u8    mac_frame_info;
+/* 20060927 add by anson's endian */
+    #ifdef _BIG_ENDIAN_
     u8    order:1;
     u8    WEP:1;
     u8    more_data:1;
@@ -540,7 +533,8 @@ struct MAC_frame_control
 } __attribute__ ((packed));
 
 struct Management_Frame {
-    struct MAC_frame_control frame_control; /* 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0 */
+/* 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0 */
+    struct MAC_frame_control frame_control;
     u16                duration;
     u8         DA[MAC_ADDR_LENGTH];                    /* Addr1 */
     u8         SA[MAC_ADDR_LENGTH];                    /* Addr2 */
@@ -552,7 +546,8 @@ struct Management_Frame {
 
 /* SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it. */
 struct Control_Frame {
-    struct MAC_frame_control frame_control; /* ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0 */
+/* ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0 */
+    struct MAC_frame_control frame_control;
     u16                duration;
     u8         RA[MAC_ADDR_LENGTH];
     u8         TA[MAC_ADDR_LENGTH];
@@ -627,8 +622,9 @@ struct Authentication_Frame_Body {
     u16    algorithmNumber;
     u16    sequenceNumber;
     u16    statusCode;
-    /* NB: don't include ChallengeText in this structure
-       // struct Challenge_Text_Element sChallengeTextElement; // wkchen added */
+       /* NB: don't include ChallengeText in this structure
+       // struct Challenge_Text_Element sChallengeTextElement;
+       // wkchen added */
 } __attribute__ ((packed));
 
 
index 78935865df19d060daeb0e805253d9a1e547bb99..5c1f05392db98aab24174c25ee60f0f0dfd86d6a 100644 (file)
 
 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
 #define LOOP_TIMES      20
-#define US              1000//MICROSECOND
+#define US              1000/* MICROSECOND*/
 
 #define AG_CONST        0.6072529350
 #define FIXED(X)        ((s32)((X) * 32768.0))
 #define DEG2RAD(X)      0.017453 * (X)
 
-static const s32 Angles[] =
-{
-    FIXED(DEG2RAD(45.0)),    FIXED(DEG2RAD(26.565)),  FIXED(DEG2RAD(14.0362)),
-    FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
-    FIXED(DEG2RAD(0.895174)),FIXED(DEG2RAD(0.447614)),FIXED(DEG2RAD(0.223811)),
-    FIXED(DEG2RAD(0.111906)),FIXED(DEG2RAD(0.055953)),FIXED(DEG2RAD(0.027977))
+static const s32 Angles[] = {
+    FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),   FIXED(DEG2RAD(14.0362)),
+    FIXED(DEG2RAD(7.12502)),  FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
+    FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
+    FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
 };
 
 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
-//void    _phy_rf_write_delay(struct hw_data *phw_data);
-//void    phy_init_rf(struct hw_data *phw_data);
+
+/*
+ * void    _phy_rf_write_delay(struct hw_data *phw_data);
+ * void    phy_init_rf(struct hw_data *phw_data);
+ */
 
 /****************** FUNCTION DEFINITION SECTION *****************************/
 
@@ -46,9 +48,7 @@ s32 _s13_to_s32(u32 data)
     val = (data & 0x0FFF);
 
     if ((data & BIT(12)) != 0)
-    {
         val |= 0xFFFFF000;
-    }
 
     return ((s32) val);
 }
@@ -58,13 +58,9 @@ u32 _s32_to_s13(s32 data)
     u32     val;
 
     if (data > 4095)
-    {
         data = 4095;
-    }
     else if (data < -4096)
-    {
         data = -4096;
-    }
 
     val = data & 0x1FFF;
 
@@ -79,9 +75,7 @@ s32 _s4_to_s32(u32 data)
     val = (data & 0x0007);
 
     if ((data & BIT(3)) != 0)
-    {
         val |= 0xFFFFFFF8;
-    }
 
     return val;
 }
@@ -91,13 +85,9 @@ u32 _s32_to_s4(s32 data)
     u32     val;
 
     if (data > 7)
-    {
         data = 7;
-    }
     else if (data < -8)
-    {
         data = -8;
-    }
 
     val = data & 0x000F;
 
@@ -112,9 +102,7 @@ s32 _s5_to_s32(u32 data)
     val = (data & 0x000F);
 
     if ((data & BIT(4)) != 0)
-    {
         val |= 0xFFFFFFF0;
-    }
 
     return val;
 }
@@ -124,13 +112,9 @@ u32 _s32_to_s5(s32 data)
     u32     val;
 
     if (data > 15)
-    {
         data = 15;
-    }
     else if (data < -16)
-    {
         data = -16;
-    }
 
     val = data & 0x001F;
 
@@ -145,9 +129,7 @@ s32 _s6_to_s32(u32 data)
     val = (data & 0x001F);
 
     if ((data & BIT(5)) != 0)
-    {
         val |= 0xFFFFFFE0;
-    }
 
     return val;
 }
@@ -157,13 +139,9 @@ u32 _s32_to_s6(s32 data)
     u32     val;
 
     if (data > 31)
-    {
         data = 31;
-    }
     else if (data < -32)
-    {
         data = -32;
-    }
 
     val = data & 0x003F;
 
@@ -178,9 +156,7 @@ s32 _s9_to_s32(u32 data)
     val = data & 0x00FF;
 
     if ((data & BIT(8)) != 0)
-    {
         val |= 0xFFFFFF00;
-    }
 
     return val;
 }
@@ -190,13 +166,9 @@ u32 _s32_to_s9(s32 data)
     u32     val;
 
     if (data > 255)
-    {
         data = 255;
-    }
     else if (data < -256)
-    {
         data = -256;
-    }
 
     val = data & 0x01FF;
 
@@ -207,21 +179,19 @@ u32 _s32_to_s9(s32 data)
 s32 _floor(s32 n)
 {
     if (n > 0)
-    {
-        n += 5;
-    }
+       n += 5;
     else
-    {
         n -= 5;
-    }
 
     return (n/10);
 }
 
 /****************************************************************************/
-// The following code is sqare-root function.
-// sqsum is the input and the output is sq_rt;
-// The maximum of sqsum = 2^27 -1;
+/*
+ * The following code is sqare-root function.
+ * sqsum is the input and the output is sq_rt;
+ * The maximum of sqsum = 2^27 -1;
+ */
 u32 _sqrt(u32 sqsum)
 {
     u32     sq_rt;
@@ -232,18 +202,17 @@ u32 _sqrt(u32 sqsum)
     int     step;
 
     g4 =  sqsum / 100000000;
-    g3 = (sqsum - g4*100000000) /1000000;
-    g2 = (sqsum - g4*100000000 - g3*1000000) /10000;
-    g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) /100;
+    g3 = (sqsum - g4*100000000) / 1000000;
+    g2 = (sqsum - g4*100000000 - g3*1000000) / 10000;
+    g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100;
     g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
 
     next = g4;
     step = 0;
     seed = 0;
-    while (((seed+1)*(step+1)) <= next)
-    {
-       step++;
-       seed++;
+    while (((seed+1)*(step+1)) <= next) {
+        step++;
+        seed++;
     }
 
     sq_rt = seed * 10000;
@@ -251,20 +220,18 @@ u32 _sqrt(u32 sqsum)
 
     step = 0;
     seed = 2 * seed * 10;
-    while (((seed+1)*(step+1)) <= next)
-    {
+    while (((seed+1)*(step+1)) <= next) {
         step++;
-       seed++;
+        seed++;
     }
 
     sq_rt = sq_rt + step * 1000;
     next = (next - seed * step) * 100 + g2;
     seed = (seed + step) * 10;
     step = 0;
-    while (((seed+1)*(step+1)) <= next)
-    {
+    while (((seed+1)*(step+1)) <= next) {
         step++;
-       seed++;
+        seed++;
     }
 
     sq_rt = sq_rt + step * 100;
@@ -272,21 +239,19 @@ u32 _sqrt(u32 sqsum)
     seed = (seed + step) * 10;
     step = 0;
 
-    while (((seed+1)*(step+1)) <= next)
-    {
+    while (((seed+1)*(step+1)) <= next) {
         step++;
-       seed++;
+        seed++;
     }
 
     sq_rt = sq_rt + step * 10;
-    next = (next - seed* step) * 100 + g0;
+    next = (next - seed * step) * 100 + g0;
     seed = (seed + step) * 10;
     step = 0;
 
-    while (((seed+1)*(step+1)) <= next)
-    {
+    while (((seed+1)*(step+1)) <= next) {
         step++;
-       seed++;
+        seed++;
     }
 
     sq_rt = sq_rt + step;
@@ -300,38 +265,31 @@ void _sin_cos(s32 angle, s32 *sin, s32 *cos)
     s32 X, Y, TargetAngle, CurrAngle;
     unsigned    Step;
 
-    X=FIXED(AG_CONST);      // AG_CONST * cos(0)
-    Y=0;                    // AG_CONST * sin(0)
-    TargetAngle=abs(angle);
-    CurrAngle=0;
+    X = FIXED(AG_CONST);      /* AG_CONST * cos(0) */
+    Y = 0;                    /* AG_CONST * sin(0) */
+    TargetAngle = abs(angle);
+    CurrAngle = 0;
 
-    for (Step=0; Step < 12; Step++)
-    {
+    for (Step = 0; Step < 12; Step++) {
        s32 NewX;
 
-        if(TargetAngle > CurrAngle)
-        {
-            NewX=X - (Y >> Step);
-            Y=(X >> Step) + Y;
-            X=NewX;
+        if (TargetAngle > CurrAngle) {
+            NewX = X - (Y >> Step);
+            Y = (X >> Step) + Y;
+            X = NewX;
             CurrAngle += Angles[Step];
-        }
-        else
-        {
-            NewX=X + (Y >> Step);
-            Y=-(X >> Step) + Y;
-            X=NewX;
+        } else {
+            NewX = X + (Y >> Step);
+            Y = -(X >> Step) + Y;
+            X = NewX;
             CurrAngle -= Angles[Step];
         }
     }
 
-    if (angle > 0)
-    {
+    if (angle > 0) {
         *cos = X;
         *sin = Y;
-    }
-    else
-    {
+    } else {
         *cos = X;
         *sin = -Y;
     }
@@ -343,7 +301,7 @@ static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 *
                number += 0x1000;
        return Wb35Reg_ReadSync(pHwData, number, pValue);
 }
-#define hw_get_dxx_reg( _A, _B, _C ) hal_get_dxx_reg( _A, _B, (u32 *)_C )
+#define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
 
 static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
 {
@@ -354,7 +312,7 @@ static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 va
        ret = Wb35Reg_WriteSync(pHwData, number, value);
        return ret;
 }
-#define hw_set_dxx_reg( _A, _B, _C ) hal_set_dxx_reg( _A, _B, (u32)_C )
+#define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
 
 
 void _reset_rx_cal(struct hw_data *phw_data)
@@ -363,25 +321,20 @@ void _reset_rx_cal(struct hw_data *phw_data)
 
        hw_get_dxx_reg(phw_data, 0x54, &val);
 
-       if (phw_data->revision == 0x2002) // 1st-cut
-       {
+       if (phw_data->revision == 0x2002) /* 1st-cut */
                val &= 0xFFFF0000;
-       }
-       else // 2nd-cut
-       {
+       else /* 2nd-cut */
                val &= 0x000003FF;
-       }
 
        hw_set_dxx_reg(phw_data, 0x54, val);
 }
 
 
-// ************for winbond calibration*********
-//
+/**************for winbond calibration*********/
+
+
 
-//
-//
-// *********************************************
+/**********************************************/
 void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
 {
     u32     reg_agc_ctrl3;
@@ -392,35 +345,31 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
     PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
     phy_init_rf(phw_data);
 
-    // set calibration channel
-    if( (RF_WB_242 == phw_data->phy_type) ||
-               (RF_WB_242_1 == phw_data->phy_type) ) // 20060619.5 Add
-    {
-        if ((frequency >= 2412) && (frequency <= 2484))
-        {
-            // w89rf242 change frequency to 2390Mhz
+    /* set calibration channel */
+    if ((RF_WB_242 == phw_data->phy_type) ||
+               (RF_WB_242_1 == phw_data->phy_type)) /* 20060619.5 Add */{
+        if ((frequency >= 2412) && (frequency <= 2484)) {
+            /* w89rf242 change frequency to 2390Mhz */
             PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
                        phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
 
         }
-    }
-    else
-       {
+    } else {
 
        }
 
-       // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
+       /* reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
        hw_get_dxx_reg(phw_data, 0x5C, &val);
        val &= ~(0x03FF);
        hw_set_dxx_reg(phw_data, 0x5C, val);
 
-       // reset the TX and RX IQ calibration data
+       /* reset the TX and RX IQ calibration data */
        hw_set_dxx_reg(phw_data, 0x3C, 0);
        hw_set_dxx_reg(phw_data, 0x54, 0);
 
-       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
+       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
 
-       // a. Disable AGC
+       /* a. Disable AGC */
        hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
        reg_agc_ctrl3 &= ~BIT(2);
        reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
@@ -430,7 +379,7 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
        val |= MASK_AGC_FIX_GAIN;
        hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
 
-       // b. Turn off BB RX
+       /* b. Turn off BB RX */
        hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
        reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
        hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
@@ -439,9 +388,9 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
        reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
        hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
 
-       // c. Make sure MAC is in receiving mode
-       // d. Turn ON ADC calibration
-       //    - ADC calibrator is triggered by this signal rising from 0 to 1
+       /* c. Make sure MAC is in receiving mode
+        * d. Turn ON ADC calibration
+        *    - ADC calibrator is triggered by this signal rising from 0 to 1 */
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
        val &= ~MASK_ADC_DC_CAL_STR;
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
@@ -449,7 +398,7 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
        val |= MASK_ADC_DC_CAL_STR;
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
 
-       // e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]"
+       /* e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */
 #ifdef _DEBUG
        hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val);
        PHY_DEBUG(("[CAL]    REG_OFFSET_READ = 0x%08X\n", val));
@@ -464,23 +413,23 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
        val &= ~MASK_ADC_DC_CAL_STR;
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
 
-       // f. Turn on BB RX
-       //hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
+       /* f. Turn on BB RX */
+       /* hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl); */
        reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG;
        hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
 
-       //hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl);
+       /* hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl); */
        reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG;
        hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
 
-       // g. Enable AGC
-       //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
+       /* g. Enable AGC */
+       /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
        reg_agc_ctrl3 |= BIT(2);
        reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
        hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
 }
 
-////////////////////////////////////////////////////////
+/****************************************************************/
 void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
 {
        u32     reg_agc_ctrl3;
@@ -497,22 +446,22 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
 
        PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
 
-       // a. Set to "TX calibration mode"
+       /* a. Set to "TX calibration mode" */
 
-       //0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits
+       /* 0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
        phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
-       //0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit
+       /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
        phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
-       //0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
+       /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
        phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
-    //0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
+        /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
        phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
-       //0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode
+       /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
        phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
 
-       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
+       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
 
-       // a. Disable AGC
+       /* a. Disable AGC */
        hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
        reg_agc_ctrl3 &= ~BIT(2);
        reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
@@ -522,19 +471,19 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
        val |= MASK_AGC_FIX_GAIN;
        hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
 
-       // b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0
+       /* b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 */
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
 
        PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
        reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
 
-       // mode=2, tone=0
-       //reg_mode_ctrl |= (MASK_CALIB_START|2);
+       /* mode=2, tone=0 */
+       /* reg_mode_ctrl |= (MASK_CALIB_START|2); */
 
-       // mode=2, tone=1
-       //reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2));
+       /* mode=2, tone=1 */
+       /* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */
 
-       // mode=2, tone=2
+       /* mode=2, tone=2 */
        reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2));
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
@@ -542,12 +491,10 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
        hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
        PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
 
-       for (loop = 0; loop < LOOP_TIMES; loop++)
-       {
+       for (loop = 0; loop < LOOP_TIMES; loop++) {
                PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
 
-               // c.
-               // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
+               /* c. reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
                reg_dc_cancel &= ~(0x03FF);
                PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
                hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
@@ -562,7 +509,7 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
                PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
                                   mag_0, iqcal_image_i, iqcal_image_q));
 
-               // d.
+               /* d. */
                reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
                PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
                hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
@@ -577,18 +524,12 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
                PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
                                   mag_1, iqcal_image_i, iqcal_image_q));
 
-               // e. Calculate the correct DC offset cancellation value for I
+               /* e. Calculate the correct DC offset cancellation value for I */
                if (mag_0 != mag_1)
-               {
                        fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
-               }
-               else
-               {
+               else {
                        if (mag_0 == mag_1)
-                       {
                                PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
-                       }
-
                        fix_cancel_dc_i = 0;
                }
 
@@ -596,12 +537,10 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
                                   fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
 
                if ((abs(mag_1-mag_0)*6) > mag_0)
-               {
                        break;
-               }
        }
 
-       if ( loop >= 19 )
+       if (loop >= 19)
           fix_cancel_dc_i = 0;
 
        reg_dc_cancel &= ~(0x03FF);
@@ -609,13 +548,13 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
        hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
        PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
 
-       // g.
+       /* g. */
        reg_mode_ctrl &= ~MASK_CALIB_START;
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 }
 
-///////////////////////////////////////////////////////
+/*****************************************************/
 void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
 {
        u32     reg_agc_ctrl3;
@@ -631,20 +570,20 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
        int     loop;
 
        PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
-       //0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits
+       /*0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
        phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
-       //0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit
+       /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
        phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
-       //0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
+       /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
        phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
-    //0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
+        /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
        phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
-       //0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode
+       /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
        phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
 
-       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
+       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
 
-       // a. Disable AGC
+       /* a. Disable AGC */
        hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
        reg_agc_ctrl3 &= ~BIT(2);
        reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
@@ -654,11 +593,11 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
        val |= MASK_AGC_FIX_GAIN;
        hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
 
-       // a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0
+       /* a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 */
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
        PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
 
-       //reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
+       /* reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); */
        reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
        reg_mode_ctrl |= (MASK_CALIB_START|3);
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
@@ -667,12 +606,10 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
        hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
        PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
 
-       for (loop = 0; loop < LOOP_TIMES; loop++)
-       {
+       for (loop = 0; loop < LOOP_TIMES; loop++) {
                PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
 
-               // b.
-               // reset cancel_dc_q[4:0] in register DC_Cancel
+               /* b. reset cancel_dc_q[4:0] in register DC_Cancel */
                reg_dc_cancel &= ~(0x001F);
                PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
                hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
@@ -687,7 +624,7 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
                PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
                                   mag_0, iqcal_image_i, iqcal_image_q));
 
-               // c.
+               /* c. */
                reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
                PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
                hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
@@ -702,18 +639,12 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
                PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
                                   mag_1, iqcal_image_i, iqcal_image_q));
 
-               // d. Calculate the correct DC offset cancellation value for I
+               /* d. Calculate the correct DC offset cancellation value for I */
                if (mag_0 != mag_1)
-               {
                        fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
-               }
-               else
-               {
+               else {
                        if (mag_0 == mag_1)
-                       {
                                PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
-                       }
-
                        fix_cancel_dc_q = 0;
                }
 
@@ -721,12 +652,10 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
                                   fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
 
                if ((abs(mag_1-mag_0)*6) > mag_0)
-               {
                        break;
-               }
        }
 
-       if ( loop >= 19 )
+       if (loop >= 19)
           fix_cancel_dc_q = 0;
 
        reg_dc_cancel &= ~(0x001F);
@@ -735,13 +664,13 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
        PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
 
 
-       // f.
+       /* f. */
        reg_mode_ctrl &= ~MASK_CALIB_START;
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 }
 
-//20060612.1.a 20060718.1 Modify
+/* 20060612.1.a 20060718.1 Modify */
 u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                                                   s32 a_2_threshold,
                                                   s32 b_2_threshold)
@@ -765,7 +694,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
        s32     temp1, temp2;
        u32     val;
        u16     loop;
-       s32     iqcal_tone_i_avg,iqcal_tone_q_avg;
+       s32     iqcal_tone_i_avg, iqcal_tone_q_avg;
        u8      verify_count;
        int capture_time;
 
@@ -780,18 +709,18 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
 
        loop = LOOP_TIMES;
 
-       while (loop > 0)
-       {
+       while (loop > 0) {
                PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
 
-               iqcal_tone_i_avg=0;
-               iqcal_tone_q_avg=0;
-               if( !hw_set_dxx_reg(phw_data, 0x3C, 0x00) ) // 20060718.1 modify
+               iqcal_tone_i_avg = 0;
+               iqcal_tone_q_avg = 0;
+               if (!hw_set_dxx_reg(phw_data, 0x3C, 0x00)) /* 20060718.1 modify */
                        return 0;
-               for(capture_time=0;capture_time<10;capture_time++)
-               {
-                       // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
-                       //    enable "IQ alibration Mode II"
+               for (capture_time = 0; capture_time < 10; capture_time++) {
+                       /*
+                        * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
+                        *    enable "IQ alibration Mode II"
+                        */
                        reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
                        reg_mode_ctrl &= ~MASK_IQCAL_MODE;
                        reg_mode_ctrl |= (MASK_CALIB_START|0x02);
@@ -799,7 +728,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
                        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
-                       // b.
+                       /* b. */
                        hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
                        PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
 
@@ -813,21 +742,23 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        iq_mag_0_tx = (s32) _sqrt(sqsum);
                        PHY_DEBUG(("[CAL]    ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
 
-                       // c. Set "calib_start" to 0x0
+                       /* c. Set "calib_start" to 0x0 */
                        reg_mode_ctrl &= ~MASK_CALIB_START;
                        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
                        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
-                       // d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
-                       //    enable "IQ alibration Mode II"
-                       //hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
+                       /*
+                        * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
+                        *    enable "IQ alibration Mode II"
+                        */
+                       /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
                        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
                        reg_mode_ctrl &= ~MASK_IQCAL_MODE;
                        reg_mode_ctrl |= (MASK_CALIB_START|0x03);
                        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
                        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
-                       // e.
+                       /* e. */
                        hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
                        PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
 
@@ -835,14 +766,11 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
                        PHY_DEBUG(("[CAL]    ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
                        iqcal_tone_i, iqcal_tone_q));
-                       if( capture_time == 0)
-                       {
+                       if (capture_time == 0)
                                continue;
-                       }
-                       else
-                       {
-                               iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
-                               iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
+                       else {
+                               iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
+                               iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
                        }
                }
 
@@ -857,11 +785,10 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                PHY_DEBUG(("[CAL]    ** rot_i_b = %d, rot_q_b = %d\n",
                                   rot_i_b, rot_q_b));
 
-               // f.
+               /* f. */
                divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
 
-               if (divisor == 0)
-               {
+               if (divisor == 0) {
                        PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
                        PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
                        PHY_DEBUG(("[CAL] ******************************************\n"));
@@ -876,18 +803,16 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                phw_data->iq_rsdl_gain_tx_d2 = a_2;
                phw_data->iq_rsdl_phase_tx_d2 = b_2;
 
-               //if ((abs(a_2) < 150) && (abs(b_2) < 100))
-               //if ((abs(a_2) < 200) && (abs(b_2) < 200))
-               if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold))
-               {
+               /* if ((abs(a_2) < 150) && (abs(b_2) < 100)) */
+               /* if ((abs(a_2) < 200) && (abs(b_2) < 200)) */
+               if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold)) {
                        verify_count++;
 
                        PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
                        PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
                        PHY_DEBUG(("[CAL] ******************************************\n"));
 
-                       if (verify_count > 2)
-                       {
+                       if (verify_count > 2) {
                                PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
                                PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
                                PHY_DEBUG(("[CAL] **************************************\n"));
@@ -895,37 +820,29 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        }
 
                        continue;
-               }
-               else
-               {
+               } else
                        verify_count = 0;
-               }
 
                _sin_cos(b_2, &sin_b, &cos_b);
                _sin_cos(b_2*2, &sin_2b, &cos_2b);
                PHY_DEBUG(("[CAL]    ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
                PHY_DEBUG(("[CAL]    ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
 
-               if (cos_2b == 0)
-               {
+               if (cos_2b == 0) {
                        PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
                        PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
                        PHY_DEBUG(("[CAL] ******************************************\n"));
                        break;
                }
 
-               // 1280 * 32768 = 41943040
+               /* 1280 * 32768 = 41943040 */
                temp1 = (41943040/cos_2b)*cos_b;
 
-               //temp2 = (41943040/cos_2b)*sin_b*(-1);
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
+               /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
+               if (phw_data->revision == 0x2002) /* 1st-cut */
                        temp2 = (41943040/cos_2b)*sin_b*(-1);
-               }
-               else // 2nd-cut
-               {
+               else /* 2nd-cut */
                        temp2 = (41943040*4/cos_2b)*sin_b*(-1);
-               }
 
                tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
                tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
@@ -937,37 +854,34 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                PHY_DEBUG(("[CAL]       tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
 
                tx_cal[2] = tx_cal_flt_b[2];
-               tx_cal[2] = tx_cal[2] +3;
+               tx_cal[2] = tx_cal[2] + 3;
                tx_cal[1] = tx_cal[2];
                tx_cal[3] = tx_cal_flt_b[3] - 128;
-               tx_cal[0] = -tx_cal[3]+1;
+               tx_cal[0] = -tx_cal[3] + 1;
 
                PHY_DEBUG(("[CAL]       tx_cal[0] = %d\n", tx_cal[0]));
                PHY_DEBUG(("[CAL]       tx_cal[1] = %d\n", tx_cal[1]));
                PHY_DEBUG(("[CAL]       tx_cal[2] = %d\n", tx_cal[2]));
                PHY_DEBUG(("[CAL]       tx_cal[3] = %d\n", tx_cal[3]));
 
-               //if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
-               //    (tx_cal[2] == 0) && (tx_cal[3] == 0))
-               //{
-               //    PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
-               //    PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
-               //    PHY_DEBUG(("[CAL] ******************************************\n"));
-               //    return 0;
-               //}
-
-               // g.
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
+               /* if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
+                     (tx_cal[2] == 0) && (tx_cal[3] == 0))
+                 { */
+               /*    PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
+                *    PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
+                *    PHY_DEBUG(("[CAL] ******************************************\n"));
+                *    return 0;
+                 } */
+
+               /* g. */
+               if (phw_data->revision == 0x2002) /* 1st-cut */{
                        hw_get_dxx_reg(phw_data, 0x54, &val);
                        PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
                        tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
                        tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
                        tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
                        tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
-               }
-               else // 2nd-cut
-               {
+               } else /* 2nd-cut */{
                        hw_get_dxx_reg(phw_data, 0x3C, &val);
                        PHY_DEBUG(("[CAL]    ** 0x3C = 0x%08X\n", val));
                        tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
@@ -982,22 +896,17 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                PHY_DEBUG(("[CAL]       tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
                PHY_DEBUG(("[CAL]       tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
 
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
-                       if (((tx_cal_reg[0]==7) || (tx_cal_reg[0]==(-8))) &&
-                               ((tx_cal_reg[3]==7) || (tx_cal_reg[3]==(-8))))
-                       {
+               if (phw_data->revision == 0x2002) /* 1st-cut */{
+                       if (((tx_cal_reg[0] == 7) || (tx_cal_reg[0] == (-8))) &&
+                               ((tx_cal_reg[3] == 7) || (tx_cal_reg[3] == (-8)))) {
                                PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
                                PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
                                PHY_DEBUG(("[CAL] **************************************\n"));
                                break;
                        }
-               }
-               else // 2nd-cut
-               {
-                       if (((tx_cal_reg[0]==31) || (tx_cal_reg[0]==(-32))) &&
-                               ((tx_cal_reg[3]==31) || (tx_cal_reg[3]==(-32))))
-                       {
+               } else /* 2nd-cut */{
+                       if (((tx_cal_reg[0] == 31) || (tx_cal_reg[0] == (-32))) &&
+                               ((tx_cal_reg[3] == 31) || (tx_cal_reg[3] == (-32)))) {
                                PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
                                PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
                                PHY_DEBUG(("[CAL] **************************************\n"));
@@ -1014,8 +923,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                PHY_DEBUG(("[CAL]       apply tx_cal[2] = %d\n", tx_cal[2]));
                PHY_DEBUG(("[CAL]       apply tx_cal[3] = %d\n", tx_cal[3]));
 
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
+               if (phw_data->revision == 0x2002) /* 1st-cut */{
                        val &= 0x0000FFFF;
                        val |= ((_s32_to_s4(tx_cal[0]) << 28)|
                                        (_s32_to_s4(tx_cal[1]) << 24)|
@@ -1024,9 +932,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        hw_set_dxx_reg(phw_data, 0x54, val);
                        PHY_DEBUG(("[CAL]    ** CALIB_DATA = 0x%08X\n", val));
                        return 0;
-               }
-               else // 2nd-cut
-               {
+               } else /* 2nd-cut */{
                        val &= 0x000003FF;
                        val |= ((_s32_to_s5(tx_cal[0]) << 27)|
                                        (_s32_to_s6(tx_cal[1]) << 21)|
@@ -1037,7 +943,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        return 0;
                }
 
-               // i. Set "calib_start" to 0x0
+               /* i. Set "calib_start" to 0x0 */
                reg_mode_ctrl &= ~MASK_CALIB_START;
                hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
                PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
@@ -1061,26 +967,26 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 
        PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
 
-       //0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits
+       /* 0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
        phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
-       //0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit
-       phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); // 20060612.1.a 0x1905D6);
-       //0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
-       phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); //0x24C60A (high temperature)
-    //0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
-       phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); // 20060612.1.a 0x06890C);
-       //0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode
+       /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
+       phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); /* 20060612.1.a 0x1905D6); */
+       /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
+       phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); /* 0x24C60A (high temperature) */
+        /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
+       phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); /* 20060612.1.a 0x06890C); */
+       /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
        phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
-       //; [BB-chip]: Calibration (6f).Send test pattern
-       //; [BB-chip]: Calibration (6g). Search RXGCL optimal value
-       //; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table
-       //phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
+       /* ; [BB-chip]: Calibration (6f).Send test pattern */
+       /* ; [BB-chip]: Calibration (6g). Search RXGCL optimal value */
+       /* ; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table */
+       /* phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); */
 
-       msleep(30); // 20060612.1.a 30ms delay. Add the follow 2 lines
-       //To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750
-       adjust_TXVGA_for_iq_mag( phw_data );
+       msleep(30); /* 20060612.1.a 30ms delay. Add the follow 2 lines */
+       /* To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750 */
+       adjust_TXVGA_for_iq_mag(phw_data);
 
-       // a. Disable AGC
+       /* a. Disable AGC */
        hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
        reg_agc_ctrl3 &= ~BIT(2);
        reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
@@ -1092,16 +998,12 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 
        result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
 
-       if (result > 0)
-       {
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
+       if (result > 0) {
+               if (phw_data->revision == 0x2002) /* 1st-cut */{
                        hw_get_dxx_reg(phw_data, 0x54, &val);
                        val &= 0x0000FFFF;
                        hw_set_dxx_reg(phw_data, 0x54, val);
-               }
-               else // 2nd-cut
-               {
+               } else /* 2nd-cut*/{
                        hw_get_dxx_reg(phw_data, 0x3C, &val);
                        val &= 0x000003FF;
                        hw_set_dxx_reg(phw_data, 0x3C, val);
@@ -1109,32 +1011,24 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 
                result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
 
-               if (result > 0)
-               {
-                       if (phw_data->revision == 0x2002) // 1st-cut
-                       {
+               if (result > 0) {
+                       if (phw_data->revision == 0x2002) /* 1st-cut */{
                                hw_get_dxx_reg(phw_data, 0x54, &val);
                                val &= 0x0000FFFF;
                                hw_set_dxx_reg(phw_data, 0x54, val);
-                       }
-                       else // 2nd-cut
-                       {
+                       } else /* 2nd-cut*/{
                                hw_get_dxx_reg(phw_data, 0x3C, &val);
                                val &= 0x000003FF;
                                hw_set_dxx_reg(phw_data, 0x3C, val);
                        }
 
                        result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
-                       if (result > 0)
-                       {
-                               if (phw_data->revision == 0x2002) // 1st-cut
-                               {
+                       if (result > 0) {
+                               if (phw_data->revision == 0x2002) /* 1st-cut */{
                                        hw_get_dxx_reg(phw_data, 0x54, &val);
                                        val &= 0x0000FFFF;
                                        hw_set_dxx_reg(phw_data, 0x54, val);
-                               }
-                               else // 2nd-cut
-                               {
+                               } else /* 2nd-cut */{
                                        hw_get_dxx_reg(phw_data, 0x3C, &val);
                                        val &= 0x000003FF;
                                        hw_set_dxx_reg(phw_data, 0x3C, val);
@@ -1143,20 +1037,16 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 
                                result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
 
-                               if (result > 0)
-                               {
+                               if (result > 0) {
                                        PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
                                        PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
                                        PHY_DEBUG(("[CAL] **************************************\n"));
 
-                                       if (phw_data->revision == 0x2002) // 1st-cut
-                                       {
+                                       if (phw_data->revision == 0x2002) /* 1st-cut */{
                                                hw_get_dxx_reg(phw_data, 0x54, &val);
                                                val &= 0x0000FFFF;
                                                hw_set_dxx_reg(phw_data, 0x54, val);
-                                       }
-                                       else // 2nd-cut
-                                       {
+                                       } else /* 2nd-cut */{
                                                hw_get_dxx_reg(phw_data, 0x3C, &val);
                                                val &= 0x000003FF;
                                                hw_set_dxx_reg(phw_data, 0x3C, val);
@@ -1166,30 +1056,27 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data)
                }
        }
 
-       // i. Set "calib_start" to 0x0
+       /* i. Set "calib_start" to 0x0 */
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
        reg_mode_ctrl &= ~MASK_CALIB_START;
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
-       // g. Enable AGC
-       //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
+       /* g. Enable AGC */
+       /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
        reg_agc_ctrl3 |= BIT(2);
        reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
        hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
 
 #ifdef _DEBUG
-       if (phw_data->revision == 0x2002) // 1st-cut
-       {
+       if (phw_data->revision == 0x2002) /* 1st-cut */{
                hw_get_dxx_reg(phw_data, 0x54, &val);
                PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
                tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
                tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
                tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
                tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
-       }
-       else // 2nd-cut
-       {
+       } else /* 2nd-cut */ {
                hw_get_dxx_reg(phw_data, 0x3C, &val);
                PHY_DEBUG(("[CAL]    ** 0x3C = 0x%08X\n", val));
                tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
@@ -1206,11 +1093,13 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 #endif
 
 
-       // for test - BEN
-       // RF Control Override
+       /*
+        * for test - BEN
+        * RF Control Override
+        */
 }
 
-/////////////////////////////////////////////////////////////////////////////////////////
+/*****************************************************/
 u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
 {
        u32     reg_mode_ctrl;
@@ -1236,51 +1125,49 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
        u32     pwr_image;
        u8      verify_count;
 
-       s32     iqcal_tone_i_avg,iqcal_tone_q_avg;
-       s32     iqcal_image_i_avg,iqcal_image_q_avg;
-       u16             capture_time;
+       s32     iqcal_tone_i_avg, iqcal_tone_q_avg;
+       s32     iqcal_image_i_avg, iqcal_image_q_avg;
+       u16     capture_time;
 
        PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
        PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
 
 
-// RF Control Override
+/* RF Control Override */
        hw_get_cxx_reg(phw_data, 0x80, &val);
        val |= BIT(19);
        hw_set_cxx_reg(phw_data, 0x80, val);
 
-// RF_Ctrl
+/* RF_Ctrl */
        hw_get_cxx_reg(phw_data, 0xE4, &val);
        val |= BIT(0);
        hw_set_cxx_reg(phw_data, 0xE4, val);
        PHY_DEBUG(("[CAL] ** RF_CTRL(0xE4) = 0x%08X", val));
 
-       hw_set_dxx_reg(phw_data, 0x58, 0x44444444); // IQ_Alpha
+       hw_set_dxx_reg(phw_data, 0x58, 0x44444444); /* IQ_Alpha */
 
-       // b.
+       /* b. */
 
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
        PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
 
        verify_count = 0;
 
-       //for (loop = 0; loop < 1; loop++)
-       //for (loop = 0; loop < LOOP_TIMES; loop++)
+       /* for (loop = 0; loop < 1; loop++) */
+       /* for (loop = 0; loop < LOOP_TIMES; loop++) */
        loop = LOOP_TIMES;
-       while (loop > 0)
-       {
+       while (loop > 0) {
                PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
-               iqcal_tone_i_avg=0;
-               iqcal_tone_q_avg=0;
-               iqcal_image_i_avg=0;
-               iqcal_image_q_avg=0;
-               capture_time=0;
-
-               for(capture_time=0; capture_time<10; capture_time++)
-               {
-               // i. Set "calib_start" to 0x0
+               iqcal_tone_i_avg = 0;
+               iqcal_tone_q_avg = 0;
+               iqcal_image_i_avg = 0;
+               iqcal_image_q_avg = 0;
+               capture_time = 0;
+
+               for (capture_time = 0; capture_time < 10; capture_time++) {
+               /* i. Set "calib_start" to 0x0 */
                reg_mode_ctrl &= ~MASK_CALIB_START;
-               if( !hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl) )//20060718.1 modify
+               if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */
                        return 0;
                PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
@@ -1289,7 +1176,7 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
                PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
-               // c.
+               /* c. */
                hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
                PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
 
@@ -1305,16 +1192,13 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
                PHY_DEBUG(("[CAL]    ** iqcal_image_i = %d, iqcal_image_q = %d\n",
                                   iqcal_image_i, iqcal_image_q));
-                       if( capture_time == 0)
-                       {
+                       if (capture_time == 0)
                                continue;
-                       }
-                       else
-                       {
-                               iqcal_image_i_avg=( iqcal_image_i_avg*(capture_time-1) +iqcal_image_i)/capture_time;
-                               iqcal_image_q_avg=( iqcal_image_q_avg*(capture_time-1) +iqcal_image_q)/capture_time;
-                               iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
-                               iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
+                       else {
+                               iqcal_image_i_avg = (iqcal_image_i_avg*(capture_time-1) + iqcal_image_i)/capture_time;
+                               iqcal_image_q_avg = (iqcal_image_q_avg*(capture_time-1) + iqcal_image_q)/capture_time;
+                               iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
+                               iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
                        }
                }
 
@@ -1324,7 +1208,7 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                iqcal_tone_i = iqcal_tone_i_avg;
                iqcal_tone_q = iqcal_tone_q_avg;
 
-               // d.
+               /* d. */
                rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
                                                iqcal_tone_q * iqcal_tone_q) / 1024;
                rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
@@ -1339,9 +1223,8 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                PHY_DEBUG(("[CAL]    ** rot_image_i_b = %d\n", rot_image_i_b));
                PHY_DEBUG(("[CAL]    ** rot_image_q_b = %d\n", rot_image_q_b));
 
-               // f.
-               if (rot_tone_i_b == 0)
-               {
+               /* f. */
+               if (rot_tone_i_b == 0) {
                        PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
                        PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
                        PHY_DEBUG(("[CAL] ******************************************\n"));
@@ -1363,26 +1246,21 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                PHY_DEBUG(("[CAL]    ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
                PHY_DEBUG(("[CAL]    ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
 
-               if (cos_2b == 0)
-               {
+               if (cos_2b == 0) {
                        PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
                        PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
                        PHY_DEBUG(("[CAL] ******************************************\n"));
                        break;
                }
 
-               // 1280 * 32768 = 41943040
+               /* 1280 * 32768 = 41943040 */
                temp1 = (41943040/cos_2b)*cos_b;
 
-               //temp2 = (41943040/cos_2b)*sin_b*(-1);
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
+               /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
+               if (phw_data->revision == 0x2002)/* 1st-cut */
                        temp2 = (41943040/cos_2b)*sin_b*(-1);
-               }
-               else // 2nd-cut
-               {
+               else/* 2nd-cut */
                        temp2 = (41943040*4/cos_2b)*sin_b*(-1);
-               }
 
                rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
                rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
@@ -1403,23 +1281,21 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                PHY_DEBUG(("[CAL]       rx_cal[2] = %d\n", rx_cal[2]));
                PHY_DEBUG(("[CAL]       rx_cal[3] = %d\n", rx_cal[3]));
 
-               // e.
+               /* e. */
                pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
                pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
 
                PHY_DEBUG(("[CAL]    ** pwr_tone  = %d\n", pwr_tone));
                PHY_DEBUG(("[CAL]    ** pwr_image  = %d\n", pwr_image));
 
-               if (pwr_tone > pwr_image)
-               {
+               if (pwr_tone > pwr_image) {
                        verify_count++;
 
                        PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
                        PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
                        PHY_DEBUG(("[CAL] ******************************************\n"));
 
-                       if (verify_count > 2)
-                       {
+                       if (verify_count > 2) {
                                PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
                                PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
                                PHY_DEBUG(("[CAL] **************************************\n"));
@@ -1428,19 +1304,16 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
 
                        continue;
                }
-               // g.
+               /* g. */
                hw_get_dxx_reg(phw_data, 0x54, &val);
                PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
 
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
+               if (phw_data->revision == 0x2002) /* 1st-cut */{
                        rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
                        rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >>  8);
                        rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >>  4);
                        rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
-               }
-               else // 2nd-cut
-               {
+               } else /* 2nd-cut */{
                        rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
                        rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
                        rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
@@ -1452,22 +1325,17 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                PHY_DEBUG(("[CAL]       rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
                PHY_DEBUG(("[CAL]       rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
 
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
-                       if (((rx_cal_reg[0]==7) || (rx_cal_reg[0]==(-8))) &&
-                               ((rx_cal_reg[3]==7) || (rx_cal_reg[3]==(-8))))
-                       {
+               if (phw_data->revision == 0x2002) /* 1st-cut */{
+                       if (((rx_cal_reg[0] == 7) || (rx_cal_reg[0] == (-8))) &&
+                               ((rx_cal_reg[3] == 7) || (rx_cal_reg[3] == (-8)))) {
                                PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
                                PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
                                PHY_DEBUG(("[CAL] **************************************\n"));
                                break;
                        }
-               }
-               else // 2nd-cut
-               {
-                       if (((rx_cal_reg[0]==31) || (rx_cal_reg[0]==(-32))) &&
-                               ((rx_cal_reg[3]==31) || (rx_cal_reg[3]==(-32))))
-                       {
+               } else /* 2nd-cut */{
+                       if (((rx_cal_reg[0] == 31) || (rx_cal_reg[0] == (-32))) &&
+                               ((rx_cal_reg[3] == 31) || (rx_cal_reg[3] == (-32)))) {
                                PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
                                PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
                                PHY_DEBUG(("[CAL] **************************************\n"));
@@ -1485,17 +1353,14 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                PHY_DEBUG(("[CAL]       apply rx_cal[3] = %d\n", rx_cal[3]));
 
                hw_get_dxx_reg(phw_data, 0x54, &val);
-               if (phw_data->revision == 0x2002) // 1st-cut
-               {
+               if (phw_data->revision == 0x2002) /* 1st-cut */{
                        val &= 0x0000FFFF;
                        val |= ((_s32_to_s4(rx_cal[0]) << 12)|
                                        (_s32_to_s4(rx_cal[1]) <<  8)|
                                        (_s32_to_s4(rx_cal[2]) <<  4)|
                                        (_s32_to_s4(rx_cal[3])));
                        hw_set_dxx_reg(phw_data, 0x54, val);
-               }
-               else // 2nd-cut
-               {
+               } else /* 2nd-cut */{
                        val &= 0x000003FF;
                        val |= ((_s32_to_s5(rx_cal[0]) << 27)|
                                        (_s32_to_s6(rx_cal[1]) << 21)|
@@ -1503,7 +1368,7 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                                        (_s32_to_s5(rx_cal[3]) << 10));
                        hw_set_dxx_reg(phw_data, 0x54, val);
 
-                       if( loop == 3 )
+                       if (loop == 3)
                        return 0;
                }
                PHY_DEBUG(("[CAL]    ** CALIB_DATA = 0x%08X\n", val));
@@ -1514,12 +1379,12 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
        return 1;
 }
 
-//////////////////////////////////////////////////////////
+/*************************************************/
 
-//////////////////////////////////////////////////////////////////////////
+/***************************************************************/
 void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 {
-// figo 20050523 marked thsi flag for can't compile for relesase
+/* figo 20050523 marked this flag for can't compile for relesase */
 #ifdef _DEBUG
        s32     rx_cal_reg[4];
        u32     val;
@@ -1528,37 +1393,34 @@ void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
        u8      result;
 
        PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
-// a. Set RFIC to "RX calibration mode"
-       //; ----- Calibration (7). RX path IQ imbalance calibration loop
-       //      0x01 0xFFBFC2  ; 3FEFF  ; Calibration (7a). enable RX IQ calibration loop circuits
+/* a. Set RFIC to "RX calibration mode" */
+       /* ; ----- Calibration (7). RX path IQ imbalance calibration loop */
+       /*      0x01 0xFFBFC2  ; 3FEFF  ; Calibration (7a). enable RX IQ calibration loop circuits */
        phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
-       //      0x0B 0x1A01D6  ; 06817  ; Calibration (7b). enable RX I/Q cal loop SW1 circuit
+       /*      0x0B 0x1A01D6  ; 06817  ; Calibration (7b). enable RX I/Q cal loop SW1 circuits */
        phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
-       //0x05 0x24848A  ; 09212  ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized
-       phy_set_rf_data(phw_data, 5, (5<<24)| phw_data->txvga_setting_for_cal);
-       //0x06 0x06840C  ; 01A10  ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized
+       /* 0x05 0x24848A  ; 09212  ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized */
+       phy_set_rf_data(phw_data, 5, (5<<24) | phw_data->txvga_setting_for_cal);
+       /* 0x06 0x06840C  ; 01A10  ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized */
        phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
-       //0x00 0xFFF1C0  ; 3F7C7  ; Calibration (7e). turn on IQ imbalance/Test mode
+       /* 0x00 0xFFF1C0  ; 3F7C7  ; Calibration (7e). turn on IQ imbalance/Test mode */
        phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
 
-       //  ; [BB-chip]: Calibration (7f). Send test pattern
-       //      ; [BB-chip]: Calibration (7g). Search RXGCL optimal value
-       //      ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table
+       /*  ; [BB-chip]: Calibration (7f). Send test pattern */
+       /*      ; [BB-chip]: Calibration (7g). Search RXGCL optimal value */
+       /*      ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table */
 
        result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
 
-       if (result > 0)
-       {
+       if (result > 0) {
                _reset_rx_cal(phw_data);
                result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
 
-               if (result > 0)
-               {
+               if (result > 0) {
                        _reset_rx_cal(phw_data);
                        result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
 
-                       if (result > 0)
-                       {
+                       if (result > 0) {
                                PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
                                PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
                                PHY_DEBUG(("[CAL] **************************************\n"));
@@ -1571,15 +1433,12 @@ void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
        hw_get_dxx_reg(phw_data, 0x54, &val);
        PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
 
-       if (phw_data->revision == 0x2002) // 1st-cut
-       {
+       if (phw_data->revision == 0x2002) /* 1st-cut */{
                rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
                rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >>  8);
                rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >>  4);
                rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
-       }
-       else // 2nd-cut
-       {
+       } else /* 2nd-cut */{
                rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
                rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
                rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
@@ -1594,7 +1453,7 @@ void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 
 }
 
-////////////////////////////////////////////////////////////////////////
+/*******************************************************/
 void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 {
        u32     reg_mode_ctrl;
@@ -1602,7 +1461,7 @@ void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 
        PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
 
-       // 20040701 1.1.25.1000 kevin
+       /* 20040701 1.1.25.1000 kevin */
        hw_get_cxx_reg(phw_data, 0x80, &mac_ctrl);
        hw_get_cxx_reg(phw_data, 0xE4, &rf_ctrl);
        hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
@@ -1610,72 +1469,71 @@ void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 
 
        _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
-       //_txidac_dc_offset_cancellation_winbond(phw_data);
-       //_txqdac_dc_offset_cacellation_winbond(phw_data);
+       /* _txidac_dc_offset_cancellation_winbond(phw_data); */
+       /* _txqdac_dc_offset_cacellation_winbond(phw_data); */
 
        _tx_iq_calibration_winbond(phw_data);
        _rx_iq_calibration_winbond(phw_data, frequency);
 
-       //------------------------------------------------------------------------
+       /*********************************************************************/
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
-       reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); // set when finish
+       reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); /* set when finish */
        hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
-       // i. Set RFIC to "Normal mode"
+       /* i. Set RFIC to "Normal mode" */
        hw_set_cxx_reg(phw_data, 0x80, mac_ctrl);
        hw_set_cxx_reg(phw_data, 0xE4, rf_ctrl);
        hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
 
 
-       //------------------------------------------------------------------------
+       /*********************************************************************/
        phy_init_rf(phw_data);
 
 }
 
-//===========================
-void phy_set_rf_data(  struct hw_data * pHwData,  u32 index,  u32 value )
+/******************/
+void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value)
 {
-   u32 ltmp=0;
-
-    switch( pHwData->phy_type )
-       {
-               case RF_MAXIM_2825:
-               case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
-                       ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
-                       break;
-
-               case RF_MAXIM_2827:
-                       ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
-                       break;
-
-               case RF_MAXIM_2828:
-                       ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
-                       break;
-
-               case RF_MAXIM_2829:
-                       ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
-                       break;
-
-               case RF_AIROHA_2230:
-               case RF_AIROHA_2230S: // 20060420 Add this
-                       ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( value, 20 );
-                       break;
-
-               case RF_AIROHA_7230:
-                       ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
-                       break;
-
-               case RF_WB_242:
-               case RF_WB_242_1: // 20060619.5 Add
-                       ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( value, 24 );
-                       break;
-       }
+   u32 ltmp = 0;
+
+    switch (pHwData->phy_type) {
+    case RF_MAXIM_2825:
+    case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */
+            ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
+            break;
+
+    case RF_MAXIM_2827:
+            ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
+           break;
+
+    case RF_MAXIM_2828:
+           ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
+           break;
+
+    case RF_MAXIM_2829:
+           ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
+           break;
+
+    case RF_AIROHA_2230:
+    case RF_AIROHA_2230S: /* 20060420 Add this */
+           ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20);
+           break;
+
+    case RF_AIROHA_7230:
+           ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
+           break;
+
+    case RF_WB_242:
+    case RF_WB_242_1:/* 20060619.5 Add */
+           ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24);
+           break;
+    }
 
-       Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+       Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
 }
 
-// 20060717 modify as Bruce's mail
+/* 20060717 modify as Bruce's mail */
 unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
 {
        int init_txvga = 0;
@@ -1685,26 +1543,27 @@ unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
        s32     iqcal_tone_q0;
        u32     sqsum;
        s32     iq_mag_0_tx;
-       u8              reg_state;
-       int             current_txvga;
+       u8      reg_state;
+       int     current_txvga;
 
 
        reg_state = 0;
-       for( init_txvga=0; init_txvga<10; init_txvga++)
-       {
-               current_txvga = ( 0x24C40A|(init_txvga<<6) );
-               phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga) );
+       for (init_txvga = 0; init_txvga < 10; init_txvga++) {
+               current_txvga = (0x24C40A|(init_txvga<<6));
+               phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga));
                phw_data->txvga_setting_for_cal = current_txvga;
 
-               msleep(30); // 20060612.1.a
+               msleep(30);/* 20060612.1.a */
 
-               if( !hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl) ) // 20060718.1 modify
+               if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl))/* 20060718.1 modify */
                        return false;
 
                PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
 
-               // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
-               //    enable "IQ alibration Mode II"
+               /*
+                * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
+                *    enable "IQ alibration Mode II"
+                */
                reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
                reg_mode_ctrl &= ~MASK_IQCAL_MODE;
                reg_mode_ctrl |= (MASK_CALIB_START|0x02);
@@ -1712,15 +1571,15 @@ unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
                hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
                PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
-               udelay(1); // 20060612.1.a
+               udelay(1);/* 20060612.1.a */
 
-               udelay(300); // 20060612.1.a
+               udelay(300);/* 20060612.1.a */
 
-               // b.
+               /* b. */
                hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
 
                PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
-               udelay(300); // 20060612.1.a
+               udelay(300);/* 20060612.1.a */
 
                iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
                iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
@@ -1731,23 +1590,18 @@ unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
                iq_mag_0_tx = (s32) _sqrt(sqsum);
                PHY_DEBUG(("[CAL]    ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
 
-               if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
+               if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
                        break;
-               else if(iq_mag_0_tx > 1750)
-               {
-                       init_txvga=-2;
+               else if (iq_mag_0_tx > 1750) {
+                       init_txvga = -2;
                        continue;
-               }
-               else
+               } else
                        continue;
 
        }
 
-       if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
+       if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
                return true;
        else
                return false;
 }
-
-
-
index d9a8128b21f0ac5c0e817c4a521e23576873aef2..990f9d4bdbbd992ffac811632a2daaf7aa1241f2 100644 (file)
@@ -966,42 +966,42 @@ void RFSynthesizer_initial(struct hw_data *pHwData)
        switch (pHwData->phy_type) {
        case RF_MAXIM_2825:
        case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */
-               number = sizeof(max2825_rf_data) / sizeof(max2825_rf_data[0]);
+               number = ARRAY_SIZE(max2825_rf_data);
                for (i = 0; i < number; i++) {
                        pHwData->phy_para[i] = max2825_rf_data[i]; /* Backup Rf parameter */
                        pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2825_rf_data[i], 18);
                }
                break;
        case RF_MAXIM_2827:
-               number = sizeof(max2827_rf_data) / sizeof(max2827_rf_data[0]);
+               number = ARRAY_SIZE(max2827_rf_data);
                for (i = 0; i < number; i++) {
                        pHwData->phy_para[i] = max2827_rf_data[i];
                        pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2827_rf_data[i], 18);
                }
                break;
        case RF_MAXIM_2828:
-               number = sizeof(max2828_rf_data) / sizeof(max2828_rf_data[0]);
+               number = ARRAY_SIZE(max2828_rf_data);
                for (i = 0; i < number; i++) {
                        pHwData->phy_para[i] = max2828_rf_data[i];
                        pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2828_rf_data[i], 18);
                }
                break;
        case RF_MAXIM_2829:
-               number = sizeof(max2829_rf_data) / sizeof(max2829_rf_data[0]);
+               number = ARRAY_SIZE(max2829_rf_data);
                for (i = 0; i < number; i++) {
                        pHwData->phy_para[i] = max2829_rf_data[i];
                        pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2829_rf_data[i], 18);
                }
                break;
        case RF_AIROHA_2230:
-               number = sizeof(al2230_rf_data) / sizeof(al2230_rf_data[0]);
+               number = ARRAY_SIZE(al2230_rf_data);
                for (i = 0; i < number; i++) {
                        pHwData->phy_para[i] = al2230_rf_data[i];
                        pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(al2230_rf_data[i], 20);
                }
                break;
        case RF_AIROHA_2230S:
-               number = sizeof(al2230s_rf_data) / sizeof(al2230s_rf_data[0]);
+               number = ARRAY_SIZE(al2230s_rf_data);
                for (i = 0; i < number; i++) {
                        pHwData->phy_para[i] = al2230s_rf_data[i];
                        pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(al2230s_rf_data[i], 20);
@@ -1013,12 +1013,12 @@ void RFSynthesizer_initial(struct hw_data *pHwData)
                #ifdef _PE_STATE_DUMP_
                printk("* PLL_ON    low\n");
                #endif
-               number = sizeof(al7230_rf_data_24) / sizeof(al7230_rf_data_24[0]);
+               number = ARRAY_SIZE(al7230_rf_data_24);
                Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number);
                break;
        case RF_WB_242:
        case RF_WB_242_1:
-               number = sizeof(w89rf242_rf_data) / sizeof(w89rf242_rf_data[0]);
+               number = ARRAY_SIZE(w89rf242_rf_data);
                for (i = 0; i < number; i++) {
                        ltmp = w89rf242_rf_data[i];
                        if (i == 4) { /* Update the VCO trim from EEPROM */
@@ -1119,7 +1119,7 @@ void RFSynthesizer_initial(struct hw_data *pHwData)
                printk("* PLL_ON    low\n");
                #endif
 
-               number = sizeof(al7230_rf_data_50) / sizeof(al7230_rf_data_50[0]);
+               number = ARRAY_SIZE(al7230_rf_data_50);
                Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number);
                /* Write to register. number must less and equal than 16 */
                for (i = 0; i < number; i++)
@@ -1747,7 +1747,7 @@ void RFSynthesizer_SwitchingChannel(struct hw_data *pHwData,  struct chan_info C
                                pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2829_channel_data_24[Channel.ChanNo-1][i], 18);
                        Wb35Reg_BurstWrite(pHwData, 0x0864, pltmp, 3, NO_INCREMENT);
                } else if (Channel.band == BAND_TYPE_OFDM_5) {
-                       count = sizeof(max2829_channel_data_50) / sizeof(max2829_channel_data_50[0]);
+                       count = ARRAY_SIZE(max2829_channel_data_50);
 
                        for (i = 0; i < count; i++) {
                                if (max2829_channel_data_50[i][0] == Channel.ChanNo) {
@@ -1783,13 +1783,13 @@ void RFSynthesizer_SwitchingChannel(struct hw_data *pHwData,  struct chan_info C
                                /* Update BB register */
                                BBProcessor_AL7230_2400(pHwData);
 
-                               number = sizeof(al7230_rf_data_24) / sizeof(al7230_rf_data_24[0]);
+                               number = ARRAY_SIZE(al7230_rf_data_24);
                                Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number);
                        } else {
                                /* Update BB register */
                                BBProcessor_AL7230_5000(pHwData);
 
-                               number = sizeof(al7230_rf_data_50) / sizeof(al7230_rf_data_50[0]);
+                               number = ARRAY_SIZE(al7230_rf_data_50);
                                Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number);
                        }
 
@@ -1814,7 +1814,7 @@ void RFSynthesizer_SwitchingChannel(struct hw_data *pHwData,  struct chan_info C
                                Wb35Reg_Write(pHwData, 0x0864, ltmp);
                        }
 
-                       count = sizeof(al7230_channel_data_5) / sizeof(al7230_channel_data_5[0]);
+                       count = ARRAY_SIZE(al7230_channel_data_5);
 
                        for (i = 0; i < count; i++) {
                                if (al7230_channel_data_5[i][0] == Channel.ChanNo) {
@@ -1978,7 +1978,7 @@ u8 RFSynthesizer_SetAiroha2230Power(struct hw_data *pHwData, u8 index)
        u32     PowerData;
        u8      i, count;
 
-       count = sizeof(al2230_txvga_data) / sizeof(al2230_txvga_data[0]);
+       count = ARRAY_SIZE(al2230_txvga_data);
        for (i = 0; i < count; i++) {
                if (al2230_txvga_data[i][1] >= index)
                        break;
@@ -1996,7 +1996,7 @@ u8 RFSynthesizer_SetAiroha7230Power(struct hw_data *pHwData, u8 index)
        u32     PowerData;
        u8      i, count;
 
-       count = sizeof(al7230_txvga_data) / sizeof(al7230_txvga_data[0]);
+       count = ARRAY_SIZE(al7230_txvga_data);
        for (i = 0; i < count; i++) {
                if (al7230_txvga_data[i][1] >= index)
                        break;
@@ -2013,7 +2013,7 @@ u8 RFSynthesizer_SetWinbond242Power(struct hw_data *pHwData, u8 index)
        u32     PowerData;
        u8      i, count;
 
-       count = sizeof(w89rf242_txvga_data) / sizeof(w89rf242_txvga_data[0]);
+       count = ARRAY_SIZE(w89rf242_txvga_data);
        for (i = 0; i < count; i++) {
                if (w89rf242_txvga_data[i][1] >= index)
                        break;
@@ -2184,14 +2184,14 @@ void GetTxVgaFromEEPROM(struct hw_data *pHwData)
        /* Adjust WB_242 to WB_242_1 TxVga scale */
        if (pHwData->phy_type == RF_WB_242) {
                for (i = 0; i < 4; i++) { /* Only 2412 2437 2462 2484 case must be modified */
-                       for (j = 0; j < (sizeof(w89rf242_txvga_old_mapping) / sizeof(w89rf242_txvga_old_mapping[0])); j++) {
+                       for (j = 0; j < ARRAY_SIZE(w89rf242_txvga_old_mapping); j++) {
                                if (pctmp[i] < (u8) w89rf242_txvga_old_mapping[j][1]) {
                                        pctmp[i] = (u8) w89rf242_txvga_old_mapping[j][0];
                                        break;
                                }
                        }
 
-                       if (j == (sizeof(w89rf242_txvga_old_mapping) / sizeof(w89rf242_txvga_old_mapping[0])))
+                       if (j == ARRAY_SIZE(w89rf242_txvga_old_mapping))
                                pctmp[i] = (u8)w89rf242_txvga_old_mapping[j-1][0];
                }
        }
index 251caa052eee3439852b811f57d34e4e39a3066b..abaa05a630f0b53918f907522b63b7cf3956101e 100644 (file)
@@ -700,7 +700,7 @@ static int wb35_hw_init(struct ieee80211_hw *hw)
        Mds_initial(priv);
 
        /*
-        * If no user-defined address in the registry, use the addresss
+        * If no user-defined address in the registry, use the address
         * "burned" on the NIC instead.
         */
        pMacAddr = priv->sLocalPara.ThisMacAddress;
index 390628c6c1ebe900c1e46586a080e92418da6475..c4fe0ec95074b3cc668fb0713b7de277730d4828 100644 (file)
@@ -502,7 +502,7 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = {
 #endif // MSF_COMPONENT_ID
        NULL                                                                    //endsentinel
   };
-#define xxxx_PRI_IDENTITY_OFFSET       (sizeof(xxxx)/sizeof(xxxx[0]) - 3)
+#define xxxx_PRI_IDENTITY_OFFSET       (ARRAY_SIZE(xxxx) - 3)
 
 #endif // MSF_COMPONENT_ID / HCF_EXT_MB
 
index b45c7ddd92e29b10840a2053f87db63b07a49caa..b50b7b0a5cacb68b0e89e07723081c698cbf19a7 100644 (file)
@@ -727,10 +727,10 @@ XX1( CFG_SCAN,                                    SCAN_RS_STRCT, scan_result[32]           ) /*Scan results                                                                                       *
 #define CFG_FCBE       0xFCBE  //FW codes ahead of available documentation, so ???????
 #define CFG_FCBF       0xFCBF  //FW codes ahead of available documentation, so ???????
 
-#define CFG_HANDOVER_ADDR                              0xFCC0          //[AP] Station MAC Adrress re-associated with other AP
+#define CFG_HANDOVER_ADDR                              0xFCC0          //[AP] Station MAC Address re-associated with other AP
 #define CFG_SCAN_CHANNEL                               0xFCC2          //Channel set for host requested scan
 //;?#define CFG_SCAN_CHANNEL_MASK                      0xFCC2          // contains
-#define CFG_DISASSOCIATE_ADDR                  0xFCC4          //[AP] Station MAC Adrress to be disassociated
+#define CFG_DISASSOCIATE_ADDR                  0xFCC4          //[AP] Station MAC Address to be disassociated
 #define CFG_PROBE_DATA_RATE                            0xFCC5          //WARP connection control
 #define CFG_FRAME_BURST_LIMIT                  0xFCC6          //
 #define CFG_COEXISTENSE_BEHAVIOUR              0xFCC7          //[AP]
index 10abd406b09b597d414ccd8daba91dce85085889..19c335458653fc1a293c2533017a5d426cdf4805 100644 (file)
@@ -23,7 +23,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2003 Agere Systems Inc.
+ * Copyright (c) 2003 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -44,7 +44,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED \93AS IS\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -83,7 +83,6 @@
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -133,36 +132,35 @@ extern dbg_info_t *DbgInfo;
  ******************************************************************************/
 static int wl_adapter_attach(struct pcmcia_device *link)
 {
-    struct net_device   *dev;
-    struct wl_private  *lp;
-    /*------------------------------------------------------------------------*/
-
-    DBG_FUNC( "wl_adapter_attach" );
-    DBG_ENTER( DbgInfo );
-
-    dev = wl_device_alloc();
-    if(dev == NULL) {
-        DBG_ERROR( DbgInfo, "wl_device_alloc returned NULL\n");
-       return -ENOMEM;
-    }
-
-    link->io.NumPorts1      = HCF_NUM_IO_PORTS;
-    link->io.Attributes1    = IO_DATA_PATH_WIDTH_16;
-    link->io.IOAddrLines    = 6;
-    link->conf.Attributes   = CONF_ENABLE_IRQ;
-    link->conf.IntType      = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex  = 5;
-    link->conf.Present      = PRESENT_OPTION;
-
-    link->priv = dev;
-    lp = wl_priv(dev);
-    lp->link = link;
-
-    wl_adapter_insert(link);
-
-    DBG_LEAVE( DbgInfo );
-    return 0;
-} // wl_adapter_attach
+       struct net_device   *dev;
+       struct wl_private   *lp;
+       /*--------------------------------------------------------------------*/
+
+       DBG_FUNC("wl_adapter_attach");
+       DBG_ENTER(DbgInfo);
+
+       dev = wl_device_alloc();
+       if (dev == NULL) {
+               DBG_ERROR(DbgInfo, "wl_device_alloc returned NULL\n");
+               return -ENOMEM;
+       }
+
+       link->resource[0]->end  = HCF_NUM_IO_PORTS;
+       link->resource[0]->flags= IO_DATA_PATH_WIDTH_16;
+       link->conf.Attributes   = CONF_ENABLE_IRQ;
+       link->conf.IntType      = INT_MEMORY_AND_IO;
+       link->conf.ConfigIndex  = 5;
+       link->conf.Present      = PRESENT_OPTION;
+
+       link->priv = dev;
+       lp = wl_priv(dev);
+       lp->link = link;
+
+       wl_adapter_insert(link);
+
+       DBG_LEAVE(DbgInfo);
+       return 0;
+} /* wl_adapter_attach */
 /*============================================================================*/
 
 
@@ -190,25 +188,24 @@ static int wl_adapter_attach(struct pcmcia_device *link)
  ******************************************************************************/
 static void wl_adapter_detach(struct pcmcia_device *link)
 {
-    struct net_device   *dev = link->priv;
-    /*------------------------------------------------------------------------*/
-
+       struct net_device   *dev = link->priv;
+       /*--------------------------------------------------------------------*/
 
-    DBG_FUNC( "wl_adapter_detach" );
-    DBG_ENTER( DbgInfo );
-    DBG_PARAM( DbgInfo, "link", "0x%p", link );
+       DBG_FUNC("wl_adapter_detach");
+       DBG_ENTER(DbgInfo);
+       DBG_PARAM(DbgInfo, "link", "0x%p", link);
 
-    wl_adapter_release(link);
+       wl_adapter_release(link);
 
-    if (dev) {
-       unregister_wlags_sysfs(dev);
-       unregister_netdev(dev);
-    }
+       if (dev) {
+               unregister_wlags_sysfs(dev);
+               unregister_netdev(dev);
+       }
 
-    wl_device_dealloc(dev);
+       wl_device_dealloc(dev);
 
-    DBG_LEAVE( DbgInfo );
-} // wl_adapter_detach
+       DBG_LEAVE(DbgInfo);
+} /* wl_adapter_detach */
 /*============================================================================*/
 
 
@@ -232,33 +229,33 @@ static void wl_adapter_detach(struct pcmcia_device *link)
  *      N/A
  *
  ******************************************************************************/
-void wl_adapter_release( struct pcmcia_device *link )
+void wl_adapter_release(struct pcmcia_device *link)
 {
-    DBG_FUNC( "wl_adapter_release" );
-    DBG_ENTER( DbgInfo );
-    DBG_PARAM( DbgInfo, "link", "0x%p", link);
+       DBG_FUNC("wl_adapter_release");
+       DBG_ENTER(DbgInfo);
+       DBG_PARAM(DbgInfo, "link", "0x%p", link);
 
-    /* Stop hardware */
-    wl_remove(link->priv);
+       /* Stop hardware */
+       wl_remove(link->priv);
 
-    pcmcia_disable_device(link);
+       pcmcia_disable_device(link);
 
-    DBG_LEAVE( DbgInfo );
-} // wl_adapter_release
+       DBG_LEAVE(DbgInfo);
+} /* wl_adapter_release */
 /*============================================================================*/
 
 static int wl_adapter_suspend(struct pcmcia_device *link)
 {
-    struct net_device *dev = link->priv;
+       struct net_device *dev = link->priv;
 
-    //if (link->open) {
+       /* if (link->open) { */
        netif_device_detach(dev);
        wl_suspend(dev);
-//// CHECK!            pcmcia_release_configuration(link->handle);
-    //}
+       /* CHECK! pcmcia_release_configuration(link->handle); */
+       /* } */
 
-    return 0;
-} // wl_adapter_suspend
+       return 0;
+} /* wl_adapter_suspend */
 
 static int wl_adapter_resume(struct pcmcia_device *link)
 {
@@ -266,10 +263,10 @@ static int wl_adapter_resume(struct pcmcia_device *link)
 
        wl_resume(dev);
 
-       netif_device_attach( dev );
+       netif_device_attach(dev);
 
        return 0;
-} // wl_adapter_resume
+} /* wl_adapter_resume */
 
 /*******************************************************************************
  *     wl_adapter_insert()
@@ -291,60 +288,60 @@ static int wl_adapter_resume(struct pcmcia_device *link)
  *      N/A
  *
  ******************************************************************************/
-void wl_adapter_insert( struct pcmcia_device *link )
+void wl_adapter_insert(struct pcmcia_device *link)
 {
-    struct net_device       *dev;
-    int i;
-    int                     ret;
-    /*------------------------------------------------------------------------*/
+       struct net_device *dev;
+       int i;
+       int ret;
+       /*--------------------------------------------------------------------*/
 
-    DBG_FUNC( "wl_adapter_insert" );
-    DBG_ENTER( DbgInfo );
-    DBG_PARAM( DbgInfo, "link", "0x%p", link );
+       DBG_FUNC("wl_adapter_insert");
+       DBG_ENTER(DbgInfo);
+       DBG_PARAM(DbgInfo, "link", "0x%p", link);
 
-    dev     = link->priv;
+       dev     = link->priv;
 
-    /* Do we need to allocate an interrupt? */
-    link->conf.Attributes |= CONF_ENABLE_IRQ;
+       /* Do we need to allocate an interrupt? */
+       link->conf.Attributes |= CONF_ENABLE_IRQ;
+       link->io_lines = 6;
 
-    ret = pcmcia_request_io(link, &link->io);
-    if (ret != 0)
-        goto failed;
+       ret = pcmcia_request_io(link);
+       if (ret != 0)
+               goto failed;
 
-    ret = pcmcia_request_irq(link, (void *) wl_isr);
-    if (ret != 0)
-        goto failed;
+       ret = pcmcia_request_irq(link, (void *) wl_isr);
+       if (ret != 0)
+               goto failed;
 
-    ret = pcmcia_request_configuration(link, &link->conf);
-    if (ret != 0)
-        goto failed;
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret != 0)
+               goto failed;
 
-    dev->irq        = link->irq;
-    dev->base_addr  = link->io.BasePort1;
+       dev->irq        = link->irq;
+       dev->base_addr  = link->resource[0]->start;
 
-    SET_NETDEV_DEV(dev, &link->dev);
-    if (register_netdev(dev) != 0) {
-       printk("%s: register_netdev() failed\n", MODULE_NAME);
-       goto failed;
-    }
+       SET_NETDEV_DEV(dev, &link->dev);
+       if (register_netdev(dev) != 0) {
+               printk("%s: register_netdev() failed\n", MODULE_NAME);
+               goto failed;
+       }
 
-    register_wlags_sysfs(dev);
+       register_wlags_sysfs(dev);
 
-    printk(KERN_INFO "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
-               dev->name, dev->base_addr, dev->irq);
-    for( i = 0; i < ETH_ALEN; i++ ) {
-        printk("%02X%c", dev->dev_addr[i], ((i < (ETH_ALEN-1)) ? ':' : '\n'));
-    }
+       printk(KERN_INFO "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
+               dev->name, dev->base_addr, dev->irq);
+       for (i = 0; i < ETH_ALEN; i++)
+               printk("%02X%c", dev->dev_addr[i], ((i < (ETH_ALEN-1)) ? ':' : '\n'));
 
-    DBG_LEAVE( DbgInfo );
-    return;
+       DBG_LEAVE(DbgInfo);
+       return;
 
 failed:
-    wl_adapter_release( link );
+       wl_adapter_release(link);
 
-    DBG_LEAVE(DbgInfo);
-    return;
-} // wl_adapter_insert
+       DBG_LEAVE(DbgInfo);
+       return;
+} /* wl_adapter_insert */
 /*============================================================================*/
 
 
@@ -367,38 +364,36 @@ failed:
  *      errno value otherwise
  *
  ******************************************************************************/
-int wl_adapter_open( struct net_device *dev )
+int wl_adapter_open(struct net_device *dev)
 {
-    struct wl_private *lp = wl_priv(dev);
-    struct pcmcia_device *link = lp->link;
-    int         result = 0;
-    int         hcf_status = HCF_SUCCESS;
-    /*------------------------------------------------------------------------*/
-
-
-    DBG_FUNC( "wl_adapter_open" );
-    DBG_ENTER( DbgInfo );
-       DBG_PRINT( "%s\n", VERSION_INFO );
-    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
-
-    if(!pcmcia_dev_present(link))
-    {
-        DBG_LEAVE( DbgInfo );
-        return -ENODEV;
-    }
-
-    link->open++;
-
-    hcf_status = wl_open( dev );
-
-    if( hcf_status != HCF_SUCCESS ) {
-        link->open--;
-        result = -ENODEV;
-    }
-
-    DBG_LEAVE( DbgInfo );
-    return result;
-} // wl_adapter_open
+       struct wl_private *lp = wl_priv(dev);
+       struct pcmcia_device *link = lp->link;
+       int result = 0;
+       int hcf_status = HCF_SUCCESS;
+       /*--------------------------------------------------------------------*/
+
+       DBG_FUNC("wl_adapter_open");
+       DBG_ENTER(DbgInfo);
+       DBG_PRINT("%s\n", VERSION_INFO);
+       DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+
+       if (!pcmcia_dev_present(link)) {
+               DBG_LEAVE(DbgInfo);
+               return -ENODEV;
+       }
+
+       link->open++;
+
+       hcf_status = wl_open(dev);
+
+       if (hcf_status != HCF_SUCCESS) {
+               link->open--;
+               result = -ENODEV;
+       }
+
+       DBG_LEAVE(DbgInfo);
+       return result;
+} /* wl_adapter_open */
 /*============================================================================*/
 
 
@@ -421,56 +416,55 @@ int wl_adapter_open( struct net_device *dev )
  *      errno value otherwise
  *
  ******************************************************************************/
-int wl_adapter_close( struct net_device *dev )
+int wl_adapter_close(struct net_device *dev)
 {
-    struct wl_private *lp = wl_priv(dev);
-    struct pcmcia_device *link = lp->link;
-    /*------------------------------------------------------------------------*/
+       struct wl_private *lp = wl_priv(dev);
+       struct pcmcia_device *link = lp->link;
+       /*--------------------------------------------------------------------*/
 
+       DBG_FUNC("wl_adapter_close");
+       DBG_ENTER(DbgInfo);
+       DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
 
-    DBG_FUNC( "wl_adapter_close" );
-    DBG_ENTER( DbgInfo );
-    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+       if (link == NULL) {
+               DBG_LEAVE(DbgInfo);
+               return -ENODEV;
+       }
 
-    if( link == NULL ) {
-        DBG_LEAVE( DbgInfo );
-        return -ENODEV;
-    }
+       DBG_TRACE(DbgInfo, "%s: Shutting down adapter.\n", dev->name);
+       wl_close(dev);
 
-    DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
-    wl_close( dev );
+       link->open--;
 
-    link->open--;
-
-    DBG_LEAVE( DbgInfo );
-    return 0;
-} // wl_adapter_close
+       DBG_LEAVE(DbgInfo);
+       return 0;
+} /* wl_adapter_close */
 /*============================================================================*/
 
 static struct pcmcia_device_id wl_adapter_ids[] = {
-#if ! ((HCF_TYPE) & HCF_TYPE_HII5)
+#if !((HCF_TYPE) & HCF_TYPE_HII5)
        PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0003),
        PCMCIA_DEVICE_PROD_ID12("Agere Systems", "Wireless PC Card Model 0110",
-                           0x33103a9b, 0xe175b0dd),
+                               0x33103a9b, 0xe175b0dd),
 #else
        PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0004),
        PCMCIA_DEVICE_PROD_ID12("Linksys", "WCF54G_Wireless-G_CompactFlash_Card",
-                            0x0733cc81, 0x98a599e1),
-#endif  // (HCF_TYPE) & HCF_TYPE_HII5
+                               0x0733cc81, 0x98a599e1),
+#endif  /* (HCF_TYPE) & HCF_TYPE_HII5 */
        PCMCIA_DEVICE_NULL,
-       };
+};
 MODULE_DEVICE_TABLE(pcmcia, wl_adapter_ids);
 
 static struct pcmcia_driver wlags49_driver = {
-    .owner          = THIS_MODULE,
-    .drv            = {
-       .name   = DRIVER_NAME,
-    },
-    .probe     = wl_adapter_attach,
-    .remove    = wl_adapter_detach,
-    .id_table  = wl_adapter_ids,
-    .suspend   = wl_adapter_suspend,
-    .resume    = wl_adapter_resume,
+       .owner      = THIS_MODULE,
+       .drv        = {
+               .name = DRIVER_NAME,
+       },
+       .probe      = wl_adapter_attach,
+       .remove     = wl_adapter_detach,
+       .id_table   = wl_adapter_ids,
+       .suspend    = wl_adapter_suspend,
+       .resume     = wl_adapter_resume,
 };
 
 
@@ -493,21 +487,20 @@ static struct pcmcia_driver wlags49_driver = {
  *      -1 on error
  *
  ******************************************************************************/
-int wl_adapter_init_module( void )
+int wl_adapter_init_module(void)
 {
-    int ret;
-    /*------------------------------------------------------------------------*/
+       int ret;
+       /*--------------------------------------------------------------------*/
 
+       DBG_FUNC("wl_adapter_init_module");
+       DBG_ENTER(DbgInfo);
+       DBG_TRACE(DbgInfo, "wl_adapter_init_module() -- PCMCIA\n");
 
-    DBG_FUNC( "wl_adapter_init_module" );
-    DBG_ENTER( DbgInfo );
-    DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCMCIA\n" );
+       ret = pcmcia_register_driver(&wlags49_driver);
 
-    ret = pcmcia_register_driver(&wlags49_driver);
-
-    DBG_LEAVE( DbgInfo );
-    return ret;
-} // wl_adapter_init_module
+       DBG_LEAVE(DbgInfo);
+       return ret;
+} /* wl_adapter_init_module */
 /*============================================================================*/
 
 
@@ -528,18 +521,18 @@ int wl_adapter_init_module( void )
  *      N/A
  *
  ******************************************************************************/
-void wl_adapter_cleanup_module( void )
+void wl_adapter_cleanup_module(void)
 {
-    DBG_FUNC( "wl_adapter_cleanup_module" );
-    DBG_ENTER( DbgInfo );
-    DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCMCIA\n" );
+       DBG_FUNC("wl_adapter_cleanup_module");
+       DBG_ENTER(DbgInfo);
+       DBG_TRACE(DbgInfo, "wl_adapter_cleanup_module() -- PCMCIA\n");
 
 
-    pcmcia_unregister_driver(&wlags49_driver);
+       pcmcia_unregister_driver(&wlags49_driver);
 
-    DBG_LEAVE( DbgInfo );
-    return;
-} // wl_adapter_cleanup_module
+       DBG_LEAVE(DbgInfo);
+       return;
+} /* wl_adapter_cleanup_module */
 /*============================================================================*/
 
 
@@ -562,17 +555,16 @@ void wl_adapter_cleanup_module( void )
  *      0 otherwise
  *
  ******************************************************************************/
-int wl_adapter_is_open( struct net_device *dev )
+int wl_adapter_is_open(struct net_device *dev)
 {
-    struct wl_private *lp = wl_priv(dev);
-    struct pcmcia_device *link = lp->link;
+       struct wl_private *lp = wl_priv(dev);
+       struct pcmcia_device *link = lp->link;
 
-    if(!pcmcia_dev_present(link)) {
-        return 0;
-    }
+       if (!pcmcia_dev_present(link))
+               return 0;
 
-    return( link->open );
-} // wl_adapter_is_open
+       return link->open;
+} /* wl_adapter_is_open */
 /*============================================================================*/
 
 
@@ -596,97 +588,95 @@ int wl_adapter_is_open( struct net_device *dev )
  *      a pointer to a string describing the error(s)
  *
  ******************************************************************************/
-const char* DbgEvent( int mask )
+const char *DbgEvent(int mask)
 {
-    static char DbgBuffer[256];
-    char *pBuf;
-    /*------------------------------------------------------------------------*/
-
+       static char DbgBuffer[256];
+       char *pBuf;
+       /*--------------------------------------------------------------------*/
 
-    pBuf    = DbgBuffer;
-    *pBuf   = '\0';
+       pBuf    = DbgBuffer;
+       *pBuf   = '\0';
 
 
-    if( mask & CS_EVENT_WRITE_PROTECT )
-        strcat( pBuf, "WRITE_PROTECT " );
+       if (mask & CS_EVENT_WRITE_PROTECT)
+               strcat(pBuf, "WRITE_PROTECT ");
 
-    if(mask & CS_EVENT_CARD_LOCK)
-        strcat( pBuf, "CARD_LOCK " );
+       if (mask & CS_EVENT_CARD_LOCK)
+               strcat(pBuf, "CARD_LOCK ");
 
-    if(mask & CS_EVENT_CARD_INSERTION)
-        strcat( pBuf, "CARD_INSERTION " );
+       if (mask & CS_EVENT_CARD_INSERTION)
+               strcat(pBuf, "CARD_INSERTION ");
 
-    if(mask & CS_EVENT_CARD_REMOVAL)
-        strcat( pBuf, "CARD_REMOVAL " );
+       if (mask & CS_EVENT_CARD_REMOVAL)
+               strcat(pBuf, "CARD_REMOVAL ");
 
-    if(mask & CS_EVENT_BATTERY_DEAD)
-        strcat( pBuf, "BATTERY_DEAD " );
+       if (mask & CS_EVENT_BATTERY_DEAD)
+               strcat(pBuf, "BATTERY_DEAD ");
 
-    if(mask & CS_EVENT_BATTERY_LOW)
-        strcat( pBuf, "BATTERY_LOW " );
+       if (mask & CS_EVENT_BATTERY_LOW)
+               strcat(pBuf, "BATTERY_LOW ");
 
-    if(mask & CS_EVENT_READY_CHANGE)
-        strcat( pBuf, "READY_CHANGE " );
+       if (mask & CS_EVENT_READY_CHANGE)
+               strcat(pBuf, "READY_CHANGE ");
 
-    if(mask & CS_EVENT_CARD_DETECT)
-        strcat( pBuf, "CARD_DETECT " );
+       if (mask & CS_EVENT_CARD_DETECT)
+               strcat(pBuf, "CARD_DETECT ");
 
-    if(mask & CS_EVENT_RESET_REQUEST)
-        strcat( pBuf, "RESET_REQUEST " );
+       if (mask & CS_EVENT_RESET_REQUEST)
+               strcat(pBuf, "RESET_REQUEST ");
 
-    if(mask & CS_EVENT_RESET_PHYSICAL)
-        strcat( pBuf, "RESET_PHYSICAL " );
+       if (mask & CS_EVENT_RESET_PHYSICAL)
+               strcat(pBuf, "RESET_PHYSICAL ");
 
-    if(mask & CS_EVENT_CARD_RESET)
-        strcat( pBuf, "CARD_RESET " );
+       if (mask & CS_EVENT_CARD_RESET)
+               strcat(pBuf, "CARD_RESET ");
 
-    if(mask & CS_EVENT_REGISTRATION_COMPLETE)
-        strcat( pBuf, "REGISTRATION_COMPLETE " );
+       if (mask & CS_EVENT_REGISTRATION_COMPLETE)
+               strcat(pBuf, "REGISTRATION_COMPLETE ");
 
-    // if(mask & CS_EVENT_RESET_COMPLETE)
-    //     strcat( pBuf, "RESET_COMPLETE " );
+       /* if (mask & CS_EVENT_RESET_COMPLETE)
+               strcat(pBuf, "RESET_COMPLETE "); */
 
-    if(mask & CS_EVENT_PM_SUSPEND)
-        strcat( pBuf, "PM_SUSPEND " );
+       if (mask & CS_EVENT_PM_SUSPEND)
+               strcat(pBuf, "PM_SUSPEND ");
 
-    if(mask & CS_EVENT_PM_RESUME)
-        strcat( pBuf, "PM_RESUME " );
+       if (mask & CS_EVENT_PM_RESUME)
+               strcat(pBuf, "PM_RESUME ");
 
-    if(mask & CS_EVENT_INSERTION_REQUEST)
-        strcat( pBuf, "INSERTION_REQUEST " );
+       if (mask & CS_EVENT_INSERTION_REQUEST)
+               strcat(pBuf, "INSERTION_REQUEST ");
 
-    if(mask & CS_EVENT_EJECTION_REQUEST)
-        strcat( pBuf, "EJECTION_REQUEST " );
+       if (mask & CS_EVENT_EJECTION_REQUEST)
+               strcat(pBuf, "EJECTION_REQUEST ");
 
-    if(mask & CS_EVENT_MTD_REQUEST)
-        strcat( pBuf, "MTD_REQUEST " );
+       if (mask & CS_EVENT_MTD_REQUEST)
+               strcat(pBuf, "MTD_REQUEST ");
 
-    if(mask & CS_EVENT_ERASE_COMPLETE)
-        strcat( pBuf, "ERASE_COMPLETE " );
+       if (mask & CS_EVENT_ERASE_COMPLETE)
+               strcat(pBuf, "ERASE_COMPLETE ");
 
-    if(mask & CS_EVENT_REQUEST_ATTENTION)
-        strcat( pBuf, "REQUEST_ATTENTION " );
+       if (mask & CS_EVENT_REQUEST_ATTENTION)
+               strcat(pBuf, "REQUEST_ATTENTION ");
 
-    if(mask & CS_EVENT_CB_DETECT)
-        strcat( pBuf, "CB_DETECT " );
+       if (mask & CS_EVENT_CB_DETECT)
+               strcat(pBuf, "CB_DETECT ");
 
-    if(mask & CS_EVENT_3VCARD)
-        strcat( pBuf, "3VCARD " );
+       if (mask & CS_EVENT_3VCARD)
+               strcat(pBuf, "3VCARD ");
 
-    if(mask & CS_EVENT_XVCARD)
-        strcat( pBuf, "XVCARD " );
+       if (mask & CS_EVENT_XVCARD)
+               strcat(pBuf, "XVCARD ");
 
 
-    if( *pBuf ) {
-        pBuf[strlen(pBuf) - 1] = '\0';
-    } else {
-        if( mask != 0x0 ) {
-            sprintf( pBuf, "<<0x%08x>>", mask );
-        }
-    }
+       if (*pBuf) {
+               pBuf[strlen(pBuf) - 1] = '\0';
+       } else {
+               if (mask != 0x0)
+                       sprintf(pBuf, "<<0x%08x>>", mask);
+       }
 
-    return pBuf;
-} // DbgEvent
+       return pBuf;
+} /* DbgEvent */
 /*============================================================================*/
 
 #endif  /* DBG */
index a9b8828a1a27c2e88e358c4f7d7833cb5683359b..21f17be4f02ae7f264d16298801a39abe85a96b7 100644 (file)
@@ -72,8 +72,6 @@ void wl_adapter_insert(struct pcmcia_device *link);
 
 void wl_adapter_release(struct pcmcia_device *link);
 
-int wl_adapter_event(event_t event, int priority, event_callback_args_t *args );
-
 int wl_adapter_init_module( void );
 
 void wl_adapter_cleanup_module( void );
index d9a0ad039c19730853fe29b20ae11208faf0b318..02f0a20e178a1cbcd72d413ec3e4973afff9794c 100644 (file)
@@ -69,7 +69,6 @@
  ******************************************************************************/
 #include <linux/version.h>
 #ifdef BUS_PCMCIA
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
index 1aa61dbdb79ffdf269332f4963789be6512f1947..e2a7ad05e545f91f85b8762873738db2ffb349de 100644 (file)
@@ -1905,8 +1905,8 @@ int wl_rx_dma( struct net_device *dev )
     DBG_FUNC("wl_rx")
     DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
 
-    if((( lp = (struct wl_private *)dev->priv ) != NULL ) &&
-          !( lp->flags & WVLAN2_UIL_BUSY )) {
+    if((( lp = dev->priv ) != NULL ) &&
+       !( lp->flags & WVLAN2_UIL_BUSY )) {
 
 #ifdef USE_RTS
         if( lp->useRTS == 1 ) {
index 6751b4bad2e43560c60f92939f6a3c5ac8fcf3fb..020b17adee2d27bcc20fddb21df10d00451570cf 100644 (file)
@@ -117,9 +117,13 @@ enum hermes_pci_versions {
 };
 
 static struct pci_device_id wl_pci_tbl[] __devinitdata = {
-       { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
-    { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
-    { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+       { PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+       { PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+       { PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+
        { }                     /* Terminating entry */
 };
 
@@ -465,7 +469,7 @@ void __devexit wl_pci_remove(struct pci_dev *pdev)
     free_irq( dev->irq, dev );
 
 #ifdef ENABLE_DMA
-    wl_pci_dma_free( pdev, (struct wl_private *)dev->priv );
+    wl_pci_dma_free( pdev, dev->priv );
 #endif
 
     wl_device_dealloc( dev );
@@ -534,7 +538,7 @@ int wl_pci_setup( struct pci_dev *pdev )
 
 #ifdef ENABLE_DMA
     /* Allocate DMA Descriptors */
-    if( wl_pci_dma_alloc( pdev, (struct wl_private *)dev->priv ) < 0 ) {
+    if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) {
         DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
         DBG_LEAVE( DbgInfo );
         return -ENOMEM;
@@ -570,7 +574,7 @@ int wl_pci_setup( struct pci_dev *pdev )
        }
 
     /* Make sure interrupts are enabled properly for CardBus */
-    lp = (struct wl_private *)dev->priv;
+    lp = dev->priv;
 
     if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
            lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI              ) {
index 18d7b514ea6cd6caf1de58fd10be0afdaf5e9fab..cea04c44ec47c5b51b23d5d1adc61bbd7b13a1da 100644 (file)
 /*******************************************************************************
  *  constant definitions
  ******************************************************************************/
-#define WL_LKM_PCI_VENDOR_ID    0x11C1  // Lucent Microelectronics
-#define WL_LKM_PCI_DEVICE_ID_0  0xAB30  // Mini PCI
-#define WL_LKM_PCI_DEVICE_ID_1  0xAB34  // Mini PCI
-#define WL_LKM_PCI_DEVICE_ID_2  0xAB11  // WARP CardBus
+#define PCI_VENDOR_IDWL_LKM     0x11C1  /* Lucent Microelectronics */
+#define PCI_DEVICE_ID_WL_LKM_0  0xAB30  /* Mini PCI */
+#define PCI_DEVICE_ID_WL_LKM_1  0xAB34  /* Mini PCI */
+#define PCI_DEVICE_ID_WL_LKM_2  0xAB11  /* WARP CardBus */
 
 
 
index 292d5792dd75dc39a96ea5304ef246f52fd708fe..7a1337db7aa1aa28150c59338a919b51542c4bb3 100644 (file)
@@ -169,7 +169,7 @@ void parse_config(struct net_device *dev)
        DBG_ENTER(DbgInfo);
 
        /* Get the wavelan specific info for this device */
-       wvlan_config = (struct wl_private *)dev->priv;
+       wvlan_config = dev->priv;
        if (wvlan_config == NULL) {
                DBG_ERROR(DbgInfo, "Wavelan specific info struct not present?\n");
                return;
index bbdb9973d1e571fe41fe6039b1d2ec14b3af925c..ce8ed410a7e3507640663af4dea13873057ae9b4 100644 (file)
@@ -258,41 +258,6 @@ int is_valid_key_string( char *s )
 
 
 
-/*******************************************************************************
- *     hexdigit2int()
- *******************************************************************************
- *
- *  DESCRIPTION:
- *
- *      Converts a hexadecimal digit character to an integer
- *
- *  PARAMETERS:
- *
- *      c   - the hexadecimal digit character
- *
- *  RETURNS:
- *
- *      the converted integer
- *
- ******************************************************************************/
-int hexdigit2int( char c )
-{
-   if( c >= '0' && c <= '9' )
-       return c - '0';
-
-   if( c >= 'A' && c <= 'F' )
-       return c - 'A' + 10;
-
-   if( c >= 'a' && c <= 'f' )
-       return c - 'a' + 10;
-
-   return 0;
-} // hexdigit2int
-/*============================================================================*/
-
-
-
-
 /*******************************************************************************
  *     key_string2key()
  *******************************************************************************
@@ -328,7 +293,7 @@ void key_string2key( char *ks, KEY_STRCT *key )
         p = (char *)key->key;
 
         for( i = 2; i < l; i+=2 ) {
-           *p++ = ( hexdigit2int( ks[i] ) << 4 ) + hexdigit2int (ks[i+1] );
+                       *p++ = (hex_to_bin(ks[i]) << 4) + hex_to_bin(ks[i+1]);
            n++;
         }
 
index 561e85b5c9b231094f03067d88070fcdf26a3690..ba537a60059bd129fa425ca9a19db589abc079fd 100644 (file)
@@ -71,8 +71,6 @@ int is_valid_key_string( char *s );
 
 void key_string2key( char *ks, KEY_STRCT *key );
 
-int hexdigit2int( char c );
-
 void wl_hcf_error( struct net_device *dev, int hcfStatus );
 
 void wl_endian_translate_event( ltv_t *pLtv );
index 82fcc1665e92e54ce504e96be39a7db1e5bfff2a..426d4efbabc34d975b8e23d827dabe9b3edb2f32 100644 (file)
@@ -1,6 +1,6 @@
 config PRISM2_USB
        tristate "Prism2.5/3 USB driver"
-       depends on WLAN && USB
+       depends on WLAN && USB && CFG80211
        select WIRELESS_EXT
        select WEXT_PRIV
        default n
index 5edac5c8d4eeb0b103d3e8bbe8065d4a94b83fcf..db5d597563f81f48f262485559c7608fc43a5b22 100644 (file)
@@ -4,5 +4,4 @@ prism2_usb-objs := prism2usb.o \
                p80211conv.o \
                p80211req.o \
                p80211wep.o \
-               p80211wext.o \
                p80211netdev.o
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
new file mode 100644 (file)
index 0000000..368c30a
--- /dev/null
@@ -0,0 +1,760 @@
+/* cfg80211 Interface for prism2_usb module */
+
+
+/* Prism2 channell/frequency/bitrate declarations */
+static const struct ieee80211_channel prism2_channels[] = {
+       { .center_freq = 2412 },
+       { .center_freq = 2417 },
+       { .center_freq = 2422 },
+       { .center_freq = 2427 },
+       { .center_freq = 2432 },
+       { .center_freq = 2437 },
+       { .center_freq = 2442 },
+       { .center_freq = 2447 },
+       { .center_freq = 2452 },
+       { .center_freq = 2457 },
+       { .center_freq = 2462 },
+       { .center_freq = 2467 },
+       { .center_freq = 2472 },
+       { .center_freq = 2484 },
+};
+
+static const struct ieee80211_rate prism2_rates[] = {
+       { .bitrate = 10 },
+       { .bitrate = 20 },
+       { .bitrate = 55 },
+       { .bitrate = 110 }
+};
+
+#define PRISM2_NUM_CIPHER_SUITES 2
+static const u32 prism2_cipher_suites[PRISM2_NUM_CIPHER_SUITES] = {
+       WLAN_CIPHER_SUITE_WEP40,
+       WLAN_CIPHER_SUITE_WEP104
+};
+
+
+/* prism2 device private data */
+struct prism2_wiphy_private {
+       wlandevice_t *wlandev;
+
+       struct ieee80211_supported_band band;
+       struct ieee80211_channel channels[ARRAY_SIZE(prism2_channels)];
+       struct ieee80211_rate rates[ARRAY_SIZE(prism2_rates)];
+
+       struct cfg80211_scan_request *scan_request;
+};
+
+static const void * const prism2_wiphy_privid = &prism2_wiphy_privid;
+
+
+/* Helper Functions */
+static int prism2_result2err(int prism2_result)
+{
+       int err = 0;
+
+       switch (prism2_result) {
+       case P80211ENUM_resultcode_invalid_parameters:
+               err = -EINVAL;
+               break;
+       case P80211ENUM_resultcode_implementation_failure:
+               err = -EIO;
+               break;
+       case P80211ENUM_resultcode_not_supported:
+               err = -EOPNOTSUPP;
+               break;
+       default:
+               err = 0;
+               break;
+       }
+
+       return err;
+}
+
+static int prism2_domibset_uint32(wlandevice_t *wlandev, u32 did, u32 data)
+{
+       struct p80211msg_dot11req_mibset msg;
+       p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data;
+
+       msg.msgcode = DIDmsg_dot11req_mibset;
+       mibitem->did = did;
+       mibitem->data = data;
+
+       return p80211req_dorequest(wlandev, (u8 *) &msg);
+}
+
+static int prism2_domibset_pstr32(wlandevice_t *wlandev,
+                                 u32 did, u8 len, u8 *data)
+{
+       struct p80211msg_dot11req_mibset msg;
+       p80211item_pstr32_t *mibitem = (p80211item_pstr32_t *) &msg.mibattribute.data;
+
+       msg.msgcode = DIDmsg_dot11req_mibset;
+       mibitem->did = did;
+       mibitem->data.len = len;
+       memcpy(mibitem->data.data, data, len);
+
+       return p80211req_dorequest(wlandev, (u8 *) &msg);
+}
+
+
+/* The interface functions, called by the cfg80211 layer */
+int prism2_change_virtual_intf(struct wiphy *wiphy,
+                              struct net_device *dev,
+                              enum nl80211_iftype type, u32 *flags,
+                              struct vif_params *params)
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+       u32 data;
+       int result;
+       int err = 0;
+
+       switch (type) {
+       case NL80211_IFTYPE_ADHOC:
+               if (wlandev->macmode == WLAN_MACMODE_IBSS_STA)
+                       goto exit;
+               wlandev->macmode = WLAN_MACMODE_IBSS_STA;
+               data = 0;
+               break;
+       case NL80211_IFTYPE_STATION:
+               if (wlandev->macmode == WLAN_MACMODE_ESS_STA)
+                       goto exit;
+               wlandev->macmode = WLAN_MACMODE_ESS_STA;
+               data = 1;
+               break;
+       default:
+               printk(KERN_WARNING "Operation mode: %d not support\n", type);
+               return -EOPNOTSUPP;
+       }
+
+       /* Set Operation mode to the PORT TYPE RID */
+       result = prism2_domibset_uint32(wlandev, DIDmib_p2_p2Static_p2CnfPortType, data);
+
+       if (result)
+               err = -EFAULT;
+
+       dev->ieee80211_ptr->iftype = type;
+
+exit:
+       return err;
+}
+
+int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
+                  u8 key_index, const u8 *mac_addr,
+                  struct key_params *params)
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+       u32 did;
+
+       int err = 0;
+       int result = 0;
+
+       switch (params->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+                                               key_index);
+               if (result)
+                       goto exit;
+
+               /* send key to driver */
+               switch (key_index) {
+               case 0:
+                       did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+                       break;
+
+               case 1:
+                       did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+                       break;
+
+               case 2:
+                       did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+                       break;
+
+               case 3:
+                       did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+                       break;
+
+               default:
+                       err = -EINVAL;
+                       goto exit;
+               }
+
+               result = prism2_domibset_pstr32(wlandev, did, params->key_len, params->key);
+               if (result)
+                       goto exit;
+               break;
+
+       default:
+               pr_debug("Unsupported cipher suite\n");
+               result = 1;
+       }
+
+exit:
+       if (result)
+               err = -EFAULT;
+
+       return err;
+}
+
+int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
+                  u8 key_index, const u8 *mac_addr, void *cookie,
+                  void (*callback)(void *cookie, struct key_params*))
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+       struct key_params params;
+       int len;
+
+       if (key_index >= NUM_WEPKEYS)
+               return -EINVAL;
+
+       len = wlandev->wep_keylens[key_index];
+       memset(&params, 0, sizeof(params));
+
+       if (len == 13)
+               params.cipher = WLAN_CIPHER_SUITE_WEP104;
+       else if (len == 5)
+               params.cipher = WLAN_CIPHER_SUITE_WEP104;
+       else
+               return -ENOENT;
+       params.key_len = len;
+       params.key = wlandev->wep_keys[key_index];
+
+       callback(cookie, &params);
+
+       return 0;
+}
+
+int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
+                  u8 key_index, const u8 *mac_addr)
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+       u32 did;
+       int err = 0;
+       int result = 0;
+
+       /* There is no direct way in the hardware (AFAIK) of removing
+          a key, so we will cheat by setting the key to a bogus value */
+       /* send key to driver */
+       switch (key_index) {
+       case 0:
+               did =
+                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+               break;
+
+       case 1:
+               did =
+                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+               break;
+
+       case 2:
+               did =
+                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+               break;
+
+       case 3:
+               did =
+                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+               break;
+
+       default:
+               err = -EINVAL;
+               goto exit;
+       }
+
+       result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000");
+
+exit:
+       if (result)
+               err = -EFAULT;
+
+       return err;
+}
+
+int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
+                          u8 key_index)
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+
+       int err = 0;
+       int result = 0;
+
+       result = prism2_domibset_uint32(wlandev,
+               DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+               key_index);
+
+       if (result)
+               err = -EFAULT;
+
+       return err;
+}
+
+
+int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
+                      u8 *mac, struct station_info *sinfo)
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+       struct p80211msg_lnxreq_commsquality quality;
+       int result;
+
+       memset(sinfo, 0, sizeof(*sinfo));
+
+       if ((wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING))
+               return -EOPNOTSUPP;
+
+       /* build request message */
+       quality.msgcode = DIDmsg_lnxreq_commsquality;
+       quality.dbm.data = P80211ENUM_truth_true;
+       quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
+
+       /* send message to nsd */
+       if (wlandev->mlmerequest == NULL)
+               return -EOPNOTSUPP;
+
+       result = wlandev->mlmerequest(wlandev, (struct p80211msg *) &quality);
+
+
+       if (result == 0) {
+               sinfo->txrate.legacy = quality.txrate.data;
+               sinfo->filled |= STATION_INFO_TX_BITRATE;
+               sinfo->signal = quality.level.data;
+               sinfo->filled |= STATION_INFO_SIGNAL;
+       }
+
+       return result;
+}
+
+int prism2_scan(struct wiphy *wiphy, struct net_device *dev,
+               struct cfg80211_scan_request *request)
+{
+       struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
+       wlandevice_t *wlandev = dev->ml_priv;
+       struct p80211msg_dot11req_scan msg1;
+       struct p80211msg_dot11req_scan_results msg2;
+       int result;
+       int err = 0;
+       int numbss = 0;
+       int i = 0;
+       u8 ie_buf[46];
+       int ie_len;
+
+       if (!request)
+               return -EINVAL;
+
+       if (priv->scan_request && priv->scan_request != request)
+               return -EBUSY;
+
+       if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
+               printk(KERN_ERR "Can't scan in AP mode\n");
+               return -EOPNOTSUPP;
+       }
+
+       priv->scan_request = request;
+
+       memset(&msg1, 0x00, sizeof(struct p80211msg_dot11req_scan));
+       msg1.msgcode = DIDmsg_dot11req_scan;
+       msg1.bsstype.data = P80211ENUM_bsstype_any;
+
+       memset(&(msg1.bssid.data), 0xFF, sizeof(p80211item_pstr6_t));
+       msg1.bssid.data.len = 6;
+
+       if (request->n_ssids > 0) {
+               msg1.scantype.data = P80211ENUM_scantype_active;
+               msg1.ssid.data.len = request->ssids->ssid_len;
+               memcpy(msg1.ssid.data.data, request->ssids->ssid, request->ssids->ssid_len);
+       } else {
+               msg1.scantype.data = 0;
+       }
+       msg1.probedelay.data = 0;
+
+       for (i = 0;
+               (i < request->n_channels) && i < ARRAY_SIZE(prism2_channels);
+               i++)
+               msg1.channellist.data.data[i] =
+                       ieee80211_frequency_to_channel(request->channels[i]->center_freq);
+       msg1.channellist.data.len = request->n_channels;
+
+       msg1.maxchanneltime.data = 250;
+       msg1.minchanneltime.data = 200;
+
+       result = p80211req_dorequest(wlandev, (u8 *) &msg1);
+       if (result) {
+               err = prism2_result2err(msg1.resultcode.data);
+               goto exit;
+       }
+       /* Now retrieve scan results */
+       numbss = msg1.numbss.data;
+
+       for (i = 0; i < numbss; i++) {
+               memset(&msg2, 0, sizeof(msg2));
+               msg2.msgcode = DIDmsg_dot11req_scan_results;
+               msg2.bssindex.data = i;
+
+               result = p80211req_dorequest(wlandev, (u8 *) &msg2);
+               if ((result != 0) ||
+                   (msg2.resultcode.data != P80211ENUM_resultcode_success)) {
+                       break;
+               }
+
+               ie_buf[0] = WLAN_EID_SSID;
+               ie_buf[1] = msg2.ssid.data.len;
+               ie_len = ie_buf[1] + 2;
+               memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len);
+               cfg80211_inform_bss(wiphy,
+                       ieee80211_get_channel(wiphy, ieee80211_dsss_chan_to_freq(msg2.dschannel.data)),
+                       (const u8 *) &(msg2.bssid.data.data),
+                       msg2.timestamp.data, msg2.capinfo.data,
+                       msg2.beaconperiod.data,
+                       ie_buf,
+                       ie_len,
+                       (msg2.signal.data - 65536) * 100, /* Conversion to signed type */
+                       GFP_KERNEL
+               );
+       }
+
+       if (result)
+               err = prism2_result2err(msg2.resultcode.data);
+
+exit:
+       cfg80211_scan_done(request, err ? 1 : 0);
+       priv->scan_request = NULL;
+       return err;
+}
+
+int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+       struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
+       wlandevice_t *wlandev = priv->wlandev;
+       u32 data;
+       int result;
+       int err = 0;
+
+       if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+               if (wiphy->rts_threshold == -1)
+                       data = 2347;
+               else
+                       data = wiphy->rts_threshold;
+
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+                                               data);
+               if (result) {
+                       err = -EFAULT;
+                       goto exit;
+               }
+       }
+
+       if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+               if (wiphy->frag_threshold == -1)
+                       data = 2346;
+               else
+                       data = wiphy->frag_threshold;
+
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+                                               data);
+               if (result) {
+                       err = -EFAULT;
+                       goto exit;
+               }
+       }
+
+exit:
+       return err;
+}
+
+int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
+                  struct cfg80211_connect_params *sme)
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+       struct ieee80211_channel *channel = sme->channel;
+       struct p80211msg_lnxreq_autojoin msg_join;
+       u32 did;
+       int length = sme->ssid_len;
+       int chan = -1;
+       int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) ||
+           (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
+       int result;
+       int err = 0;
+
+       /* Set the channel */
+       if (channel) {
+               chan = ieee80211_frequency_to_channel(channel->center_freq);
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+                                               chan);
+               if (result)
+                       goto exit;
+       }
+
+       /* Set the authorisation */
+       if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
+               ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
+                       msg_join.authtype.data = P80211ENUM_authalg_opensystem;
+       else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
+               ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
+                       msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
+       else
+               printk(KERN_WARNING
+                       "Unhandled authorisation type for connect (%d)\n",
+                       sme->auth_type);
+
+       /* Set the encryption - we only support wep */
+       if (is_wep) {
+               if (sme->key) {
+                       result = prism2_domibset_uint32(wlandev,
+                               DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+                               sme->key_idx);
+                       if (result)
+                               goto exit;
+
+                       /* send key to driver */
+                       switch (sme->key_idx) {
+                       case 0:
+                               did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+                               break;
+
+                       case 1:
+                               did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+                               break;
+
+                       case 2:
+                               did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+                               break;
+
+                       case 3:
+                               did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+                               break;
+
+                       default:
+                               err = -EINVAL;
+                               goto exit;
+                       }
+
+                       result = prism2_domibset_pstr32(wlandev, did, sme->key_len, (u8 *) sme->key);
+                       if (result)
+                               goto exit;
+
+               }
+
+               /* Assume we should set privacy invoked and exclude unencrypted
+                  We could possibly use sme->privacy here, but the assumption
+                  seems reasonable anyway */
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+                                               P80211ENUM_truth_true);
+               if (result)
+                       goto exit;
+
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+                                               P80211ENUM_truth_true);
+               if (result)
+                       goto exit;
+
+       } else {
+               /* Assume we should unset privacy invoked
+                  and exclude unencrypted */
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+                                               P80211ENUM_truth_false);
+               if (result)
+                       goto exit;
+
+               result = prism2_domibset_uint32(wlandev,
+                                               DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+                                               P80211ENUM_truth_false);
+               if (result)
+                       goto exit;
+
+       }
+
+       /* Now do the actual join. Note there is no way that I can
+          see to request a specific bssid */
+       msg_join.msgcode = DIDmsg_lnxreq_autojoin;
+
+       memcpy(msg_join.ssid.data.data, sme->ssid, length);
+       msg_join.ssid.data.len = length;
+
+       result = p80211req_dorequest(wlandev, (u8 *) &msg_join);
+
+exit:
+       if (result)
+               err = -EFAULT;
+
+       return err;
+}
+
+int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
+                     u16 reason_code)
+{
+       wlandevice_t *wlandev = dev->ml_priv;
+       struct p80211msg_lnxreq_autojoin msg_join;
+       int result;
+       int err = 0;
+
+
+       /* Do a join, with a bogus ssid. Thats the only way I can think of */
+       msg_join.msgcode = DIDmsg_lnxreq_autojoin;
+
+       memcpy(msg_join.ssid.data.data, "---", 3);
+       msg_join.ssid.data.len = 3;
+
+       result = p80211req_dorequest(wlandev, (u8 *) &msg_join);
+
+       if (result)
+               err = -EFAULT;
+
+       return err;
+}
+
+
+int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+                    struct cfg80211_ibss_params *params)
+{
+       return -EOPNOTSUPP;
+}
+
+int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+       return -EOPNOTSUPP;
+}
+
+
+int prism2_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type,
+                       int mbm)
+{
+       struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
+       wlandevice_t *wlandev = priv->wlandev;
+       u32 data;
+       int result;
+       int err = 0;
+
+       if (type == NL80211_TX_POWER_AUTOMATIC)
+               data = 30;
+       else
+               data = MBM_TO_DBM(mbm);
+
+       result = prism2_domibset_uint32(wlandev,
+               DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+               data);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+exit:
+       return err;
+}
+
+int prism2_get_tx_power(struct wiphy *wiphy, int *dbm)
+{
+       struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
+       wlandevice_t *wlandev = priv->wlandev;
+       struct p80211msg_dot11req_mibget msg;
+       p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data;
+       int result;
+       int err = 0;
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem->did =
+           DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+
+       result = p80211req_dorequest(wlandev, (u8 *) &msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       *dbm = mibitem->data;
+
+exit:
+       return err;
+}
+
+
+
+
+/* Interface callback functions, passing data back up to the cfg80211 layer */
+void prism2_connect_result(wlandevice_t *wlandev, u8 failed)
+{
+       u16 status = failed ? WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS;
+
+       cfg80211_connect_result(wlandev->netdev, wlandev->bssid,
+                               NULL, 0, NULL, 0, status, GFP_KERNEL);
+}
+
+void prism2_disconnected(wlandevice_t *wlandev)
+{
+       cfg80211_disconnected(wlandev->netdev, 0, NULL,
+               0, GFP_KERNEL);
+}
+
+void prism2_roamed(wlandevice_t *wlandev)
+{
+       cfg80211_roamed(wlandev->netdev, wlandev->bssid,
+               NULL, 0, NULL, 0, GFP_KERNEL);
+}
+
+
+/* Structures for declaring wiphy interface */
+static const struct cfg80211_ops prism2_usb_cfg_ops = {
+       .change_virtual_intf = prism2_change_virtual_intf,
+       .add_key = prism2_add_key,
+       .get_key = prism2_get_key,
+       .del_key = prism2_del_key,
+       .set_default_key = prism2_set_default_key,
+       .get_station = prism2_get_station,
+       .scan = prism2_scan,
+       .set_wiphy_params = prism2_set_wiphy_params,
+       .connect = prism2_connect,
+       .disconnect = prism2_disconnect,
+       .join_ibss = prism2_join_ibss,
+       .leave_ibss = prism2_leave_ibss,
+       .set_tx_power = prism2_set_tx_power,
+       .get_tx_power = prism2_get_tx_power,
+};
+
+
+/* Functions to create/free wiphy interface */
+struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev)
+{
+       struct wiphy *wiphy;
+       struct prism2_wiphy_private *priv;
+       wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(struct prism2_wiphy_private));
+       if (!wiphy)
+               return NULL;
+
+       priv = wiphy_priv(wiphy);
+       priv->wlandev = wlandev;
+       memcpy(priv->channels, prism2_channels, sizeof(prism2_channels));
+       memcpy(priv->rates, prism2_rates, sizeof(prism2_rates));
+       priv->band.channels = priv->channels;
+       priv->band.n_channels = ARRAY_SIZE(prism2_channels);
+       priv->band.bitrates = priv->rates;
+       priv->band.n_bitrates = ARRAY_SIZE(prism2_rates);
+       wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+
+       set_wiphy_dev(wiphy, dev);
+       wiphy->privid = prism2_wiphy_privid;
+       wiphy->max_scan_ssids = 1;
+       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+                                | BIT(NL80211_IFTYPE_ADHOC);
+       wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+       wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES;
+       wiphy->cipher_suites = prism2_cipher_suites;
+
+       if (wiphy_register(wiphy) < 0)
+               return NULL;
+
+       return wiphy;
+}
+
+
+void wlan_free_wiphy(struct wiphy *wiphy)
+{
+       wiphy_unregister(wiphy);
+       wiphy_free(wiphy);
+}
index 1fa42e01e8cb6629004c7ef71373358258a1b236..fa94a7cc86cf354934114951f9632603a3a32f1d 100644 (file)
@@ -1284,6 +1284,8 @@ typedef struct hfa384x {
        u16 link_status_new;
        struct sk_buff_head authq;
 
+       u32 txrate;
+
        /* And here we have stuff that used to be in priv */
 
        /* State variables */
@@ -1407,7 +1409,7 @@ int hfa384x_drvr_start(hfa384x_t *hw);
 int hfa384x_drvr_stop(hfa384x_t *hw);
 int
 hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
-                    p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+                    union p80211_hdr *p80211_hdr, struct p80211_metawep *p80211_wep);
 void hfa384x_tx_timeout(wlandevice_t *wlandev);
 
 int hfa384x_cmd_initialize(hfa384x_t *hw);
index a41db5dc8c7c592a0f8c670495682ecb97def021..ea81cb547bb199737b1a848243afe265d887ce8b 100644 (file)
@@ -2706,8 +2706,8 @@ int hfa384x_drvr_stop(hfa384x_t *hw)
 *      interrupt
 ----------------------------------------------------------------*/
 int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
-                        p80211_hdr_t *p80211_hdr,
-                        p80211_metawep_t *p80211_wep)
+                        union p80211_hdr *p80211_hdr,
+                        struct p80211_metawep *p80211_wep)
 {
        int usbpktlen = sizeof(hfa384x_tx_frame_t);
        int result;
@@ -2752,7 +2752,7 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
 
        /* copy the header over to the txdesc */
        memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr,
-              sizeof(p80211_hdr_t));
+              sizeof(union p80211_hdr));
 
        /* if we're using host WEP, increase size by IV+ICV */
        if (p80211_wep->data) {
@@ -2805,11 +2805,13 @@ void hfa384x_tx_timeout(wlandevice_t *wlandev)
 
        spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
-       if (!hw->wlandev->hwremoved &&
-           /* Note the bitwise OR, not the logical OR. */
-           (!test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) |
-            !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))) {
-               schedule_work(&hw->usb_work);
+       if (!hw->wlandev->hwremoved) {
+               int sched;
+
+               sched = !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags);
+               sched |= !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags);
+               if (sched)
+                       schedule_work(&hw->usb_work);
        }
 
        spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
@@ -3471,7 +3473,7 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
        hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data;
        hfa384x_t *hw = wlandev->priv;
        int hdrlen;
-       p80211_rxmeta_t *rxmeta;
+       struct p80211_rxmeta *rxmeta;
        u16 data_len;
        u16 fc;
 
@@ -3588,14 +3590,14 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
        datalen = le16_to_cpu(rxdesc->data_len);
 
        /* Allocate an ind message+framesize skb */
-       skblen = sizeof(p80211_caphdr_t) + hdrlen + datalen + WLAN_CRC_LEN;
+       skblen = sizeof(struct p80211_caphdr) + hdrlen + datalen + WLAN_CRC_LEN;
 
        /* sanity check the length */
        if (skblen >
-           (sizeof(p80211_caphdr_t) +
+           (sizeof(struct p80211_caphdr) +
             WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
                pr_debug("overlen frm: len=%zd\n",
-                        skblen - sizeof(p80211_caphdr_t));
+                        skblen - sizeof(struct p80211_caphdr));
        }
 
        skb = dev_alloc_skb(skblen);
@@ -3609,13 +3611,13 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
        /* only prepend the prism header if in the right mode */
        if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
            (hw->sniffhdr != 0)) {
-               p80211_caphdr_t *caphdr;
+               struct p80211_caphdr *caphdr;
                /* The NEW header format! */
-               datap = skb_put(skb, sizeof(p80211_caphdr_t));
-               caphdr = (p80211_caphdr_t *) datap;
+               datap = skb_put(skb, sizeof(struct p80211_caphdr));
+               caphdr = (struct p80211_caphdr *) datap;
 
                caphdr->version = htonl(P80211CAPTURE_VERSION);
-               caphdr->length = htonl(sizeof(p80211_caphdr_t));
+               caphdr->length = htonl(sizeof(struct p80211_caphdr));
                caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000;
                caphdr->hosttime = __cpu_to_be64(jiffies);
                caphdr->phytype = htonl(4);     /* dss_dot11_b */
index 059e15055b742d6e29f135be9cbd3586b506b424..83879f9a0b7d058d81476702cf7d656554194a76 100644 (file)
@@ -103,15 +103,15 @@ static u8 oui_8021h[] = { 0x00, 0x00, 0xf8 };
 *      May be called in interrupt or non-interrupt context
 ----------------------------------------------------------------*/
 int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
-                       struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
-                       p80211_metawep_t *p80211_wep)
+                       struct sk_buff *skb, union p80211_hdr *p80211_hdr,
+                       struct p80211_metawep *p80211_wep)
 {
 
        u16 fc;
        u16 proto;
-       wlan_ethhdr_t e_hdr;
-       wlan_llc_t *e_llc;
-       wlan_snap_t *e_snap;
+       struct wlan_ethhdr e_hdr;
+       struct wlan_llc *e_llc;
+       struct wlan_snap *e_snap;
        int foo;
 
        memcpy(&e_hdr, skb->data, sizeof(e_hdr));
@@ -148,7 +148,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
 
                        /* tack on SNAP */
                        e_snap =
-                           (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
+                           (struct wlan_snap *) skb_push(skb, sizeof(struct wlan_snap));
                        e_snap->type = htons(proto);
                        if (ethconv == WLAN_ETHCONV_8021h
                            && p80211_stt_findproto(proto)) {
@@ -161,7 +161,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
 
                        /* tack on llc */
                        e_llc =
-                           (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
+                           (struct wlan_llc *) skb_push(skb, sizeof(struct wlan_llc));
                        e_llc->dsap = 0xAA;     /* SNAP, see IEEE 802 */
                        e_llc->ssap = 0xAA;
                        e_llc->ctl = 0x03;
@@ -230,7 +230,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
 
 /* jkriegl: from orinoco, modified */
 static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
-                              p80211_rxmeta_t *rxmeta)
+                              struct p80211_rxmeta *rxmeta)
 {
        int i;
 
@@ -280,17 +280,17 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
        unsigned int payload_offset;
        u8 daddr[WLAN_ETHADDR_LEN];
        u8 saddr[WLAN_ETHADDR_LEN];
-       p80211_hdr_t *w_hdr;
-       wlan_ethhdr_t *e_hdr;
-       wlan_llc_t *e_llc;
-       wlan_snap_t *e_snap;
+       union p80211_hdr *w_hdr;
+       struct wlan_ethhdr *e_hdr;
+       struct wlan_llc *e_llc;
+       struct wlan_snap *e_snap;
 
        int foo;
 
        payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
        payload_offset = WLAN_HDR_A3_LEN;
 
-       w_hdr = (p80211_hdr_t *) skb->data;
+       w_hdr = (union p80211_hdr *) skb->data;
 
        /* setup some vars for convenience */
        fc = le16_to_cpu(w_hdr->a3.fc);
@@ -345,14 +345,14 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
                wlandev->rx.decrypt++;
        }
 
-       e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);
+       e_hdr = (struct wlan_ethhdr *) (skb->data + payload_offset);
 
-       e_llc = (wlan_llc_t *) (skb->data + payload_offset);
+       e_llc = (struct wlan_llc *) (skb->data + payload_offset);
        e_snap =
-           (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
+           (struct wlan_snap *) (skb->data + payload_offset + sizeof(struct wlan_llc));
 
        /* Test for the various encodings */
-       if ((payload_length >= sizeof(wlan_ethhdr_t)) &&
+       if ((payload_length >= sizeof(struct wlan_ethhdr)) &&
            (e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) &&
            ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
             (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
@@ -372,7 +372,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
                /* chop off the 802.11 CRC */
                skb_trim(skb, skb->len - WLAN_CRC_LEN);
 
-       } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t))
+       } else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap))
                   && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
                   && (e_llc->ctl == 0x03)
                   &&
@@ -398,7 +398,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
                skb_pull(skb, payload_offset);
 
                /* create 802.3 header at beginning of skb. */
-               e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+               e_hdr = (struct wlan_ethhdr *) skb_push(skb, WLAN_ETHHDR_LEN);
                memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
                memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
                e_hdr->type = htons(payload_length);
@@ -406,7 +406,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
                /* chop off the 802.11 CRC */
                skb_trim(skb, skb->len - WLAN_CRC_LEN);
 
-       } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t))
+       } else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap))
                   && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
                   && (e_llc->ctl == 0x03)) {
                pr_debug("802.1h/RFC1042 len: %d\n", payload_length);
@@ -414,13 +414,13 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
                /* build a DIXII + RFC894 */
 
                /* Test for an overlength frame */
-               if ((payload_length - sizeof(wlan_llc_t) - sizeof(wlan_snap_t))
+               if ((payload_length - sizeof(struct wlan_llc) - sizeof(struct wlan_snap))
                    > netdev->mtu) {
                        /* A bogus length ethfrm has been sent. */
                        /* Is someone trying an oflow attack? */
                        printk(KERN_ERR "DIXII frame too large (%ld > %d)\n",
-                              (long int)(payload_length - sizeof(wlan_llc_t) -
-                                         sizeof(wlan_snap_t)), netdev->mtu);
+                              (long int)(payload_length - sizeof(struct wlan_llc) -
+                                         sizeof(struct wlan_snap)), netdev->mtu);
                        return 1;
                }
 
@@ -428,13 +428,13 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
                skb_pull(skb, payload_offset);
 
                /* chop llc header from skb. */
-               skb_pull(skb, sizeof(wlan_llc_t));
+               skb_pull(skb, sizeof(struct wlan_llc));
 
                /* chop snap header from skb. */
-               skb_pull(skb, sizeof(wlan_snap_t));
+               skb_pull(skb, sizeof(struct wlan_snap));
 
                /* create 802.3 header at beginning of skb. */
-               e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+               e_hdr = (struct wlan_ethhdr *) skb_push(skb, WLAN_ETHHDR_LEN);
                e_hdr->type = e_snap->type;
                memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
                memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
@@ -461,7 +461,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
                skb_pull(skb, payload_offset);
 
                /* create 802.3 header at beginning of skb. */
-               e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+               e_hdr = (struct wlan_ethhdr *) skb_push(skb, WLAN_ETHHDR_LEN);
                memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
                memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
                e_hdr->type = htons(payload_length);
@@ -542,8 +542,8 @@ int p80211_stt_findproto(u16 proto)
 ----------------------------------------------------------------*/
 void p80211skb_rxmeta_detach(struct sk_buff *skb)
 {
-       p80211_rxmeta_t *rxmeta;
-       p80211_frmmeta_t *frmmeta;
+       struct p80211_rxmeta *rxmeta;
+       struct p80211_frmmeta *frmmeta;
 
        /* Sanity checks */
        if (skb == NULL) {      /* bad skb */
@@ -589,8 +589,8 @@ exit:
 int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
 {
        int result = 0;
-       p80211_rxmeta_t *rxmeta;
-       p80211_frmmeta_t *frmmeta;
+       struct p80211_rxmeta *rxmeta;
+       struct p80211_frmmeta *frmmeta;
 
        /* If these already have metadata, we error out! */
        if (P80211SKB_RXMETA(skb) != NULL) {
@@ -601,7 +601,7 @@ int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
        }
 
        /* Allocate the rxmeta */
-       rxmeta = kzalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC);
+       rxmeta = kzalloc(sizeof(struct p80211_rxmeta), GFP_ATOMIC);
 
        if (rxmeta == NULL) {
                printk(KERN_ERR "%s: Failed to allocate rxmeta.\n",
@@ -615,8 +615,8 @@ int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
        rxmeta->hosttime = jiffies;
 
        /* Overlay a frmmeta_t onto skb->cb */
-       memset(skb->cb, 0, sizeof(p80211_frmmeta_t));
-       frmmeta = (p80211_frmmeta_t *) (skb->cb);
+       memset(skb->cb, 0, sizeof(struct p80211_frmmeta));
+       frmmeta = (struct p80211_frmmeta *) (skb->cb);
        frmmeta->magic = P80211_FRMMETA_MAGIC;
        frmmeta->rx = rxmeta;
 exit:
@@ -641,7 +641,7 @@ exit:
 ----------------------------------------------------------------*/
 void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
 {
-       p80211_frmmeta_t *meta;
+       struct p80211_frmmeta *meta;
 
        meta = P80211SKB_FRMMETA(skb);
        if (meta && meta->rx)
index 6fe163be24f624dc8b698aea2e0b4583798c6483..eca0391c676fe537756cc12c67845d742bb2ab1e 100644 (file)
 
 #define P80211CAPTURE_VERSION  0x80211001
 
-#define        P80211_FRMMETA_MAGIC            0x802110
+#define        P80211_FRMMETA_MAGIC    0x802110
 
 #define P80211SKB_FRMMETA(s) \
-       (((((p80211_frmmeta_t *)((s)->cb))->magic) == P80211_FRMMETA_MAGIC) ? \
-               ((p80211_frmmeta_t *)((s)->cb)) : \
+       (((((struct p80211_frmmeta *)((s)->cb))->magic) == P80211_FRMMETA_MAGIC) ? \
+               ((struct p80211_frmmeta *)((s)->cb)) : \
                (NULL))
 
 #define P80211SKB_RXMETA(s) \
-       (P80211SKB_FRMMETA((s)) ?  P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t *)(NULL)))
+       (P80211SKB_FRMMETA((s)) ?  P80211SKB_FRMMETA((s))->rx : ((struct p80211_rxmeta *)(NULL)))
 
-typedef struct p80211_rxmeta {
+struct p80211_rxmeta {
        struct wlandevice *wlandev;
 
        u64 mactime;            /* Hi-rez MAC-supplied time value */
@@ -87,12 +87,12 @@ typedef struct p80211_rxmeta {
        unsigned int preamble;  /* P80211ENUM_preambletype_* */
        unsigned int encoding;  /* P80211ENUM_encoding_* */
 
-} p80211_rxmeta_t;
+};
 
-typedef struct p80211_frmmeta {
+struct p80211_frmmeta {
        unsigned int magic;
-       p80211_rxmeta_t *rx;
-} p80211_frmmeta_t;
+       struct p80211_rxmeta *rx;
+};
 
 void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb);
 int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb);
@@ -101,7 +101,7 @@ void p80211skb_rxmeta_detach(struct sk_buff *skb);
 /*
  * Frame capture header.  (See doc/capturefrm.txt)
  */
-typedef struct p80211_caphdr {
+struct p80211_caphdr {
        u32 version;
        u32 length;
        u64 mactime;
@@ -116,36 +116,36 @@ typedef struct p80211_caphdr {
        s32 ssi_noise;
        u32 preamble;
        u32 encoding;
-} p80211_caphdr_t;
+};
 
 /* buffer free method pointer type */
 typedef void (*freebuf_method_t) (void *buf, int size);
 
-typedef struct p80211_metawep {
+struct p80211_metawep {
        void *data;
        u8 iv[4];
        u8 icv[4];
-} p80211_metawep_t;
+};
 
 /* local ether header type */
-typedef struct wlan_ethhdr {
+struct wlan_ethhdr {
        u8 daddr[WLAN_ETHADDR_LEN];
        u8 saddr[WLAN_ETHADDR_LEN];
        u16 type;
-} __attribute__ ((packed)) wlan_ethhdr_t;
+} __attribute__ ((packed));
 
 /* local llc header type */
-typedef struct wlan_llc {
+struct wlan_llc {
        u8 dsap;
        u8 ssap;
        u8 ctl;
-} __attribute__ ((packed)) wlan_llc_t;
+} __attribute__ ((packed));
 
 /* local snap header type */
-typedef struct wlan_snap {
+struct wlan_snap {
        u8 oui[WLAN_IEEE_OUI_LEN];
        u16 type;
-} __attribute__ ((packed)) wlan_snap_t;
+} __attribute__ ((packed));
 
 /* Circular include trick */
 struct wlandevice;
@@ -153,8 +153,8 @@ struct wlandevice;
 int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
                        struct sk_buff *skb);
 int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
-                       struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
-                       p80211_metawep_t *p80211_wep);
+                       struct sk_buff *skb, union p80211_hdr *p80211_hdr,
+                       struct p80211_metawep *p80211_wep);
 
 int p80211_stt_findproto(u16 proto);
 
index 419de4dee560ee884cb72287ebe079997d8be126..1f6e4ebc6eb9ddc8d4a16baac234062ff38b8f8d 100644 (file)
@@ -94,7 +94,7 @@
 
 /* Control */
 #define WLAN_FSTYPE_BLOCKACKREQ                0x8
-#define WLAN_FSTYPE_BLOCKACK           0x9
+#define WLAN_FSTYPE_BLOCKACK           0x9
 #define WLAN_FSTYPE_PSPOLL             0x0a
 #define WLAN_FSTYPE_RTS                        0x0b
 #define WLAN_FSTYPE_CTS                        0x0c
 
 #define WLAN_GET_FC_FTYPE(n)   ((((u16)(n)) & (BIT(2) | BIT(3))) >> 2)
 #define WLAN_GET_FC_FSTYPE(n)  ((((u16)(n)) & (BIT(4)|BIT(5)|BIT(6)|BIT(7))) >> 4)
-#define WLAN_GET_FC_TODS(n)    ((((u16)(n)) & (BIT(8))) >> 8)
+#define WLAN_GET_FC_TODS(n)    ((((u16)(n)) & (BIT(8))) >> 8)
 #define WLAN_GET_FC_FROMDS(n)  ((((u16)(n)) & (BIT(9))) >> 9)
 #define WLAN_GET_FC_ISWEP(n)   ((((u16)(n)) & (BIT(14))) >> 14)
 
 #define WLAN_SET_FC_FTYPE(n)   (((u16)(n)) << 2)
 #define WLAN_SET_FC_FSTYPE(n)  (((u16)(n)) << 4)
-#define WLAN_SET_FC_TODS(n)    (((u16)(n)) << 8)
+#define WLAN_SET_FC_TODS(n)    (((u16)(n)) << 8)
 #define WLAN_SET_FC_FROMDS(n)  (((u16)(n)) << 9)
 #define WLAN_SET_FC_ISWEP(n)   (((u16)(n)) << 14)
 
 
 /* Generic 802.11 Header types */
 
-typedef struct p80211_hdr_a3 {
+struct p80211_hdr_a3 {
        u16 fc;
        u16 dur;
        u8 a1[ETH_ALEN];
        u8 a2[ETH_ALEN];
        u8 a3[ETH_ALEN];
        u16 seq;
-} __attribute__ ((packed)) p80211_hdr_a3_t;
+} __attribute__ ((packed));
 
-typedef struct p80211_hdr_a4 {
+struct p80211_hdr_a4 {
        u16 fc;
        u16 dur;
        u8 a1[ETH_ALEN];
@@ -164,18 +164,18 @@ typedef struct p80211_hdr_a4 {
        u8 a3[ETH_ALEN];
        u16 seq;
        u8 a4[ETH_ALEN];
-} __attribute__ ((packed)) p80211_hdr_a4_t;
+} __attribute__ ((packed));
 
-typedef union p80211_hdr {
-       p80211_hdr_a3_t a3;
-       p80211_hdr_a4_t a4;
-} __attribute__ ((packed)) p80211_hdr_t;
+union p80211_hdr {
+       struct p80211_hdr_a3 a3;
+       struct p80211_hdr_a4 a4;
+} __attribute__ ((packed));
 
 /* Frame and header length macros */
 
 #define WLAN_CTL_FRAMELEN(fstype) (\
        (fstype) == WLAN_FSTYPE_BLOCKACKREQ     ? 24 : \
-       (fstype) == WLAN_FSTYPE_BLOCKACK        ? 152 : \
+       (fstype) == WLAN_FSTYPE_BLOCKACK        ? 152 : \
        (fstype) == WLAN_FSTYPE_PSPOLL          ? 20 : \
        (fstype) == WLAN_FSTYPE_RTS             ? 20 : \
        (fstype) == WLAN_FSTYPE_CTS             ? 14 : \
index 64ca7f95262caa58bb5287bd8c4125f298ca7567..0d47765452ee0532bd808d3285188b687ac2e705 100644 (file)
 /*  argument to the ioctl system call when issuing a request to */
 /*  the p80211 module. */
 
-typedef struct p80211ioctl_req {
+struct p80211ioctl_req {
        char name[WLAN_DEVNAMELEN_MAX];
        caddr_t data;
        u32 magic;
        u16 len;
        u32 result;
-} __attribute__ ((packed)) p80211ioctl_req_t;
+} __attribute__ ((packed));
 
 #endif /* _P80211IOCTL_H */
index b9badcff681f32caa9bd52965cfc8413c2f5a23d..c5f1a63add9743345d71081d29e04a37ed1c2e89 100644 (file)
@@ -62,7 +62,7 @@
 /* representation of category list metadata, group list metadata, */
 /* and data item metadata for both Mib and Messages. */
 
-typedef struct p80211meta {
+struct p80211meta {
        char *name;             /* data item name */
        u32 did;                /* partial did */
        u32 flags;              /* set of various flag bits */
@@ -75,16 +75,16 @@ typedef struct p80211meta {
        p80211_totext_t totextptr;      /* ptr to totext conversion function */
        p80211_fromtext_t fromtextptr;  /* ptr to totext conversion function */
        p80211_valid_t validfunptr;     /* ptr to totext conversion function */
-} p80211meta_t;
+};
 
-typedef struct grplistitem {
+struct grplistitem {
        char *name;
-       p80211meta_t *itemlist;
-} grplistitem_t;
+       struct p80211meta *itemlist;
+};
 
-typedef struct catlistitem {
+struct catlistitem {
        char *name;
-       grplistitem_t *grplist;
-} catlistitem_t;
+       struct grplistitem *grplist;
+};
 
 #endif /* _P80211META_H */
index db12713eeaa9e2b566ef62d67005b9052d797fc7..a8a4e3b5ffef46f5111925cfb50782ffe40397a6 100644 (file)
 #ifndef _P80211MKMETASTRUCT_H
 #define _P80211MKMETASTRUCT_H
 
-typedef struct p80211msg_dot11req_mibget {
+struct p80211msg_dot11req_mibget {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
        p80211item_unk392_t mibattribute;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_dot11req_mibget_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_dot11req_mibset {
+struct p80211msg_dot11req_mibset {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
        p80211item_unk392_t mibattribute;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_dot11req_mibset_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_dot11req_scan {
+struct p80211msg_dot11req_scan {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -81,9 +81,9 @@ typedef struct p80211msg_dot11req_scan {
        p80211item_uint32_t resultcode;
        p80211item_uint32_t numbss;
        p80211item_uint32_t append;
-} __attribute__ ((packed)) p80211msg_dot11req_scan_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_dot11req_scan_results {
+struct p80211msg_dot11req_scan_results {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -113,6 +113,7 @@ typedef struct p80211msg_dot11req_scan_results {
        p80211item_uint32_t cfpollable;
        p80211item_uint32_t cfpollreq;
        p80211item_uint32_t privacy;
+       p80211item_uint32_t capinfo;
        p80211item_uint32_t basicrate1;
        p80211item_uint32_t basicrate2;
        p80211item_uint32_t basicrate3;
@@ -129,9 +130,9 @@ typedef struct p80211msg_dot11req_scan_results {
        p80211item_uint32_t supprate6;
        p80211item_uint32_t supprate7;
        p80211item_uint32_t supprate8;
-} __attribute__ ((packed)) p80211msg_dot11req_scan_results_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_dot11req_start {
+struct p80211msg_dot11req_start {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -167,17 +168,17 @@ typedef struct p80211msg_dot11req_start {
        p80211item_uint32_t operationalrate7;
        p80211item_uint32_t operationalrate8;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_dot11req_start_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_lnxreq_ifstate {
+struct p80211msg_lnxreq_ifstate {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
        p80211item_uint32_t ifstate;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_lnxreq_ifstate_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_lnxreq_wlansniff {
+struct p80211msg_lnxreq_wlansniff {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -189,18 +190,18 @@ typedef struct p80211msg_lnxreq_wlansniff {
        p80211item_uint32_t stripfcs;
        p80211item_uint32_t packet_trunc;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_lnxreq_wlansniff_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_lnxreq_hostwep {
+struct p80211msg_lnxreq_hostwep {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
        p80211item_uint32_t resultcode;
        p80211item_uint32_t decrypt;
        p80211item_uint32_t encrypt;
-} __attribute__ ((packed)) p80211msg_lnxreq_hostwep_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_lnxreq_commsquality {
+struct p80211msg_lnxreq_commsquality {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -209,9 +210,10 @@ typedef struct p80211msg_lnxreq_commsquality {
        p80211item_uint32_t link;
        p80211item_uint32_t level;
        p80211item_uint32_t noise;
-} __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t;
+       p80211item_uint32_t txrate;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_lnxreq_autojoin {
+struct p80211msg_lnxreq_autojoin {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -219,26 +221,26 @@ typedef struct p80211msg_lnxreq_autojoin {
        u8 pad_19D[3];
        p80211item_uint32_t authtype;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_lnxreq_autojoin_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_p2req_readpda {
+struct p80211msg_p2req_readpda {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
        p80211item_unk1024_t pda;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_p2req_readpda_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_p2req_ramdl_state {
+struct p80211msg_p2req_ramdl_state {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
        p80211item_uint32_t enable;
        p80211item_uint32_t exeaddr;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_p2req_ramdl_state_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_p2req_ramdl_write {
+struct p80211msg_p2req_ramdl_write {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -246,17 +248,17 @@ typedef struct p80211msg_p2req_ramdl_write {
        p80211item_uint32_t len;
        p80211item_unk4096_t data;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_p2req_ramdl_write_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_p2req_flashdl_state {
+struct p80211msg_p2req_flashdl_state {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
        p80211item_uint32_t enable;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_p2req_flashdl_state_t;
+} __attribute__ ((packed));
 
-typedef struct p80211msg_p2req_flashdl_write {
+struct p80211msg_p2req_flashdl_write {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
@@ -264,6 +266,6 @@ typedef struct p80211msg_p2req_flashdl_write {
        p80211item_uint32_t len;
        p80211item_unk4096_t data;
        p80211item_uint32_t resultcode;
-} __attribute__ ((packed)) p80211msg_p2req_flashdl_write_t;
+} __attribute__ ((packed));
 
 #endif
index deb52f5fd78050ed9ee1e58d99ebe433a2fc8f3c..3b5e8113ad17c55d742e4a75245c04f6ceb8f8a8 100644 (file)
@@ -298,7 +298,7 @@ typedef struct wlan_fr_mgmt {
        u16 type;
        u16 len;                /* DOES NOT include CRC !!!! */
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -310,7 +310,7 @@ typedef struct wlan_fr_beacon {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -333,7 +333,7 @@ typedef struct wlan_fr_ibssatim {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
 
@@ -349,7 +349,7 @@ typedef struct wlan_fr_disassoc {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -364,7 +364,7 @@ typedef struct wlan_fr_assocreq {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -381,7 +381,7 @@ typedef struct wlan_fr_assocresp {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -398,7 +398,7 @@ typedef struct wlan_fr_reassocreq {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -416,7 +416,7 @@ typedef struct wlan_fr_reassocresp {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -433,7 +433,7 @@ typedef struct wlan_fr_probereq {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -448,7 +448,7 @@ typedef struct wlan_fr_proberesp {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -469,7 +469,7 @@ typedef struct wlan_fr_authen {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
@@ -486,7 +486,7 @@ typedef struct wlan_fr_deauthen {
        u16 type;
        u16 len;
        u8 *buf;
-       p80211_hdr_t *hdr;
+       union p80211_hdr *hdr;
        /* used for target specific data, skb in Linux */
        void *priv;
        /*-- fixed fields -----------*/
index c691d3eeb9d004e9b285638be4df872fa21d1619..8e0f9a0cd74ab08d48d1a65f0e798e310b0d5c68 100644 (file)
 
 #define WLAN_DEVNAMELEN_MAX    16
 
-typedef struct p80211msg {
+struct p80211msg {
        u32 msgcode;
        u32 msglen;
        u8 devname[WLAN_DEVNAMELEN_MAX];
-} __attribute__ ((packed)) p80211msg_t;
+} __attribute__ ((packed));
 
 #endif /* _P80211MSG_H */
index 763ab1187a1cfe64640d0dcc14284a558ee98030..aa1792c8429ea4c049868f40f9374d9e326a3743 100644 (file)
@@ -75,6 +75,7 @@
 
 #include <net/iw_handler.h>
 #include <net/net_namespace.h>
+#include <net/cfg80211.h>
 
 #include "p80211types.h"
 #include "p80211hdr.h"
@@ -87,6 +88,8 @@
 #include "p80211metastruct.h"
 #include "p80211metadef.h"
 
+#include "cfg80211.c"
+
 /* Support functions */
 static void p80211netdev_rx_bh(unsigned long arg);
 
@@ -261,7 +264,7 @@ static void p80211netdev_rx_bh(unsigned long arg)
        wlandevice_t *wlandev = (wlandevice_t *) arg;
        struct sk_buff *skb = NULL;
        netdevice_t *dev = wlandev->netdev;
-       p80211_hdr_a3_t *hdr;
+       struct p80211_hdr_a3 *hdr;
        u16 fc;
 
        /* Let's empty our our queue */
@@ -285,7 +288,7 @@ static void p80211netdev_rx_bh(unsigned long arg)
                                netif_rx_ni(skb);
                                continue;
                        } else {
-                               hdr = (p80211_hdr_a3_t *) skb->data;
+                               hdr = (struct p80211_hdr_a3 *) skb->data;
                                fc = le16_to_cpu(hdr->fc);
                                if (p80211_rx_typedrop(wlandev, fc)) {
                                        dev_kfree_skb(skb);
@@ -347,8 +350,8 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
        int result = 0;
        int txresult = -1;
        wlandevice_t *wlandev = netdev->ml_priv;
-       p80211_hdr_t p80211_hdr;
-       p80211_metawep_t p80211_wep;
+       union p80211_hdr p80211_hdr;
+       struct p80211_metawep p80211_wep;
 
        if (skb == NULL)
                return NETDEV_TX_OK;
@@ -358,8 +361,8 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
                goto failed;
        }
 
-       memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
-       memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
+       memset(&p80211_hdr, 0, sizeof(union p80211_hdr));
+       memset(&p80211_wep, 0, sizeof(struct p80211_metawep));
 
        if (netif_queue_stopped(netdev)) {
                pr_debug("called when queue stopped.\n");
@@ -398,8 +401,8 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
                        goto failed;
                }
                /* move the header over */
-               memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t));
-               skb_pull(skb, sizeof(p80211_hdr_t));
+               memcpy(&p80211_hdr, skb->data, sizeof(union p80211_hdr));
+               skb_pull(skb, sizeof(union p80211_hdr));
        } else {
                if (skb_ether_to_p80211
                    (wlandev, wlandev->ethconv, skb, &p80211_hdr,
@@ -557,7 +560,7 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
 static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
 {
        int result = 0;
-       p80211ioctl_req_t *req = (p80211ioctl_req_t *) ifr;
+       struct p80211ioctl_req *req = (struct p80211ioctl_req *) ifr;
        wlandevice_t *wlandev = dev->ml_priv;
        u8 *msgbuf;
 
@@ -604,7 +607,8 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
                result = -ENOMEM;
        }
 bail:
-       return result;          /* If allocate,copyfrom or copyto fails, return errno */
+       /* If allocate,copyfrom or copyto fails, return errno */
+       return result;
 }
 
 /*----------------------------------------------------------------
@@ -635,7 +639,7 @@ bail:
 static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
 {
        struct sockaddr *new_addr = addr;
-       p80211msg_dot11req_mibset_t dot11req;
+       struct p80211msg_dot11req_mibset dot11req;
        p80211item_unk392_t *mibattr;
        p80211item_pstr6_t *macaddr;
        p80211item_uint32_t *resultcode;
@@ -651,9 +655,9 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
        resultcode = &dot11req.resultcode;
 
        /* Set up a dot11req_mibset */
-       memset(&dot11req, 0, sizeof(p80211msg_dot11req_mibset_t));
+       memset(&dot11req, 0, sizeof(struct p80211msg_dot11req_mibset));
        dot11req.msgcode = DIDmsg_dot11req_mibset;
-       dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
+       dot11req.msglen = sizeof(struct p80211msg_dot11req_mibset);
        memcpy(dot11req.devname,
               ((wlandevice_t *) dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1);
 
@@ -732,6 +736,7 @@ static const struct net_device_ops p80211_netdev_ops = {
 * Arguments:
 *      wlandev         ptr to the wlandev structure for the
 *                      interface.
+*      physdev         ptr to usb device
 * Returns:
 *      zero on success, non-zero otherwise.
 * Call Context:
@@ -740,10 +745,12 @@ static const struct net_device_ops p80211_netdev_ops = {
 *      compiled drivers, this function will be called in the
 *      context of the kernel startup code.
 ----------------------------------------------------------------*/
-int wlan_setup(wlandevice_t *wlandev)
+int wlan_setup(wlandevice_t *wlandev, struct device *physdev)
 {
        int result = 0;
-       netdevice_t *dev;
+       netdevice_t *netdev;
+       struct wiphy *wiphy;
+       struct wireless_dev *wdev;
 
        /* Set up the wlandev */
        wlandev->state = WLAN_DEVICE_CLOSED;
@@ -755,20 +762,30 @@ int wlan_setup(wlandevice_t *wlandev)
        tasklet_init(&wlandev->rx_bh,
                     p80211netdev_rx_bh, (unsigned long)wlandev);
 
+       /* Allocate and initialize the wiphy struct */
+       wiphy = wlan_create_wiphy(physdev, wlandev);
+       if (wiphy == NULL) {
+               printk(KERN_ERR "Failed to alloc wiphy.\n");
+               return 1;
+       }
+
        /* Allocate and initialize the struct device */
-       dev = alloc_netdev(0, "wlan%d", ether_setup);
-       if (dev == NULL) {
+       netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", ether_setup);
+       if (netdev == NULL) {
                printk(KERN_ERR "Failed to alloc netdev.\n");
+               wlan_free_wiphy(wiphy);
                result = 1;
        } else {
-               wlandev->netdev = dev;
-               dev->ml_priv = wlandev;
-               dev->netdev_ops = &p80211_netdev_ops;
-
-               dev->wireless_handlers = &p80211wext_handler_def;
-
-               netif_stop_queue(dev);
-               netif_carrier_off(dev);
+               wlandev->netdev = netdev;
+               netdev->ml_priv = wlandev;
+               netdev->netdev_ops = &p80211_netdev_ops;
+               wdev = netdev_priv(netdev);
+               wdev->wiphy = wiphy;
+               wdev->iftype = NL80211_IFTYPE_STATION;
+               netdev->ieee80211_ptr = wdev;
+
+               netif_stop_queue(netdev);
+               netif_carrier_off(netdev);
        }
 
        return result;
@@ -797,14 +814,14 @@ int wlan_setup(wlandevice_t *wlandev)
 ----------------------------------------------------------------*/
 int wlan_unsetup(wlandevice_t *wlandev)
 {
-       int result = 0;
+       struct wireless_dev *wdev;
 
        tasklet_kill(&wlandev->rx_bh);
 
-       if (wlandev->netdev == NULL) {
-               printk(KERN_ERR "called without wlandev->netdev set.\n");
-               result = 1;
-       } else {
+       if (wlandev->netdev) {
+               wdev = netdev_priv(wlandev->netdev);
+               if (wdev->wiphy)
+                       wlan_free_wiphy(wdev->wiphy);
                free_netdev(wlandev->netdev);
                wlandev->netdev = NULL;
        }
index 3c8c64800567dc2a5ffc43b92d5304704844e5c2..1ec33740f10fe6fe1451464f0ccd95af3cf479ee 100644 (file)
@@ -148,6 +148,7 @@ int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
 #define MAX_KEYLEN 32
 
 #define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0))
+#define HOSTWEP_SHAREDKEY BIT(3)
 #define HOSTWEP_DECRYPT  BIT(4)
 #define HOSTWEP_ENCRYPT  BIT(5)
 #define HOSTWEP_PRIVACYINVOKED BIT(6)
@@ -183,9 +184,9 @@ typedef struct wlandevice {
        int (*close) (struct wlandevice *wlandev);
        void (*reset) (struct wlandevice *wlandev);
        int (*txframe) (struct wlandevice *wlandev, struct sk_buff *skb,
-                       p80211_hdr_t *p80211_hdr,
-                       p80211_metawep_t *p80211_wep);
-       int (*mlmerequest) (struct wlandevice *wlandev, p80211msg_t *msg);
+                       union p80211_hdr *p80211_hdr,
+                       struct p80211_metawep *p80211_wep);
+       int (*mlmerequest) (struct wlandevice *wlandev, struct p80211msg *msg);
        int (*set_multicast_list) (struct wlandevice *wlandev,
                                   netdevice_t *dev);
        void (*tx_timeout) (struct wlandevice *wlandev);
@@ -233,7 +234,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
 int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
                u8 *iv, u8 *icv);
 
-int wlan_setup(wlandevice_t *wlandev);
+int wlan_setup(wlandevice_t *wlandev, struct device *physdev);
 int wlan_unsetup(wlandevice_t *wlandev);
 int register_wlandev(wlandevice_t *wlandev);
 int unregister_wlandev(wlandevice_t *wlandev);
index 207f080cfc9e0c2589bcd0f61d883e501e169764..179194e7d2aaaff731b4675f1016b604cc9ecee0 100644 (file)
@@ -72,9 +72,9 @@
 #include "p80211metastruct.h"
 #include "p80211req.h"
 
-static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg);
+static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg);
 static int p80211req_mibset_mibget(wlandevice_t *wlandev,
-                                  p80211msg_dot11req_mibget_t *mib_msg,
+                                  struct p80211msg_dot11req_mibget *mib_msg,
                                   int isget);
 
 /*----------------------------------------------------------------
@@ -96,7 +96,7 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev,
 int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
 {
        int result = 0;
-       p80211msg_t *msg = (p80211msg_t *) msgbuf;
+       struct p80211msg *msg = (struct p80211msg *) msgbuf;
 
        /* Check to make sure the MSD is running */
        if (!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
@@ -150,13 +150,13 @@ int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
 * Call context:
 *      Process thread
 ----------------------------------------------------------------*/
-static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg)
+static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg)
 {
        switch (msg->msgcode) {
 
        case DIDmsg_lnxreq_hostwep:{
-                       p80211msg_lnxreq_hostwep_t *req =
-                           (p80211msg_lnxreq_hostwep_t *) msg;
+                       struct p80211msg_lnxreq_hostwep *req =
+                           (struct p80211msg_lnxreq_hostwep *) msg;
                        wlandev->hostwep &=
                            ~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT);
                        if (req->decrypt.data == P80211ENUM_truth_true)
@@ -169,8 +169,8 @@ static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg)
        case DIDmsg_dot11req_mibget:
        case DIDmsg_dot11req_mibset:{
                        int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
-                       p80211msg_dot11req_mibget_t *mib_msg =
-                           (p80211msg_dot11req_mibget_t *) msg;
+                       struct p80211msg_dot11req_mibget *mib_msg =
+                           (struct p80211msg_dot11req_mibget *) msg;
                        p80211req_mibset_mibget(wlandev, mib_msg, isget);
                }
        default:
@@ -181,7 +181,7 @@ static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg)
 }
 
 static int p80211req_mibset_mibget(wlandevice_t *wlandev,
-                                  p80211msg_dot11req_mibget_t *mib_msg,
+                                  struct p80211msg_dot11req_mibget *mib_msg,
                                   int isget)
 {
        p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
deleted file mode 100644 (file)
index 387194d..0000000
+++ /dev/null
@@ -1,1690 +0,0 @@
-/* src/p80211/p80211wext.c
-*
-* Glue code to make linux-wlan-ng a happy wireless extension camper.
-*
-* original author:  Reyk Floeter <reyk@synack.de>
-* Completely re-written by Solomon Peachy <solomon@linux-wlan.com>
-*
-* Copyright (C) 2002 AbsoluteValue Systems, Inc.  All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-*   The contents of this file are subject to the Mozilla Public
-*   License Version 1.1 (the "License"); you may not use this file
-*   except in compliance with the License. You may obtain a copy of
-*   the License at http://www.mozilla.org/MPL/
-*
-*   Software distributed under the License is distributed on an "AS
-*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-*   implied. See the License for the specific language governing
-*   rights and limitations under the License.
-*
-*   Alternatively, the contents of this file may be used under the
-*   terms of the GNU Public License version 2 (the "GPL"), in which
-*   case the provisions of the GPL are applicable instead of the
-*   above.  If you wish to allow the use of your version of this file
-*   only under the terms of the GPL and not to allow others to use
-*   your version of this file under the MPL, indicate your decision
-*   by deleting the provisions above and replace them with the notice
-*   and other provisions required by the GPL.  If you do not delete
-*   the provisions above, a recipient may use your version of this
-*   file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*/
-
-/*================================================================*/
-/* System Includes */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <linux/if_arp.h>
-#include <linux/bitops.h>
-#include <linux/uaccess.h>
-#include <asm/byteorder.h>
-#include <linux/if_ether.h>
-
-#include "p80211types.h"
-#include "p80211hdr.h"
-#include "p80211conv.h"
-#include "p80211mgmt.h"
-#include "p80211msg.h"
-#include "p80211metastruct.h"
-#include "p80211metadef.h"
-#include "p80211netdev.h"
-#include "p80211ioctl.h"
-#include "p80211req.h"
-
-static int p80211wext_giwrate(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_param *rrq, char *extra);
-static int p80211wext_giwessid(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_point *data, char *essid);
-
-static u8 p80211_mhz_to_channel(u16 mhz)
-{
-       if (mhz >= 5000)
-               return (mhz - 5000) / 5;
-
-       if (mhz == 2484)
-               return 14;
-
-       if (mhz >= 2407)
-               return (mhz - 2407) / 5;
-
-       return 0;
-}
-
-static u16 p80211_channel_to_mhz(u8 ch, int dot11a)
-{
-
-       if (ch == 0)
-               return 0;
-       if (ch > 200)
-               return 0;
-
-       /* 5G */
-       if (dot11a)
-               return 5000 + (5 * ch);
-
-       /* 2.4G */
-       if (ch == 14)
-               return 2484;
-
-       if ((ch < 14) && (ch > 0))
-               return 2407 + (5 * ch);
-
-       return 0;
-}
-
-/* taken from orinoco.c ;-) */
-static const long p80211wext_channel_freq[] = {
-       2412, 2417, 2422, 2427, 2432, 2437, 2442,
-       2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-
-#define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
-
-/* steal a spare bit to store the shared/opensystems state.
-   should default to open if not set */
-#define HOSTWEP_SHAREDKEY BIT(3)
-
-static int qual_as_percent(int snr)
-{
-       if (snr <= 0)
-               return 0;
-       if (snr <= 40)
-               return snr * 5 / 2;
-       return 100;
-}
-
-static int p80211wext_setmib(wlandevice_t *wlandev, u32 did, u32 data)
-{
-       p80211msg_dot11req_mibset_t msg;
-       p80211item_uint32_t *mibitem =
-               (p80211item_uint32_t *)&msg.mibattribute.data;
-       int result;
-
-       msg.msgcode = DIDmsg_dot11req_mibset;
-       memset(mibitem, 0, sizeof(*mibitem));
-       mibitem->did = did;
-       mibitem->data = data;
-       result = p80211req_dorequest(wlandev, (u8 *) &msg);
-
-       return result;
-}
-
-/*
- * get a 32 bit mib value
- */
-static int p80211wext_getmib(wlandevice_t *wlandev, u32 did, u32 *data)
-{
-       p80211msg_dot11req_mibset_t msg;
-       p80211item_uint32_t *mibitem =
-               (p80211item_uint32_t *)&msg.mibattribute.data;
-       int result;
-
-       msg.msgcode = DIDmsg_dot11req_mibget;
-       memset(mibitem, 0, sizeof(*mibitem));
-       mibitem->did = did;
-       result = p80211req_dorequest(wlandev, (u8 *) &msg);
-       if (!result)
-               *data = mibitem->data;
-
-       return result;
-}
-
-static int p80211wext_autojoin(wlandevice_t *wlandev)
-{
-       p80211msg_lnxreq_autojoin_t msg;
-       struct iw_point data;
-       char ssid[IW_ESSID_MAX_SIZE];
-
-       int result;
-       int err = 0;
-
-       /* Get ESSID */
-       result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
-               msg.authtype.data = P80211ENUM_authalg_sharedkey;
-       else
-               msg.authtype.data = P80211ENUM_authalg_opensystem;
-
-       msg.msgcode = DIDmsg_lnxreq_autojoin;
-
-       /* Trim the last '\0' to fit the SSID format */
-
-       if (data.length && ssid[data.length - 1] == '\0')
-               data.length = data.length - 1;
-
-       memcpy(msg.ssid.data.data, ssid, data.length);
-       msg.ssid.data.len = data.length;
-
-       result = p80211req_dorequest(wlandev, (u8 *) &msg);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-exit:
-
-       return err;
-
-}
-
-/* called by /proc/net/wireless */
-struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev)
-{
-       p80211msg_lnxreq_commsquality_t quality;
-       wlandevice_t *wlandev = dev->ml_priv;
-       struct iw_statistics *wstats = &wlandev->wstats;
-       int retval;
-
-       /* Check */
-       if ((wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING))
-               return NULL;
-
-       /* XXX Only valid in station mode */
-       wstats->status = 0;
-
-       /* build request message */
-       quality.msgcode = DIDmsg_lnxreq_commsquality;
-       quality.dbm.data = P80211ENUM_truth_true;
-       quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
-
-       /* send message to nsd */
-       if (wlandev->mlmerequest == NULL)
-               return NULL;
-
-       retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) &quality);
-
-       wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
-       wstats->qual.level = quality.level.data;        /* instant signal level */
-       wstats->qual.noise = quality.noise.data;        /* instant noise level */
-
-       wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
-       wstats->discard.code = wlandev->rx.decrypt_err;
-       wstats->discard.nwid = 0;
-       wstats->discard.misc = 0;
-
-       wstats->discard.fragment = 0;   /* incomplete fragments */
-       wstats->discard.retries = 0;    /* tx retries. */
-       wstats->miss.beacon = 0;
-
-       return wstats;
-}
-
-static int p80211wext_giwname(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             char *name, char *extra)
-{
-       struct iw_param rate;
-       int result;
-       int err = 0;
-
-       result = p80211wext_giwrate(dev, NULL, &rate, NULL);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       switch (rate.value) {
-       case 1000000:
-       case 2000000:
-               strcpy(name, "IEEE 802.11-DS");
-               break;
-       case 5500000:
-       case 11000000:
-               strcpy(name, "IEEE 802.11-b");
-               break;
-       }
-exit:
-       return err;
-}
-
-static int p80211wext_giwfreq(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_freq *freq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       result = p80211wext_getmib(wlandev,
-                                  DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
-                                  &value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       if (value > NUM_CHANNELS) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       /* convert into frequency instead of a channel */
-       freq->e = 1;
-       freq->m = p80211_channel_to_mhz(value, 0) * 100000;
-
-exit:
-       return err;
-}
-
-static int p80211wext_siwfreq(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_freq *freq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       if (!wlan_wext_write) {
-               err = -EOPNOTSUPP;
-               goto exit;
-       }
-
-       if ((freq->e == 0) && (freq->m <= 1000))
-               value = freq->m;
-       else
-               value = p80211_mhz_to_channel(freq->m);
-
-       result = p80211wext_setmib(wlandev,
-                            DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
-                            value);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-exit:
-       return err;
-}
-
-static int p80211wext_giwmode(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             __u32 *mode, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-
-       switch (wlandev->macmode) {
-       case WLAN_MACMODE_IBSS_STA:
-               *mode = IW_MODE_ADHOC;
-               break;
-       case WLAN_MACMODE_ESS_STA:
-               *mode = IW_MODE_INFRA;
-               break;
-       case WLAN_MACMODE_ESS_AP:
-               *mode = IW_MODE_MASTER;
-               break;
-       default:
-               /* Not set yet. */
-               *mode = IW_MODE_AUTO;
-       }
-
-       return 0;
-}
-
-static int p80211wext_siwmode(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             __u32 *mode, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-
-       if (!wlan_wext_write) {
-               err = -EOPNOTSUPP;
-               goto exit;
-       }
-
-       if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
-           *mode != IW_MODE_MASTER) {
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       /* Operation mode is the same with current mode */
-       if (*mode == wlandev->macmode)
-               goto exit;
-
-       switch (*mode) {
-       case IW_MODE_ADHOC:
-               wlandev->macmode = WLAN_MACMODE_IBSS_STA;
-               break;
-       case IW_MODE_INFRA:
-               wlandev->macmode = WLAN_MACMODE_ESS_STA;
-               break;
-       case IW_MODE_MASTER:
-               wlandev->macmode = WLAN_MACMODE_ESS_AP;
-               break;
-       default:
-               /* Not set yet. */
-               printk(KERN_INFO "Operation mode: %d not support\n", *mode);
-               return -EOPNOTSUPP;
-       }
-
-       /* Set Operation mode to the PORT TYPE RID */
-       result = p80211wext_setmib(wlandev,
-                               DIDmib_p2_p2Static_p2CnfPortType,
-                               (*mode == IW_MODE_ADHOC) ? 0 : 1);
-       if (result)
-               err = -EFAULT;
-exit:
-       return err;
-}
-
-static int p80211wext_giwrange(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_point *data, char *extra)
-{
-       struct iw_range *range = (struct iw_range *)extra;
-       int i, val;
-
-       /* for backward compatability set size and zero everything we don't understand */
-       data->length = sizeof(*range);
-       memset(range, 0, sizeof(*range));
-
-       range->txpower_capa = IW_TXPOW_DBM;
-       /* XXX what about min/max_pmp, min/max_pmt, etc. */
-
-       range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = 13;
-
-       range->retry_capa = IW_RETRY_LIMIT;
-       range->retry_flags = IW_RETRY_LIMIT;
-       range->min_retry = 0;
-       range->max_retry = 255;
-
-       range->event_capa[0] = (IW_EVENT_CAPA_K_0 |     /* mode/freq/ssid */
-                               IW_EVENT_CAPA_MASK(SIOCGIWAP) |
-                               IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
-       range->event_capa[1] = IW_EVENT_CAPA_K_1;       /* encode */
-       range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
-                               IW_EVENT_CAPA_MASK(IWEVCUSTOM));
-
-       range->num_channels = NUM_CHANNELS;
-
-       /* XXX need to filter against the regulatory domain &| active set */
-       val = 0;
-       for (i = 0; i < NUM_CHANNELS; i++) {
-               range->freq[val].i = i + 1;
-               range->freq[val].m = p80211wext_channel_freq[i] * 100000;
-               range->freq[val].e = 1;
-               val++;
-       }
-
-       range->num_frequency = val;
-
-       /* Max of /proc/net/wireless */
-       range->max_qual.qual = 100;
-       range->max_qual.level = 0;
-       range->max_qual.noise = 0;
-       range->sensitivity = 3;
-       /* XXX these need to be nsd-specific! */
-
-       range->min_rts = 0;
-       range->max_rts = 2347;
-       range->min_frag = 256;
-       range->max_frag = 2346;
-
-       range->max_encoding_tokens = NUM_WEPKEYS;
-       range->num_encoding_sizes = 2;
-       range->encoding_size[0] = 5;
-       range->encoding_size[1] = 13;
-
-       /* XXX what about num_bitrates/throughput? */
-       range->num_bitrates = 0;
-
-       /* estimated max throughput */
-       /* XXX need to cap it if we're running at ~2Mbps.. */
-       range->throughput = 5500000;
-
-       return 0;
-}
-
-static int p80211wext_giwap(netdevice_t *dev,
-                           struct iw_request_info *info,
-                           struct sockaddr *ap_addr, char *extra)
-{
-
-       wlandevice_t *wlandev = dev->ml_priv;
-
-       memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
-       ap_addr->sa_family = ARPHRD_ETHER;
-
-       return 0;
-}
-
-static int p80211wext_giwencode(netdevice_t *dev,
-                               struct iw_request_info *info,
-                               struct iw_point *erq, char *key)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int err = 0;
-       int i;
-
-       i = (erq->flags & IW_ENCODE_INDEX) - 1;
-       erq->flags = 0;
-
-       if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
-               erq->flags |= IW_ENCODE_ENABLED;
-       else
-               erq->flags |= IW_ENCODE_DISABLED;
-
-       if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
-               erq->flags |= IW_ENCODE_RESTRICTED;
-       else
-               erq->flags |= IW_ENCODE_OPEN;
-
-       i = (erq->flags & IW_ENCODE_INDEX) - 1;
-
-       if (i == -1)
-               i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
-
-       if ((i < 0) || (i >= NUM_WEPKEYS)) {
-               err = -EINVAL;
-               goto exit;
-       }
-
-       erq->flags |= i + 1;
-
-       /* copy the key from the driver cache as the keys are read-only MIBs */
-       erq->length = wlandev->wep_keylens[i];
-       memcpy(key, wlandev->wep_keys[i], erq->length);
-
-exit:
-       return err;
-}
-
-static int p80211wext_siwencode(netdevice_t *dev,
-                               struct iw_request_info *info,
-                               struct iw_point *erq, char *key)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       p80211msg_dot11req_mibset_t msg;
-       p80211item_pstr32_t pstr;
-
-       int err = 0;
-       int result = 0;
-       int i;
-
-       if (!wlan_wext_write) {
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       /* Check the Key index first. */
-       i = (erq->flags & IW_ENCODE_INDEX);
-       if (i) {
-               if ((i < 1) || (i > NUM_WEPKEYS)) {
-                       err = -EINVAL;
-                       goto exit;
-               } else {
-                       i--;
-               }
-               /* Set current key number only if no keys are given */
-               if (erq->flags & IW_ENCODE_NOKEY) {
-                       result =
-                               p80211wext_setmib(wlandev,
-                                                 DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
-                                                 i);
-
-                       if (result) {
-                               err = -EFAULT;
-                               goto exit;
-                       }
-               }
-
-       } else {
-               /* Use defaultkey if no Key Index */
-               i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
-       }
-
-       /* Check if there is no key information in the iwconfig request */
-       if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
-
-               /*------------------------------------------------------------
-                * If there is WEP Key for setting, check the Key Information
-                * and then set it to the firmware.
-                -------------------------------------------------------------*/
-
-               if (erq->length > 0) {
-                       /* copy the key from the driver cache as the keys are read-only MIBs */
-                       wlandev->wep_keylens[i] = erq->length;
-                       memcpy(wlandev->wep_keys[i], key, erq->length);
-
-                       /* Prepare data struture for p80211req_dorequest. */
-                       memcpy(pstr.data.data, key, erq->length);
-                       pstr.data.len = erq->length;
-
-                       switch (i) {
-                       case 0:
-                               pstr.did =
-                                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
-                               break;
-
-                       case 1:
-                               pstr.did =
-                                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
-                               break;
-
-                       case 2:
-                               pstr.did =
-                                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
-                               break;
-
-                       case 3:
-                               pstr.did =
-                                   DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
-                               break;
-
-                       default:
-                               err = -EINVAL;
-                               goto exit;
-                       }
-
-                       msg.msgcode = DIDmsg_dot11req_mibset;
-                       memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
-                       result = p80211req_dorequest(wlandev, (u8 *) &msg);
-
-                       if (result) {
-                               err = -EFAULT;
-                               goto exit;
-                       }
-               }
-
-       }
-
-       /* Check the PrivacyInvoked flag */
-       if (erq->flags & IW_ENCODE_DISABLED) {
-               result =
-                   p80211wext_setmib(wlandev,
-                                        DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
-                                        P80211ENUM_truth_false);
-       } else {
-               result =
-                   p80211wext_setmib(wlandev,
-                                        DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
-                                        P80211ENUM_truth_true);
-       }
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       /*  The  security  mode  may  be open or restricted, and its meaning
-          depends on the card used. With  most  cards,  in  open  mode  no
-          authentication  is  used  and  the  card  may  also  accept non-
-          encrypted sessions, whereas in restricted  mode  only  encrypted
-          sessions  are  accepted  and the card will use authentication if
-          available.
-        */
-       if (erq->flags & IW_ENCODE_RESTRICTED) {
-               result =
-                   p80211wext_setmib(wlandev,
-                                        DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
-                                        P80211ENUM_truth_true);
-       } else if (erq->flags & IW_ENCODE_OPEN) {
-               result =
-                   p80211wext_setmib(wlandev,
-                                        DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
-                                        P80211ENUM_truth_false);
-       }
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-exit:
-
-       return err;
-}
-
-static int p80211wext_giwessid(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_point *data, char *essid)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-
-       if (wlandev->ssid.len) {
-               data->length = wlandev->ssid.len;
-               data->flags = 1;
-               memcpy(essid, wlandev->ssid.data, data->length);
-               essid[data->length] = 0;
-       } else {
-               memset(essid, 0, sizeof(wlandev->ssid.data));
-               data->length = 0;
-               data->flags = 0;
-       }
-
-       return 0;
-}
-
-static int p80211wext_siwessid(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_point *data, char *essid)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       p80211msg_lnxreq_autojoin_t msg;
-
-       int result;
-       int err = 0;
-       int length = data->length;
-
-       if (!wlan_wext_write) {
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
-               msg.authtype.data = P80211ENUM_authalg_sharedkey;
-       else
-               msg.authtype.data = P80211ENUM_authalg_opensystem;
-
-       msg.msgcode = DIDmsg_lnxreq_autojoin;
-
-       /* Trim the last '\0' to fit the SSID format */
-       if (length && essid[length - 1] == '\0')
-               length--;
-
-       memcpy(msg.ssid.data.data, essid, length);
-       msg.ssid.data.len = length;
-
-       pr_debug("autojoin_ssid for %s \n", essid);
-       result = p80211req_dorequest(wlandev, (u8 *) &msg);
-       pr_debug("autojoin_ssid %d\n", result);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-exit:
-       return err;
-}
-
-static int p80211wext_siwcommit(netdevice_t *dev,
-                               struct iw_request_info *info,
-                               struct iw_point *data, char *essid)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int err = 0;
-
-       if (!wlan_wext_write) {
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       /* Auto Join */
-       err = p80211wext_autojoin(wlandev);
-
-exit:
-       return err;
-}
-
-static int p80211wext_giwrate(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_param *rrq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       result = p80211wext_getmib(wlandev, DIDmib_p2_p2MAC_p2CurrentTxRate, &value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       rrq->fixed = 0;         /* can it change? */
-       rrq->disabled = 0;
-       rrq->value = 0;
-
-#define                HFA384x_RATEBIT_1                       ((u16)1)
-#define                HFA384x_RATEBIT_2                       ((u16)2)
-#define                HFA384x_RATEBIT_5dot5                   ((u16)4)
-#define                HFA384x_RATEBIT_11                      ((u16)8)
-
-       switch (value) {
-       case HFA384x_RATEBIT_1:
-               rrq->value = 1000000;
-               break;
-       case HFA384x_RATEBIT_2:
-               rrq->value = 2000000;
-               break;
-       case HFA384x_RATEBIT_5dot5:
-               rrq->value = 5500000;
-               break;
-       case HFA384x_RATEBIT_11:
-               rrq->value = 11000000;
-               break;
-       default:
-               err = -EINVAL;
-       }
-exit:
-       return err;
-}
-
-static int p80211wext_giwrts(netdevice_t *dev,
-                            struct iw_request_info *info,
-                            struct iw_param *rts, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       result = p80211wext_getmib(wlandev,
-                                  DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
-                                  &value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       rts->value = value;
-       rts->disabled = (rts->value == 2347);
-       rts->fixed = 1;
-
-exit:
-       return err;
-}
-
-static int p80211wext_siwrts(netdevice_t *dev,
-                            struct iw_request_info *info,
-                            struct iw_param *rts, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       if (!wlan_wext_write) {
-               err = -EOPNOTSUPP;
-               goto exit;
-       }
-
-       if (rts->disabled)
-               value = 2347;
-       else
-               value = rts->value;
-
-       result = p80211wext_setmib(wlandev,
-                                  DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
-                                  value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-exit:
-       return err;
-}
-
-static int p80211wext_giwfrag(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_param *frag, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       result = p80211wext_getmib(wlandev,
-                                  DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
-                                  &value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       frag->value = value;
-       frag->disabled = (frag->value == 2346);
-       frag->fixed = 1;
-
-exit:
-       return err;
-}
-
-static int p80211wext_siwfrag(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_param *frag, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       int value;
-
-       if (!wlan_wext_write) {
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       if (frag->disabled)
-               value = 2346;
-       else
-               value = frag->value;
-
-       result = p80211wext_setmib(wlandev,
-                  DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
-                                     value);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-exit:
-       return err;
-}
-
-#ifndef IW_RETRY_LONG
-#define IW_RETRY_LONG IW_RETRY_MAX
-#endif
-
-#ifndef IW_RETRY_SHORT
-#define IW_RETRY_SHORT IW_RETRY_MIN
-#endif
-
-static int p80211wext_giwretry(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_param *rrq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       u16 shortretry, longretry, lifetime;
-       unsigned int value;
-
-       result = p80211wext_getmib(wlandev,
-                                  DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
-                                  &value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       shortretry = value;
-
-       result = p80211wext_getmib(wlandev,
-                                  DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
-                                  &value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       longretry = value;
-
-       result = p80211wext_getmib(wlandev,
-                                  DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
-                                  &value);
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       lifetime = value;
-
-       rrq->disabled = 0;
-
-       if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
-               rrq->flags = IW_RETRY_LIFETIME;
-               rrq->value = lifetime * 1024;
-       } else {
-               if (rrq->flags & IW_RETRY_LONG) {
-                       rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
-                       rrq->value = longretry;
-               } else {
-                       rrq->flags = IW_RETRY_LIMIT;
-                       rrq->value = shortretry;
-                       if (shortretry != longretry)
-                               rrq->flags |= IW_RETRY_SHORT;
-               }
-       }
-
-exit:
-       return err;
-
-}
-
-static int p80211wext_siwretry(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_param *rrq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       p80211item_uint32_t mibitem;
-       p80211msg_dot11req_mibset_t msg;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       if (!wlan_wext_write) {
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       if (rrq->disabled) {
-               err = -EINVAL;
-               goto exit;
-       }
-
-       msg.msgcode = DIDmsg_dot11req_mibset;
-
-       if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
-
-               value = rrq->value /= 1024;
-               result = p80211wext_setmib(wlandev,
-                                          DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
-                                          value);
-               if (result) {
-                       err = -EFAULT;
-                       goto exit;
-               }
-       } else {
-               if (rrq->flags & IW_RETRY_LONG) {
-                       result = p80211wext_setmib(wlandev,
-                                                  DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
-                                                  rrq->value);
-
-                       if (result) {
-                               err = -EFAULT;
-                               goto exit;
-                       }
-               }
-
-               if (rrq->flags & IW_RETRY_SHORT) {
-                       result = p80211wext_setmib(wlandev,
-                                                  DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
-                                                  rrq->value);
-
-                       if (result) {
-                               err = -EFAULT;
-                               goto exit;
-                       }
-               }
-       }
-
-exit:
-       return err;
-
-}
-
-static int p80211wext_siwtxpow(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_param *rrq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       p80211item_uint32_t mibitem;
-       p80211msg_dot11req_mibset_t msg;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       if (!wlan_wext_write) {
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       if (rrq->fixed == 0)
-               value = 30;
-       else
-               value = rrq->value;
-       result = p80211wext_setmib(wlandev,
-                                  DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
-                                  value);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-exit:
-       return err;
-}
-
-static int p80211wext_giwtxpow(netdevice_t *dev,
-                              struct iw_request_info *info,
-                              struct iw_param *rrq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       int result;
-       int err = 0;
-       unsigned int value;
-
-       result = p80211wext_getmib(wlandev,
-                                  DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
-                                  &value);
-
-       if (result) {
-               err = -EFAULT;
-               goto exit;
-       }
-
-       /* XXX handle OFF by setting disabled = 1; */
-
-       rrq->flags = 0;         /* IW_TXPOW_DBM; */
-       rrq->disabled = 0;
-       rrq->fixed = 0;
-       rrq->value = value;
-
-exit:
-       return err;
-}
-
-static int p80211wext_siwspy(netdevice_t *dev,
-                            struct iw_request_info *info,
-                            struct iw_point *srq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       struct sockaddr address[IW_MAX_SPY];
-       int number = srq->length;
-       int i;
-
-       /* Copy the data from the input buffer */
-       memcpy(address, extra, sizeof(struct sockaddr) * number);
-
-       wlandev->spy_number = 0;
-
-       if (number > 0) {
-
-               /* extract the addresses */
-               for (i = 0; i < number; i++) {
-
-                       memcpy(wlandev->spy_address[i], address[i].sa_data,
-                              ETH_ALEN);
-               }
-
-               /* reset stats */
-               memset(wlandev->spy_stat, 0,
-                      sizeof(struct iw_quality) * IW_MAX_SPY);
-
-               /* set number of addresses */
-               wlandev->spy_number = number;
-       }
-
-       return 0;
-}
-
-/* jkriegl: from orinoco, modified */
-static int p80211wext_giwspy(netdevice_t *dev,
-                            struct iw_request_info *info,
-                            struct iw_point *srq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-
-       struct sockaddr address[IW_MAX_SPY];
-       struct iw_quality spy_stat[IW_MAX_SPY];
-       int number;
-       int i;
-
-       number = wlandev->spy_number;
-
-       if (number > 0) {
-
-               /* populate address and spy struct's */
-               for (i = 0; i < number; i++) {
-                       memcpy(address[i].sa_data, wlandev->spy_address[i],
-                              ETH_ALEN);
-                       address[i].sa_family = AF_UNIX;
-                       memcpy(&spy_stat[i], &wlandev->spy_stat[i],
-                              sizeof(struct iw_quality));
-               }
-
-               /* reset update flag */
-               for (i = 0; i < number; i++)
-                       wlandev->spy_stat[i].updated = 0;
-       }
-
-       /* push stuff to user space */
-       srq->length = number;
-       memcpy(extra, address, sizeof(struct sockaddr) * number);
-       memcpy(extra + sizeof(struct sockaddr) * number, spy_stat,
-              sizeof(struct iw_quality) * number);
-
-       return 0;
-}
-
-static int prism2_result2err(int prism2_result)
-{
-       int err = 0;
-
-       switch (prism2_result) {
-       case P80211ENUM_resultcode_invalid_parameters:
-               err = -EINVAL;
-               break;
-       case P80211ENUM_resultcode_implementation_failure:
-               err = -EIO;
-               break;
-       case P80211ENUM_resultcode_not_supported:
-               err = -EOPNOTSUPP;
-               break;
-       default:
-               err = 0;
-               break;
-       }
-
-       return err;
-}
-
-static int p80211wext_siwscan(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_point *srq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       p80211msg_dot11req_scan_t msg;
-       int result;
-       int err = 0;
-       int i = 0;
-
-       if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
-               printk(KERN_ERR "Can't scan in AP mode\n");
-               err = (-EOPNOTSUPP);
-               goto exit;
-       }
-
-       memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t));
-       msg.msgcode = DIDmsg_dot11req_scan;
-       msg.bsstype.data = P80211ENUM_bsstype_any;
-
-       memset(&(msg.bssid.data), 0xFF, sizeof(p80211item_pstr6_t));
-       msg.bssid.data.len = 6;
-
-       msg.scantype.data = P80211ENUM_scantype_active;
-       msg.probedelay.data = 0;
-
-       for (i = 1; i <= 14; i++)
-               msg.channellist.data.data[i - 1] = i;
-       msg.channellist.data.len = 14;
-
-       msg.maxchanneltime.data = 250;
-       msg.minchanneltime.data = 200;
-
-       result = p80211req_dorequest(wlandev, (u8 *) &msg);
-       if (result)
-               err = prism2_result2err(msg.resultcode.data);
-
-exit:
-       return err;
-}
-
-/* Helper to translate scan into Wireless Extensions scan results.
- * Inspired by the prism54 code, which was in turn inspired by the
- * airo driver code.
- */
-static char *wext_translate_bss(struct iw_request_info *info, char *current_ev,
-                               char *end_buf,
-                               p80211msg_dot11req_scan_results_t *bss)
-{
-       struct iw_event iwe;    /* Temporary buffer */
-
-       /* The first entry must be the MAC address */
-       memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);
-       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-       iwe.cmd = SIOCGIWAP;
-       current_ev =
-           iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-                                IW_EV_ADDR_LEN);
-
-       /* The following entries will be displayed in the same order we give them */
-
-       /* The ESSID. */
-       if (bss->ssid.data.len > 0) {
-               char essid[IW_ESSID_MAX_SIZE + 1];
-               int size;
-
-               size =
-                   min_t(unsigned short, IW_ESSID_MAX_SIZE,
-                         bss->ssid.data.len);
-               memset(&essid, 0, sizeof(essid));
-               memcpy(&essid, bss->ssid.data.data, size);
-               pr_debug(" essid size = %d\n", size);
-               iwe.u.data.length = size;
-               iwe.u.data.flags = 1;
-               iwe.cmd = SIOCGIWESSID;
-               current_ev =
-                   iwe_stream_add_point(info, current_ev, end_buf, &iwe,
-                                        &essid[0]);
-               pr_debug(" essid size OK.\n");
-       }
-
-       switch (bss->bsstype.data) {
-       case P80211ENUM_bsstype_infrastructure:
-               iwe.u.mode = IW_MODE_MASTER;
-               break;
-
-       case P80211ENUM_bsstype_independent:
-               iwe.u.mode = IW_MODE_ADHOC;
-               break;
-
-       default:
-               iwe.u.mode = 0;
-               break;
-       }
-       iwe.cmd = SIOCGIWMODE;
-       if (iwe.u.mode)
-               current_ev =
-                   iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-                                        IW_EV_UINT_LEN);
-
-       /* Encryption capability */
-       if (bss->privacy.data == P80211ENUM_truth_true)
-               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-       else
-               iwe.u.data.flags = IW_ENCODE_DISABLED;
-       iwe.u.data.length = 0;
-       iwe.cmd = SIOCGIWENCODE;
-       current_ev =
-           iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
-
-       /* Add frequency. (short) bss->channel is the frequency in MHz */
-       iwe.u.freq.m = bss->dschannel.data;
-       iwe.u.freq.e = 0;
-       iwe.cmd = SIOCGIWFREQ;
-       current_ev =
-           iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-                                IW_EV_FREQ_LEN);
-
-       /* Add quality statistics */
-       iwe.u.qual.level = bss->signal.data;
-       iwe.u.qual.noise = bss->noise.data;
-       /* do a simple SNR for quality */
-       iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data);
-       iwe.cmd = IWEVQUAL;
-       current_ev =
-           iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-                                IW_EV_QUAL_LEN);
-
-       return current_ev;
-}
-
-static int p80211wext_giwscan(netdevice_t *dev,
-                             struct iw_request_info *info,
-                             struct iw_point *srq, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       p80211msg_dot11req_scan_results_t msg;
-       int result = 0;
-       int err = 0;
-       int i = 0;
-       int scan_good = 0;
-       char *current_ev = extra;
-
-       /* Since wireless tools doesn't really have a way of passing how
-        * many scan results results there were back here, keep grabbing them
-        * until we fail.
-        */
-       do {
-               memset(&msg, 0, sizeof(msg));
-               msg.msgcode = DIDmsg_dot11req_scan_results;
-               msg.bssindex.data = i;
-
-               result = p80211req_dorequest(wlandev, (u8 *) &msg);
-               if ((result != 0) ||
-                   (msg.resultcode.data != P80211ENUM_resultcode_success)) {
-                       break;
-               }
-
-               current_ev =
-                   wext_translate_bss(info, current_ev,
-                                      extra + IW_SCAN_MAX_DATA, &msg);
-               scan_good = 1;
-               i++;
-       } while (i < IW_MAX_AP);
-
-       srq->length = (current_ev - extra);
-       srq->flags = 0;         /* todo */
-
-       if (result && !scan_good)
-               err = prism2_result2err(msg.resultcode.data);
-
-       return err;
-}
-
-/* extra wireless extensions stuff to support NetworkManager (I hope) */
-
-/* SIOCSIWENCODEEXT */
-static int p80211wext_set_encodeext(struct net_device *dev,
-                                   struct iw_request_info *info,
-                                   union iwreq_data *wrqu, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-       p80211msg_dot11req_mibset_t msg;
-       p80211item_pstr32_t *pstr;
-
-       int result = 0;
-       struct iw_point *encoding = &wrqu->encoding;
-       int idx = encoding->flags & IW_ENCODE_INDEX;
-
-       pr_debug("set_encode_ext flags[%d] alg[%d] keylen[%d]\n",
-                ext->ext_flags, (int)ext->alg, (int)ext->key_len);
-
-       if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-               /* set default key ? I'm not sure if this the the correct thing to do here */
-
-               if (idx) {
-                       if (idx < 1 || idx > NUM_WEPKEYS)
-                               return -EINVAL;
-                       else
-                               idx--;
-               }
-               pr_debug("setting default key (%d)\n", idx);
-               result =
-                   p80211wext_setmib(wlandev,
-                                        DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
-                                        idx);
-               if (result)
-                       return -EFAULT;
-       }
-
-       if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-               if (ext->alg != IW_ENCODE_ALG_WEP) {
-                       pr_debug("asked to set a non wep key :(\n");
-                       return -EINVAL;
-               }
-               if (idx) {
-                       if (idx < 1 || idx > NUM_WEPKEYS)
-                               return -EINVAL;
-                       else
-                               idx--;
-               }
-               pr_debug("Set WEP key (%d)\n", idx);
-               wlandev->wep_keylens[idx] = ext->key_len;
-               memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
-
-               memset(&msg, 0, sizeof(msg));
-               pstr = (p80211item_pstr32_t *) &msg.mibattribute.data;
-               memcpy(pstr->data.data, ext->key, ext->key_len);
-               pstr->data.len = ext->key_len;
-               switch (idx) {
-               case 0:
-                       pstr->did =
-                           DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
-                       break;
-               case 1:
-                       pstr->did =
-                           DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
-                       break;
-               case 2:
-                       pstr->did =
-                           DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
-                       break;
-               case 3:
-                       pstr->did =
-                           DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
-                       break;
-               default:
-                       break;
-               }
-               msg.msgcode = DIDmsg_dot11req_mibset;
-               result = p80211req_dorequest(wlandev, (u8 *) &msg);
-               pr_debug("result (%d)\n", result);
-       }
-       return result;
-}
-
-/* SIOCGIWENCODEEXT */
-static int p80211wext_get_encodeext(struct net_device *dev,
-                                   struct iw_request_info *info,
-                                   union iwreq_data *wrqu, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-
-       struct iw_point *encoding = &wrqu->encoding;
-       int result = 0;
-       int max_len;
-       int idx;
-
-       pr_debug("get_encode_ext flags[%d] alg[%d] keylen[%d]\n",
-                ext->ext_flags, (int)ext->alg, (int)ext->key_len);
-
-       max_len = encoding->length - sizeof(*ext);
-       if (max_len <= 0) {
-               pr_debug("get_encodeext max_len [%d] invalid\n", max_len);
-               result = -EINVAL;
-               goto exit;
-       }
-       idx = encoding->flags & IW_ENCODE_INDEX;
-
-       pr_debug("get_encode_ext index [%d]\n", idx);
-
-       if (idx) {
-               if (idx < 1 || idx > NUM_WEPKEYS) {
-                       pr_debug("get_encode_ext invalid key index [%d]\n",
-                                idx);
-                       result = -EINVAL;
-                       goto exit;
-               }
-               idx--;
-       } else {
-               /* default key ? not sure what to do */
-               /* will just use key[0] for now ! FIX ME */
-       }
-
-       encoding->flags = idx + 1;
-       memset(ext, 0, sizeof(*ext));
-
-       ext->alg = IW_ENCODE_ALG_WEP;
-       ext->key_len = wlandev->wep_keylens[idx];
-       memcpy(ext->key, wlandev->wep_keys[idx], ext->key_len);
-
-       encoding->flags |= IW_ENCODE_ENABLED;
-exit:
-       return result;
-}
-
-/* SIOCSIWAUTH */
-static int p80211_wext_set_iwauth(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 union iwreq_data *wrqu, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       struct iw_param *param = &wrqu->param;
-       int result = 0;
-
-       pr_debug("set_iwauth flags[%d]\n", (int)param->flags & IW_AUTH_INDEX);
-
-       switch (param->flags & IW_AUTH_INDEX) {
-       case IW_AUTH_DROP_UNENCRYPTED:
-               pr_debug("drop_unencrypted %d\n", param->value);
-               if (param->value)
-                       result =
-                           p80211wext_setmib(wlandev,
-                                                DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
-                                                P80211ENUM_truth_true);
-               else
-                       result =
-                           p80211wext_setmib(wlandev,
-                                                DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
-                                                P80211ENUM_truth_false);
-               break;
-
-       case IW_AUTH_PRIVACY_INVOKED:
-               pr_debug("privacy invoked %d\n", param->value);
-               if (param->value)
-                       result =
-                           p80211wext_setmib(wlandev,
-                                                DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
-                                                P80211ENUM_truth_true);
-               else
-                       result =
-                           p80211wext_setmib(wlandev,
-                                                DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
-                                                P80211ENUM_truth_false);
-
-               break;
-
-       case IW_AUTH_80211_AUTH_ALG:
-               if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
-                       pr_debug("set open_system\n");
-                       wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
-               } else if (param->value & IW_AUTH_ALG_SHARED_KEY) {
-                       pr_debug("set shared key\n");
-                       wlandev->hostwep |= HOSTWEP_SHAREDKEY;
-               } else {
-                       /* don't know what to do know  */
-                       pr_debug("unknown AUTH_ALG (%d)\n", param->value);
-                       result = -EINVAL;
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       return result;
-}
-
-/* SIOCSIWAUTH */
-static int p80211_wext_get_iwauth(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 union iwreq_data *wrqu, char *extra)
-{
-       wlandevice_t *wlandev = dev->ml_priv;
-       struct iw_param *param = &wrqu->param;
-       int result = 0;
-
-       pr_debug("get_iwauth flags[%d]\n", (int)param->flags & IW_AUTH_INDEX);
-
-       switch (param->flags & IW_AUTH_INDEX) {
-       case IW_AUTH_DROP_UNENCRYPTED:
-               param->value =
-                   wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED ? 1 : 0;
-               break;
-
-       case IW_AUTH_PRIVACY_INVOKED:
-               param->value =
-                   wlandev->hostwep & HOSTWEP_PRIVACYINVOKED ? 1 : 0;
-               break;
-
-       case IW_AUTH_80211_AUTH_ALG:
-               param->value =
-                   wlandev->hostwep & HOSTWEP_SHAREDKEY ?
-                   IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
-               break;
-
-       default:
-               break;
-       }
-
-       return result;
-}
-
-#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
-
-static iw_handler p80211wext_handlers[] = {
-       IW_IOCTL(SIOCSIWCOMMIT) = (iw_handler) p80211wext_siwcommit,
-       IW_IOCTL(SIOCGIWNAME) = (iw_handler) p80211wext_giwname,
-/* SIOCSIWNWID,SIOCGIWNWID */
-       IW_IOCTL(SIOCSIWFREQ) = (iw_handler) p80211wext_siwfreq,
-       IW_IOCTL(SIOCGIWFREQ) = (iw_handler) p80211wext_giwfreq,
-       IW_IOCTL(SIOCSIWMODE) = (iw_handler) p80211wext_siwmode,
-       IW_IOCTL(SIOCGIWMODE) = (iw_handler) p80211wext_giwmode,
-/* SIOCSIWSENS,SIOCGIWSENS,SIOCSIWRANGE */
-       IW_IOCTL(SIOCGIWRANGE) = (iw_handler) p80211wext_giwrange,
-/* SIOCSIWPRIV,SIOCGIWPRIV,SIOCSIWSTATS,SIOCGIWSTATS */
-       IW_IOCTL(SIOCSIWSPY) = (iw_handler) p80211wext_siwspy,
-       IW_IOCTL(SIOCGIWSPY) = (iw_handler) p80211wext_giwspy,
-/* SIOCSIWAP */
-       IW_IOCTL(SIOCGIWAP) = (iw_handler) p80211wext_giwap,
-/* SIOCGIWAPLIST */
-       IW_IOCTL(SIOCSIWSCAN) = (iw_handler) p80211wext_siwscan,
-       IW_IOCTL(SIOCGIWSCAN) = (iw_handler) p80211wext_giwscan,
-       IW_IOCTL(SIOCSIWESSID) = (iw_handler) p80211wext_siwessid,
-       IW_IOCTL(SIOCGIWESSID) = (iw_handler) p80211wext_giwessid,
-/* SIOCSIWNICKN */
-       IW_IOCTL(SIOCGIWNICKN) = (iw_handler) p80211wext_giwessid,
-/* SIOCSIWRATE */
-       IW_IOCTL(SIOCGIWRATE) = (iw_handler) p80211wext_giwrate,
-       IW_IOCTL(SIOCSIWRTS) = (iw_handler) p80211wext_siwrts,
-       IW_IOCTL(SIOCGIWRTS) = (iw_handler) p80211wext_giwrts,
-       IW_IOCTL(SIOCSIWFRAG) = (iw_handler) p80211wext_siwfrag,
-       IW_IOCTL(SIOCGIWFRAG) = (iw_handler) p80211wext_giwfrag,
-       IW_IOCTL(SIOCSIWTXPOW) = (iw_handler) p80211wext_siwtxpow,
-       IW_IOCTL(SIOCGIWTXPOW) = (iw_handler) p80211wext_giwtxpow,
-       IW_IOCTL(SIOCSIWRETRY) = (iw_handler) p80211wext_siwretry,
-       IW_IOCTL(SIOCGIWRETRY) = (iw_handler) p80211wext_giwretry,
-       IW_IOCTL(SIOCSIWENCODE) = (iw_handler) p80211wext_siwencode,
-       IW_IOCTL(SIOCGIWENCODE) = (iw_handler) p80211wext_giwencode,
-/* SIOCSIWPOWER,SIOCGIWPOWER */
-/* WPA operations */
-/* SIOCSIWGENIE,SIOCGIWGENIE generic IE */
-       IW_IOCTL(SIOCSIWAUTH) = (iw_handler) p80211_wext_set_iwauth, /*set authentication mode params */
-       IW_IOCTL(SIOCGIWAUTH) = (iw_handler) p80211_wext_get_iwauth, /*get authentication mode params */
-       IW_IOCTL(SIOCSIWENCODEEXT) = (iw_handler) p80211wext_set_encodeext, /*set encoding token & mode */
-       IW_IOCTL(SIOCGIWENCODEEXT) = (iw_handler) p80211wext_get_encodeext, /*get encoding token & mode */
-/* SIOCSIWPMKSA      PMKSA cache operation */
-};
-
-struct iw_handler_def p80211wext_handler_def = {
-       .num_standard = ARRAY_SIZE(p80211wext_handlers),
-       .standard = p80211wext_handlers,
-       .get_wireless_stats = p80211wext_get_wireless_stats
-};
-
-int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
-{
-       union iwreq_data data;
-
-       /* Send the association state first */
-       data.ap_addr.sa_family = ARPHRD_ETHER;
-       if (assoc)
-               memcpy(data.ap_addr.sa_data, wlandev->bssid, ETH_ALEN);
-       else
-               memset(data.ap_addr.sa_data, 0, ETH_ALEN);
-
-       if (wlan_wext_write)
-               wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
-
-       if (!assoc)
-               goto done;
-
-       /* XXX send association data, like IEs, etc etc. */
-
-done:
-       return 0;
-}
index d20c8797bcc7fe2c7d61e6dd54ca9fe63b042a10..fd5ddb29436c381d8d8deccc26fecb304996c5e1 100644 (file)
@@ -73,26 +73,26 @@ MODULE_FIRMWARE(PRISM2_USB_FWFILE);
 /*================================================================*/
 /* Local Types */
 
-typedef struct s3datarec {
+struct s3datarec {
        u32 len;
        u32 addr;
        u8 checksum;
        u8 *data;
-} s3datarec_t;
+};
 
-typedef struct s3plugrec {
+struct s3plugrec {
        u32 itemcode;
        u32 addr;
        u32 len;
-} s3plugrec_t;
+};
 
-typedef struct s3crcrec {
+struct s3crcrec {
        u32 addr;
        u32 len;
        unsigned int dowrite;
-} s3crcrec_t;
+};
 
-typedef struct s3inforec {
+struct s3inforec {
        u16 len;
        u16 type;
        union {
@@ -101,20 +101,20 @@ typedef struct s3inforec {
                u16 buildseq;
                hfa384x_compident_t platform;
        } info;
-} s3inforec_t;
+};
 
-typedef struct pda {
+struct pda {
        u8 buf[HFA384x_PDA_LEN_MAX];
        hfa384x_pdrec_t *rec[HFA384x_PDA_RECS_MAX];
        unsigned int nrec;
-} pda_t;
+};
 
-typedef struct imgchunk {
+struct imgchunk {
        u32 addr;       /* start address */
        u32 len;        /* in bytes */
        u16 crc;        /* CRC value (if it falls at a chunk boundary) */
        u8 *data;
-} imgchunk_t;
+};
 
 /*================================================================*/
 /* Local Static Definitions */
@@ -124,26 +124,26 @@ typedef struct imgchunk {
 
 /* Data records */
 unsigned int ns3data;
-s3datarec_t s3data[S3DATA_MAX];
+struct s3datarec s3data[S3DATA_MAX];
 
 /* Plug records */
 unsigned int ns3plug;
-s3plugrec_t s3plug[S3PLUG_MAX];
+struct s3plugrec s3plug[S3PLUG_MAX];
 
 /* CRC records */
 unsigned int ns3crc;
-s3crcrec_t s3crc[S3CRC_MAX];
+struct s3crcrec s3crc[S3CRC_MAX];
 
 /* Info records */
 unsigned int ns3info;
-s3inforec_t s3info[S3INFO_MAX];
+struct s3inforec s3info[S3INFO_MAX];
 
 /* S7 record (there _better_ be only one) */
 u32 startaddr;
 
 /* Load image chunks */
 unsigned int nfchunks;
-imgchunk_t fchunk[CHUNKS_MAX];
+struct imgchunk fchunk[CHUNKS_MAX];
 
 /* Note that for the following pdrec_t arrays, the len and code */
 /*   fields are stored in HOST byte order. The mkpdrlist() function */
@@ -151,7 +151,7 @@ imgchunk_t fchunk[CHUNKS_MAX];
 /*----------------------------------------------------------------*/
 /* PDA, built from [card|newfile]+[addfile1+addfile2...] */
 
-pda_t pda;
+struct pda pda;
 hfa384x_compident_t nicid;
 hfa384x_caplevel_t rfid;
 hfa384x_caplevel_t macid;
@@ -165,21 +165,21 @@ wlandevice_t *wlandev);
 
 static int read_fwfile(const struct ihex_binrec *rfptr);
 
-static int mkimage(imgchunk_t *clist, unsigned int *ccnt);
+static int mkimage(struct imgchunk *clist, unsigned int *ccnt);
 
-static int read_cardpda(pda_t *pda, wlandevice_t *wlandev);
+static int read_cardpda(struct pda *pda, wlandevice_t *wlandev);
 
-static int mkpdrlist(pda_t *pda);
+static int mkpdrlist(struct pda *pda);
 
-static int plugimage(imgchunk_t *fchunk, unsigned int nfchunks,
-             s3plugrec_t *s3plug, unsigned int ns3plug, pda_t * pda);
+static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks,
+             struct s3plugrec *s3plug, unsigned int ns3plug, struct pda * pda);
 
-static int crcimage(imgchunk_t *fchunk, unsigned int nfchunks,
-            s3crcrec_t *s3crc, unsigned int ns3crc);
+static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks,
+            struct s3crcrec *s3crc, unsigned int ns3crc);
 
-static int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
+static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk,
               unsigned int nfchunks);
-static void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks);
+static void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks);
 
 static void free_srecs(void);
 
@@ -239,7 +239,7 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev)
 int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
 {
        signed int result = 0;
-       p80211msg_dot11req_mibget_t getmsg;
+       struct p80211msg_dot11req_mibget getmsg;
        p80211itemd_t *item;
        u32 *data;
 
@@ -375,8 +375,8 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
 *      0       success
 *      ~0      failure
 ----------------------------------------------------------------*/
-int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc,
-            unsigned int ns3crc)
+int crcimage(struct imgchunk *fchunk, unsigned int nfchunks,
+            struct s3crcrec *s3crc, unsigned int ns3crc)
 {
        int result = 0;
        int i;
@@ -397,15 +397,14 @@ int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc,
                for (c = 0; c < nfchunks; c++) {
                        cstart = fchunk[c].addr;
                        cend = fchunk[c].addr + fchunk[c].len;
-                       /*  the line below does an address & len match search */
-                       /*  unfortunately, I've found that the len fields of */
-                       /*  some crc records don't match with the length of */
-                       /*  the actual data, so we're not checking right */
-                       /*  now */
-                       /* if ( crcstart-2 >= cstart && crcend <= cend ) break; */
+                       /* the line below does an address & len match search */
+                       /* unfortunately, I've found that the len fields of */
+                       /* some crc records don't match with the length of */
+                       /* the actual data, so we're not checking right now */
+                       /* if (crcstart-2 >= cstart && crcend <= cend) break; */
 
                        /* note the -2 below, it's to make sure the chunk has */
-                       /*   space for the CRC value */
+                       /* space for the CRC value */
                        if (crcstart - 2 >= cstart && crcstart < cend)
                                break;
                }
@@ -440,7 +439,7 @@ int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc,
 * Returns:
 *      nothing
 ----------------------------------------------------------------*/
-void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks)
+void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks)
 {
        int i;
        for (i = 0; i < *nfchunks; i++) {
@@ -490,7 +489,7 @@ void free_srecs(void)
 *      0       - success
 *      ~0      - failure (probably an errno)
 ----------------------------------------------------------------*/
-int mkimage(imgchunk_t *clist, unsigned int *ccnt)
+int mkimage(struct imgchunk *clist, unsigned int *ccnt)
 {
        int result = 0;
        int i;
@@ -583,7 +582,7 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt)
 *      0       - success
 *      ~0      - failure (probably an errno)
 ----------------------------------------------------------------*/
-int mkpdrlist(pda_t *pda)
+int mkpdrlist(struct pda *pda)
 {
        int result = 0;
        u16 *pda16 = (u16 *) pda->buf;
@@ -656,8 +655,8 @@ int mkpdrlist(pda_t *pda)
 *      0       success
 *      ~0      failure
 ----------------------------------------------------------------*/
-int plugimage(imgchunk_t *fchunk, unsigned int nfchunks,
-             s3plugrec_t *s3plug, unsigned int ns3plug, pda_t * pda)
+int plugimage(struct imgchunk *fchunk, unsigned int nfchunks,
+             struct s3plugrec *s3plug, unsigned int ns3plug, struct pda * pda)
 {
        int result = 0;
        int i;                  /* plug index */
@@ -675,7 +674,7 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks,
                pstart = s3plug[i].addr;
                pend = s3plug[i].addr + s3plug[i].len;
                /* find the matching PDR (or filename) */
-               if (s3plug[i].itemcode != 0xffffffffUL) {       /* not filename */
+               if (s3plug[i].itemcode != 0xffffffffUL) { /* not filename */
                        for (j = 0; j < pda->nrec; j++) {
                                if (s3plug[i].itemcode ==
                                    le16_to_cpu(pda->rec[j]->code))
@@ -684,7 +683,7 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks,
                } else {
                        j = -1;
                }
-               if (j >= pda->nrec && j != -1) {        /*  if no matching PDR, fail */
+               if (j >= pda->nrec && j != -1) { /*  if no matching PDR, fail */
                        printk(KERN_WARNING
                               "warning: Failed to find PDR for "
                               "plugrec 0x%04x.\n", s3plug[i].itemcode);
@@ -764,10 +763,10 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks,
 *      0       - success
 *      ~0      - failure (probably an errno)
 ----------------------------------------------------------------*/
-int read_cardpda(pda_t *pda, wlandevice_t *wlandev)
+int read_cardpda(struct pda *pda, wlandevice_t *wlandev)
 {
        int result = 0;
-       p80211msg_p2req_readpda_t msg;
+       struct p80211msg_p2req_readpda msg;
 
        /* set up the msg */
        msg.msgcode = DIDmsg_p2req_readpda;
@@ -839,7 +838,7 @@ int read_cardpda(pda_t *pda, wlandevice_t *wlandev)
 *                ssssttttdd..dd
 *                s - Size in words (little endian)
 *                t - Info type (little endian), see #defines and
-*                    s3inforec_t for details about types.
+*                    struct s3inforec for details about types.
 *                d - (s - 1) little endian words giving the contents of
 *                    the given info type.
 *
@@ -978,13 +977,13 @@ int read_fwfile(const struct ihex_binrec *record)
 *      0       success
 *      ~0      failure
 ----------------------------------------------------------------*/
-int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
+int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk,
               unsigned int nfchunks)
 {
        int result = 0;
-       p80211msg_p2req_ramdl_state_t rstatemsg;
-       p80211msg_p2req_ramdl_write_t rwritemsg;
-       p80211msg_t *msgp;
+       struct p80211msg_p2req_ramdl_state rstatemsg;
+       struct p80211msg_p2req_ramdl_write rwritemsg;
+       struct p80211msg *msgp;
        u32 resultcode;
        int i;
        int j;
@@ -1030,7 +1029,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
        rstatemsg.enable.data = P80211ENUM_truth_true;
        rstatemsg.exeaddr.data = startaddr;
 
-       msgp = (p80211msg_t *) &rstatemsg;
+       msgp = (struct p80211msg *) &rstatemsg;
        result = prism2mgmt_ramdl_state(wlandev, msgp);
        if (result) {
                printk(KERN_ERR
@@ -1052,11 +1051,12 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
                nwrites += (fchunk[i].len % WRITESIZE_MAX) ? 1 : 0;
                curroff = 0;
                for (j = 0; j < nwrites; j++) {
-                       currlen =
-                           (fchunk[i].len - (WRITESIZE_MAX * j)) >
-                           WRITESIZE_MAX ? WRITESIZE_MAX : (fchunk[i].len -
-                                                            (WRITESIZE_MAX *
-                                                             j));
+                       /* TODO Move this to a separate function */
+                       int lenleft = fchunk[i].len - (WRITESIZE_MAX * j);
+                       if (fchunk[i].len > WRITESIZE_MAX)
+                               currlen = WRITESIZE_MAX;
+                       else
+                               currlen = lenleft;
                        curroff = j * WRITESIZE_MAX;
                        currdaddr = fchunk[i].addr + curroff;
                        /* Setup the message */
@@ -1070,7 +1070,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
                            ("Sending xxxdl_write message addr=%06x len=%d.\n",
                             currdaddr, currlen);
 
-                       msgp = (p80211msg_t *) &rwritemsg;
+                       msgp = (struct p80211msg *) &rwritemsg;
                        result = prism2mgmt_ramdl_write(wlandev, msgp);
 
                        /* Check the results */
@@ -1097,7 +1097,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
        rstatemsg.enable.data = P80211ENUM_truth_false;
        rstatemsg.exeaddr.data = 0;
 
-       msgp = (p80211msg_t *) &rstatemsg;
+       msgp = (struct p80211msg *) &rstatemsg;
        result = prism2mgmt_ramdl_state(wlandev, msgp);
        if (result) {
                printk(KERN_ERR
index 4d1cdfc3542098054518aa12b10aa0a10afe5c44..04514a85d1019ef6641670b471342cef4440ff6e 100644 (file)
@@ -117,7 +117,7 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
 {
        int result = 0;
        hfa384x_t *hw = wlandev->priv;
-       p80211msg_dot11req_scan_t *msg = msgp;
+       struct p80211msg_dot11req_scan *msg = msgp;
        u16 roamingmode, word;
        int i, timeout;
        int istmpenable = 0;
@@ -361,13 +361,13 @@ exit:
 int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
 {
        int result = 0;
-       p80211msg_dot11req_scan_results_t *req;
+       struct p80211msg_dot11req_scan_results *req;
        hfa384x_t *hw = wlandev->priv;
        hfa384x_HScanResultSub_t *item = NULL;
 
        int count;
 
-       req = (p80211msg_dot11req_scan_results_t *) msgp;
+       req = (struct p80211msg_dot11req_scan_results *) msgp;
 
        req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 
@@ -463,6 +463,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
 
        /* capinfo bits */
        count = le16_to_cpu(item->capinfo);
+       req->capinfo.status = P80211ENUM_msgitem_status_data_ok;
+       req->capinfo.data = count;
 
        /* privacy flag */
        req->privacy.status = P80211ENUM_msgitem_status_data_ok;
@@ -511,7 +513,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
 {
        int result = 0;
        hfa384x_t *hw = wlandev->priv;
-       p80211msg_dot11req_start_t *msg = msgp;
+       struct p80211msg_dot11req_start *msg = msgp;
 
        p80211pstrd_t *pstr;
        u8 bytebuf[80];
@@ -687,7 +689,7 @@ done:
 int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
 {
        hfa384x_t *hw = wlandev->priv;
-       p80211msg_p2req_readpda_t *msg = msgp;
+       struct p80211msg_p2req_readpda *msg = msgp;
        int result;
 
        /* We only support collecting the PDA when in the FWLOAD
@@ -753,7 +755,7 @@ int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
 int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
 {
        hfa384x_t *hw = wlandev->priv;
-       p80211msg_p2req_ramdl_state_t *msg = msgp;
+       struct p80211msg_p2req_ramdl_state *msg = msgp;
 
        if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
                printk(KERN_ERR
@@ -809,7 +811,7 @@ int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
 int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
 {
        hfa384x_t *hw = wlandev->priv;
-       p80211msg_p2req_ramdl_write_t *msg = msgp;
+       struct p80211msg_p2req_ramdl_write *msg = msgp;
        u32 addr;
        u32 len;
        u8 *buf;
@@ -872,7 +874,7 @@ int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
 {
        int result = 0;
        hfa384x_t *hw = wlandev->priv;
-       p80211msg_p2req_flashdl_state_t *msg = msgp;
+       struct p80211msg_p2req_flashdl_state *msg = msgp;
 
        if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
                printk(KERN_ERR
@@ -942,7 +944,7 @@ int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
 int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
 {
        hfa384x_t *hw = wlandev->priv;
-       p80211msg_p2req_flashdl_write_t *msg = msgp;
+       struct p80211msg_p2req_flashdl_write *msg = msgp;
        u32 addr;
        u32 len;
        u8 *buf;
@@ -1006,7 +1008,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
        int result = 0;
        u16 reg;
        u16 port_type;
-       p80211msg_lnxreq_autojoin_t *msg = msgp;
+       struct p80211msg_lnxreq_autojoin *msg = msgp;
        p80211pstrd_t *pstr;
        u8 bytebuf[256];
        hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
@@ -1074,7 +1076,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
 int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
 {
        int result = 0;
-       p80211msg_lnxreq_wlansniff_t *msg = msgp;
+       struct p80211msg_lnxreq_wlansniff *msg = msgp;
 
        hfa384x_t *hw = wlandev->priv;
        u16 word;
index 0b0ec9c59a5dc1be9c9e053e5d61f06bf654b315..d3a06fa0b4f6ad934b3025b94d9be2c631b0f41d 100644 (file)
@@ -79,7 +79,7 @@
 #define  F_READ       0x2      /* MIB may be read. */
 #define  F_WRITE      0x4      /* MIB may be written. */
 
-typedef struct mibrec {
+struct mibrec {
        u32 did;
        u16 flag;
        u16 parm1;
@@ -89,63 +89,63 @@ typedef struct mibrec {
                     int isget,
                     wlandevice_t *wlandev,
                     hfa384x_t *hw,
-                    p80211msg_dot11req_mibset_t *msg, void *data);
-} mibrec_t;
+                    struct p80211msg_dot11req_mibset *msg, void *data);
+};
 
-static int prism2mib_bytearea2pstr(mibrec_t *mib,
+static int prism2mib_bytearea2pstr(struct mibrec *mib,
                                   int isget,
                                   wlandevice_t *wlandev,
                                   hfa384x_t *hw,
-                                  p80211msg_dot11req_mibset_t *msg,
+                                  struct p80211msg_dot11req_mibset *msg,
                                   void *data);
 
-static int prism2mib_uint32(mibrec_t *mib,
+static int prism2mib_uint32(struct mibrec *mib,
                            int isget,
                            wlandevice_t *wlandev,
                            hfa384x_t *hw,
-                           p80211msg_dot11req_mibset_t *msg, void *data);
+                           struct p80211msg_dot11req_mibset *msg, void *data);
 
-static int prism2mib_flag(mibrec_t *mib,
+static int prism2mib_flag(struct mibrec *mib,
                          int isget,
                          wlandevice_t *wlandev,
                          hfa384x_t *hw,
-                         p80211msg_dot11req_mibset_t *msg, void *data);
+                         struct p80211msg_dot11req_mibset *msg, void *data);
 
-static int prism2mib_wepdefaultkey(mibrec_t *mib,
+static int prism2mib_wepdefaultkey(struct mibrec *mib,
                                   int isget,
                                   wlandevice_t *wlandev,
                                   hfa384x_t *hw,
-                                  p80211msg_dot11req_mibset_t *msg,
+                                  struct p80211msg_dot11req_mibset *msg,
                                   void *data);
 
-static int prism2mib_privacyinvoked(mibrec_t *mib,
+static int prism2mib_privacyinvoked(struct mibrec *mib,
                                    int isget,
                                    wlandevice_t *wlandev,
                                    hfa384x_t *hw,
-                                   p80211msg_dot11req_mibset_t *msg,
+                                   struct p80211msg_dot11req_mibset *msg,
                                    void *data);
 
-static int prism2mib_excludeunencrypted(mibrec_t *mib,
+static int prism2mib_excludeunencrypted(struct mibrec *mib,
                                        int isget,
                                        wlandevice_t *wlandev,
                                        hfa384x_t *hw,
-                                       p80211msg_dot11req_mibset_t *msg,
+                                       struct p80211msg_dot11req_mibset *msg,
                                        void *data);
 
-static int prism2mib_fragmentationthreshold(mibrec_t *mib,
+static int prism2mib_fragmentationthreshold(struct mibrec *mib,
                                            int isget,
                                            wlandevice_t *wlandev,
                                            hfa384x_t *hw,
-                                           p80211msg_dot11req_mibset_t *msg,
+                                           struct p80211msg_dot11req_mibset *msg,
                                            void *data);
 
-static int prism2mib_priv(mibrec_t *mib,
+static int prism2mib_priv(struct mibrec *mib,
                          int isget,
                          wlandevice_t *wlandev,
                          hfa384x_t *hw,
-                         p80211msg_dot11req_mibset_t *msg, void *data);
+                         struct p80211msg_dot11req_mibset *msg, void *data);
 
-static mibrec_t mibtab[] = {
+static struct mibrec mibtab[] = {
 
        /* dot11smt MIB's */
        {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
@@ -261,11 +261,11 @@ int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
 {
        hfa384x_t *hw = wlandev->priv;
        int result, isget;
-       mibrec_t *mib;
+       struct mibrec *mib;
 
        u16 which;
 
-       p80211msg_dot11req_mibset_t *msg = msgp;
+       struct p80211msg_dot11req_mibset *msg = msgp;
        p80211itemd_t *mibitem;
 
        msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
@@ -371,11 +371,11 @@ done:
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_bytearea2pstr(mibrec_t *mib,
+static int prism2mib_bytearea2pstr(struct mibrec *mib,
                                   int isget,
                                   wlandevice_t *wlandev,
                                   hfa384x_t *hw,
-                                  p80211msg_dot11req_mibset_t *msg,
+                                  struct p80211msg_dot11req_mibset *msg,
                                   void *data)
 {
        int result;
@@ -421,11 +421,11 @@ static int prism2mib_bytearea2pstr(mibrec_t *mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_uint32(mibrec_t *mib,
+static int prism2mib_uint32(struct mibrec *mib,
                            int isget,
                            wlandevice_t *wlandev,
                            hfa384x_t *hw,
-                           p80211msg_dot11req_mibset_t *msg, void *data)
+                           struct p80211msg_dot11req_mibset *msg, void *data)
 {
        int result;
        u32 *uint32 = (u32 *) data;
@@ -468,11 +468,11 @@ static int prism2mib_uint32(mibrec_t *mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_flag(mibrec_t *mib,
+static int prism2mib_flag(struct mibrec *mib,
                          int isget,
                          wlandevice_t *wlandev,
                          hfa384x_t *hw,
-                         p80211msg_dot11req_mibset_t *msg, void *data)
+                         struct p80211msg_dot11req_mibset *msg, void *data)
 {
        int result;
        u32 *uint32 = (u32 *) data;
@@ -525,11 +525,11 @@ static int prism2mib_flag(mibrec_t *mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_wepdefaultkey(mibrec_t *mib,
+static int prism2mib_wepdefaultkey(struct mibrec *mib,
                                   int isget,
                                   wlandevice_t *wlandev,
                                   hfa384x_t *hw,
-                                  p80211msg_dot11req_mibset_t *msg,
+                                  struct p80211msg_dot11req_mibset *msg,
                                   void *data)
 {
        int result;
@@ -575,11 +575,11 @@ static int prism2mib_wepdefaultkey(mibrec_t *mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_privacyinvoked(mibrec_t *mib,
+static int prism2mib_privacyinvoked(struct mibrec *mib,
                                    int isget,
                                    wlandevice_t *wlandev,
                                    hfa384x_t *hw,
-                                   p80211msg_dot11req_mibset_t *msg,
+                                   struct p80211msg_dot11req_mibset *msg,
                                    void *data)
 {
        int result;
@@ -621,11 +621,11 @@ static int prism2mib_privacyinvoked(mibrec_t *mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_excludeunencrypted(mibrec_t *mib,
+static int prism2mib_excludeunencrypted(struct mibrec *mib,
                                        int isget,
                                        wlandevice_t *wlandev,
                                        hfa384x_t *hw,
-                                       p80211msg_dot11req_mibset_t *msg,
+                                       struct p80211msg_dot11req_mibset *msg,
                                        void *data)
 {
        int result;
@@ -660,11 +660,11 @@ static int prism2mib_excludeunencrypted(mibrec_t *mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_fragmentationthreshold(mibrec_t *mib,
+static int prism2mib_fragmentationthreshold(struct mibrec *mib,
                                            int isget,
                                            wlandevice_t *wlandev,
                                            hfa384x_t *hw,
-                                           p80211msg_dot11req_mibset_t *msg,
+                                           struct p80211msg_dot11req_mibset *msg,
                                            void *data)
 {
        int result;
@@ -709,11 +709,11 @@ static int prism2mib_fragmentationthreshold(mibrec_t *mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_priv(mibrec_t *mib,
+static int prism2mib_priv(struct mibrec *mib,
                          int isget,
                          wlandevice_t *wlandev,
                          hfa384x_t *hw,
-                         p80211msg_dot11req_mibset_t *msg, void *data)
+                         struct p80211msg_dot11req_mibset *msg, void *data)
 {
        p80211pstrd_t *pstr = (p80211pstrd_t *) data;
 
index 6cd09352f89391dcaf9bc2157de0f94852d1cf1f..ed751f418db96ebcd64b2dc3ad5d6048ce447b8c 100644 (file)
@@ -83,8 +83,6 @@
 #include "hfa384x.h"
 #include "prism2mgmt.h"
 
-#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
-
 /* Create a string of printable chars from something that might not be */
 /* It's recommended that the str be 4*len + 1 bytes long */
 #define wlan_mkprintstr(buf, buflen, str, strlen) \
@@ -99,8 +97,8 @@
                } else { \
                        (str)[j] = '\\'; \
                        (str)[j+1] = 'x'; \
-                       (str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
-                       (str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
+                       (str)[j+2] = hex_asc_hi((buf)[i]); \
+                       (str)[j+3] = hex_asc_lo((buf)[i]); \
                        j += 4; \
                } \
        } \
@@ -124,13 +122,17 @@ MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
 
 MODULE_LICENSE("Dual MPL/GPL");
 
+void prism2_connect_result(wlandevice_t *wlandev, u8 failed);
+void prism2_disconnected(wlandevice_t *wlandev);
+void prism2_roamed(wlandevice_t *wlandev);
+
 static int prism2sta_open(wlandevice_t *wlandev);
 static int prism2sta_close(wlandevice_t *wlandev);
 static void prism2sta_reset(wlandevice_t *wlandev);
 static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
-                            p80211_hdr_t *p80211_hdr,
-                            p80211_metawep_t *p80211_wep);
-static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
+                            union p80211_hdr *p80211_hdr,
+                            struct p80211_metawep *p80211_wep);
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg);
 static int prism2sta_getcardinfo(wlandevice_t *wlandev);
 static int prism2sta_globalsetup(wlandevice_t *wlandev);
 static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev);
@@ -266,8 +268,8 @@ static void prism2sta_reset(wlandevice_t *wlandev)
 *      process thread
 ----------------------------------------------------------------*/
 static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
-                            p80211_hdr_t *p80211_hdr,
-                            p80211_metawep_t *p80211_wep)
+                            union p80211_hdr *p80211_hdr,
+                            struct p80211_metawep *p80211_wep)
 {
        hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
        int result;
@@ -307,7 +309,7 @@ static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
 * Call context:
 *      process thread
 ----------------------------------------------------------------*/
-static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg)
 {
        hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
@@ -364,9 +366,9 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
                break;          /* ignore me. */
        case DIDmsg_lnxreq_ifstate:
                {
-                       p80211msg_lnxreq_ifstate_t *ifstatemsg;
+                       struct p80211msg_lnxreq_ifstate *ifstatemsg;
                        pr_debug("Received mlme ifstate request\n");
-                       ifstatemsg = (p80211msg_lnxreq_ifstate_t *) msg;
+                       ifstatemsg = (struct p80211msg_lnxreq_ifstate *) msg;
                        result =
                            prism2sta_ifstate(wlandev,
                                              ifstatemsg->ifstate.data);
@@ -385,11 +387,11 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
                result = prism2mgmt_autojoin(wlandev, msg);
                break;
        case DIDmsg_lnxreq_commsquality:{
-                       p80211msg_lnxreq_commsquality_t *qualmsg;
+                       struct p80211msg_lnxreq_commsquality *qualmsg;
 
                        pr_debug("Received commsquality request\n");
 
-                       qualmsg = (p80211msg_lnxreq_commsquality_t *) msg;
+                       qualmsg = (struct p80211msg_lnxreq_commsquality *) msg;
 
                        qualmsg->link.status =
                            P80211ENUM_msgitem_status_data_ok;
@@ -401,6 +403,7 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
                        qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS);
                        qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS);
                        qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC);
+                       qualmsg->txrate.data = hw->txrate;
 
                        break;
                }
@@ -1300,6 +1303,9 @@ void prism2sta_processing_defer(struct work_struct *data)
                            (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
                            WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
 
+                       /* signal back up to cfg80211 layer */
+                       prism2_connect_result(wlandev, P80211ENUM_truth_false);
+
                        /* Get the ball rolling on the comms quality stuff */
                        prism2sta_commsqual_defer(&hw->commsqual_bh);
                }
@@ -1315,25 +1321,16 @@ void prism2sta_processing_defer(struct work_struct *data)
                 * Indicate Deauthentication
                 * Block Transmits, Ignore receives of data frames
                 */
-               if (hw->join_ap == 2) {
-                       hfa384x_JoinRequest_data_t joinreq;
-                       joinreq = hw->joinreq;
-                       /* Send the join request */
-                       hfa384x_drvr_setconfig(hw,
-                                              HFA384x_RID_JOINREQUEST,
-                                              &joinreq,
-                                              HFA384x_RID_JOINREQUEST_LEN);
+               if (wlandev->netdev->type == ARPHRD_ETHER)
                        printk(KERN_INFO
-                           "linkstatus=DISCONNECTED (re-submitting join)\n");
-               } else {
-                       if (wlandev->netdev->type == ARPHRD_ETHER)
-                               printk(KERN_INFO
-                                      "linkstatus=DISCONNECTED (unhandled)\n");
-               }
+                              "linkstatus=DISCONNECTED (unhandled)\n");
                wlandev->macmode = WLAN_MACMODE_NONE;
 
                netif_carrier_off(wlandev->netdev);
 
+               /* signal back up to cfg80211 layer */
+               prism2_disconnected(wlandev);
+
                break;
 
        case HFA384x_LINK_AP_CHANGE:
@@ -1376,6 +1373,9 @@ void prism2sta_processing_defer(struct work_struct *data)
                hw->link_status = HFA384x_LINK_CONNECTED;
                netif_carrier_on(wlandev->netdev);
 
+               /* signal back up to cfg80211 layer */
+               prism2_roamed(wlandev);
+
                break;
 
        case HFA384x_LINK_AP_OUTOFRANGE:
@@ -1435,6 +1435,9 @@ void prism2sta_processing_defer(struct work_struct *data)
 
                netif_carrier_off(wlandev->netdev);
 
+               /* signal back up to cfg80211 layer */
+               prism2_connect_result(wlandev, P80211ENUM_truth_true);
+
                break;
 
        default:
@@ -1446,7 +1449,6 @@ void prism2sta_processing_defer(struct work_struct *data)
        }
 
        wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
-       p80211wext_event_associated(wlandev, wlandev->linkstatus);
 
 failed:
        return;
@@ -1985,6 +1987,9 @@ void prism2sta_commsqual_defer(struct work_struct *data)
        hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
        wlandevice_t *wlandev = hw->wlandev;
        hfa384x_bytestr32_t ssid;
+       struct p80211msg_dot11req_mibget msg;
+       p80211item_uint32_t *mibitem = (p80211item_uint32_t *)
+                                               &msg.mibattribute.data;
        int result = 0;
 
        if (hw->wlandev->hwremoved)
@@ -2013,6 +2018,34 @@ void prism2sta_commsqual_defer(struct work_struct *data)
                         le16_to_cpu(hw->qual.ANL_currFC));
        }
 
+       /* Get the signal rate */
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem->did = DIDmib_p2_p2MAC_p2CurrentTxRate;
+       result = p80211req_dorequest(wlandev, (u8 *) &msg);
+
+       if (result) {
+               pr_debug("get signal rate failed, result = %d\n",
+                        result);
+               goto done;
+       }
+
+       switch (mibitem->data) {
+       case HFA384x_RATEBIT_1:
+               hw->txrate = 10;
+               break;
+       case HFA384x_RATEBIT_2:
+               hw->txrate = 20;
+               break;
+       case HFA384x_RATEBIT_5dot5:
+               hw->txrate = 55;
+               break;
+       case HFA384x_RATEBIT_11:
+               hw->txrate = 110;
+               break;
+       default:
+               pr_debug("Bad ratebit (%d)\n", mibitem->data);
+       }
+
        /* Lastly, we need to make sure the BSSID didn't change on us */
        result = hfa384x_drvr_getconfig(hw,
                                        HFA384x_RID_CURRENTBSSID,
index f5cff751db2fc872f422bc35ddfdbdd02bd3a99b..4efa027a81e444d70cb07d914a223d413640c323 100644 (file)
@@ -119,7 +119,7 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
        }
        hw = wlandev->priv;
 
-       if (wlan_setup(wlandev) != 0) {
+       if (wlan_setup(wlandev, &(interface->dev)) != 0) {
                printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info);
                result = -EIO;
                goto failed;
diff --git a/drivers/staging/xgifb/XGI.h b/drivers/staging/xgifb/XGI.h
deleted file mode 100644 (file)
index 87803dd..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _XGI_H
-#define _XGI_H
-
-#if 1
-#define TWDEBUG(x)
-#else
-#define TWDEBUG(x) printk(KERN_INFO x "\n");
-#endif
-
-#endif
index 86ec3421942f931b23802b5b5a45502d493d0f65..79549742cff1ec01a116947a9730bf78f4f41bef 100644 (file)
 #include <linux/agp_backend.h>
 
 #include <linux/types.h>
-/*
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/XGIfb.h>
-#else
-#include <video/XGIfb.h>
-#endif
-*/
 #include <asm/io.h>
 
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#endif
-
-#include "osdef.h"
 #include "vgatypes.h"
 #include "vb_struct.h"
 #include "XGIfb.h"
 #include "XGI_accel.h"
 
-
-extern struct     video_info xgi_video_info;
-extern int XGIfb_accel;
-
 static const int XGIALUConv[] =
 {
     0x00,       /* dest = 0;            0,      GXclear,        0 */
@@ -108,109 +88,17 @@ static const int XGIPatALUConv[] =
     0xFF,       /* dest = 0xFF;         1,      GXset,          0xF */
 };
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
 static const unsigned char myrops[] = {
        3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
    };
-#endif
 
 /* 300 series */
-#if 0
-static void
-XGI300Sync(void)
-{
-       XGI300Idle
-}
-#endif
 static void
 XGI310Sync(void)
 {
        XGI310Idle
 }
-#if 0
-static void
-XGI300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
-                                unsigned int planemask, int trans_color)
-{
-       XGI300SetupDSTColorDepth(xgi_video_info.DstColor);
-       XGI300SetupSRCPitch(xgi_video_info.video_linelength)
-       XGI300SetupDSTRect(xgi_video_info.video_linelength, 0xFFF)
-
-       if(trans_color != -1) {
-               XGI300SetupROP(0x0A)
-               XGI300SetupSRCTrans(trans_color)
-               XGI300SetupCMDFlag(TRANSPARENT_BITBLT)
-       } else {
-               XGI300SetupROP(XGIALUConv[rop])
-       }
-       if(xdir > 0) {
-               XGI300SetupCMDFlag(X_INC)
-       }
-       if(ydir > 0) {
-               XGI300SetupCMDFlag(Y_INC)
-       }
-}
-
-static void
-XGI300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
-                                int width, int height)
-{
-       long srcbase, dstbase;
-
-       srcbase = dstbase = 0;
-       if (src_y >= 2048) {
-               srcbase = xgi_video_info.video_linelength * src_y;
-               src_y = 0;
-       }
-       if (dst_y >= 2048) {
-               dstbase = xgi_video_info.video_linelength * dst_y;
-               dst_y = 0;
-       }
-
-       XGI300SetupSRCBase(srcbase);
-       XGI300SetupDSTBase(dstbase);
-
-       if(!(xgi_video_info.CommandReg & X_INC))  {
-               src_x += width-1;
-               dst_x += width-1;
-       }
-       if(!(xgi_video_info.CommandReg & Y_INC))  {
-               src_y += height-1;
-               dst_y += height-1;
-       }
-       XGI300SetupRect(width, height)
-       XGI300SetupSRCXY(src_x, src_y)
-       XGI300SetupDSTXY(dst_x, dst_y)
-       XGI300DoCMD
-}
-
-static void
-XGI300SetupForSolidFill(int color, int rop, unsigned int planemask)
-{
-       XGI300SetupPATFG(color)
-       XGI300SetupDSTRect(xgi_video_info.video_linelength, 0xFFF)
-       XGI300SetupDSTColorDepth(xgi_video_info.DstColor);
-       XGI300SetupROP(XGIPatALUConv[rop])
-       XGI300SetupCMDFlag(PATFG)
-}
 
-static void
-XGI300SubsequentSolidFillRect(int x, int y, int w, int h)
-{
-       long dstbase;
-
-       dstbase = 0;
-       if(y >= 2048) {
-               dstbase = xgi_video_info.video_linelength * y;
-               y = 0;
-       }
-       XGI300SetupDSTBase(dstbase)
-       XGI300SetupDSTXY(x,y)
-       XGI300SetupRect(w,h)
-       XGI300SetupCMDFlag(X_INC | Y_INC | BITBLT)
-       XGI300DoCMD
-}
-#endif
 /* 310/325 series ------------------------------------------------ */
 
 static void
@@ -326,8 +214,6 @@ void XGIfb_syncaccel(void)
 
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)  /* --- KERNEL 2.5.34 and later --- */
-
 int fbcon_XGI_sync(struct fb_info *info)
 {
     if(!XGIfb_accel) return 0;
@@ -399,198 +285,5 @@ void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 
 }
 
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)  /* ------ KERNEL <2.5.34 ------ */
-
-void fbcon_XGI_bmove(struct display *p, int srcy, int srcx,
-                           int dsty, int dstx, int height, int width)
-{
-        int xdir, ydir;
-       CRITFLAGS
-
-       if(!xgi_video_info.accel) {
-           switch(xgi_video_info.video_bpp) {
-           case 8:
-#ifdef FBCON_HAS_CFB8
-              fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
-              break;
-           case 16:
-#ifdef FBCON_HAS_CFB16
-              fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
-              break;
-           case 32:
-#ifdef FBCON_HAS_CFB32
-              fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
-              break;
-            }
-           return;
-       }
-
-       srcx *= fontwidth(p);
-       srcy *= fontheight(p);
-       dstx *= fontwidth(p);
-       dsty *= fontheight(p);
-       width *= fontwidth(p);
-       height *= fontheight(p);
-
-       if(srcx < dstx) xdir = 0;
-       else            xdir = 1;
-       if(srcy < dsty) ydir = 0;
-       else            ydir = 1;
-
-
-          CRITBEGIN
-          XGI310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-          XGI310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
-          CRITEND
-          XGI310Sync();
-#if 0
-          printk(KERN_INFO "XGI_bmove sx %d sy %d dx %d dy %d w %d h %d\n",
-               srcx, srcy, dstx, dsty, width, height);
-#endif
-
-}
-
-
-static void fbcon_XGI_clear(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width, int color)
-{
-       CRITFLAGS
-
-       srcx *= fontwidth(p);
-       srcy *= fontheight(p);
-       width *= fontwidth(p);
-       height *= fontheight(p);
-
-
-          CRITBEGIN
-          XGI310SetupForSolidFill(color, 3, 0);
-          XGI310SubsequentSolidFillRect(srcx, srcy, width, height);
-          CRITEND
-          XGI310Sync();
-
-}
-
-void fbcon_XGI_clear8(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width)
-{
-       u32 bgx;
-
-       if(!xgi_video_info.accel) {
-#ifdef FBCON_HAS_CFB8
-           fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
-#endif
-           return;
-       }
-
-       bgx = attr_bgcol_ec(p, conp);
-       fbcon_XGI_clear(conp, p, srcy, srcx, height, width, bgx);
-}
-
-void fbcon_XGI_clear16(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width)
-{
-       u32 bgx;
-       if(!xgi_video_info.accel) {
-#ifdef FBCON_HAS_CFB16
-           fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
-#endif
-           return;
-       }
-
-       bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-       fbcon_XGI_clear(conp, p, srcy, srcx, height, width, bgx);
-}
-
-void fbcon_XGI_clear32(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width)
-{
-       u32 bgx;
-
-       if(!xgi_video_info.accel) {
-#ifdef FBCON_HAS_CFB32
-           fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
-#endif
-           return;
-       }
-
-       bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-       fbcon_XGI_clear(conp, p, srcy, srcx, height, width, bgx);
-}
-
-void fbcon_XGI_revc(struct display *p, int srcx, int srcy)
-{
-       CRITFLAGS
-
-       if(!xgi_video_info.accel) {
-           switch(xgi_video_info.video_bpp) {
-           case 16:
-#ifdef FBCON_HAS_CFB16
-              fbcon_cfb16_revc(p, srcx, srcy);
-#endif
-              break;
-           case 32:
-#ifdef FBCON_HAS_CFB32
-              fbcon_cfb32_revc(p, srcx, srcy);
-#endif
-              break;
-            }
-           return;
-       }
-
-       srcx *= fontwidth(p);
-       srcy *= fontheight(p);
-
-
-          CRITBEGIN
-          XGI310SetupForSolidFill(0, 0x0a, 0);
-          XGI310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
-          CRITEND
-          XGI310Sync();
-
-}
-
-#ifdef FBCON_HAS_CFB8
-struct display_switch fbcon_XGI8 = {
-       setup:                  fbcon_cfb8_setup,
-       bmove:                  fbcon_XGI_bmove,
-       clear:                  fbcon_XGI_clear8,
-       putc:                   fbcon_cfb8_putc,
-       putcs:                  fbcon_cfb8_putcs,
-       revc:                   fbcon_cfb8_revc,
-       clear_margins:          fbcon_cfb8_clear_margins,
-       fontwidthmask:          FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB16
-struct display_switch fbcon_XGI16 = {
-       setup:                  fbcon_cfb16_setup,
-       bmove:                  fbcon_XGI_bmove,
-       clear:                  fbcon_XGI_clear16,
-       putc:                   fbcon_cfb16_putc,
-       putcs:                  fbcon_cfb16_putcs,
-       revc:                   fbcon_XGI_revc,
-       clear_margins:          fbcon_cfb16_clear_margins,
-       fontwidthmask:          FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB32
-struct display_switch fbcon_XGI32 = {
-       setup:                  fbcon_cfb32_setup,
-       bmove:                  fbcon_XGI_bmove,
-       clear:                  fbcon_XGI_clear32,
-       putc:                   fbcon_cfb32_putc,
-       putcs:                  fbcon_cfb32_putcs,
-       revc:                   fbcon_XGI_revc,
-       clear_margins:          fbcon_cfb32_clear_margins,
-       fontwidthmask:          FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-
-#endif /* KERNEL VERSION */
 
 
index 04e126772bb84ed20c7088358f7362ed39f068ce..28c057994b37b9778fe7c984330aff92d9559930 100644 (file)
@@ -491,21 +491,9 @@ void XGIfb_syncaccel(void);
 
 extern struct video_info xgi_video_info;
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
-void fbcon_XGI_bmove(struct display *p, int srcy, int srcx, int dsty,
-                     int dstx, int height, int width);
-void fbcon_XGI_revc(struct display *p, int srcy, int srcx);
-void fbcon_XGI_clear8(struct vc_data *conp, struct display *p, int srcy,
-                      int srcx, int height, int width);
-void fbcon_XGI_clear16(struct vc_data *conp, struct display *p, int srcy,
-                       int srcx, int height, int width);
-void fbcon_XGI_clear32(struct vc_data *conp, struct display *p, int srcy,
-                       int srcx, int height, int width);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
 extern int XGIfb_accel;
 void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
 void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-#endif
+
 
 #endif
index 4f4171e8a68aa921ba478f3b0f63db04e9b4bf0a..fd1152eb2c925edf7f4f27e524fb17686262f463 100644 (file)
 
 
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #define XGI_IOTYPE1 void __iomem
 #define XGI_IOTYPE2 __iomem
 #define XGIINITSTATIC static
-#else
-#define XGI_IOTYPE1 unsigned char
-#define XGI_IOTYPE2
-#define XGIINITSTATIC
-#endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct pci_device_id __devinitdata xgifb_pci_table[] = {
 
        { PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -63,7 +56,7 @@ static struct pci_device_id __devinitdata xgifb_pci_table[] = {
 };
 
 MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
-#endif
+
 /* To be included in fb.h */
 #ifndef FB_ACCEL_XGI_GLAMOUR_2
 #define FB_ACCEL_XGI_GLAMOUR_2  40     /* XGI 315, 650, 740            */
@@ -255,9 +248,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
 #define BRI_DRAM_SIZE_32MB        0x04
 #define BRI_DRAM_SIZE_64MB        0x05
 
-#define HW_DEVICE_EXTENSION      XGI_HW_DEVICE_INFO
-#define PHW_DEVICE_EXTENSION      PXGI_HW_DEVICE_INFO
-
 #define SR_BUFFER_SIZE            5
 #define CR_BUFFER_SIZE            5
 
@@ -300,11 +290,7 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
 /* ------------------- Global Variables ----------------------------- */
 
 /* Fbcon variables */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct fb_info* fb_info;
-#else
-static struct fb_info XGI_fb_info;
-#endif
 
 
 static int    video_type = FB_TYPE_PACKED_PIXELS;
@@ -336,12 +322,8 @@ static struct fb_var_screeninfo default_var = {
        .vsync_len      = 0,
        .sync           = 0,
        .vmode          = FB_VMODE_NONINTERLACED,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       .reserved       = {0, 0, 0, 0, 0, 0}
-#endif
 };
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct fb_fix_screeninfo XGIfb_fix = {
        .id             = "XGI",
        .type           = FB_TYPE_PACKED_PIXELS,
@@ -350,28 +332,7 @@ static struct fb_fix_screeninfo XGIfb_fix = {
 };
 static char myid[20];
 static u32 pseudo_palette[17];
-#endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static struct display XGI_disp;
-
-static struct display_switch XGIfb_sw;
-
-static struct {
-       u16 blue, green, red, pad;
-} XGI_palette[256];
-
-static union {
-#ifdef FBCON_HAS_CFB16
-       u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-       u32 cfb32[16];
-#endif
-} XGI_fbcon_cmap;
-
-static int XGIfb_inverse = 0;
-#endif
 
 /* display status */
 static int XGIfb_off = 0;
@@ -380,9 +341,6 @@ static int XGIfb_forcecrt1 = -1;
 static int XGIvga_enabled = 0;
 static int XGIfb_userom = 0;
 //static int XGIfb_useoem = -1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int currcon = 0;
-#endif
 
 /* global flags */
 static int XGIfb_registered;
@@ -415,10 +373,10 @@ unsigned char XGIfb_detectedlcda = 0xff;
 /* XGIfb_info XGIfbinfo; */
 
 /* TW: Hardware extension; contains data on hardware */
-HW_DEVICE_EXTENSION XGIhw_ext;
+struct xgi_hw_device_info XGIhw_ext;
 
 /* TW: XGI private structure */
-VB_DEVICE_INFO  XGI_Pr;
+struct vb_device_info  XGI_Pr;
 
 /* card parameters */
 static unsigned long XGIfb_mmio_size = 0;
@@ -530,29 +488,21 @@ struct _XGIbios_mode {
 
 /* mode-related variables */
 #ifdef MODULE
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static int xgifb_mode_idx = 1;
 #else
-static int XGIfb_mode_idx = MODE_INDEX_NONE;  /* Don't use a mode by default if we are a module */
-#endif
-#else
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static int xgifb_mode_idx = -1;               /* Use a default mode if we are inside the kernel */
-#else
-static int XGIfb_mode_idx = -1;
-#endif
 #endif
 u8  XGIfb_mode_no  = 0;
 u8  XGIfb_rate_idx = 0;
 
 /* TW: CR36 evaluation */
-const USHORT XGI300paneltype[] =
+const unsigned short XGI300paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
       LCD_1280x960,  LCD_640x480,  LCD_1024x600,  LCD_1152x768,
        LCD_1024x768, LCD_1024x768,  LCD_1024x768,
       LCD_1024x768,  LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
 
-const USHORT XGI310paneltype[] =
+const unsigned short XGI310paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
       LCD_640x480,   LCD_1024x600, LCD_1152x864,  LCD_1280x960,
       LCD_1152x768,  LCD_1400x1050,LCD_1280x768,  LCD_1600x1200,
@@ -648,17 +598,6 @@ static const struct _chswtable {
        { 0,      0,      ""       , ""       }
 };
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/* Offscreen layout */
-typedef struct _XGI_GLYINFO {
-       unsigned char ch;
-       int fontwidth;
-       int fontheight;
-       u8 gmask[72];
-       int ngmask;
-} XGI_GLYINFO;
-#endif
-
 typedef struct _XGI_OH {
        struct _XGI_OH *poh_next;
        struct _XGI_OH *poh_prev;
@@ -852,50 +791,6 @@ XGIINITSTATIC int __init XGIfb_setup(char *options);
 
 
 /* fbdev routines */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       int     XGIfb_init(void);
-static int      XGIfb_get_fix(struct fb_fix_screeninfo *fix,
-                             int con,
-                             struct fb_info *info);
-static int      XGIfb_get_var(struct fb_var_screeninfo *var,
-                             int con,
-                             struct fb_info *info);
-static int      XGIfb_set_var(struct fb_var_screeninfo *var,
-                             int con,
-                             struct fb_info *info);
-static void     XGIfb_crtc_to_var(struct fb_var_screeninfo *var);
-static int      XGIfb_get_cmap(struct fb_cmap *cmap,
-                              int kspc,
-                              int con,
-                              struct fb_info *info);
-static int      XGIfb_set_cmap(struct fb_cmap *cmap,
-                              int kspc,
-                              int con,
-                              struct fb_info *info);
-static int      XGIfb_update_var(int con,
-                                struct fb_info *info);
-static int      XGIfb_switch(int con,
-                            struct fb_info *info);
-static void     XGIfb_blank(int blank,
-                           struct fb_info *info);
-static void     XGIfb_set_disp(int con,
-                              struct fb_var_screeninfo *var,
-                               struct fb_info *info);
-static int      XGI_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-                             unsigned *blue, unsigned *transp,
-                             struct fb_info *fb_info);
-static void     XGIfb_do_install_cmap(int con,
-                                      struct fb_info *info);
-static void     XGI_get_glyph(struct fb_info *info,
-                              XGI_GLYINFO *gly);
-static int     XGIfb_mmap(struct fb_info *info, struct file *file,
-                          struct vm_area_struct *vma);
-static int      XGIfb_ioctl(struct inode *inode, struct file *file,
-                           unsigned int cmd, unsigned long arg, int con,
-                           struct fb_info *info);
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 XGIINITSTATIC int __init xgifb_init(void);
 static int      XGIfb_set_par(struct fb_info *info);
 static int      XGIfb_blank(int blank,
@@ -907,36 +802,25 @@ extern void     fbcon_XGI_fillrect(struct fb_info *info,
                                    const struct fb_fillrect *rect);
 extern void     fbcon_XGI_copyarea(struct fb_info *info,
                                    const struct fb_copyarea *area);
-#if 0
-extern void     cfb_imageblit(struct fb_info *info,
-                              const struct fb_image *image);
-#endif
 extern int      fbcon_XGI_sync(struct fb_info *info);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
 static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
                            unsigned long arg);
-#else
-static int      XGIfb_ioctl(struct inode *inode,
-                           struct file *file,
-                           unsigned int cmd,
-                           unsigned long arg,
-                           struct fb_info *info);
-#endif
 
 /*
 extern int     XGIfb_mode_rate_to_dclock(VB_DEVICE_INFO *XGI_Pr,
-                             PXGI_HW_DEVICE_INFO HwDeviceExtension,
+                             struct xgi_hw_device_info *HwDeviceExtension,
                              unsigned char modeno, unsigned char rateindex);
-extern int      XGIfb_mode_rate_to_ddata(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+extern int      XGIfb_mode_rate_to_ddata(VB_DEVICE_INFO *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
                         unsigned char modeno, unsigned char rateindex,
                         unsigned int *left_margin, unsigned int *right_margin,
                         unsigned int *upper_margin, unsigned int *lower_margin,
                         unsigned int *hsync_len, unsigned int *vsync_len,
                         unsigned int *sync, unsigned int *vmode);
 */
-#endif
-                       extern   BOOLEAN  XGI_SearchModeID( USHORT ModeNo,USHORT  *ModeIdIndex, PVB_DEVICE_INFO );
+extern unsigned char XGI_SearchModeID(unsigned short ModeNo,
+                               unsigned short *ModeIdIndex,
+                               struct vb_device_info *);
 static int      XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
                              struct fb_info *info);
 
@@ -956,10 +840,10 @@ static int      XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 static void     XGIfb_pre_setmode(void);
 static void     XGIfb_post_setmode(void);
 
-static BOOLEAN  XGIfb_CheckVBRetrace(void);
-static BOOLEAN  XGIfbcheckvretracecrt2(void);
-static BOOLEAN  XGIfbcheckvretracecrt1(void);
-static BOOLEAN  XGIfb_bridgeisslave(void);
+static unsigned char  XGIfb_CheckVBRetrace(void);
+static unsigned char  XGIfbcheckvretracecrt2(void);
+static unsigned char  XGIfbcheckvretracecrt1(void);
+static unsigned char  XGIfb_bridgeisslave(void);
 
 struct XGI_memreq {
        unsigned long offset;
@@ -994,30 +878,40 @@ static XGI_OH   *XGIfb_poh_free(unsigned long base);
 static void     XGIfb_free_node(XGI_OH *poh);
 
 /* Internal routines to access PCI configuration space */
-BOOLEAN         XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
-                       unsigned long offset, unsigned long set, unsigned long *value);
+unsigned char XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
+                                          unsigned long offset,
+                                          unsigned long set,
+                                          unsigned long *value);
 //BOOLEAN         XGIfb_query_north_bridge_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
 //                     unsigned long offset, unsigned long set, unsigned long *value);
 
 
 /* Routines from init.c/init301.c */
-extern void     InitTo330Pointer(UCHAR,PVB_DEVICE_INFO pVBInfo);
-extern BOOLEAN  XGIInitNew(PXGI_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN  XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+extern void     InitTo330Pointer(unsigned char, struct vb_device_info *pVBInfo);
+extern unsigned char  XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension);
+extern unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
+                                  unsigned short ModeNo);
 //extern void     XGI_SetEnableDstn(VB_DEVICE_INFO *XGI_Pr);
-extern void     XGI_LongWait(VB_DEVICE_INFO *XGI_Pr);
-extern USHORT   XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo );
+extern void     XGI_LongWait(struct vb_device_info *XGI_Pr);
+extern unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
+                                        unsigned short ModeNo,
+                                        unsigned short ModeIdIndex,
+                                        struct vb_device_info *pVBInfo);
 /* TW: Chrontel TV functions */
-extern USHORT  XGI_GetCH700x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
-extern void    XGI_SetCH700x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
-extern USHORT  XGI_GetCH701x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
-extern void    XGI_SetCH701x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
-extern void     XGI_SetCH70xxANDOR(VB_DEVICE_INFO *XGI_Pr, USHORT tempax,USHORT tempbh);
-extern void     XGI_DDC2Delay(VB_DEVICE_INFO *XGI_Pr, USHORT delaytime);
+extern unsigned short XGI_GetCH700x(struct vb_device_info *XGI_Pr,
+                                   unsigned short tempbx);
+extern void XGI_SetCH700x(struct vb_device_info *XGI_Pr, unsigned short tempbx);
+extern unsigned short XGI_GetCH701x(struct vb_device_info *XGI_Pr,
+                                   unsigned short tempbx);
+extern void XGI_SetCH701x(struct vb_device_info *XGI_Pr, unsigned short tempbx);
+extern void XGI_SetCH70xxANDOR(struct vb_device_info *XGI_Pr,
+                              unsigned short tempax,
+                              unsigned short tempbh);
+extern void XGI_DDC2Delay(struct vb_device_info *XGI_Pr, unsigned short delaytime);
 
 /* TW: Sensing routines */
 void            XGI_Sense30x(void);
 int             XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch);
 
-extern XGI21_LVDSCapStruct XGI21_LCDCapList[13];
+extern struct XGI21_LVDSCapStruct XGI21_LCDCapList[13];
 #endif
index 867012b48a0193c7c27ae6987d8abfd44bd99019..976c39bb28669908eac770e8490f48b3f2fbc55a 100644 (file)
@@ -28,9 +28,6 @@
 #include <linux/fs.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include <linux/kernel.h>
-
-#include "osdef.h"
 
 
 #ifndef XGIFB_PAN
@@ -164,16 +161,15 @@ struct video_info  xgi_video_info;
 
 /* --------------- Hardware Access Routines -------------------------- */
 
-#ifdef LINUX_KERNEL
 int
-XGIfb_mode_rate_to_dclock(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
                          unsigned char modeno, unsigned char rateindex)
 {
-    USHORT ModeNo = modeno;
-    USHORT ModeIdIndex = 0, ClockIndex = 0;
-    USHORT RefreshRateTableIndex = 0;
+    unsigned short ModeNo = modeno;
+    unsigned short ModeIdIndex = 0, ClockIndex = 0;
+    unsigned short RefreshRateTableIndex = 0;
 
-    /*ULONG  temp = 0;*/
+    /*unsigned long  temp = 0;*/
     int    Clock;
     XGI_Pr->ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
     InitTo330Pointer( HwDeviceExtension->jChipType, XGI_Pr ) ;
@@ -201,16 +197,16 @@ XGIfb_mode_rate_to_dclock(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceEx
 }
 
 int
-XGIfb_mode_rate_to_ddata(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
                         unsigned char modeno, unsigned char rateindex,
                         u32 *left_margin, u32 *right_margin,
                         u32 *upper_margin, u32 *lower_margin,
                         u32 *hsync_len, u32 *vsync_len,
                         u32 *sync, u32 *vmode)
 {
-    USHORT ModeNo = modeno;
-    USHORT ModeIdIndex = 0, index = 0;
-    USHORT RefreshRateTableIndex = 0;
+    unsigned short ModeNo = modeno;
+    unsigned short ModeIdIndex = 0, index = 0;
+    unsigned short RefreshRateTableIndex = 0;
 
     unsigned short VRE, VBE, VRS, VBS, VDE, VT;
     unsigned short HRE, HBE, HRS, HBS, HDE, HT;
@@ -375,26 +371,13 @@ XGIfb_mode_rate_to_ddata(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceExt
       }
     }
 
-#if 0  /* That's bullshit, only the resolution needs to be shifted */
-    if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-       *upper_margin <<= 1;
-       *lower_margin <<= 1;
-       *vsync_len <<= 1;
-    } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-       *upper_margin >>= 1;
-       *lower_margin >>= 1;
-       *vsync_len >>= 1;
-    }
-#endif
-
     return 1;
 }
 
-#endif
 
 
 
-void XGIRegInit(VB_DEVICE_INFO *XGI_Pr, ULONG BaseAddr)
+void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
 {
    XGI_Pr->RelIO = BaseAddr;
    XGI_Pr->P3c4 = BaseAddr + 0x14;
@@ -432,8 +415,8 @@ u32 XGIfb_get_reg3(u16 port)
 
 /* ------------ Interface for init & mode switching code ------------- */
 
-BOOLEAN
-XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
+unsigned char
+XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
        unsigned long offset, unsigned long set, unsigned long *value)
 {
        static struct pci_dev *pdev = NULL;
@@ -445,10 +428,10 @@ XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
                DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
 
        if (!init) {
-               init = TRUE;
+               init = 1;
                pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id, pdev);
                if (pdev) {
-                       valid_pdev = TRUE;
+                       valid_pdev = 1;
                        pci_dev_put(pdev);
                }
        }
@@ -456,7 +439,7 @@ XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
        if (!valid_pdev) {
                printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
                                xgi_video_info.chip_id);
-               return FALSE;
+               return 0;
        }
 
        if (set == 0)
@@ -464,10 +447,10 @@ XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
        else
                pci_write_config_dword(pdev, offset, (u32)(*value));
 
-       return TRUE;
+       return 1;
 }
 
-/*BOOLEAN XGIfb_query_north_bridge_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
+/*unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
        unsigned long offset, unsigned long set, unsigned long *value)
 {
        static struct pci_dev *pdev = NULL;
@@ -475,7 +458,7 @@ XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
        u16 nbridge_id = 0;
 
        if (!init) {
-               init = TRUE;
+               init = 1;
                switch (xgi_video_info.chip) {
                case XGI_540:
                        nbridge_id = PCI_DEVICE_ID_XG_540;
@@ -502,13 +485,13 @@ XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
 
                pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
                if (pdev)
-                       valid_pdev = TRUE;
+                       valid_pdev = 1;
        }
 
        if (!valid_pdev) {
                printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
                                nbridge_id);
-               return FALSE;
+               return 0;
        }
 
        if (set == 0)
@@ -516,7 +499,7 @@ XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
        else
                pci_write_config_dword(pdev, offset, (u32)(*value));
 
-       return TRUE;
+       return 1;
 }
 */
 /* ------------------ Internal helper routines ----------------- */
@@ -627,7 +610,8 @@ int XGIfb_GetXG21LVDSData(void)
                 i += 25;
                 j--;
                 k++;
-        } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
+       } while ((j > 0) &&
+                (k < (sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct))));
         return 1;
     }
     return 0;
@@ -954,46 +938,52 @@ static void XGIfb_search_tvstd(const char *name)
        }
 }
 
-static BOOLEAN XGIfb_bridgeisslave(void)
+static unsigned char XGIfb_bridgeisslave(void)
 {
    unsigned char usScratchP1_00;
 
-   if(xgi_video_info.hasVB == HASVB_NONE) return FALSE;
+   if (xgi_video_info.hasVB == HASVB_NONE)
+          return 0;
 
    inXGIIDXREG(XGIPART1,0x00,usScratchP1_00);
-   if( (usScratchP1_00 & 0x50) == 0x10)  {
-          return TRUE;
-   } else {
-           return FALSE;
-   }
+   if ((usScratchP1_00 & 0x50) == 0x10)
+          return 1;
+   else
+          return 0;
 }
 
-static BOOLEAN XGIfbcheckvretracecrt1(void)
+static unsigned char XGIfbcheckvretracecrt1(void)
 {
    unsigned char temp;
 
    inXGIIDXREG(XGICR,0x17,temp);
-   if(!(temp & 0x80)) return FALSE;
+   if (!(temp & 0x80))
+          return 0;
 
 
    inXGIIDXREG(XGISR,0x1f,temp);
-   if(temp & 0xc0) return FALSE;
+   if (temp & 0xc0)
+          return 0;
 
-
-   if(inXGIREG(XGIINPSTAT) & 0x08) return TRUE;
-   else                           return FALSE;
+   if (inXGIREG(XGIINPSTAT) & 0x08)
+          return 1;
+   else
+          return 0;
 }
 
-static BOOLEAN XGIfbcheckvretracecrt2(void)
+static unsigned char XGIfbcheckvretracecrt2(void)
 {
    unsigned char temp;
-   if(xgi_video_info.hasVB == HASVB_NONE) return FALSE;
+   if (xgi_video_info.hasVB == HASVB_NONE)
+          return 0;
    inXGIIDXREG(XGIPART1, 0x30, temp);
-   if(temp & 0x02) return FALSE;
-   else           return TRUE;
+   if (temp & 0x02)
+          return 0;
+   else
+          return 1;
 }
 
-static BOOLEAN XGIfb_CheckVBRetrace(void)
+static unsigned char XGIfb_CheckVBRetrace(void)
 {
    if(xgi_video_info.disp_state & DISPTYPE_DISP2) {
       if(XGIfb_bridgeisslave()) {
@@ -1350,11 +1340,7 @@ static int XGIfb_set_par(struct fb_info *info)
 //     printk("XGIfb: inside set_par\n");
         if((err = XGIfb_do_set_var(&info->var, 1, info)))
                return err;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
-       XGIfb_get_fix(&info->fix, info->currcon, info);
-#else
        XGIfb_get_fix(&info->fix, -1, info);
-#endif
 //     printk("XGIfb:end of set_par\n");
        return 0;
 }
@@ -1540,58 +1526,7 @@ static int XGIfb_pan_display( struct fb_var_screeninfo *var,
 }
 #endif
 
-#if 0
-static int XGIfb_mmap(struct fb_info *info, struct file *file,
-                     struct vm_area_struct *vma)
-{
-       unsigned long start;
-       unsigned long off;
-       u32 len, mmio_off;
-
-       DEBUGPRN("inside mmap");
-       if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
-
-       off = vma->vm_pgoff << PAGE_SHIFT;
-
-       start = (unsigned long) xgi_video_info.video_base;
-       len = PAGE_ALIGN((start & ~PAGE_MASK) + xgi_video_info.video_size);
-       start &= PAGE_MASK;
-#if 0
-       if (off >= len) {
-               off -= len;
-#endif
-       /* By Jake Page: Treat mmap request with offset beyond heapstart
-        *               as request for mapping the mmio area
-        */
-       #if 1
-       mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + xgi_video_info.heapstart);
-       if(off >= mmio_off) {
-               off -= mmio_off;
-               if(info->var.accel_flags) return -EINVAL;
-
-               start = (unsigned long) xgi_video_info.mmio_base;
-               len = PAGE_ALIGN((start & ~PAGE_MASK) + XGIfb_mmio_size);
-       }
-       start &= PAGE_MASK;
-       #endif
-       if((vma->vm_end - vma->vm_start + off) > len)   return -EINVAL;
-
-       off += start;
-       vma->vm_pgoff = off >> PAGE_SHIFT;
-       vma->vm_flags |= VM_IO;   /* by Jake Page; is that really needed? */
-
-#if defined(__i386__) || defined(__x86_64__)
-       if (boot_cpu_data.x86 > 3)
-               pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#endif
-       if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start,
-                               vma->vm_page_prot))
-               return -EAGAIN;
 
-        DEBUGPRN("end of mmap");
-       return 0;
-}
-#endif
 static int XGIfb_blank(int blank, struct fb_info *info)
 {
        u8 reg;
@@ -1610,15 +1545,8 @@ static int XGIfb_blank(int blank, struct fb_info *info)
 }
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
 static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
                            unsigned long arg)
-#else
-static int XGIfb_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg,
-                      struct fb_info *info)
-#endif
-
 {
        DEBUGPRN("inside ioctl");
        switch (cmd) {
@@ -1687,7 +1615,7 @@ static int XGIfb_ioctl(struct inode *inode, struct file *file,
                break;
           case XGIFB_GET_INFO:  /* TW: New for communication with X driver */
                {
-                       XGIfb_info *x = (XGIfb_info *)arg;
+                       struct XGIfb_info *x = (struct XGIfb_info *)arg;
 
                        //x->XGIfb_id = XGIFB_ID;
                        x->XGIfb_version = VER_MAJOR;
@@ -1786,9 +1714,6 @@ static struct fb_ops XGIfb_ops = {
        .fb_fillrect  = fbcon_XGI_fillrect,
        .fb_copyarea  = fbcon_XGI_copyarea,
        .fb_imageblit = cfb_imageblit,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-       .fb_cursor    = soft_cursor,
-#endif
        .fb_sync      = fbcon_XGI_sync,
        .fb_ioctl     = XGIfb_ioctl,
 //     .fb_mmap      = XGIfb_mmap,
@@ -2008,9 +1933,9 @@ static int XGIfb_has_VB(void)
                break;
           default:
                xgi_video_info.hasVB = HASVB_NONE;
-               return FALSE;
+               return 0;
        }
-       return TRUE;
+       return 1;
 }
 
 
@@ -2664,13 +2589,7 @@ static void XGIfb_pre_setmode(void)
 static void XGIfb_post_setmode(void)
 {
        u8 reg;
-       BOOLEAN doit = TRUE;
-#if 0  /* TW: Wrong: Is not in MMIO space, but in RAM */
-       /* Backup mode number to MMIO space */
-       if(xgi_video_info.mmio_vbase) {
-         *(volatile u8 *)(((u8*)xgi_video_info.mmio_vbase) + 0x449) = (unsigned char)XGIfb_mode_no;
-       }
-#endif
+       unsigned char doit = 1;
 /*     outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
        outXGIIDXREG(XGICR,0x13,0x00);
        setXGIIDXREG(XGISR,0x0E,0xF0,0x01);
@@ -2678,11 +2597,11 @@ static void XGIfb_post_setmode(void)
        if (xgi_video_info.video_bpp == 8) {
                /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
                if ((xgi_video_info.hasVB == HASVB_LVDS) || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
-                       doit = FALSE;
+                       doit = 0;
                }
                /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
                if  (xgi_video_info.disp_state & DISPTYPE_LCD)  {
-                       doit = FALSE;
+                       doit = 0;
                }
        }
 
@@ -2691,14 +2610,15 @@ static void XGIfb_post_setmode(void)
                inXGIIDXREG(XGIPART1, 0x00, reg);
 
 
-               if((reg & 0x50) == 0x10) {
-                       doit = FALSE;
-               }
+               if ((reg & 0x50) == 0x10)
+                       doit = 0;
 
-       } else XGIfb_crt1off = 0;
+
+       } else
+               XGIfb_crt1off = 0;
 
        inXGIIDXREG(XGICR, 0x17, reg);
-       if((XGIfb_crt1off) && (doit))
+       if ((XGIfb_crt1off) && (doit))
                reg &= ~0x80;
        else
                reg |= 0x80;
@@ -2907,7 +2827,7 @@ XGIINITSTATIC int __init XGIfb_setup(char *options)
 
 static unsigned char VBIOS_BUF[65535];
 
-unsigned char* attempt_map_rom(struct pci_dev *dev,void *copy_address)
+unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address)
 {
     u32 rom_size      = 0;
     u32 rom_address   = 0;
@@ -2962,15 +2882,9 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        XGIfb_registered = 0;
 
-       memset(&XGIhw_ext, 0, sizeof(HW_DEVICE_EXTENSION));
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
+       memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
          fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
          if(!fb_info) return -ENOMEM;
-#else
-         XGI_fb_info = kmalloc( sizeof(struct fb_info), GFP_KERNEL);
-         if(!XGI_fb_info) return -ENOMEM;
-         memset(XGI_fb_info, 0,  sizeof(struct fb_info));
-#endif
 
        xgi_video_info.chip_id = pdev->device;
          pci_read_config_byte(pdev, PCI_REVISION_ID,&xgi_video_info.revision_id);
@@ -2988,14 +2902,15 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
          xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
          XGIfb_mmio_size =  pci_resource_len(pdev, 1);
          xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
-         XGIhw_ext.pjIOAddress = (PUCHAR)xgi_video_info.vga_base;
+         XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
          //XGI_Pr.RelIO  = ioremap(pci_resource_start(pdev, 2), 128) + 0x30;
-         printk("XGIfb: Relocate IO address: %lx [%08lx] \n", (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
+         printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
+                (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
 
          if (pci_enable_device(pdev))
                  return -EIO;
 
-    XGIRegInit(&XGI_Pr, (ULONG)XGIhw_ext.pjIOAddress);
+    XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
 
     outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
     inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
@@ -3052,7 +2967,7 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                   case XG20:
                   case XG21:
                    case XG27:
-                   XGIhw_ext.bIntegratedMMEnabled = TRUE;
+                          XGIhw_ext.bIntegratedMMEnabled = 1;
                        break;
 
                   default:
@@ -3080,7 +2995,7 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
          strcpy(XGIhw_ext.szVBIOSVer, "0.84");
 
 
-    XGIhw_ext.pSR = vmalloc(sizeof(XGI_DSReg) * SR_BUFFER_SIZE);
+    XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
          if (XGIhw_ext.pSR == NULL)
          {
                    printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
@@ -3088,7 +3003,7 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
          }
          XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
 
-         XGIhw_ext.pCR = vmalloc(sizeof(XGI_DSReg) * CR_BUFFER_SIZE);
+         XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
          if (XGIhw_ext.pCR == NULL)
          {
              vfree(XGIhw_ext.pSR);
@@ -3218,7 +3133,7 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                    xgi_video_info.disp_state = DISPTYPE_LCD;
                    if (!XGIfb_GetXG21LVDSData()) {
                            int m;
-                           for (m=0; m < sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct); m++) {
+                           for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
                                    if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
                                        (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
                                                XGINew_SetReg1( XGI_Pr.P3d4 , 0x36, m) ;
@@ -3341,14 +3256,14 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                  inXGIIDXREG(XGICR,0x38,tmp);
                      if((tmp & 0x03) == 0x03)
                      {
-//                       XGI_Pr.XGI_UseLCDA = TRUE;
+/*                       XGI_Pr.XGI_UseLCDA = 1; */
                      }else
                      {
                     //  Currently on LCDA? (Some newer BIOSes set D0 in CR35)
                         inXGIIDXREG(XGICR,0x35,tmp);
                         if(tmp & 0x01)
                         {
-//                           XGI_Pr.XGI_UseLCDA = TRUE;
+/*                           XGI_Pr.XGI_UseLCDA = 1; */
                           }else
                           {
                               inXGIIDXREG(XGICR,0x30,tmp);
@@ -3357,7 +3272,7 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                                   inXGIIDXREG(XGIPART1,0x13,tmp);
                                       if(tmp & 0x04)
                                       {
-//                                     XGI_Pr.XGI_UseLCDA = TRUE;
+/*                                     XGI_Pr.XGI_UseLCDA = 1; */
                                       }
                               }
                           }
@@ -3462,20 +3377,6 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                }
 
-
-#if 0
-#ifdef XGIFB_PAN
-               if(XGIfb_ypan) {
-                       default_var.yres_virtual =
-                               xgi_video_info.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
-                       if(default_var.yres_virtual <= default_var.yres) {
-                               default_var.yres_virtual = default_var.yres;
-                       }
-               }
-#endif
-#endif
-
-
                xgi_video_info.accel = 0;
                if(XGIfb_accel) {
                   xgi_video_info.accel = -1;
@@ -3511,7 +3412,8 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                XGIfb_registered = 1;
 
-               printk(KERN_INFO "XGIfb: Installed XGIFB_GET_INFO ioctl (%x)\n", XGIFB_GET_INFO);
+               printk(KERN_INFO "XGIfb: Installed XGIFB_GET_INFO ioctl (%lx)\n",
+                      XGIFB_GET_INFO);
 
 /*             printk(KERN_INFO "XGIfb: 2D acceleration is %s, scrolling mode %s\n",
                     XGIfb_accel ? "enabled" : "disabled",
@@ -3538,11 +3440,7 @@ static void __devexit xgifb_remove(struct pci_dev *pdev)
        /* Unregister the framebuffer */
 //     if(xgi_video_info.registered) {
                unregister_framebuffer(fb_info);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
                framebuffer_release(fb_info);
-#else
-               kfree(fb_info);
-#endif
 //     }
 
        pci_set_drvdata(pdev, NULL);
@@ -3558,23 +3456,20 @@ static struct pci_driver xgifb_driver = {
 
 XGIINITSTATIC int __init xgifb_init(void)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #ifndef MODULE
        char *option = NULL;
 
        if (fb_get_options("xgifb", &option))
                return -ENODEV;
        XGIfb_setup(option);
-#endif
 #endif
        return(pci_register_driver(&xgifb_driver));
 }
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+
 #ifndef MODULE
 module_init(xgifb_init);
 #endif
-#endif
 
 /*****************************************************/
 /*                      MODULE                       */
index 41bf163d4e6bee610da973a4e717121180502464..ef86a64d699600f9d291c83e5782a3c4e235475e 100644 (file)
@@ -27,7 +27,7 @@
 #define XGIFB_ID          0x53495346    /* Identify myself with 'XGIF' */
 #endif
 
-typedef enum _XGI_CHIP_TYPE {
+enum XGI_CHIP_TYPE {
     XGI_VGALegacy = 0,
     XGI_300,
     XGI_630,
@@ -53,9 +53,9 @@ typedef enum _XGI_CHIP_TYPE {
     XG21,
     XG27,
     MAX_XGI_CHIP
-} XGI_CHIP_TYPE;
+};
 
-typedef enum _TVTYPE {
+enum xgi_tvtype {
        TVMODE_NTSC = 0,
        TVMODE_PAL,
        TVMODE_HIVISION,
@@ -63,13 +63,11 @@ typedef enum _TVTYPE {
        TVTYPE_PALN,    // vicki@030226
        TVTYPE_NTSCJ,   // vicki@030226
        TVMODE_TOTAL
-} XGI_TV_TYPE;
-
+};
 
-typedef struct _XGIFB_INFO XGIfb_info;
-struct _XGIFB_INFO {
 
-unsigned long XGIfb_id;
+struct XGIfb_info {
+       unsigned long XGIfb_id;
        int    chip_id;                 /* PCI ID of detected chip */
        int    memory;                  /* video memory in KB which XGIfb manages */
        int    heapstart;               /* heap start (= XGIfb "mem" argument) in KB */
@@ -97,7 +95,7 @@ unsigned long XGIfb_id;
 
 
 
-typedef enum _TVPLUGTYPE {     // vicki@030226
+enum xgi_tv_plug {     /* vicki@030226 */
 //     TVPLUG_Legacy = 0,
 //     TVPLUG_COMPOSITE,
 //     TVPLUG_SVIDEO,
@@ -113,7 +111,7 @@ typedef enum _TVPLUGTYPE {  // vicki@030226
        TVPLUG_YPBPR_750P = 7,
        TVPLUG_YPBPR_1080i = 8,
        TVPLUG_TOTAL
-} XGI_TV_PLUG;
+};
 
 
 struct mode_info {
@@ -132,10 +130,10 @@ struct ap_data {
        unsigned long iobase;
        unsigned int  mem_size;
        unsigned long disp_state;
-       XGI_CHIP_TYPE chip;
+       enum XGI_CHIP_TYPE chip;
        unsigned char hasVB;
-       XGI_TV_TYPE TV_type;
-       XGI_TV_PLUG TV_plug;
+       enum xgi_tvtype TV_type;
+       enum xgi_tv_plug TV_plug;
        unsigned long version;
        char reserved[256];
 };
@@ -184,7 +182,7 @@ struct video_info{
         unsigned char TV_type;
         unsigned char TV_plug;
 
-        XGI_CHIP_TYPE chip;
+       enum XGI_CHIP_TYPE chip;
         unsigned char revision_id;
 
         unsigned short DstColor;
@@ -207,9 +205,4 @@ struct video_info{
 
 extern struct video_info xgi_video_info;
 
-#ifdef __KERNEL__
-//extern void xgi_malloc(struct xgi_memreq *req);
-extern void xgi_free(unsigned long base);
-extern void xgi_dispinfo(struct ap_data *rec);
-#endif
 #endif
diff --git a/drivers/staging/xgifb/osdef.h b/drivers/staging/xgifb/osdef.h
deleted file mode 100644 (file)
index 4bc7d3a..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef _OSDEF_H_
-#define _OSDEF_H_
-
-/* #define WINCE_HEADER*/
-/*#define WIN2000*/
-/* #define TC */
-#define LINUX_KERNEL
-/* #define LINUX_XF86 */
-
-/**********************************************************************/
-#ifdef LINUX_KERNEL
-//#include <linux/config.h>
-#endif
-
-
-/**********************************************************************/
-#ifdef TC
-#endif
-#ifdef WIN2000
-#endif
-#ifdef WINCE_HEADER
-#endif
-#ifdef LINUX_XF86
-#define LINUX
-#endif
-#ifdef LINUX_KERNEL
-#define LINUX
-#endif
-
-/**********************************************************************/
-#ifdef TC
-#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
-#endif
-#ifdef WIN2000
-#define XGI_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
-#endif
-#ifdef WINCE_HEADER
-#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
-#endif
-#ifdef LINUX_XF86
-#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#endif
-#ifdef LINUX_KERNEL
-#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#endif
-/**********************************************************************/
-
-/**********************************************************************/
-
-#ifdef TC
-#define XGI_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
-#endif
-#ifdef WIN2000
-#define XGI_MemoryCopy(Destination,Soruce,Length)  /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
-#endif
-#ifdef WINCE_HEADER
-#define XGI_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
-#endif
-#ifdef LINUX_XF86
-#define XGI_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
-#endif
-#ifdef LINUX_KERNEL
-#define XGI_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
-#endif
-
-/**********************************************************************/
-
-#ifdef OutPortByte
-#undef OutPortByte
-#endif /* OutPortByte */
-
-#ifdef OutPortWord
-#undef OutPortWord
-#endif /* OutPortWord */
-
-#ifdef OutPortLong
-#undef OutPortLong
-#endif /* OutPortLong */
-
-#ifdef InPortByte
-#undef InPortByte
-#endif /* InPortByte */
-
-#ifdef InPortWord
-#undef InPortWord
-#endif /* InPortWord */
-
-#ifdef InPortLong
-#undef InPortLong
-#endif /* InPortLong */
-
-/**********************************************************************/
-/*  TC                                                                */
-/**********************************************************************/
-
-#ifdef TC
-#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
-#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
-#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
-#define InPortByte(p)    inp((unsigned short)(p))
-#define InPortWord(p)    inp((unsigned short)(p))
-#define InPortLong(p)    ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
-#endif
-
-/**********************************************************************/
-/*  LINUX XF86                                                        */
-/**********************************************************************/
-
-#ifdef LINUX_XF86
-#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v))
-#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v))
-#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v))
-#define InPortByte(p)    inb((CARD16)(p))
-#define InPortWord(p)    inw((CARD16)(p))
-#define InPortLong(p)    inl((CARD16)(p))
-#endif
-
-#ifdef LINUX_KERNEL
-#define OutPortByte(p,v) outb((u8)(v),(p))
-#define OutPortWord(p,v) outw((u16)(v),(p))
-#define OutPortLong(p,v) outl((u32)(v),(p))
-#define InPortByte(p)    inb(p)
-#define InPortWord(p)    inw(p)
-#define InPortLong(p)    inl(p)
-#endif
-
-/**********************************************************************/
-/*  WIN 2000                                                          */
-/**********************************************************************/
-
-#ifdef WIN2000
-#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
-#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
-#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
-#define InPortByte(p)    VideoPortReadPortUchar  ((PUCHAR) (p))
-#define InPortWord(p)    VideoPortReadPortUshort ((PUSHORT) (p))
-#define InPortLong(p)    VideoPortReadPortUlong  ((PULONG) (p))
-#endif
-
-
-/**********************************************************************/
-/*  WIN CE                                                          */
-/**********************************************************************/
-
-#ifdef WINCE_HEADER
-#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
-#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
-#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
-#define InPortByte(p)    READ_PORT_UCHAR  ((PUCHAR) (p))
-#define InPortWord(p)    READ_PORT_USHORT ((PUSHORT) (p))
-#define InPortLong(p)    READ_PORT_ULONG  ((PULONG) (p))
-#endif
-#endif // _OSDEF_H_
index 17a7ada4926e9a77cddce679c198e810eead4374..4de182b23d414816b9da2ad3e9446e76c831a99f 100644 (file)
@@ -6,7 +6,7 @@
 #define NewScratch
 #endif
 /* shampoo */
-#ifdef LINUX_KERNEL
+
 #define SEQ_ADDRESS_PORT         0x0014
 #define SEQ_DATA_PORT            0x0015
 #define MISC_OUTPUT_REG_READ_PORT 0x001C
@@ -17,7 +17,7 @@
 #define CRTC_ADDRESS_PORT_COLOR   0x0024
 #define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013
 #define PCI_COMMAND            0x04
-#endif
+
 /* ~shampoo */
 
 
index 49b39ee93a89af4c1e73a918a61e2d74ee470978..1ecf9e3e85fb3b30b45b25c369069ac13be2a909 100644 (file)
@@ -1,40 +1,7 @@
-#include "osdef.h"
-
-
-
-
-#ifdef WIN2000
-
-#include <dderror.h>
-#include <devioctl.h>
-#include <miniport.h>
-#include <ntddvdeo.h>
-#include <video.h>
-#include "xgiv.h"
-#include "dd_i2c.h"
-#include "tools.h"
-#endif /* WIN2000 */
-
-#ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86PciInfo.h"
-#include "xgi.h"
-#include "xgi_regs.h"
-#endif
-
-#ifdef LINUX_KERNEL
 #include <linux/version.h>
 #include <asm/io.h>
 #include <linux/types.h>
 #include "XGIfb.h"
-/*#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#include <video/XGIfb.h>
-#else
-#include <linux/XGIfb.h>
-#endif*/
-#endif
-
-
 
 #include "vb_def.h"
 #include "vgatypes.h"
 #include "vb_util.h"
 #include "vb_setmode.h"
 #include "vb_ext.h"
-extern   UCHAR XGI330_SoftSetting;
-extern   UCHAR XGI330_OutputSelect;
-extern   USHORT XGI330_RGBSenseData2;
-extern   USHORT XGI330_YCSenseData2;
-extern   USHORT XGI330_VideoSenseData2;
-#ifdef WIN2000
-extern   UCHAR SenseCHTV(PHW_DEVICE_EXTENSION pHWDE);       /* 2007/05/17 Billy */
-#endif
-void     XGI_GetSenseStatus( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo );
-BOOLEAN  XGINew_GetPanelID(PVB_DEVICE_INFO pVBInfo);
-USHORT   XGINew_SenseLCD(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGINew_GetLCDDDCInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
-void XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE ) ;
-BOOLEAN  XGINew_BridgeIsEnable(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo );
-BOOLEAN  XGINew_Sense(USHORT tempbx,USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGINew_SenseHiTV( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
+extern   unsigned char XGI330_SoftSetting;
+extern   unsigned char XGI330_OutputSelect;
+extern   unsigned short XGI330_RGBSenseData2;
+extern   unsigned short XGI330_YCSenseData2;
+extern   unsigned short XGI330_VideoSenseData2;
+void     XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+unsigned char  XGINew_GetPanelID(struct vb_device_info *pVBInfo);
+unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *,
+                              struct vb_device_info *pVBInfo);
+unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension,
+                            struct vb_device_info *pVBInfo);
+void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE,
+               unsigned long VESA_POWER_STATE);
+unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx,
+                    struct vb_device_info *pVBInfo);
+unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension,
+                              struct vb_device_info *pVBInfo);
 
 /**************************************************************
        Dynamic Sense
 *************************************************************/
 
 void XGI_WaitDisplay(void);
-BOOLEAN XGI_Is301C(PVB_DEVICE_INFO);
-BOOLEAN XGI_Is301LV(PVB_DEVICE_INFO);
-
-#ifdef WIN2000
-UCHAR XGI_SenseLCD(PHW_DEVICE_EXTENSION, PVB_DEVICE_INFO);
-UCHAR XGI_GetLCDDDCInfo(PHW_DEVICE_EXTENSION,PVB_DEVICE_INFO);
+unsigned char XGI_Is301C(struct vb_device_info *);
+unsigned char XGI_Is301LV(struct vb_device_info *);
 
-extern BOOL bGetDdcInfo(
-PHW_DEVICE_EXTENSION  pHWDE,
-ULONG                 ulWhichOne,
-PUCHAR                pjQueryBuffer,
-ULONG                 ulBufferSize
-   );
-
-#endif
 
 
 /* --------------------------------------------------------------------- */
@@ -87,9 +44,9 @@ ULONG                 ulBufferSize
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGINew_Is301B( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo)
 {
-    USHORT flag ;
+    unsigned short flag ;
 
     flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) ;
 
@@ -105,7 +62,7 @@ BOOLEAN XGINew_Is301B( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_Is301C( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_Is301C(struct vb_device_info *pVBInfo)
 {
     if ( ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) & 0xF0 ) == 0xC0 )
         return( 1 ) ;
@@ -126,7 +83,7 @@ BOOLEAN XGI_Is301C( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_Is301LV( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_Is301LV(struct vb_device_info *pVBInfo)
 {
     if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) >= 0xD0 )
     {
@@ -145,9 +102,11 @@ BOOLEAN XGI_Is301LV( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGINew_Sense(  USHORT tempbx , USHORT tempcx, PVB_DEVICE_INFO pVBInfo )
+unsigned char XGINew_Sense(unsigned short tempbx,
+                    unsigned short tempcx,
+                    struct vb_device_info *pVBInfo)
 {
-    USHORT temp , i , tempch ;
+    unsigned short temp, i, tempch;
 
     temp = tempbx & 0xFF ;
     XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
@@ -169,284 +128,6 @@ BOOLEAN XGINew_Sense(  USHORT tempbx , USHORT tempcx, PVB_DEVICE_INFO pVBInfo )
         return( 0 ) ;
 }
 
-#ifdef WIN2000
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SenseLCD */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-UCHAR XGI_SenseLCD( PHW_DEVICE_EXTENSION pHWDE, PVB_DEVICE_INFO pVBInfo)
-{
-    USHORT tempax , tempbx , tempcx ;
-    UCHAR SoftSetting = XGI330_SoftSetting ;
-
-    if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV ) )
-        return( 1 ) ;
-
-
-    if ( SoftSetting & HotPlugFunction )       /* Hot Plug Detection */
-    {
-        XGINew_SetRegAND( pVBInfo->Part4Port , 0x0F , 0x3F ) ;
-        tempbx = 0 ;
-        tempcx = 0x9010 ;
-        if ( XGINew_Sense( tempbx , tempcx, pVBInfo ) )
-            return( 1 ) ;
-
-        return( 0 ) ;
-    }
-    else       /* Get LCD Info from EDID */
-        return(XGI_GetLCDDDCInfo(pHWDE, pVBInfo));
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDDDCInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-UCHAR XGI_GetLCDDDCInfo( PHW_DEVICE_EXTENSION pHWDE , PVB_DEVICE_INFO pVBInfo)
-{
-    UCHAR tempah , tempbl , tempbh ;
-    USHORT tempbx , temp ;
-    UCHAR pjEDIDBuf[ 256 ] ;
-    ULONG ulBufferSize = 256 ;
-    UCHAR bMASK_OUTPUTSTATE_CRT2LCD = 2 ; /* 0423 shampoo */
-
-    bGetDdcInfo( pHWDE , MASK_OUTPUTSTATE_CRT2LCD , pjEDIDBuf , ulBufferSize ) ;
-    if ( ( *( ( PULONG )pjEDIDBuf ) == 0xFFFFFF00 ) && ( *( ( PULONG )( pjEDIDBuf + 4 ) ) == 0x00FFFFFF ) )
-    {
-        tempah = Panel1024x768 ;
-        tempbl=( *( pjEDIDBuf + 0x3A ) ) & 0xf0 ;
-
-        if ( tempbl != 0x40 )
-        {
-            tempah = Panel1600x1200 ;
-            if ( tempbl != 0x60 )
-            {
-                tempah = Panel1280x1024 ;
-                tempbh = ( *( pjEDIDBuf + 0x3B ) ) ;
-                if ( tempbh != 0x00 )
-                {
-                    tempah = Panel1280x960 ;
-                    if ( tempbh != 0x0C0 )
-                    {
-                        tempbx = ( ( *( pjEDIDBuf + 0x24 ) ) << 8 ) | ( *( pjEDIDBuf + 0x23 ) ) ;
-                        tempah = Panel1280x1024 ;
-                        if ( !( tempbx & 0x0100 ) )
-                        {
-                            tempah = Panel1024x768 ;
-                            if ( !( tempbx & 0x0E00 ) )
-                            {
-                                tempah = Panel1280x1024 ;
-                            }
-                        }
-                    }
-
-                    if ( tempbx & 0x00FF )
-                    {
-                        temp = ScalingLCD ;
-                        XGINew_SetRegOR( pVBInfo->P3d4 , 0x37 , temp ) ;
-                    }
-                }
-            }
-        }
-        XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x36 , ( ~0x07 ) , tempah ) ;
-        tempah = ( ( *( pjEDIDBuf + 0x47 ) ) & 0x06 ) ;                /* Polarity */
-        tempah = ( tempah ^ 0x06 ) << 4 ;
-        tempah |= LCDSync ;
-        XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ( ~LCDSyncBit ) , tempah ) ;
-        tempbh= XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ;
-        tempbh &= 0x07 ;
-        if ( tempbh == Panel1280x960 )
-            XGINew_SetRegAND( pVBInfo->P3d4 , 0x37 , 0x0E ) ;
-    }
-    else if ( *pjEDIDBuf == 0x20 )
-    {
-        tempah = Panel1024x768 ;
-        XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x36 , ( ~0x07 ) , tempah ) ;
-    }
-    else
-    {
-        return( 0 ) ;
-    }
-
-    return( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DySense */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN XGI_DySense( PHW_DEVICE_EXTENSION pHWDE , PUCHAR ujConnectStatus)
-{
-    UCHAR pre_CRD,pre_SR1E , pre_Part2_0 , pre_Part4_D ;
-    USHORT tempax , tempbx , tempcx , pushax , temp ;
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
-    UCHAR OutputSelect = XGI330_OutputSelect ;
-    PXGI_HW_DEVICE_INFO HwDeviceExtension= pHWDE->pXGIHWDE ;
-    UCHAR   bConnectStatus = 0 ;
-    pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress ;
-    pVBInfo->ROMAddr  = pHWDE->pjVirtualRomBase ;
-
-    pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
-    pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
-    pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
-    pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
-    pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
-    pushax = XGINew_GetReg1( pVBInfo->P3d4 , 0x17 ) ;  /* 0512 Fix Dysense hanged */
-    temp = ( pushax & 0x00FF ) | 0x80 ;
-    XGINew_SetRegOR( pVBInfo->P3d4 , 0x17 , temp ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
-    /* beginning of dynamic sense CRT1 */
-
-    pVBInfo->IF_DEF_CH7007 = 0;
-    if (pHWDE->bCH7007)
-    {
-       InitTo330Pointer( pHWDE->pXGIHWDE->jChipType, pVBInfo ) ;
-        HwDeviceExtension->pDevice = (PVOID)pHWDE;
-        pVBInfo->IF_DEF_CH7007 = 1;
-        /* [Billy] 2007/05/14 For CH7007 */
-        if ( pVBInfo->IF_DEF_CH7007 == 1 )
-        {
-           bConnectStatus = SenseCHTV(HwDeviceExtension->pDevice) ; /* 07/05/28 */
-           XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~0x03 , (UCHAR)bConnectStatus ) ;
-        }
-    }
-    if(( pHWDE->jChipID >= XG40 ) || ( pHWDE->jChipID >= XG20 ))
-    {
-
-        if ( pHWDE->jChipID >= XG40 )
-           XGINew_SetReg1( pVBInfo->P3d4 , 0x57 , 0x4A ) ;     /* write sense pattern 30->4a */
-       else
-            XGINew_SetReg1( pVBInfo->P3d4 , 0x57 , 0x5F ) ;    /* write sense pattern */
-
-        XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x53 , 0xFF , 0x02 ) ;     /* enable sense DAC */
-        XGI_WaitDisply(pVBInfo) ;
-
-        if(XGINew_GetReg2( pVBInfo->P3c2 ) & 0x10 )
-            bConnectStatus |= Monitor1Sense ;
-
-        XGINew_SetRegAND( pVBInfo->P3d4 , 0x53 , 0xFD ) ;      /* disable sense DAC */
-        XGINew_SetRegAND( pVBInfo->P3d4 , 0x57 , 0x00 ) ;      /* clear sense pattern */
-
-
-        /* ---------- End of dynamic sense CRT1 ----------- */
-
-        /* ---------- beginning of dynamic sense VB ------------ */
-        pre_SR1E = XGINew_GetReg1( pVBInfo->P3c4 , 0x1E ) ;
-        XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x20 ) ;       /* Enable CRT2,work-a-round for 301B/301LV/302LV */
-        pre_Part2_0 = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
-        pre_Part4_D = XGINew_GetReg1( pVBInfo->Part4Port , 0x0D ) ;
-
-        if ( XGI_Is301C( pVBInfo ) )   /* 301C only */
-            XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0D , ~0x07 , 0x01 ) ;   /* Set Part4 0x0D D[2:0] to 001b */
-
-        /* tempax = 0 ; */
-        if ( !XGI_Is301LV( pVBInfo ) )
-        {
-           tempbx = XGI330_RGBSenseData2 ;
-            tempcx = 0x0E08 ;
-            if(XGINew_Sense( tempbx , tempcx, pVBInfo ) )
-            {
-                bConnectStatus |= Monitor2Sense ;
-                if ( OutputSelect & SetSCARTOutput )
-                {
-                    bConnectStatus ^= ( Monitor2Sense | SCARTSense ) ;
-                }
-            }
-        }
-        if ( XGI_Is301C( pVBInfo ) )   /* 301C only */
-            XGINew_SetRegOR( pVBInfo->Part4Port , 0x0D , 0x04 ) ;      /* Set Part4 0x0D D[2]=1 for dynamic sense */
-
-        if ( ( XGINew_Is301B( pVBInfo ) ) )
-            XGINew_SetRegOR( pVBInfo->Part2Port , 0x00 , 0x0C ) ;    /* ????????? */
-
-       if ( XGINew_SenseHiTV( HwDeviceExtension , pVBInfo) )           /* add by kuku for Dysense HiTV //start */
-       {
-           bConnectStatus|= YPbPrSense ;
-       }
-       else
-       {
-        tempbx = XGI330_YCSenseData2 ; /* Y/C Sense Data Ptr */
-        tempcx = 0x0604 ;
-        if ( XGINew_Sense( tempbx , tempcx , pVBInfo) )
-            bConnectStatus |= SVIDEOSense ;
-
-        if ( OutputSelect & BoardTVType )
-        {
-            tempbx = XGI330_VideoSenseData2 ;
-            tempcx = 0x0804 ;
-            if ( XGINew_Sense(tempbx , tempcx, pVBInfo) )
-                bConnectStatus|= AVIDEOSense ;
-        }
-        else
-        {
-            if ( !( bConnectStatus & SVIDEOSense ) )
-            {
-                tempbx = XGI330_VideoSenseData2 ;
-                tempcx = 0x0804 ;
-                if ( XGINew_Sense( tempbx , tempcx, pVBInfo ) )
-                    bConnectStatus |= AVIDEOSense ;
-            }
-        }
-       } /* end */
-        /* DySenseVBCnt */
-
-        tempbx = 0 ;
-        tempcx = 0 ;
-        XGINew_Sense(tempbx , tempcx, pVBInfo ) ;
-
-        if ( !( bConnectStatus & Monitor2Sense ) )
-        {
-            if ( XGI_SenseLCD( pHWDE , pVBInfo ) )
-                bConnectStatus |= LCDSense ;
-        }
-
-        XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~( AVIDEOSense | SVIDEOSense | LCDSense | Monitor2Sense | Monitor1Sense ) , bConnectStatus ) ;
-
-        XGINew_SetReg1( pVBInfo->Part4Port , 0x0D , pre_Part4_D ) ;
-        XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , pre_Part2_0 ) ;
-        XGINew_SetReg1( pVBInfo->P3c4 , 0x1E , pre_SR1E ) ;
-
-        if ( XGI_Is301C( pVBInfo ) )   /* 301C only */
-        {
-            tempax = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
-            if ( tempax & 0x20 )
-            {
-                /* Reset VBPro */
-                for( tempcx = 2 ; tempcx > 0 ; tempcx-- )
-                {
-                    tempax ^= 0x20 ;
-                    XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , tempax ) ;
-                }
-            }
-        }
-        /* End of dynamic sense VB */
-    }
-    else
-    {
-        XGI_SenseCRT1(pVBInfo) ;
-        XGI_GetSenseStatus( HwDeviceExtension, pVBInfo ) ;     /* sense CRT2 */
-        bConnectStatus = XGINew_GetReg1( pVBInfo->P3d4 , 0x32 ) ;
-    }
-    temp = pushax & 0x00FF ;           /* 0512 Fix Dysense hanged */
-    XGINew_SetReg1( pVBInfo->P3d4 , 0x17 , temp ) ;
-    if ( bConnectStatus )
-    {
-        *ujConnectStatus = bConnectStatus ;
-        return( 1 ) ;
-    }
-    else
-        return( 0 ) ;
-}
-
-#endif /* WIN2000 */
 
 /* --------------------------------------------------------------------- */
 /* Function : XGISetDPMS */
@@ -454,13 +135,14 @@ BOOLEAN XGI_DySense( PHW_DEVICE_EXTENSION pHWDE , PUCHAR ujConnectStatus)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-VOID XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE )
+void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE,
+               unsigned long VESA_POWER_STATE)
 {
-    USHORT ModeNo, ModeIdIndex ;
-    UCHAR  temp ;
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
-    pVBInfo->BaseAddr = (ULONG)pXGIHWDE->pjIOAddress ;
+    unsigned short ModeNo, ModeIdIndex;
+    unsigned char temp;
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
+    pVBInfo->BaseAddr = (unsigned long)pXGIHWDE->pjIOAddress ;
     pVBInfo->ROMAddr  = pXGIHWDE->pjVirtualRomBase ;
 
 
@@ -527,18 +209,18 @@ VOID XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE )
     }
 
     if ( VESA_POWER_STATE == 0x00000400 )
-      XGINew_SetReg1( pVBInfo->Part4Port , 0x31 , ( UCHAR )( XGINew_GetReg1( pVBInfo->Part4Port , 0x31 ) & 0xFE ) ) ;
+           XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char)(XGINew_GetReg1(pVBInfo->Part4Port, 0x31) & 0xFE));
     else
-      XGINew_SetReg1( pVBInfo->Part4Port , 0x31 , ( UCHAR )( XGINew_GetReg1( pVBInfo->Part4Port , 0x31 ) | 0x01 ) ) ;
+           XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char)(XGINew_GetReg1(pVBInfo->Part4Port, 0x31) | 0x01));
 
-    temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x1f ) ;
+    temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x1f);
     temp &= 0x3f ;
     switch ( VESA_POWER_STATE )
     {
         case 0x00000000: /* on */
             if ( ( pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) )
             {
-                XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0x00 ) ) ;
+               XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0x00));
                 XGI_EnableBridge( pXGIHWDE, pVBInfo ) ;
             }
             else
@@ -596,7 +278,7 @@ VOID XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE )
                 XGI_DisplayOff( pXGIHWDE, pVBInfo );
             }
 
-            XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0x40 ) ) ;
+           XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0x40));
             break ;
         case 0x00000200: /* suspend */
             if ( pXGIHWDE->jChipType == XG21 )
@@ -609,12 +291,12 @@ VOID XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE )
                 XGI_DisplayOff( pXGIHWDE, pVBInfo );
                 XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
             }
-            XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0x80 ) ) ;
+           XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0x80));
             break ;
         case 0x00000400: /* off */
             if ( (pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) )
             {
-                XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0xc0 ) ) ;
+               XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0xc0));
                 XGI_DisableBridge( pXGIHWDE, pVBInfo ) ;
             }
             else
@@ -677,12 +359,12 @@ VOID XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetSenseStatus( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempax = 0 , tempbx , tempcx , temp ,
+    unsigned short tempax = 0 , tempbx , tempcx , temp ,
            P2reg0 = 0 , SenseModeNo = 0 , OutputSelect = *pVBInfo->pOutputSelect ,
            ModeIdIndex , i ;
-    pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
+    pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
 
     if ( pVBInfo->IF_DEF_LVDS == 1 )
     {
@@ -876,10 +558,11 @@ void XGI_GetSenseStatus( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGINew_SenseLCD( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
+unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension,
+                              struct vb_device_info *pVBInfo)
 {
-    /* USHORT SoftSetting ; */
-    USHORT temp ;
+    /* unsigned short SoftSetting ; */
+    unsigned short temp ;
 
     if ( ( HwDeviceExtension->jChipType >= XG20 ) || ( HwDeviceExtension->jChipType >= XG40 ) )
         temp = 0 ;
@@ -899,9 +582,9 @@ USHORT XGINew_SenseLCD( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO p
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGINew_GetLCDDDCInfo( PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo)
+unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT temp ;
+    unsigned short temp ;
 
     /* add lcd sense */
     if ( HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN )
@@ -910,7 +593,7 @@ BOOLEAN XGINew_GetLCDDDCInfo( PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_I
     }
     else
     {
-        temp = ( USHORT )HwDeviceExtension->ulCRT2LCDType ;
+           temp = (unsigned short)HwDeviceExtension->ulCRT2LCDType ;
         switch( HwDeviceExtension->ulCRT2LCDType )
         {
             case LCD_INVALID:
@@ -952,26 +635,27 @@ BOOLEAN XGINew_GetLCDDDCInfo( PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_I
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGINew_GetPanelID(PVB_DEVICE_INFO pVBInfo )
+unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo)
 {
-    USHORT PanelTypeTable[ 16 ] = { SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType00 ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01 ,
-                                    SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType02 ,
-                                    SyncNN | PanelRGB18Bit | Panel640x480  | _PanelType03 ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04 ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05 ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06 ,
-                                    SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07 ,
-                                    SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType08 ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09 ,
-                                    SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType0A ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C ,
-                                    SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E ,
-                                    SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F } ;
-    USHORT tempax , tempbx , temp ;
-    /* USHORT return_flag ; */
+       unsigned short PanelTypeTable[16] = {
+               SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType00,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01,
+               SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType02,
+               SyncNN | PanelRGB18Bit | Panel640x480  | _PanelType03,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06,
+               SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07,
+               SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType08,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09,
+               SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType0A,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C,
+               SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E,
+               SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F };
+       unsigned short tempax , tempbx, temp;
+    /* unsigned short return_flag ; */
 
     tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ;
     tempbx = tempax & 0x1E ;
@@ -1024,9 +708,9 @@ BOOLEAN XGINew_GetPanelID(PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGINew_BridgeIsEnable( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
+unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT flag ;
+    unsigned short flag ;
 
     if ( XGI_BridgeIsOn( pVBInfo ) == 0 )
     {
@@ -1051,9 +735,9 @@ BOOLEAN XGINew_BridgeIsEnable( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE
 /* Output : */
 /* Description : */
 /* ------------------------------------------------------ */
-BOOLEAN XGINew_SenseHiTV( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
+unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx , tempcx , temp , i , tempch;
+    unsigned short tempbx , tempcx , temp , i , tempch;
 
     tempbx = *pVBInfo->pYCSenseData2 ;
 
@@ -1132,14 +816,14 @@ BOOLEAN XGINew_SenseHiTV( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INF
 ;                   DX: PAnel V. resolution
 ;-----------------------------------------------------------------------------
 */
-void XGI_XG21Fun14Sub70( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
+void XGI_XG21Fun14Sub70(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 {
 
-    USHORT ModeIdIndex;
-    USHORT ModeNo;
+    unsigned short ModeIdIndex;
+    unsigned short ModeNo;
 
-    USHORT EModeCount;
-    USHORT lvdstableindex;
+    unsigned short EModeCount;
+    unsigned short lvdstableindex;
 
     lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
     pBiosArguments->h.bl = 0x81;
@@ -1153,7 +837,7 @@ void XGI_XG21Fun14Sub70( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
         ModeNo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID;
         if ( pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID == 0xFF )
         {
-            pBiosArguments->h.bh = (UCHAR) EModeCount;
+           pBiosArguments->h.bh = (unsigned char) EModeCount;
             return;
         }
         if ( !XGI_XG21CheckLVDSMode( ModeNo , ModeIdIndex, pVBInfo) )
@@ -1175,13 +859,13 @@ void XGI_XG21Fun14Sub70( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
 ;
 ;-----------------------------------------------------------------------------
 */
-void XGI_XG21Fun14Sub71( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
+void XGI_XG21Fun14Sub71(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 {
 
-    USHORT EModeCount;
-    USHORT ModeIdIndex,resindex;
-    USHORT ModeNo;
-    USHORT EModeIndex = pBiosArguments->h.bh;
+    unsigned short EModeCount;
+    unsigned short ModeIdIndex, resindex;
+    unsigned short ModeNo;
+    unsigned short EModeIndex = pBiosArguments->h.bh;
 
     EModeCount = 0;
     for( ModeIdIndex = 0 ; ;  ModeIdIndex ++ )
@@ -1199,7 +883,7 @@ void XGI_XG21Fun14Sub71( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
         if (EModeCount == EModeIndex)
         {
             resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
-            pBiosArguments->h.bl = (UCHAR) ModeNo;
+           pBiosArguments->h.bl = (unsigned char) ModeNo;
             pBiosArguments->x.cx = pVBInfo->ModeResInfo[ resindex ].HTotal ;                     /* xres->ax */
             pBiosArguments->x.dx = pVBInfo->ModeResInfo[ resindex ].VTotal ;                     /* yres->bx */
             pBiosArguments->x.ax = 0x0014;
@@ -1221,10 +905,10 @@ void XGI_XG21Fun14Sub71( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
 ;
 ;-----------------------------------------------------------------------------
 */
-void XGI_XG21Fun14Sub72( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
+void XGI_XG21Fun14Sub72(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 {
-    USHORT ModeIdIndex,resindex;
-    USHORT ModeNo;
+    unsigned short ModeIdIndex, resindex;
+    unsigned short ModeNo;
 
 
     ModeNo = pBiosArguments->h.bl ;
@@ -1280,11 +964,11 @@ void XGI_XG21Fun14Sub72( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
 ;                       BX[6]: *Value1 D[6] Panel H. Polarity
 ;-----------------------------------------------------------------------------
 */
-void XGI_XG21Fun14Sub73( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
+void XGI_XG21Fun14Sub73(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 {
-    UCHAR Select;
+    unsigned char Select;
 
-    USHORT lvdstableindex;
+    unsigned short lvdstableindex;
 
     lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
     Select = pBiosArguments->h.bl;
@@ -1314,10 +998,10 @@ void XGI_XG21Fun14Sub73( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
 }
 
 
-void XGI_XG21Fun14( PXGI_HW_DEVICE_INFO pXGIHWDE, PX86_REGS pBiosArguments)
+void XGI_XG21Fun14(struct xgi_hw_device_info *pXGIHWDE, PX86_REGS pBiosArguments)
 {
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
 
     pVBInfo->IF_DEF_LVDS = 0 ;
     pVBInfo->IF_DEF_CH7005 = 0 ;
index 9a72f5ecb7133bbbc2a500fd2b703e3983013e8f..5cc4d12c22540894d7c92390c732572c0dcad963 100644 (file)
@@ -2,15 +2,17 @@
 #define  _VBEXT_
 
 struct DWORDREGS {
-    ULONG    Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp;
+    unsigned long    Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp;
 };
 
 struct WORDREGS {
-    USHORT    ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si, hi_si, di ,hi_di, bp, hi_bp;
+    unsigned short ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si,
+           hi_si, di, hi_di, bp, hi_bp;
 };
 
 struct BYTEREGS {
-    UCHAR   al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch, hi_cl, hi_ch, dl, dh, hi_dl, hi_dh;
+     unsigned char al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch,
+            hi_cl, hi_ch, dl, dh, hi_dl, hi_dh;
 };
 
 typedef union   _X86_REGS    {
@@ -19,14 +21,14 @@ typedef union   _X86_REGS    {
     struct  BYTEREGS h;
 } X86_REGS, *PX86_REGS;
 
-extern   void     XGI_XG21Fun14( PXGI_HW_DEVICE_INFO pXGIHWDE, PX86_REGS pBiosArguments);
-extern   void     XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE ) ;
-extern   void     XGI_GetSenseStatus( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo );
-extern   void     XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
-extern   void    ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
-extern   USHORT   XGINew_SenseLCD(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo);
-#ifdef WIN2000
-extern   BOOLEAN  XGI_DySense( PHW_DEVICE_EXTENSION pHWDE , PUCHAR ujConnectStatus );
-#endif /* WIN2000 */
+extern   void     XGI_XG21Fun14(struct xgi_hw_device_info *pXGIHWDE, PX86_REGS pBiosArguments);
+extern void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE,
+                      unsigned long VESA_POWER_STATE);
+extern   void     XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+extern   void     XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
+extern void ReadVBIOSTablData(unsigned char ChipType,
+                             struct vb_device_info *pVBInfo);
+extern unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *,
+                                     struct vb_device_info *pVBInfo);
 
 #endif
index b85ca9ba80769d6902281f965af9b99cfd81ece4..e02722d05f680e481c9ee7bb83be3dac74fb5b89 100644 (file)
@@ -1,29 +1,9 @@
-#include "osdef.h"
 #include "vgatypes.h"
 
-
-#ifdef LINUX_KERNEL
 #include <linux/version.h>
 #include <linux/types.h>
 #include <linux/delay.h> /* udelay */
 #include "XGIfb.h"
-/*#if LINUX_VERSxION_CODE >= KERNEL_VERSION(2,5,0)
-#include <video/XGIfb.h>
-#else
-#include <linux/XGIfb.h>
-#endif */
-#endif
-
-#ifdef WIN2000
-#include <dderror.h>
-#include <devioctl.h>
-#include <miniport.h>
-#include <ntddvdeo.h>
-#include <video.h>
-#include "xgiv.h"
-#include "dd_i2c.h"
-#include "tools.h"
-#endif
 
 #include "vb_def.h"
 #include "vb_struct.h"
 #include "vb_init.h"
 #include "vb_ext.h"
 
-#ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86PciInfo.h"
-#include "xgi.h"
-#include "xgi_regs.h"
-#endif
 
-#ifdef LINUX_KERNEL
 #include <asm/io.h>
-#include <linux/types.h>
-#endif
 
 
 
 
-UCHAR    XGINew_ChannelAB,XGINew_DataBusWidth;
-
-USHORT XGINew_DRAMType[17][5]={{0x0C,0x0A,0x02,0x40,0x39},{0x0D,0x0A,0x01,0x40,0x48},
-                     {0x0C,0x09,0x02,0x20,0x35},{0x0D,0x09,0x01,0x20,0x44},
-                     {0x0C,0x08,0x02,0x10,0x31},{0x0D,0x08,0x01,0x10,0x40},
-                     {0x0C,0x0A,0x01,0x20,0x34},{0x0C,0x09,0x01,0x08,0x32},
-                     {0x0B,0x08,0x02,0x08,0x21},{0x0C,0x08,0x01,0x08,0x30},
-                     {0x0A,0x08,0x02,0x04,0x11},{0x0B,0x0A,0x01,0x10,0x28},
-                     {0x09,0x08,0x02,0x02,0x01},{0x0B,0x09,0x01,0x08,0x24},
-                     {0x0B,0x08,0x01,0x04,0x20},{0x0A,0x08,0x01,0x02,0x10},
-                     {0x09,0x08,0x01,0x01,0x00}};
-
-USHORT XGINew_SDRDRAM_TYPE[13][5]=
-{
-{ 2,12, 9,64,0x35},
-{ 1,13, 9,64,0x44},
-{ 2,12, 8,32,0x31},
-{ 2,11, 9,32,0x25},
-{ 1,12, 9,32,0x34},
-{ 1,13, 8,32,0x40},
-{ 2,11, 8,16,0x21},
-{ 1,12, 8,16,0x30},
-{ 1,11, 9,16,0x24},
-{ 1,11, 8, 8,0x20},
-{ 2, 9, 8, 4,0x01},
-{ 1,10, 8, 4,0x10},
-{ 1, 9, 8, 2,0x00}
-};
-
-USHORT XGINew_DDRDRAM_TYPE[4][5]=
-{
-{ 2,12, 9,64,0x35},
-{ 2,12, 8,32,0x31},
-{ 2,11, 8,16,0x21},
-{ 2, 9, 8, 4,0x01}
-};
-USHORT XGINew_DDRDRAM_TYPE340[4][5]=
-{
-{ 2,13, 9,64,0x45},
-{ 2,12, 9,32,0x35},
-{ 2,12, 8,16,0x31},
-{ 2,11, 8, 8,0x21}
-};
-USHORT XGINew_DDRDRAM_TYPE20[12][5]=
-{
-{ 2,14,11,128,0x5D},
-{ 2,14,10,64,0x59},
-{ 2,13,11,64,0x4D},
-{ 2,14, 9,32,0x55},
-{ 2,13,10,32,0x49},
-{ 2,12,11,32,0x3D},
-{ 2,14, 8,16,0x51},
-{ 2,13, 9,16,0x45},
-{ 2,12,10,16,0x39},
-{ 2,13, 8, 8,0x41},
-{ 2,12, 9, 8,0x35},
-{ 2,12, 8, 4,0x31}
-};
-
-void     XGINew_SetDRAMSize_340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-void     XGINew_SetDRAMSize_310(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-void     XGINew_SetMemoryClock(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-void     XGINew_SetDRAMModeRegister(PVB_DEVICE_INFO );
-void     XGINew_SetDRAMModeRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension );
-void    XGINew_SetDRAMDefaultRegister340(PXGI_HW_DEVICE_INFO HwDeviceExtension, ULONG, PVB_DEVICE_INFO );
-UCHAR    XGINew_GetXG20DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGIInitNew( PXGI_HW_DEVICE_INFO HwDeviceExtension) ;
-
-int      XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
-void     XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO ,PVB_DEVICE_INFO) ;
-void     XGINew_CheckBusWidth_310( PVB_DEVICE_INFO) ;
-int      XGINew_SDRSizing(PVB_DEVICE_INFO);
-int      XGINew_DDRSizing( PVB_DEVICE_INFO );
-void     XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+unsigned char XGINew_ChannelAB, XGINew_DataBusWidth;
+
+unsigned short XGINew_DRAMType[17][5] = {
+       {0x0C, 0x0A, 0x02, 0x40, 0x39}, {0x0D, 0x0A, 0x01, 0x40, 0x48},
+       {0x0C, 0x09, 0x02, 0x20, 0x35}, {0x0D, 0x09, 0x01, 0x20, 0x44},
+       {0x0C, 0x08, 0x02, 0x10, 0x31}, {0x0D, 0x08, 0x01, 0x10, 0x40},
+       {0x0C, 0x0A, 0x01, 0x20, 0x34}, {0x0C, 0x09, 0x01, 0x08, 0x32},
+       {0x0B, 0x08, 0x02, 0x08, 0x21}, {0x0C, 0x08, 0x01, 0x08, 0x30},
+       {0x0A, 0x08, 0x02, 0x04, 0x11}, {0x0B, 0x0A, 0x01, 0x10, 0x28},
+       {0x09, 0x08, 0x02, 0x02, 0x01}, {0x0B, 0x09, 0x01, 0x08, 0x24},
+       {0x0B, 0x08, 0x01, 0x04, 0x20}, {0x0A, 0x08, 0x01, 0x02, 0x10},
+       {0x09, 0x08, 0x01, 0x01, 0x00} };
+
+unsigned short XGINew_SDRDRAM_TYPE[13][5] = {
+       { 2, 12, 9, 64, 0x35},
+       { 1, 13, 9, 64, 0x44},
+       { 2, 12, 8, 32, 0x31},
+       { 2, 11, 9, 32, 0x25},
+       { 1, 12, 9, 32, 0x34},
+       { 1, 13, 8, 32, 0x40},
+       { 2, 11, 8, 16, 0x21},
+       { 1, 12, 8, 16, 0x30},
+       { 1, 11, 9, 16, 0x24},
+       { 1, 11, 8,  8, 0x20},
+       { 2,  9, 8,  4, 0x01},
+       { 1, 10, 8,  4, 0x10},
+       { 1,  9, 8,  2, 0x00} };
+
+unsigned short XGINew_DDRDRAM_TYPE[4][5] = {
+       { 2, 12, 9, 64, 0x35},
+       { 2, 12, 8, 32, 0x31},
+       { 2, 11, 8, 16, 0x21},
+       { 2,  9, 8,  4, 0x01} };
+
+unsigned short XGINew_DDRDRAM_TYPE340[4][5] = {
+       { 2, 13, 9, 64, 0x45},
+       { 2, 12, 9, 32, 0x35},
+       { 2, 12, 8, 16, 0x31},
+       { 2, 11, 8,  8, 0x21} };
+
+unsigned short XGINew_DDRDRAM_TYPE20[12][5] = {
+       { 2, 14, 11, 128, 0x5D},
+       { 2, 14, 10, 64, 0x59},
+       { 2, 13, 11, 64, 0x4D},
+       { 2, 14,  9, 32, 0x55},
+       { 2, 13, 10, 32, 0x49},
+       { 2, 12, 11, 32, 0x3D},
+       { 2, 14,  8, 16, 0x51},
+       { 2, 13,  9, 16, 0x45},
+       { 2, 12, 10, 16, 0x39},
+       { 2, 13,  8,  8, 0x41},
+       { 2, 12,  9,  8, 0x35},
+       { 2, 12,  8,  4, 0x31} };
+
+void     XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_info *);
+void     XGINew_SetDRAMSize_310(struct xgi_hw_device_info *, struct vb_device_info *);
+void     XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+void     XGINew_SetDRAMModeRegister(struct vb_device_info *);
+void     XGINew_SetDRAMModeRegister340(struct xgi_hw_device_info *HwDeviceExtension);
+void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension,
+                                     unsigned long, struct vb_device_info *);
+unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
+                                    struct vb_device_info *pVBInfo);
+unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension);
+
+int      XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *);
+void     XGINew_DisableRefresh(struct xgi_hw_device_info *, struct vb_device_info *) ;
+void     XGINew_CheckBusWidth_310(struct vb_device_info *) ;
+int      XGINew_SDRSizing(struct vb_device_info *);
+int      XGINew_DDRSizing(struct vb_device_info *);
+void     XGINew_EnableRefresh(struct xgi_hw_device_info *, struct vb_device_info *);
 int      XGINew_RAMType;                  /*int      ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
-ULONG   UNIROM;                          /* UNIROM */
-BOOLEAN  ChkLFB( PVB_DEVICE_INFO );
-void     XGINew_Delay15us(ULONG);
-void     SetPowerConsume (PXGI_HW_DEVICE_INFO HwDeviceExtension,ULONG XGI_P3d4Port);
-void    ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
-void    XGINew_DDR1x_MRS_XG20( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo);
-void     XGINew_SetDRAMModeRegister_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension );
-void     XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension );
-void    XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
-void     XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
-void     XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
-UCHAR    GetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
-void     XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
-UCHAR    GetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
-
-#ifdef WIN2000
-/* [Billy] 2007/05/20 For CH7007 */
-extern  UCHAR CH7007TVReg_UNTSC[][8],CH7007TVReg_ONTSC[][8],CH7007TVReg_UPAL[][8],CH7007TVReg_OPAL[][8];
-extern  UCHAR XGI7007_CHTVVCLKUNTSC[],XGI7007_CHTVVCLKONTSC[],XGI7007_CHTVVCLKUPAL[],XGI7007_CHTVVCLKOPAL[];
-#endif
-
-#ifdef LINUX_KERNEL
-void DelayUS(ULONG MicroSeconds)
+unsigned long   UNIROM;                          /* UNIROM */
+unsigned char  ChkLFB(struct vb_device_info *);
+void     XGINew_Delay15us(unsigned long);
+void     SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension,
+                        unsigned long XGI_P3d4Port);
+void     ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo);
+void     XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo);
+void     XGINew_SetDRAMModeRegister_XG20(struct xgi_hw_device_info *HwDeviceExtension);
+void     XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension);
+void     XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
+void     XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
+void     XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
+unsigned char    GetXG21FPBits(struct vb_device_info *pVBInfo);
+void     XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
+unsigned char    GetXG27FPBits(struct vb_device_info *pVBInfo);
+
+void DelayUS(unsigned long MicroSeconds)
 {
        udelay(MicroSeconds);
 }
-#endif
+
 
 /* --------------------------------------------------------------------- */
 /* Function : XGIInitNew */
@@ -156,46 +118,44 @@ void DelayUS(ULONG MicroSeconds)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGIInitNew( PXGI_HW_DEVICE_INFO HwDeviceExtension )
+unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension)
 {
 
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
-    UCHAR   i , temp = 0 , temp1 ;
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
+    unsigned char   i, temp = 0, temp1 ;
      //       VBIOSVersion[ 5 ] ;
-    PUCHAR  volatile pVideoMemory;
+    volatile unsigned char *pVideoMemory;
 
-    /* ULONG j, k ; */
+    /* unsigned long j, k ; */
 
-    PXGI_DSReg pSR ;
+    struct XGI_DSReg *pSR ;
 
-    ULONG Temp ;
+    unsigned long Temp ;
 
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
 
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
 
-    pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
+    pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
 
-    pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr;
+    pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
 
 
 //    Newdebugcode( 0x99 ) ;
 
 
    /* if ( pVBInfo->ROMAddr == 0 ) */
-   /* return( FALSE ) ; */
+   /* return( 0 ) ; */
 
-    if ( pVBInfo->FBAddr == 0 )
-{
+    if (pVBInfo->FBAddr == 0) {
        printk("\n pVBInfo->FBAddr == 0 ");
-       return( FALSE ) ;
-}
+       return 0;
+    }
 printk("1");
-    if ( pVBInfo->BaseAddr == 0 )
-{
-       printk("\npVBInfo->BaseAddr == 0 ");
-        return( FALSE ) ;
+if (pVBInfo->BaseAddr == 0) {
+       printk("\npVBInfo->BaseAddr == 0 ");
+       return 0;
 }
 printk("2");
 
@@ -205,12 +165,9 @@ printk("2");
 printk("3");
 
 if ( !HwDeviceExtension->bIntegratedMMEnabled )
-{
-        return( FALSE ) ;      /* alan */
-}
-printk("4");
+       return 0;       /* alan */
 
-//    XGI_MemoryCopy( VBIOSVersion , HwDeviceExtension->szVBIOSVer , 4 ) ;
+printk("4");
 
  //   VBIOSVersion[ 4 ] = 0x0 ;
 
@@ -407,8 +364,8 @@ printk("15");
     XGI_UnLockCRT2( HwDeviceExtension, pVBInfo) ;
     XGINew_SetRegANDOR( pVBInfo->Part0Port , 0x3F , 0xEF , 0x00 ) ;    /* alan, disable VideoCapture */
     XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , 0x00 ) ;
-    temp1 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x7B ) ;          /* chk if BCLK>=100MHz */
-    temp = ( UCHAR )( ( temp1 >> 4 ) & 0x0F ) ;
+    temp1 = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x7B);        /* chk if BCLK>=100MHz */
+    temp = (unsigned char)((temp1 >> 4) & 0x0F);
 
 
         XGINew_SetReg1( pVBInfo->Part1Port , 0x02 , ( *pVBInfo->pCRT2Data_1_2 ) ) ;
@@ -460,15 +417,14 @@ printk("18");
         XGINew_SetReg1( pVBInfo->P3d4 , 0x83 , 0x00 ) ;
 printk("181");
 
-    if ( HwDeviceExtension->bSkipSense == FALSE )
-    {
-printk("182");
+if (HwDeviceExtension->bSkipSense == 0) {
+       printk("182");
 
         XGI_SenseCRT1(pVBInfo) ;
 
-printk("183");
+       printk("183");
         /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
-pVBInfo->IF_DEF_CH7007 = 0;
+       pVBInfo->IF_DEF_CH7007 = 0;
         if ( ( HwDeviceExtension->jChipType == XG21 ) && (pVBInfo->IF_DEF_CH7007) )
         {
 printk("184");
@@ -504,8 +460,7 @@ printk("19");
 
         XGINew_SetDRAMDefaultRegister340( HwDeviceExtension ,  pVBInfo->P3d4,  pVBInfo ) ;
 
-        if ( HwDeviceExtension->bSkipDramSizing == TRUE )
-        {
+       if (HwDeviceExtension->bSkipDramSizing == 1) {
             pSR = HwDeviceExtension->pSR ;
             if ( pSR!=NULL )
             {
@@ -519,15 +474,6 @@ printk("19");
         }      /* SkipDramSizing */
         else
         {
-#if 0
-           if ( HwDeviceExtension->jChipType == XG20 )
-            {
-               XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , pVBInfo->SR15[0][XGINew_RAMType] ) ;
-                XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , pVBInfo->SR15[1][XGINew_RAMType] ) ;
-                XGINew_SetReg1( pVBInfo->P3c4 , 0x20 , 0x20 ) ;
-            }
-            else
-#endif
 {
 printk("20");
 
@@ -544,7 +490,7 @@ printk("22");
     /* SetDefExt2Regs begin */
 /*
     AGP = 1 ;
-    temp =( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x3A ) ;
+    temp =(unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x3A) ;
     temp &= 0x30 ;
     if ( temp == 0x30 )
         AGP = 0 ;
@@ -563,7 +509,7 @@ printk("22");
 //    Temp = ( InPortLong( 0xcfc ) & 0xFFFF ) ;
 //    if ( Temp == 0x1039 )
 //    {
-        XGINew_SetReg1( pVBInfo->P3c4 , 0x22 , ( UCHAR )( ( *pVBInfo->pSR22 ) & 0xFE ) ) ;
+       XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char)((*pVBInfo->pSR22) & 0xFE));
 //    }
 //    else
 //    {
@@ -585,7 +531,7 @@ XGINew_SetReg1( pVBInfo->P3d4 , 0x8c , 0x87);
 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x31);
 printk("25");
 
-    return( TRUE ) ;
+return 1;
 } /* end of init */
 
 
@@ -600,9 +546,10 @@ printk("25");
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGINew_GetXG20DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
+                                    struct vb_device_info *pVBInfo)
 {
-    UCHAR data, temp ;
+    unsigned char data, temp;
 
     if ( HwDeviceExtension->jChipType < XG20 )
     {
@@ -670,9 +617,9 @@ UCHAR XGINew_GetXG20DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGINew_Get310DRAMType(PVB_DEVICE_INFO pVBInfo)
+unsigned char XGINew_Get310DRAMType(struct vb_device_info *pVBInfo)
 {
-    UCHAR data ;
+    unsigned char data ;
 
   /* index = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ; */
   /* index &= 07 ; */
@@ -694,7 +641,7 @@ UCHAR XGINew_Get310DRAMType(PVB_DEVICE_INFO pVBInfo)
 /* Description : */
 /* --------------------------------------------------------------------- */
 /*
-void XGINew_Delay15us(ULONG ulMicrsoSec)
+void XGINew_Delay15us(unsigned long ulMicrsoSec)
 {
 }
 */
@@ -706,9 +653,9 @@ void XGINew_Delay15us(ULONG ulMicrsoSec)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SDR_MRS(  PVB_DEVICE_INFO pVBInfo )
+void XGINew_SDR_MRS(struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
+    unsigned short data ;
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ;
     data &= 0x3F ;          /* SR16 D7=0,D6=0 */
@@ -726,7 +673,7 @@ void XGINew_SDR_MRS(  PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR1x_MRS_340( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
 {
     XGINew_SetReg1( P3c4 , 0x18 , 0x01 ) ;
     XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
@@ -764,7 +711,7 @@ void XGINew_DDR1x_MRS_340( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR2x_MRS_340( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR2x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
 {
     XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ;
     XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
@@ -793,9 +740,10 @@ void XGINew_DDR2x_MRS_340( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDRII_Bootup_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDRII_Bootup_XG27(struct xgi_hw_device_info *HwDeviceExtension,
+                             unsigned long P3c4, struct vb_device_info *pVBInfo)
 {
-    ULONG P3d4 = P3c4 + 0x10 ;
+    unsigned long P3d4 = P3c4 + 0x10 ;
     XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
     XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
 
@@ -871,9 +819,10 @@ void XGINew_DDRII_Bootup_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG P3
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR2_MRS_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
+                         unsigned long P3c4, struct vb_device_info *pVBInfo)
 {
-    ULONG P3d4 = P3c4 + 0x10 ;
+    unsigned long P3d4 = P3c4 + 0x10 ;
 
     XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
     XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
@@ -923,9 +872,10 @@ void XGINew_DDR2_MRS_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG P3c4 ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR2_MRS_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR2_MRS_XG27(struct xgi_hw_device_info *HwDeviceExtension,
+                         unsigned long P3c4, struct vb_device_info *pVBInfo)
 {
-    ULONG P3d4 = P3c4 + 0x10 ;
+    unsigned long P3d4 = P3c4 + 0x10 ;
 
      XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
      XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
@@ -1001,9 +951,10 @@ void XGINew_DDR2_MRS_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG P3c4 ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR1x_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG Port , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR1x_DefaultRegister(struct xgi_hw_device_info *HwDeviceExtension,
+                                 unsigned long Port, struct vb_device_info *pVBInfo)
 {
-    ULONG P3d4 = Port ,
+    unsigned long P3d4 = Port ,
            P3c4 = Port - 0x10 ;
 
     if ( HwDeviceExtension->jChipType >= XG20 )
@@ -1061,9 +1012,10 @@ void XGINew_DDR1x_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULON
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR2x_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG Port ,PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR2x_DefaultRegister(struct xgi_hw_device_info *HwDeviceExtension,
+                                 unsigned long Port, struct vb_device_info *pVBInfo)
 {
-    ULONG P3d4 = Port ,
+    unsigned long P3d4 = Port ,
            P3c4 = Port - 0x10 ;
 
     XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
@@ -1112,9 +1064,10 @@ void XGINew_DDR2x_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULON
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR2_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension, ULONG Port , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR2_DefaultRegister(struct xgi_hw_device_info *HwDeviceExtension,
+                                unsigned long Port, struct vb_device_info *pVBInfo)
 {
-    ULONG P3d4 = Port ,
+    unsigned long P3d4 = Port ,
            P3c4 = Port - 0x10 ;
 
     /* keep following setting sequence, each setting in the same reg insert idle */
@@ -1150,12 +1103,13 @@ void XGINew_DDR2_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension, ULONG P
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetDRAMDefaultRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension ,  ULONG Port , PVB_DEVICE_INFO pVBInfo)
+void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension,
+                                     unsigned long Port, struct vb_device_info *pVBInfo)
 {
-    UCHAR temp , temp1 , temp2 , temp3 ,
+    unsigned char temp, temp1, temp2, temp3 ,
           i , j , k ;
 
-    ULONG P3d4 = Port ,
+    unsigned long P3d4 = Port ,
            P3c4 = Port - 0x10 ;
 
     XGINew_SetReg1( P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
@@ -1293,11 +1247,11 @@ void XGINew_SetDRAMDefaultRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR_MRS(struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
+    unsigned short data ;
 
-    PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+    volatile unsigned char *pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
 
     /* SR16 <- 1F,DF,2F,AF */
     /* yriver modified SR16 <- 0F,DF,0F,AF */
@@ -1361,11 +1315,11 @@ void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_VerifyMclk( PXGI_HW_DEVICE_INFO  HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGINew_VerifyMclk(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    PUCHAR pVideoMemory = pVBInfo->FBAddr ;
-    UCHAR i , j ;
-    USHORT Temp , SR21 ;
+    unsigned char *pVideoMemory = pVBInfo->FBAddr ;
+    unsigned char i, j ;
+    unsigned short Temp , SR21 ;
 
     pVideoMemory[ 0 ] = 0xaa ;                 /* alan */
     pVideoMemory[ 16 ] = 0x55 ;        /* note: PCI read cache is off */
@@ -1407,9 +1361,9 @@ void XGINew_VerifyMclk( PXGI_HW_DEVICE_INFO  HwDeviceExtension , PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT  data ;
+    unsigned short  data ;
 
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
@@ -1418,7 +1372,7 @@ void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
 
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ;       /* disable read cache */
+    XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data & 0xDF));        /* disable read cache */
     XGI_DisplayOff( HwDeviceExtension, pVBInfo );
 
     /*data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1 ) ;*/
@@ -1426,8 +1380,7 @@ void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
     /*XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , data ) ;*/                        /* Turn OFF Display */
     XGINew_DDRSizing340( HwDeviceExtension, pVBInfo ) ;
     data=XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ;       /* enable read cache */
-
+    XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data | 0x20)); /* enable read cache */
 }
 
 
@@ -1437,9 +1390,9 @@ void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSize_310( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGINew_SetDRAMSize_310(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
+    unsigned short data ;
     pVBInfo->ROMAddr  = HwDeviceExtension->pjVirtualRomBase ,
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
 #ifdef XGI301
@@ -1455,7 +1408,7 @@ void XGINew_SetDRAMSize_310( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
     XGISetModeNew( HwDeviceExtension , 0x2e ) ;
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ;       /* disable read cache */
+    XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data & 0xDF));        /* disable read cache */
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1 ) ;
     data |= 0x20 ;
@@ -1464,7 +1417,7 @@ void XGINew_SetDRAMSize_310( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ;
 
 
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , ( USHORT )( data | 0x0F ) ) ;               /* assume lowest speed DRAM */
+    XGINew_SetReg1(pVBInfo->P3c4, 0x16, (unsigned short)(data | 0x0F));        /* assume lowest speed DRAM */
 
     XGINew_SetDRAMModeRegister( pVBInfo ) ;
     XGINew_DisableRefresh( HwDeviceExtension, pVBInfo ) ;
@@ -1485,11 +1438,11 @@ void XGINew_SetDRAMSize_310( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
 
 
 
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , pVBInfo->SR15[ 1 ][ XGINew_RAMType ] ) ;    /* restore SR16 */
+    XGINew_SetReg1(pVBInfo->P3c4, 0x16, pVBInfo->SR15[1][XGINew_RAMType]); /* restore SR16 */
 
     XGINew_EnableRefresh(  HwDeviceExtension, pVBInfo ) ;
     data=XGINew_GetReg1( pVBInfo->P3c4 ,0x21 ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ;       /* enable read cache */
+    XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data | 0x20));        /* enable read cache */
 }
 
 
@@ -1501,14 +1454,14 @@ void XGINew_SetDRAMSize_310( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
 /* Description : */
 /* --------------------------------------------------------------------- */
 
-void XGINew_SetDRAMModeRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension )
+void XGINew_SetDRAMModeRegister340(struct xgi_hw_device_info *HwDeviceExtension)
 {
-    UCHAR data ;
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
+    unsigned char data ;
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
-    pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
+    pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
     pVBInfo->ISXPDOS = 0 ;
 
     pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
@@ -1555,7 +1508,7 @@ void XGINew_SetDRAMModeRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetDRAMModeRegister( PVB_DEVICE_INFO pVBInfo)
+void XGINew_SetDRAMModeRegister(struct vb_device_info *pVBInfo)
 {
     if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
     {
@@ -1575,9 +1528,9 @@ void XGINew_SetDRAMModeRegister( PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DisableRefresh(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT  data ;
+    unsigned short  data ;
 
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1B ) ;
@@ -1593,7 +1546,7 @@ void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_I
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGINew_EnableRefresh(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
 
     XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ;    /* SR1B */
@@ -1608,9 +1561,11 @@ void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_IN
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DisableChannelInterleaving( int index , USHORT XGINew_DDRDRAM_TYPE[][ 5 ] , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DisableChannelInterleaving(int index,
+                                      unsigned short XGINew_DDRDRAM_TYPE[][5],
+                                      struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
+    unsigned short data ;
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x15 ) ;
     data &= 0x1F ;
@@ -1642,9 +1597,11 @@ void XGINew_DisableChannelInterleaving( int index , USHORT XGINew_DDRDRAM_TYPE[]
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSizingType( int index , USHORT DRAMTYPE_TABLE[][ 5 ] ,PVB_DEVICE_INFO pVBInfo)
+void XGINew_SetDRAMSizingType(int index,
+                             unsigned short DRAMTYPE_TABLE[][5],
+                             struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
+    unsigned short data;
 
     data = DRAMTYPE_TABLE[ index ][ 4 ] ;
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x13 , 0x80 , data ) ;
@@ -1659,12 +1616,12 @@ void XGINew_SetDRAMSizingType( int index , USHORT DRAMTYPE_TABLE[][ 5 ] ,PVB_DEV
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_CheckBusWidth_310(  PVB_DEVICE_INFO pVBInfo)
+void XGINew_CheckBusWidth_310(struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
-    PULONG volatile pVideoMemory ;
+    unsigned short data ;
+    volatile unsigned long *pVideoMemory ;
 
-    pVideoMemory = (PULONG) pVBInfo->FBAddr;
+    pVideoMemory = (unsigned long *) pVBInfo->FBAddr;
 
     if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
     {
@@ -1690,7 +1647,7 @@ void XGINew_CheckBusWidth_310(  PVB_DEVICE_INFO pVBInfo)
             XGINew_DataBusWidth = 64 ;
             XGINew_ChannelAB = 0 ;
             data=XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
-            XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( USHORT )( data & 0xFD ) ) ;
+           XGINew_SetReg1(pVBInfo->P3c4, 0x14, (unsigned short)(data & 0xFD));
         }
 
         if ( ( pVideoMemory[ 1 ] != 0x456789ABL ) || ( pVideoMemory[ 0 ] != 0x01234567L ) )
@@ -1699,7 +1656,8 @@ void XGINew_CheckBusWidth_310(  PVB_DEVICE_INFO pVBInfo)
             XGINew_DataBusWidth = 64 ;
             XGINew_ChannelAB = 1 ;
             data=XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
-            XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( USHORT )( ( data & 0xFD ) | 0x01 ) ) ;
+           XGINew_SetReg1(pVBInfo->P3c4, 0x14,
+                          (unsigned short)((data & 0xFD) | 0x01));
         }
 
         return ;
@@ -1792,9 +1750,13 @@ void XGINew_CheckBusWidth_310(  PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_SetRank( int index , UCHAR RankNo , UCHAR XGINew_ChannelAB , USHORT DRAMTYPE_TABLE[][ 5 ] , PVB_DEVICE_INFO pVBInfo)
+int XGINew_SetRank(int index,
+                  unsigned char RankNo,
+                  unsigned char XGINew_ChannelAB,
+                  unsigned short DRAMTYPE_TABLE[][5],
+                  struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
+    unsigned short data;
     int RankSize ;
 
     if ( ( RankNo == 2 ) && ( DRAMTYPE_TABLE[ index ][ 0 ] == 2 ) )
@@ -1829,9 +1791,13 @@ int XGINew_SetRank( int index , UCHAR RankNo , UCHAR XGINew_ChannelAB , USHORT D
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_SetDDRChannel( int index , UCHAR ChannelNo , UCHAR XGINew_ChannelAB , USHORT DRAMTYPE_TABLE[][ 5 ] , PVB_DEVICE_INFO pVBInfo)
+int XGINew_SetDDRChannel(int index,
+                        unsigned char ChannelNo,
+                        unsigned char XGINew_ChannelAB,
+                        unsigned short DRAMTYPE_TABLE[][5],
+                        struct vb_device_info *pVBInfo)
 {
-    USHORT  data ;
+    unsigned short data;
     int RankSize ;
 
     RankSize = DRAMTYPE_TABLE[index][3]/2 * XGINew_DataBusWidth/32;
@@ -1865,30 +1831,29 @@ int XGINew_SetDDRChannel( int index , UCHAR ChannelNo , UCHAR XGINew_ChannelAB ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_CheckColumn( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+int XGINew_CheckColumn(int index,
+                      unsigned short DRAMTYPE_TABLE[][5],
+                      struct vb_device_info *pVBInfo)
 {
     int i ;
-    ULONG Increment , Position ;
+    unsigned long Increment , Position ;
 
     /* Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 1 ) ; */
     Increment = 1 << ( 10 + XGINew_DataBusWidth / 64 ) ;
 
     for( i = 0 , Position = 0 ; i < 2 ; i++ )
     {
-        *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
-        Position += Increment ;
+           *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
+           Position += Increment ;
     }
 
-#ifdef WIN2000  /* chiawen for linux solution */
-    DelayUS( 100 ) ;
-#endif
 
     for( i = 0 , Position = 0 ; i < 2 ; i++ )
     {
         /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
-        if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
-            return( 0 ) ;
-        Position += Increment ;
+           if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
+                   return 0;
+           Position += Increment;
     }
     return( 1 ) ;
 }
@@ -1900,26 +1865,28 @@ int XGINew_CheckColumn( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INF
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_CheckBanks( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+int XGINew_CheckBanks(int index,
+                     unsigned short DRAMTYPE_TABLE[][5],
+                     struct vb_device_info *pVBInfo)
 {
     int i ;
-    ULONG Increment , Position ;
+    unsigned long Increment , Position ;
 
     Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 2 ) ;
 
     for( i = 0 , Position = 0 ; i < 4 ; i++ )
     {
         /* pVBInfo->FBAddr[ Position ] = Position ; */
-        *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
-        Position += Increment ;
+           *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
+           Position += Increment ;
     }
 
     for( i = 0 , Position = 0 ; i < 4 ; i++ )
     {
         /* if (pVBInfo->FBAddr[ Position ] != Position ) */
-        if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
-            return( 0 ) ;
-        Position += Increment ;
+           if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
+                   return 0;
+           Position += Increment;
     }
     return( 1 ) ;
 }
@@ -1931,10 +1898,12 @@ int XGINew_CheckBanks( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_CheckRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+int XGINew_CheckRank(int RankNo, int index,
+                    unsigned short DRAMTYPE_TABLE[][5],
+                    struct vb_device_info *pVBInfo)
 {
     int i ;
-    ULONG Increment , Position ;
+    unsigned long Increment , Position ;
 
     Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
                   DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
@@ -1942,18 +1911,18 @@ int XGINew_CheckRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB
     for( i = 0 , Position = 0 ; i < 2 ; i++ )
     {
         /* pVBInfo->FBAddr[ Position ] = Position ; */
-        /* *( ( PULONG )( pVBInfo->FBAddr ) ) = Position ; */
-        *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
-        Position += Increment ;
+        /* *( (unsigned long *)( pVBInfo->FBAddr ) ) = Position ; */
+           *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
+           Position += Increment;
     }
 
     for( i = 0 , Position = 0 ; i < 2 ; i++ )
     {
         /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
-        /* if ( ( *( PULONG )( pVBInfo->FBAddr ) ) != Position ) */
-        if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
-            return( 0 ) ;
-        Position += Increment ;
+        /* if ( ( *(unsigned long *)( pVBInfo->FBAddr ) ) != Position ) */
+           if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
+                   return 0;
+           Position += Increment;
     }
     return( 1 );
 }
@@ -1965,10 +1934,12 @@ int XGINew_CheckRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_CheckDDRRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+int XGINew_CheckDDRRank(int RankNo, int index,
+                       unsigned short DRAMTYPE_TABLE[][5],
+                       struct vb_device_info *pVBInfo)
 {
-    ULONG Increment , Position ;
-    USHORT data ;
+    unsigned long Increment , Position ;
+    unsigned short data ;
 
     Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
                        DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
@@ -1976,18 +1947,18 @@ int XGINew_CheckDDRRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ],
     Increment += Increment / 2 ;
 
     Position = 0;
-    *( ( PULONG )( pVBInfo->FBAddr + Position + 0 ) ) = 0x01234567 ;
-    *( ( PULONG )( pVBInfo->FBAddr + Position + 1 ) ) = 0x456789AB ;
-    *( ( PULONG )( pVBInfo->FBAddr + Position + 2 ) ) = 0x55555555 ;
-    *( ( PULONG )( pVBInfo->FBAddr + Position + 3 ) ) = 0x55555555 ;
-    *( ( PULONG )( pVBInfo->FBAddr + Position + 4 ) ) = 0xAAAAAAAA ;
-    *( ( PULONG )( pVBInfo->FBAddr + Position + 5 ) ) = 0xAAAAAAAA ;
-
-    if ( ( *( PULONG )( pVBInfo->FBAddr + 1 ) ) == 0x456789AB )
-        return( 1 ) ;
+    *((unsigned long *)(pVBInfo->FBAddr + Position + 0)) = 0x01234567;
+    *((unsigned long *)(pVBInfo->FBAddr + Position + 1)) = 0x456789AB;
+    *((unsigned long *)(pVBInfo->FBAddr + Position + 2)) = 0x55555555;
+    *((unsigned long *)(pVBInfo->FBAddr + Position + 3)) = 0x55555555;
+    *((unsigned long *)(pVBInfo->FBAddr + Position + 4)) = 0xAAAAAAAA;
+    *((unsigned long *)(pVBInfo->FBAddr + Position + 5)) = 0xAAAAAAAA;
 
-    if ( ( *( PULONG )( pVBInfo->FBAddr + 0 ) ) == 0x01234567 )
-        return( 0 ) ;
+    if ((*(unsigned long *)(pVBInfo->FBAddr + 1)) == 0x456789AB)
+           return 1;
+
+    if ((*(unsigned long *)(pVBInfo->FBAddr + 0)) == 0x01234567)
+           return 0;
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
     data &= 0xF3 ;
@@ -2007,7 +1978,9 @@ int XGINew_CheckDDRRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ],
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_CheckRanks( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+int XGINew_CheckRanks(int RankNo, int index,
+                     unsigned short DRAMTYPE_TABLE[][5],
+                     struct vb_device_info *pVBInfo)
 {
     int r ;
 
@@ -2033,7 +2006,9 @@ int XGINew_CheckRanks( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PV
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_CheckDDRRanks( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+int XGINew_CheckDDRRanks(int RankNo, int index,
+                        unsigned short DRAMTYPE_TABLE[][5],
+                        struct vb_device_info *pVBInfo)
 {
     int r ;
 
@@ -2059,10 +2034,10 @@ int XGINew_CheckDDRRanks( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ],
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
+int XGINew_SDRSizing(struct vb_device_info *pVBInfo)
 {
     int    i ;
-    UCHAR  j ;
+    unsigned char  j ;
 
     for( i = 0 ; i < 13 ; i++ )
     {
@@ -2070,7 +2045,8 @@ int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
 
         for( j = 2 ; j > 0 ; j-- )
         {
-            if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_SDRDRAM_TYPE , pVBInfo) )
+           if (!XGINew_SetRank(i, (unsigned char)j, XGINew_ChannelAB,
+                                XGINew_SDRDRAM_TYPE, pVBInfo))
                 continue ;
             else
             {
@@ -2089,11 +2065,13 @@ int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGINew_SetDRAMSizeReg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+unsigned short XGINew_SetDRAMSizeReg(int index,
+                                    unsigned short DRAMTYPE_TABLE[][5],
+                                    struct vb_device_info *pVBInfo)
 {
-    USHORT data = 0 , memsize = 0 ;
+    unsigned short data = 0 , memsize = 0;
     int RankSize ;
-    UCHAR ChannelNo ;
+    unsigned char ChannelNo ;
 
     RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 32 ;
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x13 ) ;
@@ -2138,11 +2116,13 @@ USHORT XGINew_SetDRAMSizeReg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVI
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGINew_SetDRAMSize20Reg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+unsigned short XGINew_SetDRAMSize20Reg(int index,
+                                      unsigned short DRAMTYPE_TABLE[][5],
+                                      struct vb_device_info *pVBInfo)
 {
-    USHORT data = 0 , memsize = 0 ;
+    unsigned short data = 0 , memsize = 0;
     int RankSize ;
-    UCHAR ChannelNo ;
+    unsigned char ChannelNo ;
 
     RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 8 ;
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x13 ) ;
@@ -2188,31 +2168,32 @@ USHORT XGINew_SetDRAMSize20Reg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DE
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_ReadWriteRest( USHORT StopAddr , USHORT StartAddr, PVB_DEVICE_INFO pVBInfo)
+int XGINew_ReadWriteRest(unsigned short StopAddr, unsigned short StartAddr,
+                        struct vb_device_info *pVBInfo)
 {
     int i ;
-    ULONG Position = 0 ;
+    unsigned long Position = 0 ;
 
-   *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+    *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
 
     for( i = StartAddr ; i <= StopAddr ; i++ )
     {
         Position = 1 << i ;
-        *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+       *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
     }
 
     DelayUS( 500 ) ;   /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
 
     Position = 0 ;
 
-   if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
-        return( 0 ) ;
+   if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
+          return 0;
 
     for( i = StartAddr ; i <= StopAddr ; i++ )
     {
         Position = 1 << i ;
-        if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
-            return( 0 ) ;
+       if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
+               return 0;
     }
     return( 1 ) ;
 }
@@ -2224,9 +2205,9 @@ int XGINew_ReadWriteRest( USHORT StopAddr , USHORT StartAddr, PVB_DEVICE_INFO pV
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGINew_CheckFrequence( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
 {
-    UCHAR data ;
+    unsigned char data ;
 
     data = XGINew_GetReg1( pVBInfo->P3d4 , 0x97 ) ;
 
@@ -2247,9 +2228,9 @@ UCHAR XGINew_CheckFrequence( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_CheckChannel( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    UCHAR data;
+    unsigned char data;
 
     switch( HwDeviceExtension->jChipType )
     {
@@ -2528,10 +2509,10 @@ void XGINew_CheckChannel( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
     int i ;
-    USHORT memsize , addr ;
+    unsigned short memsize , addr ;
 
     XGINew_SetReg1( pVBInfo->P3c4 , 0x15 , 0x00 ) ;    /* noninterleaving */
     XGINew_SetReg1( pVBInfo->P3c4 , 0x1C , 0x00 ) ;    /* nontiling */
@@ -2548,7 +2529,7 @@ int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
             continue ;
 
         addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
-        if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
+       if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long)(1 << addr))
             continue ;
 
         if ( XGINew_ReadWriteRest( addr , 5, pVBInfo ) == 1 )
@@ -2566,7 +2547,7 @@ int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
             continue ;
 
         addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
-        if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
+       if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long)(1 << addr))
             continue ;
 
         if ( XGINew_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
@@ -2583,10 +2564,10 @@ int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
+int XGINew_DDRSizing(struct vb_device_info *pVBInfo)
 {
     int    i ;
-    UCHAR  j ;
+    unsigned char  j ;
 
     for( i = 0 ; i < 4 ; i++ )
     {
@@ -2595,7 +2576,8 @@ int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
         for( j = 2 ; j > 0 ; j-- )
         {
             XGINew_SetDDRChannel( i , j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE , pVBInfo ) ;
-            if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE, pVBInfo ) )
+           if (!XGINew_SetRank(i, (unsigned char)j, XGINew_ChannelAB,
+                               XGINew_DDRDRAM_TYPE, pVBInfo))
                 continue ;
             else
             {
@@ -2613,7 +2595,7 @@ int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
 
 
@@ -2634,9 +2616,7 @@ void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_IN
       if ( ( pVBInfo->MCLKData[ XGINew_RAMType ].SR28 == 0x1C ) && ( pVBInfo->MCLKData[ XGINew_RAMType ].SR29 == 0x01 )
         && ( ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x1C ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) )
         || ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x22 ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) ) ) )
-      {
-       XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , ( ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x32 ) & 0xFC ) | 0x02 ) ;
-      }
+             XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
     }
 }
 
@@ -2647,12 +2627,12 @@ void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_IN
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN ChkLFB( PVB_DEVICE_INFO pVBInfo )
+unsigned char ChkLFB(struct vb_device_info *pVBInfo)
 {
-    if ( LFBDRAMTrap & XGINew_GetReg1( pVBInfo->P3d4 , 0x78 ) )
-        return( TRUE ) ;
-    else
-        return( FALSE );
+       if (LFBDRAMTrap & XGINew_GetReg1(pVBInfo->P3d4 , 0x78))
+               return 1;
+       else
+               return 0;
 }
 
 
@@ -2664,17 +2644,18 @@ BOOLEAN ChkLFB( PVB_DEVICE_INFO pVBInfo )
 /* in second chip, assume CR A1 D[6]="1" in this case */
 /* output : none */
 /* --------------------------------------------------------------------- */
-void SetPowerConsume ( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG XGI_P3d4Port )
+void SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension,
+                    unsigned long XGI_P3d4Port)
 {
-    ULONG   lTemp ;
-    UCHAR   bTemp;
+    unsigned long   lTemp ;
+    unsigned char   bTemp;
 
     HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x08 , 0 , &lTemp ) ; /* Get */
     if ((lTemp&0xFF)==0)
     {
         /* set CR58 D[5]=0 D[3]=0 */
         XGINew_SetRegAND( XGI_P3d4Port , 0x58 , 0xD7 ) ;
-        bTemp = (UCHAR) XGINew_GetReg1( XGI_P3d4Port , 0xCB ) ;
+       bTemp = (unsigned char) XGINew_GetReg1(XGI_P3d4Port, 0xCB);
        if (bTemp&0x20)
        {
             if (!(bTemp&0x10))
@@ -2692,15 +2673,13 @@ void SetPowerConsume ( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG XGI_P3d4Por
 }
 
 
-
-#if defined(LINUX_XF86)||defined(LINUX_KERNEL)
-void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGINew_InitVBIOSData(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
 
-       /* ULONG ROMAddr = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
+       /* unsigned long ROMAddr = (unsigned long)HwDeviceExtension->pjVirtualRomBase; */
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
-    pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
+    pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
     pVBInfo->ISXPDOS = 0 ;
 
     pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
@@ -2736,7 +2715,6 @@ void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
        }
 
 }
-#endif /* For Linux */
 
 /* --------------------------------------------------------------------- */
 /* Function : ReadVBIOSTablData */
@@ -2744,200 +2722,11 @@ void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
+void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo)
 {
-    PUCHAR  volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
-    ULONG   i ;
-    UCHAR   j , k ;
-#if 0
-    ULONG   ii , jj ;
-    i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ;               /* UniROM */
-    if ( i != 0 )
-        UNIROM = 1 ;
-
-    ii = 0x90 ;
-    for( jj = 0x00 ; jj < 0x08 ; jj++ )
-    {
-        pVBInfo->MCLKData[ jj ].SR28 = pVideoMemory[ ii ] ;
-        pVBInfo->MCLKData[ jj ].SR29 = pVideoMemory[ ii + 1] ;
-        pVBInfo->MCLKData[ jj ].SR2A = pVideoMemory[ ii + 2] ;
-        pVBInfo->MCLKData[ jj ].CLOCK = pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
-        ii += 0x05 ;
-    }
-
-    ii = 0xB8 ;
-    for( jj = 0x00 ; jj < 0x08 ; jj++ )
-    {
-        pVBInfo->ECLKData[ jj ].SR2E = pVideoMemory[ ii ] ;
-        pVBInfo->ECLKData[ jj ].SR2F=pVideoMemory[ ii + 1 ] ;
-        pVBInfo->ECLKData[ jj ].SR30= pVideoMemory[ ii + 2 ] ;
-        pVBInfo->ECLKData[ jj ].CLOCK= pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
-        ii += 0x05 ;
-    }
-
-    /* Volari customize data area start */
-    /* if ( ChipType == XG40 ) */
-    if ( ChipType >= XG40 )
-    {
-        ii = 0xE0 ;
-        for( jj = 0x00 ; jj < 0x03 ; jj++ )
-        {
-            pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ;            /* SR13, SR14, and SR18 */
-            pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
-            pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
-            pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
-            pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
-            pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
-            pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
-            pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
-            ii += 0x08 ;
-        }
-        ii = 0x110 ;
-        jj = 0x03 ;
-        pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ;                /* SR1B */
-        pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
-        pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
-        pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
-        pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
-        pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
-        pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
-        pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
-
-        *pVBInfo->pSR07 = pVideoMemory[ 0x74 ] ;
-        *pVBInfo->pSR1F = pVideoMemory[ 0x75 ] ;
-        *pVBInfo->pSR21 = pVideoMemory[ 0x76 ] ;
-        *pVBInfo->pSR22 = pVideoMemory[ 0x77 ] ;
-        *pVBInfo->pSR23 = pVideoMemory[ 0x78 ] ;
-        *pVBInfo->pSR24 = pVideoMemory[ 0x79 ] ;
-        pVBInfo->SR25[ 0 ] = pVideoMemory[ 0x7A ] ;
-        *pVBInfo->pSR31 = pVideoMemory[ 0x7B ] ;
-        *pVBInfo->pSR32 = pVideoMemory[ 0x7C ] ;
-        *pVBInfo->pSR33 = pVideoMemory[ 0x7D ] ;
-        ii = 0xF8 ;
-
-        for( jj = 0 ; jj < 3 ; jj++ )
-        {
-            pVBInfo->CR40[ jj ][ 0 ] = pVideoMemory[ ii ] ;
-            pVBInfo->CR40[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
-            pVBInfo->CR40[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
-            pVBInfo->CR40[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
-            pVBInfo->CR40[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
-            pVBInfo->CR40[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
-            pVBInfo->CR40[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
-            pVBInfo->CR40[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
-            ii += 0x08 ;
-        }
-
-        ii = 0x118 ;
-        for( j = 3 ; j < 24 ; j++ )
-        {
-            pVBInfo->CR40[ j ][ 0 ] = pVideoMemory[ ii ] ;
-            pVBInfo->CR40[ j ][ 1 ] = pVideoMemory[ ii + 1 ] ;
-            pVBInfo->CR40[ j ][ 2 ] = pVideoMemory[ ii + 2 ] ;
-            pVBInfo->CR40[ j ][ 3 ] = pVideoMemory[ ii + 3 ] ;
-            pVBInfo->CR40[ j ][ 4 ] = pVideoMemory[ ii + 4 ] ;
-            pVBInfo->CR40[ j ][ 5 ] = pVideoMemory[ ii + 5 ] ;
-            pVBInfo->CR40[ j ][ 6 ] = pVideoMemory[ ii + 6 ] ;
-            pVBInfo->CR40[ j ][ 7 ] = pVideoMemory[ ii + 7 ] ;
-            ii += 0x08 ;
-        }
-
-        i = pVideoMemory[ 0x1C0 ] | ( pVideoMemory[ 0x1C1 ] << 8 ) ;
-
-        for( j = 0 ; j < 8 ; j++ )
-        {
-            for( k = 0 ; k < 4 ; k++ )
-                pVBInfo->CR6B[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
-        }
-
-        i = pVideoMemory[ 0x1C2 ] | ( pVideoMemory[ 0x1C3 ] << 8 ) ;
-
-        for( j = 0 ; j < 8 ; j++ )
-        {
-            for( k = 0 ; k < 4 ; k++ )
-                pVBInfo->CR6E[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
-        }
-
-        i = pVideoMemory[ 0x1C4 ] | ( pVideoMemory[ 0x1C5 ] << 8 ) ;
-        for( j = 0 ; j < 8 ; j++ )
-        {
-            for( k = 0 ; k < 32 ; k++ )
-                pVBInfo->CR6F[ j ][ k ] = pVideoMemory[ i + 32 * j + k ] ;
-        }
-
-        i = pVideoMemory[ 0x1C6 ] | ( pVideoMemory[ 0x1C7 ] << 8 ) ;
-
-        for( j = 0 ; j < 8 ; j++ )
-        {
-            for( k = 0 ; k < 2 ; k++ )
-                pVBInfo->CR89[ j ][ k ] = pVideoMemory[ i + 2 * j + k ] ;
-        }
-
-        i = pVideoMemory[ 0x1C8 ] | ( pVideoMemory[ 0x1C9 ] << 8 ) ;
-        for( j = 0 ; j < 12 ; j++ )
-            pVBInfo->AGPReg[ j ] = pVideoMemory[ i + j ] ;
-
-        i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ;
-        for( j = 0 ; j < 4 ; j++ )
-            pVBInfo->SR16[ j ] = pVideoMemory[ i + j ] ;
-
-        if ( ChipType == XG21 )
-        {
-            if (pVideoMemory[ 0x67 ] & 0x80)
-            {
-                *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
-            }
-            if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
-            {
-                *pVBInfo->pCR2E = pVideoMemory[ i + 4 ] ;
-                *pVBInfo->pCR2F = pVideoMemory[ i + 5 ] ;
-                *pVBInfo->pCR46 = pVideoMemory[ i + 6 ] ;
-                *pVBInfo->pCR47 = pVideoMemory[ i + 7 ] ;
-            }
-        }
-
-        if ( ChipType == XG27 )
-        {
-            jj = i+j;
-            for( i = 0 ; i <= 0xB ; i++,jj++ )
-              pVBInfo->pCRD0[i] = pVideoMemory[ jj ] ;
-            for( i = 0x0 ; i <= 0x1 ; i++,jj++ )
-              pVBInfo->pCRDE[i] = pVideoMemory[ jj ] ;
-
-            *pVBInfo->pSR40 = pVideoMemory[ jj ] ;
-            jj++;
-            *pVBInfo->pSR41 = pVideoMemory[ jj ] ;
-
-            if (pVideoMemory[ 0x67 ] & 0x80)
-            {
-                *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
-            }
-            if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
-            {
-                jj++;
-                *pVBInfo->pCR2E = pVideoMemory[ jj ] ;
-                *pVBInfo->pCR2F = pVideoMemory[ jj + 1 ] ;
-                *pVBInfo->pCR46 = pVideoMemory[ jj + 2 ] ;
-                *pVBInfo->pCR47 = pVideoMemory[ jj + 3 ] ;
-            }
-
-        }
-
-        *pVBInfo->pCRCF = pVideoMemory[ 0x1CA ] ;
-        *pVBInfo->pXGINew_DRAMTypeDefinition = pVideoMemory[ 0x1CB ] ;
-        *pVBInfo->pXGINew_I2CDefinition = pVideoMemory[ 0x1D1 ] ;
-        if ( ChipType >= XG20 )
-        {
-           *pVBInfo->pXGINew_CR97 = pVideoMemory[ 0x1D2 ] ;
-           if ( ChipType == XG27 )
-           {
-             *pVBInfo->pSR36 = pVideoMemory[ 0x1D3 ] ;
-             *pVBInfo->pCR8F = pVideoMemory[ 0x1D5 ] ;
-           }
-        }
-
-    }
-#endif
+       volatile unsigned char *pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
+    unsigned long   i ;
+    unsigned char   j, k ;
     /* Volari customize data area end */
 
     if ( ChipType == XG21 )
@@ -2972,7 +2761,8 @@ void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
                 i += 25;
                 j--;
                 k++;
-              } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
+             } while ((j > 0) &&
+                      (k < (sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct))));
             }
             else
             {
@@ -3003,7 +2793,7 @@ void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_DDR1x_MRS_XG20( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
+void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo)
 {
 
     XGINew_SetReg1( P3c4 , 0x18 , 0x01 ) ;
@@ -3039,13 +2829,13 @@ void XGINew_DDR1x_MRS_XG20( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetDRAMModeRegister_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension )
+void XGINew_SetDRAMModeRegister_XG20(struct xgi_hw_device_info *HwDeviceExtension)
 {
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
-    pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
+    pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
     pVBInfo->ISXPDOS = 0 ;
 
     pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
@@ -3078,13 +2868,13 @@ void XGINew_SetDRAMModeRegister_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension )
     XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
 }
 
-void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
+void XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension)
 {
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
-    pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
+    pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
     pVBInfo->ISXPDOS = 0 ;
 
     pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
@@ -3120,13 +2910,12 @@ void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
 
 }
 /*
-void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
+void XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension)
 {
-#ifndef LINUX_XF86
-    UCHAR data ;
-#endif
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
+
+    unsigned char data ;
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
     pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
     pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress ;
@@ -3168,9 +2957,9 @@ void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
 /* Output : */
 /* Description : */
 /* -------------------------------------------------------- */
-void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx=0 , temp , tempcx , CR3CData;
+    unsigned short tempbx = 0, temp, tempcx, CR3CData;
 
     temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x32 ) ;
 
@@ -3229,9 +3018,9 @@ void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
 /* Output : */
 /* Description : */
 /* -------------------------------------------------------- */
-void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
+void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
+    unsigned short temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
 
     temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x3d ) ;
     temp |= XGINew_GetReg1( pVBInfo->P3d4 , 0x3e ) << 8 ;
@@ -3326,23 +3115,13 @@ void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_
 /* Output : */
 /* Description : */
 /* -------------------------------------------------------- */
-void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    UCHAR Temp;
-    PUCHAR  volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+    unsigned char Temp;
+    volatile unsigned char *pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
 
     pVBInfo->IF_DEF_LVDS = 0 ;
 
-#ifdef WIN2000
-   pVBInfo->IF_DEF_CH7007 = 0 ;
-    if ( ( pVideoMemory[ 0x65 ] & 0x02 ) )                     /* For XG21 CH7007 */
-    {
-        /* VideoDebugPrint((0, "ReadVBIOSTablData: pVideoMemory[ 0x65 ] =%x\n",pVideoMemory[ 0x65 ])); */
-        pVBInfo->IF_DEF_CH7007 = 1 ;                            /* [Billy] 07/05/03 */
-        XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0x60 ) ; /* CH7007 on chip */
-    }
-    else
-#endif
 #if 1
     if (( pVideoMemory[ 0x65 ] & 0x01 ) )                      /* For XG21 LVDS */
     {
@@ -3378,9 +3157,9 @@ void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* -------------------------------------------------------- */
-void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    UCHAR Temp,bCR4A;
+       unsigned char Temp, bCR4A;
 
      pVBInfo->IF_DEF_LVDS = 0 ;
      bCR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
@@ -3402,9 +3181,9 @@ void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
 
 }
 
-UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
+unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
 {
-    UCHAR CR38,CR4A,temp;
+       unsigned char CR38, CR4A, temp;
 
     CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
     XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x10 , 0x10 ) ; /* enable GPIOE read */
@@ -3422,9 +3201,9 @@ UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
     return temp;
 }
 
-UCHAR GetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
+unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
 {
-    UCHAR CR4A,temp;
+       unsigned char CR4A, temp;
 
     CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
     XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* enable GPIOA/B/C read */
index 1f39d9c74cdd377495381a0a9655ebf79974e3ec..b47352b8e34a321caf88506e9e71ce182dde56dd 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef  _VBINIT_
 #define  _VBINIT_
-extern   BOOLEAN    XGIInitNew( PXGI_HW_DEVICE_INFO HwDeviceExtension ) ;
-extern XGI21_LVDSCapStruct  XGI21_LCDCapList[13];
+extern   unsigned char    XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) ;
+extern struct XGI21_LVDSCapStruct  XGI21_LCDCapList[13];
 
 #endif
 
index bd7f73898644e75483e7d2abf763a220cfe6fcbf..d90bf06bf62fc003eb6378497bec15bed0566d89 100644 (file)
@@ -1,43 +1,9 @@
-#include "osdef.h"
 
-#ifdef TC
-#include <stdio.h>
-#include <string.h>
-#include <conio.h>
-#include <dos.h>
-#endif
-
-
-#ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86PciInfo.h"
-#include "xgi.h"
-#include "xgi_regs.h"
-#endif
-
-#ifdef LINUX_KERNEL
 #include <asm/io.h>
 #include <linux/types.h>
 #include <linux/version.h>
 #include "XGIfb.h"
-/*#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#include <video/XGIfb.h>
-#else
-#include <linux/XGIfb.h>
-#endif*/
-#endif
-
-#ifdef WIN2000
-#include <dderror.h>
-#include <devioctl.h>
-#include <miniport.h>
-#include <ntddvdeo.h>
-#include <video.h>
 
-#include "xgiv.h"
-#include "dd_i2c.h"
-#include "tools.h"
-#endif
 
 #include "vb_def.h"
 #include "vgatypes.h"
 
 
 
-BOOLEAN  XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo);
-
-BOOLEAN  XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_AjustCRT2Rate(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT *i, PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_SearchModeID( USHORT ModeNo,USHORT  *ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_GetLCDInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo ) ;
-BOOLEAN  XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo);
-UCHAR    XGI_GetModePtr( USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetOffset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo );
-USHORT   XGI_GetResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetColorDepth(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetVCLK2Ptr(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
-void     XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo);
-void     XGI_GetCRT2Data(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_GetCRT2ResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_PreSetGroup1(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetGroup1(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetLockRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetLCDRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetGroup2(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetGroup3(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetGroup4(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetGroup5(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void*    XGI_GetLcdPtr(USHORT BX,  USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void*    XGI_GetTVPtr(USHORT BX, USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void    XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo);
-void    XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
-void    XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
-void    XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-void    XGI_SetPanelPower(USHORT tempah,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-void    XGI_EnablePWD( PVB_DEVICE_INFO pVBInfo);
-void    XGI_DisablePWD( PVB_DEVICE_INFO pVBInfo);
-void     XGI_AutoThreshold( PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetTap4Regs( PVB_DEVICE_INFO pVBInfo);
-
-void     XGI_DisplayOn(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void     XGI_DisplayOff( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo );
-void     XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
-void     XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
-void    XGI_UpdateXG21CRTC(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo, USHORT RefreshRateTableIndex);
-void     XGI_WaitDisply(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetSeqRegs(USHORT ModeNo,USHORT StandTableIndex,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetMiscRegs(USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRTCRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetATTRegs(USHORT ModeNo,USHORT StandTableIndex,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo );
-void     XGI_SetGRCRegs(USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_ClearExt1Regs(PVB_DEVICE_INFO pVBInfo);
-
-void     XGI_SetSync(USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRT1CRTC(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo,PXGI_HW_DEVICE_INFO HwDeviceExtension);
-void     XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,PXGI_HW_DEVICE_INFO HwDeviceExtension);
-void     XGI_SetCRT1Timing_V(USHORT ModeIdIndex,USHORT ModeNo,PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRT1VCLK(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRT1FIFO(USHORT ModeNo,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
-
-void     XGI_LoadDAC(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
-void     XGI_WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh, PVB_DEVICE_INFO pVBInfo);
-/*void     XGI_ClearBuffer(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,PVB_DEVICE_INFO pVBInfo);*/
-void     XGI_SetLCDAGroup(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_GetLVDSResInfo( USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_GetLVDSData(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_ModCRT1Regs(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_SetLVDSRegs(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_GetVGAType(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_GetVBType(PVB_DEVICE_INFO  pVBInfo);
-void     XGI_GetVBInfo(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_GetTVInfo(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO  pVBInfo);
-void     XGI_SetCRT2ECLK( USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO  pVBInfo);
-void     InitTo330Pointer(UCHAR,PVB_DEVICE_INFO pVBInfo);
-void     XGI_GetLCDSync(USHORT* HSyncWidth, USHORT* VSyncWidth, PVB_DEVICE_INFO pVBInfo);
-void    XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
-void    XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRT2VCLK(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_OEM310Setting(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetLCDCap_A(USHORT tempcx,PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetLCDCap_B(USHORT tempcx,PVB_DEVICE_INFO pVBInfo);
-void     SetSpectrum(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetAntiFlicker(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetEdgeEnhance(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetYFilter(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_GetTVPtrIndex2(USHORT* tempbx,UCHAR* tempcl,UCHAR* tempch, PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetTVPtrIndex(  PVB_DEVICE_INFO pVBInfo );
-void     XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo );
-void     XGI_CloseCRTC(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void     XGI_OpenCRTC(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void     XGI_GetRAMDAC2DATA(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void     XGI_LockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void     XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo);
-void     XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo);
-void     XGI_LongWait(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetCRT1Offset( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo );
-void     XGI_GetLCDVCLKPtr(UCHAR* di_0,UCHAR *di_1, PVB_DEVICE_INFO pVBInfo);
-UCHAR    XGI_GetVCLKPtr(USHORT RefreshRateTableIndex,USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void     XGI_GetVCLKLen(UCHAR tempal,UCHAR* di_0,UCHAR* di_1, PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo);
-USHORT   XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo);
-XGI301C_Tap4TimingStruct* XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
-void     XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
-UCHAR    XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo);
-UCHAR    XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo);
-void     XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-void     XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-void     XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-BOOLEAN  XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
-void     XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
-void     XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
-UCHAR    XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo );
-
-extern   void    ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
-#ifdef WIN2000
-/* [Billy] 2007/05/17 For CH7007 */
-extern  UCHAR CH7007TVReg_UNTSC[][8],CH7007TVReg_ONTSC[][8],CH7007TVReg_UPAL[][8],CH7007TVReg_OPAL[][8];
-extern  UCHAR CH7007TVCRT1UNTSC_H[][10],CH7007TVCRT1ONTSC_H[][10],CH7007TVCRT1UPAL_H[][10],CH7007TVCRT1OPAL_H[][10] ;
-extern  UCHAR CH7007TVCRT1UNTSC_V[][10],CH7007TVCRT1ONTSC_V[][10],CH7007TVCRT1UPAL_V[][10],CH7007TVCRT1OPAL_V[][10] ;
-extern  UCHAR XGI7007_CHTVVCLKUNTSC[],XGI7007_CHTVVCLKONTSC[],XGI7007_CHTVVCLKUPAL[],XGI7007_CHTVVCLKOPAL[];
-
-extern  BOOLEAN XGI_XG21CheckCH7007TVMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo ) ;
-extern  void SetCH7007Regs(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO  pVBInfo ) ;
-extern  VP_STATUS TurnOnCH7007(PHW_DEVICE_EXTENSION pHWDE) ;
-extern  VP_STATUS TurnOffCH7007(PHW_DEVICE_EXTENSION pHWDE) ;
-extern  BOOLEAN IsCH7007TVMode(PVB_DEVICE_INFO pVBInfo) ;
-#endif
-
-/* USHORT XGINew_flag_clearbuffer; 0: no clear frame buffer 1:clear frame buffer */
-
-
-
-
-
-USHORT XGINew_MDA_DAC[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-               0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-               0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F};
-
-USHORT XGINew_CGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
-               0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
-               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
-               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
-               0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
-               0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
-               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
-               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F};
-
-USHORT XGINew_EGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
-               0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
-               0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D,
-               0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D,
-               0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17,
-               0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37,
-               0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F,
-               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F};
-
-USHORT XGINew_VGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
-               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
-               0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
-               0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
-
-               0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
-               0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
-               0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
-               0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
-               0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
-               0x0B,0x0C,0x0D,0x0F,0x10};
+unsigned char  XGI_IsLCDDualLink(struct vb_device_info *pVBInfo);
+unsigned char  XGI_SetCRT2Group301(unsigned short ModeNo,
+                            struct xgi_hw_device_info *HwDeviceExtension,
+                            struct vb_device_info *pVBInfo);
+unsigned char  XGI_BacklightByDrv(struct vb_device_info *pVBInfo);
+
+unsigned char  XGI_IsLCDON(struct vb_device_info *pVBInfo);
+unsigned char  XGI_DisableChISLCD(struct vb_device_info *pVBInfo);
+unsigned char  XGI_EnableChISLCD(struct vb_device_info *pVBInfo);
+unsigned char  XGI_AjustCRT2Rate(unsigned short ModeNo,
+                          unsigned short ModeIdIndex,
+                          unsigned short RefreshRateTableIndex,
+                          unsigned short *i, struct vb_device_info *pVBInfo);
+unsigned char  XGI_SearchModeID(unsigned short ModeNo,
+                         unsigned short *ModeIdIndex,
+                         struct vb_device_info *pVBInfo);
+unsigned char  XGI_GetLCDInfo(unsigned short ModeNo,
+                       unsigned short ModeIdIndex,
+                       struct vb_device_info *pVBInfo);
+unsigned char  XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
+                      unsigned short ModeNo);
+unsigned char  XGI_BridgeIsOn(struct vb_device_info *pVBInfo);
+unsigned char    XGI_GetModePtr(unsigned short ModeNo,
+                       unsigned short ModeIdIndex,
+                       struct vb_device_info *pVBInfo);
+unsigned short XGI_GetOffset(unsigned short ModeNo,
+                            unsigned short ModeIdIndex,
+                            unsigned short RefreshRateTableIndex,
+                            struct xgi_hw_device_info *HwDeviceExtension,
+                            struct vb_device_info *pVBInfo);
+unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
+                                 unsigned short ModeNo,
+                                 unsigned short ModeIdIndex,
+                                 struct vb_device_info *pVBInfo);
+unsigned short XGI_GetResInfo(unsigned short ModeNo,
+                             unsigned short ModeIdIndex,
+                             struct vb_device_info *pVBInfo);
+unsigned short XGI_GetColorDepth(unsigned short ModeNo,
+                                unsigned short ModeIdIndex,
+                                struct vb_device_info *pVBInfo);
+unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo);
+unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
+                              unsigned short ModeIdIndex,
+                              unsigned short RefreshRateTableIndex,
+                              struct xgi_hw_device_info *HwDeviceExtension,
+                              struct vb_device_info *pVBInfo);
+void     XGI_VBLongWait(struct vb_device_info *pVBInfo);
+void     XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo);
+void     XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     *XGI_GetLcdPtr(unsigned short BX,  unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_FirePWDEnable(struct vb_device_info *pVBInfo);
+void     XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo);
+void     XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, struct vb_device_info *pVBInfo);
+void     XGI_EnablePWD(struct vb_device_info *pVBInfo);
+void     XGI_DisablePWD(struct vb_device_info *pVBInfo);
+void     XGI_AutoThreshold(struct vb_device_info *pVBInfo);
+void     XGI_SetTap4Regs(struct vb_device_info *pVBInfo);
+
+void     XGI_DisplayOn(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+void     XGI_DisplayOff(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetXG21LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo);
+void     XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetXG27LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo);
+void    XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex);
+void     XGI_WaitDisply(struct vb_device_info *pVBInfo);
+void     XGI_SenseCRT1(struct vb_device_info *pVBInfo);
+void     XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short StandTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_ClearExt1Regs(struct vb_device_info *pVBInfo);
+
+void     XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension);
+void     XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension);
+void     XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT1FIFO(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+
+void     XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh, struct vb_device_info *pVBInfo);
+/*void     XGI_ClearBuffer(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, struct vb_device_info *pVBInfo);*/
+void     XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+                           struct vb_device_info *pVBInfo);
+void     XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
+                        unsigned short RefreshRateTableIndex,
+                        struct xgi_hw_device_info *HwDeviceExtension,
+                        struct vb_device_info *pVBInfo);
+void     XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_GetVBType(struct vb_device_info *pVBInfo);
+void     XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     InitTo330Pointer(unsigned char, struct vb_device_info *pVBInfo);
+void     XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, struct vb_device_info *pVBInfo);
+void     XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetDelayComp(struct vb_device_info *pVBInfo);
+void     XGI_SetLCDCap(struct vb_device_info *pVBInfo);
+void     XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo);
+void     XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo);
+void     SetSpectrum(struct vb_device_info *pVBInfo);
+void     XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetPhaseIncr(struct vb_device_info *pVBInfo);
+void     XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char* tempcl,
+                           unsigned char *tempch, struct vb_device_info *pVBInfo);
+unsigned short   XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo);
+void     XGI_SetCRT2ModeRegs(unsigned short ModeNo, struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+void     XGI_CloseCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+void     XGI_OpenCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+void     XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+void     XGI_UnLockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+void     XGI_LockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+void     XGINew_EnableCRT2(struct vb_device_info *pVBInfo);
+void     XGINew_LCD_Wait_Time(unsigned char DelayTime, struct vb_device_info *pVBInfo);
+void     XGI_LongWait(struct vb_device_info *pVBInfo);
+void     XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+void     XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
+                          struct vb_device_info *pVBInfo);
+unsigned char    XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
+                               unsigned short ModeNo,
+                               unsigned short ModeIdIndex,
+                               struct vb_device_info *pVBInfo);
+void     XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
+                       unsigned char *di_1, struct vb_device_info *pVBInfo);
+unsigned short   XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo);
+unsigned short   XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo);
+struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo);
+void     XGI_SetXG21FPBits(struct vb_device_info *pVBInfo);
+void     XGI_SetXG27FPBits(struct vb_device_info *pVBInfo);
+unsigned char    XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo);
+unsigned char    XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo);
+void     XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo);
+void     XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo);
+void     XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo);
+unsigned char  XGI_XG21CheckLVDSMode(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+void     XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+unsigned char  XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo);
+
+extern void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo);
+
+/* unsigned short XGINew_flag_clearbuffer; 0: no clear frame buffer 1:clear frame buffer */
+
+
+unsigned short XGINew_MDA_DAC[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+       0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+       0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F};
+
+unsigned short XGINew_CGA_DAC[] = {
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+       0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+       0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+       0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+       0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
+
+unsigned short XGINew_EGA_DAC[] = {
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
+       0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
+       0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
+       0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
+       0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
+       0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
+       0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
+       0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
+
+unsigned short XGINew_VGA_DAC[] = {
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+       0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+       0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
+       0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
+       0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
+       0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
+       0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
+       0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
+       0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
+       0x0B, 0x0C, 0x0D, 0x0F, 0x10};
 
 
 /* --------------------------------------------------------------------- */
@@ -250,35 +240,35 @@ USHORT XGINew_VGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void InitTo330Pointer( UCHAR ChipType ,PVB_DEVICE_INFO pVBInfo)
+void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
 {
-    pVBInfo->SModeIDTable = (XGI_StStruct *) XGI330_SModeIDTable ;
-    pVBInfo->StandTable = (XGI_StandTableStruct *) XGI330_StandTable ;
-    pVBInfo->EModeIDTable = (XGI_ExtStruct *) XGI330_EModeIDTable ;
-    pVBInfo->RefIndex = (XGI_Ext2Struct *) XGI330_RefIndex ;
-    pVBInfo->XGINEWUB_CRT1Table = (XGI_CRT1TableStruct *) XGI_CRT1Table ;
+    pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable ;
+    pVBInfo->StandTable = (struct XGI_StandTableStruct *) XGI330_StandTable ;
+    pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable ;
+    pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex ;
+    pVBInfo->XGINEWUB_CRT1Table = (struct XGI_CRT1TableStruct *) XGI_CRT1Table ;
 
     /* add for new UNIVGABIOS */
-    /* XGINew_UBLCDDataTable = (XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
+    /* XGINew_UBLCDDataTable = (struct XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
     /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable ; */
 
 
     if ( ChipType >= XG40 )
     {
-        pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI340New_MCLKData ;
-        pVBInfo->ECLKData = (XGI_ECLKDataStruct *) XGI340_ECLKData ;
+       pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
+       pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
     }
     else
     {
-        pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI330New_MCLKData ;
-        pVBInfo->ECLKData = (XGI_ECLKDataStruct *) XGI330_ECLKData ;
+       pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI330New_MCLKData;
+       pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI330_ECLKData;
     }
 
-    pVBInfo->VCLKData = (XGI_VCLKDataStruct *) XGI_VCLKData ;
-    pVBInfo->VBVCLKData = (XGI_VBVCLKDataStruct *) XGI_VBVCLKData ;
+    pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData ;
+    pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData ;
     pVBInfo->ScreenOffset = XGI330_ScreenOffset ;
-    pVBInfo->StResInfo = (XGI_StResInfoStruct *) XGI330_StResInfo ;
-    pVBInfo->ModeResInfo = (XGI_ModeResInfoStruct *) XGI330_ModeResInfo ;
+    pVBInfo->StResInfo = (struct XGI_StResInfoStruct *) XGI330_StResInfo ;
+    pVBInfo->ModeResInfo = (struct XGI_ModeResInfoStruct *) XGI330_ModeResInfo ;
 
     pVBInfo->pOutputSelect = &XGI330_OutputSelect ;
     pVBInfo->pSoftSetting = &XGI330_SoftSetting ;
@@ -342,9 +332,9 @@ void InitTo330Pointer( UCHAR ChipType ,PVB_DEVICE_INFO pVBInfo)
     pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3 ;
 
 
-    pVBInfo->TimingH = (XGI_TimingHStruct *) XGI_TimingH ;
-    pVBInfo->TimingV = (XGI_TimingVStruct *) XGI_TimingV ;
-    pVBInfo->UpdateCRT1 = (XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table ;
+    pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH ;
+    pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV ;
+    pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table ;
 
     pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC ;
     pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC ;
@@ -371,7 +361,7 @@ void InitTo330Pointer( UCHAR ChipType ,PVB_DEVICE_INFO pVBInfo)
 
     if ( ChipType == XG27 )
     {
-        pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI27New_MCLKData ;
+       pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI27New_MCLKData;
         pVBInfo->CR40 = XGI27_cr41 ;
        pVBInfo->pXGINew_CR97 = &XG27_CR97 ;
        pVBInfo->pSR36 = &XG27_SR36 ;
@@ -405,14 +395,15 @@ void InitTo330Pointer( UCHAR ChipType ,PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo )
+unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
+                           unsigned short ModeNo)
 {
-    USHORT ModeIdIndex ;
-        /* PUCHAR pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
-    VB_DEVICE_INFO VBINF;
-    PVB_DEVICE_INFO pVBInfo = &VBINF;
+    unsigned short ModeIdIndex ;
+        /* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
+    struct vb_device_info VBINF;
+    struct vb_device_info *pVBInfo = &VBINF;
     pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
-    pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
+    pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
     pVBInfo->IF_DEF_LVDS = 0 ;
     pVBInfo->IF_DEF_CH7005 = 0 ;
     pVBInfo->IF_DEF_LCDA = 1 ;
@@ -485,9 +476,6 @@ BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo )
     XGI_GetVBType( pVBInfo ) ;
 
     InitTo330Pointer( HwDeviceExtension->jChipType, pVBInfo ) ;
-#ifdef WIN2000
-    ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-#endif
     if ( ModeNo & 0x80 )
     {
         ModeNo = ModeNo & 0x7F ;
@@ -560,30 +548,9 @@ BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo )
     }  /* !XG20 */
     else
     {
-#ifdef WIN2000
-        if ( pVBInfo->IF_DEF_CH7007 == 1 )
-        {
-
-            VideoDebugPrint((0, "XGISetModeNew: pVBIfo->IF_DEF_CH7007==1\n"));
-            pVBInfo->VBType = VB_CH7007 ;
-            XGI_GetVBInfo(ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
-            XGI_GetTVInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
-            XGI_GetLCDInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
-            if( !(XGI_XG21CheckCH7007TVMode(ModeNo, ModeIdIndex, pVBInfo )) )
-            {
-              return FALSE;
-            }
-        }
-#endif
-
-
-        if ( pVBInfo->IF_DEF_LVDS == 1 )
-        {
-            if ( !XGI_XG21CheckLVDSMode(ModeNo , ModeIdIndex, pVBInfo) )
-            {
-              return FALSE;
-            }
-        }
+           if (pVBInfo->IF_DEF_LVDS == 1)
+                   if (!XGI_XG21CheckLVDSMode(ModeNo , ModeIdIndex, pVBInfo))
+                           return 0;
 
         if ( ModeNo <= 0x13 )
         {
@@ -642,7 +609,7 @@ BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo )
     XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
 }
 
-    return( TRUE ) ;
+    return 1;
 }
 
 
@@ -652,14 +619,16 @@ BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1Group( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension,
+                     unsigned short ModeNo,
+                     unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT StandTableIndex ,
+    unsigned short StandTableIndex ,
            RefreshRateTableIndex ,
            b3CC ,
            temp ;
 
-    USHORT XGINew_P3cc =  pVBInfo->P3cc;
+    unsigned short XGINew_P3cc =  pVBInfo->P3cc;
 
     /* XGINew_CRT1Mode = ModeNo ; // SaveModeID */
     StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
@@ -710,14 +679,14 @@ void XGI_SetCRT1Group( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo , U
        {
            XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x4E) ;
            XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE9) ;
-           b3CC =(UCHAR) XGINew_GetReg2(XGINew_P3cc) ;
+           b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc) ;
            XGINew_SetReg3(XGINew_P3cc ,  (b3CC |= 0x0C) ) ;
        }
        else if ( ( ModeNo == 0x04) | ( ModeNo == 0x05) | ( ModeNo == 0x0D) )
        {
            XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x1B) ;
            XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE3) ;
-           b3CC = (UCHAR)XGINew_GetReg2(XGINew_P3cc) ;
+           b3CC = (unsigned char)XGINew_GetReg2(XGINew_P3cc) ;
            XGINew_SetReg3(XGINew_P3cc ,  (b3CC |= 0x0C) ) ;
        }
     }
@@ -763,13 +732,6 @@ void XGI_SetCRT1Group( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo , U
 
     XGI_LoadDAC( ModeNo , ModeIdIndex, pVBInfo ) ;
     /* XGI_ClearBuffer( HwDeviceExtension , ModeNo, pVBInfo ) ; */
-#ifdef WIN2000
-   if ( pVBInfo->IF_DEF_CH7007 == 1 )  /* [Billy]  2007/05/14  */
-   {
-       VideoDebugPrint((0, "XGI_SetCRT1Group: VBInfo->IF_DEF_CH7007==1\n"));
-       SetCH7007Regs(HwDeviceExtension, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo ) ; /* 07/05/28 */
-   }
-#endif
 }
 
 
@@ -779,9 +741,10 @@ void XGI_SetCRT1Group( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo , U
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGI_GetModePtr( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex,
+                    struct vb_device_info *pVBInfo)
 {
-    UCHAR index ;
+    unsigned char index ;
 
     if ( ModeNo <= 0x13 )
         index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_StTableIndex ;
@@ -802,7 +765,7 @@ UCHAR XGI_GetModePtr( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInf
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-/*UCHAR XGI_SetBIOSData( USHORT ModeNo , USHORT ModeIdIndex )
+/*unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex)
 {
     return( 0 ) ;
 }
@@ -814,7 +777,7 @@ UCHAR XGI_GetModePtr( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInf
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-/*UCHAR XGI_ClearBankRegs( USHORT ModeNo , USHORT ModeIdIndex )
+/*unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex)
 {
     return( 0 ) ;
 }
@@ -826,12 +789,13 @@ UCHAR XGI_GetModePtr( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInf
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetSeqRegs(  USHORT ModeNo , USHORT StandTableIndex , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex,
+                   unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    UCHAR tempah ,
+    unsigned char tempah ,
           SRdata ;
 
-    USHORT i ,
+    unsigned short i ,
            modeflag ;
 
     if ( ModeNo <= 0x13 )
@@ -873,9 +837,9 @@ void XGI_SetSeqRegs(  USHORT ModeNo , USHORT StandTableIndex , USHORT ModeIdInde
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetMiscRegs( USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
 {
-    UCHAR Miscdata ;
+    unsigned char Miscdata ;
 
     Miscdata = pVBInfo->StandTable[ StandTableIndex ].MISC ;   /* Get Misc from file */
 /*
@@ -898,12 +862,13 @@ void XGI_SetMiscRegs( USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRTCRegs( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
+                    unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
 {
-    UCHAR CRTCdata ;
-    USHORT i ;
+    unsigned char CRTCdata ;
+    unsigned short i ;
 
-    CRTCdata = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
+    CRTCdata = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
     CRTCdata &= 0x7f ;
     XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , CRTCdata ) ;                /* Unlock CRTC */
 
@@ -933,11 +898,11 @@ void XGI_SetCRTCRegs( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT StandTableI
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetATTRegs( USHORT ModeNo , USHORT StandTableIndex , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex,
+                   unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    UCHAR ARdata ;
-    USHORT i ,
-           modeflag ;
+    unsigned char ARdata ;
+    unsigned short i, modeflag;
 
     if ( ModeNo <= 0x13 )
         modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
@@ -983,10 +948,10 @@ void XGI_SetATTRegs( USHORT ModeNo , USHORT StandTableIndex , USHORT ModeIdIndex
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetGRCRegs( USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
 {
-    UCHAR GRdata ;
-    USHORT i ;
+    unsigned char GRdata ;
+    unsigned short i ;
 
     for( i = 0 ; i <= 0x08 ; i++ )
     {
@@ -996,7 +961,7 @@ void XGI_SetGRCRegs( USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
 
     if ( pVBInfo->ModeType > ModeVGA )
     {
-        GRdata = ( UCHAR )XGINew_GetReg1( pVBInfo->P3ce , 0x05 ) ;
+       GRdata = (unsigned char)XGINew_GetReg1(pVBInfo->P3ce, 0x05);
         GRdata &= 0xBF ;                                               /* 256 color disable */
         XGINew_SetReg1( pVBInfo->P3ce , 0x05 , GRdata ) ;
     }
@@ -1009,9 +974,9 @@ void XGI_SetGRCRegs( USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_ClearExt1Regs(PVB_DEVICE_INFO pVBInfo)
+void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
 {
-    USHORT i ;
+    unsigned short i ;
 
     for( i = 0x0A ; i <= 0x0E ; i++ )
         XGINew_SetReg1( pVBInfo->P3c4 , i , 0x00 ) ;   /* Clear SR0A-SR0E */
@@ -1024,7 +989,7 @@ void XGI_ClearExt1Regs(PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
 {
 
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , 0x20 ) ;
@@ -1046,13 +1011,15 @@ UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
+                                 unsigned short ModeNo,
+                                 unsigned short ModeIdIndex,
+                                 struct vb_device_info *pVBInfo)
 {
-    SHORT  LCDRefreshIndex[] = { 0x00 , 0x00 , 0x03 , 0x01 } ,
+    short LCDRefreshIndex[] = { 0x00 , 0x00 , 0x03 , 0x01 } ,
            LCDARefreshIndex[] = { 0x00 , 0x00 , 0x03 , 0x01 , 0x01 , 0x01 , 0x01 } ;
 
-    USHORT RefreshRateTableIndex , i ,
-         modeflag , index , temp ;
+    unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
 
     if ( ModeNo <= 0x13 )
     {
@@ -1183,13 +1150,11 @@ USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo , USHORT
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_AjustCRT2Rate( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , USHORT *i, PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, unsigned short ModeIdIndex,
+                               unsigned short RefreshRateTableIndex,
+                               unsigned short *i, struct vb_device_info *pVBInfo)
 {
-    USHORT tempax ,
-           tempbx ,
-           resinfo ,
-           modeflag ,
-           infoflag ;
+    unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
 
     if ( ModeNo <= 0x13 )
     {
@@ -1359,9 +1324,9 @@ BOOLEAN XGI_AjustCRT2Rate( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRa
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetSync(USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT sync ,
+    unsigned short sync ,
            temp ;
 
     sync = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag >> 8 ;      /* di+0x00 */
@@ -1378,17 +1343,18 @@ void XGI_SetSync(USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1CRTC( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceExtension )
+void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+                    unsigned short RefreshRateTableIndex,
+                    struct vb_device_info *pVBInfo,
+                    struct xgi_hw_device_info *HwDeviceExtension)
 {
-    UCHAR  index ,
-           data ;
-
-    USHORT i ;
+    unsigned char index, data;
+    unsigned short i;
 
     index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;  /* Get index */
     index = index&IndexMask ;
 
-    data =( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
+    data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
     data &= 0x7F ;
     XGINew_SetReg1(pVBInfo->P3d4,0x11,data);                           /* Unlock CRTC */
 
@@ -1416,16 +1382,16 @@ void XGI_SetCRT1CRTC( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1Timing_H( PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceExtension )
+void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension)
 {
-    UCHAR data , data1, pushax;
-    USHORT i , j ;
+    unsigned char data, data1, pushax;
+    unsigned short i, j;
 
     /* XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0 ) ; */
     /* XGINew_SetReg1( pVBInfo->P3d4 , 0x56 , 0 ) ; */
     /* XGINew_SetRegANDOR( pVBInfo->P3d4 ,0x11 , 0x7f , 0x00 ) ; */
 
-    data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;           /* unlock cr0-7 */
+    data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
     data &= 0x7F ;
     XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , data ) ;
 
@@ -1435,16 +1401,16 @@ void XGI_SetCRT1Timing_H( PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceE
     for( i = 0x01 ; i <= 0x04 ; i++ )
     {
         data = pVBInfo->TimingH[ 0 ].data[ i ] ;
-        XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 1 ) , data ) ;
+       XGINew_SetReg1( pVBInfo->P3d4, (unsigned short)(i + 1), data);
     }
 
     for( i = 0x05 ; i <= 0x06 ; i++ )
     {
         data = pVBInfo->TimingH[ 0 ].data[ i ];
-        XGINew_SetReg1( pVBInfo->P3c4 ,( USHORT )( i + 6 ) , data ) ;
+       XGINew_SetReg1(pVBInfo->P3c4, (unsigned short)(i + 6), data);
     }
 
-    j = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0e ) ;
+    j = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
     j &= 0x1F ;
     data = pVBInfo->TimingH[ 0 ].data[ 7 ] ;
     data &= 0xE0 ;
@@ -1453,17 +1419,17 @@ void XGI_SetCRT1Timing_H( PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceE
 
     if ( HwDeviceExtension->jChipType >= XG20 )
     {
-       data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x04 ) ;
+       data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x04);
        data = data - 1 ;
        XGINew_SetReg1( pVBInfo->P3d4 , 0x04 , data ) ;
-       data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x05 ) ;
+       data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x05);
        data1 = data ;
        data1 &= 0xE0 ;
        data &= 0x1F ;
        if ( data == 0 )
        {
            pushax = data ;
-           data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0c ) ;
+           data = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0c);
            data &= 0xFB ;
            XGINew_SetReg1( pVBInfo->P3c4 , 0x0c , data ) ;
            data = pushax ;
@@ -1471,7 +1437,7 @@ void XGI_SetCRT1Timing_H( PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceE
        data = data - 1 ;
        data |= data1 ;
        XGINew_SetReg1( pVBInfo->P3d4 , 0x05 , data ) ;
-       data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0e ) ;
+       data = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
        data = data >> 5 ;
        data = data + 3 ;
        if ( data > 7 )
@@ -1488,10 +1454,12 @@ void XGI_SetCRT1Timing_H( PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceE
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1Timing_V( USHORT ModeIdIndex , USHORT ModeNo,PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
+                        unsigned short ModeNo,
+                        struct vb_device_info *pVBInfo)
 {
-    UCHAR data ;
-    USHORT i , j ;
+    unsigned char data;
+    unsigned short i, j;
 
     /* XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0 ) ; */
     /* XGINew_SetReg1( pVBInfo->P3d4 , 0x56 , 0 ) ; */
@@ -1500,22 +1468,22 @@ void XGI_SetCRT1Timing_V( USHORT ModeIdIndex , USHORT ModeNo,PVB_DEVICE_INFO pVB
     for( i = 0x00 ; i <= 0x01 ; i++ )
     {
         data = pVBInfo->TimingV[ 0 ].data[ i ] ;
-        XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 6 ) , data ) ;
+       XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 6), data);
     }
 
     for( i = 0x02 ; i <= 0x03 ; i++ )
     {
         data = pVBInfo->TimingV[ 0 ].data[ i ] ;
-        XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 0x0e ) , data ) ;
+       XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 0x0e), data);
     }
 
     for( i = 0x04 ; i <= 0x05 ; i++ )
     {
         data = pVBInfo->TimingV[ 0 ].data[ i ] ;
-        XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 0x11 ) , data ) ;
+       XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 0x11), data);
     }
 
-    j = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0a ) ;
+    j = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0a);
     j &= 0xC0 ;
     data = pVBInfo->TimingV[ 0 ].data[ 6 ] ;
     data &= 0x3F ;
@@ -1535,7 +1503,7 @@ void XGI_SetCRT1Timing_V( USHORT ModeIdIndex , USHORT ModeNo,PVB_DEVICE_INFO pVB
     if ( i )
         data |= 0x80 ;
 
-    j = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x09 ) ;
+    j = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x09);
     j &= 0x5F ;
     data |= j ;
     XGINew_SetReg1( pVBInfo->P3d4 , 0x09 , data ) ;
@@ -1548,10 +1516,12 @@ void XGI_SetCRT1Timing_V( USHORT ModeIdIndex , USHORT ModeNo,PVB_DEVICE_INFO pVB
 /* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
 /* Description : Set LCD timing */
 /* --------------------------------------------------------------------- */
-void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+                    unsigned short RefreshRateTableIndex,
+                    struct vb_device_info *pVBInfo)
 {
-  UCHAR StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
-  USHORT Temp1, Temp2, Temp3 ;
+  unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
+  unsigned short Temp1, Temp2, Temp3;
 
   if ( ModeNo <= 0x13 )
   {
@@ -1580,7 +1550,7 @@ void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableI
     Tempdx |= Tempcx ;                                                 /* Tempdx: VRS[8:1] */
     XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempdx ) ;                  /* SR34[7:0]: VRS[8:1] */
 
-    Temp1 = Tempcx << 1 ;                                              /* Temp1[8]: VRS[8] UCHAR -> USHORT */
+    Temp1 = Tempcx << 1 ;                                              /* Temp1[8]: VRS[8] unsigned char -> unsigned short */
     Temp1 |= Tempbx ;                                                  /* Temp1[8:0]: VRS[8:0] */
     Tempax &= 0x80 ;                                                   /* Tempax[7]: CR7[7] */
     Temp2 = Tempax << 2 ;                                              /* Temp2[9]: VRS[9] */
@@ -1594,11 +1564,11 @@ void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableI
     if ( Tempax < Temp3 )                                              /* VRE[3:0]<VRS[3:0] */
       Temp2 |= 0x10 ;                                                  /* Temp2: VRE + 0x10 */
     Temp2 &= 0xFF ;                                                    /* Temp2[7:0]: VRE[7:0] */
-    Tempax = (UCHAR)Temp2 ;                                            /* Tempax[7:0]: VRE[7:0] */
+    Tempax = (unsigned char)Temp2;                                     /* Tempax[7:0]: VRE[7:0] */
     Tempax <<= 2 ;                                                     /* Tempax << 2: VRE[5:0] */
     Temp1 &= 0x600 ;                                                   /* Temp1[10:9]: VRS[10:9] */
     Temp1 >>= 9 ;                                                      /* [10:9]->[1:0] */
-    Tempbx = (UCHAR)Temp1 ;                                            /* Tempbx[1:0]: VRS[10:9] */
+    Tempbx = (unsigned char)Temp1;                                     /* Tempbx[1:0]: VRS[10:9] */
     Tempax |= Tempbx ;                                                 /* VRE[5:0]VRS[10:9] */
     Tempax &= 0x7F ;
     XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , Tempax ) ;                  /* SR3F D[7:2]->VRE D[1:0]->VRS */
@@ -1632,7 +1602,7 @@ void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableI
       Temp2 |= 0x40 ;                                                   /* Temp2 + 0x40 */
 
     Temp2 &= 0xFF ;
-    Tempax = (UCHAR)Temp2 ;                                            /* Tempax: HRE[7:0] */
+    Tempax = (unsigned char)Temp2;                                     /* Tempax: HRE[7:0] */
     Tempax <<= 2 ;                                                     /* Tempax[7:2]: HRE[5:0] */
     Tempdx >>= 6 ;                                                     /* Tempdx[7:6]->[1:0] HRS[9:8] */
     Tempax |= Tempdx ;                                                 /* HRE[5:0]HRS[9:8] */
@@ -1676,20 +1646,22 @@ void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableI
       Temp2 |= 0x20 ;                                                  /* VRE + 0x20 */
 
     Temp2 &= 0xFF ;
-    Tempax = (UCHAR)Temp2 ;                                            /* Tempax: VRE[7:0] */
+    Tempax = (unsigned char)Temp2;                                     /* Tempax: VRE[7:0] */
     Tempax <<= 2 ;                                                     /* Tempax[7:0]; VRE[5:0]00 */
     Temp1 &= 0x600 ;                                                   /* Temp1[10:9]: VRS[10:9] */
     Temp1 >>= 9 ;                                                      /* Temp1[1:0]: VRS[10:9] */
-    Tempbx = (UCHAR)Temp1 ;
+    Tempbx = (unsigned char)Temp1;
     Tempax |= Tempbx ;                                                 /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
     Tempax &= 0x7F ;
     XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , Tempax ) ;                  /* SR3F D[7:2]->VRE D[1:0]->VRS */
   }
 }
 
-void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+                    unsigned short RefreshRateTableIndex,
+                    struct vb_device_info *pVBInfo)
 {
-  USHORT StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
+       unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
 
   if ( ModeNo <= 0x13 )
   {
@@ -1726,7 +1698,7 @@ void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableI
     Tempbx |= Tempax ;                                                 /* Tempbx[9:0]: VRE[9:0] */
     if ( Tempax <= (Tempcx & 0x0F) )                                   /* VRE[3:0]<=VRS[3:0] */
       Tempbx |= 0x10 ;                                                 /* Tempbx: VRE + 0x10 */
-    Tempax = (UCHAR)Tempbx & 0xFF;                                     /* Tempax[7:0]: VRE[7:0] */
+    Tempax = (unsigned char)Tempbx & 0xFF;                             /* Tempax[7:0]: VRE[7:0] */
     Tempax <<= 2 ;                                                     /* Tempax << 2: VRE[5:0] */
     Tempcx = (Tempcx&0x600)>>8;                                         /* Tempcx VRS[10:9] */
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC, Tempax ) ;        /* SR3F D[7:2]->VRE D[5:0] */
@@ -1810,10 +1782,12 @@ void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableI
 /* Output : FCLK duty cycle, FCLK delay compensation */
 /* Description : All values set zero */
 /* --------------------------------------------------------------------- */
-void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
+void XGI_SetXG21LCD(struct vb_device_info *pVBInfo,
+                   unsigned short RefreshRateTableIndex,
+                   unsigned short ModeNo)
 {
-  USHORT Data , Temp , b3CC ;
-  USHORT XGI_P3cc ;
+       unsigned short Data, Temp, b3CC;
+       unsigned short XGI_P3cc;
 
   XGI_P3cc = pVBInfo->P3cc ;
 
@@ -1844,7 +1818,7 @@ void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT
 
   if ( ModeNo <= 0x13 )
   {
-    b3CC = (UCHAR) XGINew_GetReg2( XGI_P3cc ) ;
+    b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
     if ( b3CC & 0x40 )
       XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
     if ( b3CC & 0x80 )
@@ -1860,10 +1834,12 @@ void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT
   }
 }
 
-void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
+void XGI_SetXG27LCD(struct vb_device_info *pVBInfo,
+                   unsigned short RefreshRateTableIndex,
+                   unsigned short ModeNo)
 {
-  USHORT Data , Temp , b3CC ;
-  USHORT XGI_P3cc ;
+  unsigned short Data , Temp , b3CC ;
+  unsigned short XGI_P3cc ;
 
   XGI_P3cc = pVBInfo->P3cc ;
 
@@ -1896,7 +1872,7 @@ void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT
 
   if ( ModeNo <= 0x13 )
   {
-    b3CC = (UCHAR) XGINew_GetReg2( XGI_P3cc ) ;
+    b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
     if ( b3CC & 0x40 )
       XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
     if ( b3CC & 0x80 )
@@ -1918,7 +1894,9 @@ void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT
 /* Output : CRT1 CRTC */
 /* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
 /* --------------------------------------------------------------------- */
-void XGI_UpdateXG21CRTC( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo , USHORT RefreshRateTableIndex )
+void XGI_UpdateXG21CRTC(unsigned short ModeNo,
+                       struct vb_device_info *pVBInfo,
+                       unsigned short RefreshRateTableIndex)
 {
   int i , index = -1;
 
@@ -1961,16 +1939,15 @@ void XGI_UpdateXG21CRTC( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo , USHORT Refres
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1DE( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo,USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
+                  unsigned short ModeNo,
+                  unsigned short ModeIdIndex,
+                  unsigned short RefreshRateTableIndex,
+                  struct vb_device_info *pVBInfo)
 {
-    USHORT resindex ,
-           tempax ,
-           tempbx ,
-           tempcx ,
-           temp ,
-           modeflag ;
+       unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
 
-    UCHAR data ;
+    unsigned char data;
 
     resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
 
@@ -2013,13 +1990,13 @@ void XGI_SetCRT1DE( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo,USHORT
     tempax -= 1 ;
     tempbx -= 1 ;
     tempcx = tempax ;
-    temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
-    data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
+    temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+    data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
     data &= 0x7F ;
     XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , data ) ;            /* Unlock CRTC */
-    XGINew_SetReg1( pVBInfo->P3d4 , 0x01 , ( USHORT )( tempcx & 0xff ) ) ;
-    XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x0b , ~0x0c , ( USHORT )( ( tempcx & 0x0ff00 ) >> 10 ) ) ;
-    XGINew_SetReg1( pVBInfo->P3d4 , 0x12 , ( USHORT )( tempbx & 0xff ) ) ;
+    XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short)(tempcx & 0xff));
+    XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c, (unsigned short)((tempcx & 0x0ff00) >> 10));
+    XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short)(tempbx & 0xff));
     tempax = 0 ;
     tempbx = tempbx >> 8 ;
 
@@ -2030,7 +2007,7 @@ void XGI_SetCRT1DE( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo,USHORT
         tempax |= 0x40 ;
 
     XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x42 , tempax ) ;
-    data =( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x07 ) ;
+    data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x07);
     data &= 0xFF ;
     tempax = 0 ;
 
@@ -2048,9 +2025,11 @@ void XGI_SetCRT1DE( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo,USHORT
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT         XGI_GetResInfo(USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+unsigned short XGI_GetResInfo(unsigned short ModeNo,
+                             unsigned short ModeIdIndex,
+                             struct vb_device_info *pVBInfo)
 {
-    USHORT resindex ;
+       unsigned short resindex;
 
     if ( ModeNo <= 0x13 )
     {
@@ -2070,9 +2049,13 @@ USHORT   XGI_GetResInfo(USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBIn
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1Offset(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT1Offset(unsigned short ModeNo,
+                      unsigned short ModeIdIndex,
+                      unsigned short RefreshRateTableIndex,
+                      struct xgi_hw_device_info *HwDeviceExtension,
+                      struct vb_device_info *pVBInfo)
 {
-    USHORT temp ,
+    unsigned short temp ,
            ah ,
            al ,
            temp2 ,
@@ -2131,7 +2114,7 @@ void XGI_SetCRT1Offset(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRate
     i |= temp ;
     XGINew_SetReg1( pVBInfo->P3c4 , 0x0E , i ) ;
 
-    temp =( UCHAR )temp2 ;
+    temp = (unsigned char)temp2;
     temp &= 0xFF ;             /* al */
     XGINew_SetReg1( pVBInfo->P3d4 , 0x13 , temp ) ;
 
@@ -2163,11 +2146,13 @@ void XGI_SetCRT1Offset(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRate
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1VCLK( USHORT ModeNo , USHORT ModeIdIndex ,
-                        PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
+                    struct xgi_hw_device_info *HwDeviceExtension,
+                    unsigned short RefreshRateTableIndex,
+                    struct vb_device_info *pVBInfo)
 {
-    UCHAR index , data ;
-    USHORT vclkindex ;
+       unsigned char index, data;
+    unsigned short vclkindex ;
 
     if ( pVBInfo->IF_DEF_LVDS == 1 )
     {
@@ -2224,9 +2209,11 @@ void XGI_SetCRT1VCLK( USHORT ModeNo , USHORT ModeIdIndex ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1FIFO( USHORT ModeNo , PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT1FIFO(unsigned short ModeNo,
+                    struct xgi_hw_device_info *HwDeviceExtension,
+                    struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
+    unsigned short data ;
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x3D ) ;
     data &= 0xfe ;
@@ -2273,10 +2260,12 @@ void XGI_SetCRT1FIFO( USHORT ModeNo , PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT1ModeRegs( PXGI_HW_DEVICE_INFO HwDeviceExtension ,
-                            USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
+                        unsigned short ModeNo, unsigned short ModeIdIndex,
+                        unsigned short RefreshRateTableIndex,
+                        struct vb_device_info *pVBInfo)
 {
-    USHORT data ,
+    unsigned short data ,
            data2 ,
            data3 ,
            infoflag = 0 ,
@@ -2411,13 +2400,16 @@ void XGI_SetCRT1ModeRegs( PXGI_HW_DEVICE_INFO HwDeviceExtension ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetVCLKState(  PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo , USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo )
+void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
+                     unsigned short ModeNo,
+                     unsigned short RefreshRateTableIndex,
+                     struct vb_device_info *pVBInfo)
 {
-    USHORT data ,
+    unsigned short data ,
            data2 = 0 ;
-    SHORT  VCLK ;
+    short VCLK ;
 
-    UCHAR  index ;
+    unsigned char index;
 
     if ( ModeNo <= 0x13 )
         VCLK = 0 ;
@@ -2475,9 +2467,9 @@ void XGI_SetVCLKState(  PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-/*void XGI_VesaLowResolution( USHORT ModeNo , USHORT ModeIdIndex ,PVB_DEVICE_INFO pVBInfo)
+/*void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT modeflag;
+    unsigned short modeflag;
 
     if ( ModeNo > 0x13 )
         modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
@@ -2518,9 +2510,11 @@ void XGI_SetVCLKState(  PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_LoadDAC( USHORT ModeNo , USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo )
+void XGI_LoadDAC(unsigned short ModeNo,
+                unsigned short ModeIdIndex,
+                struct vb_device_info *pVBInfo)
 {
-    USHORT data , data2 , time ,
+    unsigned short data , data2 , time ,
            i  , j , k , m , n , o ,
            si , di , bx , dl , al , ah , dh ,
            *table = NULL ;
@@ -2627,9 +2621,11 @@ void XGI_LoadDAC( USHORT ModeNo , USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_WriteDAC( USHORT dl , USHORT ah , USHORT al , USHORT dh,PVB_DEVICE_INFO pVBInfo )
+void XGI_WriteDAC(unsigned short dl, unsigned short ah,
+                 unsigned short al, unsigned short dh,
+                 struct vb_device_info *pVBInfo)
 {
-    USHORT temp , bh , bl ;
+    unsigned short temp , bh , bl ;
 
     bh = ah ;
     bl = al ;
@@ -2652,70 +2648,24 @@ void XGI_WriteDAC( USHORT dl , USHORT ah , USHORT al , USHORT dh,PVB_DEVICE_INFO
             bh = temp ;
         }
     }
-    XGINew_SetReg3( pVBInfo->P3c9 , ( USHORT )dh ) ;
-    XGINew_SetReg3( pVBInfo->P3c9 , ( USHORT )bh ) ;
-    XGINew_SetReg3( pVBInfo->P3c9 , ( USHORT )bl ) ;
+    XGINew_SetReg3(pVBInfo->P3c9, (unsigned short)dh);
+    XGINew_SetReg3(pVBInfo->P3c9, (unsigned short)bh);
+    XGINew_SetReg3(pVBInfo->P3c9, (unsigned short)bl);
 }
 
-#if 0
-/* --------------------------------------------------------------------- */
-/* Function : XGI_ClearBuffer */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_ClearBuffer( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo, PVB_DEVICE_INFO  pVBInfo)
-{
-    PVOID VideoMemoryAddress = ( PVOID )HwDeviceExtension->pjVideoMemoryAddress ;
-    ULONG AdapterMemorySize  = ( ULONG )HwDeviceExtension->ulVideoMemorySize ;
-    PUSHORT pBuffer ;
-#ifndef LINUX_XF86
-    int i ;
-#endif
-
-    if ( pVBInfo->ModeType >= ModeEGA )
-    {
-        if ( ModeNo > 0x13 )
-        {
-            AdapterMemorySize = 0x40000 ;      /* clear 256k */
-            /* GetDRAMSize( HwDeviceExtension ) ; */
-            XGI_SetMemory( VideoMemoryAddress , AdapterMemorySize , 0 ) ;
-        }
-        else
-        {
-/*
-            pBuffer = VideoMemoryAddress ;
-            for( i = 0 ; i < 0x4000 ; i++ )
-                pBuffer[ i ] = 0x0000 ;
-*/
-        }
-    }
-    else
-    {
-        pBuffer = VideoMemoryAddress ;
-        if ( pVBInfo->ModeType < ModeCGA )
-        {
-/*
-            for ( i = 0 ; i < 0x4000 ; i++ )
-                pBuffer[ i ] = 0x0720 ;
-*/
-        }
-        else
-            XGI_SetMemory( VideoMemoryAddress , 0x8000 , 0 ) ;
-    }
-}
-
-#endif
 /* --------------------------------------------------------------------- */
 /* Function : XGI_SetLCDAGroup */
 /* Input : */
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetLCDAGroup( USHORT ModeNo , USHORT ModeIdIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO  pVBInfo )
+void XGI_SetLCDAGroup(unsigned short ModeNo,
+                     unsigned short ModeIdIndex,
+                     struct xgi_hw_device_info *HwDeviceExtension,
+                     struct vb_device_info *pVBInfo)
 {
-    USHORT RefreshRateTableIndex ;
-    /* USHORT temp ; */
+    unsigned short RefreshRateTableIndex ;
+    /* unsigned short temp ; */
 
     /* pVBInfo->SelectCRT2Rate = 0 ; */
 
@@ -2735,9 +2685,11 @@ void XGI_SetLCDAGroup( USHORT ModeNo , USHORT ModeIdIndex , PXGI_HW_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetLVDSResInfo( USHORT ModeNo , USHORT ModeIdIndex,PVB_DEVICE_INFO  pVBInfo )
+void XGI_GetLVDSResInfo(unsigned short ModeNo,
+                       unsigned short ModeIdIndex,
+                       struct vb_device_info *pVBInfo)
 {
-    USHORT resindex , xres , yres , modeflag ;
+    unsigned short resindex , xres , yres , modeflag ;
 
     if ( ModeNo <= 0x13 )
     {
@@ -2803,17 +2755,20 @@ void XGI_GetLVDSResInfo( USHORT ModeNo , USHORT ModeIdIndex,PVB_DEVICE_INFO  pVB
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetLVDSData(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO  pVBInfo )
+void XGI_GetLVDSData(unsigned short ModeNo,
+                    unsigned short ModeIdIndex,
+                    unsigned short RefreshRateTableIndex,
+                    struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ;
-    XGI330_LVDSDataStruct *LCDPtr = NULL ;
-    XGI330_CHTVDataStruct  *TVPtr = NULL ;
+    unsigned short tempbx ;
+    struct XGI330_LVDSDataStruct *LCDPtr = NULL ;
+    struct XGI330_CHTVDataStruct  *TVPtr = NULL ;
 
     tempbx = 2 ;
 
     if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
     {
-        LCDPtr = ( XGI330_LVDSDataStruct * )XGI_GetLcdPtr( tempbx, ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo) ;
+       LCDPtr = (struct XGI330_LVDSDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
         pVBInfo->VGAHT = LCDPtr->VGAHT ;
         pVBInfo->VGAVT = LCDPtr->VGAVT ;
         pVBInfo->HT = LCDPtr->LCDHT ;
@@ -2823,7 +2778,7 @@ void XGI_GetLVDSData(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTa
     {
         if ( pVBInfo->VBInfo & SetCRT2ToTV )
         {
-            TVPtr = ( XGI330_CHTVDataStruct * )XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+           TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
             pVBInfo->VGAHT = TVPtr->VGAHT ;
             pVBInfo->VGAVT = TVPtr->VGAVT ;
             pVBInfo->HT = TVPtr->LCDHT ;
@@ -2866,16 +2821,18 @@ void XGI_GetLVDSData(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTa
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
-                        USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO  pVBInfo )
+void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
+                    unsigned short RefreshRateTableIndex,
+                    struct xgi_hw_device_info *HwDeviceExtension,
+                    struct vb_device_info *pVBInfo)
 {
-    UCHAR index ;
-    USHORT tempbx , i ;
-    XGI_LVDSCRT1HDataStruct  *LCDPtr = NULL ;
-    XGI_LVDSCRT1VDataStruct  *LCDPtr1 =NULL ;
-    /* XGI330_CHTVDataStruct *TVPtr = NULL ; */
-    XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
-    XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
+    unsigned char index;
+    unsigned short tempbx , i ;
+    struct XGI_LVDSCRT1HDataStruct  *LCDPtr = NULL;
+    struct XGI_LVDSCRT1VDataStruct  *LCDPtr1 = NULL;
+    /* struct XGI330_CHTVDataStruct *TVPtr = NULL ; */
+    struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
+    struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
 
     if( ModeNo <= 0x13 )
         index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
@@ -2890,7 +2847,7 @@ void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
 
         if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
         {
-            LCDPtr = ( XGI_LVDSCRT1HDataStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+           LCDPtr = (struct XGI_LVDSCRT1HDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 
             for( i = 0 ; i < 8 ; i++ )
                 pVBInfo->TimingH[ 0 ].data[ i ] = LCDPtr[ 0 ].Reg[ i ] ;
@@ -2900,7 +2857,7 @@ void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
         {
             if ( pVBInfo->VBInfo & SetCRT2ToTV )
             {
-                CH7007TV_TimingHPtr = ( XGI_CH7007TV_TimingHStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+               CH7007TV_TimingHPtr = (struct XGI_CH7007TV_TimingHStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 
                 for( i = 0 ; i < 8 ; i++ )
                     pVBInfo->TimingH[ 0 ].data[ i ] = CH7007TV_TimingHPtr[ 0 ].data[ i ] ;
@@ -2910,7 +2867,7 @@ void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
         /* if ( pVBInfo->IF_DEF_CH7017 == 1 )
         {
             if ( pVBInfo->VBInfo & SetCRT2ToTV )
-                TVPtr = ( XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+               TVPtr = ( struct XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
         } */
 
         XGI_SetCRT1Timing_H(pVBInfo,HwDeviceExtension) ;
@@ -2925,7 +2882,7 @@ void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
 
         if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
         {
-            LCDPtr1 = ( XGI_LVDSCRT1VDataStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+           LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
             for( i = 0 ; i < 7 ; i++ )
                 pVBInfo->TimingV[ 0 ].data[ i ] = LCDPtr1[ 0 ].Reg[ i ] ;
         }
@@ -2934,7 +2891,7 @@ void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
         {
             if ( pVBInfo->VBInfo & SetCRT2ToTV )
             {
-                CH7007TV_TimingVPtr = ( XGI_CH7007TV_TimingVStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+               CH7007TV_TimingVPtr = (struct XGI_CH7007TV_TimingVStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 
                 for( i = 0 ; i < 7 ; i++ )
                     pVBInfo->TimingV[ 0 ].data[ i ] = CH7007TV_TimingVPtr[ 0 ].data[ i ] ;
@@ -2943,7 +2900,7 @@ void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
         /* if ( pVBInfo->IF_DEF_CH7017 == 1 )
         {
             if ( pVBInfo->VBInfo & SetCRT2ToTV )
-                TVPtr = ( XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+               TVPtr = ( struct XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
         } */
 
         XGI_SetCRT1Timing_V( ModeIdIndex , ModeNo , pVBInfo) ;
@@ -2966,12 +2923,14 @@ void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO  pVBInfo )
+void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+                    unsigned short RefreshRateTableIndex,
+                    struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx , tempax , tempcx , tempdx , push1 , push2 , modeflag ;
+    unsigned short tempbx , tempax , tempcx , tempdx , push1 , push2 , modeflag ;
     unsigned long temp , temp1 , temp2 , temp3 , push3 ;
-    XGI330_LCDDataDesStruct  *LCDPtr = NULL ;
-    XGI330_LCDDataDesStruct2  *LCDPtr1 = NULL ;
+    struct XGI330_LCDDataDesStruct  *LCDPtr = NULL ;
+    struct XGI330_LCDDataDesStruct2  *LCDPtr1 = NULL ;
 
     if ( ModeNo > 0x13 )
         modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
@@ -2985,16 +2944,16 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             if ( pVBInfo->IF_DEF_OEMUtil == 1 )
             {
                tempbx = 8 ;
-               LCDPtr = ( XGI330_LCDDataDesStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+               LCDPtr = (struct XGI330_LCDDataDesStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
             }
 
             if ( ( pVBInfo->IF_DEF_OEMUtil == 0 ) || ( LCDPtr == 0 ) )
             {
                 tempbx = 3 ;
                 if ( pVBInfo->LCDInfo & EnableScalingLCD )
-                    LCDPtr1 = ( XGI330_LCDDataDesStruct2 * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+                   LCDPtr1 = (struct XGI330_LCDDataDesStruct2 *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
                 else
-                    LCDPtr = ( XGI330_LCDDataDesStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+                   LCDPtr = (struct XGI330_LCDDataDesStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
             }
 
             XGI_GetLCDSync( &tempax , &tempbx ,pVBInfo) ;
@@ -3056,8 +3015,8 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             tempcx = tempcx >> 3 ;
             tempbx = tempbx >> 3 ;
 
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x16 , ( USHORT )( tempbx & 0xff ) ) ;
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x17 , ( USHORT )( tempcx & 0xff ) ) ;
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x16, (unsigned short)(tempbx & 0xff));
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x17, (unsigned short)(tempcx & 0xff));
 
             tempax = pVBInfo->HT ;
 
@@ -3085,7 +3044,7 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             tempax |= tempcx ;
 
             XGINew_SetReg1( pVBInfo->Part1Port , 0x15 , tempax ) ;
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x14 , ( USHORT )( tempbx & 0xff ) ) ;
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x14, (unsigned short)(tempbx & 0xff));
 
             tempax = pVBInfo->VT ;
             if ( pVBInfo->LCDInfo & EnableScalingLCD )
@@ -3099,13 +3058,13 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             if ( tempcx >= tempax )
                 tempcx -= tempax ;
 
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x1b , ( USHORT )( tempbx & 0xff ) ) ;
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x1c , ( USHORT )( tempcx & 0xff ) ) ;
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x1b, (unsigned short)(tempbx & 0xff));
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x1c, (unsigned short)(tempcx & 0xff));
 
             tempbx = ( tempbx >> 8 ) & 0x07 ;
             tempcx = ( tempcx >> 8 ) & 0x07 ;
 
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x1d , ( USHORT )( ( tempcx << 3 ) | tempbx ) ) ;
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x1d, (unsigned short)((tempcx << 3) | tempbx));
 
             tempax = pVBInfo->VT ;
             if ( pVBInfo->LCDInfo & EnableScalingLCD )
@@ -3123,8 +3082,8 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             if ( tempcx >= tempax )
                 tempcx -= tempax ;
 
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x18 , ( USHORT )( tempbx & 0xff ) ) ;
-            XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , ~0x0f , ( USHORT )( tempcx & 0x0f ) ) ;
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x18, (unsigned short)(tempbx & 0xff));
+           XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f, (unsigned short)(tempcx & 0x0f));
 
             tempax = ( ( tempbx >> 8 ) & 0x07 ) << 3 ;
 
@@ -3145,7 +3104,7 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             temp = tempax ;            /* 0430 ylshieh */
             temp1 = ( temp << 18 ) / tempbx ;
 
-            tempdx = ( USHORT )( ( temp << 18 ) % tempbx ) ;
+           tempdx = (unsigned short)((temp << 18) % tempbx);
 
             if ( tempdx != 0 )
             temp1 += 1 ;
@@ -3153,10 +3112,10 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             temp2 = temp1 ;
             push3 = temp2 ;
 
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x37 , ( USHORT )( temp2 & 0xff ) ) ;
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x36 , ( USHORT )( ( temp2 >> 8 ) & 0xff ) ) ;
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x37, (unsigned short)(temp2 & 0xff));
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x36, (unsigned short)((temp2 >> 8) & 0xff));
 
-            tempbx = ( USHORT )( temp2 >> 16 ) ;
+           tempbx = (unsigned short)(temp2 >> 16);
             tempax = tempbx & 0x03 ;
 
             tempbx = pVBInfo->VGAVDE ;
@@ -3168,10 +3127,10 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
             if ( pVBInfo->VBType & VB_XGI301C )
             {
                 temp2 = push3 ;
-               XGINew_SetReg1( pVBInfo->Part4Port , 0x3c , ( USHORT )( temp2 & 0xff ) ) ;
-               XGINew_SetReg1( pVBInfo->Part4Port , 0x3b , ( USHORT )( ( temp2 >> 8 ) & 0xff ) ) ;
-               tempbx = ( USHORT )( temp2 >> 16 ) ;
-               XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x3a , ~0xc0 , ( USHORT )( ( tempbx & 0xff ) << 6 ) ) ;
+               XGINew_SetReg1(pVBInfo->Part4Port, 0x3c, (unsigned short)(temp2 & 0xff));
+               XGINew_SetReg1(pVBInfo->Part4Port, 0x3b, (unsigned short)((temp2 >> 8) & 0xff));
+               tempbx = (unsigned short)(temp2 >> 16);
+               XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a, ~0xc0, (unsigned short)((tempbx & 0xff) << 6));
 
                 tempcx = pVBInfo->VGAVDE ;
                 if ( tempcx == pVBInfo->VDE )
@@ -3185,7 +3144,7 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
 
             temp1 = tempcx << 16 ;
 
-            tempax = ( USHORT )( temp1 / tempbx ) ;
+           tempax = (unsigned short)(temp1 / tempbx);
 
             if ( ( tempbx & 0xffff ) == ( tempcx & 0xffff ) )
                 tempax = 65535 ;
@@ -3199,28 +3158,28 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
 
             temp3 = ( temp3 & 0xffff0000 ) + ( temp1 & 0xffff ) ;
 
-            tempax = ( USHORT )( temp3 & 0xff ) ;
+           tempax = (unsigned short)(temp3 & 0xff);
             XGINew_SetReg1( pVBInfo->Part1Port , 0x1f , tempax ) ;
 
             temp1 = pVBInfo->VGAVDE << 18 ;
             temp1 = temp1 / push3 ;
-            tempbx = ( USHORT )( temp1 & 0xffff ) ;
+           tempbx = (unsigned short)(temp1 & 0xffff);
 
             if ( pVBInfo->LCDResInfo == Panel1024x768 )
                 tempbx -= 1 ;
 
             tempax = ( ( tempbx >> 8 ) & 0xff ) << 3 ;
-            tempax |= ( USHORT )( ( temp3 >> 8 ) & 0x07 ) ;
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x20 , ( USHORT )( tempax & 0xff ) ) ;
-            XGINew_SetReg1( pVBInfo->Part1Port , 0x21 , ( USHORT )( tempbx & 0xff ) ) ;
+           tempax |= (unsigned short)((temp3 >> 8) & 0x07);
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x20, (unsigned short)(tempax & 0xff));
+           XGINew_SetReg1(pVBInfo->Part1Port, 0x21, (unsigned short)(tempbx & 0xff));
 
             temp3 = temp3 >> 16 ;
 
             if ( modeflag & HalfDCLK )
                 temp3 = temp3 >> 1 ;
 
-            XGINew_SetReg1(pVBInfo->Part1Port , 0x22 , ( USHORT )( ( temp3 >> 8 ) & 0xff ) ) ;
-            XGINew_SetReg1(pVBInfo->Part1Port , 0x23 , ( USHORT )( temp3 & 0xff ) ) ;
+           XGINew_SetReg1(pVBInfo->Part1Port , 0x22, (unsigned short)((temp3 >> 8) & 0xff));
+           XGINew_SetReg1(pVBInfo->Part1Port , 0x23, (unsigned short)(temp3 & 0xff));
         }
     }
 }
@@ -3232,9 +3191,9 @@ void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT2ECLK( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO  pVBInfo )
+void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
 {
-    UCHAR di_0 , di_1 , tempal ;
+    unsigned char di_0, di_1, tempal;
     int i ;
 
     tempal = XGI_GetVCLKPtr( RefreshRateTableIndex , ModeNo , ModeIdIndex, pVBInfo ) ;
@@ -3243,7 +3202,7 @@ void XGI_SetCRT2ECLK( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
 
     for( i = 0 ; i < 4 ; i++ )
     {
-        XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x31 , ~0x30 , ( USHORT )( 0x10 * i ) ) ;
+       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30, (unsigned short)(0x10 * i));
         if ( pVBInfo->IF_DEF_CH7007 == 1 )
         {
             XGINew_SetReg1( pVBInfo->P3c4 , 0x2b , di_0 ) ;
@@ -3269,9 +3228,9 @@ void XGI_SetCRT2ECLK( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_UpdateModeInfo( PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO  pVBInfo )
+void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempcl ,
+    unsigned short tempcl ,
            tempch ,
            temp ,
            tempbl ,
@@ -3377,7 +3336,7 @@ void XGI_UpdateModeInfo( PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetVGAType( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO  pVBInfo)
+void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
     /*
     if ( HwDeviceExtension->jChipType >= XG20 )
@@ -3399,9 +3358,9 @@ void XGI_GetVGAType( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO  pVB
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetVBType(PVB_DEVICE_INFO  pVBInfo)
+void XGI_GetVBType(struct vb_device_info *pVBInfo)
 {
-    USHORT flag , tempbx , tempah ;
+    unsigned short flag , tempbx , tempah ;
 
     if ( pVBInfo->IF_DEF_CH7007 == 1 )
     {
@@ -3462,9 +3421,9 @@ void XGI_GetVBType(PVB_DEVICE_INFO  pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetVBInfo( USHORT ModeNo , USHORT ModeIdIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO  pVBInfo )
+void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempax ,
+    unsigned short tempax ,
            push ,
            tempbx ,
            temp ,
@@ -3703,9 +3662,9 @@ void XGI_GetVBInfo( USHORT ModeNo , USHORT ModeIdIndex , PXGI_HW_DEVICE_INFO HwD
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetTVInfo( USHORT ModeNo , USHORT ModeIdIndex ,PVB_DEVICE_INFO  pVBInfo )
+void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT temp ,
+    unsigned short temp ,
            tempbx = 0 ,
            resinfo = 0 ,
            modeflag ,
@@ -3838,9 +3797,10 @@ void XGI_GetTVInfo( USHORT ModeNo , USHORT ModeIdIndex ,PVB_DEVICE_INFO  pVBInfo
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_GetLCDInfo( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+                            struct vb_device_info *pVBInfo)
 {
-    USHORT temp ,
+    unsigned short temp ,
            tempax ,
            tempbx ,
            modeflag ,
@@ -4047,96 +4007,12 @@ BOOLEAN XGI_GetLCDInfo( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBI
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_SearchModeID( USHORT ModeNo , USHORT *ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_SearchModeID(unsigned short ModeNo,
+                              unsigned short *ModeIdIndex,
+                              struct vb_device_info *pVBInfo)
 {
 
-#ifdef TC
-
-    if ( ModeNo <= 5 )
-        ModeNo |= 1 ;
-
-    if ( ModeNo <= 0x13 )
-    {
-        /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(XGI_StStruct);(*ModeIdIndex)++) */
-        for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
-        {
-            if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == ModeNo )
-                break ;
-            if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == 0xFF )
-                return( FALSE ) ;
-        }
-
-        VGA_INFO = ( PUCHAR )MK_FP( 0 , 0x489 ) ;
-
-        if ( ModeNo == 0x07 )
-        {
-            if ( ( *VGA_INFO & 0x10 ) != 0 )
-                ( *ModeIdIndex )++ ; /* 400 lines */
-            /* else 350 lines */
-        }
-
-        if ( ModeNo <= 3 )
-        {
-            if ( ( *VGA_INFO & 0x80 ) == 0 )
-            {
-                ( *ModeIdIndex )++ ;
-                if ( ( *VGA_INFO & 0x10 ) != 0 )
-                    ( *ModeIdIndex )++ ; /* 400 lines */
-                /* else 350 lines */
-            }
-            /* else 200 lines */
-        }
-    }
-    else
-    {
-        /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(XGI_ExtStruct);(*ModeIdIndex)++) */
-        for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
-        {
-            if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == ModeNo )
-                break ;
-            if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == 0xFF )
-                return( FALSE ) ;
-        }
-    }
-
-
-#endif
-
-#ifdef WIN2000
-
-    if ( ModeNo <= 5 )
-        ModeNo |= 1 ;
-    if ( ModeNo <= 0x13 )
-    {
-        /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(XGI_StStruct);(*ModeIdIndex)++) */
-        for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
-        {
-            if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == ModeNo )
-                break ;
-            if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == 0xFF )
-                return( FALSE ) ;
-        }
-
-        if ( ModeNo == 0x07 )
-            ( *ModeIdIndex )++ ; /* 400 lines */
-
-        if ( ModeNo <=3 )
-            ( *ModeIdIndex ) += 2 ; /* 400 lines */
-        /* else 350 lines */
-    }
-    else
-    {
-        /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(XGI_ExtStruct);(*ModeIdIndex)++) */
-        for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
-        {
-            if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == ModeNo )
-                break ;
-            if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == 0xFF )
-                return( FALSE ) ;
-        }
-    }
 
-#endif
 
 #ifdef LINUX /* chiawen for linux solution */
 
@@ -4144,13 +4020,13 @@ BOOLEAN XGI_SearchModeID( USHORT ModeNo , USHORT *ModeIdIndex, PVB_DEVICE_INFO p
         ModeNo |= 1 ;
     if ( ModeNo <= 0x13 )
     {
-        /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(XGI_StStruct);(*ModeIdIndex)++) */
+       /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(struct XGI_StStruct);(*ModeIdIndex)++) */
         for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
         {
-            if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == ModeNo )
-                break ;
-            if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == 0xFF )
-                return( FALSE ) ;
+               if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
+                       break;
+               if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
+                       return 0;
         }
 
         if ( ModeNo == 0x07 )
@@ -4162,19 +4038,19 @@ BOOLEAN XGI_SearchModeID( USHORT ModeNo , USHORT *ModeIdIndex, PVB_DEVICE_INFO p
     }
     else
     {
-        /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(XGI_ExtStruct);(*ModeIdIndex)++) */
+       /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(struct XGI_ExtStruct);(*ModeIdIndex)++) */
         for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
         {
-            if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == ModeNo )
-                break ;
-            if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == 0xFF )
-                return( FALSE ) ;
+               if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
+                       break;
+               if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+                       return 0;
         }
     }
 
 #endif
 
-    return( TRUE ) ;
+    return 1;
 }
 
 
@@ -4188,9 +4064,12 @@ BOOLEAN XGI_SearchModeID( USHORT ModeNo , USHORT *ModeIdIndex, PVB_DEVICE_INFO p
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo)
+unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension,
+                                    unsigned short ModeNo,
+                                    unsigned short ModeIdIndex,
+                                    struct vb_device_info *pVBInfo)
 {
-    USHORT memorysize ,
+    unsigned short memorysize ,
            modeflag ,
            temp ,
            temp1 ,
@@ -4199,7 +4078,7 @@ BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT Mode
 /*  if ( ( HwDeviceExtension->jChipType == XGI_650 ) ||
          ( HwDeviceExtension->jChipType == XGI_650M ) )
     {
-        return( TRUE ) ;
+       return 1;
     } */
 
     if ( ModeNo <= 0x13 )
@@ -4257,10 +4136,10 @@ BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT Mode
             temp <<= 1 ;
         }
     }
-    if ( temp < memorysize )
-        return( FALSE ) ;
+    if (temp < memorysize)
+           return 0;
     else
-        return( TRUE ) ;
+           return 1;
 }
 
 
@@ -4270,10 +4149,10 @@ BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT Mode
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-/*void XGINew_IsLowResolution( USHORT ModeNo , USHORT ModeIdIndex, BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo)
+/*void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT data ;
-    USHORT ModeFlag ;
+    unsigned short data ;
+    unsigned short ModeFlag ;
 
     data = XGINew_GetReg1( pVBInfo->P3c4 , 0x0F ) ;
     data &= 0x7F ;
@@ -4302,7 +4181,7 @@ BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT Mode
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_DisplayOn( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
+void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE, struct vb_device_info *pVBInfo)
 {
 
     XGINew_SetRegANDOR(pVBInfo->P3c4,0x01,0xDF,0x00);
@@ -4331,12 +4210,6 @@ void XGI_DisplayOn( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
 
     if (pVBInfo->IF_DEF_CH7007 == 1) /* [Billy] 07/05/23 For CH7007 */
     {
-#ifdef WIN2000
-       if ( IsCH7007TVMode( pVBInfo ) )
-       {
-           TurnOnCH7007(pXGIHWDE->pDevice) ; /* 07/05/28 */
-       }
-#endif
 
     }
 
@@ -4372,7 +4245,7 @@ void XGI_DisplayOn( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_DisplayOff( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
+void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE, struct vb_device_info *pVBInfo)
 {
 
     if ( pXGIHWDE->jChipType == XG21 )
@@ -4392,9 +4265,6 @@ void XGI_DisplayOff( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
     {
        /* if( IsCH7007TVMode( pVBInfo ) == 0 ) */
        {
-#ifdef WIN2000
-         TurnOffCH7007(pXGIHWDE->pDevice) ;  /* 07/05/28 */
-#endif
        }
     }
 
@@ -4423,7 +4293,7 @@ void XGI_DisplayOff( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : chiawen for sensecrt1 */
 /* --------------------------------------------------------------------- */
-void XGI_WaitDisply( PVB_DEVICE_INFO pVBInfo )
+void XGI_WaitDisply(struct vb_device_info *pVBInfo)
 {
     while( ( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) )
         break ;
@@ -4439,58 +4309,59 @@ void XGI_WaitDisply( PVB_DEVICE_INFO pVBInfo )
 /* Description : */
 /* --------------------------------------------------------------------- */
 
-void XGI_SenseCRT1( PVB_DEVICE_INFO pVBInfo )
+void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
 {
-    UCHAR CRTCData[ 17 ] = { 0x5F , 0x4F , 0x50 , 0x82 , 0x55 , 0x81 ,
-                             0x0B , 0x3E , 0xE9 , 0x0B , 0xDF , 0xE7 ,
-                             0x04 , 0x00 , 0x00 , 0x05 , 0x00 } ;
+       unsigned char CRTCData[17] = {
+               0x5F , 0x4F , 0x50 , 0x82 , 0x55 , 0x81 ,
+               0x0B , 0x3E , 0xE9 , 0x0B , 0xDF , 0xE7 ,
+               0x04 , 0x00 , 0x00 , 0x05 , 0x00 };
 
-    UCHAR SR01 = 0 , SR1F = 0 , SR07 = 0 , SR06 = 0 ;
+       unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
 
-    UCHAR CR17 , CR63 , SR31 ;
-    USHORT temp ;
-    UCHAR DAC_TEST_PARMS[ 3 ] = { 0x0F , 0x0F , 0x0F } ;
+       unsigned char CR17, CR63, SR31;
+       unsigned short temp ;
+       unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F } ;
 
     int i ;
     XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
 
     /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
     XGINew_SetReg1( pVBInfo->P3d4 , 0x57 , 0x4A ) ;
-    XGINew_SetReg1( pVBInfo->P3d4 , 0x53 , ( UCHAR )( XGINew_GetReg1( pVBInfo->P3d4 , 0x53 ) | 0x02 ) ) ;
+    XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char)(XGINew_GetReg1(pVBInfo->P3d4, 0x53) | 0x02));
 
-    SR31 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) ;
-    CR63 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x63 ) ;
-    SR01 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x01 ) ;
+    SR31 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x31);
+    CR63 = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x63);
+    SR01 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x01);
 
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , ( UCHAR )( SR01 & 0xDF ) ) ;
-    XGINew_SetReg1( pVBInfo->P3d4 , 0x63 , ( UCHAR )( CR63 & 0xBF ) ) ;
+    XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char)(SR01 & 0xDF));
+    XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char)(CR63 & 0xBF));
 
-    CR17 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x17 ) ;
-    XGINew_SetReg1( pVBInfo->P3d4 , 0x17 , ( UCHAR )( CR17 | 0x80 ) ) ;
+    CR17 = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x17);
+    XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char)(CR17 | 0x80)) ;
 
-    SR1F = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x1F ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , ( UCHAR )( SR1F | 0x04 ) ) ;
+    SR1F = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
+    XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char)(SR1F | 0x04));
 
-    SR07 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x07 ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x07 , ( UCHAR )( SR07 & 0xFB ) ) ;
-    SR06 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x06 ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x06 , ( UCHAR )( SR06 & 0xC3 ) ) ;
+    SR07 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x07);
+    XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char)(SR07 & 0xFB));
+    SR06 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x06);
+    XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char)(SR06 & 0xC3));
 
     XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , 0x00 ) ;
 
     for( i = 0 ; i < 8 ; i++ )
-        XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )i , CRTCData[ i ] ) ;
+           XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)i, CRTCData[i]);
 
     for( i = 8 ; i < 11 ; i++ )
-        XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 8 ) , CRTCData[ i ] ) ;
+           XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 8), CRTCData[i]);
 
     for( i = 11 ; i < 13 ; i++ )
-        XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 4 ) , CRTCData[ i ] ) ;
+           XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 4), CRTCData[i]);
 
     for( i = 13 ; i < 16 ; i++ )
-        XGINew_SetReg1( pVBInfo->P3c4 , ( USHORT )( i - 3 ) , CRTCData[ i ] ) ;
+           XGINew_SetReg1(pVBInfo->P3c4, (unsigned short)(i - 3), CRTCData[i]);
 
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x0E , ( UCHAR )( CRTCData[ 16 ] & 0xE0 ) ) ;
+    XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char)(CRTCData[16] & 0xE0));
 
     XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , 0x00 ) ;
     XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x1B ) ;
@@ -4500,9 +4371,9 @@ void XGI_SenseCRT1( PVB_DEVICE_INFO pVBInfo )
 
     for( i = 0 ; i < 256 ; i++ )
     {
-        XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , ( UCHAR )DAC_TEST_PARMS[ 0 ] ) ;
-        XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , ( UCHAR )DAC_TEST_PARMS[ 1 ] ) ;
-        XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , ( UCHAR )DAC_TEST_PARMS[ 2 ] ) ;
+       XGINew_SetReg3((pVBInfo->P3c8 + 1), (unsigned char)DAC_TEST_PARMS[0]);
+       XGINew_SetReg3((pVBInfo->P3c8 + 1), (unsigned char)DAC_TEST_PARMS[1]);
+       XGINew_SetReg3((pVBInfo->P3c8 + 1), (unsigned char)DAC_TEST_PARMS[2]);
     }
 
     XGI_VBLongWait( pVBInfo ) ;
@@ -4538,148 +4409,18 @@ void XGI_SenseCRT1( PVB_DEVICE_INFO pVBInfo )
     XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , SR31 ) ;
 
     /* [2004/05/11] Vicent */
-    XGINew_SetReg1( pVBInfo->P3d4 , 0x53 , ( UCHAR )( XGINew_GetReg1( pVBInfo->P3d4 , 0x53 ) & 0xFD ) ) ;
-    XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , ( UCHAR ) SR1F ) ;
+    XGINew_SetReg1(pVBInfo->P3d4, 0x53,
+                  (unsigned char)(XGINew_GetReg1(pVBInfo->P3d4, 0x53) & 0xFD));
+    XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char)SR1F);
 }
 
 
 
 
 
-#ifdef TC
-/* --------------------------------------------------------------------- */
-/* Function : INT1AReturnCode */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int INT1AReturnCode( union REGS regs )
-{
-    if ( regs.x.cflag )
-    {
-        /* printf( "Error to find pci device!\n" ) ; */
-        return( 1 ) ;
-    }
 
-    switch(regs.h.ah)
-    {
-        case 0: return 0;
-            break ;
-        case 0x81:
-            printf( "Function not support\n" ) ;
-            break ;
-        case 0x83:
-            printf( "bad vendor id\n" ) ;
-            break ;
-        case 0x86:
-            printf( "device not found\n" ) ;
-            break ;
-        case 0x87:
-            printf( "bad register number\n" ) ;
-            break ;
-        case 0x88:
-            printf( "set failed\n" ) ;
-            break ;
-        case 0x89:
-            printf( "buffer too small" ) ;
-            break ;
-        default:
-            break ;
-    }
-    return( 1 ) ;
-}
 
 
-/* --------------------------------------------------------------------- */
-/* Function : FindPCIIOBase */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned FindPCIIOBase( unsigned index , unsigned deviceid )
-{
-    union REGS regs ;
-
-    regs.h.ah = 0xb1 ; /* PCI_FUNCTION_ID */
-    regs.h.al = 0x02 ; /* FIND_PCI_DEVICE */
-    regs.x.cx = deviceid ;
-    regs.x.dx = 0x1039 ;
-    regs.x.si = index ;        /* find n-th device */
-
-    int86( 0x1A , &regs , &regs ) ;
-
-    if ( INT1AReturnCode( regs ) != 0 )
-        return( 0 ) ;
-
-    /* regs.h.bh bus number */
-    /* regs.h.bl device number */
-    regs.h.ah = 0xb1 ;  /* PCI_FUNCTION_ID */
-    regs.h.al = 0x09 ;  /* READ_CONFIG_WORD */
-    regs.x.cx = deviceid ;
-    regs.x.dx = 0x1039 ;
-    regs.x.di = 0x18 ;  /* register number */
-    int86( 0x1A , &regs , &regs ) ;
-
-    if ( INT1AReturnCode( regs ) != 0 )
-        return( 0 ) ;
-
-    return( regs.x.cx ) ;
-}
-
-#endif
-
-
-
-#ifdef TC
-/* --------------------------------------------------------------------- */
-/* Function : main */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void main(int argc, char *argv[])
-{
-    XGI_HW_DEVICE_INFO HwDeviceExtension ;
-    USHORT temp ;
-    USHORT ModeNo ;
-
-    /* HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
-    /* HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0); */
-
-
-    HwDeviceExtension.pjIOAddress = ( FindPCIIOBase( 0 ,0x6300 ) & 0xFF80 ) + 0x30 ;
-    HwDeviceExtension.jChipType = XGI_340 ;
-
-
-
-    /* HwDeviceExtension.pjIOAddress = ( FindPCIIOBase( 0 , 0x5315 ) & 0xFF80 ) + 0x30 ; */
-
-    HwDeviceExtension.pjIOAddress = ( FindPCIIOBase( 0 , 0x330 ) & 0xFF80 ) + 0x30 ;
-    HwDeviceExtension.jChipType = XGI_340 ;
-
-
-    HwDeviceExtension.ujVBChipID = VB_CHIP_301 ;
-    StrCpy(HwDeviceExtension.szVBIOSVer , "0.84" ) ;
-    HwDeviceExtension.bSkipDramSizing = FALSE ;
-    HwDeviceExtension.ulVideoMemorySize = 0 ;
-
-    if ( argc == 2 )
-    {
-        ModeNo = atoi( argv[ 1 ] ) ;
-    }
-    else
-    {
-        ModeNo = 0x2e ;
-        /* ModeNo = 0x37 ; 1024x768x 4bpp */
-        /* ModeNo = 0x38 ; 1024x768x 8bpp */
-        /* ModeNo = 0x4A ; 1024x768x 16bpp */
-        /* ModeNo = 0x47 ; 800x600x 16bpp */
-    }
-
-    /* XGIInitNew( &HwDeviceExtension ) ; */
-    XGISetModeNew( &HwDeviceExtension , ModeNo ) ;
-}
-#endif
 
 
 /* --------------------------------------------------------------------- */
@@ -4688,7 +4429,7 @@ void main(int argc, char *argv[])
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_WaitDisplay( PVB_DEVICE_INFO pVBInfo )
+void XGI_WaitDisplay(struct vb_device_info *pVBInfo)
 {
     while( !( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) ) ;
 
@@ -4704,9 +4445,11 @@ void XGI_WaitDisplay( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_SetCRT2Group301( USHORT ModeNo , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
+                                 struct xgi_hw_device_info *HwDeviceExtension,
+                                 struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ,
+    unsigned short tempbx ,
            ModeIdIndex ,
            RefreshRateTableIndex ;
 
@@ -4739,7 +4482,7 @@ BOOLEAN XGI_SetCRT2Group301( USHORT ModeNo , PXGI_HW_DEVICE_INFO HwDeviceExtensi
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_AutoThreshold(  PVB_DEVICE_INFO pVBInfo )
+void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
 {
     if ( !( pVBInfo->SetFlag & Win9xDOSMode ) )
       XGINew_SetRegOR( pVBInfo->Part1Port , 0x01 , 0x40 ) ;
@@ -4752,9 +4495,9 @@ void XGI_AutoThreshold(  PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SaveCRT2Info( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo)
+void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo)
 {
-    USHORT temp1 ,
+    unsigned short temp1 ,
            temp2 ;
 
     XGINew_SetReg1( pVBInfo->P3d4 , 0x34 , ModeNo ) ;  /* reserve CR34 for CRT1 Mode No */
@@ -4770,9 +4513,11 @@ void XGI_SaveCRT2Info( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetCRT2ResInfo( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_GetCRT2ResInfo(unsigned short ModeNo,
+                       unsigned short ModeIdIndex,
+                       struct vb_device_info *pVBInfo)
 {
-    USHORT xres ,
+    unsigned short xres ,
            yres ,
            modeflag ,
            resindex ;
@@ -4867,7 +4612,7 @@ void XGI_GetCRT2ResInfo( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVB
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_IsLCDDualLink( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
 {
 
     if ( ( ( ( pVBInfo->VBInfo & SetCRT2ToLCD ) | SetCRT2ToLCDA ) ) && ( pVBInfo->LCDInfo & SetLCDDualLink ) ) /* shampoo0129 */
@@ -4883,15 +4628,15 @@ BOOLEAN XGI_IsLCDDualLink( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetCRT2Data(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT tempax = 0,
+    unsigned short tempax = 0,
            tempbx ,
            modeflag ,
            resinfo ;
 
-    XGI_LCDDataStruct *LCDPtr = NULL ;
-    XGI_TVDataStruct  *TVPtr = NULL ;
+    struct XGI_LCDDataStruct *LCDPtr = NULL ;
+    struct XGI_TVDataStruct  *TVPtr = NULL ;
 
     if ( ModeNo <= 0x13 )
     {
@@ -4917,7 +4662,7 @@ void XGI_GetCRT2Data(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTa
 
     if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
     {
-        LCDPtr = (XGI_LCDDataStruct* )XGI_GetLcdPtr( tempbx, ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+       LCDPtr = (struct XGI_LCDDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 
         pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX ;
         pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT ;
@@ -5021,7 +4766,7 @@ void XGI_GetCRT2Data(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTa
     if ( pVBInfo->VBInfo & ( SetCRT2ToTV ) )
     {
         tempbx = 4 ;
-        TVPtr = ( XGI_TVDataStruct * )XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+       TVPtr = (struct XGI_TVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 
         pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX ;
         pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT ;
@@ -5109,11 +4854,9 @@ void XGI_GetCRT2Data(  USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTa
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT2VCLK( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
 {
-    UCHAR di_0 ,
-          di_1 ,
-          tempal ;
+       unsigned char di_0, di_1, tempal;
 
     tempal = XGI_GetVCLKPtr( RefreshRateTableIndex , ModeNo , ModeIdIndex, pVBInfo ) ;
     XGI_GetVCLKLen( tempal, &di_0 , &di_1, pVBInfo ) ;
@@ -5146,9 +4889,10 @@ void XGI_SetCRT2VCLK( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTab
 /* Output : al -> VCLK Index */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetLCDVCLKPtr( UCHAR* di_0 , UCHAR *di_1, PVB_DEVICE_INFO pVBInfo )
+void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
+                      struct vb_device_info *pVBInfo)
 {
-    USHORT index ;
+    unsigned short index ;
 
     if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
     {
@@ -5182,17 +4926,16 @@ void XGI_GetLCDVCLKPtr( UCHAR* di_0 , UCHAR *di_1, PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGI_GetVCLKPtr(USHORT RefreshRateTableIndex,USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
+                            unsigned short ModeNo, unsigned short ModeIdIndex,
+                            struct vb_device_info *pVBInfo)
 {
 
-    USHORT index ,
+    unsigned short index ,
            modeflag ;
-#ifndef LINUX_XF86
-    USHORT tempbx ;
-#endif
-
-    UCHAR tempal ;
-    UCHAR *CHTVVCLKPtr = NULL ;
+    unsigned short tempbx ;
+    unsigned char tempal;
+    unsigned char *CHTVVCLKPtr = NULL;
 
     if ( ModeNo <= 0x13 )
         modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;      /* si+St_ResInfo */
@@ -5344,7 +5087,7 @@ UCHAR XGI_GetVCLKPtr(USHORT RefreshRateTableIndex,USHORT ModeNo,USHORT ModeIdInd
 
     }
 
-    tempal = ( UCHAR )XGINew_GetReg2( ( pVBInfo->P3ca + 0x02 ) ) ;
+    tempal = (unsigned char)XGINew_GetReg2((pVBInfo->P3ca + 0x02));
     tempal = tempal >> 2 ;
     tempal &= 0x03 ;
 
@@ -5365,19 +5108,20 @@ UCHAR XGI_GetVCLKPtr(USHORT RefreshRateTableIndex,USHORT ModeNo,USHORT ModeIdInd
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetVCLKLen(UCHAR tempal,UCHAR* di_0,UCHAR* di_1, PVB_DEVICE_INFO pVBInfo)
+void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
+                   unsigned char *di_1, struct vb_device_info *pVBInfo)
 {
     if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 2007/05/16 */
     {
        /* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
-        *di_0 = ( UCHAR )XGI_CH7007VCLKData[ tempal ].SR2B ;
-        *di_1 = ( UCHAR )XGI_CH7007VCLKData[ tempal ].SR2C ;
+       *di_0 = (unsigned char)XGI_CH7007VCLKData[tempal].SR2B;
+       *di_1 = (unsigned char)XGI_CH7007VCLKData[tempal].SR2C;
     }
     else if ( pVBInfo->VBType & ( VB_XGI301 | VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
     {
         if ( ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) && ( pVBInfo->SetFlag & ProgrammingCRT2 ) )
         {
-            *di_0 = ( UCHAR )XGI_VBVCLKData[ tempal ].SR2B ;
+           *di_0 = (unsigned char)XGI_VBVCLKData[tempal].SR2B;
             *di_1 = XGI_VBVCLKData[ tempal ].SR2C ;
         }
     }
@@ -5395,11 +5139,14 @@ void XGI_GetVCLKLen(UCHAR tempal,UCHAR* di_0,UCHAR* di_1, PVB_DEVICE_INFO pVBInf
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT2Offset( USHORT ModeNo ,
-                                  USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetCRT2Offset(unsigned short ModeNo,
+                      unsigned short ModeIdIndex,
+                      unsigned short RefreshRateTableIndex,
+                      struct xgi_hw_device_info *HwDeviceExtension,
+                      struct vb_device_info *pVBInfo)
 {
-    USHORT offset ;
-    UCHAR temp ;
+    unsigned short offset ;
+    unsigned char temp;
 
     if ( pVBInfo->VBInfo & SetInSlaveMode )
     {
@@ -5407,12 +5154,12 @@ void XGI_SetCRT2Offset( USHORT ModeNo ,
     }
 
     offset = XGI_GetOffset(  ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
-    temp = ( UCHAR )( offset & 0xFF ) ;
+    temp = (unsigned char)(offset & 0xFF);
     XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , temp ) ;
-    temp =( UCHAR)( ( offset & 0xFF00 ) >> 8 ) ;
-    XGINew_SetReg1( pVBInfo->Part1Port , 0x09 , temp ) ;
-    temp =( UCHAR )( ( ( offset >> 3 ) & 0xFF ) + 1 ) ;
-    XGINew_SetReg1( pVBInfo->Part1Port , 0x03 , temp ) ;
+    temp = (unsigned char)((offset & 0xFF00) >> 8);
+    XGINew_SetReg1(pVBInfo->Part1Port , 0x09 , temp);
+    temp = (unsigned char)(((offset >> 3) & 0xFF) + 1) ;
+    XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
 }
 
 
@@ -5422,9 +5169,9 @@ void XGI_SetCRT2Offset( USHORT ModeNo ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetOffset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo)
+unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT temp ,
+    unsigned short temp ,
            colordepth ,
            modeinfo ,
            index ,
@@ -5471,7 +5218,7 @@ USHORT XGI_GetOffset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableInd
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT2FIFO( PVB_DEVICE_INFO pVBInfo)
+void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
 {
     XGINew_SetReg1( pVBInfo->Part1Port , 0x01 , 0x3B ) ;                       /* threshold high ,disable auto threshold */
     XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x02 , ~( 0x3F ) , 0x04 ) ;       /* threshold low default 04h */
@@ -5484,10 +5231,12 @@ void XGI_SetCRT2FIFO( PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_PreSetGroup1(USHORT ModeNo , USHORT ModeIdIndex ,PXGI_HW_DEVICE_INFO HwDeviceExtension,
-                       USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+                     struct xgi_hw_device_info *HwDeviceExtension,
+                     unsigned short RefreshRateTableIndex,
+                     struct vb_device_info *pVBInfo)
 {
-    USHORT tempcx = 0 ,
+    unsigned short tempcx = 0 ,
            CRT1Index = 0 ,
            resinfo = 0 ;
 
@@ -5518,10 +5267,12 @@ void XGI_PreSetGroup1(USHORT ModeNo , USHORT ModeIdIndex ,PXGI_HW_DEVICE_INFO Hw
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetGroup1( USHORT ModeNo , USHORT ModeIdIndex ,
-                            PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+                  struct xgi_hw_device_info *HwDeviceExtension,
+                  unsigned short RefreshRateTableIndex,
+                  struct vb_device_info *pVBInfo)
 {
-    USHORT temp = 0 ,
+    unsigned short temp = 0 ,
            tempax = 0 ,
            tempbx = 0 ,
            tempcx = 0 ,
@@ -5694,10 +5445,12 @@ void XGI_SetGroup1( USHORT ModeNo , USHORT ModeIdIndex ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void  XGI_SetLockRegs( USHORT ModeNo , USHORT ModeIdIndex ,
-                                PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void  XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+                     struct xgi_hw_device_info *HwDeviceExtension,
+                     unsigned short RefreshRateTableIndex,
+                     struct vb_device_info *pVBInfo)
 {
-    USHORT push1 ,
+    unsigned short push1 ,
            push2 ,
            tempax ,
            tempbx = 0 ,
@@ -6141,10 +5894,10 @@ void  XGI_SetLockRegs( USHORT ModeNo , USHORT ModeIdIndex ,
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-                    PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
+                  struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT i ,
+    unsigned short i ,
            j ,
            tempax ,
            tempbx ,
@@ -6155,9 +5908,9 @@ void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIn
            modeflag ,
            resinfo ,
            crt2crtc ;
-    UCHAR *TimingPoint ;
+    unsigned char *TimingPoint ;
 
-    ULONG longtemp ,
+    unsigned long longtemp ,
           tempeax ,
           tempebx ,
           temp2 ,
@@ -6266,7 +6019,7 @@ void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIn
         tempax = ( tempax & 0x00FF ) | ( ( tempax & 0x00FF ) << 8 ) ;
         push1 = tempax ;
         temp = ( tempax & 0xFF00 ) >> 8 ;
-        temp += ( USHORT )TimingPoint[ 0 ] ;
+       temp += (unsigned short)TimingPoint[0];
 
         if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
         {
@@ -6543,7 +6296,7 @@ void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIn
             tempeax += 1 ;
         }
 
-        tempax = ( USHORT )tempeax ;
+       tempax = (unsigned short)tempeax;
 
        /* 301b */
         if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
@@ -6553,8 +6306,8 @@ void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIn
         /* end 301b */
 
         tempbx = push1 ;
-        tempbx =( USHORT )( ( ( tempeax & 0x0000FF00 ) & 0x1F00 ) | ( tempbx & 0x00FF ) ) ;
-        tempax =( USHORT )( ( ( tempeax & 0x000000FF ) << 8 ) | ( tempax & 0x00FF ) ) ;
+       tempbx = (unsigned short)(((tempeax & 0x0000FF00) & 0x1F00) | (tempbx & 0x00FF));
+       tempax = (unsigned short)(((tempeax & 0x000000FF) << 8) | (tempax & 0x00FF));
         temp = ( tempax & 0xFF00 ) >> 8 ;
     }
     else
@@ -6607,7 +6360,7 @@ void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIn
 
     XGINew_SetReg1( pVBInfo->Part2Port , 0x4d , temp ) ;
     temp=XGINew_GetReg1( pVBInfo->Part2Port , 0x43 ) ;         /* 301b change */
-    XGINew_SetReg1( pVBInfo->Part2Port , 0x43 , ( USHORT )( temp - 3 ) ) ;
+    XGINew_SetReg1( pVBInfo->Part2Port , 0x43, (unsigned short)( temp - 3 ) ) ;
 
     if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) )
     {
@@ -6631,7 +6384,7 @@ void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIn
 
     if ( pVBInfo->TVInfo & SetPALMTV )
     {
-        tempax = ( UCHAR )XGINew_GetReg1( pVBInfo->Part2Port , 0x01 ) ;
+       tempax = (unsigned char)XGINew_GetReg1(pVBInfo->Part2Port, 0x01);
         tempax-- ;
         XGINew_SetRegAND( pVBInfo->Part2Port , 0x01 , tempax ) ;
 
@@ -6660,9 +6413,9 @@ void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIn
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void  XGI_SetLCDRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+void  XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT push1 ,
+    unsigned short push1 ,
            push2 ,
            pushbx ,
            tempax ,
@@ -6676,7 +6429,7 @@ void  XGI_SetLCDRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDev
            modeflag ,
            CRT1Index ;
 
-    XGI_LCDDesStruct *LCDBDesPtr = NULL ;
+    struct XGI_LCDDesStruct *LCDBDesPtr = NULL ;
 
 
     if ( ModeNo <= 0x13 )
@@ -6746,7 +6499,7 @@ void  XGI_SetLCDRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDev
 
     /* Customized LCDB Des no add */
     tempbx = 5 ;
-    LCDBDesPtr = ( XGI_LCDDesStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+    LCDBDesPtr = (struct XGI_LCDDesStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
     tempah = pVBInfo->LCDResInfo ;
     tempah &= PanelResInfo ;
 
@@ -6914,13 +6667,14 @@ void  XGI_SetLCDRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDev
 /* Output : di -> Tap4 Reg. Setting Pointer */
 /* Description : */
 /* --------------------------------------------------------------------- */
-XGI301C_Tap4TimingStruct* XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
+struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
+                                        struct vb_device_info *pVBInfo)
 {
-    USHORT tempax ,
+    unsigned short tempax ,
            tempbx ,
            i ;
 
-    XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
+    struct XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
 
     if ( tempcx == 0 )
     {
@@ -6974,12 +6728,12 @@ XGI301C_Tap4TimingStruct* XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetTap4Regs( PVB_DEVICE_INFO pVBInfo)
+void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
 {
-    USHORT i ,
+    unsigned short i ,
            j ;
 
-    XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
+    struct XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
 
     if ( !( pVBInfo->VBType & VB_XGI301C ) )
         return ;
@@ -7012,11 +6766,11 @@ void XGI_SetTap4Regs( PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetGroup3(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT i;
-    UCHAR *tempdi;
-    USHORT  modeflag;
+    unsigned short i;
+    unsigned char *tempdi;
+    unsigned short  modeflag;
 
     if(ModeNo<=0x13)
     {
@@ -7099,16 +6853,16 @@ void XGI_SetGroup3(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetGroup4(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempax ,
+    unsigned short tempax ,
            tempcx ,
            tempbx ,
            modeflag ,
            temp ,
            temp2 ;
 
-    ULONG tempebx ,
+    unsigned long tempebx ,
           tempeax ,
           templong ;
 
@@ -7230,12 +6984,12 @@ void XGI_SetGroup4(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex
     }
 
 
-    temp = ( USHORT )( tempebx & 0x000000FF ) ;
+    temp = (unsigned short)(tempebx & 0x000000FF);
     XGINew_SetReg1( pVBInfo->Part4Port , 0x1B , temp ) ;
 
-    temp = ( USHORT )( ( tempebx & 0x0000FF00 ) >> 8 ) ;
+    temp = (unsigned short)((tempebx & 0x0000FF00) >> 8);
     XGINew_SetReg1( pVBInfo->Part4Port , 0x1A , temp ) ;
-    tempbx = ( USHORT )( tempebx >> 16 ) ;
+    tempbx = (unsigned short)(tempebx >> 16);
     temp = tempbx & 0x00FF ;
     temp = temp << 4 ;
     temp |= ( ( tempcx & 0xFF00 ) >> 8 ) ;
@@ -7350,9 +7104,9 @@ void XGI_SetGroup4(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetGroup5( USHORT ModeNo , USHORT ModeIdIndex , PVB_DEVICE_INFO pVBInfo)
+void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT Pindex ,
+    unsigned short Pindex ,
            Pdata ;
 
     Pindex = pVBInfo->Part5Port ;
@@ -7375,9 +7129,13 @@ void XGI_SetGroup5( USHORT ModeNo , USHORT ModeIdIndex , PVB_DEVICE_INFO pVBInfo
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void* XGI_GetLcdPtr( USHORT BX , USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void *XGI_GetLcdPtr(unsigned short BX,
+                   unsigned short ModeNo,
+                   unsigned short ModeIdIndex,
+                   unsigned short RefreshRateTableIndex,
+                   struct vb_device_info *pVBInfo)
 {
-    USHORT i ,
+    unsigned short i ,
            tempdx ,
            tempcx ,
            tempbx ,
@@ -7385,7 +7143,7 @@ void* XGI_GetLcdPtr( USHORT BX , USHORT ModeNo , USHORT ModeIdIndex , USHORT Ref
            modeflag ,
            table ;
 
-    XGI330_LCDDataTablStruct *tempdi = 0 ;
+    struct XGI330_LCDDataTablStruct *tempdi = 0 ;
 
 
     tempbx = BX;
@@ -7877,10 +7635,13 @@ void* XGI_GetLcdPtr( USHORT BX , USHORT ModeNo , USHORT ModeIdIndex , USHORT Ref
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void* XGI_GetTVPtr (USHORT BX,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
+                  unsigned short ModeIdIndex,
+                  unsigned short RefreshRateTableIndex,
+                  struct vb_device_info *pVBInfo)
 {
-    USHORT i , tempdx , tempbx , tempal , modeflag , table ;
-    XGI330_TVDataTablStruct *tempdi = 0 ;
+    unsigned short i , tempdx , tempbx , tempal , modeflag , table ;
+    struct XGI330_TVDataTablStruct *tempdi = 0 ;
 
     tempbx = BX ;
 
@@ -7955,53 +7716,9 @@ void* XGI_GetTVPtr (USHORT BX,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRat
 
     if ( table == 0x00 ) /* 07/05/22 */
     {
-#ifdef WIN2000
-        if ( pVBInfo->IF_DEF_CH7007 == 1 )
-        {
-          switch( tempdi[ i ].DATAPTR )
-          {
-            case 0:
-                return &CH7007TVCRT1UNTSC_H[ tempal ] ;
-                break ;
-            case 1:
-                return &CH7007TVCRT1ONTSC_H[ tempal ] ;
-                break ;
-            case 2:
-                return &CH7007TVCRT1UPAL_H[ tempal ] ;
-                break ;
-            case 3:
-                return &CH7007TVCRT1OPAL_H[ tempal ] ;
-                break ;
-            default:
-                break ;
-          }
-        }
-#endif
     }
     else if ( table == 0x01 )
     {
-#ifdef WIN2000
-        if ( pVBInfo->IF_DEF_CH7007 == 1 )
-        {
-          switch( tempdi[ i ].DATAPTR )
-          {
-            case 0:
-                return &CH7007TVCRT1UNTSC_V[ tempal ] ;
-                break ;
-            case 1:
-                return &CH7007TVCRT1ONTSC_V[ tempal ] ;
-                break ;
-            case 2:
-                return &CH7007TVCRT1UPAL_V[ tempal ] ;
-                break ;
-            case 3:
-                return &CH7007TVCRT1OPAL_V[ tempal ] ;
-                break ;
-            default:
-                break ;
-          }
-        }
-#endif
     }
     else if ( table == 0x04 )
     {
@@ -8075,49 +7792,6 @@ void* XGI_GetTVPtr (USHORT BX,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRat
     }
     else if( table == 0x06 )
     {
-#ifdef WIN2000
-        if ( pVBInfo->IF_DEF_CH7007 == 1 )
-        {
-          /* VideoDebugPrint((0, "XGI_GetTVPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
-          switch( tempdi[ i ].DATAPTR )
-          {
-            case 0:
-                return &CH7007TVReg_UNTSC[ tempal ] ;
-                break ;
-            case 1:
-                return &CH7007TVReg_ONTSC[ tempal ] ;
-                break ;
-            case 2:
-                return &CH7007TVReg_UPAL[ tempal ] ;
-                break ;
-            case 3:
-                return &CH7007TVReg_OPAL[ tempal ] ;
-                break ;
-            default:
-                break ;
-          }
-        }
-        else
-        {
-            switch( tempdi[ i ].DATAPTR )
-            {
-              case 0:
-                return &XGI_CHTVRegUNTSC[ tempal ] ;
-                break ;
-              case 1:
-                return &XGI_CHTVRegONTSC[ tempal ] ;
-                break ;
-              case 2:
-                return &XGI_CHTVRegUPAL[ tempal ] ;
-                break ;
-              case 3:
-                return &XGI_CHTVRegOPAL[ tempal ] ;
-                break ;
-              default:
-                break ;
-            }
-        }
-#endif
     }
     return( 0 ) ;
 }
@@ -8126,18 +7800,18 @@ void* XGI_GetTVPtr (USHORT BX,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRat
 /* --------------------------------------------------------------------- */
 /* Function : XGI_BacklightByDrv */
 /* Input : */
-/* Output : TRUE -> Skip backlight control */
+/* Output : 1 -> Skip backlight control */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_BacklightByDrv( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo)
 {
-    UCHAR tempah ;
+    unsigned char tempah ;
 
-    tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x3A ) ;
-    if ( tempah & BacklightControlBit )
-        return TRUE ;
+    tempah = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x3A) ;
+    if (tempah & BacklightControlBit)
+           return 1;
     else
-        return FALSE ;
+           return 0;
 }
 
 
@@ -8148,7 +7822,7 @@ BOOLEAN XGI_BacklightByDrv( PVB_DEVICE_INFO pVBInfo )
 /* Description : Turn off VDD & Backlight : Fire disable procedure */
 /* --------------------------------------------------------------------- */
 /*
-void XGI_FirePWDDisable( PVB_DEVICE_INFO pVBInfo )
+void XGI_FirePWDDisable(struct vb_device_info *pVBInfo)
 {
     XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x26 , 0x00 , 0xFC ) ;
 }
@@ -8160,7 +7834,7 @@ void XGI_FirePWDDisable( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : Turn on VDD & Backlight : Fire enable procedure */
 /* --------------------------------------------------------------------- */
-void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo )
+void XGI_FirePWDEnable(struct vb_device_info *pVBInfo)
 {
     XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x26 , 0x03 , 0xFC ) ;
 }
@@ -8172,7 +7846,7 @@ void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
     XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x63 , 0xBF , 0x40 ) ;
 }
@@ -8184,7 +7858,7 @@ void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
 
     XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x63 , 0xBF , 0x00 ) ;
@@ -8201,9 +7875,9 @@ void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO
 /* : bl : 3 ; T3 : the duration between CPL off and signal off */
 /* : bl : 4 ; T4 : the duration signal off and Vdd off */
 /* --------------------------------------------------------------------- */
-void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo)
 {
-    USHORT index ;
+    unsigned short index ;
 
     index = XGI_GetLCDCapPtr(pVBInfo) ;
 
@@ -8231,7 +7905,7 @@ void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
 /* = 1011b = 0Bh ; Backlight off, Power on */
 /* = 1111b = 0Fh ; Backlight off, Power off */
 /* --------------------------------------------------------------------- */
-void XGI_SetPanelPower(USHORT tempah,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, struct vb_device_info *pVBInfo)
 {
     if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
         XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x26 , tempbl , tempah ) ;
@@ -8239,10 +7913,10 @@ void XGI_SetPanelPower(USHORT tempah,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
         XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x11 , tempbl , tempah ) ;
 }
 
-UCHAR XG21GPIODataTransfer(UCHAR ujDate)
+unsigned char XG21GPIODataTransfer(unsigned char ujDate)
 {
-    UCHAR  ujRet = 0;
-    UCHAR  i = 0;
+    unsigned char  ujRet = 0;
+    unsigned char  i = 0;
 
     for (i=0; i<8; i++)
        {
@@ -8260,9 +7934,9 @@ UCHAR XG21GPIODataTransfer(UCHAR ujDate)
 /*      bl[1] : LVDS backlight                                                */
 /*      bl[0] : LVDS VDD                                                      */
 /*----------------------------------------------------------------------------*/
-UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo)
+unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
 {
-    UCHAR CR4A,temp;
+    unsigned char CR4A, temp;
 
     CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
     XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x23 ) ; /* enable GPIO write */
@@ -8281,9 +7955,9 @@ UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo)
 /*      bl[1] : LVDS backlight                                                */
 /*      bl[0] : LVDS VDD                                                      */
 /*----------------------------------------------------------------------------*/
-UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo)
+unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
 {
-    UCHAR CR4A,CRB4,temp;
+    unsigned char CR4A, CRB4, temp;
 
     CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
     XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x0C ) ; /* enable GPIO write */
@@ -8306,9 +7980,9 @@ UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo)
 /*          000010b : clear bit 1, to set bit1                                */
 /*          000001b : clear bit 0, to set bit0                                */
 /*----------------------------------------------------------------------------*/
-void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo)
 {
-    UCHAR CR4A,temp;
+    unsigned char CR4A, temp;
 
     CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
     tempbh &= 0x23;
@@ -8331,10 +8005,10 @@ void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
     XGINew_SetReg1( pVBInfo->P3d4 , 0x48 , temp ) ;
 }
 
-void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo)
 {
-    UCHAR CR4A,temp;
-    USHORT tempbh0,tempbl0;
+    unsigned char CR4A, temp;
+    unsigned short tempbh0, tempbl0;
 
     tempbh0 = tempbh;
     tempbl0 = tempbl;
@@ -8362,15 +8036,13 @@ void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
 }
 
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo)
+unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo)
 {
-    USHORT index ;
+    unsigned short index ;
 
     index = XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ;
-    if (index<sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct))
-    {
-      return index;
-    }
+    if (index < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct))
+           return index;
     return 0;
 }
 
@@ -8384,9 +8056,9 @@ USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo)
 /* : bl : 3 ; T3 : the duration between CPL off and signal off */
 /* : bl : 4 ; T4 : the duration signal off and Vdd off */
 /* --------------------------------------------------------------------- */
-void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+void XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo)
 {
-    USHORT index ;
+    unsigned short index ;
 
     index = XGI_GetLVDSOEMTableIndex( pVBInfo );
     if ( tempbl == 1 )
@@ -8402,9 +8074,11 @@ void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
         XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S4, pVBInfo ) ;
 }
 
-BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo,
+                                   unsigned short ModeIdIndex,
+                                   struct vb_device_info *pVBInfo)
 {
-    USHORT xres ,
+    unsigned short xres ,
            yres ,
            colordepth ,
            modeflag ,
@@ -8445,10 +8119,10 @@ BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO
 
     lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
     if ( xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) )
-      return FALSE;
+           return 0;
 
     if ( yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE) )
-      return FALSE;
+           return 0;
 
     if ( ModeNo > 0x13 )
     {
@@ -8456,18 +8130,17 @@ BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO
            ( yres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE)) )
       {
           colordepth = XGI_GetColorDepth( ModeNo , ModeIdIndex, pVBInfo ) ;
-          if ( colordepth > 2 )
-          {
-            return FALSE;
-          }
+         if (colordepth > 2)
+                 return 0;
+
       }
     }
-    return TRUE;
+    return 1;
 }
 
-void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
+void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
 {
-    UCHAR temp;
+    unsigned char temp;
 
     temp = XGINew_GetReg1( pVBInfo->P3d4  , 0x37 ) ;  /* D[0] 1: 18bit */
     temp = ( temp & 1 ) << 6;
@@ -8476,9 +8149,9 @@ void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
 
 }
 
-void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
+void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
 {
-    UCHAR temp;
+    unsigned char temp;
 
     temp = XGINew_GetReg1( pVBInfo->P3d4  , 0x37 ) ;  /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
     temp = ( temp & 3 ) << 6;
@@ -8487,27 +8160,28 @@ void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
 
 }
 
-void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
+                        struct vb_device_info *pVBInfo)
 {
-    UCHAR temp,Miscdata;
-    USHORT xres ,
+    unsigned char temp, Miscdata;
+    unsigned short xres ,
            yres ,
            modeflag ,
            resindex ,
            lvdstableindex ;
-    USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
-    USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
-    USHORT value;
+    unsigned short LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
+    unsigned short LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
+    unsigned short value;
 
     lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
 
-    temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
+    temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8)) >> 8);
     temp &= LCDPolarity;
-    Miscdata =(UCHAR) XGINew_GetReg2(pVBInfo->P3cc) ;
+    Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc) ;
 
     XGINew_SetReg3( pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
 
-    temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
+    temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity) ;
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ;      /* SR35[7] FP VSync polarity */
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ;   /* SR30[5] FP HSync polarity */
 
@@ -8563,7 +8237,7 @@ void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBIn
 
     LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
 
-    temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
+    temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11) ;
     XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ;             /* Unlock CRTC */
 
     if (!( modeflag & Charx8Dot ))
@@ -8670,26 +8344,27 @@ void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBIn
 }
 
 /* no shadow case */
-void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
+                        struct vb_device_info *pVBInfo)
 {
-    UCHAR temp,Miscdata;
-    USHORT xres ,
+    unsigned char temp, Miscdata;
+    unsigned short xres ,
            yres ,
            modeflag ,
            resindex ,
            lvdstableindex ;
-    USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
-    USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
-    USHORT value;
+    unsigned short LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
+    unsigned short LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
+    unsigned short value;
 
     lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
-    temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
+    temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8)) >> 8);
     temp &= LCDPolarity;
-    Miscdata =(UCHAR) XGINew_GetReg2(pVBInfo->P3cc) ;
+    Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc);
 
     XGINew_SetReg3( pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
 
-    temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
+    temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity) ;
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ;      /* SR35[7] FP VSync polarity */
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ;   /* SR30[5] FP HSync polarity */
 
@@ -8745,7 +8420,7 @@ void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBIn
 
     LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
 
-    temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
+    temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11) ;
     XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ;             /* Unlock CRTC */
 
     if (!( modeflag & Charx8Dot ))
@@ -8853,21 +8528,21 @@ void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBIn
 /* --------------------------------------------------------------------- */
 /* Function : XGI_IsLCDON */
 /* Input : */
-/* Output : FALSE : Skip PSC Control */
-/* TRUE: Disable PSC */
+/* Output : 0 : Skip PSC Control */
+/* 1: Disable PSC */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo)
+unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
 {
-    USHORT tempax ;
+    unsigned short tempax ;
 
     tempax = pVBInfo->VBInfo ;
     if ( tempax & SetCRT2ToDualEdge )
-        return FALSE ;
+           return 0;
     else if ( tempax & ( DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode ) )
-        return TRUE ;
+           return 1;
 
-    return FALSE ;
+    return 0;
 }
 
 
@@ -8877,9 +8552,9 @@ BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_EnablePWD(  PVB_DEVICE_INFO pVBInfo )
+void XGI_EnablePWD(struct vb_device_info *pVBInfo)
 {
-    USHORT index ,
+    unsigned short index ,
            temp ;
 
     index = XGI_GetLCDCapPtr(pVBInfo) ;
@@ -8899,7 +8574,7 @@ void XGI_EnablePWD(  PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_DisablePWD( PVB_DEVICE_INFO pVBInfo )
+void XGI_DisablePWD(struct vb_device_info *pVBInfo)
 {
     XGINew_SetRegAND( pVBInfo->Part4Port , 0x27 , 0x7F ) ;     /* disable PWD */
 }
@@ -8908,30 +8583,30 @@ void XGI_DisablePWD( PVB_DEVICE_INFO pVBInfo )
 /* --------------------------------------------------------------------- */
 /* Function : XGI_DisableChISLCD */
 /* Input : */
-/* Output : FALSE -> Not LCD Mode */
+/* Output : 0 -> Not LCD Mode */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo)
+unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ,
+    unsigned short tempbx ,
            tempah ;
 
     tempbx = pVBInfo->SetFlag & ( DisableChA | DisableChB ) ;
-    tempah = ~( ( USHORT )XGINew_GetReg1( pVBInfo->Part1Port  , 0x2E ) ) ;
+    tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E));
 
     if ( tempbx & ( EnableChA | DisableChA ) )
     {
         if ( !( tempah & 0x08 ) )              /* Chk LCDA Mode */
-            return FALSE ;
+               return 0 ;
     }
 
     if ( !( tempbx & ( EnableChB | DisableChB ) ) )
-        return FALSE ;
+           return 0;
 
     if ( tempah & 0x01 )       /* Chk LCDB Mode */
-        return TRUE ;
+           return 1;
 
-    return FALSE ;
+    return 0;
 }
 
 
@@ -8941,28 +8616,28 @@ BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo)
 /* Output : 0 -> Not LCD mode */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo)
+unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ,
+    unsigned short tempbx ,
            tempah ;
 
 
     tempbx = pVBInfo->SetFlag & ( EnableChA | EnableChB ) ;
-    tempah = ~( ( USHORT )XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ) ;
+    tempah = ~( (unsigned short)XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ) ;
 
     if ( tempbx & ( EnableChA | DisableChA ) )
     {
         if ( !( tempah & 0x08 ) )              /* Chk LCDA Mode */
-            return FALSE ;
+               return 0;
     }
 
     if ( !( tempbx & ( EnableChB | DisableChB ) ) )
-        return FALSE ;
+           return 0;
 
     if ( tempah & 0x01 )       /* Chk LCDB Mode */
-        return TRUE ;
+           return 1;
 
-    return FALSE ;
+    return 0;
 }
 
 
@@ -8972,9 +8647,9 @@ BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetLCDCapPtr(  PVB_DEVICE_INFO pVBInfo )
+unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
 {
-    UCHAR tempal ,
+    unsigned char tempal ,
           tempah ,
           tempbl ,
           i ;
@@ -9011,9 +8686,9 @@ USHORT XGI_GetLCDCapPtr(  PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetLCDCapPtr1( PVB_DEVICE_INFO pVBInfo )
+unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
 {
-    USHORT tempah ,
+    unsigned short tempah ,
            tempal ,
            tempbl ,
            i ;
@@ -9056,9 +8731,10 @@ USHORT XGI_GetLCDCapPtr1( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetLCDSync( USHORT* HSyncWidth , USHORT* VSyncWidth, PVB_DEVICE_INFO pVBInfo )
+void XGI_GetLCDSync(unsigned short *HSyncWidth , unsigned short *VSyncWidth,
+                   struct vb_device_info *pVBInfo)
 {
-    USHORT Index ;
+    unsigned short Index ;
 
     Index = XGI_GetLCDCapPtr(pVBInfo) ;
     *HSyncWidth = pVBInfo->LCDCapList[ Index ].LCD_HSyncWidth ;
@@ -9075,9 +8751,9 @@ void XGI_GetLCDSync( USHORT* HSyncWidth , USHORT* VSyncWidth, PVB_DEVICE_INFO pV
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_EnableBridge( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempbl ,
+    unsigned short tempbl ,
            tempah ;
 
     if ( pVBInfo->SetFlag == Win9xDOSMode )
@@ -9146,7 +8822,7 @@ void XGI_EnableBridge( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO p
         {
             if ( ( pVBInfo->SetFlag & EnableChB ) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC ) ) )
             {
-                tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x32 ) ;
+               tempah = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x32);
                 tempah &= 0xDF;
                 if ( pVBInfo->VBInfo & SetInSlaveMode )
                 {
@@ -9156,8 +8832,7 @@ void XGI_EnableBridge( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO p
                 XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , tempah ) ;
                 XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x20 ) ;
 
-
-                tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ;
+               tempah = (unsigned char)XGINew_GetReg1(pVBInfo->Part1Port, 0x2E);
 
                 if ( !( tempah & 0x80 ) )
                     XGINew_SetRegOR( pVBInfo->Part1Port , 0x2E , 0x80 ) ;      /* BVBDOENABLE = 1 */
@@ -9238,7 +8913,7 @@ void XGI_EnableBridge( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO p
 
 
 
-        tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ;
+       tempah = (unsigned char)XGINew_GetReg1(pVBInfo->Part1Port, 0x2E);
         if ( !( tempah & 0x80 ) )
             XGINew_SetRegOR( pVBInfo->Part1Port , 0x2E , 0x80 ) ;      /* BVBDOENABLE = 1 */
 
@@ -9289,9 +8964,9 @@ void XGI_EnableBridge( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO p
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempax ,
+    unsigned short tempax ,
            tempbx ,
            tempah = 0 ,
            tempbl = 0 ;
@@ -9470,9 +9145,9 @@ void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pV
 /* A : Ext750p */
 /* B : St750p */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetTVPtrIndex(  PVB_DEVICE_INFO pVBInfo )
+unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx = 0 ;
+    unsigned short tempbx = 0 ;
 
     if ( pVBInfo->TVInfo & SetPALTV )
         tempbx = 2 ;
@@ -9497,7 +9172,7 @@ USHORT XGI_GetTVPtrIndex(  PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : Customized Param. for 301 */
 /* --------------------------------------------------------------------- */
-void XGI_OEM310Setting( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
     if ( pVBInfo->SetFlag & Win9xDOSMode )
         return ;
@@ -9527,11 +9202,11 @@ void XGI_OEM310Setting( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBI
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetDelayComp( PVB_DEVICE_INFO pVBInfo )
+void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
 {
-    USHORT index ;
+    unsigned short index ;
 
-    UCHAR  tempah ,
+    unsigned char  tempah ,
            tempbl ,
            tempbh ;
 
@@ -9605,9 +9280,9 @@ void XGI_SetDelayComp( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetLCDCap( PVB_DEVICE_INFO pVBInfo )
+void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
 {
-    USHORT tempcx ;
+    unsigned short tempcx ;
 
     tempcx = pVBInfo->LCDCapList[ XGI_GetLCDCapPtr(pVBInfo) ].LCD_Capability ;
 
@@ -9616,10 +9291,12 @@ void XGI_SetLCDCap( PVB_DEVICE_INFO pVBInfo )
         if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
         {                                      /* 301LV/302LV only */
             /* Set 301LV Capability */
-            XGINew_SetReg1( pVBInfo->Part4Port , 0x24 , ( UCHAR )( tempcx & 0x1F ) ) ;
+               XGINew_SetReg1(pVBInfo->Part4Port, 0x24, (unsigned char)(tempcx & 0x1F));
        }
         /* VB Driving */
-        XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0D , ~( ( EnableVBCLKDRVLOW | EnablePLLSPLOW ) >> 8 ) , ( USHORT )( ( tempcx & ( EnableVBCLKDRVLOW | EnablePLLSPLOW ) ) >> 8 ) ) ;
+       XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D,
+                          ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
+                          (unsigned short)((tempcx & (EnableVBCLKDRVLOW | EnablePLLSPLOW)) >> 8));
     }
 
     if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
@@ -9646,32 +9323,34 @@ void XGI_SetLCDCap( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetLCDCap_A(USHORT tempcx,PVB_DEVICE_INFO pVBInfo)
+void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo)
 {
-    USHORT temp ;
+    unsigned short temp ;
 
     temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
 
     if ( temp & LCDRGB18Bit )
     {
-        XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , 0x0F , ( USHORT )( 0x20 | ( tempcx & 0x00C0 ) ) ) ; /* Enable Dither */
+       XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
+                          (unsigned short)(0x20 | (tempcx & 0x00C0))); /* Enable Dither */
         XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1A , 0x7F , 0x80 ) ;
     }
     else
     {
-        XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , 0x0F , ( USHORT )( 0x30 | ( tempcx & 0x00C0 ) ) ) ;
+       XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
+                          (unsigned short)(0x30 | (tempcx & 0x00C0)));
         XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1A , 0x7F , 0x00 ) ;
     }
 
 /*
     if ( tempcx & EnableLCD24bpp )     // 24bits
     {
-        XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x30|(tempcx&0x00C0)) );
+       XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(unsigned short)(0x30|(tempcx&0x00C0)) );
         XGINew_SetRegANDOR(pVBInfo->Part1Port,0x1A,0x7F,0x00);
     }
     else
     {
-        XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x20|(tempcx&0x00C0)) );//Enable Dither
+       XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(unsigned short)(0x20|(tempcx&0x00C0)) ); // Enable Dither
         XGINew_SetRegANDOR(pVBInfo->Part1Port,0x1A,0x7F,0x80);
     }
 */
@@ -9684,12 +9363,14 @@ void XGI_SetLCDCap_A(USHORT tempcx,PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetLCDCap_B(USHORT tempcx,PVB_DEVICE_INFO pVBInfo)
+void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo)
 {
     if ( tempcx & EnableLCD24bpp )     /* 24bits */
-        XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1A , 0xE0 , ( USHORT )( ( ( tempcx & 0x00ff ) >> 6 ) | 0x0c ) ) ;
+           XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
+                              (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x0c));
     else
-        XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1A , 0xE0 , ( USHORT )( ( ( tempcx & 0x00ff ) >> 6 ) | 0x18 ) ) ; /* Enable Dither */
+           XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
+                              (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */
 }
 
 
@@ -9699,9 +9380,9 @@ void XGI_SetLCDCap_B(USHORT tempcx,PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void SetSpectrum( PVB_DEVICE_INFO pVBInfo )
+void SetSpectrum(struct vb_device_info *pVBInfo)
 {
-    USHORT index ;
+    unsigned short index ;
 
     index = XGI_GetLCDCapPtr(pVBInfo) ;
 
@@ -9725,12 +9406,13 @@ void SetSpectrum( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : Set TV Customized Param. */
 /* --------------------------------------------------------------------- */
-void XGI_SetAntiFlicker( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex,
+                       struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ,
+    unsigned short tempbx ,
            index ;
 
-    UCHAR tempah ;
+    unsigned char tempah ;
 
     if (pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
         return ;
@@ -9761,12 +9443,12 @@ void XGI_SetAntiFlicker( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVB
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetEdgeEnhance( USHORT ModeNo , USHORT ModeIdIndex , PVB_DEVICE_INFO pVBInfo)
+void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ,
+    unsigned short tempbx ,
            index ;
 
-    UCHAR tempah ;
+    unsigned char tempah ;
 
 
     tempbx = XGI_GetTVPtrIndex(pVBInfo ) ;
@@ -9795,22 +9477,26 @@ void XGI_SetEdgeEnhance( USHORT ModeNo , USHORT ModeIdIndex , PVB_DEVICE_INFO pV
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetPhaseIncr( PVB_DEVICE_INFO pVBInfo )
+void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ;
+    unsigned short tempbx ;
 
-    UCHAR tempcl ,
+    unsigned char tempcl ,
           tempch ;
 
-    ULONG tempData ;
+    unsigned long tempData ;
 
     XGI_GetTVPtrIndex2( &tempbx , &tempcl , &tempch, pVBInfo ) ; /* bx, cl, ch */
     tempData = TVPhaseList[ tempbx ] ;
 
-    XGINew_SetReg1( pVBInfo->Part2Port , 0x31 , ( USHORT )( tempData & 0x000000FF ) ) ;
-    XGINew_SetReg1( pVBInfo->Part2Port , 0x32 , ( USHORT )( ( tempData & 0x0000FF00 ) >> 8 ) ) ;
-    XGINew_SetReg1( pVBInfo->Part2Port , 0x33 , ( USHORT )( ( tempData & 0x00FF0000 ) >> 16 ) ) ;
-    XGINew_SetReg1( pVBInfo->Part2Port , 0x34 , ( USHORT )( ( tempData & 0xFF000000 ) >> 24 ) ) ;
+    XGINew_SetReg1(pVBInfo->Part2Port, 0x31,
+                  (unsigned short)(tempData & 0x000000FF));
+    XGINew_SetReg1(pVBInfo->Part2Port, 0x32,
+                  (unsigned short)((tempData & 0x0000FF00) >> 8));
+    XGINew_SetReg1(pVBInfo->Part2Port, 0x33,
+                  (unsigned short)((tempData & 0x00FF0000) >> 16));
+    XGINew_SetReg1(pVBInfo->Part2Port, 0x34,
+                  (unsigned short)((tempData & 0xFF000000) >> 24));
 }
 
 
@@ -9820,12 +9506,13 @@ void XGI_SetPhaseIncr( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_SetYFilter( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
+                   struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ,
+    unsigned short tempbx ,
            index ;
 
-    UCHAR tempcl ,
+    unsigned char tempcl ,
           tempch ,
           tempal ,
           *filterPtr ;
@@ -9924,7 +9611,8 @@ void XGI_SetYFilter( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo
 /* 1 : 301B/302B/301LV/302LV */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetTVPtrIndex2(USHORT* tempbx,UCHAR* tempcl,UCHAR* tempch, PVB_DEVICE_INFO pVBInfo)
+void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
+                       unsigned char *tempch, struct vb_device_info *pVBInfo)
 {
     *tempbx = 0 ;
     *tempcl = 0 ;
@@ -9966,12 +9654,14 @@ void XGI_GetTVPtrIndex2(USHORT* tempbx,UCHAR* tempcl,UCHAR* tempch, PVB_DEVICE_I
 /* Output : */
 /* Description : Origin code for crt2group */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
+                        struct xgi_hw_device_info *HwDeviceExtension,
+                        struct vb_device_info *pVBInfo)
 {
-    USHORT tempbl ;
-    SHORT  tempcl ;
+    unsigned short tempbl ;
+    short  tempcl ;
 
-    UCHAR  tempah ;
+    unsigned char  tempah ;
 
     /* XGINew_SetReg1( pVBInfo->Part1Port , 0x03 , 0x00 ) ; // fix write part1 index 0 BTDRAM bit Bug */
     tempah=0;
@@ -10195,9 +9885,9 @@ void XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO HwDeviceExtension, PV
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_CloseCRTC( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
+void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ;
+    unsigned short tempbx ;
 
     tempbx = 0 ;
 
@@ -10214,9 +9904,9 @@ void XGI_CloseCRTC( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBIn
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_OpenCRTC( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
+void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ;
+    unsigned short tempbx ;
 
     tempbx = 0 ;
 
@@ -10230,9 +9920,9 @@ void XGI_OpenCRTC( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInf
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_GetRAMDAC2DATA(USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
+void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT tempax ,
+    unsigned short tempax ,
            tempbx ,
            temp1 ,
            temp2 ,
@@ -10257,15 +9947,15 @@ void XGI_GetRAMDAC2DATA(USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateT
         modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
         CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
         CRT1Index &= IndexMask ;
-        temp1 = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 0 ] ;
-        temp2 = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 5 ] ;
+       temp1 = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
+       temp2 = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
        tempax = ( temp1 & 0xFF ) | ( ( temp2 & 0x03 ) << 8 ) ;
-        tempbx = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 8 ] ;
-        tempcx = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 14 ] << 8 ;
+       tempbx = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
+       tempcx = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
        tempcx &= 0x0100 ;
        tempcx = tempcx << 2 ;
        tempbx |= tempcx;
-        temp1 = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 9 ] ;
+       temp1 = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
     }
 
     if ( temp1 & 0x01 )
@@ -10295,11 +9985,11 @@ void XGI_GetRAMDAC2DATA(USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateT
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetColorDepth(USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+unsigned short XGI_GetColorDepth(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-    USHORT ColorDepth[ 6 ] = { 1 , 2 , 4 , 4 , 6 , 8 } ;
-    SHORT  index ;
-    USHORT modeflag ;
+    unsigned short ColorDepth[ 6 ] = { 1 , 2 , 4 , 4 , 6 , 8 } ;
+    short index ;
+    unsigned short modeflag ;
 
     if ( ModeNo <= 0x13 )
     {
@@ -10326,7 +10016,7 @@ USHORT XGI_GetColorDepth(USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVB
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_UnLockCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension,  PVB_DEVICE_INFO pVBInfo )
+void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,  struct vb_device_info *pVBInfo)
 {
 
     XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2f , 0xFF , 0x01 ) ;
@@ -10340,7 +10030,7 @@ void XGI_UnLockCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension,  PVB_DEVICE_INFO pVB
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_LockCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension,  PVB_DEVICE_INFO pVBInfo )
+void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,  struct vb_device_info *pVBInfo)
 {
 
     XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2F , 0xFE , 0x00 ) ;
@@ -10355,7 +10045,7 @@ void XGI_LockCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension,  PVB_DEVICE_INFO pVBIn
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_EnableCRT2( PVB_DEVICE_INFO pVBInfo)
+void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
 {
     XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1E , 0xFF , 0x20 ) ;
 }
@@ -10368,12 +10058,12 @@ void XGINew_EnableCRT2( PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo)
+void XGINew_LCD_Wait_Time(unsigned char DelayTime, struct vb_device_info *pVBInfo)
 {
-    USHORT i ,
+    unsigned short i ,
            j ;
 
-    ULONG temp ,
+    unsigned long temp ,
           flag ;
 
     flag = 0 ;
@@ -10405,9 +10095,9 @@ void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-BOOLEAN XGI_BridgeIsOn( PVB_DEVICE_INFO pVBInfo )
+unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
 {
-    USHORT flag ;
+    unsigned short flag ;
 
     if ( pVBInfo->IF_DEF_LVDS == 1 )
     {
@@ -10431,9 +10121,9 @@ BOOLEAN XGI_BridgeIsOn( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_LongWait(PVB_DEVICE_INFO pVBInfo)
+void XGI_LongWait(struct vb_device_info *pVBInfo)
 {
-    USHORT i ;
+    unsigned short i ;
 
     i = XGINew_GetReg1( pVBInfo->P3c4 , 0x1F ) ;
 
@@ -10460,9 +10150,9 @@ void XGI_LongWait(PVB_DEVICE_INFO pVBInfo)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGI_VBLongWait( PVB_DEVICE_INFO pVBInfo )
+void XGI_VBLongWait(struct vb_device_info *pVBInfo)
 {
-    USHORT tempal ,
+    unsigned short tempal ,
            temp ,
            i ,
            j ;
@@ -10519,16 +10209,16 @@ return ;
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetVGAHT2( PVB_DEVICE_INFO pVBInfo )
+unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
 {
-    ULONG tempax ,
+    unsigned long tempax ,
           tempbx ;
 
     tempbx = ( ( pVBInfo->VGAVT - pVBInfo->VGAVDE ) * pVBInfo->RVBHCMAX ) & 0xFFFF ;
     tempax = ( pVBInfo->VT - pVBInfo->VDE ) * pVBInfo->RVBHCFACT ;
     tempax = ( tempax * pVBInfo->HT ) /tempbx ;
 
-    return( ( USHORT )tempax ) ;
+    return( (unsigned short)tempax ) ;
 }
 
 
@@ -10538,19 +10228,23 @@ USHORT XGI_GetVGAHT2( PVB_DEVICE_INFO pVBInfo )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-USHORT XGI_GetVCLK2Ptr( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
+unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
+                              unsigned short ModeIdIndex,
+                              unsigned short RefreshRateTableIndex,
+                              struct xgi_hw_device_info *HwDeviceExtension,
+                              struct vb_device_info *pVBInfo)
 {
-    USHORT tempbx ;
+    unsigned short tempbx ;
 
-    USHORT LCDXlat1VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
-    USHORT LCDXlat2VCLK[ 4 ] = { VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 } ;
-    USHORT LVDSXlat1VCLK[ 4 ] = { VCLK40 , VCLK40 , VCLK40 , VCLK40 } ;
-    USHORT LVDSXlat2VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
-    USHORT LVDSXlat3VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
+    unsigned short LCDXlat1VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
+    unsigned short LCDXlat2VCLK[ 4 ] = { VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 } ;
+    unsigned short LVDSXlat1VCLK[ 4 ] = { VCLK40 , VCLK40 , VCLK40 , VCLK40 } ;
+    unsigned short LVDSXlat2VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
+    unsigned short LVDSXlat3VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
 
-    USHORT CRT2Index , VCLKIndex ;
-    USHORT modeflag , resinfo ;
-    UCHAR *CHTVVCLKPtr = NULL ;
+    unsigned short CRT2Index , VCLKIndex ;
+    unsigned short modeflag , resinfo ;
+    unsigned char *CHTVVCLKPtr = NULL ;
 
     if ( ModeNo <= 0x13 )
     {
@@ -10665,7 +10359,7 @@ USHORT XGI_GetVCLK2Ptr( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateT
             }
             else
             {  /* for CRT2 */
-                VCLKIndex = ( UCHAR )XGINew_GetReg2( ( pVBInfo->P3ca + 0x02 ) ) ;      /* Port 3cch */
+               VCLKIndex = (unsigned char)XGINew_GetReg2((pVBInfo->P3ca + 0x02));      /* Port 3cch */
                VCLKIndex = ( ( VCLKIndex >> 2 ) & 0x03 ) ;
                 if ( ModeNo > 0x13 )
                 {
index 09753d7066655c385a51d05fae6bf51409577140..0dcc2979617635b8f8af3b0c62447ef166098492 100644 (file)
@@ -1,40 +1,42 @@
 #ifndef  _VBSETMODE_
 #define  _VBSETMODE_
 
-extern   void     InitTo330Pointer(UCHAR,PVB_DEVICE_INFO);
-extern   void     XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void     XGI_LockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void     XGI_LongWait( PVB_DEVICE_INFO );
-extern   void     XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO,  PVB_DEVICE_INFO  );
-extern   void     XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void            XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void     XGI_DisplayOff( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
-extern   void     XGI_DisplayOn( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
-extern   void     XGI_GetVBType(PVB_DEVICE_INFO);
-extern   void     XGI_SenseCRT1(PVB_DEVICE_INFO );
-extern   void     XGI_GetVGAType(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void     XGI_GetVBInfo(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void     XGI_GetTVInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
-extern   void     XGI_SetCRT1Offset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void     XGI_SetLCDAGroup(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern   void     XGI_WaitDisply( PVB_DEVICE_INFO );
-extern   USHORT   XGI_GetResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+extern   void     InitTo330Pointer(unsigned char, struct vb_device_info *);
+extern   void     XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_LongWait(struct vb_device_info *);
+extern   void     XGI_SetCRT2ModeRegs(unsigned short ModeNo,
+                                     struct xgi_hw_device_info *,
+                                     struct vb_device_info *);
+extern   void     XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_DisplayOff(struct xgi_hw_device_info *, struct vb_device_info *);
+extern   void     XGI_DisplayOn(struct xgi_hw_device_info *, struct vb_device_info *);
+extern   void     XGI_GetVBType(struct vb_device_info *);
+extern   void     XGI_SenseCRT1(struct vb_device_info *);
+extern   void     XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *);
+extern   void     XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   void     XGI_WaitDisply(struct vb_device_info *);
+extern   unsigned short   XGI_GetResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
 
-extern   BOOLEAN  XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo ) ;
+extern   unsigned char  XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo) ;
 
-extern   BOOLEAN  XGI_SearchModeID( USHORT ModeNo,USHORT  *ModeIdIndex, PVB_DEVICE_INFO );
-extern   BOOLEAN  XGI_GetLCDInfo(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO );
-extern   BOOLEAN  XGI_BridgeIsOn( PVB_DEVICE_INFO );
-extern   BOOLEAN  XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO);
-extern   USHORT   XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
+extern   unsigned char  XGI_SearchModeID(unsigned short ModeNo, unsigned short  *ModeIdIndex, struct vb_device_info *);
+extern   unsigned char  XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *);
+extern   unsigned char  XGI_BridgeIsOn(struct vb_device_info *);
+extern   unsigned char  XGI_SetCRT2Group301(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
+extern   unsigned short   XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *);
 
-extern   void     XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
-extern   void     XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
-extern   void     XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-extern   void     XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-extern   void     XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-extern   BOOLEAN  XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
-extern   void     XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
-extern   USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo);
+extern   void     XGI_SetXG21FPBits(struct vb_device_info *pVBInfo);
+extern   void     XGI_SetXG27FPBits(struct vb_device_info *pVBInfo);
+extern   void     XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo);
+extern   void     XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo);
+extern   void     XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo);
+extern   unsigned char  XGI_XG21CheckLVDSMode(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+extern   void     XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+extern   unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo);
 
 #endif
index bb25c0e2785e110b50ad6a6a189a780a0ced28ec..9c6e0c7ac78126b7d68b0b64c7f7fb8f9dfa3df1 100644 (file)
 
 
 
-typedef struct _XGI_PanelDelayTblStruct
+struct XGI_PanelDelayTblStruct
 {
UCHAR timer[2];
-} XGI_PanelDelayTblStruct;
unsigned char timer[2];
+};
 
-typedef struct _XGI_LCDDataStruct
+struct XGI_LCDDataStruct
 {
USHORT RVBHCMAX;
USHORT RVBHCFACT;
USHORT VGAHT;
USHORT VGAVT;
USHORT LCDHT;
USHORT LCDVT;
-} XGI_LCDDataStruct;
unsigned short RVBHCMAX;
unsigned short RVBHCFACT;
unsigned short VGAHT;
unsigned short VGAVT;
unsigned short LCDHT;
unsigned short LCDVT;
+};
 
 
-typedef struct _XGI_LVDSCRT1HDataStruct
+struct XGI_LVDSCRT1HDataStruct
 {
- UCHAR Reg[8];
-} XGI_LVDSCRT1HDataStruct;
-typedef struct _XGI_LVDSCRT1VDataStruct
-{
- UCHAR Reg[7];
-} XGI_LVDSCRT1VDataStruct;
-
-
-typedef struct _XGI_TVDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT TVHDE;
- USHORT TVVDE;
- USHORT RVBHRS;
- UCHAR FlickerMode;
- USHORT HALFRVBHRS;
- UCHAR RY1COE;
- UCHAR RY2COE;
- UCHAR RY3COE;
- UCHAR RY4COE;
-} XGI_TVDataStruct;
-
-typedef struct _XGI_LVDSDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} XGI_LVDSDataStruct;
-
-typedef struct _XGI_LVDSDesStruct
-{
- USHORT LCDHDES;
- USHORT LCDVDES;
-} XGI_LVDSDesStruct;
-
-typedef struct _XGI_LVDSCRT1DataStruct
-{
- UCHAR CR[15];
-} XGI_LVDSCRT1DataStruct;
-
-/*add for LCDA*/
+ unsigned char Reg[8];
+};
 
-
-typedef struct _XGI_StStruct
-{
- UCHAR St_ModeID;
- USHORT St_ModeFlag;
- UCHAR St_StTableIndex;
- UCHAR St_CRT2CRTC;
- UCHAR St_CRT2CRTC2;
- UCHAR St_ResInfo;
- UCHAR VB_StTVFlickerIndex;
- UCHAR VB_StTVEdgeIndex;
- UCHAR VB_StTVYFilterIndex;
-} XGI_StStruct;
-
-typedef struct _XGI_StandTableStruct
-{
- UCHAR CRT_COLS;
- UCHAR ROWS;
- UCHAR CHAR_HEIGHT;
- USHORT CRT_LEN;
- UCHAR SR[4];
- UCHAR MISC;
- UCHAR CRTC[0x19];
- UCHAR ATTR[0x14];
- UCHAR GRC[9];
-} XGI_StandTableStruct;
-
-typedef struct _XGI_ExtStruct
-{
- UCHAR Ext_ModeID;
- USHORT Ext_ModeFlag;
- USHORT Ext_ModeInfo;
- USHORT Ext_Point;
- USHORT Ext_VESAID;
- UCHAR Ext_VESAMEMSize;
- UCHAR Ext_RESINFO;
- UCHAR VB_ExtTVFlickerIndex;
- UCHAR VB_ExtTVEdgeIndex;
- UCHAR VB_ExtTVYFilterIndex;
- UCHAR REFindex;
-} XGI_ExtStruct;
-
-typedef struct _XGI_Ext2Struct
+struct XGI_LVDSCRT1VDataStruct
 {
- USHORT Ext_InfoFlag;
- UCHAR Ext_CRT1CRTC;
- UCHAR Ext_CRTVCLK;
- UCHAR Ext_CRT2CRTC;
- UCHAR Ext_CRT2CRTC2;
- UCHAR  ModeID;
- USHORT XRes;
- USHORT YRes;
- /* USHORT ROM_OFFSET; */
-} XGI_Ext2Struct;
-
+ unsigned char Reg[7];
+};
 
-typedef struct _XGI_MCLKDataStruct
-{
- UCHAR SR28,SR29,SR2A;
- USHORT CLOCK;
-} XGI_MCLKDataStruct;
 
-typedef struct _XGI_ECLKDataStruct
+struct XGI_TVDataStruct
 {
- UCHAR SR2E,SR2F,SR30;
- USHORT CLOCK;
-} XGI_ECLKDataStruct;
+ unsigned short RVBHCMAX;
+ unsigned short RVBHCFACT;
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short TVHDE;
+ unsigned short TVVDE;
+ unsigned short RVBHRS;
+ unsigned char FlickerMode;
+ unsigned short HALFRVBHRS;
+ unsigned char RY1COE;
+ unsigned char RY2COE;
+ unsigned char RY3COE;
+ unsigned char RY4COE;
+};
 
-typedef struct _XGI_VCLKDataStruct
+struct XGI_LVDSDataStruct
 {
- UCHAR SR2B,SR2C;
- USHORT CLOCK;
-} XGI_VCLKDataStruct;
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short LCDHT;
+ unsigned short LCDVT;
+};
 
-typedef struct _XGI_VBVCLKDataStruct
+struct XGI_LVDSDesStruct
 {
UCHAR Part4_A,Part4_B;
USHORT CLOCK;
-} XGI_VBVCLKDataStruct;
unsigned short LCDHDES;
unsigned short LCDVDES;
+};
 
-typedef struct _XGI_StResInfoStruct
+struct XGI_LVDSCRT1DataStruct
 {
- USHORT HTotal;
- USHORT VTotal;
-} XGI_StResInfoStruct;
+ unsigned char CR[15];
+};
 
-typedef struct _XGI_ModeResInfoStruct
-{
- USHORT HTotal;
- USHORT VTotal;
- UCHAR  XChar;
- UCHAR  YChar;
-} XGI_ModeResInfoStruct;
+/*add for LCDA*/
 
-typedef struct _XGI_LCDNBDesStruct
-{
-  UCHAR NB[12];
-} XGI_LCDNBDesStruct;
+struct XGI_StStruct
+{
+ unsigned char St_ModeID;
+ unsigned short St_ModeFlag;
+ unsigned char St_StTableIndex;
+ unsigned char St_CRT2CRTC;
+ unsigned char St_CRT2CRTC2;
+ unsigned char St_ResInfo;
+ unsigned char VB_StTVFlickerIndex;
+ unsigned char VB_StTVEdgeIndex;
+ unsigned char VB_StTVYFilterIndex;
+};
+
+struct XGI_StandTableStruct
+{
+ unsigned char CRT_COLS;
+ unsigned char ROWS;
+ unsigned char CHAR_HEIGHT;
+ unsigned short CRT_LEN;
+ unsigned char SR[4];
+ unsigned char MISC;
+ unsigned char CRTC[0x19];
+ unsigned char ATTR[0x14];
+ unsigned char GRC[9];
+};
+
+struct XGI_ExtStruct
+{
+ unsigned char Ext_ModeID;
+ unsigned short Ext_ModeFlag;
+ unsigned short Ext_ModeInfo;
+ unsigned short Ext_Point;
+ unsigned short Ext_VESAID;
+ unsigned char Ext_VESAMEMSize;
+ unsigned char Ext_RESINFO;
+ unsigned char VB_ExtTVFlickerIndex;
+ unsigned char VB_ExtTVEdgeIndex;
+ unsigned char VB_ExtTVYFilterIndex;
+ unsigned char REFindex;
+};
+
+struct XGI_Ext2Struct
+{
+ unsigned short Ext_InfoFlag;
+ unsigned char Ext_CRT1CRTC;
+ unsigned char Ext_CRTVCLK;
+ unsigned char Ext_CRT2CRTC;
+ unsigned char Ext_CRT2CRTC2;
+ unsigned char  ModeID;
+ unsigned short XRes;
+ unsigned short YRes;
+ /* unsigned short ROM_OFFSET; */
+};
+
+
+struct XGI_MCLKDataStruct
+{
+ unsigned char SR28, SR29, SR2A;
+ unsigned short CLOCK;
+};
+
+struct XGI_ECLKDataStruct
+{
+ unsigned char SR2E, SR2F, SR30;
+ unsigned short CLOCK;
+};
+
+struct XGI_VCLKDataStruct
+{
+ unsigned char SR2B, SR2C;
+ unsigned short CLOCK;
+};
+
+struct XGI_VBVCLKDataStruct
+{
+ unsigned char Part4_A, Part4_B;
+ unsigned short CLOCK;
+};
+
+struct XGI_StResInfoStruct
+{
+ unsigned short HTotal;
+ unsigned short VTotal;
+};
+
+struct XGI_ModeResInfoStruct
+{
+ unsigned short HTotal;
+ unsigned short VTotal;
+ unsigned char  XChar;
+ unsigned char  YChar;
+};
+
+struct XGI_LCDNBDesStruct
+{
+  unsigned char NB[12];
+};
  /*add for new UNIVGABIOS*/
-typedef struct _XGI_LCDDesStruct
+struct XGI_LCDDesStruct
 {
USHORT LCDHDES;
USHORT LCDHRS;
USHORT LCDVDES;
USHORT LCDVRS;
-} XGI_LCDDesStruct;
unsigned short LCDHDES;
unsigned short LCDHRS;
unsigned short LCDVDES;
unsigned short LCDVRS;
+};
 
-typedef struct _XGI_LCDDataTablStruct
+struct XGI_LCDDataTablStruct
 {
UCHAR  PANELID;
USHORT MASK;
USHORT CAP;
USHORT DATAPTR;
-} XGI_LCDDataTablStruct;
unsigned char  PANELID;
unsigned short MASK;
unsigned short CAP;
unsigned short DATAPTR;
+};
 
-typedef struct _XGI_TVTablDataStruct
+struct XGI_TVTablDataStruct
 {
USHORT MASK;
USHORT CAP;
USHORT DATAPTR;
-} XGI_TVDataTablStruct;
unsigned short MASK;
unsigned short CAP;
unsigned short DATAPTR;
+};
 
-typedef struct _XGI330_LCDDesDataStruct
+struct XGI330_LCDDataDesStruct
 {
USHORT LCDHDES;
USHORT LCDHRS;
USHORT LCDVDES;
USHORT LCDVRS;
-} XGI330_LCDDataDesStruct;
unsigned short LCDHDES;
unsigned short LCDHRS;
unsigned short LCDVDES;
unsigned short LCDVRS;
+};
 
 
-typedef struct _XGI330_LVDSDataStruct
+struct XGI330_LVDSDataStruct
 {
USHORT VGAHT;
USHORT VGAVT;
USHORT LCDHT;
USHORT LCDVT;
-} XGI330_LVDSDataStruct;
unsigned short VGAHT;
unsigned short VGAVT;
unsigned short LCDHT;
unsigned short LCDVT;
+};
 
-typedef struct _XGI330_LCDDesDataStruct2
+struct XGI330_LCDDataDesStruct2
 {
USHORT LCDHDES;
USHORT LCDHRS;
USHORT LCDVDES;
USHORT LCDVRS;
USHORT LCDHSync;
USHORT LCDVSync;
-} XGI330_LCDDataDesStruct2;
unsigned short LCDHDES;
unsigned short LCDHRS;
unsigned short LCDVDES;
unsigned short LCDVRS;
unsigned short LCDHSync;
unsigned short LCDVSync;
+};
 
-typedef struct _XGI330_LCDDataStruct
+struct XGI330_LCDDataStruct
 {
USHORT RVBHCMAX;
USHORT RVBHCFACT;
USHORT VGAHT;
USHORT VGAVT;
USHORT LCDHT;
USHORT LCDVT;
-} XGI330_LCDDataStruct;
unsigned short RVBHCMAX;
unsigned short RVBHCFACT;
unsigned short VGAHT;
unsigned short VGAVT;
unsigned short LCDHT;
unsigned short LCDVT;
+};
 
 
-typedef struct _XGI330_TVDataStruct
+struct XGI330_TVDataStruct
 {
USHORT RVBHCMAX;
USHORT RVBHCFACT;
USHORT VGAHT;
USHORT VGAVT;
USHORT TVHDE;
USHORT TVVDE;
USHORT RVBHRS;
UCHAR FlickerMode;
USHORT HALFRVBHRS;
-} XGI330_TVDataStruct;
-
-typedef struct _XGI330_LCDDataTablStruct
-{
UCHAR  PANELID;
USHORT MASK;
USHORT CAP;
USHORT DATAPTR;
-} XGI330_LCDDataTablStruct;
-
-typedef struct _XGI330_TVDataTablStruct
-{
USHORT MASK;
USHORT CAP;
USHORT DATAPTR;
-} XGI330_TVDataTablStruct;
-
-
-typedef struct _XGI330_CHTVDataStruct
-{
USHORT VGAHT;
USHORT VGAVT;
USHORT LCDHT;
USHORT LCDVT;
-} XGI330_CHTVDataStruct;
unsigned short RVBHCMAX;
unsigned short RVBHCFACT;
unsigned short VGAHT;
unsigned short VGAVT;
unsigned short TVHDE;
unsigned short TVVDE;
unsigned short RVBHRS;
unsigned char FlickerMode;
unsigned short HALFRVBHRS;
+};
+
+struct XGI330_LCDDataTablStruct
+{
unsigned char  PANELID;
unsigned short MASK;
unsigned short CAP;
unsigned short DATAPTR;
+};
+
+struct XGI330_TVDataTablStruct
+{
unsigned short MASK;
unsigned short CAP;
unsigned short DATAPTR;
+};
+
+
+struct XGI330_CHTVDataStruct
+{
unsigned short VGAHT;
unsigned short VGAVT;
unsigned short LCDHT;
unsigned short LCDVT;
+};
 
-typedef struct _XGI_TimingHStruct
-{
-  UCHAR data[8];
-} XGI_TimingHStruct;
-
-typedef struct _XGI_TimingVStruct
-{
-  UCHAR data[7];
-} XGI_TimingVStruct;
-
-typedef struct _XGI_CH7007TV_TimingHStruct
-{
-  UCHAR data[10];
-} XGI_CH7007TV_TimingHStruct;
-
-typedef struct _XGI_CH7007TV_TimingVStruct
-{
-  UCHAR data[10];
-} XGI_CH7007TV_TimingVStruct;
-
-typedef struct _XGI_XG21CRT1Struct
-{
- UCHAR ModeID,CR02,CR03,CR15,CR16;
-} XGI_XG21CRT1Struct;
-
-typedef struct _XGI330_CHTVRegDataStruct
-{
- UCHAR Reg[16];
-} XGI330_CHTVRegDataStruct;
-
-typedef struct _XGI330_LCDCapStruct
-{
-               UCHAR      LCD_ID;
-                USHORT     LCD_Capability;
-                UCHAR      LCD_SetFlag;
-                UCHAR      LCD_DelayCompensation;
-                UCHAR      LCD_HSyncWidth;
-                UCHAR      LCD_VSyncWidth;
-                UCHAR      LCD_VCLK;
-                UCHAR      LCDA_VCLKData1;
-                UCHAR      LCDA_VCLKData2;
-                UCHAR      LCUCHAR_VCLKData1;
-                UCHAR      LCUCHAR_VCLKData2;
-                UCHAR      PSC_S1;
-                UCHAR      PSC_S2;
-                UCHAR      PSC_S3;
-                UCHAR      PSC_S4;
-                UCHAR      PSC_S5;
-                UCHAR      PWD_2B;
-                UCHAR      PWD_2C;
-                UCHAR      PWD_2D;
-                UCHAR      PWD_2E;
-                UCHAR      PWD_2F;
-                UCHAR      Spectrum_31;
-                UCHAR      Spectrum_32;
-                UCHAR      Spectrum_33;
-                UCHAR      Spectrum_34;
-} XGI330_LCDCapStruct;
-
-typedef struct _XGI21_LVDSCapStruct
-{
-                USHORT     LVDS_Capability;
-                USHORT     LVDSHT;
-                USHORT     LVDSVT;
-                USHORT     LVDSHDE;
-                USHORT     LVDSVDE;
-                USHORT     LVDSHFP;
-                USHORT     LVDSVFP;
-                USHORT     LVDSHSYNC;
-                USHORT     LVDSVSYNC;
-                UCHAR      VCLKData1;
-                UCHAR      VCLKData2;
-                UCHAR      PSC_S1;
-                UCHAR      PSC_S2;
-                UCHAR      PSC_S3;
-                UCHAR      PSC_S4;
-                UCHAR      PSC_S5;
-} XGI21_LVDSCapStruct;
-
-typedef struct _XGI_CRT1TableStruct
-{
-  UCHAR CR[16];
-} XGI_CRT1TableStruct;
-
-
-typedef struct _XGI330_VCLKDataStruct
-{
-    UCHAR SR2B,SR2C;
-    USHORT CLOCK;
-} XGI330_VCLKDataStruct;
-
-typedef struct _XGI301C_Tap4TimingStruct
-{
-    USHORT DE;
-    UCHAR  Reg[64];   /* C0-FF */
-} XGI301C_Tap4TimingStruct;
-
-typedef struct _XGI_New_StandTableStruct
-{
-       UCHAR  CRT_COLS;
-       UCHAR  ROWS;
-       UCHAR  CHAR_HEIGHT;
-       USHORT CRT_LEN;
-       UCHAR  SR[4];
-       UCHAR  MISC;
-       UCHAR  CRTC[0x19];
-       UCHAR  ATTR[0x14];
-       UCHAR  GRC[9];
-} XGI_New_StandTableStruct;
-
-typedef UCHAR DRAM8Type[8];
-typedef UCHAR DRAM4Type[4];
-typedef UCHAR DRAM32Type[32];
-typedef UCHAR DRAM2Type[2];
-
-typedef struct _VB_DEVICE_INFO  VB_DEVICE_INFO;
-typedef VB_DEVICE_INFO *       PVB_DEVICE_INFO;
-
-struct _VB_DEVICE_INFO
-{
-    BOOLEAN  ISXPDOS;
-    ULONG   P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
-    ULONG   P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
-    ULONG   Part0Port,Part1Port,Part2Port;
-    ULONG   Part3Port,Part4Port,Part5Port;
-    USHORT   RVBHCFACT,RVBHCMAX,RVBHRS;
-    USHORT   VGAVT,VGAHT,VGAVDE,VGAHDE;
-    USHORT   VT,HT,VDE,HDE;
-    USHORT   LCDHRS,LCDVRS,LCDHDES,LCDVDES;
-
-    USHORT   ModeType;
-    USHORT   IF_DEF_LVDS,IF_DEF_TRUMPION,IF_DEF_DSTN;/* ,IF_DEF_FSTN; add for dstn */
-    USHORT   IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
-    USHORT   IF_DEF_LCDA,IF_DEF_CH7017,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
-    USHORT   IF_DEF_ExpLink;
-    USHORT   IF_DEF_CH7005,IF_DEF_HiVision;
-    USHORT   IF_DEF_CH7007; /* Billy 2007/05/03 */
-    USHORT   LCDResInfo,LCDTypeInfo, VBType;/*301b*/
-    USHORT   VBInfo,TVInfo,LCDInfo, Set_VGAType;
-    USHORT   VBExtInfo;/*301lv*/
-    USHORT   SetFlag;
-    USHORT   NewFlickerMode;
-    USHORT   SelectCRT2Rate;
-
-    PUCHAR ROMAddr;
-    PUCHAR FBAddr;
-    ULONG BaseAddr;
-    ULONG RelIO;
-
-    DRAM4Type  *CR6B;
-    DRAM4Type  *CR6E;
-    DRAM32Type *CR6F;
-    DRAM2Type  *CR89;
-
-    DRAM8Type  *SR15; /* pointer : point to array */
-    DRAM8Type  *CR40;
-    UCHAR  *pSoftSetting;
-    UCHAR  *pOutputSelect;
-
-    USHORT *pRGBSenseData;
-    USHORT *pRGBSenseData2; /*301b*/
-    USHORT *pVideoSenseData;
-    USHORT *pVideoSenseData2;
-    USHORT *pYCSenseData;
-    USHORT *pYCSenseData2;
-
-    UCHAR  *pSR07;
-    UCHAR  *CR49;
-    UCHAR  *pSR1F;
-    UCHAR  *AGPReg;
-    UCHAR  *SR16;
-    UCHAR  *pSR21;
-    UCHAR  *pSR22;
-    UCHAR  *pSR23;
-    UCHAR  *pSR24;
-    UCHAR  *SR25;
-    UCHAR  *pSR31;
-    UCHAR  *pSR32;
-    UCHAR  *pSR33;
-    UCHAR  *pSR36;      /* alan 12/07/2006 */
-    UCHAR  *pCRCF;
-    UCHAR  *pCRD0;      /* alan 12/07/2006 */
-    UCHAR  *pCRDE;      /* alan 12/07/2006 */
-    UCHAR  *pCR8F;      /* alan 12/07/2006 */
-    UCHAR  *pSR40;      /* alan 12/07/2006 */
-    UCHAR  *pSR41;      /* alan 12/07/2006 */
-    UCHAR  *pDVOSetting;
-    UCHAR  *pCR2E;
-    UCHAR  *pCR2F;
-    UCHAR  *pCR46;
-    UCHAR  *pCR47;
-    UCHAR  *pCRT2Data_1_2;
-    UCHAR  *pCRT2Data_4_D;
-    UCHAR  *pCRT2Data_4_E;
-    UCHAR  *pCRT2Data_4_10;
-    XGI_MCLKDataStruct  *MCLKData;
-    XGI_ECLKDataStruct  *ECLKData;
-
-    UCHAR   *XGI_TVDelayList;
-    UCHAR   *XGI_TVDelayList2;
-    UCHAR   *CHTVVCLKUNTSC;
-    UCHAR   *CHTVVCLKONTSC;
-    UCHAR   *CHTVVCLKUPAL;
-    UCHAR   *CHTVVCLKOPAL;
-    UCHAR   *NTSCTiming;
-    UCHAR   *PALTiming;
-    UCHAR   *HiTVExtTiming;
-    UCHAR   *HiTVSt1Timing;
-    UCHAR   *HiTVSt2Timing;
-    UCHAR   *HiTVTextTiming;
-    UCHAR   *YPbPr750pTiming;
-    UCHAR   *YPbPr525pTiming;
-    UCHAR   *YPbPr525iTiming;
-    UCHAR   *HiTVGroup3Data;
-    UCHAR   *HiTVGroup3Simu;
-    UCHAR   *HiTVGroup3Text;
-    UCHAR   *Ren525pGroup3;
-    UCHAR   *Ren750pGroup3;
-    UCHAR   *ScreenOffset;
-    UCHAR   *pXGINew_DRAMTypeDefinition;
-    UCHAR   *pXGINew_I2CDefinition ;
-    UCHAR   *pXGINew_CR97 ;
-
-    XGI330_LCDCapStruct  *LCDCapList;
-    XGI21_LVDSCapStruct  *XG21_LVDSCapList;
-
-    XGI_TimingHStruct  *TimingH;
-    XGI_TimingVStruct  *TimingV;
-
-    XGI_StStruct          *SModeIDTable;
-    XGI_StandTableStruct  *StandTable;
-    XGI_ExtStruct         *EModeIDTable;
-    XGI_Ext2Struct        *RefIndex;
+struct XGI_TimingHStruct
+{
+  unsigned char data[8];
+};
+
+struct XGI_TimingVStruct
+{
+  unsigned char data[7];
+};
+
+struct XGI_CH7007TV_TimingHStruct
+{
+  unsigned char data[10];
+};
+
+struct XGI_CH7007TV_TimingVStruct
+{
+  unsigned char data[10];
+};
+
+struct XGI_XG21CRT1Struct
+{
+ unsigned char ModeID, CR02, CR03, CR15, CR16;
+};
+
+struct XGI330_CHTVRegDataStruct
+{
+ unsigned char Reg[16];
+};
+
+struct XGI330_LCDCapStruct
+{
+               unsigned char      LCD_ID;
+               unsigned short     LCD_Capability;
+               unsigned char      LCD_SetFlag;
+               unsigned char      LCD_DelayCompensation;
+               unsigned char      LCD_HSyncWidth;
+               unsigned char      LCD_VSyncWidth;
+               unsigned char      LCD_VCLK;
+               unsigned char      LCDA_VCLKData1;
+               unsigned char      LCDA_VCLKData2;
+               unsigned char      LCUCHAR_VCLKData1;
+               unsigned char      LCUCHAR_VCLKData2;
+               unsigned char      PSC_S1;
+               unsigned char      PSC_S2;
+               unsigned char      PSC_S3;
+               unsigned char      PSC_S4;
+               unsigned char      PSC_S5;
+               unsigned char      PWD_2B;
+               unsigned char      PWD_2C;
+               unsigned char      PWD_2D;
+               unsigned char      PWD_2E;
+               unsigned char      PWD_2F;
+               unsigned char      Spectrum_31;
+               unsigned char      Spectrum_32;
+               unsigned char      Spectrum_33;
+               unsigned char      Spectrum_34;
+};
+
+struct XGI21_LVDSCapStruct
+{
+               unsigned short     LVDS_Capability;
+               unsigned short     LVDSHT;
+               unsigned short     LVDSVT;
+               unsigned short     LVDSHDE;
+               unsigned short     LVDSVDE;
+               unsigned short     LVDSHFP;
+               unsigned short     LVDSVFP;
+               unsigned short     LVDSHSYNC;
+               unsigned short     LVDSVSYNC;
+               unsigned char      VCLKData1;
+               unsigned char      VCLKData2;
+               unsigned char      PSC_S1;
+               unsigned char      PSC_S2;
+               unsigned char      PSC_S3;
+               unsigned char      PSC_S4;
+               unsigned char      PSC_S5;
+};
+
+struct XGI_CRT1TableStruct
+{
+  unsigned char CR[16];
+};
+
+
+struct XGI330_VCLKDataStruct
+{
+    unsigned char SR2B, SR2C;
+    unsigned short CLOCK;
+};
+
+struct XGI301C_Tap4TimingStruct
+{
+    unsigned short DE;
+    unsigned char  Reg[64];   /* C0-FF */
+};
+
+struct XGI_New_StandTableStruct
+{
+       unsigned char  CRT_COLS;
+       unsigned char  ROWS;
+       unsigned char  CHAR_HEIGHT;
+       unsigned short CRT_LEN;
+       unsigned char  SR[4];
+       unsigned char  MISC;
+       unsigned char  CRTC[0x19];
+       unsigned char  ATTR[0x14];
+       unsigned char  GRC[9];
+};
+
+struct vb_device_info
+{
+    unsigned char  ISXPDOS;
+    unsigned long   P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
+    unsigned long   P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
+    unsigned long   Part0Port,Part1Port,Part2Port;
+    unsigned long   Part3Port,Part4Port,Part5Port;
+    unsigned short   RVBHCFACT,RVBHCMAX,RVBHRS;
+    unsigned short   VGAVT,VGAHT,VGAVDE,VGAHDE;
+    unsigned short   VT,HT,VDE,HDE;
+    unsigned short   LCDHRS,LCDVRS,LCDHDES,LCDVDES;
+
+    unsigned short   ModeType;
+    unsigned short   IF_DEF_LVDS,IF_DEF_TRUMPION,IF_DEF_DSTN;/* ,IF_DEF_FSTN; add for dstn */
+    unsigned short   IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
+    unsigned short   IF_DEF_LCDA,IF_DEF_CH7017,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
+    unsigned short   IF_DEF_ExpLink;
+    unsigned short   IF_DEF_CH7005,IF_DEF_HiVision;
+    unsigned short   IF_DEF_CH7007; /* Billy 2007/05/03 */
+    unsigned short   LCDResInfo,LCDTypeInfo, VBType;/*301b*/
+    unsigned short   VBInfo,TVInfo,LCDInfo, Set_VGAType;
+    unsigned short   VBExtInfo;/*301lv*/
+    unsigned short   SetFlag;
+    unsigned short   NewFlickerMode;
+    unsigned short   SelectCRT2Rate;
+
+    unsigned char *ROMAddr;
+    unsigned char *FBAddr;
+    unsigned long BaseAddr;
+    unsigned long RelIO;
+
+       unsigned char (*CR6B)[4];
+       unsigned char (*CR6E)[4];
+       unsigned char (*CR6F)[32];
+       unsigned char (*CR89)[2];
+
+       unsigned char (*SR15)[8];
+       unsigned char (*CR40)[8];
+
+    unsigned char  *pSoftSetting;
+    unsigned char  *pOutputSelect;
+
+    unsigned short *pRGBSenseData;
+    unsigned short *pRGBSenseData2; /*301b*/
+    unsigned short *pVideoSenseData;
+    unsigned short *pVideoSenseData2;
+    unsigned short *pYCSenseData;
+    unsigned short *pYCSenseData2;
+
+    unsigned char  *pSR07;
+    unsigned char  *CR49;
+    unsigned char  *pSR1F;
+    unsigned char  *AGPReg;
+    unsigned char  *SR16;
+    unsigned char  *pSR21;
+    unsigned char  *pSR22;
+    unsigned char  *pSR23;
+    unsigned char  *pSR24;
+    unsigned char  *SR25;
+    unsigned char  *pSR31;
+    unsigned char  *pSR32;
+    unsigned char  *pSR33;
+    unsigned char  *pSR36;      /* alan 12/07/2006 */
+    unsigned char  *pCRCF;
+    unsigned char  *pCRD0;      /* alan 12/07/2006 */
+    unsigned char  *pCRDE;      /* alan 12/07/2006 */
+    unsigned char  *pCR8F;      /* alan 12/07/2006 */
+    unsigned char  *pSR40;      /* alan 12/07/2006 */
+    unsigned char  *pSR41;      /* alan 12/07/2006 */
+    unsigned char  *pDVOSetting;
+    unsigned char  *pCR2E;
+    unsigned char  *pCR2F;
+    unsigned char  *pCR46;
+    unsigned char  *pCR47;
+    unsigned char  *pCRT2Data_1_2;
+    unsigned char  *pCRT2Data_4_D;
+    unsigned char  *pCRT2Data_4_E;
+    unsigned char  *pCRT2Data_4_10;
+    struct XGI_MCLKDataStruct  *MCLKData;
+    struct XGI_ECLKDataStruct  *ECLKData;
+
+    unsigned char   *XGI_TVDelayList;
+    unsigned char   *XGI_TVDelayList2;
+    unsigned char   *CHTVVCLKUNTSC;
+    unsigned char   *CHTVVCLKONTSC;
+    unsigned char   *CHTVVCLKUPAL;
+    unsigned char   *CHTVVCLKOPAL;
+    unsigned char   *NTSCTiming;
+    unsigned char   *PALTiming;
+    unsigned char   *HiTVExtTiming;
+    unsigned char   *HiTVSt1Timing;
+    unsigned char   *HiTVSt2Timing;
+    unsigned char   *HiTVTextTiming;
+    unsigned char   *YPbPr750pTiming;
+    unsigned char   *YPbPr525pTiming;
+    unsigned char   *YPbPr525iTiming;
+    unsigned char   *HiTVGroup3Data;
+    unsigned char   *HiTVGroup3Simu;
+    unsigned char   *HiTVGroup3Text;
+    unsigned char   *Ren525pGroup3;
+    unsigned char   *Ren750pGroup3;
+    unsigned char   *ScreenOffset;
+    unsigned char   *pXGINew_DRAMTypeDefinition;
+    unsigned char   *pXGINew_I2CDefinition ;
+    unsigned char   *pXGINew_CR97 ;
+
+    struct XGI330_LCDCapStruct  *LCDCapList;
+    struct XGI21_LVDSCapStruct  *XG21_LVDSCapList;
+
+    struct XGI_TimingHStruct  *TimingH;
+    struct XGI_TimingVStruct  *TimingV;
+
+    struct XGI_StStruct          *SModeIDTable;
+    struct XGI_StandTableStruct  *StandTable;
+    struct XGI_ExtStruct         *EModeIDTable;
+    struct XGI_Ext2Struct        *RefIndex;
     /* XGINew_CRT1TableStruct *CRT1Table; */
-    XGI_CRT1TableStruct    *XGINEWUB_CRT1Table;
-    XGI_VCLKDataStruct    *VCLKData;
-    XGI_VBVCLKDataStruct  *VBVCLKData;
-    XGI_StResInfoStruct   *StResInfo;
-    XGI_ModeResInfoStruct *ModeResInfo;
-    XGI_XG21CRT1Struct   *UpdateCRT1;
-};  /* _VB_DEVICE_INFO */
-
-
-typedef struct
-{
-    USHORT    Horizontal_ACTIVE;
-    USHORT    Horizontal_FP;
-    USHORT    Horizontal_SYNC;
-    USHORT    Horizontal_BP;
-    USHORT    Vertical_ACTIVE;
-    USHORT    Vertical_FP;
-    USHORT    Vertical_SYNC;
-    USHORT    Vertical_BP;
+    struct XGI_CRT1TableStruct    *XGINEWUB_CRT1Table;
+    struct XGI_VCLKDataStruct    *VCLKData;
+    struct XGI_VBVCLKDataStruct  *VBVCLKData;
+    struct XGI_StResInfoStruct   *StResInfo;
+    struct XGI_ModeResInfoStruct *ModeResInfo;
+    struct XGI_XG21CRT1Struct    *UpdateCRT1;
+};  /* _struct vb_device_info */
+
+
+struct TimingInfo
+{
+    unsigned short    Horizontal_ACTIVE;
+    unsigned short    Horizontal_FP;
+    unsigned short    Horizontal_SYNC;
+    unsigned short    Horizontal_BP;
+    unsigned short    Vertical_ACTIVE;
+    unsigned short    Vertical_FP;
+    unsigned short    Vertical_SYNC;
+    unsigned short    Vertical_BP;
     double    DCLK;
-    UCHAR     FrameRate;
-    UCHAR     Interlace;
-    USHORT    Margin;
-} TimingInfo;
+    unsigned char     FrameRate;
+    unsigned char     Interlace;
+    unsigned short    Margin;
+};
 
 #define _VB_STRUCT_
 #endif /* _VB_STRUCT_ */
index 781caefc56b14cc1f924127dec6131d99d51c920..510ef76786856a3f8274e050346a443176ddb514 100644 (file)
@@ -1,7 +1,7 @@
 #define  Tap4
 
 
-XGI_MCLKDataStruct XGI330New_MCLKData[]=
+struct XGI_MCLKDataStruct XGI330New_MCLKData[] =
 {
  { 0x5c,0x23,0x01,166},
  { 0x5c,0x23,0x01,166},
@@ -13,7 +13,7 @@ XGI_MCLKDataStruct XGI330New_MCLKData[]=
  { 0x29,0x01,0x81,300}
 };
 //yilin modify for xgi20
-XGI_MCLKDataStruct XGI340New_MCLKData[]=
+struct XGI_MCLKDataStruct XGI340New_MCLKData[] =
 {
  { 0x16,0x01,0x01,166},
  { 0x19,0x02,0x01,124},
@@ -25,7 +25,7 @@ XGI_MCLKDataStruct XGI340New_MCLKData[]=
  { 0x5c,0x23,0x01,166}
 };
 
-XGI_MCLKDataStruct XGI27New_MCLKData[]=
+struct XGI_MCLKDataStruct XGI27New_MCLKData[] =
 {
  { 0x5c,0x23,0x01,166},
  { 0x19,0x02,0x01,124},
@@ -37,7 +37,7 @@ XGI_MCLKDataStruct XGI27New_MCLKData[]=
  { 0x5c,0x23,0x01,166}
 };
 
-XGI_ECLKDataStruct XGI330_ECLKData[]=
+struct XGI_ECLKDataStruct XGI330_ECLKData[] =
 {
  { 0x7c,0x08,0x01,200},
  { 0x7c,0x08,0x01,200},
@@ -49,7 +49,7 @@ XGI_ECLKDataStruct XGI330_ECLKData[]=
  { 0x29,0x01,0x81,300}
 };
 //yilin modify for xgi20
-XGI_ECLKDataStruct XGI340_ECLKData[]=
+struct XGI_ECLKDataStruct XGI340_ECLKData[] =
 {
  { 0x5c,0x23,0x01,166},
  { 0x55,0x84,0x01,123},
@@ -63,14 +63,14 @@ XGI_ECLKDataStruct XGI340_ECLKData[]=
 
 
 
-UCHAR XGI340_SR13[4][8]={
+unsigned char XGI340_SR13[4][8] = {
 {0x35,0x45,0xb1,0x00,0x00,0x00,0x00,0x00},/* SR13 */
 {0x41,0x51,0x5c,0x00,0x00,0x00,0x00,0x00},/* SR14 */
 {0x31,0x42,0x42,0x00,0x00,0x00,0x00,0x00},/* SR18 */
 {0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00}/* SR1B */
 };
 
-UCHAR XGI340_cr41[24][8]=
+unsigned char XGI340_cr41[24][8] =
 {{0x20,0x50,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
 {0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
 {0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
@@ -98,7 +98,7 @@ UCHAR XGI340_cr41[24][8]=
 };
 
 
-UCHAR XGI27_cr41[24][8]=
+unsigned char XGI27_cr41[24][8] =
 {
 {0x20,0x40,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
 {0xC4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
@@ -126,37 +126,7 @@ UCHAR XGI27_cr41[24][8]=
 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
 };
 
-
-#if 0
-UCHAR XGI27_cr41[24][8]=
-{
-{0x20,0x60,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
-{0x04,0x44,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
-{0x04,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
-{0xb5,0x03,0xa4,0x00,0x00,0x00,0x00,0x00},/* 3 CR40[7],CR99[2:0],CR45[3:0]*/
-{0xf0,0xf5,0xf0,0x00,0x00,0x00,0x00,0x00},/* 4 CR59 */
-{0xa4,0x1C,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
-{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
-{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
-{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
-{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
-{0x48,0xa8,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
-{0x77,0x88,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
-{0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
-{0x44,0x32,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
-{0x44,0x33,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
-{0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
-{0x44,0x63,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
-{0x0A,0x14,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
-{0x0C,0x0B,0x0C,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
-{0x05,0x22,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
-{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
-{0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
-};
-#endif
-UCHAR XGI340_CR6B[8][4]={
+unsigned char XGI340_CR6B[8][4] = {
 {0xaa,0xaa,0xaa,0xaa},
 {0xaa,0xaa,0xaa,0xaa},
 {0xaa,0xaa,0xaa,0xaa},
@@ -167,7 +137,7 @@ UCHAR XGI340_CR6B[8][4]={
 {0x00,0x00,0x00,0x00}
 };
 
-UCHAR XGI340_CR6E[8][4]={
+unsigned char XGI340_CR6E[8][4] = {
 {0x00,0x00,0x00,0x00},
 {0x00,0x00,0x00,0x00},
 {0x00,0x00,0x00,0x00},
@@ -178,7 +148,7 @@ UCHAR XGI340_CR6E[8][4]={
 {0x00,0x00,0x00,0x00}
 };
 
-UCHAR XGI340_CR6F[8][32]={
+unsigned char XGI340_CR6F[8][32] = {
 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
@@ -189,7 +159,7 @@ UCHAR XGI340_CR6F[8][32]={
 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-UCHAR XGI340_CR89[8][2]={
+unsigned char XGI340_CR89[8][2] = {
 {0x00,0x00},
 {0x00,0x00},
 {0x00,0x00},
@@ -200,11 +170,12 @@ UCHAR XGI340_CR89[8][2]={
 {0x00,0x00}
 };
                         /* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */
-UCHAR XGI340_AGPReg[12]={0x28,0x23,0x00,0x20,0x00,0x20,0x00,0x05,0xd0,0x10,0x10,0x00};
+unsigned char XGI340_AGPReg[12] = {0x28, 0x23, 0x00, 0x20, 0x00, 0x20, 0x00,
+                                  0x05, 0xd0, 0x10, 0x10, 0x00};
 
-UCHAR XGI340_SR16[4]={0x03,0x83,0x03,0x83};
+unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83};
 
-UCHAR XGI330_SR15_1[8][8]={
+unsigned char XGI330_SR15_1[8][8] = {
 {0x0,0x0,0x00,0x00,0x20,0x20,0x00,0x00},
 {0x5,0x15,0x15,0x15,0x15,0x15,0x00,0x00},
 {0xba,0xba,0xba,0xba,0xBA,0xBA,0x00,0x00},
@@ -215,7 +186,7 @@ UCHAR XGI330_SR15_1[8][8]={
 {0x0,0xa5,0xfb,0xf6,0xF6,0xF6,0x00,0x00}
 };
 
-UCHAR XGI330_cr40_1[15][8]={
+unsigned char XGI330_cr40_1[15][8] = {
 {0x66,0x40,0x40,0x28,0x24,0x24,0x00,0x00},
 {0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
@@ -233,14 +204,14 @@ UCHAR XGI330_cr40_1[15][8]={
 {0x00,0xA2,0x00,0x00,0xA2,0xA2,0x00,0x00},
 };
 
-UCHAR XGI330_sr25[]={0x00,0x0};
-UCHAR XGI330_sr31=0xc0;
-UCHAR XGI330_sr32=0x11;
-UCHAR XGI330_SR33=0x00;
-UCHAR XG40_CRCF=0x13;
-UCHAR XG40_DRAMTypeDefinition=0xFF ;
+unsigned char XGI330_sr25[] = {0x00, 0x0};
+unsigned char XGI330_sr31 = 0xc0;
+unsigned char XGI330_sr32 = 0x11;
+unsigned char XGI330_SR33 = 0x00;
+unsigned char XG40_CRCF = 0x13;
+unsigned char XG40_DRAMTypeDefinition = 0xFF ;
 
-XGI_StStruct XGI330_SModeIDTable[]=
+struct XGI_StStruct XGI330_SModeIDTable[] =
 {
  {0x01,0x9208,0x01,0x00,0x10,0x00,0x00,0x01,0x00},
  {0x01,0x1210,0x14,0x01,0x00,0x01,0x00,0x01,0x00},
@@ -265,7 +236,7 @@ XGI_StStruct XGI330_SModeIDTable[]=
 };
 
 
-XGI_ExtStruct  XGI330_EModeIDTable[]=
+struct XGI_ExtStruct  XGI330_EModeIDTable[] =
 {
  {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x0e},
  {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x06},
@@ -337,7 +308,7 @@ XGI_ExtStruct  XGI330_EModeIDTable[]=
  {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-XGI_StandTableStruct XGI330_StandTable[]=
+struct XGI_StandTableStruct XGI330_StandTable[] =
 {
 /* MD_0_200 */
  {
@@ -775,13 +746,13 @@ XGI_StandTableStruct XGI330_StandTable[]=
  }
 };
 
-XGI_TimingHStruct XGI_TimingH[]=
+struct XGI_TimingHStruct XGI_TimingH[] =
 {{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
 
-XGI_TimingVStruct XGI_TimingV[]=
+struct XGI_TimingVStruct XGI_TimingV[] =
 {{{0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
 
-XGI_XG21CRT1Struct XGI_UpdateCRT1Table[]=
+struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] =
 {
  {0x01,0x27,0x91,0x8f,0xc0},   /* 00 */
  {0x03,0x4f,0x83,0x8f,0xc0},   /* 01 */
@@ -802,7 +773,7 @@ XGI_XG21CRT1Struct XGI_UpdateCRT1Table[]=
  {0x59,0x27,0x91,0x8f,0xc0}    /* 16 */
 };
 
-XGI_CRT1TableStruct XGI_CRT1Table[]=
+struct XGI_CRT1TableStruct XGI_CRT1Table[] =
 {
  {{0x2d,0x28,0x90,0x2c,0x90,0x00,0x04,0x00,
     0xbf,0x1f,0x9c,0x8e,0x96,0xb9,0x30}}, /* 0x0 */
@@ -950,7 +921,7 @@ XGI_CRT1TableStruct XGI_CRT1Table[]=
     0x03,0xDE,0xC0,0x84,0xBF,0x04,0x90}}  /* 0x47 */
 };
 
-XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
+struct XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
                 /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
                 {{      0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 00 (640x200,640x400) */
                 {{      0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 01 (640x350) */
@@ -961,7 +932,7 @@ XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
                 {{      0xEE,0x77,0xBB,0x66,0x87,0x32,0x01,0x5A,0x04,0x00,0x80,0x1B,0xD4,0x2F,0x6F,0x00  }}/* 06 (1024x768) ;;5/6/02 */
           };
 
-XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[]= {
+struct XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[] = {
                 /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
                 {{      0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 00 (640x200,640x400) */
                 {{      0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 01 (640x350) */
@@ -972,7 +943,7 @@ XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[]= {
                 {{      0xED,0x77,0xBB,0x66,0x8C,0x21,0x02,0x5A,0x04,0x00,0x80,0x1F,0xA0,0x7E,0x73,0x00  }}/* 06 (1024x768) ;;5/6/02 */
           };
 
-XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[]=  {
+struct XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[] = {
                 /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
                 {{      0x41,0x7F,0xB7,0x34,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* ; 00 (640x200,640x400) */
                 {{      0x41,0x7F,0xB7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* ; 01 (640x350) */
@@ -983,7 +954,7 @@ XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[]=  {
                 {{      0xE5,0x7F,0xB7,0x1D,0xA7,0x3E,0x04,0x5A,0x05,0x00,0x80,0x20,0x3E,0xE4,0x22,0x00  }}/* ; 06 (1024x768) ;;1/12/02 */
          };
 
-XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[]={
+struct XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[] = {
                 /* Index:000,0x01,0x02,0x04,0x03,0x05,0x06,0x07,0x08,0x15,0x1F,0x0C,0x0D,0x0E,0x0F,0x10h */
                 {{      0x41,0x7F,0xB7,0x36,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
                 {{      0x41,0x7F,0xB7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
@@ -994,14 +965,14 @@ XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[]={
                 {{      0xE4,0x7F,0xB7,0x1E,0xAF,0x29,0x37,0x5A,0x05,0x00,0x80,0x25,0x8C,0xB2,0x2A,0x00 }}/* 06 (1024x768) ;;1/12/02 */
             };
 
-UCHAR XGI_CH7017LV1024x768[]={0x60,0x02,0x00,0x07,0x40,0xED,0xA3,
-                                       0xC8,0xC7,0xAC,0xE0,0x02};
-UCHAR XGI_CH7017LV1400x1050[]={0x60,0x03,0x11,0x00,0x40,0xE3,0xAD,
-                                       0xDB,0xF6,0xAC,0xE0,0x02};
+unsigned char XGI_CH7017LV1024x768[] = {0x60, 0x02, 0x00, 0x07, 0x40, 0xED, 0xA3,
+                                       0xC8, 0xC7, 0xAC, 0xE0, 0x02};
+unsigned char XGI_CH7017LV1400x1050[] = {0x60, 0x03, 0x11, 0x00, 0x40, 0xE3, 0xAD,
+                                        0xDB, 0xF6, 0xAC, 0xE0, 0x02};
 
 
 /*add for new UNIVGABIOS*/
-XGI330_LCDDataStruct  XGI_StLCD1024x768Data[]=
+struct XGI330_LCDDataStruct  XGI_StLCD1024x768Data[] =
 {
  {   62,  25, 800, 546,1344, 806},
  {   32,  15, 930, 546,1344, 806},
@@ -1012,7 +983,7 @@ XGI330_LCDDataStruct  XGI_StLCD1024x768Data[]=
  {    1,   1,1344, 806,1344, 806}
 };
 
-XGI330_LCDDataStruct  XGI_ExtLCD1024x768Data[]=
+struct XGI330_LCDDataStruct  XGI_ExtLCD1024x768Data[] =
 {
  {   42,  25,1536, 419,1344, 806}, /* { 12, 5, 896, 512,1344, 806}, // alan 09/12/2003 */
  {   48,  25,1536, 369,1344, 806}, /* { 12, 5, 896, 510,1344, 806}, // alan 09/12/2003 */
@@ -1029,7 +1000,7 @@ XGI330_LCDDataStruct  XGI_ExtLCD1024x768Data[]=
  {    1,   1,1344, 806,1344, 806}
 };
 
-/*XGI330_LCDDataStruct  XGI_St2LCD1024x768Data[]=
+/*struct XGI330_LCDDataStruct  XGI_St2LCD1024x768Data[] =
 {
  {   62,  25, 800, 546,1344, 806},
  {   32,  15, 930, 546,1344, 806},
@@ -1040,7 +1011,7 @@ XGI330_LCDDataStruct  XGI_ExtLCD1024x768Data[]=
  {    1,   1,1344, 806,1344, 806}
 };*/
 
-XGI330_LCDDataStruct  XGI_CetLCD1024x768Data[]=
+struct XGI330_LCDDataStruct  XGI_CetLCD1024x768Data[] =
 {
        {         1,1,1344,806,1344,806           }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {         1,1,1344,806,1344,806           }, /* 01 (320x350,640x350) */
@@ -1051,7 +1022,7 @@ XGI330_LCDDataStruct  XGI_CetLCD1024x768Data[]=
         {         1,1,1344,806,1344,806           }  /* 06 (1024x768x60Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_StLCD1280x1024Data[]=
+struct XGI330_LCDDataStruct  XGI_StLCD1280x1024Data[] =
 {
  {   22,   5, 800, 510,1650,1088},
  {   22,   5, 800, 510,1650,1088},
@@ -1063,7 +1034,7 @@ XGI330_LCDDataStruct  XGI_StLCD1280x1024Data[]=
  {    1,   1,1688,1066,1688,1066}
 };
 
-XGI330_LCDDataStruct  XGI_ExtLCD1280x1024Data[]=
+struct XGI330_LCDDataStruct  XGI_ExtLCD1280x1024Data[] =
 {
  {  211,  60,1024, 501,1688,1066},
  {  211,  60,1024, 508,1688,1066},
@@ -1075,7 +1046,7 @@ XGI330_LCDDataStruct  XGI_ExtLCD1280x1024Data[]=
  {    1,   1,1688,1066,1688,1066}
 };
 
-XGI330_LCDDataStruct  XGI_St2LCD1280x1024Data[]=
+struct XGI330_LCDDataStruct  XGI_St2LCD1280x1024Data[] =
 {
  {   22,   5, 800, 510,1650,1088},
  {   22,   5, 800, 510,1650,1088},
@@ -1087,7 +1058,7 @@ XGI330_LCDDataStruct  XGI_St2LCD1280x1024Data[]=
  {    1,   1,1688,1066,1688,1066}
 };
 
-XGI330_LCDDataStruct  XGI_CetLCD1280x1024Data[]=
+struct XGI330_LCDDataStruct  XGI_CetLCD1280x1024Data[] =
 {
        {         1,1,1688,1066,1688,1066         }, /* 00 (320x200,320x400,640x200,640x400) */
         {         1,1,1688,1066,1688,1066         }, /* 01 (320x350,640x350) */
@@ -1100,7 +1071,7 @@ XGI330_LCDDataStruct  XGI_CetLCD1280x1024Data[]=
         {         1,1,1688,1066,1688,1066         } /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_StLCD1400x1050Data[]=
+struct XGI330_LCDDataStruct  XGI_StLCD1400x1050Data[] =
 {
        {         211,100,2100,408,1688,1066      }, /* 00 (320x200,320x400,640x200,640x400) */
         {         211,64,1536,358,1688,1066       }, /* 01 (320x350,640x350) */
@@ -1113,7 +1084,7 @@ XGI330_LCDDataStruct  XGI_StLCD1400x1050Data[]=
         {         1,1,1688,1066,1688,1066         }  /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_ExtLCD1400x1050Data[]=
+struct XGI330_LCDDataStruct  XGI_ExtLCD1400x1050Data[] =
 {
        {         211,100,2100,408,1688,1066      }, /* 00 (320x200,320x400,640x200,640x400) */
         {         211,64,1536,358,1688,1066       }, /* 01 (320x350,640x350) */
@@ -1126,7 +1097,7 @@ XGI330_LCDDataStruct  XGI_ExtLCD1400x1050Data[]=
         {         1,1,1688,1066,1688,1066         }  /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_ExtLCD1600x1200Data[]=
+struct XGI330_LCDDataStruct  XGI_ExtLCD1600x1200Data[] =
 {
         {         4,1,1620,420,2160,1250          }, /* { 3,1,2160,425,2160,1250 }, // 00 (320x200,320x400,640x200,640x400) // alan 10/14/2003 */
         {         27,7,1920,375,2160,1250         }, /* 01 (320x350,640x350) */
@@ -1140,7 +1111,7 @@ XGI330_LCDDataStruct  XGI_ExtLCD1600x1200Data[]=
         {         1,1,2160,1250,2160,1250         }  /* 09 (1600x1200x60Hz) ;302lv */
 };
 
-XGI330_LCDDataStruct  XGI_StLCD1600x1200Data[]=
+struct XGI330_LCDDataStruct  XGI_StLCD1600x1200Data[] =
 {
         {         27,4,800,500,2160,1250          },/* 00 (320x200,320x400,640x200,640x400) */
         {         27,4,800,500,2160,1250          },/* 01 (320x350,640x350) */
@@ -1154,7 +1125,7 @@ XGI330_LCDDataStruct  XGI_StLCD1600x1200Data[]=
         {         1,1,2160,1250,2160,1250         } /* 09 (1600x1200) */
 };
 
-XGI330_LCDDataStruct  XGI_CetLCD1400x1050Data[]=
+struct XGI330_LCDDataStruct  XGI_CetLCD1400x1050Data[] =
 {
        {         1,1,1688,1066,1688,1066         }, /* 00 (320x200,320x400,640x200,640x400) */
         {         1,1,1688,1066,1688,1066         }, /* 01 (320x350,640x350) */
@@ -1167,7 +1138,7 @@ XGI330_LCDDataStruct  XGI_CetLCD1400x1050Data[]=
         {         1,1,1688,1066,1688,1066         }  /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_NoScalingData[]=
+struct XGI330_LCDDataStruct  XGI_NoScalingData[] =
 {
  {    1,   1, 800, 449, 800, 449},
  {    1,   1, 800, 449, 800, 449},
@@ -1179,7 +1150,7 @@ XGI330_LCDDataStruct  XGI_NoScalingData[]=
  {    1,   1,1688,1066,1688,1066}
 };
 
-XGI330_LCDDataStruct  XGI_ExtLCD1024x768x75Data[]=
+struct XGI330_LCDDataStruct  XGI_ExtLCD1024x768x75Data[] =
 {
         {42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
@@ -1190,7 +1161,7 @@ XGI330_LCDDataStruct  XGI_ExtLCD1024x768x75Data[]=
         {1,1,1312,800,1312,800   }  /* ; 06 (1024x768x75Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_StLCD1024x768x75Data[]=
+struct XGI330_LCDDataStruct  XGI_StLCD1024x768x75Data[] =
 {
         {42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
@@ -1201,7 +1172,7 @@ XGI330_LCDDataStruct  XGI_StLCD1024x768x75Data[]=
         {1,1,1312,800,1312,800   }  /* ; 06 (1024x768x75Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_CetLCD1024x768x75Data[]=
+struct XGI330_LCDDataStruct  XGI_CetLCD1024x768x75Data[] =
 {
         {1,1,1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
         {1,1,1312,800,1312,800}, /* ; 01 (320x350,640x350) */
@@ -1212,7 +1183,7 @@ XGI330_LCDDataStruct  XGI_CetLCD1024x768x75Data[]=
         {1,1,1312,800,1312,800} /* ; 06 (1024x768x75Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_ExtLCD1280x1024x75Data[]=
+struct XGI330_LCDDataStruct  XGI_ExtLCD1280x1024x75Data[] =
 {
         {211,60,1024,501,1688,1066   }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {211,60,1024,508,1688,1066   }, /* ; 01 (320x350,640x350) */
@@ -1224,7 +1195,7 @@ XGI330_LCDDataStruct  XGI_ExtLCD1280x1024x75Data[]=
         {1,1,1688,1066,1688,1066     }  /* ; 07 (1280x1024x75Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_StLCD1280x1024x75Data[]=
+struct XGI330_LCDDataStruct  XGI_StLCD1280x1024x75Data[] =
 {
         {211,60,1024,501,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {211,60,1024,508,1688,1066 }, /* ; 01 (320x350,640x350) */
@@ -1236,7 +1207,7 @@ XGI330_LCDDataStruct  XGI_StLCD1280x1024x75Data[]=
         {1,1,1688,1066,1688,1066   }  /* ; 07 (1280x1024x75Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_CetLCD1280x1024x75Data[]=
+struct XGI330_LCDDataStruct  XGI_CetLCD1280x1024x75Data[] =
 {
         {1,1,1688,1066,1688,1066}, /* ; 00 (320x200,320x400,640x200,640x400) */
         {1,1,1688,1066,1688,1066}, /* ; 01 (320x350,640x350) */
@@ -1248,7 +1219,7 @@ XGI330_LCDDataStruct  XGI_CetLCD1280x1024x75Data[]=
         {1,1,1688,1066,1688,1066}  /* ; 07 (1280x1024x75Hz) */
 };
 
-XGI330_LCDDataStruct  XGI_NoScalingDatax75[]=
+struct XGI330_LCDDataStruct  XGI_NoScalingDatax75[] =
 {
         {1,1,800,449,800,449    }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {1,1,800,449,800,449    }, /* ; 01 (320x350,640x350) */
@@ -1263,7 +1234,7 @@ XGI330_LCDDataStruct  XGI_NoScalingDatax75[]=
         {1,1,1688,806,1688,806  }  /* ; 0A (1280x768x75Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768Data[]=
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768Data[] =
 {
    {  9,1057,0, 771  }, /* ; 00 (320x200,320x400,640x200,640x400) */
    {  9,1057,0, 771  }, /* ; 01 (320x350,640x350) */
@@ -1274,7 +1245,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768Data[]=
    {  9,1057,805, 770  }  /* ; 06 (1024x768x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768Data[] =
 {
         { 9,1057,737,703   }, /* ; 00 (320x200,320x400,640x200,640x400) */
         { 9,1057,686,651   }, /* ; 01 (320x350,640x350) */
@@ -1285,7 +1256,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768Data[]=
         { 9,1057,805,770   }  /* ; 06 (1024x768x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768Data[]=
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768Data[] =
 {
                {      1152,856,622,587   }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {      1152,856,597,562   }, /* ; 01 (320x350,640x350) */
@@ -1296,7 +1267,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768Data[]=
         {      0,1048,805,770   }  /* ; 06 (1024x768x60Hz) */
 };
 
-XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[]=
+struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] =
 {
         {      18,1346,981,940     },/* 00 (320x200,320x400,640x200,640x400) */
         {      18,1346,926,865     },/* 01 (320x350,640x350) */
@@ -1308,7 +1279,7 @@ XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[]=
         {      18,1346,1065,1024     }/* 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[]=
+struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] =
 {
         {      18,1346,970,907     },/* 00 (320x200,320x400,640x200,640x400) */
         {      18,1346,917,854     },/* 01 (320x350,640x350) */
@@ -1320,7 +1291,7 @@ XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[]=
         {      18,1346,1065,1024     }/* 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024Data[]=
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024Data[] =
 {
         {      1368,1008,752,711    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      1368,1008,729,688    }, /* 01 (320x350,640x350) */
@@ -1332,7 +1303,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024Data[]=
         {      18,1346,1065,1024    }  /* 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024Data[]=
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024Data[] =
 {
         {      9,1337,981,940    }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {      9,1337,926,884    }, /* ; 01 (320x350,640x350) alan, 2003/09/30 */
@@ -1344,7 +1315,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024Data[]=
         {      9,1337,1065,1024    }  /* ; 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024Data[] =
 {
         {      9,1337,970,907    }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {      9,1337,917,854    }, /* ; 01 (320x350,640x350) */
@@ -1356,7 +1327,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024Data[]=
         {      9,1337,1065,1024    }  /* ; 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024Data[]=
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024Data[] =
 {
         {      1368,1008,752,711    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      1368,1008,729,688    }, /* 01 (320x350,640x350) */
@@ -1368,7 +1339,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024Data[]=
         {      9,1337,1065,1024    }  /* 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDLDes1400x1050Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1400x1050Data[] =
 {
         {      18,1464,0,1051    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      18,1464,0,1051    }, /* 01 (320x350,640x350) */
@@ -1381,7 +1352,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDLDes1400x1050Data[]=
         {      18,1464,0,1051    }  /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1400x1050Data[]=
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1400x1050Data[] =
 {
         {      18,1464,0,1051    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      18,1464,0,1051    }, /* 01 (320x350,640x350) */
@@ -1394,7 +1365,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1400x1050Data[]=
         {      18,1464,0,1051    }  /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDes1400x1050Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDes1400x1050Data[] =
 {
         {      9,1455,0,1051     },/* 00 (320x200,320x400,640x200,640x400) */
         {      9,1455,0,1051     },/* 01 (320x350,640x350) */
@@ -1407,7 +1378,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDes1400x1050Data[]=
         {      9,1455,0,1051     } /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDes1400x1050Data[]=
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1400x1050Data[] =
 {
         {      9,1455,0,1051     },/* 00 (320x200,320x400,640x200,640x400) */
         {      9,1455,0,1051     },/* 01 (320x350,640x350) */
@@ -1420,7 +1391,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDes1400x1050Data[]=
         {      9,1455,0,1051     } /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data[]=
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data[] =
 {
         {      1308,1068,781,766    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      1308,1068,781,766    }, /* 01 (320x350,640x350) */
@@ -1433,7 +1404,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data[]=
         {      18,1464,0,1051    } /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data2[]=
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data2[] =
 {
         {      0,1448,0,1051    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      0,1448,0,1051    }, /* 01 (320x350,640x350) */
@@ -1444,7 +1415,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data2[]=
 
 
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1600x1200Data[]=
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1600x1200Data[] =
 {
        {      18,1682,0,1201    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      18,1682,0,1201    }, /* 01 (320x350,640x350) */
@@ -1458,7 +1429,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1600x1200Data[]=
         {      18,1682,0,1201    }  /* 09 (1600x1200x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDLDes1600x1200Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1600x1200Data[] =
 {
         {      18,1682,1150,1101    }, /* 00 (320x200,320x400,640x200,640x400) */
         {      18,1682,1083,1034    }, /* 01 (320x350,640x350) */
@@ -1472,7 +1443,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDLDes1600x1200Data[]=
         {      18,1682,0,1201    } /* 09 (1600x1200x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDes1600x1200Data[]=
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1600x1200Data[] =
 {
         {      9,1673,0,1201     },/* 00 (320x200,320x400,640x200,640x400) */
         {      9,1673,0,1201     },/* 01 (320x350,640x350) */
@@ -1486,7 +1457,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDes1600x1200Data[]=
         {      9,1673,0,1201     } /* 09 (1600x1200x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDes1600x1200Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDes1600x1200Data[] =
 {
        {      9,1673,1150,1101     },/* 00 (320x200,320x400,640x200,640x400) */
         {      9,1673,1083,1034     },/* 01 (320x350,640x350) */
@@ -1500,7 +1471,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDes1600x1200Data[]=
         {      9,1673,0,1201     } /* 09 (1600x1200x60Hz) */
 };
 
-XGI330_LCDDataDesStruct2  XGI_NoScalingDesData[]=
+struct XGI330_LCDDataDesStruct2  XGI_NoScalingDesData[] =
 {
         {     9,657,448,405,96,2  }, /* 00 (320x200,320x400,640x200,640x400) */
         {     9,657,448,355,96,2  }, /* 01 (320x350,640x350) */
@@ -1515,7 +1486,7 @@ XGI330_LCDDataDesStruct2  XGI_NoScalingDesData[]=
         {     9,1337,0,771,112,6  }  /* 0A (1280x768x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768x75Data[]=               /* ;;1024x768x75Hz */
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768x75Data[] =               /* ;;1024x768x75Hz */
 {
         {9,1049,0,769},    /* ; 00 (320x200,320x400,640x200,640x400) */
         {9,1049,0,769},    /* ; 01 (320x350,640x350) */
@@ -1526,7 +1497,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768x75Data[]=          /* ;;1024x768x75Hz */
         {9,1049,0,769}     /* ; 06 (1024x768x75Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768x75Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768x75Data[] =
 {
         {9,1049,0,769},    /* ; 00 (320x200,320x400,640x200,640x400) */
         {9,1049,0,769},    /* ; 01 (320x350,640x350) */
@@ -1537,7 +1508,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768x75Data[]=
         {9,1049,0,769}     /* ; 06 (1024x768x75Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768x75Data[]=       /* ;;1024x768x75Hz */
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768x75Data[] =       /* ;;1024x768x75Hz */
 {
         {1152,856,622,587},     /* ; 00 (320x200,320x400,640x200,640x400) */
         {1152,856,597,562},     /* ; 01 (320x350,640x350) */
@@ -1548,7 +1519,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768x75Data[]=  /* ;;1024x768x75Hz */
         {9,1049,0,769}                 /* ; 06 (1024x768x75Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1280x1024x75Data[]=         /* ;;1280x1024x75Hz */
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1280x1024x75Data[] =         /* ;;1280x1024x75Hz */
 {
         {18,1314,0,1025     },/* ; 00 (320x200,320x400,640x200,640x400) */
         {18,1314,0,1025     },/* ; 01 (320x350,640x350) */
@@ -1560,7 +1531,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1280x1024x75Data[]=         /* ;;1280x10
         {18,1314,0,1025     }/* ; 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDLDes1280x1024x75Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1280x1024x75Data[] =
 {
         {18,1314,0,1025     },/* ; 00 (320x200,320x400,640x200,640x400) */
         {18,1314,0,1025     },/* ; 01 (320x350,640x350) */
@@ -1572,7 +1543,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDLDes1280x1024x75Data[]=
         {18,1314,0,1025     }/* ; 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024x75Data[]=    /* 1280x1024x75Hz */
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024x75Data[] =    /* 1280x1024x75Hz */
 {
         {1368,1008,752,711},    /* ; 00 (320x200,320x400,640x200,640x400) */
         {1368,1008,729,688},    /* ; 01 (320x350,640x350) */
@@ -1584,7 +1555,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024x75Data[]=       /* 1280x1024x75Hz */
         {18,1314,0,1025}         /* ; 07 (1280x1024x75Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024x75Data[]=         /* ;;1280x1024x75Hz */
+struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024x75Data[] =         /* ;;1280x1024x75Hz */
 {
        {9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
         {9,1305,0,1025},/* ; 01 (320x350,640x350) */
@@ -1596,7 +1567,7 @@ XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024x75Data[]=         /* ;;1280x1024
         {9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024x75Data[]=
+struct XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024x75Data[] =
 {
        {9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
         {9,1305,0,1025},/* ; 01 (320x350,640x350) */
@@ -1608,7 +1579,7 @@ XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024x75Data[]=
         {9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
 };
 
-XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024x75Data[]=      /* 1280x1024x75Hz */
+struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024x75Data[] =      /* 1280x1024x75Hz */
 {
         {1368,1008,752,711},    /* ; 00 (320x200,320x400,640x200,640x400) */
         {1368,1008,729,688},    /* ; 01 (320x350,640x350) */
@@ -1620,7 +1591,7 @@ XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024x75Data[]= /* 1280x1024x75Hz */
         {9,1305,0,1025}          /* ; 07 (1280x1024x75Hz) */
 };
 
-XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[]= /* Scaling LCD 75Hz */
+struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = /* Scaling LCD 75Hz */
 {
        {9,657,448,405,96,2},   /* ; 00 (320x200,320x400,640x200,640x400) */
         {9,657,448,355,96,2},   /* ; 01 (320x350,640x350) */
@@ -1635,7 +1606,7 @@ XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[]= /* Scaling LCD 75Hz */
         {9,1337,0,771,112,6}    /* ; 0A (1280x768x60Hz) */
 };
 
-XGI330_TVDataStruct  XGI_StPALData[]=
+struct XGI330_TVDataStruct  XGI_StPALData[] =
 {
  {    1,   1, 864, 525,1270, 400, 100,   0, 760},
  {    1,   1, 864, 525,1270, 350, 100,   0, 760},
@@ -1645,7 +1616,7 @@ XGI330_TVDataStruct  XGI_StPALData[]=
  {    1,   1, 864, 525,1270, 600,  50,   0,   0}
 };
 
-XGI330_TVDataStruct  XGI_ExtPALData[]=
+struct XGI330_TVDataStruct  XGI_ExtPALData[] =
 {
  {    2,   1,1080, 463,1270, 500,  50,   0,  50},
  {   15,   7,1152, 413,1270, 500,  50,   0,  50},
@@ -1657,7 +1628,7 @@ XGI330_TVDataStruct  XGI_ExtPALData[]=
  {    3,   2,1080, 619,1270, 540, 438,   0, 438}
 };
 
-XGI330_TVDataStruct  XGI_StNTSCData[]=
+struct XGI330_TVDataStruct  XGI_StNTSCData[] =
 {
  {    1,   1, 858, 525,1270, 400,  50,   0, 760},
  {    1,   1, 858, 525,1270, 350,  50,   0, 640},
@@ -1666,7 +1637,7 @@ XGI330_TVDataStruct  XGI_StNTSCData[]=
  {    1,   1, 858, 525,1270, 480,   0,   0, 760}
 };
 
-XGI330_TVDataStruct  XGI_ExtNTSCData[]=
+struct XGI330_TVDataStruct  XGI_ExtNTSCData[] =
 {
  {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
  {   12,  5,  858, 403,1270, 420, 171,   0, 171},
@@ -1679,7 +1650,7 @@ XGI330_TVDataStruct  XGI_ExtNTSCData[]=
  {    3,   2,1001, 533,1270, 420,   0,   0,   0}
 };
 
-XGI330_TVDataStruct  XGI_St1HiTVData[]=
+struct XGI330_TVDataStruct  XGI_St1HiTVData[] =
 {
        {        1,1,892,563,690,800,0,0,0               }, /* 00 (320x200,320x400,640x200,640x400) */
         {        1,1,892,563,690,700,0,0,0               }, /* 01 (320x350,640x350) */
@@ -1689,7 +1660,7 @@ XGI330_TVDataStruct  XGI_St1HiTVData[]=
         {        8,5,1050,683,1648,960,0x150,1,0         }  /* 05 (400x300,800x600) */
 };
 
-XGI330_TVDataStruct  XGI_St2HiTVData[]=
+struct XGI330_TVDataStruct  XGI_St2HiTVData[] =
 {
         {        3,1,840,483,1648,960,0x032,0,0          }, /* 00 (320x200,320x400,640x200,640x400) */
         {        1,1,892,563,690,700,0,0,0               }, /* 01 (320x350,640x350) */
@@ -1700,7 +1671,7 @@ XGI330_TVDataStruct  XGI_St2HiTVData[]=
 
 };
 
-XGI330_TVDataStruct  XGI_ExtHiTVData[]=
+struct XGI330_TVDataStruct  XGI_ExtHiTVData[] =
 {
         {        6,1,840,563,1632,960,0,0,0              }, /* 00 (320x200,320x400,640x200,640x400) */
         {        3,1,960,563,1632,960,0,0,0              }, /* 01 (320x350,640x350) */
@@ -1716,7 +1687,7 @@ XGI330_TVDataStruct  XGI_ExtHiTVData[]=
 
 };
 
-XGI330_TVDataStruct  XGI_ExtYPbPr525iData[]=
+struct XGI330_TVDataStruct  XGI_ExtYPbPr525iData[] =
 {
  {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
  {   12,  5,  858, 403,1270, 420, 171,   0, 171},
@@ -1729,7 +1700,7 @@ XGI330_TVDataStruct  XGI_ExtYPbPr525iData[]=
  {    3,   2,1001, 533,1250, 420,   0,   0,   0}
 };
 
-XGI330_TVDataStruct  XGI_StYPbPr525iData[]=
+struct XGI330_TVDataStruct  XGI_StYPbPr525iData[] =
 {
  {    1,   1, 858, 525,1270, 400,  50,   0, 760},
  {    1,   1, 858, 525,1270, 350,  50,   0, 640},
@@ -1738,7 +1709,7 @@ XGI330_TVDataStruct  XGI_StYPbPr525iData[]=
  {    1,   1, 858, 525,1270, 480,   0,   0, 760},
 };
 
-XGI330_TVDataStruct  XGI_ExtYPbPr525pData[]=
+struct XGI330_TVDataStruct  XGI_ExtYPbPr525pData[] =
 {
  {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
  {   12,  5,  858, 403,1270, 420, 171,   0, 171},
@@ -1751,7 +1722,7 @@ XGI330_TVDataStruct  XGI_ExtYPbPr525pData[]=
  {    3,   2,1001, 533,1270, 420,   0,   0,   0}
  };
 
-XGI330_TVDataStruct  XGI_StYPbPr525pData[]=
+struct XGI330_TVDataStruct  XGI_StYPbPr525pData[] =
 {
  {    1,   1,1716, 525,1270, 400,  50,   0, 760},
  {    1,   1,1716, 525,1270, 350,  50,   0, 640},
@@ -1760,7 +1731,7 @@ XGI330_TVDataStruct  XGI_StYPbPr525pData[]=
  {    1,   1,1716, 525,1270, 480,   0,   0, 760},
 };
 
-XGI330_TVDataStruct  XGI_ExtYPbPr750pData[]=
+struct XGI330_TVDataStruct  XGI_ExtYPbPr750pData[] =
 {
  {    3,   1, 935, 470,1130, 680,  50,   0,   0},       /* 00 (320x200,320x400,640x200,640x400) */
  {   24,   7, 935, 420,1130, 680,  50,   0,   0},       /* 01 (320x350,640x350) */
@@ -1775,7 +1746,7 @@ XGI330_TVDataStruct  XGI_ExtYPbPr750pData[]=
  {   10,   9,1320, 830,1130, 640,  50,   0,   0}
 };
 
-XGI330_TVDataStruct  XGI_StYPbPr750pData[]=
+struct XGI330_TVDataStruct  XGI_StYPbPr750pData[] =
 {
  {    1,   1,1650, 750,1280, 400,  50,   0, 760},
  {    1,   1,1650, 750,1280, 350,  50,   0, 640},
@@ -1784,7 +1755,7 @@ XGI330_TVDataStruct  XGI_StYPbPr750pData[]=
  {    1,   1,1650, 750,1280, 480,   0,   0, 760},
 };
 
-UCHAR XGI330_NTSCTiming[] = {
+unsigned char XGI330_NTSCTiming[] = {
   0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
   0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
   0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
@@ -1794,7 +1765,7 @@ UCHAR XGI330_NTSCTiming[] = {
   0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
   0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00};
 
-UCHAR XGI330_PALTiming[] = {
+unsigned char XGI330_PALTiming[] = {
   0x21,0x5A,0x35,0x6e,0x04,0x38,0x3d,0x70,
   0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
   0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
@@ -1804,7 +1775,7 @@ UCHAR XGI330_PALTiming[] = {
   0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
   0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00};
 
-UCHAR XGI330_HiTVExtTiming[] =
+unsigned char XGI330_HiTVExtTiming[] =
 {
       0x2D,0x60,0x2C,0x5F,0x08,0x31,0x3A,0x64,
       0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1818,7 +1789,7 @@ UCHAR XGI330_HiTVExtTiming[] =
 
 };
 
-UCHAR XGI330_HiTVSt1Timing[] =
+unsigned char XGI330_HiTVSt1Timing[] =
 {
       0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
       0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1831,7 +1802,7 @@ UCHAR XGI330_HiTVSt1Timing[] =
       0x0E,0x00,0xfc,0xff,0x2d,0x00
 };
 
-UCHAR XGI330_HiTVSt2Timing[] =
+unsigned char XGI330_HiTVSt2Timing[] =
 {
       0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x64,
       0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1844,7 +1815,7 @@ UCHAR XGI330_HiTVSt2Timing[] =
       0x27,0x00,0xFC,0xff,0x6a,0x00
 };
 
-UCHAR XGI330_HiTVTextTiming[] =
+unsigned char XGI330_HiTVTextTiming[] =
 {
       0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
       0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1857,7 +1828,7 @@ UCHAR XGI330_HiTVTextTiming[] =
       0x11,0x00,0xFC,0xFF,0x32,0x00
 };
 
-UCHAR XGI330_YPbPr750pTiming[] =
+unsigned char XGI330_YPbPr750pTiming[] =
 {
       0x30,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
       0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
@@ -1870,7 +1841,7 @@ UCHAR XGI330_YPbPr750pTiming[] =
       0x11,0x00,0xfc,0xff,0x32,0x00
 };
 
-UCHAR XGI330_YPbPr525pTiming[] =
+unsigned char XGI330_YPbPr525pTiming[] =
 {
       0x3E,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
       0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
@@ -1883,7 +1854,7 @@ UCHAR XGI330_YPbPr525pTiming[] =
       0x11,0x00,0xFC,0xFF,0x32,0x00
 };
 
-UCHAR XGI330_YPbPr525iTiming[] =
+unsigned char XGI330_YPbPr525iTiming[] =
 {
       0x1B,0x21,0x03,0x09,0x05,0x06,0x0C,0x0C,
       0x94,0x49,0x01,0x0A,0x06,0x0D,0x04,0x0A,
@@ -1897,7 +1868,7 @@ UCHAR XGI330_YPbPr525iTiming[] =
 
 };
 
-UCHAR XGI330_HiTVGroup3Data[] =
+unsigned char XGI330_HiTVGroup3Data[] =
 {
       0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x5F,
       0x05,0x21,0xB2,0xB2,0x55,0x77,0x2A,0xA6,
@@ -1909,7 +1880,7 @@ UCHAR XGI330_HiTVGroup3Data[] =
       0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
 };
 
-UCHAR XGI330_HiTVGroup3Simu[] =
+unsigned char XGI330_HiTVGroup3Simu[] =
 {
       0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x95,
       0xDB,0x20,0xB8,0xB8,0x55,0x47,0x2A,0xA6,
@@ -1921,7 +1892,7 @@ UCHAR XGI330_HiTVGroup3Simu[] =
       0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
 };
 
-UCHAR XGI330_HiTVGroup3Text[] =
+unsigned char XGI330_HiTVGroup3Text[] =
 {
       0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0xA7,
       0xF5,0x20,0xCE,0xCE,0x55,0x47,0x2A,0xA6,
@@ -1933,7 +1904,7 @@ UCHAR XGI330_HiTVGroup3Text[] =
       0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
 };
 
-UCHAR XGI330_Ren525pGroup3[] =
+unsigned char XGI330_Ren525pGroup3[] =
 {
   0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x13,
   0xB1,0x41,0x62,0x62,0xFF,0xF4,0x45,0xa6,
@@ -1945,7 +1916,7 @@ UCHAR XGI330_Ren525pGroup3[] =
   0x1a,0x1F,0x25,0x2a,0x4C,0xAA,0x01
 };
 
-UCHAR XGI330_Ren750pGroup3[] =
+unsigned char XGI330_Ren750pGroup3[] =
 {
   0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x7a,
   0x54,0x41,0xE7,0xE7,0xFF,0xF4,0x45,0xa6,
@@ -1957,7 +1928,7 @@ UCHAR XGI330_Ren750pGroup3[] =
   0x18,0x1D,0x23,0x28,0x4C,0xAA,0x01
 };
 
-XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[]=
+struct XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[] =
 {
 {{0x00,0x00}},
 {{0x00,0x00}},
@@ -1977,7 +1948,7 @@ XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[]=
 {{0x00,0x00}}
 };
 
-XGI330_LVDSDataStruct  XGI330_LVDS320x480Data_1[]=
+struct XGI330_LVDSDataStruct  XGI330_LVDS320x480Data_1[] =
 {
  {848, 433,400,525},
  {848, 389,400,525},
@@ -1990,7 +1961,7 @@ XGI330_LVDSDataStruct  XGI330_LVDS320x480Data_1[]=
  {800, 525,1000, 635}
 };
 
-XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_1[]=
+struct XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_1[] =
 {
  {848, 433,1060, 629},
  {848, 389,1060, 629},
@@ -2003,7 +1974,7 @@ XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_1[]=
  {800, 525,1000, 635}
 };
 
-XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_2[]=
+struct XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_2[] =
 {
  {1056, 628,1056, 628},
  {1056, 628,1056, 628},
@@ -2016,7 +1987,7 @@ XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_2[]=
  {800, 525,1000, 635}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_1[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_1[] =
 {
  { 960 , 438 , 1344 , 806 } ,  /* 00 (320x200,320x400,640x200,640x400) */
  { 960 , 388 , 1344 , 806 } ,  /* 01 (320x350,640x350) */
@@ -2028,7 +1999,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_1[]=
 };
 
 
-XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_2[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_2[] =
 {
  {1344, 806,1344, 806},
  {1344, 806,1344, 806},
@@ -2041,7 +2012,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_2[]=
  {800, 525,1280, 813}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_1[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_1[] =
 {
  {1048, 442,1688, 1066},
  {1048, 392,1688, 1066},
@@ -2053,7 +2024,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_1[]=
  {1688, 1066,1688, 1066}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_2[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_2[] =
 {
  {1344, 806,1344, 806},
  {1344, 806,1344, 806},
@@ -2066,7 +2037,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_2[]=
  {800, 525,1280, 813}
 };
 /*
-XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_1[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_1[] =
 {
  {768,438,1408,806},
  {768,388,1408,806},
@@ -2079,7 +2050,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_1[]=
  {1408,806,1408,806}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_2[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_2[] =
 {
  {1408, 806,1408, 806},
  {1408, 806,1408, 806},
@@ -2092,7 +2063,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_2[]=
  {1408, 806,1408, 806}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_1[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_1[] =
 {
  {704, 438,1344, 806},
  {704, 388,1344, 806},
@@ -2105,7 +2076,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_1[]=
  {1344, 806,1344, 806}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_2[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_2[] =
 {
  {1344, 806,1344, 806},
  {1344, 806,1344, 806},
@@ -2118,7 +2089,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_2[]=
  {1344, 806,1344, 806}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_1[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_1[] =
 {
  {1048,438,1688,806},
  {1048,388,1688,806},
@@ -2131,7 +2102,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_1[]=
  {1688,806,1688,806}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_2[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_2[] =
 {
  {1688,806,1688,806},
  {1688,806,1688,806},
@@ -2144,7 +2115,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_2[]=
  {1688,806,1688,806}
 };
 */
-XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_1[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_1[] =
 {
  {928,416,1688,1066},
  {928,366,1688,1066},
@@ -2157,7 +2128,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_1[]=
  {1688,1066,1688,1066}
 };
 
-XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_2[]=
+struct XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_2[] =
 {
  {1688,1066,1688,1066},
  {1688,1066,1688,1066},
@@ -2170,7 +2141,7 @@ XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_2[]=
  {1688,1066,1688,1066}
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] =
 {      /* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */
         {        1088,520,2048,1320      },/* 00 (320x200,320x400,640x200,640x400) */
         {        1088,470,2048,1320      },/* 01 (320x350,640x350) */
@@ -2184,7 +2155,7 @@ XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[]=
         {        2048,1320,2048,1320     } /* 09 (1600x1200) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDSNoScalingData[]=
+struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] =
 {
         {        800,449,800,449             }, /* 00 (320x200,320x400,640x200,640x400) */
         {        800,449,800,449             }, /* 01 (320x350,640x350) */
@@ -2199,7 +2170,7 @@ XGI330_LVDSDataStruct XGI_LVDSNoScalingData[]=
         {        1688,806,1688,806           }  /* 0A (1280x768x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] =
 {
        {960,438,1312,800  }, /* 00 (320x200,320x400,640x200,640x400) */
         {960,388,1312,800  }, /* 01 (320x350,640x350) */
@@ -2211,7 +2182,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[]=
 };
 
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] =
 {
         {1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
         {1312,800,1312,800}, /* ; 01 (320x350,640x350) */
@@ -2222,7 +2193,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[]=
         {1312,800,1312,800}, /* ; 06 (512x384,1024x768) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] =
 {
         {1048,442,1688,1066  }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {1048,392,1688,1066  }, /* ; 01 (320x350,640x350) */
@@ -2234,7 +2205,7 @@ XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[]=
         {1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] =
 {
         {1688,1066,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {1688,1066,1688,1066 }, /* ; 01 (320x350,640x350) */
@@ -2246,7 +2217,7 @@ XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[]=
         {1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[]=
+struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] =
 {
         {800,449,800,449     }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {800,449,800,449     }, /* ; 01 (320x350,640x350) */
@@ -2261,7 +2232,7 @@ XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[]=
         {1688,806,1688,806   }, /* ; 0A (1280x768x75Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] =
 {
        {      0,1048,   0, 771     }, /* 00 (320x200,320x400,640x200,640x400) */
         {      0,1048,   0, 771     }, /* 01 (320x350,640x350) */
@@ -2272,7 +2243,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[]=
         {      0,1048, 805, 770     }  /* 06 (1024x768x60Hz) */
 } ;
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] =
 {
        {      1142, 856, 622, 587     }, /* 00 (320x200,320x400,640x200,640x400) */
         {      1142, 856, 597, 562     }, /* 01 (320x350,640x350) */
@@ -2283,7 +2254,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[]=
         {         0,1048, 805, 771     }  /* 06 (1024x768x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] =
 {
        {       320,  24, 622, 587     }, /* 00 (320x200,320x400,640x200,640x400) */
         {       320,  24, 597, 562     }, /* 01 (320x350,640x350) */
@@ -2292,7 +2263,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[]=
         {       320,  24, 722, 687     }  /* 04 (640x480x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] =
 {
        {      0,1328,    0, 1025     }, /* 00 (320x200,320x400,640x200,640x400) */
         {      0,1328,    0, 1025     }, /* 01 (320x350,640x350) */
@@ -2305,7 +2276,7 @@ XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[]=
 };
 
  /* The Display setting for DE Mode Panel */
-XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] =
 {
        {      1368,1008,752,711     }, /* 00 (320x200,320x400,640x200,640x400) */
         {      1368,1008,729,688     }, /* 01 (320x350,640x350) */
@@ -2317,7 +2288,7 @@ XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[]=
         {      0000,1328,0,1025     }  /* 07 (1280x1024x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] =
 {
        {      0,1448,0,1051     }, /* 00 (320x200,320x400,640x200,640x400) */
         {      0,1448,0,1051     }, /* 01 (320x350,640x350) */
@@ -2330,7 +2301,7 @@ XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[]=
         {      0,1448,0,1051     }  /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] =
 {
        {      1308,1068, 781, 766     }, /* 00 (320x200,320x400,640x200,640x400) */
         {      1308,1068, 781, 766     }, /* 01 (320x350,640x350) */
@@ -2343,7 +2314,7 @@ XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[]=
         {      0,1448,0,1051     }  /* 08 (1400x1050x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[] =
 {
        {      0,1664,0,1201     }, /* 00 (320x200,320x400,640x200,640x400) */
         {      0,1664,0,1201     }, /* 01 (320x350,640x350) */
@@ -2359,7 +2330,7 @@ XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[]=
 
 
 
-XGI330_LCDDataDesStruct2  XGI_LVDSNoScalingDesData[]=
+struct XGI330_LCDDataDesStruct2  XGI_LVDSNoScalingDesData[] =
 {
        {     0, 648, 448, 405,  96,   2   }, /* 00 (320x200,320x400,640x200,640x400) */
         {     0, 648, 448, 355,  96,   2   }, /* 01 (320x350,640x350) */
@@ -2374,7 +2345,7 @@ XGI330_LCDDataDesStruct2  XGI_LVDSNoScalingDesData[]=
         {     0,1328,0,0771, 112,   6   }  /* 0A (1280x768x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[]=                      /* ; 1024x768 Full-screen */
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] =                      /* ; 1024x768 Full-screen */
 {
         {0,1040,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
         {0,1040,0,769}, /* ; 01 (320x350,640x350) */
@@ -2385,7 +2356,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[]=                 /* ; 1024x768 Full-screen */
         {0,1040,0,769} /* ; 06 (1024x768x75Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[]= /* ; 1024x768 center-screen (Enh. Mode) */
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = /* ; 1024x768 center-screen (Enh. Mode) */
 {
         {1142, 856,622,587 }, /* 00 (320x200,320x400,640x200,640x400) */
         {1142, 856,597,562 }, /* 01 (320x350,640x350) */
@@ -2396,7 +2367,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[]= /* ; 1024x768 center-screen (E
         {   0,1048,805,771 }  /* 06 (1024x768x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[]= /* ; 1024x768 center-screen (St.Mode) */
+struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] = /* ; 1024x768 center-screen (St.Mode) */
 {
         {320,24,622,587  }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {320,24,597,562  }, /* ; 01 (320x350,640x350) */
@@ -2405,7 +2376,7 @@ XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[]= /* ; 1024x768 center-screen (S
         {320,24,722,687  } /* ; 04 (640x480x60Hz) */
 };
 
-XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[]=
+struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] =
 {
         {0,1296,0,1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
         {0,1296,0,1025}, /* ; 01 (320x350,640x350) */
@@ -2418,7 +2389,7 @@ XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[]=
 };
 
 /* The Display setting for DE Mode Panel */
-XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[]=   /* [ycchen] 02/18/03 Set DE as default */
+struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[] =   /* [ycchen] 02/18/03 Set DE as default */
 {
         {1368,976,752,711 }, /* ; 00 (320x200,320x400,640x200,640x400) */
         {1368,976,729,688 }, /* ; 01 (320x350,640x350) */
@@ -2430,7 +2401,7 @@ XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[]=   /* [ycchen] 02/18/03 Set DE
         {0,1296,0,1025    } /* ; 07 (1280x1024x75Hz) */
 };
 
-XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[]=  /* Scaling LCD 75Hz */
+struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] =  /* Scaling LCD 75Hz */
 {
        { 0,648,448,405,96,2  }, /* ; 00 (320x200,320x400,640x200,640x400) */
        { 0,648,448,355,96,2  }, /* ; 01 (320x350,640x350) */
@@ -2445,7 +2416,7 @@ XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[]=  /* Scaling LCD 75Hz */
        { 0,1328,0,771,112,6  }  /* ; 0A (1280x768x75Hz) */
 };
 
-XGI330_LVDSDataStruct  XGI330_LVDS640x480Data_1[]=
+struct XGI330_LVDSDataStruct  XGI330_LVDS640x480Data_1[] =
 {
  {800, 449, 800, 449},
  {800, 449, 800, 449},
@@ -2458,7 +2429,7 @@ XGI330_LVDSDataStruct  XGI330_LVDS640x480Data_1[]=
  {1056, 628,1056, 628}
 };
 
-XGI330_CHTVDataStruct  XGI_CHTVUNTSCData[]=
+struct XGI330_CHTVDataStruct  XGI_CHTVUNTSCData[] =
 {
  {840, 600, 840, 600},
  {840, 600, 840, 600},
@@ -2468,7 +2439,7 @@ XGI330_CHTVDataStruct  XGI_CHTVUNTSCData[]=
  {1064, 750,1064, 750}
 };
 
-XGI330_CHTVDataStruct  XGI_CHTVONTSCData[]=
+struct XGI330_CHTVDataStruct  XGI_CHTVONTSCData[] =
 {
  {840, 525, 840, 525},
  {840, 525, 840, 525},
@@ -2478,7 +2449,7 @@ XGI330_CHTVDataStruct  XGI_CHTVONTSCData[]=
  {1040, 700,1040, 700}
 };
 
-XGI330_CHTVDataStruct  XGI_CHTVUPALData[]=
+struct XGI330_CHTVDataStruct  XGI_CHTVUPALData[] =
 {
  {1008, 625,1008, 625},
  {1008, 625,1008, 625},
@@ -2488,7 +2459,7 @@ XGI330_CHTVDataStruct  XGI_CHTVUPALData[]=
  {936, 836, 936, 836}
 };
 
-XGI330_CHTVDataStruct  XGI_CHTVOPALData[]=
+struct XGI330_CHTVDataStruct  XGI_CHTVOPALData[] =
 {
  {1008, 625,1008, 625},
  {1008, 625,1008, 625},
@@ -2498,7 +2469,7 @@ XGI330_CHTVDataStruct  XGI_CHTVOPALData[]=
  {960, 750, 960, 750}
 };
 
-XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_1_H[]=
+struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_1_H[] =
 {
                /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
                 {{      0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }}, /* 00 (320x) */
@@ -2511,7 +2482,7 @@ XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_1_H[]=
                 {{      0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
 };
 
-XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_1_H[]=
+struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_1_H[] =
 {
                /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
                 {{      0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }}, /* 00 (320x) */
@@ -2525,7 +2496,7 @@ XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_1_H[]=
                 {{      0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
 };
 
-XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_2_H[]=
+struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_2_H[] =
 {
                /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
                 {{      0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }}, /* 00 (320x) */
@@ -2538,7 +2509,7 @@ XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_2_H[]=
                 {{      0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
 };
 
-XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_2_H[]=
+struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_2_H[] =
 {
                 /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
                 {{      0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }}, /* 00 (320x) */
@@ -2552,7 +2523,7 @@ XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_2_H[]=
                 {{      0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
 };
 
-XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[]=
+struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] =
 {               /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
                 {{      0x47,0x27,0x8B,0x2C,0x1A,0x00,0x05,0x00 }}, /* 00 (320x) */
                 {{      0x47,0x27,0x8B,0x30,0x1E,0x00,0x05,0x00 }}, /* 01 (360x) */
@@ -2566,7 +2537,7 @@ XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[]=
                 {{      0xCE,0xAE,0x92,0xB3,0x01,0x00,0x03,0x00 }} /* 09 (1400x) */
 };
 
-XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[]=
+struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] =
 {               /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
                 {{      0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 00 (320x) */
                 {{      0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 01 (360x) */
@@ -2580,7 +2551,7 @@ XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[]=
                 {{      0xCE,0xAE,0x92,0xBC,0x0A,0x00,0x03,0x00 }} /* 09 (1400x) */
 };
 
-XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[]=
+struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] =
 /* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */
 {   /* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
                 {{      0x5B,0x27,0x9F,0x32,0x0A,0x00,0x01,0x00 }},/* 00 (320x) */
@@ -2596,7 +2567,7 @@ XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[]=
                {{      0xFB,0xC7,0x9F,0xC9,0x81,0x00,0x07,0x00 }} /* 0A (1600x) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] =
 {               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
                 {{      0x97,0x1F,0x60,0x87,0x5D,0x83,0x10      }}, /* 00 (x350) */
                 {{      0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30      }}, /* 01 (x400) */
@@ -2605,7 +2576,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[]=
                 {{      0x24,0xF5,0x02,0x88,0xFF,0x25,0x90      }} /* 04 (x768) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] =
 {               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
                 {{      0x24,0xBB,0x31,0x87,0x5D,0x25,0x30      }}, /* 00 (x350) */
                 {{      0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30      }}, /* 01 (x400) */
@@ -2614,7 +2585,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[]=
                 {{      0x24,0xF5,0x02,0x88,0xFF,0x25,0x90      }} /* 04 (x768) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] =
 {               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
                 {{       0x86,0x1F,0x5E,0x82,0x5D,0x87,0x00     }}, /* 00 (x350) */
                 {{       0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30     }}, /* 01 (x400) */
@@ -2624,7 +2595,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[]=
                 {{       0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9     }} /* 05 (x1024) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] =
 {               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
                 {{      0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1      }}, /* 00 (x350) */
                 {{      0x28,0xD2,0xC8,0x8C,0xC7,0xF2,0x81      }}, /* 01 (x400) */
@@ -2634,7 +2605,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[]=
                 {{      0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9      }} /* 05 (x1024) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] =
 {               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
                 {{      0x6C,0x1F,0x60,0x84,0x5D,0x6D,0x10      }}, /* 00 (x350) */
                 {{      0x9E,0x1F,0x93,0x86,0x8F,0x9F,0x30      }}, /* 01 (x400) */
@@ -2645,7 +2616,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[]=
                 {{      0x28,0x10,0x1A,0x80,0x19,0x29,0x0F      }} /* 06 (x1050) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] =
 {              /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
                 {{      0x28,0x92,0xB6,0x83,0xB5,0xCF,0x81      }}, /* 00 (x350) */
                 {{      0x28,0x92,0xD5,0x82,0xD4,0xEE,0x81      }}, /* 01 (x400) */
@@ -2656,7 +2627,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[]=
                 {{      0x28,0x10,0x1A,0x87,0x19,0x29,0x8F      }} /* 06 (x1050) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] =
 {
                /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
                 {{      0xd4,0x1F,0x81,0x84,0x5D,0xd5,0x10      }}, /* 00 (x350) */
@@ -2669,7 +2640,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[]=
                 {{      0x26,0x11,0xd3,0x86,0xaF,0x27,0x3f      }} /* 07 (x1200) */
 };
 
-XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[]=
+struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] =
 {      /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
     {{      0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }},/* ; 00 (320x) */
     {{      0x4B,0x27,0x8F,0x2B,0x03,0x00,0x44,0x00 }},/* ; 01 (360x) */
@@ -2681,7 +2652,7 @@ XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[]=
     {{      0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00 }} /* ; 07 (1024x) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] =
 {      /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
     {{      0x97,0x1F,0x60,0x87,0x5D,0x83,0x10      }},/* ; 00 (x350) */
     {{      0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30      }},/* ; 01 (x400) */
@@ -2690,7 +2661,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[]=
     {{      0x1E,0xF5,0x00,0x83,0xFF,0x1F,0x90      }} /* ; 04 (x768) */
 };
 
-XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[]=
+struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] =
 {       /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
     {{      0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 00 (320x) */
     {{      0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 01 (360x) */
@@ -2702,7 +2673,7 @@ XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[]=
     {{      0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* ; 07 (1024x) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] =
 {       /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
     {{      0x24,0xBB,0x31,0x87,0x5D,0x25,0x30      }},/* ; 00 (x350) */
     {{      0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30      }},/* ; 01 (x400) */
@@ -2711,7 +2682,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[]=
     {{      0x24,0xF5,0x02,0x88,0xFF,0x25,0x90      }} /* ; 04 (x768) */
 };
 
-XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[]=
+struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] =
 {      /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
     {{      0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 00 (320x) */
     {{      0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 01 (360x) */
@@ -2724,7 +2695,7 @@ XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[]=
     {{      0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00 }} /* ; 08 (1280x) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] =
 {      /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
     {{      0x86,0xD1,0xBC,0x80,0xBB,0xE5,0x00      }},/* ; 00 (x350) */
     {{      0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30      }},/* ; 01 (x400) */
@@ -2734,7 +2705,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[]=
     {{      0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9      }} /* ; 05 (x1024) */
 };
 
-XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[]=
+struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] =
 {
        /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
     {{      0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }},/* ; 00 (320x) */
@@ -2748,7 +2719,7 @@ XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[]=
     {{      0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* ; 08 (1280x) */
 };
 
-XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[]=
+struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] =
 {
         /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
      {{     0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1     }},/* ; 00 (x350) */
@@ -2759,7 +2730,7 @@ XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[]=
      {{     0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9     }} /* ; 05 (x1024) */
 };
 
-XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UNTSC[]=
+struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UNTSC[] =
 {
  {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
     0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
@@ -2775,7 +2746,7 @@ XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UNTSC[]=
    0x90,0x8c,0x57,0xed,0x20,0x00,0x06,0x01 }}
 };
 
-XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1ONTSC[]=
+struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1ONTSC[] =
 {
  {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
     0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
@@ -2791,7 +2762,7 @@ XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1ONTSC[]=
    0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,0x01 }}
 };
 
-XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UPAL[]=
+struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UPAL[] =
 {
  {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
     0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
@@ -2807,7 +2778,7 @@ XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UPAL[]=
    0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,0x01 }}
 };
 
-XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1OPAL[]=
+struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1OPAL[] =
 {
  {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
     0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
@@ -2824,7 +2795,7 @@ XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1OPAL[]=
 };
 
 /*add for new UNIVGABIOS*/
-XGI330_LCDDataTablStruct XGI_LCDDataTable[]=
+struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] =
 {
   {Panel1024x768,0x0019,0x0001,0},  /* XGI_ExtLCD1024x768Data */
   {Panel1024x768,0x0019,0x0000,1},  /* XGI_StLCD1024x768Data */
@@ -2848,7 +2819,7 @@ XGI330_LCDDataTablStruct XGI_LCDDataTable[]=
   {0xFF,0x0000,0x0000,0}               /* End of table */
 };
 
-XGI330_LCDDataTablStruct XGI_LCDDesDataTable[]=
+struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] =
 {
   {Panel1024x768,0x0019,0x0001,0}, /* XGI_ExtLCDDes1024x768Data */
   {Panel1024x768,0x0019,0x0000,1}, /* XGI_StLCDDes1024x768Data */
@@ -2873,7 +2844,7 @@ XGI330_LCDDataTablStruct XGI_LCDDesDataTable[]=
   {0xFF,0x0000,0x0000,0}
 };
 
-XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[]=
+struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[] =
 {
   {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_H */
   {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_H */
@@ -2889,7 +2860,7 @@ XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[]=
   {0xFF,0x0000,0x0000,0}
 };
 
-XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[]=
+struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[] =
 {
   {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_V */
   {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_V */
@@ -2905,7 +2876,7 @@ XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[]=
   {0xFF,0x0000,0x0000,0}
 };
 
-XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[]=
+struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] =
 {
   {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Data_1 */
   {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDS1024x768Data_2 */
@@ -2923,7 +2894,7 @@ XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[]=
   {0xFF,0x0000,0x0000,0}
 };
 
-XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[]=
+struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] =
 {
   {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Des_1 */
   {Panel1024x768,0x0618,0x0410,1}, /* XGI_LVDS1024x768Des_3 */
@@ -2943,14 +2914,14 @@ XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[]=
   {0xFF,0x0000,0x0000,0}
 };
 
-XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[]=
+struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] =
 {
   {Panel1024x768,0x0000,0x0000,0}, /* XGI_CH7017LV1024x768 */
   {Panel1400x1050,0x0000,0x0000,1}, /* XGI_CH7017LV1400x1050 */
   {0xFF,0x0000,0x0000,0}
 };
 
-XGI330_TVDataTablStruct XGI_TVDataTable[]=
+struct XGI330_TVDataTablStruct XGI_TVDataTable[] =
 {
  {0x09E1,0x0001,0},    /* XGI_ExtPALData */
  {0x09E1,0x0000,1},    /* XGI_ExtNTSCData */
@@ -2968,7 +2939,7 @@ XGI330_TVDataTablStruct XGI_TVDataTable[]=
  {0xffff,0x0000,12}    /* END */
 };
 
-USHORT TVLenList[]=
+unsigned short TVLenList[] =
 {
    LVDSCRT1Len_H,
    LVDSCRT1Len_V,
@@ -2981,7 +2952,7 @@ USHORT TVLenList[]=
 } ;
 
 /* Chrontel 7017 TV CRT1 Timing List */
-XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[]=
+struct XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[] =
 {
   {0x0011,0x0000,0}, /* XGI_CHTVCRT1UNTSC */
   {0x0011,0x0010,1}, /* XGI_CHTVCRT1ONTSC */
@@ -2991,7 +2962,7 @@ XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[]=
 };
 
 /* ;;Chrontel 7017 TV Timing List */
-XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[]=
+struct XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[] =
 {
   {0x0011,0x0000,0}, /* XGI_CHTVUNTSCData */
   {0x0011,0x0010,1}, /* XGI_CHTVONTSCData */
@@ -3001,7 +2972,7 @@ XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[]=
 };
 
 /* ;;Chrontel 7017 TV Reg. List */
-XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[]=
+struct XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[] =
 {
   {0x0011,0x0000,0}, /* XGI_CHTVRegUNTSC */
   {0x0011,0x0010,1}, /* XGI_CHTVRegONTSC */
@@ -3010,7 +2981,7 @@ XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[]=
   {0xFFFF,0x0000,4}
 };
 
-USHORT LCDLenList[]=
+unsigned short LCDLenList[] =
 {
    LVDSCRT1Len_H,
    LVDSCRT1Len_V,
@@ -3024,7 +2995,7 @@ USHORT LCDLenList[]=
    0
 } ;
 
-XGI330_LCDCapStruct  XGI660_LCDDLCapList[]=  /* 660, Dual link */
+struct XGI330_LCDCapStruct  XGI660_LCDDLCapList[] =  /* 660, Dual link */
 {
 /* LCDCap1024x768 */
                {Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
@@ -3056,7 +3027,7 @@ XGI330_LCDCapStruct  XGI660_LCDDLCapList[]=  /* 660, Dual link */
                0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
-XGI330_LCDCapStruct  XGI_LCDDLCapList[]=  /* Dual link only */
+struct XGI330_LCDCapStruct  XGI_LCDDLCapList[] =  /* Dual link only */
 {
 /* LCDCap1024x768 */
                {Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
@@ -3088,7 +3059,7 @@ XGI330_LCDCapStruct  XGI_LCDDLCapList[]=  /* Dual link only */
                0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
-XGI330_LCDCapStruct  XGI660_LCDCapList[]=
+struct XGI330_LCDCapStruct  XGI660_LCDCapList[] =
 {
 /* LCDCap1024x768 */
                 {Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
@@ -3120,7 +3091,7 @@ XGI330_LCDCapStruct  XGI660_LCDCapList[]=
                0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
-XGI330_LCDCapStruct  XGI_LCDCapList[]=
+struct XGI330_LCDCapStruct  XGI_LCDCapList[] =
 {
 /* LCDCap1024x768 */
                {Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
@@ -3152,7 +3123,7 @@ XGI330_LCDCapStruct  XGI_LCDCapList[]=
                0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
-XGI21_LVDSCapStruct XGI21_LCDCapList[]=
+struct XGI21_LVDSCapStruct XGI21_LCDCapList[] =
 {
     {DisableLCD24bpp + LCDPolarity,
      2160,1250,1600,1200,  64,  1,  192,   3,
@@ -3181,7 +3152,7 @@ XGI21_LVDSCapStruct XGI21_LCDCapList[]=
 
 };
 
-XGI_Ext2Struct XGI330_RefIndex[]=
+struct XGI_Ext2Struct XGI330_RefIndex[] =
 {
 {Support32Bpp + SupportAllCRT2 + SyncPN,                       RES320x200,      VCLK25_175, 0x00,0x10,0x59, 320, 200},/* 00 */
 {Support32Bpp + SupportAllCRT2 + SyncPN,                       RES320x200,      VCLK25_175, 0x00,0x10,0x00, 320, 400},/* 01 */
@@ -3260,7 +3231,7 @@ XGI_Ext2Struct XGI330_RefIndex[]=
 
 
 
-XGI330_VCLKDataStruct XGI330_VCLKData[]=
+struct XGI330_VCLKDataStruct XGI330_VCLKData[] =
 {
  { 0x1b,0xe1, 25}, /* 0x0 */
  { 0x4e,0xe4, 28}, /* 0x1 */
@@ -3344,7 +3315,7 @@ XGI330_VCLKDataStruct XGI330_VCLKData[]=
  { 0x3b,0x61,108}  /* 0x4f */
 };
 
-XGI_VBVCLKDataStruct XGI330_VBVCLKData[]=
+struct XGI_VBVCLKDataStruct XGI330_VBVCLKData[] =
 {
  { 0x1b,0xe1, 25}, /* 0x0 */
  { 0x4e,0xe4, 28}, /* 0x1 */
@@ -3422,9 +3393,11 @@ XGI_VBVCLKDataStruct XGI330_VBVCLKData[]=
  { 0x70,0x44,108}, /* 0x49 chiawen for 1400x1050*/
 };
 
-UCHAR XGI330_ScreenOffset[]={ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,0x78,0x80,0x2d,0x35,0x57,0x48 };
+unsigned char XGI330_ScreenOffset[] = { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40,
+                                       0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
+                                       0x57, 0x48};
 
-XGI_StResInfoStruct XGI330_StResInfo[]=
+struct XGI_StResInfoStruct XGI330_StResInfo[] =
 {
  { 640,400},
  { 640,350},
@@ -3433,7 +3406,7 @@ XGI_StResInfoStruct XGI330_StResInfo[]=
  { 640,480}
 };
 
-XGI_ModeResInfoStruct XGI330_ModeResInfo[]=
+struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] =
 {
  {  320, 200, 8, 8},
  {  320, 240, 8, 8},
@@ -3460,10 +3433,10 @@ XGI_ModeResInfoStruct XGI330_ModeResInfo[]=
  { 1152, 864, 8,16}
 };
 
-UCHAR XGI330_OutputSelect =0x40;
-UCHAR XGI330_SoftSetting = 0x30;
-UCHAR XGI330_SR07=0x18;
-UCHAR XGI330New_SR15[8][8]={
+unsigned char XGI330_OutputSelect = 0x40;
+unsigned char XGI330_SoftSetting = 0x30;
+unsigned char XGI330_SR07 = 0x18;
+unsigned char XGI330New_SR15[8][8] = {
 {0x0,0x4,0x60,0x60},
 {0xf,0xf,0xf,0xf},
 {0xba,0xba,0xba,0xba},
@@ -3474,7 +3447,7 @@ UCHAR XGI330New_SR15[8][8]={
 {0x0,0xa5,0xfb,0xf6}
 };
 
-UCHAR XGI330New_CR40[5][8]={
+unsigned char XGI330New_CR40[5][8] = {
 {0x77,0x77,0x44,0x44},
 {0x77,0x77,0x44,0x44},
 {0x0,0x0,0x0,0x0},
@@ -3482,63 +3455,63 @@ UCHAR XGI330New_CR40[5][8]={
 {0x0,0x0,0xf0,0xf8}
 };
 
-UCHAR XGI330_CR49[]={0xaa,0x88};
-UCHAR XGI330_SR1F=0x0;
-UCHAR XGI330_SR21=0xa3;
-UCHAR XGI330_650_SR21=0xa7;
-UCHAR XGI330_SR22=0xfb;
-UCHAR XGI330_SR23=0xf6;
-UCHAR XGI330_SR24=0xd;
-
-UCHAR XGI660_SR21=0xa3;/* 2003.0312 */
-UCHAR XGI660_SR22=0xf3;/* 2003.0312 */
-
-UCHAR XGI330_LVDS_SR32=0x00;   /* ynlai for 650 LVDS */
-UCHAR XGI330_LVDS_SR33=0x00;   /* chiawen for 650 LVDS */
-UCHAR XGI330_650_SR31=0x40;
-UCHAR XGI330_650_SR33=0x04;
-UCHAR XGI330_CRT2Data_1_2 = 0x0;
-UCHAR XGI330_CRT2Data_4_D = 0x0;
-UCHAR XGI330_CRT2Data_4_E = 0x0;
-UCHAR XGI330_CRT2Data_4_10 = 0x80;
-USHORT XGI330_RGBSenseData = 0xd1;
-USHORT XGI330_VideoSenseData = 0xb9;
-USHORT XGI330_YCSenseData = 0xb3;
-USHORT XGI330_RGBSenseData2 = 0x0190;     /*301b*/
-USHORT XGI330_VideoSenseData2 = 0x0110;
-USHORT XGI330_YCSenseData2 = 0x016B;
-UCHAR XGI330_NTSCPhase[] = {0x21,0xed,0x8a,0x8};
-UCHAR XGI330_PALPhase[] = {0x2a,0x5,0xd3,0x0};
-UCHAR XGI330_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};/*301b*/
-UCHAR XGI330_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
-UCHAR XGI330_PALMPhase[] = {0x21,0xE4,0x2E,0x9B};   /*palmn*/
-UCHAR XGI330_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
-UCHAR XG40_I2CDefinition = 0x00 ;
-UCHAR XG20_CR97 = 0x10 ;
-
-UCHAR XG21_DVOSetting = 0x00 ;
-UCHAR XG21_CR2E = 0x00 ;
-UCHAR XG21_CR2F = 0x00 ;
-UCHAR XG21_CR46 = 0x00 ;
-UCHAR XG21_CR47 = 0x00 ;
-
-UCHAR XG27_CR97 = 0xC1 ;
-UCHAR XG27_SR36 = 0x30 ;
-UCHAR XG27_CR8F = 0x0C ;
-UCHAR XG27_CRD0[] = {0,0,0,0,0,0,0,0x82,0x00,0x66,0x01,0x00} ;
-UCHAR XG27_CRDE[] = {0,0} ;
-UCHAR XG27_SR40 = 0x04 ;
-UCHAR XG27_SR41 = 0x00 ;
-
-UCHAR XGI330_CHTVVCLKUNTSC[]={0x00 };
-
-UCHAR XGI330_CHTVVCLKONTSC[]={0x00 };
-
-UCHAR XGI330_CHTVVCLKUPAL[]={0x00 };
-
-UCHAR XGI330_CHTVVCLKOPAL[]={0x00 };
-
-UCHAR XGI7007_CHTVVCLKUNTSC[]={CH7007TVVCLK30_2,
+unsigned char XGI330_CR49[] = {0xaa, 0x88};
+unsigned char XGI330_SR1F = 0x0;
+unsigned char XGI330_SR21 = 0xa3;
+unsigned char XGI330_650_SR21 = 0xa7;
+unsigned char XGI330_SR22 = 0xfb;
+unsigned char XGI330_SR23 = 0xf6;
+unsigned char XGI330_SR24 = 0xd;
+
+unsigned char XGI660_SR21 = 0xa3;/* 2003.0312 */
+unsigned char XGI660_SR22 = 0xf3;/* 2003.0312 */
+
+unsigned char XGI330_LVDS_SR32 = 0x00;   /* ynlai for 650 LVDS */
+unsigned char XGI330_LVDS_SR33 = 0x00; /* chiawen for 650 LVDS */
+unsigned char XGI330_650_SR31 = 0x40;
+unsigned char XGI330_650_SR33 = 0x04;
+unsigned char XGI330_CRT2Data_1_2 = 0x0;
+unsigned char XGI330_CRT2Data_4_D = 0x0;
+unsigned char XGI330_CRT2Data_4_E = 0x0;
+unsigned char XGI330_CRT2Data_4_10 = 0x80;
+unsigned short XGI330_RGBSenseData = 0xd1;
+unsigned short XGI330_VideoSenseData = 0xb9;
+unsigned short XGI330_YCSenseData = 0xb3;
+unsigned short XGI330_RGBSenseData2 = 0x0190;     /*301b*/
+unsigned short XGI330_VideoSenseData2 = 0x0110;
+unsigned short XGI330_YCSenseData2 = 0x016B;
+unsigned char XGI330_NTSCPhase[] = {0x21, 0xed, 0x8a, 0x8};
+unsigned char XGI330_PALPhase[] = {0x2a, 0x5, 0xd3, 0x0};
+unsigned char XGI330_NTSCPhase2[] = {0x21, 0xF0, 0x7B, 0xD6};/*301b*/
+unsigned char XGI330_PALPhase2[] = {0x2a, 0x09, 0x86, 0xe9};
+unsigned char XGI330_PALMPhase[] = {0x21, 0xE4, 0x2E, 0x9B};   /*palmn*/
+unsigned char XGI330_PALNPhase[] = {0x21, 0xF4, 0x3E, 0xBA};
+unsigned char XG40_I2CDefinition = 0x00 ;
+unsigned char XG20_CR97 = 0x10 ;
+
+unsigned char XG21_DVOSetting = 0x00 ;
+unsigned char XG21_CR2E = 0x00 ;
+unsigned char XG21_CR2F = 0x00 ;
+unsigned char XG21_CR46 = 0x00 ;
+unsigned char XG21_CR47 = 0x00 ;
+
+unsigned char XG27_CR97 = 0xC1 ;
+unsigned char XG27_SR36 = 0x30 ;
+unsigned char XG27_CR8F = 0x0C ;
+unsigned char XG27_CRD0[] = {0, 0, 0, 0, 0, 0, 0, 0x82, 0x00, 0x66, 0x01, 0x00};
+unsigned char XG27_CRDE[] = {0, 0};
+unsigned char XG27_SR40 = 0x04 ;
+unsigned char XG27_SR41 = 0x00 ;
+
+unsigned char XGI330_CHTVVCLKUNTSC[] = {0x00};
+
+unsigned char XGI330_CHTVVCLKONTSC[] = {0x00};
+
+unsigned char XGI330_CHTVVCLKUPAL[] = {0x00};
+
+unsigned char XGI330_CHTVVCLKOPAL[] = {0x00};
+
+unsigned char XGI7007_CHTVVCLKUNTSC[] = {CH7007TVVCLK30_2,
                                CH7007TVVCLK30_2,
                                CH7007TVVCLK30_2,
                                CH7007TVVCLK30_2,
@@ -3546,7 +3519,7 @@ UCHAR XGI7007_CHTVVCLKUNTSC[]={CH7007TVVCLK30_2,
                                CH7007TVVCLK47_8
                               };
 
-UCHAR XGI7007_CHTVVCLKONTSC[]={CH7007TVVCLK26_4,
+unsigned char XGI7007_CHTVVCLKONTSC[] = {CH7007TVVCLK26_4,
                                CH7007TVVCLK26_4,
                                CH7007TVVCLK26_4,
                                CH7007TVVCLK26_4,
@@ -3554,7 +3527,7 @@ UCHAR XGI7007_CHTVVCLKONTSC[]={CH7007TVVCLK26_4,
                                CH7007TVVCLK43_6
                               };
 
-UCHAR XGI7007_CHTVVCLKUPAL[]={CH7007TVVCLK31_5,
+unsigned char XGI7007_CHTVVCLKUPAL[] = {CH7007TVVCLK31_5,
                               CH7007TVVCLK31_5,
                               CH7007TVVCLK31_5,
                               CH7007TVVCLK31_5,
@@ -3562,7 +3535,7 @@ UCHAR XGI7007_CHTVVCLKUPAL[]={CH7007TVVCLK31_5,
                               CH7007TVVCLK39
                              };
 
-UCHAR XGI7007_CHTVVCLKOPAL[]={CH7007TVVCLK31_5,
+unsigned char XGI7007_CHTVVCLKOPAL[] = {CH7007TVVCLK31_5,
                               CH7007TVVCLK31_5,
                               CH7007TVVCLK31_5,
                               CH7007TVVCLK31_5,
@@ -3570,7 +3543,7 @@ UCHAR XGI7007_CHTVVCLKOPAL[]={CH7007TVVCLK31_5,
                               CH7007TVVCLK36
                              };
 
-XGI330_VCLKDataStruct XGI_CH7007VCLKData[]=
+struct XGI330_VCLKDataStruct XGI_CH7007VCLKData[] =
 {
  { 0x60,0x36,30},  /* 0 30.2 MHZ */
  { 0x40,0x4A,28},  /* 1 28.19 MHZ */
@@ -3585,7 +3558,7 @@ XGI330_VCLKDataStruct XGI_CH7007VCLKData[]=
  { 0xFF,0x00,0 }   /* End mark      */
 };
 
-XGI330_VCLKDataStruct XGI_VCLKData[]=
+struct XGI330_VCLKDataStruct XGI_VCLKData[] =
 {
                        /* SR2B,SR2C,SR2D */
                {      0x1B,0xE1,25               },/* 00 (25.175MHz) */
@@ -3786,7 +3759,7 @@ XGI330_VCLKDataStruct XGI_VCLKData[]=
                 {      0xFF,0x00,0                }/* End mark */
  }  ;
 
-XGI330_VCLKDataStruct XGI_VBVCLKData[]=
+struct XGI330_VCLKDataStruct XGI_VBVCLKData[] =
 {
                 {      0x1B,0xE1,25               },/* 00 (25.175MHz) */
 
@@ -3987,7 +3960,7 @@ XGI330_VCLKDataStruct XGI_VBVCLKData[]=
                 {      0xFF,0x00,0                }      /* End mark */
 };
 
-UCHAR XGI660_TVDelayList[]=
+unsigned char XGI660_TVDelayList[] =
 {
           0x44,            /* ; 0 ExtNTSCDelay */
           0x44,            /* ; 1 StNTSCDelay */
@@ -4003,7 +3976,7 @@ UCHAR XGI660_TVDelayList[]=
           0x44             /* ; B StYPbPrDealy(750p) */
 };
 
-UCHAR XGI660_TVDelayList2[]=
+unsigned char XGI660_TVDelayList2[] =
 {
           0x44,           /* ; 0 ExtNTSCDelay */
           0x44,           /* ; 1 StNTSCDelay */
@@ -4019,7 +3992,7 @@ UCHAR XGI660_TVDelayList2[]=
           0x44            /* ; B StYPbPrDealy(750p) */
 };
 
-UCHAR XGI301TVDelayList[]=
+unsigned char XGI301TVDelayList[] =
 {
        0x22,            /* ; 0 ExtNTSCDelay */
        0x22,            /* ; 1 StNTSCDelay */
@@ -4035,7 +4008,7 @@ UCHAR XGI301TVDelayList[]=
        0x22            /* B StYPbPrDealy(750p) */
 };
 
-UCHAR XGI301TVDelayList2[]=
+unsigned char XGI301TVDelayList2[] =
 {
        0x22,           /* ; 0 ExtNTSCDelay */
        0x22,           /* ; 1 StNTSCDelay */
@@ -4052,7 +4025,7 @@ UCHAR XGI301TVDelayList2[]=
 };
 
 
-UCHAR TVAntiFlickList[]=
+unsigned char TVAntiFlickList[] =
 {/* NTSCAntiFlicker */
                       0x04,           /* ; 0 Adaptive */
                       0x00,           /* ; 1 new anti-flicker ? */
@@ -4065,7 +4038,7 @@ UCHAR TVAntiFlickList[]=
 };
 
 
-UCHAR TVEdgeList[]=
+unsigned char TVEdgeList[] =
 {
       0x00,            /* ; 0 NTSC No Edge enhance */
       0x04,            /* ; 1 NTSC Adaptive Edge enhance */
@@ -4075,7 +4048,7 @@ UCHAR TVEdgeList[]=
       0x00             /* ; 1 HiTV */
 };
 
-ULONG TVPhaseList[]=
+unsigned long TVPhaseList[] =
 {      0x08BAED21, /* ; 0 NTSC phase */
        0x00E3052A, /* ; 1 PAL phase */
        0x9B2EE421, /* ; 2 PAL-M phase */
@@ -4092,7 +4065,7 @@ ULONG TVPhaseList[]=
        0xE00A831E  /* ; D PAL-M 1024x768 */
 };
 
-UCHAR NTSCYFilter1[]=
+unsigned char NTSCYFilter1[] =
 {
                      0x00,0xF4,0x10,0x38     ,/* 0 : 320x text mode */
                       0x00,0xF4,0x10,0x38     ,/* 1 : 360x text mode */
@@ -4103,7 +4076,7 @@ UCHAR NTSCYFilter1[]=
                       0xEB,0x15,0x25,0xF6     /* 6 : 800x gra. mode */
 };
 
-UCHAR PALYFilter1[]=
+unsigned char PALYFilter1[] =
 {
                      0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
                       0x00,0xF4,0x10,0x38     ,/* 1 : 360x text mode */
@@ -4114,7 +4087,7 @@ UCHAR PALYFilter1[]=
                       0xFC,0xFB,0x14,0x2A     /* 6 : 800x gra. mode */
 };
 
-UCHAR PALMYFilter1[]=
+unsigned char PALMYFilter1[] =
 {
                      0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
                       0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
@@ -4126,7 +4099,7 @@ UCHAR PALMYFilter1[]=
                       0xFF,0xFF,0xFF,0xFF  /* End of Table */
 };
 
-UCHAR PALNYFilter1[]=
+unsigned char PALNYFilter1[] =
 {
                      0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
                       0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
@@ -4138,7 +4111,7 @@ UCHAR PALNYFilter1[]=
                       0xFF,0xFF,0xFF,0xFF  /* End of Table */
 };
 
-UCHAR NTSCYFilter2[]=
+unsigned char NTSCYFilter2[] =
 {
                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
                       0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4150,7 +4123,7 @@ UCHAR NTSCYFilter2[]=
                       0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
 };
 
-UCHAR PALYFilter2[]=
+unsigned char PALYFilter2[] =
 {
                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
                       0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4162,7 +4135,7 @@ UCHAR PALYFilter2[]=
                       0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
 };
 
-UCHAR PALMYFilter2[]=
+unsigned char PALMYFilter2[] =
 {
                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
                       0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4174,7 +4147,7 @@ UCHAR PALMYFilter2[]=
                       0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
 };
 
-UCHAR PALNYFilter2[]=
+unsigned char PALNYFilter2[] =
 {
                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
                       0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4186,14 +4159,14 @@ UCHAR PALNYFilter2[]=
                       0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
 };
 
-UCHAR XGI_NTSC1024AdjTime[]=
+unsigned char XGI_NTSC1024AdjTime[] =
 {
       0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
       0x13,0x40,0x34,0xF4,0x63,0xBB,0xCC,0x7A,
       0x58,0xe4,0x73,0xd0,0x13
 };
 
-XGI301C_Tap4TimingStruct HiTVTap4Timing[]=
+struct XGI301C_Tap4TimingStruct HiTVTap4Timing[] =
 {
        {0,{
        0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
@@ -4208,7 +4181,7 @@ XGI301C_Tap4TimingStruct HiTVTap4Timing[]=
        }
 };
 
-XGI301C_Tap4TimingStruct EnlargeTap4Timing[]=
+struct XGI301C_Tap4TimingStruct EnlargeTap4Timing[] =
 {
        {0,{
        0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
@@ -4223,7 +4196,7 @@ XGI301C_Tap4TimingStruct EnlargeTap4Timing[]=
        }
 };
 
-XGI301C_Tap4TimingStruct NoScaleTap4Timing[]=
+struct XGI301C_Tap4TimingStruct NoScaleTap4Timing[] =
 {
        {0,{
        0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
@@ -4238,7 +4211,7 @@ XGI301C_Tap4TimingStruct NoScaleTap4Timing[]=
        }
 };
 
-XGI301C_Tap4TimingStruct PALTap4Timing[]=
+struct XGI301C_Tap4TimingStruct PALTap4Timing[] =
 {
        {600,  {
                 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
@@ -4276,7 +4249,7 @@ XGI301C_Tap4TimingStruct PALTap4Timing[]=
         }
 };
 
-XGI301C_Tap4TimingStruct NTSCTap4Timing[]=
+struct XGI301C_Tap4TimingStruct NTSCTap4Timing[] =
 {
        {480,   {
                0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
@@ -4314,7 +4287,7 @@ XGI301C_Tap4TimingStruct NTSCTap4Timing[]=
         }
 };
 
-XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[]=
+struct XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[] =
 {
        {480,   {
                0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
@@ -4352,7 +4325,7 @@ XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[]=
         }
 };
 
-XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[]=
+struct XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[] =
 {
        {480,   {
                0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
@@ -4390,7 +4363,7 @@ XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[]=
         }
 };
 
-XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[]=
+struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] =
 {        {0xFFFF,
                {
                0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
index 87531b49b739d5ebd73339b26989f03021388fc3..2c40368ceee2c497de7bcfabd6f320f59c900a6d 100644 (file)
@@ -1,54 +1,25 @@
-#include "osdef.h"
 #include "vb_def.h"
 #include "vgatypes.h"
 #include "vb_struct.h"
 
-#ifdef LINUX_KERNEL
 #include "XGIfb.h"
 #include <asm/io.h>
 #include <linux/types.h>
-#endif
-
-#ifdef TC
-#include <stdio.h>
-#include <string.h>
-#include <conio.h>
-#include <dos.h>
-#endif
-
-#ifdef WIN2000
-#include <dderror.h>
-#include <devioctl.h>
-#include <miniport.h>
-#include <ntddvdeo.h>
-#include <video.h>
-
-#include "xgiv.h"
-#include "dd_i2c.h"
-#include "tools.h"
-#endif
-
-#ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86PciInfo.h"
-#include "xgi.h"
-#include "xgi_regs.h"
-#endif
-
-
-
-
-void XGINew_SetReg1( ULONG , USHORT , USHORT ) ;
-void XGINew_SetReg2( ULONG , USHORT , USHORT ) ;
-void XGINew_SetReg3( ULONG , USHORT ) ;
-void XGINew_SetReg4( ULONG , ULONG ) ;
-UCHAR XGINew_GetReg1( ULONG , USHORT) ;
-UCHAR XGINew_GetReg2( ULONG ) ;
-ULONG XGINew_GetReg3( ULONG ) ;
-void XGINew_ClearDAC( PUCHAR ) ;
-void     XGINew_SetRegANDOR(ULONG Port,USHORT Index,USHORT DataAND,USHORT DataOR);
-void     XGINew_SetRegOR(ULONG Port,USHORT Index,USHORT DataOR);
-void     XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND);
+
+void XGINew_SetReg1(unsigned long,unsigned short,unsigned short);
+void XGINew_SetReg2(unsigned long,unsigned short,unsigned short);
+void XGINew_SetReg3(unsigned long,unsigned short);
+void XGINew_SetReg4(unsigned long,unsigned long);
+unsigned char XGINew_GetReg1(unsigned long, unsigned short);
+unsigned char XGINew_GetReg2(unsigned long);
+unsigned long XGINew_GetReg3(unsigned long);
+void XGINew_ClearDAC(unsigned char *);
+void XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,
+                       unsigned short DataAND,unsigned short DataOR);
+void XGINew_SetRegOR(unsigned long Port,unsigned short Index,
+                    unsigned short DataOR);
+void XGINew_SetRegAND(unsigned long Port,unsigned short Index,
+                     unsigned short DataAND);
 
 
 /* --------------------------------------------------------------------- */
@@ -57,15 +28,10 @@ void     XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND);
 /* Output : */
 /* Description : SR CRTC GR */
 /* --------------------------------------------------------------------- */
-void XGINew_SetReg1( ULONG port , USHORT index , USHORT data )
+void XGINew_SetReg1( unsigned long port , unsigned short index , unsigned short data )
 {
-#ifdef LINUX_XF86
-    OutPortByte( ( PUCHAR )(ULONG)port , index ) ;
-    OutPortByte( ( PUCHAR )(ULONG)port + 1 , data ) ;
-#else
-    OutPortByte( port , index ) ;
-    OutPortByte( port + 1 , data ) ;
-#endif
+       outb(index, port);
+       outb(data, port + 1);
 }
 
 
@@ -75,9 +41,9 @@ void XGINew_SetReg1( ULONG port , USHORT index , USHORT data )
 /* Output : */
 /* Description : AR( 3C0 ) */
 /* --------------------------------------------------------------------- */
-/*void XGINew_SetReg2( ULONG port , USHORT index , USHORT data )
+/*void XGINew_SetReg2( unsigned long port , unsigned short index , unsigned short data )
 {
-    InPortByte( ( PUCHAR )port + 0x3da - 0x3c0 ) ;
+    InPortByte((P unsigned char )port + 0x3da - 0x3c0) ;
     OutPortByte( XGINew_P3c0 , index ) ;
     OutPortByte( XGINew_P3c0 , data ) ;
     OutPortByte( XGINew_P3c0 , 0x20 ) ;
@@ -90,9 +56,9 @@ void XGINew_SetReg1( ULONG port , USHORT index , USHORT data )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetReg3( ULONG port , USHORT data )
+void XGINew_SetReg3( unsigned long port , unsigned short data )
 {
-    OutPortByte( port , data ) ;
+       outb(data, port);
 }
 
 
@@ -102,9 +68,9 @@ void XGINew_SetReg3( ULONG port , USHORT data )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetReg4( ULONG port , ULONG data )
+void XGINew_SetReg4( unsigned long port , unsigned long data )
 {
-    OutPortLong( port , data ) ;
+       outl(data, port);
 }
 
 
@@ -114,18 +80,12 @@ void XGINew_SetReg4( ULONG port , ULONG data )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGINew_GetReg1( ULONG port , USHORT index )
+unsigned char XGINew_GetReg1(unsigned long port, unsigned short index)
 {
-    UCHAR data ;
-
-#ifdef LINUX_XF86
-    OutPortByte( ( PUCHAR )(ULONG)port , index ) ;
-    data = InPortByte( ( PUCHAR )(ULONG)port + 1 ) ;
-#else
-    OutPortByte( port , index ) ;
-    data = InPortByte( port + 1 ) ;
-#endif
+    unsigned char data ;
 
+    outb(index, port);
+    data = inb(port + 1) ;
     return( data ) ;
 }
 
@@ -136,11 +96,11 @@ UCHAR XGINew_GetReg1( ULONG port , USHORT index )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-UCHAR XGINew_GetReg2( ULONG port )
+unsigned char XGINew_GetReg2(unsigned long port)
 {
-    UCHAR data ;
+    unsigned char data ;
 
-    data = InPortByte( port ) ;
+    data = inb(port) ;
 
     return( data ) ;
 }
@@ -152,11 +112,11 @@ UCHAR XGINew_GetReg2( ULONG port )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-ULONG XGINew_GetReg3( ULONG port )
+unsigned long XGINew_GetReg3( unsigned long port )
 {
-    ULONG data ;
+    unsigned long data ;
 
-    data = InPortLong( port ) ;
+    data = inl(port) ;
 
     return( data ) ;
 }
@@ -169,9 +129,9 @@ ULONG XGINew_GetReg3( ULONG port )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetRegANDOR( ULONG Port , USHORT Index , USHORT DataAND , USHORT DataOR )
+void XGINew_SetRegANDOR( unsigned long Port , unsigned short Index , unsigned short DataAND , unsigned short DataOR )
 {
-    USHORT temp ;
+    unsigned short temp ;
 
     temp = XGINew_GetReg1( Port , Index ) ;            /* XGINew_Part1Port index 02 */
     temp = ( temp & ( DataAND ) ) | DataOR ;
@@ -185,9 +145,9 @@ void XGINew_SetRegANDOR( ULONG Port , USHORT Index , USHORT DataAND , USHORT Dat
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND)
+void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND)
 {
-    USHORT temp ;
+    unsigned short temp ;
 
     temp = XGINew_GetReg1( Port , Index ) ;    /* XGINew_Part1Port index 02 */
     temp &= DataAND ;
@@ -201,9 +161,9 @@ void XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND)
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void XGINew_SetRegOR( ULONG Port , USHORT Index , USHORT DataOR )
+void XGINew_SetRegOR( unsigned long Port , unsigned short Index , unsigned short DataOR )
 {
-    USHORT temp ;
+    unsigned short temp ;
 
     temp = XGINew_GetReg1( Port , Index ) ;    /* XGINew_Part1Port index 02 */
     temp |= DataOR ;
@@ -219,29 +179,14 @@ void XGINew_SetRegOR( ULONG Port , USHORT Index , USHORT DataOR )
 /* --------------------------------------------------------------------- */
 void NewDelaySeconds( int seconds )
 {
-#ifdef WIN2000
-    int j ;
-#endif
     int i ;
 
 
     for( i = 0 ; i < seconds ; i++ )
     {
-#ifdef TC
-        delay( 1000 ) ;
-#endif
-
-#ifdef WIN2000
 
-        for ( j = 0 ; j < 20000 ; j++ )
-            VideoPortStallExecution( 50 ) ;
-#endif
 
-#ifdef WINCE_HEADER
-#endif
 
-#ifdef LINUX_KERNEL
-#endif
     }
 }
 
@@ -252,7 +197,7 @@ void NewDelaySeconds( int seconds )
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-void Newdebugcode( UCHAR code )
+void Newdebugcode(unsigned char code)
 {
 //    OutPortByte ( 0x80 , code ) ;
     /* OutPortByte ( 0x300 , code ) ; */
index 91779d8cfdc6aa6826e573fe7cbb5ced8b5c6239..156f6445c88d5af3476fbf94d5b11aad3df3fb67 100644 (file)
@@ -1,15 +1,15 @@
 #ifndef _VBUTIL_
 #define _VBUTIL_
 extern   void     NewDelaySeconds( int );
-extern   void     Newdebugcode( UCHAR );
-extern   void     XGINew_SetReg1(ULONG, USHORT, USHORT);
-extern   void     XGINew_SetReg3(ULONG, USHORT);
-extern   UCHAR    XGINew_GetReg1(ULONG, USHORT);
-extern   UCHAR    XGINew_GetReg2(ULONG);
-extern   void     XGINew_SetReg4(ULONG, ULONG);
-extern   ULONG    XGINew_GetReg3(ULONG);
-extern   void     XGINew_SetRegOR(ULONG Port,USHORT Index,USHORT DataOR);
-extern   void     XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND);
-extern   void     XGINew_SetRegANDOR(ULONG Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+extern   void     Newdebugcode(unsigned char);
+extern   void     XGINew_SetReg1(unsigned long, unsigned short, unsigned short);
+extern   void     XGINew_SetReg3(unsigned long, unsigned short);
+extern    unsigned char     XGINew_GetReg1(unsigned long, unsigned short);
+extern    unsigned char     XGINew_GetReg2(unsigned long);
+extern   void     XGINew_SetReg4(unsigned long, unsigned long);
+extern   unsigned long    XGINew_GetReg3(unsigned long);
+extern   void     XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR);
+extern   void     XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND);
+extern   void     XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,unsigned short DataAND,unsigned short DataOR);
 #endif
 
index 295ea860ae470af4c110cbbf7bd878c2f0048b88..df839eeb5efd0077536024f900010f3366915613 100644 (file)
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
-#include "osdef.h"
-
-#ifdef LINUX_XF86
-#include "xf86Version.h"
-#include "xf86Pci.h"
-#endif
-
-#ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
 #include <linux/ioctl.h>
-#endif
-
-#ifndef FALSE
-#define FALSE   0
-#endif
-
-#ifndef TRUE
-#define TRUE    1
-#endif
-
-#ifndef NULL
-#define NULL    0
-#endif
-
-#ifndef CHAR
-typedef char CHAR;
-#endif
-
-#ifndef SHORT
-typedef short SHORT;
-#endif
-
-#ifndef LONG
-typedef long  LONG;
-#endif
-
-#ifndef UCHAR
-typedef unsigned char UCHAR;
-#endif
-
-#ifndef USHORT
-typedef unsigned short USHORT;
-#endif
-
-#ifndef ULONG
-typedef unsigned long ULONG;
-#endif
-
-#ifndef PUCHAR
-typedef UCHAR *PUCHAR;
-#endif
-
-#ifndef PUSHORT
-typedef USHORT *PUSHORT;
-#endif
-
-#ifndef PLONGU
-typedef ULONG *PULONG;
-#endif
-
-#ifndef VOID
-typedef void VOID;
-#endif
-
-#ifndef PVOID
-typedef void *PVOID;
-#endif
-
-#ifndef BOOLEAN
-typedef UCHAR BOOLEAN;
-#endif
-/*
-#ifndef bool
-typedef UCHAR bool;
-#endif
-*/
-#ifdef LINUX_KERNEL
-typedef unsigned long XGIIOADDRESS;
-#endif
-
-#ifdef LINUX_XF86
-#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
-typedef unsigned char IOADDRESS;
-typedef unsigned char XGIIOADDRESS;
-#else
-typedef IOADDRESS XGIIOADDRESS;
-#endif
-#endif
 
 #ifndef VBIOS_VER_MAX_LENGTH
-#define VBIOS_VER_MAX_LENGTH    4
-#endif
-
-#ifndef WIN2000
-
-#ifndef LINUX_KERNEL   /* For the linux kernel, this is defined in xgifb.h */
-#ifndef XGI_CHIP_TYPE
-typedef enum _XGI_CHIP_TYPE {
-    XGI_VGALegacy = 0,
-#ifdef LINUX_XF86
-    XGI_530,
-    XGI_OLD,
-#endif
-    XGI_300,
-    XGI_630,
-    XGI_640,
-    XGI_315H,
-    XGI_315,
-    XGI_315PRO,
-    XGI_550,
-    XGI_650,
-    XGI_650M,
-    XGI_740,
-    XGI_330,
-    XGI_661,
-    XGI_660,
-    XGI_760,
-    XG40 = 32,
-    XG41,
-    XG42,
-    XG45,
-    XG20 = 48,
-    XG21,
-    XG27,
-    MAX_XGI_CHIP
-} XGI_CHIP_TYPE;
-#endif
+#define VBIOS_VER_MAX_LENGTH    5
 #endif
 
 #ifndef XGI_VB_CHIP_TYPE
-typedef enum _XGI_VB_CHIP_TYPE {
+enum XGI_VB_CHIP_TYPE {
     VB_CHIP_Legacy = 0,
     VB_CHIP_301,
     VB_CHIP_301B,
@@ -143,11 +21,11 @@ typedef enum _XGI_VB_CHIP_TYPE {
     VB_CHIP_302ELV,
     VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
     MAX_VB_CHIP
-} XGI_VB_CHIP_TYPE;
+};
 #endif
 
 #ifndef XGI_LCD_TYPE
-typedef enum _XGI_LCD_TYPE {
+enum XGI_LCD_TYPE {
     LCD_INVALID = 0,
     LCD_320x480,       /* FSTN, DSTN */
     LCD_640x480,
@@ -171,155 +49,90 @@ typedef enum _XGI_LCD_TYPE {
     LCD_2048x1536,
     LCD_CUSTOM,
     LCD_UNKNOWN
-} XGI_LCD_TYPE;
+};
 #endif
 
-#endif   /* not WIN2000 */
-
-#ifndef PXGI_DSReg
-typedef struct _XGI_DSReg
+struct XGI_DSReg
 {
-  UCHAR  jIdx;
-  UCHAR  jVal;
-} XGI_DSReg, *PXGI_DSReg;
-#endif
-
-#ifndef XGI_HW_DEVICE_INFO
-
-typedef struct _XGI_HW_DEVICE_INFO  XGI_HW_DEVICE_INFO, *PXGI_HW_DEVICE_INFO;
-
-typedef BOOLEAN (*PXGI_QUERYSPACE)   (PXGI_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+  unsigned char  jIdx;
+  unsigned char  jVal;
+};
 
-struct _XGI_HW_DEVICE_INFO
+struct xgi_hw_device_info
 {
-    ULONG  ulExternalChip;       /* NO VB or other video bridge*/
+    unsigned long  ulExternalChip;       /* NO VB or other video bridge*/
                                  /* if ujVBChipID = VB_CHIP_UNKNOWN, */
-#ifdef LINUX_XF86
-    PCITAG PciTag;              /* PCI Tag */
-#endif
 
-    PUCHAR  pjVirtualRomBase;    /* ROM image */
+    unsigned char *pjVirtualRomBase;    /* ROM image */
 
-    BOOLEAN UseROM;             /* Use the ROM image if provided */
+    unsigned char UseROM;               /* Use the ROM image if provided */
 
-    PVOID   pDevice;
+    void *pDevice;
 
-    PUCHAR  pjVideoMemoryAddress;/* base virtual memory address */
+    unsigned char *pjVideoMemoryAddress;/* base virtual memory address */
                                  /* of Linear VGA memory */
 
-    ULONG  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
+    unsigned long  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
 
-    PUCHAR pjIOAddress;          /* base I/O address of VGA ports (0x3B0) */
+    unsigned char *pjIOAddress;          /* base I/O address of VGA ports (0x3B0) */
 
-    PUCHAR pjCustomizedROMImage;
+    unsigned char *pjCustomizedROMImage;
 
-    PUCHAR pj2ndVideoMemoryAddress;
-    ULONG  ul2ndVideoMemorySize;
+    unsigned char *pj2ndVideoMemoryAddress;
+    unsigned long  ul2ndVideoMemorySize;
 
-    PUCHAR pj2ndIOAddress;
-/*#ifndef WIN2000
-    XGIIOADDRESS pjIOAddress;   //  base I/O address of VGA ports (0x3B0)
-#endif */
-    UCHAR  jChipType;            /* Used to Identify Graphics Chip */
+    unsigned char *pj2ndIOAddress;
+    unsigned char  jChipType;            /* Used to Identify Graphics Chip */
                                  /* defined in the data structure type  */
                                  /* "XGI_CHIP_TYPE" */
 
-    UCHAR  jChipRevision;        /* Used to Identify Graphics Chip Revision */
+    unsigned char  jChipRevision;        /* Used to Identify Graphics Chip Revision */
 
-    UCHAR  ujVBChipID;           /* the ID of video bridge */
+    unsigned char  ujVBChipID;           /* the ID of video bridge */
                                  /* defined in the data structure type */
                                  /* "XGI_VB_CHIP_TYPE" */
 
-    BOOLEAN    bNewScratch;
+    unsigned char    bNewScratch;
 
-    ULONG  ulCRT2LCDType;        /* defined in the data structure type */
+    unsigned long  ulCRT2LCDType;        /* defined in the data structure type */
 
-    ULONG usExternalChip;       /* NO VB or other video bridge (other than  */
+    unsigned long usExternalChip;       /* NO VB or other video bridge (other than  */
                                  /*  video bridge) */
 
-    BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
+    unsigned char bIntegratedMMEnabled;/* supporting integration MM enable */
 
-    BOOLEAN bSkipDramSizing;     /* True: Skip video memory sizing. */
+    unsigned char bSkipDramSizing;     /* True: Skip video memory sizing. */
 
-    BOOLEAN bSkipSense;
+    unsigned char bSkipSense;
 
-    BOOLEAN bIsPowerSaving;     /* True: XGIInit() is invoked by power management,
+    unsigned char bIsPowerSaving;     /* True: XGIInit() is invoked by power management,
                                    otherwise by 2nd adapter's initialzation */
 
-    PXGI_DSReg  pSR;             /* restore SR registers in initial function. */
+    struct XGI_DSReg  *pSR;             /* restore SR registers in initial function. */
                                  /* end data :(idx, val) =  (FF, FF). */
                                  /* Note : restore SR registers if  */
-                                 /* bSkipDramSizing = TRUE */
+                                 /* bSkipDramSizing = 1 */
 
-    PXGI_DSReg  pCR;             /* restore CR registers in initial function. */
+    struct XGI_DSReg  *pCR;             /* restore CR registers in initial function. */
                                  /* end data :(idx, val) =  (FF, FF) */
                                  /* Note : restore cR registers if  */
-                                 /* bSkipDramSizing = TRUE */
-/*
-#endif
-*/
+                                 /* bSkipDramSizing = 1 */
 
-    PXGI_QUERYSPACE  pQueryVGAConfigSpace;
+       unsigned char(*pQueryVGAConfigSpace)(struct xgi_hw_device_info *,
+                                           unsigned long, unsigned long,
+                                           unsigned long *);
 
-    PXGI_QUERYSPACE  pQueryNorthBridgeSpace;
+       unsigned char(*pQueryNorthBridgeSpace)(struct xgi_hw_device_info *,
+                                             unsigned long, unsigned long,
+                                             unsigned long *);
 
-    UCHAR  szVBIOSVer[VBIOS_VER_MAX_LENGTH];
+    unsigned char szVBIOSVer[VBIOS_VER_MAX_LENGTH];
 
 };
-#endif
 
 /* Addtional IOCTL for communication xgifb <> X driver        */
 /* If changing this, xgifb.h must also be changed (for xgifb) */
 
-#ifdef LINUX_XF86  /* We don't want the X driver to depend on the kernel source */
-
-/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define XGIFB_GET_INFO    0x80046ef8  /* Wow, what a terrible hack... */
-
-/* Structure argument for XGIFB_GET_INFO ioctl  */
-typedef struct _XGIFB_INFO xgifb_info, *pxgifb_info;
-
-struct _XGIFB_INFO {
-       CARD32  xgifb_id;               /* for identifying xgifb */
-#ifndef XGIFB_ID
-#define XGIFB_ID         0x53495346    /* Identify myself with 'XGIF' */
-#endif
-       CARD32  chip_id;                /* PCI ID of detected chip */
-       CARD32  memory;                 /* video memory in KB which xgifb manages */
-       CARD32  heapstart;              /* heap start (= xgifb "mem" argument) in KB */
-       CARD8   fbvidmode;              /* current xgifb mode */
-
-       CARD8   xgifb_version;
-       CARD8   xgifb_revision;
-       CARD8   xgifb_patchlevel;
-
-       CARD8   xgifb_caps;             /* xgifb's capabilities */
-
-       CARD32  xgifb_tqlen;            /* turbo queue length (in KB) */
-
-       CARD32  xgifb_pcibus;           /* The card's PCI ID */
-       CARD32  xgifb_pcislot;
-       CARD32  xgifb_pcifunc;
-
-       CARD8   xgifb_lcdpdc;
-
-       CARD8   xgifb_lcda;
-
-       CARD32  xgifb_vbflags;
-       CARD32  xgifb_currentvbflags;
-
-       CARD32  xgifb_scalelcd;
-       CARD32  xgifb_specialtiming;
-
-       CARD8   xgifb_haveemi;
-       CARD8   xgifb_emi30,xgifb_emi31,xgifb_emi32,xgifb_emi33;
-       CARD8   xgifb_haveemilcd;
-
-       CARD8   xgifb_lcdpdca;
-
-       CARD8 reserved[212];            /* for future use */
-};
-#endif
 
 #endif
 
diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig
new file mode 100644 (file)
index 0000000..4654ae2
--- /dev/null
@@ -0,0 +1,29 @@
+config ZRAM
+       tristate "Compressed RAM block device support"
+       depends on BLOCK
+       select LZO_COMPRESS
+       select LZO_DECOMPRESS
+       default n
+       help
+         Creates virtual block devices called /dev/zramX (X = 0, 1, ...).
+         Pages written to these disks are compressed and stored in memory
+         itself. These disks allow very fast I/O and compression provides
+         good amounts of memory savings.
+
+         It has several use cases, for example: /tmp storage, use as swap
+         disks and maybe many more.
+
+         See zram.txt for more information.
+         Project home: http://compcache.googlecode.com/
+
+config ZRAM_STATS
+       bool "Enable statistics for compressed RAM disks"
+       depends on ZRAM
+       default y
+       help
+         Enable statistics collection for compressed RAM devices. Statistics
+         are exported through ioctl interface, so you have to use zramconfig
+         program to get them. This adds only a minimal overhead.
+
+         If unsure, say Y.
+
diff --git a/drivers/staging/zram/Makefile b/drivers/staging/zram/Makefile
new file mode 100644 (file)
index 0000000..b2c087a
--- /dev/null
@@ -0,0 +1,3 @@
+zram-objs      :=      zram_drv.o xvmalloc.o
+
+obj-$(CONFIG_ZRAM)     +=      zram.o
diff --git a/drivers/staging/zram/zram.txt b/drivers/staging/zram/zram.txt
new file mode 100644 (file)
index 0000000..520edc1
--- /dev/null
@@ -0,0 +1,62 @@
+zram: Compressed RAM based block devices
+----------------------------------------
+
+Project home: http://compcache.googlecode.com/
+
+* Introduction
+
+The zram module creates RAM based block devices: /dev/ramX (X = 0, 1, ...).
+Pages written to these disks are compressed and stored in memory itself.
+These disks allow very fast I/O and compression provides good amounts of
+memory savings.
+
+See project home for use cases, performance numbers and a lot more.
+
+Individual zram devices are configured and initialized using zramconfig
+userspace utility as shown in examples below. See zramconfig man page for
+more details.
+
+* Usage
+
+Following shows a typical sequence of steps for using zram.
+
+1) Load Modules:
+       modprobe zram num_devices=4
+       This creates 4 (uninitialized) devices: /dev/zram{0,1,2,3}
+       (num_devices parameter is optional. Default: 1)
+
+2) Initialize:
+       Use zramconfig utility to configure and initialize individual
+       zram devices. For example:
+       zramconfig /dev/zram0 --init # uses default value of disksize_kb
+       zramconfig /dev/zram1 --disksize_kb=102400 # 100MB /dev/zram1
+
+       *See zramconfig man page for more details and examples*
+
+3) Activate:
+       mkswap /dev/zram0
+       swapon /dev/zram0
+
+       mkfs.ext4 /dev/zram1
+       mount /dev/zram1 /tmp
+
+4) Stats:
+       zramconfig /dev/zram0 --stats
+       zramconfig /dev/zram1 --stats
+
+5) Deactivate:
+       swapoff /dev/zram0
+       umount /dev/zram1
+
+6) Reset:
+       zramconfig /dev/zram0 --reset
+       zramconfig /dev/zram1 --reset
+       (This frees memory allocated for the given device).
+
+
+Please report any problems at:
+ - Mailing list: linux-mm-cc at laptop dot org
+ - Issue tracker: http://code.google.com/p/compcache/issues/list
+
+Nitin Gupta
+ngupta@vflare.org
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
new file mode 100644 (file)
index 0000000..77d4d71
--- /dev/null
@@ -0,0 +1,805 @@
+/*
+ * Compressed RAM block device
+ *
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ * Project home: http://compcache.googlecode.com
+ */
+
+#define KMSG_COMPONENT "zram"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bio.h>
+#include <linux/bitops.h>
+#include <linux/blkdev.h>
+#include <linux/buffer_head.h>
+#include <linux/device.h>
+#include <linux/genhd.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/lzo.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+
+#include "zram_drv.h"
+
+/* Globals */
+static int zram_major;
+static struct zram *devices;
+
+/* Module params (documentation at end) */
+static unsigned int num_devices;
+
+static int zram_test_flag(struct zram *zram, u32 index,
+                       enum zram_pageflags flag)
+{
+       return zram->table[index].flags & BIT(flag);
+}
+
+static void zram_set_flag(struct zram *zram, u32 index,
+                       enum zram_pageflags flag)
+{
+       zram->table[index].flags |= BIT(flag);
+}
+
+static void zram_clear_flag(struct zram *zram, u32 index,
+                       enum zram_pageflags flag)
+{
+       zram->table[index].flags &= ~BIT(flag);
+}
+
+static int page_zero_filled(void *ptr)
+{
+       unsigned int pos;
+       unsigned long *page;
+
+       page = (unsigned long *)ptr;
+
+       for (pos = 0; pos != PAGE_SIZE / sizeof(*page); pos++) {
+               if (page[pos])
+                       return 0;
+       }
+
+       return 1;
+}
+
+static void zram_set_disksize(struct zram *zram, size_t totalram_bytes)
+{
+       if (!zram->disksize) {
+               pr_info(
+               "disk size not provided. You can use disksize_kb module "
+               "param to specify size.\nUsing default: (%u%% of RAM).\n",
+               default_disksize_perc_ram
+               );
+               zram->disksize = default_disksize_perc_ram *
+                                       (totalram_bytes / 100);
+       }
+
+       if (zram->disksize > 2 * (totalram_bytes)) {
+               pr_info(
+               "There is little point creating a zram of greater than "
+               "twice the size of memory since we expect a 2:1 compression "
+               "ratio. Note that zram uses about 0.1%% of the size of "
+               "the disk when not in use so a huge zram is "
+               "wasteful.\n"
+               "\tMemory Size: %zu kB\n"
+               "\tSize you selected: %zu kB\n"
+               "Continuing anyway ...\n",
+               totalram_bytes >> 10, zram->disksize
+               );
+       }
+
+       zram->disksize &= PAGE_MASK;
+}
+
+static void zram_ioctl_get_stats(struct zram *zram,
+                       struct zram_ioctl_stats *s)
+{
+       s->disksize = zram->disksize;
+
+#if defined(CONFIG_ZRAM_STATS)
+       {
+       struct zram_stats *rs = &zram->stats;
+       size_t succ_writes, mem_used;
+       unsigned int good_compress_perc = 0, no_compress_perc = 0;
+
+       mem_used = xv_get_total_size_bytes(zram->mem_pool)
+                       + (rs->pages_expand << PAGE_SHIFT);
+       succ_writes = zram_stat64_read(zram, &rs->num_writes) -
+                       zram_stat64_read(zram, &rs->failed_writes);
+
+       if (succ_writes && rs->pages_stored) {
+               good_compress_perc = rs->good_compress * 100
+                                       / rs->pages_stored;
+               no_compress_perc = rs->pages_expand * 100
+                                       / rs->pages_stored;
+       }
+
+       s->num_reads = zram_stat64_read(zram, &rs->num_reads);
+       s->num_writes = zram_stat64_read(zram, &rs->num_writes);
+       s->failed_reads = zram_stat64_read(zram, &rs->failed_reads);
+       s->failed_writes = zram_stat64_read(zram, &rs->failed_writes);
+       s->invalid_io = zram_stat64_read(zram, &rs->invalid_io);
+       s->notify_free = zram_stat64_read(zram, &rs->notify_free);
+       s->pages_zero = rs->pages_zero;
+
+       s->good_compress_pct = good_compress_perc;
+       s->pages_expand_pct = no_compress_perc;
+
+       s->pages_stored = rs->pages_stored;
+       s->pages_used = mem_used >> PAGE_SHIFT;
+       s->orig_data_size = rs->pages_stored << PAGE_SHIFT;
+       s->compr_data_size = rs->compr_size;
+       s->mem_used_total = mem_used;
+       }
+#endif /* CONFIG_ZRAM_STATS */
+}
+
+static void zram_free_page(struct zram *zram, size_t index)
+{
+       u32 clen;
+       void *obj;
+
+       struct page *page = zram->table[index].page;
+       u32 offset = zram->table[index].offset;
+
+       if (unlikely(!page)) {
+               /*
+                * No memory is allocated for zero filled pages.
+                * Simply clear zero page flag.
+                */
+               if (zram_test_flag(zram, index, ZRAM_ZERO)) {
+                       zram_clear_flag(zram, index, ZRAM_ZERO);
+                       zram_stat_dec(&zram->stats.pages_zero);
+               }
+               return;
+       }
+
+       if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) {
+               clen = PAGE_SIZE;
+               __free_page(page);
+               zram_clear_flag(zram, index, ZRAM_UNCOMPRESSED);
+               zram_stat_dec(&zram->stats.pages_expand);
+               goto out;
+       }
+
+       obj = kmap_atomic(page, KM_USER0) + offset;
+       clen = xv_get_object_size(obj) - sizeof(struct zobj_header);
+       kunmap_atomic(obj, KM_USER0);
+
+       xv_free(zram->mem_pool, page, offset);
+       if (clen <= PAGE_SIZE / 2)
+               zram_stat_dec(&zram->stats.good_compress);
+
+out:
+       zram->stats.compr_size -= clen;
+       zram_stat_dec(&zram->stats.pages_stored);
+
+       zram->table[index].page = NULL;
+       zram->table[index].offset = 0;
+}
+
+static void handle_zero_page(struct page *page)
+{
+       void *user_mem;
+
+       user_mem = kmap_atomic(page, KM_USER0);
+       memset(user_mem, 0, PAGE_SIZE);
+       kunmap_atomic(user_mem, KM_USER0);
+
+       flush_dcache_page(page);
+}
+
+static void handle_uncompressed_page(struct zram *zram,
+                               struct page *page, u32 index)
+{
+       unsigned char *user_mem, *cmem;
+
+       user_mem = kmap_atomic(page, KM_USER0);
+       cmem = kmap_atomic(zram->table[index].page, KM_USER1) +
+                       zram->table[index].offset;
+
+       memcpy(user_mem, cmem, PAGE_SIZE);
+       kunmap_atomic(user_mem, KM_USER0);
+       kunmap_atomic(cmem, KM_USER1);
+
+       flush_dcache_page(page);
+}
+
+static int zram_read(struct zram *zram, struct bio *bio)
+{
+
+       int i;
+       u32 index;
+       struct bio_vec *bvec;
+
+       zram_stat64_inc(zram, &zram->stats.num_reads);
+
+       index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
+       bio_for_each_segment(bvec, bio, i) {
+               int ret;
+               size_t clen;
+               struct page *page;
+               struct zobj_header *zheader;
+               unsigned char *user_mem, *cmem;
+
+               page = bvec->bv_page;
+
+               if (zram_test_flag(zram, index, ZRAM_ZERO)) {
+                       handle_zero_page(page);
+                       continue;
+               }
+
+               /* Requested page is not present in compressed area */
+               if (unlikely(!zram->table[index].page)) {
+                       pr_debug("Read before write: sector=%lu, size=%u",
+                               (ulong)(bio->bi_sector), bio->bi_size);
+                       /* Do nothing */
+                       continue;
+               }
+
+               /* Page is stored uncompressed since it's incompressible */
+               if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) {
+                       handle_uncompressed_page(zram, page, index);
+                       continue;
+               }
+
+               user_mem = kmap_atomic(page, KM_USER0);
+               clen = PAGE_SIZE;
+
+               cmem = kmap_atomic(zram->table[index].page, KM_USER1) +
+                               zram->table[index].offset;
+
+               ret = lzo1x_decompress_safe(
+                       cmem + sizeof(*zheader),
+                       xv_get_object_size(cmem) - sizeof(*zheader),
+                       user_mem, &clen);
+
+               kunmap_atomic(user_mem, KM_USER0);
+               kunmap_atomic(cmem, KM_USER1);
+
+               /* Should NEVER happen. Return bio error if it does. */
+               if (unlikely(ret != LZO_E_OK)) {
+                       pr_err("Decompression failed! err=%d, page=%u\n",
+                               ret, index);
+                       zram_stat64_inc(zram, &zram->stats.failed_reads);
+                       goto out;
+               }
+
+               flush_dcache_page(page);
+               index++;
+       }
+
+       set_bit(BIO_UPTODATE, &bio->bi_flags);
+       bio_endio(bio, 0);
+       return 0;
+
+out:
+       bio_io_error(bio);
+       return 0;
+}
+
+static int zram_write(struct zram *zram, struct bio *bio)
+{
+       int i;
+       u32 index;
+       struct bio_vec *bvec;
+
+       zram_stat64_inc(zram, &zram->stats.num_writes);
+
+       index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
+
+       bio_for_each_segment(bvec, bio, i) {
+               int ret;
+               u32 offset;
+               size_t clen;
+               struct zobj_header *zheader;
+               struct page *page, *page_store;
+               unsigned char *user_mem, *cmem, *src;
+
+               page = bvec->bv_page;
+               src = zram->compress_buffer;
+
+               /*
+                * System overwrites unused sectors. Free memory associated
+                * with this sector now.
+                */
+               if (zram->table[index].page ||
+                               zram_test_flag(zram, index, ZRAM_ZERO))
+                       zram_free_page(zram, index);
+
+               mutex_lock(&zram->lock);
+
+               user_mem = kmap_atomic(page, KM_USER0);
+               if (page_zero_filled(user_mem)) {
+                       kunmap_atomic(user_mem, KM_USER0);
+                       mutex_unlock(&zram->lock);
+                       zram_stat_inc(&zram->stats.pages_zero);
+                       zram_set_flag(zram, index, ZRAM_ZERO);
+                       continue;
+               }
+
+               ret = lzo1x_1_compress(user_mem, PAGE_SIZE, src, &clen,
+                                       zram->compress_workmem);
+
+               kunmap_atomic(user_mem, KM_USER0);
+
+               if (unlikely(ret != LZO_E_OK)) {
+                       mutex_unlock(&zram->lock);
+                       pr_err("Compression failed! err=%d\n", ret);
+                       zram_stat64_inc(zram, &zram->stats.failed_writes);
+                       goto out;
+               }
+
+               /*
+                * Page is incompressible. Store it as-is (uncompressed)
+                * since we do not want to return too many disk write
+                * errors which has side effect of hanging the system.
+                */
+               if (unlikely(clen > max_zpage_size)) {
+                       clen = PAGE_SIZE;
+                       page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
+                       if (unlikely(!page_store)) {
+                               mutex_unlock(&zram->lock);
+                               pr_info("Error allocating memory for "
+                                       "incompressible page: %u\n", index);
+                               zram_stat64_inc(zram,
+                                       &zram->stats.failed_writes);
+                               goto out;
+                       }
+
+                       offset = 0;
+                       zram_set_flag(zram, index, ZRAM_UNCOMPRESSED);
+                       zram_stat_inc(&zram->stats.pages_expand);
+                       zram->table[index].page = page_store;
+                       src = kmap_atomic(page, KM_USER0);
+                       goto memstore;
+               }
+
+               if (xv_malloc(zram->mem_pool, clen + sizeof(*zheader),
+                               &zram->table[index].page, &offset,
+                               GFP_NOIO | __GFP_HIGHMEM)) {
+                       mutex_unlock(&zram->lock);
+                       pr_info("Error allocating memory for compressed "
+                               "page: %u, size=%zu\n", index, clen);
+                       zram_stat64_inc(zram, &zram->stats.failed_writes);
+                       goto out;
+               }
+
+memstore:
+               zram->table[index].offset = offset;
+
+               cmem = kmap_atomic(zram->table[index].page, KM_USER1) +
+                               zram->table[index].offset;
+
+#if 0
+               /* Back-reference needed for memory defragmentation */
+               if (!zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)) {
+                       zheader = (struct zobj_header *)cmem;
+                       zheader->table_idx = index;
+                       cmem += sizeof(*zheader);
+               }
+#endif
+
+               memcpy(cmem, src, clen);
+
+               kunmap_atomic(cmem, KM_USER1);
+               if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)))
+                       kunmap_atomic(src, KM_USER0);
+
+               /* Update stats */
+               zram->stats.compr_size += clen;
+               zram_stat_inc(&zram->stats.pages_stored);
+               if (clen <= PAGE_SIZE / 2)
+                       zram_stat_inc(&zram->stats.good_compress);
+
+               mutex_unlock(&zram->lock);
+               index++;
+       }
+
+       set_bit(BIO_UPTODATE, &bio->bi_flags);
+       bio_endio(bio, 0);
+       return 0;
+
+out:
+       bio_io_error(bio);
+       return 0;
+}
+
+/*
+ * Check if request is within bounds and page aligned.
+ */
+static inline int valid_io_request(struct zram *zram, struct bio *bio)
+{
+       if (unlikely(
+               (bio->bi_sector >= (zram->disksize >> SECTOR_SHIFT)) ||
+               (bio->bi_sector & (SECTORS_PER_PAGE - 1)) ||
+               (bio->bi_size & (PAGE_SIZE - 1)))) {
+
+               return 0;
+       }
+
+       /* I/O request is valid */
+       return 1;
+}
+
+/*
+ * Handler function for all zram I/O requests.
+ */
+static int zram_make_request(struct request_queue *queue, struct bio *bio)
+{
+       int ret = 0;
+       struct zram *zram = queue->queuedata;
+
+       if (unlikely(!zram->init_done)) {
+               bio_io_error(bio);
+               return 0;
+       }
+
+       if (!valid_io_request(zram, bio)) {
+               zram_stat64_inc(zram, &zram->stats.invalid_io);
+               bio_io_error(bio);
+               return 0;
+       }
+
+       switch (bio_data_dir(bio)) {
+       case READ:
+               ret = zram_read(zram, bio);
+               break;
+
+       case WRITE:
+               ret = zram_write(zram, bio);
+               break;
+       }
+
+       return ret;
+}
+
+static void reset_device(struct zram *zram)
+{
+       size_t index;
+
+       /* Do not accept any new I/O request */
+       zram->init_done = 0;
+
+       /* Free various per-device buffers */
+       kfree(zram->compress_workmem);
+       free_pages((unsigned long)zram->compress_buffer, 1);
+
+       zram->compress_workmem = NULL;
+       zram->compress_buffer = NULL;
+
+       /* Free all pages that are still in this zram device */
+       for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) {
+               struct page *page;
+               u16 offset;
+
+               page = zram->table[index].page;
+               offset = zram->table[index].offset;
+
+               if (!page)
+                       continue;
+
+               if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)))
+                       __free_page(page);
+               else
+                       xv_free(zram->mem_pool, page, offset);
+       }
+
+       vfree(zram->table);
+       zram->table = NULL;
+
+       xv_destroy_pool(zram->mem_pool);
+       zram->mem_pool = NULL;
+
+       /* Reset stats */
+       memset(&zram->stats, 0, sizeof(zram->stats));
+
+       zram->disksize = 0;
+}
+
+static int zram_ioctl_init_device(struct zram *zram)
+{
+       int ret;
+       size_t num_pages;
+
+       if (zram->init_done) {
+               pr_info("Device already initialized!\n");
+               return -EBUSY;
+       }
+
+       zram_set_disksize(zram, totalram_pages << PAGE_SHIFT);
+
+       zram->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+       if (!zram->compress_workmem) {
+               pr_err("Error allocating compressor working memory!\n");
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       zram->compress_buffer = (void *)__get_free_pages(__GFP_ZERO, 1);
+       if (!zram->compress_buffer) {
+               pr_err("Error allocating compressor buffer space\n");
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       num_pages = zram->disksize >> PAGE_SHIFT;
+       zram->table = vmalloc(num_pages * sizeof(*zram->table));
+       if (!zram->table) {
+               pr_err("Error allocating zram address table\n");
+               /* To prevent accessing table entries during cleanup */
+               zram->disksize = 0;
+               ret = -ENOMEM;
+               goto fail;
+       }
+       memset(zram->table, 0, num_pages * sizeof(*zram->table));
+
+       set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
+
+       /* zram devices sort of resembles non-rotational disks */
+       queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
+
+       zram->mem_pool = xv_create_pool();
+       if (!zram->mem_pool) {
+               pr_err("Error creating memory pool\n");
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       zram->init_done = 1;
+
+       pr_debug("Initialization done!\n");
+       return 0;
+
+fail:
+       reset_device(zram);
+
+       pr_err("Initialization failed: err=%d\n", ret);
+       return ret;
+}
+
+static int zram_ioctl_reset_device(struct zram *zram)
+{
+       if (zram->init_done)
+               reset_device(zram);
+
+       return 0;
+}
+
+static int zram_ioctl(struct block_device *bdev, fmode_t mode,
+                       unsigned int cmd, unsigned long arg)
+{
+       int ret = 0;
+       size_t disksize_kb;
+
+       struct zram *zram = bdev->bd_disk->private_data;
+
+       switch (cmd) {
+       case ZRAMIO_SET_DISKSIZE_KB:
+               if (zram->init_done) {
+                       ret = -EBUSY;
+                       goto out;
+               }
+               if (copy_from_user(&disksize_kb, (void *)arg,
+                                               _IOC_SIZE(cmd))) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+               zram->disksize = disksize_kb << 10;
+               pr_info("Disk size set to %zu kB\n", disksize_kb);
+               break;
+
+       case ZRAMIO_GET_STATS:
+       {
+               struct zram_ioctl_stats *stats;
+               if (!zram->init_done) {
+                       ret = -ENOTTY;
+                       goto out;
+               }
+               stats = kzalloc(sizeof(*stats), GFP_KERNEL);
+               if (!stats) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               zram_ioctl_get_stats(zram, stats);
+               if (copy_to_user((void *)arg, stats, sizeof(*stats))) {
+                       kfree(stats);
+                       ret = -EFAULT;
+                       goto out;
+               }
+               kfree(stats);
+               break;
+       }
+       case ZRAMIO_INIT:
+               ret = zram_ioctl_init_device(zram);
+               break;
+
+       case ZRAMIO_RESET:
+               /* Do not reset an active device! */
+               if (bdev->bd_holders) {
+                       ret = -EBUSY;
+                       goto out;
+               }
+
+               /* Make sure all pending I/O is finished */
+               if (bdev)
+                       fsync_bdev(bdev);
+
+               ret = zram_ioctl_reset_device(zram);
+               break;
+
+       default:
+               pr_info("Invalid ioctl %u\n", cmd);
+               ret = -ENOTTY;
+       }
+
+out:
+       return ret;
+}
+
+void zram_slot_free_notify(struct block_device *bdev, unsigned long index)
+{
+       struct zram *zram;
+
+       zram = bdev->bd_disk->private_data;
+       zram_free_page(zram, index);
+       zram_stat64_inc(zram, &zram->stats.notify_free);
+}
+
+static const struct block_device_operations zram_devops = {
+       .ioctl = zram_ioctl,
+       .swap_slot_free_notify = zram_slot_free_notify,
+       .owner = THIS_MODULE
+};
+
+static int create_device(struct zram *zram, int device_id)
+{
+       int ret = 0;
+
+       mutex_init(&zram->lock);
+       spin_lock_init(&zram->stat64_lock);
+
+       zram->queue = blk_alloc_queue(GFP_KERNEL);
+       if (!zram->queue) {
+               pr_err("Error allocating disk queue for device %d\n",
+                       device_id);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       blk_queue_make_request(zram->queue, zram_make_request);
+       zram->queue->queuedata = zram;
+
+        /* gendisk structure */
+       zram->disk = alloc_disk(1);
+       if (!zram->disk) {
+               blk_cleanup_queue(zram->queue);
+               pr_warning("Error allocating disk structure for device %d\n",
+                       device_id);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       zram->disk->major = zram_major;
+       zram->disk->first_minor = device_id;
+       zram->disk->fops = &zram_devops;
+       zram->disk->queue = zram->queue;
+       zram->disk->private_data = zram;
+       snprintf(zram->disk->disk_name, 16, "zram%d", device_id);
+
+       /* Actual capacity set using ZRAMIO_SET_DISKSIZE_KB ioctl */
+       set_capacity(zram->disk, 0);
+
+       /*
+        * To ensure that we always get PAGE_SIZE aligned
+        * and n*PAGE_SIZED sized I/O requests.
+        */
+       blk_queue_physical_block_size(zram->disk->queue, PAGE_SIZE);
+       blk_queue_logical_block_size(zram->disk->queue, PAGE_SIZE);
+       blk_queue_io_min(zram->disk->queue, PAGE_SIZE);
+       blk_queue_io_opt(zram->disk->queue, PAGE_SIZE);
+
+       add_disk(zram->disk);
+
+       zram->init_done = 0;
+
+out:
+       return ret;
+}
+
+static void destroy_device(struct zram *zram)
+{
+       if (zram->disk) {
+               del_gendisk(zram->disk);
+               put_disk(zram->disk);
+       }
+
+       if (zram->queue)
+               blk_cleanup_queue(zram->queue);
+}
+
+static int __init zram_init(void)
+{
+       int ret, dev_id;
+
+       if (num_devices > max_num_devices) {
+               pr_warning("Invalid value for num_devices: %u\n",
+                               num_devices);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       zram_major = register_blkdev(0, "zram");
+       if (zram_major <= 0) {
+               pr_warning("Unable to get major number\n");
+               ret = -EBUSY;
+               goto out;
+       }
+
+       if (!num_devices) {
+               pr_info("num_devices not specified. Using default: 1\n");
+               num_devices = 1;
+       }
+
+       /* Allocate the device array and initialize each one */
+       pr_info("Creating %u devices ...\n", num_devices);
+       devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL);
+       if (!devices) {
+               ret = -ENOMEM;
+               goto unregister;
+       }
+
+       for (dev_id = 0; dev_id < num_devices; dev_id++) {
+               ret = create_device(&devices[dev_id], dev_id);
+               if (ret)
+                       goto free_devices;
+       }
+
+       return 0;
+
+free_devices:
+       while (dev_id)
+               destroy_device(&devices[--dev_id]);
+unregister:
+       unregister_blkdev(zram_major, "zram");
+out:
+       return ret;
+}
+
+static void __exit zram_exit(void)
+{
+       int i;
+       struct zram *zram;
+
+       for (i = 0; i < num_devices; i++) {
+               zram = &devices[i];
+
+               destroy_device(zram);
+               if (zram->init_done)
+                       reset_device(zram);
+       }
+
+       unregister_blkdev(zram_major, "zram");
+
+       kfree(devices);
+       pr_debug("Cleanup done!\n");
+}
+
+module_param(num_devices, uint, 0);
+MODULE_PARM_DESC(num_devices, "Number of zram devices");
+
+module_init(zram_init);
+module_exit(zram_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>");
+MODULE_DESCRIPTION("Compressed RAM Block Device");
similarity index 69%
rename from drivers/staging/ramzswap/ramzswap_drv.h
rename to drivers/staging/zram/zram_drv.h
index 63c30420df217ecb3944769c47a82f5fd5f1dfbf..945f9740442f016d9d575736cbf547afc8e28404 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Compressed RAM based swap device
+ * Compressed RAM block device
  *
  * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * Project home: http://compcache.googlecode.com
  */
 
-#ifndef _RAMZSWAP_DRV_H_
-#define _RAMZSWAP_DRV_H_
+#ifndef _ZRAM_DRV_H_
+#define _ZRAM_DRV_H_
 
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 
-#include "ramzswap_ioctl.h"
+#include "zram_ioctl.h"
 #include "xvmalloc.h"
 
 /*
@@ -41,7 +41,7 @@ struct zobj_header {
 
 /*-- Configurable parameters */
 
-/* Default ramzswap disk size: 25% of total RAM */
+/* Default zram disk size: 25% of total RAM */
 static const unsigned default_disksize_perc_ram = 25;
 
 /*
@@ -63,23 +63,20 @@ static const unsigned max_zpage_size = PAGE_SIZE / 4 * 3;
 #define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
 #define SECTORS_PER_PAGE       (1 << SECTORS_PER_PAGE_SHIFT)
 
-/* Flags for ramzswap pages (table[page_no].flags) */
-enum rzs_pageflags {
+/* Flags for zram pages (table[page_no].flags) */
+enum zram_pageflags {
        /* Page is stored uncompressed */
-       RZS_UNCOMPRESSED,
+       ZRAM_UNCOMPRESSED,
 
        /* Page consists entirely of zeros */
-       RZS_ZERO,
+       ZRAM_ZERO,
 
-       __NR_RZS_PAGEFLAGS,
+       __NR_ZRAM_PAGEFLAGS,
 };
 
 /*-- Data structures */
 
-/*
- * Allocated for each swap slot, indexed by page no.
- * These table entries must fit exactly in a page.
- */
+/* Allocated for each disk page */
 struct table {
        struct page *page;
        u16 offset;
@@ -87,17 +84,17 @@ struct table {
        u8 flags;
 } __attribute__((aligned(4)));
 
-struct ramzswap_stats {
+struct zram_stats {
        /* basic stats */
        size_t compr_size;      /* compressed size of pages stored -
                                 * needed to enforce memlimit */
        /* more stats */
-#if defined(CONFIG_RAMZSWAP_STATS)
+#if defined(CONFIG_ZRAM_STATS)
        u64 num_reads;          /* failed + successful */
        u64 num_writes;         /* --do-- */
        u64 failed_reads;       /* should NEVER! happen */
        u64 failed_writes;      /* can happen when memory is too low */
-       u64 invalid_io;         /* non-swap I/O requests */
+       u64 invalid_io;         /* non-page-aligned I/O requests */
        u64 notify_free;        /* no. of swap slot free notifications */
        u32 pages_zero;         /* no. of zero filled pages */
        u32 pages_stored;       /* no. of pages currently stored */
@@ -106,62 +103,62 @@ struct ramzswap_stats {
 #endif
 };
 
-struct ramzswap {
+struct zram {
        struct xv_pool *mem_pool;
        void *compress_workmem;
        void *compress_buffer;
        struct table *table;
        spinlock_t stat64_lock; /* protect 64-bit stats */
-       struct mutex lock;
+       struct mutex lock;      /* protect compression buffers against
+                                * concurrent writes */
        struct request_queue *queue;
        struct gendisk *disk;
        int init_done;
        /*
-        * This is limit on amount of *uncompressed* worth of data
-        * we can hold. When backing swap device is provided, it is
-        * set equal to device size.
+        * This is the limit on amount of *uncompressed* worth of data
+        * we can store in a disk.
         */
        size_t disksize;        /* bytes */
 
-       struct ramzswap_stats stats;
+       struct zram_stats stats;
 };
 
 /*-- */
 
 /* Debugging and Stats */
-#if defined(CONFIG_RAMZSWAP_STATS)
-static void rzs_stat_inc(u32 *v)
+#if defined(CONFIG_ZRAM_STATS)
+static void zram_stat_inc(u32 *v)
 {
        *v = *v + 1;
 }
 
-static void rzs_stat_dec(u32 *v)
+static void zram_stat_dec(u32 *v)
 {
        *v = *v - 1;
 }
 
-static void rzs_stat64_inc(struct ramzswap *rzs, u64 *v)
+static void zram_stat64_inc(struct zram *zram, u64 *v)
 {
-       spin_lock(&rzs->stat64_lock);
+       spin_lock(&zram->stat64_lock);
        *v = *v + 1;
-       spin_unlock(&rzs->stat64_lock);
+       spin_unlock(&zram->stat64_lock);
 }
 
-static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v)
+static u64 zram_stat64_read(struct zram *zram, u64 *v)
 {
        u64 val;
 
-       spin_lock(&rzs->stat64_lock);
+       spin_lock(&zram->stat64_lock);
        val = *v;
-       spin_unlock(&rzs->stat64_lock);
+       spin_unlock(&zram->stat64_lock);
 
        return val;
 }
 #else
-#define rzs_stat_inc(v)
-#define rzs_stat_dec(v)
-#define rzs_stat64_inc(r, v)
-#define rzs_stat64_read(r, v)
-#endif /* CONFIG_RAMZSWAP_STATS */
+#define zram_stat_inc(v)
+#define zram_stat_dec(v)
+#define zram_stat64_inc(r, v)
+#define zram_stat64_read(r, v)
+#endif /* CONFIG_ZRAM_STATS */
 
 #endif
similarity index 68%
rename from drivers/staging/ramzswap/ramzswap_ioctl.h
rename to drivers/staging/zram/zram_ioctl.h
index db94bcb429674846e696803bde6371981f0ad567..5c415fa4f17bb599a9e1c445dbd41787ef7e0974 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Compressed RAM based swap device
+ * Compressed RAM block device
  *
  * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * Project home: http://compcache.googlecode.com
  */
 
-#ifndef _RAMZSWAP_IOCTL_H_
-#define _RAMZSWAP_IOCTL_H_
+#ifndef _ZRAM_IOCTL_H_
+#define _ZRAM_IOCTL_H_
 
-struct ramzswap_ioctl_stats {
-       u64 disksize;           /* user specified or equal to backing swap
-                                * size (if present) */
+struct zram_ioctl_stats {
+       u64 disksize;           /* disksize in bytes (user specifies in KB) */
        u64 num_reads;          /* failed + successful */
        u64 num_writes;         /* --do-- */
        u64 failed_reads;       /* should NEVER! happen */
        u64 failed_writes;      /* can happen when memory is too low */
-       u64 invalid_io;         /* non-swap I/O requests */
+       u64 invalid_io;         /* non-page-aligned I/O requests */
        u64 notify_free;        /* no. of swap slot free notifications */
        u32 pages_zero;         /* no. of zero filled pages */
        u32 good_compress_pct;  /* no. of pages with compression ratio<=50% */
@@ -34,9 +33,9 @@ struct ramzswap_ioctl_stats {
        u64 mem_used_total;
 } __attribute__ ((packed, aligned(4)));
 
-#define RZSIO_SET_DISKSIZE_KB  _IOW('z', 0, size_t)
-#define RZSIO_GET_STATS                _IOR('z', 1, struct ramzswap_ioctl_stats)
-#define RZSIO_INIT             _IO('z', 2)
-#define RZSIO_RESET            _IO('z', 3)
+#define ZRAMIO_SET_DISKSIZE_KB _IOW('z', 0, size_t)
+#define ZRAMIO_GET_STATS       _IOR('z', 1, struct zram_ioctl_stats)
+#define ZRAMIO_INIT            _IO('z', 2)
+#define ZRAMIO_RESET           _IO('z', 3)
 
 #endif
index 99cb2246ac728c24e9d9b39335577dbeb713a6c0..a1900e5025184521e0fe1c6f0c39b233e43026fe 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/errno.h>       /* error codes */
 #include <linux/slab.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
@@ -33,9 +32,8 @@ static int ixj_probe(struct pcmcia_device *p_dev)
 {
        dev_dbg(&p_dev->dev, "ixj_attach()\n");
        /* Create new ixj device */
-       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-       p_dev->io.IOAddrLines = 3;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
        p_dev->conf.IntType = INT_MEMORY_AND_IO;
        p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
        if (!p_dev->priv) {
@@ -121,13 +119,14 @@ static int ixj_config_check(struct pcmcia_device *p_dev,
 {
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
+               p_dev->io_lines = 3;
                if (io->nwin == 2) {
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
-               if (!pcmcia_request_io(p_dev, &p_dev->io))
+               if (!pcmcia_request_io(p_dev))
                        return 0;
        }
        return -ENODEV;
@@ -151,7 +150,8 @@ static int ixj_config(struct pcmcia_device * link)
        /*
         *      Register the card with the core.
         */
-       j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10);
+       j = ixj_pcmcia_probe(link->resource[0]->start,
+                            link->resource[0]->start + 0x10);
 
        info->ndev = 1;
        ixj_get_serial(link, j);
index 371f87f8bc229f7cdcabca5d7cee7944a6b3cf7f..a8ea2f19a0ccfb3a62b1649c28b54e810703d624 100644 (file)
@@ -79,7 +79,7 @@ static int __devinit hilscher_pci_probe(struct pci_dev *dev,
        }
        info->version = "0.0.1";
        info->irq = dev->irq;
-       info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
+       info->irq_flags = IRQF_SHARED;
        info->handler = hilscher_handler;
 
        if (uio_register_device(&dev->dev, info))
index 61e569df2bba60cabc46a6e85d5f33007fd58a6c..7174d518b8a659d752033f819a333d6f717b9dda 100644 (file)
@@ -155,7 +155,6 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
         * Interrupt sharing is not supported.
         */
 
-       uioinfo->irq_flags |= IRQF_DISABLED;
        uioinfo->handler = uio_pdrv_genirq_handler;
        uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
        uioinfo->open = uio_pdrv_genirq_open;
index 3d461cd73e6b5bf9487a5e6662dbbc3da538a338..a187fa14c5c084d54dcd687e908f8dc43817a55c 100644 (file)
@@ -154,7 +154,7 @@ static int __devinit sercos3_pci_probe(struct pci_dev *dev,
        info->name = "Sercos_III_PCI";
        info->version = "0.0.1";
        info->irq = dev->irq;
-       info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
+       info->irq_flags = IRQF_SHARED;
        info->handler = sercos3_handler;
        info->irqcontrol = sercos3_irqcontrol;
 
index 82506ca297d5f1632312f8d52b7f80b7aab49637..9648b75f0283e31d9b1c02c618b979fe3472ee41 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/moduleparam.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/dma-mapping.h>
 #include <linux/usb/ch9.h>
index 58cb73c8420a785086a21a62e6e992800e4f4a03..0e13a00eb2ed51ea38126fa954a5e3a4723d87c0 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
@@ -43,8 +42,6 @@ MODULE_LICENSE("GPL");
 /* VARIABLES                                                          */
 /*====================================================================*/
 
-static const char driver_name[DEV_NAME_LEN]  = "sl811_cs";
-
 typedef struct local_info_t {
        struct pcmcia_device    *p_dev;
 } local_info_t;
@@ -165,16 +162,16 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,
        p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
        if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
                cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
 
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
 
-               return pcmcia_request_io(p_dev, &p_dev->io);
+               return pcmcia_request_io(p_dev);
        }
        pcmcia_disable_device(p_dev);
        return -ENODEV;
@@ -192,7 +189,7 @@ static int sl811_cs_config(struct pcmcia_device *link)
                goto failed;
 
        /* require an IRQ and two registers */
-       if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
+       if (resource_size(link->resource[0]) < 2)
                goto failed;
 
        if (!link->irq)
@@ -207,11 +204,10 @@ static int sl811_cs_config(struct pcmcia_device *link)
        if (link->conf.Vpp)
                printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
        printk(", irq %d", link->irq);
-       printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-              link->io.BasePort1+link->io.NumPorts1-1);
+       printk(", io %pR", link->resource[0]);
        printk("\n");
 
-       if (sl811_hc_init(parent, link->io.BasePort1, link->irq)
+       if (sl811_hc_init(parent, link->resource[0]->start, link->irq)
                        < 0) {
 failed:
                printk(KERN_WARNING "sl811_cs_config failed\n");
@@ -246,7 +242,7 @@ MODULE_DEVICE_TABLE(pcmcia, sl811_ids);
 static struct pcmcia_driver sl811_cs_driver = {
        .owner          = THIS_MODULE,
        .drv            = {
-               .name   = (char *)driver_name,
+               .name   = "sl811_cs",
        },
        .probe          = sl811_cs_probe,
        .remove         = sl811_cs_detach,
index 09f1b9b462f4a8a4ce86a600aa55a4cbf1685622..c7796637bafd2c1ae0d6501751e90d362e77e48e 100644 (file)
@@ -390,12 +390,12 @@ static int __init bw2_init(void)
        if (fb_get_options("bw2fb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&bw2_driver, &of_bus_type);
+       return of_register_platform_driver(&bw2_driver);
 }
 
 static void __exit bw2_exit(void)
 {
-       of_unregister_driver(&bw2_driver);
+       of_unregister_platform_driver(&bw2_driver);
 }
 
 module_init(bw2_init);
index e5dc2241194fed66606c1e694aa4c77ed3357c81..d09fde8beb69b548bec3eac39a6399aa29a614a4 100644 (file)
@@ -610,12 +610,12 @@ static int __init cg14_init(void)
        if (fb_get_options("cg14fb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&cg14_driver, &of_bus_type);
+       return of_register_platform_driver(&cg14_driver);
 }
 
 static void __exit cg14_exit(void)
 {
-       of_unregister_driver(&cg14_driver);
+       of_unregister_platform_driver(&cg14_driver);
 }
 
 module_init(cg14_init);
index 558d73a948a0d836c73ea20c26440229738ba581..64aa29809fb970dcb1740eb72e69cafb5cb62660 100644 (file)
@@ -477,12 +477,12 @@ static int __init cg3_init(void)
        if (fb_get_options("cg3fb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&cg3_driver, &of_bus_type);
+       return of_register_platform_driver(&cg3_driver);
 }
 
 static void __exit cg3_exit(void)
 {
-       of_unregister_driver(&cg3_driver);
+       of_unregister_platform_driver(&cg3_driver);
 }
 
 module_init(cg3_init);
index 480d761a27a839b1e265eefe8204a17fb1f56504..2389a719dcc737e04043f7c6d01a5c172ae65481 100644 (file)
@@ -870,12 +870,12 @@ static int __init cg6_init(void)
        if (fb_get_options("cg6fb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&cg6_driver, &of_bus_type);
+       return of_register_platform_driver(&cg6_driver);
 }
 
 static void __exit cg6_exit(void)
 {
-       of_unregister_driver(&cg6_driver);
+       of_unregister_platform_driver(&cg6_driver);
 }
 
 module_init(cg6_init);
index b0a3fa00706d2e25896fc862aa1bcc116010a6c7..3b3f5749af925c83d055fa41df0a1c6baed92e5a 100644 (file)
@@ -2342,6 +2342,30 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
        return 0;
 }
 
+static int fbcon_debug_enter(struct vc_data *vc)
+{
+       struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+       struct fbcon_ops *ops = info->fbcon_par;
+
+       ops->save_graphics = ops->graphics;
+       ops->graphics = 0;
+       if (info->fbops->fb_debug_enter)
+               info->fbops->fb_debug_enter(info);
+       fbcon_set_palette(vc, color_table);
+       return 0;
+}
+
+static int fbcon_debug_leave(struct vc_data *vc)
+{
+       struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+       struct fbcon_ops *ops = info->fbcon_par;
+
+       ops->graphics = ops->save_graphics;
+       if (info->fbops->fb_debug_leave)
+               info->fbops->fb_debug_leave(info);
+       return 0;
+}
+
 static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
 {
        u8 *fontdata = vc->vc_font.data;
@@ -3276,6 +3300,8 @@ static const struct consw fb_con = {
        .con_screen_pos         = fbcon_screen_pos,
        .con_getxy              = fbcon_getxy,
        .con_resize             = fbcon_resize,
+       .con_debug_enter        = fbcon_debug_enter,
+       .con_debug_leave        = fbcon_debug_leave,
 };
 
 static struct notifier_block fbcon_event_notifier = {
index 89a346880ec014897f051168013d4af7fc5cd091..6bd2e0c7f209d402cbbf75bb3b088a7c58f3ed24 100644 (file)
@@ -74,6 +74,7 @@ struct fbcon_ops {
        int    cursor_reset;
        int    blank_state;
        int    graphics;
+       int    save_graphics; /* for debug enter/leave */
        int    flags;
        int    rotate;
        int    cur_rotate;
index 49fcbe8f18ac4dbbd958f5e1973be85dda2875ae..c225dcce89e78f083f0e02c60b3064b29d001748 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/pci.h>
index 95c0227f47fcfd7fd30ea784b4202af1dace340a..f6ecfab296d39515f3639c3af2f618aa9a702f63 100644 (file)
@@ -1067,12 +1067,12 @@ static int __init ffb_init(void)
        if (fb_get_options("ffb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&ffb_driver, &of_bus_type);
+       return of_register_platform_driver(&ffb_driver);
 }
 
 static void __exit ffb_exit(void)
 {
-       of_unregister_driver(&ffb_driver);
+       of_unregister_platform_driver(&ffb_driver);
 }
 
 module_init(ffb_init);
index 9e8bf7d5e249df2a3d0f3243181bab0b76b633a9..ad677637ffbb0e480e6c318e078a5fcae2f484c2 100644 (file)
@@ -677,12 +677,12 @@ static int __init leo_init(void)
        if (fb_get_options("leofb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&leo_driver, &of_bus_type);
+       return of_register_platform_driver(&leo_driver);
 }
 
 static void __exit leo_exit(void)
 {
-       of_unregister_driver(&leo_driver);
+       of_unregister_platform_driver(&leo_driver);
 }
 
 module_init(leo_init);
index 46dda7d8aaeefae0d3a4b3a850ee6799e080a44d..cb163a5397beab1a592b836db2c273db3266351c 100644 (file)
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <asm/io.h>
-#include <asm/prom.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/pci-bridge.h>
index 6552751e81aaa058a18af29ff8892d9abe1a54af..688b055abab2066811a3115bf270319f62dd811d 100644 (file)
@@ -367,12 +367,12 @@ static int __init p9100_init(void)
        if (fb_get_options("p9100fb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&p9100_driver, &of_bus_type);
+       return of_register_platform_driver(&p9100_driver);
 }
 
 static void __exit p9100_exit(void)
 {
-       of_unregister_driver(&p9100_driver);
+       of_unregister_platform_driver(&p9100_driver);
 }
 
 module_init(p9100_init);
index 489b44e8db8153dac7a06bda8abae694c878d7e0..7288934c0d49dacfabee368b6498289f2cf635b5 100644 (file)
@@ -213,12 +213,12 @@ static int __init gfb_init(void)
        if (fb_get_options("gfb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&gfb_driver, &of_bus_type);
+       return of_register_platform_driver(&gfb_driver);
 }
 
 static void __exit gfb_exit(void)
 {
-       of_unregister_driver(&gfb_driver);
+       of_unregister_platform_driver(&gfb_driver);
 }
 
 module_init(gfb_init);
index cc039b33d2d8bd762a493bd650fceb1b0895a52f..f375e0db6776bcefae43c2e26fa08a213c88d6c3 100644 (file)
@@ -526,12 +526,12 @@ static int __init tcx_init(void)
        if (fb_get_options("tcxfb", NULL))
                return -ENODEV;
 
-       return of_register_driver(&tcx_driver, &of_bus_type);
+       return of_register_platform_driver(&tcx_driver);
 }
 
 static void __exit tcx_exit(void)
 {
-       of_unregister_driver(&tcx_driver);
+       of_unregister_platform_driver(&tcx_driver);
 }
 
 module_init(tcx_init);
index fa97d3e7c21ab2e9c7ae0098971f6b3530845a60..7c7f42a1279625673df8b21131afec33b688f506 100644 (file)
@@ -684,7 +684,7 @@ static struct xenbus_driver xenfb_driver = {
 
 static int __init xenfb_init(void)
 {
-       if (!xen_domain())
+       if (!xen_pv_domain())
                return -ENODEV;
 
        /* Nothing to do if running in dom0. */
index d62b9ce8f773cb0d402bb43794b121bddae02209..30a2512fd52e30fef23cdac728eae59d4b3803af 100644 (file)
@@ -545,7 +545,7 @@ static int __devinit cpwd_probe(struct of_device *op,
                goto out;
        }
 
-       p->irq = op->irqs[0];
+       p->irq = op->archdata.irqs[0];
 
        spin_lock_init(&p->lock);
 
@@ -688,12 +688,12 @@ static struct of_platform_driver cpwd_driver = {
 
 static int __init cpwd_init(void)
 {
-       return of_register_driver(&cpwd_driver, &of_bus_type);
+       return of_register_platform_driver(&cpwd_driver);
 }
 
 static void __exit cpwd_exit(void)
 {
-       of_unregister_driver(&cpwd_driver);
+       of_unregister_platform_driver(&cpwd_driver);
 }
 
 module_init(cpwd_init);
index 5dceeddc88596c833add1e6abc2ec5db65048279..4082b4ace1fce159089924d6718918e182fc67f7 100644 (file)
@@ -250,12 +250,12 @@ static struct of_platform_driver riowd_driver = {
 
 static int __init riowd_init(void)
 {
-       return of_register_driver(&riowd_driver, &of_bus_type);
+       return of_register_platform_driver(&riowd_driver);
 }
 
 static void __exit riowd_exit(void)
 {
-       of_unregister_driver(&riowd_driver);
+       of_unregister_platform_driver(&riowd_driver);
 }
 
 module_init(riowd_init);
index fad3df2c1276165f1e194b7c5f7bb66cda934820..0a882693663997634a553f76271f9cb287ea8fb2 100644 (file)
@@ -62,4 +62,13 @@ config XEN_SYS_HYPERVISOR
         virtual environment, /sys/hypervisor will still be present,
         but will have no xen contents.
 
+config XEN_PLATFORM_PCI
+       tristate "xen platform pci device driver"
+       depends on XEN_PVHVM
+       default m
+       help
+         Driver for the Xen PCI Platform device: it is responsible for
+         initializing xenbus and grant_table when running in a Xen HVM
+         domain. As a consequence this driver is required to run any Xen PV
+         frontend on Xen HVM.
 endmenu
index 7c284342f30fef956900f93e3386179152873bd0..e392fb776af365823e5b8985245dc5613c303a4c 100644 (file)
@@ -9,4 +9,5 @@ obj-$(CONFIG_XEN_XENCOMM)       += xencomm.o
 obj-$(CONFIG_XEN_BALLOON)      += balloon.o
 obj-$(CONFIG_XEN_DEV_EVTCHN)   += evtchn.o
 obj-$(CONFIG_XENFS)            += xenfs/
-obj-$(CONFIG_XEN_SYS_HYPERVISOR)       += sys-hypervisor.o
\ No newline at end of file
+obj-$(CONFIG_XEN_SYS_HYPERVISOR)       += sys-hypervisor.o
+obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
index db8f506817f0ad30f2b54bde0ff778a7405ba59b..72f91bff29c7d836d86844c224225e1353c76648 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/bootmem.h>
 #include <linux/slab.h>
 
+#include <asm/desc.h>
 #include <asm/ptrace.h>
 #include <asm/irq.h>
 #include <asm/idle.h>
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
 
+#include <xen/xen.h>
+#include <xen/hvm.h>
 #include <xen/xen-ops.h>
 #include <xen/events.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/event_channel.h>
+#include <xen/interface/hvm/hvm_op.h>
+#include <xen/interface/hvm/params.h>
 
 /*
  * This lock protects updates to the following mapping and reference-count
@@ -335,9 +340,18 @@ static int find_unbound_irq(void)
        int irq;
        struct irq_desc *desc;
 
-       for (irq = 0; irq < nr_irqs; irq++)
+       for (irq = 0; irq < nr_irqs; irq++) {
+               desc = irq_to_desc(irq);
+               /* only 0->15 have init'd desc; handle irq > 16 */
+               if (desc == NULL)
+                       break;
+               if (desc->chip == &no_irq_chip)
+                       break;
+               if (desc->chip != &xen_dynamic_chip)
+                       continue;
                if (irq_info[irq].type == IRQT_UNBOUND)
                        break;
+       }
 
        if (irq == nr_irqs)
                panic("No available IRQ to bind to: increase nr_irqs!\n");
@@ -346,7 +360,7 @@ static int find_unbound_irq(void)
        if (WARN_ON(desc == NULL))
                return -1;
 
-       dynamic_irq_init(irq);
+       dynamic_irq_init_keep_chip_data(irq);
 
        return irq;
 }
@@ -536,6 +550,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
        if (irq < 0)
                return irq;
 
+       irqflags |= IRQF_NO_SUSPEND;
        retval = request_irq(irq, handler, irqflags, devname, dev_id);
        if (retval != 0) {
                unbind_from_irq(irq);
@@ -617,17 +632,13 @@ static DEFINE_PER_CPU(unsigned, xed_nesting_count);
  * a bitset of words which contain pending event bits.  The second
  * level is a bitset of pending events themselves.
  */
-void xen_evtchn_do_upcall(struct pt_regs *regs)
+static void __xen_evtchn_do_upcall(void)
 {
        int cpu = get_cpu();
-       struct pt_regs *old_regs = set_irq_regs(regs);
        struct shared_info *s = HYPERVISOR_shared_info;
        struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
        unsigned count;
 
-       exit_idle();
-       irq_enter();
-
        do {
                unsigned long pending_words;
 
@@ -664,14 +675,31 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
 
                count = __get_cpu_var(xed_nesting_count);
                __get_cpu_var(xed_nesting_count) = 0;
-       } while(count != 1);
+       } while (count != 1 || vcpu_info->evtchn_upcall_pending);
 
 out:
+
+       put_cpu();
+}
+
+void xen_evtchn_do_upcall(struct pt_regs *regs)
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
+       exit_idle();
+       irq_enter();
+
+       __xen_evtchn_do_upcall();
+
        irq_exit();
        set_irq_regs(old_regs);
+}
 
-       put_cpu();
+void xen_hvm_evtchn_do_upcall(void)
+{
+       __xen_evtchn_do_upcall();
 }
+EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall);
 
 /* Rebind a new event channel to an existing irq. */
 void rebind_evtchn_irq(int evtchn, int irq)
@@ -708,7 +736,10 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
        struct evtchn_bind_vcpu bind_vcpu;
        int evtchn = evtchn_from_irq(irq);
 
-       if (!VALID_EVTCHN(evtchn))
+       /* events delivered via platform PCI interrupts are always
+        * routed to vcpu 0 */
+       if (!VALID_EVTCHN(evtchn) ||
+               (xen_hvm_domain() && !xen_have_vector_callback))
                return -1;
 
        /* Send future instances of this interrupt to other vcpu. */
@@ -933,6 +964,44 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
        .retrigger      = retrigger_dynirq,
 };
 
+int xen_set_callback_via(uint64_t via)
+{
+       struct xen_hvm_param a;
+       a.domid = DOMID_SELF;
+       a.index = HVM_PARAM_CALLBACK_IRQ;
+       a.value = via;
+       return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
+}
+EXPORT_SYMBOL_GPL(xen_set_callback_via);
+
+#ifdef CONFIG_XEN_PVHVM
+/* Vector callbacks are better than PCI interrupts to receive event
+ * channel notifications because we can receive vector callbacks on any
+ * vcpu and we don't need PCI support or APIC interactions. */
+void xen_callback_vector(void)
+{
+       int rc;
+       uint64_t callback_via;
+       if (xen_have_vector_callback) {
+               callback_via = HVM_CALLBACK_VECTOR(XEN_HVM_EVTCHN_CALLBACK);
+               rc = xen_set_callback_via(callback_via);
+               if (rc) {
+                       printk(KERN_ERR "Request for Xen HVM callback vector"
+                                       " failed.\n");
+                       xen_have_vector_callback = 0;
+                       return;
+               }
+               printk(KERN_INFO "Xen HVM callback vector for event delivery is "
+                               "enabled\n");
+               /* in the restore case the vector has already been allocated */
+               if (!test_bit(XEN_HVM_EVTCHN_CALLBACK, used_vectors))
+                       alloc_intr_gate(XEN_HVM_EVTCHN_CALLBACK, xen_hvm_callback_vector);
+       }
+}
+#else
+void xen_callback_vector(void) {}
+#endif
+
 void __init xen_init_IRQ(void)
 {
        int i;
@@ -947,5 +1016,10 @@ void __init xen_init_IRQ(void)
        for (i = 0; i < NR_EVENT_CHANNELS; i++)
                mask_evtchn(i);
 
-       irq_ctx_init(smp_processor_id());
+       if (xen_hvm_domain()) {
+               xen_callback_vector();
+               native_init_IRQ();
+       } else {
+               irq_ctx_init(smp_processor_id());
+       }
 }
index f66db3b91d6100b2fe875d410553ca0038fadabc..6c453181649683f37c0f87eb59ac1ba1161b71b0 100644 (file)
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/uaccess.h>
+#include <linux/io.h>
 
 #include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <xen/page.h>
 #include <xen/grant_table.h>
+#include <xen/interface/memory.h>
 #include <asm/xen/hypercall.h>
 
 #include <asm/pgtable.h>
@@ -59,6 +61,8 @@ static unsigned int boot_max_nr_grant_frames;
 static int gnttab_free_count;
 static grant_ref_t gnttab_free_head;
 static DEFINE_SPINLOCK(gnttab_list_lock);
+unsigned long xen_hvm_resume_frames;
+EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
 
 static struct grant_entry *shared;
 
@@ -433,7 +437,7 @@ static unsigned int __max_nr_grant_frames(void)
        return query.max_nr_frames;
 }
 
-static inline unsigned int max_nr_grant_frames(void)
+unsigned int gnttab_max_grant_frames(void)
 {
        unsigned int xen_max = __max_nr_grant_frames();
 
@@ -441,6 +445,7 @@ static inline unsigned int max_nr_grant_frames(void)
                return boot_max_nr_grant_frames;
        return xen_max;
 }
+EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
 
 static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
 {
@@ -449,6 +454,30 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
        unsigned int nr_gframes = end_idx + 1;
        int rc;
 
+       if (xen_hvm_domain()) {
+               struct xen_add_to_physmap xatp;
+               unsigned int i = end_idx;
+               rc = 0;
+               /*
+                * Loop backwards, so that the first hypercall has the largest
+                * index, ensuring that the table will grow only once.
+                */
+               do {
+                       xatp.domid = DOMID_SELF;
+                       xatp.idx = i;
+                       xatp.space = XENMAPSPACE_grant_table;
+                       xatp.gpfn = (xen_hvm_resume_frames >> PAGE_SHIFT) + i;
+                       rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
+                       if (rc != 0) {
+                               printk(KERN_WARNING
+                                               "grant table add_to_physmap failed, err=%d\n", rc);
+                               break;
+                       }
+               } while (i-- > start_idx);
+
+               return rc;
+       }
+
        frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC);
        if (!frames)
                return -ENOMEM;
@@ -465,7 +494,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
 
        BUG_ON(rc || setup.status);
 
-       rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(),
+       rc = arch_gnttab_map_shared(frames, nr_gframes, gnttab_max_grant_frames(),
                                    &shared);
        BUG_ON(rc);
 
@@ -476,9 +505,27 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
 
 int gnttab_resume(void)
 {
-       if (max_nr_grant_frames() < nr_grant_frames)
+       unsigned int max_nr_gframes;
+
+       max_nr_gframes = gnttab_max_grant_frames();
+       if (max_nr_gframes < nr_grant_frames)
                return -ENOSYS;
-       return gnttab_map(0, nr_grant_frames - 1);
+
+       if (xen_pv_domain())
+               return gnttab_map(0, nr_grant_frames - 1);
+
+       if (!shared) {
+               shared = ioremap(xen_hvm_resume_frames, PAGE_SIZE * max_nr_gframes);
+               if (shared == NULL) {
+                       printk(KERN_WARNING
+                                       "Failed to ioremap gnttab share frames!");
+                       return -ENOMEM;
+               }
+       }
+
+       gnttab_map(0, nr_grant_frames - 1);
+
+       return 0;
 }
 
 int gnttab_suspend(void)
@@ -495,7 +542,7 @@ static int gnttab_expand(unsigned int req_entries)
        cur = nr_grant_frames;
        extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
                 GREFS_PER_GRANT_FRAME);
-       if (cur + extra > max_nr_grant_frames())
+       if (cur + extra > gnttab_max_grant_frames())
                return -ENOSPC;
 
        rc = gnttab_map(cur, cur + extra - 1);
@@ -505,15 +552,12 @@ static int gnttab_expand(unsigned int req_entries)
        return rc;
 }
 
-static int __devinit gnttab_init(void)
+int gnttab_init(void)
 {
        int i;
        unsigned int max_nr_glist_frames, nr_glist_frames;
        unsigned int nr_init_grefs;
 
-       if (!xen_domain())
-               return -ENODEV;
-
        nr_grant_frames = 1;
        boot_max_nr_grant_frames = __max_nr_grant_frames();
 
@@ -556,5 +600,18 @@ static int __devinit gnttab_init(void)
        kfree(gnttab_list);
        return -ENOMEM;
 }
+EXPORT_SYMBOL_GPL(gnttab_init);
+
+static int __devinit __gnttab_init(void)
+{
+       /* Delay grant-table initialization in the PV on HVM case */
+       if (xen_hvm_domain())
+               return 0;
+
+       if (!xen_pv_domain())
+               return -ENODEV;
+
+       return gnttab_init();
+}
 
-core_initcall(gnttab_init);
+core_initcall(__gnttab_init);
index 07e857b0de13958e974181ff76f9da11e1af7c7e..1799bd8903151db422bd28cf1173564f0d6872d4 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/stop_machine.h>
 #include <linux/freezer.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/grant_table.h>
 #include <xen/events.h>
@@ -17,6 +18,7 @@
 
 #include <asm/xen/hypercall.h>
 #include <asm/xen/page.h>
+#include <asm/xen/hypervisor.h>
 
 enum shutdown_state {
        SHUTDOWN_INVALID = -1,
@@ -33,10 +35,30 @@ enum shutdown_state {
 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
 
 #ifdef CONFIG_PM_SLEEP
-static int xen_suspend(void *data)
+static int xen_hvm_suspend(void *data)
 {
+       struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
        int *cancelled = data;
+
+       BUG_ON(!irqs_disabled());
+
+       *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
+
+       xen_hvm_post_suspend(*cancelled);
+       gnttab_resume();
+
+       if (!*cancelled) {
+               xen_irq_resume();
+               xen_timer_resume();
+       }
+
+       return 0;
+}
+
+static int xen_suspend(void *data)
+{
        int err;
+       int *cancelled = data;
 
        BUG_ON(!irqs_disabled());
 
@@ -106,7 +128,10 @@ static void do_suspend(void)
                goto out_resume;
        }
 
-       err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
+       if (xen_hvm_domain())
+               err = stop_machine(xen_hvm_suspend, &cancelled, cpumask_of(0));
+       else
+               err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
 
        dpm_resume_noirq(PMSG_RESUME);
 
@@ -255,7 +280,19 @@ static int shutdown_event(struct notifier_block *notifier,
        return NOTIFY_DONE;
 }
 
-static int __init setup_shutdown_event(void)
+static int __init __setup_shutdown_event(void)
+{
+       /* Delay initialization in the PV on HVM case */
+       if (xen_hvm_domain())
+               return 0;
+
+       if (!xen_pv_domain())
+               return -ENODEV;
+
+       return xen_setup_shutdown_event();
+}
+
+int xen_setup_shutdown_event(void)
 {
        static struct notifier_block xenstore_notifier = {
                .notifier_call = shutdown_event
@@ -264,5 +301,6 @@ static int __init setup_shutdown_event(void)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
 
-subsys_initcall(setup_shutdown_event);
+subsys_initcall(__setup_shutdown_event);
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
new file mode 100644 (file)
index 0000000..c01b5dd
--- /dev/null
@@ -0,0 +1,207 @@
+/******************************************************************************
+ * platform-pci.c
+ *
+ * Xen platform PCI device driver
+ * Copyright (c) 2005, Intel Corporation.
+ * Copyright (c) 2007, XenSource Inc.
+ * Copyright (c) 2010, Citrix
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include <xen/platform_pci.h>
+#include <xen/grant_table.h>
+#include <xen/xenbus.h>
+#include <xen/events.h>
+#include <xen/hvm.h>
+#include <xen/xen-ops.h>
+
+#define DRV_NAME    "xen-platform-pci"
+
+MODULE_AUTHOR("ssmith@xensource.com and stefano.stabellini@eu.citrix.com");
+MODULE_DESCRIPTION("Xen platform PCI device");
+MODULE_LICENSE("GPL");
+
+static unsigned long platform_mmio;
+static unsigned long platform_mmio_alloc;
+static unsigned long platform_mmiolen;
+static uint64_t callback_via;
+
+unsigned long alloc_xen_mmio(unsigned long len)
+{
+       unsigned long addr;
+
+       addr = platform_mmio + platform_mmio_alloc;
+       platform_mmio_alloc += len;
+       BUG_ON(platform_mmio_alloc > platform_mmiolen);
+
+       return addr;
+}
+
+static uint64_t get_callback_via(struct pci_dev *pdev)
+{
+       u8 pin;
+       int irq;
+
+       irq = pdev->irq;
+       if (irq < 16)
+               return irq; /* ISA IRQ */
+
+       pin = pdev->pin;
+
+       /* We don't know the GSI. Specify the PCI INTx line instead. */
+       return ((uint64_t)0x01 << 56) | /* PCI INTx identifier */
+               ((uint64_t)pci_domain_nr(pdev->bus) << 32) |
+               ((uint64_t)pdev->bus->number << 16) |
+               ((uint64_t)(pdev->devfn & 0xff) << 8) |
+               ((uint64_t)(pin - 1) & 3);
+}
+
+static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id)
+{
+       xen_hvm_evtchn_do_upcall();
+       return IRQ_HANDLED;
+}
+
+static int xen_allocate_irq(struct pci_dev *pdev)
+{
+       return request_irq(pdev->irq, do_hvm_evtchn_intr,
+                       IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
+                       "xen-platform-pci", pdev);
+}
+
+static int platform_pci_resume(struct pci_dev *pdev)
+{
+       int err;
+       if (xen_have_vector_callback)
+               return 0;
+       err = xen_set_callback_via(callback_via);
+       if (err) {
+               dev_err(&pdev->dev, "platform_pci_resume failure!\n");
+               return err;
+       }
+       return 0;
+}
+
+static int __devinit platform_pci_init(struct pci_dev *pdev,
+                                      const struct pci_device_id *ent)
+{
+       int i, ret;
+       long ioaddr, iolen;
+       long mmio_addr, mmio_len;
+       unsigned int max_nr_gframes;
+
+       i = pci_enable_device(pdev);
+       if (i)
+               return i;
+
+       ioaddr = pci_resource_start(pdev, 0);
+       iolen = pci_resource_len(pdev, 0);
+
+       mmio_addr = pci_resource_start(pdev, 1);
+       mmio_len = pci_resource_len(pdev, 1);
+
+       if (mmio_addr == 0 || ioaddr == 0) {
+               dev_err(&pdev->dev, "no resources found\n");
+               ret = -ENOENT;
+               goto pci_out;
+       }
+
+       if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) {
+               dev_err(&pdev->dev, "MEM I/O resource 0x%lx @ 0x%lx busy\n",
+                      mmio_addr, mmio_len);
+               ret = -EBUSY;
+               goto pci_out;
+       }
+
+       if (request_region(ioaddr, iolen, DRV_NAME) == NULL) {
+               dev_err(&pdev->dev, "I/O resource 0x%lx @ 0x%lx busy\n",
+                      iolen, ioaddr);
+               ret = -EBUSY;
+               goto mem_out;
+       }
+
+       platform_mmio = mmio_addr;
+       platform_mmiolen = mmio_len;
+
+       if (!xen_have_vector_callback) {
+               ret = xen_allocate_irq(pdev);
+               if (ret) {
+                       dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret);
+                       goto out;
+               }
+               callback_via = get_callback_via(pdev);
+               ret = xen_set_callback_via(callback_via);
+               if (ret) {
+                       dev_warn(&pdev->dev, "Unable to set the evtchn callback "
+                                        "err=%d\n", ret);
+                       goto out;
+               }
+       }
+
+       max_nr_gframes = gnttab_max_grant_frames();
+       xen_hvm_resume_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
+       ret = gnttab_init();
+       if (ret)
+               goto out;
+       xenbus_probe(NULL);
+       ret = xen_setup_shutdown_event();
+       if (ret)
+               goto out;
+       return 0;
+
+out:
+       release_region(ioaddr, iolen);
+mem_out:
+       release_mem_region(mmio_addr, mmio_len);
+pci_out:
+       pci_disable_device(pdev);
+       return ret;
+}
+
+static struct pci_device_id platform_pci_tbl[] __devinitdata = {
+       {PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, platform_pci_tbl);
+
+static struct pci_driver platform_driver = {
+       .name =           DRV_NAME,
+       .probe =          platform_pci_init,
+       .id_table =       platform_pci_tbl,
+#ifdef CONFIG_PM
+       .resume_early =   platform_pci_resume,
+#endif
+};
+
+static int __init platform_pci_module_init(void)
+{
+       /* no unplug has been done, IGNORE hasn't been specified: just
+        * return now */
+       if (!xen_platform_pci_unplug)
+               return -ENODEV;
+
+       return pci_register_driver(&platform_driver);
+}
+
+module_init(platform_pci_module_init);
index 3479332113e998abfd311ffc079d548a342878c5..29bac5118877ef2028a781e6b409e2fe36463a99 100644 (file)
@@ -56,6 +56,9 @@
 #include <xen/events.h>
 #include <xen/page.h>
 
+#include <xen/platform_pci.h>
+#include <xen/hvm.h>
+
 #include "xenbus_comms.h"
 #include "xenbus_probe.h"
 
@@ -752,10 +755,7 @@ int register_xenstore_notifier(struct notifier_block *nb)
 {
        int ret = 0;
 
-       if (xenstored_ready > 0)
-               ret = nb->notifier_call(nb, 0, NULL);
-       else
-               blocking_notifier_chain_register(&xenstore_chain, nb);
+       blocking_notifier_chain_register(&xenstore_chain, nb);
 
        return ret;
 }
@@ -779,8 +779,23 @@ void xenbus_probe(struct work_struct *unused)
        /* Notify others that xenstore is up */
        blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
 }
+EXPORT_SYMBOL_GPL(xenbus_probe);
+
+static int __init xenbus_probe_initcall(void)
+{
+       if (!xen_domain())
+               return -ENODEV;
+
+       if (xen_initial_domain() || xen_hvm_domain())
+               return 0;
+
+       xenbus_probe(NULL);
+       return 0;
+}
+
+device_initcall(xenbus_probe_initcall);
 
-static int __init xenbus_probe_init(void)
+static int __init xenbus_init(void)
 {
        int err = 0;
 
@@ -805,11 +820,24 @@ static int __init xenbus_probe_init(void)
        if (xen_initial_domain()) {
                /* dom0 not yet supported */
        } else {
+               if (xen_hvm_domain()) {
+                       uint64_t v = 0;
+                       err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
+                       if (err)
+                               goto out_error;
+                       xen_store_evtchn = (int)v;
+                       err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
+                       if (err)
+                               goto out_error;
+                       xen_store_mfn = (unsigned long)v;
+                       xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
+               } else {
+                       xen_store_evtchn = xen_start_info->store_evtchn;
+                       xen_store_mfn = xen_start_info->store_mfn;
+                       xen_store_interface = mfn_to_virt(xen_store_mfn);
+               }
                xenstored_ready = 1;
-               xen_store_evtchn = xen_start_info->store_evtchn;
-               xen_store_mfn = xen_start_info->store_mfn;
        }
-       xen_store_interface = mfn_to_virt(xen_store_mfn);
 
        /* Initialize the interface to xenstore. */
        err = xs_init();
@@ -819,9 +847,6 @@ static int __init xenbus_probe_init(void)
                goto out_unreg_back;
        }
 
-       if (!xen_initial_domain())
-               xenbus_probe(NULL);
-
 #ifdef CONFIG_XEN_COMPAT_XENFS
        /*
         * Create xenfs mountpoint in /proc for compatibility with
@@ -842,7 +867,7 @@ static int __init xenbus_probe_init(void)
        return err;
 }
 
-postcore_initcall(xenbus_probe_init);
+postcore_initcall(xenbus_init);
 
 MODULE_LICENSE("GPL");
 
@@ -950,6 +975,9 @@ static void wait_for_devices(struct xenbus_driver *xendrv)
 #ifndef MODULE
 static int __init boot_wait_for_devices(void)
 {
+       if (xen_hvm_domain() && !xen_platform_pci_unplug)
+               return -ENODEV;
+
        ready_to_wait_for_devices = 1;
        wait_for_devices(NULL);
        return 0;
index 7b547f53f65ee9267f19dd493a6ab7321310ed4c..5534690075aff4d6b0713d04b8d98dd07ef1fba9 100644 (file)
@@ -76,6 +76,14 @@ struct xs_handle {
        /*
         * Mutex ordering: transaction_mutex -> watch_mutex -> request_mutex.
         * response_mutex is never taken simultaneously with the other three.
+        *
+        * transaction_mutex must be held before incrementing
+        * transaction_count. The mutex is held when a suspend is in
+        * progress to prevent new transactions starting.
+        *
+        * When decrementing transaction_count to zero the wait queue
+        * should be woken up, the suspend code waits for count to
+        * reach zero.
         */
 
        /* One request at a time. */
@@ -85,7 +93,9 @@ struct xs_handle {
        struct mutex response_mutex;
 
        /* Protect transactions against save/restore. */
-       struct rw_semaphore transaction_mutex;
+       struct mutex transaction_mutex;
+       atomic_t transaction_count;
+       wait_queue_head_t transaction_wq;
 
        /* Protect watch (de)register against save/restore. */
        struct rw_semaphore watch_mutex;
@@ -157,6 +167,31 @@ static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
        return body;
 }
 
+static void transaction_start(void)
+{
+       mutex_lock(&xs_state.transaction_mutex);
+       atomic_inc(&xs_state.transaction_count);
+       mutex_unlock(&xs_state.transaction_mutex);
+}
+
+static void transaction_end(void)
+{
+       if (atomic_dec_and_test(&xs_state.transaction_count))
+               wake_up(&xs_state.transaction_wq);
+}
+
+static void transaction_suspend(void)
+{
+       mutex_lock(&xs_state.transaction_mutex);
+       wait_event(xs_state.transaction_wq,
+                  atomic_read(&xs_state.transaction_count) == 0);
+}
+
+static void transaction_resume(void)
+{
+       mutex_unlock(&xs_state.transaction_mutex);
+}
+
 void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
 {
        void *ret;
@@ -164,7 +199,7 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
        int err;
 
        if (req_msg.type == XS_TRANSACTION_START)
-               down_read(&xs_state.transaction_mutex);
+               transaction_start();
 
        mutex_lock(&xs_state.request_mutex);
 
@@ -180,7 +215,7 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
        if ((msg->type == XS_TRANSACTION_END) ||
            ((req_msg.type == XS_TRANSACTION_START) &&
             (msg->type == XS_ERROR)))
-               up_read(&xs_state.transaction_mutex);
+               transaction_end();
 
        return ret;
 }
@@ -432,11 +467,11 @@ int xenbus_transaction_start(struct xenbus_transaction *t)
 {
        char *id_str;
 
-       down_read(&xs_state.transaction_mutex);
+       transaction_start();
 
        id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
        if (IS_ERR(id_str)) {
-               up_read(&xs_state.transaction_mutex);
+               transaction_end();
                return PTR_ERR(id_str);
        }
 
@@ -461,7 +496,7 @@ int xenbus_transaction_end(struct xenbus_transaction t, int abort)
 
        err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
 
-       up_read(&xs_state.transaction_mutex);
+       transaction_end();
 
        return err;
 }
@@ -662,7 +697,7 @@ EXPORT_SYMBOL_GPL(unregister_xenbus_watch);
 
 void xs_suspend(void)
 {
-       down_write(&xs_state.transaction_mutex);
+       transaction_suspend();
        down_write(&xs_state.watch_mutex);
        mutex_lock(&xs_state.request_mutex);
        mutex_lock(&xs_state.response_mutex);
@@ -677,7 +712,7 @@ void xs_resume(void)
 
        mutex_unlock(&xs_state.response_mutex);
        mutex_unlock(&xs_state.request_mutex);
-       up_write(&xs_state.transaction_mutex);
+       transaction_resume();
 
        /* No need for watches_lock: the watch_mutex is sufficient. */
        list_for_each_entry(watch, &watches, list) {
@@ -693,7 +728,7 @@ void xs_suspend_cancel(void)
        mutex_unlock(&xs_state.response_mutex);
        mutex_unlock(&xs_state.request_mutex);
        up_write(&xs_state.watch_mutex);
-       up_write(&xs_state.transaction_mutex);
+       mutex_unlock(&xs_state.transaction_mutex);
 }
 
 static int xenwatch_thread(void *unused)
@@ -843,8 +878,10 @@ int xs_init(void)
 
        mutex_init(&xs_state.request_mutex);
        mutex_init(&xs_state.response_mutex);
-       init_rwsem(&xs_state.transaction_mutex);
+       mutex_init(&xs_state.transaction_mutex);
        init_rwsem(&xs_state.watch_mutex);
+       atomic_set(&xs_state.transaction_count, 0);
+       init_waitqueue_head(&xs_state.transaction_wq);
 
        /* Initialize the shared memory rings to talk to xenstored */
        err = xb_init_comms();
index 8924d93136f152a7dd6b84d267db3162a4ff739b..78bfab0700baf187f8482dcb5a62af1e7507bc31 100644 (file)
@@ -65,7 +65,7 @@ static struct file_system_type xenfs_type = {
 
 static int __init xenfs_init(void)
 {
-       if (xen_pv_domain())
+       if (xen_domain())
                return register_filesystem(&xenfs_type);
 
        printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n");
@@ -74,7 +74,7 @@ static int __init xenfs_init(void)
 
 static void __exit xenfs_exit(void)
 {
-       if (xen_pv_domain())
+       if (xen_domain())
                unregister_filesystem(&xenfs_type);
 }
 
index f28ece397361c8545549b233a2b563a5ef617285..3b39c3752e21812976f10e393c8d0c6ecd15ea9a 100644 (file)
@@ -124,6 +124,9 @@ static ssize_t xenbus_file_read(struct file *filp,
        mutex_lock(&u->reply_mutex);
        while (list_empty(&u->read_buffers)) {
                mutex_unlock(&u->reply_mutex);
+               if (filp->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+
                ret = wait_event_interruptible(u->read_waitq,
                                               !list_empty(&u->read_buffers));
                if (ret)
index 1ccf25cef1f027a61449ed2cf12b56fb077686ea..3006b5bc33d697a2f773b2d81016fda57ee5ff68 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1277,7 +1277,7 @@ out:
 /* sys_io_destroy:
  *     Destroy the aio_context specified.  May cancel any outstanding 
  *     AIOs and block on completion.  Will fail with -ENOSYS if not
- *     implemented.  May fail with -EFAULT if the context pointed to
+ *     implemented.  May fail with -EINVAL if the context pointed to
  *     is invalid.
  */
 SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
@@ -1795,15 +1795,16 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
 
 /* io_getevents:
  *     Attempts to read at least min_nr events and up to nr events from
- *     the completion queue for the aio_context specified by ctx_id.  May
- *     fail with -EINVAL if ctx_id is invalid, if min_nr is out of range,
- *     if nr is out of range, if when is out of range.  May fail with
- *     -EFAULT if any of the memory specified to is invalid.  May return
- *     0 or < min_nr if no events are available and the timeout specified
- *     by when has elapsed, where when == NULL specifies an infinite
- *     timeout.  Note that the timeout pointed to by when is relative and
- *     will be updated if not NULL and the operation blocks.  Will fail
- *     with -ENOSYS if not implemented.
+ *     the completion queue for the aio_context specified by ctx_id. If
+ *     it succeeds, the number of read events is returned. May fail with
+ *     -EINVAL if ctx_id is invalid, if min_nr is out of range, if nr is
+ *     out of range, if timeout is out of range.  May fail with -EFAULT
+ *     if any of the memory specified is invalid.  May return 0 or
+ *     < min_nr if the timeout specified by timeout has elapsed
+ *     before sufficient events are available, where timeout == NULL
+ *     specifies an infinite timeout. Note that the timeout pointed to by
+ *     timeout is relative and will be updated if not NULL and the
+ *     operation blocks. Will fail with -ENOSYS if not implemented.
  */
 SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
                long, min_nr,
index f4a7840bf42cbb4c4be9cf74a7488e61aab4c94d..42c7fafc8bfeff5d33e8ccf36a039323f851d12f 100644 (file)
@@ -37,9 +37,9 @@ void __cachefiles_printk_object(struct cachefiles_object *object,
 
        printk(KERN_ERR "%sobject: OBJ%x\n",
               prefix, object->fscache.debug_id);
-       printk(KERN_ERR "%sobjstate=%s fl=%lx swfl=%lx ev=%lx[%lx]\n",
+       printk(KERN_ERR "%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n",
               prefix, fscache_object_states[object->fscache.state],
-              object->fscache.flags, object->fscache.work.flags,
+              object->fscache.flags, work_busy(&object->fscache.work),
               object->fscache.events,
               object->fscache.event_mask & FSCACHE_OBJECT_EVENTS_MASK);
        printk(KERN_ERR "%sops=%u inp=%u exc=%u\n",
@@ -212,7 +212,7 @@ wait_for_old_object:
 
                /* if the object we're waiting for is queued for processing,
                 * then just put ourselves on the queue behind it */
-               if (slow_work_is_queued(&xobject->fscache.work)) {
+               if (work_pending(&xobject->fscache.work)) {
                        _debug("queue OBJ%x behind OBJ%x immediately",
                               object->fscache.debug_id,
                               xobject->fscache.debug_id);
@@ -220,8 +220,7 @@ wait_for_old_object:
                }
 
                /* otherwise we sleep until either the object we're waiting for
-                * is done, or the slow-work facility wants the thread back to
-                * do other work */
+                * is done, or the fscache_object is congested */
                wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE);
                init_wait(&wait);
                requeue = false;
@@ -229,8 +228,8 @@ wait_for_old_object:
                        prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
                        if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags))
                                break;
-                       requeue = slow_work_sleep_till_thread_needed(
-                               &object->fscache.work, &timeout);
+
+                       requeue = fscache_object_sleep_till_congested(&timeout);
                } while (timeout > 0 && !requeue);
                finish_wait(wq, &wait);
 
index 0f0d41fbb03f96466393fed9766776d3113d4153..0e3c0924cc3a3f01f648731b1e3baed15a7ce1ad 100644 (file)
@@ -422,7 +422,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
        shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
 
        op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
-       op->op.flags |= FSCACHE_OP_FAST;
+       op->op.flags |= FSCACHE_OP_ASYNC;
        op->op.processor = cachefiles_read_copier;
 
        pagevec_init(&pagevec, 0);
@@ -729,7 +729,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
        pagevec_init(&pagevec, 0);
 
        op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
-       op->op.flags |= FSCACHE_OP_FAST;
+       op->op.flags |= FSCACHE_OP_ASYNC;
        op->op.processor = cachefiles_read_copier;
 
        INIT_LIST_HEAD(&backpages);
index d6db933df2b27ce43c0fe31d6e35bb0968598891..f80a4f25123c3fa912daa1eb4080e69dab3d58fb 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/cdev.h>
 #include <linux/mutex.h>
 #include <linux/backing-dev.h>
+#include <linux/tty.h>
 
 #include "internal.h"
 
index 57f0aa9f141f3f3947ad8b44ae0f1e2ed2414f23..917b7d449bb2a6248c28c23284cf82d9c032f285 100644 (file)
@@ -2,7 +2,6 @@ config CIFS
        tristate "CIFS support (advanced network filesystem, SMBFS successor)"
        depends on INET
        select NLS
-       select SLOW_WORK
        help
          This is the client VFS module for the Common Internet File System
          (CIFS) protocol which is the successor to the Server Message Block
index 2a0c892959f4acb49a2e45f67c5a1a6c3ed54e91..a5ed10c9afef09828c84cdc8434cc65f3b1bcbc8 100644 (file)
@@ -933,18 +933,13 @@ init_cifs(void)
        if (rc)
                goto out_unregister_filesystem;
 #endif
-       rc = slow_work_register_user(THIS_MODULE);
-       if (rc)
-               goto out_unregister_key_type;
 
        return 0;
 
- out_unregister_key_type:
 #ifdef CONFIG_CIFS_UPCALL
-       unregister_key_type(&cifs_spnego_key_type);
  out_unregister_filesystem:
-#endif
        unregister_filesystem(&cifs_fs_type);
+#endif
  out_destroy_request_bufs:
        cifs_destroy_request_bufs();
  out_destroy_mids:
index 59906146ad3634e89eb403530d2d592e3ac0216b..0cdfb8c32ac68c34a98f5cdf412250c0eacdec2b 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/slab.h>
-#include <linux/slow-work.h>
+#include <linux/workqueue.h>
 #include "cifs_fs_sb.h"
 #include "cifsacl.h"
 /*
@@ -356,7 +356,7 @@ struct cifsFileInfo {
        atomic_t count;         /* reference count */
        struct mutex fh_mutex; /* prevents reopen race after dead ses*/
        struct cifs_search_info srch_inf;
-       struct slow_work oplock_break; /* slow_work job for oplock breaks */
+       struct work_struct oplock_break; /* work for oplock breaks */
 };
 
 /* Take a reference on the file private data */
@@ -728,6 +728,10 @@ GLOBAL_EXTERN unsigned int cifs_min_rcv;    /* min size of big ntwrk buf pool */
 GLOBAL_EXTERN unsigned int cifs_min_small;  /* min size of small buf pool */
 GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
 
+void cifs_oplock_break(struct work_struct *work);
+void cifs_oplock_break_get(struct cifsFileInfo *cfile);
+void cifs_oplock_break_put(struct cifsFileInfo *cfile);
+
 extern const struct slow_work_ops cifs_oplock_break_ops;
 
 #endif /* _CIFS_GLOB_H */
index a7de5e9fff11f166b23dd472149277bf059c50fa..578d88c5b46e7eae539fb04aede8f59b7c9dac53 100644 (file)
@@ -157,7 +157,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
        mutex_init(&pCifsFile->lock_mutex);
        INIT_LIST_HEAD(&pCifsFile->llist);
        atomic_set(&pCifsFile->count, 1);
-       slow_work_init(&pCifsFile->oplock_break, &cifs_oplock_break_ops);
+       INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
 
        write_lock(&GlobalSMBSeslock);
        list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList);
index fa04a00d126dc5787850f905e195b41d7b310b5c..db11fdef0e92b1ca52a75fb033f03dda24e8f6a5 100644 (file)
@@ -2307,8 +2307,7 @@ static void cifs_invalidate_page(struct page *page, unsigned long offset)
                cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
 }
 
-static void
-cifs_oplock_break(struct slow_work *work)
+void cifs_oplock_break(struct work_struct *work)
 {
        struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
                                                  oplock_break);
@@ -2345,33 +2344,30 @@ cifs_oplock_break(struct slow_work *work)
                                 LOCKING_ANDX_OPLOCK_RELEASE, false);
                cFYI(1, "Oplock release rc = %d", rc);
        }
+
+       /*
+        * We might have kicked in before is_valid_oplock_break()
+        * finished grabbing reference for us.  Make sure it's done by
+        * waiting for GlobalSMSSeslock.
+        */
+       write_lock(&GlobalSMBSeslock);
+       write_unlock(&GlobalSMBSeslock);
+
+       cifs_oplock_break_put(cfile);
 }
 
-static int
-cifs_oplock_break_get(struct slow_work *work)
+void cifs_oplock_break_get(struct cifsFileInfo *cfile)
 {
-       struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
-                                                 oplock_break);
        mntget(cfile->mnt);
        cifsFileInfo_get(cfile);
-       return 0;
 }
 
-static void
-cifs_oplock_break_put(struct slow_work *work)
+void cifs_oplock_break_put(struct cifsFileInfo *cfile)
 {
-       struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
-                                                 oplock_break);
        mntput(cfile->mnt);
        cifsFileInfo_put(cfile);
 }
 
-const struct slow_work_ops cifs_oplock_break_ops = {
-       .get_ref        = cifs_oplock_break_get,
-       .put_ref        = cifs_oplock_break_put,
-       .execute        = cifs_oplock_break,
-};
-
 const struct address_space_operations cifs_addr_ops = {
        .readpage = cifs_readpage,
        .readpages = cifs_readpages,
index 1394aa37f26c59c057baee608f55ff44ac3401d7..3ccadc1326d613171e92a8bd59bf48d02c12ffc2 100644 (file)
@@ -498,7 +498,6 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
        struct cifsTconInfo *tcon;
        struct cifsInodeInfo *pCifsInode;
        struct cifsFileInfo *netfile;
-       int rc;
 
        cFYI(1, "Checking for oplock break or dnotify response");
        if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
@@ -583,13 +582,18 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                                pCifsInode->clientCanCacheAll = false;
                                if (pSMB->OplockLevel == 0)
                                        pCifsInode->clientCanCacheRead = false;
-                               rc = slow_work_enqueue(&netfile->oplock_break);
-                               if (rc) {
-                                       cERROR(1, "failed to enqueue oplock "
-                                                  "break: %d\n", rc);
-                               } else {
-                                       netfile->oplock_break_cancelled = false;
-                               }
+
+                               /*
+                                * cifs_oplock_break_put() can't be called
+                                * from here.  Get reference after queueing
+                                * succeeded.  cifs_oplock_break() will
+                                * synchronize using GlobalSMSSeslock.
+                                */
+                               if (queue_work(system_nrt_wq,
+                                              &netfile->oplock_break))
+                                       cifs_oplock_break_get(netfile);
+                               netfile->oplock_break_cancelled = false;
+
                                read_unlock(&GlobalSMBSeslock);
                                read_unlock(&cifs_tcp_ses_lock);
                                return true;
index e19de6a80339b3ceeae267283962f271ac6c5e55..97d91a03fb1339c03f2b78c42a0010d0266b1fbd 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -653,6 +653,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
        else
                stack_base = vma->vm_start - stack_expand;
 #endif
+       current->mm->start_stack = bprm->p;
        ret = expand_stack(vma, stack_base);
        if (ret)
                ret = -EFAULT;
index 34bb7f71d99404e8b91a4bfb0654505d1e537318..cccaead962c2efe31c01029ca1ffa34676cffc8a 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -178,7 +178,6 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
        fdt->open_fds = (fd_set *)data;
        data += nr / BITS_PER_BYTE;
        fdt->close_on_exec = (fd_set *)data;
-       INIT_RCU_HEAD(&fdt->rcu);
        fdt->next = NULL;
 
        return fdt;
@@ -312,7 +311,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
        new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
        new_fdt->open_fds = (fd_set *)&newf->open_fds_init;
        new_fdt->fd = &newf->fd_array[0];
-       INIT_RCU_HEAD(&new_fdt->rcu);
        new_fdt->next = NULL;
 
        spin_lock(&oldf->file_lock);
@@ -430,7 +428,6 @@ struct files_struct init_files = {
                .fd             = &init_files.fd_array[0],
                .close_on_exec  = (fd_set *)&init_files.close_on_exec_init,
                .open_fds       = (fd_set *)&init_files.open_fds_init,
-               .rcu            = RCU_HEAD_INIT,
        },
        .file_lock      = __SPIN_LOCK_UNLOCKED(init_task.file_lock),
 };
index cc94bb9563f22c83fa9d7823e38d8e6566a1683d..3f6dfa989881eb1f44315b768c943c2ac336bc74 100644 (file)
@@ -1,7 +1,6 @@
 
 config FSCACHE
        tristate "General filesystem local caching manager"
-       select SLOW_WORK
        help
          This option enables a generic filesystem caching manager that can be
          used by various network and other filesystems to cache data locally.
index edd7434ab6e5eb5ff3a8b3b9f38b127a3e2753cf..6a026441c5a6f617f352ddda5acf84c524e5095b 100644 (file)
@@ -82,6 +82,14 @@ extern unsigned fscache_defer_lookup;
 extern unsigned fscache_defer_create;
 extern unsigned fscache_debug;
 extern struct kobject *fscache_root;
+extern struct workqueue_struct *fscache_object_wq;
+extern struct workqueue_struct *fscache_op_wq;
+DECLARE_PER_CPU(wait_queue_head_t, fscache_object_cong_wait);
+
+static inline bool fscache_object_congested(void)
+{
+       return workqueue_congested(WORK_CPU_UNBOUND, fscache_object_wq);
+}
 
 extern int fscache_wait_bit(void *);
 extern int fscache_wait_bit_interruptible(void *);
index add6bdb53f04400779ca899370d07bd2480e108a..f9d856773f7993ab7eb99ec0af67daea119972e1 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/sched.h>
 #include <linux/completion.h>
 #include <linux/slab.h>
+#include <linux/seq_file.h>
 #include "internal.h"
 
 MODULE_DESCRIPTION("FS Cache Manager");
@@ -40,22 +41,105 @@ MODULE_PARM_DESC(fscache_debug,
                 "FS-Cache debugging mask");
 
 struct kobject *fscache_root;
+struct workqueue_struct *fscache_object_wq;
+struct workqueue_struct *fscache_op_wq;
+
+DEFINE_PER_CPU(wait_queue_head_t, fscache_object_cong_wait);
+
+/* these values serve as lower bounds, will be adjusted in fscache_init() */
+static unsigned fscache_object_max_active = 4;
+static unsigned fscache_op_max_active = 2;
+
+#ifdef CONFIG_SYSCTL
+static struct ctl_table_header *fscache_sysctl_header;
+
+static int fscache_max_active_sysctl(struct ctl_table *table, int write,
+                                    void __user *buffer,
+                                    size_t *lenp, loff_t *ppos)
+{
+       struct workqueue_struct **wqp = table->extra1;
+       unsigned int *datap = table->data;
+       int ret;
+
+       ret = proc_dointvec(table, write, buffer, lenp, ppos);
+       if (ret == 0)
+               workqueue_set_max_active(*wqp, *datap);
+       return ret;
+}
+
+ctl_table fscache_sysctls[] = {
+       {
+               .procname       = "object_max_active",
+               .data           = &fscache_object_max_active,
+               .maxlen         = sizeof(unsigned),
+               .mode           = 0644,
+               .proc_handler   = fscache_max_active_sysctl,
+               .extra1         = &fscache_object_wq,
+       },
+       {
+               .procname       = "operation_max_active",
+               .data           = &fscache_op_max_active,
+               .maxlen         = sizeof(unsigned),
+               .mode           = 0644,
+               .proc_handler   = fscache_max_active_sysctl,
+               .extra1         = &fscache_op_wq,
+       },
+       {}
+};
+
+ctl_table fscache_sysctls_root[] = {
+       {
+               .procname       = "fscache",
+               .mode           = 0555,
+               .child          = fscache_sysctls,
+       },
+       {}
+};
+#endif
 
 /*
  * initialise the fs caching module
  */
 static int __init fscache_init(void)
 {
+       unsigned int nr_cpus = num_possible_cpus();
+       unsigned int cpu;
        int ret;
 
-       ret = slow_work_register_user(THIS_MODULE);
-       if (ret < 0)
-               goto error_slow_work;
+       fscache_object_max_active =
+               clamp_val(nr_cpus,
+                         fscache_object_max_active, WQ_UNBOUND_MAX_ACTIVE);
+
+       ret = -ENOMEM;
+       fscache_object_wq = alloc_workqueue("fscache_object", WQ_UNBOUND,
+                                           fscache_object_max_active);
+       if (!fscache_object_wq)
+               goto error_object_wq;
+
+       fscache_op_max_active =
+               clamp_val(fscache_object_max_active / 2,
+                         fscache_op_max_active, WQ_UNBOUND_MAX_ACTIVE);
+
+       ret = -ENOMEM;
+       fscache_op_wq = alloc_workqueue("fscache_operation", WQ_UNBOUND,
+                                       fscache_op_max_active);
+       if (!fscache_op_wq)
+               goto error_op_wq;
+
+       for_each_possible_cpu(cpu)
+               init_waitqueue_head(&per_cpu(fscache_object_cong_wait, cpu));
 
        ret = fscache_proc_init();
        if (ret < 0)
                goto error_proc;
 
+#ifdef CONFIG_SYSCTL
+       ret = -ENOMEM;
+       fscache_sysctl_header = register_sysctl_table(fscache_sysctls_root);
+       if (!fscache_sysctl_header)
+               goto error_sysctl;
+#endif
+
        fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
                                               sizeof(struct fscache_cookie),
                                               0,
@@ -78,10 +162,16 @@ static int __init fscache_init(void)
 error_kobj:
        kmem_cache_destroy(fscache_cookie_jar);
 error_cookie_jar:
+#ifdef CONFIG_SYSCTL
+       unregister_sysctl_table(fscache_sysctl_header);
+error_sysctl:
+#endif
        fscache_proc_cleanup();
 error_proc:
-       slow_work_unregister_user(THIS_MODULE);
-error_slow_work:
+       destroy_workqueue(fscache_op_wq);
+error_op_wq:
+       destroy_workqueue(fscache_object_wq);
+error_object_wq:
        return ret;
 }
 
@@ -96,8 +186,12 @@ static void __exit fscache_exit(void)
 
        kobject_put(fscache_root);
        kmem_cache_destroy(fscache_cookie_jar);
+#ifdef CONFIG_SYSCTL
+       unregister_sysctl_table(fscache_sysctl_header);
+#endif
        fscache_proc_cleanup();
-       slow_work_unregister_user(THIS_MODULE);
+       destroy_workqueue(fscache_op_wq);
+       destroy_workqueue(fscache_object_wq);
        printk(KERN_NOTICE "FS-Cache: Unloaded\n");
 }
 
index 4a8eb31c53381f74fca4a1dfad3ed0f19ef4ed3b..ebe29c58138085cb1479896771db5054c6b47bfd 100644 (file)
@@ -34,8 +34,8 @@ struct fscache_objlist_data {
 #define FSCACHE_OBJLIST_CONFIG_NOREADS 0x00000200      /* show objects without active reads */
 #define FSCACHE_OBJLIST_CONFIG_EVENTS  0x00000400      /* show objects with events */
 #define FSCACHE_OBJLIST_CONFIG_NOEVENTS        0x00000800      /* show objects without no events */
-#define FSCACHE_OBJLIST_CONFIG_WORK    0x00001000      /* show objects with slow work */
-#define FSCACHE_OBJLIST_CONFIG_NOWORK  0x00002000      /* show objects without slow work */
+#define FSCACHE_OBJLIST_CONFIG_WORK    0x00001000      /* show objects with work */
+#define FSCACHE_OBJLIST_CONFIG_NOWORK  0x00002000      /* show objects without work */
 
        u8              buf[512];       /* key and aux data buffer */
 };
@@ -231,12 +231,11 @@ static int fscache_objlist_show(struct seq_file *m, void *v)
                       READS, NOREADS);
                FILTER(obj->events & obj->event_mask,
                       EVENTS, NOEVENTS);
-               FILTER(obj->work.flags & ~(1UL << SLOW_WORK_VERY_SLOW),
-                      WORK, NOWORK);
+               FILTER(work_busy(&obj->work), WORK, NOWORK);
        }
 
        seq_printf(m,
-                  "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1lx | ",
+                  "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1x | ",
                   obj->debug_id,
                   obj->parent ? obj->parent->debug_id : -1,
                   fscache_object_states_short[obj->state],
@@ -249,7 +248,7 @@ static int fscache_objlist_show(struct seq_file *m, void *v)
                   obj->event_mask & FSCACHE_OBJECT_EVENTS_MASK,
                   obj->events,
                   obj->flags,
-                  obj->work.flags);
+                  work_busy(&obj->work));
 
        no_cookie = true;
        keylen = auxlen = 0;
index 0b589a9b4ffcf623b9b1544cff596ee24b52cbb0..b6b897c550acfea609acc9f99f0cdd2eaa90b2a3 100644 (file)
@@ -14,7 +14,6 @@
 
 #define FSCACHE_DEBUG_LEVEL COOKIE
 #include <linux/module.h>
-#include <linux/seq_file.h>
 #include "internal.h"
 
 const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
@@ -50,12 +49,8 @@ const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
        [FSCACHE_OBJECT_DEAD]           = "DEAD",
 };
 
-static void fscache_object_slow_work_put_ref(struct slow_work *);
-static int  fscache_object_slow_work_get_ref(struct slow_work *);
-static void fscache_object_slow_work_execute(struct slow_work *);
-#ifdef CONFIG_SLOW_WORK_DEBUG
-static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *);
-#endif
+static int  fscache_get_object(struct fscache_object *);
+static void fscache_put_object(struct fscache_object *);
 static void fscache_initialise_object(struct fscache_object *);
 static void fscache_lookup_object(struct fscache_object *);
 static void fscache_object_available(struct fscache_object *);
@@ -64,17 +59,6 @@ static void fscache_withdraw_object(struct fscache_object *);
 static void fscache_enqueue_dependents(struct fscache_object *);
 static void fscache_dequeue_object(struct fscache_object *);
 
-const struct slow_work_ops fscache_object_slow_work_ops = {
-       .owner          = THIS_MODULE,
-       .get_ref        = fscache_object_slow_work_get_ref,
-       .put_ref        = fscache_object_slow_work_put_ref,
-       .execute        = fscache_object_slow_work_execute,
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       .desc           = fscache_object_slow_work_desc,
-#endif
-};
-EXPORT_SYMBOL(fscache_object_slow_work_ops);
-
 /*
  * we need to notify the parent when an op completes that we had outstanding
  * upon it
@@ -345,7 +329,7 @@ unsupported_event:
 /*
  * execute an object
  */
-static void fscache_object_slow_work_execute(struct slow_work *work)
+void fscache_object_work_func(struct work_struct *work)
 {
        struct fscache_object *object =
                container_of(work, struct fscache_object, work);
@@ -359,23 +343,9 @@ static void fscache_object_slow_work_execute(struct slow_work *work)
        if (object->events & object->event_mask)
                fscache_enqueue_object(object);
        clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+       fscache_put_object(object);
 }
-
-/*
- * describe an object for slow-work debugging
- */
-#ifdef CONFIG_SLOW_WORK_DEBUG
-static void fscache_object_slow_work_desc(struct slow_work *work,
-                                         struct seq_file *m)
-{
-       struct fscache_object *object =
-               container_of(work, struct fscache_object, work);
-
-       seq_printf(m, "FSC: OBJ%x: %s",
-                  object->debug_id,
-                  fscache_object_states_short[object->state]);
-}
-#endif
+EXPORT_SYMBOL(fscache_object_work_func);
 
 /*
  * initialise an object
@@ -393,7 +363,6 @@ static void fscache_initialise_object(struct fscache_object *object)
        _enter("");
        ASSERT(object->cookie != NULL);
        ASSERT(object->cookie->parent != NULL);
-       ASSERT(list_empty(&object->work.link));
 
        if (object->events & ((1 << FSCACHE_OBJECT_EV_ERROR) |
                              (1 << FSCACHE_OBJECT_EV_RELEASE) |
@@ -671,10 +640,8 @@ static void fscache_drop_object(struct fscache_object *object)
                object->parent = NULL;
        }
 
-       /* this just shifts the object release to the slow work processor */
-       fscache_stat(&fscache_n_cop_put_object);
-       object->cache->ops->put_object(object);
-       fscache_stat_d(&fscache_n_cop_put_object);
+       /* this just shifts the object release to the work processor */
+       fscache_put_object(object);
 
        _leave("");
 }
@@ -758,12 +725,10 @@ void fscache_withdrawing_object(struct fscache_cache *cache,
 }
 
 /*
- * allow the slow work item processor to get a ref on an object
+ * get a ref on an object
  */
-static int fscache_object_slow_work_get_ref(struct slow_work *work)
+static int fscache_get_object(struct fscache_object *object)
 {
-       struct fscache_object *object =
-               container_of(work, struct fscache_object, work);
        int ret;
 
        fscache_stat(&fscache_n_cop_grab_object);
@@ -773,13 +738,10 @@ static int fscache_object_slow_work_get_ref(struct slow_work *work)
 }
 
 /*
- * allow the slow work item processor to discard a ref on a work item
+ * discard a ref on a work item
  */
-static void fscache_object_slow_work_put_ref(struct slow_work *work)
+static void fscache_put_object(struct fscache_object *object)
 {
-       struct fscache_object *object =
-               container_of(work, struct fscache_object, work);
-
        fscache_stat(&fscache_n_cop_put_object);
        object->cache->ops->put_object(object);
        fscache_stat_d(&fscache_n_cop_put_object);
@@ -792,8 +754,48 @@ void fscache_enqueue_object(struct fscache_object *object)
 {
        _enter("{OBJ%x}", object->debug_id);
 
-       slow_work_enqueue(&object->work);
+       if (fscache_get_object(object) >= 0) {
+               wait_queue_head_t *cong_wq =
+                       &get_cpu_var(fscache_object_cong_wait);
+
+               if (queue_work(fscache_object_wq, &object->work)) {
+                       if (fscache_object_congested())
+                               wake_up(cong_wq);
+               } else
+                       fscache_put_object(object);
+
+               put_cpu_var(fscache_object_cong_wait);
+       }
+}
+
+/**
+ * fscache_object_sleep_till_congested - Sleep until object wq is congested
+ * @timoutp: Scheduler sleep timeout
+ *
+ * Allow an object handler to sleep until the object workqueue is congested.
+ *
+ * The caller must set up a wake up event before calling this and must have set
+ * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own
+ * condition before calling this function as no test is made here.
+ *
+ * %true is returned if the object wq is congested, %false otherwise.
+ */
+bool fscache_object_sleep_till_congested(signed long *timeoutp)
+{
+       wait_queue_head_t *cong_wq = &__get_cpu_var(fscache_object_cong_wait);
+       DEFINE_WAIT(wait);
+
+       if (fscache_object_congested())
+               return true;
+
+       add_wait_queue_exclusive(cong_wq, &wait);
+       if (!fscache_object_congested())
+               *timeoutp = schedule_timeout(*timeoutp);
+       finish_wait(cong_wq, &wait);
+
+       return fscache_object_congested();
 }
+EXPORT_SYMBOL_GPL(fscache_object_sleep_till_congested);
 
 /*
  * enqueue the dependents of an object for metadata-type processing
@@ -819,9 +821,7 @@ static void fscache_enqueue_dependents(struct fscache_object *object)
 
                /* sort onto appropriate lists */
                fscache_enqueue_object(dep);
-               fscache_stat(&fscache_n_cop_put_object);
-               dep->cache->ops->put_object(dep);
-               fscache_stat_d(&fscache_n_cop_put_object);
+               fscache_put_object(dep);
 
                if (!list_empty(&object->dependents))
                        cond_resched_lock(&object->lock);
index f17cecafae44c1a49665c7e0b865c98693d61f89..b9f34eaede09a95a24723e0a0f79151065c03fb9 100644 (file)
@@ -42,16 +42,12 @@ void fscache_enqueue_operation(struct fscache_operation *op)
 
        fscache_stat(&fscache_n_op_enqueue);
        switch (op->flags & FSCACHE_OP_TYPE) {
-       case FSCACHE_OP_FAST:
-               _debug("queue fast");
+       case FSCACHE_OP_ASYNC:
+               _debug("queue async");
                atomic_inc(&op->usage);
-               if (!schedule_work(&op->fast_work))
+               if (!queue_work(fscache_op_wq, &op->work))
                        fscache_put_operation(op);
                break;
-       case FSCACHE_OP_SLOW:
-               _debug("queue slow");
-               slow_work_enqueue(&op->slow_work);
-               break;
        case FSCACHE_OP_MYTHREAD:
                _debug("queue for caller's attention");
                break;
@@ -455,36 +451,13 @@ void fscache_operation_gc(struct work_struct *work)
 }
 
 /*
- * allow the slow work item processor to get a ref on an operation
- */
-static int fscache_op_get_ref(struct slow_work *work)
-{
-       struct fscache_operation *op =
-               container_of(work, struct fscache_operation, slow_work);
-
-       atomic_inc(&op->usage);
-       return 0;
-}
-
-/*
- * allow the slow work item processor to discard a ref on an operation
- */
-static void fscache_op_put_ref(struct slow_work *work)
-{
-       struct fscache_operation *op =
-               container_of(work, struct fscache_operation, slow_work);
-
-       fscache_put_operation(op);
-}
-
-/*
- * execute an operation using the slow thread pool to provide processing context
- * - the caller holds a ref to this object, so we don't need to hold one
+ * execute an operation using fs_op_wq to provide processing context -
+ * the caller holds a ref to this object, so we don't need to hold one
  */
-static void fscache_op_execute(struct slow_work *work)
+void fscache_op_work_func(struct work_struct *work)
 {
        struct fscache_operation *op =
-               container_of(work, struct fscache_operation, slow_work);
+               container_of(work, struct fscache_operation, work);
        unsigned long start;
 
        _enter("{OBJ%x OP%x,%d}",
@@ -494,31 +467,7 @@ static void fscache_op_execute(struct slow_work *work)
        start = jiffies;
        op->processor(op);
        fscache_hist(fscache_ops_histogram, start);
+       fscache_put_operation(op);
 
        _leave("");
 }
-
-/*
- * describe an operation for slow-work debugging
- */
-#ifdef CONFIG_SLOW_WORK_DEBUG
-static void fscache_op_desc(struct slow_work *work, struct seq_file *m)
-{
-       struct fscache_operation *op =
-               container_of(work, struct fscache_operation, slow_work);
-
-       seq_printf(m, "FSC: OBJ%x OP%x: %s/%s fl=%lx",
-                  op->object->debug_id, op->debug_id,
-                  op->name, op->state, op->flags);
-}
-#endif
-
-const struct slow_work_ops fscache_op_slow_work_ops = {
-       .owner          = THIS_MODULE,
-       .get_ref        = fscache_op_get_ref,
-       .put_ref        = fscache_op_put_ref,
-       .execute        = fscache_op_execute,
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       .desc           = fscache_op_desc,
-#endif
-};
index 723b889fd219f5eb6a6f360b807ac8e45881f00a..41c441c2058daad798aff3766cb5444c9961b44a 100644 (file)
@@ -105,7 +105,7 @@ bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
 
 page_busy:
        /* we might want to wait here, but that could deadlock the allocator as
-        * the slow-work threads writing to the cache may all end up sleeping
+        * the work threads writing to the cache may all end up sleeping
         * on memory allocation */
        fscache_stat(&fscache_n_store_vmscan_busy);
        return false;
@@ -188,9 +188,8 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
                return -ENOMEM;
        }
 
-       fscache_operation_init(op, NULL);
-       fscache_operation_init_slow(op, fscache_attr_changed_op);
-       op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE);
+       fscache_operation_init(op, fscache_attr_changed_op, NULL);
+       op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE);
        fscache_set_op_name(op, "Attr");
 
        spin_lock(&cookie->lock);
@@ -217,24 +216,6 @@ nobufs:
 }
 EXPORT_SYMBOL(__fscache_attr_changed);
 
-/*
- * handle secondary execution given to a retrieval op on behalf of the
- * cache
- */
-static void fscache_retrieval_work(struct work_struct *work)
-{
-       struct fscache_retrieval *op =
-               container_of(work, struct fscache_retrieval, op.fast_work);
-       unsigned long start;
-
-       _enter("{OP%x}", op->op.debug_id);
-
-       start = jiffies;
-       op->op.processor(&op->op);
-       fscache_hist(fscache_ops_histogram, start);
-       fscache_put_operation(&op->op);
-}
-
 /*
  * release a retrieval op reference
  */
@@ -269,13 +250,12 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
                return NULL;
        }
 
-       fscache_operation_init(&op->op, fscache_release_retrieval_op);
+       fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op);
        op->op.flags    = FSCACHE_OP_MYTHREAD | (1 << FSCACHE_OP_WAITING);
        op->mapping     = mapping;
        op->end_io_func = end_io_func;
        op->context     = context;
        op->start_time  = jiffies;
-       INIT_WORK(&op->op.fast_work, fscache_retrieval_work);
        INIT_LIST_HEAD(&op->to_do);
        fscache_set_op_name(&op->op, "Retr");
        return op;
@@ -795,9 +775,9 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        if (!op)
                goto nomem;
 
-       fscache_operation_init(&op->op, fscache_release_write_op);
-       fscache_operation_init_slow(&op->op, fscache_write_op);
-       op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING);
+       fscache_operation_init(&op->op, fscache_write_op,
+                              fscache_release_write_op);
+       op->op.flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_WAITING);
        fscache_set_op_name(&op->op, "Write1");
 
        ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
@@ -852,7 +832,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        fscache_stat(&fscache_n_store_ops);
        fscache_stat(&fscache_n_stores_ok);
 
-       /* the slow work queue now carries its own ref on the object */
+       /* the work queue now carries its own ref on the object */
        fscache_put_operation(&op->op);
        _leave(" = 0");
        return 0;
index a47b4310711201889a2e0ff84b4f004fdf3e1850..cc9665522148a730b010953596cc24edefc00ed6 100644 (file)
@@ -7,7 +7,6 @@ config GFS2_FS
        select IP_SCTP if DLM_SCTP
        select FS_POSIX_ACL
        select CRC32
-       select SLOW_WORK
        select QUOTACTL
        help
          A cluster filesystem.
index 8fcbce48a128af6414b98afe7f3d48f83dd84ef8..fdbf4b366fa540d295dcbd73b298099b50418f8c 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/fs.h>
 #include <linux/workqueue.h>
-#include <linux/slow-work.h>
 #include <linux/dlm.h>
 #include <linux/buffer_head.h>
 
@@ -383,7 +382,7 @@ struct gfs2_journal_extent {
 struct gfs2_jdesc {
        struct list_head jd_list;
        struct list_head extent_list;
-       struct slow_work jd_work;
+       struct work_struct jd_work;
        struct inode *jd_inode;
        unsigned long jd_flags;
 #define JDF_RECOVERY 1
index fb2a5f93b7c3bf088f1a1c10556fd99cf56da4e5..b1e9630eb46a8d0338fef57ffa15caf23ab1cf0f 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/gfs2_ondisk.h>
 #include <asm/atomic.h>
-#include <linux/slow-work.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -24,6 +23,7 @@
 #include "util.h"
 #include "glock.h"
 #include "quota.h"
+#include "recovery.h"
 
 static struct shrinker qd_shrinker = {
        .shrink = gfs2_shrink_qd_memory,
@@ -138,9 +138,11 @@ static int __init init_gfs2_fs(void)
        if (error)
                goto fail_unregister;
 
-       error = slow_work_register_user(THIS_MODULE);
-       if (error)
-               goto fail_slow;
+       error = -ENOMEM;
+       gfs_recovery_wq = alloc_workqueue("gfs_recovery",
+                                         WQ_NON_REENTRANT | WQ_RESCUER, 0);
+       if (!gfs_recovery_wq)
+               goto fail_wq;
 
        gfs2_register_debugfs();
 
@@ -148,7 +150,7 @@ static int __init init_gfs2_fs(void)
 
        return 0;
 
-fail_slow:
+fail_wq:
        unregister_filesystem(&gfs2meta_fs_type);
 fail_unregister:
        unregister_filesystem(&gfs2_fs_type);
@@ -190,7 +192,7 @@ static void __exit exit_gfs2_fs(void)
        gfs2_unregister_debugfs();
        unregister_filesystem(&gfs2_fs_type);
        unregister_filesystem(&gfs2meta_fs_type);
-       slow_work_unregister_user(THIS_MODULE);
+       destroy_workqueue(gfs_recovery_wq);
 
        kmem_cache_destroy(gfs2_quotad_cachep);
        kmem_cache_destroy(gfs2_rgrpd_cachep);
index 45a4a36195d87d0819958399c56601d6702d58c1..4f44bdeb2f0321a204421171fd018d4c0c2b5f4e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/gfs2_ondisk.h>
-#include <linux/slow-work.h>
 #include <linux/quotaops.h>
 
 #include "gfs2.h"
@@ -673,7 +672,7 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
                        break;
 
                INIT_LIST_HEAD(&jd->extent_list);
-               slow_work_init(&jd->jd_work, &gfs2_recover_ops);
+               INIT_WORK(&jd->jd_work, gfs2_recover_func);
                jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1);
                if (!jd->jd_inode || IS_ERR(jd->jd_inode)) {
                        if (!jd->jd_inode)
@@ -782,7 +781,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
        if (sdp->sd_lockstruct.ls_first) {
                unsigned int x;
                for (x = 0; x < sdp->sd_journals; x++) {
-                       error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x));
+                       error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x),
+                                                    true);
                        if (error) {
                                fs_err(sdp, "error recovering journal %u: %d\n",
                                       x, error);
@@ -792,7 +792,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
 
                gfs2_others_may_mount(sdp);
        } else if (!sdp->sd_args.ar_spectator) {
-               error = gfs2_recover_journal(sdp->sd_jdesc);
+               error = gfs2_recover_journal(sdp->sd_jdesc, true);
                if (error) {
                        fs_err(sdp, "error recovering my journal: %d\n", error);
                        goto fail_jinode_gh;
index 4b9bece3d4372e323135156bd029d94877da5949..f7f89a94a5a4598a4b532016a0c16846a62cef2b 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/buffer_head.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/crc32.h>
-#include <linux/slow-work.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -28,6 +27,8 @@
 #include "util.h"
 #include "dir.h"
 
+struct workqueue_struct *gfs_recovery_wq;
+
 int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
                           struct buffer_head **bh)
 {
@@ -443,23 +444,7 @@ static void gfs2_recovery_done(struct gfs2_sbd *sdp, unsigned int jid,
         kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp);
 }
 
-static int gfs2_recover_get_ref(struct slow_work *work)
-{
-       struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work);
-       if (test_and_set_bit(JDF_RECOVERY, &jd->jd_flags))
-               return -EBUSY;
-       return 0;
-}
-
-static void gfs2_recover_put_ref(struct slow_work *work)
-{
-       struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work);
-       clear_bit(JDF_RECOVERY, &jd->jd_flags);
-       smp_mb__after_clear_bit();
-       wake_up_bit(&jd->jd_flags, JDF_RECOVERY);
-}
-
-static void gfs2_recover_work(struct slow_work *work)
+void gfs2_recover_func(struct work_struct *work)
 {
        struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work);
        struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
@@ -578,7 +563,7 @@ static void gfs2_recover_work(struct slow_work *work)
                gfs2_glock_dq_uninit(&j_gh);
 
        fs_info(sdp, "jid=%u: Done\n", jd->jd_jid);
-       return;
+       goto done;
 
 fail_gunlock_tr:
        gfs2_glock_dq_uninit(&t_gh);
@@ -590,32 +575,35 @@ fail_gunlock_j:
        }
 
        fs_info(sdp, "jid=%u: %s\n", jd->jd_jid, (error) ? "Failed" : "Done");
-
 fail:
        gfs2_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP);
+done:
+       clear_bit(JDF_RECOVERY, &jd->jd_flags);
+       smp_mb__after_clear_bit();
+       wake_up_bit(&jd->jd_flags, JDF_RECOVERY);
 }
 
-struct slow_work_ops gfs2_recover_ops = {
-       .owner   = THIS_MODULE,
-       .get_ref = gfs2_recover_get_ref,
-       .put_ref = gfs2_recover_put_ref,
-       .execute = gfs2_recover_work,
-};
-
-
 static int gfs2_recovery_wait(void *word)
 {
        schedule();
        return 0;
 }
 
-int gfs2_recover_journal(struct gfs2_jdesc *jd)
+int gfs2_recover_journal(struct gfs2_jdesc *jd, bool wait)
 {
        int rv;
-       rv = slow_work_enqueue(&jd->jd_work);
-       if (rv)
-               return rv;
-       wait_on_bit(&jd->jd_flags, JDF_RECOVERY, gfs2_recovery_wait, TASK_UNINTERRUPTIBLE);
+
+       if (test_and_set_bit(JDF_RECOVERY, &jd->jd_flags))
+               return -EBUSY;
+
+       /* we have JDF_RECOVERY, queue should always succeed */
+       rv = queue_work(gfs_recovery_wq, &jd->jd_work);
+       BUG_ON(!rv);
+
+       if (wait)
+               wait_on_bit(&jd->jd_flags, JDF_RECOVERY, gfs2_recovery_wait,
+                           TASK_UNINTERRUPTIBLE);
+
        return 0;
 }
 
index 1616ac22569a940726c6123ef349ca8e157633d0..2226136c7647372c2e2a80fc20ebf439a8809dcf 100644 (file)
@@ -12,6 +12,8 @@
 
 #include "incore.h"
 
+extern struct workqueue_struct *gfs_recovery_wq;
+
 static inline void gfs2_replay_incr_blk(struct gfs2_sbd *sdp, unsigned int *blk)
 {
        if (++*blk == sdp->sd_jdesc->jd_blocks)
@@ -27,8 +29,8 @@ extern void gfs2_revoke_clean(struct gfs2_sbd *sdp);
 
 extern int gfs2_find_jhead(struct gfs2_jdesc *jd,
                    struct gfs2_log_header_host *head);
-extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd);
-extern struct slow_work_ops gfs2_recover_ops;
+extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, bool wait);
+extern void gfs2_recover_func(struct work_struct *work);
 
 #endif /* __RECOVERY_DOT_H__ */
 
index d019d0d55e00eb6a79f5cc24abfaabb2ebcd71d6..ccacffd2faaa6d65d1f116b9b2788ee732786f3f 100644 (file)
@@ -25,6 +25,7 @@
 #include "quota.h"
 #include "util.h"
 #include "glops.h"
+#include "recovery.h"
 
 struct gfs2_attr {
        struct attribute attr;
@@ -376,7 +377,7 @@ static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
        list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
                if (jd->jd_jid != jid)
                        continue;
-               rv = slow_work_enqueue(&jd->jd_work);
+               rv = gfs2_recover_journal(jd, false);
                break;
        }
 out:
index 5dcd4b0c5533346e360f12bc6c62c510a0722d28..72c52656dc2e7a00fd2f05b072002fe88302afe9 100644 (file)
@@ -459,7 +459,6 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
        }
 
        /* everything is up and running, commence */
-       INIT_RCU_HEAD(&p->rcu_head);
        rcu_assign_pointer(ptbl->part[partno], p);
 
        /* suppress uevent if the disk supresses it */
index 1beaa739d0a6399c43ac28f8b986d2aaa544972c..1b27b5688f62fdfd8abd40386c6e1ece7aa1bf49 100644 (file)
@@ -593,7 +593,8 @@ EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
  * @mode: file permissions.
  *
  */
-int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
+int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
+                    mode_t mode)
 {
        struct sysfs_dirent *sd;
        struct iattr newattrs;
index 4f3d75e1ad391a669d842c7c58e65b46bfd9cbd4..c7376bf80b0604bf8f8b9394989178d6de45ecc2 100644 (file)
@@ -31,6 +31,7 @@ static inline int gpio_is_valid(int number)
 struct device;
 struct seq_file;
 struct module;
+struct device_node;
 
 /**
  * struct gpio_chip - abstract a GPIO controller
@@ -106,6 +107,17 @@ struct gpio_chip {
        const char              *const *names;
        unsigned                can_sleep:1;
        unsigned                exported:1;
+
+#if defined(CONFIG_OF_GPIO)
+       /*
+        * If CONFIG_OF is enabled, then all GPIO controllers described in the
+        * device tree automatically may have an OF translation
+        */
+       struct device_node *of_node;
+       int of_gpio_n_cells;
+       int (*of_xlate)(struct gpio_chip *gc, struct device_node *np,
+                       const void *gpio_spec, u32 *flags);
+#endif
 };
 
 extern const char *gpiochip_is_requested(struct gpio_chip *chip,
@@ -115,6 +127,9 @@ extern int __must_check gpiochip_reserve(int start, int ngpio);
 /* add/remove chips */
 extern int gpiochip_add(struct gpio_chip *chip);
 extern int __must_check gpiochip_remove(struct gpio_chip *chip);
+extern struct gpio_chip *gpiochip_find(void *data,
+                                       int (*match)(struct gpio_chip *chip,
+                                                    void *data));
 
 
 /* Always use the library code for GPIO management calls,
diff --git a/include/asm-generic/local64.h b/include/asm-generic/local64.h
new file mode 100644 (file)
index 0000000..02ac760
--- /dev/null
@@ -0,0 +1,96 @@
+#ifndef _ASM_GENERIC_LOCAL64_H
+#define _ASM_GENERIC_LOCAL64_H
+
+#include <linux/percpu.h>
+#include <asm/types.h>
+
+/*
+ * A signed long type for operations which are atomic for a single CPU.
+ * Usually used in combination with per-cpu variables.
+ *
+ * This is the default implementation, which uses atomic64_t.  Which is
+ * rather pointless.  The whole point behind local64_t is that some processors
+ * can perform atomic adds and subtracts in a manner which is atomic wrt IRQs
+ * running on this CPU.  local64_t allows exploitation of such capabilities.
+ */
+
+/* Implement in terms of atomics. */
+
+#if BITS_PER_LONG == 64
+
+#include <asm/local.h>
+
+typedef struct {
+       local_t a;
+} local64_t;
+
+#define LOCAL64_INIT(i)        { LOCAL_INIT(i) }
+
+#define local64_read(l)                local_read(&(l)->a)
+#define local64_set(l,i)       local_set((&(l)->a),(i))
+#define local64_inc(l)         local_inc(&(l)->a)
+#define local64_dec(l)         local_dec(&(l)->a)
+#define local64_add(i,l)       local_add((i),(&(l)->a))
+#define local64_sub(i,l)       local_sub((i),(&(l)->a))
+
+#define local64_sub_and_test(i, l) local_sub_and_test((i), (&(l)->a))
+#define local64_dec_and_test(l) local_dec_and_test(&(l)->a)
+#define local64_inc_and_test(l) local_inc_and_test(&(l)->a)
+#define local64_add_negative(i, l) local_add_negative((i), (&(l)->a))
+#define local64_add_return(i, l) local_add_return((i), (&(l)->a))
+#define local64_sub_return(i, l) local_sub_return((i), (&(l)->a))
+#define local64_inc_return(l)  local_inc_return(&(l)->a)
+
+#define local64_cmpxchg(l, o, n) local_cmpxchg((&(l)->a), (o), (n))
+#define local64_xchg(l, n)     local_xchg((&(l)->a), (n))
+#define local64_add_unless(l, _a, u) local_add_unless((&(l)->a), (_a), (u))
+#define local64_inc_not_zero(l)        local_inc_not_zero(&(l)->a)
+
+/* Non-atomic variants, ie. preemption disabled and won't be touched
+ * in interrupt, etc.  Some archs can optimize this case well. */
+#define __local64_inc(l)       local64_set((l), local64_read(l) + 1)
+#define __local64_dec(l)       local64_set((l), local64_read(l) - 1)
+#define __local64_add(i,l)     local64_set((l), local64_read(l) + (i))
+#define __local64_sub(i,l)     local64_set((l), local64_read(l) - (i))
+
+#else /* BITS_PER_LONG != 64 */
+
+#include <asm/atomic.h>
+
+/* Don't use typedef: don't want them to be mixed with atomic_t's. */
+typedef struct {
+       atomic64_t a;
+} local64_t;
+
+#define LOCAL64_INIT(i)        { ATOMIC_LONG_INIT(i) }
+
+#define local64_read(l)                atomic64_read(&(l)->a)
+#define local64_set(l,i)       atomic64_set((&(l)->a),(i))
+#define local64_inc(l)         atomic64_inc(&(l)->a)
+#define local64_dec(l)         atomic64_dec(&(l)->a)
+#define local64_add(i,l)       atomic64_add((i),(&(l)->a))
+#define local64_sub(i,l)       atomic64_sub((i),(&(l)->a))
+
+#define local64_sub_and_test(i, l) atomic64_sub_and_test((i), (&(l)->a))
+#define local64_dec_and_test(l) atomic64_dec_and_test(&(l)->a)
+#define local64_inc_and_test(l) atomic64_inc_and_test(&(l)->a)
+#define local64_add_negative(i, l) atomic64_add_negative((i), (&(l)->a))
+#define local64_add_return(i, l) atomic64_add_return((i), (&(l)->a))
+#define local64_sub_return(i, l) atomic64_sub_return((i), (&(l)->a))
+#define local64_inc_return(l)  atomic64_inc_return(&(l)->a)
+
+#define local64_cmpxchg(l, o, n) atomic64_cmpxchg((&(l)->a), (o), (n))
+#define local64_xchg(l, n)     atomic64_xchg((&(l)->a), (n))
+#define local64_add_unless(l, _a, u) atomic64_add_unless((&(l)->a), (_a), (u))
+#define local64_inc_not_zero(l)        atomic64_inc_not_zero(&(l)->a)
+
+/* Non-atomic variants, ie. preemption disabled and won't be touched
+ * in interrupt, etc.  Some archs can optimize this case well. */
+#define __local64_inc(l)       local64_set((l), local64_read(l) + 1)
+#define __local64_dec(l)       local64_set((l), local64_read(l) - 1)
+#define __local64_add(i,l)     local64_set((l), local64_read(l) + (i))
+#define __local64_sub(i,l)     local64_set((l), local64_read(l) - (i))
+
+#endif /* BITS_PER_LONG != 64 */
+
+#endif /* _ASM_GENERIC_LOCAL64_H */
index 030a954ed292a59feae0bbf8437f370127b22bd6..8a92a170fb7dfd87710bb26b3c7f384dd6801363 100644 (file)
        CPU_KEEP(exit.data)                                             \
        MEM_KEEP(init.data)                                             \
        MEM_KEEP(exit.data)                                             \
-       . = ALIGN(8);                                                   \
-       VMLINUX_SYMBOL(__start___markers) = .;                          \
-       *(__markers)                                                    \
-       VMLINUX_SYMBOL(__stop___markers) = .;                           \
        . = ALIGN(32);                                                  \
        VMLINUX_SYMBOL(__start___tracepoints) = .;                      \
        *(__tracepoints)                                                \
        EXIT_DATA                                                       \
        EXIT_CALL                                                       \
        *(.discard)                                                     \
+       *(.discard.*)                                                   \
        }
 
 /**
index e3f46e0cb7dc305f8ab0b9ea7af3f96deb3bba0d..e5f70617dec55db8b8671c5d6c4444a23a698837 100644 (file)
@@ -663,6 +663,8 @@ struct drm_gem_open {
 #define DRM_IOCTL_UNLOCK               DRM_IOW( 0x2b, struct drm_lock)
 #define DRM_IOCTL_FINISH               DRM_IOW( 0x2c, struct drm_lock)
 
+#define DRM_IOCTL_GEM_PRIME_OPEN        DRM_IOWR(0x2e, struct drm_gem_open)
+
 #define DRM_IOCTL_AGP_ACQUIRE          DRM_IO(  0x30)
 #define DRM_IOCTL_AGP_RELEASE          DRM_IO(  0x31)
 #define DRM_IOCTL_AGP_ENABLE           DRM_IOW( 0x32, struct drm_agp_mode)
index c1b987158dfa20c19285e59533c40b2aa5ebb0b2..e2a4da7d7fab121215d39b7eb0058f7a159311e3 100644 (file)
@@ -9,6 +9,7 @@
 /*
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * Copyright (c) 2009-2010, Code Aurora Forum.
  * All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -48,9 +49,9 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/file.h>
+#include <linux/platform_device.h>
 #include <linux/pci.h>
 #include <linux/jiffies.h>
-#include <linux/smp_lock.h>    /* For (un)lock_kernel */
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/cdev.h>
@@ -144,6 +145,7 @@ extern void drm_ut_debug_printk(unsigned int request_level,
 #define DRIVER_IRQ_VBL2    0x800
 #define DRIVER_GEM         0x1000
 #define DRIVER_MODESET     0x2000
+#define DRIVER_USE_PLATFORM_DEVICE  0x4000
 
 /***********************************************************************/
 /** \name Begin the DRM... */
@@ -403,6 +405,8 @@ struct drm_pending_event {
        struct drm_event *event;
        struct list_head link;
        struct drm_file *file_priv;
+       pid_t pid; /* pid of requester, no guarantee it's valid by the time
+                     we deliver the event, for tracing only */
        void (*destroy)(struct drm_pending_event *event);
 };
 
@@ -823,6 +827,7 @@ struct drm_driver {
        int num_ioctls;
        struct file_operations fops;
        struct pci_driver pci_driver;
+       struct platform_device *platform_device;
        /* List of devices hanging off this driver */
        struct list_head device_list;
 };
@@ -1015,12 +1020,16 @@ struct drm_device {
 
        struct drm_agp_head *agp;       /**< AGP data */
 
+       struct device *dev;             /**< Device structure */
        struct pci_dev *pdev;           /**< PCI device structure */
        int pci_vendor;                 /**< PCI vendor id */
        int pci_device;                 /**< PCI device id */
 #ifdef __alpha__
        struct pci_controller *hose;
 #endif
+
+       struct platform_device *platformdev; /**< Platform device struture */
+
        struct drm_sg_mem *sg;  /**< Scatter gather memory */
        int num_crtcs;                  /**< Number of CRTCs on this device */
        void *dev_private;              /**< device private data */
@@ -1060,17 +1069,21 @@ struct drm_device {
 
 };
 
-static inline int drm_dev_to_irq(struct drm_device *dev)
-{
-       return dev->pdev->irq;
-}
-
 static __inline__ int drm_core_check_feature(struct drm_device *dev,
                                             int feature)
 {
        return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
+
+static inline int drm_dev_to_irq(struct drm_device *dev)
+{
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return platform_get_irq(dev->platformdev, 0);
+       else
+               return dev->pdev->irq;
+}
+
 #ifdef __alpha__
 #define drm_get_pci_domain(dev) dev->hose->index
 #else
@@ -1138,6 +1151,7 @@ extern long drm_compat_ioctl(struct file *filp,
 extern int drm_lastclose(struct drm_device *dev);
 
                                /* Device support (drm_fops.h) */
+extern struct mutex drm_global_mutex;
 extern int drm_open(struct inode *inode, struct file *filp);
 extern int drm_stub_open(struct inode *inode, struct file *filp);
 extern int drm_fasync(int fd, struct file *filp, int on);
@@ -1273,10 +1287,6 @@ extern int drm_freebufs(struct drm_device *dev, void *data,
 extern int drm_mapbufs(struct drm_device *dev, void *data,
                       struct drm_file *file_priv);
 extern int drm_order(unsigned long size);
-extern resource_size_t drm_get_resource_start(struct drm_device *dev,
-                                             unsigned int resource);
-extern resource_size_t drm_get_resource_len(struct drm_device *dev,
-                                           unsigned int resource);
 
                                /* DMA support (drm_dma.h) */
 extern int drm_dma_setup(struct drm_device *dev);
@@ -1351,8 +1361,11 @@ extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 struct drm_master *drm_master_create(struct drm_minor *minor);
 extern struct drm_master *drm_master_get(struct drm_master *master);
 extern void drm_master_put(struct drm_master **master);
-extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
-                      struct drm_driver *driver);
+extern int drm_get_pci_dev(struct pci_dev *pdev,
+                          const struct pci_device_id *ent,
+                          struct drm_driver *driver);
+extern int drm_get_platform_dev(struct platform_device *pdev,
+                               struct drm_driver *driver);
 extern void drm_put_dev(struct drm_device *dev);
 extern int drm_put_minor(struct drm_minor **minor);
 extern unsigned int drm_debug;
@@ -1440,6 +1453,8 @@ void drm_gem_vm_open(struct vm_area_struct *vma);
 void drm_gem_vm_close(struct vm_area_struct *vma);
 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 
+#include "drm_global.h"
+
 static inline void
 drm_gem_object_reference(struct drm_gem_object *obj)
 {
@@ -1529,6 +1544,9 @@ static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev,
 
 static __inline__ int drm_device_is_agp(struct drm_device *dev)
 {
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return 0;
+
        if (dev->driver->device_is_agp != NULL) {
                int err = (*dev->driver->device_is_agp) (dev);
 
@@ -1542,7 +1560,10 @@ static __inline__ int drm_device_is_agp(struct drm_device *dev)
 
 static __inline__ int drm_device_is_pcie(struct drm_device *dev)
 {
-       return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return 0;
+       else
+               return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
 }
 
 static __inline__ void drm_core_dropmap(struct drm_local_map *map)
@@ -1550,6 +1571,21 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
 }
 
 #include "drm_mem_util.h"
+
+static inline void *drm_get_device(struct drm_device *dev)
+{
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return dev->platformdev;
+       else
+               return dev->pdev;
+}
+
+extern int drm_platform_init(struct drm_driver *driver);
+extern int drm_pci_init(struct drm_driver *driver);
+extern int drm_fill_in_dev(struct drm_device *dev,
+                          const struct pci_device_id *ent,
+                          struct drm_driver *driver);
+int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type);
 /*@}*/
 
 #endif                         /* __KERNEL__ */
index 93a1a31b9c2d4020bc1c9600704a400ae4a48893..c707270bff5afef28538471ef1ee39feb9d5ce31 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/idr.h>
 
 #include <linux/fb.h>
-#include <linux/slow-work.h>
 
 struct drm_device;
 struct drm_mode_set;
@@ -595,7 +594,7 @@ struct drm_mode_config {
 
        /* output poll support */
        bool poll_enabled;
-       struct delayed_slow_work output_poll_slow_work;
+       struct delayed_work output_poll_work;
 
        /* pointers to standard properties */
        struct list_head property_blob_list;
index 1121f7799c6ff527838ec50052d51bc10b10e2e7..59b7073b13fe334815fc3dd290b49e73c4e162d4 100644 (file)
@@ -60,9 +60,14 @@ struct drm_crtc_helper_funcs {
        /* Move the crtc on the current fb to the given position *optional* */
        int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
                             struct drm_framebuffer *old_fb);
+       int (*mode_set_base_atomic)(struct drm_crtc *crtc,
+                                   struct drm_framebuffer *fb, int x, int y);
 
        /* reload the current crtc LUT */
        void (*load_lut)(struct drm_crtc *crtc);
+
+       /* disable crtc when not in use - more explicit than dpms off */
+       void (*disable)(struct drm_crtc *crtc);
 };
 
 struct drm_encoder_helper_funcs {
index f0a6afc47e761a9aba1507d16a7d80feab95e741..f22e7fe4b6dbf25815580ad3625fd09f5aed3946 100644 (file)
@@ -32,6 +32,8 @@
 
 struct drm_fb_helper;
 
+#include <linux/kgdb.h>
+
 struct drm_fb_helper_crtc {
        uint32_t crtc_id;
        struct drm_mode_set mode_set;
@@ -78,6 +80,7 @@ struct drm_fb_helper_connector {
 
 struct drm_fb_helper {
        struct drm_framebuffer *fb;
+       struct drm_framebuffer *saved_fb;
        struct drm_device *dev;
        struct drm_display_mode *mode;
        int crtc_count;
@@ -126,5 +129,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
 bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
 bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
 int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
+int drm_fb_helper_debug_enter(struct fb_info *info);
+int drm_fb_helper_debug_leave(struct fb_info *info);
 
 #endif
diff --git a/include/drm/drm_global.h b/include/drm/drm_global.h
new file mode 100644 (file)
index 0000000..a06805e
--- /dev/null
@@ -0,0 +1,53 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#ifndef _DRM_GLOBAL_H_
+#define _DRM_GLOBAL_H_
+enum drm_global_types {
+       DRM_GLOBAL_TTM_MEM = 0,
+       DRM_GLOBAL_TTM_BO,
+       DRM_GLOBAL_TTM_OBJECT,
+       DRM_GLOBAL_NUM
+};
+
+struct drm_global_reference {
+       enum drm_global_types global_type;
+       size_t size;
+       void *object;
+       int (*init) (struct drm_global_reference *);
+       void (*release) (struct drm_global_reference *);
+};
+
+extern void drm_global_init(void);
+extern void drm_global_release(void);
+extern int drm_global_item_ref(struct drm_global_reference *ref);
+extern void drm_global_item_unref(struct drm_global_reference *ref);
+
+#endif
index 4c10be39a43bd94d7568fbb41bf3cc8d15fac95f..bf01531193d530640bbdedb69c86d49d14c81ea0 100644 (file)
 #endif
 
 struct drm_mm_node {
-       struct list_head fl_entry;
-       struct list_head ml_entry;
-       int free;
+       struct list_head free_stack;
+       struct list_head node_list;
+       unsigned free : 1;
+       unsigned scanned_block : 1;
+       unsigned scanned_prev_free : 1;
+       unsigned scanned_next_free : 1;
        unsigned long start;
        unsigned long size;
        struct drm_mm *mm;
-       void *private;
 };
 
 struct drm_mm {
-       struct list_head fl_entry;
-       struct list_head ml_entry;
+       /* List of free memory blocks, most recently freed ordered. */
+       struct list_head free_stack;
+       /* List of all memory nodes, ordered according to the (increasing) start
+        * address of the memory node. */
+       struct list_head node_list;
        struct list_head unused_nodes;
        int num_unused;
        spinlock_t unused_lock;
+       unsigned scan_alignment;
+       unsigned long scan_size;
+       unsigned long scan_hit_start;
+       unsigned scan_hit_size;
+       unsigned scanned_blocks;
 };
 
 /*
@@ -133,6 +143,11 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
        return block->mm;
 }
 
+void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
+                     unsigned alignment);
+int drm_mm_scan_add_block(struct drm_mm_node *node);
+int drm_mm_scan_remove_block(struct drm_mm_node *node);
+
 extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
 #ifdef CONFIG_DEBUG_FS
 int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
index c5ba1636613c0baac637fb169b28a17fb6a08aa0..0fc7397c8f1f4c3f6f9ab454c5f66343c6b3b949 100644 (file)
@@ -74,6 +74,7 @@
 /* Dithering mode options */
 #define DRM_MODE_DITHERING_OFF 0
 #define DRM_MODE_DITHERING_ON  1
+#define DRM_MODE_DITHERING_AUTO 2
 
 /* Dirty info options */
 #define DRM_MODE_DIRTY_OFF      0
index 2d428b088cc8f7df979d4fb66f332c3fbadf9f1f..3a9940ef728bb5d2412c4cb54d84ed746e15d870 100644 (file)
        {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x688A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x688C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x688D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6898, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6899, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x689c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68be, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x68c7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68e8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68e9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68f1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x68f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x68fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9456, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x945A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x945B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x945E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x946A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9487, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9488, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9489, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x948A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x948F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9490, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9491, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9553, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9555, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9557, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x955f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9581, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x9583, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
diff --git a/include/drm/i2c/sil164.h b/include/drm/i2c/sil164.h
new file mode 100644 (file)
index 0000000..205e273
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __DRM_I2C_SIL164_H__
+#define __DRM_I2C_SIL164_H__
+
+/**
+ * struct sil164_encoder_params
+ *
+ * Describes how the sil164 is connected to the GPU. It should be used
+ * as the @params parameter of its @set_config method.
+ *
+ * See "http://www.siliconimage.com/docs/SiI-DS-0021-E-164.pdf".
+ */
+struct sil164_encoder_params {
+       enum {
+               SIL164_INPUT_EDGE_FALLING = 0,
+               SIL164_INPUT_EDGE_RISING
+       } input_edge;
+
+       enum {
+               SIL164_INPUT_WIDTH_12BIT = 0,
+               SIL164_INPUT_WIDTH_24BIT
+       } input_width;
+
+       enum {
+               SIL164_INPUT_SINGLE_EDGE = 0,
+               SIL164_INPUT_DUAL_EDGE
+       } input_dual;
+
+       enum {
+               SIL164_PLL_FILTER_ON = 0,
+               SIL164_PLL_FILTER_OFF,
+       } pll_filter;
+
+       int input_skew; /** < Allowed range [-4, 3], use 0 for no de-skew. */
+       int duallink_skew; /** < Allowed range [-4, 3]. */
+};
+
+#endif
index 5347063e9d5a52b6896c135af389f6fcf8425ff3..0acaf8f9143751791f54b3a2da0be0c40653ad19 100644 (file)
@@ -904,6 +904,8 @@ struct drm_radeon_cs {
 #define RADEON_INFO_ACCEL_WORKING      0x03
 #define RADEON_INFO_CRTC_FROM_ID       0x04
 #define RADEON_INFO_ACCEL_WORKING2     0x05
+#define RADEON_INFO_TILING_CONFIG      0x06
+#define RADEON_INFO_WANT_HYPERZ                0x07
 
 struct drm_radeon_info {
        uint32_t                request;
index 0ea602da43e7787bced23b98527ba257c695c888..b87504235f183f45c01d527ae585cbbafbd197ab 100644 (file)
@@ -34,6 +34,7 @@
 #include "ttm/ttm_memory.h"
 #include "ttm/ttm_module.h"
 #include "drm_mm.h"
+#include "drm_global.h"
 #include "linux/workqueue.h"
 #include "linux/fs.h"
 #include "linux/spinlock.h"
@@ -362,7 +363,7 @@ struct ttm_bo_driver {
  */
 
 struct ttm_bo_global_ref {
-       struct ttm_global_reference ref;
+       struct drm_global_reference ref;
        struct ttm_mem_global *mem_glob;
 };
 
@@ -687,8 +688,8 @@ extern int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
 extern void ttm_mem_io_free(struct ttm_bo_device *bdev,
                                struct ttm_mem_reg *mem);
 
-extern void ttm_bo_global_release(struct ttm_global_reference *ref);
-extern int ttm_bo_global_init(struct ttm_global_reference *ref);
+extern void ttm_bo_global_release(struct drm_global_reference *ref);
+extern int ttm_bo_global_init(struct drm_global_reference *ref);
 
 extern int ttm_bo_device_release(struct ttm_bo_device *bdev);
 
index cf416aee19affcfaaa519e111e9f6d3b4e1f30d6..45fa318c158525b8ea9b30809ba20e0f99b4071d 100644 (file)
 struct kobject;
 
 #define TTM_PFX "[TTM] "
-
-enum ttm_global_types {
-       TTM_GLOBAL_TTM_MEM = 0,
-       TTM_GLOBAL_TTM_BO,
-       TTM_GLOBAL_TTM_OBJECT,
-       TTM_GLOBAL_NUM
-};
-
-struct ttm_global_reference {
-       enum ttm_global_types global_type;
-       size_t size;
-       void *object;
-       int (*init) (struct ttm_global_reference *);
-       void (*release) (struct ttm_global_reference *);
-};
-
-extern void ttm_global_init(void);
-extern void ttm_global_release(void);
-extern int ttm_global_item_ref(struct ttm_global_reference *ref);
-extern void ttm_global_item_unref(struct ttm_global_reference *ref);
 extern struct kobject *ttm_get_kobj(void);
 
 #endif /* _TTM_MODULE_H_ */
index f7dd576dd5a41fcb6818e666689e1610c2b3ac56..be3d9a77d6edd66cbf0208bf9145490a90981129 100644 (file)
 #ifndef _AHCI_PLATFORM_H
 #define _AHCI_PLATFORM_H
 
+#include <linux/compiler.h>
+
 struct device;
 struct ata_port_info;
 
 struct ahci_platform_data {
-       int (*init)(struct device *dev);
+       int (*init)(struct device *dev, void __iomem *addr);
        void (*exit)(struct device *dev);
        const struct ata_port_info *ata_port_info;
        unsigned int force_port_map;
index 5ea3c60c160c2df2d6e0010a33d9c8e01281b1f9..c37b21ad5a3b5c16dcc6c838ce0cb652682362f2 100644 (file)
@@ -292,6 +292,8 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
  */
 extern int
 __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
+extern void
+__clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
 
 static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
 {
@@ -303,6 +305,15 @@ static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
        return __clocksource_register_scale(cs, 1000, khz);
 }
 
+static inline void __clocksource_updatefreq_hz(struct clocksource *cs, u32 hz)
+{
+       __clocksource_updatefreq_scale(cs, 1, hz);
+}
+
+static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz)
+{
+       __clocksource_updatefreq_scale(cs, 1000, khz);
+}
 
 static inline void
 clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
@@ -313,11 +324,13 @@ clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 extern void
-update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult);
+update_vsyscall(struct timespec *ts, struct timespec *wtm,
+                       struct clocksource *c, u32 mult);
 extern void update_vsyscall_tz(void);
 #else
 static inline void
-update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult)
+update_vsyscall(struct timespec *ts, struct timespec *wtm,
+                       struct clocksource *c, u32 mult)
 {
 }
 
index a5a472b10746c662450059d8af969d58c7dcac6c..c1a62c56a660226b1592bc6bc269087adac58649 100644 (file)
@@ -16,6 +16,7 @@
 # define __release(x)  __context__(x,-1)
 # define __cond_lock(x,c)      ((c) ? ({ __acquire(x); 1; }) : 0)
 # define __percpu      __attribute__((noderef, address_space(3)))
+# define __rcu
 extern void __chk_user_ptr(const volatile void __user *);
 extern void __chk_io_ptr(const volatile void __iomem *);
 #else
@@ -34,6 +35,7 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 # define __release(x) (void)0
 # define __cond_lock(x,c) (c)
 # define __percpu
+# define __rcu
 #endif
 
 #ifdef __KERNEL__
index dcca5339ceb3c65711d9fce57d27bec70153029f..95cf6f08a59d2f39e51ba182a911f8f3ec5675cd 100644 (file)
@@ -55,6 +55,16 @@ struct consw {
        void    (*con_invert_region)(struct vc_data *, u16 *, int);
        u16    *(*con_screen_pos)(struct vc_data *, int);
        unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
+       /*
+        * Prepare the console for the debugger.  This includes, but is not
+        * limited to, unblanking the console, loading an appropriate
+        * palette, and allowing debugger generated output.
+        */
+       int     (*con_debug_enter)(struct vc_data *);
+       /*
+        * Restore the console to its pre-debug state as closely as possible.
+        */
+       int     (*con_debug_leave)(struct vc_data *);
 };
 
 extern const struct consw *conswitchp;
@@ -69,6 +79,14 @@ int register_con_driver(const struct consw *csw, int first, int last);
 int unregister_con_driver(const struct consw *csw);
 int take_over_console(const struct consw *sw, int first, int last, int deflt);
 void give_up_console(const struct consw *sw);
+#ifdef CONFIG_HW_CONSOLE
+int con_debug_enter(struct vc_data *vc);
+int con_debug_leave(void);
+#else
+#define con_debug_enter(vc) (0)
+#define con_debug_leave() (0)
+#endif
+
 /* scroll */
 #define SM_UP       (1)
 #define SM_DOWN     (2)
index e287863ac053d9788756ac79c9271ba562d455b1..4823af64e9db2148c23e1ae4d0ad3fe21de4368a 100644 (file)
@@ -48,6 +48,33 @@ extern ssize_t arch_cpu_release(const char *, size_t);
 #endif
 struct notifier_block;
 
+/*
+ * CPU notifier priorities.
+ */
+enum {
+       /*
+        * SCHED_ACTIVE marks a cpu which is coming up active during
+        * CPU_ONLINE and CPU_DOWN_FAILED and must be the first
+        * notifier.  CPUSET_ACTIVE adjusts cpuset according to
+        * cpu_active mask right after SCHED_ACTIVE.  During
+        * CPU_DOWN_PREPARE, SCHED_INACTIVE and CPUSET_INACTIVE are
+        * ordered in the similar way.
+        *
+        * This ordering guarantees consistent cpu_active mask and
+        * migration behavior to all cpu notifiers.
+        */
+       CPU_PRI_SCHED_ACTIVE    = INT_MAX,
+       CPU_PRI_CPUSET_ACTIVE   = INT_MAX - 1,
+       CPU_PRI_SCHED_INACTIVE  = INT_MIN + 1,
+       CPU_PRI_CPUSET_INACTIVE = INT_MIN,
+
+       /* migration should happen before other stuff but after perf */
+       CPU_PRI_PERF            = 20,
+       CPU_PRI_MIGRATION       = 10,
+       /* prepare workqueues for other notifiers */
+       CPU_PRI_WORKQUEUE       = 5,
+};
+
 #ifdef CONFIG_SMP
 /* Need to know about CPUs going up/down? */
 #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE)
index 457ed765a116a4c06ecd192e0165cf5af096c818..f20eb8f16025d74534dd2b62fa22cf494404ef1c 100644 (file)
@@ -20,6 +20,7 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */
 
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
+extern void cpuset_update_active_cpus(void);
 extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
 extern int cpuset_cpus_allowed_fallback(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
@@ -132,6 +133,11 @@ static inline void set_mems_allowed(nodemask_t nodemask)
 static inline int cpuset_init(void) { return 0; }
 static inline void cpuset_init_smp(void) {}
 
+static inline void cpuset_update_active_cpus(void)
+{
+       partition_sched_domains(1, NULL, NULL);
+}
+
 static inline void cpuset_cpus_allowed(struct task_struct *p,
                                       struct cpumask *mask)
 {
index fd832c6d419efc377a698eecd146032d5f68a8d1..a6ecb34cf547da29ad16edf8b109de2511d10cd5 100644 (file)
@@ -45,6 +45,7 @@ extern unsigned long lpj_fine;
 void calibrate_delay(void);
 void msleep(unsigned int msecs);
 unsigned long msleep_interruptible(unsigned int msecs);
+void usleep_range(unsigned long min, unsigned long max);
 
 static inline void ssleep(unsigned int seconds)
 {
index 6a8276f683b6fe8ca5d5a770cd0b1207db676924..516fecacf27b424f29b95c9ee4921b7fd5805dc5 100644 (file)
@@ -84,9 +84,8 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
                                       struct device *start,
                                       const char *name);
 
-int __must_check bus_for_each_drv(struct bus_type *bus,
-                                 struct device_driver *start, void *data,
-                                 int (*fn)(struct device_driver *, void *));
+int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
+                    void *data, int (*fn)(struct device_driver *, void *));
 
 void bus_sort_breadthfirst(struct bus_type *bus,
                           int (*compare)(const struct device *a,
@@ -110,10 +109,12 @@ extern int bus_unregister_notifier(struct bus_type *bus,
  */
 #define BUS_NOTIFY_ADD_DEVICE          0x00000001 /* device added */
 #define BUS_NOTIFY_DEL_DEVICE          0x00000002 /* device removed */
-#define BUS_NOTIFY_BOUND_DRIVER                0x00000003 /* driver bound to device */
-#define BUS_NOTIFY_UNBIND_DRIVER       0x00000004 /* driver about to be
+#define BUS_NOTIFY_BIND_DRIVER         0x00000003 /* driver about to be
+                                                     bound */
+#define BUS_NOTIFY_BOUND_DRIVER                0x00000004 /* driver bound to device */
+#define BUS_NOTIFY_UNBIND_DRIVER       0x00000005 /* driver about to be
                                                      unbound */
-#define BUS_NOTIFY_UNBOUND_DRIVER      0x00000005 /* driver is unbound
+#define BUS_NOTIFY_UNBOUND_DRIVER      0x00000006 /* driver is unbound
                                                      from the device */
 
 extern struct kset *bus_get_kset(struct bus_type *bus);
@@ -551,7 +552,7 @@ extern int device_for_each_child(struct device *dev, void *data,
                     int (*fn)(struct device *dev, void *data));
 extern struct device *device_find_child(struct device *dev, void *data,
                                int (*match)(struct device *dev, void *data));
-extern int device_rename(struct device *dev, char *new_name);
+extern int device_rename(struct device *dev, const char *new_name);
 extern int device_move(struct device *dev, struct device *new_parent,
                       enum dpm_order dpm_order);
 extern const char *device_get_devnode(struct device *dev,
index a8a3e1ac281dfb1cb27df81200fb2055d6c71ae4..90e087f8d951808724a1207de64681f556216bf1 100644 (file)
@@ -20,6 +20,7 @@ enum dmi_device_type {
        DMI_DEV_TYPE_SAS,
        DMI_DEV_TYPE_IPMI = -1,
        DMI_DEV_TYPE_OEM_STRING = -2,
+       DMI_DEV_TYPE_DEV_ONBOARD = -3,
 };
 
 struct dmi_header {
@@ -37,6 +38,14 @@ struct dmi_device {
 
 #ifdef CONFIG_DMI
 
+struct dmi_dev_onboard {
+       struct dmi_device dev;
+       int instance;
+       int segment;
+       int bus;
+       int devfn;
+};
+
 extern int dmi_check_system(const struct dmi_system_id *list);
 const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list);
 extern const char * dmi_get_system_info(int field);
index e7445df44d6c9324fd32a85ee1145415ecbd7960..0c5659c41b01c502160ca089bd758a36963f7918 100644 (file)
@@ -3,6 +3,9 @@
 
 #include <linux/types.h>
 #include <linux/i2c.h>
+#ifdef __KERNEL__
+#include <linux/kgdb.h>
+#endif /* __KERNEL__ */
 
 /* Definitions of frame buffers                                                */
 
@@ -607,6 +610,12 @@ struct fb_deferred_io {
  * LOCKING NOTE: those functions must _ALL_ be called with the console
  * semaphore held, this is the only suitable locking mechanism we have
  * in 2.6. Some may be called at interrupt time at this point though.
+ *
+ * The exception to this is the debug related hooks.  Putting the fb
+ * into a debug state (e.g. flipping to the kernel console) and restoring
+ * it must be done in a lock-free manner, so low level drivers should
+ * keep track of the initial console (if applicable) and may need to
+ * perform direct, unlocked hardware writes in these hooks.
  */
 
 struct fb_ops {
@@ -676,6 +685,10 @@ struct fb_ops {
 
        /* teardown any resources to do with this framebuffer */
        void (*fb_destroy)(struct fb_info *info);
+
+       /* called at KDB enter and leave time to prepare the console */
+       int (*fb_debug_enter)(struct fb_info *info);
+       int (*fb_debug_leave)(struct fb_info *info);
 };
 
 #ifdef CONFIG_FB_TILEBLITTING
index d147461bc2712b9c9fb7aae84d65e600d6c60fd4..f59ed297b661fceb086a6ca188b54c3ff0006f85 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/rcupdate.h>
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/fs.h>
 
 #include <asm/atomic.h>
 
index c57db27ac86140ba13798e1736b31d9254162a82..b8581c09d19f96a5551d0b60a96ac3ee9004df3e 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/fscache.h>
 #include <linux/sched.h>
-#include <linux/slow-work.h>
+#include <linux/workqueue.h>
 
 #define NR_MAXCACHES BITS_PER_LONG
 
@@ -76,18 +76,14 @@ typedef void (*fscache_operation_release_t)(struct fscache_operation *op);
 typedef void (*fscache_operation_processor_t)(struct fscache_operation *op);
 
 struct fscache_operation {
-       union {
-               struct work_struct fast_work;   /* record for fast ops */
-               struct slow_work slow_work;     /* record for (very) slow ops */
-       };
+       struct work_struct      work;           /* record for async ops */
        struct list_head        pend_link;      /* link in object->pending_ops */
        struct fscache_object   *object;        /* object to be operated upon */
 
        unsigned long           flags;
 #define FSCACHE_OP_TYPE                0x000f  /* operation type */
-#define FSCACHE_OP_FAST                0x0001  /* - fast op, processor may not sleep for disk */
-#define FSCACHE_OP_SLOW                0x0002  /* - (very) slow op, processor may sleep for disk */
-#define FSCACHE_OP_MYTHREAD    0x0003  /* - processing is done be issuing thread, not pool */
+#define FSCACHE_OP_ASYNC       0x0001  /* - async op, processor may sleep for disk */
+#define FSCACHE_OP_MYTHREAD    0x0002  /* - processing is done be issuing thread, not pool */
 #define FSCACHE_OP_WAITING     4       /* cleared when op is woken */
 #define FSCACHE_OP_EXCLUSIVE   5       /* exclusive op, other ops must wait */
 #define FSCACHE_OP_DEAD                6       /* op is now dead */
@@ -105,7 +101,8 @@ struct fscache_operation {
        /* operation releaser */
        fscache_operation_release_t release;
 
-#ifdef CONFIG_SLOW_WORK_DEBUG
+#ifdef CONFIG_WORKQUEUE_DEBUGFS
+       struct work_struct put_work;    /* work to delay operation put */
        const char *name;               /* operation name */
        const char *state;              /* operation state */
 #define fscache_set_op_name(OP, N)     do { (OP)->name  = (N); } while(0)
@@ -117,7 +114,7 @@ struct fscache_operation {
 };
 
 extern atomic_t fscache_op_debug_id;
-extern const struct slow_work_ops fscache_op_slow_work_ops;
+extern void fscache_op_work_func(struct work_struct *work);
 
 extern void fscache_enqueue_operation(struct fscache_operation *);
 extern void fscache_put_operation(struct fscache_operation *);
@@ -128,33 +125,21 @@ extern void fscache_put_operation(struct fscache_operation *);
  * @release: The release function to assign
  *
  * Do basic initialisation of an operation.  The caller must still set flags,
- * object, either fast_work or slow_work if necessary, and processor if needed.
+ * object and processor if needed.
  */
 static inline void fscache_operation_init(struct fscache_operation *op,
-                                         fscache_operation_release_t release)
+                                       fscache_operation_processor_t processor,
+                                       fscache_operation_release_t release)
 {
+       INIT_WORK(&op->work, fscache_op_work_func);
        atomic_set(&op->usage, 1);
        op->debug_id = atomic_inc_return(&fscache_op_debug_id);
+       op->processor = processor;
        op->release = release;
        INIT_LIST_HEAD(&op->pend_link);
        fscache_set_op_state(op, "Init");
 }
 
-/**
- * fscache_operation_init_slow - Do additional initialisation of a slow op
- * @op: The operation to initialise
- * @processor: The processor function to assign
- *
- * Do additional initialisation of an operation as required for slow work.
- */
-static inline
-void fscache_operation_init_slow(struct fscache_operation *op,
-                                fscache_operation_processor_t processor)
-{
-       op->processor = processor;
-       slow_work_init(&op->slow_work, &fscache_op_slow_work_ops);
-}
-
 /*
  * data read operation
  */
@@ -389,7 +374,7 @@ struct fscache_object {
        struct fscache_cache    *cache;         /* cache that supplied this object */
        struct fscache_cookie   *cookie;        /* netfs's file/index object */
        struct fscache_object   *parent;        /* parent object */
-       struct slow_work        work;           /* attention scheduling record */
+       struct work_struct      work;           /* attention scheduling record */
        struct list_head        dependents;     /* FIFO of dependent objects */
        struct list_head        dep_link;       /* link in parent's dependents list */
        struct list_head        pending_ops;    /* unstarted operations on this object */
@@ -411,7 +396,7 @@ extern const char *fscache_object_states[];
        (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) &&     \
         (obj)->state >= FSCACHE_OBJECT_DYING)
 
-extern const struct slow_work_ops fscache_object_slow_work_ops;
+extern void fscache_object_work_func(struct work_struct *work);
 
 /**
  * fscache_object_init - Initialise a cache object description
@@ -433,7 +418,7 @@ void fscache_object_init(struct fscache_object *object,
        spin_lock_init(&object->lock);
        INIT_LIST_HEAD(&object->cache_link);
        INIT_HLIST_NODE(&object->cookie_link);
-       vslow_work_init(&object->work, &fscache_object_slow_work_ops);
+       INIT_WORK(&object->work, fscache_object_work_func);
        INIT_LIST_HEAD(&object->dependents);
        INIT_LIST_HEAD(&object->dep_link);
        INIT_LIST_HEAD(&object->pending_ops);
@@ -534,6 +519,8 @@ extern void fscache_io_error(struct fscache_cache *cache);
 extern void fscache_mark_pages_cached(struct fscache_retrieval *op,
                                      struct pagevec *pagevec);
 
+extern bool fscache_object_sleep_till_congested(signed long *timeoutp);
+
 extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
                                               const void *data,
                                               uint16_t datalen);
index 41e46330d9bedfd16d46a920cbd840dad54afffe..dcd6a7c3a4358b310b430a16dc52f43b547e02f2 100644 (file)
@@ -1,3 +1,8 @@
+/*
+ * Ftrace header.  For implementation details beyond the random comments
+ * scattered below, see: Documentation/trace/ftrace-design.txt
+ */
+
 #ifndef _LINUX_FTRACE_H
 #define _LINUX_FTRACE_H
 
index 3167f2df4126c12e195be536c687c577212da651..02b8b24f8f51f0e37156731ba94da19ba2d19131 100644 (file)
@@ -11,8 +11,6 @@ struct trace_array;
 struct tracer;
 struct dentry;
 
-DECLARE_PER_CPU(struct trace_seq, ftrace_event_seq);
-
 struct trace_print_flags {
        unsigned long           mask;
        const char              *name;
@@ -58,6 +56,9 @@ struct trace_iterator {
        struct ring_buffer_iter *buffer_iter[NR_CPUS];
        unsigned long           iter_flags;
 
+       /* trace_seq for __print_flags() and __print_symbolic() etc. */
+       struct trace_seq        tmp_seq;
+
        /* The below is zeroed out in pipe_read */
        struct trace_seq        seq;
        struct trace_entry      *ent;
@@ -146,14 +147,19 @@ struct ftrace_event_class {
        int                     (*raw_init)(struct ftrace_event_call *);
 };
 
+extern int ftrace_event_reg(struct ftrace_event_call *event,
+                           enum trace_reg type);
+
 enum {
        TRACE_EVENT_FL_ENABLED_BIT,
        TRACE_EVENT_FL_FILTERED_BIT,
+       TRACE_EVENT_FL_RECORDED_CMD_BIT,
 };
 
 enum {
-       TRACE_EVENT_FL_ENABLED  = (1 << TRACE_EVENT_FL_ENABLED_BIT),
-       TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT),
+       TRACE_EVENT_FL_ENABLED          = (1 << TRACE_EVENT_FL_ENABLED_BIT),
+       TRACE_EVENT_FL_FILTERED         = (1 << TRACE_EVENT_FL_FILTERED_BIT),
+       TRACE_EVENT_FL_RECORDED_CMD     = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT),
 };
 
 struct ftrace_event_call {
@@ -171,6 +177,7 @@ struct ftrace_event_call {
         * 32 bit flags:
         *   bit 1:             enabled
         *   bit 2:             filter_active
+        *   bit 3:             enabled cmd record
         *
         * Changes to flags must hold the event_mutex.
         *
@@ -257,8 +264,7 @@ static inline void
 perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr,
                       u64 count, struct pt_regs *regs, void *head)
 {
-       perf_tp_event(addr, count, raw_data, size, regs, head);
-       perf_swevent_put_recursion_context(rctx);
+       perf_tp_event(addr, count, raw_data, size, regs, head, rctx);
 }
 #endif
 
index c2331138ca1bb5e3d9b543b9f3d71d92b95fb399..a0384a4d1e6f4da4d39a02c0f8ba6634842dd236 100644 (file)
  * IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
  *                Used by threaded interrupts which need to keep the
  *                irq line disabled until the threaded handler has been run.
+ * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
+ *
  */
 #define IRQF_DISABLED          0x00000020
 #define IRQF_SAMPLE_RANDOM     0x00000040
 #define IRQF_SHARED            0x00000080
 #define IRQF_PROBE_SHARED      0x00000100
-#define IRQF_TIMER             0x00000200
+#define __IRQF_TIMER           0x00000200
 #define IRQF_PERCPU            0x00000400
 #define IRQF_NOBALANCING       0x00000800
 #define IRQF_IRQPOLL           0x00001000
 #define IRQF_ONESHOT           0x00002000
+#define IRQF_NO_SUSPEND                0x00004000
+
+#define IRQF_TIMER             (__IRQF_TIMER | IRQF_NO_SUSPEND)
 
 /*
  * Bits used by threaded handlers:
index 25085ddd955fda5516b4b8a73958246ba4044e41..e0ea40f6c51551c54d174bcdeb27049f885a332b 100644 (file)
@@ -79,7 +79,9 @@ io_mapping_free(struct io_mapping *mapping)
 
 /* Atomic map/unmap */
 static inline void *
-io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
+io_mapping_map_atomic_wc(struct io_mapping *mapping,
+                        unsigned long offset,
+                        int slot)
 {
        resource_size_t phys_addr;
        unsigned long pfn;
@@ -87,13 +89,13 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
        BUG_ON(offset >= mapping->size);
        phys_addr = mapping->base + offset;
        pfn = (unsigned long) (phys_addr >> PAGE_SHIFT);
-       return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot);
+       return iomap_atomic_prot_pfn(pfn, slot, mapping->prot);
 }
 
 static inline void
-io_mapping_unmap_atomic(void *vaddr)
+io_mapping_unmap_atomic(void *vaddr, int slot)
 {
-       iounmap_atomic(vaddr, KM_USER0);
+       iounmap_atomic(vaddr, slot);
 }
 
 static inline void *
@@ -133,13 +135,15 @@ io_mapping_free(struct io_mapping *mapping)
 
 /* Atomic map/unmap */
 static inline void *
-io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
+io_mapping_map_atomic_wc(struct io_mapping *mapping,
+                        unsigned long offset,
+                        int slot)
 {
        return ((char *) mapping) + offset;
 }
 
 static inline void
-io_mapping_unmap_atomic(void *vaddr)
+io_mapping_unmap_atomic(void *vaddr, int slot)
 {
 }
 
index 6c7f0ba0d5faf473b6c2ffb60d1a0c957c007059..7fd2d2138bf3de8130e5660922a32fe81a47f22b 100644 (file)
@@ -29,10 +29,10 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
 
 #ifdef CONFIG_MMU
 int ioremap_page_range(unsigned long addr, unsigned long end,
-                      unsigned long phys_addr, pgprot_t prot);
+                      phys_addr_t phys_addr, pgprot_t prot);
 #else
 static inline int ioremap_page_range(unsigned long addr, unsigned long end,
-                                    unsigned long phys_addr, pgprot_t prot)
+                                    phys_addr_t phys_addr, pgprot_t prot)
 {
        return 0;
 }
index be22ad83689cb96275d0386c5325c4079699dc9c..0a2ba4098996de9ef07ed8cdf11bd11b90901548 100644 (file)
@@ -30,6 +30,7 @@ struct iommu_domain {
 };
 
 #define IOMMU_CAP_CACHE_COHERENCY      0x1
+#define IOMMU_CAP_INTR_REMAP           0x2     /* isolates device intrs */
 
 struct iommu_ops {
        int (*domain_init)(struct iommu_domain *domain);
index ccb2b3ec0fe899769c161a844b13204d3894fd77..ea6e5244ed3f0b77d8ff644ee975d21945494a17 100644 (file)
@@ -114,4 +114,8 @@ enum {
        KDB_INIT_EARLY,
        KDB_INIT_FULL,
 };
+
+extern int kdbgetintenv(const char *, int *);
+extern int kdb_set(int, const char **);
+
 #endif /* !_KDB_H */
index 5de838b0fc1a62afb20fb75eda44089937f87eea..7d5b10ff63e0649562d26611fa98de5b57c4600e 100644 (file)
@@ -252,6 +252,13 @@ extern struct pid *session_of_pgrp(struct pid *pgrp);
 #define FW_WARN                "[Firmware Warn]: "
 #define FW_INFO                "[Firmware Info]: "
 
+/*
+ * HW_ERR
+ * Add this to a message for hardware errors, so that user can report
+ * it to hardware vendor instead of LKML or software vendor.
+ */
+#define HW_ERR         "[Hardware Error]: "
+
 #ifdef CONFIG_PRINTK
 asmlinkage int vprintk(const char *fmt, va_list args)
        __attribute__ ((format (printf, 1, 0)));
@@ -513,9 +520,6 @@ extern void tracing_start(void);
 extern void tracing_stop(void);
 extern void ftrace_off_permanent(void);
 
-extern void
-ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
-
 static inline void __attribute__ ((format (printf, 1, 2)))
 ____trace_printk_check_format(const char *fmt, ...)
 {
@@ -591,8 +595,6 @@ __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
 
 extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
 #else
-static inline void
-ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
 static inline int
 trace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
 
index 9340f34d1bb5e7af04ad247d119d341e9d5cd0a6..cc96f0f23e04a545ffd3dfc7faff7d27fb7d61f1 100644 (file)
@@ -90,6 +90,19 @@ struct kgdb_bkpt {
        enum kgdb_bpstate       state;
 };
 
+struct dbg_reg_def_t {
+       char *name;
+       int size;
+       int offset;
+};
+
+#ifndef DBG_MAX_REG_NUM
+#define DBG_MAX_REG_NUM 0
+#else
+extern struct dbg_reg_def_t dbg_reg_def[];
+extern char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs);
+extern int dbg_set_reg(int regno, void *mem, struct pt_regs *regs);
+#endif
 #ifndef KGDB_MAX_BREAKPOINTS
 # define KGDB_MAX_BREAKPOINTS  1000
 #endif
@@ -281,7 +294,7 @@ extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
 extern struct kgdb_io *dbg_io_ops;
 
 extern int kgdb_hex2long(char **ptr, unsigned long *long_val);
-extern int kgdb_mem2hex(char *mem, char *buf, int count);
+extern char *kgdb_mem2hex(char *mem, char *buf, int count);
 extern int kgdb_hex2mem(char *buf, char *mem, int count);
 
 extern int kgdb_isremovedbreak(unsigned long addr);
diff --git a/include/linux/kmemtrace.h b/include/linux/kmemtrace.h
deleted file mode 100644 (file)
index b616d39..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2008 Eduard - Gabriel Munteanu
- *
- * This file is released under GPL version 2.
- */
-
-#ifndef _LINUX_KMEMTRACE_H
-#define _LINUX_KMEMTRACE_H
-
-#ifdef __KERNEL__
-
-#include <trace/events/kmem.h>
-
-#ifdef CONFIG_KMEMTRACE
-extern void kmemtrace_init(void);
-#else
-static inline void kmemtrace_init(void)
-{
-}
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* _LINUX_KMEMTRACE_H */
-
index aabc8a13ba71c7b6f9eab1ddf3842b18800045d4..685ea65eb803fddf1c47ee3e420fe3056278685b 100644 (file)
@@ -30,8 +30,73 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
 void kthread_bind(struct task_struct *k, unsigned int cpu);
 int kthread_stop(struct task_struct *k);
 int kthread_should_stop(void);
+void *kthread_data(struct task_struct *k);
 
 int kthreadd(void *unused);
 extern struct task_struct *kthreadd_task;
 
+/*
+ * Simple work processor based on kthread.
+ *
+ * This provides easier way to make use of kthreads.  A kthread_work
+ * can be queued and flushed using queue/flush_kthread_work()
+ * respectively.  Queued kthread_works are processed by a kthread
+ * running kthread_worker_fn().
+ *
+ * A kthread_work can't be freed while it is executing.
+ */
+struct kthread_work;
+typedef void (*kthread_work_func_t)(struct kthread_work *work);
+
+struct kthread_worker {
+       spinlock_t              lock;
+       struct list_head        work_list;
+       struct task_struct      *task;
+};
+
+struct kthread_work {
+       struct list_head        node;
+       kthread_work_func_t     func;
+       wait_queue_head_t       done;
+       atomic_t                flushing;
+       int                     queue_seq;
+       int                     done_seq;
+};
+
+#define KTHREAD_WORKER_INIT(worker)    {                               \
+       .lock = SPIN_LOCK_UNLOCKED,                                     \
+       .work_list = LIST_HEAD_INIT((worker).work_list),                \
+       }
+
+#define KTHREAD_WORK_INIT(work, fn)    {                               \
+       .node = LIST_HEAD_INIT((work).node),                            \
+       .func = (fn),                                                   \
+       .done = __WAIT_QUEUE_HEAD_INITIALIZER((work).done),             \
+       .flushing = ATOMIC_INIT(0),                                     \
+       }
+
+#define DEFINE_KTHREAD_WORKER(worker)                                  \
+       struct kthread_worker worker = KTHREAD_WORKER_INIT(worker)
+
+#define DEFINE_KTHREAD_WORK(work, fn)                                  \
+       struct kthread_work work = KTHREAD_WORK_INIT(work, fn)
+
+static inline void init_kthread_worker(struct kthread_worker *worker)
+{
+       *worker = (struct kthread_worker)KTHREAD_WORKER_INIT(*worker);
+}
+
+static inline void init_kthread_work(struct kthread_work *work,
+                                    kthread_work_func_t fn)
+{
+       *work = (struct kthread_work)KTHREAD_WORK_INIT(*work, fn);
+}
+
+int kthread_worker_fn(void *worker_ptr);
+
+bool queue_kthread_work(struct kthread_worker *worker,
+                       struct kthread_work *work);
+void flush_kthread_work(struct kthread_work *work);
+void flush_kthread_worker(struct kthread_worker *worker);
+
 #endif /* _LINUX_KTHREAD_H */
index b85f3ff34d7d3d71cb99f0ded4db0ce186780b57..f010f18a0f863f39e139d65469debae94232b259 100644 (file)
@@ -751,6 +751,7 @@ struct ata_port {
        struct ata_host         *host;
        struct device           *dev;
 
+       struct mutex            scsi_scan_mutex;
        struct delayed_work     hotplug_task;
        struct work_struct      scsi_rescan_task;
 
index 6991ab5b24d1bbfd736df4d27315a83ee7271779..91b05c171854f12488e92c8fe2d23812bb1f03e5 100644 (file)
@@ -14,8 +14,10 @@ struct irq_desc;
 extern void mask_msi_irq(unsigned int irq);
 extern void unmask_msi_irq(unsigned int irq);
 extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
+extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
 extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
 extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
+extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
 extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
 
 struct msi_desc {
index b752e807addece22ec9210f0d109d2818505d34d..06aab5eee134cd56c4bade9005912fa3a785a327 100644 (file)
@@ -20,10 +20,14 @@ extern void touch_nmi_watchdog(void);
 extern void acpi_nmi_disable(void);
 extern void acpi_nmi_enable(void);
 #else
+#ifndef CONFIG_HARDLOCKUP_DETECTOR
 static inline void touch_nmi_watchdog(void)
 {
        touch_softlockup_watchdog();
 }
+#else
+extern void touch_nmi_watchdog(void);
+#endif
 static inline void acpi_nmi_disable(void) { }
 static inline void acpi_nmi_enable(void) { }
 #endif
@@ -47,4 +51,13 @@ static inline bool trigger_all_cpu_backtrace(void)
 }
 #endif
 
+#ifdef CONFIG_LOCKUP_DETECTOR
+int hw_nmi_is_cpu_stuck(struct pt_regs *);
+u64 hw_nmi_get_sample_period(void);
+extern int watchdog_enabled;
+struct ctl_table;
+extern int proc_dowatchdog_enabled(struct ctl_table *, int ,
+                       void __user *, size_t *, loff_t *);
+#endif
+
 #endif
index a367e19bb3afef4b4da81b5f0676a87b7e1911da..cad7cf0ab27855f6fff3e35fb9b95a96867a9e91 100644 (file)
@@ -70,6 +70,11 @@ extern struct device_node *allnodes;
 extern struct device_node *of_chosen;
 extern rwlock_t devtree_lock;
 
+static inline bool of_node_is_root(const struct device_node *node)
+{
+       return node && (node->parent == NULL);
+}
+
 static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
 {
        return test_bit(flag, &n->_flags);
@@ -141,6 +146,11 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
 
 #define OF_BAD_ADDR    ((u64)-1)
 
+#ifndef of_node_to_nid
+static inline int of_node_to_nid(struct device_node *np) { return -1; }
+#define of_node_to_nid of_node_to_nid
+#endif
+
 extern struct device_node *of_find_node_by_name(struct device_node *from,
        const char *name);
 #define for_each_node_by_name(dn, name) \
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
new file mode 100644 (file)
index 0000000..8aea06f
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __OF_ADDRESS_H
+#define __OF_ADDRESS_H
+#include <linux/ioport.h>
+#include <linux/of.h>
+
+extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+extern int of_address_to_resource(struct device_node *dev, int index,
+                                 struct resource *r);
+extern void __iomem *of_iomap(struct device_node *device, int index);
+
+/* Extract an address from a device, returns the region size and
+ * the address space flags too. The PCI version uses a BAR number
+ * instead of an absolute index
+ */
+extern const u32 *of_get_address(struct device_node *dev, int index,
+                          u64 *size, unsigned int *flags);
+
+#ifndef pci_address_to_pio
+static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
+#define pci_address_to_pio pci_address_to_pio
+#endif
+
+#ifdef CONFIG_PCI
+extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+                              u64 *size, unsigned int *flags);
+extern int of_pci_address_to_resource(struct device_node *dev, int bar,
+                                     struct resource *r);
+#else /* CONFIG_PCI */
+static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
+                                            struct resource *r)
+{
+       return -ENOSYS;
+}
+
+static inline const u32 *of_get_pci_address(struct device_node *dev,
+               int bar_no, u64 *size, unsigned int *flags)
+{
+       return NULL;
+}
+#endif /* CONFIG_PCI */
+
+
+#endif /* __OF_ADDRESS_H */
+
index 11651facc5f179237500ea4d43e3bcc76bfe270d..35aa44ad9f2cb21b7ce2422dfbae2fc296aba7cc 100644 (file)
@@ -1,32 +1,77 @@
 #ifndef _LINUX_OF_DEVICE_H
 #define _LINUX_OF_DEVICE_H
 
+/*
+ * The of_device *was* a kind of "base class" that was a superset of
+ * struct device for use by devices attached to an OF node and probed
+ * using OF properties.  However, the important bit of OF-style
+ * probing, namely the device node pointer, has been moved into the
+ * common struct device when CONFIG_OF is set to make OF-style probing
+ * available to all bus types.  So now, just make of_device and
+ * platform_device equivalent so that current of_platform bus users
+ * can be transparently migrated over to using the platform bus.
+ *
+ * This line will go away once all references to of_device are removed
+ * from the kernel.
+ */
+#define of_device platform_device
+#include <linux/platform_device.h>
+#include <linux/of_platform.h> /* temporary until merge */
+
 #ifdef CONFIG_OF_DEVICE
 #include <linux/device.h>
 #include <linux/of.h>
 #include <linux/mod_devicetable.h>
 
-#include <asm/of_device.h>
-
 #define        to_of_device(d) container_of(d, struct of_device, dev)
 
 extern const struct of_device_id *of_match_device(
        const struct of_device_id *matches, const struct device *dev);
+extern void of_device_make_bus_id(struct device *dev);
+
+/**
+ * of_driver_match_device - Tell if a driver's of_match_table matches a device.
+ * @drv: the device_driver structure to test
+ * @dev: the device structure to match against
+ */
+static inline int of_driver_match_device(const struct device *dev,
+                                        const struct device_driver *drv)
+{
+       return of_match_device(drv->of_match_table, dev) != NULL;
+}
 
-extern struct of_device *of_dev_get(struct of_device *dev);
-extern void of_dev_put(struct of_device *dev);
+extern struct platform_device *of_dev_get(struct platform_device *dev);
+extern void of_dev_put(struct platform_device *dev);
 
-extern int of_device_register(struct of_device *ofdev);
-extern void of_device_unregister(struct of_device *ofdev);
+extern int of_device_register(struct platform_device *ofdev);
+extern void of_device_unregister(struct platform_device *ofdev);
 extern void of_release_dev(struct device *dev);
 
-static inline void of_device_free(struct of_device *dev)
+static inline void of_device_free(struct platform_device *dev)
 {
        of_release_dev(&dev->dev);
 }
 
-extern ssize_t of_device_get_modalias(struct of_device *ofdev,
+extern ssize_t of_device_get_modalias(struct device *dev,
                                        char *str, ssize_t len);
+
+extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
+
+
+#else /* CONFIG_OF_DEVICE */
+
+static inline int of_driver_match_device(struct device *dev,
+                                        struct device_driver *drv)
+{
+       return 0;
+}
+
+static inline int of_device_uevent(struct device *dev,
+                                  struct kobj_uevent_env *env)
+{
+       return -ENODEV;
+}
+
 #endif /* CONFIG_OF_DEVICE */
 
 #endif /* _LINUX_OF_DEVICE_H */
index fc2472c3c254caf90956d6850ca0381e51a5fed7..6598c04dab01249e47722e928bb2c379b922dbba 100644 (file)
@@ -32,35 +32,18 @@ enum of_gpio_flags {
 
 #ifdef CONFIG_OF_GPIO
 
-/*
- * Generic OF GPIO chip
- */
-struct of_gpio_chip {
-       struct gpio_chip gc;
-       int gpio_cells;
-       int (*xlate)(struct of_gpio_chip *of_gc, struct device_node *np,
-                    const void *gpio_spec, enum of_gpio_flags *flags);
-};
-
-static inline struct of_gpio_chip *to_of_gpio_chip(struct gpio_chip *gc)
-{
-       return container_of(gc, struct of_gpio_chip, gc);
-}
-
 /*
  * OF GPIO chip for memory mapped banks
  */
 struct of_mm_gpio_chip {
-       struct of_gpio_chip of_gc;
+       struct gpio_chip gc;
        void (*save_regs)(struct of_mm_gpio_chip *mm_gc);
        void __iomem *regs;
 };
 
 static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
 {
-       struct of_gpio_chip *of_gc = to_of_gpio_chip(gc);
-
-       return container_of(of_gc, struct of_mm_gpio_chip, of_gc);
+       return container_of(gc, struct of_mm_gpio_chip, gc);
 }
 
 extern int of_get_gpio_flags(struct device_node *np, int index,
@@ -69,11 +52,12 @@ extern unsigned int of_gpio_count(struct device_node *np);
 
 extern int of_mm_gpiochip_add(struct device_node *np,
                              struct of_mm_gpio_chip *mm_gc);
-extern int of_gpio_simple_xlate(struct of_gpio_chip *of_gc,
-                               struct device_node *np,
-                               const void *gpio_spec,
-                               enum of_gpio_flags *flags);
-#else
+
+extern void of_gpiochip_add(struct gpio_chip *gc);
+extern void of_gpiochip_remove(struct gpio_chip *gc);
+extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np);
+
+#else /* CONFIG_OF_GPIO */
 
 /* Drivers may not strictly depend on the GPIO support, so let them link. */
 static inline int of_get_gpio_flags(struct device_node *np, int index,
@@ -87,6 +71,9 @@ static inline unsigned int of_gpio_count(struct device_node *np)
        return 0;
 }
 
+static inline void of_gpiochip_add(struct gpio_chip *gc) { }
+static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
+
 #endif /* CONFIG_OF_GPIO */
 
 /**
index 34974b5a76f78d1d9d142c3df4fb0e23a0ba106e..0efe8d465f555d4a2c0f5e7ac26d97c28867db68 100644 (file)
 #ifndef __LINUX_OF_I2C_H
 #define __LINUX_OF_I2C_H
 
+#if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE)
 #include <linux/i2c.h>
 
-void of_register_i2c_devices(struct i2c_adapter *adap,
-                            struct device_node *adap_node);
+extern void of_i2c_register_devices(struct i2c_adapter *adap);
 
 /* must call put_device() when done with returned i2c_client device */
-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+
+#else
+static inline void of_i2c_register_devices(struct i2c_adapter *adap)
+{
+       return;
+}
+#endif /* CONFIG_OF_I2C */
 
 #endif /* __LINUX_OF_I2C_H */
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
new file mode 100644 (file)
index 0000000..5929781
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef __OF_IRQ_H
+#define __OF_IRQ_H
+
+#if defined(CONFIG_OF)
+struct of_irq;
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+
+/*
+ * irq_of_parse_and_map() is used ba all OF enabled platforms; but SPARC
+ * implements it differently.  However, the prototype is the same for all,
+ * so declare it here regardless of the CONFIG_OF_IRQ setting.
+ */
+extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
+
+#if defined(CONFIG_OF_IRQ)
+/**
+ * of_irq - container for device_node/irq_specifier pair for an irq controller
+ * @controller: pointer to interrupt controller device tree node
+ * @size: size of interrupt specifier
+ * @specifier: array of cells @size long specifing the specific interrupt
+ *
+ * This structure is returned when an interrupt is mapped. The controller
+ * field needs to be put() after use
+ */
+#define OF_MAX_IRQ_SPEC                4 /* We handle specifiers of at most 4 cells */
+struct of_irq {
+       struct device_node *controller; /* Interrupt controller node */
+       u32 size; /* Specifier size */
+       u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
+};
+
+/*
+ * Workarounds only applied to 32bit powermac machines
+ */
+#define OF_IMAP_OLDWORLD_MAC   0x00000001
+#define OF_IMAP_NO_PHANDLE     0x00000002
+
+#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
+extern unsigned int of_irq_workarounds;
+extern struct device_node *of_irq_dflt_pic;
+extern int of_irq_map_oldworld(struct device_node *device, int index,
+                              struct of_irq *out_irq);
+#else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+#define of_irq_workarounds (0)
+#define of_irq_dflt_pic (NULL)
+static inline int of_irq_map_oldworld(struct device_node *device, int index,
+                                     struct of_irq *out_irq)
+{
+       return -EINVAL;
+}
+#endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+
+
+extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
+                         u32 ointsize, const u32 *addr,
+                         struct of_irq *out_irq);
+extern int of_irq_map_one(struct device_node *device, int index,
+                         struct of_irq *out_irq);
+extern unsigned int irq_create_of_mapping(struct device_node *controller,
+                                         const u32 *intspec,
+                                         unsigned int intsize);
+extern int of_irq_to_resource(struct device_node *dev, int index,
+                             struct resource *r);
+
+#endif /* CONFIG_OF_IRQ */
+#endif /* CONFIG_OF */
+#endif /* __OF_IRQ_H */
index 1643d3761eb4134897b956bed7844b05814fd662..4e6d989c06dfe9fdfe2fdd5cd35cc4da22737a33 100644 (file)
 #include <linux/mod_devicetable.h>
 #include <linux/pm.h>
 #include <linux/of_device.h>
-
-/*
- * The of_platform_bus_type is a bus type used by drivers that do not
- * attach to a macio or similar bus but still use OF probing
- * mechanism
- */
-extern struct bus_type of_platform_bus_type;
+#include <linux/platform_device.h>
 
 /*
  * An of_platform_driver driver is attached to a basic of_device on
- * the "platform bus" (of_platform_bus_type).
+ * the "platform bus" (platform_bus_type).
  */
 struct of_platform_driver
 {
-       int     (*probe)(struct of_device* dev,
+       int     (*probe)(struct platform_device* dev,
                         const struct of_device_id *match);
-       int     (*remove)(struct of_device* dev);
+       int     (*remove)(struct platform_device* dev);
 
-       int     (*suspend)(struct of_device* dev, pm_message_t state);
-       int     (*resume)(struct of_device* dev);
-       int     (*shutdown)(struct of_device* dev);
+       int     (*suspend)(struct platform_device* dev, pm_message_t state);
+       int     (*resume)(struct platform_device* dev);
+       int     (*shutdown)(struct platform_device* dev);
 
        struct device_driver    driver;
+       struct platform_driver  platform_driver;
 };
 #define        to_of_platform_driver(drv) \
        container_of(drv,struct of_platform_driver, driver)
@@ -49,20 +44,30 @@ extern int of_register_driver(struct of_platform_driver *drv,
 extern void of_unregister_driver(struct of_platform_driver *drv);
 
 /* Platform drivers register/unregister */
-static inline int of_register_platform_driver(struct of_platform_driver *drv)
-{
-       return of_register_driver(drv, &of_platform_bus_type);
-}
-static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
-{
-       of_unregister_driver(drv);
-}
+extern int of_register_platform_driver(struct of_platform_driver *drv);
+extern void of_unregister_platform_driver(struct of_platform_driver *drv);
 
-#include <asm/of_platform.h>
-
-extern struct of_device *of_find_device_by_node(struct device_node *np);
+extern struct platform_device *of_device_alloc(struct device_node *np,
+                                        const char *bus_id,
+                                        struct device *parent);
+extern struct platform_device *of_find_device_by_node(struct device_node *np);
 
 extern int of_bus_type_init(struct bus_type *bus, const char *name);
+
+#if !defined(CONFIG_SPARC) /* SPARC has its own device registration method */
+/* Platform devices and busses creation */
+extern struct platform_device *of_platform_device_create(struct device_node *np,
+                                                  const char *bus_id,
+                                                  struct device *parent);
+
+/* pseudo "matches" value to not do deep probe */
+#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
+
+extern int of_platform_bus_probe(struct device_node *root,
+                                const struct of_device_id *matches,
+                                struct device *parent);
+#endif /* !CONFIG_SPARC */
+
 #endif /* CONFIG_OF_DEVICE */
 
 #endif /* _LINUX_OF_PLATFORM_H */
index 5f71ee8c0868d6d549ded2ca2ffbbfa837160584..9e3e70f78ae64c4077917d330923d9868e290cfc 100644 (file)
@@ -9,10 +9,15 @@
 #ifndef __LINUX_OF_SPI_H
 #define __LINUX_OF_SPI_H
 
-#include <linux/of.h>
 #include <linux/spi/spi.h>
 
-extern void of_register_spi_devices(struct spi_master *master,
-                                   struct device_node *np);
+#if defined(CONFIG_OF_SPI) || defined(CONFIG_OF_SPI_MODULE)
+extern void of_register_spi_devices(struct spi_master *master);
+#else
+static inline void of_register_spi_devices(struct spi_master *master)
+{
+       return;
+}
+#endif /* CONFIG_OF_SPI */
 
 #endif /* __LINUX_OF_SPI */
index 5b59f35dcb8fdd3ef12c4bc4f2cd5f439e63053b..6fa317801e1c72be3e6977b538f49da988be49ee 100644 (file)
@@ -128,7 +128,6 @@ enum pageflags {
 
        /* SLUB */
        PG_slub_frozen = PG_active,
-       PG_slub_debug = PG_error,
 };
 
 #ifndef __GENERATING_BOUNDS_H
@@ -215,7 +214,6 @@ PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
 __PAGEFLAG(SlobFree, slob_free)
 
 __PAGEFLAG(SlubFrozen, slub_frozen)
-__PAGEFLAG(SlubDebug, slub_debug)
 
 /*
  * Private page markings that may be used by the filesystem that owns the page
index f26fda76b87fc66816f2fa286e97d760c545f165..b1d17956a1536ff9f1e913cc6f33410f2e54cfa8 100644 (file)
@@ -270,6 +270,8 @@ struct pci_dev {
        unsigned int    d1_support:1;   /* Low power state D1 is supported */
        unsigned int    d2_support:1;   /* Low power state D2 is supported */
        unsigned int    no_d1d2:1;      /* Only allow D0 and D3 */
+       unsigned int    mmio_always_on:1;       /* disallow turning off io/mem
+                                                  decoding during bar sizing */
        unsigned int    wakeup_prepared:1;
        unsigned int    d3_delay;       /* D3->D0 transition time in ms */
 
index 33145408f04508e2b10f451ccaa9bdff48486366..c81eec4d3c35118090be667157c056d2b0661d27 100644 (file)
 #define PCI_DEVICE_ID_JMICRON_JMB361   0x2361
 #define PCI_DEVICE_ID_JMICRON_JMB362   0x2362
 #define PCI_DEVICE_ID_JMICRON_JMB363   0x2363
+#define PCI_DEVICE_ID_JMICRON_JMB364   0x2364
 #define PCI_DEVICE_ID_JMICRON_JMB365   0x2365
 #define PCI_DEVICE_ID_JMICRON_JMB366   0x2366
 #define PCI_DEVICE_ID_JMICRON_JMB368   0x2368
+#define PCI_DEVICE_ID_JMICRON_JMB369   0x2369
 #define PCI_DEVICE_ID_JMICRON_JMB38X_SD        0x2381
 #define PCI_DEVICE_ID_JMICRON_JMB38X_MMC 0x2382
 #define PCI_DEVICE_ID_JMICRON_JMB38X_MS        0x2383
 #define PCI_DEVICE_ID_RME_DIGI32       0x9896
 #define PCI_DEVICE_ID_RME_DIGI32_PRO   0x9897
 #define PCI_DEVICE_ID_RME_DIGI32_8     0x9898
+
+#define PCI_VENDOR_ID_XEN              0x5853
+#define PCI_DEVICE_ID_XEN_PLATFORM     0x0001
index 5d0266d94985c65acbd8b13a41961964cdde4a72..716f99b682c1a57fb3b6f1f72e90aec3982ca5fd 100644 (file)
@@ -214,8 +214,9 @@ struct perf_event_attr {
                                 *  See also PERF_RECORD_MISC_EXACT_IP
                                 */
                                precise_ip     :  2, /* skid constraint       */
+                               mmap_data      :  1, /* non-exec mmap data    */
 
-                               __reserved_1   : 47;
+                               __reserved_1   : 46;
 
        union {
                __u32           wakeup_events;    /* wakeup every n events */
@@ -461,6 +462,7 @@ enum perf_callchain_context {
 
 #ifdef CONFIG_PERF_EVENTS
 # include <asm/perf_event.h>
+# include <asm/local64.h>
 #endif
 
 struct perf_guest_info_callbacks {
@@ -531,14 +533,16 @@ struct hw_perf_event {
                        struct hrtimer  hrtimer;
                };
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-               /* breakpoint */
-               struct arch_hw_breakpoint       info;
+               struct { /* breakpoint */
+                       struct arch_hw_breakpoint       info;
+                       struct list_head                bp_list;
+               };
 #endif
        };
-       atomic64_t                      prev_count;
+       local64_t                       prev_count;
        u64                             sample_period;
        u64                             last_period;
-       atomic64_t                      period_left;
+       local64_t                       period_left;
        u64                             interrupts;
 
        u64                             freq_time_stamp;
@@ -548,7 +552,10 @@ struct hw_perf_event {
 
 struct perf_event;
 
-#define PERF_EVENT_TXN_STARTED 1
+/*
+ * Common implementation detail of pmu::{start,commit,cancel}_txn
+ */
+#define PERF_EVENT_TXN 0x1
 
 /**
  * struct pmu - generic performance monitoring unit
@@ -562,14 +569,28 @@ struct pmu {
        void (*unthrottle)              (struct perf_event *event);
 
        /*
-        * group events scheduling is treated as a transaction,
-        * add group events as a whole and perform one schedulability test.
-        * If test fails, roll back the whole group
+        * Group events scheduling is treated as a transaction, add group
+        * events as a whole and perform one schedulability test. If the test
+        * fails, roll back the whole group
         */
 
+       /*
+        * Start the transaction, after this ->enable() doesn't need
+        * to do schedulability tests.
+        */
        void (*start_txn)       (const struct pmu *pmu);
-       void (*cancel_txn)      (const struct pmu *pmu);
+       /*
+        * If ->start_txn() disabled the ->enable() schedulability test
+        * then ->commit_txn() is required to perform one. On success
+        * the transaction is closed. On error the transaction is kept
+        * open until ->cancel_txn() is called.
+        */
        int  (*commit_txn)      (const struct pmu *pmu);
+       /*
+        * Will cancel the transaction, assumes ->disable() is called for
+        * each successfull ->enable() during the transaction.
+        */
+       void (*cancel_txn)      (const struct pmu *pmu);
 };
 
 /**
@@ -584,7 +605,9 @@ enum perf_event_active_state {
 
 struct file;
 
-struct perf_mmap_data {
+#define PERF_BUFFER_WRITABLE           0x01
+
+struct perf_buffer {
        atomic_t                        refcount;
        struct rcu_head                 rcu_head;
 #ifdef CONFIG_PERF_USE_VMALLOC
@@ -650,7 +673,8 @@ struct perf_event {
 
        enum perf_event_active_state    state;
        unsigned int                    attach_state;
-       atomic64_t                      count;
+       local64_t                       count;
+       atomic64_t                      child_count;
 
        /*
         * These are the total time in nanoseconds that the event
@@ -709,7 +733,7 @@ struct perf_event {
        atomic_t                        mmap_count;
        int                             mmap_locked;
        struct user_struct              *mmap_user;
-       struct perf_mmap_data           *data;
+       struct perf_buffer              *buffer;
 
        /* poll related */
        wait_queue_head_t               waitq;
@@ -807,7 +831,7 @@ struct perf_cpu_context {
 
 struct perf_output_handle {
        struct perf_event               *event;
-       struct perf_mmap_data           *data;
+       struct perf_buffer              *buffer;
        unsigned long                   wakeup;
        unsigned long                   size;
        void                            *addr;
@@ -910,8 +934,10 @@ extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX];
 
 extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64);
 
-extern void
-perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip);
+#ifndef perf_arch_fetch_caller_regs
+static inline void
+perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip) { }
+#endif
 
 /*
  * Take a snapshot of the regs. Skip ip and frame pointer to
@@ -921,31 +947,11 @@ perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip);
  * - bp for callchains
  * - eflags, for future purposes, just in case
  */
-static inline void perf_fetch_caller_regs(struct pt_regs *regs, int skip)
+static inline void perf_fetch_caller_regs(struct pt_regs *regs)
 {
-       unsigned long ip;
-
        memset(regs, 0, sizeof(*regs));
 
-       switch (skip) {
-       case 1 :
-               ip = CALLER_ADDR0;
-               break;
-       case 2 :
-               ip = CALLER_ADDR1;
-               break;
-       case 3 :
-               ip = CALLER_ADDR2;
-               break;
-       case 4:
-               ip = CALLER_ADDR3;
-               break;
-       /* No need to support further for now */
-       default:
-               ip = 0;
-       }
-
-       return perf_arch_fetch_caller_regs(regs, ip, skip);
+       perf_arch_fetch_caller_regs(regs, CALLER_ADDR0);
 }
 
 static inline void
@@ -955,21 +961,14 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr)
                struct pt_regs hot_regs;
 
                if (!regs) {
-                       perf_fetch_caller_regs(&hot_regs, 1);
+                       perf_fetch_caller_regs(&hot_regs);
                        regs = &hot_regs;
                }
                __perf_sw_event(event_id, nr, nmi, regs, addr);
        }
 }
 
-extern void __perf_event_mmap(struct vm_area_struct *vma);
-
-static inline void perf_event_mmap(struct vm_area_struct *vma)
-{
-       if (vma->vm_flags & VM_EXEC)
-               __perf_event_mmap(vma);
-}
-
+extern void perf_event_mmap(struct vm_area_struct *vma);
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
 extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
@@ -1001,7 +1000,7 @@ static inline bool perf_paranoid_kernel(void)
 extern void perf_event_init(void);
 extern void perf_tp_event(u64 addr, u64 count, void *record,
                          int entry_size, struct pt_regs *regs,
-                         struct hlist_head *head);
+                         struct hlist_head *head, int rctx);
 extern void perf_bp_event(struct perf_event *event, void *data);
 
 #ifndef perf_misc_flags
@@ -1068,7 +1067,7 @@ static inline void perf_event_disable(struct perf_event *event)           { }
 #define perf_cpu_notifier(fn)                                  \
 do {                                                           \
        static struct notifier_block fn##_nb __cpuinitdata =    \
-               { .notifier_call = fn, .priority = 20 };        \
+               { .notifier_call = fn, .priority = CPU_PRI_PERF }; \
        fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE,             \
                (void *)(unsigned long)smp_processor_id());     \
        fn(&fn##_nb, (unsigned long)CPU_STARTING,               \
index 5417944d3687758bdfbb286633457258fd88a913..d7ecad0093bbd6767fdd3ed7df03bf249a9de9a0 100644 (file)
@@ -43,10 +43,64 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u
 extern int platform_get_irq_byname(struct platform_device *, const char *);
 extern int platform_add_devices(struct platform_device **, int);
 
-extern struct platform_device *platform_device_register_simple(const char *, int id,
-                                       const struct resource *, unsigned int);
-extern struct platform_device *platform_device_register_data(struct device *,
-               const char *, int, const void *, size_t);
+extern struct platform_device *platform_device_register_resndata(
+               struct device *parent, const char *name, int id,
+               const struct resource *res, unsigned int num,
+               const void *data, size_t size);
+
+/**
+ * platform_device_register_simple - add a platform-level device and its resources
+ * @name: base name of the device we're adding
+ * @id: instance id
+ * @res: set of resources that needs to be allocated for the device
+ * @num: number of resources
+ *
+ * This function creates a simple platform device that requires minimal
+ * resource and memory management. Canned release function freeing memory
+ * allocated for the device allows drivers using such devices to be
+ * unloaded without waiting for the last reference to the device to be
+ * dropped.
+ *
+ * This interface is primarily intended for use with legacy drivers which
+ * probe hardware directly.  Because such drivers create sysfs device nodes
+ * themselves, rather than letting system infrastructure handle such device
+ * enumeration tasks, they don't fully conform to the Linux driver model.
+ * In particular, when such drivers are built as modules, they can't be
+ * "hotplugged".
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
+ */
+static inline struct platform_device *platform_device_register_simple(
+               const char *name, int id,
+               const struct resource *res, unsigned int num)
+{
+       return platform_device_register_resndata(NULL, name, id,
+                       res, num, NULL, 0);
+}
+
+/**
+ * platform_device_register_data - add a platform-level device with platform-specific data
+ * @parent: parent device for the device we're adding
+ * @name: base name of the device we're adding
+ * @id: instance id
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * This function creates a simple platform device that requires minimal
+ * resource and memory management. Canned release function freeing memory
+ * allocated for the device allows drivers using such devices to be
+ * unloaded without waiting for the last reference to the device to be
+ * dropped.
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
+ */
+static inline struct platform_device *platform_device_register_data(
+               struct device *parent, const char *name, int id,
+               const void *data, size_t size)
+{
+       return platform_device_register_resndata(parent, name, id,
+                       NULL, 0, data, size);
+}
 
 extern struct platform_device *platform_device_alloc(const char *name, int id);
 extern int platform_device_add_resources(struct platform_device *pdev,
index b653b4aaa8a6332c8d783f2cd9afb7c8882028b4..9fbc54a2585d42cb9276adf2c2d168f53e883f63 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/seqlock.h>
 #include <linux/lockdep.h>
 #include <linux/completion.h>
+#include <linux/debugobjects.h>
 
 #ifdef CONFIG_RCU_TORTURE_TEST
 extern int rcutorture_runnable; /* for sysctl */
@@ -79,6 +80,16 @@ extern void rcu_init(void);
        (ptr)->next = NULL; (ptr)->func = NULL; \
 } while (0)
 
+/*
+ * init_rcu_head_on_stack()/destroy_rcu_head_on_stack() are needed for dynamic
+ * initialization and destruction of rcu_head on the stack. rcu_head structures
+ * allocated dynamically in the heap or defined statically don't need any
+ * initialization.
+ */
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+extern void init_rcu_head_on_stack(struct rcu_head *head);
+extern void destroy_rcu_head_on_stack(struct rcu_head *head);
+#else /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 static inline void init_rcu_head_on_stack(struct rcu_head *head)
 {
 }
@@ -86,6 +97,7 @@ static inline void init_rcu_head_on_stack(struct rcu_head *head)
 static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
 {
 }
+#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
@@ -517,4 +529,74 @@ extern void call_rcu(struct rcu_head *head,
 extern void call_rcu_bh(struct rcu_head *head,
                        void (*func)(struct rcu_head *head));
 
+/*
+ * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
+ * by call_rcu() and rcu callback execution, and are therefore not part of the
+ * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors.
+ */
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+# define STATE_RCU_HEAD_READY  0
+# define STATE_RCU_HEAD_QUEUED 1
+
+extern struct debug_obj_descr rcuhead_debug_descr;
+
+static inline void debug_rcu_head_queue(struct rcu_head *head)
+{
+       debug_object_activate(head, &rcuhead_debug_descr);
+       debug_object_active_state(head, &rcuhead_debug_descr,
+                                 STATE_RCU_HEAD_READY,
+                                 STATE_RCU_HEAD_QUEUED);
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+       debug_object_active_state(head, &rcuhead_debug_descr,
+                                 STATE_RCU_HEAD_QUEUED,
+                                 STATE_RCU_HEAD_READY);
+       debug_object_deactivate(head, &rcuhead_debug_descr);
+}
+#else  /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+static inline void debug_rcu_head_queue(struct rcu_head *head)
+{
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+}
+#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+
+#ifndef CONFIG_PROVE_RCU
+#define __do_rcu_dereference_check(c) do { } while (0)
+#endif /* #ifdef CONFIG_PROVE_RCU */
+
+#define __rcu_dereference_index_check(p, c) \
+       ({ \
+               typeof(p) _________p1 = ACCESS_ONCE(p); \
+               __do_rcu_dereference_check(c); \
+               smp_read_barrier_depends(); \
+               (_________p1); \
+       })
+
+/**
+ * rcu_dereference_index_check() - rcu_dereference for indices with debug checking
+ * @p: The pointer to read, prior to dereferencing
+ * @c: The conditions under which the dereference will take place
+ *
+ * Similar to rcu_dereference_check(), but omits the sparse checking.
+ * This allows rcu_dereference_index_check() to be used on integers,
+ * which can then be used as array indices.  Attempting to use
+ * rcu_dereference_check() on an integer will give compiler warnings
+ * because the sparse address-space mechanism relies on dereferencing
+ * the RCU-protected pointer.  Dereferencing integers is not something
+ * that even gcc will put up with.
+ *
+ * Note that this function does not implicitly check for RCU read-side
+ * critical sections.  If this function gains lots of uses, it might
+ * make sense to provide versions for each flavor of RCU, but it does
+ * not make sense as of early 2010.
+ */
+#define rcu_dereference_index_check(p, c) \
+       __rcu_dereference_index_check((p), (c))
+
 #endif /* __LINUX_RCUPDATE_H */
index 0478888c6899d3c59a1649d38dfdd58030f14918..9591907c4f79262e82089cfa5c1f1cae502d56e0 100644 (file)
@@ -272,19 +272,10 @@ extern int runqueue_is_locked(int cpu);
 
 extern cpumask_var_t nohz_cpu_mask;
 #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
-extern int select_nohz_load_balancer(int cpu);
-extern int get_nohz_load_balancer(void);
-extern int nohz_ratelimit(int cpu);
+extern void select_nohz_load_balancer(int stop_tick);
+extern int get_nohz_timer_target(void);
 #else
-static inline int select_nohz_load_balancer(int cpu)
-{
-       return 0;
-}
-
-static inline int nohz_ratelimit(int cpu)
-{
-       return 0;
-}
+static inline void select_nohz_load_balancer(int stop_tick) { }
 #endif
 
 /*
@@ -316,20 +307,16 @@ extern void scheduler_tick(void);
 
 extern void sched_show_task(struct task_struct *p);
 
-#ifdef CONFIG_DETECT_SOFTLOCKUP
-extern void softlockup_tick(void);
+#ifdef CONFIG_LOCKUP_DETECTOR
 extern void touch_softlockup_watchdog(void);
 extern void touch_softlockup_watchdog_sync(void);
 extern void touch_all_softlockup_watchdogs(void);
-extern int proc_dosoftlockup_thresh(struct ctl_table *table, int write,
-                                   void __user *buffer,
-                                   size_t *lenp, loff_t *ppos);
+extern int proc_dowatchdog_thresh(struct ctl_table *table, int write,
+                                 void __user *buffer,
+                                 size_t *lenp, loff_t *ppos);
 extern unsigned int  softlockup_panic;
 extern int softlockup_thresh;
 #else
-static inline void softlockup_tick(void)
-{
-}
 static inline void touch_softlockup_watchdog(void)
 {
 }
@@ -805,7 +792,7 @@ enum cpu_idle_type {
 #define SD_POWERSAVINGS_BALANCE        0x0100  /* Balance for power savings */
 #define SD_SHARE_PKG_RESOURCES 0x0200  /* Domain members share cpu pkg resources */
 #define SD_SERIALIZE           0x0400  /* Only a single load balancing instance */
-
+#define SD_ASYM_PACKING                0x0800  /* Place busy groups earlier in the domain */
 #define SD_PREFER_SIBLING      0x1000  /* Prefer to place tasks in a sibling domain */
 
 enum powersavings_balance_level {
@@ -840,6 +827,8 @@ static inline int sd_balance_for_package_power(void)
        return SD_PREFER_SIBLING;
 }
 
+extern int __weak arch_sd_sibiling_asym_packing(void);
+
 /*
  * Optimise SD flags for power savings:
  * SD_BALANCE_NEWIDLE helps agressive task consolidation and power savings.
@@ -861,7 +850,7 @@ struct sched_group {
         * CPU power of this group, SCHED_LOAD_SCALE being max power for a
         * single CPU.
         */
-       unsigned int cpu_power;
+       unsigned int cpu_power, cpu_power_orig;
 
        /*
         * The CPUs this group covers.
@@ -1697,6 +1686,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
 #define PF_EXITING     0x00000004      /* getting shut down */
 #define PF_EXITPIDONE  0x00000008      /* pi exit done on shut down */
 #define PF_VCPU                0x00000010      /* I'm a virtual CPU */
+#define PF_WQ_WORKER   0x00000020      /* I'm a workqueue worker */
 #define PF_FORKNOEXEC  0x00000040      /* forked but didn't exec */
 #define PF_MCE_PROCESS  0x00000080      /* process policy on mce errors */
 #define PF_SUPERPRIV   0x00000100      /* used super-user privileges */
@@ -1791,20 +1781,23 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
 #endif
 
 /*
- * Architectures can set this to 1 if they have specified
- * CONFIG_HAVE_UNSTABLE_SCHED_CLOCK in their arch Kconfig,
- * but then during bootup it turns out that sched_clock()
- * is reliable after all:
+ * Do not use outside of architecture code which knows its limitations.
+ *
+ * sched_clock() has no promise of monotonicity or bounded drift between
+ * CPUs, use (which you should not) requires disabling IRQs.
+ *
+ * Please use one of the three interfaces below.
  */
-#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
-extern int sched_clock_stable;
-#endif
-
-/* ftrace calls sched_clock() directly */
 extern unsigned long long notrace sched_clock(void);
+/*
+ * See the comment in kernel/sched_clock.c
+ */
+extern u64 cpu_clock(int cpu);
+extern u64 local_clock(void);
+extern u64 sched_clock_cpu(int cpu);
+
 
 extern void sched_clock_init(void);
-extern u64 sched_clock_cpu(int cpu);
 
 #ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
 static inline void sched_clock_tick(void)
@@ -1819,17 +1812,19 @@ static inline void sched_clock_idle_wakeup_event(u64 delta_ns)
 {
 }
 #else
+/*
+ * Architectures can set this to 1 if they have specified
+ * CONFIG_HAVE_UNSTABLE_SCHED_CLOCK in their arch Kconfig,
+ * but then during bootup it turns out that sched_clock()
+ * is reliable after all:
+ */
+extern int sched_clock_stable;
+
 extern void sched_clock_tick(void);
 extern void sched_clock_idle_sleep_event(void);
 extern void sched_clock_idle_wakeup_event(u64 delta_ns);
 #endif
 
-/*
- * For kernel-internal use: high-speed (but slightly incorrect) per-cpu
- * clock constructed from sched_clock():
- */
-extern unsigned long long cpu_clock(int cpu);
-
 extern unsigned long long
 task_sched_runtime(struct task_struct *task);
 extern unsigned long long thread_group_sched_runtime(struct task_struct *task);
@@ -2435,18 +2430,6 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)
 
 #endif /* CONFIG_SMP */
 
-#ifdef CONFIG_TRACING
-extern void
-__trace_special(void *__tr, void *__data,
-               unsigned long arg1, unsigned long arg2, unsigned long arg3);
-#else
-static inline void
-__trace_special(void *__tr, void *__data,
-               unsigned long arg1, unsigned long arg2, unsigned long arg3)
-{
-}
-#endif
-
 extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask);
 extern long sched_getaffinity(pid_t pid, struct cpumask *mask);
 
index 49d1247cd6d904b1bc8cfc38a2193bd179855c35..59260e21bdf55f4a7207bb1fee955af59750ac02 100644 (file)
@@ -268,7 +268,8 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
  * allocator where we care about the real place the memory allocation
  * request comes from.
  */
-#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || \
+       (defined(CONFIG_SLAB) && defined(CONFIG_TRACING))
 extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
 #define kmalloc_track_caller(size, flags) \
        __kmalloc_track_caller(size, flags, _RET_IP_)
@@ -286,7 +287,8 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
  * standard allocator where we care about the real place the memory
  * allocation request comes from.
  */
-#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || \
+       (defined(CONFIG_SLAB) && defined(CONFIG_TRACING))
 extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long);
 #define kmalloc_node_track_caller(size, flags, node) \
        __kmalloc_node_track_caller(size, flags, node, \
index 1812dac8c496b8694d18b45c372b86c411cf0400..1acfa73ce2ac4597559c729301c2c6479ea49c7e 100644 (file)
@@ -14,7 +14,8 @@
 #include <asm/page.h>          /* kmalloc_sizes.h needs PAGE_SIZE */
 #include <asm/cache.h>         /* kmalloc_sizes.h needs L1_CACHE_BYTES */
 #include <linux/compiler.h>
-#include <linux/kmemtrace.h>
+
+#include <trace/events/kmem.h>
 
 #ifndef ARCH_KMALLOC_MINALIGN
 /*
diff --git a/include/linux/slow-work.h b/include/linux/slow-work.h
deleted file mode 100644 (file)
index 13337bf..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Worker thread pool for slow items, such as filesystem lookups or mkdirs
- *
- * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- *
- * See Documentation/slow-work.txt
- */
-
-#ifndef _LINUX_SLOW_WORK_H
-#define _LINUX_SLOW_WORK_H
-
-#ifdef CONFIG_SLOW_WORK
-
-#include <linux/sysctl.h>
-#include <linux/timer.h>
-
-struct slow_work;
-#ifdef CONFIG_SLOW_WORK_DEBUG
-struct seq_file;
-#endif
-
-/*
- * The operations used to support slow work items
- */
-struct slow_work_ops {
-       /* owner */
-       struct module *owner;
-
-       /* get a ref on a work item
-        * - return 0 if successful, -ve if not
-        */
-       int (*get_ref)(struct slow_work *work);
-
-       /* discard a ref to a work item */
-       void (*put_ref)(struct slow_work *work);
-
-       /* execute a work item */
-       void (*execute)(struct slow_work *work);
-
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       /* describe a work item for debugfs */
-       void (*desc)(struct slow_work *work, struct seq_file *m);
-#endif
-};
-
-/*
- * A slow work item
- * - A reference is held on the parent object by the thread pool when it is
- *   queued
- */
-struct slow_work {
-       struct module           *owner; /* the owning module */
-       unsigned long           flags;
-#define SLOW_WORK_PENDING      0       /* item pending (further) execution */
-#define SLOW_WORK_EXECUTING    1       /* item currently executing */
-#define SLOW_WORK_ENQ_DEFERRED 2       /* item enqueue deferred */
-#define SLOW_WORK_VERY_SLOW    3       /* item is very slow */
-#define SLOW_WORK_CANCELLING   4       /* item is being cancelled, don't enqueue */
-#define SLOW_WORK_DELAYED      5       /* item is struct delayed_slow_work with active timer */
-       const struct slow_work_ops *ops; /* operations table for this item */
-       struct list_head        link;   /* link in queue */
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       struct timespec         mark;   /* jiffies at which queued or exec begun */
-#endif
-};
-
-struct delayed_slow_work {
-       struct slow_work        work;
-       struct timer_list       timer;
-};
-
-/**
- * slow_work_init - Initialise a slow work item
- * @work: The work item to initialise
- * @ops: The operations to use to handle the slow work item
- *
- * Initialise a slow work item.
- */
-static inline void slow_work_init(struct slow_work *work,
-                                 const struct slow_work_ops *ops)
-{
-       work->flags = 0;
-       work->ops = ops;
-       INIT_LIST_HEAD(&work->link);
-}
-
-/**
- * slow_work_init - Initialise a delayed slow work item
- * @work: The work item to initialise
- * @ops: The operations to use to handle the slow work item
- *
- * Initialise a delayed slow work item.
- */
-static inline void delayed_slow_work_init(struct delayed_slow_work *dwork,
-                                         const struct slow_work_ops *ops)
-{
-       init_timer(&dwork->timer);
-       slow_work_init(&dwork->work, ops);
-}
-
-/**
- * vslow_work_init - Initialise a very slow work item
- * @work: The work item to initialise
- * @ops: The operations to use to handle the slow work item
- *
- * Initialise a very slow work item.  This item will be restricted such that
- * only a certain number of the pool threads will be able to execute items of
- * this type.
- */
-static inline void vslow_work_init(struct slow_work *work,
-                                  const struct slow_work_ops *ops)
-{
-       work->flags = 1 << SLOW_WORK_VERY_SLOW;
-       work->ops = ops;
-       INIT_LIST_HEAD(&work->link);
-}
-
-/**
- * slow_work_is_queued - Determine if a slow work item is on the work queue
- * work: The work item to test
- *
- * Determine if the specified slow-work item is on the work queue.  This
- * returns true if it is actually on the queue.
- *
- * If the item is executing and has been marked for requeue when execution
- * finishes, then false will be returned.
- *
- * Anyone wishing to wait for completion of execution can wait on the
- * SLOW_WORK_EXECUTING bit.
- */
-static inline bool slow_work_is_queued(struct slow_work *work)
-{
-       unsigned long flags = work->flags;
-       return flags & SLOW_WORK_PENDING && !(flags & SLOW_WORK_EXECUTING);
-}
-
-extern int slow_work_enqueue(struct slow_work *work);
-extern void slow_work_cancel(struct slow_work *work);
-extern int slow_work_register_user(struct module *owner);
-extern void slow_work_unregister_user(struct module *owner);
-
-extern int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
-                                    unsigned long delay);
-
-static inline void delayed_slow_work_cancel(struct delayed_slow_work *dwork)
-{
-       slow_work_cancel(&dwork->work);
-}
-
-extern bool slow_work_sleep_till_thread_needed(struct slow_work *work,
-                                              signed long *_timeout);
-
-#ifdef CONFIG_SYSCTL
-extern ctl_table slow_work_sysctls[];
-#endif
-
-#endif /* CONFIG_SLOW_WORK */
-#endif /* _LINUX_SLOW_WORK_H */
index 4ba59cfc1f7562c0bb8cb900c4f8d444554d25d5..6447a723ecb170b9c3fd4476e8a1c1016b2b69de 100644 (file)
 #include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/kobject.h>
-#include <linux/kmemtrace.h>
 #include <linux/kmemleak.h>
 
+#include <trace/events/kmem.h>
+
 enum stat_item {
        ALLOC_FASTPATH,         /* Allocation from cpu slab */
        ALLOC_SLOWPATH,         /* Allocation by getting a new cpu slab */
index 13ebb5413a7982c5fdd1153432794f39a708f362..a6bfd1367d2a8493cbe7534cddbc1e2841e12fa6 100644 (file)
@@ -167,7 +167,6 @@ extern struct trace_event_functions exit_syscall_print_funcs;
                .enter_event    = &event_enter_##sname,         \
                .exit_event     = &event_exit_##sname,          \
                .enter_fields   = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \
-               .exit_fields    = LIST_HEAD_INIT(__syscall_meta_##sname.exit_fields), \
        };
 
 #define SYSCALL_DEFINE0(sname)                                 \
@@ -182,7 +181,6 @@ extern struct trace_event_functions exit_syscall_print_funcs;
                .enter_event    = &event_enter__##sname,        \
                .exit_event     = &event_exit__##sname,         \
                .enter_fields   = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \
-               .exit_fields    = LIST_HEAD_INIT(__syscall_meta__##sname.exit_fields), \
        };                                                      \
        asmlinkage long sys_##sname(void)
 #else
index f2694eb4dd3dcb983ebaefd8f1e707b7130ed421..3c92121ba9afb3f75700e540e24c52f3aae8b974 100644 (file)
@@ -22,14 +22,8 @@ struct kobject;
 struct module;
 enum kobj_ns_type;
 
-/* FIXME
- * The *owner field is no longer used.
- * x86 tree has been cleaned up. The owner
- * attribute is still left for other arches.
- */
 struct attribute {
        const char              *name;
-       struct module           *owner;
        mode_t                  mode;
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
        struct lock_class_key   *key;
@@ -136,8 +130,8 @@ int __must_check sysfs_create_file(struct kobject *kobj,
                                   const struct attribute *attr);
 int __must_check sysfs_create_files(struct kobject *kobj,
                                   const struct attribute **attr);
-int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr,
-                                 mode_t mode);
+int __must_check sysfs_chmod_file(struct kobject *kobj,
+                                 const struct attribute *attr, mode_t mode);
 void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
 void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
 
@@ -225,7 +219,7 @@ static inline int sysfs_create_files(struct kobject *kobj,
 }
 
 static inline int sysfs_chmod_file(struct kobject *kobj,
-                                  struct attribute *attr, mode_t mode)
+                                  const struct attribute *attr, mode_t mode)
 {
        return 0;
 }
index ea3559f0b3f2cbac7e0373f51df471c133c23479..cb34e35fabac091f927184b786b0e3dd4550b3f7 100644 (file)
@@ -76,9 +76,25 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
                            const unsigned int min, const unsigned int sec);
 
 extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
+
+/*
+ * timespec_add_safe assumes both values are positive and checks
+ * for overflow. It will return TIME_T_MAX if the reutrn would be
+ * smaller then either of the arguments.
+ */
 extern struct timespec timespec_add_safe(const struct timespec lhs,
                                         const struct timespec rhs);
 
+
+static inline struct timespec timespec_add(struct timespec lhs,
+                                               struct timespec rhs)
+{
+       struct timespec ts_delta;
+       set_normalized_timespec(&ts_delta, lhs.tv_sec + rhs.tv_sec,
+                               lhs.tv_nsec + rhs.tv_nsec);
+       return ts_delta;
+}
+
 /*
  * sub = lhs - rhs, in normalized form
  */
@@ -97,8 +113,6 @@ static inline struct timespec timespec_sub(struct timespec lhs,
 #define timespec_valid(ts) \
        (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
 
-extern struct timespec xtime;
-extern struct timespec wall_to_monotonic;
 extern seqlock_t xtime_lock;
 
 extern void read_persistent_clock(struct timespec *ts);
@@ -110,7 +124,8 @@ extern int timekeeping_suspended;
 
 unsigned long get_seconds(void);
 struct timespec current_kernel_time(void);
-struct timespec __current_kernel_time(void); /* does not hold xtime_lock */
+struct timespec __current_kernel_time(void); /* does not take xtime_lock */
+struct timespec __get_wall_to_monotonic(void); /* does not take xtime_lock */
 struct timespec get_monotonic_coarse(void);
 
 #define CURRENT_TIME           (current_kernel_time())
index c44df50a05ab5a81e42b1a37299fb9e790298fc3..b572e432d2f361344a7de671d31035994e5c5d6d 100644 (file)
@@ -103,6 +103,7 @@ int arch_update_cpu_topology(void);
                                | 1*SD_SHARE_PKG_RESOURCES              \
                                | 0*SD_SERIALIZE                        \
                                | 0*SD_PREFER_SIBLING                   \
+                               | arch_sd_sibling_asym_packing()        \
                                ,                                       \
        .last_balance           = jiffies,                              \
        .balance_interval       = 1,                                    \
index 931078b73226a729f62b82938747c940b1593084..7802a243ee1372dfff07f1dd6c2b294abeddfb9c 100644 (file)
@@ -552,6 +552,9 @@ static inline void tty_audit_push_task(struct task_struct *tsk,
 }
 #endif
 
+/* tty_io.c */
+extern int __init tty_init(void);
+
 /* tty_ioctl.c */
 extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
                       unsigned int cmd, unsigned long arg);
index 227c2a585e4f326a4e3355fc01f34a1eb4901b03..de05e96e0a70587efd6a3043852c610796a1a140 100644 (file)
@@ -30,7 +30,7 @@ struct vm_struct {
        unsigned long           flags;
        struct page             **pages;
        unsigned int            nr_pages;
-       unsigned long           phys_addr;
+       phys_addr_t             phys_addr;
        void                    *caller;
 };
 
index 9466e860d8c2a6dd816da1f7363117ebd56291f5..4f9d277bcd9a5cd32ef35bc304bdbe3f6339a38a 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/linkage.h>
 #include <linux/bitops.h>
 #include <linux/lockdep.h>
+#include <linux/threads.h>
 #include <asm/atomic.h>
 
 struct workqueue_struct;
@@ -22,12 +23,59 @@ typedef void (*work_func_t)(struct work_struct *work);
  */
 #define work_data_bits(work) ((unsigned long *)(&(work)->data))
 
+enum {
+       WORK_STRUCT_PENDING_BIT = 0,    /* work item is pending execution */
+       WORK_STRUCT_CWQ_BIT     = 1,    /* data points to cwq */
+       WORK_STRUCT_LINKED_BIT  = 2,    /* next work is linked to this one */
+#ifdef CONFIG_DEBUG_OBJECTS_WORK
+       WORK_STRUCT_STATIC_BIT  = 3,    /* static initializer (debugobjects) */
+       WORK_STRUCT_COLOR_SHIFT = 4,    /* color for workqueue flushing */
+#else
+       WORK_STRUCT_COLOR_SHIFT = 3,    /* color for workqueue flushing */
+#endif
+
+       WORK_STRUCT_COLOR_BITS  = 4,
+
+       WORK_STRUCT_PENDING     = 1 << WORK_STRUCT_PENDING_BIT,
+       WORK_STRUCT_CWQ         = 1 << WORK_STRUCT_CWQ_BIT,
+       WORK_STRUCT_LINKED      = 1 << WORK_STRUCT_LINKED_BIT,
+#ifdef CONFIG_DEBUG_OBJECTS_WORK
+       WORK_STRUCT_STATIC      = 1 << WORK_STRUCT_STATIC_BIT,
+#else
+       WORK_STRUCT_STATIC      = 0,
+#endif
+
+       /*
+        * The last color is no color used for works which don't
+        * participate in workqueue flushing.
+        */
+       WORK_NR_COLORS          = (1 << WORK_STRUCT_COLOR_BITS) - 1,
+       WORK_NO_COLOR           = WORK_NR_COLORS,
+
+       /* special cpu IDs */
+       WORK_CPU_UNBOUND        = NR_CPUS,
+       WORK_CPU_NONE           = NR_CPUS + 1,
+       WORK_CPU_LAST           = WORK_CPU_NONE,
+
+       /*
+        * Reserve 7 bits off of cwq pointer w/ debugobjects turned
+        * off.  This makes cwqs aligned to 128 bytes which isn't too
+        * excessive while allowing 15 workqueue flush colors.
+        */
+       WORK_STRUCT_FLAG_BITS   = WORK_STRUCT_COLOR_SHIFT +
+                                 WORK_STRUCT_COLOR_BITS,
+
+       WORK_STRUCT_FLAG_MASK   = (1UL << WORK_STRUCT_FLAG_BITS) - 1,
+       WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
+       WORK_STRUCT_NO_CPU      = WORK_CPU_NONE << WORK_STRUCT_FLAG_BITS,
+
+       /* bit mask for work_busy() return values */
+       WORK_BUSY_PENDING       = 1 << 0,
+       WORK_BUSY_RUNNING       = 1 << 1,
+};
+
 struct work_struct {
        atomic_long_t data;
-#define WORK_STRUCT_PENDING 0          /* T if work item pending execution */
-#define WORK_STRUCT_STATIC  1          /* static initializer (debugobjects) */
-#define WORK_STRUCT_FLAG_MASK (3UL)
-#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
        struct list_head entry;
        work_func_t func;
 #ifdef CONFIG_LOCKDEP
@@ -35,8 +83,9 @@ struct work_struct {
 #endif
 };
 
-#define WORK_DATA_INIT()       ATOMIC_LONG_INIT(0)
-#define WORK_DATA_STATIC_INIT()        ATOMIC_LONG_INIT(2)
+#define WORK_DATA_INIT()       ATOMIC_LONG_INIT(WORK_STRUCT_NO_CPU)
+#define WORK_DATA_STATIC_INIT()        \
+       ATOMIC_LONG_INIT(WORK_STRUCT_NO_CPU | WORK_STRUCT_STATIC)
 
 struct delayed_work {
        struct work_struct work;
@@ -96,9 +145,14 @@ struct execute_work {
 #ifdef CONFIG_DEBUG_OBJECTS_WORK
 extern void __init_work(struct work_struct *work, int onstack);
 extern void destroy_work_on_stack(struct work_struct *work);
+static inline unsigned int work_static(struct work_struct *work)
+{
+       return *work_data_bits(work) & WORK_STRUCT_STATIC;
+}
 #else
 static inline void __init_work(struct work_struct *work, int onstack) { }
 static inline void destroy_work_on_stack(struct work_struct *work) { }
+static inline unsigned int work_static(struct work_struct *work) { return 0; }
 #endif
 
 /*
@@ -162,7 +216,7 @@ static inline void destroy_work_on_stack(struct work_struct *work) { }
  * @work: The work item in question
  */
 #define work_pending(work) \
-       test_bit(WORK_STRUCT_PENDING, work_data_bits(work))
+       test_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))
 
 /**
  * delayed_work_pending - Find out whether a delayable work item is currently
@@ -177,16 +231,56 @@ static inline void destroy_work_on_stack(struct work_struct *work) { }
  * @work: The work item in question
  */
 #define work_clear_pending(work) \
-       clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
+       clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))
+
+enum {
+       WQ_NON_REENTRANT        = 1 << 0, /* guarantee non-reentrance */
+       WQ_UNBOUND              = 1 << 1, /* not bound to any cpu */
+       WQ_FREEZEABLE           = 1 << 2, /* freeze during suspend */
+       WQ_RESCUER              = 1 << 3, /* has an rescue worker */
+       WQ_HIGHPRI              = 1 << 4, /* high priority */
+       WQ_CPU_INTENSIVE        = 1 << 5, /* cpu instensive workqueue */
+
+       WQ_MAX_ACTIVE           = 512,    /* I like 512, better ideas? */
+       WQ_MAX_UNBOUND_PER_CPU  = 4,      /* 4 * #cpus for unbound wq */
+       WQ_DFL_ACTIVE           = WQ_MAX_ACTIVE / 2,
+};
 
+/* unbound wq's aren't per-cpu, scale max_active according to #cpus */
+#define WQ_UNBOUND_MAX_ACTIVE  \
+       max_t(int, WQ_MAX_ACTIVE, num_possible_cpus() * WQ_MAX_UNBOUND_PER_CPU)
+
+/*
+ * System-wide workqueues which are always present.
+ *
+ * system_wq is the one used by schedule[_delayed]_work[_on]().
+ * Multi-CPU multi-threaded.  There are users which expect relatively
+ * short queue flush time.  Don't queue works which can run for too
+ * long.
+ *
+ * system_long_wq is similar to system_wq but may host long running
+ * works.  Queue flushing might take relatively long.
+ *
+ * system_nrt_wq is non-reentrant and guarantees that any given work
+ * item is never executed in parallel by multiple CPUs.  Queue
+ * flushing might take relatively long.
+ *
+ * system_unbound_wq is unbound workqueue.  Workers are not bound to
+ * any specific CPU, not concurrency managed, and all queued works are
+ * executed immediately as long as max_active limit is not reached and
+ * resources are available.
+ */
+extern struct workqueue_struct *system_wq;
+extern struct workqueue_struct *system_long_wq;
+extern struct workqueue_struct *system_nrt_wq;
+extern struct workqueue_struct *system_unbound_wq;
 
 extern struct workqueue_struct *
-__create_workqueue_key(const char *name, int singlethread,
-                      int freezeable, int rt, struct lock_class_key *key,
-                      const char *lock_name);
+__alloc_workqueue_key(const char *name, unsigned int flags, int max_active,
+                     struct lock_class_key *key, const char *lock_name);
 
 #ifdef CONFIG_LOCKDEP
-#define __create_workqueue(name, singlethread, freezeable, rt) \
+#define alloc_workqueue(name, flags, max_active)               \
 ({                                                             \
        static struct lock_class_key __key;                     \
        const char *__lock_name;                                \
@@ -196,20 +290,20 @@ __create_workqueue_key(const char *name, int singlethread,
        else                                                    \
                __lock_name = #name;                            \
                                                                \
-       __create_workqueue_key((name), (singlethread),          \
-                              (freezeable), (rt), &__key,      \
-                              __lock_name);                    \
+       __alloc_workqueue_key((name), (flags), (max_active),    \
+                             &__key, __lock_name);             \
 })
 #else
-#define __create_workqueue(name, singlethread, freezeable, rt) \
-       __create_workqueue_key((name), (singlethread), (freezeable), (rt), \
-                              NULL, NULL)
+#define alloc_workqueue(name, flags, max_active)               \
+       __alloc_workqueue_key((name), (flags), (max_active), NULL, NULL)
 #endif
 
-#define create_workqueue(name) __create_workqueue((name), 0, 0, 0)
-#define create_rt_workqueue(name) __create_workqueue((name), 0, 0, 1)
-#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0)
-#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0)
+#define create_workqueue(name)                                 \
+       alloc_workqueue((name), WQ_RESCUER, 1)
+#define create_freezeable_workqueue(name)                      \
+       alloc_workqueue((name), WQ_FREEZEABLE | WQ_UNBOUND | WQ_RESCUER, 1)
+#define create_singlethread_workqueue(name)                    \
+       alloc_workqueue((name), WQ_UNBOUND | WQ_RESCUER, 1)
 
 extern void destroy_workqueue(struct workqueue_struct *wq);
 
@@ -231,16 +325,19 @@ extern int schedule_delayed_work(struct delayed_work *work, unsigned long delay)
 extern int schedule_delayed_work_on(int cpu, struct delayed_work *work,
                                        unsigned long delay);
 extern int schedule_on_each_cpu(work_func_t func);
-extern int current_is_keventd(void);
 extern int keventd_up(void);
 
-extern void init_workqueues(void);
 int execute_in_process_context(work_func_t fn, struct execute_work *);
 
 extern int flush_work(struct work_struct *work);
-
 extern int cancel_work_sync(struct work_struct *work);
 
+extern void workqueue_set_max_active(struct workqueue_struct *wq,
+                                    int max_active);
+extern bool workqueue_congested(unsigned int cpu, struct workqueue_struct *wq);
+extern unsigned int work_cpu(struct work_struct *work);
+extern unsigned int work_busy(struct work_struct *work);
+
 /*
  * Kill off a pending schedule_delayed_work().  Note that the work callback
  * function may still be running on return from cancel_delayed_work(), unless
@@ -297,4 +394,15 @@ static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
 #else
 long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg);
 #endif /* CONFIG_SMP */
+
+#ifdef CONFIG_FREEZER
+extern void freeze_workqueues_begin(void);
+extern bool freeze_workqueues_busy(void);
+extern void thaw_workqueues(void);
+#endif /* CONFIG_FREEZER */
+
+#ifdef CONFIG_LOCKDEP
+int in_workqueue_context(struct workqueue_struct *wq);
+#endif
+
 #endif
index cfdd5af77dcc92d49eaada6ad6726c24e52cc81a..1c5088c9f7bf27c9fc94de30747703a893d49421 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef _LINUX_CISTPL_H
 #define _LINUX_CISTPL_H
 
+typedef unsigned char cisdata_t;
+
 #define CISTPL_NULL            0x00
 #define CISTPL_DEVICE          0x01
 #define CISTPL_LONGLINK_CB     0x02
index 57d8d0393567e11df947842ffcb906f4a8382262..68d8bde7e8d6e6649b554faeb3681cd87d68f777 100644 (file)
 #include <linux/interrupt.h>
 #endif
 
-/* For AccessConfigurationRegister */
-typedef struct conf_reg_t {
-    u_char     Function;
-    u_int      Action;
-    off_t      Offset;
-    u_int      Value;
-} conf_reg_t;
-
-/* Actions */
-#define CS_READ                1
-#define CS_WRITE       2
-
-/* for AdjustResourceInfo */
-/* Action field */
-#define REMOVE_MANAGED_RESOURCE                1
-#define ADD_MANAGED_RESOURCE           2
-
-
-typedef struct event_callback_args_t {
-       struct pcmcia_device    *client_handle;
-       void                    *client_data;
-} event_callback_args_t;
-
-/* For CardValues field */
-#define CV_OPTION_VALUE                0x01
-#define CV_STATUS_VALUE                0x02
-#define CV_PIN_REPLACEMENT     0x04
-#define CV_COPY_VALUE          0x08
-#define CV_EXT_STATUS          0x10
-
-/* For GetFirst/NextClient */
-typedef struct client_req_t {
-    socket_t   Socket;
-    u_int      Attributes;
-} client_req_t;
-
-#define CLIENT_THIS_SOCKET     0x01
-
 /* ModifyConfiguration */
 typedef struct modconf_t {
     u_int      Attributes;
@@ -94,43 +56,6 @@ typedef struct config_req_t {
 #define INT_CARDBUS            0x04
 #define INT_ZOOMED_VIDEO       0x08
 
-/* For RequestIO and ReleaseIO */
-typedef struct io_req_t {
-    u_int      BasePort1;
-    u_int      NumPorts1;
-    u_int      Attributes1;
-    u_int      BasePort2;
-    u_int      NumPorts2;
-    u_int      Attributes2;
-    u_int      IOAddrLines;
-} io_req_t;
-
-/* Attributes for RequestIO and ReleaseIO */
-#define IO_SHARED              0x01
-#define IO_FIRST_SHARED                0x02
-#define IO_FORCE_ALIAS_ACCESS  0x04
-#define IO_DATA_PATH_WIDTH     0x18
-#define IO_DATA_PATH_WIDTH_8   0x00
-#define IO_DATA_PATH_WIDTH_16  0x08
-#define IO_DATA_PATH_WIDTH_AUTO        0x10
-
-/* Bits in IRQInfo1 field */
-#define IRQ_NMI_ID             0x01
-#define IRQ_IOCK_ID            0x02
-#define IRQ_BERR_ID            0x04
-#define IRQ_VEND_ID            0x08
-#define IRQ_INFO2_VALID                0x10
-#define IRQ_LEVEL_ID           0x20
-#define IRQ_PULSE_ID           0x40
-#define IRQ_SHARE_ID           0x80
-
-typedef struct eventmask_t {
-    u_int      Attributes;
-    u_int      EventMask;
-} eventmask_t;
-
-#define CONF_EVENT_MASK_VALID  0x01
-
 /* Configuration registers present */
 #define PRESENT_OPTION         0x001
 #define PRESENT_STATUS         0x002
@@ -143,18 +68,6 @@ typedef struct eventmask_t {
 #define PRESENT_IOBASE_3       0x100
 #define PRESENT_IOSIZE         0x200
 
-/* For GetMemPage, MapMemPage */
-typedef struct memreq_t {
-    u_int      CardOffset;
-    page_t     Page;
-} memreq_t;
-
-/* For ModifyWindow */
-typedef struct modwin_t {
-    u_int      Attributes;
-    u_int      AccessSpeed;
-} modwin_t;
-
 /* For RequestWindow */
 typedef struct win_req_t {
     u_int      Attributes;
@@ -164,61 +77,19 @@ typedef struct win_req_t {
 } win_req_t;
 
 /* Attributes for RequestWindow */
-#define WIN_ADDR_SPACE         0x0001
-#define WIN_ADDR_SPACE_MEM     0x0000
-#define WIN_ADDR_SPACE_IO      0x0001
-#define WIN_MEMORY_TYPE                0x0002
-#define WIN_MEMORY_TYPE_CM     0x0000
-#define WIN_MEMORY_TYPE_AM     0x0002
-#define WIN_ENABLE             0x0004
-#define WIN_DATA_WIDTH         0x0018
-#define WIN_DATA_WIDTH_8       0x0000
-#define WIN_DATA_WIDTH_16      0x0008
-#define WIN_DATA_WIDTH_32      0x0010
-#define WIN_PAGED              0x0020
-#define WIN_SHARED             0x0040
-#define WIN_FIRST_SHARED       0x0080
-#define WIN_USE_WAIT           0x0100
-#define WIN_STRICT_ALIGN       0x0200
-#define WIN_MAP_BELOW_1MB      0x0400
-#define WIN_PREFETCH           0x0800
-#define WIN_CACHEABLE          0x1000
-#define WIN_BAR_MASK           0xe000
-#define WIN_BAR_SHIFT          13
-
-typedef struct error_info_t {
-    int                func;
-    int                retcode;
-} error_info_t;
-
-/* Flag to bind to all functions */
-#define BIND_FN_ALL    0xff
-
-/* Events */
-#define CS_EVENT_PRI_LOW               0
-#define CS_EVENT_PRI_HIGH              1
-
-#define CS_EVENT_WRITE_PROTECT         0x000001
-#define CS_EVENT_CARD_LOCK             0x000002
-#define CS_EVENT_CARD_INSERTION                0x000004
-#define CS_EVENT_CARD_REMOVAL          0x000008
-#define CS_EVENT_BATTERY_DEAD          0x000010
-#define CS_EVENT_BATTERY_LOW           0x000020
-#define CS_EVENT_READY_CHANGE          0x000040
-#define CS_EVENT_CARD_DETECT           0x000080
-#define CS_EVENT_RESET_REQUEST         0x000100
-#define CS_EVENT_RESET_PHYSICAL                0x000200
-#define CS_EVENT_CARD_RESET            0x000400
-#define CS_EVENT_REGISTRATION_COMPLETE 0x000800
-#define CS_EVENT_PM_SUSPEND            0x002000
-#define CS_EVENT_PM_RESUME             0x004000
-#define CS_EVENT_INSERTION_REQUEST     0x008000
-#define CS_EVENT_EJECTION_REQUEST      0x010000
-#define CS_EVENT_MTD_REQUEST           0x020000
-#define CS_EVENT_ERASE_COMPLETE                0x040000
-#define CS_EVENT_REQUEST_ATTENTION     0x080000
-#define CS_EVENT_CB_DETECT             0x100000
-#define CS_EVENT_3VCARD                        0x200000
-#define CS_EVENT_XVCARD                        0x400000
+#define WIN_MEMORY_TYPE_CM     0x00 /* default */
+#define WIN_MEMORY_TYPE_AM     0x20 /* MAP_ATTRIB */
+#define WIN_DATA_WIDTH_8       0x00 /* default */
+#define WIN_DATA_WIDTH_16      0x02 /* MAP_16BIT */
+#define WIN_ENABLE             0x01 /* MAP_ACTIVE */
+#define WIN_USE_WAIT           0x40 /* MAP_USE_WAIT */
+
+#define WIN_FLAGS_MAP          0x63 /* MAP_ATTRIB | MAP_16BIT | MAP_ACTIVE |
+                                       MAP_USE_WAIT */
+#define WIN_FLAGS_REQ          0x1c /* mapping to socket->win[i]:
+                                       0x04 -> 0
+                                       0x08 -> 1
+                                       0x0c -> 2
+                                       0x10 -> 3 */
 
 #endif /* _LINUX_CS_H */
diff --git a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h
deleted file mode 100644 (file)
index f5e3b83..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * cs_types.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
- *
- * (C) 1999             David A. Hinds
- */
-
-#ifndef _LINUX_CS_TYPES_H
-#define _LINUX_CS_TYPES_H
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-
-typedef u_short        socket_t;
-typedef u_int  event_t;
-typedef u_char cisdata_t;
-typedef u_short        page_t;
-
-typedef unsigned long window_handle_t;
-
-struct region_t;
-typedef struct region_t *memory_handle_t;
-
-#ifndef DEV_NAME_LEN
-#define DEV_NAME_LEN 32
-#endif
-
-typedef char dev_info_t[DEV_NAME_LEN];
-
-#endif /* _LINUX_CS_TYPES_H */
index c180165fbd3e2a577b16aaa50747efc8dd81a9a8..70c58ed2278c43f80a355b7aac9c30f40bd2a315 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/mod_devicetable.h>
 #endif
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/device_id.h>
 
 #ifdef __KERNEL__
@@ -37,6 +36,8 @@ struct pcmcia_device;
 struct config_t;
 struct net_device;
 
+typedef struct resource *window_handle_t;
+
 /* dynamic device IDs for PCMCIA device drivers. See
  * Documentation/pcmcia/driver.txt for details.
 */
@@ -62,6 +63,17 @@ struct pcmcia_driver {
 int pcmcia_register_driver(struct pcmcia_driver *driver);
 void pcmcia_unregister_driver(struct pcmcia_driver *driver);
 
+/* for struct resource * array embedded in struct pcmcia_device */
+enum {
+       PCMCIA_IOPORT_0,
+       PCMCIA_IOPORT_1,
+       PCMCIA_IOMEM_0,
+       PCMCIA_IOMEM_1,
+       PCMCIA_IOMEM_2,
+       PCMCIA_IOMEM_3,
+       PCMCIA_NUM_RESOURCES,
+};
+
 struct pcmcia_device {
        /* the socket and the device_no [for multifunction devices]
           uniquely define a pcmcia_device */
@@ -79,13 +91,14 @@ struct pcmcia_device {
        struct list_head        socket_device_list;
 
        /* deprecated, will be cleaned up soon */
-       u_int                   open;
-       io_req_t                io;
        config_req_t            conf;
        window_handle_t         win;
 
        /* device setup */
        unsigned int            irq;
+       struct resource         *resource[PCMCIA_NUM_RESOURCES];
+
+       unsigned int            io_lines; /* number of I/O lines */
 
        /* Is the device suspended? */
        u16                     suspended:1;
@@ -117,13 +130,9 @@ struct pcmcia_device {
        u64                     dma_mask;
        struct device           dev;
 
-#ifdef CONFIG_PCMCIA_IOCTL
-       /* device driver wanted by cardmgr */
-       struct pcmcia_driver    *cardmgr;
-#endif
-
        /* data private to drivers */
        void                    *priv;
+       unsigned int            open;
 };
 
 #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
@@ -178,11 +187,11 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *p_dev);
 int pcmcia_reset_card(struct pcmcia_socket *skt);
 
 /* CIS config */
-int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
-                                        conf_reg_t *reg);
+int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val);
+int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val);
 
 /* device configuration */
-int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
+int pcmcia_request_io(struct pcmcia_device *p_dev);
 
 int __must_check
 __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
@@ -204,215 +213,27 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req,
                          window_handle_t *wh);
 int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t win);
 int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t win,
-                       memreq_t *req);
+                       unsigned int offset);
 
 int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
 void pcmcia_disable_device(struct pcmcia_device *p_dev);
 
-#endif /* __KERNEL__ */
-
-
+/* IO ports */
+#define IO_DATA_PATH_WIDTH     0x18
+#define IO_DATA_PATH_WIDTH_8   0x00
+#define IO_DATA_PATH_WIDTH_16  0x08
+#define IO_DATA_PATH_WIDTH_AUTO        0x10
 
-/* Below, there are only definitions which are used by
- * - the PCMCIA ioctl
- * - deprecated PCMCIA userspace tools only
- *
- * here be dragons ... here be dragons ... here be dragons ... here be drag
- */
-
-#if defined(CONFIG_PCMCIA_IOCTL) || !defined(__KERNEL__)
-
-#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \
-       defined(__bfin__)
-/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
-typedef u_int   ioaddr_t;
-#else
-typedef u_short        ioaddr_t;
-#endif
+/* convert flag found in cfgtable to data path width parameter */
+static inline int pcmcia_io_cfg_data_width(unsigned int flags)
+{
+       if (!(flags & CISTPL_IO_8BIT))
+               return IO_DATA_PATH_WIDTH_16;
+       if (!(flags & CISTPL_IO_16BIT))
+               return IO_DATA_PATH_WIDTH_8;
+       return IO_DATA_PATH_WIDTH_AUTO;
+}
 
-/* for AdjustResourceInfo */
-typedef struct adjust_t {
-       u_int                   Action;
-       u_int                   Resource;
-       u_int                   Attributes;
-       union {
-               struct memory {
-                       u_long          Base;
-                       u_long          Size;
-               } memory;
-               struct io {
-                       ioaddr_t        BasePort;
-                       ioaddr_t        NumPorts;
-                       u_int           IOAddrLines;
-               } io;
-               struct irq {
-                       u_int           IRQ;
-               } irq;
-       } resource;
-} adjust_t;
-
-/* Action field */
-#define REMOVE_MANAGED_RESOURCE                1
-#define ADD_MANAGED_RESOURCE           2
-#define GET_FIRST_MANAGED_RESOURCE     3
-#define GET_NEXT_MANAGED_RESOURCE      4
-/* Resource field */
-#define RES_MEMORY_RANGE               1
-#define RES_IO_RANGE                   2
-#define RES_IRQ                                3
-/* Attribute field */
-#define RES_IRQ_TYPE                   0x03
-#define RES_IRQ_TYPE_EXCLUSIVE         0
-#define RES_IRQ_TYPE_TIME              1
-#define RES_IRQ_TYPE_DYNAMIC           2
-#define RES_IRQ_CSC                    0x04
-#define RES_SHARED                     0x08
-#define RES_RESERVED                   0x10
-#define RES_ALLOCATED                  0x20
-#define RES_REMOVED                    0x40
-
-
-typedef struct tuple_parse_t {
-       tuple_t                 tuple;
-       cisdata_t               data[255];
-       cisparse_t              parse;
-} tuple_parse_t;
-
-typedef struct win_info_t {
-       window_handle_t         handle;
-       win_req_t               window;
-       memreq_t                map;
-} win_info_t;
-
-typedef struct bind_info_t {
-       dev_info_t              dev_info;
-       u_char                  function;
-       struct pcmcia_device    *instance;
-       char                    name[DEV_NAME_LEN];
-       u_short                 major, minor;
-       void                    *next;
-} bind_info_t;
-
-typedef struct mtd_info_t {
-       dev_info_t              dev_info;
-       u_int                   Attributes;
-       u_int                   CardOffset;
-} mtd_info_t;
-
-typedef struct region_info_t {
-       u_int                   Attributes;
-       u_int                   CardOffset;
-       u_int                   RegionSize;
-       u_int                   AccessSpeed;
-       u_int                   BlockSize;
-       u_int                   PartMultiple;
-       u_char                  JedecMfr, JedecInfo;
-       memory_handle_t         next;
-} region_info_t;
-
-#define REGION_TYPE            0x0001
-#define REGION_TYPE_CM         0x0000
-#define REGION_TYPE_AM         0x0001
-#define REGION_PREFETCH                0x0008
-#define REGION_CACHEABLE       0x0010
-#define REGION_BAR_MASK                0xe000
-#define REGION_BAR_SHIFT       13
-
-/* For ReplaceCIS */
-typedef struct cisdump_t {
-       u_int                   Length;
-       cisdata_t               Data[CISTPL_MAX_CIS_SIZE];
-} cisdump_t;
-
-/* for GetConfigurationInfo */
-typedef struct config_info_t {
-       u_char                  Function;
-       u_int                   Attributes;
-       u_int                   Vcc, Vpp1, Vpp2;
-       u_int                   IntType;
-       u_int                   ConfigBase;
-       u_char                  Status, Pin, Copy, Option, ExtStatus;
-       u_int                   Present;
-       u_int                   CardValues;
-       u_int                   AssignedIRQ;
-       u_int                   IRQAttributes;
-       ioaddr_t                BasePort1;
-       ioaddr_t                NumPorts1;
-       u_int                   Attributes1;
-       ioaddr_t                BasePort2;
-       ioaddr_t                NumPorts2;
-       u_int                   Attributes2;
-       u_int                   IOAddrLines;
-} config_info_t;
-
-/* For ValidateCIS */
-typedef struct cisinfo_t {
-       u_int                   Chains;
-} cisinfo_t;
-
-typedef struct cs_status_t {
-       u_char                  Function;
-       event_t                 CardState;
-       event_t                 SocketState;
-} cs_status_t;
-
-typedef union ds_ioctl_arg_t {
-       adjust_t                adjust;
-       config_info_t           config;
-       tuple_t                 tuple;
-       tuple_parse_t           tuple_parse;
-       client_req_t            client_req;
-       cs_status_t             status;
-       conf_reg_t              conf_reg;
-       cisinfo_t               cisinfo;
-       region_info_t           region;
-       bind_info_t             bind_info;
-       mtd_info_t              mtd_info;
-       win_info_t              win_info;
-       cisdump_t               cisdump;
-} ds_ioctl_arg_t;
-
-#define DS_ADJUST_RESOURCE_INFO                        _IOWR('d',  2, adjust_t)
-#define DS_GET_CONFIGURATION_INFO              _IOWR('d',  3, config_info_t)
-#define DS_GET_FIRST_TUPLE                     _IOWR('d',  4, tuple_t)
-#define DS_GET_NEXT_TUPLE                      _IOWR('d',  5, tuple_t)
-#define DS_GET_TUPLE_DATA                      _IOWR('d',  6, tuple_parse_t)
-#define DS_PARSE_TUPLE                         _IOWR('d',  7, tuple_parse_t)
-#define DS_RESET_CARD                          _IO  ('d',  8)
-#define DS_GET_STATUS                          _IOWR('d',  9, cs_status_t)
-#define DS_ACCESS_CONFIGURATION_REGISTER       _IOWR('d', 10, conf_reg_t)
-#define DS_VALIDATE_CIS                                _IOR ('d', 11, cisinfo_t)
-#define DS_SUSPEND_CARD                                _IO  ('d', 12)
-#define DS_RESUME_CARD                         _IO  ('d', 13)
-#define DS_EJECT_CARD                          _IO  ('d', 14)
-#define DS_INSERT_CARD                         _IO  ('d', 15)
-#define DS_GET_FIRST_REGION                    _IOWR('d', 16, region_info_t)
-#define DS_GET_NEXT_REGION                     _IOWR('d', 17, region_info_t)
-#define DS_REPLACE_CIS                         _IOWR('d', 18, cisdump_t)
-#define DS_GET_FIRST_WINDOW                    _IOR ('d', 19, win_info_t)
-#define DS_GET_NEXT_WINDOW                     _IOWR('d', 20, win_info_t)
-#define DS_GET_MEM_PAGE                                _IOWR('d', 21, win_info_t)
-
-#define DS_BIND_REQUEST                                _IOWR('d', 60, bind_info_t)
-#define DS_GET_DEVICE_INFO                     _IOWR('d', 61, bind_info_t)
-#define DS_GET_NEXT_DEVICE                     _IOWR('d', 62, bind_info_t)
-#define DS_UNBIND_REQUEST                      _IOW ('d', 63, bind_info_t)
-#define DS_BIND_MTD                            _IOWR('d', 64, mtd_info_t)
-
-
-/* used in userspace only */
-#define CS_IN_USE                      0x1e
-
-#define INFO_MASTER_CLIENT     0x01
-#define INFO_IO_CLIENT         0x02
-#define INFO_MTD_CLIENT                0x04
-#define INFO_MEM_CLIENT                0x08
-#define MAX_NUM_CLIENTS                3
-
-#define INFO_CARD_SHARE                0x10
-#define INFO_CARD_EXCL         0x20
-
-
-#endif /* !defined(__KERNEL__) || defined(CONFIG_PCMCIA_IOCTL) */
+#endif /* __KERNEL__ */
 
 #endif /* _LINUX_DS_H */
index 764281b2921850efa840434b7c76e0ed933be8fe..626b63c33d9e0e374387ca106063d19048899bb5 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/sched.h>       /* task_struct, completion */
 #include <linux/mutex.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #ifdef CONFIG_CARDBUS
 #include <linux/pci.h>
@@ -162,17 +161,10 @@ struct pcmcia_socket {
        u_int                           pci_irq;
        struct pci_dev                  *cb_dev;
 
-
        /* socket setup is done so resources should be able to be allocated.
         * Only if set to 1, calls to find_{io,mem}_region are handled, and
         * insertio events are actually managed by the PCMCIA layer.*/
-       u8                              resource_setup_done:1;
-
-       /* It's old if resource setup is done using adjust_resource_info() */
-       u8                              resource_setup_old:1;
-       u8                              resource_setup_new:1;
-
-       u8                              reserved:5;
+       u8                              resource_setup_done;
 
        /* socket operations */
        struct pccard_operations        *ops;
@@ -218,15 +210,8 @@ struct pcmcia_socket {
         * incorrectness and change */
        u8                              device_count;
 
-       /* 16-bit state: */
-       struct {
-               /* "master" ioctl is used */
-               u8                      busy:1;
-               /* the PCMCIA card consists of two pseudo devices */
-               u8                      has_pfc:1;
-
-               u8                      reserved:6;
-       } pcmcia_state;
+       /* does the PCMCIA card consist of two pseudo devices? */
+       u8                              pcmcia_pfc;
 
        /* non-zero if PCMCIA card is present */
        atomic_t                        present;
@@ -234,10 +219,6 @@ struct pcmcia_socket {
        /* IRQ to be used by PCMCIA devices. May not be IRQ 0. */
        unsigned int                    pcmcia_irq;
 
-#ifdef CONFIG_PCMCIA_IOCTL
-       struct user_info_t              *user;
-       wait_queue_head_t               queue;
-#endif /* CONFIG_PCMCIA_IOCTL */
 #endif /* CONFIG_PCMCIA */
 
        /* socket device */
diff --git a/include/trace/boot.h b/include/trace/boot.h
deleted file mode 100644 (file)
index 088ea08..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _LINUX_TRACE_BOOT_H
-#define _LINUX_TRACE_BOOT_H
-
-#include <linux/module.h>
-#include <linux/kallsyms.h>
-#include <linux/init.h>
-
-/*
- * Structure which defines the trace of an initcall
- * while it is called.
- * You don't have to fill the func field since it is
- * only used internally by the tracer.
- */
-struct boot_trace_call {
-       pid_t                   caller;
-       char                    func[KSYM_SYMBOL_LEN];
-};
-
-/*
- * Structure which defines the trace of an initcall
- * while it returns.
- */
-struct boot_trace_ret {
-       char                    func[KSYM_SYMBOL_LEN];
-       int                             result;
-       unsigned long long      duration;               /* nsecs */
-};
-
-#ifdef CONFIG_BOOT_TRACER
-/* Append the traces on the ring-buffer */
-extern void trace_boot_call(struct boot_trace_call *bt, initcall_t fn);
-extern void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn);
-
-/* Tells the tracer that smp_pre_initcall is finished.
- * So we can start the tracing
- */
-extern void start_boot_trace(void);
-
-/* Resume the tracing of other necessary events
- * such as sched switches
- */
-extern void enable_boot_trace(void);
-
-/* Suspend this tracing. Actually, only sched_switches tracing have
- * to be suspended. Initcalls doesn't need it.)
- */
-extern void disable_boot_trace(void);
-#else
-static inline
-void trace_boot_call(struct boot_trace_call *bt, initcall_t fn) { }
-
-static inline
-void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn) { }
-
-static inline void start_boot_trace(void) { }
-static inline void enable_boot_trace(void) { }
-static inline void disable_boot_trace(void) { }
-#endif /* CONFIG_BOOT_TRACER */
-
-#endif /* __LINUX_TRACE_BOOT_H */
index b9e1dd6c6208b62b9201b7b9bff947fcfb0f2c51..9208c92aeab5eee575b21f3000ea8034f6c00788 100644 (file)
@@ -49,31 +49,6 @@ TRACE_EVENT(sched_kthread_stop_ret,
        TP_printk("ret=%d", __entry->ret)
 );
 
-/*
- * Tracepoint for waiting on task to unschedule:
- */
-TRACE_EVENT(sched_wait_task,
-
-       TP_PROTO(struct task_struct *p),
-
-       TP_ARGS(p),
-
-       TP_STRUCT__entry(
-               __array(        char,   comm,   TASK_COMM_LEN   )
-               __field(        pid_t,  pid                     )
-               __field(        int,    prio                    )
-       ),
-
-       TP_fast_assign(
-               memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
-               __entry->pid    = p->pid;
-               __entry->prio   = p->prio;
-       ),
-
-       TP_printk("comm=%s pid=%d prio=%d",
-                 __entry->comm, __entry->pid, __entry->prio)
-);
-
 /*
  * Tracepoint for waking up a task:
  */
@@ -239,6 +214,13 @@ DEFINE_EVENT(sched_process_template, sched_process_exit,
             TP_PROTO(struct task_struct *p),
             TP_ARGS(p));
 
+/*
+ * Tracepoint for waiting on task to unschedule:
+ */
+DEFINE_EVENT(sched_process_template, sched_wait_task,
+       TP_PROTO(struct task_struct *p),
+       TP_ARGS(p));
+
 /*
  * Tracepoint for a waiting task:
  */
index 9496b965d62ad9dd39929ccc7e471c7fcf2d374a..c624126a9c8a6fb889fe596ea261f649236d51a7 100644 (file)
@@ -8,11 +8,7 @@
 #include <linux/hrtimer.h>
 #include <linux/timer.h>
 
-/**
- * timer_init - called when the timer is initialized
- * @timer:     pointer to struct timer_list
- */
-TRACE_EVENT(timer_init,
+DECLARE_EVENT_CLASS(timer_class,
 
        TP_PROTO(struct timer_list *timer),
 
@@ -29,6 +25,17 @@ TRACE_EVENT(timer_init,
        TP_printk("timer=%p", __entry->timer)
 );
 
+/**
+ * timer_init - called when the timer is initialized
+ * @timer:     pointer to struct timer_list
+ */
+DEFINE_EVENT(timer_class, timer_init,
+
+       TP_PROTO(struct timer_list *timer),
+
+       TP_ARGS(timer)
+);
+
 /**
  * timer_start - called when the timer is started
  * @timer:     pointer to struct timer_list
@@ -94,42 +101,22 @@ TRACE_EVENT(timer_expire_entry,
  * NOTE: Do NOT derefernce timer in TP_fast_assign. The pointer might
  * be invalid. We solely track the pointer.
  */
-TRACE_EVENT(timer_expire_exit,
+DEFINE_EVENT(timer_class, timer_expire_exit,
 
        TP_PROTO(struct timer_list *timer),
 
-       TP_ARGS(timer),
-
-       TP_STRUCT__entry(
-               __field(void *, timer   )
-       ),
-
-       TP_fast_assign(
-               __entry->timer  = timer;
-       ),
-
-       TP_printk("timer=%p", __entry->timer)
+       TP_ARGS(timer)
 );
 
 /**
  * timer_cancel - called when the timer is canceled
  * @timer:     pointer to struct timer_list
  */
-TRACE_EVENT(timer_cancel,
+DEFINE_EVENT(timer_class, timer_cancel,
 
        TP_PROTO(struct timer_list *timer),
 
-       TP_ARGS(timer),
-
-       TP_STRUCT__entry(
-               __field( void *,        timer   )
-       ),
-
-       TP_fast_assign(
-               __entry->timer  = timer;
-       ),
-
-       TP_printk("timer=%p", __entry->timer)
+       TP_ARGS(timer)
 );
 
 /**
@@ -224,14 +211,7 @@ TRACE_EVENT(hrtimer_expire_entry,
                  (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now }))
  );
 
-/**
- * hrtimer_expire_exit - called immediately after the hrtimer callback returns
- * @timer:     pointer to struct hrtimer
- *
- * When used in combination with the hrtimer_expire_entry tracepoint we can
- * determine the runtime of the callback function.
- */
-TRACE_EVENT(hrtimer_expire_exit,
+DECLARE_EVENT_CLASS(hrtimer_class,
 
        TP_PROTO(struct hrtimer *hrtimer),
 
@@ -249,24 +229,28 @@ TRACE_EVENT(hrtimer_expire_exit,
 );
 
 /**
- * hrtimer_cancel - called when the hrtimer is canceled
- * @hrtimer:   pointer to struct hrtimer
+ * hrtimer_expire_exit - called immediately after the hrtimer callback returns
+ * @timer:     pointer to struct hrtimer
+ *
+ * When used in combination with the hrtimer_expire_entry tracepoint we can
+ * determine the runtime of the callback function.
  */
-TRACE_EVENT(hrtimer_cancel,
+DEFINE_EVENT(hrtimer_class, hrtimer_expire_exit,
 
        TP_PROTO(struct hrtimer *hrtimer),
 
-       TP_ARGS(hrtimer),
+       TP_ARGS(hrtimer)
+);
 
-       TP_STRUCT__entry(
-               __field( void *,        hrtimer )
-       ),
+/**
+ * hrtimer_cancel - called when the hrtimer is canceled
+ * @hrtimer:   pointer to struct hrtimer
+ */
+DEFINE_EVENT(hrtimer_class, hrtimer_cancel,
 
-       TP_fast_assign(
-               __entry->hrtimer        = hrtimer;
-       ),
+       TP_PROTO(struct hrtimer *hrtimer),
 
-       TP_printk("hrtimer=%p", __entry->hrtimer)
+       TP_ARGS(hrtimer)
 );
 
 /**
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h
deleted file mode 100644 (file)
index d6c9744..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM workqueue
-
-#if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_WORKQUEUE_H
-
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-#include <linux/tracepoint.h>
-
-DECLARE_EVENT_CLASS(workqueue,
-
-       TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
-
-       TP_ARGS(wq_thread, work),
-
-       TP_STRUCT__entry(
-               __array(char,           thread_comm,    TASK_COMM_LEN)
-               __field(pid_t,          thread_pid)
-               __field(work_func_t,    func)
-       ),
-
-       TP_fast_assign(
-               memcpy(__entry->thread_comm, wq_thread->comm, TASK_COMM_LEN);
-               __entry->thread_pid     = wq_thread->pid;
-               __entry->func           = work->func;
-       ),
-
-       TP_printk("thread=%s:%d func=%pf", __entry->thread_comm,
-               __entry->thread_pid, __entry->func)
-);
-
-DEFINE_EVENT(workqueue, workqueue_insertion,
-
-       TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
-
-       TP_ARGS(wq_thread, work)
-);
-
-DEFINE_EVENT(workqueue, workqueue_execution,
-
-       TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
-
-       TP_ARGS(wq_thread, work)
-);
-
-/* Trace the creation of one workqueue thread on a cpu */
-TRACE_EVENT(workqueue_creation,
-
-       TP_PROTO(struct task_struct *wq_thread, int cpu),
-
-       TP_ARGS(wq_thread, cpu),
-
-       TP_STRUCT__entry(
-               __array(char,   thread_comm,    TASK_COMM_LEN)
-               __field(pid_t,  thread_pid)
-               __field(int,    cpu)
-       ),
-
-       TP_fast_assign(
-               memcpy(__entry->thread_comm, wq_thread->comm, TASK_COMM_LEN);
-               __entry->thread_pid     = wq_thread->pid;
-               __entry->cpu            = cpu;
-       ),
-
-       TP_printk("thread=%s:%d cpu=%d", __entry->thread_comm,
-               __entry->thread_pid, __entry->cpu)
-);
-
-TRACE_EVENT(workqueue_destruction,
-
-       TP_PROTO(struct task_struct *wq_thread),
-
-       TP_ARGS(wq_thread),
-
-       TP_STRUCT__entry(
-               __array(char,   thread_comm,    TASK_COMM_LEN)
-               __field(pid_t,  thread_pid)
-       ),
-
-       TP_fast_assign(
-               memcpy(__entry->thread_comm, wq_thread->comm, TASK_COMM_LEN);
-               __entry->thread_pid     = wq_thread->pid;
-       ),
-
-       TP_printk("thread=%s:%d", __entry->thread_comm, __entry->thread_pid)
-);
-
-#endif /* _TRACE_WORKQUEUE_H */
-
-/* This part must be outside protection */
-#include <trace/define_trace.h>
index 5a64905d7278a47fb683a0aceb63cef029dd467b..a9377c0083ad3ed612547f783647132a8268ef09 100644 (file)
 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
        DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
 
-#undef __cpparg
-#define __cpparg(arg...) arg
-
 /* Callbacks are meaningless to ftrace. */
 #undef TRACE_EVENT_FN
 #define TRACE_EVENT_FN(name, proto, args, tstruct,                     \
                assign, print, reg, unreg)                              \
-       TRACE_EVENT(name, __cpparg(proto), __cpparg(args),              \
-               __cpparg(tstruct), __cpparg(assign), __cpparg(print))   \
+       TRACE_EVENT(name, PARAMS(proto), PARAMS(args),                  \
+               PARAMS(tstruct), PARAMS(assign), PARAMS(print))         \
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
  *     struct trace_seq *s = &iter->seq;
  *     struct ftrace_raw_<call> *field; <-- defined in stage 1
  *     struct trace_entry *entry;
- *     struct trace_seq *p;
+ *     struct trace_seq *p = &iter->tmp_seq;
  *     int ret;
  *
  *     entry = iter->ent;
  *
  *     field = (typeof(field))entry;
  *
- *     p = &get_cpu_var(ftrace_event_seq);
  *     trace_seq_init(p);
  *     ret = trace_seq_printf(s, "%s: ", <call>);
  *     if (ret)
  *             ret = trace_seq_printf(s, <TP_printk> "\n");
- *     put_cpu();
  *     if (!ret)
  *             return TRACE_TYPE_PARTIAL_LINE;
  *
@@ -216,7 +211,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags,    \
        struct trace_seq *s = &iter->seq;                               \
        struct ftrace_raw_##call *field;                                \
        struct trace_entry *entry;                                      \
-       struct trace_seq *p;                                            \
+       struct trace_seq *p = &iter->tmp_seq;                           \
        int ret;                                                        \
                                                                        \
        event = container_of(trace_event, struct ftrace_event_call,     \
@@ -231,12 +226,10 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags,  \
                                                                        \
        field = (typeof(field))entry;                                   \
                                                                        \
-       p = &get_cpu_var(ftrace_event_seq);                             \
        trace_seq_init(p);                                              \
        ret = trace_seq_printf(s, "%s: ", event->name);                 \
        if (ret)                                                        \
                ret = trace_seq_printf(s, print);                       \
-       put_cpu();                                                      \
        if (!ret)                                                       \
                return TRACE_TYPE_PARTIAL_LINE;                         \
                                                                        \
@@ -255,7 +248,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags,    \
        struct trace_seq *s = &iter->seq;                               \
        struct ftrace_raw_##template *field;                            \
        struct trace_entry *entry;                                      \
-       struct trace_seq *p;                                            \
+       struct trace_seq *p = &iter->tmp_seq;                           \
        int ret;                                                        \
                                                                        \
        entry = iter->ent;                                              \
@@ -267,12 +260,10 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags,  \
                                                                        \
        field = (typeof(field))entry;                                   \
                                                                        \
-       p = &get_cpu_var(ftrace_event_seq);                             \
        trace_seq_init(p);                                              \
        ret = trace_seq_printf(s, "%s: ", #call);                       \
        if (ret)                                                        \
                ret = trace_seq_printf(s, print);                       \
-       put_cpu();                                                      \
        if (!ret)                                                       \
                return TRACE_TYPE_PARTIAL_LINE;                         \
                                                                        \
@@ -439,6 +430,7 @@ static inline notrace int ftrace_get_offsets_##call(                        \
  *     .fields                 = LIST_HEAD_INIT(event_class_##call.fields),
  *     .raw_init               = trace_event_raw_init,
  *     .probe                  = ftrace_raw_event_##call,
+ *     .reg                    = ftrace_event_reg,
  * };
  *
  * static struct ftrace_event_call __used
@@ -567,6 +559,7 @@ static struct ftrace_event_class __used event_class_##call = {              \
        .fields                 = LIST_HEAD_INIT(event_class_##call.fields),\
        .raw_init               = trace_event_raw_init,                 \
        .probe                  = ftrace_raw_event_##call,              \
+       .reg                    = ftrace_event_reg,                     \
        _TRACE_PERF_INIT(call)                                          \
 };
 
@@ -705,7 +698,7 @@ perf_trace_##call(void *__data, proto)                                      \
        int __data_size;                                                \
        int rctx;                                                       \
                                                                        \
-       perf_fetch_caller_regs(&__regs, 1);                             \
+       perf_fetch_caller_regs(&__regs);                                \
                                                                        \
        __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
        __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\
index 257e08960d7b7f1c232ca6cef97f1cac3f0737e5..31966a4fb8ccab298a6e64f81400a1aec2c39ea9 100644 (file)
@@ -26,7 +26,6 @@ struct syscall_metadata {
        const char      **types;
        const char      **args;
        struct list_head enter_fields;
-       struct list_head exit_fields;
 
        struct ftrace_event_call *enter_event;
        struct ftrace_event_call *exit_event;
index e68d59a90ca88b73c21b431c3cf538165916d5a7..a15d93262e308706eb4f3fe6a1283d0583f2b043 100644 (file)
@@ -56,4 +56,11 @@ void xen_poll_irq(int irq);
 /* Determine the IRQ which is bound to an event channel */
 unsigned irq_from_evtchn(unsigned int evtchn);
 
+/* Xen HVM evtchn vector callback */
+extern void xen_hvm_callback_vector(void);
+extern int xen_have_vector_callback;
+int xen_set_callback_via(uint64_t via);
+void xen_evtchn_do_upcall(struct pt_regs *regs);
+void xen_hvm_evtchn_do_upcall(void);
+
 #endif /* _XEN_EVENTS_H */
index a40f1cd91be1c6ad2fa7ad431b4d599c415448c1..9a731706a0165404445972903e4cebf1695e784c 100644 (file)
@@ -51,6 +51,7 @@ struct gnttab_free_callback {
        u16 count;
 };
 
+int gnttab_init(void);
 int gnttab_suspend(void);
 int gnttab_resume(void);
 
@@ -112,6 +113,9 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
 void arch_gnttab_unmap_shared(struct grant_entry *shared,
                              unsigned long nr_gframes);
 
+extern unsigned long xen_hvm_resume_frames;
+unsigned int gnttab_max_grant_frames(void);
+
 #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
 
 #endif /* __ASM_GNTTAB_H__ */
diff --git a/include/xen/hvm.h b/include/xen/hvm.h
new file mode 100644 (file)
index 0000000..b193fa2
--- /dev/null
@@ -0,0 +1,30 @@
+/* Simple wrappers around HVM functions */
+#ifndef XEN_HVM_H__
+#define XEN_HVM_H__
+
+#include <xen/interface/hvm/params.h>
+#include <asm/xen/hypercall.h>
+
+static inline int hvm_get_parameter(int idx, uint64_t *value)
+{
+       struct xen_hvm_param xhv;
+       int r;
+
+       xhv.domid = DOMID_SELF;
+       xhv.index = idx;
+       r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
+       if (r < 0) {
+               printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n",
+                       idx, r);
+               return r;
+       }
+       *value = xhv.value;
+       return r;
+}
+
+#define HVM_CALLBACK_VIA_TYPE_VECTOR 0x2
+#define HVM_CALLBACK_VIA_TYPE_SHIFT 56
+#define HVM_CALLBACK_VECTOR(x) (((uint64_t)HVM_CALLBACK_VIA_TYPE_VECTOR)<<\
+               HVM_CALLBACK_VIA_TYPE_SHIFT | (x))
+
+#endif /* XEN_HVM_H__ */
index f51b6413b05469abab7724717b465f7277137612..70d2563ab1667f98aae852dac2d9df7f7cb7f3bf 100644 (file)
 /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
 #define XENFEAT_mmu_pt_update_preserve_ad  5
 
+/* x86: Does this Xen host support the HVM callback vector type? */
+#define XENFEAT_hvm_callback_vector        8
+
+/* x86: pvclock algorithm is safe to use on HVM */
+#define XENFEAT_hvm_safe_pvclock           9
+
 #define XENFEAT_NR_SUBMAPS 1
 
 #endif /* __XEN_PUBLIC_FEATURES_H__ */
index 39da93c21de05b3503c0b7e98c6bfefebee42b12..39e571796e324fac9782cf75fe27563bf6be0f78 100644 (file)
@@ -28,6 +28,7 @@
 #ifndef __XEN_PUBLIC_GRANT_TABLE_H__
 #define __XEN_PUBLIC_GRANT_TABLE_H__
 
+#include <xen/interface/xen.h>
 
 /***********************************
  * GRANT TABLE REPRESENTATION
diff --git a/include/xen/interface/hvm/hvm_op.h b/include/xen/interface/hvm/hvm_op.h
new file mode 100644 (file)
index 0000000..a4827f4
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
+#define __XEN_PUBLIC_HVM_HVM_OP_H__
+
+/* Get/set subcommands: the second argument of the hypercall is a
+ * pointer to a xen_hvm_param struct. */
+#define HVMOP_set_param           0
+#define HVMOP_get_param           1
+struct xen_hvm_param {
+    domid_t  domid;    /* IN */
+    uint32_t index;    /* IN */
+    uint64_t value;    /* IN/OUT */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_param);
+
+/* Hint from PV drivers for pagetable destruction. */
+#define HVMOP_pagetable_dying       9
+struct xen_hvm_pagetable_dying {
+    /* Domain with a pagetable about to be destroyed. */
+    domid_t  domid;
+    /* guest physical address of the toplevel pagetable dying */
+    aligned_u64 gpa;
+};
+typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t;
+DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_pagetable_dying_t);
+#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h
new file mode 100644 (file)
index 0000000..1888d8c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
+#define __XEN_PUBLIC_HVM_PARAMS_H__
+
+#include "hvm_op.h"
+
+/*
+ * Parameter space for HVMOP_{set,get}_param.
+ */
+
+/*
+ * How should CPU0 event-channel notifications be delivered?
+ * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
+ * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
+ *                  Domain = val[47:32], Bus  = val[31:16],
+ *                  DevFn  = val[15: 8], IntX = val[ 1: 0]
+ * val[63:56] == 2: val[7:0] is a vector number.
+ * If val == 0 then CPU0 event-channel notifications are not delivered.
+ */
+#define HVM_PARAM_CALLBACK_IRQ 0
+
+#define HVM_PARAM_STORE_PFN    1
+#define HVM_PARAM_STORE_EVTCHN 2
+
+#define HVM_PARAM_PAE_ENABLED  4
+
+#define HVM_PARAM_IOREQ_PFN    5
+
+#define HVM_PARAM_BUFIOREQ_PFN 6
+
+/*
+ * Set mode for virtual timers (currently x86 only):
+ *  delay_for_missed_ticks (default):
+ *   Do not advance a vcpu's time beyond the correct delivery time for
+ *   interrupts that have been missed due to preemption. Deliver missed
+ *   interrupts when the vcpu is rescheduled and advance the vcpu's virtual
+ *   time stepwise for each one.
+ *  no_delay_for_missed_ticks:
+ *   As above, missed interrupts are delivered, but guest time always tracks
+ *   wallclock (i.e., real) time while doing so.
+ *  no_missed_ticks_pending:
+ *   No missed interrupts are held pending. Instead, to ensure ticks are
+ *   delivered at some non-zero rate, if we detect missed ticks then the
+ *   internal tick alarm is not disabled if the VCPU is preempted during the
+ *   next tick period.
+ *  one_missed_tick_pending:
+ *   Missed interrupts are collapsed together and delivered as one 'late tick'.
+ *   Guest time always tracks wallclock (i.e., real) time.
+ */
+#define HVM_PARAM_TIMER_MODE   10
+#define HVMPTM_delay_for_missed_ticks    0
+#define HVMPTM_no_delay_for_missed_ticks 1
+#define HVMPTM_no_missed_ticks_pending   2
+#define HVMPTM_one_missed_tick_pending   3
+
+/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
+#define HVM_PARAM_HPET_ENABLED 11
+
+/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
+#define HVM_PARAM_IDENT_PT     12
+
+/* Device Model domain, defaults to 0. */
+#define HVM_PARAM_DM_DOMAIN    13
+
+/* ACPI S state: currently support S0 and S3 on x86. */
+#define HVM_PARAM_ACPI_S_STATE 14
+
+/* TSS used on Intel when CR0.PE=0. */
+#define HVM_PARAM_VM86_TSS     15
+
+/* Boolean: Enable aligning all periodic vpts to reduce interrupts */
+#define HVM_PARAM_VPT_ALIGN    16
+
+#define HVM_NR_PARAMS          17
+
+#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
diff --git a/include/xen/platform_pci.h b/include/xen/platform_pci.h
new file mode 100644 (file)
index 0000000..ce9d671
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _XEN_PLATFORM_PCI_H
+#define _XEN_PLATFORM_PCI_H
+
+#define XEN_IOPORT_MAGIC_VAL 0x49d2
+#define XEN_IOPORT_LINUX_PRODNUM 0x0003
+#define XEN_IOPORT_LINUX_DRVVER  0x0001
+
+#define XEN_IOPORT_BASE 0x10
+
+#define XEN_IOPORT_PLATFLAGS   (XEN_IOPORT_BASE + 0) /* 1 byte access (R/W) */
+#define XEN_IOPORT_MAGIC       (XEN_IOPORT_BASE + 0) /* 2 byte access (R) */
+#define XEN_IOPORT_UNPLUG      (XEN_IOPORT_BASE + 0) /* 2 byte access (W) */
+#define XEN_IOPORT_DRVVER      (XEN_IOPORT_BASE + 0) /* 4 byte access (W) */
+
+#define XEN_IOPORT_SYSLOG      (XEN_IOPORT_BASE + 2) /* 1 byte access (W) */
+#define XEN_IOPORT_PROTOVER    (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */
+#define XEN_IOPORT_PRODNUM     (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */
+
+#define XEN_UNPLUG_ALL_IDE_DISKS 1
+#define XEN_UNPLUG_ALL_NICS 2
+#define XEN_UNPLUG_AUX_IDE_DISKS 4
+#define XEN_UNPLUG_ALL 7
+#define XEN_UNPLUG_IGNORE 8
+
+static inline int xen_must_unplug_nics(void) {
+#if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \
+               defined(CONFIG_XEN_NETDEV_FRONTEND_MODULE)) && \
+               (defined(CONFIG_XEN_PLATFORM_PCI) || \
+                defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
+        return 1;
+#else
+        return 0;
+#endif
+}
+
+static inline int xen_must_unplug_disks(void) {
+#if (defined(CONFIG_XEN_BLKDEV_FRONTEND) || \
+               defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE)) && \
+               (defined(CONFIG_XEN_PLATFORM_PCI) || \
+                defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
+        return 1;
+#else
+        return 0;
+#endif
+}
+
+extern int xen_platform_pci_unplug;
+
+#endif /* _XEN_PLATFORM_PCI_H */
index 883a21bba24bac3991e79533f586679de6926a4a..46bc81ef74c67468a667e6f5d06026be1cc43f4c 100644 (file)
@@ -7,6 +7,7 @@ DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
 
 void xen_pre_suspend(void);
 void xen_post_suspend(int suspend_cancelled);
+void xen_hvm_post_suspend(int suspend_cancelled);
 
 void xen_mm_pin_all(void);
 void xen_mm_unpin_all(void);
@@ -14,4 +15,6 @@ void xen_mm_unpin_all(void);
 void xen_timer_resume(void);
 void xen_arch_resume(void);
 
+int xen_setup_shutdown_event(void);
+
 #endif /* INCLUDE_XEN_OPS_H */
index 5cff9a980c397d48491145e9d1f9e4e42313cad4..cb64c5889e028948db25fb08df5f9383eae8b32f 100644 (file)
@@ -1143,30 +1143,6 @@ config TRACEPOINTS
 
 source "arch/Kconfig"
 
-config SLOW_WORK
-       default n
-       bool
-       help
-         The slow work thread pool provides a number of dynamically allocated
-         threads that can be used by the kernel to perform operations that
-         take a relatively long time.
-
-         An example of this would be CacheFiles doing a path lookup followed
-         by a series of mkdirs and a create call, all of which have to touch
-         disk.
-
-         See Documentation/slow-work.txt.
-
-config SLOW_WORK_DEBUG
-       bool "Slow work debugging through debugfs"
-       default n
-       depends on SLOW_WORK && DEBUG_FS
-       help
-         Display the contents of the slow work run queue through debugfs,
-         including items currently executing.
-
-         See Documentation/slow-work.txt.
-
 endmenu                # General setup
 
 config HAVE_GENERIC_DMA_COHERENT
index 4ddb53f04f2acb0aefb84df89efc105e8f1ba90e..e97fadeec856e4a3c1144a14513e2feb0fb99d6b 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/start_kernel.h>
 #include <linux/security.h>
 #include <linux/smp.h>
-#include <linux/workqueue.h>
 #include <linux/profile.h>
 #include <linux/rcupdate.h>
 #include <linux/moduleparam.h>
 #include <linux/ftrace.h>
 #include <linux/async.h>
 #include <linux/kmemcheck.h>
-#include <linux/kmemtrace.h>
 #include <linux/sfi.h>
 #include <linux/shmem_fs.h>
 #include <linux/slab.h>
-#include <trace/boot.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -664,7 +661,6 @@ asmlinkage void __init start_kernel(void)
 #endif
        page_cgroup_init();
        enable_debug_pagealloc();
-       kmemtrace_init();
        kmemleak_init();
        debug_objects_mem_init();
        idr_init_cache();
@@ -726,38 +722,33 @@ int initcall_debug;
 core_param(initcall_debug, initcall_debug, bool, 0644);
 
 static char msgbuf[64];
-static struct boot_trace_call call;
-static struct boot_trace_ret ret;
 
 int do_one_initcall(initcall_t fn)
 {
        int count = preempt_count();
        ktime_t calltime, delta, rettime;
+       unsigned long long duration;
+       int ret;
 
        if (initcall_debug) {
-               call.caller = task_pid_nr(current);
-               printk("calling  %pF @ %i\n", fn, call.caller);
+               printk("calling  %pF @ %i\n", fn, task_pid_nr(current));
                calltime = ktime_get();
-               trace_boot_call(&call, fn);
-               enable_boot_trace();
        }
 
-       ret.result = fn();
+       ret = fn();
 
        if (initcall_debug) {
-               disable_boot_trace();
                rettime = ktime_get();
                delta = ktime_sub(rettime, calltime);
-               ret.duration = (unsigned long long) ktime_to_ns(delta) >> 10;
-               trace_boot_ret(&ret, fn);
-               printk("initcall %pF returned %d after %Ld usecs\n", fn,
-                       ret.result, ret.duration);
+               duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+               printk("initcall %pF returned %d after %lld usecs\n", fn,
+                       ret, duration);
        }
 
        msgbuf[0] = 0;
 
-       if (ret.result && ret.result != -ENODEV && initcall_debug)
-               sprintf(msgbuf, "error code %d ", ret.result);
+       if (ret && ret != -ENODEV && initcall_debug)
+               sprintf(msgbuf, "error code %d ", ret);
 
        if (preempt_count() != count) {
                strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
@@ -771,7 +762,7 @@ int do_one_initcall(initcall_t fn)
                printk("initcall %pF returned with %s\n", fn, msgbuf);
        }
 
-       return ret.result;
+       return ret;
 }
 
 
@@ -797,7 +788,6 @@ static void __init do_initcalls(void)
  */
 static void __init do_basic_setup(void)
 {
-       init_workqueues();
        cpuset_init_smp();
        usermodehelper_init();
        init_tmpfs();
@@ -895,7 +885,6 @@ static int __init kernel_init(void * unused)
        smp_prepare_cpus(setup_max_cpus);
 
        do_pre_smp_initcalls();
-       start_boot_trace();
 
        smp_init();
        sched_init_smp();
index 057472fbc272eed8b64f23c16f55b49217aa9043..c53e491e25a86d60a6366547dea865985405e886 100644 (file)
@@ -76,8 +76,8 @@ obj-$(CONFIG_GCOV_KERNEL) += gcov/
 obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_KGDB) += debug/
-obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
 obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o
+obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_SECCOMP) += seccomp.o
 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
@@ -99,8 +99,6 @@ obj-$(CONFIG_TRACING) += trace/
 obj-$(CONFIG_X86_DS) += trace/
 obj-$(CONFIG_RING_BUFFER) += trace/
 obj-$(CONFIG_SMP) += sched_cpupri.o
-obj-$(CONFIG_SLOW_WORK) += slow-work.o
-obj-$(CONFIG_SLOW_WORK_DEBUG) += slow-work-debugfs.o
 obj-$(CONFIG_PERF_EVENTS) += perf_event.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
 obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
index 15319d6c18fe05a3b3bbb8c91e0c654e58356bb2..cd9dbb913c777db20ecead3796bee04a6764e73b 100644 (file)
@@ -49,40 +49,33 @@ asynchronous and synchronous parts of the kernel.
 */
 
 #include <linux/async.h>
-#include <linux/bug.h>
 #include <linux/module.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 #include <asm/atomic.h>
 
 static async_cookie_t next_cookie = 1;
 
-#define MAX_THREADS    256
 #define MAX_WORK       32768
 
 static LIST_HEAD(async_pending);
 static LIST_HEAD(async_running);
 static DEFINE_SPINLOCK(async_lock);
 
-static int async_enabled = 0;
-
 struct async_entry {
-       struct list_head list;
-       async_cookie_t   cookie;
-       async_func_ptr   *func;
-       void             *data;
-       struct list_head *running;
+       struct list_head        list;
+       struct work_struct      work;
+       async_cookie_t          cookie;
+       async_func_ptr          *func;
+       void                    *data;
+       struct list_head        *running;
 };
 
 static DECLARE_WAIT_QUEUE_HEAD(async_done);
-static DECLARE_WAIT_QUEUE_HEAD(async_new);
 
 static atomic_t entry_count;
-static atomic_t thread_count;
 
 extern int initcall_debug;
 
@@ -117,27 +110,23 @@ static async_cookie_t  lowest_in_progress(struct list_head *running)
        spin_unlock_irqrestore(&async_lock, flags);
        return ret;
 }
+
 /*
  * pick the first pending entry and run it
  */
-static void run_one_entry(void)
+static void async_run_entry_fn(struct work_struct *work)
 {
+       struct async_entry *entry =
+               container_of(work, struct async_entry, work);
        unsigned long flags;
-       struct async_entry *entry;
        ktime_t calltime, delta, rettime;
 
-       /* 1) pick one task from the pending queue */
-
+       /* 1) move self to the running queue */
        spin_lock_irqsave(&async_lock, flags);
-       if (list_empty(&async_pending))
-               goto out;
-       entry = list_first_entry(&async_pending, struct async_entry, list);
-
-       /* 2) move it to the running queue */
        list_move_tail(&entry->list, entry->running);
        spin_unlock_irqrestore(&async_lock, flags);
 
-       /* 3) run it (and print duration)*/
+       /* 2) run (and print duration) */
        if (initcall_debug && system_state == SYSTEM_BOOTING) {
                printk("calling  %lli_%pF @ %i\n", (long long)entry->cookie,
                        entry->func, task_pid_nr(current));
@@ -153,31 +142,25 @@ static void run_one_entry(void)
                        (long long)ktime_to_ns(delta) >> 10);
        }
 
-       /* 4) remove it from the running queue */
+       /* 3) remove self from the running queue */
        spin_lock_irqsave(&async_lock, flags);
        list_del(&entry->list);
 
-       /* 5) free the entry  */
+       /* 4) free the entry */
        kfree(entry);
        atomic_dec(&entry_count);
 
        spin_unlock_irqrestore(&async_lock, flags);
 
-       /* 6) wake up any waiters. */
+       /* 5) wake up any waiters */
        wake_up(&async_done);
-       return;
-
-out:
-       spin_unlock_irqrestore(&async_lock, flags);
 }
 
-
 static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct list_head *running)
 {
        struct async_entry *entry;
        unsigned long flags;
        async_cookie_t newcookie;
-       
 
        /* allow irq-off callers */
        entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC);
@@ -186,7 +169,7 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l
         * If we're out of memory or if there's too much work
         * pending already, we execute synchronously.
         */
-       if (!async_enabled || !entry || atomic_read(&entry_count) > MAX_WORK) {
+       if (!entry || atomic_read(&entry_count) > MAX_WORK) {
                kfree(entry);
                spin_lock_irqsave(&async_lock, flags);
                newcookie = next_cookie++;
@@ -196,6 +179,7 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l
                ptr(data, newcookie);
                return newcookie;
        }
+       INIT_WORK(&entry->work, async_run_entry_fn);
        entry->func = ptr;
        entry->data = data;
        entry->running = running;
@@ -205,7 +189,10 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l
        list_add_tail(&entry->list, &async_pending);
        atomic_inc(&entry_count);
        spin_unlock_irqrestore(&async_lock, flags);
-       wake_up(&async_new);
+
+       /* schedule for execution */
+       queue_work(system_unbound_wq, &entry->work);
+
        return newcookie;
 }
 
@@ -312,87 +299,3 @@ void async_synchronize_cookie(async_cookie_t cookie)
        async_synchronize_cookie_domain(cookie, &async_running);
 }
 EXPORT_SYMBOL_GPL(async_synchronize_cookie);
-
-
-static int async_thread(void *unused)
-{
-       DECLARE_WAITQUEUE(wq, current);
-       add_wait_queue(&async_new, &wq);
-
-       while (!kthread_should_stop()) {
-               int ret = HZ;
-               set_current_state(TASK_INTERRUPTIBLE);
-               /*
-                * check the list head without lock.. false positives
-                * are dealt with inside run_one_entry() while holding
-                * the lock.
-                */
-               rmb();
-               if (!list_empty(&async_pending))
-                       run_one_entry();
-               else
-                       ret = schedule_timeout(HZ);
-
-               if (ret == 0) {
-                       /*
-                        * we timed out, this means we as thread are redundant.
-                        * we sign off and die, but we to avoid any races there
-                        * is a last-straw check to see if work snuck in.
-                        */
-                       atomic_dec(&thread_count);
-                       wmb(); /* manager must see our departure first */
-                       if (list_empty(&async_pending))
-                               break;
-                       /*
-                        * woops work came in between us timing out and us
-                        * signing off; we need to stay alive and keep working.
-                        */
-                       atomic_inc(&thread_count);
-               }
-       }
-       remove_wait_queue(&async_new, &wq);
-
-       return 0;
-}
-
-static int async_manager_thread(void *unused)
-{
-       DECLARE_WAITQUEUE(wq, current);
-       add_wait_queue(&async_new, &wq);
-
-       while (!kthread_should_stop()) {
-               int tc, ec;
-
-               set_current_state(TASK_INTERRUPTIBLE);
-
-               tc = atomic_read(&thread_count);
-               rmb();
-               ec = atomic_read(&entry_count);
-
-               while (tc < ec && tc < MAX_THREADS) {
-                       if (IS_ERR(kthread_run(async_thread, NULL, "async/%i",
-                                              tc))) {
-                               msleep(100);
-                               continue;
-                       }
-                       atomic_inc(&thread_count);
-                       tc++;
-               }
-
-               schedule();
-       }
-       remove_wait_queue(&async_new, &wq);
-
-       return 0;
-}
-
-static int __init async_init(void)
-{
-       async_enabled =
-               !IS_ERR(kthread_run(async_manager_thread, NULL, "async/mgr"));
-
-       WARN_ON(!async_enabled);
-       return 0;
-}
-
-core_initcall(async_init);
index a8ce099544049e787464c3e4261ac70625cc0653..d83cab06da8722f7d91fad428a74799645964676 100644 (file)
@@ -1623,6 +1623,8 @@ static struct file_system_type cgroup_fs_type = {
        .kill_sb = cgroup_kill_sb,
 };
 
+static struct kobject *cgroup_kobj;
+
 static inline struct cgroup *__d_cgrp(struct dentry *dentry)
 {
        return dentry->d_fsdata;
@@ -3894,9 +3896,18 @@ int __init cgroup_init(void)
        hhead = css_set_hash(init_css_set.subsys);
        hlist_add_head(&init_css_set.hlist, hhead);
        BUG_ON(!init_root_id(&rootnode));
+
+       cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);
+       if (!cgroup_kobj) {
+               err = -ENOMEM;
+               goto out;
+       }
+
        err = register_filesystem(&cgroup_fs_type);
-       if (err < 0)
+       if (err < 0) {
+               kobject_put(cgroup_kobj);
                goto out;
+       }
 
        proc_create("cgroups", 0, NULL, &proc_cgroupstats_operations);
 
index 97d1b426a4ac39bd49b41b9393ed9b565f8f7f33..f6e726f184916029e2d1cfdbcd4acb2b26f14e69 100644 (file)
@@ -235,11 +235,8 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
                return -EINVAL;
 
        cpu_hotplug_begin();
-       set_cpu_active(cpu, false);
        err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls);
        if (err) {
-               set_cpu_active(cpu, true);
-
                nr_calls--;
                __cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL);
                printk("%s: attempt to take down CPU %u failed\n",
@@ -249,7 +246,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 
        err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
        if (err) {
-               set_cpu_active(cpu, true);
                /* CPU didn't die: tell everyone.  Can't complain. */
                cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu);
 
@@ -321,8 +317,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
                goto out_notify;
        BUG_ON(!cpu_online(cpu));
 
-       set_cpu_active(cpu, true);
-
        /* Now call notifier in preparation. */
        cpu_notify(CPU_ONLINE | mod, hcpu);
 
index 7cb37d86a005e9eaaa85288907708689bb270f46..b23c0979bbe7212a748a9aac70697e92ee54f448 100644 (file)
@@ -2113,31 +2113,17 @@ static void scan_for_empty_cpusets(struct cpuset *root)
  * but making no active use of cpusets.
  *
  * This routine ensures that top_cpuset.cpus_allowed tracks
- * cpu_online_map on each CPU hotplug (cpuhp) event.
+ * cpu_active_mask on each CPU hotplug (cpuhp) event.
  *
  * Called within get_online_cpus().  Needs to call cgroup_lock()
  * before calling generate_sched_domains().
  */
-static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
-                               unsigned long phase, void *unused_cpu)
+void cpuset_update_active_cpus(void)
 {
        struct sched_domain_attr *attr;
        cpumask_var_t *doms;
        int ndoms;
 
-       switch (phase) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-       case CPU_DOWN_PREPARE:
-       case CPU_DOWN_PREPARE_FROZEN:
-       case CPU_DOWN_FAILED:
-       case CPU_DOWN_FAILED_FROZEN:
-               break;
-
-       default:
-               return NOTIFY_DONE;
-       }
-
        cgroup_lock();
        mutex_lock(&callback_mutex);
        cpumask_copy(top_cpuset.cpus_allowed, cpu_active_mask);
@@ -2148,8 +2134,6 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
 
        /* Have scheduler rebuild the domains */
        partition_sched_domains(ndoms, doms, attr);
-
-       return NOTIFY_OK;
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
@@ -2203,7 +2187,6 @@ void __init cpuset_init_smp(void)
        cpumask_copy(top_cpuset.cpus_allowed, cpu_active_mask);
        top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
 
-       hotcpu_notifier(cpuset_track_online_cpus, 0);
        hotplug_memory_notifier(cpuset_track_online_nodes, 10);
 
        cpuset_wq = create_singlethread_workqueue("cpuset");
index 51d14fe876485447b5cb7738d7fa780f24c9d7d2..3c2d4972d2352ad1bff0fb31a676f467420b6ddd 100644 (file)
@@ -605,6 +605,8 @@ cpu_master_loop:
                if (dbg_kdb_mode) {
                        kgdb_connected = 1;
                        error = kdb_stub(ks);
+                       if (error == -1)
+                               continue;
                        kgdb_connected = 0;
                } else {
                        error = gdb_serial_stub(ks);
index 6e81fd59566b75f896ef39715921a8a961857f24..481a7bd2dfe752267ba3273a1bb8e4a972c17fa5 100644 (file)
@@ -52,17 +52,6 @@ static unsigned long         gdb_regs[(NUMREGBYTES +
  * GDB remote protocol parser:
  */
 
-static int hex(char ch)
-{
-       if ((ch >= 'a') && (ch <= 'f'))
-               return ch - 'a' + 10;
-       if ((ch >= '0') && (ch <= '9'))
-               return ch - '0';
-       if ((ch >= 'A') && (ch <= 'F'))
-               return ch - 'A' + 10;
-       return -1;
-}
-
 #ifdef CONFIG_KGDB_KDB
 static int gdbstub_read_wait(void)
 {
@@ -123,8 +112,8 @@ static void get_packet(char *buffer)
                buffer[count] = 0;
 
                if (ch == '#') {
-                       xmitcsum = hex(gdbstub_read_wait()) << 4;
-                       xmitcsum += hex(gdbstub_read_wait());
+                       xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4;
+                       xmitcsum += hex_to_bin(gdbstub_read_wait());
 
                        if (checksum != xmitcsum)
                                /* failed checksum */
@@ -236,7 +225,7 @@ void gdbstub_msg_write(const char *s, int len)
  * buf.  Return a pointer to the last char put in buf (null). May
  * return an error.
  */
-int kgdb_mem2hex(char *mem, char *buf, int count)
+char *kgdb_mem2hex(char *mem, char *buf, int count)
 {
        char *tmp;
        int err;
@@ -248,17 +237,16 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
        tmp = buf + count;
 
        err = probe_kernel_read(tmp, mem, count);
-       if (!err) {
-               while (count > 0) {
-                       buf = pack_hex_byte(buf, *tmp);
-                       tmp++;
-                       count--;
-               }
-
-               *buf = 0;
+       if (err)
+               return NULL;
+       while (count > 0) {
+               buf = pack_hex_byte(buf, *tmp);
+               tmp++;
+               count--;
        }
+       *buf = 0;
 
-       return err;
+       return buf;
 }
 
 /*
@@ -280,8 +268,8 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
        tmp_hex = tmp_raw - 1;
        while (tmp_hex >= buf) {
                tmp_raw--;
-               *tmp_raw = hex(*tmp_hex--);
-               *tmp_raw |= hex(*tmp_hex--) << 4;
+               *tmp_raw = hex_to_bin(*tmp_hex--);
+               *tmp_raw |= hex_to_bin(*tmp_hex--) << 4;
        }
 
        return probe_kernel_write(mem, tmp_raw, count);
@@ -304,7 +292,7 @@ int kgdb_hex2long(char **ptr, unsigned long *long_val)
                (*ptr)++;
        }
        while (**ptr) {
-               hex_val = hex(**ptr);
+               hex_val = hex_to_bin(**ptr);
                if (hex_val < 0)
                        break;
 
@@ -339,6 +327,32 @@ static int kgdb_ebin2mem(char *buf, char *mem, int count)
        return probe_kernel_write(mem, c, size);
 }
 
+#if DBG_MAX_REG_NUM > 0
+void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       int i;
+       int idx = 0;
+       char *ptr = (char *)gdb_regs;
+
+       for (i = 0; i < DBG_MAX_REG_NUM; i++) {
+               dbg_get_reg(i, ptr + idx, regs);
+               idx += dbg_reg_def[i].size;
+       }
+}
+
+void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       int i;
+       int idx = 0;
+       char *ptr = (char *)gdb_regs;
+
+       for (i = 0; i < DBG_MAX_REG_NUM; i++) {
+               dbg_set_reg(i, ptr + idx, regs);
+               idx += dbg_reg_def[i].size;
+       }
+}
+#endif /* DBG_MAX_REG_NUM > 0 */
+
 /* Write memory due to an 'M' or 'X' packet. */
 static int write_mem_msg(int binary)
 {
@@ -378,28 +392,31 @@ static void error_packet(char *pkt, int error)
  * remapped to negative TIDs.
  */
 
-#define BUF_THREAD_ID_SIZE     16
+#define BUF_THREAD_ID_SIZE     8
 
 static char *pack_threadid(char *pkt, unsigned char *id)
 {
-       char *limit;
+       unsigned char *limit;
+       int lzero = 1;
+
+       limit = id + (BUF_THREAD_ID_SIZE / 2);
+       while (id < limit) {
+               if (!lzero || *id != 0) {
+                       pkt = pack_hex_byte(pkt, *id);
+                       lzero = 0;
+               }
+               id++;
+       }
 
-       limit = pkt + BUF_THREAD_ID_SIZE;
-       while (pkt < limit)
-               pkt = pack_hex_byte(pkt, *id++);
+       if (lzero)
+               pkt = pack_hex_byte(pkt, 0);
 
        return pkt;
 }
 
 static void int_to_threadref(unsigned char *id, int value)
 {
-       unsigned char *scan;
-       int i = 4;
-
-       scan = (unsigned char *)id;
-       while (i--)
-               *scan++ = 0;
-       put_unaligned_be32(value, scan);
+       put_unaligned_be32(value, id);
 }
 
 static struct task_struct *getthread(struct pt_regs *regs, int tid)
@@ -463,8 +480,7 @@ static void gdb_cmd_status(struct kgdb_state *ks)
        pack_hex_byte(&remcom_out_buffer[1], ks->signo);
 }
 
-/* Handle the 'g' get registers request */
-static void gdb_cmd_getregs(struct kgdb_state *ks)
+static void gdb_get_regs_helper(struct kgdb_state *ks)
 {
        struct task_struct *thread;
        void *local_debuggerinfo;
@@ -505,6 +521,12 @@ static void gdb_cmd_getregs(struct kgdb_state *ks)
                 */
                sleeping_thread_to_gdb_regs(gdb_regs, thread);
        }
+}
+
+/* Handle the 'g' get registers request */
+static void gdb_cmd_getregs(struct kgdb_state *ks)
+{
+       gdb_get_regs_helper(ks);
        kgdb_mem2hex((char *)gdb_regs, remcom_out_buffer, NUMREGBYTES);
 }
 
@@ -527,13 +549,13 @@ static void gdb_cmd_memread(struct kgdb_state *ks)
        char *ptr = &remcom_in_buffer[1];
        unsigned long length;
        unsigned long addr;
-       int err;
+       char *err;
 
        if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' &&
                                        kgdb_hex2long(&ptr, &length) > 0) {
                err = kgdb_mem2hex((char *)addr, remcom_out_buffer, length);
-               if (err)
-                       error_packet(remcom_out_buffer, err);
+               if (!err)
+                       error_packet(remcom_out_buffer, -EINVAL);
        } else {
                error_packet(remcom_out_buffer, -EINVAL);
        }
@@ -550,6 +572,60 @@ static void gdb_cmd_memwrite(struct kgdb_state *ks)
                strcpy(remcom_out_buffer, "OK");
 }
 
+#if DBG_MAX_REG_NUM > 0
+static char *gdb_hex_reg_helper(int regnum, char *out)
+{
+       int i;
+       int offset = 0;
+
+       for (i = 0; i < regnum; i++)
+               offset += dbg_reg_def[i].size;
+       return kgdb_mem2hex((char *)gdb_regs + offset, out,
+                           dbg_reg_def[i].size);
+}
+
+/* Handle the 'p' individual regster get */
+static void gdb_cmd_reg_get(struct kgdb_state *ks)
+{
+       unsigned long regnum;
+       char *ptr = &remcom_in_buffer[1];
+
+       kgdb_hex2long(&ptr, &regnum);
+       if (regnum >= DBG_MAX_REG_NUM) {
+               error_packet(remcom_out_buffer, -EINVAL);
+               return;
+       }
+       gdb_get_regs_helper(ks);
+       gdb_hex_reg_helper(regnum, remcom_out_buffer);
+}
+
+/* Handle the 'P' individual regster set */
+static void gdb_cmd_reg_set(struct kgdb_state *ks)
+{
+       unsigned long regnum;
+       char *ptr = &remcom_in_buffer[1];
+       int i = 0;
+
+       kgdb_hex2long(&ptr, &regnum);
+       if (*ptr++ != '=' ||
+           !(!kgdb_usethread || kgdb_usethread == current) ||
+           !dbg_get_reg(regnum, gdb_regs, ks->linux_regs)) {
+               error_packet(remcom_out_buffer, -EINVAL);
+               return;
+       }
+       memset(gdb_regs, 0, sizeof(gdb_regs));
+       while (i < sizeof(gdb_regs) * 2)
+               if (hex_to_bin(ptr[i]) >= 0)
+                       i++;
+               else
+                       break;
+       i = i / 2;
+       kgdb_hex2mem(ptr, (char *)gdb_regs, i);
+       dbg_set_reg(regnum, gdb_regs, ks->linux_regs);
+       strcpy(remcom_out_buffer, "OK");
+}
+#endif /* DBG_MAX_REG_NUM > 0 */
+
 /* Handle the 'X' memory binary write bytes */
 static void gdb_cmd_binwrite(struct kgdb_state *ks)
 {
@@ -612,7 +688,7 @@ static void gdb_cmd_query(struct kgdb_state *ks)
 {
        struct task_struct *g;
        struct task_struct *p;
-       unsigned char thref[8];
+       unsigned char thref[BUF_THREAD_ID_SIZE];
        char *ptr;
        int i;
        int cpu;
@@ -632,8 +708,7 @@ static void gdb_cmd_query(struct kgdb_state *ks)
                        for_each_online_cpu(cpu) {
                                ks->thr_query = 0;
                                int_to_threadref(thref, -cpu - 2);
-                               pack_threadid(ptr, thref);
-                               ptr += BUF_THREAD_ID_SIZE;
+                               ptr = pack_threadid(ptr, thref);
                                *(ptr++) = ',';
                                i++;
                        }
@@ -642,8 +717,7 @@ static void gdb_cmd_query(struct kgdb_state *ks)
                do_each_thread(g, p) {
                        if (i >= ks->thr_query && !finished) {
                                int_to_threadref(thref, p->pid);
-                               pack_threadid(ptr, thref);
-                               ptr += BUF_THREAD_ID_SIZE;
+                               ptr = pack_threadid(ptr, thref);
                                *(ptr++) = ',';
                                ks->thr_query++;
                                if (ks->thr_query % KGDB_MAX_THREAD_QUERY == 0)
@@ -858,11 +932,14 @@ int gdb_serial_stub(struct kgdb_state *ks)
        int error = 0;
        int tmp;
 
-       /* Clear the out buffer. */
+       /* Initialize comm buffer and globals. */
        memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
+       kgdb_usethread = kgdb_info[ks->cpu].task;
+       ks->kgdb_usethreadid = shadow_pid(kgdb_info[ks->cpu].task->pid);
+       ks->pass_exception = 0;
 
        if (kgdb_connected) {
-               unsigned char thref[8];
+               unsigned char thref[BUF_THREAD_ID_SIZE];
                char *ptr;
 
                /* Reply to host that an exception has occurred */
@@ -876,10 +953,6 @@ int gdb_serial_stub(struct kgdb_state *ks)
                put_packet(remcom_out_buffer);
        }
 
-       kgdb_usethread = kgdb_info[ks->cpu].task;
-       ks->kgdb_usethreadid = shadow_pid(kgdb_info[ks->cpu].task->pid);
-       ks->pass_exception = 0;
-
        while (1) {
                error = 0;
 
@@ -904,6 +977,14 @@ int gdb_serial_stub(struct kgdb_state *ks)
                case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA */
                        gdb_cmd_memwrite(ks);
                        break;
+#if DBG_MAX_REG_NUM > 0
+               case 'p': /* pXX Return gdb register XX (in hex) */
+                       gdb_cmd_reg_get(ks);
+                       break;
+               case 'P': /* PXX=aaaa Set gdb register XX to aaaa (in hex) */
+                       gdb_cmd_reg_set(ks);
+                       break;
+#endif /* DBG_MAX_REG_NUM > 0 */
                case 'X': /* XAA..AA,LLLL: Write LLLL bytes at address AA..AA */
                        gdb_cmd_binwrite(ks);
                        break;
index ebe4a287419e2788f4a08d263007350fa0e3eb86..28b844118bbd9d27f1e6bede2fd2502c6fd4f1b8 100644 (file)
@@ -312,7 +312,7 @@ int kdbgetularg(const char *arg, unsigned long *value)
 
        if (endp == arg) {
                /*
-                * Try base 16, for us folks too lazy to type the
+                * Also try base 16, for us folks too lazy to type the
                 * leading 0x...
                 */
                val = simple_strtoul(arg, &endp, 16);
@@ -325,6 +325,25 @@ int kdbgetularg(const char *arg, unsigned long *value)
        return 0;
 }
 
+int kdbgetu64arg(const char *arg, u64 *value)
+{
+       char *endp;
+       u64 val;
+
+       val = simple_strtoull(arg, &endp, 0);
+
+       if (endp == arg) {
+
+               val = simple_strtoull(arg, &endp, 16);
+               if (endp == arg)
+                       return KDB_BADINT;
+       }
+
+       *value = val;
+
+       return 0;
+}
+
 /*
  * kdb_set - This function implements the 'set' command.  Alter an
  *     existing environment variable or create a new one.
@@ -1770,11 +1789,65 @@ static int kdb_go(int argc, const char **argv)
  */
 static int kdb_rd(int argc, const char **argv)
 {
-       int diag = kdb_check_regs();
-       if (diag)
-               return diag;
+       int len = kdb_check_regs();
+#if DBG_MAX_REG_NUM > 0
+       int i;
+       char *rname;
+       int rsize;
+       u64 reg64;
+       u32 reg32;
+       u16 reg16;
+       u8 reg8;
+
+       if (len)
+               return len;
+
+       for (i = 0; i < DBG_MAX_REG_NUM; i++) {
+               rsize = dbg_reg_def[i].size * 2;
+               if (rsize > 16)
+                       rsize = 2;
+               if (len + strlen(dbg_reg_def[i].name) + 4 + rsize > 80) {
+                       len = 0;
+                       kdb_printf("\n");
+               }
+               if (len)
+                       len += kdb_printf("  ");
+               switch(dbg_reg_def[i].size * 8) {
+               case 8:
+                       rname = dbg_get_reg(i, &reg8, kdb_current_regs);
+                       if (!rname)
+                               break;
+                       len += kdb_printf("%s: %02x", rname, reg8);
+                       break;
+               case 16:
+                       rname = dbg_get_reg(i, &reg16, kdb_current_regs);
+                       if (!rname)
+                               break;
+                       len += kdb_printf("%s: %04x", rname, reg16);
+                       break;
+               case 32:
+                       rname = dbg_get_reg(i, &reg32, kdb_current_regs);
+                       if (!rname)
+                               break;
+                       len += kdb_printf("%s: %08x", rname, reg32);
+                       break;
+               case 64:
+                       rname = dbg_get_reg(i, &reg64, kdb_current_regs);
+                       if (!rname)
+                               break;
+                       len += kdb_printf("%s: %016llx", rname, reg64);
+                       break;
+               default:
+                       len += kdb_printf("%s: ??", dbg_reg_def[i].name);
+               }
+       }
+       kdb_printf("\n");
+#else
+       if (len)
+               return len;
 
        kdb_dumpregs(kdb_current_regs);
+#endif
        return 0;
 }
 
@@ -1782,32 +1855,67 @@ static int kdb_rd(int argc, const char **argv)
  * kdb_rm - This function implements the 'rm' (register modify)  command.
  *     rm register-name new-contents
  * Remarks:
- *     Currently doesn't allow modification of control or
- *     debug registers.
+ *     Allows register modification with the same restrictions as gdb
  */
 static int kdb_rm(int argc, const char **argv)
 {
+#if DBG_MAX_REG_NUM > 0
        int diag;
-       int ind = 0;
-       unsigned long contents;
+       const char *rname;
+       int i;
+       u64 reg64;
+       u32 reg32;
+       u16 reg16;
+       u8 reg8;
 
        if (argc != 2)
                return KDB_ARGCOUNT;
        /*
         * Allow presence or absence of leading '%' symbol.
         */
-       if (argv[1][0] == '%')
-               ind = 1;
+       rname = argv[1];
+       if (*rname == '%')
+               rname++;
 
-       diag = kdbgetularg(argv[2], &contents);
+       diag = kdbgetu64arg(argv[2], &reg64);
        if (diag)
                return diag;
 
        diag = kdb_check_regs();
        if (diag)
                return diag;
+
+       diag = KDB_BADREG;
+       for (i = 0; i < DBG_MAX_REG_NUM; i++) {
+               if (strcmp(rname, dbg_reg_def[i].name) == 0) {
+                       diag = 0;
+                       break;
+               }
+       }
+       if (!diag) {
+               switch(dbg_reg_def[i].size * 8) {
+               case 8:
+                       reg8 = reg64;
+                       dbg_set_reg(i, &reg8, kdb_current_regs);
+                       break;
+               case 16:
+                       reg16 = reg64;
+                       dbg_set_reg(i, &reg16, kdb_current_regs);
+                       break;
+               case 32:
+                       reg32 = reg64;
+                       dbg_set_reg(i, &reg32, kdb_current_regs);
+                       break;
+               case 64:
+                       dbg_set_reg(i, &reg64, kdb_current_regs);
+                       break;
+               }
+       }
+       return diag;
+#else
        kdb_printf("ERROR: Register set currently not implemented\n");
-       return 0;
+    return 0;
+#endif
 }
 
 #if defined(CONFIG_MAGIC_SYSRQ)
@@ -2440,6 +2548,7 @@ static void kdb_sysinfo(struct sysinfo *val)
  */
 static int kdb_summary(int argc, const char **argv)
 {
+       struct timespec now;
        struct kdb_tm tm;
        struct sysinfo val;
 
@@ -2454,7 +2563,8 @@ static int kdb_summary(int argc, const char **argv)
        kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
        kdb_printf("ccversion  %s\n", __stringify(CCVERSION));
 
-       kdb_gmtime(&xtime, &tm);
+       now = __current_kernel_time();
+       kdb_gmtime(&now, &tm);
        kdb_printf("date       %04d-%02d-%02d %02d:%02d:%02d "
                   "tz_minuteswest %d\n",
                1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
index 97d3ba69775df3b66120f0e7579fc8fba0d896da..c438f545a3217eca47dcae2ff98618467971a9f7 100644 (file)
@@ -144,9 +144,7 @@ extern int kdb_getword(unsigned long *, unsigned long, size_t);
 extern int kdb_putword(unsigned long, unsigned long, size_t);
 
 extern int kdbgetularg(const char *, unsigned long *);
-extern int kdb_set(int, const char **);
 extern char *kdbgetenv(const char *);
-extern int kdbgetintenv(const char *, int *);
 extern int kdbgetaddrarg(int, const char **, int*, unsigned long *,
                         long *, char **);
 extern int kdbgetsymval(const char *, kdb_symtab_t *);
index b6cce14ba0470e641bd45c68ca2067c4ee70d38c..a82a65cef741935adc51082640f63c9a5049b5ea 100644 (file)
@@ -907,7 +907,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p)
 {
        unsigned long new_flags = p->flags;
 
-       new_flags &= ~PF_SUPERPRIV;
+       new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER);
        new_flags |= PF_FORKNOEXEC;
        new_flags |= PF_STARTING;
        p->flags = new_flags;
index 5c69e996bd0f0fcba57586800924b8d2989cda1b..ce669174f355c7dd1e1893903bb4d18a25f17c34 100644 (file)
@@ -90,7 +90,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
        do {
                seq = read_seqbegin(&xtime_lock);
                xts = __current_kernel_time();
-               tom = wall_to_monotonic;
+               tom = __get_wall_to_monotonic();
        } while (read_seqretry(&xtime_lock, seq));
 
        xtim = timespec_to_ktime(xts);
@@ -144,12 +144,8 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer,
 static int hrtimer_get_target(int this_cpu, int pinned)
 {
 #ifdef CONFIG_NO_HZ
-       if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu)) {
-               int preferred_cpu = get_nohz_load_balancer();
-
-               if (preferred_cpu >= 0)
-                       return preferred_cpu;
-       }
+       if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu))
+               return get_nohz_timer_target();
 #endif
        return this_cpu;
 }
@@ -612,7 +608,7 @@ static int hrtimer_reprogram(struct hrtimer *timer,
 static void retrigger_next_event(void *arg)
 {
        struct hrtimer_cpu_base *base;
-       struct timespec realtime_offset;
+       struct timespec realtime_offset, wtm;
        unsigned long seq;
 
        if (!hrtimer_hres_active())
@@ -620,10 +616,9 @@ static void retrigger_next_event(void *arg)
 
        do {
                seq = read_seqbegin(&xtime_lock);
-               set_normalized_timespec(&realtime_offset,
-                                       -wall_to_monotonic.tv_sec,
-                                       -wall_to_monotonic.tv_nsec);
+               wtm = __get_wall_to_monotonic();
        } while (read_seqretry(&xtime_lock, seq));
+       set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec);
 
        base = &__get_cpu_var(hrtimer_bases);
 
index 71ed3ce29e12e7d2dbe25d9e4b92e8d46a71fecd..d71a987fd2bf2ba5e698f9b69fccb59db4a1bb30 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/list.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
 
@@ -62,6 +63,9 @@ static DEFINE_PER_CPU(unsigned int, nr_bp_flexible[TYPE_MAX]);
 
 static int nr_slots[TYPE_MAX];
 
+/* Keep track of the breakpoints attached to tasks */
+static LIST_HEAD(bp_task_head);
+
 static int constraints_initialized;
 
 /* Gather the number of total pinned and un-pinned bp in a cpuset */
@@ -103,33 +107,21 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
        return 0;
 }
 
-static int task_bp_pinned(struct task_struct *tsk, enum bp_type_idx type)
+/*
+ * Count the number of breakpoints of the same type and same task.
+ * The given event must be not on the list.
+ */
+static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type)
 {
-       struct perf_event_context *ctx = tsk->perf_event_ctxp;
-       struct list_head *list;
-       struct perf_event *bp;
-       unsigned long flags;
+       struct perf_event_context *ctx = bp->ctx;
+       struct perf_event *iter;
        int count = 0;
 
-       if (WARN_ONCE(!ctx, "No perf context for this task"))
-               return 0;
-
-       list = &ctx->event_list;
-
-       raw_spin_lock_irqsave(&ctx->lock, flags);
-
-       /*
-        * The current breakpoint counter is not included in the list
-        * at the open() callback time
-        */
-       list_for_each_entry(bp, list, event_entry) {
-               if (bp->attr.type == PERF_TYPE_BREAKPOINT)
-                       if (find_slot_idx(bp) == type)
-                               count += hw_breakpoint_weight(bp);
+       list_for_each_entry(iter, &bp_task_head, hw.bp_list) {
+               if (iter->ctx == ctx && find_slot_idx(iter) == type)
+                       count += hw_breakpoint_weight(iter);
        }
 
-       raw_spin_unlock_irqrestore(&ctx->lock, flags);
-
        return count;
 }
 
@@ -149,7 +141,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
                if (!tsk)
                        slots->pinned += max_task_bp_pinned(cpu, type);
                else
-                       slots->pinned += task_bp_pinned(tsk, type);
+                       slots->pinned += task_bp_pinned(bp, type);
                slots->flexible = per_cpu(nr_bp_flexible[type], cpu);
 
                return;
@@ -162,7 +154,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
                if (!tsk)
                        nr += max_task_bp_pinned(cpu, type);
                else
-                       nr += task_bp_pinned(tsk, type);
+                       nr += task_bp_pinned(bp, type);
 
                if (nr > slots->pinned)
                        slots->pinned = nr;
@@ -188,7 +180,7 @@ fetch_this_slot(struct bp_busy_slots *slots, int weight)
 /*
  * Add a pinned breakpoint for the given task in our constraint table
  */
-static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable,
+static void toggle_bp_task_slot(struct perf_event *bp, int cpu, bool enable,
                                enum bp_type_idx type, int weight)
 {
        unsigned int *tsk_pinned;
@@ -196,10 +188,11 @@ static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable,
        int old_idx = 0;
        int idx = 0;
 
-       old_count = task_bp_pinned(tsk, type);
+       old_count = task_bp_pinned(bp, type);
        old_idx = old_count - 1;
        idx = old_idx + weight;
 
+       /* tsk_pinned[n] is the number of tasks having n breakpoints */
        tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu);
        if (enable) {
                tsk_pinned[idx]++;
@@ -222,23 +215,30 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type,
        int cpu = bp->cpu;
        struct task_struct *tsk = bp->ctx->task;
 
+       /* Pinned counter cpu profiling */
+       if (!tsk) {
+
+               if (enable)
+                       per_cpu(nr_cpu_bp_pinned[type], bp->cpu) += weight;
+               else
+                       per_cpu(nr_cpu_bp_pinned[type], bp->cpu) -= weight;
+               return;
+       }
+
        /* Pinned counter task profiling */
-       if (tsk) {
-               if (cpu >= 0) {
-                       toggle_bp_task_slot(tsk, cpu, enable, type, weight);
-                       return;
-               }
 
+       if (!enable)
+               list_del(&bp->hw.bp_list);
+
+       if (cpu >= 0) {
+               toggle_bp_task_slot(bp, cpu, enable, type, weight);
+       } else {
                for_each_online_cpu(cpu)
-                       toggle_bp_task_slot(tsk, cpu, enable, type, weight);
-               return;
+                       toggle_bp_task_slot(bp, cpu, enable, type, weight);
        }
 
-       /* Pinned counter cpu profiling */
        if (enable)
-               per_cpu(nr_cpu_bp_pinned[type], bp->cpu) += weight;
-       else
-               per_cpu(nr_cpu_bp_pinned[type], bp->cpu) -= weight;
+               list_add_tail(&bp->hw.bp_list, &bp_task_head);
 }
 
 /*
@@ -312,6 +312,10 @@ static int __reserve_bp_slot(struct perf_event *bp)
        weight = hw_breakpoint_weight(bp);
 
        fetch_bp_busy_slots(&slots, bp, type);
+       /*
+        * Simulate the addition of this breakpoint to the constraints
+        * and see the result.
+        */
        fetch_this_slot(&slots, weight);
 
        /* Flexible counters need to keep at least one slot */
index e1497481fe8a6feab3554173fb313ebbef59bb39..c3003e9d91a37da04c8c7ffc9aa5f986fc90fb04 100644 (file)
@@ -216,7 +216,7 @@ static inline int setup_affinity(unsigned int irq, struct irq_desc *desc)
 void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
 {
        if (suspend) {
-               if (!desc->action || (desc->action->flags & IRQF_TIMER))
+               if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND))
                        return;
                desc->status |= IRQ_SUSPENDED;
        }
index 83911c7801751dd847348145db20f4e3e40e33b6..2dc3786349d1723394c25e512b9b570bcf5a4f7e 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/file.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/freezer.h>
 #include <trace/events/sched.h>
 
 static DEFINE_SPINLOCK(kthread_create_lock);
@@ -35,6 +37,7 @@ struct kthread_create_info
 
 struct kthread {
        int should_stop;
+       void *data;
        struct completion exited;
 };
 
@@ -54,6 +57,19 @@ int kthread_should_stop(void)
 }
 EXPORT_SYMBOL(kthread_should_stop);
 
+/**
+ * kthread_data - return data value specified on kthread creation
+ * @task: kthread task in question
+ *
+ * Return the data value specified when kthread @task was created.
+ * The caller is responsible for ensuring the validity of @task when
+ * calling this function.
+ */
+void *kthread_data(struct task_struct *task)
+{
+       return to_kthread(task)->data;
+}
+
 static int kthread(void *_create)
 {
        /* Copy data: it's on kthread's stack */
@@ -64,6 +80,7 @@ static int kthread(void *_create)
        int ret;
 
        self.should_stop = 0;
+       self.data = data;
        init_completion(&self.exited);
        current->vfork_done = &self.exited;
 
@@ -247,3 +264,150 @@ int kthreadd(void *unused)
 
        return 0;
 }
+
+/**
+ * kthread_worker_fn - kthread function to process kthread_worker
+ * @worker_ptr: pointer to initialized kthread_worker
+ *
+ * This function can be used as @threadfn to kthread_create() or
+ * kthread_run() with @worker_ptr argument pointing to an initialized
+ * kthread_worker.  The started kthread will process work_list until
+ * the it is stopped with kthread_stop().  A kthread can also call
+ * this function directly after extra initialization.
+ *
+ * Different kthreads can be used for the same kthread_worker as long
+ * as there's only one kthread attached to it at any given time.  A
+ * kthread_worker without an attached kthread simply collects queued
+ * kthread_works.
+ */
+int kthread_worker_fn(void *worker_ptr)
+{
+       struct kthread_worker *worker = worker_ptr;
+       struct kthread_work *work;
+
+       WARN_ON(worker->task);
+       worker->task = current;
+repeat:
+       set_current_state(TASK_INTERRUPTIBLE);  /* mb paired w/ kthread_stop */
+
+       if (kthread_should_stop()) {
+               __set_current_state(TASK_RUNNING);
+               spin_lock_irq(&worker->lock);
+               worker->task = NULL;
+               spin_unlock_irq(&worker->lock);
+               return 0;
+       }
+
+       work = NULL;
+       spin_lock_irq(&worker->lock);
+       if (!list_empty(&worker->work_list)) {
+               work = list_first_entry(&worker->work_list,
+                                       struct kthread_work, node);
+               list_del_init(&work->node);
+       }
+       spin_unlock_irq(&worker->lock);
+
+       if (work) {
+               __set_current_state(TASK_RUNNING);
+               work->func(work);
+               smp_wmb();      /* wmb worker-b0 paired with flush-b1 */
+               work->done_seq = work->queue_seq;
+               smp_mb();       /* mb worker-b1 paired with flush-b0 */
+               if (atomic_read(&work->flushing))
+                       wake_up_all(&work->done);
+       } else if (!freezing(current))
+               schedule();
+
+       try_to_freeze();
+       goto repeat;
+}
+EXPORT_SYMBOL_GPL(kthread_worker_fn);
+
+/**
+ * queue_kthread_work - queue a kthread_work
+ * @worker: target kthread_worker
+ * @work: kthread_work to queue
+ *
+ * Queue @work to work processor @task for async execution.  @task
+ * must have been created with kthread_worker_create().  Returns %true
+ * if @work was successfully queued, %false if it was already pending.
+ */
+bool queue_kthread_work(struct kthread_worker *worker,
+                       struct kthread_work *work)
+{
+       bool ret = false;
+       unsigned long flags;
+
+       spin_lock_irqsave(&worker->lock, flags);
+       if (list_empty(&work->node)) {
+               list_add_tail(&work->node, &worker->work_list);
+               work->queue_seq++;
+               if (likely(worker->task))
+                       wake_up_process(worker->task);
+               ret = true;
+       }
+       spin_unlock_irqrestore(&worker->lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(queue_kthread_work);
+
+/**
+ * flush_kthread_work - flush a kthread_work
+ * @work: work to flush
+ *
+ * If @work is queued or executing, wait for it to finish execution.
+ */
+void flush_kthread_work(struct kthread_work *work)
+{
+       int seq = work->queue_seq;
+
+       atomic_inc(&work->flushing);
+
+       /*
+        * mb flush-b0 paired with worker-b1, to make sure either
+        * worker sees the above increment or we see done_seq update.
+        */
+       smp_mb__after_atomic_inc();
+
+       /* A - B <= 0 tests whether B is in front of A regardless of overflow */
+       wait_event(work->done, seq - work->done_seq <= 0);
+       atomic_dec(&work->flushing);
+
+       /*
+        * rmb flush-b1 paired with worker-b0, to make sure our caller
+        * sees every change made by work->func().
+        */
+       smp_mb__after_atomic_dec();
+}
+EXPORT_SYMBOL_GPL(flush_kthread_work);
+
+struct kthread_flush_work {
+       struct kthread_work     work;
+       struct completion       done;
+};
+
+static void kthread_flush_work_fn(struct kthread_work *work)
+{
+       struct kthread_flush_work *fwork =
+               container_of(work, struct kthread_flush_work, work);
+       complete(&fwork->done);
+}
+
+/**
+ * flush_kthread_worker - flush all current works on a kthread_worker
+ * @worker: worker to flush
+ *
+ * Wait until all currently executing or pending works on @worker are
+ * finished.
+ */
+void flush_kthread_worker(struct kthread_worker *worker)
+{
+       struct kthread_flush_work fwork = {
+               KTHREAD_WORK_INIT(fwork.work, kthread_flush_work_fn),
+               COMPLETION_INITIALIZER_ONSTACK(fwork.done),
+       };
+
+       queue_kthread_work(worker, &fwork.work);
+       wait_for_completion(&fwork.done);
+}
+EXPORT_SYMBOL_GPL(flush_kthread_worker);
index 54286798c37b8e060078adbd7444c3f2c8da9847..f2852a5102327f74c39531a517e488c0d1e673e5 100644 (file)
@@ -146,7 +146,7 @@ static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS],
 
 static inline u64 lockstat_clock(void)
 {
-       return cpu_clock(smp_processor_id());
+       return local_clock();
 }
 
 static int lock_point(unsigned long points[], unsigned long ip)
index 6c562828c85c2d3d952c46be2de0b2cb0b3748a9..d0b5f8db11b4a4183c229e2a44f433a99f58090a 100644 (file)
@@ -1,6 +1,6 @@
 /*
    Copyright (C) 2002 Richard Henderson
-   Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
+   Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -110,6 +110,20 @@ int unregister_module_notifier(struct notifier_block * nb)
 }
 EXPORT_SYMBOL(unregister_module_notifier);
 
+struct load_info {
+       Elf_Ehdr *hdr;
+       unsigned long len;
+       Elf_Shdr *sechdrs;
+       char *secstrings, *strtab;
+       unsigned long *strmap;
+       unsigned long symoffs, stroffs;
+       struct _ddebug *debug;
+       unsigned int num_debug;
+       struct {
+               unsigned int sym, str, mod, vers, info, pcpu;
+       } index;
+};
+
 /* We require a truly strong try_module_get(): 0 means failure due to
    ongoing or failed initialization etc. */
 static inline int strong_try_module_get(struct module *mod)
@@ -140,42 +154,38 @@ void __module_put_and_exit(struct module *mod, long code)
 EXPORT_SYMBOL(__module_put_and_exit);
 
 /* Find a module section: 0 means not found. */
-static unsigned int find_sec(Elf_Ehdr *hdr,
-                            Elf_Shdr *sechdrs,
-                            const char *secstrings,
-                            const char *name)
+static unsigned int find_sec(const struct load_info *info, const char *name)
 {
        unsigned int i;
 
-       for (i = 1; i < hdr->e_shnum; i++)
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               Elf_Shdr *shdr = &info->sechdrs[i];
                /* Alloc bit cleared means "ignore it." */
-               if ((sechdrs[i].sh_flags & SHF_ALLOC)
-                   && strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
+               if ((shdr->sh_flags & SHF_ALLOC)
+                   && strcmp(info->secstrings + shdr->sh_name, name) == 0)
                        return i;
+       }
        return 0;
 }
 
 /* Find a module section, or NULL. */
-static void *section_addr(Elf_Ehdr *hdr, Elf_Shdr *shdrs,
-                         const char *secstrings, const char *name)
+static void *section_addr(const struct load_info *info, const char *name)
 {
        /* Section 0 has sh_addr 0. */
-       return (void *)shdrs[find_sec(hdr, shdrs, secstrings, name)].sh_addr;
+       return (void *)info->sechdrs[find_sec(info, name)].sh_addr;
 }
 
 /* Find a module section, or NULL.  Fill in number of "objects" in section. */
-static void *section_objs(Elf_Ehdr *hdr,
-                         Elf_Shdr *sechdrs,
-                         const char *secstrings,
+static void *section_objs(const struct load_info *info,
                          const char *name,
                          size_t object_size,
                          unsigned int *num)
 {
-       unsigned int sec = find_sec(hdr, sechdrs, secstrings, name);
+       unsigned int sec = find_sec(info, name);
 
        /* Section 0 has sh_addr 0 and sh_size 0. */
-       *num = sechdrs[sec].sh_size / object_size;
-       return (void *)sechdrs[sec].sh_addr;
+       *num = info->sechdrs[sec].sh_size / object_size;
+       return (void *)info->sechdrs[sec].sh_addr;
 }
 
 /* Provided by the linker */
@@ -227,7 +237,7 @@ bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
                            unsigned int symnum, void *data), void *data)
 {
        struct module *mod;
-       const struct symsearch arr[] = {
+       static const struct symsearch arr[] = {
                { __start___ksymtab, __stop___ksymtab, __start___kcrctab,
                  NOT_GPL_ONLY, false },
                { __start___ksymtab_gpl, __stop___ksymtab_gpl,
@@ -392,7 +402,8 @@ static int percpu_modalloc(struct module *mod,
        mod->percpu = __alloc_reserved_percpu(size, align);
        if (!mod->percpu) {
                printk(KERN_WARNING
-                      "Could not allocate %lu bytes percpu data\n", size);
+                      "%s: Could not allocate %lu bytes percpu data\n",
+                      mod->name, size);
                return -ENOMEM;
        }
        mod->percpu_size = size;
@@ -404,11 +415,9 @@ static void percpu_modfree(struct module *mod)
        free_percpu(mod->percpu);
 }
 
-static unsigned int find_pcpusec(Elf_Ehdr *hdr,
-                                Elf_Shdr *sechdrs,
-                                const char *secstrings)
+static unsigned int find_pcpusec(struct load_info *info)
 {
-       return find_sec(hdr, sechdrs, secstrings, ".data..percpu");
+       return find_sec(info, ".data..percpu");
 }
 
 static void percpu_modcopy(struct module *mod,
@@ -468,9 +477,7 @@ static inline int percpu_modalloc(struct module *mod,
 static inline void percpu_modfree(struct module *mod)
 {
 }
-static inline unsigned int find_pcpusec(Elf_Ehdr *hdr,
-                                       Elf_Shdr *sechdrs,
-                                       const char *secstrings)
+static unsigned int find_pcpusec(struct load_info *info)
 {
        return 0;
 }
@@ -524,21 +531,21 @@ static char last_unloaded_module[MODULE_NAME_LEN+1];
 EXPORT_TRACEPOINT_SYMBOL(module_get);
 
 /* Init the unload section of the module. */
-static void module_unload_init(struct module *mod)
+static int module_unload_init(struct module *mod)
 {
-       int cpu;
+       mod->refptr = alloc_percpu(struct module_ref);
+       if (!mod->refptr)
+               return -ENOMEM;
 
        INIT_LIST_HEAD(&mod->source_list);
        INIT_LIST_HEAD(&mod->target_list);
-       for_each_possible_cpu(cpu) {
-               per_cpu_ptr(mod->refptr, cpu)->incs = 0;
-               per_cpu_ptr(mod->refptr, cpu)->decs = 0;
-       }
 
        /* Hold reference count during initialization. */
        __this_cpu_write(mod->refptr->incs, 1);
        /* Backwards compatibility macros put refcount during init. */
        mod->waiter = current;
+
+       return 0;
 }
 
 /* Does a already use b? */
@@ -618,6 +625,8 @@ static void module_unload_free(struct module *mod)
                kfree(use);
        }
        mutex_unlock(&module_mutex);
+
+       free_percpu(mod->refptr);
 }
 
 #ifdef CONFIG_MODULE_FORCE_UNLOAD
@@ -891,8 +900,9 @@ int ref_module(struct module *a, struct module *b)
 }
 EXPORT_SYMBOL_GPL(ref_module);
 
-static inline void module_unload_init(struct module *mod)
+static inline int module_unload_init(struct module *mod)
 {
+       return 0;
 }
 #endif /* CONFIG_MODULE_UNLOAD */
 
@@ -1051,10 +1061,9 @@ static inline int same_magic(const char *amagic, const char *bmagic,
 #endif /* CONFIG_MODVERSIONS */
 
 /* Resolve a symbol for this module.  I.e. if we find one, record usage. */
-static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
-                                                 unsigned int versindex,
+static const struct kernel_symbol *resolve_symbol(struct module *mod,
+                                                 const struct load_info *info,
                                                  const char *name,
-                                                 struct module *mod,
                                                  char ownername[])
 {
        struct module *owner;
@@ -1068,7 +1077,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
        if (!sym)
                goto unlock;
 
-       if (!check_version(sechdrs, versindex, name, mod, crc, owner)) {
+       if (!check_version(info->sechdrs, info->index.vers, name, mod, crc,
+                          owner)) {
                sym = ERR_PTR(-EINVAL);
                goto getname;
        }
@@ -1087,21 +1097,20 @@ unlock:
        return sym;
 }
 
-static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs,
-                                                      unsigned int versindex,
-                                                      const char *name,
-                                                      struct module *mod)
+static const struct kernel_symbol *
+resolve_symbol_wait(struct module *mod,
+                   const struct load_info *info,
+                   const char *name)
 {
        const struct kernel_symbol *ksym;
-       char ownername[MODULE_NAME_LEN];
+       char owner[MODULE_NAME_LEN];
 
        if (wait_event_interruptible_timeout(module_wq,
-                       !IS_ERR(ksym = resolve_symbol(sechdrs, versindex, name,
-                                                     mod, ownername)) ||
-                       PTR_ERR(ksym) != -EBUSY,
+                       !IS_ERR(ksym = resolve_symbol(mod, info, name, owner))
+                       || PTR_ERR(ksym) != -EBUSY,
                                             30 * HZ) <= 0) {
                printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n",
-                      mod->name, ownername);
+                      mod->name, owner);
        }
        return ksym;
 }
@@ -1110,8 +1119,9 @@ static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs,
  * /sys/module/foo/sections stuff
  * J. Corbet <corbet@lwn.net>
  */
-#if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS)
+#ifdef CONFIG_SYSFS
 
+#ifdef CONFIG_KALLSYMS
 static inline bool sect_empty(const Elf_Shdr *sect)
 {
        return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;
@@ -1148,8 +1158,7 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
        kfree(sect_attrs);
 }
 
-static void add_sect_attrs(struct module *mod, unsigned int nsect,
-               char *secstrings, Elf_Shdr *sechdrs)
+static void add_sect_attrs(struct module *mod, const struct load_info *info)
 {
        unsigned int nloaded = 0, i, size[2];
        struct module_sect_attrs *sect_attrs;
@@ -1157,8 +1166,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
        struct attribute **gattr;
 
        /* Count loaded sections and allocate structures */
-       for (i = 0; i < nsect; i++)
-               if (!sect_empty(&sechdrs[i]))
+       for (i = 0; i < info->hdr->e_shnum; i++)
+               if (!sect_empty(&info->sechdrs[i]))
                        nloaded++;
        size[0] = ALIGN(sizeof(*sect_attrs)
                        + nloaded * sizeof(sect_attrs->attrs[0]),
@@ -1175,11 +1184,12 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
        sect_attrs->nsections = 0;
        sattr = &sect_attrs->attrs[0];
        gattr = &sect_attrs->grp.attrs[0];
-       for (i = 0; i < nsect; i++) {
-               if (sect_empty(&sechdrs[i]))
+       for (i = 0; i < info->hdr->e_shnum; i++) {
+               Elf_Shdr *sec = &info->sechdrs[i];
+               if (sect_empty(sec))
                        continue;
-               sattr->address = sechdrs[i].sh_addr;
-               sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
+               sattr->address = sec->sh_addr;
+               sattr->name = kstrdup(info->secstrings + sec->sh_name,
                                        GFP_KERNEL);
                if (sattr->name == NULL)
                        goto out;
@@ -1247,8 +1257,7 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
        kfree(notes_attrs);
 }
 
-static void add_notes_attrs(struct module *mod, unsigned int nsect,
-                           char *secstrings, Elf_Shdr *sechdrs)
+static void add_notes_attrs(struct module *mod, const struct load_info *info)
 {
        unsigned int notes, loaded, i;
        struct module_notes_attrs *notes_attrs;
@@ -1260,9 +1269,9 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
 
        /* Count notes sections and allocate structures.  */
        notes = 0;
-       for (i = 0; i < nsect; i++)
-               if (!sect_empty(&sechdrs[i]) &&
-                   (sechdrs[i].sh_type == SHT_NOTE))
+       for (i = 0; i < info->hdr->e_shnum; i++)
+               if (!sect_empty(&info->sechdrs[i]) &&
+                   (info->sechdrs[i].sh_type == SHT_NOTE))
                        ++notes;
 
        if (notes == 0)
@@ -1276,15 +1285,15 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
 
        notes_attrs->notes = notes;
        nattr = &notes_attrs->attrs[0];
-       for (loaded = i = 0; i < nsect; ++i) {
-               if (sect_empty(&sechdrs[i]))
+       for (loaded = i = 0; i < info->hdr->e_shnum; ++i) {
+               if (sect_empty(&info->sechdrs[i]))
                        continue;
-               if (sechdrs[i].sh_type == SHT_NOTE) {
+               if (info->sechdrs[i].sh_type == SHT_NOTE) {
                        sysfs_bin_attr_init(nattr);
                        nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
                        nattr->attr.mode = S_IRUGO;
-                       nattr->size = sechdrs[i].sh_size;
-                       nattr->private = (void *) sechdrs[i].sh_addr;
+                       nattr->size = info->sechdrs[i].sh_size;
+                       nattr->private = (void *) info->sechdrs[i].sh_addr;
                        nattr->read = module_notes_read;
                        ++nattr;
                }
@@ -1315,8 +1324,8 @@ static void remove_notes_attrs(struct module *mod)
 
 #else
 
-static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
-               char *sectstrings, Elf_Shdr *sechdrs)
+static inline void add_sect_attrs(struct module *mod,
+                                 const struct load_info *info)
 {
 }
 
@@ -1324,17 +1333,16 @@ static inline void remove_sect_attrs(struct module *mod)
 {
 }
 
-static inline void add_notes_attrs(struct module *mod, unsigned int nsect,
-                                  char *sectstrings, Elf_Shdr *sechdrs)
+static inline void add_notes_attrs(struct module *mod,
+                                  const struct load_info *info)
 {
 }
 
 static inline void remove_notes_attrs(struct module *mod)
 {
 }
-#endif
+#endif /* CONFIG_KALLSYMS */
 
-#ifdef CONFIG_SYSFS
 static void add_usage_links(struct module *mod)
 {
 #ifdef CONFIG_MODULE_UNLOAD
@@ -1439,6 +1447,7 @@ out:
 }
 
 static int mod_sysfs_setup(struct module *mod,
+                          const struct load_info *info,
                           struct kernel_param *kparam,
                           unsigned int num_params)
 {
@@ -1463,6 +1472,8 @@ static int mod_sysfs_setup(struct module *mod,
                goto out_unreg_param;
 
        add_usage_links(mod);
+       add_sect_attrs(mod, info);
+       add_notes_attrs(mod, info);
 
        kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
        return 0;
@@ -1479,33 +1490,26 @@ out:
 
 static void mod_sysfs_fini(struct module *mod)
 {
+       remove_notes_attrs(mod);
+       remove_sect_attrs(mod);
        kobject_put(&mod->mkobj.kobj);
 }
 
-#else /* CONFIG_SYSFS */
-
-static inline int mod_sysfs_init(struct module *mod)
-{
-       return 0;
-}
+#else /* !CONFIG_SYSFS */
 
-static inline int mod_sysfs_setup(struct module *mod,
+static int mod_sysfs_setup(struct module *mod,
+                          const struct load_info *info,
                           struct kernel_param *kparam,
                           unsigned int num_params)
 {
        return 0;
 }
 
-static inline int module_add_modinfo_attrs(struct module *mod)
-{
-       return 0;
-}
-
-static inline void module_remove_modinfo_attrs(struct module *mod)
+static void mod_sysfs_fini(struct module *mod)
 {
 }
 
-static void mod_sysfs_fini(struct module *mod)
+static void module_remove_modinfo_attrs(struct module *mod)
 {
 }
 
@@ -1515,7 +1519,7 @@ static void del_usage_links(struct module *mod)
 
 #endif /* CONFIG_SYSFS */
 
-static void mod_kobject_remove(struct module *mod)
+static void mod_sysfs_teardown(struct module *mod)
 {
        del_usage_links(mod);
        module_remove_modinfo_attrs(mod);
@@ -1545,9 +1549,7 @@ static void free_module(struct module *mod)
        mutex_lock(&module_mutex);
        stop_machine(__unlink_module, mod, NULL);
        mutex_unlock(&module_mutex);
-       remove_notes_attrs(mod);
-       remove_sect_attrs(mod);
-       mod_kobject_remove(mod);
+       mod_sysfs_teardown(mod);
 
        /* Remove dynamic debug info */
        ddebug_remove_module(mod->name);
@@ -1565,10 +1567,7 @@ static void free_module(struct module *mod)
        module_free(mod, mod->module_init);
        kfree(mod->args);
        percpu_modfree(mod);
-#if defined(CONFIG_MODULE_UNLOAD)
-       if (mod->refptr)
-               free_percpu(mod->refptr);
-#endif
+
        /* Free lock-classes: */
        lockdep_free_key_range(mod->module_core, mod->core_size);
 
@@ -1634,25 +1633,23 @@ static int verify_export_symbols(struct module *mod)
 }
 
 /* Change all symbols so that st_value encodes the pointer directly. */
-static int simplify_symbols(Elf_Shdr *sechdrs,
-                           unsigned int symindex,
-                           const char *strtab,
-                           unsigned int versindex,
-                           unsigned int pcpuindex,
-                           struct module *mod)
-{
-       Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+static int simplify_symbols(struct module *mod, const struct load_info *info)
+{
+       Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
+       Elf_Sym *sym = (void *)symsec->sh_addr;
        unsigned long secbase;
-       unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+       unsigned int i;
        int ret = 0;
        const struct kernel_symbol *ksym;
 
-       for (i = 1; i < n; i++) {
+       for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) {
+               const char *name = info->strtab + sym[i].st_name;
+
                switch (sym[i].st_shndx) {
                case SHN_COMMON:
                        /* We compiled with -fno-common.  These are not
                           supposed to happen.  */
-                       DEBUGP("Common symbol: %s\n", strtab + sym[i].st_name);
+                       DEBUGP("Common symbol: %s\n", name);
                        printk("%s: please compile with -fno-common\n",
                               mod->name);
                        ret = -ENOEXEC;
@@ -1665,9 +1662,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
                        break;
 
                case SHN_UNDEF:
-                       ksym = resolve_symbol_wait(sechdrs, versindex,
-                                                  strtab + sym[i].st_name,
-                                                  mod);
+                       ksym = resolve_symbol_wait(mod, info, name);
                        /* Ok if resolved.  */
                        if (ksym && !IS_ERR(ksym)) {
                                sym[i].st_value = ksym->value;
@@ -1679,17 +1674,16 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
                                break;
 
                        printk(KERN_WARNING "%s: Unknown symbol %s (err %li)\n",
-                              mod->name, strtab + sym[i].st_name,
-                              PTR_ERR(ksym));
+                              mod->name, name, PTR_ERR(ksym));
                        ret = PTR_ERR(ksym) ?: -ENOENT;
                        break;
 
                default:
                        /* Divert to percpu allocation if a percpu var. */
-                       if (sym[i].st_shndx == pcpuindex)
+                       if (sym[i].st_shndx == info->index.pcpu)
                                secbase = (unsigned long)mod_percpu(mod);
                        else
-                               secbase = sechdrs[sym[i].st_shndx].sh_addr;
+                               secbase = info->sechdrs[sym[i].st_shndx].sh_addr;
                        sym[i].st_value += secbase;
                        break;
                }
@@ -1698,6 +1692,35 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
        return ret;
 }
 
+static int apply_relocations(struct module *mod, const struct load_info *info)
+{
+       unsigned int i;
+       int err = 0;
+
+       /* Now do relocations. */
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               unsigned int infosec = info->sechdrs[i].sh_info;
+
+               /* Not a valid relocation section? */
+               if (infosec >= info->hdr->e_shnum)
+                       continue;
+
+               /* Don't bother with non-allocated sections */
+               if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC))
+                       continue;
+
+               if (info->sechdrs[i].sh_type == SHT_REL)
+                       err = apply_relocate(info->sechdrs, info->strtab,
+                                            info->index.sym, i, mod);
+               else if (info->sechdrs[i].sh_type == SHT_RELA)
+                       err = apply_relocate_add(info->sechdrs, info->strtab,
+                                                info->index.sym, i, mod);
+               if (err < 0)
+                       break;
+       }
+       return err;
+}
+
 /* Additional bytes needed by arch in front of individual sections */
 unsigned int __weak arch_mod_section_prepend(struct module *mod,
                                             unsigned int section)
@@ -1722,10 +1745,7 @@ static long get_offset(struct module *mod, unsigned int *size,
    might -- code, read-only data, read-write data, small data.  Tally
    sizes, and place the offsets into sh_entsize fields: high bit means it
    belongs in init. */
-static void layout_sections(struct module *mod,
-                           const Elf_Ehdr *hdr,
-                           Elf_Shdr *sechdrs,
-                           const char *secstrings)
+static void layout_sections(struct module *mod, struct load_info *info)
 {
        static unsigned long const masks[][2] = {
                /* NOTE: all executable code must be the first section
@@ -1738,21 +1758,22 @@ static void layout_sections(struct module *mod,
        };
        unsigned int m, i;
 
-       for (i = 0; i < hdr->e_shnum; i++)
-               sechdrs[i].sh_entsize = ~0UL;
+       for (i = 0; i < info->hdr->e_shnum; i++)
+               info->sechdrs[i].sh_entsize = ~0UL;
 
        DEBUGP("Core section allocation order:\n");
        for (m = 0; m < ARRAY_SIZE(masks); ++m) {
-               for (i = 0; i < hdr->e_shnum; ++i) {
-                       Elf_Shdr *s = &sechdrs[i];
+               for (i = 0; i < info->hdr->e_shnum; ++i) {
+                       Elf_Shdr *s = &info->sechdrs[i];
+                       const char *sname = info->secstrings + s->sh_name;
 
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || strstarts(secstrings + s->sh_name, ".init"))
+                           || strstarts(sname, ".init"))
                                continue;
                        s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
-                       DEBUGP("\t%s\n", secstrings + s->sh_name);
+                       DEBUGP("\t%s\n", name);
                }
                if (m == 0)
                        mod->core_text_size = mod->core_size;
@@ -1760,17 +1781,18 @@ static void layout_sections(struct module *mod,
 
        DEBUGP("Init section allocation order:\n");
        for (m = 0; m < ARRAY_SIZE(masks); ++m) {
-               for (i = 0; i < hdr->e_shnum; ++i) {
-                       Elf_Shdr *s = &sechdrs[i];
+               for (i = 0; i < info->hdr->e_shnum; ++i) {
+                       Elf_Shdr *s = &info->sechdrs[i];
+                       const char *sname = info->secstrings + s->sh_name;
 
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || !strstarts(secstrings + s->sh_name, ".init"))
+                           || !strstarts(sname, ".init"))
                                continue;
                        s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
                                         | INIT_OFFSET_MASK);
-                       DEBUGP("\t%s\n", secstrings + s->sh_name);
+                       DEBUGP("\t%s\n", sname);
                }
                if (m == 0)
                        mod->init_text_size = mod->init_size;
@@ -1809,33 +1831,28 @@ static char *next_string(char *string, unsigned long *secsize)
        return string;
 }
 
-static char *get_modinfo(Elf_Shdr *sechdrs,
-                        unsigned int info,
-                        const char *tag)
+static char *get_modinfo(struct load_info *info, const char *tag)
 {
        char *p;
        unsigned int taglen = strlen(tag);
-       unsigned long size = sechdrs[info].sh_size;
+       Elf_Shdr *infosec = &info->sechdrs[info->index.info];
+       unsigned long size = infosec->sh_size;
 
-       for (p = (char *)sechdrs[info].sh_addr; p; p = next_string(p, &size)) {
+       for (p = (char *)infosec->sh_addr; p; p = next_string(p, &size)) {
                if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
                        return p + taglen + 1;
        }
        return NULL;
 }
 
-static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
-                         unsigned int infoindex)
+static void setup_modinfo(struct module *mod, struct load_info *info)
 {
        struct module_attribute *attr;
        int i;
 
        for (i = 0; (attr = modinfo_attrs[i]); i++) {
                if (attr->setup)
-                       attr->setup(mod,
-                                   get_modinfo(sechdrs,
-                                               infoindex,
-                                               attr->attr.name));
+                       attr->setup(mod, get_modinfo(info, attr->attr.name));
        }
 }
 
@@ -1876,11 +1893,10 @@ static int is_exported(const char *name, unsigned long value,
 }
 
 /* As per nm */
-static char elf_type(const Elf_Sym *sym,
-                    Elf_Shdr *sechdrs,
-                    const char *secstrings,
-                    struct module *mod)
+static char elf_type(const Elf_Sym *sym, const struct load_info *info)
 {
+       const Elf_Shdr *sechdrs = info->sechdrs;
+
        if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
                if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
                        return 'v';
@@ -1910,8 +1926,10 @@ static char elf_type(const Elf_Sym *sym,
                else
                        return 'b';
        }
-       if (strstarts(secstrings + sechdrs[sym->st_shndx].sh_name, ".debug"))
+       if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
+                     ".debug")) {
                return 'n';
+       }
        return '?';
 }
 
@@ -1936,127 +1954,96 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
        return true;
 }
 
-static unsigned long layout_symtab(struct module *mod,
-                                  Elf_Shdr *sechdrs,
-                                  unsigned int symindex,
-                                  unsigned int strindex,
-                                  const Elf_Ehdr *hdr,
-                                  const char *secstrings,
-                                  unsigned long *pstroffs,
-                                  unsigned long *strmap)
+static void layout_symtab(struct module *mod, struct load_info *info)
 {
-       unsigned long symoffs;
-       Elf_Shdr *symsect = sechdrs + symindex;
-       Elf_Shdr *strsect = sechdrs + strindex;
+       Elf_Shdr *symsect = info->sechdrs + info->index.sym;
+       Elf_Shdr *strsect = info->sechdrs + info->index.str;
        const Elf_Sym *src;
-       const char *strtab;
        unsigned int i, nsrc, ndst;
 
        /* Put symbol section at end of init part of module. */
        symsect->sh_flags |= SHF_ALLOC;
        symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect,
-                                        symindex) | INIT_OFFSET_MASK;
-       DEBUGP("\t%s\n", secstrings + symsect->sh_name);
+                                        info->index.sym) | INIT_OFFSET_MASK;
+       DEBUGP("\t%s\n", info->secstrings + symsect->sh_name);
 
-       src = (void *)hdr + symsect->sh_offset;
+       src = (void *)info->hdr + symsect->sh_offset;
        nsrc = symsect->sh_size / sizeof(*src);
-       strtab = (void *)hdr + strsect->sh_offset;
        for (ndst = i = 1; i < nsrc; ++i, ++src)
-               if (is_core_symbol(src, sechdrs, hdr->e_shnum)) {
+               if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
                        unsigned int j = src->st_name;
 
-                       while(!__test_and_set_bit(j, strmap) && strtab[j])
+                       while (!__test_and_set_bit(j, info->strmap)
+                              && info->strtab[j])
                                ++j;
                        ++ndst;
                }
 
        /* Append room for core symbols at end of core part. */
-       symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
-       mod->core_size = symoffs + ndst * sizeof(Elf_Sym);
+       info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
+       mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
 
        /* Put string table section at end of init part of module. */
        strsect->sh_flags |= SHF_ALLOC;
        strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
-                                        strindex) | INIT_OFFSET_MASK;
-       DEBUGP("\t%s\n", secstrings + strsect->sh_name);
+                                        info->index.str) | INIT_OFFSET_MASK;
+       DEBUGP("\t%s\n", info->secstrings + strsect->sh_name);
 
        /* Append room for core symbols' strings at end of core part. */
-       *pstroffs = mod->core_size;
-       __set_bit(0, strmap);
-       mod->core_size += bitmap_weight(strmap, strsect->sh_size);
-
-       return symoffs;
+       info->stroffs = mod->core_size;
+       __set_bit(0, info->strmap);
+       mod->core_size += bitmap_weight(info->strmap, strsect->sh_size);
 }
 
-static void add_kallsyms(struct module *mod,
-                        Elf_Shdr *sechdrs,
-                        unsigned int shnum,
-                        unsigned int symindex,
-                        unsigned int strindex,
-                        unsigned long symoffs,
-                        unsigned long stroffs,
-                        const char *secstrings,
-                        unsigned long *strmap)
+static void add_kallsyms(struct module *mod, const struct load_info *info)
 {
        unsigned int i, ndst;
        const Elf_Sym *src;
        Elf_Sym *dst;
        char *s;
+       Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
 
-       mod->symtab = (void *)sechdrs[symindex].sh_addr;
-       mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
-       mod->strtab = (void *)sechdrs[strindex].sh_addr;
+       mod->symtab = (void *)symsec->sh_addr;
+       mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
+       /* Make sure we get permanent strtab: don't use info->strtab. */
+       mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
 
        /* Set types up while we still have access to sections. */
        for (i = 0; i < mod->num_symtab; i++)
-               mod->symtab[i].st_info
-                       = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
+               mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
 
-       mod->core_symtab = dst = mod->module_core + symoffs;
+       mod->core_symtab = dst = mod->module_core + info->symoffs;
        src = mod->symtab;
        *dst = *src;
        for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
-               if (!is_core_symbol(src, sechdrs, shnum))
+               if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
                        continue;
                dst[ndst] = *src;
-               dst[ndst].st_name = bitmap_weight(strmap, dst[ndst].st_name);
+               dst[ndst].st_name = bitmap_weight(info->strmap,
+                                                 dst[ndst].st_name);
                ++ndst;
        }
        mod->core_num_syms = ndst;
 
-       mod->core_strtab = s = mod->module_core + stroffs;
-       for (*s = 0, i = 1; i < sechdrs[strindex].sh_size; ++i)
-               if (test_bit(i, strmap))
+       mod->core_strtab = s = mod->module_core + info->stroffs;
+       for (*s = 0, i = 1; i < info->sechdrs[info->index.str].sh_size; ++i)
+               if (test_bit(i, info->strmap))
                        *++s = mod->strtab[i];
 }
 #else
-static inline unsigned long layout_symtab(struct module *mod,
-                                         Elf_Shdr *sechdrs,
-                                         unsigned int symindex,
-                                         unsigned int strindex,
-                                         const Elf_Ehdr *hdr,
-                                         const char *secstrings,
-                                         unsigned long *pstroffs,
-                                         unsigned long *strmap)
+static inline void layout_symtab(struct module *mod, struct load_info *info)
 {
-       return 0;
 }
 
-static inline void add_kallsyms(struct module *mod,
-                               Elf_Shdr *sechdrs,
-                               unsigned int shnum,
-                               unsigned int symindex,
-                               unsigned int strindex,
-                               unsigned long symoffs,
-                               unsigned long stroffs,
-                               const char *secstrings,
-                               const unsigned long *strmap)
+static void add_kallsyms(struct module *mod, struct load_info *info)
 {
 }
 #endif /* CONFIG_KALLSYMS */
 
 static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
 {
+       if (!debug)
+               return;
 #ifdef CONFIG_DYNAMIC_DEBUG
        if (ddebug_add_module(debug, num, debug->modname))
                printk(KERN_ERR "dynamic debug error adding module: %s\n",
@@ -2087,65 +2074,47 @@ static void *module_alloc_update_bounds(unsigned long size)
 }
 
 #ifdef CONFIG_DEBUG_KMEMLEAK
-static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
-                                Elf_Shdr *sechdrs, char *secstrings)
+static void kmemleak_load_module(const struct module *mod,
+                                const struct load_info *info)
 {
        unsigned int i;
 
        /* only scan the sections containing data */
        kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
 
-       for (i = 1; i < hdr->e_shnum; i++) {
-               if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               const char *name = info->secstrings + info->sechdrs[i].sh_name;
+               if (!(info->sechdrs[i].sh_flags & SHF_ALLOC))
                        continue;
-               if (strncmp(secstrings + sechdrs[i].sh_name, ".data", 5) != 0
-                   && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0)
+               if (!strstarts(name, ".data") && !strstarts(name, ".bss"))
                        continue;
 
-               kmemleak_scan_area((void *)sechdrs[i].sh_addr,
-                                  sechdrs[i].sh_size, GFP_KERNEL);
+               kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
+                                  info->sechdrs[i].sh_size, GFP_KERNEL);
        }
 }
 #else
-static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
-                                       Elf_Shdr *sechdrs, char *secstrings)
+static inline void kmemleak_load_module(const struct module *mod,
+                                       const struct load_info *info)
 {
 }
 #endif
 
-/* Allocate and load the module: note that size of section 0 is always
-   zero, and we rely on this for optional sections. */
-static noinline struct module *load_module(void __user *umod,
-                                 unsigned long len,
-                                 const char __user *uargs)
+/* Sets info->hdr and info->len. */
+static int copy_and_check(struct load_info *info,
+                         const void __user *umod, unsigned long len,
+                         const char __user *uargs)
 {
+       int err;
        Elf_Ehdr *hdr;
-       Elf_Shdr *sechdrs;
-       char *secstrings, *args, *modmagic, *strtab = NULL;
-       char *staging;
-       unsigned int i;
-       unsigned int symindex = 0;
-       unsigned int strindex = 0;
-       unsigned int modindex, versindex, infoindex, pcpuindex;
-       struct module *mod;
-       long err = 0;
-       void *ptr = NULL; /* Stops spurious gcc warning */
-       unsigned long symoffs, stroffs, *strmap;
-       void __percpu *percpu;
-       struct _ddebug *debug = NULL;
-       unsigned int num_debug = 0;
 
-       mm_segment_t old_fs;
-
-       DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
-              umod, len, uargs);
        if (len < sizeof(*hdr))
-               return ERR_PTR(-ENOEXEC);
+               return -ENOEXEC;
 
        /* Suck in entire file: we'll want most of it. */
        /* vmalloc barfs on "unusual" numbers.  Check here */
        if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        if (copy_from_user(hdr, umod, len) != 0) {
                err = -EFAULT;
@@ -2153,135 +2122,225 @@ static noinline struct module *load_module(void __user *umod,
        }
 
        /* Sanity checks against insmoding binaries or wrong arch,
-           weird elf version */
+          weird elf version */
        if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
            || hdr->e_type != ET_REL
            || !elf_check_arch(hdr)
-           || hdr->e_shentsize != sizeof(*sechdrs)) {
+           || hdr->e_shentsize != sizeof(Elf_Shdr)) {
                err = -ENOEXEC;
                goto free_hdr;
        }
 
-       if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr))
-               goto truncated;
+       if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
+               err = -ENOEXEC;
+               goto free_hdr;
+       }
 
-       /* Convenience variables */
-       sechdrs = (void *)hdr + hdr->e_shoff;
-       secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-       sechdrs[0].sh_addr = 0;
+       info->hdr = hdr;
+       info->len = len;
+       return 0;
 
-       for (i = 1; i < hdr->e_shnum; i++) {
-               if (sechdrs[i].sh_type != SHT_NOBITS
-                   && len < sechdrs[i].sh_offset + sechdrs[i].sh_size)
-                       goto truncated;
+free_hdr:
+       vfree(hdr);
+       return err;
+}
+
+static void free_copy(struct load_info *info)
+{
+       vfree(info->hdr);
+}
+
+static int rewrite_section_headers(struct load_info *info)
+{
+       unsigned int i;
+
+       /* This should always be true, but let's be sure. */
+       info->sechdrs[0].sh_addr = 0;
+
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               Elf_Shdr *shdr = &info->sechdrs[i];
+               if (shdr->sh_type != SHT_NOBITS
+                   && info->len < shdr->sh_offset + shdr->sh_size) {
+                       printk(KERN_ERR "Module len %lu truncated\n",
+                              info->len);
+                       return -ENOEXEC;
+               }
 
                /* Mark all sections sh_addr with their address in the
                   temporary image. */
-               sechdrs[i].sh_addr = (size_t)hdr + sechdrs[i].sh_offset;
+               shdr->sh_addr = (size_t)info->hdr + shdr->sh_offset;
 
-               /* Internal symbols and strings. */
-               if (sechdrs[i].sh_type == SHT_SYMTAB) {
-                       symindex = i;
-                       strindex = sechdrs[i].sh_link;
-                       strtab = (char *)hdr + sechdrs[strindex].sh_offset;
-               }
 #ifndef CONFIG_MODULE_UNLOAD
                /* Don't load .exit sections */
-               if (strstarts(secstrings+sechdrs[i].sh_name, ".exit"))
-                       sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
+               if (strstarts(info->secstrings+shdr->sh_name, ".exit"))
+                       shdr->sh_flags &= ~(unsigned long)SHF_ALLOC;
 #endif
        }
 
-       modindex = find_sec(hdr, sechdrs, secstrings,
-                           ".gnu.linkonce.this_module");
-       if (!modindex) {
+       /* Track but don't keep modinfo and version sections. */
+       info->index.vers = find_sec(info, "__versions");
+       info->index.info = find_sec(info, ".modinfo");
+       info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
+       info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
+       return 0;
+}
+
+/*
+ * Set up our basic convenience variables (pointers to section headers,
+ * search for module section index etc), and do some basic section
+ * verification.
+ *
+ * Return the temporary module pointer (we'll replace it with the final
+ * one when we move the module sections around).
+ */
+static struct module *setup_load_info(struct load_info *info)
+{
+       unsigned int i;
+       int err;
+       struct module *mod;
+
+       /* Set up the convenience variables */
+       info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;
+       info->secstrings = (void *)info->hdr
+               + info->sechdrs[info->hdr->e_shstrndx].sh_offset;
+
+       err = rewrite_section_headers(info);
+       if (err)
+               return ERR_PTR(err);
+
+       /* Find internal symbols and strings. */
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               if (info->sechdrs[i].sh_type == SHT_SYMTAB) {
+                       info->index.sym = i;
+                       info->index.str = info->sechdrs[i].sh_link;
+                       info->strtab = (char *)info->hdr
+                               + info->sechdrs[info->index.str].sh_offset;
+                       break;
+               }
+       }
+
+       info->index.mod = find_sec(info, ".gnu.linkonce.this_module");
+       if (!info->index.mod) {
                printk(KERN_WARNING "No module found in object\n");
-               err = -ENOEXEC;
-               goto free_hdr;
+               return ERR_PTR(-ENOEXEC);
        }
        /* This is temporary: point mod into copy of data. */
-       mod = (void *)sechdrs[modindex].sh_addr;
+       mod = (void *)info->sechdrs[info->index.mod].sh_addr;
 
-       if (symindex == 0) {
+       if (info->index.sym == 0) {
                printk(KERN_WARNING "%s: module has no symbols (stripped?)\n",
                       mod->name);
-               err = -ENOEXEC;
-               goto free_hdr;
+               return ERR_PTR(-ENOEXEC);
        }
 
-       versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
-       infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo");
-       pcpuindex = find_pcpusec(hdr, sechdrs, secstrings);
-
-       /* Don't keep modinfo and version sections. */
-       sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
-       sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
+       info->index.pcpu = find_pcpusec(info);
 
        /* Check module struct version now, before we try to use module. */
-       if (!check_modstruct_version(sechdrs, versindex, mod)) {
-               err = -ENOEXEC;
-               goto free_hdr;
-       }
+       if (!check_modstruct_version(info->sechdrs, info->index.vers, mod))
+               return ERR_PTR(-ENOEXEC);
+
+       return mod;
+}
+
+static int check_modinfo(struct module *mod, struct load_info *info)
+{
+       const char *modmagic = get_modinfo(info, "vermagic");
+       int err;
 
-       modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
                err = try_to_force_load(mod, "bad vermagic");
                if (err)
-                       goto free_hdr;
-       } else if (!same_magic(modmagic, vermagic, versindex)) {
+                       return err;
+       } else if (!same_magic(modmagic, vermagic, info->index.vers)) {
                printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
                       mod->name, modmagic, vermagic);
-               err = -ENOEXEC;
-               goto free_hdr;
+               return -ENOEXEC;
        }
 
-       staging = get_modinfo(sechdrs, infoindex, "staging");
-       if (staging) {
+       if (get_modinfo(info, "staging")) {
                add_taint_module(mod, TAINT_CRAP);
                printk(KERN_WARNING "%s: module is from the staging directory,"
                       " the quality is unknown, you have been warned.\n",
                       mod->name);
        }
 
-       /* Now copy in args */
-       args = strndup_user(uargs, ~0UL >> 1);
-       if (IS_ERR(args)) {
-               err = PTR_ERR(args);
-               goto free_hdr;
-       }
+       /* Set up license info based on the info section */
+       set_license(mod, get_modinfo(info, "license"));
 
-       strmap = kzalloc(BITS_TO_LONGS(sechdrs[strindex].sh_size)
-                        * sizeof(long), GFP_KERNEL);
-       if (!strmap) {
-               err = -ENOMEM;
-               goto free_mod;
-       }
+       return 0;
+}
 
-       mod->state = MODULE_STATE_COMING;
+static void find_module_sections(struct module *mod, struct load_info *info)
+{
+       mod->kp = section_objs(info, "__param",
+                              sizeof(*mod->kp), &mod->num_kp);
+       mod->syms = section_objs(info, "__ksymtab",
+                                sizeof(*mod->syms), &mod->num_syms);
+       mod->crcs = section_addr(info, "__kcrctab");
+       mod->gpl_syms = section_objs(info, "__ksymtab_gpl",
+                                    sizeof(*mod->gpl_syms),
+                                    &mod->num_gpl_syms);
+       mod->gpl_crcs = section_addr(info, "__kcrctab_gpl");
+       mod->gpl_future_syms = section_objs(info,
+                                           "__ksymtab_gpl_future",
+                                           sizeof(*mod->gpl_future_syms),
+                                           &mod->num_gpl_future_syms);
+       mod->gpl_future_crcs = section_addr(info, "__kcrctab_gpl_future");
 
-       /* Allow arches to frob section contents and sizes.  */
-       err = module_frob_arch_sections(hdr, sechdrs, secstrings, mod);
-       if (err < 0)
-               goto free_mod;
+#ifdef CONFIG_UNUSED_SYMBOLS
+       mod->unused_syms = section_objs(info, "__ksymtab_unused",
+                                       sizeof(*mod->unused_syms),
+                                       &mod->num_unused_syms);
+       mod->unused_crcs = section_addr(info, "__kcrctab_unused");
+       mod->unused_gpl_syms = section_objs(info, "__ksymtab_unused_gpl",
+                                           sizeof(*mod->unused_gpl_syms),
+                                           &mod->num_unused_gpl_syms);
+       mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl");
+#endif
+#ifdef CONFIG_CONSTRUCTORS
+       mod->ctors = section_objs(info, ".ctors",
+                                 sizeof(*mod->ctors), &mod->num_ctors);
+#endif
 
-       if (pcpuindex) {
-               /* We have a special allocation for this section. */
-               err = percpu_modalloc(mod, sechdrs[pcpuindex].sh_size,
-                                     sechdrs[pcpuindex].sh_addralign);
-               if (err)
-                       goto free_mod;
-               sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
-       }
-       /* Keep this around for failure path. */
-       percpu = mod_percpu(mod);
+#ifdef CONFIG_TRACEPOINTS
+       mod->tracepoints = section_objs(info, "__tracepoints",
+                                       sizeof(*mod->tracepoints),
+                                       &mod->num_tracepoints);
+#endif
+#ifdef CONFIG_EVENT_TRACING
+       mod->trace_events = section_objs(info, "_ftrace_events",
+                                        sizeof(*mod->trace_events),
+                                        &mod->num_trace_events);
+       /*
+        * This section contains pointers to allocated objects in the trace
+        * code and not scanning it leads to false positives.
+        */
+       kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
+                          mod->num_trace_events, GFP_KERNEL);
+#endif
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+       /* sechdrs[0].sh_size is always zero */
+       mod->ftrace_callsites = section_objs(info, "__mcount_loc",
+                                            sizeof(*mod->ftrace_callsites),
+                                            &mod->num_ftrace_callsites);
+#endif
 
-       /* Determine total sizes, and put offsets in sh_entsize.  For now
-          this is done generically; there doesn't appear to be any
-          special cases for the architectures. */
-       layout_sections(mod, hdr, sechdrs, secstrings);
-       symoffs = layout_symtab(mod, sechdrs, symindex, strindex, hdr,
-                               secstrings, &stroffs, strmap);
+       mod->extable = section_objs(info, "__ex_table",
+                                   sizeof(*mod->extable), &mod->num_exentries);
+
+       if (section_addr(info, "__obsparm"))
+               printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
+                      mod->name);
+
+       info->debug = section_objs(info, "__verbose",
+                                  sizeof(*info->debug), &info->num_debug);
+}
+
+static int move_module(struct module *mod, struct load_info *info)
+{
+       int i;
+       void *ptr;
 
        /* Do the allocs. */
        ptr = module_alloc_update_bounds(mod->core_size);
@@ -2291,10 +2350,9 @@ static noinline struct module *load_module(void __user *umod,
         * leak.
         */
        kmemleak_not_leak(ptr);
-       if (!ptr) {
-               err = -ENOMEM;
-               goto free_percpu;
-       }
+       if (!ptr)
+               return -ENOMEM;
+
        memset(ptr, 0, mod->core_size);
        mod->module_core = ptr;
 
@@ -2307,50 +2365,40 @@ static noinline struct module *load_module(void __user *umod,
         */
        kmemleak_ignore(ptr);
        if (!ptr && mod->init_size) {
-               err = -ENOMEM;
-               goto free_core;
+               module_free(mod, mod->module_core);
+               return -ENOMEM;
        }
        memset(ptr, 0, mod->init_size);
        mod->module_init = ptr;
 
        /* Transfer each section which specifies SHF_ALLOC */
        DEBUGP("final section addresses:\n");
-       for (i = 0; i < hdr->e_shnum; i++) {
+       for (i = 0; i < info->hdr->e_shnum; i++) {
                void *dest;
+               Elf_Shdr *shdr = &info->sechdrs[i];
 
-               if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+               if (!(shdr->sh_flags & SHF_ALLOC))
                        continue;
 
-               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
+               if (shdr->sh_entsize & INIT_OFFSET_MASK)
                        dest = mod->module_init
-                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
+                               + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
                else
-                       dest = mod->module_core + sechdrs[i].sh_entsize;
+                       dest = mod->module_core + shdr->sh_entsize;
 
-               if (sechdrs[i].sh_type != SHT_NOBITS)
-                       memcpy(dest, (void *)sechdrs[i].sh_addr,
-                              sechdrs[i].sh_size);
+               if (shdr->sh_type != SHT_NOBITS)
+                       memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
                /* Update sh_addr to point to copy in image. */
-               sechdrs[i].sh_addr = (unsigned long)dest;
-               DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
-       }
-       /* Module has been moved. */
-       mod = (void *)sechdrs[modindex].sh_addr;
-       kmemleak_load_module(mod, hdr, sechdrs, secstrings);
-
-#if defined(CONFIG_MODULE_UNLOAD)
-       mod->refptr = alloc_percpu(struct module_ref);
-       if (!mod->refptr) {
-               err = -ENOMEM;
-               goto free_init;
+               shdr->sh_addr = (unsigned long)dest;
+               DEBUGP("\t0x%lx %s\n",
+                      shdr->sh_addr, info->secstrings + shdr->sh_name);
        }
-#endif
-       /* Now we've moved module, initialize linked lists, etc. */
-       module_unload_init(mod);
 
-       /* Set up license info based on the info section */
-       set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
+       return 0;
+}
 
+static int check_module_license_and_versions(struct module *mod)
+{
        /*
         * ndiswrapper is under GPL by itself, but loads proprietary modules.
         * Don't use add_taint_module(), as it would prevent ndiswrapper from
@@ -2363,77 +2411,6 @@ static noinline struct module *load_module(void __user *umod,
        if (strcmp(mod->name, "driverloader") == 0)
                add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
 
-       /* Set up MODINFO_ATTR fields */
-       setup_modinfo(mod, sechdrs, infoindex);
-
-       /* Fix up syms, so that st_value is a pointer to location. */
-       err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
-                              mod);
-       if (err < 0)
-               goto cleanup;
-
-       /* Now we've got everything in the final locations, we can
-        * find optional sections. */
-       mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
-                              sizeof(*mod->kp), &mod->num_kp);
-       mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
-                                sizeof(*mod->syms), &mod->num_syms);
-       mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
-       mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl",
-                                    sizeof(*mod->gpl_syms),
-                                    &mod->num_gpl_syms);
-       mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl");
-       mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings,
-                                           "__ksymtab_gpl_future",
-                                           sizeof(*mod->gpl_future_syms),
-                                           &mod->num_gpl_future_syms);
-       mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings,
-                                           "__kcrctab_gpl_future");
-
-#ifdef CONFIG_UNUSED_SYMBOLS
-       mod->unused_syms = section_objs(hdr, sechdrs, secstrings,
-                                       "__ksymtab_unused",
-                                       sizeof(*mod->unused_syms),
-                                       &mod->num_unused_syms);
-       mod->unused_crcs = section_addr(hdr, sechdrs, secstrings,
-                                       "__kcrctab_unused");
-       mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings,
-                                           "__ksymtab_unused_gpl",
-                                           sizeof(*mod->unused_gpl_syms),
-                                           &mod->num_unused_gpl_syms);
-       mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
-                                           "__kcrctab_unused_gpl");
-#endif
-#ifdef CONFIG_CONSTRUCTORS
-       mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors",
-                                 sizeof(*mod->ctors), &mod->num_ctors);
-#endif
-
-#ifdef CONFIG_TRACEPOINTS
-       mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
-                                       "__tracepoints",
-                                       sizeof(*mod->tracepoints),
-                                       &mod->num_tracepoints);
-#endif
-#ifdef CONFIG_EVENT_TRACING
-       mod->trace_events = section_objs(hdr, sechdrs, secstrings,
-                                        "_ftrace_events",
-                                        sizeof(*mod->trace_events),
-                                        &mod->num_trace_events);
-       /*
-        * This section contains pointers to allocated objects in the trace
-        * code and not scanning it leads to false positives.
-        */
-       kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
-                          mod->num_trace_events, GFP_KERNEL);
-#endif
-#ifdef CONFIG_FTRACE_MCOUNT_RECORD
-       /* sechdrs[0].sh_size is always zero */
-       mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings,
-                                            "__mcount_loc",
-                                            sizeof(*mod->ftrace_callsites),
-                                            &mod->num_ftrace_callsites);
-#endif
 #ifdef CONFIG_MODVERSIONS
        if ((mod->num_syms && !mod->crcs)
            || (mod->num_gpl_syms && !mod->gpl_crcs)
@@ -2443,56 +2420,16 @@ static noinline struct module *load_module(void __user *umod,
            || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
 #endif
                ) {
-               err = try_to_force_load(mod,
-                                       "no versions for exported symbols");
-               if (err)
-                       goto cleanup;
+               return try_to_force_load(mod,
+                                        "no versions for exported symbols");
        }
 #endif
+       return 0;
+}
 
-       /* Now do relocations. */
-       for (i = 1; i < hdr->e_shnum; i++) {
-               const char *strtab = (char *)sechdrs[strindex].sh_addr;
-               unsigned int info = sechdrs[i].sh_info;
-
-               /* Not a valid relocation section? */
-               if (info >= hdr->e_shnum)
-                       continue;
-
-               /* Don't bother with non-allocated sections */
-               if (!(sechdrs[info].sh_flags & SHF_ALLOC))
-                       continue;
-
-               if (sechdrs[i].sh_type == SHT_REL)
-                       err = apply_relocate(sechdrs, strtab, symindex, i,mod);
-               else if (sechdrs[i].sh_type == SHT_RELA)
-                       err = apply_relocate_add(sechdrs, strtab, symindex, i,
-                                                mod);
-               if (err < 0)
-                       goto cleanup;
-       }
-
-       /* Set up and sort exception table */
-       mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table",
-                                   sizeof(*mod->extable), &mod->num_exentries);
-       sort_extable(mod->extable, mod->extable + mod->num_exentries);
-
-       /* Finally, copy percpu area over. */
-       percpu_modcopy(mod, (void *)sechdrs[pcpuindex].sh_addr,
-                      sechdrs[pcpuindex].sh_size);
-
-       add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex,
-                    symoffs, stroffs, secstrings, strmap);
-       kfree(strmap);
-       strmap = NULL;
-
-       if (!mod->taints)
-               debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
-                                    sizeof(*debug), &num_debug);
-
-       err = module_finalize(hdr, sechdrs, mod);
-       if (err < 0)
-               goto cleanup;
+static void flush_module_icache(const struct module *mod)
+{
+       mm_segment_t old_fs;
 
        /* flush the icache in correct context */
        old_fs = get_fs();
@@ -2511,11 +2448,160 @@ static noinline struct module *load_module(void __user *umod,
                           (unsigned long)mod->module_core + mod->core_size);
 
        set_fs(old_fs);
+}
 
-       mod->args = args;
-       if (section_addr(hdr, sechdrs, secstrings, "__obsparm"))
-               printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
-                      mod->name);
+static struct module *layout_and_allocate(struct load_info *info)
+{
+       /* Module within temporary copy. */
+       struct module *mod;
+       Elf_Shdr *pcpusec;
+       int err;
+
+       mod = setup_load_info(info);
+       if (IS_ERR(mod))
+               return mod;
+
+       err = check_modinfo(mod, info);
+       if (err)
+               return ERR_PTR(err);
+
+       /* Allow arches to frob section contents and sizes.  */
+       err = module_frob_arch_sections(info->hdr, info->sechdrs,
+                                       info->secstrings, mod);
+       if (err < 0)
+               goto out;
+
+       pcpusec = &info->sechdrs[info->index.pcpu];
+       if (pcpusec->sh_size) {
+               /* We have a special allocation for this section. */
+               err = percpu_modalloc(mod,
+                                     pcpusec->sh_size, pcpusec->sh_addralign);
+               if (err)
+                       goto out;
+               pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC;
+       }
+
+       /* Determine total sizes, and put offsets in sh_entsize.  For now
+          this is done generically; there doesn't appear to be any
+          special cases for the architectures. */
+       layout_sections(mod, info);
+
+       info->strmap = kzalloc(BITS_TO_LONGS(info->sechdrs[info->index.str].sh_size)
+                        * sizeof(long), GFP_KERNEL);
+       if (!info->strmap) {
+               err = -ENOMEM;
+               goto free_percpu;
+       }
+       layout_symtab(mod, info);
+
+       /* Allocate and move to the final place */
+       err = move_module(mod, info);
+       if (err)
+               goto free_strmap;
+
+       /* Module has been copied to its final place now: return it. */
+       mod = (void *)info->sechdrs[info->index.mod].sh_addr;
+       kmemleak_load_module(mod, info);
+       return mod;
+
+free_strmap:
+       kfree(info->strmap);
+free_percpu:
+       percpu_modfree(mod);
+out:
+       return ERR_PTR(err);
+}
+
+/* mod is no longer valid after this! */
+static void module_deallocate(struct module *mod, struct load_info *info)
+{
+       kfree(info->strmap);
+       percpu_modfree(mod);
+       module_free(mod, mod->module_init);
+       module_free(mod, mod->module_core);
+}
+
+static int post_relocation(struct module *mod, const struct load_info *info)
+{
+       /* Sort exception table now relocations are done. */
+       sort_extable(mod->extable, mod->extable + mod->num_exentries);
+
+       /* Copy relocated percpu area over. */
+       percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr,
+                      info->sechdrs[info->index.pcpu].sh_size);
+
+       /* Setup kallsyms-specific fields. */
+       add_kallsyms(mod, info);
+
+       /* Arch-specific module finalizing. */
+       return module_finalize(info->hdr, info->sechdrs, mod);
+}
+
+/* Allocate and load the module: note that size of section 0 is always
+   zero, and we rely on this for optional sections. */
+static struct module *load_module(void __user *umod,
+                                 unsigned long len,
+                                 const char __user *uargs)
+{
+       struct load_info info = { NULL, };
+       struct module *mod;
+       long err;
+
+       DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
+              umod, len, uargs);
+
+       /* Copy in the blobs from userspace, check they are vaguely sane. */
+       err = copy_and_check(&info, umod, len, uargs);
+       if (err)
+               return ERR_PTR(err);
+
+       /* Figure out module layout, and allocate all the memory. */
+       mod = layout_and_allocate(&info);
+       if (IS_ERR(mod)) {
+               err = PTR_ERR(mod);
+               goto free_copy;
+       }
+
+       /* Now module is in final location, initialize linked lists, etc. */
+       err = module_unload_init(mod);
+       if (err)
+               goto free_module;
+
+       /* Now we've got everything in the final locations, we can
+        * find optional sections. */
+       find_module_sections(mod, &info);
+
+       err = check_module_license_and_versions(mod);
+       if (err)
+               goto free_unload;
+
+       /* Set up MODINFO_ATTR fields */
+       setup_modinfo(mod, &info);
+
+       /* Fix up syms, so that st_value is a pointer to location. */
+       err = simplify_symbols(mod, &info);
+       if (err < 0)
+               goto free_modinfo;
+
+       err = apply_relocations(mod, &info);
+       if (err < 0)
+               goto free_modinfo;
+
+       err = post_relocation(mod, &info);
+       if (err < 0)
+               goto free_modinfo;
+
+       flush_module_icache(mod);
+
+       /* Now copy in args */
+       mod->args = strndup_user(uargs, ~0UL >> 1);
+       if (IS_ERR(mod->args)) {
+               err = PTR_ERR(mod->args);
+               goto free_arch_cleanup;
+       }
+
+       /* Mark state as coming so strong_try_module_get() ignores us. */
+       mod->state = MODULE_STATE_COMING;
 
        /* Now sew it into the lists so we can get lockdep and oops
         * info during argument parsing.  Noone should access us, since
@@ -2530,8 +2616,9 @@ static noinline struct module *load_module(void __user *umod,
                goto unlock;
        }
 
-       if (debug)
-               dynamic_debug_setup(debug, num_debug);
+       /* This has to be done once we're sure module name is unique. */
+       if (!mod->taints)
+               dynamic_debug_setup(info.debug, info.num_debug);
 
        /* Find duplicate symbols */
        err = verify_export_symbols(mod);
@@ -2541,23 +2628,22 @@ static noinline struct module *load_module(void __user *umod,
        list_add_rcu(&mod->list, &modules);
        mutex_unlock(&module_mutex);
 
+       /* Module is ready to execute: parsing args may do that. */
        err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
        if (err < 0)
                goto unlink;
 
-       err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
+       /* Link in to syfs. */
+       err = mod_sysfs_setup(mod, &info, mod->kp, mod->num_kp);
        if (err < 0)
                goto unlink;
 
-       add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
-       add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
-
-       /* Get rid of temporary copy */
-       vfree(hdr);
-
-       trace_module_load(mod);
+       /* Get rid of temporary copy and strmap. */
+       kfree(info.strmap);
+       free_copy(&info);
 
        /* Done! */
+       trace_module_load(mod);
        return mod;
 
  unlink:
@@ -2565,35 +2651,23 @@ static noinline struct module *load_module(void __user *umod,
        /* Unlink carefully: kallsyms could be walking list. */
        list_del_rcu(&mod->list);
  ddebug:
-       dynamic_debug_remove(debug);
+       if (!mod->taints)
+               dynamic_debug_remove(info.debug);
  unlock:
        mutex_unlock(&module_mutex);
        synchronize_sched();
+       kfree(mod->args);
+ free_arch_cleanup:
        module_arch_cleanup(mod);
cleanup:
free_modinfo:
        free_modinfo(mod);
+ free_unload:
        module_unload_free(mod);
-#if defined(CONFIG_MODULE_UNLOAD)
-       free_percpu(mod->refptr);
- free_init:
-#endif
-       module_free(mod, mod->module_init);
- free_core:
-       module_free(mod, mod->module_core);
-       /* mod will be freed with core. Don't access it beyond this line! */
- free_percpu:
-       free_percpu(percpu);
- free_mod:
-       kfree(args);
-       kfree(strmap);
- free_hdr:
-       vfree(hdr);
+ free_module:
+       module_deallocate(mod, &info);
+ free_copy:
+       free_copy(&info);
        return ERR_PTR(err);
-
- truncated:
-       printk(KERN_ERR "Module len %lu truncated\n", len);
-       err = -ENOEXEC;
-       goto free_hdr;
 }
 
 /* Call module constructors. */
index ff86c558af4c28dd4c9a7ea92cc592b70bee6d7d..403d1804b198140e4f1355c70c0b25e6efa9e5d8 100644 (file)
@@ -214,7 +214,7 @@ static void perf_unpin_context(struct perf_event_context *ctx)
 
 static inline u64 perf_clock(void)
 {
-       return cpu_clock(raw_smp_processor_id());
+       return local_clock();
 }
 
 /*
@@ -675,7 +675,6 @@ group_sched_in(struct perf_event *group_event,
        struct perf_event *event, *partial_group = NULL;
        const struct pmu *pmu = group_event->pmu;
        bool txn = false;
-       int ret;
 
        if (group_event->state == PERF_EVENT_STATE_OFF)
                return 0;
@@ -703,14 +702,8 @@ group_sched_in(struct perf_event *group_event,
                }
        }
 
-       if (!txn)
-               return 0;
-
-       ret = pmu->commit_txn(pmu);
-       if (!ret) {
-               pmu->cancel_txn(pmu);
+       if (!txn || !pmu->commit_txn(pmu))
                return 0;
-       }
 
 group_error:
        /*
@@ -1155,9 +1148,9 @@ static void __perf_event_sync_stat(struct perf_event *event,
         * In order to keep per-task stats reliable we need to flip the event
         * values when we flip the contexts.
         */
-       value = atomic64_read(&next_event->count);
-       value = atomic64_xchg(&event->count, value);
-       atomic64_set(&next_event->count, value);
+       value = local64_read(&next_event->count);
+       value = local64_xchg(&event->count, value);
+       local64_set(&next_event->count, value);
 
        swap(event->total_time_enabled, next_event->total_time_enabled);
        swap(event->total_time_running, next_event->total_time_running);
@@ -1547,10 +1540,10 @@ static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count)
 
        hwc->sample_period = sample_period;
 
-       if (atomic64_read(&hwc->period_left) > 8*sample_period) {
+       if (local64_read(&hwc->period_left) > 8*sample_period) {
                perf_disable();
                perf_event_stop(event);
-               atomic64_set(&hwc->period_left, 0);
+               local64_set(&hwc->period_left, 0);
                perf_event_start(event);
                perf_enable();
        }
@@ -1591,7 +1584,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
 
                perf_disable();
                event->pmu->read(event);
-               now = atomic64_read(&event->count);
+               now = local64_read(&event->count);
                delta = now - hwc->freq_count_stamp;
                hwc->freq_count_stamp = now;
 
@@ -1743,6 +1736,11 @@ static void __perf_event_read(void *info)
        event->pmu->read(event);
 }
 
+static inline u64 perf_event_count(struct perf_event *event)
+{
+       return local64_read(&event->count) + atomic64_read(&event->child_count);
+}
+
 static u64 perf_event_read(struct perf_event *event)
 {
        /*
@@ -1762,7 +1760,7 @@ static u64 perf_event_read(struct perf_event *event)
                raw_spin_unlock_irqrestore(&ctx->lock, flags);
        }
 
-       return atomic64_read(&event->count);
+       return perf_event_count(event);
 }
 
 /*
@@ -1883,7 +1881,7 @@ static void free_event_rcu(struct rcu_head *head)
 }
 
 static void perf_pending_sync(struct perf_event *event);
-static void perf_mmap_data_put(struct perf_mmap_data *data);
+static void perf_buffer_put(struct perf_buffer *buffer);
 
 static void free_event(struct perf_event *event)
 {
@@ -1891,7 +1889,7 @@ static void free_event(struct perf_event *event)
 
        if (!event->parent) {
                atomic_dec(&nr_events);
-               if (event->attr.mmap)
+               if (event->attr.mmap || event->attr.mmap_data)
                        atomic_dec(&nr_mmap_events);
                if (event->attr.comm)
                        atomic_dec(&nr_comm_events);
@@ -1899,9 +1897,9 @@ static void free_event(struct perf_event *event)
                        atomic_dec(&nr_task_events);
        }
 
-       if (event->data) {
-               perf_mmap_data_put(event->data);
-               event->data = NULL;
+       if (event->buffer) {
+               perf_buffer_put(event->buffer);
+               event->buffer = NULL;
        }
 
        if (event->destroy)
@@ -2126,13 +2124,13 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 static unsigned int perf_poll(struct file *file, poll_table *wait)
 {
        struct perf_event *event = file->private_data;
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
        unsigned int events = POLL_HUP;
 
        rcu_read_lock();
-       data = rcu_dereference(event->data);
-       if (data)
-               events = atomic_xchg(&data->poll, 0);
+       buffer = rcu_dereference(event->buffer);
+       if (buffer)
+               events = atomic_xchg(&buffer->poll, 0);
        rcu_read_unlock();
 
        poll_wait(file, &event->waitq, wait);
@@ -2143,7 +2141,7 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
 static void perf_event_reset(struct perf_event *event)
 {
        (void)perf_event_read(event);
-       atomic64_set(&event->count, 0);
+       local64_set(&event->count, 0);
        perf_event_update_userpage(event);
 }
 
@@ -2342,14 +2340,14 @@ static int perf_event_index(struct perf_event *event)
 void perf_event_update_userpage(struct perf_event *event)
 {
        struct perf_event_mmap_page *userpg;
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
 
        rcu_read_lock();
-       data = rcu_dereference(event->data);
-       if (!data)
+       buffer = rcu_dereference(event->buffer);
+       if (!buffer)
                goto unlock;
 
-       userpg = data->user_page;
+       userpg = buffer->user_page;
 
        /*
         * Disable preemption so as to not let the corresponding user-space
@@ -2359,9 +2357,9 @@ void perf_event_update_userpage(struct perf_event *event)
        ++userpg->lock;
        barrier();
        userpg->index = perf_event_index(event);
-       userpg->offset = atomic64_read(&event->count);
+       userpg->offset = perf_event_count(event);
        if (event->state == PERF_EVENT_STATE_ACTIVE)
-               userpg->offset -= atomic64_read(&event->hw.prev_count);
+               userpg->offset -= local64_read(&event->hw.prev_count);
 
        userpg->time_enabled = event->total_time_enabled +
                        atomic64_read(&event->child_total_time_enabled);
@@ -2376,6 +2374,25 @@ unlock:
        rcu_read_unlock();
 }
 
+static unsigned long perf_data_size(struct perf_buffer *buffer);
+
+static void
+perf_buffer_init(struct perf_buffer *buffer, long watermark, int flags)
+{
+       long max_size = perf_data_size(buffer);
+
+       if (watermark)
+               buffer->watermark = min(max_size, watermark);
+
+       if (!buffer->watermark)
+               buffer->watermark = max_size / 2;
+
+       if (flags & PERF_BUFFER_WRITABLE)
+               buffer->writable = 1;
+
+       atomic_set(&buffer->refcount, 1);
+}
+
 #ifndef CONFIG_PERF_USE_VMALLOC
 
 /*
@@ -2383,15 +2400,15 @@ unlock:
  */
 
 static struct page *
-perf_mmap_to_page(struct perf_mmap_data *data, unsigned long pgoff)
+perf_mmap_to_page(struct perf_buffer *buffer, unsigned long pgoff)
 {
-       if (pgoff > data->nr_pages)
+       if (pgoff > buffer->nr_pages)
                return NULL;
 
        if (pgoff == 0)
-               return virt_to_page(data->user_page);
+               return virt_to_page(buffer->user_page);
 
-       return virt_to_page(data->data_pages[pgoff - 1]);
+       return virt_to_page(buffer->data_pages[pgoff - 1]);
 }
 
 static void *perf_mmap_alloc_page(int cpu)
@@ -2407,42 +2424,44 @@ static void *perf_mmap_alloc_page(int cpu)
        return page_address(page);
 }
 
-static struct perf_mmap_data *
-perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
+static struct perf_buffer *
+perf_buffer_alloc(int nr_pages, long watermark, int cpu, int flags)
 {
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
        unsigned long size;
        int i;
 
-       size = sizeof(struct perf_mmap_data);
+       size = sizeof(struct perf_buffer);
        size += nr_pages * sizeof(void *);
 
-       data = kzalloc(size, GFP_KERNEL);
-       if (!data)
+       buffer = kzalloc(size, GFP_KERNEL);
+       if (!buffer)
                goto fail;
 
-       data->user_page = perf_mmap_alloc_page(event->cpu);
-       if (!data->user_page)
+       buffer->user_page = perf_mmap_alloc_page(cpu);
+       if (!buffer->user_page)
                goto fail_user_page;
 
        for (i = 0; i < nr_pages; i++) {
-               data->data_pages[i] = perf_mmap_alloc_page(event->cpu);
-               if (!data->data_pages[i])
+               buffer->data_pages[i] = perf_mmap_alloc_page(cpu);
+               if (!buffer->data_pages[i])
                        goto fail_data_pages;
        }
 
-       data->nr_pages = nr_pages;
+       buffer->nr_pages = nr_pages;
+
+       perf_buffer_init(buffer, watermark, flags);
 
-       return data;
+       return buffer;
 
 fail_data_pages:
        for (i--; i >= 0; i--)
-               free_page((unsigned long)data->data_pages[i]);
+               free_page((unsigned long)buffer->data_pages[i]);
 
-       free_page((unsigned long)data->user_page);
+       free_page((unsigned long)buffer->user_page);
 
 fail_user_page:
-       kfree(data);
+       kfree(buffer);
 
 fail:
        return NULL;
@@ -2456,17 +2475,17 @@ static void perf_mmap_free_page(unsigned long addr)
        __free_page(page);
 }
 
-static void perf_mmap_data_free(struct perf_mmap_data *data)
+static void perf_buffer_free(struct perf_buffer *buffer)
 {
        int i;
 
-       perf_mmap_free_page((unsigned long)data->user_page);
-       for (i = 0; i < data->nr_pages; i++)
-               perf_mmap_free_page((unsigned long)data->data_pages[i]);
-       kfree(data);
+       perf_mmap_free_page((unsigned long)buffer->user_page);
+       for (i = 0; i < buffer->nr_pages; i++)
+               perf_mmap_free_page((unsigned long)buffer->data_pages[i]);
+       kfree(buffer);
 }
 
-static inline int page_order(struct perf_mmap_data *data)
+static inline int page_order(struct perf_buffer *buffer)
 {
        return 0;
 }
@@ -2479,18 +2498,18 @@ static inline int page_order(struct perf_mmap_data *data)
  * Required for architectures that have d-cache aliasing issues.
  */
 
-static inline int page_order(struct perf_mmap_data *data)
+static inline int page_order(struct perf_buffer *buffer)
 {
-       return data->page_order;
+       return buffer->page_order;
 }
 
 static struct page *
-perf_mmap_to_page(struct perf_mmap_data *data, unsigned long pgoff)
+perf_mmap_to_page(struct perf_buffer *buffer, unsigned long pgoff)
 {
-       if (pgoff > (1UL << page_order(data)))
+       if (pgoff > (1UL << page_order(buffer)))
                return NULL;
 
-       return vmalloc_to_page((void *)data->user_page + pgoff * PAGE_SIZE);
+       return vmalloc_to_page((void *)buffer->user_page + pgoff * PAGE_SIZE);
 }
 
 static void perf_mmap_unmark_page(void *addr)
@@ -2500,57 +2519,59 @@ static void perf_mmap_unmark_page(void *addr)
        page->mapping = NULL;
 }
 
-static void perf_mmap_data_free_work(struct work_struct *work)
+static void perf_buffer_free_work(struct work_struct *work)
 {
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
        void *base;
        int i, nr;
 
-       data = container_of(work, struct perf_mmap_data, work);
-       nr = 1 << page_order(data);
+       buffer = container_of(work, struct perf_buffer, work);
+       nr = 1 << page_order(buffer);
 
-       base = data->user_page;
+       base = buffer->user_page;
        for (i = 0; i < nr + 1; i++)
                perf_mmap_unmark_page(base + (i * PAGE_SIZE));
 
        vfree(base);
-       kfree(data);
+       kfree(buffer);
 }
 
-static void perf_mmap_data_free(struct perf_mmap_data *data)
+static void perf_buffer_free(struct perf_buffer *buffer)
 {
-       schedule_work(&data->work);
+       schedule_work(&buffer->work);
 }
 
-static struct perf_mmap_data *
-perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
+static struct perf_buffer *
+perf_buffer_alloc(int nr_pages, long watermark, int cpu, int flags)
 {
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
        unsigned long size;
        void *all_buf;
 
-       size = sizeof(struct perf_mmap_data);
+       size = sizeof(struct perf_buffer);
        size += sizeof(void *);
 
-       data = kzalloc(size, GFP_KERNEL);
-       if (!data)
+       buffer = kzalloc(size, GFP_KERNEL);
+       if (!buffer)
                goto fail;
 
-       INIT_WORK(&data->work, perf_mmap_data_free_work);
+       INIT_WORK(&buffer->work, perf_buffer_free_work);
 
        all_buf = vmalloc_user((nr_pages + 1) * PAGE_SIZE);
        if (!all_buf)
                goto fail_all_buf;
 
-       data->user_page = all_buf;
-       data->data_pages[0] = all_buf + PAGE_SIZE;
-       data->page_order = ilog2(nr_pages);
-       data->nr_pages = 1;
+       buffer->user_page = all_buf;
+       buffer->data_pages[0] = all_buf + PAGE_SIZE;
+       buffer->page_order = ilog2(nr_pages);
+       buffer->nr_pages = 1;
+
+       perf_buffer_init(buffer, watermark, flags);
 
-       return data;
+       return buffer;
 
 fail_all_buf:
-       kfree(data);
+       kfree(buffer);
 
 fail:
        return NULL;
@@ -2558,15 +2579,15 @@ fail:
 
 #endif
 
-static unsigned long perf_data_size(struct perf_mmap_data *data)
+static unsigned long perf_data_size(struct perf_buffer *buffer)
 {
-       return data->nr_pages << (PAGE_SHIFT + page_order(data));
+       return buffer->nr_pages << (PAGE_SHIFT + page_order(buffer));
 }
 
 static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
        struct perf_event *event = vma->vm_file->private_data;
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
        int ret = VM_FAULT_SIGBUS;
 
        if (vmf->flags & FAULT_FLAG_MKWRITE) {
@@ -2576,14 +2597,14 @@ static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        }
 
        rcu_read_lock();
-       data = rcu_dereference(event->data);
-       if (!data)
+       buffer = rcu_dereference(event->buffer);
+       if (!buffer)
                goto unlock;
 
        if (vmf->pgoff && (vmf->flags & FAULT_FLAG_WRITE))
                goto unlock;
 
-       vmf->page = perf_mmap_to_page(data, vmf->pgoff);
+       vmf->page = perf_mmap_to_page(buffer, vmf->pgoff);
        if (!vmf->page)
                goto unlock;
 
@@ -2598,52 +2619,35 @@ unlock:
        return ret;
 }
 
-static void
-perf_mmap_data_init(struct perf_event *event, struct perf_mmap_data *data)
-{
-       long max_size = perf_data_size(data);
-
-       if (event->attr.watermark) {
-               data->watermark = min_t(long, max_size,
-                                       event->attr.wakeup_watermark);
-       }
-
-       if (!data->watermark)
-               data->watermark = max_size / 2;
-
-       atomic_set(&data->refcount, 1);
-       rcu_assign_pointer(event->data, data);
-}
-
-static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head)
+static void perf_buffer_free_rcu(struct rcu_head *rcu_head)
 {
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
 
-       data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
-       perf_mmap_data_free(data);
+       buffer = container_of(rcu_head, struct perf_buffer, rcu_head);
+       perf_buffer_free(buffer);
 }
 
-static struct perf_mmap_data *perf_mmap_data_get(struct perf_event *event)
+static struct perf_buffer *perf_buffer_get(struct perf_event *event)
 {
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
 
        rcu_read_lock();
-       data = rcu_dereference(event->data);
-       if (data) {
-               if (!atomic_inc_not_zero(&data->refcount))
-                       data = NULL;
+       buffer = rcu_dereference(event->buffer);
+       if (buffer) {
+               if (!atomic_inc_not_zero(&buffer->refcount))
+                       buffer = NULL;
        }
        rcu_read_unlock();
 
-       return data;
+       return buffer;
 }
 
-static void perf_mmap_data_put(struct perf_mmap_data *data)
+static void perf_buffer_put(struct perf_buffer *buffer)
 {
-       if (!atomic_dec_and_test(&data->refcount))
+       if (!atomic_dec_and_test(&buffer->refcount))
                return;
 
-       call_rcu(&data->rcu_head, perf_mmap_data_free_rcu);
+       call_rcu(&buffer->rcu_head, perf_buffer_free_rcu);
 }
 
 static void perf_mmap_open(struct vm_area_struct *vma)
@@ -2658,16 +2662,16 @@ static void perf_mmap_close(struct vm_area_struct *vma)
        struct perf_event *event = vma->vm_file->private_data;
 
        if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
-               unsigned long size = perf_data_size(event->data);
+               unsigned long size = perf_data_size(event->buffer);
                struct user_struct *user = event->mmap_user;
-               struct perf_mmap_data *data = event->data;
+               struct perf_buffer *buffer = event->buffer;
 
                atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm);
                vma->vm_mm->locked_vm -= event->mmap_locked;
-               rcu_assign_pointer(event->data, NULL);
+               rcu_assign_pointer(event->buffer, NULL);
                mutex_unlock(&event->mmap_mutex);
 
-               perf_mmap_data_put(data);
+               perf_buffer_put(buffer);
                free_uid(user);
        }
 }
@@ -2685,11 +2689,11 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
        unsigned long user_locked, user_lock_limit;
        struct user_struct *user = current_user();
        unsigned long locked, lock_limit;
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
        unsigned long vma_size;
        unsigned long nr_pages;
        long user_extra, extra;
-       int ret = 0;
+       int ret = 0, flags = 0;
 
        /*
         * Don't allow mmap() of inherited per-task counters. This would
@@ -2706,7 +2710,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
        nr_pages = (vma_size / PAGE_SIZE) - 1;
 
        /*
-        * If we have data pages ensure they're a power-of-two number, so we
+        * If we have buffer pages ensure they're a power-of-two number, so we
         * can do bitmasks instead of modulo.
         */
        if (nr_pages != 0 && !is_power_of_2(nr_pages))
@@ -2720,9 +2724,9 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 
        WARN_ON_ONCE(event->ctx->parent_ctx);
        mutex_lock(&event->mmap_mutex);
-       if (event->data) {
-               if (event->data->nr_pages == nr_pages)
-                       atomic_inc(&event->data->refcount);
+       if (event->buffer) {
+               if (event->buffer->nr_pages == nr_pages)
+                       atomic_inc(&event->buffer->refcount);
                else
                        ret = -EINVAL;
                goto unlock;
@@ -2752,17 +2756,18 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
                goto unlock;
        }
 
-       WARN_ON(event->data);
+       WARN_ON(event->buffer);
+
+       if (vma->vm_flags & VM_WRITE)
+               flags |= PERF_BUFFER_WRITABLE;
 
-       data = perf_mmap_data_alloc(event, nr_pages);
-       if (!data) {
+       buffer = perf_buffer_alloc(nr_pages, event->attr.wakeup_watermark,
+                                  event->cpu, flags);
+       if (!buffer) {
                ret = -ENOMEM;
                goto unlock;
        }
-
-       perf_mmap_data_init(event, data);
-       if (vma->vm_flags & VM_WRITE)
-               event->data->writable = 1;
+       rcu_assign_pointer(event->buffer, buffer);
 
        atomic_long_add(user_extra, &user->locked_vm);
        event->mmap_locked = extra;
@@ -2941,11 +2946,6 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
        return NULL;
 }
 
-__weak
-void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
-{
-}
-
 
 /*
  * We assume there is only KVM supporting the callbacks.
@@ -2971,15 +2971,15 @@ EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
 /*
  * Output
  */
-static bool perf_output_space(struct perf_mmap_data *data, unsigned long tail,
+static bool perf_output_space(struct perf_buffer *buffer, unsigned long tail,
                              unsigned long offset, unsigned long head)
 {
        unsigned long mask;
 
-       if (!data->writable)
+       if (!buffer->writable)
                return true;
 
-       mask = perf_data_size(data) - 1;
+       mask = perf_data_size(buffer) - 1;
 
        offset = (offset - tail) & mask;
        head   = (head   - tail) & mask;
@@ -2992,7 +2992,7 @@ static bool perf_output_space(struct perf_mmap_data *data, unsigned long tail,
 
 static void perf_output_wakeup(struct perf_output_handle *handle)
 {
-       atomic_set(&handle->data->poll, POLL_IN);
+       atomic_set(&handle->buffer->poll, POLL_IN);
 
        if (handle->nmi) {
                handle->event->pending_wakeup = 1;
@@ -3012,45 +3012,45 @@ static void perf_output_wakeup(struct perf_output_handle *handle)
  */
 static void perf_output_get_handle(struct perf_output_handle *handle)
 {
-       struct perf_mmap_data *data = handle->data;
+       struct perf_buffer *buffer = handle->buffer;
 
        preempt_disable();
-       local_inc(&data->nest);
-       handle->wakeup = local_read(&data->wakeup);
+       local_inc(&buffer->nest);
+       handle->wakeup = local_read(&buffer->wakeup);
 }
 
 static void perf_output_put_handle(struct perf_output_handle *handle)
 {
-       struct perf_mmap_data *data = handle->data;
+       struct perf_buffer *buffer = handle->buffer;
        unsigned long head;
 
 again:
-       head = local_read(&data->head);
+       head = local_read(&buffer->head);
 
        /*
         * IRQ/NMI can happen here, which means we can miss a head update.
         */
 
-       if (!local_dec_and_test(&data->nest))
+       if (!local_dec_and_test(&buffer->nest))
                goto out;
 
        /*
         * Publish the known good head. Rely on the full barrier implied
-        * by atomic_dec_and_test() order the data->head read and this
+        * by atomic_dec_and_test() order the buffer->head read and this
         * write.
         */
-       data->user_page->data_head = head;
+       buffer->user_page->data_head = head;
 
        /*
         * Now check if we missed an update, rely on the (compiler)
-        * barrier in atomic_dec_and_test() to re-read data->head.
+        * barrier in atomic_dec_and_test() to re-read buffer->head.
         */
-       if (unlikely(head != local_read(&data->head))) {
-               local_inc(&data->nest);
+       if (unlikely(head != local_read(&buffer->head))) {
+               local_inc(&buffer->nest);
                goto again;
        }
 
-       if (handle->wakeup != local_read(&data->wakeup))
+       if (handle->wakeup != local_read(&buffer->wakeup))
                perf_output_wakeup(handle);
 
  out:
@@ -3070,12 +3070,12 @@ __always_inline void perf_output_copy(struct perf_output_handle *handle,
                buf += size;
                handle->size -= size;
                if (!handle->size) {
-                       struct perf_mmap_data *data = handle->data;
+                       struct perf_buffer *buffer = handle->buffer;
 
                        handle->page++;
-                       handle->page &= data->nr_pages - 1;
-                       handle->addr = data->data_pages[handle->page];
-                       handle->size = PAGE_SIZE << page_order(data);
+                       handle->page &= buffer->nr_pages - 1;
+                       handle->addr = buffer->data_pages[handle->page];
+                       handle->size = PAGE_SIZE << page_order(buffer);
                }
        } while (len);
 }
@@ -3084,7 +3084,7 @@ int perf_output_begin(struct perf_output_handle *handle,
                      struct perf_event *event, unsigned int size,
                      int nmi, int sample)
 {
-       struct perf_mmap_data *data;
+       struct perf_buffer *buffer;
        unsigned long tail, offset, head;
        int have_lost;
        struct {
@@ -3100,19 +3100,19 @@ int perf_output_begin(struct perf_output_handle *handle,
        if (event->parent)
                event = event->parent;
 
-       data = rcu_dereference(event->data);
-       if (!data)
+       buffer = rcu_dereference(event->buffer);
+       if (!buffer)
                goto out;
 
-       handle->data    = data;
+       handle->buffer  = buffer;
        handle->event   = event;
        handle->nmi     = nmi;
        handle->sample  = sample;
 
-       if (!data->nr_pages)
+       if (!buffer->nr_pages)
                goto out;
 
-       have_lost = local_read(&data->lost);
+       have_lost = local_read(&buffer->lost);
        if (have_lost)
                size += sizeof(lost_event);
 
@@ -3124,30 +3124,30 @@ int perf_output_begin(struct perf_output_handle *handle,
                 * tail pointer. So that all reads will be completed before the
                 * write is issued.
                 */
-               tail = ACCESS_ONCE(data->user_page->data_tail);
+               tail = ACCESS_ONCE(buffer->user_page->data_tail);
                smp_rmb();
-               offset = head = local_read(&data->head);
+               offset = head = local_read(&buffer->head);
                head += size;
-               if (unlikely(!perf_output_space(data, tail, offset, head)))
+               if (unlikely(!perf_output_space(buffer, tail, offset, head)))
                        goto fail;
-       } while (local_cmpxchg(&data->head, offset, head) != offset);
+       } while (local_cmpxchg(&buffer->head, offset, head) != offset);
 
-       if (head - local_read(&data->wakeup) > data->watermark)
-               local_add(data->watermark, &data->wakeup);
+       if (head - local_read(&buffer->wakeup) > buffer->watermark)
+               local_add(buffer->watermark, &buffer->wakeup);
 
-       handle->page = offset >> (PAGE_SHIFT + page_order(data));
-       handle->page &= data->nr_pages - 1;
-       handle->size = offset & ((PAGE_SIZE << page_order(data)) - 1);
-       handle->addr = data->data_pages[handle->page];
+       handle->page = offset >> (PAGE_SHIFT + page_order(buffer));
+       handle->page &= buffer->nr_pages - 1;
+       handle->size = offset & ((PAGE_SIZE << page_order(buffer)) - 1);
+       handle->addr = buffer->data_pages[handle->page];
        handle->addr += handle->size;
-       handle->size = (PAGE_SIZE << page_order(data)) - handle->size;
+       handle->size = (PAGE_SIZE << page_order(buffer)) - handle->size;
 
        if (have_lost) {
                lost_event.header.type = PERF_RECORD_LOST;
                lost_event.header.misc = 0;
                lost_event.header.size = sizeof(lost_event);
                lost_event.id          = event->id;
-               lost_event.lost        = local_xchg(&data->lost, 0);
+               lost_event.lost        = local_xchg(&buffer->lost, 0);
 
                perf_output_put(handle, lost_event);
        }
@@ -3155,7 +3155,7 @@ int perf_output_begin(struct perf_output_handle *handle,
        return 0;
 
 fail:
-       local_inc(&data->lost);
+       local_inc(&buffer->lost);
        perf_output_put_handle(handle);
 out:
        rcu_read_unlock();
@@ -3166,15 +3166,15 @@ out:
 void perf_output_end(struct perf_output_handle *handle)
 {
        struct perf_event *event = handle->event;
-       struct perf_mmap_data *data = handle->data;
+       struct perf_buffer *buffer = handle->buffer;
 
        int wakeup_events = event->attr.wakeup_events;
 
        if (handle->sample && wakeup_events) {
-               int events = local_inc_return(&data->events);
+               int events = local_inc_return(&buffer->events);
                if (events >= wakeup_events) {
-                       local_sub(wakeup_events, &data->events);
-                       local_inc(&data->wakeup);
+                       local_sub(wakeup_events, &buffer->events);
+                       local_inc(&buffer->wakeup);
                }
        }
 
@@ -3211,7 +3211,7 @@ static void perf_output_read_one(struct perf_output_handle *handle,
        u64 values[4];
        int n = 0;
 
-       values[n++] = atomic64_read(&event->count);
+       values[n++] = perf_event_count(event);
        if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
                values[n++] = event->total_time_enabled +
                        atomic64_read(&event->child_total_time_enabled);
@@ -3248,7 +3248,7 @@ static void perf_output_read_group(struct perf_output_handle *handle,
        if (leader != event)
                leader->pmu->read(leader);
 
-       values[n++] = atomic64_read(&leader->count);
+       values[n++] = perf_event_count(leader);
        if (read_format & PERF_FORMAT_ID)
                values[n++] = primary_event_id(leader);
 
@@ -3260,7 +3260,7 @@ static void perf_output_read_group(struct perf_output_handle *handle,
                if (sub != event)
                        sub->pmu->read(sub);
 
-               values[n++] = atomic64_read(&sub->count);
+               values[n++] = perf_event_count(sub);
                if (read_format & PERF_FORMAT_ID)
                        values[n++] = primary_event_id(sub);
 
@@ -3491,7 +3491,7 @@ perf_event_read_event(struct perf_event *event,
 /*
  * task tracking -- fork/exit
  *
- * enabled by: attr.comm | attr.mmap | attr.task
+ * enabled by: attr.comm | attr.mmap | attr.mmap_data | attr.task
  */
 
 struct perf_task_event {
@@ -3541,7 +3541,8 @@ static int perf_event_task_match(struct perf_event *event)
        if (event->cpu != -1 && event->cpu != smp_processor_id())
                return 0;
 
-       if (event->attr.comm || event->attr.mmap || event->attr.task)
+       if (event->attr.comm || event->attr.mmap ||
+           event->attr.mmap_data || event->attr.task)
                return 1;
 
        return 0;
@@ -3766,7 +3767,8 @@ static void perf_event_mmap_output(struct perf_event *event,
 }
 
 static int perf_event_mmap_match(struct perf_event *event,
-                                  struct perf_mmap_event *mmap_event)
+                                  struct perf_mmap_event *mmap_event,
+                                  int executable)
 {
        if (event->state < PERF_EVENT_STATE_INACTIVE)
                return 0;
@@ -3774,19 +3776,21 @@ static int perf_event_mmap_match(struct perf_event *event,
        if (event->cpu != -1 && event->cpu != smp_processor_id())
                return 0;
 
-       if (event->attr.mmap)
+       if ((!executable && event->attr.mmap_data) ||
+           (executable && event->attr.mmap))
                return 1;
 
        return 0;
 }
 
 static void perf_event_mmap_ctx(struct perf_event_context *ctx,
-                                 struct perf_mmap_event *mmap_event)
+                                 struct perf_mmap_event *mmap_event,
+                                 int executable)
 {
        struct perf_event *event;
 
        list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
-               if (perf_event_mmap_match(event, mmap_event))
+               if (perf_event_mmap_match(event, mmap_event, executable))
                        perf_event_mmap_output(event, mmap_event);
        }
 }
@@ -3830,6 +3834,14 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
                if (!vma->vm_mm) {
                        name = strncpy(tmp, "[vdso]", sizeof(tmp));
                        goto got_name;
+               } else if (vma->vm_start <= vma->vm_mm->start_brk &&
+                               vma->vm_end >= vma->vm_mm->brk) {
+                       name = strncpy(tmp, "[heap]", sizeof(tmp));
+                       goto got_name;
+               } else if (vma->vm_start <= vma->vm_mm->start_stack &&
+                               vma->vm_end >= vma->vm_mm->start_stack) {
+                       name = strncpy(tmp, "[stack]", sizeof(tmp));
+                       goto got_name;
                }
 
                name = strncpy(tmp, "//anon", sizeof(tmp));
@@ -3846,17 +3858,17 @@ got_name:
 
        rcu_read_lock();
        cpuctx = &get_cpu_var(perf_cpu_context);
-       perf_event_mmap_ctx(&cpuctx->ctx, mmap_event);
+       perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, vma->vm_flags & VM_EXEC);
        ctx = rcu_dereference(current->perf_event_ctxp);
        if (ctx)
-               perf_event_mmap_ctx(ctx, mmap_event);
+               perf_event_mmap_ctx(ctx, mmap_event, vma->vm_flags & VM_EXEC);
        put_cpu_var(perf_cpu_context);
        rcu_read_unlock();
 
        kfree(buf);
 }
 
-void __perf_event_mmap(struct vm_area_struct *vma)
+void perf_event_mmap(struct vm_area_struct *vma)
 {
        struct perf_mmap_event mmap_event;
 
@@ -4018,14 +4030,14 @@ static u64 perf_swevent_set_period(struct perf_event *event)
        hwc->last_period = hwc->sample_period;
 
 again:
-       old = val = atomic64_read(&hwc->period_left);
+       old = val = local64_read(&hwc->period_left);
        if (val < 0)
                return 0;
 
        nr = div64_u64(period + val, period);
        offset = nr * period;
        val -= offset;
-       if (atomic64_cmpxchg(&hwc->period_left, old, val) != old)
+       if (local64_cmpxchg(&hwc->period_left, old, val) != old)
                goto again;
 
        return nr;
@@ -4064,7 +4076,7 @@ static void perf_swevent_add(struct perf_event *event, u64 nr,
 {
        struct hw_perf_event *hwc = &event->hw;
 
-       atomic64_add(nr, &event->count);
+       local64_add(nr, &event->count);
 
        if (!regs)
                return;
@@ -4075,7 +4087,7 @@ static void perf_swevent_add(struct perf_event *event, u64 nr,
        if (nr == 1 && hwc->sample_period == 1 && !event->attr.freq)
                return perf_swevent_overflow(event, 1, nmi, data, regs);
 
-       if (atomic64_add_negative(nr, &hwc->period_left))
+       if (local64_add_negative(nr, &hwc->period_left))
                return;
 
        perf_swevent_overflow(event, 0, nmi, data, regs);
@@ -4213,14 +4225,12 @@ int perf_swevent_get_recursion_context(void)
 }
 EXPORT_SYMBOL_GPL(perf_swevent_get_recursion_context);
 
-void perf_swevent_put_recursion_context(int rctx)
+void inline perf_swevent_put_recursion_context(int rctx)
 {
        struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
        barrier();
        cpuctx->recursion[rctx]--;
 }
-EXPORT_SYMBOL_GPL(perf_swevent_put_recursion_context);
-
 
 void __perf_sw_event(u32 event_id, u64 nr, int nmi,
                            struct pt_regs *regs, u64 addr)
@@ -4368,8 +4378,8 @@ static void cpu_clock_perf_event_update(struct perf_event *event)
        u64 now;
 
        now = cpu_clock(cpu);
-       prev = atomic64_xchg(&event->hw.prev_count, now);
-       atomic64_add(now - prev, &event->count);
+       prev = local64_xchg(&event->hw.prev_count, now);
+       local64_add(now - prev, &event->count);
 }
 
 static int cpu_clock_perf_event_enable(struct perf_event *event)
@@ -4377,7 +4387,7 @@ static int cpu_clock_perf_event_enable(struct perf_event *event)
        struct hw_perf_event *hwc = &event->hw;
        int cpu = raw_smp_processor_id();
 
-       atomic64_set(&hwc->prev_count, cpu_clock(cpu));
+       local64_set(&hwc->prev_count, cpu_clock(cpu));
        perf_swevent_start_hrtimer(event);
 
        return 0;
@@ -4409,9 +4419,9 @@ static void task_clock_perf_event_update(struct perf_event *event, u64 now)
        u64 prev;
        s64 delta;
 
-       prev = atomic64_xchg(&event->hw.prev_count, now);
+       prev = local64_xchg(&event->hw.prev_count, now);
        delta = now - prev;
-       atomic64_add(delta, &event->count);
+       local64_add(delta, &event->count);
 }
 
 static int task_clock_perf_event_enable(struct perf_event *event)
@@ -4421,7 +4431,7 @@ static int task_clock_perf_event_enable(struct perf_event *event)
 
        now = event->ctx->time;
 
-       atomic64_set(&hwc->prev_count, now);
+       local64_set(&hwc->prev_count, now);
 
        perf_swevent_start_hrtimer(event);
 
@@ -4601,7 +4611,7 @@ static int perf_tp_event_match(struct perf_event *event,
 }
 
 void perf_tp_event(u64 addr, u64 count, void *record, int entry_size,
-                  struct pt_regs *regs, struct hlist_head *head)
+                  struct pt_regs *regs, struct hlist_head *head, int rctx)
 {
        struct perf_sample_data data;
        struct perf_event *event;
@@ -4615,12 +4625,12 @@ void perf_tp_event(u64 addr, u64 count, void *record, int entry_size,
        perf_sample_data_init(&data, addr);
        data.raw = &raw;
 
-       rcu_read_lock();
        hlist_for_each_entry_rcu(event, node, head, hlist_entry) {
                if (perf_tp_event_match(event, &data, regs))
                        perf_swevent_add(event, count, 1, &data, regs);
        }
-       rcu_read_unlock();
+
+       perf_swevent_put_recursion_context(rctx);
 }
 EXPORT_SYMBOL_GPL(perf_tp_event);
 
@@ -4864,7 +4874,7 @@ perf_event_alloc(struct perf_event_attr *attr,
                hwc->sample_period = 1;
        hwc->last_period = hwc->sample_period;
 
-       atomic64_set(&hwc->period_left, hwc->sample_period);
+       local64_set(&hwc->period_left, hwc->sample_period);
 
        /*
         * we currently do not support PERF_FORMAT_GROUP on inherited events
@@ -4913,7 +4923,7 @@ done:
 
        if (!event->parent) {
                atomic_inc(&nr_events);
-               if (event->attr.mmap)
+               if (event->attr.mmap || event->attr.mmap_data)
                        atomic_inc(&nr_mmap_events);
                if (event->attr.comm)
                        atomic_inc(&nr_comm_events);
@@ -5007,7 +5017,7 @@ err_size:
 static int
 perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
 {
-       struct perf_mmap_data *data = NULL, *old_data = NULL;
+       struct perf_buffer *buffer = NULL, *old_buffer = NULL;
        int ret = -EINVAL;
 
        if (!output_event)
@@ -5037,19 +5047,19 @@ set:
 
        if (output_event) {
                /* get the buffer we want to redirect to */
-               data = perf_mmap_data_get(output_event);
-               if (!data)
+               buffer = perf_buffer_get(output_event);
+               if (!buffer)
                        goto unlock;
        }
 
-       old_data = event->data;
-       rcu_assign_pointer(event->data, data);
+       old_buffer = event->buffer;
+       rcu_assign_pointer(event->buffer, buffer);
        ret = 0;
 unlock:
        mutex_unlock(&event->mmap_mutex);
 
-       if (old_data)
-               perf_mmap_data_put(old_data);
+       if (old_buffer)
+               perf_buffer_put(old_buffer);
 out:
        return ret;
 }
@@ -5298,7 +5308,7 @@ inherit_event(struct perf_event *parent_event,
                hwc->sample_period = sample_period;
                hwc->last_period   = sample_period;
 
-               atomic64_set(&hwc->period_left, sample_period);
+               local64_set(&hwc->period_left, sample_period);
        }
 
        child_event->overflow_handler = parent_event->overflow_handler;
@@ -5359,12 +5369,12 @@ static void sync_child_event(struct perf_event *child_event,
        if (child_event->attr.inherit_stat)
                perf_event_read_event(child_event, child);
 
-       child_val = atomic64_read(&child_event->count);
+       child_val = perf_event_count(child_event);
 
        /*
         * Add back the child's count to the parent's count:
         */
-       atomic64_add(child_val, &parent_event->count);
+       atomic64_add(child_val, &parent_event->child_count);
        atomic64_add(child_event->total_time_enabled,
                     &parent_event->child_total_time_enabled);
        atomic64_add(child_event->total_time_running,
index 9829646d399c5bf0304aa863f78f6f43ae1e4d5e..f66bdd33a6c61f58f033732d24b9a3a7d19ae989 100644 (file)
@@ -232,31 +232,24 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
 
 void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
 {
-       struct sighand_struct *sighand;
-       struct signal_struct *sig;
+       struct signal_struct *sig = tsk->signal;
        struct task_struct *t;
 
-       *times = INIT_CPUTIME;
+       times->utime = sig->utime;
+       times->stime = sig->stime;
+       times->sum_exec_runtime = sig->sum_sched_runtime;
 
        rcu_read_lock();
-       sighand = rcu_dereference(tsk->sighand);
-       if (!sighand)
+       /* make sure we can trust tsk->thread_group list */
+       if (!likely(pid_alive(tsk)))
                goto out;
 
-       sig = tsk->signal;
-
        t = tsk;
        do {
                times->utime = cputime_add(times->utime, t->utime);
                times->stime = cputime_add(times->stime, t->stime);
                times->sum_exec_runtime += t->se.sum_exec_runtime;
-
-               t = next_thread(t);
-       } while (t != tsk);
-
-       times->utime = cputime_add(times->utime, sig->utime);
-       times->stime = cputime_add(times->stime, sig->stime);
-       times->sum_exec_runtime += sig->sum_sched_runtime;
+       } while_each_thread(tsk, t);
 out:
        rcu_read_unlock();
 }
@@ -1279,10 +1272,6 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
 {
        struct signal_struct *sig;
 
-       /* tsk == current, ensure it is safe to use ->signal/sighand */
-       if (unlikely(tsk->exit_state))
-               return 0;
-
        if (!task_cputime_zero(&tsk->cputime_expires)) {
                struct task_cputime task_sample = {
                        .utime = tsk->utime,
@@ -1298,7 +1287,10 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
        if (sig->cputimer.running) {
                struct task_cputime group_sample;
 
-               thread_group_cputimer(tsk, &group_sample);
+               spin_lock(&sig->cputimer.lock);
+               group_sample = sig->cputimer.cputime;
+               spin_unlock(&sig->cputimer.lock);
+
                if (task_cputime_expired(&group_sample, &sig->cputime_expires))
                        return 1;
        }
@@ -1315,6 +1307,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
 {
        LIST_HEAD(firing);
        struct k_itimer *timer, *next;
+       unsigned long flags;
 
        BUG_ON(!irqs_disabled());
 
@@ -1325,7 +1318,8 @@ void run_posix_cpu_timers(struct task_struct *tsk)
        if (!fastpath_timer_check(tsk))
                return;
 
-       spin_lock(&tsk->sighand->siglock);
+       if (!lock_task_sighand(tsk, &flags))
+               return;
        /*
         * Here we take off tsk->signal->cpu_timers[N] and
         * tsk->cpu_timers[N] all the timers that are firing, and
@@ -1347,7 +1341,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
         * that gets the timer lock before we do will give it up and
         * spin until we've taken care of that timer below.
         */
-       spin_unlock(&tsk->sighand->siglock);
+       unlock_task_sighand(tsk, &flags);
 
        /*
         * Now that all the timers on our list have the firing flag,
index ad723420acc3e765b12cf393f3cd22a754d80206..9ca4973f736d53b04bf4eea9373ce635cf7098c3 100644 (file)
@@ -560,11 +560,6 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
        new_timer->it_clock = which_clock;
        new_timer->it_overrun = -1;
 
-       if (copy_to_user(created_timer_id,
-                        &new_timer_id, sizeof (new_timer_id))) {
-               error = -EFAULT;
-               goto out;
-       }
        if (timer_event_spec) {
                if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
                        error = -EFAULT;
@@ -590,6 +585,12 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
        new_timer->sigq->info.si_tid   = new_timer->it_id;
        new_timer->sigq->info.si_code  = SI_TIMER;
 
+       if (copy_to_user(created_timer_id,
+                        &new_timer_id, sizeof (new_timer_id))) {
+               error = -EFAULT;
+               goto out;
+       }
+
        error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
        if (error)
                goto out;
index 71ae29052ab6c2275c6f48239b56cdd4be4cba33..028a99598f4986b6dfcfaf946af51952f071c346 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/syscalls.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
+#include <linux/workqueue.h>
 
 /* 
  * Timeout for stopping processes
@@ -35,6 +36,7 @@ static int try_to_freeze_tasks(bool sig_only)
        struct task_struct *g, *p;
        unsigned long end_time;
        unsigned int todo;
+       bool wq_busy = false;
        struct timeval start, end;
        u64 elapsed_csecs64;
        unsigned int elapsed_csecs;
@@ -42,6 +44,10 @@ static int try_to_freeze_tasks(bool sig_only)
        do_gettimeofday(&start);
 
        end_time = jiffies + TIMEOUT;
+
+       if (!sig_only)
+               freeze_workqueues_begin();
+
        while (true) {
                todo = 0;
                read_lock(&tasklist_lock);
@@ -63,6 +69,12 @@ static int try_to_freeze_tasks(bool sig_only)
                                todo++;
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
+
+               if (!sig_only) {
+                       wq_busy = freeze_workqueues_busy();
+                       todo += wq_busy;
+               }
+
                if (!todo || time_after(jiffies, end_time))
                        break;
 
@@ -86,8 +98,12 @@ static int try_to_freeze_tasks(bool sig_only)
                 */
                printk("\n");
                printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
-                               "(%d tasks refusing to freeze):\n",
-                               elapsed_csecs / 100, elapsed_csecs % 100, todo);
+                      "(%d tasks refusing to freeze, wq_busy=%d):\n",
+                      elapsed_csecs / 100, elapsed_csecs % 100,
+                      todo - wq_busy, wq_busy);
+
+               thaw_workqueues();
+
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
                        task_lock(p);
@@ -157,6 +173,7 @@ void thaw_processes(void)
        oom_killer_enable();
 
        printk("Restarting tasks ... ");
+       thaw_workqueues();
        thaw_tasks(true);
        thaw_tasks(false);
        schedule();
index 72a8dc9567f5825ee24bb52174b67953ca372b63..4d169835fb362dcd6eb52a916a0d8e85e48c8fb8 100644 (file)
@@ -114,3 +114,163 @@ int rcu_my_thread_group_empty(void)
 }
 EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
 #endif /* #ifdef CONFIG_PROVE_RCU */
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+static inline void debug_init_rcu_head(struct rcu_head *head)
+{
+       debug_object_init(head, &rcuhead_debug_descr);
+}
+
+static inline void debug_rcu_head_free(struct rcu_head *head)
+{
+       debug_object_free(head, &rcuhead_debug_descr);
+}
+
+/*
+ * fixup_init is called when:
+ * - an active object is initialized
+ */
+static int rcuhead_fixup_init(void *addr, enum debug_obj_state state)
+{
+       struct rcu_head *head = addr;
+
+       switch (state) {
+       case ODEBUG_STATE_ACTIVE:
+               /*
+                * Ensure that queued callbacks are all executed.
+                * If we detect that we are nested in a RCU read-side critical
+                * section, we should simply fail, otherwise we would deadlock.
+                */
+               if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
+                   irqs_disabled()) {
+                       WARN_ON(1);
+                       return 0;
+               }
+               rcu_barrier();
+               rcu_barrier_sched();
+               rcu_barrier_bh();
+               debug_object_init(head, &rcuhead_debug_descr);
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/*
+ * fixup_activate is called when:
+ * - an active object is activated
+ * - an unknown object is activated (might be a statically initialized object)
+ * Activation is performed internally by call_rcu().
+ */
+static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state)
+{
+       struct rcu_head *head = addr;
+
+       switch (state) {
+
+       case ODEBUG_STATE_NOTAVAILABLE:
+               /*
+                * This is not really a fixup. We just make sure that it is
+                * tracked in the object tracker.
+                */
+               debug_object_init(head, &rcuhead_debug_descr);
+               debug_object_activate(head, &rcuhead_debug_descr);
+               return 0;
+
+       case ODEBUG_STATE_ACTIVE:
+               /*
+                * Ensure that queued callbacks are all executed.
+                * If we detect that we are nested in a RCU read-side critical
+                * section, we should simply fail, otherwise we would deadlock.
+                */
+               if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
+                   irqs_disabled()) {
+                       WARN_ON(1);
+                       return 0;
+               }
+               rcu_barrier();
+               rcu_barrier_sched();
+               rcu_barrier_bh();
+               debug_object_activate(head, &rcuhead_debug_descr);
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/*
+ * fixup_free is called when:
+ * - an active object is freed
+ */
+static int rcuhead_fixup_free(void *addr, enum debug_obj_state state)
+{
+       struct rcu_head *head = addr;
+
+       switch (state) {
+       case ODEBUG_STATE_ACTIVE:
+               /*
+                * Ensure that queued callbacks are all executed.
+                * If we detect that we are nested in a RCU read-side critical
+                * section, we should simply fail, otherwise we would deadlock.
+                */
+#ifndef CONFIG_PREEMPT
+               WARN_ON(1);
+               return 0;
+#else
+               if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
+                   irqs_disabled()) {
+                       WARN_ON(1);
+                       return 0;
+               }
+               rcu_barrier();
+               rcu_barrier_sched();
+               rcu_barrier_bh();
+               debug_object_free(head, &rcuhead_debug_descr);
+               return 1;
+#endif
+       default:
+               return 0;
+       }
+}
+
+/**
+ * init_rcu_head_on_stack() - initialize on-stack rcu_head for debugobjects
+ * @head: pointer to rcu_head structure to be initialized
+ *
+ * This function informs debugobjects of a new rcu_head structure that
+ * has been allocated as an auto variable on the stack.  This function
+ * is not required for rcu_head structures that are statically defined or
+ * that are dynamically allocated on the heap.  This function has no
+ * effect for !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
+ */
+void init_rcu_head_on_stack(struct rcu_head *head)
+{
+       debug_object_init_on_stack(head, &rcuhead_debug_descr);
+}
+EXPORT_SYMBOL_GPL(init_rcu_head_on_stack);
+
+/**
+ * destroy_rcu_head_on_stack() - destroy on-stack rcu_head for debugobjects
+ * @head: pointer to rcu_head structure to be initialized
+ *
+ * This function informs debugobjects that an on-stack rcu_head structure
+ * is about to go out of scope.  As with init_rcu_head_on_stack(), this
+ * function is not required for rcu_head structures that are statically
+ * defined or that are dynamically allocated on the heap.  Also as with
+ * init_rcu_head_on_stack(), this function has no effect for
+ * !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
+ */
+void destroy_rcu_head_on_stack(struct rcu_head *head)
+{
+       debug_object_free(head, &rcuhead_debug_descr);
+}
+EXPORT_SYMBOL_GPL(destroy_rcu_head_on_stack);
+
+struct debug_obj_descr rcuhead_debug_descr = {
+       .name = "rcu_head",
+       .fixup_init = rcuhead_fixup_init,
+       .fixup_activate = rcuhead_fixup_activate,
+       .fixup_free = rcuhead_fixup_free,
+};
+EXPORT_SYMBOL_GPL(rcuhead_debug_descr);
+#endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
index 38729d3cd23692887afac015b442c052a150f38c..196ec02f8be0c1ad884b7d69599005a6fc3a4429 100644 (file)
@@ -169,6 +169,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
        while (list) {
                next = list->next;
                prefetch(next);
+               debug_rcu_head_unqueue(list);
                list->func(list);
                list = next;
        }
@@ -211,6 +212,7 @@ static void __call_rcu(struct rcu_head *head,
 {
        unsigned long flags;
 
+       debug_rcu_head_queue(head);
        head->func = func;
        head->next = NULL;
 
index 6535ac8bc6a5935ceebd05ea24390e25b13fba41..2e2726d790b98eff18d88d71dbeba8caf8ec7f7a 100644 (file)
@@ -239,8 +239,7 @@ static unsigned long
 rcu_random(struct rcu_random_state *rrsp)
 {
        if (--rrsp->rrs_count < 0) {
-               rrsp->rrs_state +=
-                       (unsigned long)cpu_clock(raw_smp_processor_id());
+               rrsp->rrs_state += (unsigned long)local_clock();
                rrsp->rrs_count = RCU_RANDOM_REFRESH;
        }
        rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
index d4437345706f8a539eee6dba201662fd791978ef..d5bc43976c5ad202fa41be0456797d40bdde0c0d 100644 (file)
@@ -1112,6 +1112,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
        while (list) {
                next = list->next;
                prefetch(next);
+               debug_rcu_head_unqueue(list);
                list->func(list);
                list = next;
                if (++count >= rdp->blimit)
@@ -1388,6 +1389,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
        unsigned long flags;
        struct rcu_data *rdp;
 
+       debug_rcu_head_queue(head);
        head->func = func;
        head->next = NULL;
 
index f52a8801b7a285fb252ecc6935b55f525813881b..41541d79e3c85ac7d367f3ddffc4e51a0f63e755 100644 (file)
@@ -77,6 +77,7 @@
 #include <asm/irq_regs.h>
 
 #include "sched_cpupri.h"
+#include "workqueue_sched.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/sched.h>
@@ -456,9 +457,10 @@ struct rq {
        unsigned long nr_running;
        #define CPU_LOAD_IDX_MAX 5
        unsigned long cpu_load[CPU_LOAD_IDX_MAX];
+       unsigned long last_load_update_tick;
 #ifdef CONFIG_NO_HZ
        u64 nohz_stamp;
-       unsigned char in_nohz_recently;
+       unsigned char nohz_balance_kick;
 #endif
        unsigned int skip_clock_update;
 
@@ -1192,6 +1194,27 @@ static void resched_cpu(int cpu)
 }
 
 #ifdef CONFIG_NO_HZ
+/*
+ * In the semi idle case, use the nearest busy cpu for migrating timers
+ * from an idle cpu.  This is good for power-savings.
+ *
+ * We don't do similar optimization for completely idle system, as
+ * selecting an idle cpu will add more delays to the timers than intended
+ * (as that cpu's timer base may not be uptodate wrt jiffies etc).
+ */
+int get_nohz_timer_target(void)
+{
+       int cpu = smp_processor_id();
+       int i;
+       struct sched_domain *sd;
+
+       for_each_domain(cpu, sd) {
+               for_each_cpu(i, sched_domain_span(sd))
+                       if (!idle_cpu(i))
+                               return i;
+       }
+       return cpu;
+}
 /*
  * When add_timer_on() enqueues a timer into the timer wheel of an
  * idle CPU then this timer might expire before the next timer event
@@ -1232,16 +1255,6 @@ void wake_up_idle_cpu(int cpu)
                smp_send_reschedule(cpu);
 }
 
-int nohz_ratelimit(int cpu)
-{
-       struct rq *rq = cpu_rq(cpu);
-       u64 diff = rq->clock - rq->nohz_stamp;
-
-       rq->nohz_stamp = rq->clock;
-
-       return diff < (NSEC_PER_SEC / HZ) >> 1;
-}
-
 #endif /* CONFIG_NO_HZ */
 
 static u64 sched_avg_period(void)
@@ -1652,7 +1665,7 @@ static void update_shares(struct sched_domain *sd)
        if (root_task_group_empty())
                return;
 
-       now = cpu_clock(raw_smp_processor_id());
+       now = local_clock();
        elapsed = now - sd->last_update;
 
        if (elapsed >= (s64)(u64)sysctl_sched_shares_ratelimit) {
@@ -1805,6 +1818,7 @@ static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
 static void calc_load_account_idle(struct rq *this_rq);
 static void update_sysctl(void);
 static int get_update_sysctl_factor(void);
+static void update_cpu_load(struct rq *this_rq);
 
 static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
 {
@@ -2267,11 +2281,55 @@ static void update_avg(u64 *avg, u64 sample)
 }
 #endif
 
-/***
+static inline void ttwu_activate(struct task_struct *p, struct rq *rq,
+                                bool is_sync, bool is_migrate, bool is_local,
+                                unsigned long en_flags)
+{
+       schedstat_inc(p, se.statistics.nr_wakeups);
+       if (is_sync)
+               schedstat_inc(p, se.statistics.nr_wakeups_sync);
+       if (is_migrate)
+               schedstat_inc(p, se.statistics.nr_wakeups_migrate);
+       if (is_local)
+               schedstat_inc(p, se.statistics.nr_wakeups_local);
+       else
+               schedstat_inc(p, se.statistics.nr_wakeups_remote);
+
+       activate_task(rq, p, en_flags);
+}
+
+static inline void ttwu_post_activation(struct task_struct *p, struct rq *rq,
+                                       int wake_flags, bool success)
+{
+       trace_sched_wakeup(p, success);
+       check_preempt_curr(rq, p, wake_flags);
+
+       p->state = TASK_RUNNING;
+#ifdef CONFIG_SMP
+       if (p->sched_class->task_woken)
+               p->sched_class->task_woken(rq, p);
+
+       if (unlikely(rq->idle_stamp)) {
+               u64 delta = rq->clock - rq->idle_stamp;
+               u64 max = 2*sysctl_sched_migration_cost;
+
+               if (delta > max)
+                       rq->avg_idle = max;
+               else
+                       update_avg(&rq->avg_idle, delta);
+               rq->idle_stamp = 0;
+       }
+#endif
+       /* if a worker is waking up, notify workqueue */
+       if ((p->flags & PF_WQ_WORKER) && success)
+               wq_worker_waking_up(p, cpu_of(rq));
+}
+
+/**
  * try_to_wake_up - wake up a thread
- * @p: the to-be-woken-up thread
+ * @p: the thread to be awakened
  * @state: the mask of task states that can be woken
- * @sync: do a synchronous wakeup?
+ * @wake_flags: wake modifier flags (WF_*)
  *
  * Put it on the run-queue if it's not already there. The "current"
  * thread is always on the run-queue (except when the actual
@@ -2279,7 +2337,8 @@ static void update_avg(u64 *avg, u64 sample)
  * the simpler "current->state = TASK_RUNNING" to mark yourself
  * runnable without the overhead of this.
  *
- * returns failure only if the task is already active.
+ * Returns %true if @p was woken up, %false if it was already running
+ * or @state didn't match @p's state.
  */
 static int try_to_wake_up(struct task_struct *p, unsigned int state,
                          int wake_flags)
@@ -2359,38 +2418,11 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
 
 out_activate:
 #endif /* CONFIG_SMP */
-       schedstat_inc(p, se.statistics.nr_wakeups);
-       if (wake_flags & WF_SYNC)
-               schedstat_inc(p, se.statistics.nr_wakeups_sync);
-       if (orig_cpu != cpu)
-               schedstat_inc(p, se.statistics.nr_wakeups_migrate);
-       if (cpu == this_cpu)
-               schedstat_inc(p, se.statistics.nr_wakeups_local);
-       else
-               schedstat_inc(p, se.statistics.nr_wakeups_remote);
-       activate_task(rq, p, en_flags);
+       ttwu_activate(p, rq, wake_flags & WF_SYNC, orig_cpu != cpu,
+                     cpu == this_cpu, en_flags);
        success = 1;
-
 out_running:
-       trace_sched_wakeup(p, success);
-       check_preempt_curr(rq, p, wake_flags);
-
-       p->state = TASK_RUNNING;
-#ifdef CONFIG_SMP
-       if (p->sched_class->task_woken)
-               p->sched_class->task_woken(rq, p);
-
-       if (unlikely(rq->idle_stamp)) {
-               u64 delta = rq->clock - rq->idle_stamp;
-               u64 max = 2*sysctl_sched_migration_cost;
-
-               if (delta > max)
-                       rq->avg_idle = max;
-               else
-                       update_avg(&rq->avg_idle, delta);
-               rq->idle_stamp = 0;
-       }
-#endif
+       ttwu_post_activation(p, rq, wake_flags, success);
 out:
        task_rq_unlock(rq, &flags);
        put_cpu();
@@ -2398,6 +2430,37 @@ out:
        return success;
 }
 
+/**
+ * try_to_wake_up_local - try to wake up a local task with rq lock held
+ * @p: the thread to be awakened
+ *
+ * Put @p on the run-queue if it's not alredy there.  The caller must
+ * ensure that this_rq() is locked, @p is bound to this_rq() and not
+ * the current task.  this_rq() stays locked over invocation.
+ */
+static void try_to_wake_up_local(struct task_struct *p)
+{
+       struct rq *rq = task_rq(p);
+       bool success = false;
+
+       BUG_ON(rq != this_rq());
+       BUG_ON(p == current);
+       lockdep_assert_held(&rq->lock);
+
+       if (!(p->state & TASK_NORMAL))
+               return;
+
+       if (!p->se.on_rq) {
+               if (likely(!task_running(rq, p))) {
+                       schedstat_inc(rq, ttwu_count);
+                       schedstat_inc(rq, ttwu_local);
+               }
+               ttwu_activate(p, rq, false, false, true, ENQUEUE_WAKEUP);
+               success = true;
+       }
+       ttwu_post_activation(p, rq, 0, success);
+}
+
 /**
  * wake_up_process - Wake up a specific process
  * @p: The process to be woken up.
@@ -3011,24 +3074,103 @@ static void calc_load_account_active(struct rq *this_rq)
        this_rq->calc_load_update += LOAD_FREQ;
 }
 
+/*
+ * The exact cpuload at various idx values, calculated at every tick would be
+ * load = (2^idx - 1) / 2^idx * load + 1 / 2^idx * cur_load
+ *
+ * If a cpu misses updates for n-1 ticks (as it was idle) and update gets called
+ * on nth tick when cpu may be busy, then we have:
+ * load = ((2^idx - 1) / 2^idx)^(n-1) * load
+ * load = (2^idx - 1) / 2^idx) * load + 1 / 2^idx * cur_load
+ *
+ * decay_load_missed() below does efficient calculation of
+ * load = ((2^idx - 1) / 2^idx)^(n-1) * load
+ * avoiding 0..n-1 loop doing load = ((2^idx - 1) / 2^idx) * load
+ *
+ * The calculation is approximated on a 128 point scale.
+ * degrade_zero_ticks is the number of ticks after which load at any
+ * particular idx is approximated to be zero.
+ * degrade_factor is a precomputed table, a row for each load idx.
+ * Each column corresponds to degradation factor for a power of two ticks,
+ * based on 128 point scale.
+ * Example:
+ * row 2, col 3 (=12) says that the degradation at load idx 2 after
+ * 8 ticks is 12/128 (which is an approximation of exact factor 3^8/4^8).
+ *
+ * With this power of 2 load factors, we can degrade the load n times
+ * by looking at 1 bits in n and doing as many mult/shift instead of
+ * n mult/shifts needed by the exact degradation.
+ */
+#define DEGRADE_SHIFT          7
+static const unsigned char
+               degrade_zero_ticks[CPU_LOAD_IDX_MAX] = {0, 8, 32, 64, 128};
+static const unsigned char
+               degrade_factor[CPU_LOAD_IDX_MAX][DEGRADE_SHIFT + 1] = {
+                                       {0, 0, 0, 0, 0, 0, 0, 0},
+                                       {64, 32, 8, 0, 0, 0, 0, 0},
+                                       {96, 72, 40, 12, 1, 0, 0},
+                                       {112, 98, 75, 43, 15, 1, 0},
+                                       {120, 112, 98, 76, 45, 16, 2} };
+
+/*
+ * Update cpu_load for any missed ticks, due to tickless idle. The backlog
+ * would be when CPU is idle and so we just decay the old load without
+ * adding any new load.
+ */
+static unsigned long
+decay_load_missed(unsigned long load, unsigned long missed_updates, int idx)
+{
+       int j = 0;
+
+       if (!missed_updates)
+               return load;
+
+       if (missed_updates >= degrade_zero_ticks[idx])
+               return 0;
+
+       if (idx == 1)
+               return load >> missed_updates;
+
+       while (missed_updates) {
+               if (missed_updates % 2)
+                       load = (load * degrade_factor[idx][j]) >> DEGRADE_SHIFT;
+
+               missed_updates >>= 1;
+               j++;
+       }
+       return load;
+}
+
 /*
  * Update rq->cpu_load[] statistics. This function is usually called every
- * scheduler tick (TICK_NSEC).
+ * scheduler tick (TICK_NSEC). With tickless idle this will not be called
+ * every tick. We fix it up based on jiffies.
  */
 static void update_cpu_load(struct rq *this_rq)
 {
        unsigned long this_load = this_rq->load.weight;
+       unsigned long curr_jiffies = jiffies;
+       unsigned long pending_updates;
        int i, scale;
 
        this_rq->nr_load_updates++;
 
+       /* Avoid repeated calls on same jiffy, when moving in and out of idle */
+       if (curr_jiffies == this_rq->last_load_update_tick)
+               return;
+
+       pending_updates = curr_jiffies - this_rq->last_load_update_tick;
+       this_rq->last_load_update_tick = curr_jiffies;
+
        /* Update our load: */
-       for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
+       this_rq->cpu_load[0] = this_load; /* Fasttrack for idx 0 */
+       for (i = 1, scale = 2; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
                unsigned long old_load, new_load;
 
                /* scale is effectively 1 << i now, and >> i divides by scale */
 
                old_load = this_rq->cpu_load[i];
+               old_load = decay_load_missed(old_load, pending_updates - 1, i);
                new_load = this_load;
                /*
                 * Round up the averaging division if load is increasing. This
@@ -3036,9 +3178,15 @@ static void update_cpu_load(struct rq *this_rq)
                 * example.
                 */
                if (new_load > old_load)
-                       new_load += scale-1;
-               this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
+                       new_load += scale - 1;
+
+               this_rq->cpu_load[i] = (old_load * (scale - 1) + new_load) >> i;
        }
+}
+
+static void update_cpu_load_active(struct rq *this_rq)
+{
+       update_cpu_load(this_rq);
 
        calc_load_account_active(this_rq);
 }
@@ -3426,7 +3574,7 @@ void scheduler_tick(void)
 
        raw_spin_lock(&rq->lock);
        update_rq_clock(rq);
-       update_cpu_load(rq);
+       update_cpu_load_active(rq);
        curr->sched_class->task_tick(rq, curr, 0);
        raw_spin_unlock(&rq->lock);
 
@@ -3598,7 +3746,6 @@ need_resched:
        rq = cpu_rq(cpu);
        rcu_note_context_switch(cpu);
        prev = rq->curr;
-       switch_count = &prev->nivcsw;
 
        release_kernel_lock(prev);
 need_resched_nonpreemptible:
@@ -3611,11 +3758,26 @@ need_resched_nonpreemptible:
        raw_spin_lock_irq(&rq->lock);
        clear_tsk_need_resched(prev);
 
+       switch_count = &prev->nivcsw;
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
-               if (unlikely(signal_pending_state(prev->state, prev)))
+               if (unlikely(signal_pending_state(prev->state, prev))) {
                        prev->state = TASK_RUNNING;
-               else
+               } else {
+                       /*
+                        * If a worker is going to sleep, notify and
+                        * ask workqueue whether it wants to wake up a
+                        * task to maintain concurrency.  If so, wake
+                        * up the task.
+                        */
+                       if (prev->flags & PF_WQ_WORKER) {
+                               struct task_struct *to_wakeup;
+
+                               to_wakeup = wq_worker_sleeping(prev, cpu);
+                               if (to_wakeup)
+                                       try_to_wake_up_local(to_wakeup);
+                       }
                        deactivate_task(rq, prev, DEQUEUE_SLEEP);
+               }
                switch_count = &prev->nvcsw;
        }
 
@@ -3637,8 +3799,10 @@ need_resched_nonpreemptible:
 
                context_switch(rq, prev, next); /* unlocks the rq */
                /*
-                * the context switch might have flipped the stack from under
-                * us, hence refresh the local variables.
+                * The context switch have flipped the stack from under us
+                * and restored the local variables which were saved when
+                * this task called schedule() in the past. prev == current
+                * is still correct, but it can be moved to another cpu/rq.
                 */
                cpu = smp_processor_id();
                rq = cpu_rq(cpu);
@@ -3647,11 +3811,8 @@ need_resched_nonpreemptible:
 
        post_schedule(rq);
 
-       if (unlikely(reacquire_kernel_lock(current) < 0)) {
-               prev = rq->curr;
-               switch_count = &prev->nivcsw;
+       if (unlikely(reacquire_kernel_lock(prev)))
                goto need_resched_nonpreemptible;
-       }
 
        preempt_enable_no_resched();
        if (need_resched())
@@ -3726,7 +3887,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
  * off of preempt_enable. Kernel preemptions off return from interrupt
  * occur there and call schedule directly.
  */
-asmlinkage void __sched preempt_schedule(void)
+asmlinkage void __sched notrace preempt_schedule(void)
 {
        struct thread_info *ti = current_thread_info();
 
@@ -3738,9 +3899,9 @@ asmlinkage void __sched preempt_schedule(void)
                return;
 
        do {
-               add_preempt_count(PREEMPT_ACTIVE);
+               add_preempt_count_notrace(PREEMPT_ACTIVE);
                schedule();
-               sub_preempt_count(PREEMPT_ACTIVE);
+               sub_preempt_count_notrace(PREEMPT_ACTIVE);
 
                /*
                 * Check again in case we missed a preemption opportunity
@@ -4441,12 +4602,8 @@ recheck:
         */
        if (user && !capable(CAP_SYS_NICE)) {
                if (rt_policy(policy)) {
-                       unsigned long rlim_rtprio;
-
-                       if (!lock_task_sighand(p, &flags))
-                               return -ESRCH;
-                       rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO);
-                       unlock_task_sighand(p, &flags);
+                       unsigned long rlim_rtprio =
+                                       task_rlimit(p, RLIMIT_RTPRIO);
 
                        /* can't set/change the rt policy */
                        if (policy != p->policy && !rlim_rtprio)
@@ -5816,20 +5973,49 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
  */
 static struct notifier_block __cpuinitdata migration_notifier = {
        .notifier_call = migration_call,
-       .priority = 10
+       .priority = CPU_PRI_MIGRATION,
 };
 
+static int __cpuinit sched_cpu_active(struct notifier_block *nfb,
+                                     unsigned long action, void *hcpu)
+{
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+               set_cpu_active((long)hcpu, true);
+               return NOTIFY_OK;
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
+static int __cpuinit sched_cpu_inactive(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_DOWN_PREPARE:
+               set_cpu_active((long)hcpu, false);
+               return NOTIFY_OK;
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
 static int __init migration_init(void)
 {
        void *cpu = (void *)(long)smp_processor_id();
        int err;
 
-       /* Start one for the boot CPU: */
+       /* Initialize migration for the boot CPU */
        err = migration_call(&migration_notifier, CPU_UP_PREPARE, cpu);
        BUG_ON(err == NOTIFY_BAD);
        migration_call(&migration_notifier, CPU_ONLINE, cpu);
        register_cpu_notifier(&migration_notifier);
 
+       /* Register cpu active notifiers */
+       cpu_notifier(sched_cpu_active, CPU_PRI_SCHED_ACTIVE);
+       cpu_notifier(sched_cpu_inactive, CPU_PRI_SCHED_INACTIVE);
+
        return 0;
 }
 early_initcall(migration_init);
@@ -6064,23 +6250,18 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd)
                free_rootdomain(old_rd);
 }
 
-static int init_rootdomain(struct root_domain *rd, bool bootmem)
+static int init_rootdomain(struct root_domain *rd)
 {
-       gfp_t gfp = GFP_KERNEL;
-
        memset(rd, 0, sizeof(*rd));
 
-       if (bootmem)
-               gfp = GFP_NOWAIT;
-
-       if (!alloc_cpumask_var(&rd->span, gfp))
+       if (!alloc_cpumask_var(&rd->span, GFP_KERNEL))
                goto out;
-       if (!alloc_cpumask_var(&rd->online, gfp))
+       if (!alloc_cpumask_var(&rd->online, GFP_KERNEL))
                goto free_span;
-       if (!alloc_cpumask_var(&rd->rto_mask, gfp))
+       if (!alloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
                goto free_online;
 
-       if (cpupri_init(&rd->cpupri, bootmem) != 0)
+       if (cpupri_init(&rd->cpupri) != 0)
                goto free_rto_mask;
        return 0;
 
@@ -6096,7 +6277,7 @@ out:
 
 static void init_defrootdomain(void)
 {
-       init_rootdomain(&def_root_domain, true);
+       init_rootdomain(&def_root_domain);
 
        atomic_set(&def_root_domain.refcount, 1);
 }
@@ -6109,7 +6290,7 @@ static struct root_domain *alloc_rootdomain(void)
        if (!rd)
                return NULL;
 
-       if (init_rootdomain(rd, false) != 0) {
+       if (init_rootdomain(rd) != 0) {
                kfree(rd);
                return NULL;
        }
@@ -7288,29 +7469,35 @@ int __init sched_create_sysfs_power_savings_entries(struct sysdev_class *cls)
 }
 #endif /* CONFIG_SCHED_MC || CONFIG_SCHED_SMT */
 
-#ifndef CONFIG_CPUSETS
 /*
- * Add online and remove offline CPUs from the scheduler domains.
- * When cpusets are enabled they take over this function.
+ * Update cpusets according to cpu_active mask.  If cpusets are
+ * disabled, cpuset_update_active_cpus() becomes a simple wrapper
+ * around partition_sched_domains().
  */
-static int update_sched_domains(struct notifier_block *nfb,
-                               unsigned long action, void *hcpu)
+static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
+                            void *hcpu)
 {
-       switch (action) {
+       switch (action & ~CPU_TASKS_FROZEN) {
        case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-       case CPU_DOWN_PREPARE:
-       case CPU_DOWN_PREPARE_FROZEN:
        case CPU_DOWN_FAILED:
-       case CPU_DOWN_FAILED_FROZEN:
-               partition_sched_domains(1, NULL, NULL);
+               cpuset_update_active_cpus();
                return NOTIFY_OK;
+       default:
+               return NOTIFY_DONE;
+       }
+}
 
+static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
+                              void *hcpu)
+{
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_DOWN_PREPARE:
+               cpuset_update_active_cpus();
+               return NOTIFY_OK;
        default:
                return NOTIFY_DONE;
        }
 }
-#endif
 
 static int update_runtime(struct notifier_block *nfb,
                                unsigned long action, void *hcpu)
@@ -7356,10 +7543,8 @@ void __init sched_init_smp(void)
        mutex_unlock(&sched_domains_mutex);
        put_online_cpus();
 
-#ifndef CONFIG_CPUSETS
-       /* XXX: Theoretical race here - CPU may be hotplugged now */
-       hotcpu_notifier(update_sched_domains, 0);
-#endif
+       hotcpu_notifier(cpuset_cpu_active, CPU_PRI_CPUSET_ACTIVE);
+       hotcpu_notifier(cpuset_cpu_inactive, CPU_PRI_CPUSET_INACTIVE);
 
        /* RT runtime code needs to handle some hotplug events */
        hotcpu_notifier(update_runtime, 0);
@@ -7604,6 +7789,9 @@ void __init sched_init(void)
 
                for (j = 0; j < CPU_LOAD_IDX_MAX; j++)
                        rq->cpu_load[j] = 0;
+
+               rq->last_load_update_tick = jiffies;
+
 #ifdef CONFIG_SMP
                rq->sd = NULL;
                rq->rd = NULL;
@@ -7617,6 +7805,10 @@ void __init sched_init(void)
                rq->idle_stamp = 0;
                rq->avg_idle = 2*sysctl_sched_migration_cost;
                rq_attach_root(rq, &def_root_domain);
+#ifdef CONFIG_NO_HZ
+               rq->nohz_balance_kick = 0;
+               init_sched_softirq_csd(&per_cpu(remote_sched_softirq_cb, i));
+#endif
 #endif
                init_rq_hrtick(rq);
                atomic_set(&rq->nr_iowait, 0);
@@ -7661,8 +7853,11 @@ void __init sched_init(void)
        zalloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT);
 #ifdef CONFIG_SMP
 #ifdef CONFIG_NO_HZ
-       zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT);
-       alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT);
+       alloc_cpumask_var(&nohz.grp_idle_mask, GFP_NOWAIT);
+       atomic_set(&nohz.load_balancer, nr_cpu_ids);
+       atomic_set(&nohz.first_pick_cpu, nr_cpu_ids);
+       atomic_set(&nohz.second_pick_cpu, nr_cpu_ids);
 #endif
        /* May be allocated at isolcpus cmdline parse time */
        if (cpu_isolated_map == NULL)
index 906a0f718cb32c16797b83df68a4eb23d3e15a16..52f1a149bfb15a871a362255498fadf90e357c57 100644 (file)
  *   Ingo Molnar <mingo@redhat.com>
  *   Guillaume Chazarain <guichaz@gmail.com>
  *
- * Create a semi stable clock from a mixture of other events, including:
- *  - gtod
+ *
+ * What:
+ *
+ * cpu_clock(i) provides a fast (execution time) high resolution
+ * clock with bounded drift between CPUs. The value of cpu_clock(i)
+ * is monotonic for constant i. The timestamp returned is in nanoseconds.
+ *
+ * ######################### BIG FAT WARNING ##########################
+ * # when comparing cpu_clock(i) to cpu_clock(j) for i != j, time can #
+ * # go backwards !!                                                  #
+ * ####################################################################
+ *
+ * There is no strict promise about the base, although it tends to start
+ * at 0 on boot (but people really shouldn't rely on that).
+ *
+ * cpu_clock(i)       -- can be used from any context, including NMI.
+ * sched_clock_cpu(i) -- must be used with local IRQs disabled (implied by NMI)
+ * local_clock()      -- is cpu_clock() on the current cpu.
+ *
+ * How:
+ *
+ * The implementation either uses sched_clock() when
+ * !CONFIG_HAVE_UNSTABLE_SCHED_CLOCK, which means in that case the
+ * sched_clock() is assumed to provide these properties (mostly it means
+ * the architecture provides a globally synchronized highres time source).
+ *
+ * Otherwise it tries to create a semi stable clock from a mixture of other
+ * clocks, including:
+ *
+ *  - GTOD (clock monotomic)
  *  - sched_clock()
  *  - explicit idle events
  *
- * We use gtod as base and the unstable clock deltas. The deltas are filtered,
- * making it monotonic and keeping it within an expected window.
+ * We use GTOD as base and use sched_clock() deltas to improve resolution. The
+ * deltas are filtered to provide monotonicity and keeping it within an
+ * expected window.
  *
  * Furthermore, explicit sleep and wakeup hooks allow us to account for time
  * that is otherwise invisible (TSC gets stopped).
  *
- * The clock: sched_clock_cpu() is monotonic per cpu, and should be somewhat
- * consistent between cpus (never more than 2 jiffies difference).
+ *
+ * Notes:
+ *
+ * The !IRQ-safetly of sched_clock() and sched_clock_cpu() comes from things
+ * like cpufreq interrupts that can change the base clock (TSC) multiplier
+ * and cause funny jumps in time -- although the filtering provided by
+ * sched_clock_cpu() should mitigate serious artifacts we cannot rely on it
+ * in general since for !CONFIG_HAVE_UNSTABLE_SCHED_CLOCK we fully rely on
+ * sched_clock().
  */
 #include <linux/spinlock.h>
 #include <linux/hardirq.h>
@@ -170,6 +206,11 @@ again:
        return val;
 }
 
+/*
+ * Similar to cpu_clock(), but requires local IRQs to be disabled.
+ *
+ * See cpu_clock().
+ */
 u64 sched_clock_cpu(int cpu)
 {
        struct sched_clock_data *scd;
@@ -237,9 +278,19 @@ void sched_clock_idle_wakeup_event(u64 delta_ns)
 }
 EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
 
-unsigned long long cpu_clock(int cpu)
+/*
+ * As outlined at the top, provides a fast, high resolution, nanosecond
+ * time source that is monotonic per cpu argument and has bounded drift
+ * between cpus.
+ *
+ * ######################### BIG FAT WARNING ##########################
+ * # when comparing cpu_clock(i) to cpu_clock(j) for i != j, time can #
+ * # go backwards !!                                                  #
+ * ####################################################################
+ */
+u64 cpu_clock(int cpu)
 {
-       unsigned long long clock;
+       u64 clock;
        unsigned long flags;
 
        local_irq_save(flags);
@@ -249,6 +300,25 @@ unsigned long long cpu_clock(int cpu)
        return clock;
 }
 
+/*
+ * Similar to cpu_clock() for the current cpu. Time will only be observed
+ * to be monotonic if care is taken to only compare timestampt taken on the
+ * same CPU.
+ *
+ * See cpu_clock().
+ */
+u64 local_clock(void)
+{
+       u64 clock;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       clock = sched_clock_cpu(smp_processor_id());
+       local_irq_restore(flags);
+
+       return clock;
+}
+
 #else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
 
 void sched_clock_init(void)
@@ -264,12 +334,17 @@ u64 sched_clock_cpu(int cpu)
        return sched_clock();
 }
 
-
-unsigned long long cpu_clock(int cpu)
+u64 cpu_clock(int cpu)
 {
        return sched_clock_cpu(cpu);
 }
 
+u64 local_clock(void)
+{
+       return sched_clock_cpu(0);
+}
+
 #endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
 
 EXPORT_SYMBOL_GPL(cpu_clock);
+EXPORT_SYMBOL_GPL(local_clock);
index e6871cb3fc83dde1901b62c6355edc30ea55a64e..2722dc1b41383fa6f8108802315cbc82c3c1e814 100644 (file)
@@ -166,14 +166,10 @@ void cpupri_set(struct cpupri *cp, int cpu, int newpri)
  *
  * Returns: -ENOMEM if memory fails.
  */
-int cpupri_init(struct cpupri *cp, bool bootmem)
+int cpupri_init(struct cpupri *cp)
 {
-       gfp_t gfp = GFP_KERNEL;
        int i;
 
-       if (bootmem)
-               gfp = GFP_NOWAIT;
-
        memset(cp, 0, sizeof(*cp));
 
        for (i = 0; i < CPUPRI_NR_PRIORITIES; i++) {
@@ -181,7 +177,7 @@ int cpupri_init(struct cpupri *cp, bool bootmem)
 
                raw_spin_lock_init(&vec->lock);
                vec->count = 0;
-               if (!zalloc_cpumask_var(&vec->mask, gfp))
+               if (!zalloc_cpumask_var(&vec->mask, GFP_KERNEL))
                        goto cleanup;
        }
 
index 7cb5bb6b95be5a4be62c7a7f937388a0fe8ae1e1..9fc7d386fea4b845f5e3be3183825d00d182cda9 100644 (file)
@@ -27,7 +27,7 @@ struct cpupri {
 int  cpupri_find(struct cpupri *cp,
                 struct task_struct *p, struct cpumask *lowest_mask);
 void cpupri_set(struct cpupri *cp, int cpu, int pri);
-int cpupri_init(struct cpupri *cp, bool bootmem);
+int cpupri_init(struct cpupri *cp);
 void cpupri_cleanup(struct cpupri *cp);
 #else
 #define cpupri_set(cp, cpu, pri) do { } while (0)
index 35565395d00d32c7c295d3c36fa722ecdadda097..2e1b0d17dd9b6a8b4ac48891a988c025a8b07ed5 100644 (file)
@@ -332,7 +332,7 @@ static int sched_debug_show(struct seq_file *m, void *v)
        PN(sysctl_sched_latency);
        PN(sysctl_sched_min_granularity);
        PN(sysctl_sched_wakeup_granularity);
-       PN(sysctl_sched_child_runs_first);
+       P(sysctl_sched_child_runs_first);
        P(sysctl_sched_features);
 #undef PN
 #undef P
index a878b5332daad5d7db16625f298a4e963edac909..806d1b227a21060aac100994a8992266c00b59b5 100644 (file)
@@ -2287,13 +2287,6 @@ static void update_cpu_power(struct sched_domain *sd, int cpu)
        unsigned long power = SCHED_LOAD_SCALE;
        struct sched_group *sdg = sd->groups;
 
-       if (sched_feat(ARCH_POWER))
-               power *= arch_scale_freq_power(sd, cpu);
-       else
-               power *= default_scale_freq_power(sd, cpu);
-
-       power >>= SCHED_LOAD_SHIFT;
-
        if ((sd->flags & SD_SHARE_CPUPOWER) && weight > 1) {
                if (sched_feat(ARCH_POWER))
                        power *= arch_scale_smt_power(sd, cpu);
@@ -2303,6 +2296,15 @@ static void update_cpu_power(struct sched_domain *sd, int cpu)
                power >>= SCHED_LOAD_SHIFT;
        }
 
+       sdg->cpu_power_orig = power;
+
+       if (sched_feat(ARCH_POWER))
+               power *= arch_scale_freq_power(sd, cpu);
+       else
+               power *= default_scale_freq_power(sd, cpu);
+
+       power >>= SCHED_LOAD_SHIFT;
+
        power *= scale_rt_power(cpu);
        power >>= SCHED_LOAD_SHIFT;
 
@@ -2335,6 +2337,31 @@ static void update_group_power(struct sched_domain *sd, int cpu)
        sdg->cpu_power = power;
 }
 
+/*
+ * Try and fix up capacity for tiny siblings, this is needed when
+ * things like SD_ASYM_PACKING need f_b_g to select another sibling
+ * which on its own isn't powerful enough.
+ *
+ * See update_sd_pick_busiest() and check_asym_packing().
+ */
+static inline int
+fix_small_capacity(struct sched_domain *sd, struct sched_group *group)
+{
+       /*
+        * Only siblings can have significantly less than SCHED_LOAD_SCALE
+        */
+       if (sd->level != SD_LV_SIBLING)
+               return 0;
+
+       /*
+        * If ~90% of the cpu_power is still there, we're good.
+        */
+       if (group->cpu_power * 32 > group->cpu_power_orig * 29)
+               return 1;
+
+       return 0;
+}
+
 /**
  * update_sg_lb_stats - Update sched_group's statistics for load balancing.
  * @sd: The sched_domain whose statistics are to be updated.
@@ -2400,14 +2427,14 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
         * domains. In the newly idle case, we will allow all the cpu's
         * to do the newly idle load balance.
         */
-       if (idle != CPU_NEWLY_IDLE && local_group &&
-           balance_cpu != this_cpu) {
-               *balance = 0;
-               return;
+       if (idle != CPU_NEWLY_IDLE && local_group) {
+               if (balance_cpu != this_cpu) {
+                       *balance = 0;
+                       return;
+               }
+               update_group_power(sd, this_cpu);
        }
 
-       update_group_power(sd, this_cpu);
-
        /* Adjust by relative CPU power of the group */
        sgs->avg_load = (sgs->group_load * SCHED_LOAD_SCALE) / group->cpu_power;
 
@@ -2428,6 +2455,51 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
 
        sgs->group_capacity =
                DIV_ROUND_CLOSEST(group->cpu_power, SCHED_LOAD_SCALE);
+       if (!sgs->group_capacity)
+               sgs->group_capacity = fix_small_capacity(sd, group);
+}
+
+/**
+ * update_sd_pick_busiest - return 1 on busiest group
+ * @sd: sched_domain whose statistics are to be checked
+ * @sds: sched_domain statistics
+ * @sg: sched_group candidate to be checked for being the busiest
+ * @sgs: sched_group statistics
+ * @this_cpu: the current cpu
+ *
+ * Determine if @sg is a busier group than the previously selected
+ * busiest group.
+ */
+static bool update_sd_pick_busiest(struct sched_domain *sd,
+                                  struct sd_lb_stats *sds,
+                                  struct sched_group *sg,
+                                  struct sg_lb_stats *sgs,
+                                  int this_cpu)
+{
+       if (sgs->avg_load <= sds->max_load)
+               return false;
+
+       if (sgs->sum_nr_running > sgs->group_capacity)
+               return true;
+
+       if (sgs->group_imb)
+               return true;
+
+       /*
+        * ASYM_PACKING needs to move all the work to the lowest
+        * numbered CPUs in the group, therefore mark all groups
+        * higher than ourself as busy.
+        */
+       if ((sd->flags & SD_ASYM_PACKING) && sgs->sum_nr_running &&
+           this_cpu < group_first_cpu(sg)) {
+               if (!sds->busiest)
+                       return true;
+
+               if (group_first_cpu(sds->busiest) > group_first_cpu(sg))
+                       return true;
+       }
+
+       return false;
 }
 
 /**
@@ -2435,7 +2507,7 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
  * @sd: sched_domain whose statistics are to be updated.
  * @this_cpu: Cpu for which load balance is currently performed.
  * @idle: Idle status of this_cpu
- * @sd_idle: Idle status of the sched_domain containing group.
+ * @sd_idle: Idle status of the sched_domain containing sg.
  * @cpus: Set of cpus considered for load balancing.
  * @balance: Should we balance.
  * @sds: variable to hold the statistics for this sched_domain.
@@ -2446,7 +2518,7 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
                        struct sd_lb_stats *sds)
 {
        struct sched_domain *child = sd->child;
-       struct sched_group *group = sd->groups;
+       struct sched_group *sg = sd->groups;
        struct sg_lb_stats sgs;
        int load_idx, prefer_sibling = 0;
 
@@ -2459,21 +2531,20 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
        do {
                int local_group;
 
-               local_group = cpumask_test_cpu(this_cpu,
-                                              sched_group_cpus(group));
+               local_group = cpumask_test_cpu(this_cpu, sched_group_cpus(sg));
                memset(&sgs, 0, sizeof(sgs));
-               update_sg_lb_stats(sd, group, this_cpu, idle, load_idx, sd_idle,
+               update_sg_lb_stats(sd, sg, this_cpu, idle, load_idx, sd_idle,
                                local_group, cpus, balance, &sgs);
 
                if (local_group && !(*balance))
                        return;
 
                sds->total_load += sgs.group_load;
-               sds->total_pwr += group->cpu_power;
+               sds->total_pwr += sg->cpu_power;
 
                /*
                 * In case the child domain prefers tasks go to siblings
-                * first, lower the group capacity to one so that we'll try
+                * first, lower the sg capacity to one so that we'll try
                 * and move all the excess tasks away.
                 */
                if (prefer_sibling)
@@ -2481,23 +2552,72 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
 
                if (local_group) {
                        sds->this_load = sgs.avg_load;
-                       sds->this = group;
+                       sds->this = sg;
                        sds->this_nr_running = sgs.sum_nr_running;
                        sds->this_load_per_task = sgs.sum_weighted_load;
-               } else if (sgs.avg_load > sds->max_load &&
-                          (sgs.sum_nr_running > sgs.group_capacity ||
-                               sgs.group_imb)) {
+               } else if (update_sd_pick_busiest(sd, sds, sg, &sgs, this_cpu)) {
                        sds->max_load = sgs.avg_load;
-                       sds->busiest = group;
+                       sds->busiest = sg;
                        sds->busiest_nr_running = sgs.sum_nr_running;
                        sds->busiest_group_capacity = sgs.group_capacity;
                        sds->busiest_load_per_task = sgs.sum_weighted_load;
                        sds->group_imb = sgs.group_imb;
                }
 
-               update_sd_power_savings_stats(group, sds, local_group, &sgs);
-               group = group->next;
-       } while (group != sd->groups);
+               update_sd_power_savings_stats(sg, sds, local_group, &sgs);
+               sg = sg->next;
+       } while (sg != sd->groups);
+}
+
+int __weak arch_sd_sibling_asym_packing(void)
+{
+       return 0*SD_ASYM_PACKING;
+}
+
+/**
+ * check_asym_packing - Check to see if the group is packed into the
+ *                     sched doman.
+ *
+ * This is primarily intended to used at the sibling level.  Some
+ * cores like POWER7 prefer to use lower numbered SMT threads.  In the
+ * case of POWER7, it can move to lower SMT modes only when higher
+ * threads are idle.  When in lower SMT modes, the threads will
+ * perform better since they share less core resources.  Hence when we
+ * have idle threads, we want them to be the higher ones.
+ *
+ * This packing function is run on idle threads.  It checks to see if
+ * the busiest CPU in this domain (core in the P7 case) has a higher
+ * CPU number than the packing function is being run on.  Here we are
+ * assuming lower CPU number will be equivalent to lower a SMT thread
+ * number.
+ *
+ * Returns 1 when packing is required and a task should be moved to
+ * this CPU.  The amount of the imbalance is returned in *imbalance.
+ *
+ * @sd: The sched_domain whose packing is to be checked.
+ * @sds: Statistics of the sched_domain which is to be packed
+ * @this_cpu: The cpu at whose sched_domain we're performing load-balance.
+ * @imbalance: returns amount of imbalanced due to packing.
+ */
+static int check_asym_packing(struct sched_domain *sd,
+                             struct sd_lb_stats *sds,
+                             int this_cpu, unsigned long *imbalance)
+{
+       int busiest_cpu;
+
+       if (!(sd->flags & SD_ASYM_PACKING))
+               return 0;
+
+       if (!sds->busiest)
+               return 0;
+
+       busiest_cpu = group_first_cpu(sds->busiest);
+       if (this_cpu > busiest_cpu)
+               return 0;
+
+       *imbalance = DIV_ROUND_CLOSEST(sds->max_load * sds->busiest->cpu_power,
+                                      SCHED_LOAD_SCALE);
+       return 1;
 }
 
 /**
@@ -2692,6 +2812,10 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
        if (!(*balance))
                goto ret;
 
+       if ((idle == CPU_IDLE || idle == CPU_NEWLY_IDLE) &&
+           check_asym_packing(sd, &sds, this_cpu, imbalance))
+               return sds.busiest;
+
        if (!sds.busiest || sds.busiest_nr_running == 0)
                goto out_balanced;
 
@@ -2726,8 +2850,9 @@ ret:
  * find_busiest_queue - find the busiest runqueue among the cpus in group.
  */
 static struct rq *
-find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
-                  unsigned long imbalance, const struct cpumask *cpus)
+find_busiest_queue(struct sched_domain *sd, struct sched_group *group,
+                  enum cpu_idle_type idle, unsigned long imbalance,
+                  const struct cpumask *cpus)
 {
        struct rq *busiest = NULL, *rq;
        unsigned long max_load = 0;
@@ -2738,6 +2863,9 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
                unsigned long capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE);
                unsigned long wl;
 
+               if (!capacity)
+                       capacity = fix_small_capacity(sd, group);
+
                if (!cpumask_test_cpu(i, cpus))
                        continue;
 
@@ -2777,9 +2905,19 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
 /* Working cpumask for load_balance and load_balance_newidle. */
 static DEFINE_PER_CPU(cpumask_var_t, load_balance_tmpmask);
 
-static int need_active_balance(struct sched_domain *sd, int sd_idle, int idle)
+static int need_active_balance(struct sched_domain *sd, int sd_idle, int idle,
+                              int busiest_cpu, int this_cpu)
 {
        if (idle == CPU_NEWLY_IDLE) {
+
+               /*
+                * ASYM_PACKING needs to force migrate tasks from busy but
+                * higher numbered CPUs in order to pack all tasks in the
+                * lowest numbered CPUs.
+                */
+               if ((sd->flags & SD_ASYM_PACKING) && busiest_cpu > this_cpu)
+                       return 1;
+
                /*
                 * The only task running in a non-idle cpu can be moved to this
                 * cpu in an attempt to completely freeup the other CPU
@@ -2854,7 +2992,7 @@ redo:
                goto out_balanced;
        }
 
-       busiest = find_busiest_queue(group, idle, imbalance, cpus);
+       busiest = find_busiest_queue(sd, group, idle, imbalance, cpus);
        if (!busiest) {
                schedstat_inc(sd, lb_nobusyq[idle]);
                goto out_balanced;
@@ -2898,7 +3036,8 @@ redo:
                schedstat_inc(sd, lb_failed[idle]);
                sd->nr_balance_failed++;
 
-               if (need_active_balance(sd, sd_idle, idle)) {
+               if (need_active_balance(sd, sd_idle, idle, cpu_of(busiest),
+                                       this_cpu)) {
                        raw_spin_lock_irqsave(&busiest->lock, flags);
 
                        /* don't kick the active_load_balance_cpu_stop,
@@ -3093,13 +3232,40 @@ out_unlock:
 }
 
 #ifdef CONFIG_NO_HZ
+
+static DEFINE_PER_CPU(struct call_single_data, remote_sched_softirq_cb);
+
+static void trigger_sched_softirq(void *data)
+{
+       raise_softirq_irqoff(SCHED_SOFTIRQ);
+}
+
+static inline void init_sched_softirq_csd(struct call_single_data *csd)
+{
+       csd->func = trigger_sched_softirq;
+       csd->info = NULL;
+       csd->flags = 0;
+       csd->priv = 0;
+}
+
+/*
+ * idle load balancing details
+ * - One of the idle CPUs nominates itself as idle load_balancer, while
+ *   entering idle.
+ * - This idle load balancer CPU will also go into tickless mode when
+ *   it is idle, just like all other idle CPUs
+ * - When one of the busy CPUs notice that there may be an idle rebalancing
+ *   needed, they will kick the idle load balancer, which then does idle
+ *   load balancing for all the idle CPUs.
+ */
 static struct {
        atomic_t load_balancer;
-       cpumask_var_t cpu_mask;
-       cpumask_var_t ilb_grp_nohz_mask;
-} nohz ____cacheline_aligned = {
-       .load_balancer = ATOMIC_INIT(-1),
-};
+       atomic_t first_pick_cpu;
+       atomic_t second_pick_cpu;
+       cpumask_var_t idle_cpus_mask;
+       cpumask_var_t grp_idle_mask;
+       unsigned long next_balance;     /* in jiffy units */
+} nohz ____cacheline_aligned;
 
 int get_nohz_load_balancer(void)
 {
@@ -3153,17 +3319,17 @@ static inline struct sched_domain *lowest_flag_domain(int cpu, int flag)
  */
 static inline int is_semi_idle_group(struct sched_group *ilb_group)
 {
-       cpumask_and(nohz.ilb_grp_nohz_mask, nohz.cpu_mask,
+       cpumask_and(nohz.grp_idle_mask, nohz.idle_cpus_mask,
                                        sched_group_cpus(ilb_group));
 
        /*
         * A sched_group is semi-idle when it has atleast one busy cpu
         * and atleast one idle cpu.
         */
-       if (cpumask_empty(nohz.ilb_grp_nohz_mask))
+       if (cpumask_empty(nohz.grp_idle_mask))
                return 0;
 
-       if (cpumask_equal(nohz.ilb_grp_nohz_mask, sched_group_cpus(ilb_group)))
+       if (cpumask_equal(nohz.grp_idle_mask, sched_group_cpus(ilb_group)))
                return 0;
 
        return 1;
@@ -3196,7 +3362,7 @@ static int find_new_ilb(int cpu)
         * Optimize for the case when we have no idle CPUs or only one
         * idle CPU. Don't walk the sched_domain hierarchy in such cases
         */
-       if (cpumask_weight(nohz.cpu_mask) < 2)
+       if (cpumask_weight(nohz.idle_cpus_mask) < 2)
                goto out_done;
 
        for_each_flag_domain(cpu, sd, SD_POWERSAVINGS_BALANCE) {
@@ -3204,7 +3370,7 @@ static int find_new_ilb(int cpu)
 
                do {
                        if (is_semi_idle_group(ilb_group))
-                               return cpumask_first(nohz.ilb_grp_nohz_mask);
+                               return cpumask_first(nohz.grp_idle_mask);
 
                        ilb_group = ilb_group->next;
 
@@ -3212,98 +3378,116 @@ static int find_new_ilb(int cpu)
        }
 
 out_done:
-       return cpumask_first(nohz.cpu_mask);
+       return nr_cpu_ids;
 }
 #else /*  (CONFIG_SCHED_MC || CONFIG_SCHED_SMT) */
 static inline int find_new_ilb(int call_cpu)
 {
-       return cpumask_first(nohz.cpu_mask);
+       return nr_cpu_ids;
 }
 #endif
 
+/*
+ * Kick a CPU to do the nohz balancing, if it is time for it. We pick the
+ * nohz_load_balancer CPU (if there is one) otherwise fallback to any idle
+ * CPU (if there is one).
+ */
+static void nohz_balancer_kick(int cpu)
+{
+       int ilb_cpu;
+
+       nohz.next_balance++;
+
+       ilb_cpu = get_nohz_load_balancer();
+
+       if (ilb_cpu >= nr_cpu_ids) {
+               ilb_cpu = cpumask_first(nohz.idle_cpus_mask);
+               if (ilb_cpu >= nr_cpu_ids)
+                       return;
+       }
+
+       if (!cpu_rq(ilb_cpu)->nohz_balance_kick) {
+               struct call_single_data *cp;
+
+               cpu_rq(ilb_cpu)->nohz_balance_kick = 1;
+               cp = &per_cpu(remote_sched_softirq_cb, cpu);
+               __smp_call_function_single(ilb_cpu, cp, 0);
+       }
+       return;
+}
+
 /*
  * This routine will try to nominate the ilb (idle load balancing)
  * owner among the cpus whose ticks are stopped. ilb owner will do the idle
- * load balancing on behalf of all those cpus. If all the cpus in the system
- * go into this tickless mode, then there will be no ilb owner (as there is
- * no need for one) and all the cpus will sleep till the next wakeup event
- * arrives...
- *
- * For the ilb owner, tick is not stopped. And this tick will be used
- * for idle load balancing. ilb owner will still be part of
- * nohz.cpu_mask..
+ * load balancing on behalf of all those cpus.
  *
- * While stopping the tick, this cpu will become the ilb owner if there
- * is no other owner. And will be the owner till that cpu becomes busy
- * or if all cpus in the system stop their ticks at which point
- * there is no need for ilb owner.
+ * When the ilb owner becomes busy, we will not have new ilb owner until some
+ * idle CPU wakes up and goes back to idle or some busy CPU tries to kick
+ * idle load balancing by kicking one of the idle CPUs.
  *
- * When the ilb owner becomes busy, it nominates another owner, during the
- * next busy scheduler_tick()
+ * Ticks are stopped for the ilb owner as well, with busy CPU kicking this
+ * ilb owner CPU in future (when there is a need for idle load balancing on
+ * behalf of all idle CPUs).
  */
-int select_nohz_load_balancer(int stop_tick)
+void select_nohz_load_balancer(int stop_tick)
 {
        int cpu = smp_processor_id();
 
        if (stop_tick) {
-               cpu_rq(cpu)->in_nohz_recently = 1;
-
                if (!cpu_active(cpu)) {
                        if (atomic_read(&nohz.load_balancer) != cpu)
-                               return 0;
+                               return;
 
                        /*
                         * If we are going offline and still the leader,
                         * give up!
                         */
-                       if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
+                       if (atomic_cmpxchg(&nohz.load_balancer, cpu,
+                                          nr_cpu_ids) != cpu)
                                BUG();
 
-                       return 0;
+                       return;
                }
 
-               cpumask_set_cpu(cpu, nohz.cpu_mask);
+               cpumask_set_cpu(cpu, nohz.idle_cpus_mask);
 
-               /* time for ilb owner also to sleep */
-               if (cpumask_weight(nohz.cpu_mask) == num_active_cpus()) {
-                       if (atomic_read(&nohz.load_balancer) == cpu)
-                               atomic_set(&nohz.load_balancer, -1);
-                       return 0;
-               }
+               if (atomic_read(&nohz.first_pick_cpu) == cpu)
+                       atomic_cmpxchg(&nohz.first_pick_cpu, cpu, nr_cpu_ids);
+               if (atomic_read(&nohz.second_pick_cpu) == cpu)
+                       atomic_cmpxchg(&nohz.second_pick_cpu, cpu, nr_cpu_ids);
 
-               if (atomic_read(&nohz.load_balancer) == -1) {
-                       /* make me the ilb owner */
-                       if (atomic_cmpxchg(&nohz.load_balancer, -1, cpu) == -1)
-                               return 1;
-               } else if (atomic_read(&nohz.load_balancer) == cpu) {
+               if (atomic_read(&nohz.load_balancer) >= nr_cpu_ids) {
                        int new_ilb;
 
-                       if (!(sched_smt_power_savings ||
-                                               sched_mc_power_savings))
-                               return 1;
+                       /* make me the ilb owner */
+                       if (atomic_cmpxchg(&nohz.load_balancer, nr_cpu_ids,
+                                          cpu) != nr_cpu_ids)
+                               return;
+
                        /*
                         * Check to see if there is a more power-efficient
                         * ilb.
                         */
                        new_ilb = find_new_ilb(cpu);
                        if (new_ilb < nr_cpu_ids && new_ilb != cpu) {
-                               atomic_set(&nohz.load_balancer, -1);
+                               atomic_set(&nohz.load_balancer, nr_cpu_ids);
                                resched_cpu(new_ilb);
-                               return 0;
+                               return;
                        }
-                       return 1;
+                       return;
                }
        } else {
-               if (!cpumask_test_cpu(cpu, nohz.cpu_mask))
-                       return 0;
+               if (!cpumask_test_cpu(cpu, nohz.idle_cpus_mask))
+                       return;
 
-               cpumask_clear_cpu(cpu, nohz.cpu_mask);
+               cpumask_clear_cpu(cpu, nohz.idle_cpus_mask);
 
                if (atomic_read(&nohz.load_balancer) == cpu)
-                       if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
+                       if (atomic_cmpxchg(&nohz.load_balancer, cpu,
+                                          nr_cpu_ids) != cpu)
                                BUG();
        }
-       return 0;
+       return;
 }
 #endif
 
@@ -3385,11 +3569,102 @@ out:
                rq->next_balance = next_balance;
 }
 
+#ifdef CONFIG_NO_HZ
 /*
- * run_rebalance_domains is triggered when needed from the scheduler tick.
- * In CONFIG_NO_HZ case, the idle load balance owner will do the
+ * In CONFIG_NO_HZ case, the idle balance kickee will do the
  * rebalancing for all the cpus for whom scheduler ticks are stopped.
  */
+static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle)
+{
+       struct rq *this_rq = cpu_rq(this_cpu);
+       struct rq *rq;
+       int balance_cpu;
+
+       if (idle != CPU_IDLE || !this_rq->nohz_balance_kick)
+               return;
+
+       for_each_cpu(balance_cpu, nohz.idle_cpus_mask) {
+               if (balance_cpu == this_cpu)
+                       continue;
+
+               /*
+                * If this cpu gets work to do, stop the load balancing
+                * work being done for other cpus. Next load
+                * balancing owner will pick it up.
+                */
+               if (need_resched()) {
+                       this_rq->nohz_balance_kick = 0;
+                       break;
+               }
+
+               raw_spin_lock_irq(&this_rq->lock);
+               update_rq_clock(this_rq);
+               update_cpu_load(this_rq);
+               raw_spin_unlock_irq(&this_rq->lock);
+
+               rebalance_domains(balance_cpu, CPU_IDLE);
+
+               rq = cpu_rq(balance_cpu);
+               if (time_after(this_rq->next_balance, rq->next_balance))
+                       this_rq->next_balance = rq->next_balance;
+       }
+       nohz.next_balance = this_rq->next_balance;
+       this_rq->nohz_balance_kick = 0;
+}
+
+/*
+ * Current heuristic for kicking the idle load balancer
+ * - first_pick_cpu is the one of the busy CPUs. It will kick
+ *   idle load balancer when it has more than one process active. This
+ *   eliminates the need for idle load balancing altogether when we have
+ *   only one running process in the system (common case).
+ * - If there are more than one busy CPU, idle load balancer may have
+ *   to run for active_load_balance to happen (i.e., two busy CPUs are
+ *   SMT or core siblings and can run better if they move to different
+ *   physical CPUs). So, second_pick_cpu is the second of the busy CPUs
+ *   which will kick idle load balancer as soon as it has any load.
+ */
+static inline int nohz_kick_needed(struct rq *rq, int cpu)
+{
+       unsigned long now = jiffies;
+       int ret;
+       int first_pick_cpu, second_pick_cpu;
+
+       if (time_before(now, nohz.next_balance))
+               return 0;
+
+       if (!rq->nr_running)
+               return 0;
+
+       first_pick_cpu = atomic_read(&nohz.first_pick_cpu);
+       second_pick_cpu = atomic_read(&nohz.second_pick_cpu);
+
+       if (first_pick_cpu < nr_cpu_ids && first_pick_cpu != cpu &&
+           second_pick_cpu < nr_cpu_ids && second_pick_cpu != cpu)
+               return 0;
+
+       ret = atomic_cmpxchg(&nohz.first_pick_cpu, nr_cpu_ids, cpu);
+       if (ret == nr_cpu_ids || ret == cpu) {
+               atomic_cmpxchg(&nohz.second_pick_cpu, cpu, nr_cpu_ids);
+               if (rq->nr_running > 1)
+                       return 1;
+       } else {
+               ret = atomic_cmpxchg(&nohz.second_pick_cpu, nr_cpu_ids, cpu);
+               if (ret == nr_cpu_ids || ret == cpu) {
+                       if (rq->nr_running)
+                               return 1;
+               }
+       }
+       return 0;
+}
+#else
+static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) { }
+#endif
+
+/*
+ * run_rebalance_domains is triggered when needed from the scheduler tick.
+ * Also triggered for nohz idle balancing (with nohz_balancing_kick set).
+ */
 static void run_rebalance_domains(struct softirq_action *h)
 {
        int this_cpu = smp_processor_id();
@@ -3399,37 +3674,12 @@ static void run_rebalance_domains(struct softirq_action *h)
 
        rebalance_domains(this_cpu, idle);
 
-#ifdef CONFIG_NO_HZ
        /*
-        * If this cpu is the owner for idle load balancing, then do the
+        * If this cpu has a pending nohz_balance_kick, then do the
         * balancing on behalf of the other idle cpus whose ticks are
         * stopped.
         */
-       if (this_rq->idle_at_tick &&
-           atomic_read(&nohz.load_balancer) == this_cpu) {
-               struct rq *rq;
-               int balance_cpu;
-
-               for_each_cpu(balance_cpu, nohz.cpu_mask) {
-                       if (balance_cpu == this_cpu)
-                               continue;
-
-                       /*
-                        * If this cpu gets work to do, stop the load balancing
-                        * work being done for other cpus. Next load
-                        * balancing owner will pick it up.
-                        */
-                       if (need_resched())
-                               break;
-
-                       rebalance_domains(balance_cpu, CPU_IDLE);
-
-                       rq = cpu_rq(balance_cpu);
-                       if (time_after(this_rq->next_balance, rq->next_balance))
-                               this_rq->next_balance = rq->next_balance;
-               }
-       }
-#endif
+       nohz_idle_balance(this_cpu, idle);
 }
 
 static inline int on_null_domain(int cpu)
@@ -3439,57 +3689,17 @@ static inline int on_null_domain(int cpu)
 
 /*
  * Trigger the SCHED_SOFTIRQ if it is time to do periodic load balancing.
- *
- * In case of CONFIG_NO_HZ, this is the place where we nominate a new
- * idle load balancing owner or decide to stop the periodic load balancing,
- * if the whole system is idle.
  */
 static inline void trigger_load_balance(struct rq *rq, int cpu)
 {
-#ifdef CONFIG_NO_HZ
-       /*
-        * If we were in the nohz mode recently and busy at the current
-        * scheduler tick, then check if we need to nominate new idle
-        * load balancer.
-        */
-       if (rq->in_nohz_recently && !rq->idle_at_tick) {
-               rq->in_nohz_recently = 0;
-
-               if (atomic_read(&nohz.load_balancer) == cpu) {
-                       cpumask_clear_cpu(cpu, nohz.cpu_mask);
-                       atomic_set(&nohz.load_balancer, -1);
-               }
-
-               if (atomic_read(&nohz.load_balancer) == -1) {
-                       int ilb = find_new_ilb(cpu);
-
-                       if (ilb < nr_cpu_ids)
-                               resched_cpu(ilb);
-               }
-       }
-
-       /*
-        * If this cpu is idle and doing idle load balancing for all the
-        * cpus with ticks stopped, is it time for that to stop?
-        */
-       if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) == cpu &&
-           cpumask_weight(nohz.cpu_mask) == num_online_cpus()) {
-               resched_cpu(cpu);
-               return;
-       }
-
-       /*
-        * If this cpu is idle and the idle load balancing is done by
-        * someone else, then no need raise the SCHED_SOFTIRQ
-        */
-       if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) != cpu &&
-           cpumask_test_cpu(cpu, nohz.cpu_mask))
-               return;
-#endif
        /* Don't need to rebalance while attached to NULL domain */
        if (time_after_eq(jiffies, rq->next_balance) &&
            likely(!on_null_domain(cpu)))
                raise_softirq(SCHED_SOFTIRQ);
+#ifdef CONFIG_NO_HZ
+       else if (nohz_kick_needed(rq, cpu) && likely(!on_null_domain(cpu)))
+               nohz_balancer_kick(cpu);
+#endif
 }
 
 static void rq_online_fair(struct rq *rq)
index 8afb953e31c6c1ba9a263a78929a04a0d82ff2c7..d10c80ebb67a2821038a9c59b912bf8e323d67e3 100644 (file)
@@ -1663,9 +1663,6 @@ static void watchdog(struct rq *rq, struct task_struct *p)
 {
        unsigned long soft, hard;
 
-       if (!p->signal)
-               return;
-
        /* max may change after cur was read, this will be fixed next tick */
        soft = task_rlimit(p, RLIMIT_RTTIME);
        hard = task_rlimit_max(p, RLIMIT_RTTIME);
index 32d2bd4061b02b343f566478a5fe7a07c23a3021..25c2f962f6fcb3b545719e4a8871c991bdbeb37f 100644 (file)
@@ -295,13 +295,7 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
 static inline void account_group_user_time(struct task_struct *tsk,
                                           cputime_t cputime)
 {
-       struct thread_group_cputimer *cputimer;
-
-       /* tsk == current, ensure it is safe to use ->signal */
-       if (unlikely(tsk->exit_state))
-               return;
-
-       cputimer = &tsk->signal->cputimer;
+       struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
 
        if (!cputimer->running)
                return;
@@ -325,13 +319,7 @@ static inline void account_group_user_time(struct task_struct *tsk,
 static inline void account_group_system_time(struct task_struct *tsk,
                                             cputime_t cputime)
 {
-       struct thread_group_cputimer *cputimer;
-
-       /* tsk == current, ensure it is safe to use ->signal */
-       if (unlikely(tsk->exit_state))
-               return;
-
-       cputimer = &tsk->signal->cputimer;
+       struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
 
        if (!cputimer->running)
                return;
@@ -355,16 +343,7 @@ static inline void account_group_system_time(struct task_struct *tsk,
 static inline void account_group_exec_runtime(struct task_struct *tsk,
                                              unsigned long long ns)
 {
-       struct thread_group_cputimer *cputimer;
-       struct signal_struct *sig;
-
-       sig = tsk->signal;
-       /* see __exit_signal()->task_rq_unlock_wait() */
-       barrier();
-       if (unlikely(!sig))
-               return;
-
-       cputimer = &sig->cputimer;
+       struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
 
        if (!cputimer->running)
                return;
diff --git a/kernel/slow-work-debugfs.c b/kernel/slow-work-debugfs.c
deleted file mode 100644 (file)
index e45c436..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/* Slow work debugging
- *
- * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/slow-work.h>
-#include <linux/fs.h>
-#include <linux/time.h>
-#include <linux/seq_file.h>
-#include "slow-work.h"
-
-#define ITERATOR_SHIFT         (BITS_PER_LONG - 4)
-#define ITERATOR_SELECTOR      (0xfUL << ITERATOR_SHIFT)
-#define ITERATOR_COUNTER       (~ITERATOR_SELECTOR)
-
-void slow_work_new_thread_desc(struct slow_work *work, struct seq_file *m)
-{
-       seq_puts(m, "Slow-work: New thread");
-}
-
-/*
- * Render the time mark field on a work item into a 5-char time with units plus
- * a space
- */
-static void slow_work_print_mark(struct seq_file *m, struct slow_work *work)
-{
-       struct timespec now, diff;
-
-       now = CURRENT_TIME;
-       diff = timespec_sub(now, work->mark);
-
-       if (diff.tv_sec < 0)
-               seq_puts(m, "  -ve ");
-       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000)
-               seq_printf(m, "%3luns ", diff.tv_nsec);
-       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000)
-               seq_printf(m, "%3luus ", diff.tv_nsec / 1000);
-       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000000)
-               seq_printf(m, "%3lums ", diff.tv_nsec / 1000000);
-       else if (diff.tv_sec <= 1)
-               seq_puts(m, "   1s ");
-       else if (diff.tv_sec < 60)
-               seq_printf(m, "%4lus ", diff.tv_sec);
-       else if (diff.tv_sec < 60 * 60)
-               seq_printf(m, "%4lum ", diff.tv_sec / 60);
-       else if (diff.tv_sec < 60 * 60 * 24)
-               seq_printf(m, "%4luh ", diff.tv_sec / 3600);
-       else
-               seq_puts(m, "exces ");
-}
-
-/*
- * Describe a slow work item for debugfs
- */
-static int slow_work_runqueue_show(struct seq_file *m, void *v)
-{
-       struct slow_work *work;
-       struct list_head *p = v;
-       unsigned long id;
-
-       switch ((unsigned long) v) {
-       case 1:
-               seq_puts(m, "THR PID   ITEM ADDR        FL MARK  DESC\n");
-               return 0;
-       case 2:
-               seq_puts(m, "=== ===== ================ == ===== ==========\n");
-               return 0;
-
-       case 3 ... 3 + SLOW_WORK_THREAD_LIMIT - 1:
-               id = (unsigned long) v - 3;
-
-               read_lock(&slow_work_execs_lock);
-               work = slow_work_execs[id];
-               if (work) {
-                       smp_read_barrier_depends();
-
-                       seq_printf(m, "%3lu %5d %16p %2lx ",
-                                  id, slow_work_pids[id], work, work->flags);
-                       slow_work_print_mark(m, work);
-
-                       if (work->ops->desc)
-                               work->ops->desc(work, m);
-                       seq_putc(m, '\n');
-               }
-               read_unlock(&slow_work_execs_lock);
-               return 0;
-
-       default:
-               work = list_entry(p, struct slow_work, link);
-               seq_printf(m, "%3s     - %16p %2lx ",
-                          work->flags & SLOW_WORK_VERY_SLOW ? "vsq" : "sq",
-                          work, work->flags);
-               slow_work_print_mark(m, work);
-
-               if (work->ops->desc)
-                       work->ops->desc(work, m);
-               seq_putc(m, '\n');
-               return 0;
-       }
-}
-
-/*
- * map the iterator to a work item
- */
-static void *slow_work_runqueue_index(struct seq_file *m, loff_t *_pos)
-{
-       struct list_head *p;
-       unsigned long count, id;
-
-       switch (*_pos >> ITERATOR_SHIFT) {
-       case 0x0:
-               if (*_pos == 0)
-                       *_pos = 1;
-               if (*_pos < 3)
-                       return (void *)(unsigned long) *_pos;
-               if (*_pos < 3 + SLOW_WORK_THREAD_LIMIT)
-                       for (id = *_pos - 3;
-                            id < SLOW_WORK_THREAD_LIMIT;
-                            id++, (*_pos)++)
-                               if (slow_work_execs[id])
-                                       return (void *)(unsigned long) *_pos;
-               *_pos = 0x1UL << ITERATOR_SHIFT;
-
-       case 0x1:
-               count = *_pos & ITERATOR_COUNTER;
-               list_for_each(p, &slow_work_queue) {
-                       if (count == 0)
-                               return p;
-                       count--;
-               }
-               *_pos = 0x2UL << ITERATOR_SHIFT;
-
-       case 0x2:
-               count = *_pos & ITERATOR_COUNTER;
-               list_for_each(p, &vslow_work_queue) {
-                       if (count == 0)
-                               return p;
-                       count--;
-               }
-               *_pos = 0x3UL << ITERATOR_SHIFT;
-
-       default:
-               return NULL;
-       }
-}
-
-/*
- * set up the iterator to start reading from the first line
- */
-static void *slow_work_runqueue_start(struct seq_file *m, loff_t *_pos)
-{
-       spin_lock_irq(&slow_work_queue_lock);
-       return slow_work_runqueue_index(m, _pos);
-}
-
-/*
- * move to the next line
- */
-static void *slow_work_runqueue_next(struct seq_file *m, void *v, loff_t *_pos)
-{
-       struct list_head *p = v;
-       unsigned long selector = *_pos >> ITERATOR_SHIFT;
-
-       (*_pos)++;
-       switch (selector) {
-       case 0x0:
-               return slow_work_runqueue_index(m, _pos);
-
-       case 0x1:
-               if (*_pos >> ITERATOR_SHIFT == 0x1) {
-                       p = p->next;
-                       if (p != &slow_work_queue)
-                               return p;
-               }
-               *_pos = 0x2UL << ITERATOR_SHIFT;
-               p = &vslow_work_queue;
-
-       case 0x2:
-               if (*_pos >> ITERATOR_SHIFT == 0x2) {
-                       p = p->next;
-                       if (p != &vslow_work_queue)
-                               return p;
-               }
-               *_pos = 0x3UL << ITERATOR_SHIFT;
-
-       default:
-               return NULL;
-       }
-}
-
-/*
- * clean up after reading
- */
-static void slow_work_runqueue_stop(struct seq_file *m, void *v)
-{
-       spin_unlock_irq(&slow_work_queue_lock);
-}
-
-static const struct seq_operations slow_work_runqueue_ops = {
-       .start          = slow_work_runqueue_start,
-       .stop           = slow_work_runqueue_stop,
-       .next           = slow_work_runqueue_next,
-       .show           = slow_work_runqueue_show,
-};
-
-/*
- * open "/sys/kernel/debug/slow_work/runqueue" to list queue contents
- */
-static int slow_work_runqueue_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &slow_work_runqueue_ops);
-}
-
-const struct file_operations slow_work_runqueue_fops = {
-       .owner          = THIS_MODULE,
-       .open           = slow_work_runqueue_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
diff --git a/kernel/slow-work.c b/kernel/slow-work.c
deleted file mode 100644 (file)
index 7d3f4fa..0000000
+++ /dev/null
@@ -1,1068 +0,0 @@
-/* Worker thread pool for slow items, such as filesystem lookups or mkdirs
- *
- * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- *
- * See Documentation/slow-work.txt
- */
-
-#include <linux/module.h>
-#include <linux/slow-work.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/wait.h>
-#include <linux/debugfs.h>
-#include "slow-work.h"
-
-static void slow_work_cull_timeout(unsigned long);
-static void slow_work_oom_timeout(unsigned long);
-
-#ifdef CONFIG_SYSCTL
-static int slow_work_min_threads_sysctl(struct ctl_table *, int,
-                                       void __user *, size_t *, loff_t *);
-
-static int slow_work_max_threads_sysctl(struct ctl_table *, int ,
-                                       void __user *, size_t *, loff_t *);
-#endif
-
-/*
- * The pool of threads has at least min threads in it as long as someone is
- * using the facility, and may have as many as max.
- *
- * A portion of the pool may be processing very slow operations.
- */
-static unsigned slow_work_min_threads = 2;
-static unsigned slow_work_max_threads = 4;
-static unsigned vslow_work_proportion = 50; /* % of threads that may process
-                                            * very slow work */
-
-#ifdef CONFIG_SYSCTL
-static const int slow_work_min_min_threads = 2;
-static int slow_work_max_max_threads = SLOW_WORK_THREAD_LIMIT;
-static const int slow_work_min_vslow = 1;
-static const int slow_work_max_vslow = 99;
-
-ctl_table slow_work_sysctls[] = {
-       {
-               .procname       = "min-threads",
-               .data           = &slow_work_min_threads,
-               .maxlen         = sizeof(unsigned),
-               .mode           = 0644,
-               .proc_handler   = slow_work_min_threads_sysctl,
-               .extra1         = (void *) &slow_work_min_min_threads,
-               .extra2         = &slow_work_max_threads,
-       },
-       {
-               .procname       = "max-threads",
-               .data           = &slow_work_max_threads,
-               .maxlen         = sizeof(unsigned),
-               .mode           = 0644,
-               .proc_handler   = slow_work_max_threads_sysctl,
-               .extra1         = &slow_work_min_threads,
-               .extra2         = (void *) &slow_work_max_max_threads,
-       },
-       {
-               .procname       = "vslow-percentage",
-               .data           = &vslow_work_proportion,
-               .maxlen         = sizeof(unsigned),
-               .mode           = 0644,
-               .proc_handler   = proc_dointvec_minmax,
-               .extra1         = (void *) &slow_work_min_vslow,
-               .extra2         = (void *) &slow_work_max_vslow,
-       },
-       {}
-};
-#endif
-
-/*
- * The active state of the thread pool
- */
-static atomic_t slow_work_thread_count;
-static atomic_t vslow_work_executing_count;
-
-static bool slow_work_may_not_start_new_thread;
-static bool slow_work_cull; /* cull a thread due to lack of activity */
-static DEFINE_TIMER(slow_work_cull_timer, slow_work_cull_timeout, 0, 0);
-static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0);
-static struct slow_work slow_work_new_thread; /* new thread starter */
-
-/*
- * slow work ID allocation (use slow_work_queue_lock)
- */
-static DECLARE_BITMAP(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
-
-/*
- * Unregistration tracking to prevent put_ref() from disappearing during module
- * unload
- */
-#ifdef CONFIG_MODULES
-static struct module *slow_work_thread_processing[SLOW_WORK_THREAD_LIMIT];
-static struct module *slow_work_unreg_module;
-static struct slow_work *slow_work_unreg_work_item;
-static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq);
-static DEFINE_MUTEX(slow_work_unreg_sync_lock);
-
-static void slow_work_set_thread_processing(int id, struct slow_work *work)
-{
-       if (work)
-               slow_work_thread_processing[id] = work->owner;
-}
-static void slow_work_done_thread_processing(int id, struct slow_work *work)
-{
-       struct module *module = slow_work_thread_processing[id];
-
-       slow_work_thread_processing[id] = NULL;
-       smp_mb();
-       if (slow_work_unreg_work_item == work ||
-           slow_work_unreg_module == module)
-               wake_up_all(&slow_work_unreg_wq);
-}
-static void slow_work_clear_thread_processing(int id)
-{
-       slow_work_thread_processing[id] = NULL;
-}
-#else
-static void slow_work_set_thread_processing(int id, struct slow_work *work) {}
-static void slow_work_done_thread_processing(int id, struct slow_work *work) {}
-static void slow_work_clear_thread_processing(int id) {}
-#endif
-
-/*
- * Data for tracking currently executing items for indication through /proc
- */
-#ifdef CONFIG_SLOW_WORK_DEBUG
-struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT];
-pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT];
-DEFINE_RWLOCK(slow_work_execs_lock);
-#endif
-
-/*
- * The queues of work items and the lock governing access to them.  These are
- * shared between all the CPUs.  It doesn't make sense to have per-CPU queues
- * as the number of threads bears no relation to the number of CPUs.
- *
- * There are two queues of work items: one for slow work items, and one for
- * very slow work items.
- */
-LIST_HEAD(slow_work_queue);
-LIST_HEAD(vslow_work_queue);
-DEFINE_SPINLOCK(slow_work_queue_lock);
-
-/*
- * The following are two wait queues that get pinged when a work item is placed
- * on an empty queue.  These allow work items that are hogging a thread by
- * sleeping in a way that could be deferred to yield their thread and enqueue
- * themselves.
- */
-static DECLARE_WAIT_QUEUE_HEAD(slow_work_queue_waits_for_occupation);
-static DECLARE_WAIT_QUEUE_HEAD(vslow_work_queue_waits_for_occupation);
-
-/*
- * The thread controls.  A variable used to signal to the threads that they
- * should exit when the queue is empty, a waitqueue used by the threads to wait
- * for signals, and a completion set by the last thread to exit.
- */
-static bool slow_work_threads_should_exit;
-static DECLARE_WAIT_QUEUE_HEAD(slow_work_thread_wq);
-static DECLARE_COMPLETION(slow_work_last_thread_exited);
-
-/*
- * The number of users of the thread pool and its lock.  Whilst this is zero we
- * have no threads hanging around, and when this reaches zero, we wait for all
- * active or queued work items to complete and kill all the threads we do have.
- */
-static int slow_work_user_count;
-static DEFINE_MUTEX(slow_work_user_lock);
-
-static inline int slow_work_get_ref(struct slow_work *work)
-{
-       if (work->ops->get_ref)
-               return work->ops->get_ref(work);
-
-       return 0;
-}
-
-static inline void slow_work_put_ref(struct slow_work *work)
-{
-       if (work->ops->put_ref)
-               work->ops->put_ref(work);
-}
-
-/*
- * Calculate the maximum number of active threads in the pool that are
- * permitted to process very slow work items.
- *
- * The answer is rounded up to at least 1, but may not equal or exceed the
- * maximum number of the threads in the pool.  This means we always have at
- * least one thread that can process slow work items, and we always have at
- * least one thread that won't get tied up doing so.
- */
-static unsigned slow_work_calc_vsmax(void)
-{
-       unsigned vsmax;
-
-       vsmax = atomic_read(&slow_work_thread_count) * vslow_work_proportion;
-       vsmax /= 100;
-       vsmax = max(vsmax, 1U);
-       return min(vsmax, slow_work_max_threads - 1);
-}
-
-/*
- * Attempt to execute stuff queued on a slow thread.  Return true if we managed
- * it, false if there was nothing to do.
- */
-static noinline bool slow_work_execute(int id)
-{
-       struct slow_work *work = NULL;
-       unsigned vsmax;
-       bool very_slow;
-
-       vsmax = slow_work_calc_vsmax();
-
-       /* see if we can schedule a new thread to be started if we're not
-        * keeping up with the work */
-       if (!waitqueue_active(&slow_work_thread_wq) &&
-           (!list_empty(&slow_work_queue) || !list_empty(&vslow_work_queue)) &&
-           atomic_read(&slow_work_thread_count) < slow_work_max_threads &&
-           !slow_work_may_not_start_new_thread)
-               slow_work_enqueue(&slow_work_new_thread);
-
-       /* find something to execute */
-       spin_lock_irq(&slow_work_queue_lock);
-       if (!list_empty(&vslow_work_queue) &&
-           atomic_read(&vslow_work_executing_count) < vsmax) {
-               work = list_entry(vslow_work_queue.next,
-                                 struct slow_work, link);
-               if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
-                       BUG();
-               list_del_init(&work->link);
-               atomic_inc(&vslow_work_executing_count);
-               very_slow = true;
-       } else if (!list_empty(&slow_work_queue)) {
-               work = list_entry(slow_work_queue.next,
-                                 struct slow_work, link);
-               if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
-                       BUG();
-               list_del_init(&work->link);
-               very_slow = false;
-       } else {
-               very_slow = false; /* avoid the compiler warning */
-       }
-
-       slow_work_set_thread_processing(id, work);
-       if (work) {
-               slow_work_mark_time(work);
-               slow_work_begin_exec(id, work);
-       }
-
-       spin_unlock_irq(&slow_work_queue_lock);
-
-       if (!work)
-               return false;
-
-       if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags))
-               BUG();
-
-       /* don't execute if the work is in the process of being cancelled */
-       if (!test_bit(SLOW_WORK_CANCELLING, &work->flags))
-               work->ops->execute(work);
-
-       if (very_slow)
-               atomic_dec(&vslow_work_executing_count);
-       clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags);
-
-       /* wake up anyone waiting for this work to be complete */
-       wake_up_bit(&work->flags, SLOW_WORK_EXECUTING);
-
-       slow_work_end_exec(id, work);
-
-       /* if someone tried to enqueue the item whilst we were executing it,
-        * then it'll be left unenqueued to avoid multiple threads trying to
-        * execute it simultaneously
-        *
-        * there is, however, a race between us testing the pending flag and
-        * getting the spinlock, and between the enqueuer setting the pending
-        * flag and getting the spinlock, so we use a deferral bit to tell us
-        * if the enqueuer got there first
-        */
-       if (test_bit(SLOW_WORK_PENDING, &work->flags)) {
-               spin_lock_irq(&slow_work_queue_lock);
-
-               if (!test_bit(SLOW_WORK_EXECUTING, &work->flags) &&
-                   test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags))
-                       goto auto_requeue;
-
-               spin_unlock_irq(&slow_work_queue_lock);
-       }
-
-       /* sort out the race between module unloading and put_ref() */
-       slow_work_put_ref(work);
-       slow_work_done_thread_processing(id, work);
-
-       return true;
-
-auto_requeue:
-       /* we must complete the enqueue operation
-        * - we transfer our ref on the item back to the appropriate queue
-        * - don't wake another thread up as we're awake already
-        */
-       slow_work_mark_time(work);
-       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
-               list_add_tail(&work->link, &vslow_work_queue);
-       else
-               list_add_tail(&work->link, &slow_work_queue);
-       spin_unlock_irq(&slow_work_queue_lock);
-       slow_work_clear_thread_processing(id);
-       return true;
-}
-
-/**
- * slow_work_sleep_till_thread_needed - Sleep till thread needed by other work
- * work: The work item under execution that wants to sleep
- * _timeout: Scheduler sleep timeout
- *
- * Allow a requeueable work item to sleep on a slow-work processor thread until
- * that thread is needed to do some other work or the sleep is interrupted by
- * some other event.
- *
- * The caller must set up a wake up event before calling this and must have set
- * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own
- * condition before calling this function as no test is made here.
- *
- * False is returned if there is nothing on the queue; true is returned if the
- * work item should be requeued
- */
-bool slow_work_sleep_till_thread_needed(struct slow_work *work,
-                                       signed long *_timeout)
-{
-       wait_queue_head_t *wfo_wq;
-       struct list_head *queue;
-
-       DEFINE_WAIT(wait);
-
-       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
-               wfo_wq = &vslow_work_queue_waits_for_occupation;
-               queue = &vslow_work_queue;
-       } else {
-               wfo_wq = &slow_work_queue_waits_for_occupation;
-               queue = &slow_work_queue;
-       }
-
-       if (!list_empty(queue))
-               return true;
-
-       add_wait_queue_exclusive(wfo_wq, &wait);
-       if (list_empty(queue))
-               *_timeout = schedule_timeout(*_timeout);
-       finish_wait(wfo_wq, &wait);
-
-       return !list_empty(queue);
-}
-EXPORT_SYMBOL(slow_work_sleep_till_thread_needed);
-
-/**
- * slow_work_enqueue - Schedule a slow work item for processing
- * @work: The work item to queue
- *
- * Schedule a slow work item for processing.  If the item is already undergoing
- * execution, this guarantees not to re-enter the execution routine until the
- * first execution finishes.
- *
- * The item is pinned by this function as it retains a reference to it, managed
- * through the item operations.  The item is unpinned once it has been
- * executed.
- *
- * An item may hog the thread that is running it for a relatively large amount
- * of time, sufficient, for example, to perform several lookup, mkdir, create
- * and setxattr operations.  It may sleep on I/O and may sleep to obtain locks.
- *
- * Conversely, if a number of items are awaiting processing, it may take some
- * time before any given item is given attention.  The number of threads in the
- * pool may be increased to deal with demand, but only up to a limit.
- *
- * If SLOW_WORK_VERY_SLOW is set on the work item, then it will be placed in
- * the very slow queue, from which only a portion of the threads will be
- * allowed to pick items to execute.  This ensures that very slow items won't
- * overly block ones that are just ordinarily slow.
- *
- * Returns 0 if successful, -EAGAIN if not (or -ECANCELED if cancelled work is
- * attempted queued)
- */
-int slow_work_enqueue(struct slow_work *work)
-{
-       wait_queue_head_t *wfo_wq;
-       struct list_head *queue;
-       unsigned long flags;
-       int ret;
-
-       if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
-               return -ECANCELED;
-
-       BUG_ON(slow_work_user_count <= 0);
-       BUG_ON(!work);
-       BUG_ON(!work->ops);
-
-       /* when honouring an enqueue request, we only promise that we will run
-        * the work function in the future; we do not promise to run it once
-        * per enqueue request
-        *
-        * we use the PENDING bit to merge together repeat requests without
-        * having to disable IRQs and take the spinlock, whilst still
-        * maintaining our promise
-        */
-       if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
-               if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
-                       wfo_wq = &vslow_work_queue_waits_for_occupation;
-                       queue = &vslow_work_queue;
-               } else {
-                       wfo_wq = &slow_work_queue_waits_for_occupation;
-                       queue = &slow_work_queue;
-               }
-
-               spin_lock_irqsave(&slow_work_queue_lock, flags);
-
-               if (unlikely(test_bit(SLOW_WORK_CANCELLING, &work->flags)))
-                       goto cancelled;
-
-               /* we promise that we will not attempt to execute the work
-                * function in more than one thread simultaneously
-                *
-                * this, however, leaves us with a problem if we're asked to
-                * enqueue the work whilst someone is executing the work
-                * function as simply queueing the work immediately means that
-                * another thread may try executing it whilst it is already
-                * under execution
-                *
-                * to deal with this, we set the ENQ_DEFERRED bit instead of
-                * enqueueing, and the thread currently executing the work
-                * function will enqueue the work item when the work function
-                * returns and it has cleared the EXECUTING bit
-                */
-               if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
-                       set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
-               } else {
-                       ret = slow_work_get_ref(work);
-                       if (ret < 0)
-                               goto failed;
-                       slow_work_mark_time(work);
-                       list_add_tail(&work->link, queue);
-                       wake_up(&slow_work_thread_wq);
-
-                       /* if someone who could be requeued is sleeping on a
-                        * thread, then ask them to yield their thread */
-                       if (work->link.prev == queue)
-                               wake_up(wfo_wq);
-               }
-
-               spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       }
-       return 0;
-
-cancelled:
-       ret = -ECANCELED;
-failed:
-       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       return ret;
-}
-EXPORT_SYMBOL(slow_work_enqueue);
-
-static int slow_work_wait(void *word)
-{
-       schedule();
-       return 0;
-}
-
-/**
- * slow_work_cancel - Cancel a slow work item
- * @work: The work item to cancel
- *
- * This function will cancel a previously enqueued work item. If we cannot
- * cancel the work item, it is guarenteed to have run when this function
- * returns.
- */
-void slow_work_cancel(struct slow_work *work)
-{
-       bool wait = true, put = false;
-
-       set_bit(SLOW_WORK_CANCELLING, &work->flags);
-       smp_mb();
-
-       /* if the work item is a delayed work item with an active timer, we
-        * need to wait for the timer to finish _before_ getting the spinlock,
-        * lest we deadlock against the timer routine
-        *
-        * the timer routine will leave DELAYED set if it notices the
-        * CANCELLING flag in time
-        */
-       if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
-               struct delayed_slow_work *dwork =
-                       container_of(work, struct delayed_slow_work, work);
-               del_timer_sync(&dwork->timer);
-       }
-
-       spin_lock_irq(&slow_work_queue_lock);
-
-       if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
-               /* the timer routine aborted or never happened, so we are left
-                * holding the timer's reference on the item and should just
-                * drop the pending flag and wait for any ongoing execution to
-                * finish */
-               struct delayed_slow_work *dwork =
-                       container_of(work, struct delayed_slow_work, work);
-
-               BUG_ON(timer_pending(&dwork->timer));
-               BUG_ON(!list_empty(&work->link));
-
-               clear_bit(SLOW_WORK_DELAYED, &work->flags);
-               put = true;
-               clear_bit(SLOW_WORK_PENDING, &work->flags);
-
-       } else if (test_bit(SLOW_WORK_PENDING, &work->flags) &&
-                  !list_empty(&work->link)) {
-               /* the link in the pending queue holds a reference on the item
-                * that we will need to release */
-               list_del_init(&work->link);
-               wait = false;
-               put = true;
-               clear_bit(SLOW_WORK_PENDING, &work->flags);
-
-       } else if (test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags)) {
-               /* the executor is holding our only reference on the item, so
-                * we merely need to wait for it to finish executing */
-               clear_bit(SLOW_WORK_PENDING, &work->flags);
-       }
-
-       spin_unlock_irq(&slow_work_queue_lock);
-
-       /* the EXECUTING flag is set by the executor whilst the spinlock is set
-        * and before the item is dequeued - so assuming the above doesn't
-        * actually dequeue it, simply waiting for the EXECUTING flag to be
-        * released here should be sufficient */
-       if (wait)
-               wait_on_bit(&work->flags, SLOW_WORK_EXECUTING, slow_work_wait,
-                           TASK_UNINTERRUPTIBLE);
-
-       clear_bit(SLOW_WORK_CANCELLING, &work->flags);
-       if (put)
-               slow_work_put_ref(work);
-}
-EXPORT_SYMBOL(slow_work_cancel);
-
-/*
- * Handle expiry of the delay timer, indicating that a delayed slow work item
- * should now be queued if not cancelled
- */
-static void delayed_slow_work_timer(unsigned long data)
-{
-       wait_queue_head_t *wfo_wq;
-       struct list_head *queue;
-       struct slow_work *work = (struct slow_work *) data;
-       unsigned long flags;
-       bool queued = false, put = false, first = false;
-
-       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
-               wfo_wq = &vslow_work_queue_waits_for_occupation;
-               queue = &vslow_work_queue;
-       } else {
-               wfo_wq = &slow_work_queue_waits_for_occupation;
-               queue = &slow_work_queue;
-       }
-
-       spin_lock_irqsave(&slow_work_queue_lock, flags);
-       if (likely(!test_bit(SLOW_WORK_CANCELLING, &work->flags))) {
-               clear_bit(SLOW_WORK_DELAYED, &work->flags);
-
-               if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
-                       /* we discard the reference the timer was holding in
-                        * favour of the one the executor holds */
-                       set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
-                       put = true;
-               } else {
-                       slow_work_mark_time(work);
-                       list_add_tail(&work->link, queue);
-                       queued = true;
-                       if (work->link.prev == queue)
-                               first = true;
-               }
-       }
-
-       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       if (put)
-               slow_work_put_ref(work);
-       if (first)
-               wake_up(wfo_wq);
-       if (queued)
-               wake_up(&slow_work_thread_wq);
-}
-
-/**
- * delayed_slow_work_enqueue - Schedule a delayed slow work item for processing
- * @dwork: The delayed work item to queue
- * @delay: When to start executing the work, in jiffies from now
- *
- * This is similar to slow_work_enqueue(), but it adds a delay before the work
- * is actually queued for processing.
- *
- * The item can have delayed processing requested on it whilst it is being
- * executed.  The delay will begin immediately, and if it expires before the
- * item finishes executing, the item will be placed back on the queue when it
- * has done executing.
- */
-int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
-                             unsigned long delay)
-{
-       struct slow_work *work = &dwork->work;
-       unsigned long flags;
-       int ret;
-
-       if (delay == 0)
-               return slow_work_enqueue(&dwork->work);
-
-       BUG_ON(slow_work_user_count <= 0);
-       BUG_ON(!work);
-       BUG_ON(!work->ops);
-
-       if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
-               return -ECANCELED;
-
-       if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
-               spin_lock_irqsave(&slow_work_queue_lock, flags);
-
-               if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
-                       goto cancelled;
-
-               /* the timer holds a reference whilst it is pending */
-               ret = slow_work_get_ref(work);
-               if (ret < 0)
-                       goto cant_get_ref;
-
-               if (test_and_set_bit(SLOW_WORK_DELAYED, &work->flags))
-                       BUG();
-               dwork->timer.expires = jiffies + delay;
-               dwork->timer.data = (unsigned long) work;
-               dwork->timer.function = delayed_slow_work_timer;
-               add_timer(&dwork->timer);
-
-               spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       }
-
-       return 0;
-
-cancelled:
-       ret = -ECANCELED;
-cant_get_ref:
-       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       return ret;
-}
-EXPORT_SYMBOL(delayed_slow_work_enqueue);
-
-/*
- * Schedule a cull of the thread pool at some time in the near future
- */
-static void slow_work_schedule_cull(void)
-{
-       mod_timer(&slow_work_cull_timer,
-                 round_jiffies(jiffies + SLOW_WORK_CULL_TIMEOUT));
-}
-
-/*
- * Worker thread culling algorithm
- */
-static bool slow_work_cull_thread(void)
-{
-       unsigned long flags;
-       bool do_cull = false;
-
-       spin_lock_irqsave(&slow_work_queue_lock, flags);
-
-       if (slow_work_cull) {
-               slow_work_cull = false;
-
-               if (list_empty(&slow_work_queue) &&
-                   list_empty(&vslow_work_queue) &&
-                   atomic_read(&slow_work_thread_count) >
-                   slow_work_min_threads) {
-                       slow_work_schedule_cull();
-                       do_cull = true;
-               }
-       }
-
-       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       return do_cull;
-}
-
-/*
- * Determine if there is slow work available for dispatch
- */
-static inline bool slow_work_available(int vsmax)
-{
-       return !list_empty(&slow_work_queue) ||
-               (!list_empty(&vslow_work_queue) &&
-                atomic_read(&vslow_work_executing_count) < vsmax);
-}
-
-/*
- * Worker thread dispatcher
- */
-static int slow_work_thread(void *_data)
-{
-       int vsmax, id;
-
-       DEFINE_WAIT(wait);
-
-       set_freezable();
-       set_user_nice(current, -5);
-
-       /* allocate ourselves an ID */
-       spin_lock_irq(&slow_work_queue_lock);
-       id = find_first_zero_bit(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
-       BUG_ON(id < 0 || id >= SLOW_WORK_THREAD_LIMIT);
-       __set_bit(id, slow_work_ids);
-       slow_work_set_thread_pid(id, current->pid);
-       spin_unlock_irq(&slow_work_queue_lock);
-
-       sprintf(current->comm, "kslowd%03u", id);
-
-       for (;;) {
-               vsmax = vslow_work_proportion;
-               vsmax *= atomic_read(&slow_work_thread_count);
-               vsmax /= 100;
-
-               prepare_to_wait_exclusive(&slow_work_thread_wq, &wait,
-                                         TASK_INTERRUPTIBLE);
-               if (!freezing(current) &&
-                   !slow_work_threads_should_exit &&
-                   !slow_work_available(vsmax) &&
-                   !slow_work_cull)
-                       schedule();
-               finish_wait(&slow_work_thread_wq, &wait);
-
-               try_to_freeze();
-
-               vsmax = vslow_work_proportion;
-               vsmax *= atomic_read(&slow_work_thread_count);
-               vsmax /= 100;
-
-               if (slow_work_available(vsmax) && slow_work_execute(id)) {
-                       cond_resched();
-                       if (list_empty(&slow_work_queue) &&
-                           list_empty(&vslow_work_queue) &&
-                           atomic_read(&slow_work_thread_count) >
-                           slow_work_min_threads)
-                               slow_work_schedule_cull();
-                       continue;
-               }
-
-               if (slow_work_threads_should_exit)
-                       break;
-
-               if (slow_work_cull && slow_work_cull_thread())
-                       break;
-       }
-
-       spin_lock_irq(&slow_work_queue_lock);
-       slow_work_set_thread_pid(id, 0);
-       __clear_bit(id, slow_work_ids);
-       spin_unlock_irq(&slow_work_queue_lock);
-
-       if (atomic_dec_and_test(&slow_work_thread_count))
-               complete_and_exit(&slow_work_last_thread_exited, 0);
-       return 0;
-}
-
-/*
- * Handle thread cull timer expiration
- */
-static void slow_work_cull_timeout(unsigned long data)
-{
-       slow_work_cull = true;
-       wake_up(&slow_work_thread_wq);
-}
-
-/*
- * Start a new slow work thread
- */
-static void slow_work_new_thread_execute(struct slow_work *work)
-{
-       struct task_struct *p;
-
-       if (slow_work_threads_should_exit)
-               return;
-
-       if (atomic_read(&slow_work_thread_count) >= slow_work_max_threads)
-               return;
-
-       if (!mutex_trylock(&slow_work_user_lock))
-               return;
-
-       slow_work_may_not_start_new_thread = true;
-       atomic_inc(&slow_work_thread_count);
-       p = kthread_run(slow_work_thread, NULL, "kslowd");
-       if (IS_ERR(p)) {
-               printk(KERN_DEBUG "Slow work thread pool: OOM\n");
-               if (atomic_dec_and_test(&slow_work_thread_count))
-                       BUG(); /* we're running on a slow work thread... */
-               mod_timer(&slow_work_oom_timer,
-                         round_jiffies(jiffies + SLOW_WORK_OOM_TIMEOUT));
-       } else {
-               /* ratelimit the starting of new threads */
-               mod_timer(&slow_work_oom_timer, jiffies + 1);
-       }
-
-       mutex_unlock(&slow_work_user_lock);
-}
-
-static const struct slow_work_ops slow_work_new_thread_ops = {
-       .owner          = THIS_MODULE,
-       .execute        = slow_work_new_thread_execute,
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       .desc           = slow_work_new_thread_desc,
-#endif
-};
-
-/*
- * post-OOM new thread start suppression expiration
- */
-static void slow_work_oom_timeout(unsigned long data)
-{
-       slow_work_may_not_start_new_thread = false;
-}
-
-#ifdef CONFIG_SYSCTL
-/*
- * Handle adjustment of the minimum number of threads
- */
-static int slow_work_min_threads_sysctl(struct ctl_table *table, int write,
-                                       void __user *buffer,
-                                       size_t *lenp, loff_t *ppos)
-{
-       int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
-       int n;
-
-       if (ret == 0) {
-               mutex_lock(&slow_work_user_lock);
-               if (slow_work_user_count > 0) {
-                       /* see if we need to start or stop threads */
-                       n = atomic_read(&slow_work_thread_count) -
-                               slow_work_min_threads;
-
-                       if (n < 0 && !slow_work_may_not_start_new_thread)
-                               slow_work_enqueue(&slow_work_new_thread);
-                       else if (n > 0)
-                               slow_work_schedule_cull();
-               }
-               mutex_unlock(&slow_work_user_lock);
-       }
-
-       return ret;
-}
-
-/*
- * Handle adjustment of the maximum number of threads
- */
-static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
-                                       void __user *buffer,
-                                       size_t *lenp, loff_t *ppos)
-{
-       int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
-       int n;
-
-       if (ret == 0) {
-               mutex_lock(&slow_work_user_lock);
-               if (slow_work_user_count > 0) {
-                       /* see if we need to stop threads */
-                       n = slow_work_max_threads -
-                               atomic_read(&slow_work_thread_count);
-
-                       if (n < 0)
-                               slow_work_schedule_cull();
-               }
-               mutex_unlock(&slow_work_user_lock);
-       }
-
-       return ret;
-}
-#endif /* CONFIG_SYSCTL */
-
-/**
- * slow_work_register_user - Register a user of the facility
- * @module: The module about to make use of the facility
- *
- * Register a user of the facility, starting up the initial threads if there
- * aren't any other users at this point.  This will return 0 if successful, or
- * an error if not.
- */
-int slow_work_register_user(struct module *module)
-{
-       struct task_struct *p;
-       int loop;
-
-       mutex_lock(&slow_work_user_lock);
-
-       if (slow_work_user_count == 0) {
-               printk(KERN_NOTICE "Slow work thread pool: Starting up\n");
-               init_completion(&slow_work_last_thread_exited);
-
-               slow_work_threads_should_exit = false;
-               slow_work_init(&slow_work_new_thread,
-                              &slow_work_new_thread_ops);
-               slow_work_may_not_start_new_thread = false;
-               slow_work_cull = false;
-
-               /* start the minimum number of threads */
-               for (loop = 0; loop < slow_work_min_threads; loop++) {
-                       atomic_inc(&slow_work_thread_count);
-                       p = kthread_run(slow_work_thread, NULL, "kslowd");
-                       if (IS_ERR(p))
-                               goto error;
-               }
-               printk(KERN_NOTICE "Slow work thread pool: Ready\n");
-       }
-
-       slow_work_user_count++;
-       mutex_unlock(&slow_work_user_lock);
-       return 0;
-
-error:
-       if (atomic_dec_and_test(&slow_work_thread_count))
-               complete(&slow_work_last_thread_exited);
-       if (loop > 0) {
-               printk(KERN_ERR "Slow work thread pool:"
-                      " Aborting startup on ENOMEM\n");
-               slow_work_threads_should_exit = true;
-               wake_up_all(&slow_work_thread_wq);
-               wait_for_completion(&slow_work_last_thread_exited);
-               printk(KERN_ERR "Slow work thread pool: Aborted\n");
-       }
-       mutex_unlock(&slow_work_user_lock);
-       return PTR_ERR(p);
-}
-EXPORT_SYMBOL(slow_work_register_user);
-
-/*
- * wait for all outstanding items from the calling module to complete
- * - note that more items may be queued whilst we're waiting
- */
-static void slow_work_wait_for_items(struct module *module)
-{
-#ifdef CONFIG_MODULES
-       DECLARE_WAITQUEUE(myself, current);
-       struct slow_work *work;
-       int loop;
-
-       mutex_lock(&slow_work_unreg_sync_lock);
-       add_wait_queue(&slow_work_unreg_wq, &myself);
-
-       for (;;) {
-               spin_lock_irq(&slow_work_queue_lock);
-
-               /* first of all, we wait for the last queued item in each list
-                * to be processed */
-               list_for_each_entry_reverse(work, &vslow_work_queue, link) {
-                       if (work->owner == module) {
-                               set_current_state(TASK_UNINTERRUPTIBLE);
-                               slow_work_unreg_work_item = work;
-                               goto do_wait;
-                       }
-               }
-               list_for_each_entry_reverse(work, &slow_work_queue, link) {
-                       if (work->owner == module) {
-                               set_current_state(TASK_UNINTERRUPTIBLE);
-                               slow_work_unreg_work_item = work;
-                               goto do_wait;
-                       }
-               }
-
-               /* then we wait for the items being processed to finish */
-               slow_work_unreg_module = module;
-               smp_mb();
-               for (loop = 0; loop < SLOW_WORK_THREAD_LIMIT; loop++) {
-                       if (slow_work_thread_processing[loop] == module)
-                               goto do_wait;
-               }
-               spin_unlock_irq(&slow_work_queue_lock);
-               break; /* okay, we're done */
-
-       do_wait:
-               spin_unlock_irq(&slow_work_queue_lock);
-               schedule();
-               slow_work_unreg_work_item = NULL;
-               slow_work_unreg_module = NULL;
-       }
-
-       remove_wait_queue(&slow_work_unreg_wq, &myself);
-       mutex_unlock(&slow_work_unreg_sync_lock);
-#endif /* CONFIG_MODULES */
-}
-
-/**
- * slow_work_unregister_user - Unregister a user of the facility
- * @module: The module whose items should be cleared
- *
- * Unregister a user of the facility, killing all the threads if this was the
- * last one.
- *
- * This waits for all the work items belonging to the nominated module to go
- * away before proceeding.
- */
-void slow_work_unregister_user(struct module *module)
-{
-       /* first of all, wait for all outstanding items from the calling module
-        * to complete */
-       if (module)
-               slow_work_wait_for_items(module);
-
-       /* then we can actually go about shutting down the facility if need
-        * be */
-       mutex_lock(&slow_work_user_lock);
-
-       BUG_ON(slow_work_user_count <= 0);
-
-       slow_work_user_count--;
-       if (slow_work_user_count == 0) {
-               printk(KERN_NOTICE "Slow work thread pool: Shutting down\n");
-               slow_work_threads_should_exit = true;
-               del_timer_sync(&slow_work_cull_timer);
-               del_timer_sync(&slow_work_oom_timer);
-               wake_up_all(&slow_work_thread_wq);
-               wait_for_completion(&slow_work_last_thread_exited);
-               printk(KERN_NOTICE "Slow work thread pool:"
-                      " Shut down complete\n");
-       }
-
-       mutex_unlock(&slow_work_user_lock);
-}
-EXPORT_SYMBOL(slow_work_unregister_user);
-
-/*
- * Initialise the slow work facility
- */
-static int __init init_slow_work(void)
-{
-       unsigned nr_cpus = num_possible_cpus();
-
-       if (slow_work_max_threads < nr_cpus)
-               slow_work_max_threads = nr_cpus;
-#ifdef CONFIG_SYSCTL
-       if (slow_work_max_max_threads < nr_cpus * 2)
-               slow_work_max_max_threads = nr_cpus * 2;
-#endif
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       {
-               struct dentry *dbdir;
-
-               dbdir = debugfs_create_dir("slow_work", NULL);
-               if (dbdir && !IS_ERR(dbdir))
-                       debugfs_create_file("runqueue", S_IFREG | 0400, dbdir,
-                                           NULL, &slow_work_runqueue_fops);
-       }
-#endif
-       return 0;
-}
-
-subsys_initcall(init_slow_work);
diff --git a/kernel/slow-work.h b/kernel/slow-work.h
deleted file mode 100644 (file)
index a29ebd1..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Slow work private definitions
- *
- * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#define SLOW_WORK_CULL_TIMEOUT (5 * HZ)        /* cull threads 5s after running out of
-                                        * things to do */
-#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
-                                        * OOM */
-
-#define SLOW_WORK_THREAD_LIMIT 255     /* abs maximum number of slow-work threads */
-
-/*
- * slow-work.c
- */
-#ifdef CONFIG_SLOW_WORK_DEBUG
-extern struct slow_work *slow_work_execs[];
-extern pid_t slow_work_pids[];
-extern rwlock_t slow_work_execs_lock;
-#endif
-
-extern struct list_head slow_work_queue;
-extern struct list_head vslow_work_queue;
-extern spinlock_t slow_work_queue_lock;
-
-/*
- * slow-work-debugfs.c
- */
-#ifdef CONFIG_SLOW_WORK_DEBUG
-extern const struct file_operations slow_work_runqueue_fops;
-
-extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *);
-#endif
-
-/*
- * Helper functions
- */
-static inline void slow_work_set_thread_pid(int id, pid_t pid)
-{
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       slow_work_pids[id] = pid;
-#endif
-}
-
-static inline void slow_work_mark_time(struct slow_work *work)
-{
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       work->mark = CURRENT_TIME;
-#endif
-}
-
-static inline void slow_work_begin_exec(int id, struct slow_work *work)
-{
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       slow_work_execs[id] = work;
-#endif
-}
-
-static inline void slow_work_end_exec(int id, struct slow_work *work)
-{
-#ifdef CONFIG_SLOW_WORK_DEBUG
-       write_lock(&slow_work_execs_lock);
-       slow_work_execs[id] = NULL;
-       write_unlock(&slow_work_execs_lock);
-#endif
-}
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
deleted file mode 100644 (file)
index 4b493f6..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Detect Soft Lockups
- *
- * started by Ingo Molnar, Copyright (C) 2005, 2006 Red Hat, Inc.
- *
- * this code detects soft lockups: incidents in where on a CPU
- * the kernel does not reschedule for 10 seconds or more.
- */
-#include <linux/mm.h>
-#include <linux/cpu.h>
-#include <linux/nmi.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/freezer.h>
-#include <linux/kthread.h>
-#include <linux/lockdep.h>
-#include <linux/notifier.h>
-#include <linux/module.h>
-#include <linux/sysctl.h>
-
-#include <asm/irq_regs.h>
-
-static DEFINE_SPINLOCK(print_lock);
-
-static DEFINE_PER_CPU(unsigned long, softlockup_touch_ts); /* touch timestamp */
-static DEFINE_PER_CPU(unsigned long, softlockup_print_ts); /* print timestamp */
-static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog);
-static DEFINE_PER_CPU(bool, softlock_touch_sync);
-
-static int __read_mostly did_panic;
-int __read_mostly softlockup_thresh = 60;
-
-/*
- * Should we panic (and reboot, if panic_timeout= is set) when a
- * soft-lockup occurs:
- */
-unsigned int __read_mostly softlockup_panic =
-                               CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
-
-static int __init softlockup_panic_setup(char *str)
-{
-       softlockup_panic = simple_strtoul(str, NULL, 0);
-
-       return 1;
-}
-__setup("softlockup_panic=", softlockup_panic_setup);
-
-static int
-softlock_panic(struct notifier_block *this, unsigned long event, void *ptr)
-{
-       did_panic = 1;
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
-       .notifier_call = softlock_panic,
-};
-
-/*
- * Returns seconds, approximately.  We don't need nanosecond
- * resolution, and we don't need to waste time with a big divide when
- * 2^30ns == 1.074s.
- */
-static unsigned long get_timestamp(int this_cpu)
-{
-       return cpu_clock(this_cpu) >> 30LL;  /* 2^30 ~= 10^9 */
-}
-
-static void __touch_softlockup_watchdog(void)
-{
-       int this_cpu = raw_smp_processor_id();
-
-       __raw_get_cpu_var(softlockup_touch_ts) = get_timestamp(this_cpu);
-}
-
-void touch_softlockup_watchdog(void)
-{
-       __raw_get_cpu_var(softlockup_touch_ts) = 0;
-}
-EXPORT_SYMBOL(touch_softlockup_watchdog);
-
-void touch_softlockup_watchdog_sync(void)
-{
-       __raw_get_cpu_var(softlock_touch_sync) = true;
-       __raw_get_cpu_var(softlockup_touch_ts) = 0;
-}
-
-void touch_all_softlockup_watchdogs(void)
-{
-       int cpu;
-
-       /* Cause each CPU to re-update its timestamp rather than complain */
-       for_each_online_cpu(cpu)
-               per_cpu(softlockup_touch_ts, cpu) = 0;
-}
-EXPORT_SYMBOL(touch_all_softlockup_watchdogs);
-
-int proc_dosoftlockup_thresh(struct ctl_table *table, int write,
-                            void __user *buffer,
-                            size_t *lenp, loff_t *ppos)
-{
-       touch_all_softlockup_watchdogs();
-       return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
-}
-
-/*
- * This callback runs from the timer interrupt, and checks
- * whether the watchdog thread has hung or not:
- */
-void softlockup_tick(void)
-{
-       int this_cpu = smp_processor_id();
-       unsigned long touch_ts = per_cpu(softlockup_touch_ts, this_cpu);
-       unsigned long print_ts;
-       struct pt_regs *regs = get_irq_regs();
-       unsigned long now;
-
-       /* Is detection switched off? */
-       if (!per_cpu(softlockup_watchdog, this_cpu) || softlockup_thresh <= 0) {
-               /* Be sure we don't false trigger if switched back on */
-               if (touch_ts)
-                       per_cpu(softlockup_touch_ts, this_cpu) = 0;
-               return;
-       }
-
-       if (touch_ts == 0) {
-               if (unlikely(per_cpu(softlock_touch_sync, this_cpu))) {
-                       /*
-                        * If the time stamp was touched atomically
-                        * make sure the scheduler tick is up to date.
-                        */
-                       per_cpu(softlock_touch_sync, this_cpu) = false;
-                       sched_clock_tick();
-               }
-               __touch_softlockup_watchdog();
-               return;
-       }
-
-       print_ts = per_cpu(softlockup_print_ts, this_cpu);
-
-       /* report at most once a second */
-       if (print_ts == touch_ts || did_panic)
-               return;
-
-       /* do not print during early bootup: */
-       if (unlikely(system_state != SYSTEM_RUNNING)) {
-               __touch_softlockup_watchdog();
-               return;
-       }
-
-       now = get_timestamp(this_cpu);
-
-       /*
-        * Wake up the high-prio watchdog task twice per
-        * threshold timespan.
-        */
-       if (time_after(now - softlockup_thresh/2, touch_ts))
-               wake_up_process(per_cpu(softlockup_watchdog, this_cpu));
-
-       /* Warn about unreasonable delays: */
-       if (time_before_eq(now - softlockup_thresh, touch_ts))
-               return;
-
-       per_cpu(softlockup_print_ts, this_cpu) = touch_ts;
-
-       spin_lock(&print_lock);
-       printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n",
-                       this_cpu, now - touch_ts,
-                       current->comm, task_pid_nr(current));
-       print_modules();
-       print_irqtrace_events(current);
-       if (regs)
-               show_regs(regs);
-       else
-               dump_stack();
-       spin_unlock(&print_lock);
-
-       if (softlockup_panic)
-               panic("softlockup: hung tasks");
-}
-
-/*
- * The watchdog thread - runs every second and touches the timestamp.
- */
-static int watchdog(void *__bind_cpu)
-{
-       struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
-
-       sched_setscheduler(current, SCHED_FIFO, &param);
-
-       /* initialize timestamp */
-       __touch_softlockup_watchdog();
-
-       set_current_state(TASK_INTERRUPTIBLE);
-       /*
-        * Run briefly once per second to reset the softlockup timestamp.
-        * If this gets delayed for more than 60 seconds then the
-        * debug-printout triggers in softlockup_tick().
-        */
-       while (!kthread_should_stop()) {
-               __touch_softlockup_watchdog();
-               schedule();
-
-               if (kthread_should_stop())
-                       break;
-
-               set_current_state(TASK_INTERRUPTIBLE);
-       }
-       __set_current_state(TASK_RUNNING);
-
-       return 0;
-}
-
-/*
- * Create/destroy watchdog threads as CPUs come and go:
- */
-static int __cpuinit
-cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
-{
-       int hotcpu = (unsigned long)hcpu;
-       struct task_struct *p;
-
-       switch (action) {
-       case CPU_UP_PREPARE:
-       case CPU_UP_PREPARE_FROZEN:
-               BUG_ON(per_cpu(softlockup_watchdog, hotcpu));
-               p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu);
-               if (IS_ERR(p)) {
-                       printk(KERN_ERR "watchdog for %i failed\n", hotcpu);
-                       return NOTIFY_BAD;
-               }
-               per_cpu(softlockup_touch_ts, hotcpu) = 0;
-               per_cpu(softlockup_watchdog, hotcpu) = p;
-               kthread_bind(p, hotcpu);
-               break;
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               wake_up_process(per_cpu(softlockup_watchdog, hotcpu));
-               break;
-#ifdef CONFIG_HOTPLUG_CPU
-       case CPU_UP_CANCELED:
-       case CPU_UP_CANCELED_FROZEN:
-               if (!per_cpu(softlockup_watchdog, hotcpu))
-                       break;
-               /* Unbind so it can run.  Fall thru. */
-               kthread_bind(per_cpu(softlockup_watchdog, hotcpu),
-                            cpumask_any(cpu_online_mask));
-       case CPU_DEAD:
-       case CPU_DEAD_FROZEN:
-               p = per_cpu(softlockup_watchdog, hotcpu);
-               per_cpu(softlockup_watchdog, hotcpu) = NULL;
-               kthread_stop(p);
-               break;
-#endif /* CONFIG_HOTPLUG_CPU */
-       }
-       return NOTIFY_OK;
-}
-
-static struct notifier_block __cpuinitdata cpu_nfb = {
-       .notifier_call = cpu_callback
-};
-
-static int __initdata nosoftlockup;
-
-static int __init nosoftlockup_setup(char *str)
-{
-       nosoftlockup = 1;
-       return 1;
-}
-__setup("nosoftlockup", nosoftlockup_setup);
-
-static int __init spawn_softlockup_task(void)
-{
-       void *cpu = (void *)(long)smp_processor_id();
-       int err;
-
-       if (nosoftlockup)
-               return 0;
-
-       err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
-       if (err == NOTIFY_BAD) {
-               BUG();
-               return 1;
-       }
-       cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
-       register_cpu_notifier(&cpu_nfb);
-
-       atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
-
-       return 0;
-}
-early_initcall(spawn_softlockup_task);
index d24f761f48769d925692efcbb233a276dad01905..6d850bf0a5178f3b6c5c435e89f6d6f2dfb8cfa5 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/acpi.h>
 #include <linux/reboot.h>
 #include <linux/ftrace.h>
-#include <linux/slow-work.h>
 #include <linux/perf_event.h>
 #include <linux/kprobes.h>
 #include <linux/pipe_fs_i.h>
 #include <scsi/sg.h>
 #endif
 
+#ifdef CONFIG_LOCKUP_DETECTOR
+#include <linux/nmi.h>
+#endif
+
 
 #if defined(CONFIG_SYSCTL)
 
@@ -106,7 +109,7 @@ extern int blk_iopoll_enabled;
 #endif
 
 /* Constants used for minimum and  maximum */
-#ifdef CONFIG_DETECT_SOFTLOCKUP
+#ifdef CONFIG_LOCKUP_DETECTOR
 static int sixty = 60;
 static int neg_one = -1;
 #endif
@@ -562,7 +565,7 @@ static struct ctl_table kern_table[] = {
                .extra2         = &one,
        },
 #endif
-#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
+#ifdef CONFIG_HOTPLUG
        {
                .procname       = "hotplug",
                .data           = &uevent_helper,
@@ -710,7 +713,34 @@ static struct ctl_table kern_table[] = {
                .mode           = 0444,
                .proc_handler   = proc_dointvec,
        },
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
+#if defined(CONFIG_LOCKUP_DETECTOR)
+       {
+               .procname       = "watchdog",
+               .data           = &watchdog_enabled,
+               .maxlen         = sizeof (int),
+               .mode           = 0644,
+               .proc_handler   = proc_dowatchdog_enabled,
+       },
+       {
+               .procname       = "watchdog_thresh",
+               .data           = &softlockup_thresh,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dowatchdog_thresh,
+               .extra1         = &neg_one,
+               .extra2         = &sixty,
+       },
+       {
+               .procname       = "softlockup_panic",
+               .data           = &softlockup_panic,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
+#endif
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) && !defined(CONFIG_LOCKUP_DETECTOR)
        {
                .procname       = "unknown_nmi_panic",
                .data           = &unknown_nmi_panic,
@@ -813,26 +843,6 @@ static struct ctl_table kern_table[] = {
                .proc_handler   = proc_dointvec,
        },
 #endif
-#ifdef CONFIG_DETECT_SOFTLOCKUP
-       {
-               .procname       = "softlockup_panic",
-               .data           = &softlockup_panic,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = proc_dointvec_minmax,
-               .extra1         = &zero,
-               .extra2         = &one,
-       },
-       {
-               .procname       = "softlockup_thresh",
-               .data           = &softlockup_thresh,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = proc_dosoftlockup_thresh,
-               .extra1         = &neg_one,
-               .extra2         = &sixty,
-       },
-#endif
 #ifdef CONFIG_DETECT_HUNG_TASK
        {
                .procname       = "hung_task_panic",
@@ -906,13 +916,6 @@ static struct ctl_table kern_table[] = {
                .proc_handler   = proc_dointvec,
        },
 #endif
-#ifdef CONFIG_SLOW_WORK
-       {
-               .procname       = "slow-work",
-               .mode           = 0555,
-               .child          = slow_work_sysctls,
-       },
-#endif
 #ifdef CONFIG_PERF_EVENTS
        {
                .procname       = "perf_event_paranoid",
index 848b1c2ab09a411858c8bef030ecdfc61b8017e8..ba9b338d1835e071273d8f8f8d2a054ab9c95790 100644 (file)
@@ -300,22 +300,6 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
 }
 EXPORT_SYMBOL(timespec_trunc);
 
-#ifndef CONFIG_GENERIC_TIME
-/*
- * Simulate gettimeofday using do_gettimeofday which only allows a timeval
- * and therefore only yields usec accuracy
- */
-void getnstimeofday(struct timespec *tv)
-{
-       struct timeval x;
-
-       do_gettimeofday(&x);
-       tv->tv_sec = x.tv_sec;
-       tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
-}
-EXPORT_SYMBOL_GPL(getnstimeofday);
-#endif
-
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
index 95ed42951e0adb536db3783b5d026914ddfdbc73..f06a8a3656481d7e3120ed074a1b16c04357a9dd 100644 (file)
@@ -6,7 +6,7 @@ config TICK_ONESHOT
 
 config NO_HZ
        bool "Tickless System (Dynamic Ticks)"
-       depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
+       depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
        help
          This option enables a tickless system: timer interrupts will
@@ -15,7 +15,7 @@ config NO_HZ
 
 config HIGH_RES_TIMERS
        bool "High Resolution Timer Support"
-       depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
+       depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
        help
          This option enables high resolution timer support. If your
index f08e99c1d5617252aa909cd457f0310bd67a0f6b..c18d7efa1b4b10b0146466094016d74a69702c30 100644 (file)
@@ -531,7 +531,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs)
        return max_nsecs - (max_nsecs >> 5);
 }
 
-#ifdef CONFIG_GENERIC_TIME
+#ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
 
 /**
  * clocksource_select - Select the best clocksource available
@@ -577,7 +577,7 @@ static void clocksource_select(void)
        }
 }
 
-#else /* CONFIG_GENERIC_TIME */
+#else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */
 
 static inline void clocksource_select(void) { }
 
@@ -639,19 +639,18 @@ static void clocksource_enqueue(struct clocksource *cs)
 #define MAX_UPDATE_LENGTH 5 /* Seconds */
 
 /**
- * __clocksource_register_scale - Used to install new clocksources
+ * __clocksource_updatefreq_scale - Used update clocksource with new freq
  * @t:         clocksource to be registered
  * @scale:     Scale factor multiplied against freq to get clocksource hz
  * @freq:      clocksource frequency (cycles per second) divided by scale
  *
- * Returns -EBUSY if registration fails, zero otherwise.
+ * This should only be called from the clocksource->enable() method.
  *
  * This *SHOULD NOT* be called directly! Please use the
- * clocksource_register_hz() or clocksource_register_khz helper functions.
+ * clocksource_updatefreq_hz() or clocksource_updatefreq_khz helper functions.
  */
-int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
+void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
 {
-
        /*
         * Ideally we want to use  some of the limits used in
         * clocksource_max_deferment, to provide a more informed
@@ -662,7 +661,27 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
                                      NSEC_PER_SEC/scale,
                                      MAX_UPDATE_LENGTH*scale);
        cs->max_idle_ns = clocksource_max_deferment(cs);
+}
+EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
+
+/**
+ * __clocksource_register_scale - Used to install new clocksources
+ * @t:         clocksource to be registered
+ * @scale:     Scale factor multiplied against freq to get clocksource hz
+ * @freq:      clocksource frequency (cycles per second) divided by scale
+ *
+ * Returns -EBUSY if registration fails, zero otherwise.
+ *
+ * This *SHOULD NOT* be called directly! Please use the
+ * clocksource_register_hz() or clocksource_register_khz helper functions.
+ */
+int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
+{
+
+       /* Intialize mult/shift and max_idle_ns */
+       __clocksource_updatefreq_scale(cs, scale, freq);
 
+       /* Add clocksource to the clcoksource list */
        mutex_lock(&clocksource_mutex);
        clocksource_enqueue(cs);
        clocksource_select();
index 813993b5fb61048f24f876a7247e4f8ac2c861a2..3e216e01bbd19191f440cf8b202af38007d06ece 100644 (file)
@@ -325,7 +325,7 @@ void tick_nohz_stop_sched_tick(int inidle)
        } while (read_seqretry(&xtime_lock, seq));
 
        if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) ||
-           arch_needs_cpu(cpu) || nohz_ratelimit(cpu)) {
+           arch_needs_cpu(cpu)) {
                next_jiffies = last_jiffies + 1;
                delta_jiffies = 1;
        } else {
@@ -405,13 +405,7 @@ void tick_nohz_stop_sched_tick(int inidle)
                 * the scheduler tick in nohz_restart_sched_tick.
                 */
                if (!ts->tick_stopped) {
-                       if (select_nohz_load_balancer(1)) {
-                               /*
-                                * sched tick not stopped!
-                                */
-                               cpumask_clear_cpu(cpu, nohz_cpu_mask);
-                               goto out;
-                       }
+                       select_nohz_load_balancer(1);
 
                        ts->idle_tick = hrtimer_get_expires(&ts->sched_timer);
                        ts->tick_stopped = 1;
@@ -780,7 +774,6 @@ void tick_setup_sched_timer(void)
 {
        struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
        ktime_t now = ktime_get();
-       u64 offset;
 
        /*
         * Emulate tick processing via per-CPU hrtimers:
@@ -790,10 +783,6 @@ void tick_setup_sched_timer(void)
 
        /* Get the next period (per cpu) */
        hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());
-       offset = ktime_to_ns(tick_period) >> 1;
-       do_div(offset, num_possible_cpus());
-       offset *= smp_processor_id();
-       hrtimer_add_expires_ns(&ts->sched_timer, offset);
 
        for (;;) {
                hrtimer_forward(&ts->sched_timer, now, tick_period);
index caf8d4d4f5c873dffbbc124c62cff08d84a0eb0d..e14c839e9faa7ab212d805ea41ffaa16667abc23 100644 (file)
@@ -153,8 +153,8 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
  * - wall_to_monotonic is no longer the boot time, getboottime must be
  * used instead.
  */
-struct timespec xtime __attribute__ ((aligned (16)));
-struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
+static struct timespec xtime __attribute__ ((aligned (16)));
+static struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
 static struct timespec total_sleep_time;
 
 /*
@@ -170,11 +170,10 @@ void timekeeping_leap_insert(int leapsecond)
 {
        xtime.tv_sec += leapsecond;
        wall_to_monotonic.tv_sec -= leapsecond;
-       update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
+       update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
+                       timekeeper.mult);
 }
 
-#ifdef CONFIG_GENERIC_TIME
-
 /**
  * timekeeping_forward_now - update clock to the current time
  *
@@ -328,7 +327,8 @@ int do_settimeofday(struct timespec *tv)
        timekeeper.ntp_error = 0;
        ntp_clear();
 
-       update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
+       update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
+                               timekeeper.mult);
 
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -376,52 +376,6 @@ void timekeeping_notify(struct clocksource *clock)
        tick_clock_notify();
 }
 
-#else /* GENERIC_TIME */
-
-static inline void timekeeping_forward_now(void) { }
-
-/**
- * ktime_get - get the monotonic time in ktime_t format
- *
- * returns the time in ktime_t format
- */
-ktime_t ktime_get(void)
-{
-       struct timespec now;
-
-       ktime_get_ts(&now);
-
-       return timespec_to_ktime(now);
-}
-EXPORT_SYMBOL_GPL(ktime_get);
-
-/**
- * ktime_get_ts - get the monotonic clock in timespec format
- * @ts:                pointer to timespec variable
- *
- * The function calculates the monotonic clock from the realtime
- * clock and the wall_to_monotonic offset and stores the result
- * in normalized timespec format in the variable pointed to by @ts.
- */
-void ktime_get_ts(struct timespec *ts)
-{
-       struct timespec tomono;
-       unsigned long seq;
-
-       do {
-               seq = read_seqbegin(&xtime_lock);
-               getnstimeofday(ts);
-               tomono = wall_to_monotonic;
-
-       } while (read_seqretry(&xtime_lock, seq));
-
-       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
-                               ts->tv_nsec + tomono.tv_nsec);
-}
-EXPORT_SYMBOL_GPL(ktime_get_ts);
-
-#endif /* !GENERIC_TIME */
-
 /**
  * ktime_get_real - get the real (wall-) time in ktime_t format
  *
@@ -579,9 +533,9 @@ static int timekeeping_resume(struct sys_device *dev)
 
        if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
                ts = timespec_sub(ts, timekeeping_suspend_time);
-               xtime = timespec_add_safe(xtime, ts);
+               xtime = timespec_add(xtime, ts);
                wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
-               total_sleep_time = timespec_add_safe(total_sleep_time, ts);
+               total_sleep_time = timespec_add(total_sleep_time, ts);
        }
        /* re-base the last cycle value */
        timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
@@ -784,10 +738,11 @@ void update_wall_time(void)
                return;
 
        clock = timekeeper.clock;
-#ifdef CONFIG_GENERIC_TIME
-       offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
-#else
+
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
        offset = timekeeper.cycle_interval;
+#else
+       offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
 #endif
        timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
 
@@ -856,7 +811,8 @@ void update_wall_time(void)
        }
 
        /* check to see if there is a new clocksource to use */
-       update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
+       update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
+                               timekeeper.mult);
 }
 
 /**
@@ -887,7 +843,7 @@ EXPORT_SYMBOL_GPL(getboottime);
  */
 void monotonic_to_bootbased(struct timespec *ts)
 {
-       *ts = timespec_add_safe(*ts, total_sleep_time);
+       *ts = timespec_add(*ts, total_sleep_time);
 }
 EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
 
@@ -902,6 +858,11 @@ struct timespec __current_kernel_time(void)
        return xtime;
 }
 
+struct timespec __get_wall_to_monotonic(void)
+{
+       return wall_to_monotonic;
+}
+
 struct timespec current_kernel_time(void)
 {
        struct timespec now;
index efde11e197c4d40f2abd8badd13459e159fdb5cb..f1b8afe1ad86bd609f2bb63133ca1f0840aa86d3 100644 (file)
@@ -90,8 +90,13 @@ static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
 
 /*
  * Note that all tvec_bases are 2 byte aligned and lower bit of
- * base in timer_list is guaranteed to be zero. Use the LSB for
- * the new flag to indicate whether the timer is deferrable
+ * base in timer_list is guaranteed to be zero. Use the LSB to
+ * indicate whether the timer is deferrable.
+ *
+ * A deferrable timer will work normally when the system is busy, but
+ * will not cause a CPU to come out of idle just to service it; instead,
+ * the timer will be serviced when the CPU eventually wakes up with a
+ * subsequent non-deferrable timer.
  */
 #define TBASE_DEFERRABLE_FLAG          (0x1)
 
@@ -692,12 +697,8 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
        cpu = smp_processor_id();
 
 #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
-       if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) {
-               int preferred_cpu = get_nohz_load_balancer();
-
-               if (preferred_cpu >= 0)
-                       cpu = preferred_cpu;
-       }
+       if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu))
+               cpu = get_nohz_timer_target();
 #endif
        new_base = per_cpu(tvec_bases, cpu);
 
@@ -1302,7 +1303,6 @@ void run_local_timers(void)
 {
        hrtimer_run_queues();
        raise_softirq(TIMER_SOFTIRQ);
-       softlockup_tick();
 }
 
 /*
@@ -1763,3 +1763,25 @@ unsigned long msleep_interruptible(unsigned int msecs)
 }
 
 EXPORT_SYMBOL(msleep_interruptible);
+
+static int __sched do_usleep_range(unsigned long min, unsigned long max)
+{
+       ktime_t kmin;
+       unsigned long delta;
+
+       kmin = ktime_set(0, min * NSEC_PER_USEC);
+       delta = (max - min) * NSEC_PER_USEC;
+       return schedule_hrtimeout_range(&kmin, delta, HRTIMER_MODE_REL);
+}
+
+/**
+ * usleep_range - Drop in replacement for udelay where wakeup is flexible
+ * @min: Minimum time in usecs to sleep
+ * @max: Maximum time in usecs to sleep
+ */
+void usleep_range(unsigned long min, unsigned long max)
+{
+       __set_current_state(TASK_UNINTERRUPTIBLE);
+       do_usleep_range(min, max);
+}
+EXPORT_SYMBOL(usleep_range);
index 8b1797c4545b41c00cca7b3e5e268cf8b8f0e164..538501c6ea5058cf703eaa2608307f03f3aee89a 100644 (file)
@@ -153,7 +153,7 @@ config IRQSOFF_TRACER
        bool "Interrupts-off Latency Tracer"
        default n
        depends on TRACE_IRQFLAGS_SUPPORT
-       depends on GENERIC_TIME
+       depends on !ARCH_USES_GETTIMEOFFSET
        select TRACE_IRQFLAGS
        select GENERIC_TRACER
        select TRACER_MAX_TRACE
@@ -175,7 +175,7 @@ config IRQSOFF_TRACER
 config PREEMPT_TRACER
        bool "Preemption-off Latency Tracer"
        default n
-       depends on GENERIC_TIME
+       depends on !ARCH_USES_GETTIMEOFFSET
        depends on PREEMPT
        select GENERIC_TRACER
        select TRACER_MAX_TRACE
@@ -194,15 +194,6 @@ config PREEMPT_TRACER
          enabled. This option and the irqs-off timing option can be
          used together or separately.)
 
-config SYSPROF_TRACER
-       bool "Sysprof Tracer"
-       depends on X86
-       select GENERIC_TRACER
-       select CONTEXT_SWITCH_TRACER
-       help
-         This tracer provides the trace needed by the 'Sysprof' userspace
-         tool.
-
 config SCHED_TRACER
        bool "Scheduling Latency Tracer"
        select GENERIC_TRACER
@@ -229,23 +220,6 @@ config FTRACE_SYSCALLS
        help
          Basic tracer to catch the syscall entry and exit events.
 
-config BOOT_TRACER
-       bool "Trace boot initcalls"
-       select GENERIC_TRACER
-       select CONTEXT_SWITCH_TRACER
-       help
-         This tracer helps developers to optimize boot times: it records
-         the timings of the initcalls and traces key events and the identity
-         of tasks that can cause boot delays, such as context-switches.
-
-         Its aim is to be parsed by the scripts/bootgraph.pl tool to
-         produce pretty graphics about boot inefficiencies, giving a visual
-         representation of the delays during initcalls - but the raw
-         /debug/tracing/trace text output is readable too.
-
-         You must pass in initcall_debug and ftrace=initcall to the kernel
-         command line to enable this on bootup.
-
 config TRACE_BRANCH_PROFILING
        bool
        select GENERIC_TRACER
@@ -325,28 +299,6 @@ config BRANCH_TRACER
 
          Say N if unsure.
 
-config KSYM_TRACER
-       bool "Trace read and write access on kernel memory locations"
-       depends on HAVE_HW_BREAKPOINT
-       select TRACING
-       help
-         This tracer helps find read and write operations on any given kernel
-         symbol i.e. /proc/kallsyms.
-
-config PROFILE_KSYM_TRACER
-       bool "Profile all kernel memory accesses on 'watched' variables"
-       depends on KSYM_TRACER
-       help
-         This tracer profiles kernel accesses on variables watched through the
-         ksym tracer ftrace plugin. Depending upon the hardware, all read
-         and write operations on kernel variables can be monitored for
-         accesses.
-
-         The results will be displayed in:
-         /debugfs/tracing/profile_ksym
-
-         Say N if unsure.
-
 config STACK_TRACER
        bool "Trace max stack"
        depends on HAVE_FUNCTION_TRACER
@@ -371,37 +323,6 @@ config STACK_TRACER
 
          Say N if unsure.
 
-config KMEMTRACE
-       bool "Trace SLAB allocations"
-       select GENERIC_TRACER
-       help
-         kmemtrace provides tracing for slab allocator functions, such as
-         kmalloc, kfree, kmem_cache_alloc, kmem_cache_free, etc. Collected
-         data is then fed to the userspace application in order to analyse
-         allocation hotspots, internal fragmentation and so on, making it
-         possible to see how well an allocator performs, as well as debug
-         and profile kernel code.
-
-         This requires an userspace application to use. See
-         Documentation/trace/kmemtrace.txt for more information.
-
-         Saying Y will make the kernel somewhat larger and slower. However,
-         if you disable kmemtrace at run-time or boot-time, the performance
-         impact is minimal (depending on the arch the kernel is built for).
-
-         If unsure, say N.
-
-config WORKQUEUE_TRACER
-       bool "Trace workqueues"
-       select GENERIC_TRACER
-       help
-         The workqueue tracer provides some statistical information
-          about each cpu workqueue thread such as the number of the
-          works inserted and executed since their creation. It can help
-          to evaluate the amount of work each of them has to perform.
-          For example it can help a developer to decide whether he should
-          choose a per-cpu workqueue instead of a singlethreaded one.
-
 config BLK_DEV_IO_TRACE
        bool "Support for tracing block IO actions"
        depends on SYSFS
index ffb1a5b0550e3f071c568695a386a10ea84290b8..53f338190b260df929d3ef6020d2bad817fcc73f 100644 (file)
@@ -30,7 +30,6 @@ obj-$(CONFIG_TRACING) += trace_output.o
 obj-$(CONFIG_TRACING) += trace_stat.o
 obj-$(CONFIG_TRACING) += trace_printk.o
 obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
-obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o
 obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o
 obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
 obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
@@ -38,10 +37,8 @@ obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o
 obj-$(CONFIG_NOP_TRACER) += trace_nop.o
 obj-$(CONFIG_STACK_TRACER) += trace_stack.o
 obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o
-obj-$(CONFIG_BOOT_TRACER) += trace_boot.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += trace_functions_graph.o
 obj-$(CONFIG_TRACE_BRANCH_PROFILING) += trace_branch.o
-obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
 obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o
 obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
 ifeq ($(CONFIG_BLOCK),y)
@@ -55,7 +52,9 @@ obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o
 endif
 obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
 obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
-obj-$(CONFIG_KSYM_TRACER) += trace_ksym.o
 obj-$(CONFIG_EVENT_TRACING) += power-traces.o
+ifeq ($(CONFIG_TRACING),y)
+obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
+endif
 
 libftrace-y := ftrace.o
index 6d2cb14f9449083c9a2e78f507b9c1255c8e7ca2..0d88ce9b9fb8828c9a81fdffcd47763ae5cc2543 100644 (file)
@@ -1883,7 +1883,6 @@ function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
        struct hlist_head *hhd;
        struct hlist_node *n;
        unsigned long key;
-       int resched;
 
        key = hash_long(ip, FTRACE_HASH_BITS);
 
@@ -1897,12 +1896,12 @@ function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
         * period. This syncs the hash iteration and freeing of items
         * on the hash. rcu_read_lock is too dangerous here.
         */
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
        hlist_for_each_entry_rcu(entry, n, hhd, node) {
                if (entry->ip == ip)
                        entry->ops->func(ip, parent_ip, &entry->data);
        }
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
 }
 
 static struct ftrace_ops trace_probe_ops __read_mostly =
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
deleted file mode 100644 (file)
index bbfc1bb..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Memory allocator tracing
- *
- * Copyright (C) 2008 Eduard - Gabriel Munteanu
- * Copyright (C) 2008 Pekka Enberg <penberg@cs.helsinki.fi>
- * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
- */
-
-#include <linux/tracepoint.h>
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-#include <linux/dcache.h>
-#include <linux/fs.h>
-
-#include <linux/kmemtrace.h>
-
-#include "trace_output.h"
-#include "trace.h"
-
-/* Select an alternative, minimalistic output than the original one */
-#define TRACE_KMEM_OPT_MINIMAL 0x1
-
-static struct tracer_opt kmem_opts[] = {
-       /* Default disable the minimalistic output */
-       { TRACER_OPT(kmem_minimalistic, TRACE_KMEM_OPT_MINIMAL) },
-       { }
-};
-
-static struct tracer_flags kmem_tracer_flags = {
-       .val                    = 0,
-       .opts                   = kmem_opts
-};
-
-static struct trace_array *kmemtrace_array;
-
-/* Trace allocations */
-static inline void kmemtrace_alloc(enum kmemtrace_type_id type_id,
-                                  unsigned long call_site,
-                                  const void *ptr,
-                                  size_t bytes_req,
-                                  size_t bytes_alloc,
-                                  gfp_t gfp_flags,
-                                  int node)
-{
-       struct ftrace_event_call *call = &event_kmem_alloc;
-       struct trace_array *tr = kmemtrace_array;
-       struct kmemtrace_alloc_entry *entry;
-       struct ring_buffer_event *event;
-
-       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
-       if (!event)
-               return;
-
-       entry = ring_buffer_event_data(event);
-       tracing_generic_entry_update(&entry->ent, 0, 0);
-
-       entry->ent.type         = TRACE_KMEM_ALLOC;
-       entry->type_id          = type_id;
-       entry->call_site        = call_site;
-       entry->ptr              = ptr;
-       entry->bytes_req        = bytes_req;
-       entry->bytes_alloc      = bytes_alloc;
-       entry->gfp_flags        = gfp_flags;
-       entry->node             = node;
-
-       if (!filter_check_discard(call, entry, tr->buffer, event))
-               ring_buffer_unlock_commit(tr->buffer, event);
-
-       trace_wake_up();
-}
-
-static inline void kmemtrace_free(enum kmemtrace_type_id type_id,
-                                 unsigned long call_site,
-                                 const void *ptr)
-{
-       struct ftrace_event_call *call = &event_kmem_free;
-       struct trace_array *tr = kmemtrace_array;
-       struct kmemtrace_free_entry *entry;
-       struct ring_buffer_event *event;
-
-       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
-       if (!event)
-               return;
-       entry   = ring_buffer_event_data(event);
-       tracing_generic_entry_update(&entry->ent, 0, 0);
-
-       entry->ent.type         = TRACE_KMEM_FREE;
-       entry->type_id          = type_id;
-       entry->call_site        = call_site;
-       entry->ptr              = ptr;
-
-       if (!filter_check_discard(call, entry, tr->buffer, event))
-               ring_buffer_unlock_commit(tr->buffer, event);
-
-       trace_wake_up();
-}
-
-static void kmemtrace_kmalloc(void *ignore,
-                             unsigned long call_site,
-                             const void *ptr,
-                             size_t bytes_req,
-                             size_t bytes_alloc,
-                             gfp_t gfp_flags)
-{
-       kmemtrace_alloc(KMEMTRACE_TYPE_KMALLOC, call_site, ptr,
-                       bytes_req, bytes_alloc, gfp_flags, -1);
-}
-
-static void kmemtrace_kmem_cache_alloc(void *ignore,
-                                      unsigned long call_site,
-                                      const void *ptr,
-                                      size_t bytes_req,
-                                      size_t bytes_alloc,
-                                      gfp_t gfp_flags)
-{
-       kmemtrace_alloc(KMEMTRACE_TYPE_CACHE, call_site, ptr,
-                       bytes_req, bytes_alloc, gfp_flags, -1);
-}
-
-static void kmemtrace_kmalloc_node(void *ignore,
-                                  unsigned long call_site,
-                                  const void *ptr,
-                                  size_t bytes_req,
-                                  size_t bytes_alloc,
-                                  gfp_t gfp_flags,
-                                  int node)
-{
-       kmemtrace_alloc(KMEMTRACE_TYPE_KMALLOC, call_site, ptr,
-                       bytes_req, bytes_alloc, gfp_flags, node);
-}
-
-static void kmemtrace_kmem_cache_alloc_node(void *ignore,
-                                           unsigned long call_site,
-                                           const void *ptr,
-                                           size_t bytes_req,
-                                           size_t bytes_alloc,
-                                           gfp_t gfp_flags,
-                                           int node)
-{
-       kmemtrace_alloc(KMEMTRACE_TYPE_CACHE, call_site, ptr,
-                       bytes_req, bytes_alloc, gfp_flags, node);
-}
-
-static void
-kmemtrace_kfree(void *ignore, unsigned long call_site, const void *ptr)
-{
-       kmemtrace_free(KMEMTRACE_TYPE_KMALLOC, call_site, ptr);
-}
-
-static void kmemtrace_kmem_cache_free(void *ignore,
-                                     unsigned long call_site, const void *ptr)
-{
-       kmemtrace_free(KMEMTRACE_TYPE_CACHE, call_site, ptr);
-}
-
-static int kmemtrace_start_probes(void)
-{
-       int err;
-
-       err = register_trace_kmalloc(kmemtrace_kmalloc, NULL);
-       if (err)
-               return err;
-       err = register_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc, NULL);
-       if (err)
-               return err;
-       err = register_trace_kmalloc_node(kmemtrace_kmalloc_node, NULL);
-       if (err)
-               return err;
-       err = register_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node, NULL);
-       if (err)
-               return err;
-       err = register_trace_kfree(kmemtrace_kfree, NULL);
-       if (err)
-               return err;
-       err = register_trace_kmem_cache_free(kmemtrace_kmem_cache_free, NULL);
-
-       return err;
-}
-
-static void kmemtrace_stop_probes(void)
-{
-       unregister_trace_kmalloc(kmemtrace_kmalloc, NULL);
-       unregister_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc, NULL);
-       unregister_trace_kmalloc_node(kmemtrace_kmalloc_node, NULL);
-       unregister_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node, NULL);
-       unregister_trace_kfree(kmemtrace_kfree, NULL);
-       unregister_trace_kmem_cache_free(kmemtrace_kmem_cache_free, NULL);
-}
-
-static int kmem_trace_init(struct trace_array *tr)
-{
-       kmemtrace_array = tr;
-
-       tracing_reset_online_cpus(tr);
-
-       kmemtrace_start_probes();
-
-       return 0;
-}
-
-static void kmem_trace_reset(struct trace_array *tr)
-{
-       kmemtrace_stop_probes();
-}
-
-static void kmemtrace_headers(struct seq_file *s)
-{
-       /* Don't need headers for the original kmemtrace output */
-       if (!(kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL))
-               return;
-
-       seq_printf(s, "#\n");
-       seq_printf(s, "# ALLOC  TYPE  REQ   GIVEN  FLAGS     "
-                       "      POINTER         NODE    CALLER\n");
-       seq_printf(s, "# FREE   |      |     |       |       "
-                       "       |   |            |        |\n");
-       seq_printf(s, "# |\n\n");
-}
-
-/*
- * The following functions give the original output from kmemtrace,
- * plus the origin CPU, since reordering occurs in-kernel now.
- */
-
-#define KMEMTRACE_USER_ALLOC   0
-#define KMEMTRACE_USER_FREE    1
-
-struct kmemtrace_user_event {
-       u8                      event_id;
-       u8                      type_id;
-       u16                     event_size;
-       u32                     cpu;
-       u64                     timestamp;
-       unsigned long           call_site;
-       unsigned long           ptr;
-};
-
-struct kmemtrace_user_event_alloc {
-       size_t                  bytes_req;
-       size_t                  bytes_alloc;
-       unsigned                gfp_flags;
-       int                     node;
-};
-
-static enum print_line_t
-kmemtrace_print_alloc(struct trace_iterator *iter, int flags,
-                     struct trace_event *event)
-{
-       struct trace_seq *s = &iter->seq;
-       struct kmemtrace_alloc_entry *entry;
-       int ret;
-
-       trace_assign_type(entry, iter->ent);
-
-       ret = trace_seq_printf(s, "type_id %d call_site %pF ptr %lu "
-           "bytes_req %lu bytes_alloc %lu gfp_flags %lu node %d\n",
-           entry->type_id, (void *)entry->call_site, (unsigned long)entry->ptr,
-           (unsigned long)entry->bytes_req, (unsigned long)entry->bytes_alloc,
-           (unsigned long)entry->gfp_flags, entry->node);
-
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-       return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t
-kmemtrace_print_free(struct trace_iterator *iter, int flags,
-                    struct trace_event *event)
-{
-       struct trace_seq *s = &iter->seq;
-       struct kmemtrace_free_entry *entry;
-       int ret;
-
-       trace_assign_type(entry, iter->ent);
-
-       ret = trace_seq_printf(s, "type_id %d call_site %pF ptr %lu\n",
-                              entry->type_id, (void *)entry->call_site,
-                              (unsigned long)entry->ptr);
-
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-       return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t
-kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags,
-                          struct trace_event *event)
-{
-       struct trace_seq *s = &iter->seq;
-       struct kmemtrace_alloc_entry *entry;
-       struct kmemtrace_user_event *ev;
-       struct kmemtrace_user_event_alloc *ev_alloc;
-
-       trace_assign_type(entry, iter->ent);
-
-       ev = trace_seq_reserve(s, sizeof(*ev));
-       if (!ev)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       ev->event_id            = KMEMTRACE_USER_ALLOC;
-       ev->type_id             = entry->type_id;
-       ev->event_size          = sizeof(*ev) + sizeof(*ev_alloc);
-       ev->cpu                 = iter->cpu;
-       ev->timestamp           = iter->ts;
-       ev->call_site           = entry->call_site;
-       ev->ptr                 = (unsigned long)entry->ptr;
-
-       ev_alloc = trace_seq_reserve(s, sizeof(*ev_alloc));
-       if (!ev_alloc)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       ev_alloc->bytes_req     = entry->bytes_req;
-       ev_alloc->bytes_alloc   = entry->bytes_alloc;
-       ev_alloc->gfp_flags     = entry->gfp_flags;
-       ev_alloc->node          = entry->node;
-
-       return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t
-kmemtrace_print_free_user(struct trace_iterator *iter, int flags,
-                         struct trace_event *event)
-{
-       struct trace_seq *s = &iter->seq;
-       struct kmemtrace_free_entry *entry;
-       struct kmemtrace_user_event *ev;
-
-       trace_assign_type(entry, iter->ent);
-
-       ev = trace_seq_reserve(s, sizeof(*ev));
-       if (!ev)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       ev->event_id            = KMEMTRACE_USER_FREE;
-       ev->type_id             = entry->type_id;
-       ev->event_size          = sizeof(*ev);
-       ev->cpu                 = iter->cpu;
-       ev->timestamp           = iter->ts;
-       ev->call_site           = entry->call_site;
-       ev->ptr                 = (unsigned long)entry->ptr;
-
-       return TRACE_TYPE_HANDLED;
-}
-
-/* The two other following provide a more minimalistic output */
-static enum print_line_t
-kmemtrace_print_alloc_compress(struct trace_iterator *iter)
-{
-       struct kmemtrace_alloc_entry *entry;
-       struct trace_seq *s = &iter->seq;
-       int ret;
-
-       trace_assign_type(entry, iter->ent);
-
-       /* Alloc entry */
-       ret = trace_seq_printf(s, "  +      ");
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Type */
-       switch (entry->type_id) {
-       case KMEMTRACE_TYPE_KMALLOC:
-               ret = trace_seq_printf(s, "K   ");
-               break;
-       case KMEMTRACE_TYPE_CACHE:
-               ret = trace_seq_printf(s, "C   ");
-               break;
-       case KMEMTRACE_TYPE_PAGES:
-               ret = trace_seq_printf(s, "P   ");
-               break;
-       default:
-               ret = trace_seq_printf(s, "?   ");
-       }
-
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Requested */
-       ret = trace_seq_printf(s, "%4zu   ", entry->bytes_req);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Allocated */
-       ret = trace_seq_printf(s, "%4zu   ", entry->bytes_alloc);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Flags
-        * TODO: would be better to see the name of the GFP flag names
-        */
-       ret = trace_seq_printf(s, "%08x   ", entry->gfp_flags);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Pointer to allocated */
-       ret = trace_seq_printf(s, "0x%tx   ", (ptrdiff_t)entry->ptr);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Node and call site*/
-       ret = trace_seq_printf(s, "%4d   %pf\n", entry->node,
-                                                (void *)entry->call_site);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t
-kmemtrace_print_free_compress(struct trace_iterator *iter)
-{
-       struct kmemtrace_free_entry *entry;
-       struct trace_seq *s = &iter->seq;
-       int ret;
-
-       trace_assign_type(entry, iter->ent);
-
-       /* Free entry */
-       ret = trace_seq_printf(s, "  -      ");
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Type */
-       switch (entry->type_id) {
-       case KMEMTRACE_TYPE_KMALLOC:
-               ret = trace_seq_printf(s, "K     ");
-               break;
-       case KMEMTRACE_TYPE_CACHE:
-               ret = trace_seq_printf(s, "C     ");
-               break;
-       case KMEMTRACE_TYPE_PAGES:
-               ret = trace_seq_printf(s, "P     ");
-               break;
-       default:
-               ret = trace_seq_printf(s, "?     ");
-       }
-
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Skip requested/allocated/flags */
-       ret = trace_seq_printf(s, "                       ");
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Pointer to allocated */
-       ret = trace_seq_printf(s, "0x%tx   ", (ptrdiff_t)entry->ptr);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       /* Skip node and print call site*/
-       ret = trace_seq_printf(s, "       %pf\n", (void *)entry->call_site);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter)
-{
-       struct trace_entry *entry = iter->ent;
-
-       if (!(kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL))
-               return TRACE_TYPE_UNHANDLED;
-
-       switch (entry->type) {
-       case TRACE_KMEM_ALLOC:
-               return kmemtrace_print_alloc_compress(iter);
-       case TRACE_KMEM_FREE:
-               return kmemtrace_print_free_compress(iter);
-       default:
-               return TRACE_TYPE_UNHANDLED;
-       }
-}
-
-static struct trace_event_functions kmem_trace_alloc_funcs = {
-       .trace                  = kmemtrace_print_alloc,
-       .binary                 = kmemtrace_print_alloc_user,
-};
-
-static struct trace_event kmem_trace_alloc = {
-       .type                   = TRACE_KMEM_ALLOC,
-       .funcs                  = &kmem_trace_alloc_funcs,
-};
-
-static struct trace_event_functions kmem_trace_free_funcs = {
-       .trace                  = kmemtrace_print_free,
-       .binary                 = kmemtrace_print_free_user,
-};
-
-static struct trace_event kmem_trace_free = {
-       .type                   = TRACE_KMEM_FREE,
-       .funcs                  = &kmem_trace_free_funcs,
-};
-
-static struct tracer kmem_tracer __read_mostly = {
-       .name                   = "kmemtrace",
-       .init                   = kmem_trace_init,
-       .reset                  = kmem_trace_reset,
-       .print_line             = kmemtrace_print_line,
-       .print_header           = kmemtrace_headers,
-       .flags                  = &kmem_tracer_flags
-};
-
-void kmemtrace_init(void)
-{
-       /* earliest opportunity to start kmem tracing */
-}
-
-static int __init init_kmem_tracer(void)
-{
-       if (!register_ftrace_event(&kmem_trace_alloc)) {
-               pr_warning("Warning: could not register kmem events\n");
-               return 1;
-       }
-
-       if (!register_ftrace_event(&kmem_trace_free)) {
-               pr_warning("Warning: could not register kmem events\n");
-               return 1;
-       }
-
-       if (register_tracer(&kmem_tracer) != 0) {
-               pr_warning("Warning: could not register the kmem tracer\n");
-               return 1;
-       }
-
-       return 0;
-}
-device_initcall(init_kmem_tracer);
index 1da7b6ea8b85d70dde15b50369202cb68acab0bf..3632ce87674f88dfd6c4ce5c8ed09eb184ace1a3 100644 (file)
@@ -443,6 +443,7 @@ int ring_buffer_print_page_header(struct trace_seq *s)
  */
 struct ring_buffer_per_cpu {
        int                             cpu;
+       atomic_t                        record_disabled;
        struct ring_buffer              *buffer;
        spinlock_t                      reader_lock;    /* serialize readers */
        arch_spinlock_t                 lock;
@@ -462,7 +463,6 @@ struct ring_buffer_per_cpu {
        unsigned long                   read;
        u64                             write_stamp;
        u64                             read_stamp;
-       atomic_t                        record_disabled;
 };
 
 struct ring_buffer {
@@ -2242,8 +2242,6 @@ static void trace_recursive_unlock(void)
 
 #endif
 
-static DEFINE_PER_CPU(int, rb_need_resched);
-
 /**
  * ring_buffer_lock_reserve - reserve a part of the buffer
  * @buffer: the ring buffer to reserve from
@@ -2264,13 +2262,13 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_event *event;
-       int cpu, resched;
+       int cpu;
 
        if (ring_buffer_flags != RB_BUFFERS_ON)
                return NULL;
 
        /* If we are tracing schedule, we don't want to recurse */
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
 
        if (atomic_read(&buffer->record_disabled))
                goto out_nocheck;
@@ -2295,21 +2293,13 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
        if (!event)
                goto out;
 
-       /*
-        * Need to store resched state on this cpu.
-        * Only the first needs to.
-        */
-
-       if (preempt_count() == 1)
-               per_cpu(rb_need_resched, cpu) = resched;
-
        return event;
 
  out:
        trace_recursive_unlock();
 
  out_nocheck:
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
        return NULL;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_lock_reserve);
@@ -2355,13 +2345,7 @@ int ring_buffer_unlock_commit(struct ring_buffer *buffer,
 
        trace_recursive_unlock();
 
-       /*
-        * Only the last preempt count needs to restore preemption.
-        */
-       if (preempt_count() == 1)
-               ftrace_preempt_enable(per_cpu(rb_need_resched, cpu));
-       else
-               preempt_enable_no_resched_notrace();
+       preempt_enable_notrace();
 
        return 0;
 }
@@ -2469,13 +2453,7 @@ void ring_buffer_discard_commit(struct ring_buffer *buffer,
 
        trace_recursive_unlock();
 
-       /*
-        * Only the last preempt count needs to restore preemption.
-        */
-       if (preempt_count() == 1)
-               ftrace_preempt_enable(per_cpu(rb_need_resched, cpu));
-       else
-               preempt_enable_no_resched_notrace();
+       preempt_enable_notrace();
 
 }
 EXPORT_SYMBOL_GPL(ring_buffer_discard_commit);
@@ -2501,12 +2479,12 @@ int ring_buffer_write(struct ring_buffer *buffer,
        struct ring_buffer_event *event;
        void *body;
        int ret = -EBUSY;
-       int cpu, resched;
+       int cpu;
 
        if (ring_buffer_flags != RB_BUFFERS_ON)
                return -EBUSY;
 
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
 
        if (atomic_read(&buffer->record_disabled))
                goto out;
@@ -2536,7 +2514,7 @@ int ring_buffer_write(struct ring_buffer *buffer,
 
        ret = 0;
  out:
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
 
        return ret;
 }
index 086d3631680505f20d0820371c50b43f4056e316..ed1032d6f81de5afd35f4c017a849394d4d9615f 100644 (file)
@@ -101,10 +101,7 @@ static inline void ftrace_enable_cpu(void)
        preempt_enable();
 }
 
-static cpumask_var_t __read_mostly     tracing_buffer_mask;
-
-#define for_each_tracing_cpu(cpu)      \
-       for_each_cpu(cpu, tracing_buffer_mask)
+cpumask_var_t __read_mostly    tracing_buffer_mask;
 
 /*
  * ftrace_dump_on_oops - variable to dump ftrace buffer on oops
@@ -344,7 +341,7 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait);
 /* trace_flags holds trace_options default values */
 unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
        TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME |
-       TRACE_ITER_GRAPH_TIME;
+       TRACE_ITER_GRAPH_TIME | TRACE_ITER_RECORD_CMD;
 
 static int trace_stop_count;
 static DEFINE_SPINLOCK(tracing_start_lock);
@@ -428,6 +425,7 @@ static const char *trace_options[] = {
        "latency-format",
        "sleep-time",
        "graph-time",
+       "record-cmd",
        NULL
 };
 
@@ -659,6 +657,10 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
                return;
 
        WARN_ON_ONCE(!irqs_disabled());
+       if (!current_trace->use_max_tr) {
+               WARN_ON_ONCE(1);
+               return;
+       }
        arch_spin_lock(&ftrace_max_lock);
 
        tr->buffer = max_tr.buffer;
@@ -685,6 +687,11 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
                return;
 
        WARN_ON_ONCE(!irqs_disabled());
+       if (!current_trace->use_max_tr) {
+               WARN_ON_ONCE(1);
+               return;
+       }
+
        arch_spin_lock(&ftrace_max_lock);
 
        ftrace_disable_cpu();
@@ -729,7 +736,7 @@ __acquires(kernel_lock)
                return -1;
        }
 
-       if (strlen(type->name) > MAX_TRACER_SIZE) {
+       if (strlen(type->name) >= MAX_TRACER_SIZE) {
                pr_info("Tracer has a name longer than %d\n", MAX_TRACER_SIZE);
                return -1;
        }
@@ -1331,61 +1338,6 @@ static void __trace_userstack(struct trace_array *tr, unsigned long flags)
 
 #endif /* CONFIG_STACKTRACE */
 
-static void
-ftrace_trace_special(void *__tr,
-                    unsigned long arg1, unsigned long arg2, unsigned long arg3,
-                    int pc)
-{
-       struct ftrace_event_call *call = &event_special;
-       struct ring_buffer_event *event;
-       struct trace_array *tr = __tr;
-       struct ring_buffer *buffer = tr->buffer;
-       struct special_entry *entry;
-
-       event = trace_buffer_lock_reserve(buffer, TRACE_SPECIAL,
-                                         sizeof(*entry), 0, pc);
-       if (!event)
-               return;
-       entry   = ring_buffer_event_data(event);
-       entry->arg1                     = arg1;
-       entry->arg2                     = arg2;
-       entry->arg3                     = arg3;
-
-       if (!filter_check_discard(call, entry, buffer, event))
-               trace_buffer_unlock_commit(buffer, event, 0, pc);
-}
-
-void
-__trace_special(void *__tr, void *__data,
-               unsigned long arg1, unsigned long arg2, unsigned long arg3)
-{
-       ftrace_trace_special(__tr, arg1, arg2, arg3, preempt_count());
-}
-
-void
-ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3)
-{
-       struct trace_array *tr = &global_trace;
-       struct trace_array_cpu *data;
-       unsigned long flags;
-       int cpu;
-       int pc;
-
-       if (tracing_disabled)
-               return;
-
-       pc = preempt_count();
-       local_irq_save(flags);
-       cpu = raw_smp_processor_id();
-       data = tr->data[cpu];
-
-       if (likely(atomic_inc_return(&data->disabled) == 1))
-               ftrace_trace_special(tr, arg1, arg2, arg3, pc);
-
-       atomic_dec(&data->disabled);
-       local_irq_restore(flags);
-}
-
 /**
  * trace_vbprintk - write binary msg to tracing buffer
  *
@@ -1404,7 +1356,6 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
        struct bprint_entry *entry;
        unsigned long flags;
        int disable;
-       int resched;
        int cpu, len = 0, size, pc;
 
        if (unlikely(tracing_selftest_running || tracing_disabled))
@@ -1414,7 +1365,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
        pause_graph_tracing();
 
        pc = preempt_count();
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
        cpu = raw_smp_processor_id();
        data = tr->data[cpu];
 
@@ -1452,7 +1403,7 @@ out_unlock:
 
 out:
        atomic_dec_return(&data->disabled);
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
        unpause_graph_tracing();
 
        return len;
@@ -1539,11 +1490,6 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
 }
 EXPORT_SYMBOL_GPL(trace_vprintk);
 
-enum trace_file_type {
-       TRACE_FILE_LAT_FMT      = 1,
-       TRACE_FILE_ANNOTATE     = 2,
-};
-
 static void trace_iterator_increment(struct trace_iterator *iter)
 {
        /* Don't allow ftrace to trace into the ring buffers */
@@ -1641,7 +1587,7 @@ struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
 }
 
 /* Find the next real entry, and increment the iterator to the next entry */
-static void *find_next_entry_inc(struct trace_iterator *iter)
+void *trace_find_next_entry_inc(struct trace_iterator *iter)
 {
        iter->ent = __find_next_entry(iter, &iter->cpu,
                                      &iter->lost_events, &iter->ts);
@@ -1676,19 +1622,19 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos)
                return NULL;
 
        if (iter->idx < 0)
-               ent = find_next_entry_inc(iter);
+               ent = trace_find_next_entry_inc(iter);
        else
                ent = iter;
 
        while (ent && iter->idx < i)
-               ent = find_next_entry_inc(iter);
+               ent = trace_find_next_entry_inc(iter);
 
        iter->pos = *pos;
 
        return ent;
 }
 
-static void tracing_iter_reset(struct trace_iterator *iter, int cpu)
+void tracing_iter_reset(struct trace_iterator *iter, int cpu)
 {
        struct trace_array *tr = iter->tr;
        struct ring_buffer_event *event;
@@ -2049,7 +1995,7 @@ int trace_empty(struct trace_iterator *iter)
 }
 
 /*  Called with trace_event_read_lock() held. */
-static enum print_line_t print_trace_line(struct trace_iterator *iter)
+enum print_line_t print_trace_line(struct trace_iterator *iter)
 {
        enum print_line_t ret;
 
@@ -2394,6 +2340,7 @@ static const struct file_operations show_traces_fops = {
        .open           = show_traces_open,
        .read           = seq_read,
        .release        = seq_release,
+       .llseek         = seq_lseek,
 };
 
 /*
@@ -2487,6 +2434,7 @@ static const struct file_operations tracing_cpumask_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_cpumask_read,
        .write          = tracing_cpumask_write,
+       .llseek         = generic_file_llseek,
 };
 
 static int tracing_trace_options_show(struct seq_file *m, void *v)
@@ -2562,6 +2510,9 @@ static void set_tracer_flags(unsigned int mask, int enabled)
                trace_flags |= mask;
        else
                trace_flags &= ~mask;
+
+       if (mask == TRACE_ITER_RECORD_CMD)
+               trace_event_enable_cmd_record(enabled);
 }
 
 static ssize_t
@@ -2653,6 +2604,7 @@ tracing_readme_read(struct file *filp, char __user *ubuf,
 static const struct file_operations tracing_readme_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_readme_read,
+       .llseek         = generic_file_llseek,
 };
 
 static ssize_t
@@ -2703,6 +2655,7 @@ tracing_saved_cmdlines_read(struct file *file, char __user *ubuf,
 static const struct file_operations tracing_saved_cmdlines_fops = {
     .open       = tracing_open_generic,
     .read       = tracing_saved_cmdlines_read,
+    .llseek    = generic_file_llseek,
 };
 
 static ssize_t
@@ -2798,6 +2751,9 @@ static int tracing_resize_ring_buffer(unsigned long size)
        if (ret < 0)
                return ret;
 
+       if (!current_trace->use_max_tr)
+               goto out;
+
        ret = ring_buffer_resize(max_tr.buffer, size);
        if (ret < 0) {
                int r;
@@ -2825,11 +2781,14 @@ static int tracing_resize_ring_buffer(unsigned long size)
                return ret;
        }
 
+       max_tr.entries = size;
+ out:
        global_trace.entries = size;
 
        return ret;
 }
 
+
 /**
  * tracing_update_buffers - used by tracing facility to expand ring buffers
  *
@@ -2890,12 +2849,26 @@ static int tracing_set_tracer(const char *buf)
        trace_branch_disable();
        if (current_trace && current_trace->reset)
                current_trace->reset(tr);
-
+       if (current_trace && current_trace->use_max_tr) {
+               /*
+                * We don't free the ring buffer. instead, resize it because
+                * The max_tr ring buffer has some state (e.g. ring->clock) and
+                * we want preserve it.
+                */
+               ring_buffer_resize(max_tr.buffer, 1);
+               max_tr.entries = 1;
+       }
        destroy_trace_option_files(topts);
 
        current_trace = t;
 
        topts = create_trace_option_files(current_trace);
+       if (current_trace->use_max_tr) {
+               ret = ring_buffer_resize(max_tr.buffer, global_trace.entries);
+               if (ret < 0)
+                       goto out;
+               max_tr.entries = global_trace.entries;
+       }
 
        if (t->init) {
                ret = tracer_init(t, tr);
@@ -3032,6 +3005,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
        if (iter->trace->pipe_open)
                iter->trace->pipe_open(iter);
 
+       nonseekable_open(inode, filp);
 out:
        mutex_unlock(&trace_types_lock);
        return ret;
@@ -3211,7 +3185,7 @@ waitagain:
 
        trace_event_read_lock();
        trace_access_lock(iter->cpu_file);
-       while (find_next_entry_inc(iter) != NULL) {
+       while (trace_find_next_entry_inc(iter) != NULL) {
                enum print_line_t ret;
                int len = iter->seq.len;
 
@@ -3294,7 +3268,7 @@ tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter)
                if (ret != TRACE_TYPE_NO_CONSUME)
                        trace_consume(iter);
                rem -= count;
-               if (!find_next_entry_inc(iter)) {
+               if (!trace_find_next_entry_inc(iter))   {
                        rem = 0;
                        iter->ent = NULL;
                        break;
@@ -3350,7 +3324,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
        if (ret <= 0)
                goto out_err;
 
-       if (!iter->ent && !find_next_entry_inc(iter)) {
+       if (!iter->ent && !trace_find_next_entry_inc(iter)) {
                ret = -EFAULT;
                goto out_err;
        }
@@ -3477,7 +3451,6 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
        }
 
        tracing_start();
-       max_tr.entries = global_trace.entries;
        mutex_unlock(&trace_types_lock);
 
        return cnt;
@@ -3590,18 +3563,21 @@ static const struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
        .write          = tracing_max_lat_write,
+       .llseek         = generic_file_llseek,
 };
 
 static const struct file_operations tracing_ctrl_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_ctrl_read,
        .write          = tracing_ctrl_write,
+       .llseek         = generic_file_llseek,
 };
 
 static const struct file_operations set_tracer_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_set_trace_read,
        .write          = tracing_set_trace_write,
+       .llseek         = generic_file_llseek,
 };
 
 static const struct file_operations tracing_pipe_fops = {
@@ -3610,17 +3586,20 @@ static const struct file_operations tracing_pipe_fops = {
        .read           = tracing_read_pipe,
        .splice_read    = tracing_splice_read_pipe,
        .release        = tracing_release_pipe,
+       .llseek         = no_llseek,
 };
 
 static const struct file_operations tracing_entries_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_entries_read,
        .write          = tracing_entries_write,
+       .llseek         = generic_file_llseek,
 };
 
 static const struct file_operations tracing_mark_fops = {
        .open           = tracing_open_generic,
        .write          = tracing_mark_write,
+       .llseek         = generic_file_llseek,
 };
 
 static const struct file_operations trace_clock_fops = {
@@ -3926,6 +3905,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
 static const struct file_operations tracing_stats_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_stats_read,
+       .llseek         = generic_file_llseek,
 };
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -3962,6 +3942,7 @@ tracing_read_dyn_info(struct file *filp, char __user *ubuf,
 static const struct file_operations tracing_dyn_info_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_read_dyn_info,
+       .llseek         = generic_file_llseek,
 };
 #endif
 
@@ -4115,6 +4096,7 @@ static const struct file_operations trace_options_fops = {
        .open = tracing_open_generic,
        .read = trace_options_read,
        .write = trace_options_write,
+       .llseek = generic_file_llseek,
 };
 
 static ssize_t
@@ -4166,6 +4148,7 @@ static const struct file_operations trace_options_core_fops = {
        .open = tracing_open_generic,
        .read = trace_options_core_read,
        .write = trace_options_core_write,
+       .llseek = generic_file_llseek,
 };
 
 struct dentry *trace_create_file(const char *name,
@@ -4355,9 +4338,6 @@ static __init int tracer_init_debugfs(void)
        trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
                        &ftrace_update_tot_cnt, &tracing_dyn_info_fops);
 #endif
-#ifdef CONFIG_SYSPROF_TRACER
-       init_tracer_sysprof_debugfs(d_tracer);
-#endif
 
        create_trace_options_dir();
 
@@ -4414,7 +4394,7 @@ static struct notifier_block trace_die_notifier = {
  */
 #define KERN_TRACE             KERN_EMERG
 
-static void
+void
 trace_printk_seq(struct trace_seq *s)
 {
        /* Probably should print a warning here. */
@@ -4429,6 +4409,13 @@ trace_printk_seq(struct trace_seq *s)
        trace_seq_init(s);
 }
 
+void trace_init_global_iter(struct trace_iterator *iter)
+{
+       iter->tr = &global_trace;
+       iter->trace = current_trace;
+       iter->cpu_file = TRACE_PIPE_ALL_CPU;
+}
+
 static void
 __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
 {
@@ -4454,8 +4441,10 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
        if (disable_tracing)
                ftrace_kill();
 
+       trace_init_global_iter(&iter);
+
        for_each_tracing_cpu(cpu) {
-               atomic_inc(&global_trace.data[cpu]->disabled);
+               atomic_inc(&iter.tr->data[cpu]->disabled);
        }
 
        old_userobj = trace_flags & TRACE_ITER_SYM_USEROBJ;
@@ -4504,7 +4493,7 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
                iter.iter_flags |= TRACE_FILE_LAT_FMT;
                iter.pos = -1;
 
-               if (find_next_entry_inc(&iter) != NULL) {
+               if (trace_find_next_entry_inc(&iter) != NULL) {
                        int ret;
 
                        ret = print_trace_line(&iter);
@@ -4526,7 +4515,7 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
                trace_flags |= old_userobj;
 
                for_each_tracing_cpu(cpu) {
-                       atomic_dec(&global_trace.data[cpu]->disabled);
+                       atomic_dec(&iter.tr->data[cpu]->disabled);
                }
                tracing_on();
        }
@@ -4575,16 +4564,14 @@ __init static int tracer_alloc_buffers(void)
 
 
 #ifdef CONFIG_TRACER_MAX_TRACE
-       max_tr.buffer = ring_buffer_alloc(ring_buf_size,
-                                            TRACE_BUFFER_FLAGS);
+       max_tr.buffer = ring_buffer_alloc(1, TRACE_BUFFER_FLAGS);
        if (!max_tr.buffer) {
                printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n");
                WARN_ON(1);
                ring_buffer_free(global_trace.buffer);
                goto out_free_cpumask;
        }
-       max_tr.entries = ring_buffer_size(max_tr.buffer);
-       WARN_ON(max_tr.entries != global_trace.entries);
+       max_tr.entries = 1;
 #endif
 
        /* Allocate the first page for all buffers */
@@ -4597,9 +4584,6 @@ __init static int tracer_alloc_buffers(void)
 
        register_tracer(&nop_trace);
        current_trace = &nop_trace;
-#ifdef CONFIG_BOOT_TRACER
-       register_tracer(&boot_tracer);
-#endif
        /* All seems OK, enable tracing */
        tracing_disabled = 0;
 
index 2cd96399463f88d51a5683802cc34f74343f881f..d39b3c5454a5e684b8c720e0791894b36529f1cf 100644 (file)
@@ -9,10 +9,7 @@
 #include <linux/mmiotrace.h>
 #include <linux/tracepoint.h>
 #include <linux/ftrace.h>
-#include <trace/boot.h>
-#include <linux/kmemtrace.h>
 #include <linux/hw_breakpoint.h>
-
 #include <linux/trace_seq.h>
 #include <linux/ftrace_event.h>
 
@@ -25,30 +22,17 @@ enum trace_type {
        TRACE_STACK,
        TRACE_PRINT,
        TRACE_BPRINT,
-       TRACE_SPECIAL,
        TRACE_MMIO_RW,
        TRACE_MMIO_MAP,
        TRACE_BRANCH,
-       TRACE_BOOT_CALL,
-       TRACE_BOOT_RET,
        TRACE_GRAPH_RET,
        TRACE_GRAPH_ENT,
        TRACE_USER_STACK,
-       TRACE_KMEM_ALLOC,
-       TRACE_KMEM_FREE,
        TRACE_BLK,
-       TRACE_KSYM,
 
        __TRACE_LAST_TYPE,
 };
 
-enum kmemtrace_type_id {
-       KMEMTRACE_TYPE_KMALLOC = 0,     /* kmalloc() or kfree(). */
-       KMEMTRACE_TYPE_CACHE,           /* kmem_cache_*(). */
-       KMEMTRACE_TYPE_PAGES,           /* __get_free_pages() and friends. */
-};
-
-extern struct tracer boot_tracer;
 
 #undef __field
 #define __field(type, item)            type    item;
@@ -204,23 +188,15 @@ extern void __ftrace_bad_type(void);
                IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\
                IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);   \
                IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \
-               IF_ASSIGN(var, ent, struct special_entry, 0);           \
                IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,          \
                          TRACE_MMIO_RW);                               \
                IF_ASSIGN(var, ent, struct trace_mmiotrace_map,         \
                          TRACE_MMIO_MAP);                              \
-               IF_ASSIGN(var, ent, struct trace_boot_call, TRACE_BOOT_CALL);\
-               IF_ASSIGN(var, ent, struct trace_boot_ret, TRACE_BOOT_RET);\
                IF_ASSIGN(var, ent, struct trace_branch, TRACE_BRANCH); \
                IF_ASSIGN(var, ent, struct ftrace_graph_ent_entry,      \
                          TRACE_GRAPH_ENT);             \
                IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry,      \
                          TRACE_GRAPH_RET);             \
-               IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry,       \
-                         TRACE_KMEM_ALLOC);    \
-               IF_ASSIGN(var, ent, struct kmemtrace_free_entry,        \
-                         TRACE_KMEM_FREE);     \
-               IF_ASSIGN(var, ent, struct ksym_trace_entry, TRACE_KSYM);\
                __ftrace_bad_type();                                    \
        } while (0)
 
@@ -298,6 +274,7 @@ struct tracer {
        struct tracer           *next;
        int                     print_max;
        struct tracer_flags     *flags;
+       int                     use_max_tr;
 };
 
 
@@ -318,7 +295,6 @@ struct dentry *trace_create_file(const char *name,
                                 const struct file_operations *fops);
 
 struct dentry *tracing_init_dentry(void);
-void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
 
 struct ring_buffer_event;
 
@@ -338,6 +314,14 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
 struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
                                          int *ent_cpu, u64 *ent_ts);
 
+int trace_empty(struct trace_iterator *iter);
+
+void *trace_find_next_entry_inc(struct trace_iterator *iter);
+
+void trace_init_global_iter(struct trace_iterator *iter);
+
+void tracing_iter_reset(struct trace_iterator *iter, int cpu);
+
 void default_wait_pipe(struct trace_iterator *iter);
 void poll_wait_pipe(struct trace_iterator *iter);
 
@@ -355,11 +339,6 @@ void tracing_sched_wakeup_trace(struct trace_array *tr,
                                struct task_struct *wakee,
                                struct task_struct *cur,
                                unsigned long flags, int pc);
-void trace_special(struct trace_array *tr,
-                  struct trace_array_cpu *data,
-                  unsigned long arg1,
-                  unsigned long arg2,
-                  unsigned long arg3, int pc);
 void trace_function(struct trace_array *tr,
                    unsigned long ip,
                    unsigned long parent_ip,
@@ -380,8 +359,15 @@ void tracing_start_sched_switch_record(void);
 int register_tracer(struct tracer *type);
 void unregister_tracer(struct tracer *type);
 int is_tracing_stopped(void);
+enum trace_file_type {
+       TRACE_FILE_LAT_FMT      = 1,
+       TRACE_FILE_ANNOTATE     = 2,
+};
+
+extern cpumask_var_t __read_mostly tracing_buffer_mask;
 
-extern int process_new_ksym_entry(char *ksymname, int op, unsigned long addr);
+#define for_each_tracing_cpu(cpu)      \
+       for_each_cpu(cpu, tracing_buffer_mask)
 
 extern unsigned long nsecs_to_usecs(unsigned long nsecs);
 
@@ -452,12 +438,8 @@ extern int trace_selftest_startup_nop(struct tracer *trace,
                                         struct trace_array *tr);
 extern int trace_selftest_startup_sched_switch(struct tracer *trace,
                                               struct trace_array *tr);
-extern int trace_selftest_startup_sysprof(struct tracer *trace,
-                                              struct trace_array *tr);
 extern int trace_selftest_startup_branch(struct tracer *trace,
                                         struct trace_array *tr);
-extern int trace_selftest_startup_ksym(struct tracer *trace,
-                                        struct trace_array *tr);
 #endif /* CONFIG_FTRACE_STARTUP_TEST */
 
 extern void *head_page(struct trace_array_cpu *data);
@@ -471,6 +453,8 @@ trace_array_vprintk(struct trace_array *tr,
                    unsigned long ip, const char *fmt, va_list args);
 int trace_array_printk(struct trace_array *tr,
                       unsigned long ip, const char *fmt, ...);
+void trace_printk_seq(struct trace_seq *s);
+enum print_line_t print_trace_line(struct trace_iterator *iter);
 
 extern unsigned long trace_flags;
 
@@ -617,6 +601,7 @@ enum trace_iterator_flags {
        TRACE_ITER_LATENCY_FMT          = 0x20000,
        TRACE_ITER_SLEEP_TIME           = 0x40000,
        TRACE_ITER_GRAPH_TIME           = 0x80000,
+       TRACE_ITER_RECORD_CMD           = 0x100000,
 };
 
 /*
@@ -628,54 +613,6 @@ enum trace_iterator_flags {
 
 extern struct tracer nop_trace;
 
-/**
- * ftrace_preempt_disable - disable preemption scheduler safe
- *
- * When tracing can happen inside the scheduler, there exists
- * cases that the tracing might happen before the need_resched
- * flag is checked. If this happens and the tracer calls
- * preempt_enable (after a disable), a schedule might take place
- * causing an infinite recursion.
- *
- * To prevent this, we read the need_resched flag before
- * disabling preemption. When we want to enable preemption we
- * check the flag, if it is set, then we call preempt_enable_no_resched.
- * Otherwise, we call preempt_enable.
- *
- * The rational for doing the above is that if need_resched is set
- * and we have yet to reschedule, we are either in an atomic location
- * (where we do not need to check for scheduling) or we are inside
- * the scheduler and do not want to resched.
- */
-static inline int ftrace_preempt_disable(void)
-{
-       int resched;
-
-       resched = need_resched();
-       preempt_disable_notrace();
-
-       return resched;
-}
-
-/**
- * ftrace_preempt_enable - enable preemption scheduler safe
- * @resched: the return value from ftrace_preempt_disable
- *
- * This is a scheduler safe way to enable preemption and not miss
- * any preemption checks. The disabled saved the state of preemption.
- * If resched is set, then we are either inside an atomic or
- * are inside the scheduler (we would have already scheduled
- * otherwise). In this case, we do not want to call normal
- * preempt_enable, but preempt_enable_no_resched instead.
- */
-static inline void ftrace_preempt_enable(int resched)
-{
-       if (resched)
-               preempt_enable_no_resched_notrace();
-       else
-               preempt_enable_notrace();
-}
-
 #ifdef CONFIG_BRANCH_TRACER
 extern int enable_branch_tracing(struct trace_array *tr);
 extern void disable_branch_tracing(void);
@@ -766,6 +703,8 @@ struct filter_pred {
        int                     pop_n;
 };
 
+extern struct list_head ftrace_common_fields;
+
 extern enum regex_type
 filter_parse_regex(char *buff, int len, char **search, int *not);
 extern void print_event_filter(struct ftrace_event_call *call,
@@ -795,6 +734,8 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,
        return 0;
 }
 
+extern void trace_event_enable_cmd_record(bool enable);
+
 extern struct mutex event_mutex;
 extern struct list_head ftrace_events;
 
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
deleted file mode 100644 (file)
index c21d5f3..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * ring buffer based initcalls tracer
- *
- * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/debugfs.h>
-#include <linux/ftrace.h>
-#include <linux/kallsyms.h>
-#include <linux/time.h>
-
-#include "trace.h"
-#include "trace_output.h"
-
-static struct trace_array *boot_trace;
-static bool pre_initcalls_finished;
-
-/* Tells the boot tracer that the pre_smp_initcalls are finished.
- * So we are ready .
- * It doesn't enable sched events tracing however.
- * You have to call enable_boot_trace to do so.
- */
-void start_boot_trace(void)
-{
-       pre_initcalls_finished = true;
-}
-
-void enable_boot_trace(void)
-{
-       if (boot_trace && pre_initcalls_finished)
-               tracing_start_sched_switch_record();
-}
-
-void disable_boot_trace(void)
-{
-       if (boot_trace && pre_initcalls_finished)
-               tracing_stop_sched_switch_record();
-}
-
-static int boot_trace_init(struct trace_array *tr)
-{
-       boot_trace = tr;
-
-       if (!tr)
-               return 0;
-
-       tracing_reset_online_cpus(tr);
-
-       tracing_sched_switch_assign_trace(tr);
-       return 0;
-}
-
-static enum print_line_t
-initcall_call_print_line(struct trace_iterator *iter)
-{
-       struct trace_entry *entry = iter->ent;
-       struct trace_seq *s = &iter->seq;
-       struct trace_boot_call *field;
-       struct boot_trace_call *call;
-       u64 ts;
-       unsigned long nsec_rem;
-       int ret;
-
-       trace_assign_type(field, entry);
-       call = &field->boot_call;
-       ts = iter->ts;
-       nsec_rem = do_div(ts, NSEC_PER_SEC);
-
-       ret = trace_seq_printf(s, "[%5ld.%09ld] calling  %s @ %i\n",
-                       (unsigned long)ts, nsec_rem, call->func, call->caller);
-
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-       else
-               return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t
-initcall_ret_print_line(struct trace_iterator *iter)
-{
-       struct trace_entry *entry = iter->ent;
-       struct trace_seq *s = &iter->seq;
-       struct trace_boot_ret *field;
-       struct boot_trace_ret *init_ret;
-       u64 ts;
-       unsigned long nsec_rem;
-       int ret;
-
-       trace_assign_type(field, entry);
-       init_ret = &field->boot_ret;
-       ts = iter->ts;
-       nsec_rem = do_div(ts, NSEC_PER_SEC);
-
-       ret = trace_seq_printf(s, "[%5ld.%09ld] initcall %s "
-                       "returned %d after %llu msecs\n",
-                       (unsigned long) ts,
-                       nsec_rem,
-                       init_ret->func, init_ret->result, init_ret->duration);
-
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-       else
-               return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t initcall_print_line(struct trace_iterator *iter)
-{
-       struct trace_entry *entry = iter->ent;
-
-       switch (entry->type) {
-       case TRACE_BOOT_CALL:
-               return initcall_call_print_line(iter);
-       case TRACE_BOOT_RET:
-               return initcall_ret_print_line(iter);
-       default:
-               return TRACE_TYPE_UNHANDLED;
-       }
-}
-
-struct tracer boot_tracer __read_mostly =
-{
-       .name           = "initcall",
-       .init           = boot_trace_init,
-       .reset          = tracing_reset_online_cpus,
-       .print_line     = initcall_print_line,
-};
-
-void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
-{
-       struct ftrace_event_call *call = &event_boot_call;
-       struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
-       struct trace_boot_call *entry;
-       struct trace_array *tr = boot_trace;
-
-       if (!tr || !pre_initcalls_finished)
-               return;
-
-       /* Get its name now since this function could
-        * disappear because it is in the .init section.
-        */
-       sprint_symbol(bt->func, (unsigned long)fn);
-       preempt_disable();
-
-       buffer = tr->buffer;
-       event = trace_buffer_lock_reserve(buffer, TRACE_BOOT_CALL,
-                                         sizeof(*entry), 0, 0);
-       if (!event)
-               goto out;
-       entry   = ring_buffer_event_data(event);
-       entry->boot_call = *bt;
-       if (!filter_check_discard(call, entry, buffer, event))
-               trace_buffer_unlock_commit(buffer, event, 0, 0);
- out:
-       preempt_enable();
-}
-
-void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
-{
-       struct ftrace_event_call *call = &event_boot_ret;
-       struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
-       struct trace_boot_ret *entry;
-       struct trace_array *tr = boot_trace;
-
-       if (!tr || !pre_initcalls_finished)
-               return;
-
-       sprint_symbol(bt->func, (unsigned long)fn);
-       preempt_disable();
-
-       buffer = tr->buffer;
-       event = trace_buffer_lock_reserve(buffer, TRACE_BOOT_RET,
-                                         sizeof(*entry), 0, 0);
-       if (!event)
-               goto out;
-       entry   = ring_buffer_event_data(event);
-       entry->boot_ret = *bt;
-       if (!filter_check_discard(call, entry, buffer, event))
-               trace_buffer_unlock_commit(buffer, event, 0, 0);
- out:
-       preempt_enable();
-}
index 9d589d8dcd1aa7e9470b6868980a20c4aeaf6160..685a67d55db09ced33759b19e56aecb73db7696b 100644 (file)
 u64 notrace trace_clock_local(void)
 {
        u64 clock;
-       int resched;
 
        /*
         * sched_clock() is an architecture implemented, fast, scalable,
         * lockless clock. It is not guaranteed to be coherent across
         * CPUs, nor across CPU idle events.
         */
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
        clock = sched_clock();
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
 
        return clock;
 }
@@ -56,7 +55,7 @@ u64 notrace trace_clock_local(void)
  */
 u64 notrace trace_clock(void)
 {
-       return cpu_clock(raw_smp_processor_id());
+       return local_clock();
 }
 
 
index dc008c1240da54ae8ebc6fcccb204ad205897e96..e3dfecaf13e6adb65b33347b33be299f164766e8 100644 (file)
@@ -150,23 +150,6 @@ FTRACE_ENTRY_DUP(wakeup, ctx_switch_entry,
                )
 );
 
-/*
- * Special (free-form) trace entry:
- */
-FTRACE_ENTRY(special, special_entry,
-
-       TRACE_SPECIAL,
-
-       F_STRUCT(
-               __field(        unsigned long,  arg1    )
-               __field(        unsigned long,  arg2    )
-               __field(        unsigned long,  arg3    )
-       ),
-
-       F_printk("(%08lx) (%08lx) (%08lx)",
-                __entry->arg1, __entry->arg2, __entry->arg3)
-);
-
 /*
  * Stack-trace entry:
  */
@@ -271,33 +254,6 @@ FTRACE_ENTRY(mmiotrace_map, trace_mmiotrace_map,
                 __entry->map_id, __entry->opcode)
 );
 
-FTRACE_ENTRY(boot_call, trace_boot_call,
-
-       TRACE_BOOT_CALL,
-
-       F_STRUCT(
-               __field_struct( struct boot_trace_call, boot_call       )
-               __field_desc(   pid_t,  boot_call,      caller          )
-               __array_desc(   char,   boot_call,      func,   KSYM_SYMBOL_LEN)
-       ),
-
-       F_printk("%d  %s", __entry->caller, __entry->func)
-);
-
-FTRACE_ENTRY(boot_ret, trace_boot_ret,
-
-       TRACE_BOOT_RET,
-
-       F_STRUCT(
-               __field_struct( struct boot_trace_ret,  boot_ret        )
-               __array_desc(   char,   boot_ret,       func,   KSYM_SYMBOL_LEN)
-               __field_desc(   int,    boot_ret,       result          )
-               __field_desc(   unsigned long, boot_ret, duration       )
-       ),
-
-       F_printk("%s %d %lx",
-                __entry->func, __entry->result, __entry->duration)
-);
 
 #define TRACE_FUNC_SIZE 30
 #define TRACE_FILE_SIZE 20
@@ -318,53 +274,3 @@ FTRACE_ENTRY(branch, trace_branch,
                 __entry->func, __entry->file, __entry->correct)
 );
 
-FTRACE_ENTRY(kmem_alloc, kmemtrace_alloc_entry,
-
-       TRACE_KMEM_ALLOC,
-
-       F_STRUCT(
-               __field(        enum kmemtrace_type_id, type_id         )
-               __field(        unsigned long,          call_site       )
-               __field(        const void *,           ptr             )
-               __field(        size_t,                 bytes_req       )
-               __field(        size_t,                 bytes_alloc     )
-               __field(        gfp_t,                  gfp_flags       )
-               __field(        int,                    node            )
-       ),
-
-       F_printk("type:%u call_site:%lx ptr:%p req:%zi alloc:%zi"
-                " flags:%x node:%d",
-                __entry->type_id, __entry->call_site, __entry->ptr,
-                __entry->bytes_req, __entry->bytes_alloc,
-                __entry->gfp_flags, __entry->node)
-);
-
-FTRACE_ENTRY(kmem_free, kmemtrace_free_entry,
-
-       TRACE_KMEM_FREE,
-
-       F_STRUCT(
-               __field(        enum kmemtrace_type_id, type_id         )
-               __field(        unsigned long,          call_site       )
-               __field(        const void *,           ptr             )
-       ),
-
-       F_printk("type:%u call_site:%lx ptr:%p",
-                __entry->type_id, __entry->call_site, __entry->ptr)
-);
-
-FTRACE_ENTRY(ksym_trace, ksym_trace_entry,
-
-       TRACE_KSYM,
-
-       F_STRUCT(
-               __field(        unsigned long,  ip                        )
-               __field(        unsigned char,  type                      )
-               __array(        char         ,  cmd,       TASK_COMM_LEN  )
-               __field(        unsigned long,  addr                      )
-       ),
-
-       F_printk("ip: %pF type: %d ksym_name: %pS cmd: %s",
-               (void *)__entry->ip, (unsigned int)__entry->type,
-               (void *)__entry->addr,  __entry->cmd)
-);
index 8a2b73f7c0683358541272bd58ea32625f83aa65..000e6e85b445906893d7003b2f28c615453bb726 100644 (file)
@@ -9,8 +9,6 @@
 #include <linux/kprobes.h>
 #include "trace.h"
 
-EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs);
-
 static char *perf_trace_buf[4];
 
 /*
@@ -56,13 +54,7 @@ static int perf_trace_event_init(struct ftrace_event_call *tp_event,
                }
        }
 
-       if (tp_event->class->reg)
-               ret = tp_event->class->reg(tp_event, TRACE_REG_PERF_REGISTER);
-       else
-               ret = tracepoint_probe_register(tp_event->name,
-                                               tp_event->class->perf_probe,
-                                               tp_event);
-
+       ret = tp_event->class->reg(tp_event, TRACE_REG_PERF_REGISTER);
        if (ret)
                goto fail;
 
@@ -96,9 +88,7 @@ int perf_trace_init(struct perf_event *p_event)
        mutex_lock(&event_mutex);
        list_for_each_entry(tp_event, &ftrace_events, list) {
                if (tp_event->event.type == event_id &&
-                   tp_event->class &&
-                   (tp_event->class->perf_probe ||
-                    tp_event->class->reg) &&
+                   tp_event->class && tp_event->class->reg &&
                    try_module_get(tp_event->mod)) {
                        ret = perf_trace_event_init(tp_event, p_event);
                        break;
@@ -138,18 +128,13 @@ void perf_trace_destroy(struct perf_event *p_event)
        if (--tp_event->perf_refcount > 0)
                goto out;
 
-       if (tp_event->class->reg)
-               tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER);
-       else
-               tracepoint_probe_unregister(tp_event->name,
-                                           tp_event->class->perf_probe,
-                                           tp_event);
+       tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER);
 
        /*
-        * Ensure our callback won't be called anymore. See
-        * tracepoint_probe_unregister() and __DO_TRACE().
+        * Ensure our callback won't be called anymore. The buffers
+        * will be freed after that.
         */
-       synchronize_sched();
+       tracepoint_synchronize_unregister();
 
        free_percpu(tp_event->perf_events);
        tp_event->perf_events = NULL;
index 53cffc0b08014db76d9e87da0d8bbc3c9768bd49..09b4fa6e4d3be8b83758c48a529d01a6f18010da 100644 (file)
@@ -28,6 +28,7 @@
 DEFINE_MUTEX(event_mutex);
 
 LIST_HEAD(ftrace_events);
+LIST_HEAD(ftrace_common_fields);
 
 struct list_head *
 trace_get_fields(struct ftrace_event_call *event_call)
@@ -37,15 +38,11 @@ trace_get_fields(struct ftrace_event_call *event_call)
        return event_call->class->get_fields(event_call);
 }
 
-int trace_define_field(struct ftrace_event_call *call, const char *type,
-                      const char *name, int offset, int size, int is_signed,
-                      int filter_type)
+static int __trace_define_field(struct list_head *head, const char *type,
+                               const char *name, int offset, int size,
+                               int is_signed, int filter_type)
 {
        struct ftrace_event_field *field;
-       struct list_head *head;
-
-       if (WARN_ON(!call->class))
-               return 0;
 
        field = kzalloc(sizeof(*field), GFP_KERNEL);
        if (!field)
@@ -68,7 +65,6 @@ int trace_define_field(struct ftrace_event_call *call, const char *type,
        field->size = size;
        field->is_signed = is_signed;
 
-       head = trace_get_fields(call);
        list_add(&field->link, head);
 
        return 0;
@@ -80,17 +76,32 @@ err:
 
        return -ENOMEM;
 }
+
+int trace_define_field(struct ftrace_event_call *call, const char *type,
+                      const char *name, int offset, int size, int is_signed,
+                      int filter_type)
+{
+       struct list_head *head;
+
+       if (WARN_ON(!call->class))
+               return 0;
+
+       head = trace_get_fields(call);
+       return __trace_define_field(head, type, name, offset, size,
+                                   is_signed, filter_type);
+}
 EXPORT_SYMBOL_GPL(trace_define_field);
 
 #define __common_field(type, item)                                     \
-       ret = trace_define_field(call, #type, "common_" #item,          \
-                                offsetof(typeof(ent), item),           \
-                                sizeof(ent.item),                      \
-                                is_signed_type(type), FILTER_OTHER);   \
+       ret = __trace_define_field(&ftrace_common_fields, #type,        \
+                                  "common_" #item,                     \
+                                  offsetof(typeof(ent), item),         \
+                                  sizeof(ent.item),                    \
+                                  is_signed_type(type), FILTER_OTHER); \
        if (ret)                                                        \
                return ret;
 
-static int trace_define_common_fields(struct ftrace_event_call *call)
+static int trace_define_common_fields(void)
 {
        int ret;
        struct trace_entry ent;
@@ -130,6 +141,55 @@ int trace_event_raw_init(struct ftrace_event_call *call)
 }
 EXPORT_SYMBOL_GPL(trace_event_raw_init);
 
+int ftrace_event_reg(struct ftrace_event_call *call, enum trace_reg type)
+{
+       switch (type) {
+       case TRACE_REG_REGISTER:
+               return tracepoint_probe_register(call->name,
+                                                call->class->probe,
+                                                call);
+       case TRACE_REG_UNREGISTER:
+               tracepoint_probe_unregister(call->name,
+                                           call->class->probe,
+                                           call);
+               return 0;
+
+#ifdef CONFIG_PERF_EVENTS
+       case TRACE_REG_PERF_REGISTER:
+               return tracepoint_probe_register(call->name,
+                                                call->class->perf_probe,
+                                                call);
+       case TRACE_REG_PERF_UNREGISTER:
+               tracepoint_probe_unregister(call->name,
+                                           call->class->perf_probe,
+                                           call);
+               return 0;
+#endif
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ftrace_event_reg);
+
+void trace_event_enable_cmd_record(bool enable)
+{
+       struct ftrace_event_call *call;
+
+       mutex_lock(&event_mutex);
+       list_for_each_entry(call, &ftrace_events, list) {
+               if (!(call->flags & TRACE_EVENT_FL_ENABLED))
+                       continue;
+
+               if (enable) {
+                       tracing_start_cmdline_record();
+                       call->flags |= TRACE_EVENT_FL_RECORDED_CMD;
+               } else {
+                       tracing_stop_cmdline_record();
+                       call->flags &= ~TRACE_EVENT_FL_RECORDED_CMD;
+               }
+       }
+       mutex_unlock(&event_mutex);
+}
+
 static int ftrace_event_enable_disable(struct ftrace_event_call *call,
                                        int enable)
 {
@@ -139,24 +199,20 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call,
        case 0:
                if (call->flags & TRACE_EVENT_FL_ENABLED) {
                        call->flags &= ~TRACE_EVENT_FL_ENABLED;
-                       tracing_stop_cmdline_record();
-                       if (call->class->reg)
-                               call->class->reg(call, TRACE_REG_UNREGISTER);
-                       else
-                               tracepoint_probe_unregister(call->name,
-                                                           call->class->probe,
-                                                           call);
+                       if (call->flags & TRACE_EVENT_FL_RECORDED_CMD) {
+                               tracing_stop_cmdline_record();
+                               call->flags &= ~TRACE_EVENT_FL_RECORDED_CMD;
+                       }
+                       call->class->reg(call, TRACE_REG_UNREGISTER);
                }
                break;
        case 1:
                if (!(call->flags & TRACE_EVENT_FL_ENABLED)) {
-                       tracing_start_cmdline_record();
-                       if (call->class->reg)
-                               ret = call->class->reg(call, TRACE_REG_REGISTER);
-                       else
-                               ret = tracepoint_probe_register(call->name,
-                                                               call->class->probe,
-                                                               call);
+                       if (trace_flags & TRACE_ITER_RECORD_CMD) {
+                               tracing_start_cmdline_record();
+                               call->flags |= TRACE_EVENT_FL_RECORDED_CMD;
+                       }
+                       ret = call->class->reg(call, TRACE_REG_REGISTER);
                        if (ret) {
                                tracing_stop_cmdline_record();
                                pr_info("event trace: Could not enable event "
@@ -194,8 +250,7 @@ static int __ftrace_set_clr_event(const char *match, const char *sub,
        mutex_lock(&event_mutex);
        list_for_each_entry(call, &ftrace_events, list) {
 
-               if (!call->name || !call->class ||
-                   (!call->class->probe && !call->class->reg))
+               if (!call->name || !call->class || !call->class->reg)
                        continue;
 
                if (match &&
@@ -321,7 +376,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
                 * The ftrace subsystem is for showing formats only.
                 * They can not be enabled or disabled via the event files.
                 */
-               if (call->class && (call->class->probe || call->class->reg))
+               if (call->class && call->class->reg)
                        return call;
        }
 
@@ -474,8 +529,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
 
        mutex_lock(&event_mutex);
        list_for_each_entry(call, &ftrace_events, list) {
-               if (!call->name || !call->class ||
-                   (!call->class->probe && !call->class->reg))
+               if (!call->name || !call->class || !call->class->reg)
                        continue;
 
                if (system && strcmp(call->class->system, system) != 0)
@@ -544,32 +598,10 @@ out:
        return ret;
 }
 
-static ssize_t
-event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
-                 loff_t *ppos)
+static void print_event_fields(struct trace_seq *s, struct list_head *head)
 {
-       struct ftrace_event_call *call = filp->private_data;
        struct ftrace_event_field *field;
-       struct list_head *head;
-       struct trace_seq *s;
-       int common_field_count = 5;
-       char *buf;
-       int r = 0;
-
-       if (*ppos)
-               return 0;
-
-       s = kmalloc(sizeof(*s), GFP_KERNEL);
-       if (!s)
-               return -ENOMEM;
-
-       trace_seq_init(s);
-
-       trace_seq_printf(s, "name: %s\n", call->name);
-       trace_seq_printf(s, "ID: %d\n", call->event.type);
-       trace_seq_printf(s, "format:\n");
 
-       head = trace_get_fields(call);
        list_for_each_entry_reverse(field, head, link) {
                /*
                 * Smartly shows the array type(except dynamic array).
@@ -584,29 +616,54 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
                        array_descriptor = NULL;
 
                if (!array_descriptor) {
-                       r = trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"
+                       trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"
                                        "\tsize:%u;\tsigned:%d;\n",
                                        field->type, field->name, field->offset,
                                        field->size, !!field->is_signed);
                } else {
-                       r = trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"
+                       trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"
                                        "\tsize:%u;\tsigned:%d;\n",
                                        (int)(array_descriptor - field->type),
                                        field->type, field->name,
                                        array_descriptor, field->offset,
                                        field->size, !!field->is_signed);
                }
+       }
+}
 
-               if (--common_field_count == 0)
-                       r = trace_seq_printf(s, "\n");
+static ssize_t
+event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
+                 loff_t *ppos)
+{
+       struct ftrace_event_call *call = filp->private_data;
+       struct list_head *head;
+       struct trace_seq *s;
+       char *buf;
+       int r;
 
-               if (!r)
-                       break;
-       }
+       if (*ppos)
+               return 0;
+
+       s = kmalloc(sizeof(*s), GFP_KERNEL);
+       if (!s)
+               return -ENOMEM;
+
+       trace_seq_init(s);
+
+       trace_seq_printf(s, "name: %s\n", call->name);
+       trace_seq_printf(s, "ID: %d\n", call->event.type);
+       trace_seq_printf(s, "format:\n");
+
+       /* print common fields */
+       print_event_fields(s, &ftrace_common_fields);
 
-       if (r)
-               r = trace_seq_printf(s, "\nprint fmt: %s\n",
-                               call->print_fmt);
+       trace_seq_putc(s, '\n');
+
+       /* print event specific fields */
+       head = trace_get_fields(call);
+       print_event_fields(s, head);
+
+       r = trace_seq_printf(s, "\nprint fmt: %s\n", call->print_fmt);
 
        if (!r) {
                /*
@@ -963,35 +1020,31 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
                return -1;
        }
 
-       if (call->class->probe || call->class->reg)
+       if (call->class->reg)
                trace_create_file("enable", 0644, call->dir, call,
                                  enable);
 
 #ifdef CONFIG_PERF_EVENTS
-       if (call->event.type && (call->class->perf_probe || call->class->reg))
+       if (call->event.type && call->class->reg)
                trace_create_file("id", 0444, call->dir, call,
                                  id);
 #endif
 
-       if (call->class->define_fields) {
-               /*
-                * Other events may have the same class. Only update
-                * the fields if they are not already defined.
-                */
-               head = trace_get_fields(call);
-               if (list_empty(head)) {
-                       ret = trace_define_common_fields(call);
-                       if (!ret)
-                               ret = call->class->define_fields(call);
-                       if (ret < 0) {
-                               pr_warning("Could not initialize trace point"
-                                          " events/%s\n", call->name);
-                               return ret;
-                       }
+       /*
+        * Other events may have the same class. Only update
+        * the fields if they are not already defined.
+        */
+       head = trace_get_fields(call);
+       if (list_empty(head)) {
+               ret = call->class->define_fields(call);
+               if (ret < 0) {
+                       pr_warning("Could not initialize trace point"
+                                  " events/%s\n", call->name);
+                       return ret;
                }
-               trace_create_file("filter", 0644, call->dir, call,
-                                 filter);
        }
+       trace_create_file("filter", 0644, call->dir, call,
+                         filter);
 
        trace_create_file("format", 0444, call->dir, call,
                          format);
@@ -999,11 +1052,17 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
        return 0;
 }
 
-static int __trace_add_event_call(struct ftrace_event_call *call)
+static int
+__trace_add_event_call(struct ftrace_event_call *call, struct module *mod,
+                      const struct file_operations *id,
+                      const struct file_operations *enable,
+                      const struct file_operations *filter,
+                      const struct file_operations *format)
 {
        struct dentry *d_events;
        int ret;
 
+       /* The linker may leave blanks */
        if (!call->name)
                return -EINVAL;
 
@@ -1011,8 +1070,8 @@ static int __trace_add_event_call(struct ftrace_event_call *call)
                ret = call->class->raw_init(call);
                if (ret < 0) {
                        if (ret != -ENOSYS)
-                               pr_warning("Could not initialize trace "
-                               "events/%s\n", call->name);
+                               pr_warning("Could not initialize trace events/%s\n",
+                                          call->name);
                        return ret;
                }
        }
@@ -1021,11 +1080,10 @@ static int __trace_add_event_call(struct ftrace_event_call *call)
        if (!d_events)
                return -ENOENT;
 
-       ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
-                               &ftrace_enable_fops, &ftrace_event_filter_fops,
-                               &ftrace_event_format_fops);
+       ret = event_create_dir(call, d_events, id, enable, filter, format);
        if (!ret)
                list_add(&call->list, &ftrace_events);
+       call->mod = mod;
 
        return ret;
 }
@@ -1035,7 +1093,10 @@ int trace_add_event_call(struct ftrace_event_call *call)
 {
        int ret;
        mutex_lock(&event_mutex);
-       ret = __trace_add_event_call(call);
+       ret = __trace_add_event_call(call, NULL, &ftrace_event_id_fops,
+                                    &ftrace_enable_fops,
+                                    &ftrace_event_filter_fops,
+                                    &ftrace_event_format_fops);
        mutex_unlock(&event_mutex);
        return ret;
 }
@@ -1152,8 +1213,6 @@ static void trace_module_add_events(struct module *mod)
 {
        struct ftrace_module_file_ops *file_ops = NULL;
        struct ftrace_event_call *call, *start, *end;
-       struct dentry *d_events;
-       int ret;
 
        start = mod->trace_events;
        end = mod->trace_events + mod->num_trace_events;
@@ -1161,38 +1220,14 @@ static void trace_module_add_events(struct module *mod)
        if (start == end)
                return;
 
-       d_events = event_trace_events_dir();
-       if (!d_events)
+       file_ops = trace_create_file_ops(mod);
+       if (!file_ops)
                return;
 
        for_each_event(call, start, end) {
-               /* The linker may leave blanks */
-               if (!call->name)
-                       continue;
-               if (call->class->raw_init) {
-                       ret = call->class->raw_init(call);
-                       if (ret < 0) {
-                               if (ret != -ENOSYS)
-                                       pr_warning("Could not initialize trace "
-                                       "point events/%s\n", call->name);
-                               continue;
-                       }
-               }
-               /*
-                * This module has events, create file ops for this module
-                * if not already done.
-                */
-               if (!file_ops) {
-                       file_ops = trace_create_file_ops(mod);
-                       if (!file_ops)
-                               return;
-               }
-               call->mod = mod;
-               ret = event_create_dir(call, d_events,
+               __trace_add_event_call(call, mod,
                                       &file_ops->id, &file_ops->enable,
                                       &file_ops->filter, &file_ops->format);
-               if (!ret)
-                       list_add(&call->list, &ftrace_events);
        }
 }
 
@@ -1319,25 +1354,14 @@ static __init int event_trace_init(void)
        trace_create_file("enable", 0644, d_events,
                          NULL, &ftrace_system_enable_fops);
 
+       if (trace_define_common_fields())
+               pr_warning("tracing: Failed to allocate common fields");
+
        for_each_event(call, __start_ftrace_events, __stop_ftrace_events) {
-               /* The linker may leave blanks */
-               if (!call->name)
-                       continue;
-               if (call->class->raw_init) {
-                       ret = call->class->raw_init(call);
-                       if (ret < 0) {
-                               if (ret != -ENOSYS)
-                                       pr_warning("Could not initialize trace "
-                                       "point events/%s\n", call->name);
-                               continue;
-                       }
-               }
-               ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
+               __trace_add_event_call(call, NULL, &ftrace_event_id_fops,
                                       &ftrace_enable_fops,
                                       &ftrace_event_filter_fops,
                                       &ftrace_event_format_fops);
-               if (!ret)
-                       list_add(&call->list, &ftrace_events);
        }
 
        while (true) {
@@ -1524,12 +1548,11 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip)
        struct ftrace_entry *entry;
        unsigned long flags;
        long disabled;
-       int resched;
        int cpu;
        int pc;
 
        pc = preempt_count();
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
        cpu = raw_smp_processor_id();
        disabled = atomic_inc_return(&per_cpu(ftrace_test_event_disable, cpu));
 
@@ -1551,7 +1574,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip)
 
  out:
        atomic_dec(&per_cpu(ftrace_test_event_disable, cpu));
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
 }
 
 static struct ftrace_ops trace_ops __initdata  =
index 57bb1bb329997f62bc5805e6a3af8d5ecf64479a..36d40104b17f6d53cdc89b45841cff2679551c56 100644 (file)
@@ -497,12 +497,10 @@ void print_subsystem_event_filter(struct event_subsystem *system,
 }
 
 static struct ftrace_event_field *
-find_event_field(struct ftrace_event_call *call, char *name)
+__find_event_field(struct list_head *head, char *name)
 {
        struct ftrace_event_field *field;
-       struct list_head *head;
 
-       head = trace_get_fields(call);
        list_for_each_entry(field, head, link) {
                if (!strcmp(field->name, name))
                        return field;
@@ -511,6 +509,20 @@ find_event_field(struct ftrace_event_call *call, char *name)
        return NULL;
 }
 
+static struct ftrace_event_field *
+find_event_field(struct ftrace_event_call *call, char *name)
+{
+       struct ftrace_event_field *field;
+       struct list_head *head;
+
+       field = __find_event_field(&ftrace_common_fields, name);
+       if (field)
+               return field;
+
+       head = trace_get_fields(call);
+       return __find_event_field(head, name);
+}
+
 static void filter_free_pred(struct filter_pred *pred)
 {
        if (!pred)
@@ -627,9 +639,6 @@ static int init_subsystem_preds(struct event_subsystem *system)
        int err;
 
        list_for_each_entry(call, &ftrace_events, list) {
-               if (!call->class || !call->class->define_fields)
-                       continue;
-
                if (strcmp(call->class->system, system->name) != 0)
                        continue;
 
@@ -646,9 +655,6 @@ static void filter_free_subsystem_preds(struct event_subsystem *system)
        struct ftrace_event_call *call;
 
        list_for_each_entry(call, &ftrace_events, list) {
-               if (!call->class || !call->class->define_fields)
-                       continue;
-
                if (strcmp(call->class->system, system->name) != 0)
                        continue;
 
@@ -1251,9 +1257,6 @@ static int replace_system_preds(struct event_subsystem *system,
        list_for_each_entry(call, &ftrace_events, list) {
                struct event_filter *filter = call->filter;
 
-               if (!call->class || !call->class->define_fields)
-                       continue;
-
                if (strcmp(call->class->system, system->name) != 0)
                        continue;
 
index 8536e2a659690f5aa82935ec20eb7d8fa74e3b5f..4ba44deaac259d05fb67d5d31e8ce5371844a414 100644 (file)
@@ -125,12 +125,6 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call)  \
 
 #include "trace_entries.h"
 
-static int ftrace_raw_init_event(struct ftrace_event_call *call)
-{
-       INIT_LIST_HEAD(&call->class->fields);
-       return 0;
-}
-
 #undef __entry
 #define __entry REC
 
@@ -158,7 +152,7 @@ static int ftrace_raw_init_event(struct ftrace_event_call *call)
 struct ftrace_event_class event_class_ftrace_##call = {                        \
        .system                 = __stringify(TRACE_SYSTEM),            \
        .define_fields          = ftrace_define_fields_##call,          \
-       .raw_init               = ftrace_raw_init_event,                \
+       .fields                 = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\
 };                                                                     \
                                                                        \
 struct ftrace_event_call __used                                                \
index b3f3776b0cd64002605f6c3d2f2dc9528f2b9932..16aee4d44e8fd3e121c2dc4910a120968d01d5d8 100644 (file)
@@ -54,14 +54,14 @@ function_trace_call_preempt_only(unsigned long ip, unsigned long parent_ip)
        struct trace_array_cpu *data;
        unsigned long flags;
        long disabled;
-       int cpu, resched;
+       int cpu;
        int pc;
 
        if (unlikely(!ftrace_function_enabled))
                return;
 
        pc = preempt_count();
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
        local_save_flags(flags);
        cpu = raw_smp_processor_id();
        data = tr->data[cpu];
@@ -71,7 +71,7 @@ function_trace_call_preempt_only(unsigned long ip, unsigned long parent_ip)
                trace_function(tr, ip, parent_ip, flags, pc);
 
        atomic_dec(&data->disabled);
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
 }
 
 static void
index 79f4bac99a94a767569a8247091eb7fd196fae7b..6bff2362578115f4a087195362a5257c3b838d42 100644 (file)
@@ -641,7 +641,8 @@ trace_print_graph_duration(unsigned long long duration, struct trace_seq *s)
 
        /* Print nsecs (we don't want to exceed 7 numbers) */
        if (len < 7) {
-               snprintf(nsecs_str, 8 - len, "%03lu", nsecs_rem);
+               snprintf(nsecs_str, min(sizeof(nsecs_str), 8UL - len), "%03lu",
+                        nsecs_rem);
                ret = trace_seq_printf(s, ".%s", nsecs_str);
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
index 6fd486e0cef407b1cf3c416d15c31be14bf8dd6a..73a6b0601f2e301c0cd5575cc96f7f0b788853d9 100644 (file)
@@ -649,6 +649,7 @@ static struct tracer irqsoff_tracer __read_mostly =
 #endif
        .open           = irqsoff_trace_open,
        .close          = irqsoff_trace_close,
+       .use_max_tr     = 1,
 };
 # define register_irqsoff(trace) register_tracer(&trace)
 #else
@@ -681,6 +682,7 @@ static struct tracer preemptoff_tracer __read_mostly =
 #endif
        .open           = irqsoff_trace_open,
        .close          = irqsoff_trace_close,
+       .use_max_tr     = 1,
 };
 # define register_preemptoff(trace) register_tracer(&trace)
 #else
@@ -715,6 +717,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
 #endif
        .open           = irqsoff_trace_open,
        .close          = irqsoff_trace_close,
+       .use_max_tr     = 1,
 };
 
 # define register_preemptirqsoff(trace) register_tracer(&trace)
diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c
new file mode 100644 (file)
index 0000000..7b8ecd7
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * kdb helper for dumping the ftrace buffer
+ *
+ * Copyright (C) 2010 Jason Wessel <jason.wessel@windriver.com>
+ *
+ * ftrace_dump_buf based on ftrace_dump:
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
+ *
+ */
+#include <linux/init.h>
+#include <linux/kgdb.h>
+#include <linux/kdb.h>
+#include <linux/ftrace.h>
+
+#include "../debug/kdb/kdb_private.h"
+#include "trace.h"
+#include "trace_output.h"
+
+static void ftrace_dump_buf(int skip_lines, long cpu_file)
+{
+       /* use static because iter can be a bit big for the stack */
+       static struct trace_iterator iter;
+       unsigned int old_userobj;
+       int cnt = 0, cpu;
+
+       trace_init_global_iter(&iter);
+
+       for_each_tracing_cpu(cpu) {
+               atomic_inc(&iter.tr->data[cpu]->disabled);
+       }
+
+       old_userobj = trace_flags;
+
+       /* don't look at user memory in panic mode */
+       trace_flags &= ~TRACE_ITER_SYM_USEROBJ;
+
+       kdb_printf("Dumping ftrace buffer:\n");
+
+       /* reset all but tr, trace, and overruns */
+       memset(&iter.seq, 0,
+                  sizeof(struct trace_iterator) -
+                  offsetof(struct trace_iterator, seq));
+       iter.iter_flags |= TRACE_FILE_LAT_FMT;
+       iter.pos = -1;
+
+       if (cpu_file == TRACE_PIPE_ALL_CPU) {
+               for_each_tracing_cpu(cpu) {
+                       iter.buffer_iter[cpu] =
+                       ring_buffer_read_prepare(iter.tr->buffer, cpu);
+                       ring_buffer_read_start(iter.buffer_iter[cpu]);
+                       tracing_iter_reset(&iter, cpu);
+               }
+       } else {
+               iter.cpu_file = cpu_file;
+               iter.buffer_iter[cpu_file] =
+                       ring_buffer_read_prepare(iter.tr->buffer, cpu_file);
+               ring_buffer_read_start(iter.buffer_iter[cpu_file]);
+               tracing_iter_reset(&iter, cpu_file);
+       }
+       if (!trace_empty(&iter))
+               trace_find_next_entry_inc(&iter);
+       while (!trace_empty(&iter)) {
+               if (!cnt)
+                       kdb_printf("---------------------------------\n");
+               cnt++;
+
+               if (trace_find_next_entry_inc(&iter) != NULL && !skip_lines)
+                       print_trace_line(&iter);
+               if (!skip_lines)
+                       trace_printk_seq(&iter.seq);
+               else
+                       skip_lines--;
+               if (KDB_FLAG(CMD_INTERRUPT))
+                       goto out;
+       }
+
+       if (!cnt)
+               kdb_printf("   (ftrace buffer empty)\n");
+       else
+               kdb_printf("---------------------------------\n");
+
+out:
+       trace_flags = old_userobj;
+
+       for_each_tracing_cpu(cpu) {
+               atomic_dec(&iter.tr->data[cpu]->disabled);
+       }
+
+       for_each_tracing_cpu(cpu)
+               if (iter.buffer_iter[cpu])
+                       ring_buffer_read_finish(iter.buffer_iter[cpu]);
+}
+
+/*
+ * kdb_ftdump - Dump the ftrace log buffer
+ */
+static int kdb_ftdump(int argc, const char **argv)
+{
+       int skip_lines = 0;
+       long cpu_file;
+       char *cp;
+
+       if (argc > 2)
+               return KDB_ARGCOUNT;
+
+       if (argc) {
+               skip_lines = simple_strtol(argv[1], &cp, 0);
+               if (*cp)
+                       skip_lines = 0;
+       }
+
+       if (argc == 2) {
+               cpu_file = simple_strtol(argv[2], &cp, 0);
+               if (*cp || cpu_file >= NR_CPUS || cpu_file < 0 ||
+                   !cpu_online(cpu_file))
+                       return KDB_BADINT;
+       } else {
+               cpu_file = TRACE_PIPE_ALL_CPU;
+       }
+
+       kdb_trap_printk++;
+       ftrace_dump_buf(skip_lines, cpu_file);
+       kdb_trap_printk--;
+
+       return 0;
+}
+
+static __init int kdb_ftrace_register(void)
+{
+       kdb_register_repeat("ftdump", kdb_ftdump, "[skip_#lines] [cpu]",
+                           "Dump ftrace log", 0, KDB_REPEAT_NONE);
+       return 0;
+}
+
+late_initcall(kdb_ftrace_register);
index f52b5f50299dae5cc74dfe807054cd7d0e3f875e..8b27c9849b427905ea9a5ef83864a88526afe405 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/ptrace.h>
 #include <linux/perf_event.h>
 #include <linux/stringify.h>
+#include <linux/limits.h>
+#include <linux/uaccess.h>
 #include <asm/bitsperlong.h>
 
 #include "trace.h"
@@ -38,6 +40,7 @@
 #define MAX_TRACE_ARGS 128
 #define MAX_ARGSTR_LEN 63
 #define MAX_EVENT_NAME_LEN 64
+#define MAX_STRING_SIZE PATH_MAX
 #define KPROBE_EVENT_SYSTEM "kprobes"
 
 /* Reserved field names */
@@ -58,14 +61,16 @@ const char *reserved_field_names[] = {
 };
 
 /* Printing function type */
-typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *);
+typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *,
+                                void *);
 #define PRINT_TYPE_FUNC_NAME(type)     print_type_##type
 #define PRINT_TYPE_FMT_NAME(type)      print_type_format_##type
 
 /* Printing  in basic type function template */
 #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)                  \
 static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,   \
-                                               const char *name, void *data)\
+                                               const char *name,       \
+                                               void *data, void *ent)\
 {                                                                      \
        return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
 }                                                                      \
@@ -80,6 +85,49 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
 DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
 DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
 
+/* data_rloc: data relative location, compatible with u32 */
+#define make_data_rloc(len, roffs)     \
+       (((u32)(len) << 16) | ((u32)(roffs) & 0xffff))
+#define get_rloc_len(dl)       ((u32)(dl) >> 16)
+#define get_rloc_offs(dl)      ((u32)(dl) & 0xffff)
+
+static inline void *get_rloc_data(u32 *dl)
+{
+       return (u8 *)dl + get_rloc_offs(*dl);
+}
+
+/* For data_loc conversion */
+static inline void *get_loc_data(u32 *dl, void *ent)
+{
+       return (u8 *)ent + get_rloc_offs(*dl);
+}
+
+/*
+ * Convert data_rloc to data_loc:
+ *  data_rloc stores the offset from data_rloc itself, but data_loc
+ *  stores the offset from event entry.
+ */
+#define convert_rloc_to_loc(dl, offs)  ((u32)(dl) + (offs))
+
+/* For defining macros, define string/string_size types */
+typedef u32 string;
+typedef u32 string_size;
+
+/* Print type function for string type */
+static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
+                                                 const char *name,
+                                                 void *data, void *ent)
+{
+       int len = *(u32 *)data >> 16;
+
+       if (!len)
+               return trace_seq_printf(s, " %s=(fault)", name);
+       else
+               return trace_seq_printf(s, " %s=\"%s\"", name,
+                                       (const char *)get_loc_data(data, ent));
+}
+static const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
+
 /* Data fetch function type */
 typedef        void (*fetch_func_t)(struct pt_regs *, void *, void *);
 
@@ -94,32 +142,38 @@ static __kprobes void call_fetch(struct fetch_param *fprm,
        return fprm->fn(regs, fprm->data, dest);
 }
 
-#define FETCH_FUNC_NAME(kind, type)    fetch_##kind##_##type
+#define FETCH_FUNC_NAME(method, type)  fetch_##method##_##type
 /*
  * Define macro for basic types - we don't need to define s* types, because
  * we have to care only about bitwidth at recording time.
  */
-#define DEFINE_BASIC_FETCH_FUNCS(kind)  \
-DEFINE_FETCH_##kind(u8)                        \
-DEFINE_FETCH_##kind(u16)               \
-DEFINE_FETCH_##kind(u32)               \
-DEFINE_FETCH_##kind(u64)
-
-#define CHECK_BASIC_FETCH_FUNCS(kind, fn)      \
-       ((FETCH_FUNC_NAME(kind, u8) == fn) ||   \
-        (FETCH_FUNC_NAME(kind, u16) == fn) ||  \
-        (FETCH_FUNC_NAME(kind, u32) == fn) ||  \
-        (FETCH_FUNC_NAME(kind, u64) == fn))
+#define DEFINE_BASIC_FETCH_FUNCS(method) \
+DEFINE_FETCH_##method(u8)              \
+DEFINE_FETCH_##method(u16)             \
+DEFINE_FETCH_##method(u32)             \
+DEFINE_FETCH_##method(u64)
+
+#define CHECK_FETCH_FUNCS(method, fn)                  \
+       (((FETCH_FUNC_NAME(method, u8) == fn) ||        \
+         (FETCH_FUNC_NAME(method, u16) == fn) ||       \
+         (FETCH_FUNC_NAME(method, u32) == fn) ||       \
+         (FETCH_FUNC_NAME(method, u64) == fn) ||       \
+         (FETCH_FUNC_NAME(method, string) == fn) ||    \
+         (FETCH_FUNC_NAME(method, string_size) == fn)) \
+        && (fn != NULL))
 
 /* Data fetch function templates */
 #define DEFINE_FETCH_reg(type)                                         \
 static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \
-                                         void *offset, void *dest)     \
+                                       void *offset, void *dest)       \
 {                                                                      \
        *(type *)dest = (type)regs_get_register(regs,                   \
                                (unsigned int)((unsigned long)offset)); \
 }
 DEFINE_BASIC_FETCH_FUNCS(reg)
+/* No string on the register */
+#define fetch_reg_string NULL
+#define fetch_reg_string_size NULL
 
 #define DEFINE_FETCH_stack(type)                                       \
 static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
@@ -129,6 +183,9 @@ static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
                                (unsigned int)((unsigned long)offset)); \
 }
 DEFINE_BASIC_FETCH_FUNCS(stack)
+/* No string on the stack entry */
+#define fetch_stack_string NULL
+#define fetch_stack_string_size NULL
 
 #define DEFINE_FETCH_retval(type)                                      \
 static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
@@ -137,6 +194,9 @@ static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
        *(type *)dest = (type)regs_return_value(regs);                  \
 }
 DEFINE_BASIC_FETCH_FUNCS(retval)
+/* No string on the retval */
+#define fetch_retval_string NULL
+#define fetch_retval_string_size NULL
 
 #define DEFINE_FETCH_memory(type)                                      \
 static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
@@ -149,6 +209,62 @@ static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
                *(type *)dest = retval;                                 \
 }
 DEFINE_BASIC_FETCH_FUNCS(memory)
+/*
+ * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
+ * length and relative data location.
+ */
+static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
+                                                     void *addr, void *dest)
+{
+       long ret;
+       int maxlen = get_rloc_len(*(u32 *)dest);
+       u8 *dst = get_rloc_data(dest);
+       u8 *src = addr;
+       mm_segment_t old_fs = get_fs();
+       if (!maxlen)
+               return;
+       /*
+        * Try to get string again, since the string can be changed while
+        * probing.
+        */
+       set_fs(KERNEL_DS);
+       pagefault_disable();
+       do
+               ret = __copy_from_user_inatomic(dst++, src++, 1);
+       while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
+       dst[-1] = '\0';
+       pagefault_enable();
+       set_fs(old_fs);
+
+       if (ret < 0) {  /* Failed to fetch string */
+               ((u8 *)get_rloc_data(dest))[0] = '\0';
+               *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
+       } else
+               *(u32 *)dest = make_data_rloc(src - (u8 *)addr,
+                                             get_rloc_offs(*(u32 *)dest));
+}
+/* Return the length of string -- including null terminal byte */
+static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
+                                                       void *addr, void *dest)
+{
+       int ret, len = 0;
+       u8 c;
+       mm_segment_t old_fs = get_fs();
+
+       set_fs(KERNEL_DS);
+       pagefault_disable();
+       do {
+               ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
+               len++;
+       } while (c && ret == 0 && len < MAX_STRING_SIZE);
+       pagefault_enable();
+       set_fs(old_fs);
+
+       if (ret < 0)    /* Failed to check the length */
+               *(u32 *)dest = 0;
+       else
+               *(u32 *)dest = len;
+}
 
 /* Memory fetching by symbol */
 struct symbol_cache {
@@ -203,6 +319,8 @@ static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
                *(type *)dest = 0;                                      \
 }
 DEFINE_BASIC_FETCH_FUNCS(symbol)
+DEFINE_FETCH_symbol(string)
+DEFINE_FETCH_symbol(string_size)
 
 /* Dereference memory access function */
 struct deref_fetch_param {
@@ -224,12 +342,14 @@ static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
                *(type *)dest = 0;                                      \
 }
 DEFINE_BASIC_FETCH_FUNCS(deref)
+DEFINE_FETCH_deref(string)
+DEFINE_FETCH_deref(string_size)
 
 static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
 {
-       if (CHECK_BASIC_FETCH_FUNCS(deref, data->orig.fn))
+       if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
                free_deref_fetch_param(data->orig.data);
-       else if (CHECK_BASIC_FETCH_FUNCS(symbol, data->orig.fn))
+       else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
                free_symbol_cache(data->orig.data);
        kfree(data);
 }
@@ -240,23 +360,43 @@ static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
 #define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
 #define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
 
-#define ASSIGN_FETCH_FUNC(kind, type)  \
-       .kind = FETCH_FUNC_NAME(kind, type)
-
-#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)  \
-       {.name = #ptype,                        \
-        .size = sizeof(ftype),                 \
-        .is_signed = sign,                     \
-        .print = PRINT_TYPE_FUNC_NAME(ptype),  \
-        .fmt = PRINT_TYPE_FMT_NAME(ptype),     \
-ASSIGN_FETCH_FUNC(reg, ftype),                 \
-ASSIGN_FETCH_FUNC(stack, ftype),               \
-ASSIGN_FETCH_FUNC(retval, ftype),              \
-ASSIGN_FETCH_FUNC(memory, ftype),              \
-ASSIGN_FETCH_FUNC(symbol, ftype),              \
-ASSIGN_FETCH_FUNC(deref, ftype),               \
+/* Fetch types */
+enum {
+       FETCH_MTD_reg = 0,
+       FETCH_MTD_stack,
+       FETCH_MTD_retval,
+       FETCH_MTD_memory,
+       FETCH_MTD_symbol,
+       FETCH_MTD_deref,
+       FETCH_MTD_END,
+};
+
+#define ASSIGN_FETCH_FUNC(method, type)        \
+       [FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
+
+#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)        \
+       {.name = _name,                         \
+        .size = _size,                                 \
+        .is_signed = sign,                             \
+        .print = PRINT_TYPE_FUNC_NAME(ptype),          \
+        .fmt = PRINT_TYPE_FMT_NAME(ptype),             \
+        .fmttype = _fmttype,                           \
+        .fetch = {                                     \
+ASSIGN_FETCH_FUNC(reg, ftype),                         \
+ASSIGN_FETCH_FUNC(stack, ftype),                       \
+ASSIGN_FETCH_FUNC(retval, ftype),                      \
+ASSIGN_FETCH_FUNC(memory, ftype),                      \
+ASSIGN_FETCH_FUNC(symbol, ftype),                      \
+ASSIGN_FETCH_FUNC(deref, ftype),                       \
+         }                                             \
        }
 
+#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)                  \
+       __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
+
+#define FETCH_TYPE_STRING 0
+#define FETCH_TYPE_STRSIZE 1
+
 /* Fetch type information table */
 static const struct fetch_type {
        const char      *name;          /* Name of type */
@@ -264,14 +404,16 @@ static const struct fetch_type {
        int             is_signed;      /* Signed flag */
        print_type_func_t       print;  /* Print functions */
        const char      *fmt;           /* Fromat string */
+       const char      *fmttype;       /* Name in format file */
        /* Fetch functions */
-       fetch_func_t    reg;
-       fetch_func_t    stack;
-       fetch_func_t    retval;
-       fetch_func_t    memory;
-       fetch_func_t    symbol;
-       fetch_func_t    deref;
+       fetch_func_t    fetch[FETCH_MTD_END];
 } fetch_type_table[] = {
+       /* Special types */
+       [FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
+                                       sizeof(u32), 1, "__data_loc char[]"),
+       [FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
+                                       string_size, sizeof(u32), 0, "u32"),
+       /* Basic types */
        ASSIGN_FETCH_TYPE(u8,  u8,  0),
        ASSIGN_FETCH_TYPE(u16, u16, 0),
        ASSIGN_FETCH_TYPE(u32, u32, 0),
@@ -302,12 +444,28 @@ static __kprobes void fetch_stack_address(struct pt_regs *regs,
        *(unsigned long *)dest = kernel_stack_pointer(regs);
 }
 
+static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
+                                           fetch_func_t orig_fn)
+{
+       int i;
+
+       if (type != &fetch_type_table[FETCH_TYPE_STRING])
+               return NULL;    /* Only string type needs size function */
+       for (i = 0; i < FETCH_MTD_END; i++)
+               if (type->fetch[i] == orig_fn)
+                       return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i];
+
+       WARN_ON(1);     /* This should not happen */
+       return NULL;
+}
+
 /**
  * Kprobe event core functions
  */
 
 struct probe_arg {
        struct fetch_param      fetch;
+       struct fetch_param      fetch_size;
        unsigned int            offset; /* Offset from argument entry */
        const char              *name;  /* Name of this argument */
        const char              *comm;  /* Command of this argument */
@@ -429,9 +587,9 @@ error:
 
 static void free_probe_arg(struct probe_arg *arg)
 {
-       if (CHECK_BASIC_FETCH_FUNCS(deref, arg->fetch.fn))
+       if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
                free_deref_fetch_param(arg->fetch.data);
-       else if (CHECK_BASIC_FETCH_FUNCS(symbol, arg->fetch.fn))
+       else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
                free_symbol_cache(arg->fetch.data);
        kfree(arg->name);
        kfree(arg->comm);
@@ -548,7 +706,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
 
        if (strcmp(arg, "retval") == 0) {
                if (is_return)
-                       f->fn = t->retval;
+                       f->fn = t->fetch[FETCH_MTD_retval];
                else
                        ret = -EINVAL;
        } else if (strncmp(arg, "stack", 5) == 0) {
@@ -562,7 +720,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
                        if (ret || param > PARAM_MAX_STACK)
                                ret = -EINVAL;
                        else {
-                               f->fn = t->stack;
+                               f->fn = t->fetch[FETCH_MTD_stack];
                                f->data = (void *)param;
                        }
                } else
@@ -588,7 +746,7 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t,
        case '%':       /* named register */
                ret = regs_query_register_offset(arg + 1);
                if (ret >= 0) {
-                       f->fn = t->reg;
+                       f->fn = t->fetch[FETCH_MTD_reg];
                        f->data = (void *)(unsigned long)ret;
                        ret = 0;
                }
@@ -598,7 +756,7 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t,
                        ret = strict_strtoul(arg + 1, 0, &param);
                        if (ret)
                                break;
-                       f->fn = t->memory;
+                       f->fn = t->fetch[FETCH_MTD_memory];
                        f->data = (void *)param;
                } else {
                        ret = split_symbol_offset(arg + 1, &offset);
@@ -606,7 +764,7 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t,
                                break;
                        f->data = alloc_symbol_cache(arg + 1, offset);
                        if (f->data)
-                               f->fn = t->symbol;
+                               f->fn = t->fetch[FETCH_MTD_symbol];
                }
                break;
        case '+':       /* deref memory */
@@ -636,14 +794,17 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t,
                        if (ret)
                                kfree(dprm);
                        else {
-                               f->fn = t->deref;
+                               f->fn = t->fetch[FETCH_MTD_deref];
                                f->data = (void *)dprm;
                        }
                }
                break;
        }
-       if (!ret && !f->fn)
+       if (!ret && !f->fn) {   /* Parsed, but do not find fetch method */
+               pr_info("%s type has no corresponding fetch method.\n",
+                       t->name);
                ret = -EINVAL;
+       }
        return ret;
 }
 
@@ -652,6 +813,7 @@ static int parse_probe_arg(char *arg, struct trace_probe *tp,
                           struct probe_arg *parg, int is_return)
 {
        const char *t;
+       int ret;
 
        if (strlen(arg) > MAX_ARGSTR_LEN) {
                pr_info("Argument is too long.: %s\n",  arg);
@@ -674,7 +836,13 @@ static int parse_probe_arg(char *arg, struct trace_probe *tp,
        }
        parg->offset = tp->size;
        tp->size += parg->type->size;
-       return __parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
+       ret = __parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
+       if (ret >= 0) {
+               parg->fetch_size.fn = get_fetch_size_function(parg->type,
+                                                             parg->fetch.fn);
+               parg->fetch_size.data = parg->fetch.data;
+       }
+       return ret;
 }
 
 /* Return 1 if name is reserved or already used by another argument */
@@ -757,14 +925,17 @@ static int create_trace_probe(int argc, char **argv)
                        pr_info("Delete command needs an event name.\n");
                        return -EINVAL;
                }
+               mutex_lock(&probe_lock);
                tp = find_probe_event(event, group);
                if (!tp) {
+                       mutex_unlock(&probe_lock);
                        pr_info("Event %s/%s doesn't exist.\n", group, event);
                        return -ENOENT;
                }
                /* delete an event */
                unregister_trace_probe(tp);
                free_trace_probe(tp);
+               mutex_unlock(&probe_lock);
                return 0;
        }
 
@@ -1043,6 +1214,54 @@ static const struct file_operations kprobe_profile_ops = {
        .release        = seq_release,
 };
 
+/* Sum up total data length for dynamic arraies (strings) */
+static __kprobes int __get_data_size(struct trace_probe *tp,
+                                    struct pt_regs *regs)
+{
+       int i, ret = 0;
+       u32 len;
+
+       for (i = 0; i < tp->nr_args; i++)
+               if (unlikely(tp->args[i].fetch_size.fn)) {
+                       call_fetch(&tp->args[i].fetch_size, regs, &len);
+                       ret += len;
+               }
+
+       return ret;
+}
+
+/* Store the value of each argument */
+static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp,
+                                      struct pt_regs *regs,
+                                      u8 *data, int maxlen)
+{
+       int i;
+       u32 end = tp->size;
+       u32 *dl;        /* Data (relative) location */
+
+       for (i = 0; i < tp->nr_args; i++) {
+               if (unlikely(tp->args[i].fetch_size.fn)) {
+                       /*
+                        * First, we set the relative location and
+                        * maximum data length to *dl
+                        */
+                       dl = (u32 *)(data + tp->args[i].offset);
+                       *dl = make_data_rloc(maxlen, end - tp->args[i].offset);
+                       /* Then try to fetch string or dynamic array data */
+                       call_fetch(&tp->args[i].fetch, regs, dl);
+                       /* Reduce maximum length */
+                       end += get_rloc_len(*dl);
+                       maxlen -= get_rloc_len(*dl);
+                       /* Trick here, convert data_rloc to data_loc */
+                       *dl = convert_rloc_to_loc(*dl,
+                                ent_size + tp->args[i].offset);
+               } else
+                       /* Just fetching data normally */
+                       call_fetch(&tp->args[i].fetch, regs,
+                                  data + tp->args[i].offset);
+       }
+}
+
 /* Kprobe handler */
 static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
 {
@@ -1050,8 +1269,7 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
        struct kprobe_trace_entry_head *entry;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
-       u8 *data;
-       int size, i, pc;
+       int size, dsize, pc;
        unsigned long irq_flags;
        struct ftrace_event_call *call = &tp->call;
 
@@ -1060,7 +1278,8 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       size = sizeof(*entry) + tp->size;
+       dsize = __get_data_size(tp, regs);
+       size = sizeof(*entry) + tp->size + dsize;
 
        event = trace_current_buffer_lock_reserve(&buffer, call->event.type,
                                                  size, irq_flags, pc);
@@ -1069,9 +1288,7 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
 
        entry = ring_buffer_event_data(event);
        entry->ip = (unsigned long)kp->addr;
-       data = (u8 *)&entry[1];
-       for (i = 0; i < tp->nr_args; i++)
-               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
+       store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
        if (!filter_current_check_discard(buffer, call, entry, event))
                trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -1085,15 +1302,15 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
        struct kretprobe_trace_entry_head *entry;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
-       u8 *data;
-       int size, i, pc;
+       int size, pc, dsize;
        unsigned long irq_flags;
        struct ftrace_event_call *call = &tp->call;
 
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       size = sizeof(*entry) + tp->size;
+       dsize = __get_data_size(tp, regs);
+       size = sizeof(*entry) + tp->size + dsize;
 
        event = trace_current_buffer_lock_reserve(&buffer, call->event.type,
                                                  size, irq_flags, pc);
@@ -1103,9 +1320,7 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
        entry = ring_buffer_event_data(event);
        entry->func = (unsigned long)tp->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
-       data = (u8 *)&entry[1];
-       for (i = 0; i < tp->nr_args; i++)
-               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
+       store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
        if (!filter_current_check_discard(buffer, call, entry, event))
                trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -1137,7 +1352,7 @@ print_kprobe_event(struct trace_iterator *iter, int flags,
        data = (u8 *)&field[1];
        for (i = 0; i < tp->nr_args; i++)
                if (!tp->args[i].type->print(s, tp->args[i].name,
-                                            data + tp->args[i].offset))
+                                            data + tp->args[i].offset, field))
                        goto partial;
 
        if (!trace_seq_puts(s, "\n"))
@@ -1179,7 +1394,7 @@ print_kretprobe_event(struct trace_iterator *iter, int flags,
        data = (u8 *)&field[1];
        for (i = 0; i < tp->nr_args; i++)
                if (!tp->args[i].type->print(s, tp->args[i].name,
-                                            data + tp->args[i].offset))
+                                            data + tp->args[i].offset, field))
                        goto partial;
 
        if (!trace_seq_puts(s, "\n"))
@@ -1214,11 +1429,6 @@ static void probe_event_disable(struct ftrace_event_call *call)
        }
 }
 
-static int probe_event_raw_init(struct ftrace_event_call *event_call)
-{
-       return 0;
-}
-
 #undef DEFINE_FIELD
 #define DEFINE_FIELD(type, item, name, is_signed)                      \
        do {                                                            \
@@ -1239,7 +1449,7 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
        DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
        /* Set argument names as fields */
        for (i = 0; i < tp->nr_args; i++) {
-               ret = trace_define_field(event_call, tp->args[i].type->name,
+               ret = trace_define_field(event_call, tp->args[i].type->fmttype,
                                         tp->args[i].name,
                                         sizeof(field) + tp->args[i].offset,
                                         tp->args[i].type->size,
@@ -1261,7 +1471,7 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
        DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
        /* Set argument names as fields */
        for (i = 0; i < tp->nr_args; i++) {
-               ret = trace_define_field(event_call, tp->args[i].type->name,
+               ret = trace_define_field(event_call, tp->args[i].type->fmttype,
                                         tp->args[i].name,
                                         sizeof(field) + tp->args[i].offset,
                                         tp->args[i].type->size,
@@ -1301,8 +1511,13 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len)
        pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
 
        for (i = 0; i < tp->nr_args; i++) {
-               pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
-                               tp->args[i].name);
+               if (strcmp(tp->args[i].type->name, "string") == 0)
+                       pos += snprintf(buf + pos, LEN_OR_ZERO,
+                                       ", __get_str(%s)",
+                                       tp->args[i].name);
+               else
+                       pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
+                                       tp->args[i].name);
        }
 
 #undef LEN_OR_ZERO
@@ -1339,11 +1554,11 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
        struct ftrace_event_call *call = &tp->call;
        struct kprobe_trace_entry_head *entry;
        struct hlist_head *head;
-       u8 *data;
-       int size, __size, i;
+       int size, __size, dsize;
        int rctx;
 
-       __size = sizeof(*entry) + tp->size;
+       dsize = __get_data_size(tp, regs);
+       __size = sizeof(*entry) + tp->size + dsize;
        size = ALIGN(__size + sizeof(u32), sizeof(u64));
        size -= sizeof(u32);
        if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
@@ -1355,9 +1570,8 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
                return;
 
        entry->ip = (unsigned long)kp->addr;
-       data = (u8 *)&entry[1];
-       for (i = 0; i < tp->nr_args; i++)
-               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
+       memset(&entry[1], 0, dsize);
+       store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
        head = this_cpu_ptr(call->perf_events);
        perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head);
@@ -1371,11 +1585,11 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
        struct ftrace_event_call *call = &tp->call;
        struct kretprobe_trace_entry_head *entry;
        struct hlist_head *head;
-       u8 *data;
-       int size, __size, i;
+       int size, __size, dsize;
        int rctx;
 
-       __size = sizeof(*entry) + tp->size;
+       dsize = __get_data_size(tp, regs);
+       __size = sizeof(*entry) + tp->size + dsize;
        size = ALIGN(__size + sizeof(u32), sizeof(u64));
        size -= sizeof(u32);
        if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
@@ -1388,9 +1602,7 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
 
        entry->func = (unsigned long)tp->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
-       data = (u8 *)&entry[1];
-       for (i = 0; i < tp->nr_args; i++)
-               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
+       store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
        head = this_cpu_ptr(call->perf_events);
        perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head);
@@ -1486,15 +1698,12 @@ static int register_probe_event(struct trace_probe *tp)
        int ret;
 
        /* Initialize ftrace_event_call */
+       INIT_LIST_HEAD(&call->class->fields);
        if (probe_is_return(tp)) {
-               INIT_LIST_HEAD(&call->class->fields);
                call->event.funcs = &kretprobe_funcs;
-               call->class->raw_init = probe_event_raw_init;
                call->class->define_fields = kretprobe_event_define_fields;
        } else {
-               INIT_LIST_HEAD(&call->class->fields);
                call->event.funcs = &kprobe_funcs;
-               call->class->raw_init = probe_event_raw_init;
                call->class->define_fields = kprobe_event_define_fields;
        }
        if (set_print_fmt(tp) < 0)
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
deleted file mode 100644 (file)
index 8eaf007..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * trace_ksym.c - Kernel Symbol Tracer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2009
- */
-
-#include <linux/kallsyms.h>
-#include <linux/uaccess.h>
-#include <linux/debugfs.h>
-#include <linux/ftrace.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-
-#include "trace_output.h"
-#include "trace.h"
-
-#include <linux/hw_breakpoint.h>
-#include <asm/hw_breakpoint.h>
-
-#include <asm/atomic.h>
-
-#define KSYM_TRACER_OP_LEN 3 /* rw- */
-
-struct trace_ksym {
-       struct perf_event       **ksym_hbp;
-       struct perf_event_attr  attr;
-#ifdef CONFIG_PROFILE_KSYM_TRACER
-       atomic64_t              counter;
-#endif
-       struct hlist_node       ksym_hlist;
-};
-
-static struct trace_array *ksym_trace_array;
-
-static unsigned int ksym_tracing_enabled;
-
-static HLIST_HEAD(ksym_filter_head);
-
-static DEFINE_MUTEX(ksym_tracer_mutex);
-
-#ifdef CONFIG_PROFILE_KSYM_TRACER
-
-#define MAX_UL_INT 0xffffffff
-
-void ksym_collect_stats(unsigned long hbp_hit_addr)
-{
-       struct hlist_node *node;
-       struct trace_ksym *entry;
-
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) {
-               if (entry->attr.bp_addr == hbp_hit_addr) {
-                       atomic64_inc(&entry->counter);
-                       break;
-               }
-       }
-       rcu_read_unlock();
-}
-#endif /* CONFIG_PROFILE_KSYM_TRACER */
-
-void ksym_hbp_handler(struct perf_event *hbp, int nmi,
-                     struct perf_sample_data *data,
-                     struct pt_regs *regs)
-{
-       struct ring_buffer_event *event;
-       struct ksym_trace_entry *entry;
-       struct ring_buffer *buffer;
-       int pc;
-
-       if (!ksym_tracing_enabled)
-               return;
-
-       buffer = ksym_trace_array->buffer;
-
-       pc = preempt_count();
-
-       event = trace_buffer_lock_reserve(buffer, TRACE_KSYM,
-                                                       sizeof(*entry), 0, pc);
-       if (!event)
-               return;
-
-       entry           = ring_buffer_event_data(event);
-       entry->ip       = instruction_pointer(regs);
-       entry->type     = hw_breakpoint_type(hbp);
-       entry->addr     = hw_breakpoint_addr(hbp);
-       strlcpy(entry->cmd, current->comm, TASK_COMM_LEN);
-
-#ifdef CONFIG_PROFILE_KSYM_TRACER
-       ksym_collect_stats(hw_breakpoint_addr(hbp));
-#endif /* CONFIG_PROFILE_KSYM_TRACER */
-
-       trace_buffer_unlock_commit(buffer, event, 0, pc);
-}
-
-/* Valid access types are represented as
- *
- * rw- : Set Read/Write Access Breakpoint
- * -w- : Set Write Access Breakpoint
- * --- : Clear Breakpoints
- * --x : Set Execution Break points (Not available yet)
- *
- */
-static int ksym_trace_get_access_type(char *str)
-{
-       int access = 0;
-
-       if (str[0] == 'r')
-               access |= HW_BREAKPOINT_R;
-
-       if (str[1] == 'w')
-               access |= HW_BREAKPOINT_W;
-
-       if (str[2] == 'x')
-               access |= HW_BREAKPOINT_X;
-
-       switch (access) {
-       case HW_BREAKPOINT_R:
-       case HW_BREAKPOINT_W:
-       case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
-               return access;
-       default:
-               return -EINVAL;
-       }
-}
-
-/*
- * There can be several possible malformed requests and we attempt to capture
- * all of them. We enumerate some of the rules
- * 1. We will not allow kernel symbols with ':' since it is used as a delimiter.
- *    i.e. multiple ':' symbols disallowed. Possible uses are of the form
- *    <module>:<ksym_name>:<op>.
- * 2. No delimiter symbol ':' in the input string
- * 3. Spurious operator symbols or symbols not in their respective positions
- * 4. <ksym_name>:--- i.e. clear breakpoint request when ksym_name not in file
- * 5. Kernel symbol not a part of /proc/kallsyms
- * 6. Duplicate requests
- */
-static int parse_ksym_trace_str(char *input_string, char **ksymname,
-                                                       unsigned long *addr)
-{
-       int ret;
-
-       *ksymname = strsep(&input_string, ":");
-       *addr = kallsyms_lookup_name(*ksymname);
-
-       /* Check for malformed request: (2), (1) and (5) */
-       if ((!input_string) ||
-           (strlen(input_string) != KSYM_TRACER_OP_LEN) ||
-           (*addr == 0))
-               return -EINVAL;;
-
-       ret = ksym_trace_get_access_type(input_string);
-
-       return ret;
-}
-
-int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
-{
-       struct trace_ksym *entry;
-       int ret = -ENOMEM;
-
-       entry = kzalloc(sizeof(struct trace_ksym), GFP_KERNEL);
-       if (!entry)
-               return -ENOMEM;
-
-       hw_breakpoint_init(&entry->attr);
-
-       entry->attr.bp_type = op;
-       entry->attr.bp_addr = addr;
-       entry->attr.bp_len = HW_BREAKPOINT_LEN_4;
-
-       entry->ksym_hbp = register_wide_hw_breakpoint(&entry->attr,
-                                       ksym_hbp_handler);
-
-       if (IS_ERR(entry->ksym_hbp)) {
-               ret = PTR_ERR(entry->ksym_hbp);
-               if (ret == -ENOSPC) {
-                       printk(KERN_ERR "ksym_tracer: Maximum limit reached."
-                       " No new requests for tracing can be accepted now.\n");
-               } else {
-                       printk(KERN_INFO "ksym_tracer request failed. Try again"
-                                        " later!!\n");
-               }
-               goto err;
-       }
-
-       hlist_add_head_rcu(&(entry->ksym_hlist), &ksym_filter_head);
-
-       return 0;
-
-err:
-       kfree(entry);
-
-       return ret;
-}
-
-static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf,
-                                               size_t count, loff_t *ppos)
-{
-       struct trace_ksym *entry;
-       struct hlist_node *node;
-       struct trace_seq *s;
-       ssize_t cnt = 0;
-       int ret;
-
-       s = kmalloc(sizeof(*s), GFP_KERNEL);
-       if (!s)
-               return -ENOMEM;
-       trace_seq_init(s);
-
-       mutex_lock(&ksym_tracer_mutex);
-
-       hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
-               ret = trace_seq_printf(s, "%pS:",
-                               (void *)(unsigned long)entry->attr.bp_addr);
-               if (entry->attr.bp_type == HW_BREAKPOINT_R)
-                       ret = trace_seq_puts(s, "r--\n");
-               else if (entry->attr.bp_type == HW_BREAKPOINT_W)
-                       ret = trace_seq_puts(s, "-w-\n");
-               else if (entry->attr.bp_type == (HW_BREAKPOINT_W | HW_BREAKPOINT_R))
-                       ret = trace_seq_puts(s, "rw-\n");
-               WARN_ON_ONCE(!ret);
-       }
-
-       cnt = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len);
-
-       mutex_unlock(&ksym_tracer_mutex);
-
-       kfree(s);
-
-       return cnt;
-}
-
-static void __ksym_trace_reset(void)
-{
-       struct trace_ksym *entry;
-       struct hlist_node *node, *node1;
-
-       mutex_lock(&ksym_tracer_mutex);
-       hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head,
-                                                               ksym_hlist) {
-               unregister_wide_hw_breakpoint(entry->ksym_hbp);
-               hlist_del_rcu(&(entry->ksym_hlist));
-               synchronize_rcu();
-               kfree(entry);
-       }
-       mutex_unlock(&ksym_tracer_mutex);
-}
-
-static ssize_t ksym_trace_filter_write(struct file *file,
-                                       const char __user *buffer,
-                                               size_t count, loff_t *ppos)
-{
-       struct trace_ksym *entry;
-       struct hlist_node *node;
-       char *buf, *input_string, *ksymname = NULL;
-       unsigned long ksym_addr = 0;
-       int ret, op, changed = 0;
-
-       buf = kzalloc(count + 1, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
-       ret = -EFAULT;
-       if (copy_from_user(buf, buffer, count))
-               goto out;
-
-       buf[count] = '\0';
-       input_string = strstrip(buf);
-
-       /*
-        * Clear all breakpoints if:
-        * 1: echo > ksym_trace_filter
-        * 2: echo 0 > ksym_trace_filter
-        * 3: echo "*:---" > ksym_trace_filter
-        */
-       if (!input_string[0] || !strcmp(input_string, "0") ||
-           !strcmp(input_string, "*:---")) {
-               __ksym_trace_reset();
-               ret = 0;
-               goto out;
-       }
-
-       ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr);
-       if (ret < 0)
-               goto out;
-
-       mutex_lock(&ksym_tracer_mutex);
-
-       ret = -EINVAL;
-       hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
-               if (entry->attr.bp_addr == ksym_addr) {
-                       /* Check for malformed request: (6) */
-                       if (entry->attr.bp_type != op)
-                               changed = 1;
-                       else
-                               goto out_unlock;
-                       break;
-               }
-       }
-       if (changed) {
-               unregister_wide_hw_breakpoint(entry->ksym_hbp);
-               entry->attr.bp_type = op;
-               ret = 0;
-               if (op > 0) {
-                       entry->ksym_hbp =
-                               register_wide_hw_breakpoint(&entry->attr,
-                                       ksym_hbp_handler);
-                       if (IS_ERR(entry->ksym_hbp))
-                               ret = PTR_ERR(entry->ksym_hbp);
-                       else
-                               goto out_unlock;
-               }
-               /* Error or "symbol:---" case: drop it */
-               hlist_del_rcu(&(entry->ksym_hlist));
-               synchronize_rcu();
-               kfree(entry);
-               goto out_unlock;
-       } else {
-               /* Check for malformed request: (4) */
-               if (op)
-                       ret = process_new_ksym_entry(ksymname, op, ksym_addr);
-       }
-out_unlock:
-       mutex_unlock(&ksym_tracer_mutex);
-out:
-       kfree(buf);
-       return !ret ? count : ret;
-}
-
-static const struct file_operations ksym_tracing_fops = {
-       .open           = tracing_open_generic,
-       .read           = ksym_trace_filter_read,
-       .write          = ksym_trace_filter_write,
-};
-
-static void ksym_trace_reset(struct trace_array *tr)
-{
-       ksym_tracing_enabled = 0;
-       __ksym_trace_reset();
-}
-
-static int ksym_trace_init(struct trace_array *tr)
-{
-       int cpu, ret = 0;
-
-       for_each_online_cpu(cpu)
-               tracing_reset(tr, cpu);
-       ksym_tracing_enabled = 1;
-       ksym_trace_array = tr;
-
-       return ret;
-}
-
-static void ksym_trace_print_header(struct seq_file *m)
-{
-       seq_puts(m,
-                "#       TASK-PID   CPU#      Symbol                    "
-                "Type    Function\n");
-       seq_puts(m,
-                "#          |        |          |                       "
-                " |         |\n");
-}
-
-static enum print_line_t ksym_trace_output(struct trace_iterator *iter)
-{
-       struct trace_entry *entry = iter->ent;
-       struct trace_seq *s = &iter->seq;
-       struct ksym_trace_entry *field;
-       char str[KSYM_SYMBOL_LEN];
-       int ret;
-
-       if (entry->type != TRACE_KSYM)
-               return TRACE_TYPE_UNHANDLED;
-
-       trace_assign_type(field, entry);
-
-       ret = trace_seq_printf(s, "%11s-%-5d [%03d] %pS", field->cmd,
-                               entry->pid, iter->cpu, (char *)field->addr);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       switch (field->type) {
-       case HW_BREAKPOINT_R:
-               ret = trace_seq_printf(s, " R  ");
-               break;
-       case HW_BREAKPOINT_W:
-               ret = trace_seq_printf(s, " W  ");
-               break;
-       case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
-               ret = trace_seq_printf(s, " RW ");
-               break;
-       default:
-               return TRACE_TYPE_PARTIAL_LINE;
-       }
-
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       sprint_symbol(str, field->ip);
-       ret = trace_seq_printf(s, "%s\n", str);
-       if (!ret)
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       return TRACE_TYPE_HANDLED;
-}
-
-struct tracer ksym_tracer __read_mostly =
-{
-       .name           = "ksym_tracer",
-       .init           = ksym_trace_init,
-       .reset          = ksym_trace_reset,
-#ifdef CONFIG_FTRACE_SELFTEST
-       .selftest       = trace_selftest_startup_ksym,
-#endif
-       .print_header   = ksym_trace_print_header,
-       .print_line     = ksym_trace_output
-};
-
-#ifdef CONFIG_PROFILE_KSYM_TRACER
-static int ksym_profile_show(struct seq_file *m, void *v)
-{
-       struct hlist_node *node;
-       struct trace_ksym *entry;
-       int access_type = 0;
-       char fn_name[KSYM_NAME_LEN];
-
-       seq_puts(m, "  Access Type ");
-       seq_puts(m, "  Symbol                                       Counter\n");
-       seq_puts(m, "  ----------- ");
-       seq_puts(m, "  ------                                       -------\n");
-
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) {
-
-               access_type = entry->attr.bp_type;
-
-               switch (access_type) {
-               case HW_BREAKPOINT_R:
-                       seq_puts(m, "  R           ");
-                       break;
-               case HW_BREAKPOINT_W:
-                       seq_puts(m, "  W           ");
-                       break;
-               case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
-                       seq_puts(m, "  RW          ");
-                       break;
-               default:
-                       seq_puts(m, "  NA          ");
-               }
-
-               if (lookup_symbol_name(entry->attr.bp_addr, fn_name) >= 0)
-                       seq_printf(m, "  %-36s", fn_name);
-               else
-                       seq_printf(m, "  %-36s", "<NA>");
-               seq_printf(m, " %15llu\n",
-                          (unsigned long long)atomic64_read(&entry->counter));
-       }
-       rcu_read_unlock();
-
-       return 0;
-}
-
-static int ksym_profile_open(struct inode *node, struct file *file)
-{
-       return single_open(file, ksym_profile_show, NULL);
-}
-
-static const struct file_operations ksym_profile_fops = {
-       .open           = ksym_profile_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-#endif /* CONFIG_PROFILE_KSYM_TRACER */
-
-__init static int init_ksym_trace(void)
-{
-       struct dentry *d_tracer;
-
-       d_tracer = tracing_init_dentry();
-
-       trace_create_file("ksym_trace_filter", 0644, d_tracer,
-                         NULL, &ksym_tracing_fops);
-
-#ifdef CONFIG_PROFILE_KSYM_TRACER
-       trace_create_file("ksym_profile", 0444, d_tracer,
-                         NULL, &ksym_profile_fops);
-#endif
-
-       return register_tracer(&ksym_tracer);
-}
-device_initcall(init_ksym_trace);
index 57c1b45964703d8c0af75c1ffed5c3e31df66737..02272baa22065c14c98e1c7394d2486a4d6a473e 100644 (file)
@@ -16,9 +16,6 @@
 
 DECLARE_RWSEM(trace_event_mutex);
 
-DEFINE_PER_CPU(struct trace_seq, ftrace_event_seq);
-EXPORT_PER_CPU_SYMBOL(ftrace_event_seq);
-
 static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
 
 static int next_event_type = __TRACE_LAST_TYPE + 1;
@@ -1069,65 +1066,6 @@ static struct trace_event trace_wake_event = {
        .funcs          = &trace_wake_funcs,
 };
 
-/* TRACE_SPECIAL */
-static enum print_line_t trace_special_print(struct trace_iterator *iter,
-                                            int flags, struct trace_event *event)
-{
-       struct special_entry *field;
-
-       trace_assign_type(field, iter->ent);
-
-       if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
-                             field->arg1,
-                             field->arg2,
-                             field->arg3))
-               return TRACE_TYPE_PARTIAL_LINE;
-
-       return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t trace_special_hex(struct trace_iterator *iter,
-                                          int flags, struct trace_event *event)
-{
-       struct special_entry *field;
-       struct trace_seq *s = &iter->seq;
-
-       trace_assign_type(field, iter->ent);
-
-       SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
-       SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
-       SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
-
-       return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t trace_special_bin(struct trace_iterator *iter,
-                                          int flags, struct trace_event *event)
-{
-       struct special_entry *field;
-       struct trace_seq *s = &iter->seq;
-
-       trace_assign_type(field, iter->ent);
-
-       SEQ_PUT_FIELD_RET(s, field->arg1);
-       SEQ_PUT_FIELD_RET(s, field->arg2);
-       SEQ_PUT_FIELD_RET(s, field->arg3);
-
-       return TRACE_TYPE_HANDLED;
-}
-
-static struct trace_event_functions trace_special_funcs = {
-       .trace          = trace_special_print,
-       .raw            = trace_special_print,
-       .hex            = trace_special_hex,
-       .binary         = trace_special_bin,
-};
-
-static struct trace_event trace_special_event = {
-       .type           = TRACE_SPECIAL,
-       .funcs          = &trace_special_funcs,
-};
-
 /* TRACE_STACK */
 
 static enum print_line_t trace_stack_print(struct trace_iterator *iter,
@@ -1161,9 +1099,6 @@ static enum print_line_t trace_stack_print(struct trace_iterator *iter,
 
 static struct trace_event_functions trace_stack_funcs = {
        .trace          = trace_stack_print,
-       .raw            = trace_special_print,
-       .hex            = trace_special_hex,
-       .binary         = trace_special_bin,
 };
 
 static struct trace_event trace_stack_event = {
@@ -1194,9 +1129,6 @@ static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
 
 static struct trace_event_functions trace_user_stack_funcs = {
        .trace          = trace_user_stack_print,
-       .raw            = trace_special_print,
-       .hex            = trace_special_hex,
-       .binary         = trace_special_bin,
 };
 
 static struct trace_event trace_user_stack_event = {
@@ -1314,7 +1246,6 @@ static struct trace_event *events[] __initdata = {
        &trace_fn_event,
        &trace_ctx_event,
        &trace_wake_event,
-       &trace_special_event,
        &trace_stack_event,
        &trace_user_stack_event,
        &trace_bprint_event,
index 0e73bc2ef8c55a0b8a47ffe19d7b1aad3577de2b..4086eae6e81b1c1b9762edc01600d3294c6bc130 100644 (file)
@@ -46,7 +46,6 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
        struct trace_array_cpu *data;
        unsigned long flags;
        long disabled;
-       int resched;
        int cpu;
        int pc;
 
@@ -54,7 +53,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
                return;
 
        pc = preempt_count();
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
 
        cpu = raw_smp_processor_id();
        if (cpu != wakeup_current_cpu)
@@ -74,7 +73,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
  out:
        atomic_dec(&data->disabled);
  out_enable:
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
 }
 
 static struct ftrace_ops trace_ops __read_mostly =
@@ -383,6 +382,7 @@ static struct tracer wakeup_tracer __read_mostly =
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_wakeup,
 #endif
+       .use_max_tr     = 1,
 };
 
 static struct tracer wakeup_rt_tracer __read_mostly =
@@ -397,6 +397,7 @@ static struct tracer wakeup_rt_tracer __read_mostly =
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_wakeup,
 #endif
+       .use_max_tr     = 1,
 };
 
 __init static int init_wakeup_tracer(void)
index 250e7f9bd2f0114c998d26c239fb3bfb535ebde2..155a415b3209c0c4e65936be1b593678aea42d27 100644 (file)
@@ -13,11 +13,9 @@ static inline int trace_valid_entry(struct trace_entry *entry)
        case TRACE_WAKE:
        case TRACE_STACK:
        case TRACE_PRINT:
-       case TRACE_SPECIAL:
        case TRACE_BRANCH:
        case TRACE_GRAPH_ENT:
        case TRACE_GRAPH_RET:
-       case TRACE_KSYM:
                return 1;
        }
        return 0;
@@ -691,38 +689,6 @@ trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr
 }
 #endif /* CONFIG_CONTEXT_SWITCH_TRACER */
 
-#ifdef CONFIG_SYSPROF_TRACER
-int
-trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr)
-{
-       unsigned long count;
-       int ret;
-
-       /* start the tracing */
-       ret = tracer_init(trace, tr);
-       if (ret) {
-               warn_failed_init_tracer(trace, ret);
-               return ret;
-       }
-
-       /* Sleep for a 1/10 of a second */
-       msleep(100);
-       /* stop the tracing. */
-       tracing_stop();
-       /* check the trace buffer */
-       ret = trace_test_buffer(tr, &count);
-       trace->reset(tr);
-       tracing_start();
-
-       if (!ret && !count) {
-               printk(KERN_CONT ".. no entries found ..");
-               ret = -1;
-       }
-
-       return ret;
-}
-#endif /* CONFIG_SYSPROF_TRACER */
-
 #ifdef CONFIG_BRANCH_TRACER
 int
 trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
@@ -755,56 +721,3 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
 }
 #endif /* CONFIG_BRANCH_TRACER */
 
-#ifdef CONFIG_KSYM_TRACER
-static int ksym_selftest_dummy;
-
-int
-trace_selftest_startup_ksym(struct tracer *trace, struct trace_array *tr)
-{
-       unsigned long count;
-       int ret;
-
-       /* start the tracing */
-       ret = tracer_init(trace, tr);
-       if (ret) {
-               warn_failed_init_tracer(trace, ret);
-               return ret;
-       }
-
-       ksym_selftest_dummy = 0;
-       /* Register the read-write tracing request */
-
-       ret = process_new_ksym_entry("ksym_selftest_dummy",
-                                    HW_BREAKPOINT_R | HW_BREAKPOINT_W,
-                                       (unsigned long)(&ksym_selftest_dummy));
-
-       if (ret < 0) {
-               printk(KERN_CONT "ksym_trace read-write startup test failed\n");
-               goto ret_path;
-       }
-       /* Perform a read and a write operation over the dummy variable to
-        * trigger the tracer
-        */
-       if (ksym_selftest_dummy == 0)
-               ksym_selftest_dummy++;
-
-       /* stop the tracing. */
-       tracing_stop();
-       /* check the trace buffer */
-       ret = trace_test_buffer(tr, &count);
-       trace->reset(tr);
-       tracing_start();
-
-       /* read & write operations - one each is performed on the dummy variable
-        * triggering two entries in the trace buffer
-        */
-       if (!ret && count != 2) {
-               printk(KERN_CONT "Ksym tracer startup test failed");
-               ret = -1;
-       }
-
-ret_path:
-       return ret;
-}
-#endif /* CONFIG_KSYM_TRACER */
-
index f4bc9b27de5fd13d131dd13b204b1e5432a4283a..056468eae7cfce7a76bf5c2364f71c722adeb325 100644 (file)
@@ -110,12 +110,12 @@ static inline void check_stack(void)
 static void
 stack_trace_call(unsigned long ip, unsigned long parent_ip)
 {
-       int cpu, resched;
+       int cpu;
 
        if (unlikely(!ftrace_enabled || stack_trace_disabled))
                return;
 
-       resched = ftrace_preempt_disable();
+       preempt_disable_notrace();
 
        cpu = raw_smp_processor_id();
        /* no atomic needed, we only modify this variable by this cpu */
@@ -127,7 +127,7 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip)
  out:
        per_cpu(trace_active, cpu)--;
        /* prevent recursion in schedule */
-       ftrace_preempt_enable(resched);
+       preempt_enable_notrace();
 }
 
 static struct ftrace_ops trace_ops __read_mostly =
index 34e35804304b03a7549b2f3a00064e8ec4675d7f..bac752f0cfb503b4847fc84ddb0e7ecea18464a5 100644 (file)
@@ -23,6 +23,9 @@ static int syscall_exit_register(struct ftrace_event_call *event,
 static int syscall_enter_define_fields(struct ftrace_event_call *call);
 static int syscall_exit_define_fields(struct ftrace_event_call *call);
 
+/* All syscall exit events have the same fields */
+static LIST_HEAD(syscall_exit_fields);
+
 static struct list_head *
 syscall_get_enter_fields(struct ftrace_event_call *call)
 {
@@ -34,9 +37,7 @@ syscall_get_enter_fields(struct ftrace_event_call *call)
 static struct list_head *
 syscall_get_exit_fields(struct ftrace_event_call *call)
 {
-       struct syscall_metadata *entry = call->data;
-
-       return &entry->exit_fields;
+       return &syscall_exit_fields;
 }
 
 struct trace_event_functions enter_syscall_print_funcs = {
diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c
deleted file mode 100644 (file)
index a7974a5..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * trace stack traces
- *
- * Copyright (C) 2004-2008, Soeren Sandmann
- * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com>
- * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
- */
-#include <linux/kallsyms.h>
-#include <linux/debugfs.h>
-#include <linux/hrtimer.h>
-#include <linux/uaccess.h>
-#include <linux/ftrace.h>
-#include <linux/module.h>
-#include <linux/irq.h>
-#include <linux/fs.h>
-
-#include <asm/stacktrace.h>
-
-#include "trace.h"
-
-static struct trace_array      *sysprof_trace;
-static int __read_mostly       tracer_enabled;
-
-/*
- * 1 msec sample interval by default:
- */
-static unsigned long sample_period = 1000000;
-static const unsigned int sample_max_depth = 512;
-
-static DEFINE_MUTEX(sample_timer_lock);
-/*
- * Per CPU hrtimers that do the profiling:
- */
-static DEFINE_PER_CPU(struct hrtimer, stack_trace_hrtimer);
-
-struct stack_frame {
-       const void __user       *next_fp;
-       unsigned long           return_address;
-};
-
-static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
-{
-       int ret;
-
-       if (!access_ok(VERIFY_READ, fp, sizeof(*frame)))
-               return 0;
-
-       ret = 1;
-       pagefault_disable();
-       if (__copy_from_user_inatomic(frame, fp, sizeof(*frame)))
-               ret = 0;
-       pagefault_enable();
-
-       return ret;
-}
-
-struct backtrace_info {
-       struct trace_array_cpu  *data;
-       struct trace_array      *tr;
-       int                     pos;
-};
-
-static void
-backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-       /* Ignore warnings */
-}
-
-static void backtrace_warning(void *data, char *msg)
-{
-       /* Ignore warnings */
-}
-
-static int backtrace_stack(void *data, char *name)
-{
-       /* Don't bother with IRQ stacks for now */
-       return -1;
-}
-
-static void backtrace_address(void *data, unsigned long addr, int reliable)
-{
-       struct backtrace_info *info = data;
-
-       if (info->pos < sample_max_depth && reliable) {
-               __trace_special(info->tr, info->data, 1, addr, 0);
-
-               info->pos++;
-       }
-}
-
-static const struct stacktrace_ops backtrace_ops = {
-       .warning                = backtrace_warning,
-       .warning_symbol         = backtrace_warning_symbol,
-       .stack                  = backtrace_stack,
-       .address                = backtrace_address,
-       .walk_stack             = print_context_stack,
-};
-
-static int
-trace_kernel(struct pt_regs *regs, struct trace_array *tr,
-            struct trace_array_cpu *data)
-{
-       struct backtrace_info info;
-       unsigned long bp;
-       char *stack;
-
-       info.tr = tr;
-       info.data = data;
-       info.pos = 1;
-
-       __trace_special(info.tr, info.data, 1, regs->ip, 0);
-
-       stack = ((char *)regs + sizeof(struct pt_regs));
-#ifdef CONFIG_FRAME_POINTER
-       bp = regs->bp;
-#else
-       bp = 0;
-#endif
-
-       dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, &info);
-
-       return info.pos;
-}
-
-static void timer_notify(struct pt_regs *regs, int cpu)
-{
-       struct trace_array_cpu *data;
-       struct stack_frame frame;
-       struct trace_array *tr;
-       const void __user *fp;
-       int is_user;
-       int i;
-
-       if (!regs)
-               return;
-
-       tr = sysprof_trace;
-       data = tr->data[cpu];
-       is_user = user_mode(regs);
-
-       if (!current || current->pid == 0)
-               return;
-
-       if (is_user && current->state != TASK_RUNNING)
-               return;
-
-       __trace_special(tr, data, 0, 0, current->pid);
-
-       if (!is_user)
-               i = trace_kernel(regs, tr, data);
-       else
-               i = 0;
-
-       /*
-        * Trace user stack if we are not a kernel thread
-        */
-       if (current->mm && i < sample_max_depth) {
-               regs = (struct pt_regs *)current->thread.sp0 - 1;
-
-               fp = (void __user *)regs->bp;
-
-               __trace_special(tr, data, 2, regs->ip, 0);
-
-               while (i < sample_max_depth) {
-                       frame.next_fp = NULL;
-                       frame.return_address = 0;
-                       if (!copy_stack_frame(fp, &frame))
-                               break;
-                       if ((unsigned long)fp < regs->sp)
-                               break;
-
-                       __trace_special(tr, data, 2, frame.return_address,
-                                       (unsigned long)fp);
-                       fp = frame.next_fp;
-
-                       i++;
-               }
-
-       }
-
-       /*
-        * Special trace entry if we overflow the max depth:
-        */
-       if (i == sample_max_depth)
-               __trace_special(tr, data, -1, -1, -1);
-
-       __trace_special(tr, data, 3, current->pid, i);
-}
-
-static enum hrtimer_restart stack_trace_timer_fn(struct hrtimer *hrtimer)
-{
-       /* trace here */
-       timer_notify(get_irq_regs(), smp_processor_id());
-
-       hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period));
-
-       return HRTIMER_RESTART;
-}
-
-static void start_stack_timer(void *unused)
-{
-       struct hrtimer *hrtimer = &__get_cpu_var(stack_trace_hrtimer);
-
-       hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-       hrtimer->function = stack_trace_timer_fn;
-
-       hrtimer_start(hrtimer, ns_to_ktime(sample_period),
-                     HRTIMER_MODE_REL_PINNED);
-}
-
-static void start_stack_timers(void)
-{
-       on_each_cpu(start_stack_timer, NULL, 1);
-}
-
-static void stop_stack_timer(int cpu)
-{
-       struct hrtimer *hrtimer = &per_cpu(stack_trace_hrtimer, cpu);
-
-       hrtimer_cancel(hrtimer);
-}
-
-static void stop_stack_timers(void)
-{
-       int cpu;
-
-       for_each_online_cpu(cpu)
-               stop_stack_timer(cpu);
-}
-
-static void stop_stack_trace(struct trace_array *tr)
-{
-       mutex_lock(&sample_timer_lock);
-       stop_stack_timers();
-       tracer_enabled = 0;
-       mutex_unlock(&sample_timer_lock);
-}
-
-static int stack_trace_init(struct trace_array *tr)
-{
-       sysprof_trace = tr;
-
-       tracing_start_cmdline_record();
-
-       mutex_lock(&sample_timer_lock);
-       start_stack_timers();
-       tracer_enabled = 1;
-       mutex_unlock(&sample_timer_lock);
-       return 0;
-}
-
-static void stack_trace_reset(struct trace_array *tr)
-{
-       tracing_stop_cmdline_record();
-       stop_stack_trace(tr);
-}
-
-static struct tracer stack_trace __read_mostly =
-{
-       .name           = "sysprof",
-       .init           = stack_trace_init,
-       .reset          = stack_trace_reset,
-#ifdef CONFIG_FTRACE_SELFTEST
-       .selftest    = trace_selftest_startup_sysprof,
-#endif
-};
-
-__init static int init_stack_trace(void)
-{
-       return register_tracer(&stack_trace);
-}
-device_initcall(init_stack_trace);
-
-#define MAX_LONG_DIGITS 22
-
-static ssize_t
-sysprof_sample_read(struct file *filp, char __user *ubuf,
-                   size_t cnt, loff_t *ppos)
-{
-       char buf[MAX_LONG_DIGITS];
-       int r;
-
-       r = sprintf(buf, "%ld\n", nsecs_to_usecs(sample_period));
-
-       return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
-}
-
-static ssize_t
-sysprof_sample_write(struct file *filp, const char __user *ubuf,
-                    size_t cnt, loff_t *ppos)
-{
-       char buf[MAX_LONG_DIGITS];
-       unsigned long val;
-
-       if (cnt > MAX_LONG_DIGITS-1)
-               cnt = MAX_LONG_DIGITS-1;
-
-       if (copy_from_user(&buf, ubuf, cnt))
-               return -EFAULT;
-
-       buf[cnt] = 0;
-
-       val = simple_strtoul(buf, NULL, 10);
-       /*
-        * Enforce a minimum sample period of 100 usecs:
-        */
-       if (val < 100)
-               val = 100;
-
-       mutex_lock(&sample_timer_lock);
-       stop_stack_timers();
-       sample_period = val * 1000;
-       start_stack_timers();
-       mutex_unlock(&sample_timer_lock);
-
-       return cnt;
-}
-
-static const struct file_operations sysprof_sample_fops = {
-       .read           = sysprof_sample_read,
-       .write          = sysprof_sample_write,
-};
-
-void init_tracer_sysprof_debugfs(struct dentry *d_tracer)
-{
-
-       trace_create_file("sysprof_sample_period", 0644,
-                       d_tracer, NULL, &sysprof_sample_fops);
-}
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
new file mode 100644 (file)
index 0000000..613bc1f
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * Detect hard and soft lockups on a system
+ *
+ * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc.
+ *
+ * this code detects hard lockups: incidents in where on a CPU
+ * the kernel does not respond to anything except NMI.
+ *
+ * Note: Most of this code is borrowed heavily from softlockup.c,
+ * so thanks to Ingo for the initial implementation.
+ * Some chunks also taken from arch/x86/kernel/apic/nmi.c, thanks
+ * to those contributors as well.
+ */
+
+#include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/nmi.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+#include <linux/lockdep.h>
+#include <linux/notifier.h>
+#include <linux/module.h>
+#include <linux/sysctl.h>
+
+#include <asm/irq_regs.h>
+#include <linux/perf_event.h>
+
+int watchdog_enabled;
+int __read_mostly softlockup_thresh = 60;
+
+static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts);
+static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog);
+static DEFINE_PER_CPU(struct hrtimer, watchdog_hrtimer);
+static DEFINE_PER_CPU(bool, softlockup_touch_sync);
+static DEFINE_PER_CPU(bool, soft_watchdog_warn);
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+static DEFINE_PER_CPU(bool, hard_watchdog_warn);
+static DEFINE_PER_CPU(bool, watchdog_nmi_touch);
+static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts);
+static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved);
+static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
+#endif
+
+static int __read_mostly did_panic;
+static int __initdata no_watchdog;
+
+
+/* boot commands */
+/*
+ * Should we panic when a soft-lockup or hard-lockup occurs:
+ */
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+static int hardlockup_panic;
+
+static int __init hardlockup_panic_setup(char *str)
+{
+       if (!strncmp(str, "panic", 5))
+               hardlockup_panic = 1;
+       return 1;
+}
+__setup("nmi_watchdog=", hardlockup_panic_setup);
+#endif
+
+unsigned int __read_mostly softlockup_panic =
+                       CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
+
+static int __init softlockup_panic_setup(char *str)
+{
+       softlockup_panic = simple_strtoul(str, NULL, 0);
+
+       return 1;
+}
+__setup("softlockup_panic=", softlockup_panic_setup);
+
+static int __init nowatchdog_setup(char *str)
+{
+       no_watchdog = 1;
+       return 1;
+}
+__setup("nowatchdog", nowatchdog_setup);
+
+/* deprecated */
+static int __init nosoftlockup_setup(char *str)
+{
+       no_watchdog = 1;
+       return 1;
+}
+__setup("nosoftlockup", nosoftlockup_setup);
+/*  */
+
+
+/*
+ * Returns seconds, approximately.  We don't need nanosecond
+ * resolution, and we don't need to waste time with a big divide when
+ * 2^30ns == 1.074s.
+ */
+static unsigned long get_timestamp(int this_cpu)
+{
+       return cpu_clock(this_cpu) >> 30LL;  /* 2^30 ~= 10^9 */
+}
+
+static unsigned long get_sample_period(void)
+{
+       /*
+        * convert softlockup_thresh from seconds to ns
+        * the divide by 5 is to give hrtimer 5 chances to
+        * increment before the hardlockup detector generates
+        * a warning
+        */
+       return softlockup_thresh / 5 * NSEC_PER_SEC;
+}
+
+/* Commands for resetting the watchdog */
+static void __touch_watchdog(void)
+{
+       int this_cpu = smp_processor_id();
+
+       __get_cpu_var(watchdog_touch_ts) = get_timestamp(this_cpu);
+}
+
+void touch_softlockup_watchdog(void)
+{
+       __get_cpu_var(watchdog_touch_ts) = 0;
+}
+EXPORT_SYMBOL(touch_softlockup_watchdog);
+
+void touch_all_softlockup_watchdogs(void)
+{
+       int cpu;
+
+       /*
+        * this is done lockless
+        * do we care if a 0 races with a timestamp?
+        * all it means is the softlock check starts one cycle later
+        */
+       for_each_online_cpu(cpu)
+               per_cpu(watchdog_touch_ts, cpu) = 0;
+}
+
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+void touch_nmi_watchdog(void)
+{
+       __get_cpu_var(watchdog_nmi_touch) = true;
+       touch_softlockup_watchdog();
+}
+EXPORT_SYMBOL(touch_nmi_watchdog);
+
+#endif
+
+void touch_softlockup_watchdog_sync(void)
+{
+       __raw_get_cpu_var(softlockup_touch_sync) = true;
+       __raw_get_cpu_var(watchdog_touch_ts) = 0;
+}
+
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+/* watchdog detector functions */
+static int is_hardlockup(void)
+{
+       unsigned long hrint = __get_cpu_var(hrtimer_interrupts);
+
+       if (__get_cpu_var(hrtimer_interrupts_saved) == hrint)
+               return 1;
+
+       __get_cpu_var(hrtimer_interrupts_saved) = hrint;
+       return 0;
+}
+#endif
+
+static int is_softlockup(unsigned long touch_ts)
+{
+       unsigned long now = get_timestamp(smp_processor_id());
+
+       /* Warn about unreasonable delays: */
+       if (time_after(now, touch_ts + softlockup_thresh))
+               return now - touch_ts;
+
+       return 0;
+}
+
+static int
+watchdog_panic(struct notifier_block *this, unsigned long event, void *ptr)
+{
+       did_panic = 1;
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+       .notifier_call = watchdog_panic,
+};
+
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+static struct perf_event_attr wd_hw_attr = {
+       .type           = PERF_TYPE_HARDWARE,
+       .config         = PERF_COUNT_HW_CPU_CYCLES,
+       .size           = sizeof(struct perf_event_attr),
+       .pinned         = 1,
+       .disabled       = 1,
+};
+
+/* Callback function for perf event subsystem */
+void watchdog_overflow_callback(struct perf_event *event, int nmi,
+                struct perf_sample_data *data,
+                struct pt_regs *regs)
+{
+       if (__get_cpu_var(watchdog_nmi_touch) == true) {
+               __get_cpu_var(watchdog_nmi_touch) = false;
+               return;
+       }
+
+       /* check for a hardlockup
+        * This is done by making sure our timer interrupt
+        * is incrementing.  The timer interrupt should have
+        * fired multiple times before we overflow'd.  If it hasn't
+        * then this is a good indication the cpu is stuck
+        */
+       if (is_hardlockup()) {
+               int this_cpu = smp_processor_id();
+
+               /* only print hardlockups once */
+               if (__get_cpu_var(hard_watchdog_warn) == true)
+                       return;
+
+               if (hardlockup_panic)
+                       panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu);
+               else
+                       WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu);
+
+               __get_cpu_var(hard_watchdog_warn) = true;
+               return;
+       }
+
+       __get_cpu_var(hard_watchdog_warn) = false;
+       return;
+}
+static void watchdog_interrupt_count(void)
+{
+       __get_cpu_var(hrtimer_interrupts)++;
+}
+#else
+static inline void watchdog_interrupt_count(void) { return; }
+#endif /* CONFIG_HARDLOCKUP_DETECTOR */
+
+/* watchdog kicker functions */
+static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
+{
+       unsigned long touch_ts = __get_cpu_var(watchdog_touch_ts);
+       struct pt_regs *regs = get_irq_regs();
+       int duration;
+
+       /* kick the hardlockup detector */
+       watchdog_interrupt_count();
+
+       /* kick the softlockup detector */
+       wake_up_process(__get_cpu_var(softlockup_watchdog));
+
+       /* .. and repeat */
+       hrtimer_forward_now(hrtimer, ns_to_ktime(get_sample_period()));
+
+       if (touch_ts == 0) {
+               if (unlikely(__get_cpu_var(softlockup_touch_sync))) {
+                       /*
+                        * If the time stamp was touched atomically
+                        * make sure the scheduler tick is up to date.
+                        */
+                       __get_cpu_var(softlockup_touch_sync) = false;
+                       sched_clock_tick();
+               }
+               __touch_watchdog();
+               return HRTIMER_RESTART;
+       }
+
+       /* check for a softlockup
+        * This is done by making sure a high priority task is
+        * being scheduled.  The task touches the watchdog to
+        * indicate it is getting cpu time.  If it hasn't then
+        * this is a good indication some task is hogging the cpu
+        */
+       duration = is_softlockup(touch_ts);
+       if (unlikely(duration)) {
+               /* only warn once */
+               if (__get_cpu_var(soft_watchdog_warn) == true)
+                       return HRTIMER_RESTART;
+
+               printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",
+                       smp_processor_id(), duration,
+                       current->comm, task_pid_nr(current));
+               print_modules();
+               print_irqtrace_events(current);
+               if (regs)
+                       show_regs(regs);
+               else
+                       dump_stack();
+
+               if (softlockup_panic)
+                       panic("softlockup: hung tasks");
+               __get_cpu_var(soft_watchdog_warn) = true;
+       } else
+               __get_cpu_var(soft_watchdog_warn) = false;
+
+       return HRTIMER_RESTART;
+}
+
+
+/*
+ * The watchdog thread - touches the timestamp.
+ */
+static int watchdog(void *unused)
+{
+       struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
+       struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
+
+       sched_setscheduler(current, SCHED_FIFO, &param);
+
+       /* initialize timestamp */
+       __touch_watchdog();
+
+       /* kick off the timer for the hardlockup detector */
+       /* done here because hrtimer_start can only pin to smp_processor_id() */
+       hrtimer_start(hrtimer, ns_to_ktime(get_sample_period()),
+                     HRTIMER_MODE_REL_PINNED);
+
+       set_current_state(TASK_INTERRUPTIBLE);
+       /*
+        * Run briefly once per second to reset the softlockup timestamp.
+        * If this gets delayed for more than 60 seconds then the
+        * debug-printout triggers in watchdog_timer_fn().
+        */
+       while (!kthread_should_stop()) {
+               __touch_watchdog();
+               schedule();
+
+               if (kthread_should_stop())
+                       break;
+
+               set_current_state(TASK_INTERRUPTIBLE);
+       }
+       __set_current_state(TASK_RUNNING);
+
+       return 0;
+}
+
+
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+static int watchdog_nmi_enable(int cpu)
+{
+       struct perf_event_attr *wd_attr;
+       struct perf_event *event = per_cpu(watchdog_ev, cpu);
+
+       /* is it already setup and enabled? */
+       if (event && event->state > PERF_EVENT_STATE_OFF)
+               goto out;
+
+       /* it is setup but not enabled */
+       if (event != NULL)
+               goto out_enable;
+
+       /* Try to register using hardware perf events */
+       wd_attr = &wd_hw_attr;
+       wd_attr->sample_period = hw_nmi_get_sample_period();
+       event = perf_event_create_kernel_counter(wd_attr, cpu, -1, watchdog_overflow_callback);
+       if (!IS_ERR(event)) {
+               printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n");
+               goto out_save;
+       }
+
+       printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event);
+       return -1;
+
+       /* success path */
+out_save:
+       per_cpu(watchdog_ev, cpu) = event;
+out_enable:
+       perf_event_enable(per_cpu(watchdog_ev, cpu));
+out:
+       return 0;
+}
+
+static void watchdog_nmi_disable(int cpu)
+{
+       struct perf_event *event = per_cpu(watchdog_ev, cpu);
+
+       if (event) {
+               perf_event_disable(event);
+               per_cpu(watchdog_ev, cpu) = NULL;
+
+               /* should be in cleanup, but blocks oprofile */
+               perf_event_release_kernel(event);
+       }
+       return;
+}
+#else
+static int watchdog_nmi_enable(int cpu) { return 0; }
+static void watchdog_nmi_disable(int cpu) { return; }
+#endif /* CONFIG_HARDLOCKUP_DETECTOR */
+
+/* prepare/enable/disable routines */
+static int watchdog_prepare_cpu(int cpu)
+{
+       struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu);
+
+       WARN_ON(per_cpu(softlockup_watchdog, cpu));
+       hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       hrtimer->function = watchdog_timer_fn;
+
+       return 0;
+}
+
+static int watchdog_enable(int cpu)
+{
+       struct task_struct *p = per_cpu(softlockup_watchdog, cpu);
+
+       /* enable the perf event */
+       if (watchdog_nmi_enable(cpu) != 0)
+               return -1;
+
+       /* create the watchdog thread */
+       if (!p) {
+               p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu);
+               if (IS_ERR(p)) {
+                       printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu);
+                       return -1;
+               }
+               kthread_bind(p, cpu);
+               per_cpu(watchdog_touch_ts, cpu) = 0;
+               per_cpu(softlockup_watchdog, cpu) = p;
+               wake_up_process(p);
+       }
+
+       return 0;
+}
+
+static void watchdog_disable(int cpu)
+{
+       struct task_struct *p = per_cpu(softlockup_watchdog, cpu);
+       struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu);
+
+       /*
+        * cancel the timer first to stop incrementing the stats
+        * and waking up the kthread
+        */
+       hrtimer_cancel(hrtimer);
+
+       /* disable the perf event */
+       watchdog_nmi_disable(cpu);
+
+       /* stop the watchdog thread */
+       if (p) {
+               per_cpu(softlockup_watchdog, cpu) = NULL;
+               kthread_stop(p);
+       }
+
+       /* if any cpu succeeds, watchdog is considered enabled for the system */
+       watchdog_enabled = 1;
+}
+
+static void watchdog_enable_all_cpus(void)
+{
+       int cpu;
+       int result = 0;
+
+       for_each_online_cpu(cpu)
+               result += watchdog_enable(cpu);
+
+       if (result)
+               printk(KERN_ERR "watchdog: failed to be enabled on some cpus\n");
+
+}
+
+static void watchdog_disable_all_cpus(void)
+{
+       int cpu;
+
+       for_each_online_cpu(cpu)
+               watchdog_disable(cpu);
+
+       /* if all watchdogs are disabled, then they are disabled for the system */
+       watchdog_enabled = 0;
+}
+
+
+/* sysctl functions */
+#ifdef CONFIG_SYSCTL
+/*
+ * proc handler for /proc/sys/kernel/nmi_watchdog
+ */
+
+int proc_dowatchdog_enabled(struct ctl_table *table, int write,
+                    void __user *buffer, size_t *length, loff_t *ppos)
+{
+       proc_dointvec(table, write, buffer, length, ppos);
+
+       if (watchdog_enabled)
+               watchdog_enable_all_cpus();
+       else
+               watchdog_disable_all_cpus();
+       return 0;
+}
+
+int proc_dowatchdog_thresh(struct ctl_table *table, int write,
+                            void __user *buffer,
+                            size_t *lenp, loff_t *ppos)
+{
+       return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+}
+#endif /* CONFIG_SYSCTL */
+
+
+/*
+ * Create/destroy watchdog threads as CPUs come and go:
+ */
+static int __cpuinit
+cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+       int hotcpu = (unsigned long)hcpu;
+
+       switch (action) {
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+               if (watchdog_prepare_cpu(hotcpu))
+                       return NOTIFY_BAD;
+               break;
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               if (watchdog_enable(hotcpu))
+                       return NOTIFY_BAD;
+               break;
+#ifdef CONFIG_HOTPLUG_CPU
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
+               watchdog_disable(hotcpu);
+               break;
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+               watchdog_disable(hotcpu);
+               break;
+#endif /* CONFIG_HOTPLUG_CPU */
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata cpu_nfb = {
+       .notifier_call = cpu_callback
+};
+
+static int __init spawn_watchdog_task(void)
+{
+       void *cpu = (void *)(long)smp_processor_id();
+       int err;
+
+       if (no_watchdog)
+               return 0;
+
+       err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+       WARN_ON(err == NOTIFY_BAD);
+
+       cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
+       register_cpu_notifier(&cpu_nfb);
+
+       atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+
+       return 0;
+}
+early_initcall(spawn_watchdog_task);
index 327d2deb44515b438c8e43cec56415d85b22342d..9ca34cddaf6d961c1e07bee9080ff4dd6be1338e 100644 (file)
 #include <linux/kallsyms.h>
 #include <linux/debug_locks.h>
 #include <linux/lockdep.h>
-#define CREATE_TRACE_POINTS
-#include <trace/events/workqueue.h>
+#include <linux/idr.h>
+
+#include "workqueue_sched.h"
+
+enum {
+       /* global_cwq flags */
+       GCWQ_MANAGE_WORKERS     = 1 << 0,       /* need to manage workers */
+       GCWQ_MANAGING_WORKERS   = 1 << 1,       /* managing workers */
+       GCWQ_DISASSOCIATED      = 1 << 2,       /* cpu can't serve workers */
+       GCWQ_FREEZING           = 1 << 3,       /* freeze in progress */
+       GCWQ_HIGHPRI_PENDING    = 1 << 4,       /* highpri works on queue */
+
+       /* worker flags */
+       WORKER_STARTED          = 1 << 0,       /* started */
+       WORKER_DIE              = 1 << 1,       /* die die die */
+       WORKER_IDLE             = 1 << 2,       /* is idle */
+       WORKER_PREP             = 1 << 3,       /* preparing to run works */
+       WORKER_ROGUE            = 1 << 4,       /* not bound to any cpu */
+       WORKER_REBIND           = 1 << 5,       /* mom is home, come back */
+       WORKER_CPU_INTENSIVE    = 1 << 6,       /* cpu intensive */
+       WORKER_UNBOUND          = 1 << 7,       /* worker is unbound */
+
+       WORKER_NOT_RUNNING      = WORKER_PREP | WORKER_ROGUE | WORKER_REBIND |
+                                 WORKER_CPU_INTENSIVE | WORKER_UNBOUND,
+
+       /* gcwq->trustee_state */
+       TRUSTEE_START           = 0,            /* start */
+       TRUSTEE_IN_CHARGE       = 1,            /* trustee in charge of gcwq */
+       TRUSTEE_BUTCHER         = 2,            /* butcher workers */
+       TRUSTEE_RELEASE         = 3,            /* release workers */
+       TRUSTEE_DONE            = 4,            /* trustee is done */
+
+       BUSY_WORKER_HASH_ORDER  = 6,            /* 64 pointers */
+       BUSY_WORKER_HASH_SIZE   = 1 << BUSY_WORKER_HASH_ORDER,
+       BUSY_WORKER_HASH_MASK   = BUSY_WORKER_HASH_SIZE - 1,
+
+       MAX_IDLE_WORKERS_RATIO  = 4,            /* 1/4 of busy can be idle */
+       IDLE_WORKER_TIMEOUT     = 300 * HZ,     /* keep idle ones for 5 mins */
+
+       MAYDAY_INITIAL_TIMEOUT  = HZ / 100,     /* call for help after 10ms */
+       MAYDAY_INTERVAL         = HZ / 10,      /* and then every 100ms */
+       CREATE_COOLDOWN         = HZ,           /* time to breath after fail */
+       TRUSTEE_COOLDOWN        = HZ / 10,      /* for trustee draining */
+
+       /*
+        * Rescue workers are used only on emergencies and shared by
+        * all cpus.  Give -20.
+        */
+       RESCUER_NICE_LEVEL      = -20,
+};
 
 /*
- * The per-CPU workqueue (if single thread, we always use the first
- * possible cpu).
+ * Structure fields follow one of the following exclusion rules.
+ *
+ * I: Set during initialization and read-only afterwards.
+ *
+ * P: Preemption protected.  Disabling preemption is enough and should
+ *    only be modified and accessed from the local cpu.
+ *
+ * L: gcwq->lock protected.  Access with gcwq->lock held.
+ *
+ * X: During normal operation, modification requires gcwq->lock and
+ *    should be done only from local cpu.  Either disabling preemption
+ *    on local cpu or grabbing gcwq->lock is enough for read access.
+ *    If GCWQ_DISASSOCIATED is set, it's identical to L.
+ *
+ * F: wq->flush_mutex protected.
+ *
+ * W: workqueue_lock protected.
  */
-struct cpu_workqueue_struct {
 
-       spinlock_t lock;
+struct global_cwq;
 
-       struct list_head worklist;
-       wait_queue_head_t more_work;
-       struct work_struct *current_work;
+/*
+ * The poor guys doing the actual heavy lifting.  All on-duty workers
+ * are either serving the manager role, on idle list or on busy hash.
+ */
+struct worker {
+       /* on idle list while idle, on busy hash table while busy */
+       union {
+               struct list_head        entry;  /* L: while idle */
+               struct hlist_node       hentry; /* L: while busy */
+       };
 
-       struct workqueue_struct *wq;
-       struct task_struct *thread;
-} ____cacheline_aligned;
+       struct work_struct      *current_work;  /* L: work being processed */
+       struct cpu_workqueue_struct *current_cwq; /* L: current_work's cwq */
+       struct list_head        scheduled;      /* L: scheduled works */
+       struct task_struct      *task;          /* I: worker task */
+       struct global_cwq       *gcwq;          /* I: the associated gcwq */
+       /* 64 bytes boundary on 64bit, 32 on 32bit */
+       unsigned long           last_active;    /* L: last active timestamp */
+       unsigned int            flags;          /* X: flags */
+       int                     id;             /* I: worker id */
+       struct work_struct      rebind_work;    /* L: rebind worker to cpu */
+};
+
+/*
+ * Global per-cpu workqueue.  There's one and only one for each cpu
+ * and all works are queued and processed here regardless of their
+ * target workqueues.
+ */
+struct global_cwq {
+       spinlock_t              lock;           /* the gcwq lock */
+       struct list_head        worklist;       /* L: list of pending works */
+       unsigned int            cpu;            /* I: the associated cpu */
+       unsigned int            flags;          /* L: GCWQ_* flags */
+
+       int                     nr_workers;     /* L: total number of workers */
+       int                     nr_idle;        /* L: currently idle ones */
+
+       /* workers are chained either in the idle_list or busy_hash */
+       struct list_head        idle_list;      /* X: list of idle workers */
+       struct hlist_head       busy_hash[BUSY_WORKER_HASH_SIZE];
+                                               /* L: hash of busy workers */
+
+       struct timer_list       idle_timer;     /* L: worker idle timeout */
+       struct timer_list       mayday_timer;   /* L: SOS timer for dworkers */
+
+       struct ida              worker_ida;     /* L: for worker IDs */
+
+       struct task_struct      *trustee;       /* L: for gcwq shutdown */
+       unsigned int            trustee_state;  /* L: trustee state */
+       wait_queue_head_t       trustee_wait;   /* trustee wait */
+       struct worker           *first_idle;    /* L: first idle worker */
+} ____cacheline_aligned_in_smp;
+
+/*
+ * The per-CPU workqueue.  The lower WORK_STRUCT_FLAG_BITS of
+ * work_struct->data are used for flags and thus cwqs need to be
+ * aligned at two's power of the number of flag bits.
+ */
+struct cpu_workqueue_struct {
+       struct global_cwq       *gcwq;          /* I: the associated gcwq */
+       struct workqueue_struct *wq;            /* I: the owning workqueue */
+       int                     work_color;     /* L: current color */
+       int                     flush_color;    /* L: flushing color */
+       int                     nr_in_flight[WORK_NR_COLORS];
+                                               /* L: nr of in_flight works */
+       int                     nr_active;      /* L: nr of active works */
+       int                     max_active;     /* L: max active works */
+       struct list_head        delayed_works;  /* L: delayed works */
+};
+
+/*
+ * Structure used to wait for workqueue flush.
+ */
+struct wq_flusher {
+       struct list_head        list;           /* F: list of flushers */
+       int                     flush_color;    /* F: flush color waiting for */
+       struct completion       done;           /* flush completion */
+};
+
+/*
+ * All cpumasks are assumed to be always set on UP and thus can't be
+ * used to determine whether there's something to be done.
+ */
+#ifdef CONFIG_SMP
+typedef cpumask_var_t mayday_mask_t;
+#define mayday_test_and_set_cpu(cpu, mask)     \
+       cpumask_test_and_set_cpu((cpu), (mask))
+#define mayday_clear_cpu(cpu, mask)            cpumask_clear_cpu((cpu), (mask))
+#define for_each_mayday_cpu(cpu, mask)         for_each_cpu((cpu), (mask))
+#define alloc_mayday_mask(maskp, gfp)          alloc_cpumask_var((maskp), (gfp))
+#define free_mayday_mask(mask)                 free_cpumask_var((mask))
+#else
+typedef unsigned long mayday_mask_t;
+#define mayday_test_and_set_cpu(cpu, mask)     test_and_set_bit(0, &(mask))
+#define mayday_clear_cpu(cpu, mask)            clear_bit(0, &(mask))
+#define for_each_mayday_cpu(cpu, mask)         if ((cpu) = 0, (mask))
+#define alloc_mayday_mask(maskp, gfp)          true
+#define free_mayday_mask(mask)                 do { } while (0)
+#endif
 
 /*
  * The externally visible workqueue abstraction is an array of
  * per-CPU workqueues:
  */
 struct workqueue_struct {
-       struct cpu_workqueue_struct *cpu_wq;
-       struct list_head list;
-       const char *name;
-       int singlethread;
-       int freezeable;         /* Freeze threads during suspend */
-       int rt;
+       unsigned int            flags;          /* I: WQ_* flags */
+       union {
+               struct cpu_workqueue_struct __percpu    *pcpu;
+               struct cpu_workqueue_struct             *single;
+               unsigned long                           v;
+       } cpu_wq;                               /* I: cwq's */
+       struct list_head        list;           /* W: list of all workqueues */
+
+       struct mutex            flush_mutex;    /* protects wq flushing */
+       int                     work_color;     /* F: current work color */
+       int                     flush_color;    /* F: current flush color */
+       atomic_t                nr_cwqs_to_flush; /* flush in progress */
+       struct wq_flusher       *first_flusher; /* F: first flusher */
+       struct list_head        flusher_queue;  /* F: flush waiters */
+       struct list_head        flusher_overflow; /* F: flush overflow list */
+
+       mayday_mask_t           mayday_mask;    /* cpus requesting rescue */
+       struct worker           *rescuer;       /* I: rescue worker */
+
+       int                     saved_max_active; /* W: saved cwq max_active */
+       const char              *name;          /* I: workqueue name */
 #ifdef CONFIG_LOCKDEP
-       struct lockdep_map lockdep_map;
+       struct lockdep_map      lockdep_map;
 #endif
 };
 
+struct workqueue_struct *system_wq __read_mostly;
+struct workqueue_struct *system_long_wq __read_mostly;
+struct workqueue_struct *system_nrt_wq __read_mostly;
+struct workqueue_struct *system_unbound_wq __read_mostly;
+EXPORT_SYMBOL_GPL(system_wq);
+EXPORT_SYMBOL_GPL(system_long_wq);
+EXPORT_SYMBOL_GPL(system_nrt_wq);
+EXPORT_SYMBOL_GPL(system_unbound_wq);
+
+#define for_each_busy_worker(worker, i, pos, gcwq)                     \
+       for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++)                     \
+               hlist_for_each_entry(worker, pos, &gcwq->busy_hash[i], hentry)
+
+static inline int __next_gcwq_cpu(int cpu, const struct cpumask *mask,
+                                 unsigned int sw)
+{
+       if (cpu < nr_cpu_ids) {
+               if (sw & 1) {
+                       cpu = cpumask_next(cpu, mask);
+                       if (cpu < nr_cpu_ids)
+                               return cpu;
+               }
+               if (sw & 2)
+                       return WORK_CPU_UNBOUND;
+       }
+       return WORK_CPU_NONE;
+}
+
+static inline int __next_wq_cpu(int cpu, const struct cpumask *mask,
+                               struct workqueue_struct *wq)
+{
+       return __next_gcwq_cpu(cpu, mask, !(wq->flags & WQ_UNBOUND) ? 1 : 2);
+}
+
+/*
+ * CPU iterators
+ *
+ * An extra gcwq is defined for an invalid cpu number
+ * (WORK_CPU_UNBOUND) to host workqueues which are not bound to any
+ * specific CPU.  The following iterators are similar to
+ * for_each_*_cpu() iterators but also considers the unbound gcwq.
+ *
+ * for_each_gcwq_cpu()         : possible CPUs + WORK_CPU_UNBOUND
+ * for_each_online_gcwq_cpu()  : online CPUs + WORK_CPU_UNBOUND
+ * for_each_cwq_cpu()          : possible CPUs for bound workqueues,
+ *                               WORK_CPU_UNBOUND for unbound workqueues
+ */
+#define for_each_gcwq_cpu(cpu)                                         \
+       for ((cpu) = __next_gcwq_cpu(-1, cpu_possible_mask, 3);         \
+            (cpu) < WORK_CPU_NONE;                                     \
+            (cpu) = __next_gcwq_cpu((cpu), cpu_possible_mask, 3))
+
+#define for_each_online_gcwq_cpu(cpu)                                  \
+       for ((cpu) = __next_gcwq_cpu(-1, cpu_online_mask, 3);           \
+            (cpu) < WORK_CPU_NONE;                                     \
+            (cpu) = __next_gcwq_cpu((cpu), cpu_online_mask, 3))
+
+#define for_each_cwq_cpu(cpu, wq)                                      \
+       for ((cpu) = __next_wq_cpu(-1, cpu_possible_mask, (wq));        \
+            (cpu) < WORK_CPU_NONE;                                     \
+            (cpu) = __next_wq_cpu((cpu), cpu_possible_mask, (wq)))
+
+#ifdef CONFIG_LOCKDEP
+/**
+ * in_workqueue_context() - in context of specified workqueue?
+ * @wq: the workqueue of interest
+ *
+ * Checks lockdep state to see if the current task is executing from
+ * within a workqueue item.  This function exists only if lockdep is
+ * enabled.
+ */
+int in_workqueue_context(struct workqueue_struct *wq)
+{
+       return lock_is_held(&wq->lockdep_map);
+}
+#endif
+
 #ifdef CONFIG_DEBUG_OBJECTS_WORK
 
 static struct debug_obj_descr work_debug_descr;
@@ -107,7 +353,7 @@ static int work_fixup_activate(void *addr, enum debug_obj_state state)
                 * statically initialized. We just make sure that it
                 * is tracked in the object tracker.
                 */
-               if (test_bit(WORK_STRUCT_STATIC, work_data_bits(work))) {
+               if (test_bit(WORK_STRUCT_STATIC_BIT, work_data_bits(work))) {
                        debug_object_init(work, &work_debug_descr);
                        debug_object_activate(work, &work_debug_descr);
                        return 0;
@@ -181,94 +427,575 @@ static inline void debug_work_deactivate(struct work_struct *work) { }
 /* Serializes the accesses to the list of workqueues. */
 static DEFINE_SPINLOCK(workqueue_lock);
 static LIST_HEAD(workqueues);
+static bool workqueue_freezing;                /* W: have wqs started freezing? */
+
+/*
+ * The almighty global cpu workqueues.  nr_running is the only field
+ * which is expected to be used frequently by other cpus via
+ * try_to_wake_up().  Put it in a separate cacheline.
+ */
+static DEFINE_PER_CPU(struct global_cwq, global_cwq);
+static DEFINE_PER_CPU_SHARED_ALIGNED(atomic_t, gcwq_nr_running);
 
-static int singlethread_cpu __read_mostly;
-static const struct cpumask *cpu_singlethread_map __read_mostly;
 /*
- * _cpu_down() first removes CPU from cpu_online_map, then CPU_DEAD
- * flushes cwq->worklist. This means that flush_workqueue/wait_on_work
- * which comes in between can't use for_each_online_cpu(). We could
- * use cpu_possible_map, the cpumask below is more a documentation
- * than optimization.
+ * Global cpu workqueue and nr_running counter for unbound gcwq.  The
+ * gcwq is always online, has GCWQ_DISASSOCIATED set, and all its
+ * workers have WORKER_UNBOUND set.
  */
-static cpumask_var_t cpu_populated_map __read_mostly;
+static struct global_cwq unbound_global_cwq;
+static atomic_t unbound_gcwq_nr_running = ATOMIC_INIT(0);      /* always 0 */
+
+static int worker_thread(void *__worker);
+
+static struct global_cwq *get_gcwq(unsigned int cpu)
+{
+       if (cpu != WORK_CPU_UNBOUND)
+               return &per_cpu(global_cwq, cpu);
+       else
+               return &unbound_global_cwq;
+}
+
+static atomic_t *get_gcwq_nr_running(unsigned int cpu)
+{
+       if (cpu != WORK_CPU_UNBOUND)
+               return &per_cpu(gcwq_nr_running, cpu);
+       else
+               return &unbound_gcwq_nr_running;
+}
+
+static struct cpu_workqueue_struct *get_cwq(unsigned int cpu,
+                                           struct workqueue_struct *wq)
+{
+       if (!(wq->flags & WQ_UNBOUND)) {
+               if (likely(cpu < nr_cpu_ids)) {
+#ifdef CONFIG_SMP
+                       return per_cpu_ptr(wq->cpu_wq.pcpu, cpu);
+#else
+                       return wq->cpu_wq.single;
+#endif
+               }
+       } else if (likely(cpu == WORK_CPU_UNBOUND))
+               return wq->cpu_wq.single;
+       return NULL;
+}
 
-/* If it's single threaded, it isn't in the list of workqueues. */
-static inline int is_wq_single_threaded(struct workqueue_struct *wq)
+static unsigned int work_color_to_flags(int color)
 {
-       return wq->singlethread;
+       return color << WORK_STRUCT_COLOR_SHIFT;
 }
 
-static const struct cpumask *wq_cpu_map(struct workqueue_struct *wq)
+static int get_work_color(struct work_struct *work)
 {
-       return is_wq_single_threaded(wq)
-               ? cpu_singlethread_map : cpu_populated_map;
+       return (*work_data_bits(work) >> WORK_STRUCT_COLOR_SHIFT) &
+               ((1 << WORK_STRUCT_COLOR_BITS) - 1);
 }
 
-static
-struct cpu_workqueue_struct *wq_per_cpu(struct workqueue_struct *wq, int cpu)
+static int work_next_color(int color)
 {
-       if (unlikely(is_wq_single_threaded(wq)))
-               cpu = singlethread_cpu;
-       return per_cpu_ptr(wq->cpu_wq, cpu);
+       return (color + 1) % WORK_NR_COLORS;
 }
 
 /*
- * Set the workqueue on which a work item is to be run
- * - Must *only* be called if the pending flag is set
+ * A work's data points to the cwq with WORK_STRUCT_CWQ set while the
+ * work is on queue.  Once execution starts, WORK_STRUCT_CWQ is
+ * cleared and the work data contains the cpu number it was last on.
+ *
+ * set_work_{cwq|cpu}() and clear_work_data() can be used to set the
+ * cwq, cpu or clear work->data.  These functions should only be
+ * called while the work is owned - ie. while the PENDING bit is set.
+ *
+ * get_work_[g]cwq() can be used to obtain the gcwq or cwq
+ * corresponding to a work.  gcwq is available once the work has been
+ * queued anywhere after initialization.  cwq is available only from
+ * queueing until execution starts.
  */
-static inline void set_wq_data(struct work_struct *work,
-                               struct cpu_workqueue_struct *cwq)
+static inline void set_work_data(struct work_struct *work, unsigned long data,
+                                unsigned long flags)
 {
-       unsigned long new;
-
        BUG_ON(!work_pending(work));
+       atomic_long_set(&work->data, data | flags | work_static(work));
+}
+
+static void set_work_cwq(struct work_struct *work,
+                        struct cpu_workqueue_struct *cwq,
+                        unsigned long extra_flags)
+{
+       set_work_data(work, (unsigned long)cwq,
+                     WORK_STRUCT_PENDING | WORK_STRUCT_CWQ | extra_flags);
+}
+
+static void set_work_cpu(struct work_struct *work, unsigned int cpu)
+{
+       set_work_data(work, cpu << WORK_STRUCT_FLAG_BITS, WORK_STRUCT_PENDING);
+}
+
+static void clear_work_data(struct work_struct *work)
+{
+       set_work_data(work, WORK_STRUCT_NO_CPU, 0);
+}
+
+static struct cpu_workqueue_struct *get_work_cwq(struct work_struct *work)
+{
+       unsigned long data = atomic_long_read(&work->data);
+
+       if (data & WORK_STRUCT_CWQ)
+               return (void *)(data & WORK_STRUCT_WQ_DATA_MASK);
+       else
+               return NULL;
+}
+
+static struct global_cwq *get_work_gcwq(struct work_struct *work)
+{
+       unsigned long data = atomic_long_read(&work->data);
+       unsigned int cpu;
+
+       if (data & WORK_STRUCT_CWQ)
+               return ((struct cpu_workqueue_struct *)
+                       (data & WORK_STRUCT_WQ_DATA_MASK))->gcwq;
+
+       cpu = data >> WORK_STRUCT_FLAG_BITS;
+       if (cpu == WORK_CPU_NONE)
+               return NULL;
+
+       BUG_ON(cpu >= nr_cpu_ids && cpu != WORK_CPU_UNBOUND);
+       return get_gcwq(cpu);
+}
+
+/*
+ * Policy functions.  These define the policies on how the global
+ * worker pool is managed.  Unless noted otherwise, these functions
+ * assume that they're being called with gcwq->lock held.
+ */
+
+static bool __need_more_worker(struct global_cwq *gcwq)
+{
+       return !atomic_read(get_gcwq_nr_running(gcwq->cpu)) ||
+               gcwq->flags & GCWQ_HIGHPRI_PENDING;
+}
+
+/*
+ * Need to wake up a worker?  Called from anything but currently
+ * running workers.
+ */
+static bool need_more_worker(struct global_cwq *gcwq)
+{
+       return !list_empty(&gcwq->worklist) && __need_more_worker(gcwq);
+}
+
+/* Can I start working?  Called from busy but !running workers. */
+static bool may_start_working(struct global_cwq *gcwq)
+{
+       return gcwq->nr_idle;
+}
+
+/* Do I need to keep working?  Called from currently running workers. */
+static bool keep_working(struct global_cwq *gcwq)
+{
+       atomic_t *nr_running = get_gcwq_nr_running(gcwq->cpu);
+
+       return !list_empty(&gcwq->worklist) && atomic_read(nr_running) <= 1;
+}
+
+/* Do we need a new worker?  Called from manager. */
+static bool need_to_create_worker(struct global_cwq *gcwq)
+{
+       return need_more_worker(gcwq) && !may_start_working(gcwq);
+}
 
-       new = (unsigned long) cwq | (1UL << WORK_STRUCT_PENDING);
-       new |= WORK_STRUCT_FLAG_MASK & *work_data_bits(work);
-       atomic_long_set(&work->data, new);
+/* Do I need to be the manager? */
+static bool need_to_manage_workers(struct global_cwq *gcwq)
+{
+       return need_to_create_worker(gcwq) || gcwq->flags & GCWQ_MANAGE_WORKERS;
+}
+
+/* Do we have too many workers and should some go away? */
+static bool too_many_workers(struct global_cwq *gcwq)
+{
+       bool managing = gcwq->flags & GCWQ_MANAGING_WORKERS;
+       int nr_idle = gcwq->nr_idle + managing; /* manager is considered idle */
+       int nr_busy = gcwq->nr_workers - nr_idle;
+
+       return nr_idle > 2 && (nr_idle - 2) * MAX_IDLE_WORKERS_RATIO >= nr_busy;
 }
 
 /*
- * Clear WORK_STRUCT_PENDING and the workqueue on which it was queued.
+ * Wake up functions.
+ */
+
+/* Return the first worker.  Safe with preemption disabled */
+static struct worker *first_worker(struct global_cwq *gcwq)
+{
+       if (unlikely(list_empty(&gcwq->idle_list)))
+               return NULL;
+
+       return list_first_entry(&gcwq->idle_list, struct worker, entry);
+}
+
+/**
+ * wake_up_worker - wake up an idle worker
+ * @gcwq: gcwq to wake worker for
+ *
+ * Wake up the first idle worker of @gcwq.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ */
+static void wake_up_worker(struct global_cwq *gcwq)
+{
+       struct worker *worker = first_worker(gcwq);
+
+       if (likely(worker))
+               wake_up_process(worker->task);
+}
+
+/**
+ * wq_worker_waking_up - a worker is waking up
+ * @task: task waking up
+ * @cpu: CPU @task is waking up to
+ *
+ * This function is called during try_to_wake_up() when a worker is
+ * being awoken.
+ *
+ * CONTEXT:
+ * spin_lock_irq(rq->lock)
+ */
+void wq_worker_waking_up(struct task_struct *task, unsigned int cpu)
+{
+       struct worker *worker = kthread_data(task);
+
+       if (likely(!(worker->flags & WORKER_NOT_RUNNING)))
+               atomic_inc(get_gcwq_nr_running(cpu));
+}
+
+/**
+ * wq_worker_sleeping - a worker is going to sleep
+ * @task: task going to sleep
+ * @cpu: CPU in question, must be the current CPU number
+ *
+ * This function is called during schedule() when a busy worker is
+ * going to sleep.  Worker on the same cpu can be woken up by
+ * returning pointer to its task.
+ *
+ * CONTEXT:
+ * spin_lock_irq(rq->lock)
+ *
+ * RETURNS:
+ * Worker task on @cpu to wake up, %NULL if none.
+ */
+struct task_struct *wq_worker_sleeping(struct task_struct *task,
+                                      unsigned int cpu)
+{
+       struct worker *worker = kthread_data(task), *to_wakeup = NULL;
+       struct global_cwq *gcwq = get_gcwq(cpu);
+       atomic_t *nr_running = get_gcwq_nr_running(cpu);
+
+       if (unlikely(worker->flags & WORKER_NOT_RUNNING))
+               return NULL;
+
+       /* this can only happen on the local cpu */
+       BUG_ON(cpu != raw_smp_processor_id());
+
+       /*
+        * The counterpart of the following dec_and_test, implied mb,
+        * worklist not empty test sequence is in insert_work().
+        * Please read comment there.
+        *
+        * NOT_RUNNING is clear.  This means that trustee is not in
+        * charge and we're running on the local cpu w/ rq lock held
+        * and preemption disabled, which in turn means that none else
+        * could be manipulating idle_list, so dereferencing idle_list
+        * without gcwq lock is safe.
+        */
+       if (atomic_dec_and_test(nr_running) && !list_empty(&gcwq->worklist))
+               to_wakeup = first_worker(gcwq);
+       return to_wakeup ? to_wakeup->task : NULL;
+}
+
+/**
+ * worker_set_flags - set worker flags and adjust nr_running accordingly
+ * @worker: self
+ * @flags: flags to set
+ * @wakeup: wakeup an idle worker if necessary
+ *
+ * Set @flags in @worker->flags and adjust nr_running accordingly.  If
+ * nr_running becomes zero and @wakeup is %true, an idle worker is
+ * woken up.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock)
+ */
+static inline void worker_set_flags(struct worker *worker, unsigned int flags,
+                                   bool wakeup)
+{
+       struct global_cwq *gcwq = worker->gcwq;
+
+       WARN_ON_ONCE(worker->task != current);
+
+       /*
+        * If transitioning into NOT_RUNNING, adjust nr_running and
+        * wake up an idle worker as necessary if requested by
+        * @wakeup.
+        */
+       if ((flags & WORKER_NOT_RUNNING) &&
+           !(worker->flags & WORKER_NOT_RUNNING)) {
+               atomic_t *nr_running = get_gcwq_nr_running(gcwq->cpu);
+
+               if (wakeup) {
+                       if (atomic_dec_and_test(nr_running) &&
+                           !list_empty(&gcwq->worklist))
+                               wake_up_worker(gcwq);
+               } else
+                       atomic_dec(nr_running);
+       }
+
+       worker->flags |= flags;
+}
+
+/**
+ * worker_clr_flags - clear worker flags and adjust nr_running accordingly
+ * @worker: self
+ * @flags: flags to clear
+ *
+ * Clear @flags in @worker->flags and adjust nr_running accordingly.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock)
+ */
+static inline void worker_clr_flags(struct worker *worker, unsigned int flags)
+{
+       struct global_cwq *gcwq = worker->gcwq;
+       unsigned int oflags = worker->flags;
+
+       WARN_ON_ONCE(worker->task != current);
+
+       worker->flags &= ~flags;
+
+       /* if transitioning out of NOT_RUNNING, increment nr_running */
+       if ((flags & WORKER_NOT_RUNNING) && (oflags & WORKER_NOT_RUNNING))
+               if (!(worker->flags & WORKER_NOT_RUNNING))
+                       atomic_inc(get_gcwq_nr_running(gcwq->cpu));
+}
+
+/**
+ * busy_worker_head - return the busy hash head for a work
+ * @gcwq: gcwq of interest
+ * @work: work to be hashed
+ *
+ * Return hash head of @gcwq for @work.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ *
+ * RETURNS:
+ * Pointer to the hash head.
+ */
+static struct hlist_head *busy_worker_head(struct global_cwq *gcwq,
+                                          struct work_struct *work)
+{
+       const int base_shift = ilog2(sizeof(struct work_struct));
+       unsigned long v = (unsigned long)work;
+
+       /* simple shift and fold hash, do we need something better? */
+       v >>= base_shift;
+       v += v >> BUSY_WORKER_HASH_ORDER;
+       v &= BUSY_WORKER_HASH_MASK;
+
+       return &gcwq->busy_hash[v];
+}
+
+/**
+ * __find_worker_executing_work - find worker which is executing a work
+ * @gcwq: gcwq of interest
+ * @bwh: hash head as returned by busy_worker_head()
+ * @work: work to find worker for
+ *
+ * Find a worker which is executing @work on @gcwq.  @bwh should be
+ * the hash head obtained by calling busy_worker_head() with the same
+ * work.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ *
+ * RETURNS:
+ * Pointer to worker which is executing @work if found, NULL
+ * otherwise.
+ */
+static struct worker *__find_worker_executing_work(struct global_cwq *gcwq,
+                                                  struct hlist_head *bwh,
+                                                  struct work_struct *work)
+{
+       struct worker *worker;
+       struct hlist_node *tmp;
+
+       hlist_for_each_entry(worker, tmp, bwh, hentry)
+               if (worker->current_work == work)
+                       return worker;
+       return NULL;
+}
+
+/**
+ * find_worker_executing_work - find worker which is executing a work
+ * @gcwq: gcwq of interest
+ * @work: work to find worker for
+ *
+ * Find a worker which is executing @work on @gcwq.  This function is
+ * identical to __find_worker_executing_work() except that this
+ * function calculates @bwh itself.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ *
+ * RETURNS:
+ * Pointer to worker which is executing @work if found, NULL
+ * otherwise.
  */
-static inline void clear_wq_data(struct work_struct *work)
+static struct worker *find_worker_executing_work(struct global_cwq *gcwq,
+                                                struct work_struct *work)
 {
-       unsigned long flags = *work_data_bits(work) &
-                               (1UL << WORK_STRUCT_STATIC);
-       atomic_long_set(&work->data, flags);
+       return __find_worker_executing_work(gcwq, busy_worker_head(gcwq, work),
+                                           work);
 }
 
-static inline
-struct cpu_workqueue_struct *get_wq_data(struct work_struct *work)
+/**
+ * gcwq_determine_ins_pos - find insertion position
+ * @gcwq: gcwq of interest
+ * @cwq: cwq a work is being queued for
+ *
+ * A work for @cwq is about to be queued on @gcwq, determine insertion
+ * position for the work.  If @cwq is for HIGHPRI wq, the work is
+ * queued at the head of the queue but in FIFO order with respect to
+ * other HIGHPRI works; otherwise, at the end of the queue.  This
+ * function also sets GCWQ_HIGHPRI_PENDING flag to hint @gcwq that
+ * there are HIGHPRI works pending.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ *
+ * RETURNS:
+ * Pointer to inserstion position.
+ */
+static inline struct list_head *gcwq_determine_ins_pos(struct global_cwq *gcwq,
+                                              struct cpu_workqueue_struct *cwq)
 {
-       return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);
+       struct work_struct *twork;
+
+       if (likely(!(cwq->wq->flags & WQ_HIGHPRI)))
+               return &gcwq->worklist;
+
+       list_for_each_entry(twork, &gcwq->worklist, entry) {
+               struct cpu_workqueue_struct *tcwq = get_work_cwq(twork);
+
+               if (!(tcwq->wq->flags & WQ_HIGHPRI))
+                       break;
+       }
+
+       gcwq->flags |= GCWQ_HIGHPRI_PENDING;
+       return &twork->entry;
 }
 
+/**
+ * insert_work - insert a work into gcwq
+ * @cwq: cwq @work belongs to
+ * @work: work to insert
+ * @head: insertion point
+ * @extra_flags: extra WORK_STRUCT_* flags to set
+ *
+ * Insert @work which belongs to @cwq into @gcwq after @head.
+ * @extra_flags is or'd to work_struct flags.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ */
 static void insert_work(struct cpu_workqueue_struct *cwq,
-                       struct work_struct *work, struct list_head *head)
+                       struct work_struct *work, struct list_head *head,
+                       unsigned int extra_flags)
 {
-       trace_workqueue_insertion(cwq->thread, work);
+       struct global_cwq *gcwq = cwq->gcwq;
+
+       /* we own @work, set data and link */
+       set_work_cwq(work, cwq, extra_flags);
 
-       set_wq_data(work, cwq);
        /*
         * Ensure that we get the right work->data if we see the
         * result of list_add() below, see try_to_grab_pending().
         */
        smp_wmb();
+
        list_add_tail(&work->entry, head);
-       wake_up(&cwq->more_work);
+
+       /*
+        * Ensure either worker_sched_deactivated() sees the above
+        * list_add_tail() or we see zero nr_running to avoid workers
+        * lying around lazily while there are works to be processed.
+        */
+       smp_mb();
+
+       if (__need_more_worker(gcwq))
+               wake_up_worker(gcwq);
 }
 
-static void __queue_work(struct cpu_workqueue_struct *cwq,
+static void __queue_work(unsigned int cpu, struct workqueue_struct *wq,
                         struct work_struct *work)
 {
+       struct global_cwq *gcwq;
+       struct cpu_workqueue_struct *cwq;
+       struct list_head *worklist;
        unsigned long flags;
 
        debug_work_activate(work);
-       spin_lock_irqsave(&cwq->lock, flags);
-       insert_work(cwq, work, &cwq->worklist);
-       spin_unlock_irqrestore(&cwq->lock, flags);
+
+       /* determine gcwq to use */
+       if (!(wq->flags & WQ_UNBOUND)) {
+               struct global_cwq *last_gcwq;
+
+               if (unlikely(cpu == WORK_CPU_UNBOUND))
+                       cpu = raw_smp_processor_id();
+
+               /*
+                * It's multi cpu.  If @wq is non-reentrant and @work
+                * was previously on a different cpu, it might still
+                * be running there, in which case the work needs to
+                * be queued on that cpu to guarantee non-reentrance.
+                */
+               gcwq = get_gcwq(cpu);
+               if (wq->flags & WQ_NON_REENTRANT &&
+                   (last_gcwq = get_work_gcwq(work)) && last_gcwq != gcwq) {
+                       struct worker *worker;
+
+                       spin_lock_irqsave(&last_gcwq->lock, flags);
+
+                       worker = find_worker_executing_work(last_gcwq, work);
+
+                       if (worker && worker->current_cwq->wq == wq)
+                               gcwq = last_gcwq;
+                       else {
+                               /* meh... not running there, queue here */
+                               spin_unlock_irqrestore(&last_gcwq->lock, flags);
+                               spin_lock_irqsave(&gcwq->lock, flags);
+                       }
+               } else
+                       spin_lock_irqsave(&gcwq->lock, flags);
+       } else {
+               gcwq = get_gcwq(WORK_CPU_UNBOUND);
+               spin_lock_irqsave(&gcwq->lock, flags);
+       }
+
+       /* gcwq determined, get cwq and queue */
+       cwq = get_cwq(gcwq->cpu, wq);
+
+       BUG_ON(!list_empty(&work->entry));
+
+       cwq->nr_in_flight[cwq->work_color]++;
+
+       if (likely(cwq->nr_active < cwq->max_active)) {
+               cwq->nr_active++;
+               worklist = gcwq_determine_ins_pos(gcwq, cwq);
+       } else
+               worklist = &cwq->delayed_works;
+
+       insert_work(cwq, work, worklist, work_color_to_flags(cwq->work_color));
+
+       spin_unlock_irqrestore(&gcwq->lock, flags);
 }
 
 /**
@@ -308,9 +1035,8 @@ queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work)
 {
        int ret = 0;
 
-       if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
-               BUG_ON(!list_empty(&work->entry));
-               __queue_work(wq_per_cpu(wq, cpu), work);
+       if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) {
+               __queue_work(cpu, wq, work);
                ret = 1;
        }
        return ret;
@@ -320,10 +1046,9 @@ EXPORT_SYMBOL_GPL(queue_work_on);
 static void delayed_work_timer_fn(unsigned long __data)
 {
        struct delayed_work *dwork = (struct delayed_work *)__data;
-       struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work);
-       struct workqueue_struct *wq = cwq->wq;
+       struct cpu_workqueue_struct *cwq = get_work_cwq(&dwork->work);
 
-       __queue_work(wq_per_cpu(wq, smp_processor_id()), &dwork->work);
+       __queue_work(smp_processor_id(), cwq->wq, &dwork->work);
 }
 
 /**
@@ -360,16 +1085,33 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
        struct timer_list *timer = &dwork->timer;
        struct work_struct *work = &dwork->work;
 
-       if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
+       if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) {
+               unsigned int lcpu;
+
                BUG_ON(timer_pending(timer));
                BUG_ON(!list_empty(&work->entry));
 
                timer_stats_timer_set_start_info(&dwork->timer);
 
-               /* This stores cwq for the moment, for the timer_fn */
-               set_wq_data(work, wq_per_cpu(wq, raw_smp_processor_id()));
-               timer->expires = jiffies + delay;
-               timer->data = (unsigned long)dwork;
+               /*
+                * This stores cwq for the moment, for the timer_fn.
+                * Note that the work's gcwq is preserved to allow
+                * reentrance detection for delayed works.
+                */
+               if (!(wq->flags & WQ_UNBOUND)) {
+                       struct global_cwq *gcwq = get_work_gcwq(work);
+
+                       if (gcwq && gcwq->cpu != WORK_CPU_UNBOUND)
+                               lcpu = gcwq->cpu;
+                       else
+                               lcpu = raw_smp_processor_id();
+               } else
+                       lcpu = WORK_CPU_UNBOUND;
+
+               set_work_cwq(work, get_cwq(lcpu, wq), 0);
+
+               timer->expires = jiffies + delay;
+               timer->data = (unsigned long)dwork;
                timer->function = delayed_work_timer_fn;
 
                if (unlikely(cpu >= 0))
@@ -382,80 +1124,872 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
 }
 EXPORT_SYMBOL_GPL(queue_delayed_work_on);
 
-static void run_workqueue(struct cpu_workqueue_struct *cwq)
+/**
+ * worker_enter_idle - enter idle state
+ * @worker: worker which is entering idle state
+ *
+ * @worker is entering idle state.  Update stats and idle timer if
+ * necessary.
+ *
+ * LOCKING:
+ * spin_lock_irq(gcwq->lock).
+ */
+static void worker_enter_idle(struct worker *worker)
+{
+       struct global_cwq *gcwq = worker->gcwq;
+
+       BUG_ON(worker->flags & WORKER_IDLE);
+       BUG_ON(!list_empty(&worker->entry) &&
+              (worker->hentry.next || worker->hentry.pprev));
+
+       /* can't use worker_set_flags(), also called from start_worker() */
+       worker->flags |= WORKER_IDLE;
+       gcwq->nr_idle++;
+       worker->last_active = jiffies;
+
+       /* idle_list is LIFO */
+       list_add(&worker->entry, &gcwq->idle_list);
+
+       if (likely(!(worker->flags & WORKER_ROGUE))) {
+               if (too_many_workers(gcwq) && !timer_pending(&gcwq->idle_timer))
+                       mod_timer(&gcwq->idle_timer,
+                                 jiffies + IDLE_WORKER_TIMEOUT);
+       } else
+               wake_up_all(&gcwq->trustee_wait);
+
+       /* sanity check nr_running */
+       WARN_ON_ONCE(gcwq->nr_workers == gcwq->nr_idle &&
+                    atomic_read(get_gcwq_nr_running(gcwq->cpu)));
+}
+
+/**
+ * worker_leave_idle - leave idle state
+ * @worker: worker which is leaving idle state
+ *
+ * @worker is leaving idle state.  Update stats.
+ *
+ * LOCKING:
+ * spin_lock_irq(gcwq->lock).
+ */
+static void worker_leave_idle(struct worker *worker)
 {
-       spin_lock_irq(&cwq->lock);
-       while (!list_empty(&cwq->worklist)) {
-               struct work_struct *work = list_entry(cwq->worklist.next,
-                                               struct work_struct, entry);
-               work_func_t f = work->func;
-#ifdef CONFIG_LOCKDEP
+       struct global_cwq *gcwq = worker->gcwq;
+
+       BUG_ON(!(worker->flags & WORKER_IDLE));
+       worker_clr_flags(worker, WORKER_IDLE);
+       gcwq->nr_idle--;
+       list_del_init(&worker->entry);
+}
+
+/**
+ * worker_maybe_bind_and_lock - bind worker to its cpu if possible and lock gcwq
+ * @worker: self
+ *
+ * Works which are scheduled while the cpu is online must at least be
+ * scheduled to a worker which is bound to the cpu so that if they are
+ * flushed from cpu callbacks while cpu is going down, they are
+ * guaranteed to execute on the cpu.
+ *
+ * This function is to be used by rogue workers and rescuers to bind
+ * themselves to the target cpu and may race with cpu going down or
+ * coming online.  kthread_bind() can't be used because it may put the
+ * worker to already dead cpu and set_cpus_allowed_ptr() can't be used
+ * verbatim as it's best effort and blocking and gcwq may be
+ * [dis]associated in the meantime.
+ *
+ * This function tries set_cpus_allowed() and locks gcwq and verifies
+ * the binding against GCWQ_DISASSOCIATED which is set during
+ * CPU_DYING and cleared during CPU_ONLINE, so if the worker enters
+ * idle state or fetches works without dropping lock, it can guarantee
+ * the scheduling requirement described in the first paragraph.
+ *
+ * CONTEXT:
+ * Might sleep.  Called without any lock but returns with gcwq->lock
+ * held.
+ *
+ * RETURNS:
+ * %true if the associated gcwq is online (@worker is successfully
+ * bound), %false if offline.
+ */
+static bool worker_maybe_bind_and_lock(struct worker *worker)
+{
+       struct global_cwq *gcwq = worker->gcwq;
+       struct task_struct *task = worker->task;
+
+       while (true) {
                /*
-                * It is permissible to free the struct work_struct
-                * from inside the function that is called from it,
-                * this we need to take into account for lockdep too.
-                * To avoid bogus "held lock freed" warnings as well
-                * as problems when looking into work->lockdep_map,
-                * make a copy and use that here.
+                * The following call may fail, succeed or succeed
+                * without actually migrating the task to the cpu if
+                * it races with cpu hotunplug operation.  Verify
+                * against GCWQ_DISASSOCIATED.
                 */
-               struct lockdep_map lockdep_map = work->lockdep_map;
-#endif
-               trace_workqueue_execution(cwq->thread, work);
-               debug_work_deactivate(work);
-               cwq->current_work = work;
-               list_del_init(cwq->worklist.next);
-               spin_unlock_irq(&cwq->lock);
-
-               BUG_ON(get_wq_data(work) != cwq);
-               work_clear_pending(work);
-               lock_map_acquire(&cwq->wq->lockdep_map);
-               lock_map_acquire(&lockdep_map);
-               f(work);
-               lock_map_release(&lockdep_map);
-               lock_map_release(&cwq->wq->lockdep_map);
-
-               if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
-                       printk(KERN_ERR "BUG: workqueue leaked lock or atomic: "
-                                       "%s/0x%08x/%d\n",
-                                       current->comm, preempt_count(),
-                                       task_pid_nr(current));
-                       printk(KERN_ERR "    last function: ");
-                       print_symbol("%s\n", (unsigned long)f);
-                       debug_show_held_locks(current);
-                       dump_stack();
+               if (!(gcwq->flags & GCWQ_DISASSOCIATED))
+                       set_cpus_allowed_ptr(task, get_cpu_mask(gcwq->cpu));
+
+               spin_lock_irq(&gcwq->lock);
+               if (gcwq->flags & GCWQ_DISASSOCIATED)
+                       return false;
+               if (task_cpu(task) == gcwq->cpu &&
+                   cpumask_equal(&current->cpus_allowed,
+                                 get_cpu_mask(gcwq->cpu)))
+                       return true;
+               spin_unlock_irq(&gcwq->lock);
+
+               /* CPU has come up inbetween, retry migration */
+               cpu_relax();
+       }
+}
+
+/*
+ * Function for worker->rebind_work used to rebind rogue busy workers
+ * to the associated cpu which is coming back online.  This is
+ * scheduled by cpu up but can race with other cpu hotplug operations
+ * and may be executed twice without intervening cpu down.
+ */
+static void worker_rebind_fn(struct work_struct *work)
+{
+       struct worker *worker = container_of(work, struct worker, rebind_work);
+       struct global_cwq *gcwq = worker->gcwq;
+
+       if (worker_maybe_bind_and_lock(worker))
+               worker_clr_flags(worker, WORKER_REBIND);
+
+       spin_unlock_irq(&gcwq->lock);
+}
+
+static struct worker *alloc_worker(void)
+{
+       struct worker *worker;
+
+       worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+       if (worker) {
+               INIT_LIST_HEAD(&worker->entry);
+               INIT_LIST_HEAD(&worker->scheduled);
+               INIT_WORK(&worker->rebind_work, worker_rebind_fn);
+               /* on creation a worker is in !idle && prep state */
+               worker->flags = WORKER_PREP;
+       }
+       return worker;
+}
+
+/**
+ * create_worker - create a new workqueue worker
+ * @gcwq: gcwq the new worker will belong to
+ * @bind: whether to set affinity to @cpu or not
+ *
+ * Create a new worker which is bound to @gcwq.  The returned worker
+ * can be started by calling start_worker() or destroyed using
+ * destroy_worker().
+ *
+ * CONTEXT:
+ * Might sleep.  Does GFP_KERNEL allocations.
+ *
+ * RETURNS:
+ * Pointer to the newly created worker.
+ */
+static struct worker *create_worker(struct global_cwq *gcwq, bool bind)
+{
+       bool on_unbound_cpu = gcwq->cpu == WORK_CPU_UNBOUND;
+       struct worker *worker = NULL;
+       int id = -1;
+
+       spin_lock_irq(&gcwq->lock);
+       while (ida_get_new(&gcwq->worker_ida, &id)) {
+               spin_unlock_irq(&gcwq->lock);
+               if (!ida_pre_get(&gcwq->worker_ida, GFP_KERNEL))
+                       goto fail;
+               spin_lock_irq(&gcwq->lock);
+       }
+       spin_unlock_irq(&gcwq->lock);
+
+       worker = alloc_worker();
+       if (!worker)
+               goto fail;
+
+       worker->gcwq = gcwq;
+       worker->id = id;
+
+       if (!on_unbound_cpu)
+               worker->task = kthread_create(worker_thread, worker,
+                                             "kworker/%u:%d", gcwq->cpu, id);
+       else
+               worker->task = kthread_create(worker_thread, worker,
+                                             "kworker/u:%d", id);
+       if (IS_ERR(worker->task))
+               goto fail;
+
+       /*
+        * A rogue worker will become a regular one if CPU comes
+        * online later on.  Make sure every worker has
+        * PF_THREAD_BOUND set.
+        */
+       if (bind && !on_unbound_cpu)
+               kthread_bind(worker->task, gcwq->cpu);
+       else {
+               worker->task->flags |= PF_THREAD_BOUND;
+               if (on_unbound_cpu)
+                       worker->flags |= WORKER_UNBOUND;
+       }
+
+       return worker;
+fail:
+       if (id >= 0) {
+               spin_lock_irq(&gcwq->lock);
+               ida_remove(&gcwq->worker_ida, id);
+               spin_unlock_irq(&gcwq->lock);
+       }
+       kfree(worker);
+       return NULL;
+}
+
+/**
+ * start_worker - start a newly created worker
+ * @worker: worker to start
+ *
+ * Make the gcwq aware of @worker and start it.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ */
+static void start_worker(struct worker *worker)
+{
+       worker->flags |= WORKER_STARTED;
+       worker->gcwq->nr_workers++;
+       worker_enter_idle(worker);
+       wake_up_process(worker->task);
+}
+
+/**
+ * destroy_worker - destroy a workqueue worker
+ * @worker: worker to be destroyed
+ *
+ * Destroy @worker and adjust @gcwq stats accordingly.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock) which is released and regrabbed.
+ */
+static void destroy_worker(struct worker *worker)
+{
+       struct global_cwq *gcwq = worker->gcwq;
+       int id = worker->id;
+
+       /* sanity check frenzy */
+       BUG_ON(worker->current_work);
+       BUG_ON(!list_empty(&worker->scheduled));
+
+       if (worker->flags & WORKER_STARTED)
+               gcwq->nr_workers--;
+       if (worker->flags & WORKER_IDLE)
+               gcwq->nr_idle--;
+
+       list_del_init(&worker->entry);
+       worker->flags |= WORKER_DIE;
+
+       spin_unlock_irq(&gcwq->lock);
+
+       kthread_stop(worker->task);
+       kfree(worker);
+
+       spin_lock_irq(&gcwq->lock);
+       ida_remove(&gcwq->worker_ida, id);
+}
+
+static void idle_worker_timeout(unsigned long __gcwq)
+{
+       struct global_cwq *gcwq = (void *)__gcwq;
+
+       spin_lock_irq(&gcwq->lock);
+
+       if (too_many_workers(gcwq)) {
+               struct worker *worker;
+               unsigned long expires;
+
+               /* idle_list is kept in LIFO order, check the last one */
+               worker = list_entry(gcwq->idle_list.prev, struct worker, entry);
+               expires = worker->last_active + IDLE_WORKER_TIMEOUT;
+
+               if (time_before(jiffies, expires))
+                       mod_timer(&gcwq->idle_timer, expires);
+               else {
+                       /* it's been idle for too long, wake up manager */
+                       gcwq->flags |= GCWQ_MANAGE_WORKERS;
+                       wake_up_worker(gcwq);
                }
+       }
 
-               spin_lock_irq(&cwq->lock);
-               cwq->current_work = NULL;
+       spin_unlock_irq(&gcwq->lock);
+}
+
+static bool send_mayday(struct work_struct *work)
+{
+       struct cpu_workqueue_struct *cwq = get_work_cwq(work);
+       struct workqueue_struct *wq = cwq->wq;
+       unsigned int cpu;
+
+       if (!(wq->flags & WQ_RESCUER))
+               return false;
+
+       /* mayday mayday mayday */
+       cpu = cwq->gcwq->cpu;
+       /* WORK_CPU_UNBOUND can't be set in cpumask, use cpu 0 instead */
+       if (cpu == WORK_CPU_UNBOUND)
+               cpu = 0;
+       if (!mayday_test_and_set_cpu(cpu, wq->mayday_mask))
+               wake_up_process(wq->rescuer->task);
+       return true;
+}
+
+static void gcwq_mayday_timeout(unsigned long __gcwq)
+{
+       struct global_cwq *gcwq = (void *)__gcwq;
+       struct work_struct *work;
+
+       spin_lock_irq(&gcwq->lock);
+
+       if (need_to_create_worker(gcwq)) {
+               /*
+                * We've been trying to create a new worker but
+                * haven't been successful.  We might be hitting an
+                * allocation deadlock.  Send distress signals to
+                * rescuers.
+                */
+               list_for_each_entry(work, &gcwq->worklist, entry)
+                       send_mayday(work);
        }
-       spin_unlock_irq(&cwq->lock);
+
+       spin_unlock_irq(&gcwq->lock);
+
+       mod_timer(&gcwq->mayday_timer, jiffies + MAYDAY_INTERVAL);
 }
 
-static int worker_thread(void *__cwq)
+/**
+ * maybe_create_worker - create a new worker if necessary
+ * @gcwq: gcwq to create a new worker for
+ *
+ * Create a new worker for @gcwq if necessary.  @gcwq is guaranteed to
+ * have at least one idle worker on return from this function.  If
+ * creating a new worker takes longer than MAYDAY_INTERVAL, mayday is
+ * sent to all rescuers with works scheduled on @gcwq to resolve
+ * possible allocation deadlock.
+ *
+ * On return, need_to_create_worker() is guaranteed to be false and
+ * may_start_working() true.
+ *
+ * LOCKING:
+ * spin_lock_irq(gcwq->lock) which may be released and regrabbed
+ * multiple times.  Does GFP_KERNEL allocations.  Called only from
+ * manager.
+ *
+ * RETURNS:
+ * false if no action was taken and gcwq->lock stayed locked, true
+ * otherwise.
+ */
+static bool maybe_create_worker(struct global_cwq *gcwq)
 {
-       struct cpu_workqueue_struct *cwq = __cwq;
-       DEFINE_WAIT(wait);
+       if (!need_to_create_worker(gcwq))
+               return false;
+restart:
+       spin_unlock_irq(&gcwq->lock);
+
+       /* if we don't make progress in MAYDAY_INITIAL_TIMEOUT, call for help */
+       mod_timer(&gcwq->mayday_timer, jiffies + MAYDAY_INITIAL_TIMEOUT);
+
+       while (true) {
+               struct worker *worker;
+
+               worker = create_worker(gcwq, true);
+               if (worker) {
+                       del_timer_sync(&gcwq->mayday_timer);
+                       spin_lock_irq(&gcwq->lock);
+                       start_worker(worker);
+                       BUG_ON(need_to_create_worker(gcwq));
+                       return true;
+               }
 
-       if (cwq->wq->freezeable)
-               set_freezable();
+               if (!need_to_create_worker(gcwq))
+                       break;
 
-       for (;;) {
-               prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE);
-               if (!freezing(current) &&
-                   !kthread_should_stop() &&
-                   list_empty(&cwq->worklist))
-                       schedule();
-               finish_wait(&cwq->more_work, &wait);
+               __set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(CREATE_COOLDOWN);
 
-               try_to_freeze();
+               if (!need_to_create_worker(gcwq))
+                       break;
+       }
 
-               if (kthread_should_stop())
+       del_timer_sync(&gcwq->mayday_timer);
+       spin_lock_irq(&gcwq->lock);
+       if (need_to_create_worker(gcwq))
+               goto restart;
+       return true;
+}
+
+/**
+ * maybe_destroy_worker - destroy workers which have been idle for a while
+ * @gcwq: gcwq to destroy workers for
+ *
+ * Destroy @gcwq workers which have been idle for longer than
+ * IDLE_WORKER_TIMEOUT.
+ *
+ * LOCKING:
+ * spin_lock_irq(gcwq->lock) which may be released and regrabbed
+ * multiple times.  Called only from manager.
+ *
+ * RETURNS:
+ * false if no action was taken and gcwq->lock stayed locked, true
+ * otherwise.
+ */
+static bool maybe_destroy_workers(struct global_cwq *gcwq)
+{
+       bool ret = false;
+
+       while (too_many_workers(gcwq)) {
+               struct worker *worker;
+               unsigned long expires;
+
+               worker = list_entry(gcwq->idle_list.prev, struct worker, entry);
+               expires = worker->last_active + IDLE_WORKER_TIMEOUT;
+
+               if (time_before(jiffies, expires)) {
+                       mod_timer(&gcwq->idle_timer, expires);
                        break;
+               }
 
-               run_workqueue(cwq);
+               destroy_worker(worker);
+               ret = true;
        }
 
-       return 0;
+       return ret;
+}
+
+/**
+ * manage_workers - manage worker pool
+ * @worker: self
+ *
+ * Assume the manager role and manage gcwq worker pool @worker belongs
+ * to.  At any given time, there can be only zero or one manager per
+ * gcwq.  The exclusion is handled automatically by this function.
+ *
+ * The caller can safely start processing works on false return.  On
+ * true return, it's guaranteed that need_to_create_worker() is false
+ * and may_start_working() is true.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock) which may be released and regrabbed
+ * multiple times.  Does GFP_KERNEL allocations.
+ *
+ * RETURNS:
+ * false if no action was taken and gcwq->lock stayed locked, true if
+ * some action was taken.
+ */
+static bool manage_workers(struct worker *worker)
+{
+       struct global_cwq *gcwq = worker->gcwq;
+       bool ret = false;
+
+       if (gcwq->flags & GCWQ_MANAGING_WORKERS)
+               return ret;
+
+       gcwq->flags &= ~GCWQ_MANAGE_WORKERS;
+       gcwq->flags |= GCWQ_MANAGING_WORKERS;
+
+       /*
+        * Destroy and then create so that may_start_working() is true
+        * on return.
+        */
+       ret |= maybe_destroy_workers(gcwq);
+       ret |= maybe_create_worker(gcwq);
+
+       gcwq->flags &= ~GCWQ_MANAGING_WORKERS;
+
+       /*
+        * The trustee might be waiting to take over the manager
+        * position, tell it we're done.
+        */
+       if (unlikely(gcwq->trustee))
+               wake_up_all(&gcwq->trustee_wait);
+
+       return ret;
+}
+
+/**
+ * move_linked_works - move linked works to a list
+ * @work: start of series of works to be scheduled
+ * @head: target list to append @work to
+ * @nextp: out paramter for nested worklist walking
+ *
+ * Schedule linked works starting from @work to @head.  Work series to
+ * be scheduled starts at @work and includes any consecutive work with
+ * WORK_STRUCT_LINKED set in its predecessor.
+ *
+ * If @nextp is not NULL, it's updated to point to the next work of
+ * the last scheduled work.  This allows move_linked_works() to be
+ * nested inside outer list_for_each_entry_safe().
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ */
+static void move_linked_works(struct work_struct *work, struct list_head *head,
+                             struct work_struct **nextp)
+{
+       struct work_struct *n;
+
+       /*
+        * Linked worklist will always end before the end of the list,
+        * use NULL for list head.
+        */
+       list_for_each_entry_safe_from(work, n, NULL, entry) {
+               list_move_tail(&work->entry, head);
+               if (!(*work_data_bits(work) & WORK_STRUCT_LINKED))
+                       break;
+       }
+
+       /*
+        * If we're already inside safe list traversal and have moved
+        * multiple works to the scheduled queue, the next position
+        * needs to be updated.
+        */
+       if (nextp)
+               *nextp = n;
+}
+
+static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq)
+{
+       struct work_struct *work = list_first_entry(&cwq->delayed_works,
+                                                   struct work_struct, entry);
+       struct list_head *pos = gcwq_determine_ins_pos(cwq->gcwq, cwq);
+
+       move_linked_works(work, pos, NULL);
+       cwq->nr_active++;
+}
+
+/**
+ * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight
+ * @cwq: cwq of interest
+ * @color: color of work which left the queue
+ *
+ * A work either has completed or is removed from pending queue,
+ * decrement nr_in_flight of its cwq and handle workqueue flushing.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ */
+static void cwq_dec_nr_in_flight(struct cpu_workqueue_struct *cwq, int color)
+{
+       /* ignore uncolored works */
+       if (color == WORK_NO_COLOR)
+               return;
+
+       cwq->nr_in_flight[color]--;
+       cwq->nr_active--;
+
+       if (!list_empty(&cwq->delayed_works)) {
+               /* one down, submit a delayed one */
+               if (cwq->nr_active < cwq->max_active)
+                       cwq_activate_first_delayed(cwq);
+       }
+
+       /* is flush in progress and are we at the flushing tip? */
+       if (likely(cwq->flush_color != color))
+               return;
+
+       /* are there still in-flight works? */
+       if (cwq->nr_in_flight[color])
+               return;
+
+       /* this cwq is done, clear flush_color */
+       cwq->flush_color = -1;
+
+       /*
+        * If this was the last cwq, wake up the first flusher.  It
+        * will handle the rest.
+        */
+       if (atomic_dec_and_test(&cwq->wq->nr_cwqs_to_flush))
+               complete(&cwq->wq->first_flusher->done);
+}
+
+/**
+ * process_one_work - process single work
+ * @worker: self
+ * @work: work to process
+ *
+ * Process @work.  This function contains all the logics necessary to
+ * process a single work including synchronization against and
+ * interaction with other workers on the same cpu, queueing and
+ * flushing.  As long as context requirement is met, any worker can
+ * call this function to process a work.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock) which is released and regrabbed.
+ */
+static void process_one_work(struct worker *worker, struct work_struct *work)
+{
+       struct cpu_workqueue_struct *cwq = get_work_cwq(work);
+       struct global_cwq *gcwq = cwq->gcwq;
+       struct hlist_head *bwh = busy_worker_head(gcwq, work);
+       bool cpu_intensive = cwq->wq->flags & WQ_CPU_INTENSIVE;
+       work_func_t f = work->func;
+       int work_color;
+       struct worker *collision;
+#ifdef CONFIG_LOCKDEP
+       /*
+        * It is permissible to free the struct work_struct from
+        * inside the function that is called from it, this we need to
+        * take into account for lockdep too.  To avoid bogus "held
+        * lock freed" warnings as well as problems when looking into
+        * work->lockdep_map, make a copy and use that here.
+        */
+       struct lockdep_map lockdep_map = work->lockdep_map;
+#endif
+       /*
+        * A single work shouldn't be executed concurrently by
+        * multiple workers on a single cpu.  Check whether anyone is
+        * already processing the work.  If so, defer the work to the
+        * currently executing one.
+        */
+       collision = __find_worker_executing_work(gcwq, bwh, work);
+       if (unlikely(collision)) {
+               move_linked_works(work, &collision->scheduled, NULL);
+               return;
+       }
+
+       /* claim and process */
+       debug_work_deactivate(work);
+       hlist_add_head(&worker->hentry, bwh);
+       worker->current_work = work;
+       worker->current_cwq = cwq;
+       work_color = get_work_color(work);
+
+       /* record the current cpu number in the work data and dequeue */
+       set_work_cpu(work, gcwq->cpu);
+       list_del_init(&work->entry);
+
+       /*
+        * If HIGHPRI_PENDING, check the next work, and, if HIGHPRI,
+        * wake up another worker; otherwise, clear HIGHPRI_PENDING.
+        */
+       if (unlikely(gcwq->flags & GCWQ_HIGHPRI_PENDING)) {
+               struct work_struct *nwork = list_first_entry(&gcwq->worklist,
+                                               struct work_struct, entry);
+
+               if (!list_empty(&gcwq->worklist) &&
+                   get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI)
+                       wake_up_worker(gcwq);
+               else
+                       gcwq->flags &= ~GCWQ_HIGHPRI_PENDING;
+       }
+
+       /*
+        * CPU intensive works don't participate in concurrency
+        * management.  They're the scheduler's responsibility.
+        */
+       if (unlikely(cpu_intensive))
+               worker_set_flags(worker, WORKER_CPU_INTENSIVE, true);
+
+       spin_unlock_irq(&gcwq->lock);
+
+       work_clear_pending(work);
+       lock_map_acquire(&cwq->wq->lockdep_map);
+       lock_map_acquire(&lockdep_map);
+       f(work);
+       lock_map_release(&lockdep_map);
+       lock_map_release(&cwq->wq->lockdep_map);
+
+       if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
+               printk(KERN_ERR "BUG: workqueue leaked lock or atomic: "
+                      "%s/0x%08x/%d\n",
+                      current->comm, preempt_count(), task_pid_nr(current));
+               printk(KERN_ERR "    last function: ");
+               print_symbol("%s\n", (unsigned long)f);
+               debug_show_held_locks(current);
+               dump_stack();
+       }
+
+       spin_lock_irq(&gcwq->lock);
+
+       /* clear cpu intensive status */
+       if (unlikely(cpu_intensive))
+               worker_clr_flags(worker, WORKER_CPU_INTENSIVE);
+
+       /* we're done with it, release */
+       hlist_del_init(&worker->hentry);
+       worker->current_work = NULL;
+       worker->current_cwq = NULL;
+       cwq_dec_nr_in_flight(cwq, work_color);
+}
+
+/**
+ * process_scheduled_works - process scheduled works
+ * @worker: self
+ *
+ * Process all scheduled works.  Please note that the scheduled list
+ * may change while processing a work, so this function repeatedly
+ * fetches a work from the top and executes it.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock) which may be released and regrabbed
+ * multiple times.
+ */
+static void process_scheduled_works(struct worker *worker)
+{
+       while (!list_empty(&worker->scheduled)) {
+               struct work_struct *work = list_first_entry(&worker->scheduled,
+                                               struct work_struct, entry);
+               process_one_work(worker, work);
+       }
+}
+
+/**
+ * worker_thread - the worker thread function
+ * @__worker: self
+ *
+ * The gcwq worker thread function.  There's a single dynamic pool of
+ * these per each cpu.  These workers process all works regardless of
+ * their specific target workqueue.  The only exception is works which
+ * belong to workqueues with a rescuer which will be explained in
+ * rescuer_thread().
+ */
+static int worker_thread(void *__worker)
+{
+       struct worker *worker = __worker;
+       struct global_cwq *gcwq = worker->gcwq;
+
+       /* tell the scheduler that this is a workqueue worker */
+       worker->task->flags |= PF_WQ_WORKER;
+woke_up:
+       spin_lock_irq(&gcwq->lock);
+
+       /* DIE can be set only while we're idle, checking here is enough */
+       if (worker->flags & WORKER_DIE) {
+               spin_unlock_irq(&gcwq->lock);
+               worker->task->flags &= ~PF_WQ_WORKER;
+               return 0;
+       }
+
+       worker_leave_idle(worker);
+recheck:
+       /* no more worker necessary? */
+       if (!need_more_worker(gcwq))
+               goto sleep;
+
+       /* do we need to manage? */
+       if (unlikely(!may_start_working(gcwq)) && manage_workers(worker))
+               goto recheck;
+
+       /*
+        * ->scheduled list can only be filled while a worker is
+        * preparing to process a work or actually processing it.
+        * Make sure nobody diddled with it while I was sleeping.
+        */
+       BUG_ON(!list_empty(&worker->scheduled));
+
+       /*
+        * When control reaches this point, we're guaranteed to have
+        * at least one idle worker or that someone else has already
+        * assumed the manager role.
+        */
+       worker_clr_flags(worker, WORKER_PREP);
+
+       do {
+               struct work_struct *work =
+                       list_first_entry(&gcwq->worklist,
+                                        struct work_struct, entry);
+
+               if (likely(!(*work_data_bits(work) & WORK_STRUCT_LINKED))) {
+                       /* optimization path, not strictly necessary */
+                       process_one_work(worker, work);
+                       if (unlikely(!list_empty(&worker->scheduled)))
+                               process_scheduled_works(worker);
+               } else {
+                       move_linked_works(work, &worker->scheduled, NULL);
+                       process_scheduled_works(worker);
+               }
+       } while (keep_working(gcwq));
+
+       worker_set_flags(worker, WORKER_PREP, false);
+sleep:
+       if (unlikely(need_to_manage_workers(gcwq)) && manage_workers(worker))
+               goto recheck;
+
+       /*
+        * gcwq->lock is held and there's no work to process and no
+        * need to manage, sleep.  Workers are woken up only while
+        * holding gcwq->lock or from local cpu, so setting the
+        * current state before releasing gcwq->lock is enough to
+        * prevent losing any event.
+        */
+       worker_enter_idle(worker);
+       __set_current_state(TASK_INTERRUPTIBLE);
+       spin_unlock_irq(&gcwq->lock);
+       schedule();
+       goto woke_up;
+}
+
+/**
+ * rescuer_thread - the rescuer thread function
+ * @__wq: the associated workqueue
+ *
+ * Workqueue rescuer thread function.  There's one rescuer for each
+ * workqueue which has WQ_RESCUER set.
+ *
+ * Regular work processing on a gcwq may block trying to create a new
+ * worker which uses GFP_KERNEL allocation which has slight chance of
+ * developing into deadlock if some works currently on the same queue
+ * need to be processed to satisfy the GFP_KERNEL allocation.  This is
+ * the problem rescuer solves.
+ *
+ * When such condition is possible, the gcwq summons rescuers of all
+ * workqueues which have works queued on the gcwq and let them process
+ * those works so that forward progress can be guaranteed.
+ *
+ * This should happen rarely.
+ */
+static int rescuer_thread(void *__wq)
+{
+       struct workqueue_struct *wq = __wq;
+       struct worker *rescuer = wq->rescuer;
+       struct list_head *scheduled = &rescuer->scheduled;
+       bool is_unbound = wq->flags & WQ_UNBOUND;
+       unsigned int cpu;
+
+       set_user_nice(current, RESCUER_NICE_LEVEL);
+repeat:
+       set_current_state(TASK_INTERRUPTIBLE);
+
+       if (kthread_should_stop())
+               return 0;
+
+       /*
+        * See whether any cpu is asking for help.  Unbounded
+        * workqueues use cpu 0 in mayday_mask for CPU_UNBOUND.
+        */
+       for_each_mayday_cpu(cpu, wq->mayday_mask) {
+               unsigned int tcpu = is_unbound ? WORK_CPU_UNBOUND : cpu;
+               struct cpu_workqueue_struct *cwq = get_cwq(tcpu, wq);
+               struct global_cwq *gcwq = cwq->gcwq;
+               struct work_struct *work, *n;
+
+               __set_current_state(TASK_RUNNING);
+               mayday_clear_cpu(cpu, wq->mayday_mask);
+
+               /* migrate to the target cpu if possible */
+               rescuer->gcwq = gcwq;
+               worker_maybe_bind_and_lock(rescuer);
+
+               /*
+                * Slurp in all works issued via this workqueue and
+                * process'em.
+                */
+               BUG_ON(!list_empty(&rescuer->scheduled));
+               list_for_each_entry_safe(work, n, &gcwq->worklist, entry)
+                       if (get_work_cwq(work) == cwq)
+                               move_linked_works(work, scheduled, &n);
+
+               process_scheduled_works(rescuer);
+               spin_unlock_irq(&gcwq->lock);
+       }
+
+       schedule();
+       goto repeat;
 }
 
 struct wq_barrier {
@@ -469,44 +2003,137 @@ static void wq_barrier_func(struct work_struct *work)
        complete(&barr->done);
 }
 
+/**
+ * insert_wq_barrier - insert a barrier work
+ * @cwq: cwq to insert barrier into
+ * @barr: wq_barrier to insert
+ * @target: target work to attach @barr to
+ * @worker: worker currently executing @target, NULL if @target is not executing
+ *
+ * @barr is linked to @target such that @barr is completed only after
+ * @target finishes execution.  Please note that the ordering
+ * guarantee is observed only with respect to @target and on the local
+ * cpu.
+ *
+ * Currently, a queued barrier can't be canceled.  This is because
+ * try_to_grab_pending() can't determine whether the work to be
+ * grabbed is at the head of the queue and thus can't clear LINKED
+ * flag of the previous work while there must be a valid next work
+ * after a work with LINKED flag set.
+ *
+ * Note that when @worker is non-NULL, @target may be modified
+ * underneath us, so we can't reliably determine cwq from @target.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock).
+ */
 static void insert_wq_barrier(struct cpu_workqueue_struct *cwq,
-                       struct wq_barrier *barr, struct list_head *head)
+                             struct wq_barrier *barr,
+                             struct work_struct *target, struct worker *worker)
 {
+       struct list_head *head;
+       unsigned int linked = 0;
+
        /*
-        * debugobject calls are safe here even with cwq->lock locked
+        * debugobject calls are safe here even with gcwq->lock locked
         * as we know for sure that this will not trigger any of the
         * checks and call back into the fixup functions where we
         * might deadlock.
         */
        INIT_WORK_ON_STACK(&barr->work, wq_barrier_func);
-       __set_bit(WORK_STRUCT_PENDING, work_data_bits(&barr->work));
+       __set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work));
+       init_completion(&barr->done);
+
+       /*
+        * If @target is currently being executed, schedule the
+        * barrier to the worker; otherwise, put it after @target.
+        */
+       if (worker)
+               head = worker->scheduled.next;
+       else {
+               unsigned long *bits = work_data_bits(target);
+
+               head = target->entry.next;
+               /* there can already be other linked works, inherit and set */
+               linked = *bits & WORK_STRUCT_LINKED;
+               __set_bit(WORK_STRUCT_LINKED_BIT, bits);
+       }
+
+       debug_work_activate(&barr->work);
+       insert_work(cwq, &barr->work, head,
+                   work_color_to_flags(WORK_NO_COLOR) | linked);
+}
+
+/**
+ * flush_workqueue_prep_cwqs - prepare cwqs for workqueue flushing
+ * @wq: workqueue being flushed
+ * @flush_color: new flush color, < 0 for no-op
+ * @work_color: new work color, < 0 for no-op
+ *
+ * Prepare cwqs for workqueue flushing.
+ *
+ * If @flush_color is non-negative, flush_color on all cwqs should be
+ * -1.  If no cwq has in-flight commands at the specified color, all
+ * cwq->flush_color's stay at -1 and %false is returned.  If any cwq
+ * has in flight commands, its cwq->flush_color is set to
+ * @flush_color, @wq->nr_cwqs_to_flush is updated accordingly, cwq
+ * wakeup logic is armed and %true is returned.
+ *
+ * The caller should have initialized @wq->first_flusher prior to
+ * calling this function with non-negative @flush_color.  If
+ * @flush_color is negative, no flush color update is done and %false
+ * is returned.
+ *
+ * If @work_color is non-negative, all cwqs should have the same
+ * work_color which is previous to @work_color and all will be
+ * advanced to @work_color.
+ *
+ * CONTEXT:
+ * mutex_lock(wq->flush_mutex).
+ *
+ * RETURNS:
+ * %true if @flush_color >= 0 and there's something to flush.  %false
+ * otherwise.
+ */
+static bool flush_workqueue_prep_cwqs(struct workqueue_struct *wq,
+                                     int flush_color, int work_color)
+{
+       bool wait = false;
+       unsigned int cpu;
+
+       if (flush_color >= 0) {
+               BUG_ON(atomic_read(&wq->nr_cwqs_to_flush));
+               atomic_set(&wq->nr_cwqs_to_flush, 1);
+       }
+
+       for_each_cwq_cpu(cpu, wq) {
+               struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+               struct global_cwq *gcwq = cwq->gcwq;
 
-       init_completion(&barr->done);
+               spin_lock_irq(&gcwq->lock);
 
-       debug_work_activate(&barr->work);
-       insert_work(cwq, &barr->work, head);
-}
+               if (flush_color >= 0) {
+                       BUG_ON(cwq->flush_color != -1);
 
-static int flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
-{
-       int active = 0;
-       struct wq_barrier barr;
+                       if (cwq->nr_in_flight[flush_color]) {
+                               cwq->flush_color = flush_color;
+                               atomic_inc(&wq->nr_cwqs_to_flush);
+                               wait = true;
+                       }
+               }
 
-       WARN_ON(cwq->thread == current);
+               if (work_color >= 0) {
+                       BUG_ON(work_color != work_next_color(cwq->work_color));
+                       cwq->work_color = work_color;
+               }
 
-       spin_lock_irq(&cwq->lock);
-       if (!list_empty(&cwq->worklist) || cwq->current_work != NULL) {
-               insert_wq_barrier(cwq, &barr, &cwq->worklist);
-               active = 1;
+               spin_unlock_irq(&gcwq->lock);
        }
-       spin_unlock_irq(&cwq->lock);
 
-       if (active) {
-               wait_for_completion(&barr.done);
-               destroy_work_on_stack(&barr.work);
-       }
+       if (flush_color >= 0 && atomic_dec_and_test(&wq->nr_cwqs_to_flush))
+               complete(&wq->first_flusher->done);
 
-       return active;
+       return wait;
 }
 
 /**
@@ -518,20 +2145,150 @@ static int flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
  *
  * We sleep until all works which were queued on entry have been handled,
  * but we are not livelocked by new incoming ones.
- *
- * This function used to run the workqueues itself.  Now we just wait for the
- * helper threads to do it.
  */
 void flush_workqueue(struct workqueue_struct *wq)
 {
-       const struct cpumask *cpu_map = wq_cpu_map(wq);
-       int cpu;
+       struct wq_flusher this_flusher = {
+               .list = LIST_HEAD_INIT(this_flusher.list),
+               .flush_color = -1,
+               .done = COMPLETION_INITIALIZER_ONSTACK(this_flusher.done),
+       };
+       int next_color;
 
-       might_sleep();
        lock_map_acquire(&wq->lockdep_map);
        lock_map_release(&wq->lockdep_map);
-       for_each_cpu(cpu, cpu_map)
-               flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
+
+       mutex_lock(&wq->flush_mutex);
+
+       /*
+        * Start-to-wait phase
+        */
+       next_color = work_next_color(wq->work_color);
+
+       if (next_color != wq->flush_color) {
+               /*
+                * Color space is not full.  The current work_color
+                * becomes our flush_color and work_color is advanced
+                * by one.
+                */
+               BUG_ON(!list_empty(&wq->flusher_overflow));
+               this_flusher.flush_color = wq->work_color;
+               wq->work_color = next_color;
+
+               if (!wq->first_flusher) {
+                       /* no flush in progress, become the first flusher */
+                       BUG_ON(wq->flush_color != this_flusher.flush_color);
+
+                       wq->first_flusher = &this_flusher;
+
+                       if (!flush_workqueue_prep_cwqs(wq, wq->flush_color,
+                                                      wq->work_color)) {
+                               /* nothing to flush, done */
+                               wq->flush_color = next_color;
+                               wq->first_flusher = NULL;
+                               goto out_unlock;
+                       }
+               } else {
+                       /* wait in queue */
+                       BUG_ON(wq->flush_color == this_flusher.flush_color);
+                       list_add_tail(&this_flusher.list, &wq->flusher_queue);
+                       flush_workqueue_prep_cwqs(wq, -1, wq->work_color);
+               }
+       } else {
+               /*
+                * Oops, color space is full, wait on overflow queue.
+                * The next flush completion will assign us
+                * flush_color and transfer to flusher_queue.
+                */
+               list_add_tail(&this_flusher.list, &wq->flusher_overflow);
+       }
+
+       mutex_unlock(&wq->flush_mutex);
+
+       wait_for_completion(&this_flusher.done);
+
+       /*
+        * Wake-up-and-cascade phase
+        *
+        * First flushers are responsible for cascading flushes and
+        * handling overflow.  Non-first flushers can simply return.
+        */
+       if (wq->first_flusher != &this_flusher)
+               return;
+
+       mutex_lock(&wq->flush_mutex);
+
+       /* we might have raced, check again with mutex held */
+       if (wq->first_flusher != &this_flusher)
+               goto out_unlock;
+
+       wq->first_flusher = NULL;
+
+       BUG_ON(!list_empty(&this_flusher.list));
+       BUG_ON(wq->flush_color != this_flusher.flush_color);
+
+       while (true) {
+               struct wq_flusher *next, *tmp;
+
+               /* complete all the flushers sharing the current flush color */
+               list_for_each_entry_safe(next, tmp, &wq->flusher_queue, list) {
+                       if (next->flush_color != wq->flush_color)
+                               break;
+                       list_del_init(&next->list);
+                       complete(&next->done);
+               }
+
+               BUG_ON(!list_empty(&wq->flusher_overflow) &&
+                      wq->flush_color != work_next_color(wq->work_color));
+
+               /* this flush_color is finished, advance by one */
+               wq->flush_color = work_next_color(wq->flush_color);
+
+               /* one color has been freed, handle overflow queue */
+               if (!list_empty(&wq->flusher_overflow)) {
+                       /*
+                        * Assign the same color to all overflowed
+                        * flushers, advance work_color and append to
+                        * flusher_queue.  This is the start-to-wait
+                        * phase for these overflowed flushers.
+                        */
+                       list_for_each_entry(tmp, &wq->flusher_overflow, list)
+                               tmp->flush_color = wq->work_color;
+
+                       wq->work_color = work_next_color(wq->work_color);
+
+                       list_splice_tail_init(&wq->flusher_overflow,
+                                             &wq->flusher_queue);
+                       flush_workqueue_prep_cwqs(wq, -1, wq->work_color);
+               }
+
+               if (list_empty(&wq->flusher_queue)) {
+                       BUG_ON(wq->flush_color != wq->work_color);
+                       break;
+               }
+
+               /*
+                * Need to flush more colors.  Make the next flusher
+                * the new first flusher and arm cwqs.
+                */
+               BUG_ON(wq->flush_color == wq->work_color);
+               BUG_ON(wq->flush_color != next->flush_color);
+
+               list_del_init(&next->list);
+               wq->first_flusher = next;
+
+               if (flush_workqueue_prep_cwqs(wq, wq->flush_color, -1))
+                       break;
+
+               /*
+                * Meh... this color is already done, clear first
+                * flusher and repeat cascading.
+                */
+               wq->first_flusher = NULL;
+       }
+
+out_unlock:
+       mutex_unlock(&wq->flush_mutex);
 }
 EXPORT_SYMBOL_GPL(flush_workqueue);
 
@@ -547,43 +2304,46 @@ EXPORT_SYMBOL_GPL(flush_workqueue);
  */
 int flush_work(struct work_struct *work)
 {
+       struct worker *worker = NULL;
+       struct global_cwq *gcwq;
        struct cpu_workqueue_struct *cwq;
-       struct list_head *prev;
        struct wq_barrier barr;
 
        might_sleep();
-       cwq = get_wq_data(work);
-       if (!cwq)
+       gcwq = get_work_gcwq(work);
+       if (!gcwq)
                return 0;
 
-       lock_map_acquire(&cwq->wq->lockdep_map);
-       lock_map_release(&cwq->wq->lockdep_map);
-
-       prev = NULL;
-       spin_lock_irq(&cwq->lock);
+       spin_lock_irq(&gcwq->lock);
        if (!list_empty(&work->entry)) {
                /*
                 * See the comment near try_to_grab_pending()->smp_rmb().
-                * If it was re-queued under us we are not going to wait.
+                * If it was re-queued to a different gcwq under us, we
+                * are not going to wait.
                 */
                smp_rmb();
-               if (unlikely(cwq != get_wq_data(work)))
-                       goto out;
-               prev = &work->entry;
+               cwq = get_work_cwq(work);
+               if (unlikely(!cwq || gcwq != cwq->gcwq))
+                       goto already_gone;
        } else {
-               if (cwq->current_work != work)
-                       goto out;
-               prev = &cwq->worklist;
+               worker = find_worker_executing_work(gcwq, work);
+               if (!worker)
+                       goto already_gone;
+               cwq = worker->current_cwq;
        }
-       insert_wq_barrier(cwq, &barr, prev->next);
-out:
-       spin_unlock_irq(&cwq->lock);
-       if (!prev)
-               return 0;
+
+       insert_wq_barrier(cwq, &barr, work, worker);
+       spin_unlock_irq(&gcwq->lock);
+
+       lock_map_acquire(&cwq->wq->lockdep_map);
+       lock_map_release(&cwq->wq->lockdep_map);
 
        wait_for_completion(&barr.done);
        destroy_work_on_stack(&barr.work);
        return 1;
+already_gone:
+       spin_unlock_irq(&gcwq->lock);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(flush_work);
 
@@ -593,54 +2353,55 @@ EXPORT_SYMBOL_GPL(flush_work);
  */
 static int try_to_grab_pending(struct work_struct *work)
 {
-       struct cpu_workqueue_struct *cwq;
+       struct global_cwq *gcwq;
        int ret = -1;
 
-       if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work)))
+       if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)))
                return 0;
 
        /*
         * The queueing is in progress, or it is already queued. Try to
         * steal it from ->worklist without clearing WORK_STRUCT_PENDING.
         */
-
-       cwq = get_wq_data(work);
-       if (!cwq)
+       gcwq = get_work_gcwq(work);
+       if (!gcwq)
                return ret;
 
-       spin_lock_irq(&cwq->lock);
+       spin_lock_irq(&gcwq->lock);
        if (!list_empty(&work->entry)) {
                /*
-                * This work is queued, but perhaps we locked the wrong cwq.
+                * This work is queued, but perhaps we locked the wrong gcwq.
                 * In that case we must see the new value after rmb(), see
                 * insert_work()->wmb().
                 */
                smp_rmb();
-               if (cwq == get_wq_data(work)) {
+               if (gcwq == get_work_gcwq(work)) {
                        debug_work_deactivate(work);
                        list_del_init(&work->entry);
+                       cwq_dec_nr_in_flight(get_work_cwq(work),
+                                            get_work_color(work));
                        ret = 1;
                }
        }
-       spin_unlock_irq(&cwq->lock);
+       spin_unlock_irq(&gcwq->lock);
 
        return ret;
 }
 
-static void wait_on_cpu_work(struct cpu_workqueue_struct *cwq,
-                               struct work_struct *work)
+static void wait_on_cpu_work(struct global_cwq *gcwq, struct work_struct *work)
 {
        struct wq_barrier barr;
-       int running = 0;
+       struct worker *worker;
 
-       spin_lock_irq(&cwq->lock);
-       if (unlikely(cwq->current_work == work)) {
-               insert_wq_barrier(cwq, &barr, cwq->worklist.next);
-               running = 1;
-       }
-       spin_unlock_irq(&cwq->lock);
+       spin_lock_irq(&gcwq->lock);
 
-       if (unlikely(running)) {
+       worker = find_worker_executing_work(gcwq, work);
+       if (unlikely(worker))
+               insert_wq_barrier(worker->current_cwq, &barr, work, worker);
+
+       spin_unlock_irq(&gcwq->lock);
+
+       if (unlikely(worker)) {
                wait_for_completion(&barr.done);
                destroy_work_on_stack(&barr.work);
        }
@@ -648,9 +2409,6 @@ static void wait_on_cpu_work(struct cpu_workqueue_struct *cwq,
 
 static void wait_on_work(struct work_struct *work)
 {
-       struct cpu_workqueue_struct *cwq;
-       struct workqueue_struct *wq;
-       const struct cpumask *cpu_map;
        int cpu;
 
        might_sleep();
@@ -658,15 +2416,8 @@ static void wait_on_work(struct work_struct *work)
        lock_map_acquire(&work->lockdep_map);
        lock_map_release(&work->lockdep_map);
 
-       cwq = get_wq_data(work);
-       if (!cwq)
-               return;
-
-       wq = cwq->wq;
-       cpu_map = wq_cpu_map(wq);
-
-       for_each_cpu(cpu, cpu_map)
-               wait_on_cpu_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
+       for_each_gcwq_cpu(cpu)
+               wait_on_cpu_work(get_gcwq(cpu), work);
 }
 
 static int __cancel_work_timer(struct work_struct *work,
@@ -681,7 +2432,7 @@ static int __cancel_work_timer(struct work_struct *work,
                wait_on_work(work);
        } while (unlikely(ret < 0));
 
-       clear_wq_data(work);
+       clear_work_data(work);
        return ret;
 }
 
@@ -727,8 +2478,6 @@ int cancel_delayed_work_sync(struct delayed_work *dwork)
 }
 EXPORT_SYMBOL(cancel_delayed_work_sync);
 
-static struct workqueue_struct *keventd_wq __read_mostly;
-
 /**
  * schedule_work - put work task in global workqueue
  * @work: job to be done
@@ -742,7 +2491,7 @@ static struct workqueue_struct *keventd_wq __read_mostly;
  */
 int schedule_work(struct work_struct *work)
 {
-       return queue_work(keventd_wq, work);
+       return queue_work(system_wq, work);
 }
 EXPORT_SYMBOL(schedule_work);
 
@@ -755,7 +2504,7 @@ EXPORT_SYMBOL(schedule_work);
  */
 int schedule_work_on(int cpu, struct work_struct *work)
 {
-       return queue_work_on(cpu, keventd_wq, work);
+       return queue_work_on(cpu, system_wq, work);
 }
 EXPORT_SYMBOL(schedule_work_on);
 
@@ -770,7 +2519,7 @@ EXPORT_SYMBOL(schedule_work_on);
 int schedule_delayed_work(struct delayed_work *dwork,
                                        unsigned long delay)
 {
-       return queue_delayed_work(keventd_wq, dwork, delay);
+       return queue_delayed_work(system_wq, dwork, delay);
 }
 EXPORT_SYMBOL(schedule_delayed_work);
 
@@ -783,9 +2532,8 @@ EXPORT_SYMBOL(schedule_delayed_work);
 void flush_delayed_work(struct delayed_work *dwork)
 {
        if (del_timer_sync(&dwork->timer)) {
-               struct cpu_workqueue_struct *cwq;
-               cwq = wq_per_cpu(get_wq_data(&dwork->work)->wq, get_cpu());
-               __queue_work(cwq, &dwork->work);
+               __queue_work(get_cpu(), get_work_cwq(&dwork->work)->wq,
+                            &dwork->work);
                put_cpu();
        }
        flush_work(&dwork->work);
@@ -804,7 +2552,7 @@ EXPORT_SYMBOL(flush_delayed_work);
 int schedule_delayed_work_on(int cpu,
                        struct delayed_work *dwork, unsigned long delay)
 {
-       return queue_delayed_work_on(cpu, keventd_wq, dwork, delay);
+       return queue_delayed_work_on(cpu, system_wq, dwork, delay);
 }
 EXPORT_SYMBOL(schedule_delayed_work_on);
 
@@ -820,7 +2568,6 @@ EXPORT_SYMBOL(schedule_delayed_work_on);
 int schedule_on_each_cpu(work_func_t func)
 {
        int cpu;
-       int orig = -1;
        struct work_struct *works;
 
        works = alloc_percpu(struct work_struct);
@@ -829,329 +2576,762 @@ int schedule_on_each_cpu(work_func_t func)
 
        get_online_cpus();
 
+       for_each_online_cpu(cpu) {
+               struct work_struct *work = per_cpu_ptr(works, cpu);
+
+               INIT_WORK(work, func);
+               schedule_work_on(cpu, work);
+       }
+
+       for_each_online_cpu(cpu)
+               flush_work(per_cpu_ptr(works, cpu));
+
+       put_online_cpus();
+       free_percpu(works);
+       return 0;
+}
+
+/**
+ * flush_scheduled_work - ensure that any scheduled work has run to completion.
+ *
+ * Forces execution of the kernel-global workqueue and blocks until its
+ * completion.
+ *
+ * Think twice before calling this function!  It's very easy to get into
+ * trouble if you don't take great care.  Either of the following situations
+ * will lead to deadlock:
+ *
+ *     One of the work items currently on the workqueue needs to acquire
+ *     a lock held by your code or its caller.
+ *
+ *     Your code is running in the context of a work routine.
+ *
+ * They will be detected by lockdep when they occur, but the first might not
+ * occur very often.  It depends on what work items are on the workqueue and
+ * what locks they need, which you have no control over.
+ *
+ * In most situations flushing the entire workqueue is overkill; you merely
+ * need to know that a particular work item isn't queued and isn't running.
+ * In such cases you should use cancel_delayed_work_sync() or
+ * cancel_work_sync() instead.
+ */
+void flush_scheduled_work(void)
+{
+       flush_workqueue(system_wq);
+}
+EXPORT_SYMBOL(flush_scheduled_work);
+
+/**
+ * execute_in_process_context - reliably execute the routine with user context
+ * @fn:                the function to execute
+ * @ew:                guaranteed storage for the execute work structure (must
+ *             be available when the work executes)
+ *
+ * Executes the function immediately if process context is available,
+ * otherwise schedules the function for delayed execution.
+ *
+ * Returns:    0 - function was executed
+ *             1 - function was scheduled for execution
+ */
+int execute_in_process_context(work_func_t fn, struct execute_work *ew)
+{
+       if (!in_interrupt()) {
+               fn(&ew->work);
+               return 0;
+       }
+
+       INIT_WORK(&ew->work, fn);
+       schedule_work(&ew->work);
+
+       return 1;
+}
+EXPORT_SYMBOL_GPL(execute_in_process_context);
+
+int keventd_up(void)
+{
+       return system_wq != NULL;
+}
+
+static int alloc_cwqs(struct workqueue_struct *wq)
+{
        /*
-        * When running in keventd don't schedule a work item on
-        * itself.  Can just call directly because the work queue is
-        * already bound.  This also is faster.
+        * cwqs are forced aligned according to WORK_STRUCT_FLAG_BITS.
+        * Make sure that the alignment isn't lower than that of
+        * unsigned long long.
         */
-       if (current_is_keventd())
-               orig = raw_smp_processor_id();
+       const size_t size = sizeof(struct cpu_workqueue_struct);
+       const size_t align = max_t(size_t, 1 << WORK_STRUCT_FLAG_BITS,
+                                  __alignof__(unsigned long long));
+#ifdef CONFIG_SMP
+       bool percpu = !(wq->flags & WQ_UNBOUND);
+#else
+       bool percpu = false;
+#endif
 
-       for_each_online_cpu(cpu) {
-               struct work_struct *work = per_cpu_ptr(works, cpu);
+       if (percpu)
+               wq->cpu_wq.pcpu = __alloc_percpu(size, align);
+       else {
+               void *ptr;
+
+               /*
+                * Allocate enough room to align cwq and put an extra
+                * pointer at the end pointing back to the originally
+                * allocated pointer which will be used for free.
+                */
+               ptr = kzalloc(size + align + sizeof(void *), GFP_KERNEL);
+               if (ptr) {
+                       wq->cpu_wq.single = PTR_ALIGN(ptr, align);
+                       *(void **)(wq->cpu_wq.single + 1) = ptr;
+               }
+       }
+
+       /* just in case, make sure it's actually aligned */
+       BUG_ON(!IS_ALIGNED(wq->cpu_wq.v, align));
+       return wq->cpu_wq.v ? 0 : -ENOMEM;
+}
+
+static void free_cwqs(struct workqueue_struct *wq)
+{
+#ifdef CONFIG_SMP
+       bool percpu = !(wq->flags & WQ_UNBOUND);
+#else
+       bool percpu = false;
+#endif
+
+       if (percpu)
+               free_percpu(wq->cpu_wq.pcpu);
+       else if (wq->cpu_wq.single) {
+               /* the pointer to free is stored right after the cwq */
+               kfree(*(void **)(wq->cpu_wq.single + 1));
+       }
+}
+
+static int wq_clamp_max_active(int max_active, unsigned int flags,
+                              const char *name)
+{
+       int lim = flags & WQ_UNBOUND ? WQ_UNBOUND_MAX_ACTIVE : WQ_MAX_ACTIVE;
+
+       if (max_active < 1 || max_active > lim)
+               printk(KERN_WARNING "workqueue: max_active %d requested for %s "
+                      "is out of range, clamping between %d and %d\n",
+                      max_active, name, 1, lim);
+
+       return clamp_val(max_active, 1, lim);
+}
+
+struct workqueue_struct *__alloc_workqueue_key(const char *name,
+                                              unsigned int flags,
+                                              int max_active,
+                                              struct lock_class_key *key,
+                                              const char *lock_name)
+{
+       struct workqueue_struct *wq;
+       unsigned int cpu;
+
+       /*
+        * Unbound workqueues aren't concurrency managed and should be
+        * dispatched to workers immediately.
+        */
+       if (flags & WQ_UNBOUND)
+               flags |= WQ_HIGHPRI;
+
+       max_active = max_active ?: WQ_DFL_ACTIVE;
+       max_active = wq_clamp_max_active(max_active, flags, name);
+
+       wq = kzalloc(sizeof(*wq), GFP_KERNEL);
+       if (!wq)
+               goto err;
+
+       wq->flags = flags;
+       wq->saved_max_active = max_active;
+       mutex_init(&wq->flush_mutex);
+       atomic_set(&wq->nr_cwqs_to_flush, 0);
+       INIT_LIST_HEAD(&wq->flusher_queue);
+       INIT_LIST_HEAD(&wq->flusher_overflow);
+
+       wq->name = name;
+       lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
+       INIT_LIST_HEAD(&wq->list);
+
+       if (alloc_cwqs(wq) < 0)
+               goto err;
+
+       for_each_cwq_cpu(cpu, wq) {
+               struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+               struct global_cwq *gcwq = get_gcwq(cpu);
+
+               BUG_ON((unsigned long)cwq & WORK_STRUCT_FLAG_MASK);
+               cwq->gcwq = gcwq;
+               cwq->wq = wq;
+               cwq->flush_color = -1;
+               cwq->max_active = max_active;
+               INIT_LIST_HEAD(&cwq->delayed_works);
+       }
+
+       if (flags & WQ_RESCUER) {
+               struct worker *rescuer;
+
+               if (!alloc_mayday_mask(&wq->mayday_mask, GFP_KERNEL))
+                       goto err;
+
+               wq->rescuer = rescuer = alloc_worker();
+               if (!rescuer)
+                       goto err;
+
+               rescuer->task = kthread_create(rescuer_thread, wq, "%s", name);
+               if (IS_ERR(rescuer->task))
+                       goto err;
+
+               wq->rescuer = rescuer;
+               rescuer->task->flags |= PF_THREAD_BOUND;
+               wake_up_process(rescuer->task);
+       }
+
+       /*
+        * workqueue_lock protects global freeze state and workqueues
+        * list.  Grab it, set max_active accordingly and add the new
+        * workqueue to workqueues list.
+        */
+       spin_lock(&workqueue_lock);
+
+       if (workqueue_freezing && wq->flags & WQ_FREEZEABLE)
+               for_each_cwq_cpu(cpu, wq)
+                       get_cwq(cpu, wq)->max_active = 0;
+
+       list_add(&wq->list, &workqueues);
+
+       spin_unlock(&workqueue_lock);
+
+       return wq;
+err:
+       if (wq) {
+               free_cwqs(wq);
+               free_mayday_mask(wq->mayday_mask);
+               kfree(wq->rescuer);
+               kfree(wq);
+       }
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(__alloc_workqueue_key);
+
+/**
+ * destroy_workqueue - safely terminate a workqueue
+ * @wq: target workqueue
+ *
+ * Safely destroy a workqueue. All work currently pending will be done first.
+ */
+void destroy_workqueue(struct workqueue_struct *wq)
+{
+       unsigned int cpu;
+
+       flush_workqueue(wq);
+
+       /*
+        * wq list is used to freeze wq, remove from list after
+        * flushing is complete in case freeze races us.
+        */
+       spin_lock(&workqueue_lock);
+       list_del(&wq->list);
+       spin_unlock(&workqueue_lock);
+
+       /* sanity check */
+       for_each_cwq_cpu(cpu, wq) {
+               struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+               int i;
+
+               for (i = 0; i < WORK_NR_COLORS; i++)
+                       BUG_ON(cwq->nr_in_flight[i]);
+               BUG_ON(cwq->nr_active);
+               BUG_ON(!list_empty(&cwq->delayed_works));
+       }
+
+       if (wq->flags & WQ_RESCUER) {
+               kthread_stop(wq->rescuer->task);
+               free_mayday_mask(wq->mayday_mask);
+       }
+
+       free_cwqs(wq);
+       kfree(wq);
+}
+EXPORT_SYMBOL_GPL(destroy_workqueue);
+
+/**
+ * workqueue_set_max_active - adjust max_active of a workqueue
+ * @wq: target workqueue
+ * @max_active: new max_active value.
+ *
+ * Set max_active of @wq to @max_active.
+ *
+ * CONTEXT:
+ * Don't call from IRQ context.
+ */
+void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
+{
+       unsigned int cpu;
+
+       max_active = wq_clamp_max_active(max_active, wq->flags, wq->name);
+
+       spin_lock(&workqueue_lock);
+
+       wq->saved_max_active = max_active;
+
+       for_each_cwq_cpu(cpu, wq) {
+               struct global_cwq *gcwq = get_gcwq(cpu);
+
+               spin_lock_irq(&gcwq->lock);
+
+               if (!(wq->flags & WQ_FREEZEABLE) ||
+                   !(gcwq->flags & GCWQ_FREEZING))
+                       get_cwq(gcwq->cpu, wq)->max_active = max_active;
 
-               INIT_WORK(work, func);
-               if (cpu != orig)
-                       schedule_work_on(cpu, work);
+               spin_unlock_irq(&gcwq->lock);
        }
-       if (orig >= 0)
-               func(per_cpu_ptr(works, orig));
-
-       for_each_online_cpu(cpu)
-               flush_work(per_cpu_ptr(works, cpu));
 
-       put_online_cpus();
-       free_percpu(works);
-       return 0;
+       spin_unlock(&workqueue_lock);
 }
+EXPORT_SYMBOL_GPL(workqueue_set_max_active);
 
 /**
- * flush_scheduled_work - ensure that any scheduled work has run to completion.
- *
- * Forces execution of the kernel-global workqueue and blocks until its
- * completion.
- *
- * Think twice before calling this function!  It's very easy to get into
- * trouble if you don't take great care.  Either of the following situations
- * will lead to deadlock:
- *
- *     One of the work items currently on the workqueue needs to acquire
- *     a lock held by your code or its caller.
- *
- *     Your code is running in the context of a work routine.
+ * workqueue_congested - test whether a workqueue is congested
+ * @cpu: CPU in question
+ * @wq: target workqueue
  *
- * They will be detected by lockdep when they occur, but the first might not
- * occur very often.  It depends on what work items are on the workqueue and
- * what locks they need, which you have no control over.
+ * Test whether @wq's cpu workqueue for @cpu is congested.  There is
+ * no synchronization around this function and the test result is
+ * unreliable and only useful as advisory hints or for debugging.
  *
- * In most situations flushing the entire workqueue is overkill; you merely
- * need to know that a particular work item isn't queued and isn't running.
- * In such cases you should use cancel_delayed_work_sync() or
- * cancel_work_sync() instead.
+ * RETURNS:
+ * %true if congested, %false otherwise.
  */
-void flush_scheduled_work(void)
+bool workqueue_congested(unsigned int cpu, struct workqueue_struct *wq)
 {
-       flush_workqueue(keventd_wq);
+       struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+
+       return !list_empty(&cwq->delayed_works);
 }
-EXPORT_SYMBOL(flush_scheduled_work);
+EXPORT_SYMBOL_GPL(workqueue_congested);
 
 /**
- * execute_in_process_context - reliably execute the routine with user context
- * @fn:                the function to execute
- * @ew:                guaranteed storage for the execute work structure (must
- *             be available when the work executes)
+ * work_cpu - return the last known associated cpu for @work
+ * @work: the work of interest
  *
- * Executes the function immediately if process context is available,
- * otherwise schedules the function for delayed execution.
- *
- * Returns:    0 - function was executed
- *             1 - function was scheduled for execution
+ * RETURNS:
+ * CPU number if @work was ever queued.  WORK_CPU_NONE otherwise.
  */
-int execute_in_process_context(work_func_t fn, struct execute_work *ew)
+unsigned int work_cpu(struct work_struct *work)
 {
-       if (!in_interrupt()) {
-               fn(&ew->work);
-               return 0;
-       }
-
-       INIT_WORK(&ew->work, fn);
-       schedule_work(&ew->work);
+       struct global_cwq *gcwq = get_work_gcwq(work);
 
-       return 1;
+       return gcwq ? gcwq->cpu : WORK_CPU_NONE;
 }
-EXPORT_SYMBOL_GPL(execute_in_process_context);
+EXPORT_SYMBOL_GPL(work_cpu);
 
-int keventd_up(void)
+/**
+ * work_busy - test whether a work is currently pending or running
+ * @work: the work to be tested
+ *
+ * Test whether @work is currently pending or running.  There is no
+ * synchronization around this function and the test result is
+ * unreliable and only useful as advisory hints or for debugging.
+ * Especially for reentrant wqs, the pending state might hide the
+ * running state.
+ *
+ * RETURNS:
+ * OR'd bitmask of WORK_BUSY_* bits.
+ */
+unsigned int work_busy(struct work_struct *work)
 {
-       return keventd_wq != NULL;
-}
+       struct global_cwq *gcwq = get_work_gcwq(work);
+       unsigned long flags;
+       unsigned int ret = 0;
 
-int current_is_keventd(void)
-{
-       struct cpu_workqueue_struct *cwq;
-       int cpu = raw_smp_processor_id(); /* preempt-safe: keventd is per-cpu */
-       int ret = 0;
+       if (!gcwq)
+               return false;
 
-       BUG_ON(!keventd_wq);
+       spin_lock_irqsave(&gcwq->lock, flags);
 
-       cwq = per_cpu_ptr(keventd_wq->cpu_wq, cpu);
-       if (current == cwq->thread)
-               ret = 1;
+       if (work_pending(work))
+               ret |= WORK_BUSY_PENDING;
+       if (find_worker_executing_work(gcwq, work))
+               ret |= WORK_BUSY_RUNNING;
 
-       return ret;
+       spin_unlock_irqrestore(&gcwq->lock, flags);
 
+       return ret;
 }
+EXPORT_SYMBOL_GPL(work_busy);
 
-static struct cpu_workqueue_struct *
-init_cpu_workqueue(struct workqueue_struct *wq, int cpu)
-{
-       struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
+/*
+ * CPU hotplug.
+ *
+ * There are two challenges in supporting CPU hotplug.  Firstly, there
+ * are a lot of assumptions on strong associations among work, cwq and
+ * gcwq which make migrating pending and scheduled works very
+ * difficult to implement without impacting hot paths.  Secondly,
+ * gcwqs serve mix of short, long and very long running works making
+ * blocked draining impractical.
+ *
+ * This is solved by allowing a gcwq to be detached from CPU, running
+ * it with unbound (rogue) workers and allowing it to be reattached
+ * later if the cpu comes back online.  A separate thread is created
+ * to govern a gcwq in such state and is called the trustee of the
+ * gcwq.
+ *
+ * Trustee states and their descriptions.
+ *
+ * START       Command state used on startup.  On CPU_DOWN_PREPARE, a
+ *             new trustee is started with this state.
+ *
+ * IN_CHARGE   Once started, trustee will enter this state after
+ *             assuming the manager role and making all existing
+ *             workers rogue.  DOWN_PREPARE waits for trustee to
+ *             enter this state.  After reaching IN_CHARGE, trustee
+ *             tries to execute the pending worklist until it's empty
+ *             and the state is set to BUTCHER, or the state is set
+ *             to RELEASE.
+ *
+ * BUTCHER     Command state which is set by the cpu callback after
+ *             the cpu has went down.  Once this state is set trustee
+ *             knows that there will be no new works on the worklist
+ *             and once the worklist is empty it can proceed to
+ *             killing idle workers.
+ *
+ * RELEASE     Command state which is set by the cpu callback if the
+ *             cpu down has been canceled or it has come online
+ *             again.  After recognizing this state, trustee stops
+ *             trying to drain or butcher and clears ROGUE, rebinds
+ *             all remaining workers back to the cpu and releases
+ *             manager role.
+ *
+ * DONE                Trustee will enter this state after BUTCHER or RELEASE
+ *             is complete.
+ *
+ *          trustee                 CPU                draining
+ *         took over                down               complete
+ * START -----------> IN_CHARGE -----------> BUTCHER -----------> DONE
+ *                        |                     |                  ^
+ *                        | CPU is back online  v   return workers |
+ *                         ----------------> RELEASE --------------
+ */
 
-       cwq->wq = wq;
-       spin_lock_init(&cwq->lock);
-       INIT_LIST_HEAD(&cwq->worklist);
-       init_waitqueue_head(&cwq->more_work);
+/**
+ * trustee_wait_event_timeout - timed event wait for trustee
+ * @cond: condition to wait for
+ * @timeout: timeout in jiffies
+ *
+ * wait_event_timeout() for trustee to use.  Handles locking and
+ * checks for RELEASE request.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock) which may be released and regrabbed
+ * multiple times.  To be used by trustee.
+ *
+ * RETURNS:
+ * Positive indicating left time if @cond is satisfied, 0 if timed
+ * out, -1 if canceled.
+ */
+#define trustee_wait_event_timeout(cond, timeout) ({                   \
+       long __ret = (timeout);                                         \
+       while (!((cond) || (gcwq->trustee_state == TRUSTEE_RELEASE)) && \
+              __ret) {                                                 \
+               spin_unlock_irq(&gcwq->lock);                           \
+               __wait_event_timeout(gcwq->trustee_wait, (cond) ||      \
+                       (gcwq->trustee_state == TRUSTEE_RELEASE),       \
+                       __ret);                                         \
+               spin_lock_irq(&gcwq->lock);                             \
+       }                                                               \
+       gcwq->trustee_state == TRUSTEE_RELEASE ? -1 : (__ret);          \
+})
 
-       return cwq;
-}
+/**
+ * trustee_wait_event - event wait for trustee
+ * @cond: condition to wait for
+ *
+ * wait_event() for trustee to use.  Automatically handles locking and
+ * checks for CANCEL request.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock) which may be released and regrabbed
+ * multiple times.  To be used by trustee.
+ *
+ * RETURNS:
+ * 0 if @cond is satisfied, -1 if canceled.
+ */
+#define trustee_wait_event(cond) ({                                    \
+       long __ret1;                                                    \
+       __ret1 = trustee_wait_event_timeout(cond, MAX_SCHEDULE_TIMEOUT);\
+       __ret1 < 0 ? -1 : 0;                                            \
+})
 
-static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
+static int __cpuinit trustee_thread(void *__gcwq)
 {
-       struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
-       struct workqueue_struct *wq = cwq->wq;
-       const char *fmt = is_wq_single_threaded(wq) ? "%s" : "%s/%d";
-       struct task_struct *p;
+       struct global_cwq *gcwq = __gcwq;
+       struct worker *worker;
+       struct work_struct *work;
+       struct hlist_node *pos;
+       long rc;
+       int i;
 
-       p = kthread_create(worker_thread, cwq, fmt, wq->name, cpu);
+       BUG_ON(gcwq->cpu != smp_processor_id());
+
+       spin_lock_irq(&gcwq->lock);
        /*
-        * Nobody can add the work_struct to this cwq,
-        *      if (caller is __create_workqueue)
-        *              nobody should see this wq
-        *      else // caller is CPU_UP_PREPARE
-        *              cpu is not on cpu_online_map
-        * so we can abort safely.
+        * Claim the manager position and make all workers rogue.
+        * Trustee must be bound to the target cpu and can't be
+        * cancelled.
         */
-       if (IS_ERR(p))
-               return PTR_ERR(p);
-       if (cwq->wq->rt)
-               sched_setscheduler_nocheck(p, SCHED_FIFO, &param);
-       cwq->thread = p;
+       BUG_ON(gcwq->cpu != smp_processor_id());
+       rc = trustee_wait_event(!(gcwq->flags & GCWQ_MANAGING_WORKERS));
+       BUG_ON(rc < 0);
 
-       trace_workqueue_creation(cwq->thread, cpu);
+       gcwq->flags |= GCWQ_MANAGING_WORKERS;
 
-       return 0;
-}
+       list_for_each_entry(worker, &gcwq->idle_list, entry)
+               worker->flags |= WORKER_ROGUE;
 
-static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
-{
-       struct task_struct *p = cwq->thread;
+       for_each_busy_worker(worker, i, pos, gcwq)
+               worker->flags |= WORKER_ROGUE;
 
-       if (p != NULL) {
-               if (cpu >= 0)
-                       kthread_bind(p, cpu);
-               wake_up_process(p);
-       }
-}
+       /*
+        * Call schedule() so that we cross rq->lock and thus can
+        * guarantee sched callbacks see the rogue flag.  This is
+        * necessary as scheduler callbacks may be invoked from other
+        * cpus.
+        */
+       spin_unlock_irq(&gcwq->lock);
+       schedule();
+       spin_lock_irq(&gcwq->lock);
 
-struct workqueue_struct *__create_workqueue_key(const char *name,
-                                               int singlethread,
-                                               int freezeable,
-                                               int rt,
-                                               struct lock_class_key *key,
-                                               const char *lock_name)
-{
-       struct workqueue_struct *wq;
-       struct cpu_workqueue_struct *cwq;
-       int err = 0, cpu;
+       /*
+        * Sched callbacks are disabled now.  Zap nr_running.  After
+        * this, nr_running stays zero and need_more_worker() and
+        * keep_working() are always true as long as the worklist is
+        * not empty.
+        */
+       atomic_set(get_gcwq_nr_running(gcwq->cpu), 0);
 
-       wq = kzalloc(sizeof(*wq), GFP_KERNEL);
-       if (!wq)
-               return NULL;
+       spin_unlock_irq(&gcwq->lock);
+       del_timer_sync(&gcwq->idle_timer);
+       spin_lock_irq(&gcwq->lock);
 
-       wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);
-       if (!wq->cpu_wq) {
-               kfree(wq);
-               return NULL;
-       }
+       /*
+        * We're now in charge.  Notify and proceed to drain.  We need
+        * to keep the gcwq running during the whole CPU down
+        * procedure as other cpu hotunplug callbacks may need to
+        * flush currently running tasks.
+        */
+       gcwq->trustee_state = TRUSTEE_IN_CHARGE;
+       wake_up_all(&gcwq->trustee_wait);
 
-       wq->name = name;
-       lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
-       wq->singlethread = singlethread;
-       wq->freezeable = freezeable;
-       wq->rt = rt;
-       INIT_LIST_HEAD(&wq->list);
+       /*
+        * The original cpu is in the process of dying and may go away
+        * anytime now.  When that happens, we and all workers would
+        * be migrated to other cpus.  Try draining any left work.  We
+        * want to get it over with ASAP - spam rescuers, wake up as
+        * many idlers as necessary and create new ones till the
+        * worklist is empty.  Note that if the gcwq is frozen, there
+        * may be frozen works in freezeable cwqs.  Don't declare
+        * completion while frozen.
+        */
+       while (gcwq->nr_workers != gcwq->nr_idle ||
+              gcwq->flags & GCWQ_FREEZING ||
+              gcwq->trustee_state == TRUSTEE_IN_CHARGE) {
+               int nr_works = 0;
+
+               list_for_each_entry(work, &gcwq->worklist, entry) {
+                       send_mayday(work);
+                       nr_works++;
+               }
 
-       if (singlethread) {
-               cwq = init_cpu_workqueue(wq, singlethread_cpu);
-               err = create_workqueue_thread(cwq, singlethread_cpu);
-               start_workqueue_thread(cwq, -1);
-       } else {
-               cpu_maps_update_begin();
-               /*
-                * We must place this wq on list even if the code below fails.
-                * cpu_down(cpu) can remove cpu from cpu_populated_map before
-                * destroy_workqueue() takes the lock, in that case we leak
-                * cwq[cpu]->thread.
-                */
-               spin_lock(&workqueue_lock);
-               list_add(&wq->list, &workqueues);
-               spin_unlock(&workqueue_lock);
-               /*
-                * We must initialize cwqs for each possible cpu even if we
-                * are going to call destroy_workqueue() finally. Otherwise
-                * cpu_up() can hit the uninitialized cwq once we drop the
-                * lock.
-                */
-               for_each_possible_cpu(cpu) {
-                       cwq = init_cpu_workqueue(wq, cpu);
-                       if (err || !cpu_online(cpu))
-                               continue;
-                       err = create_workqueue_thread(cwq, cpu);
-                       start_workqueue_thread(cwq, cpu);
+               list_for_each_entry(worker, &gcwq->idle_list, entry) {
+                       if (!nr_works--)
+                               break;
+                       wake_up_process(worker->task);
+               }
+
+               if (need_to_create_worker(gcwq)) {
+                       spin_unlock_irq(&gcwq->lock);
+                       worker = create_worker(gcwq, false);
+                       spin_lock_irq(&gcwq->lock);
+                       if (worker) {
+                               worker->flags |= WORKER_ROGUE;
+                               start_worker(worker);
+                       }
                }
-               cpu_maps_update_done();
-       }
 
-       if (err) {
-               destroy_workqueue(wq);
-               wq = NULL;
+               /* give a breather */
+               if (trustee_wait_event_timeout(false, TRUSTEE_COOLDOWN) < 0)
+                       break;
        }
-       return wq;
-}
-EXPORT_SYMBOL_GPL(__create_workqueue_key);
 
-static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq)
-{
        /*
-        * Our caller is either destroy_workqueue() or CPU_POST_DEAD,
-        * cpu_add_remove_lock protects cwq->thread.
+        * Either all works have been scheduled and cpu is down, or
+        * cpu down has already been canceled.  Wait for and butcher
+        * all workers till we're canceled.
         */
-       if (cwq->thread == NULL)
-               return;
-
-       lock_map_acquire(&cwq->wq->lockdep_map);
-       lock_map_release(&cwq->wq->lockdep_map);
+       do {
+               rc = trustee_wait_event(!list_empty(&gcwq->idle_list));
+               while (!list_empty(&gcwq->idle_list))
+                       destroy_worker(list_first_entry(&gcwq->idle_list,
+                                                       struct worker, entry));
+       } while (gcwq->nr_workers && rc >= 0);
 
-       flush_cpu_workqueue(cwq);
        /*
-        * If the caller is CPU_POST_DEAD and cwq->worklist was not empty,
-        * a concurrent flush_workqueue() can insert a barrier after us.
-        * However, in that case run_workqueue() won't return and check
-        * kthread_should_stop() until it flushes all work_struct's.
-        * When ->worklist becomes empty it is safe to exit because no
-        * more work_structs can be queued on this cwq: flush_workqueue
-        * checks list_empty(), and a "normal" queue_work() can't use
-        * a dead CPU.
+        * At this point, either draining has completed and no worker
+        * is left, or cpu down has been canceled or the cpu is being
+        * brought back up.  There shouldn't be any idle one left.
+        * Tell the remaining busy ones to rebind once it finishes the
+        * currently scheduled works by scheduling the rebind_work.
         */
-       trace_workqueue_destruction(cwq->thread);
-       kthread_stop(cwq->thread);
-       cwq->thread = NULL;
+       WARN_ON(!list_empty(&gcwq->idle_list));
+
+       for_each_busy_worker(worker, i, pos, gcwq) {
+               struct work_struct *rebind_work = &worker->rebind_work;
+
+               /*
+                * Rebind_work may race with future cpu hotplug
+                * operations.  Use a separate flag to mark that
+                * rebinding is scheduled.
+                */
+               worker->flags |= WORKER_REBIND;
+               worker->flags &= ~WORKER_ROGUE;
+
+               /* queue rebind_work, wq doesn't matter, use the default one */
+               if (test_and_set_bit(WORK_STRUCT_PENDING_BIT,
+                                    work_data_bits(rebind_work)))
+                       continue;
+
+               debug_work_activate(rebind_work);
+               insert_work(get_cwq(gcwq->cpu, system_wq), rebind_work,
+                           worker->scheduled.next,
+                           work_color_to_flags(WORK_NO_COLOR));
+       }
+
+       /* relinquish manager role */
+       gcwq->flags &= ~GCWQ_MANAGING_WORKERS;
+
+       /* notify completion */
+       gcwq->trustee = NULL;
+       gcwq->trustee_state = TRUSTEE_DONE;
+       wake_up_all(&gcwq->trustee_wait);
+       spin_unlock_irq(&gcwq->lock);
+       return 0;
 }
 
 /**
- * destroy_workqueue - safely terminate a workqueue
- * @wq: target workqueue
+ * wait_trustee_state - wait for trustee to enter the specified state
+ * @gcwq: gcwq the trustee of interest belongs to
+ * @state: target state to wait for
  *
- * Safely destroy a workqueue. All work currently pending will be done first.
+ * Wait for the trustee to reach @state.  DONE is already matched.
+ *
+ * CONTEXT:
+ * spin_lock_irq(gcwq->lock) which may be released and regrabbed
+ * multiple times.  To be used by cpu_callback.
  */
-void destroy_workqueue(struct workqueue_struct *wq)
+static void __cpuinit wait_trustee_state(struct global_cwq *gcwq, int state)
 {
-       const struct cpumask *cpu_map = wq_cpu_map(wq);
-       int cpu;
-
-       cpu_maps_update_begin();
-       spin_lock(&workqueue_lock);
-       list_del(&wq->list);
-       spin_unlock(&workqueue_lock);
-
-       for_each_cpu(cpu, cpu_map)
-               cleanup_workqueue_thread(per_cpu_ptr(wq->cpu_wq, cpu));
-       cpu_maps_update_done();
-
-       free_percpu(wq->cpu_wq);
-       kfree(wq);
+       if (!(gcwq->trustee_state == state ||
+             gcwq->trustee_state == TRUSTEE_DONE)) {
+               spin_unlock_irq(&gcwq->lock);
+               __wait_event(gcwq->trustee_wait,
+                            gcwq->trustee_state == state ||
+                            gcwq->trustee_state == TRUSTEE_DONE);
+               spin_lock_irq(&gcwq->lock);
+       }
 }
-EXPORT_SYMBOL_GPL(destroy_workqueue);
 
 static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
                                                unsigned long action,
                                                void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
-       struct cpu_workqueue_struct *cwq;
-       struct workqueue_struct *wq;
-       int err = 0;
+       struct global_cwq *gcwq = get_gcwq(cpu);
+       struct task_struct *new_trustee = NULL;
+       struct worker *uninitialized_var(new_worker);
+       unsigned long flags;
 
        action &= ~CPU_TASKS_FROZEN;
 
        switch (action) {
+       case CPU_DOWN_PREPARE:
+               new_trustee = kthread_create(trustee_thread, gcwq,
+                                            "workqueue_trustee/%d\n", cpu);
+               if (IS_ERR(new_trustee))
+                       return notifier_from_errno(PTR_ERR(new_trustee));
+               kthread_bind(new_trustee, cpu);
+               /* fall through */
        case CPU_UP_PREPARE:
-               cpumask_set_cpu(cpu, cpu_populated_map);
-       }
-undo:
-       list_for_each_entry(wq, &workqueues, list) {
-               cwq = per_cpu_ptr(wq->cpu_wq, cpu);
-
-               switch (action) {
-               case CPU_UP_PREPARE:
-                       err = create_workqueue_thread(cwq, cpu);
-                       if (!err)
-                               break;
-                       printk(KERN_ERR "workqueue [%s] for %i failed\n",
-                               wq->name, cpu);
-                       action = CPU_UP_CANCELED;
-                       err = -ENOMEM;
-                       goto undo;
-
-               case CPU_ONLINE:
-                       start_workqueue_thread(cwq, cpu);
-                       break;
-
-               case CPU_UP_CANCELED:
-                       start_workqueue_thread(cwq, -1);
-               case CPU_POST_DEAD:
-                       cleanup_workqueue_thread(cwq);
-                       break;
+               BUG_ON(gcwq->first_idle);
+               new_worker = create_worker(gcwq, false);
+               if (!new_worker) {
+                       if (new_trustee)
+                               kthread_stop(new_trustee);
+                       return NOTIFY_BAD;
                }
        }
 
+       /* some are called w/ irq disabled, don't disturb irq status */
+       spin_lock_irqsave(&gcwq->lock, flags);
+
        switch (action) {
-       case CPU_UP_CANCELED:
+       case CPU_DOWN_PREPARE:
+               /* initialize trustee and tell it to acquire the gcwq */
+               BUG_ON(gcwq->trustee || gcwq->trustee_state != TRUSTEE_DONE);
+               gcwq->trustee = new_trustee;
+               gcwq->trustee_state = TRUSTEE_START;
+               wake_up_process(gcwq->trustee);
+               wait_trustee_state(gcwq, TRUSTEE_IN_CHARGE);
+               /* fall through */
+       case CPU_UP_PREPARE:
+               BUG_ON(gcwq->first_idle);
+               gcwq->first_idle = new_worker;
+               break;
+
+       case CPU_DYING:
+               /*
+                * Before this, the trustee and all workers except for
+                * the ones which are still executing works from
+                * before the last CPU down must be on the cpu.  After
+                * this, they'll all be diasporas.
+                */
+               gcwq->flags |= GCWQ_DISASSOCIATED;
+               break;
+
        case CPU_POST_DEAD:
-               cpumask_clear_cpu(cpu, cpu_populated_map);
+               gcwq->trustee_state = TRUSTEE_BUTCHER;
+               /* fall through */
+       case CPU_UP_CANCELED:
+               destroy_worker(gcwq->first_idle);
+               gcwq->first_idle = NULL;
+               break;
+
+       case CPU_DOWN_FAILED:
+       case CPU_ONLINE:
+               gcwq->flags &= ~GCWQ_DISASSOCIATED;
+               if (gcwq->trustee_state != TRUSTEE_DONE) {
+                       gcwq->trustee_state = TRUSTEE_RELEASE;
+                       wake_up_process(gcwq->trustee);
+                       wait_trustee_state(gcwq, TRUSTEE_DONE);
+               }
+
+               /*
+                * Trustee is done and there might be no worker left.
+                * Put the first_idle in and request a real manager to
+                * take a look.
+                */
+               spin_unlock_irq(&gcwq->lock);
+               kthread_bind(gcwq->first_idle->task, cpu);
+               spin_lock_irq(&gcwq->lock);
+               gcwq->flags |= GCWQ_MANAGE_WORKERS;
+               start_worker(gcwq->first_idle);
+               gcwq->first_idle = NULL;
+               break;
        }
 
-       return notifier_from_errno(err);
+       spin_unlock_irqrestore(&gcwq->lock, flags);
+
+       return notifier_from_errno(0);
 }
 
 #ifdef CONFIG_SMP
@@ -1201,14 +3381,199 @@ long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
 EXPORT_SYMBOL_GPL(work_on_cpu);
 #endif /* CONFIG_SMP */
 
-void __init init_workqueues(void)
+#ifdef CONFIG_FREEZER
+
+/**
+ * freeze_workqueues_begin - begin freezing workqueues
+ *
+ * Start freezing workqueues.  After this function returns, all
+ * freezeable workqueues will queue new works to their frozen_works
+ * list instead of gcwq->worklist.
+ *
+ * CONTEXT:
+ * Grabs and releases workqueue_lock and gcwq->lock's.
+ */
+void freeze_workqueues_begin(void)
+{
+       unsigned int cpu;
+
+       spin_lock(&workqueue_lock);
+
+       BUG_ON(workqueue_freezing);
+       workqueue_freezing = true;
+
+       for_each_gcwq_cpu(cpu) {
+               struct global_cwq *gcwq = get_gcwq(cpu);
+               struct workqueue_struct *wq;
+
+               spin_lock_irq(&gcwq->lock);
+
+               BUG_ON(gcwq->flags & GCWQ_FREEZING);
+               gcwq->flags |= GCWQ_FREEZING;
+
+               list_for_each_entry(wq, &workqueues, list) {
+                       struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+
+                       if (cwq && wq->flags & WQ_FREEZEABLE)
+                               cwq->max_active = 0;
+               }
+
+               spin_unlock_irq(&gcwq->lock);
+       }
+
+       spin_unlock(&workqueue_lock);
+}
+
+/**
+ * freeze_workqueues_busy - are freezeable workqueues still busy?
+ *
+ * Check whether freezing is complete.  This function must be called
+ * between freeze_workqueues_begin() and thaw_workqueues().
+ *
+ * CONTEXT:
+ * Grabs and releases workqueue_lock.
+ *
+ * RETURNS:
+ * %true if some freezeable workqueues are still busy.  %false if
+ * freezing is complete.
+ */
+bool freeze_workqueues_busy(void)
+{
+       unsigned int cpu;
+       bool busy = false;
+
+       spin_lock(&workqueue_lock);
+
+       BUG_ON(!workqueue_freezing);
+
+       for_each_gcwq_cpu(cpu) {
+               struct workqueue_struct *wq;
+               /*
+                * nr_active is monotonically decreasing.  It's safe
+                * to peek without lock.
+                */
+               list_for_each_entry(wq, &workqueues, list) {
+                       struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+
+                       if (!cwq || !(wq->flags & WQ_FREEZEABLE))
+                               continue;
+
+                       BUG_ON(cwq->nr_active < 0);
+                       if (cwq->nr_active) {
+                               busy = true;
+                               goto out_unlock;
+                       }
+               }
+       }
+out_unlock:
+       spin_unlock(&workqueue_lock);
+       return busy;
+}
+
+/**
+ * thaw_workqueues - thaw workqueues
+ *
+ * Thaw workqueues.  Normal queueing is restored and all collected
+ * frozen works are transferred to their respective gcwq worklists.
+ *
+ * CONTEXT:
+ * Grabs and releases workqueue_lock and gcwq->lock's.
+ */
+void thaw_workqueues(void)
+{
+       unsigned int cpu;
+
+       spin_lock(&workqueue_lock);
+
+       if (!workqueue_freezing)
+               goto out_unlock;
+
+       for_each_gcwq_cpu(cpu) {
+               struct global_cwq *gcwq = get_gcwq(cpu);
+               struct workqueue_struct *wq;
+
+               spin_lock_irq(&gcwq->lock);
+
+               BUG_ON(!(gcwq->flags & GCWQ_FREEZING));
+               gcwq->flags &= ~GCWQ_FREEZING;
+
+               list_for_each_entry(wq, &workqueues, list) {
+                       struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+
+                       if (!cwq || !(wq->flags & WQ_FREEZEABLE))
+                               continue;
+
+                       /* restore max_active and repopulate worklist */
+                       cwq->max_active = wq->saved_max_active;
+
+                       while (!list_empty(&cwq->delayed_works) &&
+                              cwq->nr_active < cwq->max_active)
+                               cwq_activate_first_delayed(cwq);
+               }
+
+               wake_up_worker(gcwq);
+
+               spin_unlock_irq(&gcwq->lock);
+       }
+
+       workqueue_freezing = false;
+out_unlock:
+       spin_unlock(&workqueue_lock);
+}
+#endif /* CONFIG_FREEZER */
+
+static int __init init_workqueues(void)
 {
-       alloc_cpumask_var(&cpu_populated_map, GFP_KERNEL);
+       unsigned int cpu;
+       int i;
+
+       hotcpu_notifier(workqueue_cpu_callback, CPU_PRI_WORKQUEUE);
+
+       /* initialize gcwqs */
+       for_each_gcwq_cpu(cpu) {
+               struct global_cwq *gcwq = get_gcwq(cpu);
+
+               spin_lock_init(&gcwq->lock);
+               INIT_LIST_HEAD(&gcwq->worklist);
+               gcwq->cpu = cpu;
+               if (cpu == WORK_CPU_UNBOUND)
+                       gcwq->flags |= GCWQ_DISASSOCIATED;
+
+               INIT_LIST_HEAD(&gcwq->idle_list);
+               for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++)
+                       INIT_HLIST_HEAD(&gcwq->busy_hash[i]);
+
+               init_timer_deferrable(&gcwq->idle_timer);
+               gcwq->idle_timer.function = idle_worker_timeout;
+               gcwq->idle_timer.data = (unsigned long)gcwq;
 
-       cpumask_copy(cpu_populated_map, cpu_online_mask);
-       singlethread_cpu = cpumask_first(cpu_possible_mask);
-       cpu_singlethread_map = cpumask_of(singlethread_cpu);
-       hotcpu_notifier(workqueue_cpu_callback, 0);
-       keventd_wq = create_workqueue("events");
-       BUG_ON(!keventd_wq);
+               setup_timer(&gcwq->mayday_timer, gcwq_mayday_timeout,
+                           (unsigned long)gcwq);
+
+               ida_init(&gcwq->worker_ida);
+
+               gcwq->trustee_state = TRUSTEE_DONE;
+               init_waitqueue_head(&gcwq->trustee_wait);
+       }
+
+       /* create the initial worker */
+       for_each_online_gcwq_cpu(cpu) {
+               struct global_cwq *gcwq = get_gcwq(cpu);
+               struct worker *worker;
+
+               worker = create_worker(gcwq, true);
+               BUG_ON(!worker);
+               spin_lock_irq(&gcwq->lock);
+               start_worker(worker);
+               spin_unlock_irq(&gcwq->lock);
+       }
+
+       system_wq = alloc_workqueue("events", 0, 0);
+       system_long_wq = alloc_workqueue("events_long", 0, 0);
+       system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0);
+       system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
+                                           WQ_UNBOUND_MAX_ACTIVE);
+       BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq);
+       return 0;
 }
+early_initcall(init_workqueues);
diff --git a/kernel/workqueue_sched.h b/kernel/workqueue_sched.h
new file mode 100644 (file)
index 0000000..2d10fc9
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * kernel/workqueue_sched.h
+ *
+ * Scheduler hooks for concurrency managed workqueue.  Only to be
+ * included from sched.c and workqueue.c.
+ */
+void wq_worker_waking_up(struct task_struct *task, unsigned int cpu);
+struct task_struct *wq_worker_sleeping(struct task_struct *task,
+                                      unsigned int cpu);
index 154ff43aaa81cbaccd058e4486805099924b9af2..79e0dff1cdcb4e103c9f93b42f79c400fbdc498d 100644 (file)
@@ -76,7 +76,6 @@ config UNUSED_SYMBOLS
 
 config DEBUG_FS
        bool "Debug Filesystem"
-       depends on SYSFS
        help
          debugfs is a virtual file system that kernel developers use to put
          debugging files into.  Enable this option to be able to read and
@@ -152,28 +151,33 @@ config DEBUG_SHIRQ
          Drivers ought to be able to handle interrupts coming in at those
          points; some don't and need to be caught.
 
-config DETECT_SOFTLOCKUP
-       bool "Detect Soft Lockups"
+config LOCKUP_DETECTOR
+       bool "Detect Hard and Soft Lockups"
        depends on DEBUG_KERNEL && !S390
-       default y
        help
-         Say Y here to enable the kernel to detect "soft lockups",
-         which are bugs that cause the kernel to loop in kernel
+         Say Y here to enable the kernel to act as a watchdog to detect
+         hard and soft lockups.
+
+         Softlockups are bugs that cause the kernel to loop in kernel
          mode for more than 60 seconds, without giving other tasks a
-         chance to run.
+         chance to run.  The current stack trace is displayed upon
+         detection and the system will stay locked up.
 
-         When a soft-lockup is detected, the kernel will print the
-         current stack trace (which you should report), but the
-         system will stay locked up. This feature has negligible
-         overhead.
+         Hardlockups are bugs that cause the CPU to loop in kernel mode
+         for more than 60 seconds, without letting other interrupts have a
+         chance to run.  The current stack trace is displayed upon detection
+         and the system will stay locked up.
 
-         (Note that "hard lockups" are separate type of bugs that
-          can be detected via the NMI-watchdog, on platforms that
-          support it.)
+         The overhead should be minimal.  A periodic hrtimer runs to
+         generate interrupts and kick the watchdog task every 10-12 seconds.
+         An NMI is generated every 60 seconds or so to check for hardlockups.
+
+config HARDLOCKUP_DETECTOR
+       def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI
 
 config BOOTPARAM_SOFTLOCKUP_PANIC
        bool "Panic (Reboot) On Soft Lockups"
-       depends on DETECT_SOFTLOCKUP
+       depends on LOCKUP_DETECTOR
        help
          Say Y here to enable the kernel to panic on "soft lockups",
          which are bugs that cause the kernel to loop in kernel
@@ -190,7 +194,7 @@ config BOOTPARAM_SOFTLOCKUP_PANIC
 
 config BOOTPARAM_SOFTLOCKUP_PANIC_VALUE
        int
-       depends on DETECT_SOFTLOCKUP
+       depends on LOCKUP_DETECTOR
        range 0 1
        default 0 if !BOOTPARAM_SOFTLOCKUP_PANIC
        default 1 if BOOTPARAM_SOFTLOCKUP_PANIC
@@ -307,6 +311,12 @@ config DEBUG_OBJECTS_WORK
          work queue routines to track the life time of work objects and
          validate the work operations.
 
+config DEBUG_OBJECTS_RCU_HEAD
+       bool "Debug RCU callbacks objects"
+       depends on DEBUG_OBJECTS && PREEMPT
+       help
+         Enable this to turn on debugging of RCU list heads (call_rcu() usage).
+
 config DEBUG_OBJECTS_ENABLE_DEFAULT
        int "debug_objects bootup default value (0-1)"
         range 0 1
@@ -628,6 +638,19 @@ config DEBUG_INFO
 
          If unsure, say N.
 
+config DEBUG_INFO_REDUCED
+       bool "Reduce debugging information"
+       depends on DEBUG_INFO
+       help
+         If you say Y here gcc is instructed to generate less debugging
+         information for structure types. This means that tools that
+         need full debugging information (like kgdb or systemtap) won't
+         be happy. But if you merely need debugging information to
+         resolve line numbers there is no loss. Advantage is that
+         build directory object sizes shrink dramatically over a full
+         DEBUG_INFO build and compile times are reduced too.
+         Only works with newer gcc versions.
+
 config DEBUG_VM
        bool "Debug VM"
        depends on DEBUG_KERNEL
index 14c6078f17a2a2aa26da4ac638da4a7e966649ed..5730ecd3eb6678aca50355955955f0cf5ea5ee38 100644 (file)
 #include <asm/pgtable.h>
 
 static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
-               unsigned long end, unsigned long phys_addr, pgprot_t prot)
+               unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 {
        pte_t *pte;
-       unsigned long pfn;
+       u64 pfn;
 
        pfn = phys_addr >> PAGE_SHIFT;
        pte = pte_alloc_kernel(pmd, addr);
@@ -31,7 +31,7 @@ static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
 }
 
 static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
-               unsigned long end, unsigned long phys_addr, pgprot_t prot)
+               unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 {
        pmd_t *pmd;
        unsigned long next;
@@ -49,7 +49,7 @@ static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
 }
 
 static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
-               unsigned long end, unsigned long phys_addr, pgprot_t prot)
+               unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 {
        pud_t *pud;
        unsigned long next;
@@ -67,7 +67,7 @@ static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
 }
 
 int ioremap_page_range(unsigned long addr,
-                      unsigned long end, unsigned long phys_addr, pgprot_t prot)
+                      unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 {
        pgd_t *pgd;
        unsigned long start;
index 123bcef13e51806ce3d57232d4ad665a60d7d172..f9fd3dd3916b97067fbac7b2742c2195c04f4748 100644 (file)
@@ -665,7 +665,6 @@ int bdi_init(struct backing_dev_info *bdi)
        bdi->max_ratio = 100;
        bdi->max_prop_frac = PROP_FRAC_BASE;
        spin_lock_init(&bdi->wb_lock);
-       INIT_RCU_HEAD(&bdi->rcu_head);
        INIT_LIST_HEAD(&bdi->bdi_list);
        INIT_LIST_HEAD(&bdi->wb_list);
        INIT_LIST_HEAD(&bdi->work_list);
index 66baa20f78f5a4265f16ebf6bb0b7d131bf80684..7a0aa1be4993521f7d55da731b3f69f8a59ea7c7 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/hash.h>
 #include <linux/highmem.h>
+#include <linux/kgdb.h>
 #include <asm/tlbflush.h>
 
 /*
@@ -470,6 +471,12 @@ void debug_kmap_atomic(enum km_type type)
                        warn_count--;
                }
        }
+#ifdef CONFIG_KGDB_KDB
+       if (unlikely(type == KM_KDB && atomic_read(&kgdb_active) == -1)) {
+               WARN_ON(1);
+               warn_count--;
+       }
+#endif /* CONFIG_KGDB_KDB */
 }
 
 #endif
index 456ec6f278897a560bd915e6d84297ac3de7ddef..e38e910cb75673c528116e9e0a114fb0c8f3b8cb 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1734,8 +1734,10 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
                grow = (address - vma->vm_end) >> PAGE_SHIFT;
 
                error = acct_stack_growth(vma, size, grow);
-               if (!error)
+               if (!error) {
                        vma->vm_end = address;
+                       perf_event_mmap(vma);
+               }
        }
        anon_vma_unlock(vma);
        return error;
@@ -1781,6 +1783,7 @@ static int expand_downwards(struct vm_area_struct *vma,
                if (!error) {
                        vma->vm_start = address;
                        vma->vm_pgoff -= grow;
+                       perf_event_mmap(vma);
                }
        }
        anon_vma_unlock(vma);
@@ -2208,6 +2211,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
        vma->vm_page_prot = vm_get_page_prot(flags);
        vma_link(mm, vma, prev, rb_link, rb_parent);
 out:
+       perf_event_mmap(vma);
        mm->total_vm += len >> PAGE_SHIFT;
        if (flags & VM_LOCKED) {
                if (!mlock_vma_pages_range(vma, addr, addr + len))
index e49f8f46f46d6878dba427dae10fc9b5fb153a9f..736e497733d60c99ed376ae2bc1b378aea34a0f7 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
 #include       <linux/cpu.h>
 #include       <linux/sysctl.h>
 #include       <linux/module.h>
-#include       <linux/kmemtrace.h>
 #include       <linux/rcupdate.h>
 #include       <linux/string.h>
 #include       <linux/uaccess.h>
@@ -861,7 +860,7 @@ static void __cpuinit start_cpu_timer(int cpu)
         */
        if (keventd_up() && reap_work->work.func == NULL) {
                init_reap_node(cpu);
-               INIT_DELAYED_WORK(reap_work, cache_reap);
+               INIT_DELAYED_WORK_DEFERRABLE(reap_work, cache_reap);
                schedule_delayed_work_on(cpu, reap_work,
                                        __round_jiffies_relative(HZ, cpu));
        }
index 23631e2bb57af43c5cb577a75323cc9768798016..d582171c81014c027227ddbb7b3916661ecb1ef8 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
 #include <linux/module.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
-#include <linux/kmemtrace.h>
 #include <linux/kmemleak.h>
+
+#include <trace/events/kmem.h>
+
 #include <asm/atomic.h>
 
 /*
@@ -394,6 +396,7 @@ static void slob_free(void *block, int size)
        slob_t *prev, *next, *b = (slob_t *)block;
        slobidx_t units;
        unsigned long flags;
+       struct list_head *slob_list;
 
        if (unlikely(ZERO_OR_NULL_PTR(block)))
                return;
@@ -422,7 +425,13 @@ static void slob_free(void *block, int size)
                set_slob(b, units,
                        (void *)((unsigned long)(b +
                                        SLOB_UNITS(PAGE_SIZE)) & PAGE_MASK));
-               set_slob_page_free(sp, &free_slob_small);
+               if (size < SLOB_BREAK1)
+                       slob_list = &free_slob_small;
+               else if (size < SLOB_BREAK2)
+                       slob_list = &free_slob_medium;
+               else
+                       slob_list = &free_slob_large;
+               set_slob_page_free(sp, slob_list);
                goto out;
        }
 
@@ -639,7 +648,6 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
        if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
                struct slob_rcu *slob_rcu;
                slob_rcu = b + (c->size - sizeof(struct slob_rcu));
-               INIT_RCU_HEAD(&slob_rcu->head);
                slob_rcu->size = c->size;
                call_rcu(&slob_rcu->head, kmem_rcu_free);
        } else {
index 578f68f3c51f76ed3c2ff21b5ff2545d2ab64c0d..13fffe1f0f3dc5992471ffd590326b9517b0cc3a 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/kmemtrace.h>
 #include <linux/kmemcheck.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
  *                     the fast path and disables lockless freelists.
  */
 
+#define SLAB_DEBUG_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
+               SLAB_TRACE | SLAB_DEBUG_FREE)
+
+static inline int kmem_cache_debug(struct kmem_cache *s)
+{
 #ifdef CONFIG_SLUB_DEBUG
-#define SLABDEBUG 1
+       return unlikely(s->flags & SLAB_DEBUG_FLAGS);
 #else
-#define SLABDEBUG 0
+       return 0;
 #endif
+}
 
 /*
  * Issues still to be resolved:
 #define MAX_OBJS_PER_PAGE      65535 /* since page.objects is u16 */
 
 /* Internal SLUB flags */
-#define __OBJECT_POISON                0x80000000 /* Poison object */
-#define __SYSFS_ADD_DEFERRED   0x40000000 /* Not yet visible via sysfs */
+#define __OBJECT_POISON                0x80000000UL /* Poison object */
+#define __SYSFS_ADD_DEFERRED   0x40000000UL /* Not yet visible via sysfs */
 
 static int kmem_size = sizeof(struct kmem_cache);
 
@@ -1073,7 +1078,7 @@ static inline struct page *alloc_slab_page(gfp_t flags, int node,
 
        flags |= __GFP_NOTRACK;
 
-       if (node == -1)
+       if (node == NUMA_NO_NODE)
                return alloc_pages(flags, order);
        else
                return alloc_pages_exact_node(node, flags, order);
@@ -1157,9 +1162,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
        inc_slabs_node(s, page_to_nid(page), page->objects);
        page->slab = s;
        page->flags |= 1 << PG_slab;
-       if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
-                       SLAB_STORE_USER | SLAB_TRACE))
-               __SetPageSlubDebug(page);
 
        start = page_address(page);
 
@@ -1186,14 +1188,13 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
        int order = compound_order(page);
        int pages = 1 << order;
 
-       if (unlikely(SLABDEBUG && PageSlubDebug(page))) {
+       if (kmem_cache_debug(s)) {
                void *p;
 
                slab_pad_check(s, page);
                for_each_object(p, s, page_address(page),
                                                page->objects)
                        check_object(s, page, p, 0);
-               __ClearPageSlubDebug(page);
        }
 
        kmemcheck_free_shadow(page, compound_order(page));
@@ -1387,10 +1388,10 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags)
 static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node)
 {
        struct page *page;
-       int searchnode = (node == -1) ? numa_node_id() : node;
+       int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node;
 
        page = get_partial_node(get_node(s, searchnode));
-       if (page || (flags & __GFP_THISNODE))
+       if (page || node != -1)
                return page;
 
        return get_any_partial(s, flags);
@@ -1415,8 +1416,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
                        stat(s, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD);
                } else {
                        stat(s, DEACTIVATE_FULL);
-                       if (SLABDEBUG && PageSlubDebug(page) &&
-                                               (s->flags & SLAB_STORE_USER))
+                       if (kmem_cache_debug(s) && (s->flags & SLAB_STORE_USER))
                                add_full(n, page);
                }
                slab_unlock(page);
@@ -1515,7 +1515,7 @@ static void flush_all(struct kmem_cache *s)
 static inline int node_match(struct kmem_cache_cpu *c, int node)
 {
 #ifdef CONFIG_NUMA
-       if (node != -1 && c->node != node)
+       if (node != NUMA_NO_NODE && c->node != node)
                return 0;
 #endif
        return 1;
@@ -1624,7 +1624,7 @@ load_freelist:
        object = c->page->freelist;
        if (unlikely(!object))
                goto another_slab;
-       if (unlikely(SLABDEBUG && PageSlubDebug(c->page)))
+       if (kmem_cache_debug(s))
                goto debug;
 
        c->freelist = get_freepointer(s, object);
@@ -1727,7 +1727,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
 
 void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
 {
-       void *ret = slab_alloc(s, gfpflags, -1, _RET_IP_);
+       void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
 
        trace_kmem_cache_alloc(_RET_IP_, ret, s->objsize, s->size, gfpflags);
 
@@ -1738,7 +1738,7 @@ EXPORT_SYMBOL(kmem_cache_alloc);
 #ifdef CONFIG_TRACING
 void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
 {
-       return slab_alloc(s, gfpflags, -1, _RET_IP_);
+       return slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
 }
 EXPORT_SYMBOL(kmem_cache_alloc_notrace);
 #endif
@@ -1783,7 +1783,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
        stat(s, FREE_SLOWPATH);
        slab_lock(page);
 
-       if (unlikely(SLABDEBUG && PageSlubDebug(page)))
+       if (kmem_cache_debug(s))
                goto debug;
 
 checks_ok:
@@ -2490,7 +2490,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
        s->refcount--;
        if (!s->refcount) {
                list_del(&s->list);
-               up_write(&slub_lock);
                if (kmem_cache_close(s)) {
                        printk(KERN_ERR "SLUB %s: %s called for cache that "
                                "still has objects.\n", s->name, __func__);
@@ -2499,8 +2498,8 @@ void kmem_cache_destroy(struct kmem_cache *s)
                if (s->flags & SLAB_DESTROY_BY_RCU)
                        rcu_barrier();
                sysfs_slab_remove(s);
-       } else
-               up_write(&slub_lock);
+       }
+       up_write(&slub_lock);
 }
 EXPORT_SYMBOL(kmem_cache_destroy);
 
@@ -2728,7 +2727,7 @@ void *__kmalloc(size_t size, gfp_t flags)
        if (unlikely(ZERO_OR_NULL_PTR(s)))
                return s;
 
-       ret = slab_alloc(s, flags, -1, _RET_IP_);
+       ret = slab_alloc(s, flags, NUMA_NO_NODE, _RET_IP_);
 
        trace_kmalloc(_RET_IP_, ret, size, s->size, flags);
 
@@ -3118,9 +3117,12 @@ void __init kmem_cache_init(void)
        slab_state = UP;
 
        /* Provide the correct kmalloc names now that the caches are up */
-       for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++)
-               kmalloc_caches[i]. name =
-                       kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i);
+       for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) {
+               char *s = kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i);
+
+               BUG_ON(!s);
+               kmalloc_caches[i].name = s;
+       }
 
 #ifdef CONFIG_SMP
        register_cpu_notifier(&slab_notifier);
@@ -3223,14 +3225,12 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
                 */
                s->objsize = max(s->objsize, (int)size);
                s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
-               up_write(&slub_lock);
 
                if (sysfs_slab_alias(s, name)) {
-                       down_write(&slub_lock);
                        s->refcount--;
-                       up_write(&slub_lock);
                        goto err;
                }
+               up_write(&slub_lock);
                return s;
        }
 
@@ -3239,14 +3239,12 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
                if (kmem_cache_open(s, GFP_KERNEL, name,
                                size, align, flags, ctor)) {
                        list_add(&s->list, &slab_caches);
-                       up_write(&slub_lock);
                        if (sysfs_slab_add(s)) {
-                               down_write(&slub_lock);
                                list_del(&s->list);
-                               up_write(&slub_lock);
                                kfree(s);
                                goto err;
                        }
+                       up_write(&slub_lock);
                        return s;
                }
                kfree(s);
@@ -3312,7 +3310,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
        if (unlikely(ZERO_OR_NULL_PTR(s)))
                return s;
 
-       ret = slab_alloc(s, gfpflags, -1, caller);
+       ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, caller);
 
        /* Honor the call site pointer we recieved. */
        trace_kmalloc(caller, ret, size, s->size, gfpflags);
@@ -3395,16 +3393,6 @@ static void validate_slab_slab(struct kmem_cache *s, struct page *page,
        } else
                printk(KERN_INFO "SLUB %s: Skipped busy slab 0x%p\n",
                        s->name, page);
-
-       if (s->flags & DEBUG_DEFAULT_FLAGS) {
-               if (!PageSlubDebug(page))
-                       printk(KERN_ERR "SLUB %s: SlubDebug not set "
-                               "on slab 0x%p\n", s->name, page);
-       } else {
-               if (PageSlubDebug(page))
-                       printk(KERN_ERR "SLUB %s: SlubDebug set on "
-                               "slab 0x%p\n", s->name, page);
-       }
 }
 
 static int validate_slab_node(struct kmem_cache *s,
@@ -4504,6 +4492,13 @@ static int sysfs_slab_add(struct kmem_cache *s)
 
 static void sysfs_slab_remove(struct kmem_cache *s)
 {
+       if (slab_state < SYSFS)
+               /*
+                * Sysfs has not been setup yet so no need to remove the
+                * cache from sysfs.
+                */
+               return;
+
        kobject_uevent(&s->kobj, KOBJ_REMOVE);
        kobject_del(&s->kobj);
        kobject_put(&s->kobj);
@@ -4549,8 +4544,11 @@ static int __init slab_sysfs_init(void)
        struct kmem_cache *s;
        int err;
 
+       down_write(&slub_lock);
+
        slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj);
        if (!slab_kset) {
+               up_write(&slub_lock);
                printk(KERN_ERR "Cannot register slab subsystem.\n");
                return -ENOSYS;
        }
@@ -4575,6 +4573,7 @@ static int __init slab_sysfs_init(void)
                kfree(al);
        }
 
+       up_write(&slub_lock);
        resiliency_test();
        return 0;
 }
index ae007462b7f6e8c2463d83edc2d202107f996a32..b7e314b1009f62e8c723064fc28b4e7a1528e275 100644 (file)
@@ -2403,7 +2403,7 @@ static int s_show(struct seq_file *m, void *p)
                seq_printf(m, " pages=%d", v->nr_pages);
 
        if (v->phys_addr)
-               seq_printf(m, " phys=%lx", v->phys_addr);
+               seq_printf(m, " phys=%llx", (unsigned long long)v->phys_addr);
 
        if (v->flags & VM_IOREMAP)
                seq_printf(m, " ioremap");
index e4deb73e9a84971d46ac3dab9bd96cf8ffc8236f..a1a5cf95a68d73bd5179474e07b274f77eb5efaf 100644 (file)
@@ -115,7 +115,10 @@ endif
 # ---------------------------------------------------------------------------
 
 # Default is built-in, unless we know otherwise
-modkern_cflags = $(if $(part-of-module), $(CFLAGS_MODULE), $(CFLAGS_KERNEL))
+modkern_cflags =                                          \
+       $(if $(part-of-module),                           \
+               $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
+               $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
 quiet_modtag := $(empty)   $(empty)
 
 $(real-objs-m)        : part-of-module := y
@@ -156,14 +159,14 @@ $(obj)/%.i: $(src)/%.c FORCE
 
 cmd_gensymtypes =                                                           \
     $(CPP) -D__GENKSYMS__ $(c_flags) $< |                                   \
-    $(GENKSYMS) -T $@ -a $(ARCH)                                            \
+    $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH)                              \
      $(if $(KBUILD_PRESERVE),-p)                                            \
-     $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null)))
+     -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
 
 quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
 cmd_cc_symtypes_c =                                                         \
     set -e;                                                                 \
-    $(call cmd_gensymtypes, true) >/dev/null;                               \
+    $(call cmd_gensymtypes,true,$@) >/dev/null;                             \
     test -s $@ || rm -f $@
 
 $(obj)/%.symtypes : $(src)/%.c FORCE
@@ -192,16 +195,16 @@ else
 #   the actual value of the checksum generated by genksyms
 
 cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
-cmd_modversions =                                                      \
-       if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then     \
-               $(call cmd_gensymtypes, $(KBUILD_SYMTYPES))             \
-                   > $(@D)/.tmp_$(@F:.o=.ver);                         \
-                                                                       \
-               $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)              \
-                       -T $(@D)/.tmp_$(@F:.o=.ver);                    \
-               rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);        \
-       else                                                            \
-               mv -f $(@D)/.tmp_$(@F) $@;                              \
+cmd_modversions =                                                              \
+       if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then             \
+               $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))    \
+                   > $(@D)/.tmp_$(@F:.o=.ver);                                 \
+                                                                               \
+               $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)                      \
+                       -T $(@D)/.tmp_$(@F:.o=.ver);                            \
+               rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);                \
+       else                                                                    \
+               mv -f $(@D)/.tmp_$(@F) $@;                                      \
        fi;
 endif
 
@@ -248,10 +251,10 @@ $(obj)/%.lst: $(src)/%.c FORCE
 # Compile assembler sources (.S)
 # ---------------------------------------------------------------------------
 
-modkern_aflags := $(AFLAGS_KERNEL)
+modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
 
-$(real-objs-m)      : modkern_aflags := $(AFLAGS_MODULE)
-$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
+$(real-objs-m)      : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
+$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
 
 quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
 cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $< 
diff --git a/scripts/Makefile.help b/scripts/Makefile.help
new file mode 100644 (file)
index 0000000..d03608f
--- /dev/null
@@ -0,0 +1,3 @@
+
+checker-help:
+       @echo  '  coccicheck      - Check with Coccinelle.'
index 8f14c81abbc773507546d68e1d0a56c4e22be36b..7d22056582c11619013fbe38ea2c8c126dbab6d9 100644 (file)
@@ -30,7 +30,7 @@
 #     - See include/linux/module.h for more details
 
 # Step 4 is solely used to allow module versioning in external modules,
-# where the CRC of each module is retrieved from the Module.symers file.
+# where the CRC of each module is retrieved from the Module.symvers file.
 
 # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
 # symbols in the final module linking stage
@@ -107,7 +107,7 @@ $(modules:.ko=.mod.c): __modpost ;
 modname = $(notdir $(@:.mod.o=))
 
 quiet_cmd_cc_o_c = CC      $@
-      cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE)   \
+      cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \
                   -c -o $@ $<
 
 $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
@@ -117,8 +117,9 @@ targets += $(modules:.ko=.mod.o)
 
 # Step 6), final link of the modules
 quiet_cmd_ld_ko_o = LD [M]  $@
-      cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@                \
-                         $(filter-out FORCE,$^)
+      cmd_ld_ko_o = $(LD) -r $(LDFLAGS)                                 \
+                             $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
+                             -o $@ $(filter-out FORCE,$^)
 
 $(modules): %.ko :%.o %.mod.o FORCE
        $(call if_changed,ld_ko_o)
index 46be3c5a62b79d533668aeefd50905a6f5dbf383..2ca49bb31efc0b19995944260466d4601b403016 100755 (executable)
@@ -14,7 +14,7 @@ find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while
 do
        # Output the bare Kconfig variable and the filename; the _MODULE part at
        # the end is not removed here (would need perl an not-hungry regexp for that).
-       sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Z_]\+\).*!\2 '$i'!p' < $i
+       sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Za-z_]\+\).*!\2 '$i'!p' < $i
 done | \
 # Smart "sort|uniq" implemented in awk and tuned to collect the names of all
 # files which use a given symbol
diff --git a/scripts/coccicheck b/scripts/coccicheck
new file mode 100755 (executable)
index 0000000..b8bcf1f
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+SPATCH="`which ${SPATCH:=spatch}`"
+
+if [ "$C" = "1" -o "$C" = "2" ]; then
+    ONLINE=1
+
+# This requires Coccinelle >= 0.2.3
+#    FLAGS="-ignore_unknown_options -very_quiet"
+#    OPTIONS=$*
+
+# Workaround for Coccinelle < 0.2.3
+    FLAGS="-I $srctree/include -very_quiet"
+    shift $(( $# - 1 ))
+    OPTIONS=$1
+else
+    ONLINE=0
+    FLAGS="-very_quiet"
+fi
+
+if [ ! -x "$SPATCH" ]; then
+    echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
+    exit 1
+fi
+
+if [ "$MODE" = "" ] ; then
+    if [ "$ONLINE" = "0" ] ; then
+       echo 'You have not explicitly specify the mode to use. Fallback to "report".'
+       echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
+       echo 'Available modes are: report, patch, context, org'
+    fi
+    MODE="report"
+fi
+
+if [ "$ONLINE" = "0" ] ; then
+    echo ''
+    echo 'Please check for false positives in the output before submitting a patch.'
+    echo 'When using "patch" mode, carefully review the patch before submitting it.'
+    echo ''
+fi
+
+coccinelle () {
+    COCCI="$1"
+
+    OPT=`grep "Option" $COCCI | cut -d':' -f2`
+
+#   The option '-parse_cocci' can be used to syntaxically check the SmPL files.
+#
+#    $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
+
+    if [ "$ONLINE" = "0" ] ; then
+
+       FILE=`echo $COCCI | sed "s|$srctree/||"`
+
+       echo "Processing `basename $COCCI` with option(s) \"$OPT\""
+       echo 'Message example to submit a patch:'
+
+       sed -e '/\/\/\//!d' -e 's|^///||' $COCCI
+
+       echo ' The semantic patch that makes this change is available'
+       echo " in $FILE."
+       echo ''
+       echo ' More information about semantic patching is available at'
+       echo ' http://coccinelle.lip6.fr/'
+       echo ''
+
+       $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1
+    else
+       $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
+    fi
+
+}
+
+if [ "$COCCI" = "" ] ; then
+    for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
+       coccinelle $f
+    done
+else
+    coccinelle $COCCI
+fi
diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
new file mode 100644 (file)
index 0000000..7d4771d
--- /dev/null
@@ -0,0 +1,67 @@
+///
+/// Casting (void *) value returned by kmalloc is useless
+/// as mentioned in Documentation/CodingStyle, Chap 14.
+///
+// Confidence: High
+// Copyright: 2009,2010 Nicolas Palix, DIKU.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: -no_includes -include_headers
+//
+// Keywords: kmalloc, kzalloc, kcalloc
+// Version min: < 2.6.12 kmalloc
+// Version min: < 2.6.12 kcalloc
+// Version min:   2.6.14 kzalloc
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+@depends on context@
+type T;
+@@
+
+* (T *)
+  \(kmalloc\|kzalloc\|kcalloc\)(...)
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+type T;
+@@
+
+- (T *)
+  \(kmalloc\|kzalloc\|kcalloc\)(...)
+
+//----------------------------------------------------------
+//  For org and report mode
+//----------------------------------------------------------
+
+@r depends on org || report@
+type T;
+position p;
+@@
+
+ (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
+
+@script:python depends on org@
+p << r.p;
+t << r.T;
+@@
+
+coccilib.org.print_safe_todo(p[0], t)
+
+@script:python depends on report@
+p << r.p;
+t << r.T;
+@@
+
+msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/alloc/kzalloc-simple.cocci
new file mode 100644 (file)
index 0000000..2eae828
--- /dev/null
@@ -0,0 +1,82 @@
+///
+/// kzalloc should be used rather than kmalloc followed by memset 0
+///
+// Confidence: High
+// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
+// Options: -no_includes -include_headers
+//
+// Keywords: kmalloc, kzalloc
+// Version min: < 2.6.12 kmalloc
+// Version min:   2.6.14 kzalloc
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+@depends on context@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+@@
+
+* x = (T)kmalloc(E1,E2);
+  if ((x==NULL) || ...) S
+* memset((T2)x,0,E1);
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+@@
+
+- x = (T)kmalloc(E1,E2);
++ x = kzalloc(E1,E2);
+  if ((x==NULL) || ...) S
+- memset((T2)x,0,E1);
+
+//----------------------------------------------------------
+//  For org mode
+//----------------------------------------------------------
+
+@r depends on org || report@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+position p;
+@@
+
+ x = (T)kmalloc@p(E1,E2);
+ if ((x==NULL) || ...) S
+ memset((T2)x,0,E1);
+
+@script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="%s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/deref_null.cocci
new file mode 100644 (file)
index 0000000..9969d76
--- /dev/null
@@ -0,0 +1,293 @@
+///
+/// A variable is dereference under a NULL test.
+/// Even though it is know to be NULL.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: -I ... -all_includes can give more complete results
+// Options:
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+@initialize:python depends on !context && patch && !org && !report@
+
+import sys
+print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
+
+@depends on patch@
+@@
+
+this_rule_should_never_matches();
+
+@ifm depends on !patch@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...) S1 else S2
+
+// The following two rules are separate, because both can match a single
+// expression in different ways
+@pr1 depends on !patch expression@
+expression *ifm.E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
+
+@pr2 depends on !patch expression@
+expression *ifm.E;
+identifier f;
+position p2;
+@@
+
+(
+  (E != NULL) && ... && <+...E->f@p2...+>
+|
+  (E == NULL) || ... || <+...E->f@p2...+>
+|
+ sizeof(<+...E->f@p2...+>)
+)
+
+// For org and report modes
+
+@r depends on !context && !patch && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f@p // bad use
+)
+  ... when any
+  return ...;
+}
+else S3
+
+@script:python depends on !context && !patch && !org && report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+cocci.include_match(False)
+
+@script:python depends on !context && !patch && org && !report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+cocci.include_match(False)
+
+@s depends on !context && !patch && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f@p // bad use
+)
+  ... when any
+}
+else S3
+
+@script:python depends on !context && !patch && !org && report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+
+@script:python depends on !context && !patch && org && !report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+
+// For context mode
+
+@depends on context && !patch && !org && !report exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f@p // bad use
+)
+  ... when any
+  return ...;
+}
+else S3
+
+// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
+// It is need because the previous rule as already made a "change".
+
+@ifm1 depends on !patch@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...) S1 else S2
+
+@pr11 depends on !patch expression@
+expression *ifm1.E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
+
+@pr12 depends on !patch expression@
+expression *ifm1.E;
+identifier f;
+position p2;
+@@
+
+(
+  (E != NULL) && ... && <+...E->f@p2...+>
+|
+  (E == NULL) || ... || <+...E->f@p2...+>
+|
+ sizeof(<+...E->f@p2...+>)
+)
+
+@depends on context && !patch && !org && !report exists@
+expression subE <= ifm1.E;
+expression *ifm1.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr11.p1,pr12.p2};
+position ifm1.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f@p // bad use
+)
+  ... when any
+}
+else S3
diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/err_cast.cocci
new file mode 100644 (file)
index 0000000..2ce1150
--- /dev/null
@@ -0,0 +1,56 @@
+///
+/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
+///
+// Confidence: High
+// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2009, 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options:
+//
+// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
+// Version min: 2.6.25
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+
+@ depends on context && !patch && !org && !report@
+expression x;
+@@
+
+* ERR_PTR(PTR_ERR(x))
+
+@ depends on !context && patch && !org && !report @
+expression x;
+@@
+
+- ERR_PTR(PTR_ERR(x))
++ ERR_CAST(x)
+
+@r depends on !context && !patch && (org || report)@
+expression x;
+position p;
+@@
+
+ ERR_PTR@p(PTR_ERR(x))
+
+@script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING ERR_CAST can be used with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING: ERR_CAST can be used with %s" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/resource_size.cocci
new file mode 100644 (file)
index 0000000..1935a58
--- /dev/null
@@ -0,0 +1,93 @@
+///
+/// Use resource_size function on resource object
+/// instead of explicit computation.
+///
+//  Confidence: High
+//  Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.  GPLv2.
+//  Copyright: (C) 2009, 2010 Julia Lawall, DIKU.  GPLv2.
+//  Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+//  URL: http://coccinelle.lip6.fr/
+//  Options:
+//
+//  Keywords: resource_size
+//  Version min: 2.6.27 resource_size
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+@r_context depends on context && !patch && !org@
+struct resource *res;
+@@
+
+* (res->end - res->start) + 1
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+@r_patch depends on !context && patch && !org@
+struct resource *res;
+@@
+
+- (res->end - res->start) + 1
++ resource_size(res)
+
+//----------------------------------------------------------
+//  For org mode
+//----------------------------------------------------------
+
+
+@r_org depends on !context && !patch && (org || report)@
+struct resource *res;
+position p;
+@@
+
+ (res->end@p - res->start) + 1
+
+@rbad_org depends on !context && !patch && (org || report)@
+struct resource *res;
+position p != r_org.p;
+@@
+
+ res->end@p - res->start
+
+@script:python depends on org@
+p << r_org.p;
+x << r_org.res;
+@@
+
+msg="ERROR with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << r_org.p;
+x << r_org.res;
+@@
+
+msg="ERROR: Missing resource_size with %s" % (x)
+coccilib.report.print_report(p[0], msg)
+
+@script:python depends on org@
+p << rbad_org.p;
+x << rbad_org.res;
+@@
+
+msg="WARNING with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << rbad_org.p;
+x << rbad_org.res;
+@@
+
+msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
+coccilib.report.print_report(p[0], msg)
index 8b30cc36744f8c2c1d5c24fcaebc9d2cfbd1889e..18ba881c34159a8bcdc3b8b582bd3f0617f90e8a 100755 (executable)
@@ -40,7 +40,7 @@ echo $code
 code=`echo $code | sed -e 's/.*Code: //'`
 
 width=`expr index "$code" ' '`
-width=$[($width-1)/2]
+width=$((($width-1)/2))
 case $width in
 1) type=byte ;;
 2) type=2byte ;;
@@ -48,10 +48,10 @@ case $width in
 esac
 
 disas() {
-       ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
+       ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
 
-       if [ "$ARCH" == "arm" ]; then
-               if [ $width == 2 ]; then
+       if [ "$ARCH" = "arm" ]; then
+               if [ $width -eq 2 ]; then
                        OBJDUMPFLAGS="-M force-thumb"
                fi
 
@@ -59,7 +59,7 @@ disas() {
        fi
 
        ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
-               grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
+               grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
 }
 
 marker=`expr index "$code" "\<"`
index 766b2694d93589fe39ea6313dbae7b1ce5a21daa..8fe1bdf239f0f7a4d1e40baadf9cd8430c5176aa 100644 (file)
@@ -77,6 +77,7 @@ static struct node *read_fstree(const char *dirname)
                free(tmpnam);
        }
 
+       closedir(d);
        return tree;
 }
 
index 6a36a76e6606437f3369aeb3345592aa309a547b..624f6502e03e704b7be881817924cddbbdb708f1 100644 (file)
@@ -17,6 +17,7 @@ gconf.glade.h
 #
 conf
 mconf
+nconf
 qconf
 gconf
 kxgettext
index 7ea649da19400252ba751bfdb8bea5e7a5dba426..de934def410f0d2563a41105b8e02400b7f4cb44 100644 (file)
@@ -21,17 +21,17 @@ menuconfig: $(obj)/mconf
        $< $(Kconfig)
 
 config: $(obj)/conf
-       $< $(Kconfig)
+       $< --oldaskconfig $(Kconfig)
 
 nconfig: $(obj)/nconf
        $< $(Kconfig)
 
 oldconfig: $(obj)/conf
-       $< -o $(Kconfig)
+       $< --$@ $(Kconfig)
 
 silentoldconfig: $(obj)/conf
        $(Q)mkdir -p include/generated
-       $< -s $(Kconfig)
+       $< --$@ $(Kconfig)
 
 # if no path is given, then use src directory to find file
 ifdef LSMOD
@@ -44,15 +44,15 @@ endif
 localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
        $(Q)mkdir -p include/generated
        $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
-       $(Q)if [ -f .config ]; then                             \
-                       cmp -s .tmp.config .config ||           \
-                       (mv -f .config .config.old.1;           \
-                        mv -f .tmp.config .config;             \
-                        $(obj)/conf -s $(Kconfig);             \
-                        mv -f .config.old.1 .config.old)       \
-       else                                                    \
-                       mv -f .tmp.config .config;              \
-                       $(obj)/conf -s $(Kconfig);              \
+       $(Q)if [ -f .config ]; then                                     \
+                       cmp -s .tmp.config .config ||                   \
+                       (mv -f .config .config.old.1;                   \
+                        mv -f .tmp.config .config;                     \
+                        $(obj)/conf --silentoldconfig $(Kconfig);      \
+                        mv -f .config.old.1 .config.old)               \
+       else                                                            \
+                       mv -f .tmp.config .config;                      \
+                       $(obj)/conf --silentoldconfig $(Kconfig);       \
        fi
        $(Q)rm -f .tmp.config
 
@@ -60,15 +60,15 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
        $(Q)mkdir -p include/generated
        $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
        $(Q)sed -i s/=m/=y/ .tmp.config
-       $(Q)if [ -f .config ]; then                             \
-                       cmp -s .tmp.config .config ||           \
-                       (mv -f .config .config.old.1;           \
-                        mv -f .tmp.config .config;             \
-                        $(obj)/conf -s $(Kconfig);             \
-                        mv -f .config.old.1 .config.old)       \
-       else                                                    \
-                       mv -f .tmp.config .config;              \
-                       $(obj)/conf -s $(Kconfig);              \
+       $(Q)if [ -f .config ]; then                                     \
+                       cmp -s .tmp.config .config ||                   \
+                       (mv -f .config .config.old.1;                   \
+                        mv -f .tmp.config .config;                     \
+                        $(obj)/conf --silentoldconfig $(Kconfig);      \
+                        mv -f .config.old.1 .config.old)               \
+       else                                                            \
+                       mv -f .tmp.config .config;                      \
+                       $(obj)/conf --silentoldconfig $(Kconfig);       \
        fi
        $(Q)rm -f .tmp.config
 
@@ -95,30 +95,29 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
        $(Q)rm -f arch/um/Kconfig.arch
        $(Q)rm -f $(obj)/config.pot
 
-PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
+PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
 
-randconfig: $(obj)/conf
-       $< -r $(Kconfig)
+allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
+       $< --$@ $(Kconfig)
 
-allyesconfig: $(obj)/conf
-       $< -y $(Kconfig)
+PHONY += listnewconfig oldnoconfig savedefconfig defconfig
 
-allnoconfig: $(obj)/conf
-       $< -n $(Kconfig)
+listnewconfig oldnoconfig: $(obj)/conf
+       $< --$@ $(Kconfig)
 
-allmodconfig: $(obj)/conf
-       $< -m $(Kconfig)
+savedefconfig: $(obj)/conf
+       $< --$@=defconfig $(Kconfig)
 
 defconfig: $(obj)/conf
 ifeq ($(KBUILD_DEFCONFIG),)
-       $< -d $(Kconfig)
+       $< --defconfig $(Kconfig)
 else
        @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
-       $(Q)$< -arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
+       $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
 endif
 
 %_defconfig: $(obj)/conf
-       $(Q)$< -arch/$(SRCARCH)/configs/$@ $(Kconfig)
+       $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
 
 # Help text used by make help
 help:
@@ -131,11 +130,15 @@ help:
        @echo  '  localmodconfig  - Update current config disabling modules not loaded'
        @echo  '  localyesconfig  - Update current config converting local mods to core'
        @echo  '  silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
-       @echo  '  randconfig      - New config with random answer to all options'
-       @echo  '  defconfig       - New config with default answer to all options'
-       @echo  '  allmodconfig    - New config selecting modules when possible'
-       @echo  '  allyesconfig    - New config where all options are accepted with yes'
+       @echo  '  defconfig       - New config with default from ARCH supplied defconfig'
+       @echo  '  savedefconfig   - Save current config as ./defconfig (minimal config)'
        @echo  '  allnoconfig     - New config where all options are answered with no'
+       @echo  '  allyesconfig    - New config where all options are accepted with yes'
+       @echo  '  allmodconfig    - New config selecting modules when possible'
+       @echo  '  alldefconfig    - New config with all symbols set to default'
+       @echo  '  randconfig      - New config with random answer to all options'
+       @echo  '  listnewconfig   - List new options'
+       @echo  '  oldnoconfig     - Same as silentoldconfig but set new symbols to n (unset)'
 
 # lxdialog stuff
 check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
index 9960d1c303f8c2f985a1a92de8e990850c33ccf6..274f2716b03e9d4b0a5865a86a09b11799359523 100644 (file)
@@ -10,6 +10,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <getopt.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 
 static void conf(struct menu *menu);
 static void check_conf(struct menu *menu);
 
-enum {
-       ask_all,
-       ask_new,
-       ask_silent,
-       set_default,
-       set_yes,
-       set_mod,
-       set_no,
-       set_random
-} input_mode = ask_all;
+enum input_mode {
+       oldaskconfig,
+       silentoldconfig,
+       oldconfig,
+       allnoconfig,
+       allyesconfig,
+       allmodconfig,
+       alldefconfig,
+       randconfig,
+       defconfig,
+       savedefconfig,
+       listnewconfig,
+       oldnoconfig,
+} input_mode = oldaskconfig;
+
 char *defconfig_file;
 
 static int indent = 1;
@@ -93,14 +99,14 @@ static int conf_askvalue(struct symbol *sym, const char *def)
        }
 
        switch (input_mode) {
-       case ask_new:
-       case ask_silent:
+       case oldconfig:
+       case silentoldconfig:
                if (sym_has_value(sym)) {
                        printf("%s\n", def);
                        return 0;
                }
                check_stdin();
-       case ask_all:
+       case oldaskconfig:
                fflush(stdout);
                fgets(line, 128, stdin);
                return 1;
@@ -156,14 +162,12 @@ static int conf_string(struct menu *menu)
 static int conf_sym(struct menu *menu)
 {
        struct symbol *sym = menu->sym;
-       int type;
        tristate oldval, newval;
 
        while (1) {
                printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
                if (sym->name)
                        printf("(%s) ", sym->name);
-               type = sym_get_type(sym);
                putchar('[');
                oldval = sym_get_tristate_value(sym);
                switch (oldval) {
@@ -228,11 +232,9 @@ static int conf_choice(struct menu *menu)
 {
        struct symbol *sym, *def_sym;
        struct menu *child;
-       int type;
        bool is_new;
 
        sym = menu->sym;
-       type = sym_get_type(sym);
        is_new = !sym_has_value(sym);
        if (sym_is_changable(sym)) {
                conf_sym(menu);
@@ -294,15 +296,15 @@ static int conf_choice(struct menu *menu)
                        printf("?");
                printf("]: ");
                switch (input_mode) {
-               case ask_new:
-               case ask_silent:
+               case oldconfig:
+               case silentoldconfig:
                        if (!is_new) {
                                cnt = def;
                                printf("%d\n", cnt);
                                break;
                        }
                        check_stdin();
-               case ask_all:
+               case oldaskconfig:
                        fflush(stdout);
                        fgets(line, 128, stdin);
                        strip(line);
@@ -360,7 +362,10 @@ static void conf(struct menu *menu)
 
                switch (prop->type) {
                case P_MENU:
-                       if (input_mode == ask_silent && rootEntry != menu) {
+                       if ((input_mode == silentoldconfig ||
+                            input_mode == listnewconfig ||
+                            input_mode == oldnoconfig) &&
+                           rootEntry != menu) {
                                check_conf(menu);
                                return;
                        }
@@ -418,10 +423,16 @@ static void check_conf(struct menu *menu)
        if (sym && !sym_has_value(sym)) {
                if (sym_is_changable(sym) ||
                    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
-                       if (!conf_cnt++)
-                               printf(_("*\n* Restart config...\n*\n"));
-                       rootEntry = menu_get_parent_menu(menu);
-                       conf(rootEntry);
+                       if (input_mode == listnewconfig) {
+                               if (sym->name && !sym_is_choice_value(sym)) {
+                                       printf("CONFIG_%s\n", sym->name);
+                               }
+                       } else {
+                               if (!conf_cnt++)
+                                       printf(_("*\n* Restart config...\n*\n"));
+                               rootEntry = menu_get_parent_menu(menu);
+                               conf(rootEntry);
+                       }
                }
        }
 
@@ -429,6 +440,22 @@ static void check_conf(struct menu *menu)
                check_conf(child);
 }
 
+static struct option long_opts[] = {
+       {"oldaskconfig",    no_argument,       NULL, oldaskconfig},
+       {"oldconfig",       no_argument,       NULL, oldconfig},
+       {"silentoldconfig", no_argument,       NULL, silentoldconfig},
+       {"defconfig",       optional_argument, NULL, defconfig},
+       {"savedefconfig",   required_argument, NULL, savedefconfig},
+       {"allnoconfig",     no_argument,       NULL, allnoconfig},
+       {"allyesconfig",    no_argument,       NULL, allyesconfig},
+       {"allmodconfig",    no_argument,       NULL, allmodconfig},
+       {"alldefconfig",    no_argument,       NULL, alldefconfig},
+       {"randconfig",      no_argument,       NULL, randconfig},
+       {"listnewconfig",   no_argument,       NULL, listnewconfig},
+       {"oldnoconfig",     no_argument,       NULL, oldnoconfig},
+       {NULL, 0, NULL, 0}
+};
+
 int main(int ac, char **av)
 {
        int opt;
@@ -439,32 +466,17 @@ int main(int ac, char **av)
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
 
-       while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
+       while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) {
+               input_mode = (enum input_mode)opt;
                switch (opt) {
-               case 'o':
-                       input_mode = ask_silent;
-                       break;
-               case 's':
-                       input_mode = ask_silent;
+               case silentoldconfig:
                        sync_kconfig = 1;
                        break;
-               case 'd':
-                       input_mode = set_default;
-                       break;
-               case 'D':
-                       input_mode = set_default;
+               case defconfig:
+               case savedefconfig:
                        defconfig_file = optarg;
                        break;
-               case 'n':
-                       input_mode = set_no;
-                       break;
-               case 'm':
-                       input_mode = set_mod;
-                       break;
-               case 'y':
-                       input_mode = set_yes;
-                       break;
-               case 'r':
+               case randconfig:
                {
                        struct timeval now;
                        unsigned int seed;
@@ -477,17 +489,12 @@ int main(int ac, char **av)
 
                        seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
                        srand(seed);
-
-                       input_mode = set_random;
                        break;
                }
-               case 'h':
-                       printf(_("See README for usage info\n"));
-                       exit(0);
-                       break;
-               default:
+               case '?':
                        fprintf(stderr, _("See README for usage info\n"));
                        exit(1);
+                       break;
                }
        }
        if (ac == optind) {
@@ -512,7 +519,7 @@ int main(int ac, char **av)
        }
 
        switch (input_mode) {
-       case set_default:
+       case defconfig:
                if (!defconfig_file)
                        defconfig_file = conf_get_default_confname();
                if (conf_read(defconfig_file)) {
@@ -522,25 +529,32 @@ int main(int ac, char **av)
                        exit(1);
                }
                break;
-       case ask_silent:
-       case ask_all:
-       case ask_new:
+       case savedefconfig:
+               conf_read(NULL);
+               break;
+       case silentoldconfig:
+       case oldaskconfig:
+       case oldconfig:
+       case listnewconfig:
+       case oldnoconfig:
                conf_read(NULL);
                break;
-       case set_no:
-       case set_mod:
-       case set_yes:
-       case set_random:
+       case allnoconfig:
+       case allyesconfig:
+       case allmodconfig:
+       case alldefconfig:
+       case randconfig:
                name = getenv("KCONFIG_ALLCONFIG");
                if (name && !stat(name, &tmpstat)) {
                        conf_read_simple(name, S_DEF_USER);
                        break;
                }
                switch (input_mode) {
-               case set_no:     name = "allno.config"; break;
-               case set_mod:    name = "allmod.config"; break;
-               case set_yes:    name = "allyes.config"; break;
-               case set_random: name = "allrandom.config"; break;
+               case allnoconfig:       name = "allno.config"; break;
+               case allyesconfig:      name = "allyes.config"; break;
+               case allmodconfig:      name = "allmod.config"; break;
+               case alldefconfig:      name = "alldef.config"; break;
+               case randconfig:        name = "allrandom.config"; break;
                default: break;
                }
                if (!stat(name, &tmpstat))
@@ -565,33 +579,42 @@ int main(int ac, char **av)
        }
 
        switch (input_mode) {
-       case set_no:
+       case allnoconfig:
                conf_set_all_new_symbols(def_no);
                break;
-       case set_yes:
+       case allyesconfig:
                conf_set_all_new_symbols(def_yes);
                break;
-       case set_mod:
+       case allmodconfig:
                conf_set_all_new_symbols(def_mod);
                break;
-       case set_random:
+       case alldefconfig:
+               conf_set_all_new_symbols(def_default);
+               break;
+       case randconfig:
                conf_set_all_new_symbols(def_random);
                break;
-       case set_default:
+       case defconfig:
                conf_set_all_new_symbols(def_default);
                break;
-       case ask_new:
-       case ask_all:
+       case savedefconfig:
+               break;
+       case oldaskconfig:
                rootEntry = &rootmenu;
                conf(&rootmenu);
-               input_mode = ask_silent;
+               input_mode = silentoldconfig;
                /* fall through */
-       case ask_silent:
+       case oldconfig:
+       case listnewconfig:
+       case oldnoconfig:
+       case silentoldconfig:
                /* Update until a loop caused no more changes */
                do {
                        conf_cnt = 0;
                        check_conf(&rootmenu);
-               } while (conf_cnt);
+               } while (conf_cnt &&
+                        (input_mode != listnewconfig &&
+                         input_mode != oldnoconfig));
                break;
        }
 
@@ -607,7 +630,13 @@ int main(int ac, char **av)
                        fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
                        return 1;
                }
-       } else {
+       } else if (input_mode == savedefconfig) {
+               if (conf_write_defconfig(defconfig_file)) {
+                       fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
+                               defconfig_file);
+                       return 1;
+               }
+       } else if (input_mode != listnewconfig) {
                if (conf_write(NULL)) {
                        fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
                        exit(1);
index c4dec80cfd8e14a94792af807da0e9705256257d..f81f263b64f27ee166d56020b6ecce7043523811 100644 (file)
@@ -170,8 +170,11 @@ int conf_read_simple(const char *name, int def)
                if (in)
                        goto load;
                sym_add_change_count(1);
-               if (!sym_defconfig_list)
+               if (!sym_defconfig_list) {
+                       if (modules_sym)
+                               sym_calc_value(modules_sym);
                        return 1;
+               }
 
                for_all_defaults(sym_defconfig_list, prop) {
                        if (expr_calc_value(prop->visible.expr) == no ||
@@ -396,15 +399,149 @@ int conf_read(const char *name)
        return 0;
 }
 
+/* Write a S_STRING */
+static void conf_write_string(bool headerfile, const char *name,
+                              const char *str, FILE *out)
+{
+       int l;
+       if (headerfile)
+               fprintf(out, "#define CONFIG_%s \"", name);
+       else
+               fprintf(out, "CONFIG_%s=\"", name);
+
+       while (1) {
+               l = strcspn(str, "\"\\");
+               if (l) {
+                       fwrite(str, l, 1, out);
+                       str += l;
+               }
+               if (!*str)
+                       break;
+               fprintf(out, "\\%c", *str++);
+       }
+       fputs("\"\n", out);
+}
+
+static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
+                              FILE *out, bool write_no)
+{
+       const char *str;
+
+       switch (type) {
+       case S_BOOLEAN:
+       case S_TRISTATE:
+               switch (sym_get_tristate_value(sym)) {
+               case no:
+                       if (write_no)
+                               fprintf(out, "# CONFIG_%s is not set\n", sym->name);
+                       break;
+               case mod:
+                       fprintf(out, "CONFIG_%s=m\n", sym->name);
+                       break;
+               case yes:
+                       fprintf(out, "CONFIG_%s=y\n", sym->name);
+                       break;
+               }
+               break;
+       case S_STRING:
+               conf_write_string(false, sym->name, sym_get_string_value(sym), out);
+               break;
+       case S_HEX:
+       case S_INT:
+               str = sym_get_string_value(sym);
+               fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+               break;
+       case S_OTHER:
+       case S_UNKNOWN:
+               break;
+       }
+}
+
+/*
+ * Write out a minimal config.
+ * All values that has default values are skipped as this is redundant.
+ */
+int conf_write_defconfig(const char *filename)
+{
+       struct symbol *sym;
+       struct menu *menu;
+       FILE *out;
+
+       out = fopen(filename, "w");
+       if (!out)
+               return 1;
+
+       sym_clear_all_valid();
+
+       /* Traverse all menus to find all relevant symbols */
+       menu = rootmenu.list;
+
+       while (menu != NULL)
+       {
+               sym = menu->sym;
+               if (sym == NULL) {
+                       if (!menu_is_visible(menu))
+                               goto next_menu;
+               } else if (!sym_is_choice(sym)) {
+                       sym_calc_value(sym);
+                       if (!(sym->flags & SYMBOL_WRITE))
+                               goto next_menu;
+                       sym->flags &= ~SYMBOL_WRITE;
+                       /* If we cannot change the symbol - skip */
+                       if (!sym_is_changable(sym))
+                               goto next_menu;
+                       /* If symbol equals to default value - skip */
+                       if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
+                               goto next_menu;
+
+                       /*
+                        * If symbol is a choice value and equals to the
+                        * default for a choice - skip.
+                        * But only if value equal to "y".
+                        */
+                       if (sym_is_choice_value(sym)) {
+                               struct symbol *cs;
+                               struct symbol *ds;
+
+                               cs = prop_get_symbol(sym_get_choice_prop(sym));
+                               ds = sym_choice_default(cs);
+                               if (sym == ds) {
+                                       if ((sym->type == S_BOOLEAN ||
+                                       sym->type == S_TRISTATE) &&
+                                       sym_get_tristate_value(sym) == yes)
+                                               goto next_menu;
+                               }
+                       }
+                       conf_write_symbol(sym, sym->type, out, true);
+               }
+next_menu:
+               if (menu->list != NULL) {
+                       menu = menu->list;
+               }
+               else if (menu->next != NULL) {
+                       menu = menu->next;
+               } else {
+                       while ((menu = menu->parent)) {
+                               if (menu->next != NULL) {
+                                       menu = menu->next;
+                                       break;
+                               }
+                       }
+               }
+       }
+       fclose(out);
+       return 0;
+}
+
 int conf_write(const char *name)
 {
        FILE *out;
        struct symbol *sym;
        struct menu *menu;
        const char *basename;
-       char dirname[128], tmpname[128], newname[128];
-       int type, l;
        const char *str;
+       char dirname[128], tmpname[128], newname[128];
+       enum symbol_type type;
        time_t now;
        int use_timestamp = 1;
        char *env;
@@ -484,50 +621,11 @@ int conf_write(const char *name)
                                if (modules_sym->curr.tri == no)
                                        type = S_BOOLEAN;
                        }
-                       switch (type) {
-                       case S_BOOLEAN:
-                       case S_TRISTATE:
-                               switch (sym_get_tristate_value(sym)) {
-                               case no:
-                                       fprintf(out, "# CONFIG_%s is not set\n", sym->name);
-                                       break;
-                               case mod:
-                                       fprintf(out, "CONFIG_%s=m\n", sym->name);
-                                       break;
-                               case yes:
-                                       fprintf(out, "CONFIG_%s=y\n", sym->name);
-                                       break;
-                               }
-                               break;
-                       case S_STRING:
-                               str = sym_get_string_value(sym);
-                               fprintf(out, "CONFIG_%s=\"", sym->name);
-                               while (1) {
-                                       l = strcspn(str, "\"\\");
-                                       if (l) {
-                                               fwrite(str, l, 1, out);
-                                               str += l;
-                                       }
-                                       if (!*str)
-                                               break;
-                                       fprintf(out, "\\%c", *str++);
-                               }
-                               fputs("\"\n", out);
-                               break;
-                       case S_HEX:
-                               str = sym_get_string_value(sym);
-                               if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
-                                       fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
-                                       break;
-                               }
-                       case S_INT:
-                               str = sym_get_string_value(sym);
-                               fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
-                               break;
-                       }
+                       /* Write config symbol to file */
+                       conf_write_symbol(sym, type, out, true);
                }
 
-       next:
+next:
                if (menu->list) {
                        menu = menu->list;
                        continue;
@@ -679,7 +777,7 @@ int conf_write_autoconf(void)
        const char *name;
        FILE *out, *tristate, *out_h;
        time_t now;
-       int i, l;
+       int i;
 
        sym_clear_all_valid();
 
@@ -729,6 +827,11 @@ int conf_write_autoconf(void)
                sym_calc_value(sym);
                if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
                        continue;
+
+               /* write symbol to config file */
+               conf_write_symbol(sym, sym->type, out, false);
+
+               /* update autoconf and tristate files */
                switch (sym->type) {
                case S_BOOLEAN:
                case S_TRISTATE:
@@ -736,12 +839,10 @@ int conf_write_autoconf(void)
                        case no:
                                break;
                        case mod:
-                               fprintf(out, "CONFIG_%s=m\n", sym->name);
                                fprintf(tristate, "CONFIG_%s=M\n", sym->name);
                                fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
                                break;
                        case yes:
-                               fprintf(out, "CONFIG_%s=y\n", sym->name);
                                if (sym->type == S_TRISTATE)
                                        fprintf(tristate, "CONFIG_%s=Y\n",
                                                        sym->name);
@@ -750,35 +851,16 @@ int conf_write_autoconf(void)
                        }
                        break;
                case S_STRING:
-                       str = sym_get_string_value(sym);
-                       fprintf(out, "CONFIG_%s=\"", sym->name);
-                       fprintf(out_h, "#define CONFIG_%s \"", sym->name);
-                       while (1) {
-                               l = strcspn(str, "\"\\");
-                               if (l) {
-                                       fwrite(str, l, 1, out);
-                                       fwrite(str, l, 1, out_h);
-                                       str += l;
-                               }
-                               if (!*str)
-                                       break;
-                               fprintf(out, "\\%c", *str);
-                               fprintf(out_h, "\\%c", *str);
-                               str++;
-                       }
-                       fputs("\"\n", out);
-                       fputs("\"\n", out_h);
+                       conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
                        break;
                case S_HEX:
                        str = sym_get_string_value(sym);
                        if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
-                               fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
                                fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
                                break;
                        }
                case S_INT:
                        str = sym_get_string_value(sym);
-                       fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
                        fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
                        break;
                default:
@@ -862,7 +944,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
                                sym->def[S_DEF_USER].tri = no;
                                break;
                        case def_random:
-                               sym->def[S_DEF_USER].tri = (tristate)(rand() % 3);
+                               cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
+                               sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
                                break;
                        default:
                                continue;
index d83f2322893a8adb10f027e2c4fa4757a33e26f0..8f18e37892cb42152ddda716edb6ae4f5592e7ac 100644 (file)
@@ -1121,7 +1121,7 @@ static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *s
        }
 
        str_append(gs, str);
-       if (sym)
+       if (sym && sym->type != S_UNKNOWN)
                str_printf(gs, " [=%s]", sym_str);
 }
 
index 891cd9ce9ba21b915d0b0aa993fc2d0c8d2fb10c..6ee2e4fb148146ace18b2e5a7414e6a89d5d3e2f 100644 (file)
@@ -83,6 +83,7 @@ struct symbol {
        tristate visible;
        int flags;
        struct property *prop;
+       struct expr_value dir_dep;
        struct expr_value rev_dep;
 };
 
@@ -131,6 +132,7 @@ enum prop_type {
        P_SELECT,   /* select BAR */
        P_RANGE,    /* range 7..100 (for a symbol) */
        P_ENV,      /* value from environment variable */
+       P_SYMBOL,   /* where a symbol is defined */
 };
 
 struct property {
@@ -163,6 +165,7 @@ struct menu {
        struct symbol *sym;
        struct property *prompt;
        struct expr *dep;
+       struct expr *dir_dep;
        unsigned int flags;
        char *help;
        struct file *file;
index bef10411837fb758bdf564818aa2c23888ad8958..d66988265f899b47a1dbf75767eb3330ec556d26 100644 (file)
@@ -1114,7 +1114,7 @@ static gchar **fill_row(struct menu *menu)
 
        row[COL_OPTION] =
            g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
-                           sym && sym_has_value(sym) ? "(NEW)" : "");
+                           sym && !sym_has_value(sym) ? "(NEW)" : "");
 
        if (opt_mode == OPT_ALL && !menu_is_visible(menu))
                row[COL_COLOR] = g_strdup("DarkGray");
@@ -1343,7 +1343,8 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
 #endif
 
                if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
-                   (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) {
+                   (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
+                   (opt_mode == OPT_ALL    && !menu_get_prompt(child1))) {
 
                        /* remove node */
                        if (gtktree_iter_find_node(dst, menu1) != NULL) {
@@ -1425,7 +1426,7 @@ static void display_tree(struct menu *menu)
 
                if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
                    (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
-                   (opt_mode == OPT_ALL))
+                   (opt_mode == OPT_ALL    && menu_get_prompt(child)))
                        place_node(child, fill_row(child));
 #ifdef DEBUG
                printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
index ce6549cdaccf4b79443d1e06267502f68e769d89..76db065ed72c069aa4371d875bdcfe71c96a9316 100644 (file)
@@ -126,6 +126,8 @@ void sym_init(void);
 void sym_clear_all_valid(void);
 void sym_set_all_changed(void);
 void sym_set_changed(struct symbol *sym);
+struct symbol *sym_choice_default(struct symbol *sym);
+const char *sym_get_string_default(struct symbol *sym);
 struct symbol *sym_check_deps(struct symbol *sym);
 struct property *prop_alloc(enum prop_type type, struct symbol *sym);
 struct symbol *prop_get_symbol(struct property *prop);
index 7cadcad8233bb37cd8c2e40ccae7d999a1284a63..9a948c9ce44edd4732d6beb579266b23b9049cb0 100644 (file)
@@ -3,6 +3,7 @@
 P(conf_parse,void,(const char *name));
 P(conf_read,int,(const char *name));
 P(conf_read_simple,int,(const char *name, int));
+P(conf_write_defconfig,int,(const char *name));
 P(conf_write,int,(const char *name));
 P(conf_write_autoconf,int,(void));
 P(conf_get_changed,bool,(void));
index bcc6f19c3a35f8dedc9809ffefb5e77b1d16493a..a2eb80fbc896fe28b2b0f8efc614cf83fcbfc7b8 100644 (file)
@@ -31,6 +31,10 @@ static int list_width, check_x, item_x;
 static void print_item(WINDOW * win, int choice, int selected)
 {
        int i;
+       char *list_item = malloc(list_width + 1);
+
+       strncpy(list_item, item_str(), list_width - item_x);
+       list_item[list_width - item_x] = '\0';
 
        /* Clear 'residue' of last item */
        wattrset(win, dlg.menubox.atr);
@@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected)
                wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
 
        wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
-       mvwaddch(win, choice, item_x, item_str()[0]);
+       mvwaddch(win, choice, item_x, list_item[0]);
        wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
-       waddstr(win, (char *)item_str() + 1);
+       waddstr(win, list_item + 1);
        if (selected) {
                wmove(win, choice, check_x + 1);
                wrefresh(win);
        }
+       free(list_item);
 }
 
 /*
@@ -175,6 +180,7 @@ do_resize:
        check_x = 0;
        item_foreach()
                check_x = MAX(check_x, strlen(item_str()) + 4);
+       check_x = MIN(check_x, list_width);
 
        check_x = (list_width - check_x) / 2;
        item_x = check_x + 4;
index 2c83d3234d304dc0c3d25fac44b1af59c1a631fb..d2f6e056c058151cfb91ae2ab9ce2d0bea8b879d 100644 (file)
@@ -74,7 +74,7 @@ static const char mconf_readme[] = N_(
 "\n"
 "   Shortcut: Press <H> or <?>.\n"
 "\n"
-"o  To show hidden options, press <Z>.\n"
+"o  To toggle the display of hidden options, press <Z>.\n"
 "\n"
 "\n"
 "Radiolists  (Choice lists)\n"
index 203632cc30bdbe12ad0644c3aff15ed07a4e7c0d..4fb590247f330bb75215fe88eb749d42da8b489e 100644 (file)
@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym)
        *last_entry_ptr = menu;
        last_entry_ptr = &menu->next;
        current_entry = menu;
+       if (sym)
+               menu_add_symbol(P_SYMBOL, sym, NULL);
 }
 
 void menu_end_entry(void)
@@ -105,6 +107,7 @@ static struct expr *menu_check_dep(struct expr *e)
 void menu_add_dep(struct expr *dep)
 {
        current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
+       current_entry->dir_dep = current_entry->dep;
 }
 
 void menu_set_type(int type)
@@ -288,6 +291,10 @@ void menu_finalize(struct menu *parent)
                for (menu = parent->list; menu; menu = menu->next)
                        menu_finalize(menu);
        } else if (sym) {
+               /* ignore inherited dependencies for dir_dep */
+               sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
+               sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
+
                basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
                basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
                basedep = expr_eliminate_dups(expr_transform(basedep));
@@ -419,9 +426,13 @@ bool menu_is_visible(struct menu *menu)
        if (!sym || sym_get_tristate_value(menu->sym) == no)
                return false;
 
-       for (child = menu->list; child; child = child->next)
-               if (menu_is_visible(child))
+       for (child = menu->list; child; child = child->next) {
+               if (menu_is_visible(child)) {
+                       if (sym)
+                               sym->flags |= SYMBOL_DEF_USER;
                        return true;
+               }
+       }
 
        return false;
 }
@@ -501,9 +512,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
        bool hit;
        struct property *prop;
 
-       if (sym && sym->name)
+       if (sym && sym->name) {
                str_printf(r, "Symbol: %s [=%s]\n", sym->name,
                           sym_get_string_value(sym));
+               str_printf(r, "Type  : %s\n", sym_type_name(sym->type));
+               if (sym->type == S_INT || sym->type == S_HEX) {
+                       prop = sym_get_range_prop(sym);
+                       if (prop) {
+                               str_printf(r, "Range : ");
+                               expr_gstr_print(prop->expr, r);
+                               str_append(r, "\n");
+                       }
+               }
+       }
        for_all_prompts(sym, prop)
                get_prompt_str(r, prop);
        hit = false;
index 00c51507cfcc44acfe434fc35e08827c14ff7f0d..820df2d1217b7b8fd2d64640cfb848d97a9db9bc 100644 (file)
@@ -58,11 +58,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
 {
        QValueList<int> result;
        QStringList entryList = readListEntry(key, ok);
-       if (ok) {
-               QStringList::Iterator it;
-               for (it = entryList.begin(); it != entryList.end(); ++it)
-                       result.push_back((*it).toInt());
-       }
+       QStringList::Iterator it;
+
+       for (it = entryList.begin(); it != entryList.end(); ++it)
+               result.push_back((*it).toInt());
 
        return result;
 }
@@ -149,7 +148,7 @@ void ConfigItem::updateMenu(void)
        case S_TRISTATE:
                char ch;
 
-               if (!sym_is_changable(sym) && !list->showAll) {
+               if (!sym_is_changable(sym) && list->optMode == normalOpt) {
                        setPixmap(promptColIdx, 0);
                        setText(noColIdx, QString::null);
                        setText(modColIdx, QString::null);
@@ -320,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
          symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
          choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
          menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
-         showAll(false), showName(false), showRange(false), showData(false),
+         showName(false), showRange(false), showData(false), optMode(normalOpt),
          rootEntry(0), headerPopup(0)
 {
        int i;
@@ -337,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
 
        if (name) {
                configSettings->beginGroup(name);
-               showAll = configSettings->readBoolEntry("/showAll", false);
                showName = configSettings->readBoolEntry("/showName", false);
                showRange = configSettings->readBoolEntry("/showRange", false);
                showData = configSettings->readBoolEntry("/showData", false);
+               optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
                configSettings->endGroup();
                connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
        }
@@ -352,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
        reinit();
 }
 
+bool ConfigList::menuSkip(struct menu *menu)
+{
+       if (optMode == normalOpt && menu_is_visible(menu))
+               return false;
+       if (optMode == promptOpt && menu_has_prompt(menu))
+               return false;
+       if (optMode == allOpt)
+               return false;
+       return true;
+}
+
 void ConfigList::reinit(void)
 {
        removeColumn(dataColIdx);
@@ -380,7 +390,7 @@ void ConfigList::saveSettings(void)
                configSettings->writeEntry("/showName", showName);
                configSettings->writeEntry("/showRange", showRange);
                configSettings->writeEntry("/showData", showData);
-               configSettings->writeEntry("/showAll", showAll);
+               configSettings->writeEntry("/optionMode", (int)optMode);
                configSettings->endGroup();
        }
 }
@@ -606,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
                }
 
                visible = menu_is_visible(child);
-               if (showAll || visible) {
+               if (!menuSkip(child)) {
                        if (!child->sym && !child->list && !child->prompt)
                                continue;
                        if (!item || item->menu != child)
@@ -835,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
                e->ignore();
 }
 
-ConfigView* ConfigView::viewList;
+ConfigView*ConfigView::viewList;
+QAction *ConfigView::showNormalAction;
+QAction *ConfigView::showAllAction;
+QAction *ConfigView::showPromptAction;
 
 ConfigView::ConfigView(QWidget* parent, const char *name)
        : Parent(parent, name)
@@ -860,13 +873,16 @@ ConfigView::~ConfigView(void)
        }
 }
 
-void ConfigView::setShowAll(bool b)
+void ConfigView::setOptionMode(QAction *act)
 {
-       if (list->showAll != b) {
-               list->showAll = b;
-               list->updateListAll();
-               emit showAllChanged(b);
-       }
+       if (act == showNormalAction)
+               list->optMode = normalOpt;
+       else if (act == showAllAction)
+               list->optMode = allOpt;
+       else
+               list->optMode = promptOpt;
+
+       list->updateListAll();
 }
 
 void ConfigView::setShowName(bool b)
@@ -964,34 +980,6 @@ void ConfigInfoView::setInfo(struct menu *m)
                menuInfo();
 }
 
-void ConfigInfoView::setSource(const QString& name)
-{
-       const char *p = name.latin1();
-
-       menu = NULL;
-       sym = NULL;
-
-       switch (p[0]) {
-       case 'm':
-               struct menu *m;
-
-               if (sscanf(p, "m%p", &m) == 1 && menu != m) {
-                       menu = m;
-                       menuInfo();
-                       emit menuSelected(menu);
-               }
-               break;
-       case 's':
-               struct symbol *s;
-
-               if (sscanf(p, "s%p", &s) == 1 && sym != s) {
-                       sym = s;
-                       symbolInfo();
-               }
-               break;
-       }
-}
-
 void ConfigInfoView::symbolInfo(void)
 {
        QString str;
@@ -1349,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void)
          connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
          connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
          showDataAction->setOn(configList->showData);
-       QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
-         showAllAction->setToggleAction(TRUE);
-         connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
-         connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
-         showAllAction->setOn(configList->showAll);
+
+       QActionGroup *optGroup = new QActionGroup(this);
+       optGroup->setExclusive(TRUE);
+       connect(optGroup, SIGNAL(selected(QAction *)), configView,
+               SLOT(setOptionMode(QAction *)));
+       connect(optGroup, SIGNAL(selected(QAction *)), menuView,
+               SLOT(setOptionMode(QAction *)));
+
+       configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup);
+       configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup);
+       configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup);
+       configView->showNormalAction->setToggleAction(TRUE);
+       configView->showNormalAction->setOn(configList->optMode == normalOpt);
+       configView->showAllAction->setToggleAction(TRUE);
+       configView->showAllAction->setOn(configList->optMode == allOpt);
+       configView->showPromptAction->setToggleAction(TRUE);
+       configView->showPromptAction->setOn(configList->optMode == promptOpt);
+
        QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
          showDebugAction->setToggleAction(TRUE);
          connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
@@ -1396,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void)
        showRangeAction->addTo(optionMenu);
        showDataAction->addTo(optionMenu);
        optionMenu->insertSeparator();
-       showAllAction->addTo(optionMenu);
+       optGroup->addTo(optionMenu);
+       optionMenu->insertSeparator();
        showDebugAction->addTo(optionMenu);
 
        // create help menu
@@ -1491,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
        ConfigList* list = NULL;
        ConfigItem* item;
 
-       if (!menu_is_visible(menu) && !configView->showAll())
+       if (configList->menuSkip(menu))
                return;
 
        switch (configList->mode) {
index b3b5657b6b35423c003bf40aff66cc047e894d22..636a74b23bf93bba0eeb2a3e263d21891a60889b 100644 (file)
@@ -44,6 +44,9 @@ enum colIdx {
 enum listMode {
        singleMode, menuMode, symbolMode, fullMode, listMode
 };
+enum optionMode {
+       normalOpt = 0, allOpt, promptOpt
+};
 
 class ConfigList : public QListView {
        Q_OBJECT
@@ -115,6 +118,8 @@ public:
        void setAllOpen(bool open);
        void setParentMenu(void);
 
+       bool menuSkip(struct menu *);
+
        template <class P>
        void updateMenuList(P*, struct menu*);
 
@@ -124,8 +129,9 @@ public:
        QPixmap choiceYesPix, choiceNoPix;
        QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
 
-       bool showAll, showName, showRange, showData;
+       bool showName, showRange, showData;
        enum listMode mode;
+       enum optionMode optMode;
        struct menu *rootEntry;
        QColorGroup disabledColorGroup;
        QColorGroup inactivedColorGroup;
@@ -222,17 +228,15 @@ public:
        static void updateList(ConfigItem* item);
        static void updateListAll(void);
 
-       bool showAll(void) const { return list->showAll; }
        bool showName(void) const { return list->showName; }
        bool showRange(void) const { return list->showRange; }
        bool showData(void) const { return list->showData; }
 public slots:
-       void setShowAll(bool);
        void setShowName(bool);
        void setShowRange(bool);
        void setShowData(bool);
+       void setOptionMode(QAction *);
 signals:
-       void showAllChanged(bool);
        void showNameChanged(bool);
        void showRangeChanged(bool);
        void showDataChanged(bool);
@@ -242,6 +246,10 @@ public:
 
        static ConfigView* viewList;
        ConfigView* nextView;
+
+       static QAction *showNormalAction;
+       static QAction *showAllAction;
+       static QAction *showPromptAction;
 };
 
 class ConfigInfoView : public QTextBrowser {
@@ -254,7 +262,6 @@ public:
 public slots:
        void setInfo(struct menu *menu);
        void saveSettings(void);
-       void setSource(const QString& name);
        void setShowDebug(bool);
 
 signals:
index 2e7a048e0cfceb32970d4d0a6fa8b211d70ef83e..e95718fea3555de1b8db125b16add3cf9a350719 100644 (file)
@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym)
        }
        if (sym_is_choice_value(sym))
                return;
+       /* defaulting to "yes" if no explicit "depends on" are given */
+       tri = yes;
+       if (sym->dir_dep.expr)
+               tri = expr_calc_value(sym->dir_dep.expr);
+       if (tri == mod)
+               tri = yes;
+       if (sym->dir_dep.tri != tri) {
+               sym->dir_dep.tri = tri;
+               sym_set_changed(sym);
+       }
        tri = no;
        if (sym->rev_dep.expr)
                tri = expr_calc_value(sym->rev_dep.expr);
@@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym)
        }
 }
 
-static struct symbol *sym_calc_choice(struct symbol *sym)
+/*
+ * Find the default symbol for a choice.
+ * First try the default values for the choice symbol
+ * Next locate the first visible choice value
+ * Return NULL if none was found
+ */
+struct symbol *sym_choice_default(struct symbol *sym)
 {
        struct symbol *def_sym;
        struct property *prop;
        struct expr *e;
 
-       /* is the user choice visible? */
-       def_sym = sym->def[S_DEF_USER].val;
-       if (def_sym) {
-               sym_calc_visibility(def_sym);
-               if (def_sym->visible != no)
-                       return def_sym;
-       }
-
        /* any of the defaults visible? */
        for_all_defaults(sym, prop) {
                prop->visible.tri = expr_calc_value(prop->visible.expr);
                if (prop->visible.tri == no)
                        continue;
                def_sym = prop_get_symbol(prop);
-               sym_calc_visibility(def_sym);
                if (def_sym->visible != no)
                        return def_sym;
        }
 
        /* just get the first visible value */
        prop = sym_get_choice_prop(sym);
-       expr_list_for_each_sym(prop->expr, e, def_sym) {
-               sym_calc_visibility(def_sym);
+       expr_list_for_each_sym(prop->expr, e, def_sym)
                if (def_sym->visible != no)
                        return def_sym;
-       }
 
-       /* no choice? reset tristate value */
-       sym->curr.tri = no;
+       /* failed to locate any defaults */
        return NULL;
 }
 
+static struct symbol *sym_calc_choice(struct symbol *sym)
+{
+       struct symbol *def_sym;
+       struct property *prop;
+       struct expr *e;
+
+       /* first calculate all choice values' visibilities */
+       prop = sym_get_choice_prop(sym);
+       expr_list_for_each_sym(prop->expr, e, def_sym)
+               sym_calc_visibility(def_sym);
+
+       /* is the user choice visible? */
+       def_sym = sym->def[S_DEF_USER].val;
+       if (def_sym && def_sym->visible != no)
+               return def_sym;
+
+       def_sym = sym_choice_default(sym);
+
+       if (def_sym == NULL)
+               /* no choice? reset tristate value */
+               sym->curr.tri = no;
+
+       return def_sym;
+}
+
 void sym_calc_value(struct symbol *sym)
 {
        struct symbol_value newval, oldval;
@@ -321,6 +350,14 @@ void sym_calc_value(struct symbol *sym)
                                }
                        }
                calc_newval:
+                       if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
+                               fprintf(stderr, "warning: (");
+                               expr_fprint(sym->rev_dep.expr, stderr);
+                               fprintf(stderr, ") selects %s which has unmet direct dependencies (",
+                                       sym->name);
+                               expr_fprint(sym->dir_dep.expr, stderr);
+                               fprintf(stderr, ")\n");
+                       }
                        newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
                }
                if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
@@ -365,12 +402,13 @@ void sym_calc_value(struct symbol *sym)
 
        if (sym_is_choice(sym)) {
                struct symbol *choice_sym;
-               int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
 
                prop = sym_get_choice_prop(sym);
                expr_list_for_each_sym(prop->expr, e, choice_sym) {
-                       choice_sym->flags |= flags;
-                       if (flags & SYMBOL_CHANGED)
+                       if ((sym->flags & SYMBOL_WRITE) &&
+                           choice_sym->visible != no)
+                               choice_sym->flags |= SYMBOL_WRITE;
+                       if (sym->flags & SYMBOL_CHANGED)
                                sym_set_changed(choice_sym);
                }
        }
@@ -623,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
        return true;
 }
 
+/*
+ * Find the default value associated to a symbol.
+ * For tristate symbol handle the modules=n case
+ * in which case "m" becomes "y".
+ * If the symbol does not have any default then fallback
+ * to the fixed default values.
+ */
+const char *sym_get_string_default(struct symbol *sym)
+{
+       struct property *prop;
+       struct symbol *ds;
+       const char *str;
+       tristate val;
+
+       sym_calc_visibility(sym);
+       sym_calc_value(modules_sym);
+       val = symbol_no.curr.tri;
+       str = symbol_empty.curr.val;
+
+       /* If symbol has a default value look it up */
+       prop = sym_get_default_prop(sym);
+       if (prop != NULL) {
+               switch (sym->type) {
+               case S_BOOLEAN:
+               case S_TRISTATE:
+                       /* The visibility imay limit the value from yes => mod */
+                       val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
+                       break;
+               default:
+                       /*
+                        * The following fails to handle the situation
+                        * where a default value is further limited by
+                        * the valid range.
+                        */
+                       ds = prop_get_symbol(prop);
+                       if (ds != NULL) {
+                               sym_calc_value(ds);
+                               str = (const char *)ds->curr.val;
+                       }
+               }
+       }
+
+       /* Handle select statements */
+       val = EXPR_OR(val, sym->rev_dep.tri);
+
+       /* transpose mod to yes if modules are not enabled */
+       if (val == mod)
+               if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
+                       val = yes;
+
+       /* transpose mod to yes if type is bool */
+       if (sym->type == S_BOOLEAN && val == mod)
+               val = yes;
+
+       switch (sym->type) {
+       case S_BOOLEAN:
+       case S_TRISTATE:
+               switch (val) {
+               case no: return "n";
+               case mod: return "m";
+               case yes: return "y";
+               }
+       case S_INT:
+       case S_HEX:
+               return str;
+       case S_STRING:
+               return str;
+       case S_OTHER:
+       case S_UNKNOWN:
+               break;
+       }
+       return "";
+}
+
 const char *sym_get_string_value(struct symbol *sym)
 {
        tristate val;
@@ -765,6 +877,110 @@ struct symbol **sym_re_search(const char *pattern)
        return sym_arr;
 }
 
+/*
+ * When we check for recursive dependencies we use a stack to save
+ * current state so we can print out relevant info to user.
+ * The entries are located on the call stack so no need to free memory.
+ * Note inser() remove() must always match to properly clear the stack.
+ */
+static struct dep_stack {
+       struct dep_stack *prev, *next;
+       struct symbol *sym;
+       struct property *prop;
+       struct expr *expr;
+} *check_top;
+
+static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
+{
+       memset(stack, 0, sizeof(*stack));
+       if (check_top)
+               check_top->next = stack;
+       stack->prev = check_top;
+       stack->sym = sym;
+       check_top = stack;
+}
+
+static void dep_stack_remove(void)
+{
+       check_top = check_top->prev;
+       if (check_top)
+               check_top->next = NULL;
+}
+
+/*
+ * Called when we have detected a recursive dependency.
+ * check_top point to the top of the stact so we use
+ * the ->prev pointer to locate the bottom of the stack.
+ */
+static void sym_check_print_recursive(struct symbol *last_sym)
+{
+       struct dep_stack *stack;
+       struct symbol *sym, *next_sym;
+       struct menu *menu = NULL;
+       struct property *prop;
+       struct dep_stack cv_stack;
+
+       if (sym_is_choice_value(last_sym)) {
+               dep_stack_insert(&cv_stack, last_sym);
+               last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
+       }
+
+       for (stack = check_top; stack != NULL; stack = stack->prev)
+               if (stack->sym == last_sym)
+                       break;
+       if (!stack) {
+               fprintf(stderr, "unexpected recursive dependency error\n");
+               return;
+       }
+
+       for (; stack; stack = stack->next) {
+               sym = stack->sym;
+               next_sym = stack->next ? stack->next->sym : last_sym;
+               prop = stack->prop;
+
+               /* for choice values find the menu entry (used below) */
+               if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
+                       for (prop = sym->prop; prop; prop = prop->next) {
+                               menu = prop->menu;
+                               if (prop->menu)
+                                       break;
+                       }
+               }
+               if (stack->sym == last_sym)
+                       fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
+                               prop->file->name, prop->lineno);
+               if (stack->expr) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
+                               prop->file->name, prop->lineno,
+                               sym->name ? sym->name : "<choice>",
+                               prop_get_type_name(prop->type),
+                               next_sym->name ? next_sym->name : "<choice>");
+               } else if (stack->prop) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
+                               prop->file->name, prop->lineno,
+                               sym->name ? sym->name : "<choice>",
+                               next_sym->name ? next_sym->name : "<choice>");
+               } else if (sym_is_choice(sym)) {
+                       fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
+                               menu->file->name, menu->lineno,
+                               sym->name ? sym->name : "<choice>",
+                               next_sym->name ? next_sym->name : "<choice>");
+               } else if (sym_is_choice_value(sym)) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
+                               menu->file->name, menu->lineno,
+                               sym->name ? sym->name : "<choice>",
+                               next_sym->name ? next_sym->name : "<choice>");
+               } else {
+                       fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
+                               prop->file->name, prop->lineno,
+                               sym->name ? sym->name : "<choice>",
+                               next_sym->name ? next_sym->name : "<choice>");
+               }
+       }
+
+       if (check_top == &cv_stack)
+               dep_stack_remove();
+}
 
 static struct symbol *sym_check_expr_deps(struct expr *e)
 {
@@ -801,24 +1017,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
 {
        struct symbol *sym2;
        struct property *prop;
+       struct dep_stack stack;
+
+       dep_stack_insert(&stack, sym);
 
        sym2 = sym_check_expr_deps(sym->rev_dep.expr);
        if (sym2)
-               return sym2;
+               goto out;
 
        for (prop = sym->prop; prop; prop = prop->next) {
                if (prop->type == P_CHOICE || prop->type == P_SELECT)
                        continue;
+               stack.prop = prop;
                sym2 = sym_check_expr_deps(prop->visible.expr);
                if (sym2)
                        break;
                if (prop->type != P_DEFAULT || sym_is_choice(sym))
                        continue;
+               stack.expr = prop->expr;
                sym2 = sym_check_expr_deps(prop->expr);
                if (sym2)
                        break;
+               stack.expr = NULL;
        }
 
+out:
+       dep_stack_remove();
+
        return sym2;
 }
 
@@ -827,6 +1052,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
        struct symbol *sym, *sym2;
        struct property *prop;
        struct expr *e;
+       struct dep_stack stack;
+
+       dep_stack_insert(&stack, choice);
 
        prop = sym_get_choice_prop(choice);
        expr_list_for_each_sym(prop->expr, e, sym)
@@ -840,10 +1068,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
 
        expr_list_for_each_sym(prop->expr, e, sym) {
                sym2 = sym_check_sym_deps(sym);
-               if (sym2) {
-                       fprintf(stderr, " -> %s", sym->name);
+               if (sym2)
                        break;
-               }
        }
 out:
        expr_list_for_each_sym(prop->expr, e, sym)
@@ -853,6 +1079,8 @@ out:
            prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
                sym2 = choice;
 
+       dep_stack_remove();
+
        return sym2;
 }
 
@@ -862,18 +1090,20 @@ struct symbol *sym_check_deps(struct symbol *sym)
        struct property *prop;
 
        if (sym->flags & SYMBOL_CHECK) {
-               fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
-                       sym->prop->file->name, sym->prop->lineno,
-                       sym->name ? sym->name : "<choice>");
+               sym_check_print_recursive(sym);
                return sym;
        }
        if (sym->flags & SYMBOL_CHECKED)
                return NULL;
 
        if (sym_is_choice_value(sym)) {
+               struct dep_stack stack;
+
                /* for choice groups start the check with main choice symbol */
+               dep_stack_insert(&stack, sym);
                prop = sym_get_choice_prop(sym);
                sym2 = sym_check_deps(prop_get_symbol(prop));
+               dep_stack_remove();
        } else if (sym_is_choice(sym)) {
                sym2 = sym_check_choice_deps(sym);
        } else {
@@ -882,14 +1112,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
                sym->flags &= ~SYMBOL_CHECK;
        }
 
-       if (sym2) {
-               fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
-               if (sym2 == sym) {
-                       fprintf(stderr, "\n");
-                       zconfnerrs++;
-                       sym2 = NULL;
-               }
-       }
+       if (sym2 && sym2 == sym)
+               sym2 = NULL;
 
        return sym2;
 }
@@ -943,6 +1167,8 @@ const char *prop_get_type_name(enum prop_type type)
                return "select";
        case P_RANGE:
                return "range";
+       case P_SYMBOL:
+               return "symbol";
        case P_UNKNOWN:
                break;
        }
index 5758aab0d8bb6c8f401b8e2e8374432007ba172b..88f3f07205f88647e5665858f40fde875deec763 100644 (file)
@@ -884,16 +884,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
        char *zeros = NULL;
 
        /* We're looking for a section relative symbol */
-       if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
+       if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
                return;
 
        /* Handle all-NULL symbols allocated into .bss */
-       if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) {
+       if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
                zeros = calloc(1, sym->st_size);
                symval = zeros;
        } else {
                symval = (void *)info->hdr
-                       + info->sechdrs[sym->st_shndx].sh_offset
+                       + info->sechdrs[get_secindex(info, sym)].sh_offset
                        + sym->st_value;
        }
 
index f6127b9f5acac16c10842fee3c53445fddfacd2a..c827309c29cf727bae89d42a4b6e38164b9d72a7 100644 (file)
@@ -253,7 +253,7 @@ static enum export export_no(const char *s)
        return export_unknown;
 }
 
-static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
+static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
 {
        if (sec == elf->export_sec)
                return export_plain;
@@ -373,6 +373,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
        Elf_Ehdr *hdr;
        Elf_Shdr *sechdrs;
        Elf_Sym  *sym;
+       const char *secstrings;
+       unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
 
        hdr = grab_file(filename, &info->size);
        if (!hdr) {
@@ -417,8 +419,27 @@ static int parse_elf(struct elf_info *info, const char *filename)
                return 0;
        }
 
+       if (hdr->e_shnum == 0) {
+               /*
+                * There are more than 64k sections,
+                * read count from .sh_size.
+                * note: it doesn't need shndx2secindex()
+                */
+               info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
+       }
+       else {
+               info->num_sections = hdr->e_shnum;
+       }
+       if (hdr->e_shstrndx == SHN_XINDEX) {
+               info->secindex_strings =
+                   shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
+       }
+       else {
+               info->secindex_strings = hdr->e_shstrndx;
+       }
+
        /* Fix endianness in section headers */
-       for (i = 0; i < hdr->e_shnum; i++) {
+       for (i = 0; i < info->num_sections; i++) {
                sechdrs[i].sh_name      = TO_NATIVE(sechdrs[i].sh_name);
                sechdrs[i].sh_type      = TO_NATIVE(sechdrs[i].sh_type);
                sechdrs[i].sh_flags     = TO_NATIVE(sechdrs[i].sh_flags);
@@ -431,9 +452,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
                sechdrs[i].sh_entsize   = TO_NATIVE(sechdrs[i].sh_entsize);
        }
        /* Find symbol table. */
-       for (i = 1; i < hdr->e_shnum; i++) {
-               const char *secstrings
-                       = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+       secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
+       for (i = 1; i < info->num_sections; i++) {
                const char *secname;
                int nobits = sechdrs[i].sh_type == SHT_NOBITS;
 
@@ -461,14 +481,26 @@ static int parse_elf(struct elf_info *info, const char *filename)
                else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
                        info->export_gpl_future_sec = i;
 
-               if (sechdrs[i].sh_type != SHT_SYMTAB)
-                       continue;
+               if (sechdrs[i].sh_type == SHT_SYMTAB) {
+                       unsigned int sh_link_idx;
+                       symtab_idx = i;
+                       info->symtab_start = (void *)hdr +
+                           sechdrs[i].sh_offset;
+                       info->symtab_stop  = (void *)hdr +
+                           sechdrs[i].sh_offset + sechdrs[i].sh_size;
+                       sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
+                       info->strtab       = (void *)hdr +
+                           sechdrs[sh_link_idx].sh_offset;
+               }
 
-               info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
-               info->symtab_stop  = (void *)hdr + sechdrs[i].sh_offset
-                                                + sechdrs[i].sh_size;
-               info->strtab       = (void *)hdr +
-                                    sechdrs[sechdrs[i].sh_link].sh_offset;
+               /* 32bit section no. table? ("more than 64k sections") */
+               if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
+                       symtab_shndx_idx = i;
+                       info->symtab_shndx_start = (void *)hdr +
+                           sechdrs[i].sh_offset;
+                       info->symtab_shndx_stop  = (void *)hdr +
+                           sechdrs[i].sh_offset + sechdrs[i].sh_size;
+               }
        }
        if (!info->symtab_start)
                fatal("%s has no symtab?\n", filename);
@@ -480,6 +512,21 @@ static int parse_elf(struct elf_info *info, const char *filename)
                sym->st_value = TO_NATIVE(sym->st_value);
                sym->st_size  = TO_NATIVE(sym->st_size);
        }
+
+       if (symtab_shndx_idx != ~0U) {
+               Elf32_Word *p;
+               if (symtab_idx !=
+                   shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
+                       fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
+                             filename,
+                             shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
+                             symtab_idx);
+               /* Fix endianness */
+               for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
+                    p++)
+                       *p = TO_NATIVE(*p);
+       }
+
        return 1;
 }
 
@@ -519,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
                               Elf_Sym *sym, const char *symname)
 {
        unsigned int crc;
-       enum export export = export_from_sec(info, sym->st_shndx);
+       enum export export = export_from_sec(info, get_secindex(info, sym));
 
        switch (sym->st_shndx) {
        case SHN_COMMON:
@@ -661,19 +708,19 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
                return "(unknown)";
 }
 
-static const char *sec_name(struct elf_info *elf, int shndx)
+static const char *sec_name(struct elf_info *elf, int secindex)
 {
        Elf_Shdr *sechdrs = elf->sechdrs;
        return (void *)elf->hdr +
-               elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
-               sechdrs[shndx].sh_name;
+               elf->sechdrs[elf->secindex_strings].sh_offset +
+               sechdrs[secindex].sh_name;
 }
 
 static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
 {
        return (void *)elf->hdr +
-               elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
-               sechdr->sh_name;
+               elf->sechdrs[elf->secindex_strings].sh_offset +
+               sechdr->sh_name;
 }
 
 /* if sym is empty or point to a string
@@ -1052,11 +1099,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
        Elf_Sym *near = NULL;
        Elf64_Sword distance = 20;
        Elf64_Sword d;
+       unsigned int relsym_secindex;
 
        if (relsym->st_name != 0)
                return relsym;
+
+       relsym_secindex = get_secindex(elf, relsym);
        for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
-               if (sym->st_shndx != relsym->st_shndx)
+               if (get_secindex(elf, sym) != relsym_secindex)
                        continue;
                if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
                        continue;
@@ -1118,9 +1168,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
        for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
                const char *symsec;
 
-               if (sym->st_shndx >= SHN_LORESERVE)
+               if (is_shndx_special(sym->st_shndx))
                        continue;
-               symsec = sec_name(elf, sym->st_shndx);
+               symsec = sec_name(elf, get_secindex(elf, sym));
                if (strcmp(symsec, sec) != 0)
                        continue;
                if (!is_valid_name(elf, sym))
@@ -1316,7 +1366,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
        const char *tosec;
        const struct sectioncheck *mismatch;
 
-       tosec = sec_name(elf, sym->st_shndx);
+       tosec = sec_name(elf, get_secindex(elf, sym));
        mismatch = section_mismatch(fromsec, tosec);
        if (mismatch) {
                Elf_Sym *to;
@@ -1344,7 +1394,7 @@ static unsigned int *reloc_location(struct elf_info *elf,
                                    Elf_Shdr *sechdr, Elf_Rela *r)
 {
        Elf_Shdr *sechdrs = elf->sechdrs;
-       int section = sechdr->sh_info;
+       int section = shndx2secindex(sechdr->sh_info);
 
        return (void *)elf->hdr + sechdrs[section].sh_offset +
                r->r_offset - sechdrs[section].sh_addr;
@@ -1452,7 +1502,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
                r.r_addend = TO_NATIVE(rela->r_addend);
                sym = elf->symtab_start + r_sym;
                /* Skip special sections */
-               if (sym->st_shndx >= SHN_LORESERVE)
+               if (is_shndx_special(sym->st_shndx))
                        continue;
                check_section_mismatch(modname, elf, &r, sym, fromsec);
        }
@@ -1510,7 +1560,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
                }
                sym = elf->symtab_start + r_sym;
                /* Skip special sections */
-               if (sym->st_shndx >= SHN_LORESERVE)
+               if (is_shndx_special(sym->st_shndx))
                        continue;
                check_section_mismatch(modname, elf, &r, sym, fromsec);
        }
@@ -1535,7 +1585,7 @@ static void check_sec_ref(struct module *mod, const char *modname,
        Elf_Shdr *sechdrs = elf->sechdrs;
 
        /* Walk through all sections */
-       for (i = 0; i < elf->hdr->e_shnum; i++) {
+       for (i = 0; i < elf->num_sections; i++) {
                check_section(modname, elf, &elf->sechdrs[i]);
                /* We want to process only relocation sections and not .init */
                if (sechdrs[i].sh_type == SHT_RELA)
index be987a44f2502139871c559654f479dd1bf05b50..0388cfccac8db64818b12732e519d6d233557908 100644 (file)
@@ -129,8 +129,51 @@ struct elf_info {
        const char   *strtab;
        char         *modinfo;
        unsigned int modinfo_len;
+
+       /* support for 32bit section numbers */
+
+       unsigned int num_sections; /* max_secindex + 1 */
+       unsigned int secindex_strings;
+       /* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
+        * take shndx from symtab_shndx_start[N] instead */
+       Elf32_Word   *symtab_shndx_start;
+       Elf32_Word   *symtab_shndx_stop;
 };
 
+static inline int is_shndx_special(unsigned int i)
+{
+       return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
+}
+
+/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus:
+ * shndx == 0               <=> sechdrs[0]
+ * ......
+ * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1]
+ * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE]
+ * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1]
+ * ......
+ * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff,
+ * so basically we map  0000..feff -> 0000..feff
+ *                      ff00..ffff -> (you are a bad boy, dont do it)
+ *                     10000..xxxx -> ff00..(xxxx-0x100)
+ */
+static inline unsigned int shndx2secindex(unsigned int i)
+{
+       if (i <= SHN_HIRESERVE)
+               return i;
+       return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
+}
+
+/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
+static inline unsigned int get_secindex(const struct elf_info *info,
+                                       const Elf_Sym *sym)
+{
+       if (sym->st_shndx != SHN_XINDEX)
+               return sym->st_shndx;
+       return shndx2secindex(info->symtab_shndx_start[sym -
+                                                      info->symtab_start]);
+}
+
 /* file2alias.c */
 extern unsigned int cross_build;
 void handle_moddevtable(struct module *mod, struct elf_info *info,
index d2c29b63addaa04dbd3df94d1adbfa9bc3ff8518..d0b931b994fccebc025c1c281c8cfd1573b7f64b 100644 (file)
@@ -111,13 +111,38 @@ tar%pkg: FORCE
 clean-dirs += $(objtree)/tar-install/
 
 
+# perf-pkg - generate a source tarball with perf source
+# ---------------------------------------------------------------------------
+
+perf-tar=perf-$(KERNELVERSION)
+
+quiet_cmd_perf_tar = TAR
+      cmd_perf_tar = \
+git archive --prefix=$(perf-tar)/ HEAD^{tree}                       \
+       $$(cat $(srctree)/tools/perf/MANIFEST) -o $(perf-tar).tar;  \
+mkdir -p $(perf-tar);                                               \
+git rev-parse HEAD > $(perf-tar)/HEAD;                              \
+tar rf $(perf-tar).tar $(perf-tar)/HEAD;                            \
+rm -r $(perf-tar);                                                  \
+$(if $(findstring tar-src,$@),,                                     \
+$(if $(findstring bz2,$@),bzip2,                                    \
+$(if $(findstring gz,$@),gzip,                                      \
+$(error unknown target $@)))                                       \
+       -f -9 $(perf-tar).tar)
+
+perf-%pkg: FORCE
+       $(call cmd,perf_tar)
+
 # Help text displayed when executing 'make help'
 # ---------------------------------------------------------------------------
 help: FORCE
-       @echo '  rpm-pkg         - Build both source and binary RPM kernel packages'
-       @echo '  binrpm-pkg      - Build only the binary kernel package'
-       @echo '  deb-pkg         - Build the kernel as an deb package'
-       @echo '  tar-pkg         - Build the kernel as an uncompressed tarball'
-       @echo '  targz-pkg       - Build the kernel as a gzip compressed tarball'
-       @echo '  tarbz2-pkg      - Build the kernel as a bzip2 compressed tarball'
+       @echo '  rpm-pkg             - Build both source and binary RPM kernel packages'
+       @echo '  binrpm-pkg          - Build only the binary kernel package'
+       @echo '  deb-pkg             - Build the kernel as an deb package'
+       @echo '  tar-pkg             - Build the kernel as an uncompressed tarball'
+       @echo '  targz-pkg           - Build the kernel as a gzip compressed tarball'
+       @echo '  tarbz2-pkg          - Build the kernel as a bzip2 compressed tarball'
+       @echo '  perf-tar-src-pkg    - Build $(perf-tar).tar source tarball'
+       @echo '  perf-targz-src-pkg  - Build $(perf-tar).tar.gz source tarball'
+       @echo '  perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball'
 
index 07f2fbde2abf85a5f92040a10608a38e23db3905..5f1e2fc7f171e65dcf0dfd5f9c56afc3c77e7d9f 100644 (file)
@@ -148,10 +148,11 @@ EOF
 # Generate a control file
 cat <<EOF > debian/control
 Source: linux-upstream
-Section: admin
+Section: kernel
 Priority: optional
 Maintainer: $maintainer
-Standards-Version: 3.8.1
+Standards-Version: 3.8.4
+Homepage: http://www.kernel.org/
 EOF
 
 if [ "$ARCH" = "um" ]; then
index f3c9c0a90b98cad68389da5d591a9921e1cb8f39..0171060b5fd654e66434bc9f3ef3ee9064296d35 100755 (executable)
@@ -326,7 +326,7 @@ if ($arch eq "x86_64") {
     #                    14: R_MIPS_NONE *ABS*
     #   18:   00020021        nop
     if ($is_module eq "0") {
-           $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
+           $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_26\\s+_mcount\$";
     } else {
            $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$";
     }
index 72555b9ca7d632ef4f48b373445f00f8743ed401..9b9013b2e3211a9c6de17a9001e7939a73bf48e9 100644 (file)
@@ -1,6 +1,6 @@
 config SECURITY_APPARMOR
        bool "AppArmor support"
-       depends on SECURITY
+       depends on SECURITY && NET
        select AUDIT
        select SECURITY_PATH
        select SECURITYFS
index 0d26f689bd7726f7d253607a0f5899c00e947fcc..0088dd8bf68a77b29637527733ff0b8985b8ecb7 100644 (file)
@@ -537,6 +537,8 @@ int wait_for_key_construction(struct key *key, bool intr)
                          intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
        if (ret < 0)
                return ret;
+       if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+               return -ENOKEY;
        return key_validate(key);
 }
 EXPORT_SYMBOL(wait_for_key_construction);
index df110df52a8b2724c27c4b84490a5a9bc747cafc..7ab9174a8a841b4a924474deb3c238a003180188 100644 (file)
@@ -139,8 +139,8 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
        pdacf->p_dev = link;
        link->priv = pdacf;
 
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       link->io.NumPorts1 = 16;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+       link->resource[0]->end = 16;
 
        link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -219,7 +219,7 @@ static int pdacf_config(struct pcmcia_device *link)
        snd_printdd(KERN_DEBUG "pdacf_config called\n");
        link->conf.ConfigIndex = 0x5;
 
-       ret = pcmcia_request_io(link, &link->io);
+       ret = pcmcia_request_io(link);
        if (ret)
                goto failed;
 
@@ -231,7 +231,8 @@ static int pdacf_config(struct pcmcia_device *link)
        if (ret)
                goto failed;
 
-       if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0)
+       if (snd_pdacf_assign_resources(pdacf, link->resource[0]->start,
+                                       link->irq) < 0)
                goto failed;
 
        return 0;
index a0a7ec64222a822ca9707ba7cfe03cba57349fde..5cc3e45730747fc62e505e965b3bfe7d4d2054eb 100644 (file)
@@ -24,7 +24,6 @@
 #include <sound/pcm.h>
 #include <asm/io.h>
 #include <linux/interrupt.h>
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index 624b47a85f0a1623153f6d7c572b0a4a4d6d934f..a6edfc3be29a59b018d6b268f9a01255b08451db 100644 (file)
@@ -159,8 +159,8 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
        vxp->p_dev = link;
        link->priv = chip;
 
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       link->io.NumPorts1 = 16;
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+       link->resource[0]->end = 16;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -226,7 +226,7 @@ static int vxpocket_config(struct pcmcia_device *link)
                strcpy(chip->card->driver, vxp440_hw.name);
        }
 
-       ret = pcmcia_request_io(link, &link->io);
+       ret = pcmcia_request_io(link);
        if (ret)
                goto failed;
 
@@ -241,7 +241,8 @@ static int vxpocket_config(struct pcmcia_device *link)
        chip->dev = &link->dev;
        snd_card_set_dev(chip->card, chip->dev);
 
-       if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0)
+       if (snd_vxpocket_assign_resources(chip, link->resource[0]->start,
+                                               link->irq) < 0)
                goto failed;
 
        return 0;
index ea4df16a28ef16e74f4205769698d20e565a216f..d9110669d0425cd6f4bc652073335bacac6ab8b1 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <sound/vx_core.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index 71221fd209445b55a09093986a7a330546277381..9eb1a4e0363be8ba203f78ffde906ea202f0e319 100644 (file)
@@ -1010,7 +1010,7 @@ static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_de
        struct snd_amd7930 *amd;
        int err, irq;
 
-       irq = op->irqs[0];
+       irq = op->archdata.irqs[0];
 
        if (dev_num >= SNDRV_CARDS)
                return -ENODEV;
@@ -1075,7 +1075,7 @@ static struct of_platform_driver amd7930_sbus_driver = {
 
 static int __init amd7930_init(void)
 {
-       return of_register_driver(&amd7930_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&amd7930_sbus_driver);
 }
 
 static void __exit amd7930_exit(void)
@@ -1092,7 +1092,7 @@ static void __exit amd7930_exit(void)
 
        amd7930_list = NULL;
 
-       of_unregister_driver(&amd7930_sbus_driver);
+       of_unregister_platform_driver(&amd7930_sbus_driver);
 }
 
 module_init(amd7930_init);
index fb4c6f2f29e5d1b97a69ec2ccd00d6ff7b750ff4..68570ee2c9bb91079a0948d4832fd0c0a2079eea 100644 (file)
@@ -1832,14 +1832,14 @@ static int __devinit snd_cs4231_sbus_create(struct snd_card *card,
        chip->c_dma.request = sbus_dma_request;
        chip->c_dma.address = sbus_dma_addr;
 
-       if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt,
+       if (request_irq(op->archdata.irqs[0], snd_cs4231_sbus_interrupt,
                        IRQF_SHARED, "cs4231", chip)) {
                snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n",
-                           dev, op->irqs[0]);
+                           dev, op->archdata.irqs[0]);
                snd_cs4231_sbus_free(chip);
                return -EBUSY;
        }
-       chip->irq[0] = op->irqs[0];
+       chip->irq[0] = op->archdata.irqs[0];
 
        if (snd_cs4231_probe(chip) < 0) {
                snd_cs4231_sbus_free(chip);
@@ -1870,7 +1870,7 @@ static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_dev
                card->shortname,
                rp->flags & 0xffL,
                (unsigned long long)rp->start,
-               op->irqs[0]);
+               op->archdata.irqs[0]);
 
        err = snd_cs4231_sbus_create(card, op, dev);
        if (err < 0) {
@@ -1979,12 +1979,12 @@ static int __devinit snd_cs4231_ebus_create(struct snd_card *card,
        chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
        chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
        chip->c_dma.ebus_info.client_cookie = chip;
-       chip->c_dma.ebus_info.irq = op->irqs[0];
+       chip->c_dma.ebus_info.irq = op->archdata.irqs[0];
        strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
        chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
        chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
        chip->p_dma.ebus_info.client_cookie = chip;
-       chip->p_dma.ebus_info.irq = op->irqs[1];
+       chip->p_dma.ebus_info.irq = op->archdata.irqs[1];
 
        chip->p_dma.prepare = _ebus_dma_prepare;
        chip->p_dma.enable = _ebus_dma_enable;
@@ -2060,7 +2060,7 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev
        sprintf(card->longname, "%s at 0x%llx, irq %d",
                card->shortname,
                op->resource[0].start,
-               op->irqs[0]);
+               op->archdata.irqs[0]);
 
        err = snd_cs4231_ebus_create(card, op, dev);
        if (err < 0) {
@@ -2120,12 +2120,12 @@ static struct of_platform_driver cs4231_driver = {
 
 static int __init cs4231_init(void)
 {
-       return of_register_driver(&cs4231_driver, &of_bus_type);
+       return of_register_platform_driver(&cs4231_driver);
 }
 
 static void __exit cs4231_exit(void)
 {
-       of_unregister_driver(&cs4231_driver);
+       of_unregister_platform_driver(&cs4231_driver);
 }
 
 module_init(cs4231_init);
index 1557bf132e732fe172a383f3f64cec7ca4bb27f4..c421901c48d0f40286da25ae42425e528afc8767 100644 (file)
@@ -2608,7 +2608,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id
                return -ENOENT;
        }
 
-       irq = op->irqs[0];
+       irq = op->archdata.irqs[0];
        if (irq <= 0) {
                printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
                return -ENODEV;
@@ -2699,12 +2699,12 @@ static struct of_platform_driver dbri_sbus_driver = {
 /* Probe for the dbri chip and then attach the driver. */
 static int __init dbri_init(void)
 {
-       return of_register_driver(&dbri_sbus_driver, &of_bus_type);
+       return of_register_platform_driver(&dbri_sbus_driver);
 }
 
 static void __exit dbri_exit(void)
 {
-       of_unregister_driver(&dbri_sbus_driver);
+       of_unregister_platform_driver(&dbri_sbus_driver);
 }
 
 module_init(dbri_init);
index e1d60d780784b8dd5ecedb42760a7802478276c1..cb43289e447f9d880b32ebadf173fa0f01aca166 100644 (file)
@@ -18,3 +18,5 @@ perf-archive
 tags
 TAGS
 cscope*
+config.mak
+config.mak.autogen
index 5d1a9500277f32535fc8f95ffa12907a3720e6d5..c1057701a7dc7d61e49f9b827d747e686a06bfd1 100644 (file)
@@ -12,9 +12,9 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-This command manages the build-id cache. It can add and remove files to the
-cache. In the future it should as well purge older entries, set upper limits
-for the space used by the cache, etc.
+This command manages the build-id cache. It can add and remove files to/from
+the cache. In the future it should as well purge older entries, set upper
+limits for the space used by the cache, etc.
 
 OPTIONS
 -------
@@ -23,7 +23,7 @@ OPTIONS
         Add specified file to the cache.
 -r::
 --remove=::
-        Remove specified file to the cache.
+        Remove specified file from the cache.
 -v::
 --verbose::
        Be more verbose.
index 94a258c96a440b091616264fb2a7d0fd8b515967..27d52dae5a43aa842234ba6d6596ca7ce89e9e1e 100644 (file)
@@ -31,6 +31,10 @@ OPTIONS
 --vmlinux=PATH::
        Specify vmlinux path which has debuginfo (Dwarf binary).
 
+-s::
+--source=PATH::
+       Specify path to kernel source.
+
 -v::
 --verbose::
         Be more verbose (show parsed arguments, etc).
@@ -90,8 +94,8 @@ Each probe argument follows below syntax.
 
  [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
 
-'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
-'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo.
+'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
+'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo. You can specify 'string' type only for the local variable or structure member which is an array of or a pointer to 'char' or 'unsigned char' type.
 
 LINE SYNTAX
 -----------
index 34e255fc3e2f14d0a559efd207b6def3abfdea9e..3ee27dccfde97d6c58f562bd890a6df9c6026d25 100644 (file)
@@ -103,6 +103,19 @@ OPTIONS
 --raw-samples::
 Collect raw sample records from all opened counters (default for tracepoint counters).
 
+-C::
+--cpu::
+Collect samples only on the list of cpus provided. Multiple CPUs can be provided as a
+comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
+In per-thread mode with inheritance mode on (default), samples are captured only when
+the thread executes on the designated CPUs. Default is to monitor all CPUs.
+
+-N::
+--no-buildid-cache::
+Do not update the builid cache. This saves some overhead in situations
+where the information in the perf.data file (which includes buildids)
+is sufficient.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-list[1]
index 909fa766fa1cfa014041e41ddb76d29555c2469c..4b3a2d46b4378607f5195d12328646f5b1d7a638 100644 (file)
@@ -46,6 +46,13 @@ OPTIONS
 -B::
         print large numbers with thousands' separators according to locale
 
+-C::
+--cpu=::
+Count only on the list of cpus provided. Multiple CPUs can be provided as a
+comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
+In per-thread mode, this option is ignored. The -a option is still necessary
+to activate system-wide monitoring. Default is to count on all CPUs.
+
 EXAMPLES
 --------
 
index 785b9fc32a46f45559a77c193ed56fdf9bfc7702..1f9687663f2a9cd62d6cff9f597395523b3da931 100644 (file)
@@ -25,9 +25,11 @@ OPTIONS
 --count=<count>::
        Event period to sample.
 
--C <cpu>::
---CPU=<cpu>::
-       CPU to profile.
+-C <cpu-list>::
+--cpu=<cpu>::
+Monitor only on the list of cpus provided. Multiple CPUs can be provided as a
+comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
+Default is to monitor all CPUS.
 
 -d <seconds>::
 --delay=<seconds>::
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
new file mode 100644 (file)
index 0000000..8c7fc0c
--- /dev/null
@@ -0,0 +1,12 @@
+tools/perf
+include/linux/perf_event.h
+include/linux/rbtree.h
+include/linux/list.h
+include/linux/hash.h
+include/linux/stringify.h
+lib/rbtree.c
+include/linux/swab.h
+arch/*/include/asm/unistd*.h
+include/linux/poison.h
+include/linux/magic.h
+include/linux/hw_breakpoint.h
index d75c28a825f5356d9b0dbe16459111d3b6c5e81a..26f626d45a9e2bb0a7e5157f48ddfe7c9a0851fe 100644 (file)
@@ -285,14 +285,10 @@ else
        QUIET_STDERR = ">/dev/null 2>&1"
 endif
 
-BITBUCKET = "/dev/null"
+-include feature-tests.mak
 
-ifneq ($(shell sh -c "(echo '\#include <stdio.h>'; echo 'int main(void) { return puts(\"hi\"); }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y)
-       BITBUCKET = .perf.dev.null
-endif
-
-ifeq ($(shell sh -c "echo 'int foo(void) {char X[2]; return 3;}' | $(CC) -x c -c -Werror -fstack-protector-all - -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y)
-  CFLAGS := $(CFLAGS) -fstack-protector-all
+ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y)
+       CFLAGS := $(CFLAGS) -fstack-protector-all
 endif
 
 
@@ -508,7 +504,8 @@ PERFLIBS = $(LIB_FILE)
 -include config.mak
 
 ifndef NO_DWARF
-ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo '\#include <version.h>'; echo '\#ifndef _ELFUTILS_PREREQ'; echo '\#error'; echo '\#endif'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+FLAGS_DWARF=$(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
+ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
        msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
        NO_DWARF := 1
 endif # Dwarf support
@@ -536,16 +533,18 @@ ifneq ($(OUTPUT),)
        BASIC_CFLAGS += -I$(OUTPUT)
 endif
 
-ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
-ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
-       msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
+FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
+       FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
+       ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y)
+               msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
+       else
+               msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel);
+       endif
 endif
 
-       ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
-               BASIC_CFLAGS += -DLIBELF_NO_MMAP
-       endif
-else
-       msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
+ifneq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y)
+       BASIC_CFLAGS += -DLIBELF_NO_MMAP
 endif
 
 ifndef NO_DWARF
@@ -561,64 +560,73 @@ endif # NO_DWARF
 ifdef NO_NEWT
        BASIC_CFLAGS += -DNO_NEWT_SUPPORT
 else
-ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
-       msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
-       BASIC_CFLAGS += -DNO_NEWT_SUPPORT
-else
-       # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
-       BASIC_CFLAGS += -I/usr/include/slang
-       EXTLIBS += -lnewt -lslang
-       LIB_OBJS += $(OUTPUT)util/newt.o
-endif
-endif # NO_NEWT
-
-ifndef NO_LIBPERL
-PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null`
-PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
+       FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt
+       ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y)
+               msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
+               BASIC_CFLAGS += -DNO_NEWT_SUPPORT
+       else
+               # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
+               BASIC_CFLAGS += -I/usr/include/slang
+               EXTLIBS += -lnewt -lslang
+               LIB_OBJS += $(OUTPUT)util/newt.o
+       endif
 endif
 
-ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o $(BITBUCKET) $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
+ifdef NO_LIBPERL
        BASIC_CFLAGS += -DNO_LIBPERL
 else
-       ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
-       LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
-       LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
-endif
+       PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null`
+       PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
+       FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
 
-ifndef NO_LIBPYTHON
-PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null`
-PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null`
+       ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y)
+               BASIC_CFLAGS += -DNO_LIBPERL
+       else
+               ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
+               LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
+               LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
+       endif
 endif
 
-ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o $(BITBUCKET) $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
+ifdef NO_LIBPYTHON
        BASIC_CFLAGS += -DNO_LIBPYTHON
 else
-       ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS)
-       LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
-       LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
+       PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null`
+       PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null`
+       FLAGS_PYTHON_EMBED=$(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
+       ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y)
+               BASIC_CFLAGS += -DNO_LIBPYTHON
+       else
+               ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS)
+               LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
+               LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
+       endif
 endif
 
 ifdef NO_DEMANGLE
        BASIC_CFLAGS += -DNO_DEMANGLE
 else
-       ifdef HAVE_CPLUS_DEMANGLE
+        ifdef HAVE_CPLUS_DEMANGLE
                EXTLIBS += -liberty
                BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
-       else
-               has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y")
-
+        else
+               FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd
+               has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD))
                ifeq ($(has_bfd),y)
                        EXTLIBS += -lbfd
                else
-                       has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty "$(QUIET_STDERR)" && echo y")
+                       FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
+                       has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY))
                        ifeq ($(has_bfd_iberty),y)
                                EXTLIBS += -lbfd -liberty
                        else
-                               has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty -lz "$(QUIET_STDERR)" && echo y")
+                               FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
+                               has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z))
                                ifeq ($(has_bfd_iberty_z),y)
                                        EXTLIBS += -lbfd -liberty -lz
                                else
-                                       has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -liberty "$(QUIET_STDERR)" && echo y")
+                                       FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
+                                       has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE))
                                        ifeq ($(has_cplus_demangle),y)
                                                EXTLIBS += -liberty
                                                BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
@@ -867,7 +875,7 @@ export TAR INSTALL DESTDIR SHELL_PATH
 
 SHELL = $(SHELL_PATH)
 
-all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) $(OUTPUT)PERF-BUILD-OPTIONS
+all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) $(OUTPUT)PERF-BUILD-OPTIONS
 ifneq (,$X)
        $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
 endif
@@ -1197,11 +1205,6 @@ clean:
 .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS
 .PHONY: .FORCE-PERF-BUILD-OPTIONS
 
-.perf.dev.null:
-               touch .perf.dev.null
-
-.INTERMEDIATE: .perf.dev.null
-
 ### Make sure built-ins do not have dups and listed in perf.c
 #
 check-builtins::
diff --git a/tools/perf/arch/sh/Makefile b/tools/perf/arch/sh/Makefile
new file mode 100644 (file)
index 0000000..15130b5
--- /dev/null
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/sh/util/dwarf-regs.c b/tools/perf/arch/sh/util/dwarf-regs.c
new file mode 100644 (file)
index 0000000..a11edb0
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Matt Fleming <matt@console-pimps.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+/*
+ * Generic dwarf analysis helpers
+ */
+
+#define SH_MAX_REGS 18
+const char *sh_regs_table[SH_MAX_REGS] = {
+       "r0",
+       "r1",
+       "r2",
+       "r3",
+       "r4",
+       "r5",
+       "r6",
+       "r7",
+       "r8",
+       "r9",
+       "r10",
+       "r11",
+       "r12",
+       "r13",
+       "r14",
+       "r15",
+       "pc",
+       "pr",
+};
+
+/* Return architecture dependent register string (for kprobe-tracer) */
+const char *get_arch_regstr(unsigned int n)
+{
+       return (n <= SH_MAX_REGS) ? sh_regs_table[n] : NULL;
+}
index 96db5248e99569914c62427a3466aa9b91559530..fd20670ce986bae016759aa61bd01c272bd7f47f 100644 (file)
@@ -61,11 +61,9 @@ static int hists__add_entry(struct hists *self, struct addr_location *al)
 static int process_sample_event(event_t *event, struct perf_session *session)
 {
        struct addr_location al;
+       struct sample_data data;
 
-       dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc,
-                   event->ip.pid, event->ip.ip);
-
-       if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+       if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) {
                pr_warning("problem processing %d event, skipping it.\n",
                           event->header.type);
                return -1;
index f8e3d1852029b65c9c2efbdf5b6315f6f9e9d492..29ad20e6791969625303ed25ec5321f0ddd2c528 100644 (file)
@@ -78,8 +78,7 @@ static int __cmd_buildid_cache(void)
        struct str_node *pos;
        char debugdir[PATH_MAX];
 
-       snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"),
-                DEBUG_CACHE_DIR);
+       snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
 
        if (add_name_list_str) {
                list = strlist__new(true, add_name_list_str);
index 99890728409eba3bc390d2060a58d140f543c488..44a47e13bd673eb362f956b80bd02adbec367d45 100644 (file)
@@ -43,10 +43,8 @@ static int __cmd_buildid_list(void)
        if (session == NULL)
                return -1;
 
-       if (with_hits) {
-               symbol_conf.full_paths = true;
+       if (with_hits)
                perf_session__process_events(session, &build_id__mark_dso_hit_ops);
-       }
 
        perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
 
index a6e2fdc7a04e16613087a4c65e70d832ab903505..fca1d4402910ab13a6f7aa45299e31c0289cb27c 100644 (file)
@@ -35,10 +35,7 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi
        struct addr_location al;
        struct sample_data data = { .period = 1, };
 
-       dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc,
-                   event->ip.pid, event->ip.ip);
-
-       if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+       if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) {
                pr_warning("problem processing %d event, skipping it.\n",
                           event->header.type);
                return -1;
@@ -47,8 +44,6 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi
        if (al.filtered || al.sym == NULL)
                return 0;
 
-       event__parse_sample(event, session->sample_type, &data);
-
        if (hists__add_entry(&session->hists, &al, data.period)) {
                pr_warning("problem incrementing symbol period, skipping event\n");
                return -1;
@@ -185,8 +180,6 @@ static const struct option options[] = {
        OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
        OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
                    "load module symbols - WARNING: use only with -k and LIVE kernel"),
-       OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths,
-                   "Don't shorten the pathnames taking into account the cwd"),
        OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
                   "only consider symbols in these dsos"),
        OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
index e4a4da32a56864a7c1d95ec44a5b603f4f541e92..199d5e19554f62fcfc3d6c960c115edb6f7c0535 100644 (file)
@@ -182,6 +182,8 @@ static const struct option options[] = {
                     "Show source code lines.", opt_show_lines),
        OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
                   "file", "vmlinux pathname"),
+       OPT_STRING('s', "source", &symbol_conf.source_prefix,
+                  "directory", "path to kernel source"),
 #endif
        OPT__DRY_RUN(&probe_event_dry_run),
        OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -265,4 +267,3 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
        }
        return 0;
 }
-
index 711745f56bba32bbea9ffbb048aae3bf3ea52c5c..ff77b805de71ac1b0d058a1489efd34797b9a004 100644 (file)
@@ -49,7 +49,6 @@ static int                    group                           =      0;
 static int                     realtime_prio                   =      0;
 static bool                    raw_samples                     =  false;
 static bool                    system_wide                     =  false;
-static int                     profile_cpu                     =     -1;
 static pid_t                   target_pid                      =     -1;
 static pid_t                   target_tid                      =     -1;
 static pid_t                   *all_tids                       =      NULL;
@@ -61,6 +60,7 @@ static bool                   call_graph                      =  false;
 static bool                    inherit_stat                    =  false;
 static bool                    no_samples                      =  false;
 static bool                    sample_address                  =  false;
+static bool                    no_buildid                      =  false;
 
 static long                    samples                         =      0;
 static u64                     bytes_written                   =      0;
@@ -74,6 +74,7 @@ static int                    file_new                        =      1;
 static off_t                   post_processing_offset;
 
 static struct perf_session     *session;
+static const char              *cpu_list;
 
 struct mmap_data {
        int                     counter;
@@ -268,12 +269,17 @@ static void create_counter(int counter, int cpu)
        if (inherit_stat)
                attr->inherit_stat = 1;
 
-       if (sample_address)
+       if (sample_address) {
                attr->sample_type       |= PERF_SAMPLE_ADDR;
+               attr->mmap_data = track;
+       }
 
        if (call_graph)
                attr->sample_type       |= PERF_SAMPLE_CALLCHAIN;
 
+       if (system_wide)
+               attr->sample_type       |= PERF_SAMPLE_CPU;
+
        if (raw_samples) {
                attr->sample_type       |= PERF_SAMPLE_TIME;
                attr->sample_type       |= PERF_SAMPLE_RAW;
@@ -300,7 +306,7 @@ try_again:
                                die("Permission error - are you root?\n"
                                        "\t Consider tweaking"
                                        " /proc/sys/kernel/perf_event_paranoid.\n");
-                       else if (err ==  ENODEV && profile_cpu != -1) {
+                       else if (err ==  ENODEV && cpu_list) {
                                die("No such device - did you specify"
                                        " an out-of-range profile CPU?\n");
                        }
@@ -433,14 +439,14 @@ static void atexit_header(void)
 
                process_buildids();
                perf_header__write(&session->header, output, true);
+               perf_session__delete(session);
+               symbol__exit();
        }
 }
 
 static void event__synthesize_guest_os(struct machine *machine, void *data)
 {
        int err;
-       char *guest_kallsyms;
-       char path[PATH_MAX];
        struct perf_session *psession = data;
 
        if (machine__is_host(machine))
@@ -460,13 +466,6 @@ static void event__synthesize_guest_os(struct machine *machine, void *data)
                pr_err("Couldn't record guest kernel [%d]'s reference"
                       " relocation symbol.\n", machine->pid);
 
-       if (machine__is_default_guest(machine))
-               guest_kallsyms = (char *) symbol_conf.default_guest_kallsyms;
-       else {
-               sprintf(path, "%s/proc/kallsyms", machine->root_dir);
-               guest_kallsyms = path;
-       }
-
        /*
         * We use _stext for guest kernel because guest kernel's /proc/kallsyms
         * have no _text sometimes.
@@ -561,12 +560,15 @@ static int __cmd_record(int argc, const char **argv)
        if (!file_new) {
                err = perf_header__read(session, output);
                if (err < 0)
-                       return err;
+                       goto out_delete_session;
        }
 
        if (have_tracepoints(attrs, nr_counters))
                perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
 
+       /*
+        * perf_session__delete(session) will be called at atexit_header()
+        */
        atexit(atexit_header);
 
        if (forks) {
@@ -622,10 +624,15 @@ static int __cmd_record(int argc, const char **argv)
                close(child_ready_pipe[0]);
        }
 
-       if ((!system_wide && no_inherit) || profile_cpu != -1) {
-               open_counters(profile_cpu);
+       nr_cpus = read_cpu_map(cpu_list);
+       if (nr_cpus < 1) {
+               perror("failed to collect number of CPUs\n");
+               return -1;
+       }
+
+       if (!system_wide && no_inherit && !cpu_list) {
+               open_counters(-1);
        } else {
-               nr_cpus = read_cpu_map();
                for (i = 0; i < nr_cpus; i++)
                        open_counters(cpumap[i]);
        }
@@ -704,7 +711,7 @@ static int __cmd_record(int argc, const char **argv)
        if (perf_guest)
                perf_session__process_machines(session, event__synthesize_guest_os);
 
-       if (!system_wide && profile_cpu == -1)
+       if (!system_wide)
                event__synthesize_thread(target_tid, process_synthesized_event,
                                         session);
        else
@@ -766,6 +773,10 @@ static int __cmd_record(int argc, const char **argv)
                bytes_written / 24);
 
        return 0;
+
+out_delete_session:
+       perf_session__delete(session);
+       return err;
 }
 
 static const char * const record_usage[] = {
@@ -794,8 +805,8 @@ static const struct option options[] = {
                            "system-wide collection from all CPUs"),
        OPT_BOOLEAN('A', "append", &append_file,
                            "append to the output file to do incremental profiling"),
-       OPT_INTEGER('C', "profile_cpu", &profile_cpu,
-                           "CPU to profile on"),
+       OPT_STRING('C', "cpu", &cpu_list, "cpu",
+                   "list of cpus to monitor"),
        OPT_BOOLEAN('f', "force", &force,
                        "overwrite existing data file (deprecated)"),
        OPT_U64('c', "count", &user_interval, "event period to sample"),
@@ -815,17 +826,19 @@ static const struct option options[] = {
                    "Sample addresses"),
        OPT_BOOLEAN('n', "no-samples", &no_samples,
                    "don't sample"),
+       OPT_BOOLEAN('N', "no-buildid-cache", &no_buildid,
+                   "do not update the buildid cache"),
        OPT_END()
 };
 
 int cmd_record(int argc, const char **argv, const char *prefix __used)
 {
-       int i,j;
+       int i, j, err = -ENOMEM;
 
        argc = parse_options(argc, argv, options, record_usage,
                            PARSE_OPT_STOP_AT_NON_OPTION);
        if (!argc && target_pid == -1 && target_tid == -1 &&
-               !system_wide && profile_cpu == -1)
+               !system_wide && !cpu_list)
                usage_with_options(record_usage, options);
 
        if (force && append_file) {
@@ -839,6 +852,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
        }
 
        symbol__init();
+       if (no_buildid)
+               disable_buildid_cache();
 
        if (!nr_counters) {
                nr_counters     = 1;
@@ -857,7 +872,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
        } else {
                all_tids=malloc(sizeof(pid_t));
                if (!all_tids)
-                       return -ENOMEM;
+                       goto out_symbol_exit;
 
                all_tids[0] = target_tid;
                thread_num = 1;
@@ -867,13 +882,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
                for (j = 0; j < MAX_COUNTERS; j++) {
                        fd[i][j] = malloc(sizeof(int)*thread_num);
                        if (!fd[i][j])
-                               return -ENOMEM;
+                               goto out_free_fd;
                }
        }
        event_array = malloc(
                sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
        if (!event_array)
-               return -ENOMEM;
+               goto out_free_fd;
 
        if (user_interval != ULLONG_MAX)
                default_interval = user_interval;
@@ -889,8 +904,22 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
                default_interval = freq;
        } else {
                fprintf(stderr, "frequency and count are zero, aborting\n");
-               exit(EXIT_FAILURE);
+               err = -EINVAL;
+               goto out_free_event_array;
        }
 
-       return __cmd_record(argc, argv);
+       err = __cmd_record(argc, argv);
+
+out_free_event_array:
+       free(event_array);
+out_free_fd:
+       for (i = 0; i < MAX_NR_CPUS; i++) {
+               for (j = 0; j < MAX_COUNTERS; j++)
+                       free(fd[i][j]);
+       }
+       free(all_tids);
+       all_tids = NULL;
+out_symbol_exit:
+       symbol__exit();
+       return err;
 }
index fd7407c7205c7be809ce4c3b048e68ab9b7b9487..2f4b92925b2619a85d615ed109851c78619f4465 100644 (file)
@@ -155,30 +155,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        struct addr_location al;
        struct perf_event_attr *attr;
 
-       event__parse_sample(event, session->sample_type, &data);
-
-       dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
-                   data.pid, data.tid, data.ip, data.period);
-
-       if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
-               unsigned int i;
-
-               dump_printf("... chain: nr:%Lu\n", data.callchain->nr);
-
-               if (!ip_callchain__valid(data.callchain, event)) {
-                       pr_debug("call-chain problem with event, "
-                                "skipping it.\n");
-                       return 0;
-               }
-
-               if (dump_trace) {
-                       for (i = 0; i < data.callchain->nr; i++)
-                               dump_printf("..... %2d: %016Lx\n",
-                                           i, data.callchain->ips[i]);
-               }
-       }
-
-       if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+       if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) {
                fprintf(stderr, "problem processing %d event, skipping it.\n",
                        event->header.type);
                return -1;
@@ -464,8 +441,6 @@ static const struct option options[] = {
                   "pretty printing style key: normal raw"),
        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
                   "sort by key(s): pid, comm, dso, symbol, parent"),
-       OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths,
-                   "Don't shorten the pathnames taking into account the cwd"),
        OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
                    "Show sample percentage for different cpu modes"),
        OPT_STRING('p', "parent", &parent_pattern, "regex",
index 9a39ca3c3ac4fe77f5ed23c82b8dc8cc973b9f51..a6b4d44f950246e27d4cb6b0bc3e6d5afd27adcc 100644 (file)
@@ -69,7 +69,7 @@ static struct perf_event_attr default_attrs[] = {
 };
 
 static bool                    system_wide                     =  false;
-static unsigned int            nr_cpus                         =  0;
+static int                     nr_cpus                         =  0;
 static int                     run_idx                         =  0;
 
 static int                     run_count                       =  1;
@@ -82,6 +82,7 @@ static int                    thread_num                      =  0;
 static pid_t                   child_pid                       = -1;
 static bool                    null_run                        =  false;
 static bool                    big_num                         =  false;
+static const char              *cpu_list;
 
 
 static int                     *fd[MAX_NR_CPUS][MAX_COUNTERS];
@@ -158,7 +159,7 @@ static int create_perf_stat_counter(int counter)
                                    PERF_FORMAT_TOTAL_TIME_RUNNING;
 
        if (system_wide) {
-               unsigned int cpu;
+               int cpu;
 
                for (cpu = 0; cpu < nr_cpus; cpu++) {
                        fd[cpu][counter][0] = sys_perf_event_open(attr,
@@ -208,7 +209,7 @@ static inline int nsec_counter(int counter)
 static void read_counter(int counter)
 {
        u64 count[3], single_count[3];
-       unsigned int cpu;
+       int cpu;
        size_t res, nv;
        int scaled;
        int i, thread;
@@ -542,6 +543,8 @@ static const struct option options[] = {
                    "null run - dont start any counters"),
        OPT_BOOLEAN('B', "big-num", &big_num,
                    "print large numbers with thousands\' separators"),
+       OPT_STRING('C', "cpu", &cpu_list, "cpu",
+                   "list of cpus to monitor in system-wide"),
        OPT_END()
 };
 
@@ -566,10 +569,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
        }
 
        if (system_wide)
-               nr_cpus = read_cpu_map();
+               nr_cpus = read_cpu_map(cpu_list);
        else
                nr_cpus = 1;
 
+       if (nr_cpus < 1)
+               usage_with_options(stat_usage, options);
+
        if (target_pid != -1) {
                target_tid = target_pid;
                thread_num = find_all_tid(target_pid, &all_tids);
index a66f4272b994b546b0c2a811b0f1f613a4100a9a..b513e40974f46bf45f816d658d78d574762f5b17 100644 (file)
@@ -102,6 +102,7 @@ struct sym_entry            *sym_filter_entry_sched         =   NULL;
 static int                     sym_pcnt_filter                 =      5;
 static int                     sym_counter                     =      0;
 static int                     display_weighted                =     -1;
+static const char              *cpu_list;
 
 /*
  * Symbols
@@ -982,6 +983,7 @@ static void event__process_sample(const event_t *self,
        u64 ip = self->ip.ip;
        struct sym_entry *syme;
        struct addr_location al;
+       struct sample_data data;
        struct machine *machine;
        u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
@@ -1024,7 +1026,8 @@ static void event__process_sample(const event_t *self,
        if (self->header.misc & PERF_RECORD_MISC_EXACT_IP)
                exact_samples++;
 
-       if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
+       if (event__preprocess_sample(self, session, &al, &data,
+                                    symbol_filter) < 0 ||
            al.filtered)
                return;
 
@@ -1079,26 +1082,6 @@ static void event__process_sample(const event_t *self,
        }
 }
 
-static int event__process(event_t *event, struct perf_session *session)
-{
-       switch (event->header.type) {
-       case PERF_RECORD_COMM:
-               event__process_comm(event, session);
-               break;
-       case PERF_RECORD_MMAP:
-               event__process_mmap(event, session);
-               break;
-       case PERF_RECORD_FORK:
-       case PERF_RECORD_EXIT:
-               event__process_task(event, session);
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
 struct mmap_data {
        int                     counter;
        void                    *base;
@@ -1351,8 +1334,8 @@ static const struct option options[] = {
                    "profile events on existing thread id"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                            "system-wide collection from all CPUs"),
-       OPT_INTEGER('C', "CPU", &profile_cpu,
-                   "CPU to profile on"),
+       OPT_STRING('C', "cpu", &cpu_list, "cpu",
+                   "list of cpus to monitor"),
        OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
                   "file", "vmlinux pathname"),
        OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols,
@@ -1428,10 +1411,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
                return -ENOMEM;
 
        /* CPU and PID are mutually exclusive */
-       if (target_tid > 0 && profile_cpu != -1) {
+       if (target_tid > 0 && cpu_list) {
                printf("WARNING: PID switch overriding CPU\n");
                sleep(1);
-               profile_cpu = -1;
+               cpu_list = NULL;
        }
 
        if (!nr_counters)
@@ -1469,10 +1452,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
                attrs[counter].sample_period = default_interval;
        }
 
-       if (target_tid != -1 || profile_cpu != -1)
+       if (target_tid != -1)
                nr_cpus = 1;
        else
-               nr_cpus = read_cpu_map();
+               nr_cpus = read_cpu_map(cpu_list);
+
+       if (nr_cpus < 1)
+               usage_with_options(top_usage, options);
 
        get_term_dimensions(&winsize);
        if (print_entries == 0) {
index dddf3f01b5ab3c91db25611ac4a2ed6c5adcf064..294da725a57d12867788baa9c5ea98c410486cdf 100644 (file)
@@ -11,8 +11,9 @@
 
 static char const              *script_name;
 static char const              *generate_script_lang;
-static bool                    debug_ordering;
+static bool                    debug_mode;
 static u64                     last_timestamp;
+static u64                     nr_unordered;
 
 static int default_start_script(const char *script __unused,
                                int argc __unused,
@@ -91,13 +92,15 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        }
 
        if (session->sample_type & PERF_SAMPLE_RAW) {
-               if (debug_ordering) {
+               if (debug_mode) {
                        if (data.time < last_timestamp) {
                                pr_err("Samples misordered, previous: %llu "
                                        "this: %llu\n", last_timestamp,
                                        data.time);
+                               nr_unordered++;
                        }
                        last_timestamp = data.time;
+                       return 0;
                }
                /*
                 * FIXME: better resolve from pid from the struct trace_entry
@@ -113,6 +116,15 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        return 0;
 }
 
+static u64 nr_lost;
+
+static int process_lost_event(event_t *event, struct perf_session *session __used)
+{
+       nr_lost += event->lost.lost;
+
+       return 0;
+}
+
 static struct perf_event_ops event_ops = {
        .sample = process_sample_event,
        .comm   = event__process_comm,
@@ -120,6 +132,7 @@ static struct perf_event_ops event_ops = {
        .event_type = event__process_event_type,
        .tracing_data = event__process_tracing_data,
        .build_id = event__process_build_id,
+       .lost = process_lost_event,
        .ordered_samples = true,
 };
 
@@ -132,9 +145,18 @@ static void sig_handler(int sig __unused)
 
 static int __cmd_trace(struct perf_session *session)
 {
+       int ret;
+
        signal(SIGINT, sig_handler);
 
-       return perf_session__process_events(session, &event_ops);
+       ret = perf_session__process_events(session, &event_ops);
+
+       if (debug_mode) {
+               pr_err("Misordered timestamps: %llu\n", nr_unordered);
+               pr_err("Lost events: %llu\n", nr_lost);
+       }
+
+       return ret;
 }
 
 struct script_spec {
@@ -544,8 +566,8 @@ static const struct option options[] = {
                   "generate perf-trace.xx script in specified language"),
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
-       OPT_BOOLEAN('d', "debug-ordering", &debug_ordering,
-                  "check that samples time ordering is monotonic"),
+       OPT_BOOLEAN('d', "debug-mode", &debug_mode,
+                  "do various checks like samples ordering and lost events"),
 
        OPT_END()
 };
diff --git a/tools/perf/feature-tests.mak b/tools/perf/feature-tests.mak
new file mode 100644 (file)
index 0000000..ddb68e6
--- /dev/null
@@ -0,0 +1,119 @@
+define SOURCE_HELLO
+#include <stdio.h>
+int main(void)
+{
+       return puts(\"hi\");
+}
+endef
+
+ifndef NO_DWARF
+define SOURCE_DWARF
+#include <dwarf.h>
+#include <libdw.h>
+#include <version.h>
+#ifndef _ELFUTILS_PREREQ
+#error
+#endif
+
+int main(void)
+{
+       Dwarf *dbg = dwarf_begin(0, DWARF_C_READ);
+       return (long)dbg;
+}
+endef
+endif
+
+define SOURCE_LIBELF
+#include <libelf.h>
+
+int main(void)
+{
+       Elf *elf = elf_begin(0, ELF_C_READ, 0);
+       return (long)elf;
+}
+endef
+
+define SOURCE_GLIBC
+#include <gnu/libc-version.h>
+
+int main(void)
+{
+       const char *version = gnu_get_libc_version();
+       return (long)version;
+}
+endef
+
+define SOURCE_ELF_MMAP
+#include <libelf.h>
+int main(void)
+{
+       Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0);
+       return (long)elf;
+}
+endef
+
+ifndef NO_NEWT
+define SOURCE_NEWT
+#include <newt.h>
+
+int main(void)
+{
+       newtInit();
+       newtCls();
+       return newtFinished();
+}
+endef
+endif
+
+ifndef NO_LIBPERL
+define SOURCE_PERL_EMBED
+#include <EXTERN.h>
+#include <perl.h>
+
+int main(void)
+{
+perl_alloc();
+return 0;
+}
+endef
+endif
+
+ifndef NO_LIBPYTHON
+define SOURCE_PYTHON_EMBED
+#include <Python.h>
+
+int main(void)
+{
+       Py_Initialize();
+       return 0;
+}
+endef
+endif
+
+define SOURCE_BFD
+#include <bfd.h>
+
+int main(void)
+{
+       bfd_demangle(0, 0, 0);
+       return 0;
+}
+endef
+
+define SOURCE_CPLUS_DEMANGLE
+extern char *cplus_demangle(const char *, int);
+
+int main(void)
+{
+       cplus_demangle(0, 0);
+       return 0;
+}
+endef
+
+# try-cc
+# Usage: option = $(call try-cc, source-to-build, cc-options)
+try-cc = $(shell sh -c                                           \
+       'TMP="$(TMPOUT).$$$$";                                    \
+        echo "$(1)" |                                            \
+        $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
+        rm -f "$$TMP"')
index 2e7a4f417e2065c336614f853554357146bb73ce..677e59d62a8dc3ae0475ab31d8c78acaeca50e51 100644 (file)
@@ -7,7 +7,17 @@ if [ $# -ne 0 ] ; then
        PERF_DATA=$1
 fi
 
-DEBUGDIR=~/.debug/
+#
+# PERF_BUILDID_DIR environment variable set by perf
+# path to buildid directory, default to $HOME/.debug
+#
+if [ -z $PERF_BUILDID_DIR ]; then
+       PERF_BUILDID_DIR=~/.debug/
+else
+        # append / to make substitutions work
+        PERF_BUILDID_DIR=$PERF_BUILDID_DIR/
+fi
+
 BUILDIDS=$(mktemp /tmp/perf-archive-buildids.XXXXXX)
 NOBUILDID=0000000000000000000000000000000000000000
 
@@ -22,13 +32,13 @@ MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX)
 
 cut -d ' ' -f 1 $BUILDIDS | \
 while read build_id ; do
-       linkname=$DEBUGDIR.build-id/${build_id:0:2}/${build_id:2}
+       linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2}
        filename=$(readlink -f $linkname)
-       echo ${linkname#$DEBUGDIR} >> $MANIFEST
-       echo ${filename#$DEBUGDIR} >> $MANIFEST
+       echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST
+       echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST
 done
 
-tar cfj $PERF_DATA.tar.bz2 -C $DEBUGDIR -T $MANIFEST
+tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST
 rm -f $MANIFEST $BUILDIDS
 echo -e "Now please run:\n"
 echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n"
index 6e4871191138970e57ea0dbeedf185eabb4ce0c1..cdd6c03f1e14c132e550b85e07b22e7621a710d2 100644 (file)
@@ -458,6 +458,8 @@ int main(int argc, const char **argv)
        handle_options(&argv, &argc, NULL);
        commit_pager_choice();
        set_debugfs_path();
+       set_buildid_dir();
+
        if (argc > 0) {
                if (!prefixcmp(argv[0], "--"))
                        argv[0] += 2;
index 1dc464ee2ca8817042107f1cd222ef22e3f79460..aad7525bca1dc5a45ca72cd4be79eec7411a2bb0 100644 (file)
@@ -89,3 +89,33 @@ def trace_flag_str(value):
            value &= ~idx
 
     return string
+
+
+def taskState(state):
+       states = {
+               0 : "R",
+               1 : "S",
+               2 : "D",
+               64: "DEAD"
+       }
+
+       if state not in states:
+               return "Unknown"
+
+       return states[state]
+
+
+class EventHeaders:
+       def __init__(self, common_cpu, common_secs, common_nsecs,
+                    common_pid, common_comm):
+               self.cpu = common_cpu
+               self.secs = common_secs
+               self.nsecs = common_nsecs
+               self.pid = common_pid
+               self.comm = common_comm
+
+       def ts(self):
+               return (self.secs * (10 ** 9)) + self.nsecs
+
+       def ts_format(self):
+               return "%d.%d" % (self.secs, int(self.nsecs / 1000))
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py
new file mode 100644 (file)
index 0000000..ae9a56e
--- /dev/null
@@ -0,0 +1,184 @@
+# SchedGui.py - Python extension for perf trace, basic GUI code for
+#              traces drawing and overview.
+#
+# Copyright (C) 2010 by Frederic Weisbecker <fweisbec@gmail.com>
+#
+# This software is distributed under the terms of the GNU General
+# Public License ("GPL") version 2 as published by the Free Software
+# Foundation.
+
+
+try:
+       import wx
+except ImportError:
+       raise ImportError, "You need to install the wxpython lib for this script"
+
+
+class RootFrame(wx.Frame):
+       Y_OFFSET = 100
+       RECT_HEIGHT = 100
+       RECT_SPACE = 50
+       EVENT_MARKING_WIDTH = 5
+
+       def __init__(self, sched_tracer, title, parent = None, id = -1):
+               wx.Frame.__init__(self, parent, id, title)
+
+               (self.screen_width, self.screen_height) = wx.GetDisplaySize()
+               self.screen_width -= 10
+               self.screen_height -= 10
+               self.zoom = 0.5
+               self.scroll_scale = 20
+               self.sched_tracer = sched_tracer
+               self.sched_tracer.set_root_win(self)
+               (self.ts_start, self.ts_end) = sched_tracer.interval()
+               self.update_width_virtual()
+               self.nr_rects = sched_tracer.nr_rectangles() + 1
+               self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
+
+               # whole window panel
+               self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
+
+               # scrollable container
+               self.scroll = wx.ScrolledWindow(self.panel)
+               self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
+               self.scroll.EnableScrolling(True, True)
+               self.scroll.SetFocus()
+
+               # scrollable drawing area
+               self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
+               self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
+               self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
+               self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
+               self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
+               self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
+               self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
+
+               self.scroll.Fit()
+               self.Fit()
+
+               self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
+
+               self.txt = None
+
+               self.Show(True)
+
+       def us_to_px(self, val):
+               return val / (10 ** 3) * self.zoom
+
+       def px_to_us(self, val):
+               return (val / self.zoom) * (10 ** 3)
+
+       def scroll_start(self):
+               (x, y) = self.scroll.GetViewStart()
+               return (x * self.scroll_scale, y * self.scroll_scale)
+
+       def scroll_start_us(self):
+               (x, y) = self.scroll_start()
+               return self.px_to_us(x)
+
+       def paint_rectangle_zone(self, nr, color, top_color, start, end):
+               offset_px = self.us_to_px(start - self.ts_start)
+               width_px = self.us_to_px(end - self.ts_start)
+
+               offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
+               width_py = RootFrame.RECT_HEIGHT
+
+               dc = self.dc
+
+               if top_color is not None:
+                       (r, g, b) = top_color
+                       top_color = wx.Colour(r, g, b)
+                       brush = wx.Brush(top_color, wx.SOLID)
+                       dc.SetBrush(brush)
+                       dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
+                       width_py -= RootFrame.EVENT_MARKING_WIDTH
+                       offset_py += RootFrame.EVENT_MARKING_WIDTH
+
+               (r ,g, b) = color
+               color = wx.Colour(r, g, b)
+               brush = wx.Brush(color, wx.SOLID)
+               dc.SetBrush(brush)
+               dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
+
+       def update_rectangles(self, dc, start, end):
+               start += self.ts_start
+               end += self.ts_start
+               self.sched_tracer.fill_zone(start, end)
+
+       def on_paint(self, event):
+               dc = wx.PaintDC(self.scroll_panel)
+               self.dc = dc
+
+               width = min(self.width_virtual, self.screen_width)
+               (x, y) = self.scroll_start()
+               start = self.px_to_us(x)
+               end = self.px_to_us(x + width)
+               self.update_rectangles(dc, start, end)
+
+       def rect_from_ypixel(self, y):
+               y -= RootFrame.Y_OFFSET
+               rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
+               height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
+
+               if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
+                       return -1
+
+               return rect
+
+       def update_summary(self, txt):
+               if self.txt:
+                       self.txt.Destroy()
+               self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
+
+
+       def on_mouse_down(self, event):
+               (x, y) = event.GetPositionTuple()
+               rect = self.rect_from_ypixel(y)
+               if rect == -1:
+                       return
+
+               t = self.px_to_us(x) + self.ts_start
+
+               self.sched_tracer.mouse_down(rect, t)
+
+
+       def update_width_virtual(self):
+               self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
+
+       def __zoom(self, x):
+               self.update_width_virtual()
+               (xpos, ypos) = self.scroll.GetViewStart()
+               xpos = self.us_to_px(x) / self.scroll_scale
+               self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
+               self.Refresh()
+
+       def zoom_in(self):
+               x = self.scroll_start_us()
+               self.zoom *= 2
+               self.__zoom(x)
+
+       def zoom_out(self):
+               x = self.scroll_start_us()
+               self.zoom /= 2
+               self.__zoom(x)
+
+
+       def on_key_press(self, event):
+               key = event.GetRawKeyCode()
+               if key == ord("+"):
+                       self.zoom_in()
+                       return
+               if key == ord("-"):
+                       self.zoom_out()
+                       return
+
+               key = event.GetKeyCode()
+               (x, y) = self.scroll.GetViewStart()
+               if key == wx.WXK_RIGHT:
+                       self.scroll.Scroll(x + 1, y)
+               elif key == wx.WXK_LEFT:
+                       self.scroll.Scroll(x - 1, y)
+               elif key == wx.WXK_DOWN:
+                       self.scroll.Scroll(x, y + 1)
+               elif key == wx.WXK_UP:
+                       self.scroll.Scroll(x, y - 1)
diff --git a/tools/perf/scripts/python/bin/sched-migration-record b/tools/perf/scripts/python/bin/sched-migration-record
new file mode 100644 (file)
index 0000000..17a3e9b
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -m 16384 -a -e sched:sched_wakeup -e sched:sched_wakeup_new -e sched:sched_switch -e sched:sched_migrate_task $@
diff --git a/tools/perf/scripts/python/bin/sched-migration-report b/tools/perf/scripts/python/bin/sched-migration-report
new file mode 100644 (file)
index 0000000..61d05f7
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/bash
+# description: sched migration overview
+perf trace $@ -s ~/libexec/perf-core/scripts/python/sched-migration.py
diff --git a/tools/perf/scripts/python/sched-migration.py b/tools/perf/scripts/python/sched-migration.py
new file mode 100644 (file)
index 0000000..b934383
--- /dev/null
@@ -0,0 +1,461 @@
+#!/usr/bin/python
+#
+# Cpu task migration overview toy
+#
+# Copyright (C) 2010 Frederic Weisbecker <fweisbec@gmail.com>
+#
+# perf trace event handlers have been generated by perf trace -g python
+#
+# This software is distributed under the terms of the GNU General
+# Public License ("GPL") version 2 as published by the Free Software
+# Foundation.
+
+
+import os
+import sys
+
+from collections import defaultdict
+from UserList import UserList
+
+sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+       '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+sys.path.append('scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+
+from perf_trace_context import *
+from Core import *
+from SchedGui import *
+
+
+threads = { 0 : "idle"}
+
+def thread_name(pid):
+       return "%s:%d" % (threads[pid], pid)
+
+class RunqueueEventUnknown:
+       @staticmethod
+       def color():
+               return None
+
+       def __repr__(self):
+               return "unknown"
+
+class RunqueueEventSleep:
+       @staticmethod
+       def color():
+               return (0, 0, 0xff)
+
+       def __init__(self, sleeper):
+               self.sleeper = sleeper
+
+       def __repr__(self):
+               return "%s gone to sleep" % thread_name(self.sleeper)
+
+class RunqueueEventWakeup:
+       @staticmethod
+       def color():
+               return (0xff, 0xff, 0)
+
+       def __init__(self, wakee):
+               self.wakee = wakee
+
+       def __repr__(self):
+               return "%s woke up" % thread_name(self.wakee)
+
+class RunqueueEventFork:
+       @staticmethod
+       def color():
+               return (0, 0xff, 0)
+
+       def __init__(self, child):
+               self.child = child
+
+       def __repr__(self):
+               return "new forked task %s" % thread_name(self.child)
+
+class RunqueueMigrateIn:
+       @staticmethod
+       def color():
+               return (0, 0xf0, 0xff)
+
+       def __init__(self, new):
+               self.new = new
+
+       def __repr__(self):
+               return "task migrated in %s" % thread_name(self.new)
+
+class RunqueueMigrateOut:
+       @staticmethod
+       def color():
+               return (0xff, 0, 0xff)
+
+       def __init__(self, old):
+               self.old = old
+
+       def __repr__(self):
+               return "task migrated out %s" % thread_name(self.old)
+
+class RunqueueSnapshot:
+       def __init__(self, tasks = [0], event = RunqueueEventUnknown()):
+               self.tasks = tuple(tasks)
+               self.event = event
+
+       def sched_switch(self, prev, prev_state, next):
+               event = RunqueueEventUnknown()
+
+               if taskState(prev_state) == "R" and next in self.tasks \
+                       and prev in self.tasks:
+                       return self
+
+               if taskState(prev_state) != "R":
+                       event = RunqueueEventSleep(prev)
+
+               next_tasks = list(self.tasks[:])
+               if prev in self.tasks:
+                       if taskState(prev_state) != "R":
+                               next_tasks.remove(prev)
+               elif taskState(prev_state) == "R":
+                       next_tasks.append(prev)
+
+               if next not in next_tasks:
+                       next_tasks.append(next)
+
+               return RunqueueSnapshot(next_tasks, event)
+
+       def migrate_out(self, old):
+               if old not in self.tasks:
+                       return self
+               next_tasks = [task for task in self.tasks if task != old]
+
+               return RunqueueSnapshot(next_tasks, RunqueueMigrateOut(old))
+
+       def __migrate_in(self, new, event):
+               if new in self.tasks:
+                       self.event = event
+                       return self
+               next_tasks = self.tasks[:] + tuple([new])
+
+               return RunqueueSnapshot(next_tasks, event)
+
+       def migrate_in(self, new):
+               return self.__migrate_in(new, RunqueueMigrateIn(new))
+
+       def wake_up(self, new):
+               return self.__migrate_in(new, RunqueueEventWakeup(new))
+
+       def wake_up_new(self, new):
+               return self.__migrate_in(new, RunqueueEventFork(new))
+
+       def load(self):
+               """ Provide the number of tasks on the runqueue.
+                   Don't count idle"""
+               return len(self.tasks) - 1
+
+       def __repr__(self):
+               ret = self.tasks.__repr__()
+               ret += self.origin_tostring()
+
+               return ret
+
+class TimeSlice:
+       def __init__(self, start, prev):
+               self.start = start
+               self.prev = prev
+               self.end = start
+               # cpus that triggered the event
+               self.event_cpus = []
+               if prev is not None:
+                       self.total_load = prev.total_load
+                       self.rqs = prev.rqs.copy()
+               else:
+                       self.rqs = defaultdict(RunqueueSnapshot)
+                       self.total_load = 0
+
+       def __update_total_load(self, old_rq, new_rq):
+               diff = new_rq.load() - old_rq.load()
+               self.total_load += diff
+
+       def sched_switch(self, ts_list, prev, prev_state, next, cpu):
+               old_rq = self.prev.rqs[cpu]
+               new_rq = old_rq.sched_switch(prev, prev_state, next)
+
+               if old_rq is new_rq:
+                       return
+
+               self.rqs[cpu] = new_rq
+               self.__update_total_load(old_rq, new_rq)
+               ts_list.append(self)
+               self.event_cpus = [cpu]
+
+       def migrate(self, ts_list, new, old_cpu, new_cpu):
+               if old_cpu == new_cpu:
+                       return
+               old_rq = self.prev.rqs[old_cpu]
+               out_rq = old_rq.migrate_out(new)
+               self.rqs[old_cpu] = out_rq
+               self.__update_total_load(old_rq, out_rq)
+
+               new_rq = self.prev.rqs[new_cpu]
+               in_rq = new_rq.migrate_in(new)
+               self.rqs[new_cpu] = in_rq
+               self.__update_total_load(new_rq, in_rq)
+
+               ts_list.append(self)
+
+               if old_rq is not out_rq:
+                       self.event_cpus.append(old_cpu)
+               self.event_cpus.append(new_cpu)
+
+       def wake_up(self, ts_list, pid, cpu, fork):
+               old_rq = self.prev.rqs[cpu]
+               if fork:
+                       new_rq = old_rq.wake_up_new(pid)
+               else:
+                       new_rq = old_rq.wake_up(pid)
+
+               if new_rq is old_rq:
+                       return
+               self.rqs[cpu] = new_rq
+               self.__update_total_load(old_rq, new_rq)
+               ts_list.append(self)
+               self.event_cpus = [cpu]
+
+       def next(self, t):
+               self.end = t
+               return TimeSlice(t, self)
+
+class TimeSliceList(UserList):
+       def __init__(self, arg = []):
+               self.data = arg
+
+       def get_time_slice(self, ts):
+               if len(self.data) == 0:
+                       slice = TimeSlice(ts, TimeSlice(-1, None))
+               else:
+                       slice = self.data[-1].next(ts)
+               return slice
+
+       def find_time_slice(self, ts):
+               start = 0
+               end = len(self.data)
+               found = -1
+               searching = True
+               while searching:
+                       if start == end or start == end - 1:
+                               searching = False
+
+                       i = (end + start) / 2
+                       if self.data[i].start <= ts and self.data[i].end >= ts:
+                               found = i
+                               end = i
+                               continue
+
+                       if self.data[i].end < ts:
+                               start = i
+
+                       elif self.data[i].start > ts:
+                               end = i
+
+               return found
+
+       def set_root_win(self, win):
+               self.root_win = win
+
+       def mouse_down(self, cpu, t):
+               idx = self.find_time_slice(t)
+               if idx == -1:
+                       return
+
+               ts = self[idx]
+               rq = ts.rqs[cpu]
+               raw = "CPU: %d\n" % cpu
+               raw += "Last event : %s\n" % rq.event.__repr__()
+               raw += "Timestamp : %d.%06d\n" % (ts.start / (10 ** 9), (ts.start % (10 ** 9)) / 1000)
+               raw += "Duration : %6d us\n" % ((ts.end - ts.start) / (10 ** 6))
+               raw += "Load = %d\n" % rq.load()
+               for t in rq.tasks:
+                       raw += "%s \n" % thread_name(t)
+
+               self.root_win.update_summary(raw)
+
+       def update_rectangle_cpu(self, slice, cpu):
+               rq = slice.rqs[cpu]
+
+               if slice.total_load != 0:
+                       load_rate = rq.load() / float(slice.total_load)
+               else:
+                       load_rate = 0
+
+               red_power = int(0xff - (0xff * load_rate))
+               color = (0xff, red_power, red_power)
+
+               top_color = None
+
+               if cpu in slice.event_cpus:
+                       top_color = rq.event.color()
+
+               self.root_win.paint_rectangle_zone(cpu, color, top_color, slice.start, slice.end)
+
+       def fill_zone(self, start, end):
+               i = self.find_time_slice(start)
+               if i == -1:
+                       return
+
+               for i in xrange(i, len(self.data)):
+                       timeslice = self.data[i]
+                       if timeslice.start > end:
+                               return
+
+                       for cpu in timeslice.rqs:
+                               self.update_rectangle_cpu(timeslice, cpu)
+
+       def interval(self):
+               if len(self.data) == 0:
+                       return (0, 0)
+
+               return (self.data[0].start, self.data[-1].end)
+
+       def nr_rectangles(self):
+               last_ts = self.data[-1]
+               max_cpu = 0
+               for cpu in last_ts.rqs:
+                       if cpu > max_cpu:
+                               max_cpu = cpu
+               return max_cpu
+
+
+class SchedEventProxy:
+       def __init__(self):
+               self.current_tsk = defaultdict(lambda : -1)
+               self.timeslices = TimeSliceList()
+
+       def sched_switch(self, headers, prev_comm, prev_pid, prev_prio, prev_state,
+                        next_comm, next_pid, next_prio):
+               """ Ensure the task we sched out this cpu is really the one
+                   we logged. Otherwise we may have missed traces """
+
+               on_cpu_task = self.current_tsk[headers.cpu]
+
+               if on_cpu_task != -1 and on_cpu_task != prev_pid:
+                       print "Sched switch event rejected ts: %s cpu: %d prev: %s(%d) next: %s(%d)" % \
+                               (headers.ts_format(), headers.cpu, prev_comm, prev_pid, next_comm, next_pid)
+
+               threads[prev_pid] = prev_comm
+               threads[next_pid] = next_comm
+               self.current_tsk[headers.cpu] = next_pid
+
+               ts = self.timeslices.get_time_slice(headers.ts())
+               ts.sched_switch(self.timeslices, prev_pid, prev_state, next_pid, headers.cpu)
+
+       def migrate(self, headers, pid, prio, orig_cpu, dest_cpu):
+               ts = self.timeslices.get_time_slice(headers.ts())
+               ts.migrate(self.timeslices, pid, orig_cpu, dest_cpu)
+
+       def wake_up(self, headers, comm, pid, success, target_cpu, fork):
+               if success == 0:
+                       return
+               ts = self.timeslices.get_time_slice(headers.ts())
+               ts.wake_up(self.timeslices, pid, target_cpu, fork)
+
+
+def trace_begin():
+       global parser
+       parser = SchedEventProxy()
+
+def trace_end():
+       app = wx.App(False)
+       timeslices = parser.timeslices
+       frame = RootFrame(timeslices, "Migration")
+       app.MainLoop()
+
+def sched__sched_stat_runtime(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, runtime, vruntime):
+       pass
+
+def sched__sched_stat_iowait(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, delay):
+       pass
+
+def sched__sched_stat_sleep(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, delay):
+       pass
+
+def sched__sched_stat_wait(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, delay):
+       pass
+
+def sched__sched_process_fork(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       parent_comm, parent_pid, child_comm, child_pid):
+       pass
+
+def sched__sched_process_wait(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, prio):
+       pass
+
+def sched__sched_process_exit(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, prio):
+       pass
+
+def sched__sched_process_free(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, prio):
+       pass
+
+def sched__sched_migrate_task(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, prio, orig_cpu,
+       dest_cpu):
+       headers = EventHeaders(common_cpu, common_secs, common_nsecs,
+                               common_pid, common_comm)
+       parser.migrate(headers, pid, prio, orig_cpu, dest_cpu)
+
+def sched__sched_switch(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       prev_comm, prev_pid, prev_prio, prev_state,
+       next_comm, next_pid, next_prio):
+
+       headers = EventHeaders(common_cpu, common_secs, common_nsecs,
+                               common_pid, common_comm)
+       parser.sched_switch(headers, prev_comm, prev_pid, prev_prio, prev_state,
+                        next_comm, next_pid, next_prio)
+
+def sched__sched_wakeup_new(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, prio, success,
+       target_cpu):
+       headers = EventHeaders(common_cpu, common_secs, common_nsecs,
+                               common_pid, common_comm)
+       parser.wake_up(headers, comm, pid, success, target_cpu, 1)
+
+def sched__sched_wakeup(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, prio, success,
+       target_cpu):
+       headers = EventHeaders(common_cpu, common_secs, common_nsecs,
+                               common_pid, common_comm)
+       parser.wake_up(headers, comm, pid, success, target_cpu, 0)
+
+def sched__sched_wait_task(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid, prio):
+       pass
+
+def sched__sched_kthread_stop_ret(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       ret):
+       pass
+
+def sched__sched_kthread_stop(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       comm, pid):
+       pass
+
+def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs,
+               common_pid, common_comm):
+       pass
index 70c5cf87d020d9d44750da480face3820d2ded15..e437edb72417ba2f12e90b810f8851caef2c24fb 100644 (file)
@@ -12,6 +12,7 @@
 #include "event.h"
 #include "symbol.h"
 #include <linux/kernel.h>
+#include "debug.h"
 
 static int build_id__mark_dso_hit(event_t *event, struct perf_session *session)
 {
@@ -34,28 +35,43 @@ static int build_id__mark_dso_hit(event_t *event, struct perf_session *session)
        return 0;
 }
 
+static int event__exit_del_thread(event_t *self, struct perf_session *session)
+{
+       struct thread *thread = perf_session__findnew(session, self->fork.tid);
+
+       dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
+                   self->fork.ppid, self->fork.ptid);
+
+       if (thread) {
+               rb_erase(&thread->rb_node, &session->threads);
+               session->last_match = NULL;
+               thread__delete(thread);
+       }
+
+       return 0;
+}
+
 struct perf_event_ops build_id__mark_dso_hit_ops = {
        .sample = build_id__mark_dso_hit,
        .mmap   = event__process_mmap,
        .fork   = event__process_task,
+       .exit   = event__exit_del_thread,
 };
 
 char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
 {
        char build_id_hex[BUILD_ID_SIZE * 2 + 1];
-       const char *home;
 
        if (!self->has_build_id)
                return NULL;
 
        build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex);
-       home = getenv("HOME");
        if (bf == NULL) {
-               if (asprintf(&bf, "%s/%s/.build-id/%.2s/%s", home,
-                            DEBUG_CACHE_DIR, build_id_hex, build_id_hex + 2) < 0)
+               if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir,
+                            build_id_hex, build_id_hex + 2) < 0)
                        return NULL;
        } else
-               snprintf(bf, size, "%s/%s/.build-id/%.2s/%s", home,
-                        DEBUG_CACHE_DIR, build_id_hex, build_id_hex + 2);
+               snprintf(bf, size, "%s/.build-id/%.2s/%s", buildid_dir,
+                        build_id_hex, build_id_hex + 2);
        return bf;
 }
index 65fe664fddf698e67aa0639169665e64fffbdf61..27e9ebe4076e0efbf4117a46f2dbbcc74a1dcc3e 100644 (file)
@@ -23,6 +23,7 @@ extern int perf_config(config_fn_t fn, void *);
 extern int perf_config_int(const char *, const char *);
 extern int perf_config_bool(const char *, const char *);
 extern int config_error_nonbool(const char *);
+extern const char *perf_config_dirname(const char *, const char *);
 
 /* pager.c */
 extern void setup_pager(void);
index 52c777e451ed8ebc049f39edfb651bfe848d66cc..f231f43424d27930a286cb52902c21cb4534a068 100644 (file)
@@ -18,7 +18,7 @@
 #include "util.h"
 #include "callchain.h"
 
-bool ip_callchain__valid(struct ip_callchain *chain, event_t *event)
+bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event)
 {
        unsigned int chain_size = event->header.size;
        chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
index f2e9ee164bd8ce7bcf2bb7c7af5901e6c78ebcc3..624a96c636fdbc36a472ecaadf5fcb72c226bf38 100644 (file)
@@ -63,5 +63,5 @@ int register_callchain_param(struct callchain_param *param);
 int append_chain(struct callchain_node *root, struct ip_callchain *chain,
                 struct map_symbol *syms, u64 period);
 
-bool ip_callchain__valid(struct ip_callchain *chain, event_t *event);
+bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event);
 #endif /* __PERF_CALLCHAIN_H */
index dabe892d0e5374ad8689040e6865a642e161f752..e02d78cae70f688fc0fc32957d078cf45796ed75 100644 (file)
 
 #define MAXNAME (256)
 
+#define DEBUG_CACHE_DIR ".debug"
+
+
+char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */
+
 static FILE *config_file;
 static const char *config_file_name;
 static int config_linenr;
@@ -127,7 +132,7 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
                        break;
                if (!iskeychar(c))
                        break;
-               name[len++] = tolower(c);
+               name[len++] = c;
                if (len >= MAXNAME)
                        return -1;
        }
@@ -327,6 +332,13 @@ int perf_config_bool(const char *name, const char *value)
        return !!perf_config_bool_or_int(name, value, &discard);
 }
 
+const char *perf_config_dirname(const char *name, const char *value)
+{
+       if (!name)
+               return NULL;
+       return value;
+}
+
 static int perf_default_core_config(const char *var __used, const char *value __used)
 {
        /* Add other config variables here and to Documentation/config.txt. */
@@ -428,3 +440,53 @@ int config_error_nonbool(const char *var)
 {
        return error("Missing value for '%s'", var);
 }
+
+struct buildid_dir_config {
+       char *dir;
+};
+
+static int buildid_dir_command_config(const char *var, const char *value,
+                                     void *data)
+{
+       struct buildid_dir_config *c = data;
+       const char *v;
+
+       /* same dir for all commands */
+       if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) {
+               v = perf_config_dirname(var, value);
+               if (!v)
+                       return -1;
+               strncpy(c->dir, v, MAXPATHLEN-1);
+               c->dir[MAXPATHLEN-1] = '\0';
+       }
+       return 0;
+}
+
+static void check_buildid_dir_config(void)
+{
+       struct buildid_dir_config c;
+       c.dir = buildid_dir;
+       perf_config(buildid_dir_command_config, &c);
+}
+
+void set_buildid_dir(void)
+{
+       buildid_dir[0] = '\0';
+
+       /* try config file */
+       check_buildid_dir_config();
+
+       /* default to $HOME/.debug */
+       if (buildid_dir[0] == '\0') {
+               char *v = getenv("HOME");
+               if (v) {
+                       snprintf(buildid_dir, MAXPATHLEN-1, "%s/%s",
+                                v, DEBUG_CACHE_DIR);
+               } else {
+                       strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1);
+               }
+               buildid_dir[MAXPATHLEN-1] = '\0';
+       }
+       /* for communicating with external commands */
+       setenv("PERF_BUILDID_DIR", buildid_dir, 1);
+}
index 4e01490e51e549c1be5b3e5d640683f65a765f7f..0f9b8d7a7d7e7d62f38c48ec8846251beb532918 100644 (file)
@@ -20,7 +20,7 @@ static int default_cpu_map(void)
        return nr_cpus;
 }
 
-int read_cpu_map(void)
+static int read_all_cpu_map(void)
 {
        FILE *onlnf;
        int nr_cpus = 0;
@@ -57,3 +57,58 @@ int read_cpu_map(void)
 
        return default_cpu_map();
 }
+
+int read_cpu_map(const char *cpu_list)
+{
+       unsigned long start_cpu, end_cpu = 0;
+       char *p = NULL;
+       int i, nr_cpus = 0;
+
+       if (!cpu_list)
+               return read_all_cpu_map();
+
+       if (!isdigit(*cpu_list))
+               goto invalid;
+
+       while (isdigit(*cpu_list)) {
+               p = NULL;
+               start_cpu = strtoul(cpu_list, &p, 0);
+               if (start_cpu >= INT_MAX
+                   || (*p != '\0' && *p != ',' && *p != '-'))
+                       goto invalid;
+
+               if (*p == '-') {
+                       cpu_list = ++p;
+                       p = NULL;
+                       end_cpu = strtoul(cpu_list, &p, 0);
+
+                       if (end_cpu >= INT_MAX || (*p != '\0' && *p != ','))
+                               goto invalid;
+
+                       if (end_cpu < start_cpu)
+                               goto invalid;
+               } else {
+                       end_cpu = start_cpu;
+               }
+
+               for (; start_cpu <= end_cpu; start_cpu++) {
+                       /* check for duplicates */
+                       for (i = 0; i < nr_cpus; i++)
+                               if (cpumap[i] == (int)start_cpu)
+                                       goto invalid;
+
+                       assert(nr_cpus < MAX_NR_CPUS);
+                       cpumap[nr_cpus++] = (int)start_cpu;
+               }
+               if (*p)
+                       ++p;
+
+               cpu_list = p;
+       }
+       if (nr_cpus > 0)
+               return nr_cpus;
+
+       return default_cpu_map();
+invalid:
+       return -1;
+}
index 86c78bb330982619589a11329c5719c03a3bb725..3e60f56e490eb10f8cf08981e703bf5699d6b20c 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __PERF_CPUMAP_H
 #define __PERF_CPUMAP_H
 
-extern int read_cpu_map(void);
+extern int read_cpu_map(const char *cpu_list);
 extern int cpumap[];
 
 #endif /* __PERF_CPUMAP_H */
index 6cddff2bc970b1aeb49322aaf7c5b0028ee5fecd..318dab15d17732a709ab7b72b8db03fb6e08b24f 100644 (file)
@@ -86,12 +86,10 @@ void trace_event(event_t *event)
                        dump_printf_color("  ", color);
                        for (j = 0; j < 15-(i & 15); j++)
                                dump_printf_color("   ", color);
-                       for (j = 0; j < (i & 15); j++) {
-                               if (isprint(raw_event[i-15+j]))
-                                       dump_printf_color("%c", color,
-                                                         raw_event[i-15+j]);
-                               else
-                                       dump_printf_color(".", color);
+                       for (j = i & ~15; j <= i; j++) {
+                               dump_printf_color("%c", color,
+                                               isprint(raw_event[j]) ?
+                                               raw_event[j] : '.');
                        }
                        dump_printf_color("\n", color);
                }
index 2fbf6a463c8174e1fdf56e6714a2e402987c85f4..dab9e754a28103b1727d6dee29669aaa2d7f89da 100644 (file)
@@ -151,7 +151,6 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                        continue;
                pbf += n + 3;
                if (*pbf == 'x') { /* vm_exec */
-                       u64 vm_pgoff;
                        char *execname = strchr(bf, '/');
 
                        /* Catch VDSO */
@@ -162,12 +161,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                                continue;
 
                        pbf += 3;
-                       n = hex2u64(pbf, &vm_pgoff);
-                       /* pgoff is in bytes, not pages */
-                       if (n >= 0)
-                               ev.mmap.pgoff = vm_pgoff << getpagesize();
-                       else
-                               ev.mmap.pgoff = 0;
+                       n = hex2u64(pbf, &ev.mmap.pgoff);
 
                        size = strlen(execname);
                        execname[size - 1] = '\0'; /* Remove \n */
@@ -340,30 +334,29 @@ int event__synthesize_kernel_mmap(event__handler_t process,
        return process(&ev, session);
 }
 
-static void thread__comm_adjust(struct thread *self)
+static void thread__comm_adjust(struct thread *self, struct hists *hists)
 {
        char *comm = self->comm;
 
        if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
            (!symbol_conf.comm_list ||
             strlist__has_entry(symbol_conf.comm_list, comm))) {
-               unsigned int slen = strlen(comm);
+               u16 slen = strlen(comm);
 
-               if (slen > comms__col_width) {
-                       comms__col_width = slen;
-                       threads__col_width = slen + 6;
-               }
+               if (hists__new_col_len(hists, HISTC_COMM, slen))
+                       hists__set_col_len(hists, HISTC_THREAD, slen + 6);
        }
 }
 
-static int thread__set_comm_adjust(struct thread *self, const char *comm)
+static int thread__set_comm_adjust(struct thread *self, const char *comm,
+                                  struct hists *hists)
 {
        int ret = thread__set_comm(self, comm);
 
        if (ret)
                return ret;
 
-       thread__comm_adjust(self);
+       thread__comm_adjust(self, hists);
 
        return 0;
 }
@@ -374,7 +367,8 @@ int event__process_comm(event_t *self, struct perf_session *session)
 
        dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid);
 
-       if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) {
+       if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm,
+                                                     &session->hists)) {
                dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
                return -1;
        }
@@ -456,6 +450,7 @@ static int event__process_kernel_mmap(event_t *self,
                        goto out_problem;
 
                map->dso->short_name = name;
+               map->dso->sname_alloc = 1;
                map->end = map->start + self->mmap.len;
        } else if (is_kernel_mmap) {
                const char *symbol_name = (self->mmap.filename +
@@ -514,12 +509,13 @@ int event__process_mmap(event_t *self, struct perf_session *session)
        if (machine == NULL)
                goto out_problem;
        thread = perf_session__findnew(session, self->mmap.pid);
+       if (thread == NULL)
+               goto out_problem;
        map = map__new(&machine->user_dsos, self->mmap.start,
                        self->mmap.len, self->mmap.pgoff,
                        self->mmap.pid, self->mmap.filename,
-                       MAP__FUNCTION, session->cwd, session->cwdlen);
-
-       if (thread == NULL || map == NULL)
+                       MAP__FUNCTION);
+       if (map == NULL)
                goto out_problem;
 
        thread__insert_map(thread, map);
@@ -552,6 +548,26 @@ int event__process_task(event_t *self, struct perf_session *session)
        return 0;
 }
 
+int event__process(event_t *event, struct perf_session *session)
+{
+       switch (event->header.type) {
+       case PERF_RECORD_COMM:
+               event__process_comm(event, session);
+               break;
+       case PERF_RECORD_MMAP:
+               event__process_mmap(event, session);
+               break;
+       case PERF_RECORD_FORK:
+       case PERF_RECORD_EXIT:
+               event__process_task(event, session);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 void thread__find_addr_map(struct thread *self,
                           struct perf_session *session, u8 cpumode,
                           enum map_type type, pid_t pid, u64 addr,
@@ -641,27 +657,49 @@ void thread__find_addr_location(struct thread *self,
                al->sym = NULL;
 }
 
-static void dso__calc_col_width(struct dso *self)
+static void dso__calc_col_width(struct dso *self, struct hists *hists)
 {
        if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
            (!symbol_conf.dso_list ||
             strlist__has_entry(symbol_conf.dso_list, self->name))) {
-               u16 slen = self->short_name_len;
-               if (verbose)
-                       slen = self->long_name_len;
-               if (dsos__col_width < slen)
-                       dsos__col_width = slen;
+               u16 slen = dso__name_len(self);
+               hists__new_col_len(hists, HISTC_DSO, slen);
        }
 
        self->slen_calculated = 1;
 }
 
 int event__preprocess_sample(const event_t *self, struct perf_session *session,
-                            struct addr_location *al, symbol_filter_t filter)
+                            struct addr_location *al, struct sample_data *data,
+                            symbol_filter_t filter)
 {
        u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-       struct thread *thread = perf_session__findnew(session, self->ip.pid);
+       struct thread *thread;
 
+       event__parse_sample(self, session->sample_type, data);
+
+       dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n",
+                   self->header.misc, data->pid, data->tid, data->ip,
+                   data->period, data->cpu);
+
+       if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
+               unsigned int i;
+
+               dump_printf("... chain: nr:%Lu\n", data->callchain->nr);
+
+               if (!ip_callchain__valid(data->callchain, self)) {
+                       pr_debug("call-chain problem with event, "
+                                "skipping it.\n");
+                       goto out_filtered;
+               }
+
+               if (dump_trace) {
+                       for (i = 0; i < data->callchain->nr; i++)
+                               dump_printf("..... %2d: %016Lx\n",
+                                           i, data->callchain->ips[i]);
+               }
+       }
+       thread = perf_session__findnew(session, self->ip.pid);
        if (thread == NULL)
                return -1;
 
@@ -687,6 +725,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                    al->map ? al->map->dso->long_name :
                        al->level == 'H' ? "[hypervisor]" : "<not found>");
        al->sym = NULL;
+       al->cpu = data->cpu;
 
        if (al->map) {
                if (symbol_conf.dso_list &&
@@ -703,16 +742,17 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                 * sampled.
                 */
                if (!sort_dso.elide && !al->map->dso->slen_calculated)
-                       dso__calc_col_width(al->map->dso);
+                       dso__calc_col_width(al->map->dso, &session->hists);
 
                al->sym = map__find_symbol(al->map, al->addr, filter);
        } else {
                const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
 
-               if (dsos__col_width < unresolved_col_width &&
+               if (hists__col_len(&session->hists, HISTC_DSO) < unresolved_col_width &&
                    !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
                    !symbol_conf.dso_list)
-                       dsos__col_width = unresolved_col_width;
+                       hists__set_col_len(&session->hists, HISTC_DSO,
+                                          unresolved_col_width);
        }
 
        if (symbol_conf.sym_list && al->sym &&
@@ -726,9 +766,9 @@ out_filtered:
        return 0;
 }
 
-int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
+int event__parse_sample(const event_t *event, u64 type, struct sample_data *data)
 {
-       u64 *array = event->sample.array;
+       const u64 *array = event->sample.array;
 
        if (type & PERF_SAMPLE_IP) {
                data->ip = event->ip.ip;
@@ -767,7 +807,8 @@ int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
                u32 *p = (u32 *)array;
                data->cpu = *p;
                array++;
-       }
+       } else
+               data->cpu = -1;
 
        if (type & PERF_SAMPLE_PERIOD) {
                data->period = *array;
index 8577085db067bb3d7b6a7530fab877b3e28afe96..8e790dae702625aa564594bee1dd52618b94f8d8 100644 (file)
@@ -154,11 +154,13 @@ int event__process_comm(event_t *self, struct perf_session *session);
 int event__process_lost(event_t *self, struct perf_session *session);
 int event__process_mmap(event_t *self, struct perf_session *session);
 int event__process_task(event_t *self, struct perf_session *session);
+int event__process(event_t *event, struct perf_session *session);
 
 struct addr_location;
 int event__preprocess_sample(const event_t *self, struct perf_session *session,
-                            struct addr_location *al, symbol_filter_t filter);
-int event__parse_sample(event_t *event, u64 type, struct sample_data *data);
+                            struct addr_location *al, struct sample_data *data,
+                            symbol_filter_t filter);
+int event__parse_sample(const event_t *event, u64 type, struct sample_data *data);
 
 extern const char *event__name[];
 
index 1f62435f96c2fe6a3ef6a1a82f0f28ddca13652d..d7e67b167ea338a28fed519260f1069dd8e92cf9 100644 (file)
@@ -16,6 +16,8 @@
 #include "symbol.h"
 #include "debug.h"
 
+static bool no_buildid_cache = false;
+
 /*
  * Create new perf.data header attribute:
  */
@@ -385,8 +387,7 @@ static int perf_session__cache_build_ids(struct perf_session *self)
        int ret;
        char debugdir[PATH_MAX];
 
-       snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"),
-                DEBUG_CACHE_DIR);
+       snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
 
        if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
                return -1;
@@ -471,7 +472,8 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
                }
                buildid_sec->size = lseek(fd, 0, SEEK_CUR) -
                                          buildid_sec->offset;
-               perf_session__cache_build_ids(session);
+               if (!no_buildid_cache)
+                       perf_session__cache_build_ids(session);
        }
 
        lseek(fd, sec_start, SEEK_SET);
@@ -1190,3 +1192,8 @@ int event__process_build_id(event_t *self,
                                 session);
        return 0;
 }
+
+void disable_buildid_cache(void)
+{
+       no_buildid_cache = true;
+}
index 784ee0bdda7754f329428e40fa790a22dd331568..e7263d49bcf0e3041c359e722201988f2da79995 100644 (file)
@@ -5,11 +5,61 @@
 #include "sort.h"
 #include <math.h>
 
+enum hist_filter {
+       HIST_FILTER__DSO,
+       HIST_FILTER__THREAD,
+       HIST_FILTER__PARENT,
+};
+
 struct callchain_param callchain_param = {
        .mode   = CHAIN_GRAPH_REL,
        .min_percent = 0.5
 };
 
+u16 hists__col_len(struct hists *self, enum hist_column col)
+{
+       return self->col_len[col];
+}
+
+void hists__set_col_len(struct hists *self, enum hist_column col, u16 len)
+{
+       self->col_len[col] = len;
+}
+
+bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len)
+{
+       if (len > hists__col_len(self, col)) {
+               hists__set_col_len(self, col, len);
+               return true;
+       }
+       return false;
+}
+
+static void hists__reset_col_len(struct hists *self)
+{
+       enum hist_column col;
+
+       for (col = 0; col < HISTC_NR_COLS; ++col)
+               hists__set_col_len(self, col, 0);
+}
+
+static void hists__calc_col_len(struct hists *self, struct hist_entry *h)
+{
+       u16 len;
+
+       if (h->ms.sym)
+               hists__new_col_len(self, HISTC_SYMBOL, h->ms.sym->namelen);
+
+       len = thread__comm_len(h->thread);
+       if (hists__new_col_len(self, HISTC_COMM, len))
+               hists__set_col_len(self, HISTC_THREAD, len + 6);
+
+       if (h->ms.map) {
+               len = dso__name_len(h->ms.map->dso);
+               hists__new_col_len(self, HISTC_DSO, len);
+       }
+}
+
 static void hist_entry__add_cpumode_period(struct hist_entry *self,
                                           unsigned int cpumode, u64 period)
 {
@@ -43,6 +93,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
        if (self != NULL) {
                *self = *template;
                self->nr_events = 1;
+               if (self->ms.map)
+                       self->ms.map->referenced = true;
                if (symbol_conf.use_callchain)
                        callchain_init(self->callchain);
        }
@@ -50,11 +102,19 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
        return self;
 }
 
-static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry)
+static void hists__inc_nr_entries(struct hists *self, struct hist_entry *h)
 {
-       if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen)
-               self->max_sym_namelen = entry->ms.sym->namelen;
-       ++self->nr_entries;
+       if (!h->filtered) {
+               hists__calc_col_len(self, h);
+               ++self->nr_entries;
+       }
+}
+
+static u8 symbol__parent_filter(const struct symbol *parent)
+{
+       if (symbol_conf.exclude_other && parent == NULL)
+               return 1 << HIST_FILTER__PARENT;
+       return 0;
 }
 
 struct hist_entry *__hists__add_entry(struct hists *self,
@@ -70,10 +130,12 @@ struct hist_entry *__hists__add_entry(struct hists *self,
                        .map    = al->map,
                        .sym    = al->sym,
                },
+               .cpu    = al->cpu,
                .ip     = al->addr,
                .level  = al->level,
                .period = period,
                .parent = sym_parent,
+               .filtered = symbol__parent_filter(sym_parent),
        };
        int cmp;
 
@@ -191,7 +253,7 @@ void hists__collapse_resort(struct hists *self)
        tmp = RB_ROOT;
        next = rb_first(&self->entries);
        self->nr_entries = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
@@ -248,7 +310,7 @@ void hists__output_resort(struct hists *self)
        next = rb_first(&self->entries);
 
        self->nr_entries = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
@@ -515,8 +577,9 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
 }
 
 int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
-                        struct hists *pair_hists, bool show_displacement,
-                        long displacement, bool color, u64 session_total)
+                        struct hists *hists, struct hists *pair_hists,
+                        bool show_displacement, long displacement,
+                        bool color, u64 session_total)
 {
        struct sort_entry *se;
        u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
@@ -620,29 +683,25 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
 
                ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
                ret += se->se_snprintf(self, s + ret, size - ret,
-                                      se->se_width ? *se->se_width : 0);
+                                      hists__col_len(hists, se->se_width_idx));
        }
 
        return ret;
 }
 
-int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
-                       bool show_displacement, long displacement, FILE *fp,
-                       u64 session_total)
+int hist_entry__fprintf(struct hist_entry *self, struct hists *hists,
+                       struct hists *pair_hists, bool show_displacement,
+                       long displacement, FILE *fp, u64 session_total)
 {
        char bf[512];
-       int ret;
-
-       ret = hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
-                                  show_displacement, displacement,
-                                  true, session_total);
-       if (!ret)
-               return 0;
-
+       hist_entry__snprintf(self, bf, sizeof(bf), hists, pair_hists,
+                            show_displacement, displacement,
+                            true, session_total);
        return fprintf(fp, "%s\n", bf);
 }
 
-static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
+static size_t hist_entry__fprintf_callchain(struct hist_entry *self,
+                                           struct hists *hists, FILE *fp,
                                            u64 session_total)
 {
        int left_margin = 0;
@@ -650,7 +709,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
        if (sort__first_dimension == SORT_COMM) {
                struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
                                                         typeof(*se), list);
-               left_margin = se->se_width ? *se->se_width : 0;
+               left_margin = hists__col_len(hists, se->se_width_idx);
                left_margin -= thread__comm_len(self->thread);
        }
 
@@ -721,17 +780,17 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
                        continue;
                }
                width = strlen(se->se_header);
-               if (se->se_width) {
-                       if (symbol_conf.col_width_list_str) {
-                               if (col_width) {
-                                       *se->se_width = atoi(col_width);
-                                       col_width = strchr(col_width, ',');
-                                       if (col_width)
-                                               ++col_width;
-                               }
+               if (symbol_conf.col_width_list_str) {
+                       if (col_width) {
+                               hists__set_col_len(self, se->se_width_idx,
+                                                  atoi(col_width));
+                               col_width = strchr(col_width, ',');
+                               if (col_width)
+                                       ++col_width;
                        }
-                       width = *se->se_width = max(*se->se_width, width);
                }
+               if (!hists__new_col_len(self, se->se_width_idx, width))
+                       width = hists__col_len(self, se->se_width_idx);
                fprintf(fp, "  %*s", width, se->se_header);
        }
        fprintf(fp, "\n");
@@ -754,9 +813,8 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
                        continue;
 
                fprintf(fp, "  ");
-               if (se->se_width)
-                       width = *se->se_width;
-               else
+               width = hists__col_len(self, se->se_width_idx);
+               if (width == 0)
                        width = strlen(se->se_header);
                for (i = 0; i < width; i++)
                        fprintf(fp, ".");
@@ -767,7 +825,6 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
 print_entries:
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-               int cnt;
 
                if (show_displacement) {
                        if (h->pair != NULL)
@@ -777,17 +834,12 @@ print_entries:
                                displacement = 0;
                        ++position;
                }
-               cnt = hist_entry__fprintf(h, pair, show_displacement,
-                                         displacement, fp, self->stats.total_period);
-               /* Ignore those that didn't match the parent filter */
-               if (!cnt)
-                       continue;
-
-               ret += cnt;
+               ret += hist_entry__fprintf(h, self, pair, show_displacement,
+                                          displacement, fp, self->stats.total_period);
 
                if (symbol_conf.use_callchain)
-                       ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period);
-
+                       ret += hist_entry__fprintf_callchain(h, self, fp,
+                                                            self->stats.total_period);
                if (h->ms.map == NULL && verbose > 1) {
                        __map_groups__fprintf_maps(&h->thread->mg,
                                                   MAP__FUNCTION, verbose, fp);
@@ -800,10 +852,49 @@ print_entries:
        return ret;
 }
 
-enum hist_filter {
-       HIST_FILTER__DSO,
-       HIST_FILTER__THREAD,
-};
+/*
+ * See hists__fprintf to match the column widths
+ */
+unsigned int hists__sort_list_width(struct hists *self)
+{
+       struct sort_entry *se;
+       int ret = 9; /* total % */
+
+       if (symbol_conf.show_cpu_utilization) {
+               ret += 7; /* count_sys % */
+               ret += 6; /* count_us % */
+               if (perf_guest) {
+                       ret += 13; /* count_guest_sys % */
+                       ret += 12; /* count_guest_us % */
+               }
+       }
+
+       if (symbol_conf.show_nr_samples)
+               ret += 11;
+
+       list_for_each_entry(se, &hist_entry__sort_list, list)
+               if (!se->elide)
+                       ret += 2 + hists__col_len(self, se->se_width_idx);
+
+       return ret;
+}
+
+static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h,
+                                      enum hist_filter filter)
+{
+       h->filtered &= ~(1 << filter);
+       if (h->filtered)
+               return;
+
+       ++self->nr_entries;
+       if (h->ms.unfolded)
+               self->nr_entries += h->nr_rows;
+       h->row_offset = 0;
+       self->stats.total_period += h->period;
+       self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
+
+       hists__calc_col_len(self, h);
+}
 
 void hists__filter_by_dso(struct hists *self, const struct dso *dso)
 {
@@ -811,7 +902,7 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso)
 
        self->nr_entries = self->stats.total_period = 0;
        self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
@@ -824,15 +915,7 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso)
                        continue;
                }
 
-               h->filtered &= ~(1 << HIST_FILTER__DSO);
-               if (!h->filtered) {
-                       ++self->nr_entries;
-                       self->stats.total_period += h->period;
-                       self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
-                       if (h->ms.sym &&
-                           self->max_sym_namelen < h->ms.sym->namelen)
-                               self->max_sym_namelen = h->ms.sym->namelen;
-               }
+               hists__remove_entry_filter(self, h, HIST_FILTER__DSO);
        }
 }
 
@@ -842,7 +925,7 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread)
 
        self->nr_entries = self->stats.total_period = 0;
        self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
@@ -851,15 +934,8 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread)
                        h->filtered |= (1 << HIST_FILTER__THREAD);
                        continue;
                }
-               h->filtered &= ~(1 << HIST_FILTER__THREAD);
-               if (!h->filtered) {
-                       ++self->nr_entries;
-                       self->stats.total_period += h->period;
-                       self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
-                       if (h->ms.sym &&
-                           self->max_sym_namelen < h->ms.sym->namelen)
-                               self->max_sym_namelen = h->ms.sym->namelen;
-               }
+
+               hists__remove_entry_filter(self, h, HIST_FILTER__THREAD);
        }
 }
 
@@ -1052,7 +1128,7 @@ fallback:
                 dso, dso->long_name, sym, sym->name);
 
        snprintf(command, sizeof(command),
-                "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s|expand",
+                "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand",
                 map__rip_2objdump(map, sym->start),
                 map__rip_2objdump(map, sym->end),
                 filename, filename);
index 83fa33a7b38b53555b166d4b04fc3d51f98bf930..65a48db46a29f0b0766f43474271f6e935b3c952 100644 (file)
@@ -56,6 +56,16 @@ struct events_stats {
        u32 nr_unknown_events;
 };
 
+enum hist_column {
+       HISTC_SYMBOL,
+       HISTC_DSO,
+       HISTC_THREAD,
+       HISTC_COMM,
+       HISTC_PARENT,
+       HISTC_CPU,
+       HISTC_NR_COLS, /* Last entry */
+};
+
 struct hists {
        struct rb_node          rb_node;
        struct rb_root          entries;
@@ -64,7 +74,7 @@ struct hists {
        u64                     config;
        u64                     event_stream;
        u32                     type;
-       u32                     max_sym_namelen;
+       u16                     col_len[HISTC_NR_COLS];
 };
 
 struct hist_entry *__hists__add_entry(struct hists *self,
@@ -72,12 +82,13 @@ struct hist_entry *__hists__add_entry(struct hists *self,
                                      struct symbol *parent, u64 period);
 extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
 extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
-int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
-                       bool show_displacement, long displacement, FILE *fp,
-                       u64 total);
+int hist_entry__fprintf(struct hist_entry *self, struct hists *hists,
+                       struct hists *pair_hists, bool show_displacement,
+                       long displacement, FILE *fp, u64 total);
 int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
-                        struct hists *pair_hists, bool show_displacement,
-                        long displacement, bool color, u64 total);
+                        struct hists *hists, struct hists *pair_hists,
+                        bool show_displacement, long displacement,
+                        bool color, u64 total);
 void hist_entry__free(struct hist_entry *);
 
 void hists__output_resort(struct hists *self);
@@ -95,6 +106,10 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head);
 void hists__filter_by_dso(struct hists *self, const struct dso *dso);
 void hists__filter_by_thread(struct hists *self, const struct thread *thread);
 
+u16 hists__col_len(struct hists *self, enum hist_column col);
+void hists__set_col_len(struct hists *self, enum hist_column col, u16 len);
+bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len);
+
 #ifdef NO_NEWT_SUPPORT
 static inline int hists__browse(struct hists *self __used,
                                const char *helpline __used,
@@ -126,4 +141,7 @@ int hist_entry__tui_annotate(struct hist_entry *self);
 
 int hists__tui_browse_tree(struct rb_root *self, const char *help);
 #endif
+
+unsigned int hists__sort_list_width(struct hists *self);
+
 #endif /* __PERF_HIST_H */
index e672f2fef65baaf62dd20d869bca33e027c1cfe6..3a7eb6ec0eecf2c13dcd2ae098f56b4020d70301 100644 (file)
@@ -17,16 +17,6 @@ static inline int is_anon_memory(const char *filename)
        return strcmp(filename, "//anon") == 0;
 }
 
-static int strcommon(const char *pathname, char *cwd, int cwdlen)
-{
-       int n = 0;
-
-       while (n < cwdlen && pathname[n] == cwd[n])
-               ++n;
-
-       return n;
-}
-
 void map__init(struct map *self, enum map_type type,
               u64 start, u64 end, u64 pgoff, struct dso *dso)
 {
@@ -39,11 +29,12 @@ void map__init(struct map *self, enum map_type type,
        self->unmap_ip = map__unmap_ip;
        RB_CLEAR_NODE(&self->rb_node);
        self->groups   = NULL;
+       self->referenced = false;
 }
 
 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                     u64 pgoff, u32 pid, char *filename,
-                    enum map_type type, char *cwd, int cwdlen)
+                    enum map_type type)
 {
        struct map *self = malloc(sizeof(*self));
 
@@ -52,16 +43,6 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                struct dso *dso;
                int anon;
 
-               if (cwd) {
-                       int n = strcommon(filename, cwd, cwdlen);
-
-                       if (n == cwdlen) {
-                               snprintf(newfilename, sizeof(newfilename),
-                                        ".%s", filename + n);
-                               filename = newfilename;
-                       }
-               }
-
                anon = is_anon_memory(filename);
 
                if (anon) {
@@ -248,6 +229,39 @@ void map_groups__init(struct map_groups *self)
        self->machine = NULL;
 }
 
+static void maps__delete(struct rb_root *self)
+{
+       struct rb_node *next = rb_first(self);
+
+       while (next) {
+               struct map *pos = rb_entry(next, struct map, rb_node);
+
+               next = rb_next(&pos->rb_node);
+               rb_erase(&pos->rb_node, self);
+               map__delete(pos);
+       }
+}
+
+static void maps__delete_removed(struct list_head *self)
+{
+       struct map *pos, *n;
+
+       list_for_each_entry_safe(pos, n, self, node) {
+               list_del(&pos->node);
+               map__delete(pos);
+       }
+}
+
+void map_groups__exit(struct map_groups *self)
+{
+       int i;
+
+       for (i = 0; i < MAP__NR_TYPES; ++i) {
+               maps__delete(&self->maps[i]);
+               maps__delete_removed(&self->removed_maps[i]);
+       }
+}
+
 void map_groups__flush(struct map_groups *self)
 {
        int type;
@@ -374,6 +388,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
 {
        struct rb_root *root = &self->maps[map->type];
        struct rb_node *next = rb_first(root);
+       int err = 0;
 
        while (next) {
                struct map *pos = rb_entry(next, struct map, rb_node);
@@ -389,12 +404,6 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
                }
 
                rb_erase(&pos->rb_node, root);
-               /*
-                * We may have references to this map, for instance in some
-                * hist_entry instances, so just move them to a separate
-                * list.
-                */
-               list_add_tail(&pos->node, &self->removed_maps[map->type]);
                /*
                 * Now check if we need to create new maps for areas not
                 * overlapped by the new map:
@@ -402,8 +411,10 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
                if (map->start > pos->start) {
                        struct map *before = map__clone(pos);
 
-                       if (before == NULL)
-                               return -ENOMEM;
+                       if (before == NULL) {
+                               err = -ENOMEM;
+                               goto move_map;
+                       }
 
                        before->end = map->start - 1;
                        map_groups__insert(self, before);
@@ -414,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
                if (map->end < pos->end) {
                        struct map *after = map__clone(pos);
 
-                       if (after == NULL)
-                               return -ENOMEM;
+                       if (after == NULL) {
+                               err = -ENOMEM;
+                               goto move_map;
+                       }
 
                        after->start = map->end + 1;
                        map_groups__insert(self, after);
                        if (verbose >= 2)
                                map__fprintf(after, fp);
                }
+move_map:
+               /*
+                * If we have references, just move them to a separate list.
+                */
+               if (pos->referenced)
+                       list_add_tail(&pos->node, &self->removed_maps[map->type]);
+               else
+                       map__delete(pos);
+
+               if (err)
+                       return err;
        }
 
        return 0;
@@ -493,6 +517,11 @@ void maps__insert(struct rb_root *maps, struct map *map)
        rb_insert_color(&map->rb_node, maps);
 }
 
+void maps__remove(struct rb_root *self, struct map *map)
+{
+       rb_erase(&map->rb_node, self);
+}
+
 struct map *maps__find(struct rb_root *maps, u64 ip)
 {
        struct rb_node **p = &maps->rb_node;
@@ -526,6 +555,31 @@ int machine__init(struct machine *self, const char *root_dir, pid_t pid)
        return self->root_dir == NULL ? -ENOMEM : 0;
 }
 
+static void dsos__delete(struct list_head *self)
+{
+       struct dso *pos, *n;
+
+       list_for_each_entry_safe(pos, n, self, node) {
+               list_del(&pos->node);
+               dso__delete(pos);
+       }
+}
+
+void machine__exit(struct machine *self)
+{
+       map_groups__exit(&self->kmaps);
+       dsos__delete(&self->user_dsos);
+       dsos__delete(&self->kernel_dsos);
+       free(self->root_dir);
+       self->root_dir = NULL;
+}
+
+void machine__delete(struct machine *self)
+{
+       machine__exit(self);
+       free(self);
+}
+
 struct machine *machines__add(struct rb_root *self, pid_t pid,
                              const char *root_dir)
 {
index f39134512829c89c48662996d6a1a75f5d41deed..78575796d5f315bff5fa933c906821e610addfff 100644 (file)
@@ -29,7 +29,8 @@ struct map {
        };
        u64                     start;
        u64                     end;
-       enum map_type           type;
+       u8 /* enum map_type */  type;
+       bool                    referenced;
        u32                     priv;
        u64                     pgoff;
 
@@ -106,7 +107,7 @@ void map__init(struct map *self, enum map_type type,
               u64 start, u64 end, u64 pgoff, struct dso *dso);
 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                     u64 pgoff, u32 pid, char *filename,
-                    enum map_type type, char *cwd, int cwdlen);
+                    enum map_type type);
 void map__delete(struct map *self);
 struct map *map__clone(struct map *self);
 int map__overlap(struct map *l, struct map *r);
@@ -125,8 +126,10 @@ void map__reloc_vmlinux(struct map *self);
 size_t __map_groups__fprintf_maps(struct map_groups *self,
                                  enum map_type type, int verbose, FILE *fp);
 void maps__insert(struct rb_root *maps, struct map *map);
+void maps__remove(struct rb_root *self, struct map *map);
 struct map *maps__find(struct rb_root *maps, u64 addr);
 void map_groups__init(struct map_groups *self);
+void map_groups__exit(struct map_groups *self);
 int map_groups__clone(struct map_groups *self,
                      struct map_groups *parent, enum map_type type);
 size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp);
@@ -142,6 +145,8 @@ struct machine *machines__find(struct rb_root *self, pid_t pid);
 struct machine *machines__findnew(struct rb_root *self, pid_t pid);
 char *machine__mmap_name(struct machine *self, char *bf, size_t size);
 int machine__init(struct machine *self, const char *root_dir, pid_t pid);
+void machine__exit(struct machine *self);
+void machine__delete(struct machine *self);
 
 /*
  * Default guest kernel is defined by parameter --guestkallsyms
@@ -163,6 +168,11 @@ static inline void map_groups__insert(struct map_groups *self, struct map *map)
        map->groups = self;
 }
 
+static inline void map_groups__remove(struct map_groups *self, struct map *map)
+{
+       maps__remove(&self->maps[map->type], map);
+}
+
 static inline struct map *map_groups__find(struct map_groups *self,
                                           enum map_type type, u64 addr)
 {
index 7537ca15900b121852cc19545fe45a2b266403f7..91de99b58445b7b4ac798c40c6e3a3583405d6df 100644 (file)
@@ -11,6 +11,7 @@
 #define HAVE_LONG_LONG __GLIBC_HAVE_LONG_LONG
 #endif
 #include <slang.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <newt.h>
 #include <sys/ttydefaults.h>
@@ -278,9 +279,48 @@ struct ui_browser {
        void            *first_visible_entry, *entries;
        u16             top, left, width, height;
        void            *priv;
+       unsigned int    (*refresh_entries)(struct ui_browser *self);
+       void            (*seek)(struct ui_browser *self,
+                               off_t offset, int whence);
        u32             nr_entries;
 };
 
+static void ui_browser__list_head_seek(struct ui_browser *self,
+                                      off_t offset, int whence)
+{
+       struct list_head *head = self->entries;
+       struct list_head *pos;
+
+       switch (whence) {
+       case SEEK_SET:
+               pos = head->next;
+               break;
+       case SEEK_CUR:
+               pos = self->first_visible_entry;
+               break;
+       case SEEK_END:
+               pos = head->prev;
+               break;
+       default:
+               return;
+       }
+
+       if (offset > 0) {
+               while (offset-- != 0)
+                       pos = pos->next;
+       } else {
+               while (offset++ != 0)
+                       pos = pos->prev;
+       }
+
+       self->first_visible_entry = pos;
+}
+
+static bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row)
+{
+       return (self->first_visible_entry_idx + row) == self->index;
+}
+
 static void ui_browser__refresh_dimensions(struct ui_browser *self)
 {
        int cols, rows;
@@ -297,8 +337,36 @@ static void ui_browser__refresh_dimensions(struct ui_browser *self)
 
 static void ui_browser__reset_index(struct ui_browser *self)
 {
-        self->index = self->first_visible_entry_idx = 0;
-        self->first_visible_entry = NULL;
+       self->index = self->first_visible_entry_idx = 0;
+       self->seek(self, 0, SEEK_SET);
+}
+
+static int ui_browser__show(struct ui_browser *self, const char *title)
+{
+       if (self->form != NULL) {
+               newtFormDestroy(self->form);
+               newtPopWindow();
+       }
+       ui_browser__refresh_dimensions(self);
+       newtCenteredWindow(self->width, self->height, title);
+       self->form = newt_form__new();
+       if (self->form == NULL)
+               return -1;
+
+       self->sb = newtVerticalScrollbar(self->width, 0, self->height,
+                                        HE_COLORSET_NORMAL,
+                                        HE_COLORSET_SELECTED);
+       if (self->sb == NULL)
+               return -1;
+
+       newtFormAddHotKey(self->form, NEWT_KEY_UP);
+       newtFormAddHotKey(self->form, NEWT_KEY_DOWN);
+       newtFormAddHotKey(self->form, NEWT_KEY_PGUP);
+       newtFormAddHotKey(self->form, NEWT_KEY_PGDN);
+       newtFormAddHotKey(self->form, NEWT_KEY_HOME);
+       newtFormAddHotKey(self->form, NEWT_KEY_END);
+       newtFormAddComponent(self->form, self->sb);
+       return 0;
 }
 
 static int objdump_line__show(struct objdump_line *self, struct list_head *head,
@@ -352,26 +420,10 @@ static int objdump_line__show(struct objdump_line *self, struct list_head *head,
 
 static int ui_browser__refresh_entries(struct ui_browser *self)
 {
-       struct objdump_line *pos;
-       struct list_head *head = self->entries;
-       struct hist_entry *he = self->priv;
-       int row = 0;
-       int len = he->ms.sym->end - he->ms.sym->start;
-
-       if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries)
-                self->first_visible_entry = head->next;
-
-       pos = list_entry(self->first_visible_entry, struct objdump_line, node);
-
-       list_for_each_entry_from(pos, head, node) {
-               bool current_entry = (self->first_visible_entry_idx + row) == self->index;
-               SLsmg_gotorc(self->top + row, self->left);
-               objdump_line__show(pos, head, self->width,
-                                  he, len, current_entry);
-               if (++row == self->height)
-                       break;
-       }
+       int row;
 
+       newtScrollbarSet(self->sb, self->index, self->nr_entries - 1);
+       row = self->refresh_entries(self);
        SLsmg_set_color(HE_COLORSET_NORMAL);
        SLsmg_fill_region(self->top + row, self->left,
                          self->height - row, self->width, ' ');
@@ -379,42 +431,13 @@ static int ui_browser__refresh_entries(struct ui_browser *self)
        return 0;
 }
 
-static int ui_browser__run(struct ui_browser *self, const char *title,
-                          struct newtExitStruct *es)
+static int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es)
 {
-       if (self->form) {
-               newtFormDestroy(self->form);
-               newtPopWindow();
-       }
-
-       ui_browser__refresh_dimensions(self);
-       newtCenteredWindow(self->width + 2, self->height, title);
-       self->form = newt_form__new();
-       if (self->form == NULL)
-               return -1;
-
-       self->sb = newtVerticalScrollbar(self->width + 1, 0, self->height,
-                                        HE_COLORSET_NORMAL,
-                                        HE_COLORSET_SELECTED);
-       if (self->sb == NULL)
-               return -1;
-
-       newtFormAddHotKey(self->form, NEWT_KEY_UP);
-       newtFormAddHotKey(self->form, NEWT_KEY_DOWN);
-       newtFormAddHotKey(self->form, NEWT_KEY_PGUP);
-       newtFormAddHotKey(self->form, NEWT_KEY_PGDN);
-       newtFormAddHotKey(self->form, ' ');
-       newtFormAddHotKey(self->form, NEWT_KEY_HOME);
-       newtFormAddHotKey(self->form, NEWT_KEY_END);
-       newtFormAddHotKey(self->form, NEWT_KEY_TAB);
-       newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
-
        if (ui_browser__refresh_entries(self) < 0)
                return -1;
-       newtFormAddComponent(self->form, self->sb);
 
        while (1) {
-               unsigned int offset;
+               off_t offset;
 
                newtFormRun(self->form, es);
 
@@ -428,9 +451,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
                                break;
                        ++self->index;
                        if (self->index == self->first_visible_entry_idx + self->height) {
-                               struct list_head *pos = self->first_visible_entry;
                                ++self->first_visible_entry_idx;
-                               self->first_visible_entry = pos->next;
+                               self->seek(self, +1, SEEK_CUR);
                        }
                        break;
                case NEWT_KEY_UP:
@@ -438,9 +460,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
                                break;
                        --self->index;
                        if (self->index < self->first_visible_entry_idx) {
-                               struct list_head *pos = self->first_visible_entry;
                                --self->first_visible_entry_idx;
-                               self->first_visible_entry = pos->prev;
+                               self->seek(self, -1, SEEK_CUR);
                        }
                        break;
                case NEWT_KEY_PGDN:
@@ -453,12 +474,7 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
                                offset = self->nr_entries - 1 - self->index;
                        self->index += offset;
                        self->first_visible_entry_idx += offset;
-
-                       while (offset--) {
-                               struct list_head *pos = self->first_visible_entry;
-                               self->first_visible_entry = pos->next;
-                       }
-
+                       self->seek(self, +offset, SEEK_CUR);
                        break;
                case NEWT_KEY_PGUP:
                        if (self->first_visible_entry_idx == 0)
@@ -471,36 +487,22 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
 
                        self->index -= offset;
                        self->first_visible_entry_idx -= offset;
-
-                       while (offset--) {
-                               struct list_head *pos = self->first_visible_entry;
-                               self->first_visible_entry = pos->prev;
-                       }
+                       self->seek(self, -offset, SEEK_CUR);
                        break;
                case NEWT_KEY_HOME:
                        ui_browser__reset_index(self);
                        break;
-               case NEWT_KEY_END: {
-                       struct list_head *head = self->entries;
+               case NEWT_KEY_END:
                        offset = self->height - 1;
+                       if (offset >= self->nr_entries)
+                               offset = self->nr_entries - 1;
 
-                       if (offset > self->nr_entries)
-                               offset = self->nr_entries;
-
-                       self->index = self->first_visible_entry_idx = self->nr_entries - 1 - offset;
-                       self->first_visible_entry = head->prev;
-                       while (offset-- != 0) {
-                               struct list_head *pos = self->first_visible_entry;
-                               self->first_visible_entry = pos->prev;
-                       }
-               }
+                       self->index = self->nr_entries - 1;
+                       self->first_visible_entry_idx = self->index - offset;
+                       self->seek(self, -offset, SEEK_END);
                        break;
-               case NEWT_KEY_RIGHT:
-               case NEWT_KEY_LEFT:
-               case NEWT_KEY_TAB:
-                       return es->u.key;
                default:
-                       continue;
+                       return es->u.key;
                }
                if (ui_browser__refresh_entries(self) < 0)
                        return -1;
@@ -508,38 +510,6 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
        return 0;
 }
 
-/*
- * When debugging newt problems it was useful to be able to "unroll"
- * the calls to newtCheckBoxTreeAdd{Array,Item}, so that we can generate
- * a source file with the sequence of calls to these methods, to then
- * tweak the arrays to get the intended results, so I'm keeping this code
- * here, may be useful again in the future.
- */
-#undef NEWT_DEBUG
-
-static void newt_checkbox_tree__add(newtComponent tree, const char *str,
-                                   void *priv, int *indexes)
-{
-#ifdef NEWT_DEBUG
-       /* Print the newtCheckboxTreeAddArray to tinker with its index arrays */
-       int i = 0, len = 40 - strlen(str);
-
-       fprintf(stderr,
-               "\tnewtCheckboxTreeAddItem(tree, %*.*s\"%s\", (void *)%p, 0, ",
-               len, len, " ", str, priv);
-       while (indexes[i] != NEWT_ARG_LAST) {
-               if (indexes[i] != NEWT_ARG_APPEND)
-                       fprintf(stderr, " %d,", indexes[i]);
-               else
-                       fprintf(stderr, " %s,", "NEWT_ARG_APPEND");
-               ++i;
-       }
-       fprintf(stderr, " %s", " NEWT_ARG_LAST);\n");
-       fflush(stderr);
-#endif
-       newtCheckboxTreeAddArray(tree, str, priv, 0, indexes);
-}
-
 static char *callchain_list__sym_name(struct callchain_list *self,
                                      char *bf, size_t bfsize)
 {
@@ -550,144 +520,29 @@ static char *callchain_list__sym_name(struct callchain_list *self,
        return bf;
 }
 
-static void __callchain__append_graph_browser(struct callchain_node *self,
-                                             newtComponent tree, u64 total,
-                                             int *indexes, int depth)
+static unsigned int hist_entry__annotate_browser_refresh(struct ui_browser *self)
 {
-       struct rb_node *node;
-       u64 new_total, remaining;
-       int idx = 0;
-
-       if (callchain_param.mode == CHAIN_GRAPH_REL)
-               new_total = self->children_hit;
-       else
-               new_total = total;
-
-       remaining = new_total;
-       node = rb_first(&self->rb_root);
-       while (node) {
-               struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
-               struct rb_node *next = rb_next(node);
-               u64 cumul = cumul_hits(child);
-               struct callchain_list *chain;
-               int first = true, printed = 0;
-               int chain_idx = -1;
-               remaining -= cumul;
-
-               indexes[depth] = NEWT_ARG_APPEND;
-               indexes[depth + 1] = NEWT_ARG_LAST;
-
-               list_for_each_entry(chain, &child->val, list) {
-                       char ipstr[BITS_PER_LONG / 4 + 1],
-                            *alloc_str = NULL;
-                       const char *str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
-
-                       if (first) {
-                               double percent = cumul * 100.0 / new_total;
-
-                               first = false;
-                               if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
-                                       str = "Not enough memory!";
-                               else
-                                       str = alloc_str;
-                       } else {
-                               indexes[depth] = idx;
-                               indexes[depth + 1] = NEWT_ARG_APPEND;
-                               indexes[depth + 2] = NEWT_ARG_LAST;
-                               ++chain_idx;
-                       }
-                       newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
-                       free(alloc_str);
-                       ++printed;
-               }
-
-               indexes[depth] = idx;
-               if (chain_idx != -1)
-                       indexes[depth + 1] = chain_idx;
-               if (printed != 0)
-                       ++idx;
-               __callchain__append_graph_browser(child, tree, new_total, indexes,
-                                                 depth + (chain_idx != -1 ? 2 : 1));
-               node = next;
-       }
-}
-
-static void callchain__append_graph_browser(struct callchain_node *self,
-                                           newtComponent tree, u64 total,
-                                           int *indexes, int parent_idx)
-{
-       struct callchain_list *chain;
-       int i = 0;
-
-       indexes[1] = NEWT_ARG_APPEND;
-       indexes[2] = NEWT_ARG_LAST;
-
-       list_for_each_entry(chain, &self->val, list) {
-               char ipstr[BITS_PER_LONG / 4 + 1], *str;
-
-               if (chain->ip >= PERF_CONTEXT_MAX)
-                       continue;
-
-               if (!i++ && sort__first_dimension == SORT_SYM)
-                       continue;
+       struct objdump_line *pos;
+       struct list_head *head = self->entries;
+       struct hist_entry *he = self->priv;
+       int row = 0;
+       int len = he->ms.sym->end - he->ms.sym->start;
 
-               str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
-               newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
-       }
+       if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries)
+                self->first_visible_entry = head->next;
 
-       indexes[1] = parent_idx;
-       indexes[2] = NEWT_ARG_APPEND;
-       indexes[3] = NEWT_ARG_LAST;
-       __callchain__append_graph_browser(self, tree, total, indexes, 2);
-}
+       pos = list_entry(self->first_visible_entry, struct objdump_line, node);
 
-static void hist_entry__append_callchain_browser(struct hist_entry *self,
-                                                newtComponent tree, u64 total, int parent_idx)
-{
-       struct rb_node *rb_node;
-       int indexes[1024] = { [0] = parent_idx, };
-       int idx = 0;
-       struct callchain_node *chain;
-
-       rb_node = rb_first(&self->sorted_chain);
-       while (rb_node) {
-               chain = rb_entry(rb_node, struct callchain_node, rb_node);
-               switch (callchain_param.mode) {
-               case CHAIN_FLAT:
-                       break;
-               case CHAIN_GRAPH_ABS: /* falldown */
-               case CHAIN_GRAPH_REL:
-                       callchain__append_graph_browser(chain, tree, total, indexes, idx++);
-                       break;
-               case CHAIN_NONE:
-               default:
+       list_for_each_entry_from(pos, head, node) {
+               bool current_entry = ui_browser__is_current_entry(self, row);
+               SLsmg_gotorc(self->top + row, self->left);
+               objdump_line__show(pos, head, self->width,
+                                  he, len, current_entry);
+               if (++row == self->height)
                        break;
-               }
-               rb_node = rb_next(rb_node);
        }
-}
-
-static size_t hist_entry__append_browser(struct hist_entry *self,
-                                        newtComponent tree, u64 total)
-{
-       char s[256];
-       size_t ret;
-
-       if (symbol_conf.exclude_other && !self->parent)
-               return 0;
 
-       ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
-                                  false, 0, false, total);
-       if (symbol_conf.use_callchain) {
-               int indexes[2];
-
-               indexes[0] = NEWT_ARG_APPEND;
-               indexes[1] = NEWT_ARG_LAST;
-               newt_checkbox_tree__add(tree, s, &self->ms, indexes);
-       } else
-               newtListboxAppendEntry(tree, s, &self->ms);
-
-       return ret;
+       return row;
 }
 
 int hist_entry__tui_annotate(struct hist_entry *self)
@@ -712,7 +567,9 @@ int hist_entry__tui_annotate(struct hist_entry *self)
        ui_helpline__push("Press <- or ESC to exit");
 
        memset(&browser, 0, sizeof(browser));
-       browser.entries = &head;
+       browser.entries         = &head;
+       browser.refresh_entries = hist_entry__annotate_browser_refresh;
+       browser.seek            = ui_browser__list_head_seek;
        browser.priv = self;
        list_for_each_entry(pos, &head, node) {
                size_t line_len = strlen(pos->line);
@@ -722,7 +579,9 @@ int hist_entry__tui_annotate(struct hist_entry *self)
        }
 
        browser.width += 18; /* Percentage */
-       ret = ui_browser__run(&browser, self->ms.sym->name, &es);
+       ui_browser__show(&browser, self->ms.sym->name);
+       newtFormAddHotKey(browser.form, ' ');
+       ret = ui_browser__run(&browser, &es);
        newtFormDestroy(browser.form);
        newtPopWindow();
        list_for_each_entry_safe(pos, n, &head, node) {
@@ -733,157 +592,48 @@ int hist_entry__tui_annotate(struct hist_entry *self)
        return ret;
 }
 
-static const void *newt__symbol_tree_get_current(newtComponent self)
-{
-       if (symbol_conf.use_callchain)
-               return newtCheckboxTreeGetCurrent(self);
-       return newtListboxGetCurrent(self);
-}
-
-static void hist_browser__selection(newtComponent self, void *data)
-{
-       const struct map_symbol **symbol_ptr = data;
-       *symbol_ptr = newt__symbol_tree_get_current(self);
-}
-
 struct hist_browser {
-       newtComponent           form, tree;
-       const struct map_symbol *selection;
+       struct ui_browser   b;
+       struct hists        *hists;
+       struct hist_entry   *he_selection;
+       struct map_symbol   *selection;
 };
 
-static struct hist_browser *hist_browser__new(void)
+static void hist_browser__reset(struct hist_browser *self);
+static int hist_browser__run(struct hist_browser *self, const char *title,
+                            struct newtExitStruct *es);
+static unsigned int hist_browser__refresh_entries(struct ui_browser *self);
+static void ui_browser__hists_seek(struct ui_browser *self,
+                                  off_t offset, int whence);
+
+static struct hist_browser *hist_browser__new(struct hists *hists)
 {
-       struct hist_browser *self = malloc(sizeof(*self));
+       struct hist_browser *self = zalloc(sizeof(*self));
 
-       if (self != NULL)
-               self->form = NULL;
+       if (self) {
+               self->hists = hists;
+               self->b.refresh_entries = hist_browser__refresh_entries;
+               self->b.seek = ui_browser__hists_seek;
+       }
 
        return self;
 }
 
 static void hist_browser__delete(struct hist_browser *self)
 {
-       newtFormDestroy(self->form);
+       newtFormDestroy(self->b.form);
        newtPopWindow();
        free(self);
 }
 
-static int hist_browser__populate(struct hist_browser *self, struct hists *hists,
-                                 const char *title)
-{
-       int max_len = 0, idx, cols, rows;
-       struct ui_progress *progress;
-       struct rb_node *nd;
-       u64 curr_hist = 0;
-       char seq[] = ".", unit;
-       char str[256];
-       unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
-
-       if (self->form) {
-               newtFormDestroy(self->form);
-               newtPopWindow();
-       }
-
-       nr_events = convert_unit(nr_events, &unit);
-       snprintf(str, sizeof(str), "Events: %lu%c                            ",
-                nr_events, unit);
-       newtDrawRootText(0, 0, str);
-
-       newtGetScreenSize(NULL, &rows);
-
-       if (symbol_conf.use_callchain)
-               self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
-                                                  NEWT_FLAG_SCROLL);
-       else
-               self->tree = newtListbox(0, 0, rows - 5,
-                                       (NEWT_FLAG_SCROLL |
-                                        NEWT_FLAG_RETURNEXIT));
-
-       newtComponentAddCallback(self->tree, hist_browser__selection,
-                                &self->selection);
-
-       progress = ui_progress__new("Adding entries to the browser...",
-                                   hists->nr_entries);
-       if (progress == NULL)
-               return -1;
-
-       idx = 0;
-       for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
-               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
-               int len;
-
-               if (h->filtered)
-                       continue;
-
-               len = hist_entry__append_browser(h, self->tree, hists->stats.total_period);
-               if (len > max_len)
-                       max_len = len;
-               if (symbol_conf.use_callchain)
-                       hist_entry__append_callchain_browser(h, self->tree,
-                                                            hists->stats.total_period, idx++);
-               ++curr_hist;
-               if (curr_hist % 5)
-                       ui_progress__update(progress, curr_hist);
-       }
-
-       ui_progress__delete(progress);
-
-       newtGetScreenSize(&cols, &rows);
-
-       if (max_len > cols)
-               max_len = cols - 3;
-
-       if (!symbol_conf.use_callchain)
-               newtListboxSetWidth(self->tree, max_len);
-
-       newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0),
-                          rows - 5, title);
-       self->form = newt_form__new();
-       if (self->form == NULL)
-               return -1;
-
-       newtFormAddHotKey(self->form, 'A');
-       newtFormAddHotKey(self->form, 'a');
-       newtFormAddHotKey(self->form, 'D');
-       newtFormAddHotKey(self->form, 'd');
-       newtFormAddHotKey(self->form, 'T');
-       newtFormAddHotKey(self->form, 't');
-       newtFormAddHotKey(self->form, '?');
-       newtFormAddHotKey(self->form, 'H');
-       newtFormAddHotKey(self->form, 'h');
-       newtFormAddHotKey(self->form, NEWT_KEY_F1);
-       newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
-       newtFormAddHotKey(self->form, NEWT_KEY_TAB);
-       newtFormAddHotKey(self->form, NEWT_KEY_UNTAB);
-       newtFormAddComponents(self->form, self->tree, NULL);
-       self->selection = newt__symbol_tree_get_current(self->tree);
-
-       return 0;
-}
-
 static struct hist_entry *hist_browser__selected_entry(struct hist_browser *self)
 {
-       int *indexes;
-
-       if (!symbol_conf.use_callchain)
-               goto out;
-
-       indexes = newtCheckboxTreeFindItem(self->tree, (void *)self->selection);
-       if (indexes) {
-               bool is_hist_entry = indexes[1] == NEWT_ARG_LAST;
-               free(indexes);
-               if (is_hist_entry)
-                       goto out;
-       }
-       return NULL;
-out:
-       return container_of(self->selection, struct hist_entry, ms);
+       return self->he_selection;
 }
 
 static struct thread *hist_browser__selected_thread(struct hist_browser *self)
 {
-       struct hist_entry *he = hist_browser__selected_entry(self);
-       return he ? he->thread : NULL;
+       return self->he_selection->thread;
 }
 
 static int hist_browser__title(char *bf, size_t size, const char *ev_name,
@@ -905,7 +655,7 @@ static int hist_browser__title(char *bf, size_t size, const char *ev_name,
 
 int hists__browse(struct hists *self, const char *helpline, const char *ev_name)
 {
-       struct hist_browser *browser = hist_browser__new();
+       struct hist_browser *browser = hist_browser__new(self);
        struct pstack *fstack;
        const struct thread *thread_filter = NULL;
        const struct dso *dso_filter = NULL;
@@ -924,8 +674,6 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name)
 
        hist_browser__title(msg, sizeof(msg), ev_name,
                            dso_filter, thread_filter);
-       if (hist_browser__populate(browser, self, msg) < 0)
-               goto out_free_stack;
 
        while (1) {
                const struct thread *thread;
@@ -934,7 +682,8 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name)
                int nr_options = 0, choice = 0, i,
                    annotate = -2, zoom_dso = -2, zoom_thread = -2;
 
-               newtFormRun(browser->form, &es);
+               if (hist_browser__run(browser, msg, &es))
+                       break;
 
                thread = hist_browser__selected_thread(browser);
                dso = browser->selection->map ? browser->selection->map->dso : NULL;
@@ -1069,8 +818,7 @@ zoom_out_dso:
                        hists__filter_by_dso(self, dso_filter);
                        hist_browser__title(msg, sizeof(msg), ev_name,
                                            dso_filter, thread_filter);
-                       if (hist_browser__populate(browser, self, msg) < 0)
-                               goto out;
+                       hist_browser__reset(browser);
                } else if (choice == zoom_thread) {
 zoom_thread:
                        if (thread_filter) {
@@ -1088,8 +836,7 @@ zoom_out_thread:
                        hists__filter_by_thread(self, thread_filter);
                        hist_browser__title(msg, sizeof(msg), ev_name,
                                            dso_filter, thread_filter);
-                       if (hist_browser__populate(browser, self, msg) < 0)
-                               goto out;
+                       hist_browser__reset(browser);
                }
        }
 out_free_stack:
@@ -1145,6 +892,13 @@ static struct newtPercentTreeColors {
        "blue",      "lightgray",
 };
 
+static void newt_suspend(void *d __used)
+{
+       newtSuspend();
+       raise(SIGTSTP);
+       newtResume();
+}
+
 void setup_browser(void)
 {
        struct newtPercentTreeColors *c = &defaultPercentTreeColors;
@@ -1158,6 +912,7 @@ void setup_browser(void)
        use_browser = 1;
        newtInit();
        newtCls();
+       newtSetSuspendCallback(newt_suspend, NULL);
        ui_helpline__puts(" ");
        sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg);
        sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg);
@@ -1176,3 +931,638 @@ void exit_browser(bool wait_for_ok)
                newtFinished();
        }
 }
+
+static void hist_browser__refresh_dimensions(struct hist_browser *self)
+{
+       /* 3 == +/- toggle symbol before actual hist_entry rendering */
+       self->b.width = 3 + (hists__sort_list_width(self->hists) +
+                            sizeof("[k]"));
+}
+
+static void hist_browser__reset(struct hist_browser *self)
+{
+       self->b.nr_entries = self->hists->nr_entries;
+       hist_browser__refresh_dimensions(self);
+       ui_browser__reset_index(&self->b);
+}
+
+static char tree__folded_sign(bool unfolded)
+{
+       return unfolded ? '-' : '+';
+}
+
+static char map_symbol__folded(const struct map_symbol *self)
+{
+       return self->has_children ? tree__folded_sign(self->unfolded) : ' ';
+}
+
+static char hist_entry__folded(const struct hist_entry *self)
+{
+       return map_symbol__folded(&self->ms);
+}
+
+static char callchain_list__folded(const struct callchain_list *self)
+{
+       return map_symbol__folded(&self->ms);
+}
+
+static bool map_symbol__toggle_fold(struct map_symbol *self)
+{
+       if (!self->has_children)
+               return false;
+
+       self->unfolded = !self->unfolded;
+       return true;
+}
+
+#define LEVEL_OFFSET_STEP 3
+
+static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *self,
+                                                    struct callchain_node *chain_node,
+                                                    u64 total, int level,
+                                                    unsigned short row,
+                                                    off_t *row_offset,
+                                                    bool *is_current_entry)
+{
+       struct rb_node *node;
+       int first_row = row, width, offset = level * LEVEL_OFFSET_STEP;
+       u64 new_total, remaining;
+
+       if (callchain_param.mode == CHAIN_GRAPH_REL)
+               new_total = chain_node->children_hit;
+       else
+               new_total = total;
+
+       remaining = new_total;
+       node = rb_first(&chain_node->rb_root);
+       while (node) {
+               struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
+               struct rb_node *next = rb_next(node);
+               u64 cumul = cumul_hits(child);
+               struct callchain_list *chain;
+               char folded_sign = ' ';
+               int first = true;
+               int extra_offset = 0;
+
+               remaining -= cumul;
+
+               list_for_each_entry(chain, &child->val, list) {
+                       char ipstr[BITS_PER_LONG / 4 + 1], *alloc_str;
+                       const char *str;
+                       int color;
+                       bool was_first = first;
+
+                       if (first) {
+                               first = false;
+                               chain->ms.has_children = chain->list.next != &child->val ||
+                                                        rb_first(&child->rb_root) != NULL;
+                       } else {
+                               extra_offset = LEVEL_OFFSET_STEP;
+                               chain->ms.has_children = chain->list.next == &child->val &&
+                                                        rb_first(&child->rb_root) != NULL;
+                       }
+
+                       folded_sign = callchain_list__folded(chain);
+                       if (*row_offset != 0) {
+                               --*row_offset;
+                               goto do_next;
+                       }
+
+                       alloc_str = NULL;
+                       str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
+                       if (was_first) {
+                               double percent = cumul * 100.0 / new_total;
+
+                               if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
+                                       str = "Not enough memory!";
+                               else
+                                       str = alloc_str;
+                       }
+
+                       color = HE_COLORSET_NORMAL;
+                       width = self->b.width - (offset + extra_offset + 2);
+                       if (ui_browser__is_current_entry(&self->b, row)) {
+                               self->selection = &chain->ms;
+                               color = HE_COLORSET_SELECTED;
+                               *is_current_entry = true;
+                       }
+
+                       SLsmg_set_color(color);
+                       SLsmg_gotorc(self->b.top + row, self->b.left);
+                       slsmg_write_nstring(" ", offset + extra_offset);
+                       slsmg_printf("%c ", folded_sign);
+                       slsmg_write_nstring(str, width);
+                       free(alloc_str);
+
+                       if (++row == self->b.height)
+                               goto out;
+do_next:
+                       if (folded_sign == '+')
+                               break;
+               }
+
+               if (folded_sign == '-') {
+                       const int new_level = level + (extra_offset ? 2 : 1);
+                       row += hist_browser__show_callchain_node_rb_tree(self, child, new_total,
+                                                                        new_level, row, row_offset,
+                                                                        is_current_entry);
+               }
+               if (row == self->b.height)
+                       goto out;
+               node = next;
+       }
+out:
+       return row - first_row;
+}
+
+static int hist_browser__show_callchain_node(struct hist_browser *self,
+                                            struct callchain_node *node,
+                                            int level, unsigned short row,
+                                            off_t *row_offset,
+                                            bool *is_current_entry)
+{
+       struct callchain_list *chain;
+       int first_row = row,
+            offset = level * LEVEL_OFFSET_STEP,
+            width = self->b.width - offset;
+       char folded_sign = ' ';
+
+       list_for_each_entry(chain, &node->val, list) {
+               char ipstr[BITS_PER_LONG / 4 + 1], *s;
+               int color;
+               /*
+                * FIXME: This should be moved to somewhere else,
+                * probably when the callchain is created, so as not to
+                * traverse it all over again
+                */
+               chain->ms.has_children = rb_first(&node->rb_root) != NULL;
+               folded_sign = callchain_list__folded(chain);
+
+               if (*row_offset != 0) {
+                       --*row_offset;
+                       continue;
+               }
+
+               color = HE_COLORSET_NORMAL;
+               if (ui_browser__is_current_entry(&self->b, row)) {
+                       self->selection = &chain->ms;
+                       color = HE_COLORSET_SELECTED;
+                       *is_current_entry = true;
+               }
+
+               s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
+               SLsmg_gotorc(self->b.top + row, self->b.left);
+               SLsmg_set_color(color);
+               slsmg_write_nstring(" ", offset);
+               slsmg_printf("%c ", folded_sign);
+               slsmg_write_nstring(s, width - 2);
+
+               if (++row == self->b.height)
+                       goto out;
+       }
+
+       if (folded_sign == '-')
+               row += hist_browser__show_callchain_node_rb_tree(self, node,
+                                                                self->hists->stats.total_period,
+                                                                level + 1, row,
+                                                                row_offset,
+                                                                is_current_entry);
+out:
+       return row - first_row;
+}
+
+static int hist_browser__show_callchain(struct hist_browser *self,
+                                       struct rb_root *chain,
+                                       int level, unsigned short row,
+                                       off_t *row_offset,
+                                       bool *is_current_entry)
+{
+       struct rb_node *nd;
+       int first_row = row;
+
+       for (nd = rb_first(chain); nd; nd = rb_next(nd)) {
+               struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
+
+               row += hist_browser__show_callchain_node(self, node, level,
+                                                        row, row_offset,
+                                                        is_current_entry);
+               if (row == self->b.height)
+                       break;
+       }
+
+       return row - first_row;
+}
+
+static int hist_browser__show_entry(struct hist_browser *self,
+                                   struct hist_entry *entry,
+                                   unsigned short row)
+{
+       char s[256];
+       double percent;
+       int printed = 0;
+       int color, width = self->b.width;
+       char folded_sign = ' ';
+       bool current_entry = ui_browser__is_current_entry(&self->b, row);
+       off_t row_offset = entry->row_offset;
+
+       if (current_entry) {
+               self->he_selection = entry;
+               self->selection = &entry->ms;
+       }
+
+       if (symbol_conf.use_callchain) {
+               entry->ms.has_children = !RB_EMPTY_ROOT(&entry->sorted_chain);
+               folded_sign = hist_entry__folded(entry);
+       }
+
+       if (row_offset == 0) {
+               hist_entry__snprintf(entry, s, sizeof(s), self->hists, NULL, false,
+                                    0, false, self->hists->stats.total_period);
+               percent = (entry->period * 100.0) / self->hists->stats.total_period;
+
+               color = HE_COLORSET_SELECTED;
+               if (!current_entry) {
+                       if (percent >= MIN_RED)
+                               color = HE_COLORSET_TOP;
+                       else if (percent >= MIN_GREEN)
+                               color = HE_COLORSET_MEDIUM;
+                       else
+                               color = HE_COLORSET_NORMAL;
+               }
+
+               SLsmg_set_color(color);
+               SLsmg_gotorc(self->b.top + row, self->b.left);
+               if (symbol_conf.use_callchain) {
+                       slsmg_printf("%c ", folded_sign);
+                       width -= 2;
+               }
+               slsmg_write_nstring(s, width);
+               ++row;
+               ++printed;
+       } else
+               --row_offset;
+
+       if (folded_sign == '-' && row != self->b.height) {
+               printed += hist_browser__show_callchain(self, &entry->sorted_chain,
+                                                       1, row, &row_offset,
+                                                       &current_entry);
+               if (current_entry)
+                       self->he_selection = entry;
+       }
+
+       return printed;
+}
+
+static unsigned int hist_browser__refresh_entries(struct ui_browser *self)
+{
+       unsigned row = 0;
+       struct rb_node *nd;
+       struct hist_browser *hb = container_of(self, struct hist_browser, b);
+
+       if (self->first_visible_entry == NULL)
+               self->first_visible_entry = rb_first(&hb->hists->entries);
+
+       for (nd = self->first_visible_entry; nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+
+               if (h->filtered)
+                       continue;
+
+               row += hist_browser__show_entry(hb, h, row);
+               if (row == self->height)
+                       break;
+       }
+
+       return row;
+}
+
+static void callchain_node__init_have_children_rb_tree(struct callchain_node *self)
+{
+       struct rb_node *nd = rb_first(&self->rb_root);
+
+       for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) {
+               struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node);
+               struct callchain_list *chain;
+               int first = true;
+
+               list_for_each_entry(chain, &child->val, list) {
+                       if (first) {
+                               first = false;
+                               chain->ms.has_children = chain->list.next != &child->val ||
+                                                        rb_first(&child->rb_root) != NULL;
+                       } else
+                               chain->ms.has_children = chain->list.next == &child->val &&
+                                                        rb_first(&child->rb_root) != NULL;
+               }
+
+               callchain_node__init_have_children_rb_tree(child);
+       }
+}
+
+static void callchain_node__init_have_children(struct callchain_node *self)
+{
+       struct callchain_list *chain;
+
+       list_for_each_entry(chain, &self->val, list)
+               chain->ms.has_children = rb_first(&self->rb_root) != NULL;
+
+       callchain_node__init_have_children_rb_tree(self);
+}
+
+static void callchain__init_have_children(struct rb_root *self)
+{
+       struct rb_node *nd;
+
+       for (nd = rb_first(self); nd; nd = rb_next(nd)) {
+               struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
+               callchain_node__init_have_children(node);
+       }
+}
+
+static void hist_entry__init_have_children(struct hist_entry *self)
+{
+       if (!self->init_have_children) {
+               callchain__init_have_children(&self->sorted_chain);
+               self->init_have_children = true;
+       }
+}
+
+static struct rb_node *hists__filter_entries(struct rb_node *nd)
+{
+       while (nd != NULL) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+               if (!h->filtered)
+                       return nd;
+
+               nd = rb_next(nd);
+       }
+
+       return NULL;
+}
+
+static struct rb_node *hists__filter_prev_entries(struct rb_node *nd)
+{
+       while (nd != NULL) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+               if (!h->filtered)
+                       return nd;
+
+               nd = rb_prev(nd);
+       }
+
+       return NULL;
+}
+
+static void ui_browser__hists_seek(struct ui_browser *self,
+                                  off_t offset, int whence)
+{
+       struct hist_entry *h;
+       struct rb_node *nd;
+       bool first = true;
+
+       switch (whence) {
+       case SEEK_SET:
+               nd = hists__filter_entries(rb_first(self->entries));
+               break;
+       case SEEK_CUR:
+               nd = self->first_visible_entry;
+               goto do_offset;
+       case SEEK_END:
+               nd = hists__filter_prev_entries(rb_last(self->entries));
+               first = false;
+               break;
+       default:
+               return;
+       }
+
+       /*
+        * Moves not relative to the first visible entry invalidates its
+        * row_offset:
+        */
+       h = rb_entry(self->first_visible_entry, struct hist_entry, rb_node);
+       h->row_offset = 0;
+
+       /*
+        * Here we have to check if nd is expanded (+), if it is we can't go
+        * the next top level hist_entry, instead we must compute an offset of
+        * what _not_ to show and not change the first visible entry.
+        *
+        * This offset increments when we are going from top to bottom and
+        * decreases when we're going from bottom to top.
+        *
+        * As we don't have backpointers to the top level in the callchains
+        * structure, we need to always print the whole hist_entry callchain,
+        * skipping the first ones that are before the first visible entry
+        * and stop when we printed enough lines to fill the screen.
+        */
+do_offset:
+       if (offset > 0) {
+               do {
+                       h = rb_entry(nd, struct hist_entry, rb_node);
+                       if (h->ms.unfolded) {
+                               u16 remaining = h->nr_rows - h->row_offset;
+                               if (offset > remaining) {
+                                       offset -= remaining;
+                                       h->row_offset = 0;
+                               } else {
+                                       h->row_offset += offset;
+                                       offset = 0;
+                                       self->first_visible_entry = nd;
+                                       break;
+                               }
+                       }
+                       nd = hists__filter_entries(rb_next(nd));
+                       if (nd == NULL)
+                               break;
+                       --offset;
+                       self->first_visible_entry = nd;
+               } while (offset != 0);
+       } else if (offset < 0) {
+               while (1) {
+                       h = rb_entry(nd, struct hist_entry, rb_node);
+                       if (h->ms.unfolded) {
+                               if (first) {
+                                       if (-offset > h->row_offset) {
+                                               offset += h->row_offset;
+                                               h->row_offset = 0;
+                                       } else {
+                                               h->row_offset += offset;
+                                               offset = 0;
+                                               self->first_visible_entry = nd;
+                                               break;
+                                       }
+                               } else {
+                                       if (-offset > h->nr_rows) {
+                                               offset += h->nr_rows;
+                                               h->row_offset = 0;
+                                       } else {
+                                               h->row_offset = h->nr_rows + offset;
+                                               offset = 0;
+                                               self->first_visible_entry = nd;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       nd = hists__filter_prev_entries(rb_prev(nd));
+                       if (nd == NULL)
+                               break;
+                       ++offset;
+                       self->first_visible_entry = nd;
+                       if (offset == 0) {
+                               /*
+                                * Last unfiltered hist_entry, check if it is
+                                * unfolded, if it is then we should have
+                                * row_offset at its last entry.
+                                */
+                               h = rb_entry(nd, struct hist_entry, rb_node);
+                               if (h->ms.unfolded)
+                                       h->row_offset = h->nr_rows;
+                               break;
+                       }
+                       first = false;
+               }
+       } else {
+               self->first_visible_entry = nd;
+               h = rb_entry(nd, struct hist_entry, rb_node);
+               h->row_offset = 0;
+       }
+}
+
+static int callchain_node__count_rows_rb_tree(struct callchain_node *self)
+{
+       int n = 0;
+       struct rb_node *nd;
+
+       for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) {
+               struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node);
+               struct callchain_list *chain;
+               char folded_sign = ' '; /* No children */
+
+               list_for_each_entry(chain, &child->val, list) {
+                       ++n;
+                       /* We need this because we may not have children */
+                       folded_sign = callchain_list__folded(chain);
+                       if (folded_sign == '+')
+                               break;
+               }
+
+               if (folded_sign == '-') /* Have children and they're unfolded */
+                       n += callchain_node__count_rows_rb_tree(child);
+       }
+
+       return n;
+}
+
+static int callchain_node__count_rows(struct callchain_node *node)
+{
+       struct callchain_list *chain;
+       bool unfolded = false;
+       int n = 0;
+
+       list_for_each_entry(chain, &node->val, list) {
+               ++n;
+               unfolded = chain->ms.unfolded;
+       }
+
+       if (unfolded)
+               n += callchain_node__count_rows_rb_tree(node);
+
+       return n;
+}
+
+static int callchain__count_rows(struct rb_root *chain)
+{
+       struct rb_node *nd;
+       int n = 0;
+
+       for (nd = rb_first(chain); nd; nd = rb_next(nd)) {
+               struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
+               n += callchain_node__count_rows(node);
+       }
+
+       return n;
+}
+
+static bool hist_browser__toggle_fold(struct hist_browser *self)
+{
+       if (map_symbol__toggle_fold(self->selection)) {
+               struct hist_entry *he = self->he_selection;
+
+               hist_entry__init_have_children(he);
+               self->hists->nr_entries -= he->nr_rows;
+
+               if (he->ms.unfolded)
+                       he->nr_rows = callchain__count_rows(&he->sorted_chain);
+               else
+                       he->nr_rows = 0;
+               self->hists->nr_entries += he->nr_rows;
+               self->b.nr_entries = self->hists->nr_entries;
+
+               return true;
+       }
+
+       /* If it doesn't have children, no toggling performed */
+       return false;
+}
+
+static int hist_browser__run(struct hist_browser *self, const char *title,
+                            struct newtExitStruct *es)
+{
+       char str[256], unit;
+       unsigned long nr_events = self->hists->stats.nr_events[PERF_RECORD_SAMPLE];
+
+       self->b.entries = &self->hists->entries;
+       self->b.nr_entries = self->hists->nr_entries;
+
+       hist_browser__refresh_dimensions(self);
+
+       nr_events = convert_unit(nr_events, &unit);
+       snprintf(str, sizeof(str), "Events: %lu%c                            ",
+                nr_events, unit);
+       newtDrawRootText(0, 0, str);
+
+       if (ui_browser__show(&self->b, title) < 0)
+               return -1;
+
+       newtFormAddHotKey(self->b.form, 'A');
+       newtFormAddHotKey(self->b.form, 'a');
+       newtFormAddHotKey(self->b.form, '?');
+       newtFormAddHotKey(self->b.form, 'h');
+       newtFormAddHotKey(self->b.form, 'H');
+       newtFormAddHotKey(self->b.form, 'd');
+
+       newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT);
+       newtFormAddHotKey(self->b.form, NEWT_KEY_RIGHT);
+       newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER);
+
+       while (1) {
+               ui_browser__run(&self->b, es);
+
+               if (es->reason != NEWT_EXIT_HOTKEY)
+                       break;
+               switch (es->u.key) {
+               case 'd': { /* Debug */
+                       static int seq;
+                       struct hist_entry *h = rb_entry(self->b.first_visible_entry,
+                                                       struct hist_entry, rb_node);
+                       ui_helpline__pop();
+                       ui_helpline__fpush("%d: nr_ent=(%d,%d), height=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
+                                          seq++, self->b.nr_entries,
+                                          self->hists->nr_entries,
+                                          self->b.height,
+                                          self->b.index,
+                                          self->b.first_visible_entry_idx,
+                                          h->row_offset, h->nr_rows);
+               }
+                       continue;
+               case NEWT_KEY_ENTER:
+                       if (hist_browser__toggle_fold(self))
+                               break;
+                       /* fall thru */
+               default:
+                       return 0;
+               }
+       }
+       return 0;
+}
index 9bf0f402ca730a938d79ddf2121ed822ff12de92..4af5bd59cfd14b475d0f2fa60e15f1b4b4e908de 100644 (file)
@@ -602,8 +602,15 @@ parse_breakpoint_event(const char **strp, struct perf_event_attr *attr)
                        return EVT_FAILED;
        }
 
-       /* We should find a nice way to override the access type */
-       attr->bp_len = HW_BREAKPOINT_LEN_4;
+       /*
+        * We should find a nice way to override the access length
+        * Provide some defaults for now
+        */
+       if (attr->bp_type == HW_BREAKPOINT_X)
+               attr->bp_len = sizeof(long);
+       else
+               attr->bp_len = HW_BREAKPOINT_LEN_4;
+
        attr->type = PERF_TYPE_BREAKPOINT;
 
        return EVT_HANDLED;
index 914c67095d965d14ca7ca8b1c58f37ba83b9573c..2e665cb84055042edcddb9bef62cf45d71cbe238 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * probe-event.c : perf-probe definition to kprobe_events format converter
+ * probe-event.c : perf-probe definition to probe_events format converter
  *
  * Written by Masami Hiramatsu <mhiramat@redhat.com>
  *
@@ -120,8 +120,11 @@ static int open_vmlinux(void)
        return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
 }
 
-/* Convert trace point to probe point with debuginfo */
-static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+/*
+ * Convert trace point to probe point with debuginfo
+ * Currently only handles kprobes.
+ */
+static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
                                       struct perf_probe_point *pp)
 {
        struct symbol *sym;
@@ -151,8 +154,8 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
 }
 
 /* Try to find perf_probe_event with debuginfo */
-static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
-                                          struct kprobe_trace_event **tevs,
+static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
+                                          struct probe_trace_event **tevs,
                                           int max_tevs)
 {
        bool need_dwarf = perf_probe_event_need_dwarf(pev);
@@ -169,11 +172,11 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
        }
 
        /* Searching trace events corresponding to probe event */
-       ntevs = find_kprobe_trace_events(fd, pev, tevs, max_tevs);
+       ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs);
        close(fd);
 
        if (ntevs > 0) {        /* Succeeded to find trace events */
-               pr_debug("find %d kprobe_trace_events.\n", ntevs);
+               pr_debug("find %d probe_trace_events.\n", ntevs);
                return ntevs;
        }
 
@@ -195,6 +198,65 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
        return ntevs;
 }
 
+/*
+ * Find a src file from a DWARF tag path. Prepend optional source path prefix
+ * and chop off leading directories that do not exist. Result is passed back as
+ * a newly allocated path on success.
+ * Return 0 if file was found and readable, -errno otherwise.
+ */
+static int get_real_path(const char *raw_path, const char *comp_dir,
+                        char **new_path)
+{
+       const char *prefix = symbol_conf.source_prefix;
+
+       if (!prefix) {
+               if (raw_path[0] != '/' && comp_dir)
+                       /* If not an absolute path, try to use comp_dir */
+                       prefix = comp_dir;
+               else {
+                       if (access(raw_path, R_OK) == 0) {
+                               *new_path = strdup(raw_path);
+                               return 0;
+                       } else
+                               return -errno;
+               }
+       }
+
+       *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2));
+       if (!*new_path)
+               return -ENOMEM;
+
+       for (;;) {
+               sprintf(*new_path, "%s/%s", prefix, raw_path);
+
+               if (access(*new_path, R_OK) == 0)
+                       return 0;
+
+               if (!symbol_conf.source_prefix)
+                       /* In case of searching comp_dir, don't retry */
+                       return -errno;
+
+               switch (errno) {
+               case ENAMETOOLONG:
+               case ENOENT:
+               case EROFS:
+               case EFAULT:
+                       raw_path = strchr(++raw_path, '/');
+                       if (!raw_path) {
+                               free(*new_path);
+                               *new_path = NULL;
+                               return -ENOENT;
+                       }
+                       continue;
+
+               default:
+                       free(*new_path);
+                       *new_path = NULL;
+                       return -errno;
+               }
+       }
+}
+
 #define LINEBUF_SIZE 256
 #define NR_ADDITIONAL_LINES 2
 
@@ -244,6 +306,7 @@ int show_line_range(struct line_range *lr)
        struct line_node *ln;
        FILE *fp;
        int fd, ret;
+       char *tmp;
 
        /* Search a line range */
        ret = init_vmlinux();
@@ -266,6 +329,15 @@ int show_line_range(struct line_range *lr)
                return ret;
        }
 
+       /* Convert source file path */
+       tmp = lr->path;
+       ret = get_real_path(tmp, lr->comp_dir, &lr->path);
+       free(tmp);      /* Free old path */
+       if (ret < 0) {
+               pr_warning("Failed to find source file. (%d)\n", ret);
+               return ret;
+       }
+
        setup_pager();
 
        if (lr->function)
@@ -308,8 +380,8 @@ end:
 
 #else  /* !DWARF_SUPPORT */
 
-static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
-                                       struct perf_probe_point *pp)
+static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
+                                      struct perf_probe_point *pp)
 {
        pp->function = strdup(tp->symbol);
        if (pp->function == NULL)
@@ -320,8 +392,8 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
        return 0;
 }
 
-static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
-                               struct kprobe_trace_event **tevs __unused,
+static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
+                               struct probe_trace_event **tevs __unused,
                                int max_tevs __unused)
 {
        if (perf_probe_event_need_dwarf(pev)) {
@@ -557,7 +629,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 /* Parse perf-probe event argument */
 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
 {
-       char *tmp;
+       char *tmp, *goodname;
        struct perf_probe_arg_field **fieldp;
 
        pr_debug("parsing arg: %s into ", str);
@@ -580,7 +652,7 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
                pr_debug("type:%s ", arg->type);
        }
 
-       tmp = strpbrk(str, "-.");
+       tmp = strpbrk(str, "-.[");
        if (!is_c_varname(str) || !tmp) {
                /* A variable, register, symbol or special value */
                arg->var = strdup(str);
@@ -590,10 +662,11 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
                return 0;
        }
 
-       /* Structure fields */
+       /* Structure fields or array element */
        arg->var = strndup(str, tmp - str);
        if (arg->var == NULL)
                return -ENOMEM;
+       goodname = arg->var;
        pr_debug("%s, ", arg->var);
        fieldp = &arg->field;
 
@@ -601,22 +674,38 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
                *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
                if (*fieldp == NULL)
                        return -ENOMEM;
-               if (*tmp == '.') {
-                       str = tmp + 1;
-                       (*fieldp)->ref = false;
-               } else if (tmp[1] == '>') {
-                       str = tmp + 2;
+               if (*tmp == '[') {      /* Array */
+                       str = tmp;
+                       (*fieldp)->index = strtol(str + 1, &tmp, 0);
                        (*fieldp)->ref = true;
-               } else {
-                       semantic_error("Argument parse error: %s\n", str);
-                       return -EINVAL;
+                       if (*tmp != ']' || tmp == str + 1) {
+                               semantic_error("Array index must be a"
+                                               " number.\n");
+                               return -EINVAL;
+                       }
+                       tmp++;
+                       if (*tmp == '\0')
+                               tmp = NULL;
+               } else {                /* Structure */
+                       if (*tmp == '.') {
+                               str = tmp + 1;
+                               (*fieldp)->ref = false;
+                       } else if (tmp[1] == '>') {
+                               str = tmp + 2;
+                               (*fieldp)->ref = true;
+                       } else {
+                               semantic_error("Argument parse error: %s\n",
+                                              str);
+                               return -EINVAL;
+                       }
+                       tmp = strpbrk(str, "-.[");
                }
-
-               tmp = strpbrk(str, "-.");
                if (tmp) {
                        (*fieldp)->name = strndup(str, tmp - str);
                        if ((*fieldp)->name == NULL)
                                return -ENOMEM;
+                       if (*str != '[')
+                               goodname = (*fieldp)->name;
                        pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
                        fieldp = &(*fieldp)->next;
                }
@@ -624,11 +713,13 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
        (*fieldp)->name = strdup(str);
        if ((*fieldp)->name == NULL)
                return -ENOMEM;
+       if (*str != '[')
+               goodname = (*fieldp)->name;
        pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
 
-       /* If no name is specified, set the last field name */
+       /* If no name is specified, set the last field name (not array index)*/
        if (!arg->name) {
-               arg->name = strdup((*fieldp)->name);
+               arg->name = strdup(goodname);
                if (arg->name == NULL)
                        return -ENOMEM;
        }
@@ -693,16 +784,17 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
        return false;
 }
 
-/* Parse kprobe_events event into struct probe_point */
-int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
+/* Parse probe_events event into struct probe_point */
+static int parse_probe_trace_command(const char *cmd,
+                                       struct probe_trace_event *tev)
 {
-       struct kprobe_trace_point *tp = &tev->point;
+       struct probe_trace_point *tp = &tev->point;
        char pr;
        char *p;
        int ret, i, argc;
        char **argv;
 
-       pr_debug("Parsing kprobe_events: %s\n", cmd);
+       pr_debug("Parsing probe_events: %s\n", cmd);
        argv = argv_split(cmd, &argc);
        if (!argv) {
                pr_debug("Failed to split arguments.\n");
@@ -734,7 +826,7 @@ int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
                tp->offset = 0;
 
        tev->nargs = argc - 2;
-       tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
+       tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
        if (tev->args == NULL) {
                ret = -ENOMEM;
                goto out;
@@ -776,8 +868,11 @@ int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
        len -= ret;
 
        while (field) {
-               ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".",
-                                field->name);
+               if (field->name[0] == '[')
+                       ret = e_snprintf(tmp, len, "%s", field->name);
+               else
+                       ret = e_snprintf(tmp, len, "%s%s",
+                                        field->ref ? "->" : ".", field->name);
                if (ret <= 0)
                        goto error;
                tmp += ret;
@@ -877,13 +972,13 @@ char *synthesize_perf_probe_command(struct perf_probe_event *pev)
 }
 #endif
 
-static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref,
+static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
                                             char **buf, size_t *buflen,
                                             int depth)
 {
        int ret;
        if (ref->next) {
-               depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf,
+               depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
                                                         buflen, depth + 1);
                if (depth < 0)
                        goto out;
@@ -901,9 +996,10 @@ out:
 
 }
 
-static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
+static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
                                       char *buf, size_t buflen)
 {
+       struct probe_trace_arg_ref *ref = arg->ref;
        int ret, depth = 0;
        char *tmp = buf;
 
@@ -917,16 +1013,24 @@ static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
        buf += ret;
        buflen -= ret;
 
+       /* Special case: @XXX */
+       if (arg->value[0] == '@' && arg->ref)
+                       ref = ref->next;
+
        /* Dereferencing arguments */
-       if (arg->ref) {
-               depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf,
+       if (ref) {
+               depth = __synthesize_probe_trace_arg_ref(ref, &buf,
                                                          &buflen, 1);
                if (depth < 0)
                        return depth;
        }
 
        /* Print argument value */
-       ret = e_snprintf(buf, buflen, "%s", arg->value);
+       if (arg->value[0] == '@' && arg->ref)
+               ret = e_snprintf(buf, buflen, "%s%+ld", arg->value,
+                                arg->ref->offset);
+       else
+               ret = e_snprintf(buf, buflen, "%s", arg->value);
        if (ret < 0)
                return ret;
        buf += ret;
@@ -951,9 +1055,9 @@ static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
        return buf - tmp;
 }
 
-char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
+char *synthesize_probe_trace_command(struct probe_trace_event *tev)
 {
-       struct kprobe_trace_point *tp = &tev->point;
+       struct probe_trace_point *tp = &tev->point;
        char *buf;
        int i, len, ret;
 
@@ -969,7 +1073,7 @@ char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
                goto error;
 
        for (i = 0; i < tev->nargs; i++) {
-               ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len,
+               ret = synthesize_probe_trace_arg(&tev->args[i], buf + len,
                                                  MAX_CMDLEN - len);
                if (ret <= 0)
                        goto error;
@@ -982,7 +1086,7 @@ error:
        return NULL;
 }
 
-int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
+static int convert_to_perf_probe_event(struct probe_trace_event *tev,
                                struct perf_probe_event *pev)
 {
        char buf[64] = "";
@@ -995,7 +1099,7 @@ int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
                return -ENOMEM;
 
        /* Convert trace_point to probe_point */
-       ret = convert_to_perf_probe_point(&tev->point, &pev->point);
+       ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point);
        if (ret < 0)
                return ret;
 
@@ -1008,7 +1112,7 @@ int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
                if (tev->args[i].name)
                        pev->args[i].name = strdup(tev->args[i].name);
                else {
-                       ret = synthesize_kprobe_trace_arg(&tev->args[i],
+                       ret = synthesize_probe_trace_arg(&tev->args[i],
                                                          buf, 64);
                        pev->args[i].name = strdup(buf);
                }
@@ -1059,9 +1163,9 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
        memset(pev, 0, sizeof(*pev));
 }
 
-void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
+static void clear_probe_trace_event(struct probe_trace_event *tev)
 {
-       struct kprobe_trace_arg_ref *ref, *next;
+       struct probe_trace_arg_ref *ref, *next;
        int i;
 
        if (tev->event)
@@ -1122,7 +1226,7 @@ static int open_kprobe_events(bool readwrite)
 }
 
 /* Get raw string list of current kprobe_events */
-static struct strlist *get_kprobe_trace_command_rawlist(int fd)
+static struct strlist *get_probe_trace_command_rawlist(int fd)
 {
        int ret, idx;
        FILE *fp;
@@ -1190,7 +1294,7 @@ static int show_perf_probe_event(struct perf_probe_event *pev)
 int show_perf_probe_events(void)
 {
        int fd, ret;
-       struct kprobe_trace_event tev;
+       struct probe_trace_event tev;
        struct perf_probe_event pev;
        struct strlist *rawlist;
        struct str_node *ent;
@@ -1207,20 +1311,20 @@ int show_perf_probe_events(void)
        if (fd < 0)
                return fd;
 
-       rawlist = get_kprobe_trace_command_rawlist(fd);
+       rawlist = get_probe_trace_command_rawlist(fd);
        close(fd);
        if (!rawlist)
                return -ENOENT;
 
        strlist__for_each(ent, rawlist) {
-               ret = parse_kprobe_trace_command(ent->s, &tev);
+               ret = parse_probe_trace_command(ent->s, &tev);
                if (ret >= 0) {
                        ret = convert_to_perf_probe_event(&tev, &pev);
                        if (ret >= 0)
                                ret = show_perf_probe_event(&pev);
                }
                clear_perf_probe_event(&pev);
-               clear_kprobe_trace_event(&tev);
+               clear_probe_trace_event(&tev);
                if (ret < 0)
                        break;
        }
@@ -1230,20 +1334,19 @@ int show_perf_probe_events(void)
 }
 
 /* Get current perf-probe event names */
-static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
+static struct strlist *get_probe_trace_event_names(int fd, bool include_group)
 {
        char buf[128];
        struct strlist *sl, *rawlist;
        struct str_node *ent;
-       struct kprobe_trace_event tev;
+       struct probe_trace_event tev;
        int ret = 0;
 
        memset(&tev, 0, sizeof(tev));
-
-       rawlist = get_kprobe_trace_command_rawlist(fd);
+       rawlist = get_probe_trace_command_rawlist(fd);
        sl = strlist__new(true, NULL);
        strlist__for_each(ent, rawlist) {
-               ret = parse_kprobe_trace_command(ent->s, &tev);
+               ret = parse_probe_trace_command(ent->s, &tev);
                if (ret < 0)
                        break;
                if (include_group) {
@@ -1253,7 +1356,7 @@ static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
                                ret = strlist__add(sl, buf);
                } else
                        ret = strlist__add(sl, tev.event);
-               clear_kprobe_trace_event(&tev);
+               clear_probe_trace_event(&tev);
                if (ret < 0)
                        break;
        }
@@ -1266,13 +1369,13 @@ static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
        return sl;
 }
 
-static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
+static int write_probe_trace_event(int fd, struct probe_trace_event *tev)
 {
        int ret = 0;
-       char *buf = synthesize_kprobe_trace_command(tev);
+       char *buf = synthesize_probe_trace_command(tev);
 
        if (!buf) {
-               pr_debug("Failed to synthesize kprobe trace event.\n");
+               pr_debug("Failed to synthesize probe trace event.\n");
                return -EINVAL;
        }
 
@@ -1325,12 +1428,12 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
        return ret;
 }
 
-static int __add_kprobe_trace_events(struct perf_probe_event *pev,
-                                    struct kprobe_trace_event *tevs,
+static int __add_probe_trace_events(struct perf_probe_event *pev,
+                                    struct probe_trace_event *tevs,
                                     int ntevs, bool allow_suffix)
 {
        int i, fd, ret;
-       struct kprobe_trace_event *tev = NULL;
+       struct probe_trace_event *tev = NULL;
        char buf[64];
        const char *event, *group;
        struct strlist *namelist;
@@ -1339,7 +1442,7 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev,
        if (fd < 0)
                return fd;
        /* Get current event names */
-       namelist = get_kprobe_trace_event_names(fd, false);
+       namelist = get_probe_trace_event_names(fd, false);
        if (!namelist) {
                pr_debug("Failed to get current event list.\n");
                return -EIO;
@@ -1374,7 +1477,7 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev,
                        ret = -ENOMEM;
                        break;
                }
-               ret = write_kprobe_trace_event(fd, tev);
+               ret = write_probe_trace_event(fd, tev);
                if (ret < 0)
                        break;
                /* Add added event name to namelist */
@@ -1411,21 +1514,21 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev,
        return ret;
 }
 
-static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
-                                         struct kprobe_trace_event **tevs,
+static int convert_to_probe_trace_events(struct perf_probe_event *pev,
+                                         struct probe_trace_event **tevs,
                                          int max_tevs)
 {
        struct symbol *sym;
        int ret = 0, i;
-       struct kprobe_trace_event *tev;
+       struct probe_trace_event *tev;
 
        /* Convert perf_probe_event with debuginfo */
-       ret = try_to_find_kprobe_trace_events(pev, tevs, max_tevs);
+       ret = try_to_find_probe_trace_events(pev, tevs, max_tevs);
        if (ret != 0)
                return ret;
 
        /* Allocate trace event buffer */
-       tev = *tevs = zalloc(sizeof(struct kprobe_trace_event));
+       tev = *tevs = zalloc(sizeof(struct probe_trace_event));
        if (tev == NULL)
                return -ENOMEM;
 
@@ -1438,7 +1541,7 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
        tev->point.offset = pev->point.offset;
        tev->nargs = pev->nargs;
        if (tev->nargs) {
-               tev->args = zalloc(sizeof(struct kprobe_trace_arg)
+               tev->args = zalloc(sizeof(struct probe_trace_arg)
                                   * tev->nargs);
                if (tev->args == NULL) {
                        ret = -ENOMEM;
@@ -1479,7 +1582,7 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
 
        return 1;
 error:
-       clear_kprobe_trace_event(tev);
+       clear_probe_trace_event(tev);
        free(tev);
        *tevs = NULL;
        return ret;
@@ -1487,7 +1590,7 @@ error:
 
 struct __event_package {
        struct perf_probe_event         *pev;
-       struct kprobe_trace_event       *tevs;
+       struct probe_trace_event        *tevs;
        int                             ntevs;
 };
 
@@ -1510,7 +1613,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
        for (i = 0; i < npevs; i++) {
                pkgs[i].pev = &pevs[i];
                /* Convert with or without debuginfo */
-               ret  = convert_to_kprobe_trace_events(pkgs[i].pev,
+               ret  = convert_to_probe_trace_events(pkgs[i].pev,
                                                      &pkgs[i].tevs, max_tevs);
                if (ret < 0)
                        goto end;
@@ -1519,24 +1622,24 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
 
        /* Loop 2: add all events */
        for (i = 0; i < npevs && ret >= 0; i++)
-               ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
+               ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs,
                                                pkgs[i].ntevs, force_add);
 end:
        /* Loop 3: cleanup trace events  */
        for (i = 0; i < npevs; i++)
                for (j = 0; j < pkgs[i].ntevs; j++)
-                       clear_kprobe_trace_event(&pkgs[i].tevs[j]);
+                       clear_probe_trace_event(&pkgs[i].tevs[j]);
 
        return ret;
 }
 
-static int __del_trace_kprobe_event(int fd, struct str_node *ent)
+static int __del_trace_probe_event(int fd, struct str_node *ent)
 {
        char *p;
        char buf[128];
        int ret;
 
-       /* Convert from perf-probe event to trace-kprobe event */
+       /* Convert from perf-probe event to trace-probe event */
        ret = e_snprintf(buf, 128, "-:%s", ent->s);
        if (ret < 0)
                goto error;
@@ -1562,7 +1665,7 @@ error:
        return ret;
 }
 
-static int del_trace_kprobe_event(int fd, const char *group,
+static int del_trace_probe_event(int fd, const char *group,
                                  const char *event, struct strlist *namelist)
 {
        char buf[128];
@@ -1579,7 +1682,7 @@ static int del_trace_kprobe_event(int fd, const char *group,
                strlist__for_each_safe(ent, n, namelist)
                        if (strglobmatch(ent->s, buf)) {
                                found++;
-                               ret = __del_trace_kprobe_event(fd, ent);
+                               ret = __del_trace_probe_event(fd, ent);
                                if (ret < 0)
                                        break;
                                strlist__remove(namelist, ent);
@@ -1588,7 +1691,7 @@ static int del_trace_kprobe_event(int fd, const char *group,
                ent = strlist__find(namelist, buf);
                if (ent) {
                        found++;
-                       ret = __del_trace_kprobe_event(fd, ent);
+                       ret = __del_trace_probe_event(fd, ent);
                        if (ret >= 0)
                                strlist__remove(namelist, ent);
                }
@@ -1612,7 +1715,7 @@ int del_perf_probe_events(struct strlist *dellist)
                return fd;
 
        /* Get current event names */
-       namelist = get_kprobe_trace_event_names(fd, true);
+       namelist = get_probe_trace_event_names(fd, true);
        if (namelist == NULL)
                return -EINVAL;
 
@@ -1633,7 +1736,7 @@ int del_perf_probe_events(struct strlist *dellist)
                        event = str;
                }
                pr_debug("Group: %s, Event: %s\n", group, event);
-               ret = del_trace_kprobe_event(fd, group, event, namelist);
+               ret = del_trace_probe_event(fd, group, event, namelist);
                free(str);
                if (ret < 0)
                        break;
index e9db1a214ca4d9c4c7f9e3a46151070c6cd68ce7..5af39243a25bd00975d6880f4524180edebb236a 100644 (file)
@@ -7,33 +7,33 @@
 extern bool probe_event_dry_run;
 
 /* kprobe-tracer tracing point */
-struct kprobe_trace_point {
+struct probe_trace_point {
        char            *symbol;        /* Base symbol */
        unsigned long   offset;         /* Offset from symbol */
        bool            retprobe;       /* Return probe flag */
 };
 
-/* kprobe-tracer tracing argument referencing offset */
-struct kprobe_trace_arg_ref {
-       struct kprobe_trace_arg_ref     *next;  /* Next reference */
+/* probe-tracer tracing argument referencing offset */
+struct probe_trace_arg_ref {
+       struct probe_trace_arg_ref      *next;  /* Next reference */
        long                            offset; /* Offset value */
 };
 
 /* kprobe-tracer tracing argument */
-struct kprobe_trace_arg {
+struct probe_trace_arg {
        char                            *name;  /* Argument name */
        char                            *value; /* Base value */
        char                            *type;  /* Type name */
-       struct kprobe_trace_arg_ref     *ref;   /* Referencing offset */
+       struct probe_trace_arg_ref      *ref;   /* Referencing offset */
 };
 
 /* kprobe-tracer tracing event (point + arg) */
-struct kprobe_trace_event {
+struct probe_trace_event {
        char                            *event; /* Event name */
        char                            *group; /* Group name */
-       struct kprobe_trace_point       point;  /* Trace point */
+       struct probe_trace_point        point;  /* Trace point */
        int                             nargs;  /* Number of args */
-       struct kprobe_trace_arg         *args;  /* Arguments */
+       struct probe_trace_arg          *args;  /* Arguments */
 };
 
 /* Perf probe probing point */
@@ -50,6 +50,7 @@ struct perf_probe_point {
 struct perf_probe_arg_field {
        struct perf_probe_arg_field     *next;  /* Next field */
        char                            *name;  /* Name of the field */
+       long                            index;  /* Array index number */
        bool                            ref;    /* Referencing flag */
 };
 
@@ -85,31 +86,25 @@ struct line_range {
        int                     end;            /* End line number */
        int                     offset;         /* Start line offset */
        char                    *path;          /* Real path name */
+       char                    *comp_dir;      /* Compile directory */
        struct list_head        line_list;      /* Visible lines */
 };
 
 /* Command string to events */
 extern int parse_perf_probe_command(const char *cmd,
                                    struct perf_probe_event *pev);
-extern int parse_kprobe_trace_command(const char *cmd,
-                                     struct kprobe_trace_event *tev);
 
 /* Events to command string */
 extern char *synthesize_perf_probe_command(struct perf_probe_event *pev);
-extern char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev);
+extern char *synthesize_probe_trace_command(struct probe_trace_event *tev);
 extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf,
                                     size_t len);
 
 /* Check the perf_probe_event needs debuginfo */
 extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
 
-/* Convert from kprobe_trace_event to perf_probe_event */
-extern int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
-                                      struct perf_probe_event *pev);
-
 /* Release event contents */
 extern void clear_perf_probe_event(struct perf_probe_event *pev);
-extern void clear_kprobe_trace_event(struct kprobe_trace_event *tev);
 
 /* Command string to line-range */
 extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
index d964cb199c672f96712c4125ba036b7bfe038687..840f1aabbb748b5cd9ef8c8e8b3cc722067b215e 100644 (file)
@@ -37,6 +37,7 @@
 #include "event.h"
 #include "debug.h"
 #include "util.h"
+#include "symbol.h"
 #include "probe-finder.h"
 
 /* Kprobe tracer basic type is up to u64 */
@@ -143,12 +144,21 @@ static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
        return src;
 }
 
+/* Get DW_AT_comp_dir (should be NULL with older gcc) */
+static const char *cu_get_comp_dir(Dwarf_Die *cu_die)
+{
+       Dwarf_Attribute attr;
+       if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
+               return NULL;
+       return dwarf_formstring(&attr);
+}
+
 /* Compare diename and tname */
 static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
 {
        const char *name;
        name = dwarf_diename(dw_die);
-       return name ? strcmp(tname, name) : -1;
+       return name ? (strcmp(tname, name) == 0) : false;
 }
 
 /* Get type die, but skip qualifiers and typedef */
@@ -319,7 +329,7 @@ static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
        tag = dwarf_tag(die_mem);
        if ((tag == DW_TAG_formal_parameter ||
             tag == DW_TAG_variable) &&
-           (die_compare_name(die_mem, name) == 0))
+           die_compare_name(die_mem, name))
                return DIE_FIND_CB_FOUND;
 
        return DIE_FIND_CB_CONTINUE;
@@ -338,7 +348,7 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
        const char *name = data;
 
        if ((dwarf_tag(die_mem) == DW_TAG_member) &&
-           (die_compare_name(die_mem, name) == 0))
+           die_compare_name(die_mem, name))
                return DIE_FIND_CB_FOUND;
 
        return DIE_FIND_CB_SIBLING;
@@ -356,14 +366,50 @@ static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
  * Probe finder related functions
  */
 
+static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
+{
+       struct probe_trace_arg_ref *ref;
+       ref = zalloc(sizeof(struct probe_trace_arg_ref));
+       if (ref != NULL)
+               ref->offset = offs;
+       return ref;
+}
+
 /* Show a location */
-static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
+static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf)
 {
+       Dwarf_Attribute attr;
+       Dwarf_Op *op;
+       size_t nops;
        unsigned int regn;
        Dwarf_Word offs = 0;
        bool ref = false;
        const char *regs;
-       struct kprobe_trace_arg *tvar = pf->tvar;
+       struct probe_trace_arg *tvar = pf->tvar;
+       int ret;
+
+       /* TODO: handle more than 1 exprs */
+       if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL ||
+           dwarf_getlocation_addr(&attr, pf->addr, &op, &nops, 1) <= 0 ||
+           nops == 0) {
+               /* TODO: Support const_value */
+               pr_err("Failed to find the location of %s at this address.\n"
+                      " Perhaps, it has been optimized out.\n", pf->pvar->var);
+               return -ENOENT;
+       }
+
+       if (op->atom == DW_OP_addr) {
+               /* Static variables on memory (not stack), make @varname */
+               ret = strlen(dwarf_diename(vr_die));
+               tvar->value = zalloc(ret + 2);
+               if (tvar->value == NULL)
+                       return -ENOMEM;
+               snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die));
+               tvar->ref = alloc_trace_arg_ref((long)offs);
+               if (tvar->ref == NULL)
+                       return -ENOMEM;
+               return 0;
+       }
 
        /* If this is based on frame buffer, set the offset */
        if (op->atom == DW_OP_fbreg) {
@@ -405,27 +451,72 @@ static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
                return -ENOMEM;
 
        if (ref) {
-               tvar->ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
+               tvar->ref = alloc_trace_arg_ref((long)offs);
                if (tvar->ref == NULL)
                        return -ENOMEM;
-               tvar->ref->offset = (long)offs;
        }
        return 0;
 }
 
 static int convert_variable_type(Dwarf_Die *vr_die,
-                                struct kprobe_trace_arg *targ)
+                                struct probe_trace_arg *tvar,
+                                const char *cast)
 {
+       struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
        Dwarf_Die type;
        char buf[16];
        int ret;
 
+       /* TODO: check all types */
+       if (cast && strcmp(cast, "string") != 0) {
+               /* Non string type is OK */
+               tvar->type = strdup(cast);
+               return (tvar->type == NULL) ? -ENOMEM : 0;
+       }
+
        if (die_get_real_type(vr_die, &type) == NULL) {
                pr_warning("Failed to get a type information of %s.\n",
                           dwarf_diename(vr_die));
                return -ENOENT;
        }
 
+       pr_debug("%s type is %s.\n",
+                dwarf_diename(vr_die), dwarf_diename(&type));
+
+       if (cast && strcmp(cast, "string") == 0) {      /* String type */
+               ret = dwarf_tag(&type);
+               if (ret != DW_TAG_pointer_type &&
+                   ret != DW_TAG_array_type) {
+                       pr_warning("Failed to cast into string: "
+                                  "%s(%s) is not a pointer nor array.",
+                                  dwarf_diename(vr_die), dwarf_diename(&type));
+                       return -EINVAL;
+               }
+               if (ret == DW_TAG_pointer_type) {
+                       if (die_get_real_type(&type, &type) == NULL) {
+                               pr_warning("Failed to get a type information.");
+                               return -ENOENT;
+                       }
+                       while (*ref_ptr)
+                               ref_ptr = &(*ref_ptr)->next;
+                       /* Add new reference with offset +0 */
+                       *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
+                       if (*ref_ptr == NULL) {
+                               pr_warning("Out of memory error\n");
+                               return -ENOMEM;
+                       }
+               }
+               if (!die_compare_name(&type, "char") &&
+                   !die_compare_name(&type, "unsigned char")) {
+                       pr_warning("Failed to cast into string: "
+                                  "%s is not (unsigned) char *.",
+                                  dwarf_diename(vr_die));
+                       return -EINVAL;
+               }
+               tvar->type = strdup(cast);
+               return (tvar->type == NULL) ? -ENOMEM : 0;
+       }
+
        ret = die_get_byte_size(&type) * 8;
        if (ret) {
                /* Check the bitwidth */
@@ -445,8 +536,8 @@ static int convert_variable_type(Dwarf_Die *vr_die,
                                   strerror(-ret));
                        return ret;
                }
-               targ->type = strdup(buf);
-               if (targ->type == NULL)
+               tvar->type = strdup(buf);
+               if (tvar->type == NULL)
                        return -ENOMEM;
        }
        return 0;
@@ -454,22 +545,50 @@ static int convert_variable_type(Dwarf_Die *vr_die,
 
 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
                                    struct perf_probe_arg_field *field,
-                                   struct kprobe_trace_arg_ref **ref_ptr,
+                                   struct probe_trace_arg_ref **ref_ptr,
                                    Dwarf_Die *die_mem)
 {
-       struct kprobe_trace_arg_ref *ref = *ref_ptr;
+       struct probe_trace_arg_ref *ref = *ref_ptr;
        Dwarf_Die type;
        Dwarf_Word offs;
-       int ret;
+       int ret, tag;
 
        pr_debug("converting %s in %s\n", field->name, varname);
        if (die_get_real_type(vr_die, &type) == NULL) {
                pr_warning("Failed to get the type of %s.\n", varname);
                return -ENOENT;
        }
-
-       /* Check the pointer and dereference */
-       if (dwarf_tag(&type) == DW_TAG_pointer_type) {
+       pr_debug2("Var real type: (%x)\n", (unsigned)dwarf_dieoffset(&type));
+       tag = dwarf_tag(&type);
+
+       if (field->name[0] == '[' &&
+           (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) {
+               if (field->next)
+                       /* Save original type for next field */
+                       memcpy(die_mem, &type, sizeof(*die_mem));
+               /* Get the type of this array */
+               if (die_get_real_type(&type, &type) == NULL) {
+                       pr_warning("Failed to get the type of %s.\n", varname);
+                       return -ENOENT;
+               }
+               pr_debug2("Array real type: (%x)\n",
+                        (unsigned)dwarf_dieoffset(&type));
+               if (tag == DW_TAG_pointer_type) {
+                       ref = zalloc(sizeof(struct probe_trace_arg_ref));
+                       if (ref == NULL)
+                               return -ENOMEM;
+                       if (*ref_ptr)
+                               (*ref_ptr)->next = ref;
+                       else
+                               *ref_ptr = ref;
+               }
+               ref->offset += die_get_byte_size(&type) * field->index;
+               if (!field->next)
+                       /* Save vr_die for converting types */
+                       memcpy(die_mem, vr_die, sizeof(*die_mem));
+               goto next;
+       } else if (tag == DW_TAG_pointer_type) {
+               /* Check the pointer and dereference */
                if (!field->ref) {
                        pr_err("Semantic error: %s must be referred by '->'\n",
                               field->name);
@@ -486,7 +605,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
                        return -EINVAL;
                }
 
-               ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
+               ref = zalloc(sizeof(struct probe_trace_arg_ref));
                if (ref == NULL)
                        return -ENOMEM;
                if (*ref_ptr)
@@ -495,10 +614,15 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
                        *ref_ptr = ref;
        } else {
                /* Verify it is a data structure  */
-               if (dwarf_tag(&type) != DW_TAG_structure_type) {
+               if (tag != DW_TAG_structure_type) {
                        pr_warning("%s is not a data structure.\n", varname);
                        return -EINVAL;
                }
+               if (field->name[0] == '[') {
+                       pr_err("Semantic error: %s is not a pointor nor array.",
+                              varname);
+                       return -EINVAL;
+               }
                if (field->ref) {
                        pr_err("Semantic error: %s must be referred by '.'\n",
                               field->name);
@@ -525,6 +649,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
        }
        ref->offset += (long)offs;
 
+next:
        /* Converting next field */
        if (field->next)
                return convert_variable_fields(die_mem, field->name,
@@ -536,51 +661,32 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 /* Show a variables in kprobe event format */
 static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 {
-       Dwarf_Attribute attr;
        Dwarf_Die die_mem;
-       Dwarf_Op *expr;
-       size_t nexpr;
        int ret;
 
-       if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
-               goto error;
-       /* TODO: handle more than 1 exprs */
-       ret = dwarf_getlocation_addr(&attr, pf->addr, &expr, &nexpr, 1);
-       if (ret <= 0 || nexpr == 0)
-               goto error;
+       pr_debug("Converting variable %s into trace event.\n",
+                dwarf_diename(vr_die));
 
-       ret = convert_location(expr, pf);
+       ret = convert_variable_location(vr_die, pf);
        if (ret == 0 && pf->pvar->field) {
                ret = convert_variable_fields(vr_die, pf->pvar->var,
                                              pf->pvar->field, &pf->tvar->ref,
                                              &die_mem);
                vr_die = &die_mem;
        }
-       if (ret == 0) {
-               if (pf->pvar->type) {
-                       pf->tvar->type = strdup(pf->pvar->type);
-                       if (pf->tvar->type == NULL)
-                               ret = -ENOMEM;
-               } else
-                       ret = convert_variable_type(vr_die, pf->tvar);
-       }
+       if (ret == 0)
+               ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
        /* *expr will be cached in libdw. Don't free it. */
        return ret;
-error:
-       /* TODO: Support const_value */
-       pr_err("Failed to find the location of %s at this address.\n"
-              " Perhaps, it has been optimized out.\n", pf->pvar->var);
-       return -ENOENT;
 }
 
 /* Find a variable in a subprogram die */
 static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
-       Dwarf_Die vr_die;
+       Dwarf_Die vr_die, *scopes;
        char buf[32], *ptr;
-       int ret;
+       int ret, nscopes;
 
-       /* TODO: Support arrays */
        if (pf->pvar->name)
                pf->tvar->name = strdup(pf->pvar->name);
        else {
@@ -607,18 +713,32 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
        pr_debug("Searching '%s' variable in context.\n",
                 pf->pvar->var);
        /* Search child die for local variables and parameters. */
-       if (!die_find_variable(sp_die, pf->pvar->var, &vr_die)) {
+       if (die_find_variable(sp_die, pf->pvar->var, &vr_die))
+               ret = convert_variable(&vr_die, pf);
+       else {
+               /* Search upper class */
+               nscopes = dwarf_getscopes_die(sp_die, &scopes);
+               if (nscopes > 0) {
+                       ret = dwarf_getscopevar(scopes, nscopes, pf->pvar->var,
+                                               0, NULL, 0, 0, &vr_die);
+                       if (ret >= 0)
+                               ret = convert_variable(&vr_die, pf);
+                       else
+                               ret = -ENOENT;
+                       free(scopes);
+               } else
+                       ret = -ENOENT;
+       }
+       if (ret < 0)
                pr_warning("Failed to find '%s' in this function.\n",
                           pf->pvar->var);
-               return -ENOENT;
-       }
-       return convert_variable(&vr_die, pf);
+       return ret;
 }
 
 /* Show a probe point to output buffer */
 static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
-       struct kprobe_trace_event *tev;
+       struct probe_trace_event *tev;
        Dwarf_Addr eaddr;
        Dwarf_Die die_mem;
        const char *name;
@@ -683,7 +803,7 @@ static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
 
        /* Find each argument */
        tev->nargs = pf->pev->nargs;
-       tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
+       tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
        if (tev->args == NULL)
                return -ENOMEM;
        for (i = 0; i < pf->pev->nargs; i++) {
@@ -897,7 +1017,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 
        /* Check tag and diename */
        if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
-           die_compare_name(sp_die, pp->function) != 0)
+           !die_compare_name(sp_die, pp->function))
                return DWARF_CB_OK;
 
        pf->fname = dwarf_decl_file(sp_die);
@@ -940,9 +1060,9 @@ static int find_probe_point_by_func(struct probe_finder *pf)
        return _param.retval;
 }
 
-/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
-int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
-                            struct kprobe_trace_event **tevs, int max_tevs)
+/* Find probe_trace_events specified by perf_probe_event from debuginfo */
+int find_probe_trace_events(int fd, struct perf_probe_event *pev,
+                            struct probe_trace_event **tevs, int max_tevs)
 {
        struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs};
        struct perf_probe_point *pp = &pev->point;
@@ -952,7 +1072,7 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
        Dwarf *dbg;
        int ret = 0;
 
-       pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * max_tevs);
+       pf.tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
        if (pf.tevs == NULL)
                return -ENOMEM;
        *tevs = pf.tevs;
@@ -1096,7 +1216,7 @@ end:
 static int line_range_add_line(const char *src, unsigned int lineno,
                               struct line_range *lr)
 {
-       /* Copy real path */
+       /* Copy source path */
        if (!lr->path) {
                lr->path = strdup(src);
                if (lr->path == NULL)
@@ -1220,7 +1340,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
        struct line_range *lr = lf->lr;
 
        if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
-           die_compare_name(sp_die, lr->function) == 0) {
+           die_compare_name(sp_die, lr->function)) {
                lf->fname = dwarf_decl_file(sp_die);
                dwarf_decl_line(sp_die, &lr->offset);
                pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
@@ -1263,6 +1383,7 @@ int find_line_range(int fd, struct line_range *lr)
        size_t cuhl;
        Dwarf_Die *diep;
        Dwarf *dbg;
+       const char *comp_dir;
 
        dbg = dwarf_begin(fd, DWARF_C_READ);
        if (!dbg) {
@@ -1298,7 +1419,18 @@ int find_line_range(int fd, struct line_range *lr)
                }
                off = noff;
        }
-       pr_debug("path: %lx\n", (unsigned long)lr->path);
+
+       /* Store comp_dir */
+       if (lf.found) {
+               comp_dir = cu_get_comp_dir(&lf.cu_die);
+               if (comp_dir) {
+                       lr->comp_dir = strdup(comp_dir);
+                       if (!lr->comp_dir)
+                               ret = -ENOMEM;
+               }
+       }
+
+       pr_debug("path: %s\n", lr->path);
        dwarf_end(dbg);
 
        return (ret < 0) ? ret : lf.found;
index e1f61dcd18ff7ed18bff7a337ddcdf0dc8c68e36..4507d519f183b71be35c448dddb37f7610835cfc 100644 (file)
@@ -16,9 +16,9 @@ static inline int is_c_varname(const char *name)
 }
 
 #ifdef DWARF_SUPPORT
-/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
-extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
-                                   struct kprobe_trace_event **tevs,
+/* Find probe_trace_events specified by perf_probe_event from debuginfo */
+extern int find_probe_trace_events(int fd, struct perf_probe_event *pev,
+                                   struct probe_trace_event **tevs,
                                    int max_tevs);
 
 /* Find a perf_probe_point from debuginfo */
@@ -33,7 +33,7 @@ extern int find_line_range(int fd, struct line_range *lr);
 
 struct probe_finder {
        struct perf_probe_event *pev;           /* Target probe event */
-       struct kprobe_trace_event *tevs;        /* Result trace events */
+       struct probe_trace_event *tevs;         /* Result trace events */
        int                     ntevs;          /* Number of trace events */
        int                     max_tevs;       /* Max number of trace events */
 
@@ -50,7 +50,7 @@ struct probe_finder {
 #endif
        Dwarf_Op                *fb_ops;        /* Frame base attribute */
        struct perf_probe_arg   *pvar;          /* Current target variable */
-       struct kprobe_trace_arg *tvar;          /* Current result variable */
+       struct probe_trace_arg  *tvar;          /* Current result variable */
 };
 
 struct line_finder {
index c422cd6763135c10575f8621165262b48a1315a3..fa9d652c2dc3c07182028d4a196293333be75d78 100644 (file)
@@ -27,8 +27,10 @@ static int perf_session__open(struct perf_session *self, bool force)
 
        self->fd = open(self->filename, O_RDONLY);
        if (self->fd < 0) {
-               pr_err("failed to open file: %s", self->filename);
-               if (!strcmp(self->filename, "perf.data"))
+               int err = errno;
+
+               pr_err("failed to open %s: %s", self->filename, strerror(err));
+               if (err == ENOENT && !strcmp(self->filename, "perf.data"))
                        pr_err("  (try 'perf record' first)");
                pr_err("\n");
                return -errno;
@@ -77,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self)
        return ret;
 }
 
+static void perf_session__destroy_kernel_maps(struct perf_session *self)
+{
+       machine__destroy_kernel_maps(&self->host_machine);
+       machines__destroy_guest_kernel_maps(&self->machines);
+}
+
 struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe)
 {
        size_t len = filename ? strlen(filename) + 1 : 0;
@@ -94,8 +102,6 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
        self->hists_tree = RB_ROOT;
        self->last_match = NULL;
        self->mmap_window = 32;
-       self->cwd = NULL;
-       self->cwdlen = 0;
        self->machines = RB_ROOT;
        self->repipe = repipe;
        INIT_LIST_HEAD(&self->ordered_samples.samples_head);
@@ -124,16 +130,43 @@ out_delete:
        return NULL;
 }
 
+static void perf_session__delete_dead_threads(struct perf_session *self)
+{
+       struct thread *n, *t;
+
+       list_for_each_entry_safe(t, n, &self->dead_threads, node) {
+               list_del(&t->node);
+               thread__delete(t);
+       }
+}
+
+static void perf_session__delete_threads(struct perf_session *self)
+{
+       struct rb_node *nd = rb_first(&self->threads);
+
+       while (nd) {
+               struct thread *t = rb_entry(nd, struct thread, rb_node);
+
+               rb_erase(&t->rb_node, &self->threads);
+               nd = rb_next(nd);
+               thread__delete(t);
+       }
+}
+
 void perf_session__delete(struct perf_session *self)
 {
        perf_header__exit(&self->header);
+       perf_session__destroy_kernel_maps(self);
+       perf_session__delete_dead_threads(self);
+       perf_session__delete_threads(self);
+       machine__exit(&self->host_machine);
        close(self->fd);
-       free(self->cwd);
        free(self);
 }
 
 void perf_session__remove_thread(struct perf_session *self, struct thread *th)
 {
+       self->last_match = NULL;
        rb_erase(&th->rb_node, &self->threads);
        /*
         * We may have references to this thread, for instance in some hist_entry
@@ -830,23 +863,6 @@ int perf_session__process_events(struct perf_session *self,
        if (perf_session__register_idle_thread(self) == NULL)
                return -ENOMEM;
 
-       if (!symbol_conf.full_paths) {
-               char bf[PATH_MAX];
-
-               if (getcwd(bf, sizeof(bf)) == NULL) {
-                       err = -errno;
-out_getcwd_err:
-                       pr_err("failed to get the current directory\n");
-                       goto out_err;
-               }
-               self->cwd = strdup(bf);
-               if (self->cwd == NULL) {
-                       err = -ENOMEM;
-                       goto out_getcwd_err;
-               }
-               self->cwdlen = strlen(self->cwd);
-       }
-
        if (!self->fd_pipe)
                err = __perf_session__process_events(self,
                                                     self->header.data_offset,
@@ -854,7 +870,7 @@ out_getcwd_err:
                                                     self->size, ops);
        else
                err = __perf_session__process_pipe_events(self, ops);
-out_err:
+
        return err;
 }
 
index 2316cb5a41164d4d99fbb289118def977b74cf5e..1c61a4f4aa8affbf01df5992a50a149893257b68 100644 (file)
@@ -1,4 +1,5 @@
 #include "sort.h"
+#include "hist.h"
 
 regex_t                parent_regex;
 const char     default_parent_pattern[] = "^sys_|^do_page_fault";
@@ -10,10 +11,6 @@ int          sort__has_parent = 0;
 
 enum sort_type sort__first_dimension;
 
-unsigned int dsos__col_width;
-unsigned int comms__col_width;
-unsigned int threads__col_width;
-static unsigned int parent_symbol__col_width;
 char * field_sep;
 
 LIST_HEAD(hist_entry__sort_list);
@@ -28,12 +25,14 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
                                    size_t size, unsigned int width);
 static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
                                       size_t size, unsigned int width);
+static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, unsigned int width);
 
 struct sort_entry sort_thread = {
        .se_header      = "Command:  Pid",
        .se_cmp         = sort__thread_cmp,
        .se_snprintf    = hist_entry__thread_snprintf,
-       .se_width       = &threads__col_width,
+       .se_width_idx   = HISTC_THREAD,
 };
 
 struct sort_entry sort_comm = {
@@ -41,27 +40,35 @@ struct sort_entry sort_comm = {
        .se_cmp         = sort__comm_cmp,
        .se_collapse    = sort__comm_collapse,
        .se_snprintf    = hist_entry__comm_snprintf,
-       .se_width       = &comms__col_width,
+       .se_width_idx   = HISTC_COMM,
 };
 
 struct sort_entry sort_dso = {
        .se_header      = "Shared Object",
        .se_cmp         = sort__dso_cmp,
        .se_snprintf    = hist_entry__dso_snprintf,
-       .se_width       = &dsos__col_width,
+       .se_width_idx   = HISTC_DSO,
 };
 
 struct sort_entry sort_sym = {
        .se_header      = "Symbol",
        .se_cmp         = sort__sym_cmp,
        .se_snprintf    = hist_entry__sym_snprintf,
+       .se_width_idx   = HISTC_SYMBOL,
 };
 
 struct sort_entry sort_parent = {
        .se_header      = "Parent symbol",
        .se_cmp         = sort__parent_cmp,
        .se_snprintf    = hist_entry__parent_snprintf,
-       .se_width       = &parent_symbol__col_width,
+       .se_width_idx   = HISTC_PARENT,
+};
+struct sort_entry sort_cpu = {
+       .se_header      = "CPU",
+       .se_cmp         = sort__cpu_cmp,
+       .se_snprintf    = hist_entry__cpu_snprintf,
+       .se_width_idx   = HISTC_CPU,
 };
 
 struct sort_dimension {
@@ -76,6 +83,7 @@ static struct sort_dimension sort_dimensions[] = {
        { .name = "dso",        .entry = &sort_dso,     },
        { .name = "symbol",     .entry = &sort_sym,     },
        { .name = "parent",     .entry = &sort_parent,  },
+       { .name = "cpu",        .entry = &sort_cpu,     },
 };
 
 int64_t cmp_null(void *l, void *r)
@@ -242,6 +250,20 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
                              self->parent ? self->parent->name : "[other]");
 }
 
+/* --sort cpu */
+
+int64_t
+sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+       return right->cpu - left->cpu;
+}
+
+static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width)
+{
+       return repsep_snprintf(bf, size, "%-*d", width, self->cpu);
+}
+
 int sort_dimension__add(const char *tok)
 {
        unsigned int i;
@@ -281,6 +303,8 @@ int sort_dimension__add(const char *tok)
                                sort__first_dimension = SORT_SYM;
                        else if (!strcmp(sd->name, "parent"))
                                sort__first_dimension = SORT_PARENT;
+                       else if (!strcmp(sd->name, "cpu"))
+                               sort__first_dimension = SORT_CPU;
                }
 
                list_add_tail(&sd->entry->list, &hist_entry__sort_list);
index 0d61c4082f43849ddfe4ac1f6cb1cf9841009dd8..46e531d09e8bfcbe1064a4307ce5a75ef72a6405 100644 (file)
@@ -36,11 +36,14 @@ extern struct sort_entry sort_comm;
 extern struct sort_entry sort_dso;
 extern struct sort_entry sort_sym;
 extern struct sort_entry sort_parent;
-extern unsigned int dsos__col_width;
-extern unsigned int comms__col_width;
-extern unsigned int threads__col_width;
 extern enum sort_type sort__first_dimension;
 
+/**
+ * struct hist_entry - histogram entry
+ *
+ * @row_offset - offset from the first callchain expanded to appear on screen
+ * @nr_rows - rows expanded in callchain, recalculated on folding/unfolding
+ */
 struct hist_entry {
        struct rb_node          rb_node;
        u64                     period;
@@ -51,7 +54,14 @@ struct hist_entry {
        struct map_symbol       ms;
        struct thread           *thread;
        u64                     ip;
+       s32                     cpu;
        u32                     nr_events;
+
+       /* XXX These two should move to some tree widget lib */
+       u16                     row_offset;
+       u16                     nr_rows;
+
+       bool                    init_have_children;
        char                    level;
        u8                      filtered;
        struct symbol           *parent;
@@ -68,7 +78,8 @@ enum sort_type {
        SORT_COMM,
        SORT_DSO,
        SORT_SYM,
-       SORT_PARENT
+       SORT_PARENT,
+       SORT_CPU,
 };
 
 /*
@@ -84,7 +95,7 @@ struct sort_entry {
        int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
        int     (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
                               unsigned int width);
-       unsigned int *se_width;
+       u8      se_width_idx;
        bool    elide;
 };
 
@@ -104,6 +115,7 @@ extern int64_t sort__comm_collapse(struct hist_entry *, struct hist_entry *);
 extern int64_t sort__dso_cmp(struct hist_entry *, struct hist_entry *);
 extern int64_t sort__sym_cmp(struct hist_entry *, struct hist_entry *);
 extern int64_t sort__parent_cmp(struct hist_entry *, struct hist_entry *);
+int64_t sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right);
 extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int);
 extern int sort_dimension__add(const char *);
 void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
index 5b276833e2bfea3bae9115f2555b32e3a3b8b628..6f0dd90c36ce75496e78e9be7662e08a7d000511 100644 (file)
@@ -12,6 +12,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include "build-id.h"
+#include "debug.h"
 #include "symbol.h"
 #include "strlist.h"
 
@@ -25,6 +26,8 @@
 #define NT_GNU_BUILD_ID 3
 #endif
 
+static bool dso__build_id_equal(const struct dso *self, u8 *build_id);
+static int elf_read_build_id(Elf *elf, void *bf, size_t size);
 static void dsos__add(struct list_head *head, struct dso *dso);
 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
 static int dso__load_kernel_sym(struct dso *self, struct map *map,
@@ -40,6 +43,14 @@ struct symbol_conf symbol_conf = {
        .try_vmlinux_path = true,
 };
 
+int dso__name_len(const struct dso *self)
+{
+       if (verbose)
+               return self->long_name_len;
+
+       return self->short_name_len;
+}
+
 bool dso__loaded(const struct dso *self, enum map_type type)
 {
        return self->loaded & (1 << type);
@@ -215,7 +226,9 @@ void dso__delete(struct dso *self)
        int i;
        for (i = 0; i < MAP__NR_TYPES; ++i)
                symbols__delete(&self->symbols[i]);
-       if (self->long_name != self->name)
+       if (self->sname_alloc)
+               free((char *)self->short_name);
+       if (self->lname_alloc)
                free(self->long_name);
        free(self);
 }
@@ -933,8 +946,28 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type
        }
 }
 
+static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
+{
+       Elf_Scn *sec = NULL;
+       GElf_Shdr shdr;
+       size_t cnt = 1;
+
+       while ((sec = elf_nextscn(elf, sec)) != NULL) {
+               gelf_getshdr(sec, &shdr);
+
+               if ((addr >= shdr.sh_addr) &&
+                   (addr < (shdr.sh_addr + shdr.sh_size)))
+                       return cnt;
+
+               ++cnt;
+       }
+
+       return -1;
+}
+
 static int dso__load_sym(struct dso *self, struct map *map, const char *name,
-                        int fd, symbol_filter_t filter, int kmodule)
+                        int fd, symbol_filter_t filter, int kmodule,
+                        int want_symtab)
 {
        struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
        struct map *curr_map = map;
@@ -944,31 +977,51 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
        int err = -1;
        uint32_t idx;
        GElf_Ehdr ehdr;
-       GElf_Shdr shdr;
-       Elf_Data *syms;
+       GElf_Shdr shdr, opdshdr;
+       Elf_Data *syms, *opddata = NULL;
        GElf_Sym sym;
-       Elf_Scn *sec, *sec_strndx;
+       Elf_Scn *sec, *sec_strndx, *opdsec;
        Elf *elf;
        int nr = 0;
+       size_t opdidx = 0;
 
        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
        if (elf == NULL) {
-               pr_err("%s: cannot read %s ELF file.\n", __func__, name);
+               pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
                goto out_close;
        }
 
        if (gelf_getehdr(elf, &ehdr) == NULL) {
-               pr_err("%s: cannot get elf header.\n", __func__);
+               pr_debug("%s: cannot get elf header.\n", __func__);
                goto out_elf_end;
        }
 
+       /* Always reject images with a mismatched build-id: */
+       if (self->has_build_id) {
+               u8 build_id[BUILD_ID_SIZE];
+
+               if (elf_read_build_id(elf, build_id,
+                                     BUILD_ID_SIZE) != BUILD_ID_SIZE)
+                       goto out_elf_end;
+
+               if (!dso__build_id_equal(self, build_id))
+                       goto out_elf_end;
+       }
+
        sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
        if (sec == NULL) {
+               if (want_symtab)
+                       goto out_elf_end;
+
                sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
                if (sec == NULL)
                        goto out_elf_end;
        }
 
+       opdsec = elf_section_by_name(elf, &ehdr, &opdshdr, ".opd", &opdidx);
+       if (opdsec)
+               opddata = elf_rawdata(opdsec, NULL);
+
        syms = elf_getdata(sec, NULL);
        if (syms == NULL)
                goto out_elf_end;
@@ -1013,6 +1066,13 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
                if (!is_label && !elf_sym__is_a(&sym, map->type))
                        continue;
 
+               if (opdsec && sym.st_shndx == opdidx) {
+                       u32 offset = sym.st_value - opdshdr.sh_addr;
+                       u64 *opd = opddata->d_buf + offset;
+                       sym.st_value = *opd;
+                       sym.st_shndx = elf_addr_to_index(elf, sym.st_value);
+               }
+
                sec = elf_getscn(elf, sym.st_shndx);
                if (!sec)
                        goto out_elf_end;
@@ -1151,37 +1211,26 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
  */
 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
 
-int filename__read_build_id(const char *filename, void *bf, size_t size)
+static int elf_read_build_id(Elf *elf, void *bf, size_t size)
 {
-       int fd, err = -1;
+       int err = -1;
        GElf_Ehdr ehdr;
        GElf_Shdr shdr;
        Elf_Data *data;
        Elf_Scn *sec;
        Elf_Kind ek;
        void *ptr;
-       Elf *elf;
 
        if (size < BUILD_ID_SIZE)
                goto out;
 
-       fd = open(filename, O_RDONLY);
-       if (fd < 0)
-               goto out;
-
-       elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
-       if (elf == NULL) {
-               pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
-               goto out_close;
-       }
-
        ek = elf_kind(elf);
        if (ek != ELF_K_ELF)
-               goto out_elf_end;
+               goto out;
 
        if (gelf_getehdr(elf, &ehdr) == NULL) {
                pr_err("%s: cannot get elf header.\n", __func__);
-               goto out_elf_end;
+               goto out;
        }
 
        sec = elf_section_by_name(elf, &ehdr, &shdr,
@@ -1190,12 +1239,12 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
                sec = elf_section_by_name(elf, &ehdr, &shdr,
                                          ".notes", NULL);
                if (sec == NULL)
-                       goto out_elf_end;
+                       goto out;
        }
 
        data = elf_getdata(sec, NULL);
        if (data == NULL)
-               goto out_elf_end;
+               goto out;
 
        ptr = data->d_buf;
        while (ptr < (data->d_buf + data->d_size)) {
@@ -1217,7 +1266,31 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
                }
                ptr += descsz;
        }
-out_elf_end:
+
+out:
+       return err;
+}
+
+int filename__read_build_id(const char *filename, void *bf, size_t size)
+{
+       int fd, err = -1;
+       Elf *elf;
+
+       if (size < BUILD_ID_SIZE)
+               goto out;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               goto out;
+
+       elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
+       if (elf == NULL) {
+               pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
+               goto out_close;
+       }
+
+       err = elf_read_build_id(elf, bf, size);
+
        elf_end(elf);
 out_close:
        close(fd);
@@ -1293,11 +1366,11 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 {
        int size = PATH_MAX;
        char *name;
-       u8 build_id[BUILD_ID_SIZE];
        int ret = -1;
        int fd;
        struct machine *machine;
        const char *root_dir;
+       int want_symtab;
 
        dso__set_loaded(self, map->type);
 
@@ -1324,13 +1397,18 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
                return ret;
        }
 
-       self->origin = DSO__ORIG_BUILD_ID_CACHE;
-       if (dso__build_id_filename(self, name, size) != NULL)
-               goto open_file;
-more:
-       do {
-               self->origin++;
+       /* Iterate over candidate debug images.
+        * On the first pass, only load images if they have a full symtab.
+        * Failing that, do a second pass where we accept .dynsym also
+        */
+       for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1;
+            self->origin != DSO__ORIG_NOT_FOUND;
+            self->origin++) {
                switch (self->origin) {
+               case DSO__ORIG_BUILD_ID_CACHE:
+                       if (dso__build_id_filename(self, name, size) == NULL)
+                               continue;
+                       break;
                case DSO__ORIG_FEDORA:
                        snprintf(name, size, "/usr/lib/debug%s.debug",
                                 self->long_name);
@@ -1339,21 +1417,20 @@ more:
                        snprintf(name, size, "/usr/lib/debug%s",
                                 self->long_name);
                        break;
-               case DSO__ORIG_BUILDID:
-                       if (filename__read_build_id(self->long_name, build_id,
-                                                   sizeof(build_id))) {
-                               char build_id_hex[BUILD_ID_SIZE * 2 + 1];
-                               build_id__sprintf(build_id, sizeof(build_id),
-                                                 build_id_hex);
-                               snprintf(name, size,
-                                        "/usr/lib/debug/.build-id/%.2s/%s.debug",
-                                       build_id_hex, build_id_hex + 2);
-                               if (self->has_build_id)
-                                       goto compare_build_id;
-                               break;
+               case DSO__ORIG_BUILDID: {
+                       char build_id_hex[BUILD_ID_SIZE * 2 + 1];
+
+                       if (!self->has_build_id)
+                               continue;
+
+                       build_id__sprintf(self->build_id,
+                                         sizeof(self->build_id),
+                                         build_id_hex);
+                       snprintf(name, size,
+                                "/usr/lib/debug/.build-id/%.2s/%s.debug",
+                                build_id_hex, build_id_hex + 2);
                        }
-                       self->origin++;
-                       /* Fall thru */
+                       break;
                case DSO__ORIG_DSO:
                        snprintf(name, size, "%s", self->long_name);
                        break;
@@ -1366,36 +1443,41 @@ more:
                        break;
 
                default:
-                       goto out;
+                       /*
+                        * If we wanted a full symtab but no image had one,
+                        * relax our requirements and repeat the search.
+                        */
+                       if (want_symtab) {
+                               want_symtab = 0;
+                               self->origin = DSO__ORIG_BUILD_ID_CACHE;
+                       } else
+                               continue;
                }
 
-               if (self->has_build_id) {
-                       if (filename__read_build_id(name, build_id,
-                                                   sizeof(build_id)) < 0)
-                               goto more;
-compare_build_id:
-                       if (!dso__build_id_equal(self, build_id))
-                               goto more;
-               }
-open_file:
+               /* Name is now the name of the next image to try */
                fd = open(name, O_RDONLY);
-       } while (fd < 0);
+               if (fd < 0)
+                       continue;
 
-       ret = dso__load_sym(self, map, name, fd, filter, 0);
-       close(fd);
+               ret = dso__load_sym(self, map, name, fd, filter, 0,
+                                   want_symtab);
+               close(fd);
 
-       /*
-        * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
-        */
-       if (!ret)
-               goto more;
+               /*
+                * Some people seem to have debuginfo files _WITHOUT_ debug
+                * info!?!?
+                */
+               if (!ret)
+                       continue;
 
-       if (ret > 0) {
-               int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
-               if (nr_plt > 0)
-                       ret += nr_plt;
+               if (ret > 0) {
+                       int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
+                       if (nr_plt > 0)
+                               ret += nr_plt;
+                       break;
+               }
        }
-out:
+
        free(name);
        if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
                return 0;
@@ -1494,6 +1576,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *self,
                                goto out;
                        }
                        dso__set_long_name(map->dso, long_name);
+                       map->dso->lname_alloc = 1;
                        dso__kernel_module_get_build_id(map->dso, "");
                }
        }
@@ -1656,36 +1739,12 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
 {
        int err = -1, fd;
 
-       if (self->has_build_id) {
-               u8 build_id[BUILD_ID_SIZE];
-
-               if (filename__read_build_id(vmlinux, build_id,
-                                           sizeof(build_id)) < 0) {
-                       pr_debug("No build_id in %s, ignoring it\n", vmlinux);
-                       return -1;
-               }
-               if (!dso__build_id_equal(self, build_id)) {
-                       char expected_build_id[BUILD_ID_SIZE * 2 + 1],
-                            vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
-
-                       build_id__sprintf(self->build_id,
-                                         sizeof(self->build_id),
-                                         expected_build_id);
-                       build_id__sprintf(build_id, sizeof(build_id),
-                                         vmlinux_build_id);
-                       pr_debug("build_id in %s is %s while expected is %s, "
-                                "ignoring it\n", vmlinux, vmlinux_build_id,
-                                expected_build_id);
-                       return -1;
-               }
-       }
-
        fd = open(vmlinux, O_RDONLY);
        if (fd < 0)
                return -1;
 
        dso__set_loaded(self, map->type);
-       err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
+       err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
        close(fd);
 
        if (err > 0)
@@ -2048,6 +2107,36 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
        return 0;
 }
 
+void machine__destroy_kernel_maps(struct machine *self)
+{
+       enum map_type type;
+
+       for (type = 0; type < MAP__NR_TYPES; ++type) {
+               struct kmap *kmap;
+
+               if (self->vmlinux_maps[type] == NULL)
+                       continue;
+
+               kmap = map__kmap(self->vmlinux_maps[type]);
+               map_groups__remove(&self->kmaps, self->vmlinux_maps[type]);
+               if (kmap->ref_reloc_sym) {
+                       /*
+                        * ref_reloc_sym is shared among all maps, so free just
+                        * on one of them.
+                        */
+                       if (type == MAP__FUNCTION) {
+                               free((char *)kmap->ref_reloc_sym->name);
+                               kmap->ref_reloc_sym->name = NULL;
+                               free(kmap->ref_reloc_sym);
+                       }
+                       kmap->ref_reloc_sym = NULL;
+               }
+
+               map__delete(self->vmlinux_maps[type]);
+               self->vmlinux_maps[type] = NULL;
+       }
+}
+
 int machine__create_kernel_maps(struct machine *self)
 {
        struct dso *kernel = machine__create_kernel(self);
@@ -2189,6 +2278,15 @@ out_free_comm_list:
        return -1;
 }
 
+void symbol__exit(void)
+{
+       strlist__delete(symbol_conf.sym_list);
+       strlist__delete(symbol_conf.dso_list);
+       strlist__delete(symbol_conf.comm_list);
+       vmlinux_path__exit();
+       symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
+}
+
 int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
 {
        struct machine *machine = machines__findnew(self, pid);
@@ -2283,6 +2381,19 @@ failure:
        return ret;
 }
 
+void machines__destroy_guest_kernel_maps(struct rb_root *self)
+{
+       struct rb_node *next = rb_first(self);
+
+       while (next) {
+               struct machine *pos = rb_entry(next, struct machine, rb_node);
+
+               next = rb_next(&pos->rb_node);
+               rb_erase(&pos->rb_node, self);
+               machine__delete(pos);
+       }
+}
+
 int machine__load_kallsyms(struct machine *self, const char *filename,
                           enum map_type type, symbol_filter_t filter)
 {
index 5e02d2c1715425c800af943b808143c9ed302ba3..906be20011d93ce7aeeea9d02c9026a3bf2db359 100644 (file)
@@ -9,8 +9,6 @@
 #include <linux/rbtree.h>
 #include <stdio.h>
 
-#define DEBUG_CACHE_DIR ".debug"
-
 #ifdef HAVE_CPLUS_DEMANGLE
 extern char *cplus_demangle(const char *, int);
 
@@ -70,9 +68,9 @@ struct symbol_conf {
                        show_nr_samples,
                        use_callchain,
                        exclude_other,
-                       full_paths,
                        show_cpu_utilization;
        const char      *vmlinux_name,
+                       *source_prefix,
                        *field_sep;
        const char      *default_guest_vmlinux_name,
                        *default_guest_kallsyms,
@@ -103,6 +101,8 @@ struct ref_reloc_sym {
 struct map_symbol {
        struct map    *map;
        struct symbol *sym;
+       bool          unfolded;
+       bool          has_children;
 };
 
 struct addr_location {
@@ -112,7 +112,8 @@ struct addr_location {
        u64           addr;
        char          level;
        bool          filtered;
-       unsigned int  cpumode;
+       u8            cpumode;
+       s32           cpu;
 };
 
 enum dso_kernel_type {
@@ -125,12 +126,14 @@ struct dso {
        struct list_head node;
        struct rb_root   symbols[MAP__NR_TYPES];
        struct rb_root   symbol_names[MAP__NR_TYPES];
+       enum dso_kernel_type    kernel;
        u8               adjust_symbols:1;
        u8               slen_calculated:1;
        u8               has_build_id:1;
-       enum dso_kernel_type    kernel;
        u8               hit:1;
        u8               annotate_warned:1;
+       u8               sname_alloc:1;
+       u8               lname_alloc:1;
        unsigned char    origin;
        u8               sorted_by_name;
        u8               loaded;
@@ -146,6 +149,8 @@ struct dso *dso__new(const char *name);
 struct dso *dso__new_kernel(const char *name);
 void dso__delete(struct dso *self);
 
+int dso__name_len(const struct dso *self);
+
 bool dso__loaded(const struct dso *self, enum map_type type);
 bool dso__sorted_by_name(const struct dso *self, enum map_type type);
 
@@ -207,13 +212,16 @@ int kallsyms__parse(const char *filename, void *arg,
                    int (*process_symbol)(void *arg, const char *name,
                                          char type, u64 start));
 
+void machine__destroy_kernel_maps(struct machine *self);
 int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
 int machine__create_kernel_maps(struct machine *self);
 
 int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
 int machines__create_guest_kernel_maps(struct rb_root *self);
+void machines__destroy_guest_kernel_maps(struct rb_root *self);
 
 int symbol__init(void);
+void symbol__exit(void);
 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
 
 size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp);
index 9a448b47400c8ec2305c4d0153d885fe4962a612..8c72d888e449989dcdf1c349fdc4a97ead6b694a 100644 (file)
@@ -62,6 +62,13 @@ static struct thread *thread__new(pid_t pid)
        return self;
 }
 
+void thread__delete(struct thread *self)
+{
+       map_groups__exit(&self->mg);
+       free(self->comm);
+       free(self);
+}
+
 int thread__set_comm(struct thread *self, const char *comm)
 {
        int err;
index ee6bbcf277cad88ea4143a8d7a6a9e21cc07a74c..688500ff826f008a4c48cd5bf782ad60c1363325 100644 (file)
@@ -20,6 +20,8 @@ struct thread {
 
 struct perf_session;
 
+void thread__delete(struct thread *self);
+
 int find_all_tid(int pid, pid_t ** all_tid);
 int thread__set_comm(struct thread *self, const char *comm);
 int thread__comm_len(struct thread *self);
index 4e8b6b0c551c87cd98f78857e4205ff3f5cd79d5..f380fed74359034a843756256d6e7a79b0ff22b5 100644 (file)
@@ -89,6 +89,7 @@
 
 extern const char *graph_line;
 extern const char *graph_dotted_line;
+extern char buildid_dir[];
 
 /* On most systems <limits.h> would have given us this, but
  * not on some systems (e.g. GNU/Hurd).
@@ -152,6 +153,8 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)))
 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
 
 extern int prefixcmp(const char *str, const char *prefix);
+extern void set_buildid_dir(void);
+extern void disable_buildid_cache(void);
 
 static inline const char *skip_prefix(const char *str, const char *prefix)
 {